From 3fcc7cd391aee7c195ec1c97a96ca0507794ac21 Mon Sep 17 00:00:00 2001 From: short <> Date: Mon, 1 Sep 2003 11:11:27 +0000 Subject: [PATCH 1/1] ftp://ftp.redhat.com/pub/redhat/linux/rawhide/SRPMS/SRPMS/gnome-vfs2-2.3.8-1.src.rpm --- AUTHORS | 75 + COPYING | 340 + COPYING.LIB | 481 + ChangeLog | 21423 +++++++++++++++++++ HACKING | 54 + INSTALL | 182 + Makefile.am | 27 + Makefile.in | 520 + NEWS | 267 + README | 18 + TODO | 127 + acconfig.h | 43 + acinclude.m4 | 185 + aclocal.m4 | 4913 +++++ autogen.sh | 21 + config.guess | 1409 ++ config.h.in | 238 + config.sub | 1469 ++ configure | 16861 +++++++++++++++ configure.in | 695 + devel-docs/Makefile.am | 9 + devel-docs/Makefile.in | 416 + devel-docs/gnome-vfs-tutorial/Makefile.am | 2 + devel-docs/gnome-vfs-tutorial/Makefile.in | 283 + .../gnome-vfs-tutorial/gnome-vfs-tutorial.sgml | 3752 ++++ doc/Makefile.am | 208 + doc/Makefile.in | 488 + doc/about.sgml | 182 + doc/gnome-vfs-2.0-docs.sgml | 180 + doc/gnome-vfs-2.0-overrides.txt | 0 doc/gnome-vfs-2.0-sections.txt | 553 + doc/gnome-vfs-2.0.types | 0 doc/html/about.html | 58 + doc/html/advanced-operations.html | 33 + doc/html/c9456.html | 239 + doc/html/c9466.html | 172 + doc/html/ch08.html | 31 + doc/html/data-types.html | 34 + doc/html/directory-operations.html | 165 + doc/html/everything-else.html | 249 + doc/html/file-operations.html | 180 + ...nome-vfs-20-gnome-vfs-application-registry.html | 344 + doc/html/gnome-vfs-20-gnome-vfs-async-ops.html | 978 + doc/html/gnome-vfs-20-gnome-vfs-cancellation.html | 93 + doc/html/gnome-vfs-20-gnome-vfs-context.html | 83 + ...gnome-vfs-20-gnome-vfs-directory-basic-ops.html | 89 + .../gnome-vfs-20-gnome-vfs-directory-find-ops.html | 90 + .../gnome-vfs-20-gnome-vfs-directory-list-ops.html | 286 + .../gnome-vfs-20-gnome-vfs-file-advanced-ops.html | 57 + .../gnome-vfs-20-gnome-vfs-file-basic-ops.html | 278 + doc/html/gnome-vfs-20-gnome-vfs-file-info-ops.html | 130 + doc/html/gnome-vfs-20-gnome-vfs-file-info.html | 438 + doc/html/gnome-vfs-20-gnome-vfs-file-rw-ops.html | 118 + doc/html/gnome-vfs-20-gnome-vfs-file-size.html | 58 + .../gnome-vfs-20-gnome-vfs-file-trunc-ops.html | 70 + .../gnome-vfs-20-gnome-vfs-inet-connection.html | 107 + doc/html/gnome-vfs-20-gnome-vfs-init.html | 117 + doc/html/gnome-vfs-20-gnome-vfs-method.html | 129 + doc/html/gnome-vfs-20-gnome-vfs-mime-database.html | 818 + doc/html/gnome-vfs-20-gnome-vfs-mime-monitor.html | 53 + doc/html/gnome-vfs-20-gnome-vfs-mime.html | 133 + ...fs-20-gnome-vfs-module-callback-module-api.html | 89 + .../gnome-vfs-20-gnome-vfs-module-callback.html | 350 + doc/html/gnome-vfs-20-gnome-vfs-module-shared.html | 98 + doc/html/gnome-vfs-20-gnome-vfs-module.html | 69 + doc/html/gnome-vfs-20-gnome-vfs-monitor.html | 128 + doc/html/gnome-vfs-20-gnome-vfs-parse-ls.html | 53 + doc/html/gnome-vfs-20-gnome-vfs-result.html | 118 + doc/html/gnome-vfs-20-gnome-vfs-socket-buffer.html | 127 + doc/html/gnome-vfs-20-gnome-vfs-socket.html | 161 + doc/html/gnome-vfs-20-gnome-vfs-ssl.html | 126 + .../gnome-vfs-20-gnome-vfs-standard-callbacks.html | 140 + doc/html/gnome-vfs-20-gnome-vfs-transform.html | 65 + doc/html/gnome-vfs-20-gnome-vfs-uri.html | 571 + doc/html/gnome-vfs-20-gnome-vfs-utils.html | 270 + doc/html/gnome-vfs-20-gnome-vfs-xfer.html | 374 + doc/html/gnome-vfs-application-registry.html | 2346 ++ doc/html/gnome-vfs-asynchronous-operations.html | 4066 ++++ doc/html/gnome-vfs-cancellation.html | 772 + doc/html/gnome-vfs-configuration.html | 555 + doc/html/gnome-vfs-context.html | 764 + doc/html/gnome-vfs-directory-operations.html | 36 + doc/html/gnome-vfs-directory.html | 1780 ++ doc/html/gnome-vfs-file-info.html | 2129 ++ doc/html/gnome-vfs-file-operations.html | 43 + doc/html/gnome-vfs-file-size.html | 426 + .../gnome-vfs-finding-special-directories.html | 516 + doc/html/gnome-vfs-first-steps.html | 142 + .../gnome-vfs-gnome-vfs-application-registry.html | 349 + doc/html/gnome-vfs-gnome-vfs-async-ops.html | 981 + doc/html/gnome-vfs-gnome-vfs-cancellation.html | 98 + doc/html/gnome-vfs-gnome-vfs-context.html | 86 + .../gnome-vfs-gnome-vfs-directory-basic-ops.html | 94 + .../gnome-vfs-gnome-vfs-directory-find-ops.html | 95 + .../gnome-vfs-gnome-vfs-directory-list-ops.html | 293 + doc/html/gnome-vfs-gnome-vfs-directory.html | 2318 ++ .../gnome-vfs-gnome-vfs-file-advanced-ops.html | 59 + doc/html/gnome-vfs-gnome-vfs-file-basic-ops.html | 278 + doc/html/gnome-vfs-gnome-vfs-file-info-ops.html | 130 + doc/html/gnome-vfs-gnome-vfs-file-info.html | 443 + doc/html/gnome-vfs-gnome-vfs-file-rw-ops.html | 118 + doc/html/gnome-vfs-gnome-vfs-file-size.html | 65 + doc/html/gnome-vfs-gnome-vfs-file-trunc-ops.html | 70 + doc/html/gnome-vfs-gnome-vfs-find-directory.html | 454 + doc/html/gnome-vfs-gnome-vfs-inet-connection.html | 107 + doc/html/gnome-vfs-gnome-vfs-init.html | 120 + doc/html/gnome-vfs-gnome-vfs-method.html | 131 + doc/html/gnome-vfs-gnome-vfs-mime-database.html | 825 + doc/html/gnome-vfs-gnome-vfs-mime-monitor.html | 58 + doc/html/gnome-vfs-gnome-vfs-mime.html | 136 + ...e-vfs-gnome-vfs-module-callback-module-api.html | 89 + doc/html/gnome-vfs-gnome-vfs-module-callback.html | 350 + doc/html/gnome-vfs-gnome-vfs-module-shared.html | 98 + doc/html/gnome-vfs-gnome-vfs-module.html | 69 + doc/html/gnome-vfs-gnome-vfs-monitor.html | 133 + doc/html/gnome-vfs-gnome-vfs-ops.html | 3817 ++++ doc/html/gnome-vfs-gnome-vfs-parse-ls.html | 53 + doc/html/gnome-vfs-gnome-vfs-result.html | 125 + doc/html/gnome-vfs-gnome-vfs-socket-buffer.html | 127 + doc/html/gnome-vfs-gnome-vfs-socket.html | 163 + doc/html/gnome-vfs-gnome-vfs-ssl.html | 128 + .../gnome-vfs-gnome-vfs-standard-callbacks.html | 140 + doc/html/gnome-vfs-gnome-vfs-transform.html | 65 + doc/html/gnome-vfs-gnome-vfs-uri.html | 575 + doc/html/gnome-vfs-gnome-vfs-utils.html | 269 + doc/html/gnome-vfs-gnome-vfs-xfer.html | 376 + doc/html/gnome-vfs-gnomevfsmetadata.html | 638 + doc/html/gnome-vfs-gnomevfsmimemonitor.html | 288 + doc/html/gnome-vfs-inet-connection.html | 603 + doc/html/gnome-vfs-initialization.html | 726 + doc/html/gnome-vfs-iobuf.html | 950 + doc/html/gnome-vfs-method.html | 1081 + doc/html/gnome-vfs-mime-handlers.html | 4630 ++++ doc/html/gnome-vfs-mime-info.html | 1709 ++ doc/html/gnome-vfs-mime-magic.html | 542 + doc/html/gnome-vfs-mime-monitor.html | 383 + doc/html/gnome-vfs-mime-sniff-buffer.html | 1625 ++ doc/html/gnome-vfs-mime.html | 1265 ++ doc/html/gnome-vfs-module-callback-module-api.html | 522 + doc/html/gnome-vfs-module-callbacks.html | 1862 ++ doc/html/gnome-vfs-module-shared.html | 816 + doc/html/gnome-vfs-module.html | 635 + doc/html/gnome-vfs-ops.html | 4262 ++++ doc/html/gnome-vfs-parse-ls.html | 415 + doc/html/gnome-vfs-process.html | 275 + doc/html/gnome-vfs-result.html | 598 + doc/html/gnome-vfs-ssl.html | 734 + doc/html/gnome-vfs-standard-callbacks.html | 719 + doc/html/gnome-vfs-types.html | 2514 +++ doc/html/gnome-vfs-uri.html | 3941 ++++ doc/html/gnome-vfs-utils.html | 1864 ++ doc/html/gnome-vfs-writing-modules.html | 328 + doc/html/gnome-vfs-xfer.html | 1103 + doc/html/index.html | 39 + doc/html/index.sgml | 424 + doc/html/mime-registry.html | 42 + doc/html/modules.html | 38 + doc/html/writing-modules.html | 974 + doc/html/x27.html | 474 + doc/tmpl/gnome-vfs-2.0-unused.sgml | 114 + doc/tmpl/gnome-vfs-application-registry.sgml | 233 + doc/tmpl/gnome-vfs-async-ops.sgml | 411 + doc/tmpl/gnome-vfs-cancellation.sgml | 67 + doc/tmpl/gnome-vfs-context.sgml | 66 + doc/tmpl/gnome-vfs-directory-basic-ops.sgml | 55 + doc/tmpl/gnome-vfs-directory-find-ops.sgml | 39 + doc/tmpl/gnome-vfs-directory-list-ops.sgml | 147 + doc/tmpl/gnome-vfs-directory.sgml | 185 + doc/tmpl/gnome-vfs-file-advanced-ops.sgml | 27 + doc/tmpl/gnome-vfs-file-basic-ops.sgml | 164 + doc/tmpl/gnome-vfs-file-info-ops.sgml | 86 + doc/tmpl/gnome-vfs-file-info.sgml | 316 + doc/tmpl/gnome-vfs-file-rw-ops.sgml | 71 + doc/tmpl/gnome-vfs-file-size.sgml | 49 + doc/tmpl/gnome-vfs-file-trunc-ops.sgml | 46 + doc/tmpl/gnome-vfs-find-directory.sgml | 39 + doc/tmpl/gnome-vfs-inet-connection.sgml | 73 + doc/tmpl/gnome-vfs-init.sgml | 68 + doc/tmpl/gnome-vfs-metadata.sgml | 70 + doc/tmpl/gnome-vfs-method.sgml | 93 + doc/tmpl/gnome-vfs-mime-database.sgml | 591 + doc/tmpl/gnome-vfs-mime-monitor.sgml | 38 + doc/tmpl/gnome-vfs-mime.sgml | 98 + doc/tmpl/gnome-vfs-module-callback-module-api.sgml | 29 + doc/tmpl/gnome-vfs-module-callback.sgml | 110 + doc/tmpl/gnome-vfs-module-shared.sgml | 65 + doc/tmpl/gnome-vfs-module.sgml | 44 + doc/tmpl/gnome-vfs-monitor.sgml | 71 + doc/tmpl/gnome-vfs-ops.sgml | 23 + doc/tmpl/gnome-vfs-parse-ls.sgml | 28 + doc/tmpl/gnome-vfs-result.sgml | 104 + doc/tmpl/gnome-vfs-socket-buffer.sgml | 80 + doc/tmpl/gnome-vfs-socket.sgml | 97 + doc/tmpl/gnome-vfs-ssl.sgml | 86 + doc/tmpl/gnome-vfs-standard-callbacks.sgml | 93 + doc/tmpl/gnome-vfs-transform.sgml | 38 + doc/tmpl/gnome-vfs-unused.sgml | 114 + doc/tmpl/gnome-vfs-uri.sgml | 405 + doc/tmpl/gnome-vfs-utils.sgml | 223 + doc/tmpl/gnome-vfs-xfer.sgml | 166 + doc/tmpl/gnome-vfs.sgml | 16 + doc/writing-modules.sgml | 554 + doc/xml/gnome-vfs-application-registry.xml | 527 + doc/xml/gnome-vfs-async-ops.xml | 1227 ++ doc/xml/gnome-vfs-cancellation.xml | 142 + doc/xml/gnome-vfs-context.xml | 131 + doc/xml/gnome-vfs-directory-basic-ops.xml | 120 + doc/xml/gnome-vfs-directory-find-ops.xml | 109 + doc/xml/gnome-vfs-directory-list-ops.xml | 394 + doc/xml/gnome-vfs-file-advanced-ops.xml | 73 + doc/xml/gnome-vfs-file-basic-ops.xml | 381 + doc/xml/gnome-vfs-file-info-ops.xml | 203 + doc/xml/gnome-vfs-file-info.xml | 849 + doc/xml/gnome-vfs-file-rw-ops.xml | 189 + doc/xml/gnome-vfs-file-size.xml | 85 + doc/xml/gnome-vfs-file-trunc-ops.xml | 106 + doc/xml/gnome-vfs-inet-connection.xml | 167 + doc/xml/gnome-vfs-init.xml | 138 + doc/xml/gnome-vfs-method.xml | 200 + doc/xml/gnome-vfs-mime-database.xml | 1268 ++ doc/xml/gnome-vfs-mime-monitor.xml | 75 + doc/xml/gnome-vfs-mime.xml | 214 + doc/xml/gnome-vfs-module-callback-module-api.xml | 95 + doc/xml/gnome-vfs-module-callback.xml | 413 + doc/xml/gnome-vfs-module-shared.xml | 149 + doc/xml/gnome-vfs-module.xml | 106 + doc/xml/gnome-vfs-monitor.xml | 192 + doc/xml/gnome-vfs-ops.xml | 53 + doc/xml/gnome-vfs-parse-ls.xml | 74 + doc/xml/gnome-vfs-result.xml | 161 + doc/xml/gnome-vfs-socket-buffer.xml | 192 + doc/xml/gnome-vfs-socket.xml | 229 + doc/xml/gnome-vfs-ssl.xml | 195 + doc/xml/gnome-vfs-standard-callbacks.xml | 195 + doc/xml/gnome-vfs-transform.xml | 96 + doc/xml/gnome-vfs-uri.xml | 844 + doc/xml/gnome-vfs-utils.xml | 464 + doc/xml/gnome-vfs-xfer.xml | 472 + gnome-vfs-2.0.pc.in | 12 + gnome-vfs-module-2.0.pc.in | 12 + gnome-vfs.spec | 122 + gnome-vfs.spec.in | 122 + install-sh | 251 + intltool-extract.in | 406 + intltool-merge.in | 933 + intltool-update.in | 792 + libgnomevfs/Makefile.am | 180 + libgnomevfs/Makefile.am.vfolder-hacks | 179 + libgnomevfs/Makefile.in | 978 + libgnomevfs/check-headers.pl | 123 + libgnomevfs/gnome-vfs-application-registry.c | 1999 ++ libgnomevfs/gnome-vfs-application-registry.h | 153 + libgnomevfs/gnome-vfs-async-job-map.c | 293 + libgnomevfs/gnome-vfs-async-job-map.h | 54 + libgnomevfs/gnome-vfs-async-ops.c | 1065 + libgnomevfs/gnome-vfs-async-ops.h | 425 + libgnomevfs/gnome-vfs-backend.h | 22 + libgnomevfs/gnome-vfs-cancellable-ops.c | 449 + libgnomevfs/gnome-vfs-cancellable-ops.h | 163 + libgnomevfs/gnome-vfs-cancellation.c | 178 + libgnomevfs/gnome-vfs-cancellation.h | 46 + libgnomevfs/gnome-vfs-configuration.c | 581 + libgnomevfs/gnome-vfs-configuration.h | 41 + libgnomevfs/gnome-vfs-context.c | 146 + libgnomevfs/gnome-vfs-context.h | 52 + libgnomevfs/gnome-vfs-directory.c | 684 + libgnomevfs/gnome-vfs-directory.h | 108 + libgnomevfs/gnome-vfs-file-info.c | 309 + libgnomevfs/gnome-vfs-file-info.h | 426 + libgnomevfs/gnome-vfs-file-size.h | 53 + libgnomevfs/gnome-vfs-file-size.h.in | 53 + libgnomevfs/gnome-vfs-find-directory.c | 65 + libgnomevfs/gnome-vfs-find-directory.h | 50 + libgnomevfs/gnome-vfs-handle-private.h | 71 + libgnomevfs/gnome-vfs-handle.c | 194 + libgnomevfs/gnome-vfs-handle.h | 78 + libgnomevfs/gnome-vfs-i18n.c | 354 + libgnomevfs/gnome-vfs-i18n.h | 25 + libgnomevfs/gnome-vfs-inet-connection.c | 337 + libgnomevfs/gnome-vfs-inet-connection.h | 61 + libgnomevfs/gnome-vfs-init.c | 224 + libgnomevfs/gnome-vfs-init.h | 47 + libgnomevfs/gnome-vfs-job-limit.h | 32 + libgnomevfs/gnome-vfs-job-queue.c | 369 + libgnomevfs/gnome-vfs-job-queue.h | 36 + libgnomevfs/gnome-vfs-job-slave.c | 149 + libgnomevfs/gnome-vfs-job-slave.h | 36 + libgnomevfs/gnome-vfs-job.c | 1795 ++ libgnomevfs/gnome-vfs-job.h | 416 + libgnomevfs/gnome-vfs-method.c | 353 + libgnomevfs/gnome-vfs-method.h | 265 + libgnomevfs/gnome-vfs-mime-handlers.c | 2340 ++ libgnomevfs/gnome-vfs-mime-handlers.h | 168 + libgnomevfs/gnome-vfs-mime-info.c | 1653 ++ libgnomevfs/gnome-vfs-mime-info.h | 87 + libgnomevfs/gnome-vfs-mime-magic.c | 958 + libgnomevfs/gnome-vfs-mime-magic.h | 45 + libgnomevfs/gnome-vfs-mime-monitor.c | 205 + libgnomevfs/gnome-vfs-mime-monitor.h | 62 + libgnomevfs/gnome-vfs-mime-private.h | 46 + libgnomevfs/gnome-vfs-mime-sniff-buffer-private.h | 47 + libgnomevfs/gnome-vfs-mime-sniff-buffer.c | 181 + libgnomevfs/gnome-vfs-mime-sniff-buffer.h | 73 + libgnomevfs/gnome-vfs-mime-utils.h | 47 + libgnomevfs/gnome-vfs-mime.c | 1017 + libgnomevfs/gnome-vfs-mime.h | 61 + libgnomevfs/gnome-vfs-module-callback-module-api.c | 2 + libgnomevfs/gnome-vfs-module-callback-module-api.h | 37 + libgnomevfs/gnome-vfs-module-callback-private.c | 2 + libgnomevfs/gnome-vfs-module-callback-private.h | 38 + libgnomevfs/gnome-vfs-module-callback.c | 965 + libgnomevfs/gnome-vfs-module-callback.h | 75 + libgnomevfs/gnome-vfs-module-shared.c | 149 + libgnomevfs/gnome-vfs-module-shared.h | 54 + libgnomevfs/gnome-vfs-module.c | 2 + libgnomevfs/gnome-vfs-module.h | 74 + libgnomevfs/gnome-vfs-monitor-private.h | 45 + libgnomevfs/gnome-vfs-monitor.c | 465 + libgnomevfs/gnome-vfs-monitor.h | 82 + libgnomevfs/gnome-vfs-open-fd.c | 428 + libgnomevfs/gnome-vfs-ops.c | 811 + libgnomevfs/gnome-vfs-ops.h | 146 + libgnomevfs/gnome-vfs-parse-ls.c | 660 + libgnomevfs/gnome-vfs-parse-ls.h | 44 + libgnomevfs/gnome-vfs-private-utils.c | 846 + libgnomevfs/gnome-vfs-private-utils.h | 93 + libgnomevfs/gnome-vfs-private.c | 2 + libgnomevfs/gnome-vfs-private.h | 31 + libgnomevfs/gnome-vfs-process.c | 281 + libgnomevfs/gnome-vfs-process.h | 73 + libgnomevfs/gnome-vfs-result.c | 177 + libgnomevfs/gnome-vfs-result.h | 93 + libgnomevfs/gnome-vfs-socket-buffer.c | 353 + libgnomevfs/gnome-vfs-socket-buffer.h | 56 + libgnomevfs/gnome-vfs-socket.c | 121 + libgnomevfs/gnome-vfs-socket.h | 73 + libgnomevfs/gnome-vfs-ssl-private.h | 37 + libgnomevfs/gnome-vfs-ssl.c | 479 + libgnomevfs/gnome-vfs-ssl.h | 55 + libgnomevfs/gnome-vfs-standard-callbacks.h | 182 + libgnomevfs/gnome-vfs-thread-pool.c | 266 + libgnomevfs/gnome-vfs-thread-pool.h | 36 + libgnomevfs/gnome-vfs-transform.c | 2 + libgnomevfs/gnome-vfs-transform.h | 49 + libgnomevfs/gnome-vfs-types.h | 90 + libgnomevfs/gnome-vfs-uri.c | 2042 ++ libgnomevfs/gnome-vfs-uri.h | 200 + libgnomevfs/gnome-vfs-utils.c | 2065 ++ libgnomevfs/gnome-vfs-utils.h | 174 + libgnomevfs/gnome-vfs-xfer.c | 2496 +++ libgnomevfs/gnome-vfs-xfer.h | 293 + libgnomevfs/gnome-vfs.h | 41 + ltmain.sh | 5118 +++++ missing | 198 + mkinstalldirs | 40 + modules/Makefile.am | 205 + modules/Makefile.am.old-modules | 191 + modules/Makefile.in | 1049 + modules/bzip2-method.c | 573 + modules/cdda-cddb.c | 1012 + modules/cdda-cddb.h | 179 + modules/cdda-cdrom-extensions.h | 277 + modules/cdda-method.c | 1035 + modules/cdda-module.conf | 1 + modules/cdemenu-desktop-method.c | 736 + modules/cdemenu-module.conf | 1 + modules/default-modules.conf | 51 + modules/default-modules.conf.modules-conf | 51 + modules/default-modules.conf.with-menu-editing | 51 + modules/desktop-method.c | 985 + modules/desktop-method.c.network-uri | 978 + modules/desktop-method.c.no-private-methods | 985 + modules/extfs-method.c | 971 + modules/extfs/Makefile.am | 41 + modules/extfs/Makefile.in | 383 + modules/extfs/README | 192 + modules/extfs/a | 89 + modules/extfs/ar.in | 48 + modules/extfs/arj | 34 + modules/extfs/cpio.in | 75 + modules/extfs/deb.in | 188 + modules/extfs/hp48 | 97 + modules/extfs/lha.in | 164 + modules/extfs/mailfs | 115 + modules/extfs/patchfs | 73 + modules/extfs/rar.in | 101 + modules/extfs/rpm | 171 + modules/extfs/rpms | 61 + modules/extfs/tar | 34 + modules/extfs/trpm | 161 + modules/extfs/uha.in | 43 + modules/extfs/zip.in | 134 + modules/extfs/zoo.in | 69 + modules/file-method.c | 2380 ++ modules/fstype.c | 424 + modules/ftp-method.c | 1673 ++ modules/gzip-method.c | 771 + modules/http-authn.c | 546 + modules/http-authn.h | 54 + modules/http-cache.c | 526 + modules/http-cache.h | 53 + modules/http-method.c | 3195 +++ modules/http-method.h | 51 + modules/nntp-method.c | 2275 ++ modules/nntp-method.h | 89 + modules/pipe-method.c | 280 + modules/ssh-method.c | 1104 + modules/ssl-modules.conf | 1 + modules/tar-method.c | 730 + modules/tarpet.h | 119 + modules/test-method.c | 615 + modules/translate-method.c | 1257 ++ modules/vfolder-desktop-method.c | 6148 ++++++ ...der-desktop-method.c.hide-with-empty-subfolders | 6137 ++++++ modules/vfolder-desktop-method.c.moved-menu-files | 6130 ++++++ .../vfolder-desktop-method.c.never-show-if-empty | 6136 ++++++ modules/vfolder-desktop-method.c.newstat | 6129 ++++++ modules/vfolder-desktop-method.c.only-show-in | 6129 ++++++ modules/vfolder-desktop-method.c.read-only | 6135 ++++++ modules/vfolder/Makefile.am | 95 + modules/vfolder/Makefile.in | 649 + modules/vfolder/TODO | 31 + .../vfolder/applications-all-users.vfolder-info.in | 209 + modules/vfolder/favorites.vfolder-info.in | 6 + modules/vfolder/network.vfolder-info.in | 17 + .../vfolder/preferences-all-users.vfolder-info.in | 100 + modules/vfolder/server-settings.vfolder-info.in | 6 + modules/vfolder/start-here.vfolder-info.in | 6 + modules/vfolder/system-settings.vfolder-info.in | 6 + modules/vfolder/test-vfolder-modules.conf | 3 + .../vfolder/test-vfolder-parent.vfolder-info.in | 14 + modules/vfolder/test-vfolder.c | 529 + modules/vfolder/test-vfolder.vfolder-info.in | 32 + modules/vfolder/vfolder-common.c | 1743 ++ modules/vfolder/vfolder-common.c.vfolder-hacks | 1668 ++ modules/vfolder/vfolder-common.h | 363 + modules/vfolder/vfolder-common.h.vfolder-hacks | 360 + modules/vfolder/vfolder-info.c | 2215 ++ modules/vfolder/vfolder-info.c.vfolder-hacks | 2189 ++ modules/vfolder/vfolder-method.c | 1734 ++ modules/vfolder/vfolder-util.c | 493 + modules/vfolder/vfolder-util.c.vfolder-hacks | 491 + modules/vfolder/vfolder-util.h | 111 + monikers/ChangeLog | 218 + monikers/GNOME_VFS_Moniker_std.server.in.in | 48 + monikers/Makefile.am | 49 + monikers/Makefile.in | 537 + monikers/bonobo-moniker-extender-file.c | 97 + monikers/bonobo-moniker-file.c | 80 + monikers/bonobo-moniker-vfs.c | 69 + monikers/bonobo-storage-fs.c | 505 + monikers/bonobo-storage-fs.h | 34 + monikers/bonobo-storage-vfs.c | 348 + monikers/bonobo-storage-vfs.h | 33 + monikers/bonobo-stream-fs.c | 417 + monikers/bonobo-stream-fs.h | 48 + monikers/bonobo-stream-vfs.c | 356 + monikers/bonobo-stream-vfs.h | 45 + monikers/gnome-moniker-std.c | 41 + monikers/gnome-moniker-std.h | 24 + po/ChangeLog | 1953 ++ po/Makefile.in.in | 254 + po/POTFILES.in | 15 + po/am.gmo | Bin 0 -> 1286 bytes po/am.po | 409 + po/ar.gmo | Bin 0 -> 5342 bytes po/ar.po | 412 + po/az.gmo | Bin 0 -> 5441 bytes po/az.po | 408 + po/be.gmo | Bin 0 -> 6860 bytes po/be.po | 477 + po/bg.gmo | Bin 0 -> 6077 bytes po/bg.po | 411 + po/bn.gmo | Bin 0 -> 6695 bytes po/bn.po | 411 + po/bs.gmo | Bin 0 -> 4584 bytes po/bs.po | 410 + po/ca.gmo | Bin 0 -> 5504 bytes po/ca.po | 1591 ++ po/cs.gmo | Bin 0 -> 5586 bytes po/cs.po | 411 + po/cy.gmo | Bin 0 -> 5409 bytes po/cy.po | 408 + po/da.gmo | Bin 0 -> 5373 bytes po/da.po | 416 + po/de.gmo | Bin 0 -> 5536 bytes po/de.po | 413 + po/el.gmo | Bin 0 -> 6125 bytes po/el.po | 1531 ++ po/eo.gmo | Bin 0 -> 5327 bytes po/eo.po | 407 + po/es.gmo | Bin 0 -> 5893 bytes po/es.po | 414 + po/et.gmo | Bin 0 -> 4488 bytes po/et.po | 408 + po/eu.gmo | Bin 0 -> 4085 bytes po/eu.po | 1155 + po/fa.gmo | Bin 0 -> 5159 bytes po/fa.po | 408 + po/fi.gmo | Bin 0 -> 5490 bytes po/fi.po | 409 + po/fr.gmo | Bin 0 -> 5220 bytes po/fr.po | 410 + po/ga.gmo | Bin 0 -> 1264 bytes po/ga.po | 447 + po/gl.gmo | Bin 0 -> 4749 bytes po/gl.po | 414 + po/gnome-vfs-2.0.pot | 408 + po/he.gmo | Bin 0 -> 5868 bytes po/he.po | 411 + po/hi.gmo | Bin 0 -> 8315 bytes po/hi.po | 478 + po/hu.gmo | Bin 0 -> 5532 bytes po/hu.po | 408 + po/id.gmo | Bin 0 -> 5387 bytes po/id.po | 407 + po/is.gmo | Bin 0 -> 5345 bytes po/is.po | 409 + po/it.gmo | Bin 0 -> 5392 bytes po/it.po | 409 + po/ja.gmo | Bin 0 -> 6425 bytes po/ja.po | 408 + po/ko.gmo | Bin 0 -> 5914 bytes po/ko.po | 407 + po/li.gmo | Bin 0 -> 5356 bytes po/li.po | 407 + po/lt.gmo | Bin 0 -> 3570 bytes po/lt.po | 900 + po/lv.gmo | Bin 0 -> 4686 bytes po/lv.po | 407 + po/mk.gmo | Bin 0 -> 6949 bytes po/mk.po | 415 + po/ml.gmo | Bin 0 -> 4203 bytes po/ml.po | 411 + po/mn.gmo | Bin 0 -> 6634 bytes po/mn.po | 412 + po/ms.gmo | Bin 0 -> 4757 bytes po/ms.po | 409 + po/nl.gmo | Bin 0 -> 5270 bytes po/nl.po | 406 + po/nn.gmo | Bin 0 -> 4489 bytes po/nn.po | 1158 + po/no.gmo | Bin 0 -> 5246 bytes po/no.po | 406 + po/pl.gmo | Bin 0 -> 5544 bytes po/pl.po | 413 + po/pt.gmo | Bin 0 -> 5604 bytes po/pt.po | 1157 + po/pt_BR.gmo | Bin 0 -> 5641 bytes po/pt_BR.po | 1157 + po/ro.gmo | Bin 0 -> 3937 bytes po/ro.po | 1461 ++ po/ru.gmo | Bin 0 -> 7068 bytes po/ru.po | 472 + po/sk.gmo | Bin 0 -> 5519 bytes po/sk.po | 411 + po/sl.gmo | Bin 0 -> 5404 bytes po/sl.po | 1567 ++ po/sq.gmo | Bin 0 -> 5581 bytes po/sq.po | 411 + po/sr.gmo | Bin 0 -> 6868 bytes po/sr.po | 412 + po/sr@Latn.gmo | Bin 0 -> 5575 bytes po/sr@Latn.po | 412 + po/sv.gmo | Bin 0 -> 5339 bytes po/sv.po | 455 + po/tr.gmo | Bin 0 -> 4596 bytes po/tr.po | 469 + po/uk.gmo | Bin 0 -> 5830 bytes po/uk.po | 407 + po/vi.gmo | Bin 0 -> 5707 bytes po/vi.po | 407 + po/wa.gmo | Bin 0 -> 5254 bytes po/wa.po | 408 + po/yi.gmo | Bin 0 -> 6110 bytes po/yi.po | 407 + po/zh_CN.gmo | Bin 0 -> 5143 bytes po/zh_CN.po | 409 + po/zh_TW.gmo | Bin 0 -> 5268 bytes po/zh_TW.po | 407 + programs/Makefile.am | 38 + programs/Makefile.in | 563 + programs/gnomevfs-cat.c | 95 + programs/gnomevfs-copy.c | 74 + programs/gnomevfs-info.c | 149 + programs/gnomevfs-ls.c | 125 + programs/gnomevfs-mkdir.c | 127 + schemas/Makefile.am | 18 + schemas/Makefile.in | 319 + schemas/desktop_default_applications.schemas | 38 + schemas/system_http_proxy.schemas | 92 + stamp-h.in | 1 + test/Makefile.am | 160 + test/Makefile.in | 1152 + test/auto-test | 13 + test/test-async-cancel.c | 768 + test/test-async-directory.c | 339 + test/test-async.c | 181 + test/test-callback.c | 315 + test/test-channel.c | 128 + test/test-directory-visit.c | 111 + test/test-directory.c | 202 + test/test-dirop.c | 89 + test/test-escape.c | 313 + test/test-find-directory.c | 85 + test/test-info.c | 188 + test/test-mime-handlers-set.c | 170 + test/test-mime-handlers.c | 233 + test/test-mime-info.c | 242 + test/test-mime.c | 181 + test/test-module-selftest.c | 134 + test/test-monitor.c | 138 + test/test-performance.c | 27 + test/test-queue.c | 324 + test/test-seek.c | 236 + test/test-shell.c | 1165 + test/test-ssl.c | 176 + test/test-symlinks.c | 303 + test/test-sync-create.c | 94 + test/test-sync-write.c | 92 + test/test-sync.c | 97 + test/test-unlink.c | 76 + test/test-uri.c | 727 + test/test-xfer.c | 256 + test/test.cmds | 55 + test/test.input | 340 + test/test.output | Bin 0 -> 1812 bytes test/vfs-run.in | 16 + 628 files changed, 319982 insertions(+) create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 COPYING.LIB create mode 100644 ChangeLog create mode 100644 HACKING create mode 100644 INSTALL create mode 100644 Makefile.am create mode 100644 Makefile.in create mode 100644 NEWS create mode 100644 README create mode 100644 TODO create mode 100644 acconfig.h create mode 100644 acinclude.m4 create mode 100644 aclocal.m4 create mode 100755 autogen.sh create mode 100755 config.guess create mode 100644 config.h.in create mode 100755 config.sub create mode 100755 configure create mode 100644 configure.in create mode 100644 devel-docs/Makefile.am create mode 100644 devel-docs/Makefile.in create mode 100644 devel-docs/gnome-vfs-tutorial/Makefile.am create mode 100644 devel-docs/gnome-vfs-tutorial/Makefile.in create mode 100644 devel-docs/gnome-vfs-tutorial/gnome-vfs-tutorial.sgml create mode 100644 doc/Makefile.am create mode 100644 doc/Makefile.in create mode 100644 doc/about.sgml create mode 100644 doc/gnome-vfs-2.0-docs.sgml create mode 100644 doc/gnome-vfs-2.0-overrides.txt create mode 100644 doc/gnome-vfs-2.0-sections.txt create mode 100644 doc/gnome-vfs-2.0.types create mode 100644 doc/html/about.html create mode 100644 doc/html/advanced-operations.html create mode 100644 doc/html/c9456.html create mode 100644 doc/html/c9466.html create mode 100644 doc/html/ch08.html create mode 100644 doc/html/data-types.html create mode 100644 doc/html/directory-operations.html create mode 100644 doc/html/everything-else.html create mode 100644 doc/html/file-operations.html create mode 100644 doc/html/gnome-vfs-20-gnome-vfs-application-registry.html create mode 100644 doc/html/gnome-vfs-20-gnome-vfs-async-ops.html create mode 100644 doc/html/gnome-vfs-20-gnome-vfs-cancellation.html create mode 100644 doc/html/gnome-vfs-20-gnome-vfs-context.html create mode 100644 doc/html/gnome-vfs-20-gnome-vfs-directory-basic-ops.html create mode 100644 doc/html/gnome-vfs-20-gnome-vfs-directory-find-ops.html create mode 100644 doc/html/gnome-vfs-20-gnome-vfs-directory-list-ops.html create mode 100644 doc/html/gnome-vfs-20-gnome-vfs-file-advanced-ops.html create mode 100644 doc/html/gnome-vfs-20-gnome-vfs-file-basic-ops.html create mode 100644 doc/html/gnome-vfs-20-gnome-vfs-file-info-ops.html create mode 100644 doc/html/gnome-vfs-20-gnome-vfs-file-info.html create mode 100644 doc/html/gnome-vfs-20-gnome-vfs-file-rw-ops.html create mode 100644 doc/html/gnome-vfs-20-gnome-vfs-file-size.html create mode 100644 doc/html/gnome-vfs-20-gnome-vfs-file-trunc-ops.html create mode 100644 doc/html/gnome-vfs-20-gnome-vfs-inet-connection.html create mode 100644 doc/html/gnome-vfs-20-gnome-vfs-init.html create mode 100644 doc/html/gnome-vfs-20-gnome-vfs-method.html create mode 100644 doc/html/gnome-vfs-20-gnome-vfs-mime-database.html create mode 100644 doc/html/gnome-vfs-20-gnome-vfs-mime-monitor.html create mode 100644 doc/html/gnome-vfs-20-gnome-vfs-mime.html create mode 100644 doc/html/gnome-vfs-20-gnome-vfs-module-callback-module-api.html create mode 100644 doc/html/gnome-vfs-20-gnome-vfs-module-callback.html create mode 100644 doc/html/gnome-vfs-20-gnome-vfs-module-shared.html create mode 100644 doc/html/gnome-vfs-20-gnome-vfs-module.html create mode 100644 doc/html/gnome-vfs-20-gnome-vfs-monitor.html create mode 100644 doc/html/gnome-vfs-20-gnome-vfs-parse-ls.html create mode 100644 doc/html/gnome-vfs-20-gnome-vfs-result.html create mode 100644 doc/html/gnome-vfs-20-gnome-vfs-socket-buffer.html create mode 100644 doc/html/gnome-vfs-20-gnome-vfs-socket.html create mode 100644 doc/html/gnome-vfs-20-gnome-vfs-ssl.html create mode 100644 doc/html/gnome-vfs-20-gnome-vfs-standard-callbacks.html create mode 100644 doc/html/gnome-vfs-20-gnome-vfs-transform.html create mode 100644 doc/html/gnome-vfs-20-gnome-vfs-uri.html create mode 100644 doc/html/gnome-vfs-20-gnome-vfs-utils.html create mode 100644 doc/html/gnome-vfs-20-gnome-vfs-xfer.html create mode 100644 doc/html/gnome-vfs-application-registry.html create mode 100644 doc/html/gnome-vfs-asynchronous-operations.html create mode 100644 doc/html/gnome-vfs-cancellation.html create mode 100644 doc/html/gnome-vfs-configuration.html create mode 100644 doc/html/gnome-vfs-context.html create mode 100644 doc/html/gnome-vfs-directory-operations.html create mode 100644 doc/html/gnome-vfs-directory.html create mode 100644 doc/html/gnome-vfs-file-info.html create mode 100644 doc/html/gnome-vfs-file-operations.html create mode 100644 doc/html/gnome-vfs-file-size.html create mode 100644 doc/html/gnome-vfs-finding-special-directories.html create mode 100644 doc/html/gnome-vfs-first-steps.html create mode 100644 doc/html/gnome-vfs-gnome-vfs-application-registry.html create mode 100644 doc/html/gnome-vfs-gnome-vfs-async-ops.html create mode 100644 doc/html/gnome-vfs-gnome-vfs-cancellation.html create mode 100644 doc/html/gnome-vfs-gnome-vfs-context.html create mode 100644 doc/html/gnome-vfs-gnome-vfs-directory-basic-ops.html create mode 100644 doc/html/gnome-vfs-gnome-vfs-directory-find-ops.html create mode 100644 doc/html/gnome-vfs-gnome-vfs-directory-list-ops.html create mode 100644 doc/html/gnome-vfs-gnome-vfs-directory.html create mode 100644 doc/html/gnome-vfs-gnome-vfs-file-advanced-ops.html create mode 100644 doc/html/gnome-vfs-gnome-vfs-file-basic-ops.html create mode 100644 doc/html/gnome-vfs-gnome-vfs-file-info-ops.html create mode 100644 doc/html/gnome-vfs-gnome-vfs-file-info.html create mode 100644 doc/html/gnome-vfs-gnome-vfs-file-rw-ops.html create mode 100644 doc/html/gnome-vfs-gnome-vfs-file-size.html create mode 100644 doc/html/gnome-vfs-gnome-vfs-file-trunc-ops.html create mode 100644 doc/html/gnome-vfs-gnome-vfs-find-directory.html create mode 100644 doc/html/gnome-vfs-gnome-vfs-inet-connection.html create mode 100644 doc/html/gnome-vfs-gnome-vfs-init.html create mode 100644 doc/html/gnome-vfs-gnome-vfs-method.html create mode 100644 doc/html/gnome-vfs-gnome-vfs-mime-database.html create mode 100644 doc/html/gnome-vfs-gnome-vfs-mime-monitor.html create mode 100644 doc/html/gnome-vfs-gnome-vfs-mime.html create mode 100644 doc/html/gnome-vfs-gnome-vfs-module-callback-module-api.html create mode 100644 doc/html/gnome-vfs-gnome-vfs-module-callback.html create mode 100644 doc/html/gnome-vfs-gnome-vfs-module-shared.html create mode 100644 doc/html/gnome-vfs-gnome-vfs-module.html create mode 100644 doc/html/gnome-vfs-gnome-vfs-monitor.html create mode 100644 doc/html/gnome-vfs-gnome-vfs-ops.html create mode 100644 doc/html/gnome-vfs-gnome-vfs-parse-ls.html create mode 100644 doc/html/gnome-vfs-gnome-vfs-result.html create mode 100644 doc/html/gnome-vfs-gnome-vfs-socket-buffer.html create mode 100644 doc/html/gnome-vfs-gnome-vfs-socket.html create mode 100644 doc/html/gnome-vfs-gnome-vfs-ssl.html create mode 100644 doc/html/gnome-vfs-gnome-vfs-standard-callbacks.html create mode 100644 doc/html/gnome-vfs-gnome-vfs-transform.html create mode 100644 doc/html/gnome-vfs-gnome-vfs-uri.html create mode 100644 doc/html/gnome-vfs-gnome-vfs-utils.html create mode 100644 doc/html/gnome-vfs-gnome-vfs-xfer.html create mode 100644 doc/html/gnome-vfs-gnomevfsmetadata.html create mode 100644 doc/html/gnome-vfs-gnomevfsmimemonitor.html create mode 100644 doc/html/gnome-vfs-inet-connection.html create mode 100644 doc/html/gnome-vfs-initialization.html create mode 100644 doc/html/gnome-vfs-iobuf.html create mode 100644 doc/html/gnome-vfs-method.html create mode 100644 doc/html/gnome-vfs-mime-handlers.html create mode 100644 doc/html/gnome-vfs-mime-info.html create mode 100644 doc/html/gnome-vfs-mime-magic.html create mode 100644 doc/html/gnome-vfs-mime-monitor.html create mode 100644 doc/html/gnome-vfs-mime-sniff-buffer.html create mode 100644 doc/html/gnome-vfs-mime.html create mode 100644 doc/html/gnome-vfs-module-callback-module-api.html create mode 100644 doc/html/gnome-vfs-module-callbacks.html create mode 100644 doc/html/gnome-vfs-module-shared.html create mode 100644 doc/html/gnome-vfs-module.html create mode 100644 doc/html/gnome-vfs-ops.html create mode 100644 doc/html/gnome-vfs-parse-ls.html create mode 100644 doc/html/gnome-vfs-process.html create mode 100644 doc/html/gnome-vfs-result.html create mode 100644 doc/html/gnome-vfs-ssl.html create mode 100644 doc/html/gnome-vfs-standard-callbacks.html create mode 100644 doc/html/gnome-vfs-types.html create mode 100644 doc/html/gnome-vfs-uri.html create mode 100644 doc/html/gnome-vfs-utils.html create mode 100644 doc/html/gnome-vfs-writing-modules.html create mode 100644 doc/html/gnome-vfs-xfer.html create mode 100644 doc/html/index.html create mode 100644 doc/html/index.sgml create mode 100644 doc/html/mime-registry.html create mode 100644 doc/html/modules.html create mode 100644 doc/html/writing-modules.html create mode 100644 doc/html/x27.html create mode 100644 doc/tmpl/gnome-vfs-2.0-unused.sgml create mode 100644 doc/tmpl/gnome-vfs-application-registry.sgml create mode 100644 doc/tmpl/gnome-vfs-async-ops.sgml create mode 100644 doc/tmpl/gnome-vfs-cancellation.sgml create mode 100644 doc/tmpl/gnome-vfs-context.sgml create mode 100644 doc/tmpl/gnome-vfs-directory-basic-ops.sgml create mode 100644 doc/tmpl/gnome-vfs-directory-find-ops.sgml create mode 100644 doc/tmpl/gnome-vfs-directory-list-ops.sgml create mode 100644 doc/tmpl/gnome-vfs-directory.sgml create mode 100644 doc/tmpl/gnome-vfs-file-advanced-ops.sgml create mode 100644 doc/tmpl/gnome-vfs-file-basic-ops.sgml create mode 100644 doc/tmpl/gnome-vfs-file-info-ops.sgml create mode 100644 doc/tmpl/gnome-vfs-file-info.sgml create mode 100644 doc/tmpl/gnome-vfs-file-rw-ops.sgml create mode 100644 doc/tmpl/gnome-vfs-file-size.sgml create mode 100644 doc/tmpl/gnome-vfs-file-trunc-ops.sgml create mode 100644 doc/tmpl/gnome-vfs-find-directory.sgml create mode 100644 doc/tmpl/gnome-vfs-inet-connection.sgml create mode 100644 doc/tmpl/gnome-vfs-init.sgml create mode 100644 doc/tmpl/gnome-vfs-metadata.sgml create mode 100644 doc/tmpl/gnome-vfs-method.sgml create mode 100644 doc/tmpl/gnome-vfs-mime-database.sgml create mode 100644 doc/tmpl/gnome-vfs-mime-monitor.sgml create mode 100644 doc/tmpl/gnome-vfs-mime.sgml create mode 100644 doc/tmpl/gnome-vfs-module-callback-module-api.sgml create mode 100644 doc/tmpl/gnome-vfs-module-callback.sgml create mode 100644 doc/tmpl/gnome-vfs-module-shared.sgml create mode 100644 doc/tmpl/gnome-vfs-module.sgml create mode 100644 doc/tmpl/gnome-vfs-monitor.sgml create mode 100644 doc/tmpl/gnome-vfs-ops.sgml create mode 100644 doc/tmpl/gnome-vfs-parse-ls.sgml create mode 100644 doc/tmpl/gnome-vfs-result.sgml create mode 100644 doc/tmpl/gnome-vfs-socket-buffer.sgml create mode 100644 doc/tmpl/gnome-vfs-socket.sgml create mode 100644 doc/tmpl/gnome-vfs-ssl.sgml create mode 100644 doc/tmpl/gnome-vfs-standard-callbacks.sgml create mode 100644 doc/tmpl/gnome-vfs-transform.sgml create mode 100644 doc/tmpl/gnome-vfs-unused.sgml create mode 100644 doc/tmpl/gnome-vfs-uri.sgml create mode 100644 doc/tmpl/gnome-vfs-utils.sgml create mode 100644 doc/tmpl/gnome-vfs-xfer.sgml create mode 100644 doc/tmpl/gnome-vfs.sgml create mode 100644 doc/writing-modules.sgml create mode 100644 doc/xml/gnome-vfs-application-registry.xml create mode 100644 doc/xml/gnome-vfs-async-ops.xml create mode 100644 doc/xml/gnome-vfs-cancellation.xml create mode 100644 doc/xml/gnome-vfs-context.xml create mode 100644 doc/xml/gnome-vfs-directory-basic-ops.xml create mode 100644 doc/xml/gnome-vfs-directory-find-ops.xml create mode 100644 doc/xml/gnome-vfs-directory-list-ops.xml create mode 100644 doc/xml/gnome-vfs-file-advanced-ops.xml create mode 100644 doc/xml/gnome-vfs-file-basic-ops.xml create mode 100644 doc/xml/gnome-vfs-file-info-ops.xml create mode 100644 doc/xml/gnome-vfs-file-info.xml create mode 100644 doc/xml/gnome-vfs-file-rw-ops.xml create mode 100644 doc/xml/gnome-vfs-file-size.xml create mode 100644 doc/xml/gnome-vfs-file-trunc-ops.xml create mode 100644 doc/xml/gnome-vfs-inet-connection.xml create mode 100644 doc/xml/gnome-vfs-init.xml create mode 100644 doc/xml/gnome-vfs-method.xml create mode 100644 doc/xml/gnome-vfs-mime-database.xml create mode 100644 doc/xml/gnome-vfs-mime-monitor.xml create mode 100644 doc/xml/gnome-vfs-mime.xml create mode 100644 doc/xml/gnome-vfs-module-callback-module-api.xml create mode 100644 doc/xml/gnome-vfs-module-callback.xml create mode 100644 doc/xml/gnome-vfs-module-shared.xml create mode 100644 doc/xml/gnome-vfs-module.xml create mode 100644 doc/xml/gnome-vfs-monitor.xml create mode 100644 doc/xml/gnome-vfs-ops.xml create mode 100644 doc/xml/gnome-vfs-parse-ls.xml create mode 100644 doc/xml/gnome-vfs-result.xml create mode 100644 doc/xml/gnome-vfs-socket-buffer.xml create mode 100644 doc/xml/gnome-vfs-socket.xml create mode 100644 doc/xml/gnome-vfs-ssl.xml create mode 100644 doc/xml/gnome-vfs-standard-callbacks.xml create mode 100644 doc/xml/gnome-vfs-transform.xml create mode 100644 doc/xml/gnome-vfs-uri.xml create mode 100644 doc/xml/gnome-vfs-utils.xml create mode 100644 doc/xml/gnome-vfs-xfer.xml create mode 100644 gnome-vfs-2.0.pc.in create mode 100644 gnome-vfs-module-2.0.pc.in create mode 100644 gnome-vfs.spec create mode 100644 gnome-vfs.spec.in create mode 100755 install-sh create mode 100644 intltool-extract.in create mode 100644 intltool-merge.in create mode 100644 intltool-update.in create mode 100644 libgnomevfs/Makefile.am create mode 100644 libgnomevfs/Makefile.am.vfolder-hacks create mode 100644 libgnomevfs/Makefile.in create mode 100755 libgnomevfs/check-headers.pl create mode 100644 libgnomevfs/gnome-vfs-application-registry.c create mode 100644 libgnomevfs/gnome-vfs-application-registry.h create mode 100644 libgnomevfs/gnome-vfs-async-job-map.c create mode 100644 libgnomevfs/gnome-vfs-async-job-map.h create mode 100644 libgnomevfs/gnome-vfs-async-ops.c create mode 100644 libgnomevfs/gnome-vfs-async-ops.h create mode 100644 libgnomevfs/gnome-vfs-backend.h create mode 100644 libgnomevfs/gnome-vfs-cancellable-ops.c create mode 100644 libgnomevfs/gnome-vfs-cancellable-ops.h create mode 100644 libgnomevfs/gnome-vfs-cancellation.c create mode 100644 libgnomevfs/gnome-vfs-cancellation.h create mode 100644 libgnomevfs/gnome-vfs-configuration.c create mode 100644 libgnomevfs/gnome-vfs-configuration.h create mode 100644 libgnomevfs/gnome-vfs-context.c create mode 100644 libgnomevfs/gnome-vfs-context.h create mode 100644 libgnomevfs/gnome-vfs-directory.c create mode 100644 libgnomevfs/gnome-vfs-directory.h create mode 100644 libgnomevfs/gnome-vfs-file-info.c create mode 100644 libgnomevfs/gnome-vfs-file-info.h create mode 100644 libgnomevfs/gnome-vfs-file-size.h create mode 100644 libgnomevfs/gnome-vfs-file-size.h.in create mode 100644 libgnomevfs/gnome-vfs-find-directory.c create mode 100644 libgnomevfs/gnome-vfs-find-directory.h create mode 100644 libgnomevfs/gnome-vfs-handle-private.h create mode 100644 libgnomevfs/gnome-vfs-handle.c create mode 100644 libgnomevfs/gnome-vfs-handle.h create mode 100644 libgnomevfs/gnome-vfs-i18n.c create mode 100644 libgnomevfs/gnome-vfs-i18n.h create mode 100644 libgnomevfs/gnome-vfs-inet-connection.c create mode 100644 libgnomevfs/gnome-vfs-inet-connection.h create mode 100644 libgnomevfs/gnome-vfs-init.c create mode 100644 libgnomevfs/gnome-vfs-init.h create mode 100644 libgnomevfs/gnome-vfs-job-limit.h create mode 100644 libgnomevfs/gnome-vfs-job-queue.c create mode 100644 libgnomevfs/gnome-vfs-job-queue.h create mode 100644 libgnomevfs/gnome-vfs-job-slave.c create mode 100644 libgnomevfs/gnome-vfs-job-slave.h create mode 100644 libgnomevfs/gnome-vfs-job.c create mode 100644 libgnomevfs/gnome-vfs-job.h create mode 100644 libgnomevfs/gnome-vfs-method.c create mode 100644 libgnomevfs/gnome-vfs-method.h create mode 100644 libgnomevfs/gnome-vfs-mime-handlers.c create mode 100644 libgnomevfs/gnome-vfs-mime-handlers.h create mode 100644 libgnomevfs/gnome-vfs-mime-info.c create mode 100644 libgnomevfs/gnome-vfs-mime-info.h create mode 100644 libgnomevfs/gnome-vfs-mime-magic.c create mode 100644 libgnomevfs/gnome-vfs-mime-magic.h create mode 100644 libgnomevfs/gnome-vfs-mime-monitor.c create mode 100644 libgnomevfs/gnome-vfs-mime-monitor.h create mode 100644 libgnomevfs/gnome-vfs-mime-private.h create mode 100644 libgnomevfs/gnome-vfs-mime-sniff-buffer-private.h create mode 100644 libgnomevfs/gnome-vfs-mime-sniff-buffer.c create mode 100644 libgnomevfs/gnome-vfs-mime-sniff-buffer.h create mode 100644 libgnomevfs/gnome-vfs-mime-utils.h create mode 100644 libgnomevfs/gnome-vfs-mime.c create mode 100644 libgnomevfs/gnome-vfs-mime.h create mode 100644 libgnomevfs/gnome-vfs-module-callback-module-api.c create mode 100644 libgnomevfs/gnome-vfs-module-callback-module-api.h create mode 100644 libgnomevfs/gnome-vfs-module-callback-private.c create mode 100644 libgnomevfs/gnome-vfs-module-callback-private.h create mode 100644 libgnomevfs/gnome-vfs-module-callback.c create mode 100644 libgnomevfs/gnome-vfs-module-callback.h create mode 100644 libgnomevfs/gnome-vfs-module-shared.c create mode 100644 libgnomevfs/gnome-vfs-module-shared.h create mode 100644 libgnomevfs/gnome-vfs-module.c create mode 100644 libgnomevfs/gnome-vfs-module.h create mode 100644 libgnomevfs/gnome-vfs-monitor-private.h create mode 100644 libgnomevfs/gnome-vfs-monitor.c create mode 100644 libgnomevfs/gnome-vfs-monitor.h create mode 100644 libgnomevfs/gnome-vfs-open-fd.c create mode 100644 libgnomevfs/gnome-vfs-ops.c create mode 100644 libgnomevfs/gnome-vfs-ops.h create mode 100644 libgnomevfs/gnome-vfs-parse-ls.c create mode 100644 libgnomevfs/gnome-vfs-parse-ls.h create mode 100644 libgnomevfs/gnome-vfs-private-utils.c create mode 100644 libgnomevfs/gnome-vfs-private-utils.h create mode 100644 libgnomevfs/gnome-vfs-private.c create mode 100644 libgnomevfs/gnome-vfs-private.h create mode 100644 libgnomevfs/gnome-vfs-process.c create mode 100644 libgnomevfs/gnome-vfs-process.h create mode 100644 libgnomevfs/gnome-vfs-result.c create mode 100644 libgnomevfs/gnome-vfs-result.h create mode 100644 libgnomevfs/gnome-vfs-socket-buffer.c create mode 100644 libgnomevfs/gnome-vfs-socket-buffer.h create mode 100644 libgnomevfs/gnome-vfs-socket.c create mode 100644 libgnomevfs/gnome-vfs-socket.h create mode 100644 libgnomevfs/gnome-vfs-ssl-private.h create mode 100644 libgnomevfs/gnome-vfs-ssl.c create mode 100644 libgnomevfs/gnome-vfs-ssl.h create mode 100644 libgnomevfs/gnome-vfs-standard-callbacks.h create mode 100644 libgnomevfs/gnome-vfs-thread-pool.c create mode 100644 libgnomevfs/gnome-vfs-thread-pool.h create mode 100644 libgnomevfs/gnome-vfs-transform.c create mode 100644 libgnomevfs/gnome-vfs-transform.h create mode 100644 libgnomevfs/gnome-vfs-types.h create mode 100644 libgnomevfs/gnome-vfs-uri.c create mode 100644 libgnomevfs/gnome-vfs-uri.h create mode 100644 libgnomevfs/gnome-vfs-utils.c create mode 100644 libgnomevfs/gnome-vfs-utils.h create mode 100644 libgnomevfs/gnome-vfs-xfer.c create mode 100644 libgnomevfs/gnome-vfs-xfer.h create mode 100644 libgnomevfs/gnome-vfs.h create mode 100644 ltmain.sh create mode 100755 missing create mode 100755 mkinstalldirs create mode 100644 modules/Makefile.am create mode 100644 modules/Makefile.am.old-modules create mode 100644 modules/Makefile.in create mode 100644 modules/bzip2-method.c create mode 100644 modules/cdda-cddb.c create mode 100644 modules/cdda-cddb.h create mode 100644 modules/cdda-cdrom-extensions.h create mode 100644 modules/cdda-method.c create mode 100644 modules/cdda-module.conf create mode 100644 modules/cdemenu-desktop-method.c create mode 100644 modules/cdemenu-module.conf create mode 100644 modules/default-modules.conf create mode 100644 modules/default-modules.conf.modules-conf create mode 100644 modules/default-modules.conf.with-menu-editing create mode 100644 modules/desktop-method.c create mode 100644 modules/desktop-method.c.network-uri create mode 100644 modules/desktop-method.c.no-private-methods create mode 100644 modules/extfs-method.c create mode 100644 modules/extfs/Makefile.am create mode 100644 modules/extfs/Makefile.in create mode 100644 modules/extfs/README create mode 100755 modules/extfs/a create mode 100644 modules/extfs/ar.in create mode 100644 modules/extfs/arj create mode 100644 modules/extfs/cpio.in create mode 100644 modules/extfs/deb.in create mode 100644 modules/extfs/hp48 create mode 100644 modules/extfs/lha.in create mode 100644 modules/extfs/mailfs create mode 100644 modules/extfs/patchfs create mode 100644 modules/extfs/rar.in create mode 100644 modules/extfs/rpm create mode 100755 modules/extfs/rpms create mode 100644 modules/extfs/tar create mode 100644 modules/extfs/trpm create mode 100644 modules/extfs/uha.in create mode 100644 modules/extfs/zip.in create mode 100644 modules/extfs/zoo.in create mode 100644 modules/file-method.c create mode 100644 modules/fstype.c create mode 100644 modules/ftp-method.c create mode 100644 modules/gzip-method.c create mode 100644 modules/http-authn.c create mode 100644 modules/http-authn.h create mode 100644 modules/http-cache.c create mode 100644 modules/http-cache.h create mode 100644 modules/http-method.c create mode 100644 modules/http-method.h create mode 100644 modules/nntp-method.c create mode 100644 modules/nntp-method.h create mode 100644 modules/pipe-method.c create mode 100644 modules/ssh-method.c create mode 100644 modules/ssl-modules.conf create mode 100644 modules/tar-method.c create mode 100644 modules/tarpet.h create mode 100644 modules/test-method.c create mode 100644 modules/translate-method.c create mode 100644 modules/vfolder-desktop-method.c create mode 100644 modules/vfolder-desktop-method.c.hide-with-empty-subfolders create mode 100644 modules/vfolder-desktop-method.c.moved-menu-files create mode 100644 modules/vfolder-desktop-method.c.never-show-if-empty create mode 100644 modules/vfolder-desktop-method.c.newstat create mode 100644 modules/vfolder-desktop-method.c.only-show-in create mode 100644 modules/vfolder-desktop-method.c.read-only create mode 100644 modules/vfolder/Makefile.am create mode 100644 modules/vfolder/Makefile.in create mode 100644 modules/vfolder/TODO create mode 100644 modules/vfolder/applications-all-users.vfolder-info.in create mode 100644 modules/vfolder/favorites.vfolder-info.in create mode 100644 modules/vfolder/network.vfolder-info.in create mode 100644 modules/vfolder/preferences-all-users.vfolder-info.in create mode 100644 modules/vfolder/server-settings.vfolder-info.in create mode 100644 modules/vfolder/start-here.vfolder-info.in create mode 100644 modules/vfolder/system-settings.vfolder-info.in create mode 100644 modules/vfolder/test-vfolder-modules.conf create mode 100644 modules/vfolder/test-vfolder-parent.vfolder-info.in create mode 100644 modules/vfolder/test-vfolder.c create mode 100644 modules/vfolder/test-vfolder.vfolder-info.in create mode 100644 modules/vfolder/vfolder-common.c create mode 100644 modules/vfolder/vfolder-common.c.vfolder-hacks create mode 100644 modules/vfolder/vfolder-common.h create mode 100644 modules/vfolder/vfolder-common.h.vfolder-hacks create mode 100644 modules/vfolder/vfolder-info.c create mode 100644 modules/vfolder/vfolder-info.c.vfolder-hacks create mode 100644 modules/vfolder/vfolder-method.c create mode 100644 modules/vfolder/vfolder-util.c create mode 100644 modules/vfolder/vfolder-util.c.vfolder-hacks create mode 100644 modules/vfolder/vfolder-util.h create mode 100644 monikers/ChangeLog create mode 100644 monikers/GNOME_VFS_Moniker_std.server.in.in create mode 100644 monikers/Makefile.am create mode 100644 monikers/Makefile.in create mode 100644 monikers/bonobo-moniker-extender-file.c create mode 100644 monikers/bonobo-moniker-file.c create mode 100644 monikers/bonobo-moniker-vfs.c create mode 100644 monikers/bonobo-storage-fs.c create mode 100644 monikers/bonobo-storage-fs.h create mode 100644 monikers/bonobo-storage-vfs.c create mode 100644 monikers/bonobo-storage-vfs.h create mode 100644 monikers/bonobo-stream-fs.c create mode 100644 monikers/bonobo-stream-fs.h create mode 100644 monikers/bonobo-stream-vfs.c create mode 100644 monikers/bonobo-stream-vfs.h create mode 100644 monikers/gnome-moniker-std.c create mode 100644 monikers/gnome-moniker-std.h create mode 100644 po/ChangeLog create mode 100644 po/Makefile.in.in create mode 100644 po/POTFILES.in create mode 100644 po/am.gmo create mode 100644 po/am.po create mode 100644 po/ar.gmo create mode 100644 po/ar.po create mode 100644 po/az.gmo create mode 100644 po/az.po create mode 100644 po/be.gmo create mode 100644 po/be.po create mode 100644 po/bg.gmo create mode 100644 po/bg.po create mode 100644 po/bn.gmo create mode 100644 po/bn.po create mode 100644 po/bs.gmo create mode 100644 po/bs.po create mode 100644 po/ca.gmo create mode 100644 po/ca.po create mode 100644 po/cs.gmo create mode 100644 po/cs.po create mode 100644 po/cy.gmo create mode 100644 po/cy.po create mode 100644 po/da.gmo create mode 100644 po/da.po create mode 100644 po/de.gmo create mode 100644 po/de.po create mode 100644 po/el.gmo create mode 100644 po/el.po create mode 100644 po/eo.gmo create mode 100644 po/eo.po create mode 100644 po/es.gmo create mode 100644 po/es.po create mode 100644 po/et.gmo create mode 100644 po/et.po create mode 100644 po/eu.gmo create mode 100644 po/eu.po create mode 100644 po/fa.gmo create mode 100644 po/fa.po create mode 100644 po/fi.gmo create mode 100644 po/fi.po create mode 100644 po/fr.gmo create mode 100644 po/fr.po create mode 100644 po/ga.gmo create mode 100644 po/ga.po create mode 100644 po/gl.gmo create mode 100644 po/gl.po create mode 100644 po/gnome-vfs-2.0.pot create mode 100644 po/he.gmo create mode 100644 po/he.po create mode 100644 po/hi.gmo create mode 100644 po/hi.po create mode 100644 po/hu.gmo create mode 100644 po/hu.po create mode 100644 po/id.gmo create mode 100644 po/id.po create mode 100644 po/is.gmo create mode 100644 po/is.po create mode 100644 po/it.gmo create mode 100644 po/it.po create mode 100644 po/ja.gmo create mode 100644 po/ja.po create mode 100644 po/ko.gmo create mode 100644 po/ko.po create mode 100644 po/li.gmo create mode 100644 po/li.po create mode 100644 po/lt.gmo create mode 100644 po/lt.po create mode 100644 po/lv.gmo create mode 100644 po/lv.po create mode 100644 po/mk.gmo create mode 100644 po/mk.po create mode 100644 po/ml.gmo create mode 100644 po/ml.po create mode 100644 po/mn.gmo create mode 100644 po/mn.po create mode 100644 po/ms.gmo create mode 100644 po/ms.po create mode 100644 po/nl.gmo create mode 100644 po/nl.po create mode 100644 po/nn.gmo create mode 100644 po/nn.po create mode 100644 po/no.gmo create mode 100644 po/no.po create mode 100644 po/pl.gmo create mode 100644 po/pl.po create mode 100644 po/pt.gmo create mode 100644 po/pt.po create mode 100644 po/pt_BR.gmo create mode 100644 po/pt_BR.po create mode 100644 po/ro.gmo create mode 100644 po/ro.po create mode 100644 po/ru.gmo create mode 100644 po/ru.po create mode 100644 po/sk.gmo create mode 100644 po/sk.po create mode 100644 po/sl.gmo create mode 100644 po/sl.po create mode 100644 po/sq.gmo create mode 100644 po/sq.po create mode 100644 po/sr.gmo create mode 100644 po/sr.po create mode 100644 po/sr@Latn.gmo create mode 100644 po/sr@Latn.po create mode 100644 po/sv.gmo create mode 100644 po/sv.po create mode 100644 po/tr.gmo create mode 100644 po/tr.po create mode 100644 po/uk.gmo create mode 100644 po/uk.po create mode 100644 po/vi.gmo create mode 100644 po/vi.po create mode 100644 po/wa.gmo create mode 100644 po/wa.po create mode 100644 po/yi.gmo create mode 100644 po/yi.po create mode 100644 po/zh_CN.gmo create mode 100644 po/zh_CN.po create mode 100644 po/zh_TW.gmo create mode 100644 po/zh_TW.po create mode 100644 programs/Makefile.am create mode 100644 programs/Makefile.in create mode 100644 programs/gnomevfs-cat.c create mode 100644 programs/gnomevfs-copy.c create mode 100644 programs/gnomevfs-info.c create mode 100644 programs/gnomevfs-ls.c create mode 100644 programs/gnomevfs-mkdir.c create mode 100644 schemas/Makefile.am create mode 100644 schemas/Makefile.in create mode 100644 schemas/desktop_default_applications.schemas create mode 100644 schemas/system_http_proxy.schemas create mode 100644 stamp-h.in create mode 100644 test/Makefile.am create mode 100644 test/Makefile.in create mode 100755 test/auto-test create mode 100644 test/test-async-cancel.c create mode 100644 test/test-async-directory.c create mode 100644 test/test-async.c create mode 100644 test/test-callback.c create mode 100644 test/test-channel.c create mode 100644 test/test-directory-visit.c create mode 100644 test/test-directory.c create mode 100644 test/test-dirop.c create mode 100644 test/test-escape.c create mode 100644 test/test-find-directory.c create mode 100644 test/test-info.c create mode 100644 test/test-mime-handlers-set.c create mode 100644 test/test-mime-handlers.c create mode 100644 test/test-mime-info.c create mode 100644 test/test-mime.c create mode 100644 test/test-module-selftest.c create mode 100644 test/test-monitor.c create mode 100644 test/test-performance.c create mode 100644 test/test-queue.c create mode 100644 test/test-seek.c create mode 100644 test/test-shell.c create mode 100644 test/test-ssl.c create mode 100644 test/test-symlinks.c create mode 100644 test/test-sync-create.c create mode 100644 test/test-sync-write.c create mode 100644 test/test-sync.c create mode 100644 test/test-unlink.c create mode 100644 test/test-uri.c create mode 100644 test/test-xfer.c create mode 100644 test/test.cmds create mode 100644 test/test.input create mode 100644 test/test.output create mode 100755 test/vfs-run.in diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..044d6ab --- /dev/null +++ b/AUTHORS @@ -0,0 +1,75 @@ +Main VFS engine: + Ettore Perazzoli + +VFS engine contributors: + Elliot Lee + Miguel de Icaza + Maciej Stachowiak + Darin Adler + John Sullivan + Pavel Cisler + Gene Ragan + Rebecca Schulman + Seth Nickel + Ian McKellar + Michael Meeks + Dan Winship + Mathieu Lacage + +"file" method: + Ettore Perazzoli + Pavel Cisler + +"gzip", "extfs" methods: + Ettore Perazzoli + +"http" methods: + Ettore Perazzoli + Mike Fleming + +"ftp" method: + Ian McKellar + +"bzip" method: + Cody Russell + +"gconf" method: + Dave Camp + +"pipe" and "translate" methods: + Elliot Lee + +"nfs" method: + Grahame Bowland + Ian McKellar + +MIME API and the MIME capplet: + John Sullivan + Pavel Cisler + Maciej Stachowiak + Gene Ragan + Rebecca Schulman + Aaron Brick + +Misc changes: + J Shane Culpepper + Ali Abdin + Seth Nickell + Chris Toshok + Glynn Foster + Martin Baulig + Jarkko Ranta + Eskil Heyn Olsen + Andy Hertzfeld + Kjartan Maraas + Christophe Merlet + Ramiro Estrugo + Don Melton + Robin * Slomkowski + Robey Pointer + Rolf Grossmann + Kenneth Christiansen + Lutz Müller + Matt Bissiri + Yukihiro Nakai + Ross Golder diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..d60c31a --- /dev/null +++ b/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/COPYING.LIB b/COPYING.LIB new file mode 100644 index 0000000..eb685a5 --- /dev/null +++ b/COPYING.LIB @@ -0,0 +1,481 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..a1c4bfe --- /dev/null +++ b/ChangeLog @@ -0,0 +1,21423 @@ +2003-08-25 Alexander Larsson + + * NEWS: + * configure.in: + Bump to 2.3.8 + +2003-08-25 Alexander Larsson + + * libgnomevfs/gnome-vfs-utils.c (gnome_vfs_make_uri_from_input_internal): + Only add http: if the string looks like a http uri. + +2003-08-25 Alexander Larsson + + * modules/default-modules.conf: + Add dav: scheme, handled by the http module. + +2003-08-19 Alexander Larsson + + * modules/file-method.c (fam_do_iter_unlocked): + Don't do anything if fam_connection is NULL. + Should fix bug #120211 + +2003-08-13 Alexander Larsson + + * libgnomevfs/gnome-vfs-utils.c: + revert the ngettext usage. + +2003-08-13 Alexander Larsson + + * modules/http-method.c: Fix the build for Solaris, FreeBSD (and + probably anything else that is "not Linux"). Fixes bug #119706. + based on patch by Malcolm Tredinnick + +2003-08-12 Thomas Vander Stichele + + * configure.in: make maintainer builds work with aclocal + +2003-08-12 Leena Gunda + + * modules/cdemenu-desktop-method.c (get_title): + Added this to get the menu names without quotes. + * modules/cdemenu-desktop-method.c (do_open): + * modules/cdemenu-desktop-method.c (do_read_directory): + Make sure that for unquoted menu item names, the pointers are + not NULL. Bugzilla bug# 119425 + +=== gnome-vfs 2.3.7 === + +2003-08-11 Alexander Larsson + + * NEWS: Update + + * configure.in: Bump to 2.3.7. + +2003-08-11 Malcolm Tredinnick + + * modules/http-method.c: + Process the contents of the /system/http_proxy/ignore_hosts + gconf key and do not use the proxy when connecting to these + hosts. + + * schemas/system_http_proxy.schemas: + Add an entry for /system/http_proxy/ignore_hosts. + +2003-08-04 Michael Meeks + + * test/test-shell.c (authentication_callback), + (get_input_string): don't pollute user/password with + trailing '\n's. + +2003-08-01 Michael Meeks + + * test/test-shell.c (do_ls): add ls [dir] + (main): quit properly at end of stream. + +2003-08-03 Danilo Segan + + * libgnomevfs/gnome-vfs-utils.c: uses ngettext + + (committed by teuf@gnome.org, please note this makes gnome-vfs + depend on a 'new enough' gettext implementation, and compilation + will break if such a gettext impl is not available. Hopefully some + gnome module (intltool?) makes sure this is the case(?)) + +=== gnome-vfs 2.3.6 === + +2003-08-01 Christophe Fergeau + + * NEWS: + * configure.in: + Bump version to 2.3.6. + +2003-07-25 Christophe Fergeau + + * libgnomevfs/gnome-vfs-xfer.h: another gcc 3.3 fix, remove + unnecessary ',' at the end of some enums. Fixes bug #118851 + +2003-07-25 Christophe Fergeau + + * libgnomevfs/gnome-vfs-file-size.h.in: add G_GNUC_EXTENSION before + GnomeVFSFileSize declaration to prevent g++ from spitting warnings + about long long being forbidden in C++ when used with -pedantic + (glib does exactly the same thing in its gint64 definition) + Fixes bug #118315 + +2003-07-24 Leena Gunda + + * libgnomevfs/gnome-vfs-process.c: + Create hash table before associating signal handler for SIGCHLD. + Fixes bug #118059 + +2003-07-18 Christophe Fergeau + + * test/test-symlinks.c: removed unnecessary ;, fixes build on older + gcc and bug #117818 + +2003-07-18 Fredrik Jönsson + + * modules/ssh-method.c: cast pid_t* to gint * (fixes compilation on + Solaris, bug #117788) + * modules/cde-method.c: removed unused variable (fixes compilation + on Solaris, bug #117789) + * modules/ftp-method.c: include strings.h (for index) (fixes #117787) + +2003-07-18 Christophe Fergeau + + * test/Makefile.am: don't build test-subdir.c since it uses a private + gnome-vfs symbol (prefixed with _) which breaks build on some non + linux platforms (fixes bug #117791) + +2003-07-18 Christophe Fergeau + + * libgnomevfs/gnome-vfs-mime.c: some stuff wasn't properly freed when + calling gnome_vfs_mime_shutdown + * libgnomevfs/gnome-vfs-uri.c (gnome_vfs_uri_to_string): fixed a small + leak + * libgnomevfs/gnome-vfs-uri.c + * libgnomevfs/gnome-vfs-utils.c: fixed a few function descriptions + to explicitly say when these functions return a newly allocated + string + * libgnomevfs/gnome-vfs-utils.c (_gnome_vfs_uri_is_in_subdir): fixed + a memory leak + * test/test-uri.c + * test/test-subdir.c + * test/test-symlinks.c: fixed some memory leaks (it may seem pointless, + but this will save some precious time the next time someone runs + valgrind on those tests) + +2003-07-17 Christophe Fergeau + + * test/test-mime-handlers.c: don't segfault on unknown mime types + +2003-07-17 Christophe Fergeau + + * libgnomevfs/gnome-vfs-mime-info.c: fixed a memory leak, fixed a bug + where the last line of .mime and .keys files wouldn't be read properly + if it didn't end with a \n. + +2003-07-17 Christophe Fergeau + + * modules/vfolder/vfolder-info.c: properly ignore // which can + appear in elements + * modules/vfolder/vfolder-util.h: fixes debug macro so that it compiles + with gcc 3.3 + +2003-07-17 Christophe Fergeau + + * test/test-mime-handlers.c: free all allocated memory before exiting + to make valgrind happy (and to identify the leaks which are truly + coming from gnome-vfs ;) + +2003-07-17 Christophe Fergeau + + * test/test-mime.c: fixed a crash when using an absolute path + +2003-07-11 Calum Benson + + reviewed by: Alex Larsson + + * modules/vfolder/applications-all-users.vfolder-info.in: + Add an Accessibility menu to the Applications menu. Closes + #116379, #115979 and #115981. + +2003-07-11 Arvind Samptur + + Reviewed by: Stephen Browne + + * modules/cdemenu-desktop-method.c: (do_open),(do_open_directory), + (do_read_directory): Replace chars such as '/' and '#' with + appropriate % escape codes the then unescape again when used to + search the dtwmrc files. + + * modules/cdemenu-desktop-method.c: (open_and_find_pointer_to_menu): + Do an exact match of the menu names (strcmp) from the dtwrmc file + and not just the first occurance of the string(strchr). + +2003-07-10 Alexander Larsson + + * libgnomevfs/gnome-vfs-thread-pool.c (new_thread_state): + Make vfs thread stack size 256k + +2003-07-08 Alexander Larsson + + * libgnomevfs/gnome-vfs-directory.c (gnome_vfs_directory_visit): + Handle NULL uris + + * libgnomevfs/gnome-vfs-cancellable-ops.c (gnome_vfs_get_file_info_uri_cancellable): + Handle NULL uris + +2003-07-04 Christophe Fergeau + + * libgnomevfs/gnome-vfs-mime-info.c: (set_value_real): + added missing g_string_free (fixes leak) + * test/Makefile.am: disabled test-resolv since it uses a private + gnome-vfs symbol, which breaks compilation on some non-linux + platforms + +2003-07-02 Leena Gunda + + * modules/cdemenu-desktop-method.c + (open_and_find_pointer_to_menu): Show the last custom menu + defined for the CDE menu items. Bugzilla bug #116101 + +2003-06-28 Christophe Fergeau + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_set_short_list_applications): when adding an app + to the short_list for a mime-type, also add it to the global list + of apps able to handle this mime-type + +2003-06-28 Christophe Fergeau + + * libgnomevfs/gnome-vfs-uri.c (BV_IS_SET): don't read out of + the buffer bounds if the uri contains 8-bit chars (this fixes + some problem when trying to parse uris containing UTF-8 chars) + +2003-06-25 Christophe Fergeau + + * programs/gnomevfs-mkdir.c: removed debugging code, fixes compilation + with Forte on Solaris (bug #115862) + +=== gnome-vfs 2.3.5 === + +2003-06-23 Dave Camp + + * NEWS: + * configure.in: + Bump version to 2.3.5. + +2003-06-13 Alexander Larsson + + * libgnomevfs/gnome-vfs-mime-handlers.c (expand_parameters): + Fix memory handling. We were freeing already freed stuff in the + GNOME_VFS_ERROR_NOT_SUPPORTED case. + +2003-06-11 Jon Svendsen + + * libgnomevfs/gnome-vfs-application-registry.h + (GNOME_VFS_APPLICATION_REGISTRY_STARTUP_NOTIFY): Add a macro + describing a new application registry key to determine if an + application supports startup notification. + +2003-06-11 Leena Gunda + + * modules/cdemenu-desktop-method.c (do_open): + Make sure that for unquoted menu item names, the pointers are + not NULL. Bugzilla bug#114555 + +2003-06-10 Alexander Larsson + + * libgnomevfs/gnome-vfs-job.c: + Make job_private static. + +==== gnome-vfs 2.3.4 ==== + +2003-06-10 Alexander Larsson + + * NEWS: + * configure.in: + Bump version + +2003-06-07 Mark Finlay + + * modules/vfolder/applications-all-users.vfolder-info.in + + Make other point to Other.directory (bug #81834) + +2003-06-05 Kenneth Rohde Christiansen + + * configure.in: Added li to ALL_LINGUAS. + +==== gnome-vfs 2.3.3 ==== + +2003-06-04 Alexander Larsson + + * NEWS: + * configure.in: + Bump version + + * libgnomevfs/gnome-vfs-mime-magic.c + (_gnome_vfs_sniff_buffer_looks_like_text): + Make sure to fallback to returning FALSE. + +2003-05-26 Alexander Larsson + + * configure.in: + Reomve -Wsign-promo and add -Wno-strict-aliasing to the list + of options to test for. Fixes the gcc 3.3 aliasing warnings. + +2003-05-24 Christophe Fergeau + + * doc/Makefile.am + * doc/gnome-vfs-2.0-docs.sgml (added) + * doc/gnome-vfs-2.0-overrides.txt (added) + * doc/gnome-vfs-2.0-sections.txt (added) + * doc/gnome-vfs-2.0.types (added) + * doc/gnome-vfs-docs.sgml (removed) + * doc/gnome-vfs-overrides.txt (removed) + * doc/gnome-vfs-sections.txt (removed) + * doc/gnome-vfs.types (removed): fixed API docs building so that they + appear in devhelp + * doc/tmpl/*.tmpl: removed unnecessary \n in section names, + added descriptions for some sections + +2003-05-23 Alexander Larsson + + * modules/file-method.c: + Handle the fam connection going away if the connection breaks. + +2003-05-23 Alexander Larsson + + * modules/file-method.c (do_monitor_add): + Make FAM usage threadsafe. + +2003-05-21 Hidetoshi Tajima + + * configure.in (GETTEXT_PACKAGE): do libnsl and libsocket checks + before inet_pton (#113325). + +2003-05-20 Christophe Fergeau + + * modules/ftp-method.c + * modules/http-method.c + * modules/ssh-method.c: fixed potential crash with uris containing + %2F, fixed a few small leaks + +==== gnome-vfs 2.3.2 ==== + +2003-05-19 Alexander Larsson + + * NEWS: + * configure.in: + Bump to 2.3.2. + +2003-05-17 Bastien Nocera + + * Makefile.am: add the programs subdir so the programs are built by + default + +2003-05-16 Radu Greab + Christophe Fergeau + + * libgnomevfs/gnome-vfs-utils.c(gnome_vfs_get_volume_free_space): + fixed a leak when the function was called with an non-file:// uri + * modules/file-method.c(do_is_local): ncpfs file systems aren't local + (fixes #97789) + +2003-05-16 Bastien Nocera + + * programs/gnomevfs-ls.c: (show_data), (main): remove use of SHOW_ICON + +2003-05-16 Bastien Nocera + + reviewed by: Alexander Larsson + + * configure.in: + * programs/.cvsignore: + * programs/Makefile.am: + * programs/gnomevfs-cat.c: + * programs/gnomevfs-copy.c: + * programs/gnomevfs-info.c: + * programs/gnomevfs-ls.c: + * programs/gnomevfs-mkdir.c: added some programs to test out + gnome-vfs methods, use the gnomevfs- prefix for them, add some + more information from get_info in -ls and -info + +2003-05-14 Pasupathi Duraisamy + + * configure.in: check "getdelim" in AC_CHECK_FUNCS + + * libgnomevfs/Makefile.am (EXTRA_DIST): remove getdelim.c + + * modules/extfs-method.c: Wrap getdelim definition inside + #ifndef HAVE_GETDELIM + + (patch reviewed by alexl@redhat.com) + +2003-05-14 Malcolm Tredinnick + + * modules/http-method.c: Bring comment about gconf keys into + line with reality. + +2003-05-13 Shailesh Mittal + + (applied by Ian McKellar ) + + Changes are made by keeping nautilus in focus. + + * libgnomevfs/gnome-vfs-uri.c: + Macro for URI_DELIMITER_IPV6_SET is added and a value + is added to array of structures uri_strspn_sets[]. + + (split_toplevel_uri): Changed to parse IPv6 address + (given in square brackets) like [fe80::203:baff:fe0b:a63d]. + + (gnome_vfs_uri_to_string): Modified to enclose an IPv6 + address within '[' and ']', while converting uri to string. + +2003-05-12 Michael Meeks + + * libgnomevfs/gnome-vfs-job.c: update misc. calls + to spew more pleasant debug. + + * libgnomevfs/gnome-vfs-job.h: add gettimeofday call + to JOB_DEBUG_PRINT, add job_debug_types array and + JOB_DEBUG_TYPE macro to pretty-print the job type. + +2003-05-09 Telsa Gwynne + + * configure.in: Added cy to ALL_LINGUAS + +2003-05-08 Samúel Jón Gunnarsson + + * configure.in: Added "is" into ALL_LINGUAS + +2003-05-06 Danilo Å egan + + * configure.in: Added "sr" and "sr@Latn" to ALL_LINGUAS. + +2003-05-05 Bastien Nocera + + * libgnomevfs/gnome-vfs-mime.c: + (_gnome_vfs_get_mime_type_internal): "audio/mpeg" is the right + mimetype for MP3 files, not "audio/x-mp3" (Closes: #100523) + +2003-05-05 Xan Lopez + + * modules/cdda-cddb.c: (CDDBConnect): + + Init sock variable to -1, fixes warning compilation. + +==== gnome-vfs 2.3.1 ==== + +2003-05-05 Alexander Larsson + + * libgnomevfs/Makefile.am: + * configure.in: + Go to libgnome/gtk+ style library versioning. + +2003-05-05 Alexander Larsson + + * NEWS: + Update + + * configure.in: + Bump version + +2003-05-03 Arvind Samptur + * modules/cdemenu-desktop-method.c: + (create_cde_icon_name_cache): While running the dttypes + command to create a icon cache for the cde menu, we need + to reap the child process. wait() currently on a solaris box + fails with an EINTR. So loop till you succeed. Fixes #111628 + +2003-04-25 Alexander Larsson + + Based on patch by Frank Worsley + + * libgnomevfs/gnome-vfs-utils.[ch]: + (gnome_vfs_icon_path_from_filename): + Use g_file_test instead of hack_file_exists. + + (gnome_vfs_make_uri_from_input_with_dirs): + Add new function. + +2003-04-24 Alexander Larsson + + * libgnomevfs/Makefile.am (libgnomevfs_2_la_LIBADD): + Remove LTLIBOBJS for the moment. It was breaking the build. + +2003-04-24 Alexander Larsson + + Patch from Frank Worsley + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_application_new_from_id), + (gnome_vfs_mime_action_launch), + (gnome_vfs_mime_action_launch_with_env), + (gnome_vfs_mime_application_launch), + (gnome_vfs_mime_application_launch_with_env), (expand_parameters): + new functions for launching mime actions and applications + + * libgnomevfs/gnome-vfs-mime-handlers.h: + updated for new functions + + * libgnomevfs/gnome-vfs-private-utils.c: + (_gnome_vfs_use_handler_for_scheme), + (_gnome_vfs_url_show_using_handler_with_env): + private functions for launching url handlers defined in gconf + + (gnome_vfs_prepend_terminal_to_vector): + the default terminal is needed by gnome-vfs so we make a copy of this + from libgnome + + * libgnomevfs/gnome-vfs-private-utils.h: + update for new functions + + * libgnomevfs/gnome-vfs-result.c: + * libgnomevfs/gnome-vfs-result.h: + new error codes for the new functions + + * libgnomevfs/gnome-vfs-utils.c: + (gnome_vfs_url_show), (gnome_vfs_url_show_with_env): + convenience functions for launching a url in string form using + the default application or component + + * libgnomevfs/gnome-vfs-utils.h: + updated for new functions + + * schemas/desktop_default_applications.schemas: + new schema that defines the default terminal application + + * schemas/Makefile.am: + updated for new schema + +2003-04-24 Masahiro Sakai + + * configure.in: fix IPV6 test. check inet_pton() and off64_t. + + * configure.in: call AC_LIBTOOL_WIN32_DLL. This is necessary for + building DLL on some win32 platform. + + * modules/cdemenu-module.conf + * modules/default-modules.conf: remove "lib" prefix from module names + since it is added automatically by g_module_build_path(), and it + breaks on Cygwin. (Cygwin uses "cyg" as library prefix.) + + * libgnomevfs/Makefile.am + * modules/Makefile.am + * modules/vfolder/Makefile.am: add -no-undefined to each library's + LDFLAGS, and write each library's depencency libraries explicitly + in its LIBADD. These are necessary for building DLL on some win32 + platform. + + * libgnomevfs/Makefile.am (libgnomevfs_2_la_LIBADD): add $(LTLIBOBJS) + to link getdelim.lo. + + * libgnomevfs/getdelim.c: add prototype and fix to work on Cygwin. + + * modules/file-method.c: + don't use lseek64() when off64_t is not available. + (do_read_directory): call G_UNLOCK(readdir) when readdir() is failed. + (find_trash_in_one_hierarchy_level): fix to work without readdir_r(). + + * modules/vfolder/Makefile.am (module_flags): add -module + + * modules/vfolder/vfolder-common.c (entry_reload_if_needed): comment + out vfolder_monitor_emit() call since this function is not defined. + + * modules/http-method.c: if inet_pton() is not available, define + the function using inet_aton(). + [FIXME: should be done using AC_REPLACE_FUNCS]. + +2003-04-24 Michael Meeks + + * TODO: waffle unproductively - this file is really stale. + +2003-04-23 Alexander Larsson + + * libgnomevfs/gnome-vfs-mime-info.c (gnome_vfs_mime_type_is_known): + Nothing is known if the mime type has been deleted. + Fixes bug #109479 + +2003-04-23 Alexander Larsson + + * libgnomevfs/gnome-vfs-mime-handlers.c (gnome_vfs_mime_remove_extension): + Handle the case when the last extension is removed. + + * modules/file-method.c (get_stat_info): + Correct handling of symlinks. + Fixes bug #111397. Based on patch in bug by jon. + +2003-04-18 Christophe Fergeau + + * libgnomevfs/gnome-vfs-private-utils.h: removed misleading comment + * modules/cdemenu-module.conf + * modules/default-modules.conf: removed .so extension to module names + since this is added automatically by gmodule, and it breaks on + some unices (eg HPUX). Fixes #110986 + +2003-4-17 HideToshi Tajima + + * modules/cdemenu-desktop-method.c (get_icon_for_menu): + Fixes bug #103306. Translators, please translate these messages + exactly the same in CDE's sys.dtwmrc file of the locale. + +2003-04-17 Balamurali Viswanathan + + * modules/http-method.c: Changed private symbol inet_aton + to inet_pton. + +2003-04-15 Christophe Fergeau + + * configure.in: + * libgnomevfs/gnome-vfs-mime-magic.c: don't try to use wctype.h + and mbrtowc on platforms which don't have it (bug #110226) + +2003-04-11 Christophe Fergeau + + * modules/http-method.[ch]: cleaned up some eazel related stuff + parses an HTTP error code in the body of an answer to a PROPFIND + request (fixes access to WebDAV servers using Resin). + Fixes bug #110532 + +2003-04-11 Christophe Fergeau + + * test/test-uri.c: added regression test for + gnome_vfs_uri_make_full_from_relative + +2003-04-11 Christophe Fergeau + + * libgnomevfs/gnome-vfs-i18n.c (read_aliases): make it work + * libgnomevfs/gnome-vfs-utils.c: removed bogus + #ifndef GNOME_VFS_DISABLE_DEPRECATED + +2003-04-11 Hidetoshi Tajima + + * libgnomevfs/gnome-vfs-init.c (gnome_vfs_init): call bindtextdomain + inside #ifdef ENABLE_NLS. Fixes bug #110213. + +2003-04-11 Michael Meeks + + * test/test-shell.c (authentication_callback, main): + hook up some really dumb authentication bits. + +2003-04-11 Alexander Larsson + + * test/test-async.c (file_control_callback): + Don't double free operation_data. + +2003-04-09 Michael Meeks + + * libgnomevfs/gnome-vfs-module-callback.h: add + G_BEGIN/END_DECLS for my C++ + +2003-04-05 Christophe Fergeau + + * libgnomevfs/gnome-vfs-uri.c + * libgnomevfs/gnome-vfs-utils.c + * libgnomevfs/gnome-vfs-utils.h: removed duplicated code, deprecated + gnome_vfs_make_uri_full_from_relative, use + gnome_vfs_uri_make_full_from_relative instead + +2003-04-04 Christophe Fergeau + + * modules/fstype.c: don't try to call getmntent with a NULL parameter + if mtab is non-existent. Fixes bug #106950 + +2003-04-03 Kaushal Kumar + + * libgnomevfs/gnome-vfs-mime-info.c (gnome_vfs_mime_set_extensions_list): + Set the deleted key to "" if it exists before resetting ext key. + Fixes bug #109795. + +2003-04-02 Shailesh Mittal + + * configure.in : + Added option for enabling IPv6 support, and only enabling + IPv6 support if AF_INET6 and function getaddrinfo are + defined there. + + * libgnomevfs/gnome-vfs-inet-connection.c : + Added a field addr6 of #sockaddr_in6 type in structure + GnomeVFSInetConnection, for holding IPv6 address. + One more field socklen is added to the definition of + structure GnomeVFSInetConnection to hold the length of + socket for identification of address family. + (gnome_vfs_inet_connection_create): + Modified to have support for IPv6 addresses too. + Included for prototype of the + function _gnome_vfs_have_ipv6 (). + + * libgnomevfs/gnome-vfs-private-utils.c : + (_gnome_vfs_have_ipv6): + Function added to check for run-time IPv6 support. + + * libgnomevfs/gnome-vfs-private-utils.h : + Added prototype for function _gnome_vfs_have_ipv6 (). + + * libgnomevfs/gnome-vfs-ssl.c (gnome_vfs_ssl_create) : + Modified to have support for IPv6 addresses as well. + Included for prototype of the + function _gnome_vfs_have_ipv6 (). + + * modules/cdda-cddb.c : + Included "config.h" for having definition of macro ENABLE_IPV6. + (CDDBConnect) : + Modified to support IPv6 addresses in addition to IPv4. + (have_ipv6) : + Function added to check for run-time IPv6 support. + + * modules/http-method.c : + Included header for prototype of getaddrinfo(). + (have_ipv6) : + Function added to check for run-time IPv6 support. + (proxy_should_for_hostname) : + It is modified to work with IPv6 and IPv4-Mapped IPv6 addresses + in addition to IPv4 addresses. + +==== gnome-vfs 2.2.4 ==== + +2003-03-31 Alexander Larsson + + * NEWS: + * configure.in: + Bump to 2.2.4. + +2003-03-31 Alexander Larsson + + * libgnomevfs/gnome-vfs-configuration.c (_gnome_vfs_configuration_init): + Look for user modules in ~/.gnome2/vfs/modules instead of ~/.gnome/vfs/modules. + +2003-03-27 Christophe Fergeau + + * modules/ftp-method.c: make sure the current directory is / when + using an uri without directory + +2003-03-26 Christian Rose + + * configure.in: Added "yi" to ALL_LINGUAS. + +2003-03-25 Alexander Larsson + + * libgnomevfs/gnome-vfs-utils.c (gnome_vfs_get_volume_free_space): + statvfs works for nfs! + +2003-03-25 Alexander Larsson + + * libgnomevfs/gnome-vfs-monitor.c: + Don't queue changes to canceled monitors. + Fix sign bug that caused events to be missed. + Fix theoretical race with setting up the idle handler. + +2003-03-23 Murray Cumming + + * doc/about.sgml: Simple Sample Progam: Allocated memory for the + read buffer. Initializing this to 0 would show the error. I don't + know how this ran without crashing before. + +2003-03-24 Alexander Larsson + + * libgnomevfs/gnome-vfs-job.c (_gnome_vfs_job_destroy_notify_result): + Don't free OP_XFER notify result. Its stack-allocated. (#100654) + +2003-03-20 Guntupalli Karunakar + + * configure.in: Added "ml" in ALL_LINGUAS + +2003-03-18 Alexander Larsson + + * libgnomevfs/gnome-vfs-xfer.c (copy_symlink): + Check for errors when copying symlinks. + +2003-03-14 Alexander Larsson + + * libgnomevfs/gnome-vfs-monitor.c (gnome_vfs_monitor_callback): + Throttle the change event rate so that applications don't + use 100% cpu when monitoring a directory someone is downloading + to. + +2003-03-14 Dave Camp + + * libgnomevfs/gnome-vfs-job.c (_gnome_vfs_job_destroy_notify_result): + Remove the unnecessary g_warning here. + +2003-03-14 Joël Brich + + * configure.in: Added "eo" to ALL_LINGUAS. + +2003-03-14 Michael Meeks + + * test/test-shell.c (do_ssl): impl. + (main, list_commands): upd. + +2003-03-14 Alexander Larsson + + * Makefile.am: + Remove hardcoded ACLOCAL_AMFLAGS. + Please do not make changes to modules without + permission from the maintainer. + +==== gnome-vfs 2.2.3 ==== + +2003-03-10 Alexander Larsson + + * NEWS: + * configure.in: + Bump to 2.2.3 + +2003-03-05 Alexander Larsson + + * configure.in: + Try pkg-config for detecting openssl. + Add --disable-openssl to not use openssl + Add --enable-gnutls to enable gnutls. + +2003-02-25 Taneem Ahmed + + * configure.in: Added "bn" to ALL_LINGUAS. + +2003-02-24 Alexander Larsson + + * libgnomevfs/gnome-vfs-job.c (_gnome_vfs_job_destroy_notify_result): + Turn crash into g_warning for smb: module callback bug. This needs + looking into. I'm not sure what is happening here. + +2003-02-24 Alexander Larsson + + * modules/file-method.c (do_read_directory): + Actually make the non-readdir_r case work. + +2003-02-24 Alexander Larsson + + * libgnomevfs/gnome-vfs-monitor.c (destroy_monitor_handle): + Warn if the handle was not in the hash table. + (gnome_vfs_monitor_callback): + Loop to get the hashtable. This fixes a possible race where + there is a callback before the add_monitor code has added the + monitor to the hashtable. (#106758) + +2003-02-21 Alexander Larsson + + * monikers/Makefile.am: + Assign CLEANFILES with normal assignment + + * libgnomevfs/Makefile.am: + Remove commented out lines that were confusing automake. + +2003-02-20 Alexander Larsson + + * libgnomevfs/gnome-vfs-job.h: + Remove include of semaphore.h. Not needed. + +2003-02-19 Alexander Larsson + + * libgnomevfs/gnome-vfs-mime-magic.c: + Fix vorbis sniff change. + (_gnome_vfs_sniff_buffer_looks_like_text): + Non utf8 text sniffing. + + * schemas/Makefile.am (install-data-local): + Don't install schemas if --disable-schemas-install was passed + + * test/test-shell.c: + Add support for get_info_from_handle. + + * modules/http-method.c (do_get_file_info_from_handle): + For get_info_from_handle we use the cached file info to + avoid re-connecting. + +2003-02-18 Alexander Larsson + + * configure.in: + * modules/file-method.c (do_read_directory): + Check for readdir_r and use locks + readdir if it doesn't exist. + +2003-02-18 Alexander Larsson + * libgnomevfs/gnome-vfs-mime-magic.c (_gnome_vfs_sniff_buffer_looks_like_mp3): + Don't interpret vorbis files with ID3 tags as mp3. + +2003-02-18 Alexander Larsson + + * configure.in: + Define HAVE_SYS_PARAM_H. Patch from jmmv@hispabsd.org. + +2003-02-18 Roozbeh Pournader + + * configure.in: Added "fa" to ALL_LINGUAS. + +2003-02-17 Bastien Nocera + + * modules/ssh-method.c: (do_read_directory): implement setting the + type of the file when we have a symlink (Closes: #92630) + +2003-02-17 Bastien Nocera + + * modules/ssh-method.c: (do_read_directory): implement mime-type + checking for symlinks, still doesn't work for directories + +2003-02-17 Frederic Crozat + + * modules/file-method.c: (read_link): fix memleak when readlink + fails. + * test/.cvsignore : quiet CVS, quiet. + +2003-02-13 Bastien Nocera + + * modules/ssh-method.c: (do_move), (do_unlink), (do_check_same_fs): + implement do_move and revive do_check_same_fs + +2003-02-13 Bastien Nocera + + * modules/ssh-method.c: (ssh_connect), (do_open_directory): don't crash + when accessing ssh://, nicer error message when we get a connection + refused + +2003-02-13 Bastien Nocera + + reviewed by: Alexander Larsson + + * modules/ssh-method.c: (ssh_connect), (ssh_destroy), + (ssh_check_for_done), (do_read), (do_read_directory): + add more robust error checking, check for EOF and EOD when we're done + reading rather than on close + +==== gnome-vfs 2.2.2 ==== + +2003-02-12 Alexander Larsson + + * NEWS: + * configure.in: + Bump to 2.2.2 + +2003-02-12 Alexander Larsson + + * libgnomevfs/gnome-vfs-ops.c (gnome_vfs_monitor_add): + Free uri if no monitor_add implementation. Plugs leak. + + * libgnomevfs/gnome-vfs-monitor.c (_gnome_vfs_monitor_do_cancel): + Correctly destroy the handle of result == OK. Plugs leak. + +2003-02-12 Bastien Nocera + + reviewed by: Alexander Larsson + + * modules/Makefile.am: + * modules/ssh-method.c: (ssh_connect), (ssh_read_error), + (ssh_wait_and_destroy), (do_open), (do_close), (do_read), + (do_make_directory), (do_remove_directory), (do_unlink), + (do_check_same_fs), (do_set_file_info): give a login failed error when + no key is setup to access the machine, a server not available when the + machine doesn't have its keys in the known_hosts, use port information + from the URI, redirect ssh:/// to ssh://localhost/, wait 30 secs for ssh to finish before killing it (fixes the data loss problem when copying + files to a remote location), check for cancellation when ssh takes + to much time to finish, implement do_check_same_fs (disabled until + move is implemented) + +2003-02-10 Christophe Fergeau + + * modules/file-method.c: disabled the annoying "FAMOpen failed..." + warning + +==== gnome-vfs 2.2.1 ==== + +2003-02-10 Alexander Larsson + + * NEWS: + * configure.in: + Bump to 2.2.1 + + * modules/file-method.c: + Queue up fam events before adding/removing monitors to avoid + deadlocking. Fixes gnome-theme-manager hang. + +2003-02-09 Christophe Fergeau + + * libgnomevfs/gnome-vfs-configuration.c: fixed a memory leak + +2003-02-08 Kang Jeong-Hee + + * Makefile.am: Added ACLOCAL_AMFLAGS. bug #102296 + +2003-02-06 Christian Rose + + * configure.in: Added "id" to ALL_LINGUAS. + +2003-01-22 Pablo Saratxaga + + * configure.in: Added Amharic (am), Bosnian (bs), + Macedonian (mk) to ALL_LINGUAS + +2003-01-22 Christian Rose + + * configure.in: Added "mn" to ALL_LINGUAS. + +==== gnome-vfs 2.2.0 ==== + +2003-01-20 Alexander Larsson + + * NEWS: + * configure.in: + Bump to 2.2.0 + +2003-01-17 Alexander Larsson + + * libgnomevfs/gnome-vfs-ssl.c (gnome_vfs_ssl_create_from_fd): + Fix warning. + +2003-01-16 Alexander Larsson + + * configure.in: + Comment out the gnutls check since its not tested. + +2003-01-16 Alexander Larsson + + * acinclude.m4: + * acconfig.h: + * configure.in: + * libgnomevfs/gnome-vfs-ssl.c: + gnutls support if openssl is not availible. + Patch from Andrew McDonald (debian). + I haven't tested this. + +2003-01-14 Alexander Larsson + + * libgnomevfs/gnome-vfs-job.c: + Fix race and bugs. Patches from Josh Parsons (jp30@st-and.ac.uk). + Fixes #103420 and #103236. + +==== gnome-vfs 2.1.91 ==== + +2003-01-13 Alexander Larsson + + * NEWS: + * configure.in: + Bump to 2.1.91 + +2003-01-07 Alexander Larsson + + * modules/gzip-method.c (write_gzip_header): + Set creation time. Based on patch by davh@davh.dk. (#41172) + + * libgnomevfs/gnome-vfs-uri.c (gnome_vfs_uri_extract_dirname): + Don't crash on NULL uri->text. Patch by Dennis Haney. (#79730) + + * libgnomevfs/gnome-vfs-socket-buffer.c (gnome_vfs_socket_buffer_peekc): + Return correct char instead of first in buffer. + + Patch from ksato@users.sourceforge.net (#102202) + +==== gnome-vfs 2.1.6 ==== + +2003-01-06 Alexander Larsson + + * NEWS: + * configure.in: + Bump version to 2.1.6. + +2002-12-19 Alexander Larsson + + * libgnomevfs/gnome-vfs-utils.c (gnome_vfs_format_file_size_for_display): + Fix erronous change in string. + +2002-12-19 Michael Meeks + + * big sed job to '_' prefix 'internal' methods, it + turns out that the modules use loads of these + methods, based on Tim Janik's patch (thanks Tim) + +2002-12-18 Diego Gonzalez + + * libgnomevfs/gnome-vfs-job.h: + spelling fix + * libgnomevfs/gnome-vfs-handle.h: + add the description of GnomeVFSHandle + +2002-12-18 Alexander Larsson + + * configure.in: + Fix up mistakes from previous change. + +2002-12-18 Diego Gonzalez + + * configure.in: accidentaly changed the version in the last merge + +2002-12-18 Diego Gonzalez + + * configure.in: check for gtk-doc version 0.10 + + * libgnomevfs/gnome-vfs-async-ops.[c-h] + * libgnomevfs/gnome-vfs-directory.h + * libgnomevfs/gnome-vfs-file-info.[c-h] + * libgnomevfs/gnome-vfs-handle.h + * libgnomevfs/gnome-vfs-init.c + * libgnomevfs/gnome-vfs-mime.[c-h] + * libgnomevfs/gnome-vfs-mime-info.h + * libgnomevfs/gnome-vfs-job.h + * libgnomevfs/gnome-vfs-mime-handlers.h + * libgnomevfs/gnome-vfs-open-fd.c + * libgnomevfs/gnome-vfs-ops.c + * libgnomevfs/gnome-vfs-monitor.h + * libgnomevfs/gnome-vfs-result.h + * libgnomevfs/gnome-vfs-utils.c + * libgnomevfs/gnome-vfs-xfer.[c-h] + add API docs + + * doc/writing-modules.sgml: + * doc/gnome-vfs-sections.txt + * doc/gnome-vfs-docs.sgml + * doc/about.sgml + * doc/tmpl/gnome-vfs-async-ops.sgml + * doc/tmpl/gnome-vfs-directory.sgml + * doc/tmpl/gnome-vfs-file-info.sgml + * doc/tmpl/gnome-vfs-init.sgml + * doc/tmpl/gnome-vfs-metadata.sgml + * doc/tmpl/gnome-vfs-ops.sgml + * doc/tmpl/gnome-vfs-result.sgml + * doc/tmpl/gnome-vfs-uri.sgml + * doc/tmpl/gnome-vfs-utils.sgml + * doc/tmpl/gnome-vfs-xfer.sgml + * doc/Makefile.am + fix documentation, reorganize it and migrate the generation to use + xml and lixslt + + * doc/tmpl/gnome-vfs-directory-basic-ops.sgml + * doc/tmpl/gnome-vfs-directory-find-ops.sgml + * doc/tmpl/gnome-vfs-directory-list-ops.sgml + * doc/tmpl/gnome-vfs-file-rw-ops.sgml + * doc/tmpl/gnome-vfs-file-trunc-ops.sgml + * doc/tmpl/gnome-vfs-file-basic-ops.sgml + * doc/tmpl/gnome-vfs-file-advanced-ops.sgml + * doc/tmpl/gnome-vfs-file-info-ops.sgml + new files + +2002-12-18 Alexander Larsson + + * libgnomevfs/gnome-vfs-mime.h: + * libgnomevfs/gnome-vfs-init.h: + Deprecate gnome_vfs_mime_shutdown, gnome_vfs_loadinit, + gnome_vfs_preinit and gnome_vfs_postinit. + +2002-12-18 Frederic Crozat + + * modules/Makefile.am: + * modules/extfs-method.c: + * modules/extfs/Makefile.am: + use $(libdir) instead of $(prefix)/lib (needed for AMD x86-64) + +2002-12-18 Alexander Larsson + + * libgnomevfs/gnome-vfs-private-utils.h: + * libgnomevfs/gnome-vfs-utils.c: + (_gnome_vfs_uri_resolve_all_symlinks_uri), + (_gnome_vfs_uri_resolve_all_symlinks), + (_gnome_vfs_uri_is_in_subdir): + New functions. Not exported since we're in a freeze, but might + be nice to export later. + + * libgnomevfs/gnome-vfs-xfer.c: + (move_source_is_in_target), + (handle_name_conflicts): + Handle the case when moving a file over a directory it is contained in. + (Bug #99346) + + * test/Makefile.am: + * test/test-resolv.c: (main): + * test/test-subdir.c: (main): + Some test code. + +2002-12-17 Alexander Larsson + + * configure.in: + * modules/vfolder/Makefile.am (libvfolder_desktop_la_LIBADD): + Add gthread-2.0 to TEST_LIBS and add it to LIBADD. + Patch from owen taylor. + +==== gnome-vfs 2.1.5 ==== + +2002-12-16 Alexander Larsson + + * NEWS: + * configure.in: + Bump to 2.1.5 + +2002-12-12 Alexander Larsson + + * libgnomevfs/gnome-vfs-result.[ch]: + Add GNOME_VFS_ERROR_NO_MASTER_BROWSER error. + +==== gnome-vfs 2.1.4 ==== + +2002-12-09 Alexander Larsson + + * configure.in: + Bump version to 2.1.4. + + * NEWS: + Update + +2002-12-06 Frederic Crozat + + * libgnomevfs/gnome-vfs-mime-info.c: (ensure_user_directory_exist): + Check dir is not NULL before trying to close it. + +2002-12-05 Frederic Crozat + + * libgnomevfs/gnome-vfs-mime-info.c: (ensure_user_directory_exist), + (write_back_mime_user_file), (write_back_keys_user_file): + Ensure directory stream is never leaked. + +2002-12-05 Frederic Crozat + + * libgnomevfs/gnome-vfs-mime-monitor.c: + (gnome_vfs_mime_monitor_init): + Ensure user mime dir exists before monitoring it + +2002-12-05 Alexander Larsson + + * modules/default-modules.conf: + * modules/console-method.c: + * modules/Makefile.am: + Remove console method. + + * libgnomevfs/Makefile.am: + * libgnomevfs/gnome-vfs-open-fd.c: + * libgnomevfs/gnome-vfs-utils.h: + Implement gnome_vfs_open_fd(). + Patch from Giovanni Corriga + +2002-11-27 Jody Goldberg + + * configure.in : post release version bump + +2002-11-27 Jody Goldberg + + * Release 2.1.3.1 + +2002-11-27 Jody Goldberg + + * configure.in : bump to 2.1.3.1 for release + +2002-11-12 Michael Meeks + + * modules/extfs-method.c (do_get_file_info): check + result before using the handle. + +2002-11-12 Alexander Larsson + + * libgnomevfs/gnome-vfs-method.h: + Added file_control to ops + + * libgnomevfs/gnome-vfs-async-ops.[ch]: + Added gnome_vfs_async_file_control + + * libgnomevfs/gnome-vfs-cancellable-ops.[ch]: + Added gnome_vfs_file_control_cancellable + + * libgnomevfs/gnome-vfs-ops.[ch]: + Added gnome_vfs_file_control + + * libgnomevfs/gnome-vfs-handle-private.h: + * libgnomevfs/gnome-vfs-handle.c: + * libgnomevfs/gnome-vfs-job.[ch]: + Implement file_control + +2002-11-08 Giovanni Corriga + + * modules/Makefile.am + * modules/default-modules.conf + * modules/console-method.c: added console method (which adds + console:///stdin, console:///stdout, console:///stderr uris) + +2002-11-08 Christophe Fergeau + + * libgnomevfs/gnome-vfs-file-info.h: documented + GNOME_VFS_FILE_INFO_FIELDS_ACCESS and + GNOME_VFS_FILE_INFO_GET_ACCESS_RIGHTS + * modules/ssh-method.c: only get mime type and access info if they + were asked + +2002-11-06 Christophe Fergeau + + * libgnomevfs/gnome-vfs-mime-magic.c + * libgnomevfs/gnome-vfs-mime-sniff-buffer.h: rework looks_like_text to + use glib functions, remove looks_like_gzip (moved in gnome-mime-data) + * libgnomevfs/gnome-vfs-mime.c: removed looks_like_gzip call, replaced + by a strcmp on the mime type returned by the sniff function + +2002-11-05 Michael Meeks + + * test/Makefile.am: disable test-metadata + + * libgnomevfs/gnome-vfs.h: remove + gnome-vfs-metadata.h. + + * libgnomevfs/gnome-vfs-metadata-private.h, + * libgnomevfs/gnome-vfs-metadata.h, + * libgnomevfs/gnome-vfs-metadata.c: add + generated files to CVS, so they can be + canonicalized later if neccessary. + + * libgnomevfs/Makefile.am: disable gob + builds, and remove generated files from + install - immature / unfinished API. + + * configure.in: disable building gob. + +2002-11-04 Frederic Vannere + + * modules/ftp-method.c: add support for Microsoft and Netware FTP + servers + +2002-11-04 bugzilla-gnome@thewrittenword.com + + * configure.in: + * libgnomevfs/gnome-vfs-method.c: check whether to use seteuid/setegid + or setresuid/setregid (fixes #96078) + +2002-11-04 Jens Elkner + + * configure.in: fixes --with-openssl-includes + +2002-11-04 Josh Lucas + + * test/test-shell.c: display more info, fixes #42800 + +2002-11-03 Dmitry G. Mastrukov + + * configure.in: Added Belarusian to ALL_LINGUAS + +2002-11-02 Michael Meeks + + * Version 2.1.3 + + * libgnomevfs/Makefile.am: disable + check-headers.pl, we have some path issues here. + + * modules/vfolder/Makefile.am: disable this, doesn't + pass either (grr.) + +2002-10-31 Bastien Nocera + + * modules/vfolder/network.vfolder-info.in: make writing to network: + work again + +2002-10-30 Bastien Nocera + + * modules/default-modules.conf: + * modules/vfolder/Makefile.am: + * modules/vfolder/network.vfolder-info.in: added network: scheme + +2002-10-29 Jody Goldberg + + Patch from Christophe Fergeau + * libgnomevfs/gnome-vfs-file-info.h : Add explicit flags to request + permissioning. + * modules/file-method.c (get_access_info) : new. + * modules/ssh-method.c (get_access_info) : new. + * test/test-info.c (print_file_info) : test for the new flag. + +2002-10-29 Michael Meeks + + * libgnomevfs/gnome-vfs-module-callback.c + (copy_one_callback): bin so we can build -Wall + cleanly again. + +2002-10-29 Colin Walters + + * test/test-xfer.c: add params so we can regression + test the various options nicely. + + * libgnomevfs/gnome-vfs-xfer.h (GnomeVFSXferOptions): + add GNOME_VFS_XFER_FOLLOW_LINKS_RECURSIVE. + + * libgnomevfs/gnome-vfs-xfer.c (copy_directory): add + recursive symlink following copy support. + +2002-10-25 Alex Graveley + + Drop support for the broken .vfolder-info-default concept. + + * modules/vfolder/Makefile.am (EXTRA_DIST): Remove + applications.vfolder-info-default.in and + preferences.vfolder-info-default.in + (vfolder_DATA): Remove applications.vfolder-info-default and + preferences.vfolder-info-default. + + * modules/vfolder/applications-all-users.vfolder-info.in: Link to + preferences:/// instead of preferences-all-users:///. If admins + want to edit preferences-all-users:, they should go there + directly. + + * modules/vfolder/vfolder-info.c (vfolder_info_find_filenames): + Don't look for .vfolder-info-default, and don't copy it to the + user's vfolder directory. + (copy_user_default_file): Remove. + (vfolder_info_init): Set the default writedir to + ~/.gnome2/vfolders/scheme, in case a .vfolder-info files doesn't + exist to tell us where to write changes. + +2002-10-25 Alex Graveley + + * libgnomevfs/gnome-vfs-uri.c (gnome_vfs_uri_new_private): Use + gnome_vfs_context_peek_current() instead of + gnome_vfs_context_new() which was triggering an abort if resolving + a transform URI from a worker thread because you cannot create + contexts in anything other than the primary thread (for some + reason). + +2002-10-25 Alex Graveley + + * modules/vfolder/vfolder-common.c (folder_add_include): Don't add + the include to a hashtable, since a) we don't use it and b) it was + causing memory corruption on folder free. Fixes #95965. + (folder_remove_include): Drop hashtable removing code. + +2002-10-24 Brian Cameron + + * libgnomevfs/gnome-vfs-module-callback.c: Performance fix. + No longer copy the default callback functions to stack_info + in the function gnome_vfs_module_callback_get_stack_info. + Note that the function gnome_vfs_module_callback_invoke is + the only function to access the callback hashes, and it + already will get the callback from the default if it is not + in the private thread memory. + +2002-10-21 Stephen Browne + + * modules/cdemenu-desktop-method.c: Find correct titles + and use last defintion instead of first found of a menu + that is defined multiple times. + +2002-10-12 Seth Nickell + + * modules/vfolder/applications.vfolder-info-default.in: + + Disable favorites folder... Everything is favorites now. + +2002-10-04 Mark McLoughlin + + * modules/vfolder/vfolder-common.h: turn on VFOLDER_DEBUG + for debugging spew and VFOLDER_DEBUG_WITHOUT_MONITORING + for testing non-FAM monitoring code. + + * modules/vfolder/vfolder-common.c: + * modules/vfolder/vfolder-info.c: only spew debugging info + if VFOLDER_DEBUG. + + * modules/vfolder/vfolder-util.c: (monitor_callback_internal): + Use non-FAM monitoring code if VFOLDER_DEBUG_WITHOUT_MONITORING + is defined. + +2002-10-07 Seth Nickell + + * modules/vfolder/applications-all-users.vfolder-info.in: + + Don't hardcode displaying evolution and galeon into the + top-level menu. + +2002-10-01 Yanko Kaneti + + * schemas/system_http_proxy.schemas: reorder some elements so that it + validates. + +2002-09-30 Christophe Fergeau + + * modules/ssh-method.c: + Quote filenames using g_shell_quote before passing them to ssh + +2002-09-30 Christophe Fergeau + + * modules/ssh-method.c: + Make do_read return GNOME_VFS_ERROR_EOF when it read 0 byte + Force C locale in ssh_connect before running ssh (the ls parsing + function expects ls output to be in this locale) + When the uri contains no username, use the name of the current user + (otherwise ssh://localhost won't work). + Fix a possible buffer overflow in do_read_directory + +2002-09-30 Christophe Fergeau + + * modules/ftp-method.c: + Moved ftp authentification to a separate function (ftp_login) + Correctly return GNOME_VFS_ERROR_EOF when do_read didn't read anything + +2002-09-27 Arvind Samptur + + * modules/Makefile.am : look for cde menus only if cde is present. + * cdemenu-module.conf : added the new file. + * default-modules.conf : remove cdemenu from defaults. + Fixes #86736. Patch from Stephen Browne. + +2002-09-20 Arvind Samptur + + * modules/cde-desktop-method.c: Removing Comment field + from the desktop files. Fixes #88484 + Redoing this since gnome-vfs-rewrite and gnome-2-0 branch + merge had knocked it off. + +2002-09-19 James Willcox + + Moved some of eel-vfs-extensions.c into gnome-vfs-utils.c + + * libgnomevfs/gnome-vfs-utils.c: + (gnome_vfs_escape_string_internal), + (gnome_vfs_make_uri_canonical_old), (gnome_vfs_make_valid_utf8), + (gnome_vfs_format_uri_for_display_internal), + (gnome_vfs_format_uri_for_display), (is_valid_scheme_character), + (has_valid_scheme), (gnome_vfs_escape_high_chars), + (gnome_vfs_make_uri_from_input_internal), + (gnome_vfs_make_uri_from_input), + (gnome_vfs_make_uri_canonical_strip_fragment), (uris_match), + (gnome_vfs_uris_match), (gnome_vfs_str_has_prefix), + (gnome_vfs_uri_is_local_scheme), + (gnome_vfs_handle_trailing_slashes), + (gnome_vfs_make_uri_canonical), (gnome_vfs_get_uri_scheme), + (file_uri_from_local_relative_path), + (gnome_vfs_make_uri_from_shell_arg), (is_uri_partial), + (remove_internal_relative_components), + (gnome_vfs_make_uri_full_from_relative): + * libgnomevfs/gnome-vfs-utils.h: + +2002-09-19 Christophe Fergeau + + * libgnomevfs/gnome-vfs-application-registry.c + * libgnomevfs/gnome-vfs-application-registry.h + * libgnomevfs/gnome-vfs-configuration.c + * libgnomevfs/gnome-vfs-configuration.h: added support for + uses_gnomevfs in .application file so that apps can indicate they + can open all uris supported by gnomevfs + * doc/mime-data-specification.txt: updated doc accordingly + +2002-09-13 Ghee Teo + + * Fixes #92132 in modules/http-method.c which leaks file descriptor + on a bad page, error 405. + +2002-09-09 Jody Goldberg + + * libgnomevfs/gnome-vfs-job.c (gnome_vfs_job_destroy_notify_result) : + Add an entry to OP_XFER. + +2002-09-04 Ian McKellar + + * libgnomevfs/gnome-vfs-configuration.c: + (gnome_vfs_configuration_init): + Fixed bug #90035. If g_get_home_dir returns NULL then don't load + configuration from your home directory. + +2002-09-04 Ian McKellar + + * LIMITATIONS: Document a few of GnomeVFS's limitations + +2002-08-29 Alex Graveley + + * configure.in: Bump version to 2.1.2 for development. + +=== start merge changes from gnome-vfs-2-0-vfolder-rewrite branch === + +2002-08-23 Alex Graveley + + * modules/vfolder/vfolder-method.c (do_move): Remove fake CHANGED + event for .directory files since it is really a bug in nautilus + renames (see bug #89616). + +2002-08-23 Alex Graveley + + * modules/vfolder/vfolder-info.c (vfolder_info_emit_change): Call + gnome_vfs_escape_path_string() on the path arg. This fixes some + strange behavior in nautilus when editing .desktop files with + emacs, since emacs' temporary #files were being parsed as URI + fragment identifiers. + + * modules/vfolder/vfolder-util.h (VFOLDER_URI_PARSE): Add debug + printf with function name being called. This allows us to trace + the vfs method calls. + +2002-08-23 Alex Graveley + + * modules/vfolder/vfolder-common.c (folder_extend_monitor_cb): + Fix segfault where we accidentally used child.entry instead of + entry. Remove local entry var, and use child.entry throughout. + Fixes bug #91271. + +2002-08-19 Alex Graveley + + * modules/vfolder/vfolder-method.c (set_desktop_file_key): + Impl. Append a key/value pair to the end of the buffer, after + removing any prior occurances of the same keyname. + (set_desktop_file_locale_key): Impl. Localize the keyname with + the current locale gotten from gnome_vfs_i18n_get_language_list(), + and call set_desktop_file_key(). + (set_dot_directory_locale_name): Impl. Handles renaming + .directory files by making them user-private if necessary, reading + in the file contents, replacing the localized Name key, and + writing it back out again. Also generates a CHANGED event for the + .directory file. + (do_move): Call set_dot_directory_locale_name() to change the + folder name as described in the .directory file, as well as + renaming the "physical" directory name. + (do_create_symbolic_link): Fix deadlock by unlocking the vfolder + before calling get_file_info() and locking it again afterwards , + in case the target URI is on the same filesystem (which may always + be the case). + + * modules/vfolder/vfolder-common.c (entry_make_user_private): Make + a .directory file user-private by calling + folder_set_desktop_file(), instead of modifying includes/excludes. + (create_dot_directory_entry): Make files user_private + again, so we don't make a new user-private copy for each edit. + Ths has the side effect that changes to applications-all-users: + directory names will be reflected in the original .directory files. + + * modules/vfolder/vfolder-info.c (filename_monitor_handle): Reset + info->filename_reload_tag to 0 as a precaution. + +2002-08-16 Alex Graveley + + * modules/vfolder/vfolder-method.c (do_remove_directory_unlocked): + Use vfolder_build_uri instead of creating a parent uri only to + concat the filename to. + (do_move): Call folder_set_name() after folder_make_user_private() + just in case. + + * modules/vfolder/vfolder-info.c + (integrate_writedir_entry_changed): Call entry_set_dirty() on the + changed entry. + (writedir_monitor_cb): Handle files with a .directory extension. + + * modules/vfolder/vfolder-common.c (folder_extend_monitor_cb): + Handle extended subfolder deletion, and don't iterate child + entries for changed/delete just lookup based on filename and + compare URIs. + (create_dot_directory_entry): Don't consider files + user_private. + (folder_reload_if_needed): Reset the entries and the + non-user-private subfolders here. + (folder_new): Set dirty to true for new folders. + (folder_remove_subfolder): Don't blindly unref the child folder, + instead unref the folder we know is our child. Set the removed + child's parent to NULL. + (folder_add_subfolder): Call folder_remove_subfolder() before + adding, but ref first of all. + +2002-08-14 Alex Graveley + + * modules/vfolder/vfolder-util.c (vfolder_untimestamp_file_name): + Only remove one set of timestamp, in case we are copying the same + file around multiple times. + + * modules/vfolder/vfolder-common.c (create_dot_directory_entry): + Only add entry to folder if it does not contain one with the same + name and a higher weight. + (read_one_extended_entry): Ditto. + (read_one_extended_entry): Ditto. + (read_one_include): Ditto. + + * modules/vfolder/vfolder-method.c (do_remove_directory_unlocked): + Remove check for hiddeness, as a recursive delete on a folder with + will not allow the actual folder to be deleted + once all its contents are removed. + (do_unlink_unlocked): Only check result of file delete if parent + is a linked directory, since if it fails we can still just remove + it from the .vfolder-info. + (do_read_directory): Skip to next entry if getting the real file's + info fails. + + * modules/vfolder/vfolder-common.c (read_one_include): Untimestamp + included files that originate in the writedir. + (folder_remove_entry): Only unref the existing entry, instead of + assuming the one we are removing is the same. + (folder_add_entry): Ref before calling folder_remove_entry, in + case we hold the only ref. + + * modules/vfolder/preferences-all-users.vfolder-info.in: Set the + WriteDir to @vfolderdir@/preferences-all-users. + + * modules/vfolder/applications-all-users.vfolder-info.in: Set the + WriteDir to @vfolderdir@/applications-all-users. + + * modules/vfolder/Makefile.am (VFOLDER_INFO_CREATE): Translate + @vfolderdir@ in .vfolder-info.in files as + $(sysconfdir)/gnome-vfs-2.0/vfolders. + + * modules/vfolder/vfolder-info.c (vfolder_info_find_filenames): + Check for system-global file first, then user-local, then try + copying the system-default file. This allows administrator + override of editing. Remove default WriteDir. + (create_itemdir_entry): Don't create ItemDir/MergeDir entries as + user-private, because we probably don't really want them + deleted/edited. + (read_vfolder_from_file): Don't bother creating ItemDir struct to + monitor writedirs, since I don't think we actually care about the + results. + +2002-08-12 Alex Graveley + + * modules/Makefile.am (modules_LTLIBRARIES): Remove libdesktop.so. + + * modules/default-modules.conf: Use libvfolder-desktop.so instead + of libdesktop.so. + + * modules/desktop-method.c: Delete in favor of vfolder-based impl. + + * modules/vfolder/Makefile.am (vfolder_DATA): Install + favorites.vfolder-info, start-here.vfolder-info, + server-settings.vfolder-info, and system-settings.vfolder-info. + + * modules/vfolder/favorites.vfolder-info.in: + * modules/vfolder/start-here.vfolder-info.in: + * modules/vfolder/server-settings.vfolder-info.in: + * modules/vfolder/system-settings.vfolder-info.in: New vfolder info + files to support the vfs methods currently handled by + desktop-method.c + +2002-08-12 Alex Graveley + + * modules/vfolder/vfolder-info.c (find_replacement_for_delete): + For correctness, only call set_mergedir_entry_keywords() if + id_next is a MergeDir. + (itemdir_monitor_handle): Ditto. + (itemdir_monitor_cb): Don't handle events other than CHANGED for + the WriteDir, since if we care about them the .vfolder-info should + be updated and reread, instead of us trying to guess where they + go. + (vfolder_info_find_filenames): Load user-private, else try copying + system-default to user-private, else try using system-global + .vfolder-info directly, else fall back to empty user-private + .vfolder-info. Fixes bug #90202. + +2002-08-09 Alex Graveley + + * modules/vfolder/vfolder-method.c (do_remove_directory_unlocked): + Always unconditionally the deleted folder name, in case + the folder is overrriding a system one. + (do_unlink_unlocked): Always exclude the deleted entry's + displayname, for the same reasons. + +2002-08-09 Alex Graveley + + * modules/vfolder/vfolder-info.c (set_mergedir_entry_keywords): + Abstract the MergeDir keyword adding to here. + (create_mergedir_entry): Call set_mergedir_entry_keywords(). + (find_replacement_for_delete): Take an entry which this + mmanipulates directly. Make sure to load up MergeDir keywords for + the replaced file on the existing entry. Set the entry weight to + that of the ItemDir where we are finding our replacement. + (itemdir_monitor_handle): Set weight and load MergeDir keywords + when the CREATED entry has a higher weight than an existing one + with the same name. + (check_monitors_foreach): Don't emit events for + folders, since we can't be sure all the entries have been + allocated yet. + + * modules/vfolder/vfolder-common.c (entry_make_user_private): Set + the weigth to 1000 so no other entries will override us. + (entry_set_weight): Impl. + +2002-08-09 Alex Graveley + + * modules/vfolder/vfolder-method.c (fill_file_info_for_directory): + Copy code for filling a GnomeVFSFileInfo with a directory's + properties to here from get_file_info_internal(). + (get_file_info_internal): Make child a pointer to a FolderChild, + not pass-by-value. + (do_get_file_info_from_handle): Use get_file_info_internal(), and + be sure to read lock the info. + + * modules/vfolder/vfolder-info.c (vfolder_info_read_info): Don't + forget to add the moniitor for the root directory, as + directory_visit doesn't call create_entry_directory_visit_cb() for + the starting directory. + (itemdir_monitor_cb): If the file matches the monitored uri, + ignore since we only care about events from our children. Don't + set the Vfolder to loading, since we want events to actually be + sent. Check the child filename in question is not hidden. + +2002-08-08 Alex Graveley + + * modules/vfolder/vfolder-method.c (do_create): Don't Forgot to + write unlock when returning from a failed parent directory + creation. + (dir_handle_new): Don't hold a read lock here, otherwise directory + deletion deadlocks as nautilus traverses the files and deletes + them one by one. + (dir_handle_new_all): Ditto. + (dir_handle_free): Don't read unlock, to match above. + (get_file_info_internal): Abstract the GnomeVFSFileInfo filling to + here to share code between do_read_directory() and + do_get_file_info(). + (do_read_directory): Acquire read lock while reading the next + entry. + (do_make_directory): Add check to block against trying to create + the root folder, which always exists. Don't forget to write + unlock if make_directory fails for a link folder's actual + destination. + (do_remove_directory_unlocked): Don't write unlock here, since + this is an _unlocked function :-) + (do_unlink_unlocked): Only add exclude for displayname if file is + not user-private. + (do_create_symbolic_link): Use GNOME_VFS_FILE_INFO_FOLLOW_LINKS + when stat'ing our target link, as we need to be able to tell if + the destination is really a directory. + + * modules/vfolder/vfolder-info.c (filename_monitor_handle): Move + code from filename_monitor_cb, so we can be called from the + filename event timeout handler. + (filename_monitor_cb): For delete events set a 2 second delay + before processing .vfolder-info files, for create a .5 second + delay and process change events instantly. + + * modules/vfolder/vfolder-common.c (entry_make_user_private): + Clean up include/exclude handling. Exclude current displayname, + remove include for current filename, and add include for new + filename. + (read_one_include): Simplify include loading, don't try to futz + with untimestamping filenames, handle include with just a + filename and not a full uri. + + * modules/vfolder/applications-all-users.vfolder-info.in: Don't + include sep.desktop. + +2002-08-08 Alex Graveley + + * modules/vfolder/vfolder-method.c (do_unlink_unlocked): Call + folder_remove_include() if the entry is user-private, so we don't + leave old tags around. + + * modules/vfolder/vfolder-info.c (itemdir_free): g_slist_free() + monitor list. + (vfolder_info_write_user): Check filename monitor exists before + trying to freeze/thaw it. This should fix bug #90160. + (integrate_entry): Skip folders. Emit a monitor + event based on the outcome here. + (itemdir_monitor_handle): Update info->modification_time. Fix + botched relative path handling on create events. + (itemdir_monitor_cb): Fix typo causing double write lock instead + of an unlock. Doh :) + (copy_user_default_file): Call + vfolder_make_directory_and_parents() before trying to copy the + default .vfolder-info file. + + * modules/vfolder/vfolder-common.c (folder_emit_changed): Make + non-static. + + Add some monitor-related debugging g_prints. + +2002-08-06 Alex Graveley + + * modules/vfolder/vfolder-util.c (vfolder_monitor_freeze): Use + gnome_vfs_monitor_cancel instead of setting a freeze flag, because + the events can arrive after the flag has been reset, causing + unneccessary .vfolder-info reads. + (vfolder_monitor_thaw): Use gnome_vfs_monitor_add() to add the + monitor back. + + * modules/vfolder/vfolder-method.c (do_create): Create entry with + highest weight (1000). + (dir_handle_new): Read lock info on DirHandle creation. Use new + folder_list_children(). + (dir_handle_free): Read unlock info. + (do_move): Only delete directory if source and destination folders + are different. + (do_create_symbolic_link): Impl. Support creation of symbolic + links to direcctories by creating a new directory with a + tag. + (do_monitor_add): Use a read lock instead of write lock because we + don't want to write out changes after creating a new monitor. + (do_monitor_cancel): Ditto. + + * modules/vfolder/vfolder-info.c (folder_read): Escape + directories beginning with '~'. Unref the child folder after + adding it as a subfolder. + (read_vfolder_from_file): Ditto, but for ItemDir, MergeDir, + WriteDir, and DesktopDir. + (itemdir_new): Take weight and untimestamp_files parameters. The + first is the weight which will be assigned to entries created from + this folder, the second is for WriteDirs, so filenames are + displayed without the timestamp. Add ourselves to the info's + item_dirs list. + (itemdir_free): Free the list of monitors on subdirs of this + ItemDir. + (create_itemdir_entry): Refactor entry creation for + dirs. Add a monitor to the ItemDir struct if the child is a dir, + so that we are informed of changes in subfolders. + (create_mergedir_entry): Use create_itemdir_entry() to create the + entries for dirs, and add keywords by splitting up the + relative path and matching against the known list of dir names. + (create_entry_directory_visit_cb): directory_visit callback which + creates entries based on the type of ItemDir. + (vfolder_info_read_info): After reading .vfolder-info, foreach + ItemDir call gnome_vfs_directory_visit() so we can create all the + entries. + (vfolder_info_write_user): Write XML to temporary file then use + gnome_vfs_move to move to the config filename, in order to + minimize listeners getting libxml parse errors from empty + .vfolder-info files. + (find_replacement_for_delete): Impl. Look for a like-named + replacement for a file which has been deleted. + (integrate_entry): Impl. Conditionally traverse and replace all + entries with the same name and a lower weight, after rechecking + that the new entry matches the folder's query. + (itemdir_monitor_handle): Impl. Handling monitor events on + ItemDirs by either updating or replacing existing entires, then + integrate with all folders using integrate_entry(). + (vfolder_info_find_filenames): Complexify the .vfolder-info + filename finding code by first checking the standard user + location, and then if it doesn't exist copying a system default + file to the standard location. This allows for overrides and + additions of things in the -all-users.vfolder-info file, such as + preferences:// and favorites:///. + + (filename_monitor_cb): Correctly handle .vfolder-info filename + events by looking at the requested monitors, and if they monitor a + directory, constructing a list of that directory's children. Then + free all the folder/entry resources and reread the .vfolder-info + configuration file. Then trave trhough the list we created and + check if the folders and their children still exist (if not, + then send a DELETED event to the monitor), and then send CREATED + events for any new children. + + * modules/vfolder/vfolder-common.h: Clean out specific monitors + from VFolderInfo, as they are all handled as ItemDirs now. + + * modules/vfolder/vfolder-common.c (entry_new): Accept a weight, + which can be used to tell if a given Entry is more important than + another based on load order. + (entry_reload_if_needed): Copy implicit keywords lists when + reloading so we don't lose the MergeDir keywords. + (entry_get_weight): Return weight. + (entry_add_implicit_keyword): Add Quark to implicit_keywords as + well as keywords. + (folder_new): Take user_private as a parameter. + (folder_extend_monitor_cb): Handle monitor events from our + extend_uri correctly by refreshing, deleting, or creating child + entries. + (create_dot_directory_entry): Move code to create a ".directory" + entry here from vfolder-info.c + (read_includes): Create entries with highest weight (1000). + (read_one_extended_entry): Pass 900 as weight for created entries. + Create folders as non-user-private. + (folder_reload_if_needed): Start monitoring the extend_uri here, + to cut down on unneeded events + (folder_emit_changed): Take a child argument, which emits the + given event with the uri of the named folder child. + (folder_set_extend_uri): Cancel the extend_monitor here. + (folder_set_desktop_file): Don't set the folder dirty. + (folder_list_children): Impl. Copies all the folder children's + names into a list, moved from vfolder-method.c. + (folder_get_subfolder): Don't ref the returned folder. + (folder_remove_subfolder): Don't modify includes/excludes here, + but let the caller do it. Don't set the parent folder to dirty. + (folder_add_subfolder): Don't emit monitor changes here, let our + caller do it. + +2002-07-29 Alex Graveley + + * modules/vfolder/vfolder-info.c: Add WordProcessing->Office and + Toys->Utility keyword mapping. These are two top-level KDE menus. + + * modules/vfolder/applications-all-users.vfolder-info.in: Use + for Preferences, so changes get written out to + preferences-all-users:///. + +2002-07-29 Alex Graveley + + * modules/vfolder/vfolder-util.c (vfolder_escape_home): Impl, + if the filename starts with '~', escape with home directory. + + * modules/vfolder/vfolder-method.c Support is_link folders + thoughtout. Probably buggy. + (do_create_symbolic_link): Impl, support creating "symbolic links" + to directories using the element. + + * modules/vfolder/vfolder-info.c (folder_read): Support ParentLink + elements, which means all changes to a directory are forwarded to + the parent, and not a private copy in the WriteDir. + (itemdir_new): Use vfolder_escape_home(). + (read_vfolder_from_file): Ditto. + (add_xml_tree_from_folder): Store parent as if + is_link is set. + (vfolder_info_reset): Reset the flags. + (copy_user_default_file): Impl. Copies the + scheme.vfolder-info-default to scheme.vfolder-info in the user's + .vfolder-info dir. + (vfolder_info_init): Split filename choosing out to + vfolder_info_find_filenames. + + * modules/vfolder/vfolder-common.h: Use one bit allocation for + flags. Rename inhibit_write to loading in VFolderInfo. Add + is_link to Folder. Turn off debugging. + + * modules/vfolder/vfolder-common.c (read_extended_entries): Call + read_one_extended_entry() for each file. + (read_info_entry_pool): Call read_one_info_entry_pool() for each + entry in the entry pool. + + * modules/vfolder/Makefile.am (EXTRA_DIST): Installed vfolder-info + files are now applications-all-users.vfolder-info, + preferences-all-users.vfolder-info, and + applications.vfolder-info-default. + +2002-07-26 Alex Graveley + + * modules/vfolder/test-vfolder.c (main): Use putenv() as setenv() + is not portable to Solaris. + +2002-07-26 Alex Graveley + + * modules/vfolder/vfolder-util.c (monitor_timeout_cb): Fix + reentrency by copying the stat_monitors list, and checking each + VFolderMonitor is still in the list while iterating. + + * modules/vfolder/vfolder-method.c (do_open): Handle all-scheme by + loading the FolderChild manually. + (dir_handle_new_all): ret->list is a list of entry names, not + Entry pointers. + (do_read_directory): Handle all-scheme. + (do_get_file_info): Ditto. Also, handle a NULL parent folder for + all-scheme. + (do_remove_directory_unlocked): New, unlocked version of + do_remove_directory. + (do_remove_directory): Wrap do_remove_directory_unlocked() with a + lock. + (do_unlink_unlocked): New, unlocked version of do_unlink. + (do_unlink): Wrap do_unlink_unlocked() with a lock. + (do_move): Fix some logic bugs, use _unlocked versions of unlink + and remove_directory, only make the moved file user-private if the + displayname has changed. + + * modules/vfolder/vfolder-info.c (vfolder_info_write_user): Freeze + and thaw the filename_monitor while writing out the .vfolder-info, + so we don't trigger our own reloads. + (vfolder_info_set_dirty): just set info->dirty to true, instead of + writing the .vfolder-info out every time. + + * modules/vfolder/vfolder-common.h (VFOLDER_INFO_WRITE_UNLOCK): + Call vfolder_info_write_user() before unlocking, so we batch + .vfoldeer-info file writes. + + * modules/vfolder/vfolder-common.c (entry_reload_if_needed): Add + basic support for a "Deprecates" keyword, to allow differently + named .desktop files to replace one-another. + (read_includes): Read and load the explicit includes here, so we + can support including arbitrary URLs, not just extended/pool + entries. + (is_excluded): New, check the displayname and filename for + includability. + (folder_reload_if_needed): Call read_includes. + (folder_add_include): remove_exclude here. + (folder_add_exclude): remove_include here. + +2002-07-25 Alex Graveley + + * modules/vfolder/test-vfolder.c (main): NULL term + g_build_filename(). Use putenv() which is more portable than + setenv(). + +2002-07-24 jacob berkman + + * modules/vfolder/Makefile.am (libvfolder_desktop_la_LIBADD): + point to $(top_builddir) and not a relative path + +2002-07-24 Alex Graveley + + * modules/vfolder/vfolder-method.c (dir_handle_new): Match with + folder query for OnlyUnallocated folders when listing contents. + (do_make_directory): Handle existing but hidden folder by removing + DontShowIfEmpty. + + * modules/vfolder/vfolder-common.c (folder_is_hidden): Match with + folder query for OnlyUnallocated folders, which clears out the + Other menu somewhat. + + * modules/vfolder/vfolder-info.c (get_folder_for_path_list_n): + return NULL if parent folder is hidden. + + * modules/vfolder/test-vfolder.c (test_vfolder_ops): Fix some bad + args to gnome-vfs, implement test #6 and #7. + +2002-07-23 Alex Graveley + + * modules/vfolder/vfolder-util.c (vfolder_build_uri): Rip off of + g_build_filename, but which handles the first element being a + uri scheme://. + + * modules/vfolder/vfolder-method.c: Use vfolder_build_uri(). + + * modules/vfolder/vfolder-info.c: Use vfolder_build_uri(). + + * modules/vfolder/vfolder-common.c: Use vfolder_build_uri(). + +2002-07-22 Alex Graveley + + * modules/vfolder/vfolder-common.c (read_extended_entries): Use + g_build_filename(). + +2002-07-22 Alex Graveley + + * modules/vfolder/vfolder-method.c (do_create): Uniquely timestamp + filename if there is a writedir, otherwise use the folder's + extended URI, otherwise give up. Ensure destination directory + before creating. + (do_get_file_info): Set permissions to read-only for ReadOnly + folders. + + * modules/vfolder/vfolder-info.c: Add some keywords so ximian + menus get organized nicely. + (create_entries_from_itemdir): Allow stripping of timestamp at + beginning of file if we are reading from the WriteDir. + (vfolder_info_read_info): Pass TRUE for user_private so folders + are persisted correctly. + (vfolder_info_read_info): Strip timestamps from filenames for + WriteDir and not from ItemDir. + (vfolder_info_write_user): Make directory and parents before + saving file. + (vfolder_info_init): Allow overwriting of WriteDir and directory + containing .vfolder-info files from environment variables. + + * modules/vfolder/vfolder-common.c (entry_make_user_private): + Ensure write directory is created before xferring file. Uniqueify + filename, to avoid naming conflicts. Fail if there is no + filename. Exclude the old displayname, and include the new + timestamped one. Take the parent folder as an arg so we can + manage the Includes/Excludes. + (entry_set_filename): Free entry->uri on change. + (read_extended_entries): Check include/exclude against full uri + and filename. + + * modules/vfolder/test-vfolder.c: New, loads and performs + operations on the test-vfolder:/// uri. Still needs a few more + tests implemented to be complete. + + * modules/vfolder/test-vfolder.vfolder-info.in: New, .vfolder-info + file used by test-vfolder. + + * modules/vfolder/test-vfolder-parent.vfolder-info.in: New, + .vfolder-info file used by test-vfolder. + + * modules/vfolder/test-vfolder-modules.conf: Created, vfs module + description used by test-vfolder. + + * modules/vfolder/applications.vfolder-info.in: Merge in ximian + menus, as they add some sanity. On the root folder, Exclude gmc, + nautilus-help, and gnome-help, Include evolution & galeon. Remove + silly rule on root folder causing root entries from GNOME1 to not + be shown. Remove silly rule about hiding "System" entries from + the Accessories menu. + + * modules/vfolder/TODO: Update. + + * modules/vfolder/Makefile.am (test_vfolder_SOURCES): Build + test-vfolder, and generate test-vfolder-parent.vfolder-info & + test-vfolder.vfolder-info. + +2002-07-18 Damon Chaplin + + * modules/vfolder/vfolder-common.c (folder_emit_changed): for the + root folder pass "/" as the uri rather than NULL. + +2002-07-18 Damon Chaplin + + * modules/vfolder/vfolder-common.c (entry_quick_read_keys): oops. + didn't need to add '\0' to a GString. That was silly. + +2002-07-18 Damon Chaplin + + * modules/vfolder/vfolder-common.c (entry_quick_read_keys): init + *result1 & *result2 to NULL, in case there is an error reading the + .desktop file. (Some of my X11 .desktop files are not readable by me, + so that caused a problem here.) + Also append '\0' to the GString, so we can use it like a normal string. + These 2 fixes seem to fix the corruption problems I was having. + +2002-07-18 Alex Graveley + + * modules/vfolder/vfolder-common.c (folder_get_child): Don't call + vfolder_info_lookup_entry here for only_unallocated folders, let + folder_get_entry() do it. + +2002-07-17 Alex Graveley + + * modules/vfolder/vfolder-info.c (vfolder_info_locate): Wrap + load_folders in an inhibit_write, so the vfolder info file doesn't + get written out as we create new extended folders. + +2002-07-17 Alex Graveley + + * modules/vfolder/vfolder-info.c (read_vfolder_from_file): Don't + free default itemdirs/mergedirs since they are now pulled from + GNOME2_PATH. + + * modules/vfolder/vfolder-common.c (read_extended_entries): Put + the '/' in the right place between dirname and filename. + (read_extended_entries): Remove extraneous entry_set_filename(). + +2002-07-17 Damon Chaplin + + * modules/vfolder/vfolder-common.c (entry_reload_if_needed): store + the value returned from g_slist_prepend(). Fixes bug #88132. + +2002-07-17 Alex Graveley + + * modules/vfolder/vfolder-method.c (do_create): If there is a + write dir, then the parent folder's URI, otherwise read-only. + + * modules/vfolder/vfolder-common.c (entry_quick_read_keys): Free + fullbuf even if empty. + (entry_make_user_private): Use g_build_filename, not + g_build_path. Return success if there is no WriteDir. + (folder_unref): Dealloc entries as well as unref. Dealloc any + entries which we Excluded. + (read_info_entry_pool): Alloc excluded files. + + * modules/vfolder/applications.vfolder-info.in: Add some defaults, + so we don't rely on mandatory defaults from vfolder_info_init(). + Spell "Accessories" correctly. Remove the duplication of the + preferences-all-users:/// vfolder layout, and just make it the + of the Preferences folder. + + * modules/vfolder/vfolder-info.c (vfolder_info_init): Remove the + default itemdir/writedir/desktopdir; just listen to the config + file. Use GNOME2_PATH as a bunch of prefixes for itemdirs. + +2002-07-16 Alex Graveley + + * modules/vfolder/ABOUT: Add file describing the vfolder + architecture somewhat. + +2002-07-15 Frederic Crozat + + * test/test-uri.c: (main): + Fix test, due to canonization change + +2002-07-13 Peteris Krisjanis + + * configure.in - (ALL_LINGUAS) Added support for Latvian (lv) language. + +2002-07-12 Rohit R + Laavanya K R + * modules/file-method.c + (do_find_directory): modified the code so as to create the + .Trash directory with permissions 0700 only. + Fixes bug #46475. + +2002-07-12 Alex Graveley + + * modules/vfolder/vfolder-info.c (read_vfolder_from_file): Load + mergedirs and itemdirs to the same list, so we retain load order. + (itemdir_new): Add is_mergedir arg. + +2002-07-12 Alex Graveley + + * modules/vfolder/vfolder-method.c (do_unlink): Exclude based on + displayname, not filename. + (do_create): Include based on displayname, not filename. + + * modules/vfolder/vfolder-common.c (read_info_entry_pool): Check + include/exclude against entry's displayname, note full filename. + +2002-07-12 Alex Graveley + + * modules/vfolder/vfolder-info.c (vfolder_info_destroy): Call + vfolder_info_reset. + (vfolder_info_reset): Implement. Free everything except scheme, + requested_monitors, and rw_lock. + (filename_monitor_cb): Call vfolder_info_reset() then + vfolder_info_read_info() to reload everything from scratch. + (write_dir_monitor_cb): Ditto. + + * modules/vfolder/vfolder-common.c (entry_quick_read_keys): Fix to + not expect fgets() type strings. + (entry_set_dirty): Set a dirty flag, instead of always reloading. + (entry_set_filename): Set entry dirty. + (entry_add_implicit_keyword): Set entry dirty. + (entry_get_keywords): Call entry_reload_if_needed(), in case the + entry is dirty. + +2002-07-11 Alexander Larsson + + * modules/file-method.c (get_stat_info, do_open): + Correctly set O_TRUNC in do_open. + Fix uninitialized memory read bug with symlinks in get_stat_info. + +2002-07-11 Alex Graveley + + * modules/vfolder/vfolder-info.c (vfolder_info_init): Free + base_scheme. + + * modules/vfolder/vfolder-util.c (vfolder_monitor_cancel): Free + monitor->uri. + + * modules/vfolder/applcations.vfolder-info: Spell Accessories + correctly. + +2002-07-10 Alex Graveley + + * modules/vfolder/vfolder-method.c (dir_handle_new): Fix typo, + handle unallocated folders, sorting, and the entry display name + being different from the source file's. + + * modules/vfolder/vfolder-common.c: Redo lots of things + here. Notably fixes folder and entry dirtying, and dir loading + fixups. + + * modules/vfolder/vfolder-info.c: Implement missing featues: + like correct .directory file handling and, implicit mergedir + keywords, and client monitors. + + * modules/default-modules.conf (all-applications): Add + applications-all-users: and preferences-all-users: methods to + allow access to system-global vfolders, to allow administrator + changes and folder extension. + +=== end merge changes from gnome-vfs-2-0-vfolder-rewrite branch === + +2002-08-16 Arvind Samptur + + * modules/cde-desktop-method.c: Removing Comment field + from the desktop files. Fixes #88484 + Re-doing this patch as Hidetoshi's patch to fix + menus to correctly translate to utf-8 had knocked it off. + +2002-08-15 Michael Meeks + + * modules/file-method.c + (read_saved_cached_trash_entries): code should agree + on the size of the buffer and how much to read into it. + (find_trash_directory): hold a lock on the trash cache + while operating on it. #10438 + +Thu Aug 8 11:26:03 2002 HideToshi Tajima + + * modules/cdemenu-desktop-method.c (expand_env_vars): get LC_CTYPE + from setlocale when no LC_CTYPE environment variable is set. Fixes #86462 + * modules/cdemenu-desktop-method.c (get_icon_for_action): use + /usr/dt/appconfig/icons/C for fallback to avoid returning + "ICON=NONE" which makes gnome-panel crash in many locales. + * modules/cdemenu-desktop-method.c (do_open): Patch to fix the cde + menus to correctly translate to utf-8, originally by George Lebl + Fixes #84074 + + merged changes back from the gnome-2-0 branch + +2002-08-08 jacob berkman + + * modules/Makefile.am (module_flags): add -module flag (fixes + building on OS X) + + * modules/cdemenu-desktop-method.c (expand_env_vars): fix some + broken logic to make cde menu work when $LANG is not set + + (fixes bug #87684) + +2002-08-07 Dave Camp + + * modules/fstype.c (filesystem_type): Use g_free to free + the g_strduped string. + +2002-08-05 Federico Mena Quintero + + Should fix #48539. + + * modules/fstype.c (filesystem_type_uncached): Merged fix from GNU + findutils-4.1.7; return a copied string instead of a pointer to a + string on the stack... + (filesystem_type): Free the string we got when we must cache a new + value. + +2002-08-05 Michael Meeks + + * libgnomevfs/gnome-vfs-mime-info.c + (reload_if_needed): forward port Jody's fix for the 5s + problem. + +2002-02-29 Arvind Samptur + + * modules/cde-desktop-method.c: Removing Comment field + from the desktop files. Fixes #88484 + + * modules/cde-desktop-method.c (do_read_directory): + REALLY ignore CDE specific actions that make no sense in GNOME + Patch by Stephen Browne. Fixes #88483 + +2002-07-27 Ian McKellar + + * libgnomevfs/gnome-vfs-cancellable-ops.c: + (gnome_vfs_read_cancellable), (gnome_vfs_write_cancellable): + Check for NULL bytes_(read|written), pass in dummy pointer. + +2002-07-26 Ian McKellar + + * libgnomevfs/gnome-vfs-xfer.c: (copy_file): + Fixed up gnome-vfs-xfer problem pointed out by Josh Parsons. My fix + is slightly different than his proposed fix but the spirits the same. + +2002-07-25 Dave Camp + + * libgnomevfs/gnome-vfs-inet-connection.c + (gnome_vfs_inet_connection_read): Return EOF if 0 bytes were read. + +2002-07-25 Michael Meeks + + * libgnomevfs/gnome-vfs-init.c + (gnome_vfs_pthread_init, gnome_vfs_init): init threads + if we have to before taking the vfs_already_initialized + lock - makes Valgrind happy; thanks to Julian Seward. + +2002-07-25 Laszlo Peter + + reviewed by Michael Meeks + + * configure.in: added test for libpopt + + * test/Makefile.am: link libpopt to the test programs. + +2002-07-25 Pablo Saratxaga + + * configure.in: Added Bosnian (bs) to ALL_LINGUAS + +2002-07-24 Frederic Crozat + + * test/Makefile.am: + add auto-test to EXTRA_DIST (otherwise make check + fails with tarball) + +2002-07-24 Michael Meeks + + * libgnomevfs/gnome-vfs-job.c (gnome_vfs_job_go): dump + debug before scheduling the job, rather than when job + might be invalid. + (handle_cancelled_open): don't do daft things with + re-using the original job, and trying to signal + strangely to the caller. + (dispatch_job_callback): expand switch for + CREATE_SYMBOLIC_LINK test for a valid handle before + destroying it here, since it wasn't killed at the + exit of gnome-vfs-job-slave.c (thread_routine). + (execute_read, execute_write): set the op type to + READ_WRITE_DONE here before job might be invalid. + (gnome_vfs_job_execute): and not here, when it may + be duff / freed. + + * libgnomevfs/gnome-vfs-async-ops.c + (gnome_vfs_async_xfer): set handle_return before + calling job_go [ which may invalidate job ] + + * libgnomevfs/gnome-vfs-job.c + (job_notify): prune semaphore mess. + (gnome_vfs_job_set): lock/unlock. + +2002-07-23 Michael Meeks + + * test/test-async-cancel.c (file_open_callback): move + the async_read into the open_callback. + + * libgnomevfs/gnome-vfs-job.c + (empty_close_callback): kill. + + * libgnomevfs/gnome-vfs-job-queue.c + (job_queue_get_first): don't foreach a NULL job_queue. + +2002-07-23 Michael Meeks + + * libgnomevfs/gnome-vfs-async-job-map.c + (async_job_callback_map_destroy): don't assert on the + idly built async_job_callback_map. + + * libgnomevfs/gnome-vfs-job-slave.c (thread_routine): + always destroy the VFS job, if we are complete, instead + of checking for whether we have a callback still + registered in the job map, therein lies a race. + + * libgnomevfs/gnome-vfs-job.c + (job_oneway_notify, job_notify): don't leak on cancel. + (gnome_vfs_job_destroy): blank the memory for good + measure. + + * libgnomevfs/gnome-vfs-async-job-map.c + (gnome_vfs_async_job_map_unlock), + (gnome_vfs_async_job_map_lock): cope with the + recursive nature of this properly. + + * libgnomevfs/gnome-vfs-job-queue.c + (gnome_vfs_job_queue_shutdown): try locking the + job_queue lock before destroying the entire tree, sob. + (gnome_vfs_job_queue_run): kill black magic with + volatile 'gnome_vfs_quitting' stuff, we don't need + that - just hold the job queue lock. + + * test/test-async-cancel.c (wait_until_vfs_jobs_gone): + eliminate follow on error, so we can try and isolate + problems more accurately. + (test_get_file_info): don't leak URIs in lists. + (main): if memprof is running, don't quit just loop. + +2002-07-19 Frederic Crozat + + * configure.in: + don't set OPENSSL_CFLAGS if it is "/usr/include", + otherwise gcc >= 3.1 issues a warning. + +2002-07-19 Frederic Crozat + + * modules/ssh-method.c: (ssh_connect): + Fix bug 88539 (leaking ssh processes) by using + g_spawn_async_with_pipes + +2002-07-17 Michael Meeks + + * test/auto-test: re-write. + + * test/Makefile.am: connect auto-test, upd env. + + * test/test-async-cancel.c + (MAX_THREAD_WAIT): bump the thread wait for my poor + old machine. + +2002-07-16 Michael Meeks + + * libgnomevfs/gnome-vfs-async-job-map.c: + re-arrange to ensure the locks protect the bits + they are supposed to. Kill the volatile things + assert on. + +2002-07-16 Michael Meeks + + * libgnomevfs/gnome-vfs-thread-pool.c + (thread_list_locks): don't use a recursive mutex. + debug print thread pointer not pthread id. + + * libgnomevfs/gnome-vfs-method.c + (init_hash_table, init_path_list): don't take fine + grained locks here. + (gnome_vfs_method_init): take a lock here instead. + (gnome_vfs_add_module_to_hash_table): hold the lock + for longer, to avoid nasty races, change sig. + (gnome_vfs_method_get): upd / simplify / speedup. + (gnome_vfs_transform_get): ditto. + + * libgnomevfs/gnome-vfs-module-callback.c + (stack_keys_alloc): kill in favour of + (gnome_vfs_module_callback_private_init): this. + (initialize_per_thread_if_needed): upd. + (async_callback_response): broadcast instead of + signalling, there might be multiple threads waiting. + + * libgnomevfs/gnome-vfs-init.c + (gnome_vfs_pthread_init): upd. + (gnome_vfs_init): here. + (gnome_vfs_postinit): ensure we do it here too & re-order. + +2002-07-15 Michael Meeks + + * libgnomevfs/gnome-vfs-thread-pool.c + (gnome_vfs_thread_create): kill unused thread argument + (new_thread_state): port to g_thread. + + * libgnomevfs/gnome-vfs-init.c (gnome_vfs_init): use + g_thread_init not gnome_vfs_pthread stuff. + (gnome_vfs_postinit): ditto. + + * libgnomevfs/Makefile.am: remove gnome-vfs-pthread.[ch] + + * *.[ch]: switch pthread -> g_thread stuff, mostly a sed. + +2002-07-12 Michael Meeks + + * libgnomevfs/gnome-vfs-cancellation.c + (gnome_vfs_cancellation_cancel), + (gnome_vfs_cancellation_ack): only write if we have a pipe. + (gnome_vfs_cancellation_get_fd): idly create the pipes, + return -1 on error. + (gnome_vfs_cancellation_new): init the pipe fds to -1 + + * libgnomevfs/gnome-vfs-init.c (gnome_vfs_init): + move pthread_init up the order. If we don't do this + we create a default main context, without the + 'wake_up_pipe' initialized, which means that anyone + doing a plain gnome-init has a '0' wake_up_pipe by + the time they need to write / read to it. This means + you see an 'A' on the console and have to hit enter + before getting any async callbacks. + + * libgnomevfs/gnome-vfs-job.h (JOB_DEBUG_PRINT): + make more standard. + + * test/test-async.c (async_queue_callback): impl. + (main): hammer the async queue to test efficiency. + re-hash lots of this. + +2002-07-15 Frederic Crozat + + * libgnomevfs/gnome-vfs-uri.c: (set_uri_element): + canonize NULL uri into "/". "start-here:" will now be + canonized into "start-here:///", fixing some monitoring + problem in nautilus + + * test/test-uri.c: (main): Fix test due to canonization change + +2002-07-11 Michael Meeks + + * libgnomevfs/gnome-vfs-mime-info.c + (load_type_info_from): use g_string_truncate + for a 20% speedup. + (APPEND_CHAR): inline more for another 20%. + + * test/test-mime.c (main): add --speedTest + for mime info reloading. + +2002-07-07 Seth Nickell + + * libgnomevfs/gnome-vfs-method.gob: + + Ahem. Getting built accidentally. Not a good thing. + Replacing decent clean files. + +2002-07-05 Stephen Browne + + * modules/cdemenu-desktop-method.c + Patch from rohit.raveendran@wipro.com + modified the code so that the function create_cde_icon_name_cache + creates the file g-cdeiconnames with permissions 644 in .gnome + directory in the users home directory. + Fixes #87267 + +2002-06-27 Michael Meeks + + * modules/vfolder-desktop-method.c + (try_free_file_monitors_create_files_unlocked): use + ensure_folder_unlocked to avoid deadlock. + (rescan_monitors): ditto. #84910 + +2002-06-25 Jody Goldberg + + * libgnomevfs/gnome-vfs-mime.c (file_date_record_update_mtime) : track + monitor files even if they do not exist at start up. That way we can + notice the first user defined mime type is added. + (mime_fill_from_file) : ditto. + (mime_load) : don't ignore the unborn files just because their parent + dir does not exist yet. + +2002-06-25 Damon Chaplin + + * libgnomevfs/gnome-vfs-async-job-map.c (gnome_vfs_async_job_map_init): + initialize the async_job_callback_map_lock mutex here, instead of in + gnome_vfs_async_job_add_callback(), so we can use it even when + async_job_callback_map is NULL. + (gnome_vfs_async_job_add_callback): lock the above mutex before + checking & creating the async_job_callback_map hash table, to avoid + a tiny race condition. + (gnome_vfs_async_job_cancel_job_and_callbacks): lock the above mutex + first and set job->cancelled. Previously it was just returning if + async_job_callback_map was NULL, which meant that job->cancelled + didn't get set. + (async_job_callback_map_destroy): don't destroy the + async_job_callback_map_lock mutex here. We keep it around forever. + + Fixes bug #74189. + +2002-06-21 Seth Nickell + + * doc/tmpl/gnome-vfs-method.sgml: + * libgnomevfs/gnome-vfs-async-ops.h: + * libgnomevfs/gnome-vfs-file-info.h: + * libgnomevfs/gnome-vfs-mime-handlers.h: + * libgnomevfs/gnome-vfs-standard-callbacks.h: + * libgnomevfs/gnome-vfs-uri.h: + * libgnomevfs/gnome-vfs-xfer.h: + + Pad every struct by at least two "void *"s to avoid + future breaks in ABI compatibility. + + When we already know we're going to have to add + fields to a struct, and can forsee needing extra, + pad by a little more (notable GnomeVFSFileInfo). + + * modules/ssh-method.c: + + Fix compilation problem on Solaris. + + * libgnomevfs/gnome-vfs-types.h: + * libgnomevfs/Makefile.am + + Add gnome-vfs-types.h back in. + +2002-06-21 Stephen Browne + + * modules/cdemenu-desktop-method.c (find_all_included_files): fix for + bug #84967. Patch from ghee.teo@sun.com + +2002-06-21 Michael Meeks + + * configure.in: bin GTK_REQUIRED, upd. BONOBO_REQUIRED + and ORBIT_REQUIRED, bonobo-activation-required. #80244 + +2002-06-13 Glynn Foster + + * docs/vfolder-info-spec.dtd: Remove some confusing whitespace so + you can see where the comments are directed. + +2002-06-17 Damon Chaplin + + * libgnomevfs/gnome-vfs-monitor.c (gnome_vfs_monitor_do_add): if + the monitor_add call fails, return NULL as the handle. It was + returning a pointer to freed memory before. Fixes bug #84693. + Approved by Ian McKellar. + +2002-06-17 Seth Nickell + + * libgnomevfs/gnome-vfs-method.gob: + + Formatting improvements. + +2002-06-17 Seth Nickell + + * libgnomevfs/gnome-vfs-method.gob: + + Initial (non-working) pass at converting GnomeVFSMethods + into a GObject. + +2002-06-17 Seth Nickell + + * doc/tmpl/gnome-vfs-context.sgml: + + Add a short description of GnomeVFSContext. + + * libgnomevfs/gnome-vfs-init.c: + + Fix documentation for gnome_vfs_is_primary_thread() + + * libgnomevfs/gnome-vfs-utils.c: + + Document several string escaping calls. + +2002-06-17 Seth Nickell + + * HACKING: + + Clean up the hacking file, add comments on making sure + any API changes are reflected in the documentation. + +2002-06-17 Seth Nickell + + * libgnomevfs/gnome-vfs-application-registry.h: + + Document a few special key types. + + * libgnomevfs/gnome-vfs-async-ops.c: + * libgnomevfs/gnome-vfs-async-ops.h: + + Document all the AsyncCallbacks. + + * libgnomevfs/gnome-vfs-mime-info.c: + * libgnomevfs/gnome-vfs-mime-monitor.c: + * libgnomevfs/gnome-vfs-mime-utils.h: + + Finish documenting these files. + + * libgnomevfs/gnome-vfs-uri.h: + * libgnomevfs/gnome-vfs-utils.h: + + Add documentation for a few data types. + + * libgnomevfs/gnome-vfs-xfer.h: + + Improve documentation of Xfer data types + and enumerations. + +2002-06-16 Seth Nickell + + * doc/tmpl/gnome-vfs-context.sgml: + * libgnomevfs/gnome-vfs-context.c: (gnome_vfs_context_new), + (gnome_vfs_context_free): + * libgnomevfs/gnome-vfs-context.h: + + Remove "unref" and "ref" calls. Replace with "free". + + Document context. + + * doc/gnome-vfs-sections.txt: + * libgnomevfs/gnome-vfs-async-ops.c: + * libgnomevfs/gnome-vfs-file-info.h: + * libgnomevfs/gnome-vfs-job.c: (gnome_vfs_op_destroy): + * libgnomevfs/gnome-vfs-uri.c: (gnome_vfs_uri_new_private): + * libgnomevfs/gnome-vfs-uri.h: + * libgnomevfs/gnome-vfs-xfer.h: + + Finish URI documentation, document xfer, and some enums + in file-info. + +2002-06-16 Seth Nickell + + * doc/tmpl/gnome-vfs-async-ops.sgml: + * doc/tmpl/gnome-vfs-inet-connection.sgml: + * libgnomevfs/gnome-vfs-async-ops.h: + * libgnomevfs/gnome-vfs-standard-callbacks.h: + * libgnomevfs/gnome-vfs-uri.h: + + More documentation. + +2002-06-16 Seth Nickell + + * doc/gnome-vfs-sections.txt: + * doc/tmpl/gnome-vfs-directory.sgml: + * doc/tmpl/gnome-vfs-inet-connection.sgml: + * doc/tmpl/gnome-vfs-iobuf.sgml: + * doc/tmpl/gnome-vfs-socket-buffer.sgml: + * libgnomevfs/Makefile.am: + * libgnomevfs/gnome-vfs-application-registry.c: + * libgnomevfs/gnome-vfs-async-ops.c: + (gnome_vfs_async_get_file_info), (gnome_vfs_async_find_directory): + * libgnomevfs/gnome-vfs-directory.c: + (gnome_vfs_directory_visit_files): + * libgnomevfs/gnome-vfs-directory.h: + * libgnomevfs/gnome-vfs-inet-connection.c: + (gnome_vfs_inet_connection_to_socket), + (gnome_vfs_inet_connection_to_socket_buffer): + * libgnomevfs/gnome-vfs-inet-connection.h: + * libgnomevfs/gnome-vfs-job-queue.c: + * libgnomevfs/gnome-vfs-mime-info.c: + * libgnomevfs/gnome-vfs-module.h: + * libgnomevfs/gnome-vfs-ops.c: + * libgnomevfs/gnome-vfs-socket-buffer.c: + (gnome_vfs_socket_buffer_destroy), (gnome_vfs_socket_buffer_peekc): + * libgnomevfs/gnome-vfs-socket-buffer.h: + * libgnomevfs/gnome-vfs-socket.c: + * libgnomevfs/gnome-vfs-ssl.c: (gnome_vfs_ssl_create): + * libgnomevfs/gnome-vfs-uri.c: + * libgnomevfs/gnome-vfs-utils.c: + + Bunch more documentation :-) + + * libgnomevfs/gnome-vfs-iobuf.c: + * libgnomevfs/gnome-vfs-iobuf.h: + + Remove from GnomeVFS as they have the same functions as GnomeVFSSocketBuffer. + + * modules/ftp-method.c: (read_response_line), (do_control_write), + (do_transfer_command), (end_transfer), (ftp_connection_create), + (ftp_connection_destroy), (do_read), (do_write), + (internal_get_file_info), (do_open_directory): + * modules/nntp-method.c: (read_response_line), (do_control_write), + (nntp_connection_create), (nntp_connection_destroy): + * modules/nntp-method.h: + + Convert from iobuf to socket_buffer. + +2002-06-16 Seth Nickell + + * libgnomevfs/gnome-vfs-metadata.gob: + * libgnomevfs/gnome-vfs-monitor.h: + * libgnomevfs/gnome-vfs-ops.c: + + Add some documentation for metadata and monitoring APIs. + +2002-06-16 Seth Nickell + + * doc/gnome-vfs-docs.sgml: + * doc/gnome-vfs-sections.txt: + * doc/tmpl/gnome-vfs-async-ops.sgml: + * doc/tmpl/gnome-vfs-job-limit.sgml: + * doc/tmpl/gnome-vfs-mime-monitor.sgml: + * doc/tmpl/gnome-vfs-ops.sgml: + + Merge some needless categories into ops and + async-ops. + +2002-06-16 Seth Nickell + + * doc/gnome-vfs-docs.sgml: + * doc/gnome-vfs-sections.txt: + + Re-organize documentation, move stuff more fluidly + between sections rather than relying so heavily on + the (rather poor) header file organization. + + * doc/tmpl/application-registry.sgml: + * doc/tmpl/async-ops.sgml: + * doc/tmpl/cancellation.sgml: + * doc/tmpl/context.sgml: + * doc/tmpl/directory.sgml: + * doc/tmpl/file-info.sgml: + * doc/tmpl/file-size.sgml: + * doc/tmpl/find-directory.sgml: + * doc/tmpl/gnome-vfs-application-registry.sgml: + * doc/tmpl/gnome-vfs-async-ops.sgml: + * doc/tmpl/gnome-vfs-cancellation.sgml: + * doc/tmpl/gnome-vfs-context.sgml: + * doc/tmpl/gnome-vfs-directory.sgml: + * doc/tmpl/gnome-vfs-file-info.sgml: + * doc/tmpl/gnome-vfs-file-size.sgml: + * doc/tmpl/gnome-vfs-find-directory.sgml: + * doc/tmpl/gnome-vfs-inet-connection.sgml: + * doc/tmpl/gnome-vfs-init.sgml: + * doc/tmpl/gnome-vfs-iobuf.sgml: + * doc/tmpl/gnome-vfs-job-limit.sgml: + * doc/tmpl/gnome-vfs-metadata.sgml: + * doc/tmpl/gnome-vfs-method.sgml: + * doc/tmpl/gnome-vfs-mime-database.sgml: + * doc/tmpl/gnome-vfs-mime-monitor.sgml: + * doc/tmpl/gnome-vfs-mime.sgml: + * doc/tmpl/gnome-vfs-module-callback-module-api.sgml: + * doc/tmpl/gnome-vfs-module-callback.sgml: + * doc/tmpl/gnome-vfs-module-shared.sgml: + * doc/tmpl/gnome-vfs-module.sgml: + * doc/tmpl/gnome-vfs-monitor.sgml: + * doc/tmpl/gnome-vfs-ops.sgml: + * doc/tmpl/gnome-vfs-parse-ls.sgml: + * doc/tmpl/gnome-vfs-result.sgml: + * doc/tmpl/gnome-vfs-socket-buffer.sgml: + * doc/tmpl/gnome-vfs-socket.sgml: + * doc/tmpl/gnome-vfs-ssl.sgml: + * doc/tmpl/gnome-vfs-standard-callbacks.sgml: + * doc/tmpl/gnome-vfs-transform.sgml: + * doc/tmpl/gnome-vfs-unused.sgml: + * doc/tmpl/gnome-vfs-uri.sgml: + * doc/tmpl/gnome-vfs-utils.sgml: + * doc/tmpl/gnome-vfs-xfer.sgml: + * doc/tmpl/gnome-vfs.sgml: + * doc/tmpl/handle.sgml: + * doc/tmpl/inet-connection.sgml: + * doc/tmpl/init.sgml: + * doc/tmpl/iobuf.sgml: + * doc/tmpl/method.sgml: + * doc/tmpl/mime-handlers.sgml: + * doc/tmpl/mime-info.sgml: + * doc/tmpl/mime-monitor.sgml: + * doc/tmpl/mime.sgml: + * doc/tmpl/module-callback-module-api.sgml: + * doc/tmpl/module-callback.sgml: + * doc/tmpl/module-shared.sgml: + * doc/tmpl/module.sgml: + * doc/tmpl/ops.sgml: + * doc/tmpl/parse-ls.sgml: + * doc/tmpl/result.sgml: + * doc/tmpl/ssl.sgml: + * doc/tmpl/standard-callbacks.sgml: + * doc/tmpl/types.sgml: + * doc/tmpl/uri.sgml: + * doc/tmpl/utils.sgml: + * doc/tmpl/xfer.sgml: + + New templates... woo hoo. + +2002-06-16 Seth Nickell + + * doc/Makefile.am: + * doc/gnome-vfs-docs.sgml: + * doc/gnome-vfs-sections.txt: + * doc/tmpl/cancellable-ops.sgml: + * doc/tmpl/configuration.sgml: + * doc/tmpl/gnome-vfs-unused.sgml: + * doc/tmpl/handle.sgml: + * doc/tmpl/mime-magic.sgml: + * doc/tmpl/mime-sniff-buffer.sgml: + * doc/tmpl/module.sgml: + * doc/tmpl/process.sgml: + * doc/tmpl/uri.sgml: + * doc/tmpl/xfer.sgml: + + Remove some unused sections, add labels to others. + + * doc/writing-modules.txt: + + Remove since its outdated by the SGML version. + + * libgnomevfs/gnome-vfs-handle-private.h: + * libgnomevfs/gnome-vfs-handle.c: + * libgnomevfs/gnome-vfs-handle.h: + + Split handle into a type declaration and a GnomeVFS-internal + function declaration. The type needs to be installed (since + a number of ops use Handles) but the functions for manipulating + handles shouldn't be needed by either modules or library users. + + * libgnomevfs/gnome-vfs-cancellable-ops.c: + * libgnomevfs/gnome-vfs-file-info.c: + * libgnomevfs/gnome-vfs-file-info.h: + * libgnomevfs/gnome-vfs-method.c: + * libgnomevfs/gnome-vfs-mime-info.c: + * libgnomevfs/gnome-vfs-mime-magic.c: + * libgnomevfs/gnome-vfs-module.h: + * libgnomevfs/gnome-vfs-ops.c: + * libgnomevfs/gnome-vfs-result.c: (gnome_vfs_result_to_string): + * libgnomevfs/gnome-vfs-utils.c: + + Document a bunch of functions. + + * libgnomevfs/Makefile.am: + * libgnomevfs/check-headers.pl: + + Use noinst_HEADERS instead of including non-installed + headers in the source. This makes it easier to find headers + that should not be included in documentation. + + * libgnomevfs/gnome-vfs-types.h: + Remove deprecated header. + +2002-06-15 Seth Nickell + + * doc/tmpl/ops.sgml: + * doc/tmpl/uri.sgml: + * doc/tmpl/utils.sgml: + * libgnomevfs/gnome-vfs-file-info.h: + * libgnomevfs/gnome-vfs-init.c: + * libgnomevfs/gnome-vfs-mime-info.c: + * libgnomevfs/gnome-vfs-ops.c: + * libgnomevfs/gnome-vfs-ops.h: + * libgnomevfs/gnome-vfs-uri.c: + * libgnomevfs/gnome-vfs-uri.h: + * libgnomevfs/gnome-vfs-utils.c: + * libgnomevfs/gnome-vfs-utils.h: + * libgnomevfs/gnome-vfs-xfer.c: + + Document some 30 GnomeVFS functions, bringing our coverage to + a miserable 54%. + +2002-06-15 Seth Nickell + + * .cvsignore: + * libgnomevfs/.cvsignore: + + Don't pay attention to weird GOB crap. + + * test/test-metadata.c: (main): + + Oops, forgot a cvs add. + +2002-06-15 Seth Nickell + + * libgnomevfs/gnome-vfs-metadata.gob: + + Load XML properly using GnomeVFS rather than just from local files. + + * libgnomevfs/gnome-vfs-utils.c: (gnome_vfs_read_entire_file): + * libgnomevfs/gnome-vfs-utils.h: + + Add convenience function for reading in entire files (very useful for + use with libxml). + +2002-06-15 James Henstridge + + * modules/Makefile.am: link modules back against libgnomevfs-2.la + +2002-06-15 Seth Nickell + + * HACKING: + + Clarify checkin policies. + +2002-06-15 Seth Nickell + + Semi-working metadata code, landed as requested by commodore Yakk. + + * Makefile.am: + * configure.in: + + Add included GOB into the build. + + * libgnomevfs/Makefile.am: + + Build the metadata code, and install the header. + + * libgnomevfs/gnome-vfs.h: + + Pull in the metadata header. + + * libgnomevfs/gnome-vfs-metadata.gob: + * test/Makefile.am: + + The metadata code itself. + +2002-06-13 Alex Graveley + + * libgnomevfs/gnome-vfs-init.c (gnome_vfs_init): Always ensure + ~/.gnome exists before initializing. + (ensure_dot_gnome_exists): Create ~/.gnome if it does not exist. + +2002-06-13 Damon Chaplin + + * modules/file-method.c (do_find_directory): always use 0700 (S_IRWXU) + when creating trash directories outside of $HOME, so other users can't + see your files. Fixes bug #46475. + +2002-06-13 Glynn Foster + + * docs/vfolder-info-spec.dtd: Initial version of the vfolder-info + dtd. + +-------------------2.0.0------------------------ +2002-06-10 Seth Nickell + + * NEWS: + * configure.in: + + Release the big 2.0.0. + +Thu Jun 06 15:17:01 2002 George Lebl + + * modules/vfolder-desktop-method.c: some more monitors tinkering, + this time it makes file create and delete monitors work as they + should + +Thu Jun 06 14:34:30 2002 George Lebl + + * modules/vfolder-desktop-method.c: Actually return the method + handle on add and don't crash on NULL on cancel for file monitors. + +Thu Jun 06 14:16:27 2002 George Lebl + + * modules/vfolder-desktop-method.c: implement file monitors + as per the 2.0.0 bug #81670. The bug is not closed even though + it seems to be that we are emitting monitors correctly, but + nautilus isn't catching them. This also fixes some errors + in the directory monitors as well. + +2002-06-06 Jacob Berkman + + * modules/ssh-method.c: include + +Wed Jun 05 12:31:10 2002 George Lebl + + * modules/vfolder-desktop-method.c: implement directory monitors + as per the 2.0.0 bug #81670. Still not completely finished since + according to test-monitor we are getting changes, but nautilus + refuses to update. So I think there is some problem in nautilus, + perhaps it doesn't like the fact that it has dir monitors but + not file monitors? + +2002-06-05 Yanko Kaneti + + * configure.in: (ALL_LINGUAS) Added Bulgarian (bg). + +2002-06-04 Jody Goldberg + + * libgnomevfs/gnome-vfs-mime-info.c (reload_if_needed) : honour + gnome_vfs_is_frozen. + (gnome_vfs_is_frozen) : rename from should_write_file_back. + +2002-06-04 Kristian Rietveld + + * libgnomevfs/gnome-vfs-standard-callbacks.h: add + http:send-additional-headers and http:received-headers hooks. + + * modules/http-method.c (create_handle): invoke headers received + callback after receiving full header, + (make_request): invoke send additional headers callback and add + extra headers if needed, + (invoke_callback_headers_received): new function, + (invoke_callback_send_additional_headers): new function + +2002-06-03 Ian McKellar + + * modules/ssh-method.c: Big improvement to the ssh method from + Robert Migues + +2002-06-02 Alex Graveley + + * modules/desktop-method.c (do_get_file_info): Set mime_type to + "x-directory/vfolder-desktop", to allow launcher creation from + nautilus. + (do_get_file_info_from_handle): Ditto. + +Fri May 31 10:23:01 2002 George Lebl + + * modules/applications.vfolder-info.in, + modules/preferences.vfolder-info.in: Handle both kewords + 'Sawfish' and 'X-GNOME-Sawfish' to make a clear transition, + in case someone has an older install of sawfish. + +Thu May 30 17:11:04 2002 George Lebl + + * modules/preferences.vfolder-info.in: arghh! we have two places + where preference menus are defined. Ok fix the bug here as well. + +Thu May 30 17:04:48 2002 George Lebl + + * modules/applications.vfolder-info.in: don't put sawfish capplets + in the advanced dir fixes #77772 + +Thu May 30 10:03:03 2002 George Lebl + + * modules/vfolder-desktop-method.c: the directories are of type + x-directory/vfolder-desktop + +2002-05-28 Jody Goldberg + + * libgnomevfs/gnome-vfs-application-registry.c + (gnome_vfs_application_registry_init) : initialize before we load the + applications so that things do not loop. + +Tue May 28 15:04:17 2002 George Lebl + + * modules/vfolder-desktop-method.c: fix adding/removing of includes + to remove inconsistencies between the has and the list + +2002-05-27 Ian McKellar + + * configure.in: + Don't make libgnomevfs depend on libbonobo. It doesn't need it and + it isn't in the .pc file anyway. + +2002-05-26 Alex Graveley + + * configure.in (FAM_LIBS): Don't use C++ compiler to compile FAM + test, as the problem is really with a miscompiled libfam which + doesn't pull in the needed libstdc++.so, and hence won't link. + Removing as per alexl's suggestion on bug #80826. + +2002-05-24 Alex Graveley + + * modules/applications.vfolder-info.in: Remove explicit + cddb-capplet exclusion, so it will shot up in the Advanced + settings menu. Fixes bug #74767. + +2002-05-24 Jody Goldberg + + http://bugzilla.gnome.org/show_bug.cgi?id=80776 + * libgnomevfs/gnome-vfs-application-registry.c + (application_lookup_or_create) : make sure to load the app db before + trying to store something. + +2002-05-24 Seth Nickell + + * configure.in: + + Bump version number & release. + +2002-05-24 Seth Nickell + + * modules/vfolder-desktop-method.c: + (vfolder_info_read_items_merge): + + Add filters for the "Office" sub-directory (which KDE uses). + +2002-05-22 Alex Graveley + + * modules/desktop-method.c (do_monitor_add): Implement monitoring, + by registering a monitor with the parent method, and changing the + destination uri for events to start with the proper prefix for + this method before sending on to the real destination. + +2002-05-22 Alex Graveley + + * configure.in (FAM_MISSING_WARNING): Print a warning if FAM is + not found. + + * modules/file-method.c (fam_callback): Handle FAMEvent pathnames + that can be either relative or absolute. Clean up the code a + little as well. + +2002-05-20 Laszlo Peter + + * modules/vfolder-desktop-method.c: (VFOLDER_URI_PARSE): remove + unnecessary ( )'s that break the build on Solaris. + (do_create): basename is undefined, use vuri.file. + +Mon May 20 10:51:32 2002 George Lebl + + * modules/vfolder-desktop-method.c: make note if we have had a slash + on the end of a path, and in that case don't allow the 'file' + specific operations on it + +Mon May 20 10:41:17 2002 George Lebl + + * modules/vfolder-desktop-method.c: fix root path reading (case where + we read something like all-applications:/ rather then + all-applications: This fixes the panel run box and should fix + the rest of issues of #82187 + +2002-05-20 Alex Graveley + + * modules/vfolder-desktop-method.c (vfolder_uri_parse_internal): + Set file to start of path if there are no slashes. + +2002-05-20 Alex Graveley + + * modules/vfolder-desktop-method.c (vfolder_uri_parse_internal): + Set vuri->file to the basename of the URL, strip trailing slashes. + (resolve_folder): Simplify lookup as trailing slashes are now + stripped. + (get_entry_unlocked): Don't call any_subdir, just let the lookup + fail. + (get_entry_unlocked): Resolve optinal leading path for + all-applictions: + +2002-05-20 Mark McLoughlin + + * modules/vfolder-desktop-method.c: + (vfolder_uri_parse_internal): band aid for crasher. Work out + basename correctly. + (vfolder_desktop_dir_monitor), (vfolder_user_desktop_dir_monitor), + (do_open), (do_read_directory): remove debug info. + +2002-05-17 Alex Graveley + + * modules/vfolder-desktop-method.c (VFOLDER_URI_PARSE): New + macro/internal function to populate on-stack VFolderURI with + unescaped copy of vfs uri. Used throughout instead of + get_basename() and broken path handling. + +2002-05-17 Alex Graveley + + * libgnomevfs/gnome-vfs-xfer.c + (gnome_vfs_destination_is_writable): Handle + GNOME_VFS_ERROR_INVALID_URI when creating .vfs-write.tmp, and + assume writability. + +2002-05-17 Michael Meeks + + * test/test-mime.c (main): do a debug_shutdown. + + * test/mime-test-files/small-file: add as regression test, + causes the crash below. + + * libgnomevfs/gnome-vfs-mime-magic.c + (gnome_vfs_mime_try_one_magic_pattern): check vs. the + range_end + pattern_length, not the range_start + pattern_length, + otherwise for small files eg. 66 bytes and GnomeMagicEntry of + nautilus_link ( range_end == 256, pattern_length == 13), we + fairly soon segv in try_one_pattern_on_buffer. + +2002-05-17 Anders Carlsson + + * libgnomevfs/gnome-vfs-mime-magic.c: + (gnome_vfs_mime_try_one_magic_pattern): + Don't try to check the buffer if it's not long enough. + Fixes #82027, reported by Jacob Berkman. + +2002-05-16 Jody Goldberg + + * libgnomevfs/gnome-vfs-application-registry.c (application_sync) : + add some safety. Just in case. + +2002-05-16 Michael Meeks + + * libgnomevfs/gnome-vfs-mime-handlers.c + (gnome_vfs_mime_edit_user_file_full): don't dup (leak) + key and value. + + * modules/file-method.c (fam_callback): unref the + URI we create. + +2002-04-19 Mark McLoughlin + + * modules/http-method.c: (construct_gl_http_proxy), + (set_proxy_auth): split these methods out from + sig_gconf_value_changed. + (notify_gconf_value_changed): rename from + sig_gconf_value_changed + (vfs_module_init): don't use gconf_init. Also use + gconf_client_notify_add instead of the 'value-changed' signal + on GConfClient so that we don't get notified of other user + changes. + +2002-05-15 Mark McLoughlin + + * schema/system_http_proxy.schemas: set default for + all string keys so that the PropertyEditor doesn't + complain. + +2002-05-14 Seth Nickell + + * modules/applications.vfolder-info.in: + * modules/preferences.vfolder-info.in: + + Tweak merging so we don't get so much crap from GNOME 1.4 + +2002-05-14 Jody Goldberg + + From ali.akcaagac@stud.fh-wilhelmshaven.de (Ali Akcaagac) + http://bugzilla.gnome.org/show_bug.cgi?id=80826 + * configure.in : improve FAM test. + +Mon May 13 17:35:39 2002 Jonathan Blandford + + * modules/tarpet.h (TARPET_TYPE_FIFO): Modify to make match tar + documentation better. + +2002-05-13 Anders Carlsson + + * modules/applications.vfolder-info.in: + * modules/http-method.c: (strip_semicolon), (set_content_type), + (process_propfind_propstat): + Always try to strip off text after the semicolon when looking + for the mime type. Fixes #81561, reported by Rene Seindal. + +2002-05-12 Rachel Hestilow + + * modules/Makefile.am: + * modules/default-modules.conf: Add tar module. + + * modules/tar-method.c: + * modules/tarpet.h: + Added. Many thanks to Abi Brady for + her cleanroom tar header implementation. + + * docs/tarpet: Added: tar format documentation used for + cleanroom. + +2002-05-10 Naba Kumar + + * configure.in: Added "hi" to ALL_LINGUAS. + +Wed May 8 15:04:05 2002 Jonathan Blandford + + * Makefile.am: new supdir + * configure.in: Add GConf testing + * modules/cdda-method.c: Fix http proxy keys + * modules/http-method.c: ditto + * modules/ftp-method.c: ditto, though they seem to be effectively unused + * schemas/.cvsignore: shut up, cvs + * schemas/Makefile.am: Install new proxy schemas + * schemas/system_http_proxy.schemas: new proxy schemas + +2002-05-07 Seth Nickell + + * configure.in: + + Bump version number to 1.9.15 and release. + +2002-05-07 Seth Nickell + + * modules/vfolder-desktop-method.c: + (vfolder_info_read_items_merge): + + Inherit all keywords to lower level directories, allowing + nested directories (not common, but they exist) to figure + out their main category name unless they match a "closer" + category. + + Flag merged .desktop files with "Merged" so we can optionally + handle them specially in the vfolder. + + * modules/applications.vfolder-info.in: + + Merge "Merged" capplets into Advanced by default. + +2002-05-06 Seth Nickell + + * modules/vfolder-desktop-method.c: + (vfolder_info_read_items_merge), (vfolder_info_read_items): + + Handle knowledge of settings directory recursively so it covers + things like Settings/Sawfish too. + +2002-05-06 Seth Nickell + + * modules/applications.vfolder-info.in: + + Merge in .desktop files installed into /usr PREFIX. + + * modules/vfolder-desktop-method.c: + (vfolder_info_read_items_merge): + + Do not set "Applications" category flag on merged + .desktop files that come from the Settings directory. + + * modules/fstype.c: (fstype_internal_error): + + Fix the build. + +2002-05-03 David Emory Watson + + * libgnomevfs/gnome-vfs-uri.c: + (gnome_vfs_uri_extract_dirname): Should return URI_PATH_STR whenever + there is only one URI_PATH_CHR in the uri (and it occurs at the + begining), not just when the string equals URI_PATH_CHR. + * test/test-uri.c: + (test_uri_extract_dirname): New. + (main): Update. + +2002-05-03 jacob berkman + + * doc/Makefile.am $(TARGET_DIR): don't conflict with the gnome-vfs + 1 docs + +2002-05-02 Bastien Nocera + + * test/test-directory.c: (show_result): + print error before exiting + * test/vfs-test: new "all-in-one" automatic tester + +2002-05-02 Bastien Nocera + + * test/test-monitor.c: (timeout_cb), (callback), (main): + make the test be automatic, by exiting after 2 events, + add in an timeout function 1 file create and 1 file deletion + +2002-05-02 Bastien Nocera + + * test/test-mime-info.c: (main): fixup for current gnome2 + removed test for default_component_iid, change test for + gnome_vfs_mime_set_registered_type_key as the behaviour + change in gnome2 + +2002-05-02 James Henstridge + + * modules/fstype.c: get rid of some warnings that were preventing + it from compiling due to -Werror + +2002-05-01 Jody Goldberg + + * test/test-info.c (main) : add a test for is_local. + + * modules/Makefile.am : add fstype.c from gnu/findutils + + * modules/file-method.c (do_is_local) : implement. + + * configure.in : Add afs option and check for some utilities required + for the fstype code from gnu/findutils. + +2002-04-26 Jody Goldberg + + * libgnomevfs/gnome-vfs-application-registry.c (application_add_key) : + Store supported_uri_schemes as a key in addition to the internal + representation. + +Wed May 01 16:49:01 2002 George Lebl + + * modules/vfolder-desktop-method.c: reverted fix for #75150 and + fixed this correctly. Do not reload the entire info structure, + all we need to do is to invalidate the root folder. Also + in unrelated revert, g_build_filename already takes care of the '/'. + +Wed May 1 19:12:02 2002 Jonathan Blandford + + * libgnomevfs/gnome-vfs-mime-info.c: + (_gnome_vfs_mime_info_mark_gnome_mime_dir_dirty), + (_gnome_vfs_mime_info_mark_user_mime_dir_dirty), + (reload_if_needed), (gnome_vfs_mime_info_reload): Only reload the + data if it is needed to be reloaded. + + * libgnomevfs/gnome-vfs-mime-monitor.c: + (gnome_vfs_mime_monitor_init), (mime_dir_changed_callback), + (gnome_vfs_mime_monitor_finalize): Let the data know that it needs + to be reloaded. + + * libgnomevfs/gnome-vfs-mime-private.h: add + _gnome_vfs_mime_info_mark_gnome_mime_dir_dirty and + _gnome_vfs_mime_info_mark_user_mime_dir_dirty. + +2002-05-01 Stephen Browne + + * configure.in: + * modules/Makefile.am: + + Made compile of cdemenu module conditional on solaris. + +2002-04-30 Pablo Saratxaga + + * configure.in (ALL_LINGUAS): added Vietnamese (vi) + +2002-04-30 Stephen Browne + + * modules/Makefile.am + * modules/default-modules.conf + * modules/cdemenu-desktop-method.c + Added new 'read-only' module to read CDE (dtwmrc) menus. + This is used by the gnome-panel on Solaris systems. + +2002-04-29 Pablo Saratxaga + + * configure.in (ALL_LINGUAS): added Basque (eu) + +2002-04-29 Seth Nickell + + * configure.in: + + Bump version number to 1.9.14, release, rinse, repeat. + +Mon Apr 29 15:54:45 2002 Jonathan Blandford + + * libgnomevfs/gnome-vfs-mime-info.c: (gnome_vfs_mime_info_reload): + remove FIXME that's now fixed. + + * libgnomevfs/gnome-vfs-mime-monitor.c: + (gnome_vfs_mime_monitor_class_init), (gnome_vfs_mime_monitor_init), + (mime_dir_changed_callback), (gnome_vfs_mime_monitor_monitor_dir), + (gnome_vfs_mime_monitor_finalize), (gnome_vfs_mime_monitor_get), + (gnome_vfs_mime_monitor_get_type): Let the user know if any + directory we care about changes. + +2002-04-26 Benedikt Roth + + * modules/applications.vfolder-info.in: + Added entry for the Applications folder so that nautilus + will display applications:/// information in the sidebar (#72718). + Moved all before and added one to the + Accessibility folder. + + * modules/vfolder-desktop-method.c: (get_entry_unlocked): + If the user made a request for 'applications:' (which would fail) + use 'applications:/' to be consistent witch eg 'start-here:' (#75033) + + * modules/vfolder-desktop-method.c: (vfolder_info_recheck): + Fix monitoring of directories so that eg newly installed + .desktop files will show up. (#75150) + + * modules/vfolder-desktop-method.c: (vfolder_info_init), + (make_file_private): + Changed ~/.gnome2vfolders/ to ~/.gnome2/vfolders (#78065). + +2002-04-25 Jody Goldberg + + * libgnomevfs/gnome-vfs-application-registry.c + (cb_application_collect) : fix. + +2002-04-24 Iain + + * modules/preferences.vfolder-info.in: Allow the CDDB capplet in the + main menu. + +2002-04-24 Anders Carlsson + + * libgnomevfs/gnome-vfs-mime.c (add_to_key): + NULL out the key and list if we don't find the + extension. + +2002-04-22 Jody Goldberg + + * configure.in : post release version bump. + +2002-04-22 Jody Goldberg + + * Release 1.9.12 + +2002-04-22 Jody Goldberg + + * configure.in : bump version number in preparation for release. + +2002-04-21 Jody Goldberg + + * libgnomevfs/gnome-vfs-utils.c (gnome_vfs_icon_path_from_filename) : + See if this is an absolute path. + +2002-04-21 Jody Goldberg + + * libgnomevfs/gnome-vfs-application-registry.c + (gnome_vfs_application_registry_get_applications) : add a hook for the + file-type capplet such that passing NULL as the mime type returns + _all_ applications. + +2002-04-21 Anders Carlsson + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_do_short_list_processing), + (gnome_vfs_mime_get_short_list_applications), + (gnome_vfs_mime_get_short_list_components), + (gnome_vfs_mime_set_short_list_applications), + (gnome_vfs_mime_set_short_list_components), (copy_str_list), + (gnome_vfs_mime_maybe_get_user_level_value): + Don't look at the user level for components, just use + "short_list_component_iids". We do the same thing for + applications, except that we fall back to the advanced + user level if we don't find any items at first. + + * libgnomevfs/gnome-vfs-mime.c: (add_to_key): + Plug a memory leak. + +2002-04-16 Jody Goldberg + + * modules/file-method.c (do_monitor_cancel) : really cancel things. + +2002-04-12 Jody Goldberg + + * libgnomevfs/gnome-vfs-mime-info.c (set_value_real) : just use + g_hash_table_replace. Avoid double freeing memory. + +2002-04-10 Seth Nickell + + * modules/applications.vfolder-info.in: + + Hide search tool since it will be in actions (we'd + still like it to show up in non-gnome-panel situations + so we leave the .desktop file as installed) + + * modules/file-method.c: (do_monitor_cancel): + + Fix build warning. + +2002-04-02 Jody Goldberg + + * modules/file-method.c (fam_callback) : Alex pointed out the + Acknowledged event. I'll use that, it is much cleaner. + Ignore events that are tagged as cancelled, and delete cancelled + handlers when an ack comes in. + (do_monitor_add) : init cancelled. + (do_monitor_cancel) : watch out for double cancels. + +2002-04-06 Zbigniew Chyla + + * libgnomevfs/gnome-vfs-init.c (gnome_vfs_init): + Set textdomain's encoding to UTF-8 using bind_textdomain_codeset. + +2002-04-07 Michael Meeks + + * test/test-performance.c (main): upd. + + * libgnomevfs/gnome-vfs-mime-info.c + (context_new): use g_hash_table_new_full. + (context_add_key): make the logic more sane, + don't do stupid things keeping 'previous_key' + around, since it's always the same (current) key. + (load_mime_list_info_from, load_mime_type_info_from): + expunge previous_key inefficiency. + (load_mime_type_info_from): don't keep dupping stuff + we don't need to, instead build the several strings + we need in the GString. + (load_mime_list_info_from): ditto. + (release_key_and_value): kill. + (context_destroy): upd. + use g_string_insert_c instead of append_char. + (load_mime_type_info_from): rename to + (load_type_info_from): and unify from giant ugly cut and paste + (load_mime_list_info_from): kill junk. + use defines to map to old names. + (load_type_info_from): ignore lines that don't have the + right lang before doing much slower parsing on them. + +2002-03-30 Jody Goldberg + + http://bugzilla.gnome.org/show_bug.cgi?id=71391 + * modules/file-method.c (do_monitor_cancel) : add a comment + explaining the issue here. + (fam_callback) : and here. Then patch the problem by not accessing + the uri unless we really need to. + +2002-03-31 Murray Cumming + + * monikers/bonobo-stream-fs.c & monikers/bonobo-stream-vfs.c: + Changed use of e.g. Bonobo_Stream_SEEK_CUR to + Bonobo_Stream_SeekCur, due to recent change in libbonobo. + +2002-03-28 Kevin Vandersloot + + * modules/http-method.c: bind to the "value_changed" gconf + signal for the proxy settings so that changes made by the user + are updated instantly. Fixes bug # 73578 incidentally. + +2002-03-27 Seth Nickell + + * configure.in: + + Bump version number to 1.9.11 + +2002-03-27 Seth Nickell + + * modules/applications.vfolder-info.in: + + Add accesibility category to applications: too. + +2002-03-25 Seth Nickell + + * modules/applications.vfolder-info.in: + + Change "Applications" to "Other", since lots of people are seeing this + category and its weird to have Applications->Applications. + +2002-03-18 Jody Goldberg + + * modules/preferences.vfolder-info.in : add an Accessibility category. + +Fri Mar 22 11:13:30 2002 Owen Taylor + + * test/test-async.c (main): Fix includes and + g_type_init (0) [ g_type_init() hasn't taken + arguments for a long time. ] + +2002-03-22 jacob berkman + + * modules/extfs/Makefile.am (extfsdir): + * modules/extfs-method.c (EXTFS_COMMAND_DIR): move into a 2.0 + subdirectory for parallel install + +2002-03-14 Seth Nickell + + * HACKING: + * configure.in: + + Build sherrif commits, bump version number to deal with + tarball that built wrong. + +2002-03-11 James Henstridge + + * configure.in: shell doesn't need semicolons to terminate + statements. In fact it can be harmful if an m4 expansion leaves a + semicolon on a line alone, as that is a syntax error. + +2002-03-09 Darin Adler + + * test/.cvsignore: Ignore test-performance. + +2002-03-08 Seth Nickell + + * configure.in: + + Release 1.9.9 + +2002-03-08 Seth Nickell + + * modules/applications.vfolder-info.in: + + Update applications vfolder for capplet movement too. + +2002-03-05 jacob berkman + + * modules/preferences.vfolder-info.in: the capplets apparently + moved + +2002-02-25 Laszlo Peter + + * modules/file-method.c: (do_read_directory): work around a Solaris + bug where readdir64_r returns -1 instead of 0 at EOF. + +2002-02-25 Hasbullah Bin Pit + + * configure.in: REALLY Added ms (Malay) at ALL_LINGUAS. + +2002-02-25 Seth Nickell + + * NEWS: + * configure.in: + + Release 1.9.8 + +2002-02-23 Andy Hertzfeld + + * modules/nntp-method.c: (do_basic_command), (get_auth_info), + (get_files_from_newsgroup), (add_file_to_folder), + (do_get_file_info), (do_open_directory): + added password interrogation when necessary, using the standard + gnome-vfs facilities. Also, added some checks to avoid crashing + with badly formed urls. + + * modules/default-modules.conf: + removed the "news" protocol variant since it's supposed to get the + servername from preferences; I'll put it back when that's implemented + +2002-02-20 Seth Nickell + + * modules/applications.vfolder-info.in: + * modules/preferences.vfolder-info.in: + + more minor tweaks + +2002-02-20 Michael Meeks + + * test/test-performance.c: add. + + * test/Makefile.am: upd. + + * libgnomevfs/gnome-vfs-mime-info.c + (fast_file_getc, fast_file_open, fast_file_close): impl. + (hack_getc): expunge the crack smoking evil. + (load_mime_type_info_from), + (load_mime_list_info_from): adapt to not need + hack_getc, these parsers sucked - they couldn't cope with + two lines starting with '#', remove need for ungetc. + switch to the faster read methods. + + * test/test-shell.c: dump the mime type. + +Tue Feb 19 17:11:41 2002 George Lebl + + * tests/test-monitor.c: when printing out value of a pointer use + %p and not %d to fix compilation on alpha + +2002-02-18 Seth Nickell + + * libgnomevfs/gnome-vfs-mime-magic.c: + (gnome_vfs_sniff_buffer_looks_like_gzip): + * libgnomevfs/gnome-vfs-mime.c: (gnome_vfs_get_mime_type_internal): + + Prioritize suffix matching over gzip sniffing. Not + very elegant, but the number of gzip'd documents misidentified + as gzip files far exceeds the number of improperly suffixed + gzip files. + + * modules/applications.vfolder-info.in: + * modules/preferences.vfolder-info.in: + + Minor menu tweaks. + +2002-02-17 Alexander Larsson + + * modules/vfolder-desktop-method.c (vfolder_info_insert_entry): + Use g_hash_table_replace instead of g_hash_table_insert, so we don't + keep a pointer to the old key which eventually got freed. + Seems to fix a startup segfault in the panel. + +2002-02-14 Tõivo Leedjärv + + * configure.in: Added et to ALL_LINGUAS. + +2002-02-12 Morten Welinder + + * libgnomevfs/gnome-vfs-method.h, libgnomevfs/gnome-vfs-job.h, + libgnomevfs/gnome-vfs-mime.h, gnome-vfs-parse-ls.h: Fix Solaris + compile. + +2002-02-11 Seth Nickell + + * NEWS: + * configure.in: + + Release 1.9.7 + +2002-02-08 Mark McLoughlin + + * modules/vfolder-desktop-method.c: + (invalidate_folder_T): impl lock taken version. + (invalidate_folder): split out subfolder stuff to + (invalidate_folder_subfolders): here. + (do_close): use _T here to avoid deadlock. + +2002-02-09 Darin Adler + + * libgnomevfs/gnome-vfs-file-info.h: Oops. Missed that inode + numbers also are 64 bits when _FILE_OFFSET_BITS=64. + +2002-02-09 Bastien Nocera + + reviewed by: Darin Adler + + * configure.in: check for bzlib.h, bomb if it's not there + * modules/Makefile.am: use BZ2_LIBS and CDDA_LIBS defines + +2002-02-09 Jon K Hellan + + * configure.in: s/OPENSSL_LDFLAGS/OPENSSL_LIBS/ + +2002-02-09 Darin Adler + + Fix some 64-bit problems by setting flags properly. + + * libgnomevfs/Makefile.am: + * modules/Makefile.am: + GNOME_VFS_CONFDIR -> SYSCONFDIR + GNOME_VFS_DATADIR -> DATADIR + GNOME_VFS_PREFIX -> PREFIX + Define _FILE_OFFSET_BITS=64; needed to get large file + sizes from stat. + Define _BSD_SOURCE; previous defined in some source files, + but it does no harm to define it consistently. + Define _LARGEFILE64_SOURCE; previously defined in some + source files, but affects the stat structure, so needs to + be consistent across more files. + + * libgnomevfs/gnome-vfs-application-registry.c: + (gnome_vfs_application_registry_init): GNOME_VFS_DATADIR -> DATADIR + * libgnomevfs/gnome-vfs-mime-info.c: (gnome_vfs_mime_init): + GNOME_VFS_DATADIR -> DATADIR + * libgnomevfs/gnome-vfs-mime-magic.c: Remove the _BSD_SOURCE define + now that it's handled on the command line. + (gnome_vfs_mime_get_magic_table): GNOME_VFS_CONFDIR -> SYSCONFDIR + * libgnomevfs/gnome-vfs-mime.c: (mime_init): GNOME_VFS_DATADIR -> + DATADIR + * libgnomevfs/gnome-vfs-module-shared.c: Remove the _BSD_SOURCE and + _LARGEFILE64_SOURCE defines, not that they are handled on the + command line. + * libgnomevfs/gnome-vfs-module-shared.h: Add a check so that we fail + to compile if there are incompatibilities in the definition of the + stat structure. + * libgnomevfs/gnome-vfs-utils.c: + (gnome_vfs_icon_path_from_filename): GNOME_VFS_PREFIX -> PREFIX + * modules/file-method.c: Remove the _LARGEFILE64_SOURCE define, now + that it's handled on the command line. + +2002-02-05 Havoc Pennington + + * configure.in (HAVE_OPENSSL): don't AC_SUBST OPENSSL_CFLAGS + OPENSSL_LIBS; don't put -L/usr/lib in the ldflags, only + /otherplace/lib. Put OPENSSL_CFLAGS OPENSSL_LIBS in + LIBGNOMEVFS_CFLAGS LIBGNOMEVFS_LIBS + + * libgnomevfs/Makefile.am (INCLUDES, libgnomevfs_2_la_LIBADD): + remove OPENSSL_* variables from makefile; instead merge them on + configure script level. + +2002-02-04 Seth Nickell + + * NEWS: + * configure.in: + + Release 1.9.6 + +2002-02-02 Seth Nickell + + * modules/applications.vfolder-info.in: + + Start re-arranging categories. + +Fri Feb 01 16:54:02 2002 George Lebl + + * modules/vfolder-desktop-method.c: correctly save DontShowIfEmpty + +2002-01-31 John Harper + + * libgnomevfs/Makefile.am: install gnome-vfs-cancellable-ops.h + in the module-only header directory + +2002-01-31 Jeff Waugh + + * gnome-vfs-2.0.pc.in: + * gnome-vfs-module-2.0.pc.in: + + Fix specifics in pc.in files for 'non-standard' builds. + Permission from Seth to commit. + +2002-01-30 Seth Nickell + + * NEWS: + + Update news. + + * configure.in: + + Bump version number to 1.9.5 + +2002-01-29 Seth Nickell + + * libgnomevfs/gnome-vfs-monitor.c: (gnome_vfs_monitor_do_add): + * test/test-monitor.c: (main): + + Fix a bug in the monitor code... wasn't returning the method + handle (oops!). + + * modules/applications.vfolder-info.in: + * modules/preferences.vfolder-info.in: + * modules/vfolder-desktop-method.c: (invalidate_folder), + (do_monitor_add): + + Add rudimentary monitoring support to the vfolder method. + Its currently wildly overzealous (basically notifies + everyone anytime anything changes), but the menu structure + shouldn't be jumping around that often, and rereading the + entire menu structure ain't that costly. + + Currently doesn't work for deletions. + +2002-01-28 Seth Nickell + + * modules/applications.vfolder-info.in: + * modules/preferences.vfolder-info.in: + + More exciting updates to the vfolders. + +2002-01-28 Darin Adler + + * gnome-vfs.spec.in: Remove man page. + +2002-01-28 Darin Adler + + * libgnomevfs/gnome-vfs-configuration.c: + (gnome_vfs_configuration_get_module_path): Patch from + Alvaro Lopez Ortega to fix crash + instead of warning when configuration is not set up. + + * modules/nntp-method.c: Misc. cleanup. + +2002-01-27 Seth Nickell + + * modules/applications.vfolder-info.in: + * modules/preferences.vfolder-info.in: + + And Systems folder for XST. + +2002-01-27 Seth Nickell + + * modules/preferences.vfolder-info.in: + + Add Advanced folder. + +2002-01-27 Seth Nickell + + * modules/applications.vfolder-info.in: + + Change where we look for capplets. + +2002-01-27 Seth Nickell + + * modules/preferences.vfolder-info.in: + + Change where we look for capplets. + +2002-01-27 Anders Carlsson + + * libgnomevfs/gnome-vfs-xfer.c (gnome_vfs_xfer_delete_items): Call + count_Items_and_size with move set to FALSE. Fixes #46777. + Approved by Seth Nickell. + +2002-01-22 jacob berkman + + * man/: + * configure.in (AC_OUTPUT): + * Makefile.am (SUBDIRS): remove man page + +2002-01-21 Alexander Larsson + + * modules/file-method.c (monitor_setup): + Fix deadlock when fam connection failed twice. + +2002-01-21 jacob berkman + + * modules/Makefile.am (libnntp_la_SOURCES): include nntp-method.h + +2002-01-20 Seth Nickell + + * modules/Makefile.am: + * modules/default-modules.conf: + * modules/nntp-method.c: (nntp_response_to_vfs_result), + (read_response_line), (get_response), (do_control_write), + (nntp_connection_reset_buffer), (do_basic_command), + (nntp_connection_create), (nntp_connection_destroy), (my_str_hash), + (my_str_equal), (nntp_connection_uri_hash), + (nntp_connection_uri_equal), (nntp_connection_acquire), + (nntp_connection_release), (is_number_or_space), + (all_numbers_or_spaces), (remove_numbers_between_dashes), + (remove_number_at_end), (trim_nonalpha_chars), + (remove_of_expressions), (filter_folder_name), (remove_commas), + (is_number), (parse_date_string), (parse_header), + (nntp_fragment_new), (nntp_fragment_destroy), (map_slashes), + (nntp_file_new), (nntp_file_destroy), (nntp_file_look_up_fragment), + (nntp_file_get_total_size), (nntp_file_add_part), (look_up_file), + (start_loading_article), (uu_decode_text), (base_64_map), + (base_64_decode_text), (line_in_decode_range), (load_from_article), + (load_file_fragment), (bytes_in_buffer), (copy_bytes_from_buffer), + (nntp_file_read), (free_nntp_file_list), + (get_files_from_newsgroup), (strip_slashes), + (extract_newsgroup_and_filename), (nntp_file_from_uri), + (has_all_fragments), (add_file_fragment), (remove_partial_files), + (update_file_sizes), (add_file_to_folder), (remove_file_from_list), + (remove_contained_files), (calculate_folder_mod_date), + (generate_folder_from_element), (generate_folders), + (destroy_element), (destroy_folder_hash), (assemble_folders), + (assemble_files_from_overview), (do_is_local), + (prepare_to_read_file), (do_open), (do_close), (do_read), + (do_get_file_info), (do_get_file_info_from_handle), + (do_open_directory), (do_close_directory), (do_read_directory), + (do_check_same_fs), (vfs_module_init), (vfs_module_shutdown): + * modules/nntp-method.h: + + Port of Andy's NNTP module from GnomeVFS1. + +2002-01-19 Hasbullah Bin Pit + + * configure.in: Added ms (Malay) at ALL_LINGUAS. + * po/ms.po: Added Malay Translation by + Mohamad Afifi Omar (App) and me.. + +Thu Jan 17 16:31:31 2002 George Lebl + + * modules/vfolder-desktop-method.c: Fix some memory leaks and + fix memory corruption when duplicate filenames are found + +2002-01-17 Darin Adler + + * libgnomevfs/gnome-vfs-async-ops.h: Remove unneeded includes. + * libgnomevfs/gnome-vfs-init.h: Remove unneeded includes. + * libgnomevfs/gnome-vfs-mime-handlers.h: Remove unneeded includes. + + * libgnomevfs/gnome-vfs-mime-handlers.c: Add includes. + +2002-01-17 Darin Adler + + * libgnomevfs/gnome-vfs-mime.h: Removed all sorts of extra + include statements that somehow got in here. + + * libgnomevfs/gnome-vfs-mime.c: + * modules/ftp-method.c: + * modules/pipe-method.c: + * modules/translate-method.c: + * test/test-mime.c: + Added includes as necessary to files that were depending on + the extra includes. + +Thu Jan 17 01:55:23 2002 George Lebl + + * modules/vfolder-desktop-method.c: Fix open_directory with + NULL path and treat it just like "/". Also a ref fix in + insert_entry (probably just being anal though) + +2002-01-17 Anders Carlsson + + * test/test-mime.c (main): Ugh, don't try to free argv. + +Fri Jan 11 02:22:26 2002 George Lebl + + * modules/vfolder-desktop-method.c: define structure fields for + monitors, start support for monitoring the desktop_dir's and + use .gnome2 and not .gnome for user vfolder storage + +Thu Jan 10 23:17:41 2002 George Lebl + + * modules/file-method.c: don't do g_warning on the last 4 fam events, + they do come (except for FAMMoved) this was causing everything + to spew tons of warnings + + * modules/default-methods.conf: fix for all-applications: and add + all-preferences: + +Thu Jan 10 11:12:24 2002 Owen Taylor + + * libgnomevfs/Makefile.am (libgnomevfs_2_la_LIBADD): Reorder + to get -ldl in the right place wrt. OPENSSL libs. (Probably + irrelevant) + + * configure.in (HAVE_OPENSSL): Omit -ldl here, since we have + it already from gmodule. + +Tue Jan 08 23:28:27 2002 George Lebl + + * test/test-shell.c: make things run in a main loop so that we can + test things that require it (such as the vfolder monitoring) + + * modules/vfolder-desktop-method.c: make threadsafe (hopefully), + add ctime/mtime for most entries (somewhat fake for directories, + but good enough for noticing changes). When we notice a change + there is a hack so that we read in stuff about 200ms later (this + is a HACK! but it makes it work for now). Fix moving files. + +2002-01-04 Havoc Pennington + + * modules/http-method.c (vfs_module_init): preload the GConfClient + cache, since we immediately get all the values from it. + +2002-01-03 Darin Adler + + * libgnomevfs/gnome-vfs-xfer.c: (move_items), (link_items): + Update count when moving and linking too. Not 100% sure this + makes the count perfect, but it shoudl be better than before. + +Wed Jan 02 20:45:09 2002 George Lebl + + * modules/vfolder-desktop-method.c: organize a todo/fixme list + at the top of the file. Implement vfolder file rereading. + Implement stating of things that we can't monitor otherwise. + So that we notice changes on disk. This stuff is now mostly + finished, modulo the .directory files. Though this is not + well tested yet. + +Sun Dec 30 01:40:40 2001 George Lebl + + * modules/vfolder-desktop-method.c: Start working on monitoring. For + now it monitors the item directories for added directories plus + there is a few more FIXMEs around. There are still many open + questions of how to do things without being a slow pig. For + example we need to update at least somewhat if there are is no fam + around as well. + +2001-12-16 Duarte Loreto + + * configure.in: Added Portuguese locale to ALL_LINGUAS. + +2001-12-15 Ross Golder + + * gnome-vfs.spec.in (Name): was gnome_vfs, now @PACKAGE@. + * configure.in: Updated RPM dependency versions + +2001-12-12 Michael Meeks + + * libgnomevfs/gnome-vfs-mime-handlers.c + (unref_gconf_engine): kill. + (get_user_level): kill atexit handler & use the gconf_client + API instead of the gconf_engine one. + +2001-12-14 Seth Nickell + + * modules/applications.vfolder-info.in: + + Rename Settings folder to Preferences. + +2001-12-14 Seth Nickell + + * modules/preferences.vfolder-info.in: + + Fix stupid typo that was breaking substitution + of @datadir@ + +2001-12-14 Seth Nickell + + * modules/Makefile.am: + * modules/default-modules.conf: + * modules/desktop-method.c: (vfs_module_init): + * modules/preferences.vfolder-info.in: + + Switch the "preferences:/" URI over to using the vfolder + method and create a vfolder for preferences. + +2001-12-14 Seth Nickell + + * modules/Makefile.am: + * modules/applications.vfolder-info.in: + * modules/default-modules.conf: + * modules/programs.vfolder-info.in: + + Change from "programs:/" to "applications:/" + +2001-12-05 ERDI Gergo + + * libgnomevfs/gnome-vfs-context.h: balance G_END_DECLS with + G_BEGIN_DECLS + +Sun Dec 02 11:55:57 2001 George Lebl + + * modules/vfolder-desktop-method.c, modules/programs.vfolder-info.in: + change the Unallocated query type to an OnlyUnallocated flag on + the folder. This way we can have multiple onlyunallocated folders, + though that may lead to some operations not being very efficent. + Also it fixes some ugly corner cases with that being a query type + and cleans up the code somewhat. Also write all 3 folder flags + to disk when writing the user vfolder-info file. + + * test/test-shell.c: when getting file info, always get the mime + type. + +Wed Nov 28 13:16:06 2001 George Lebl + + * modules/vfolder-desktop-method.c: Fix set_file_info, fix + a few leaks, some possible crashes, and add cancellation + checks to a bunch of places (not everywhere yet) + +2001-11-28 Seth Nickell + + * modules/vfolder-desktop-method.c: (get_entry), + (desktop_uri_to_file_uri), (do_open): + + Track down a couple bugs that were preventing + .directory files from being read... Folders should + now have directory info... woo hoo! + + * modules/programs.vfolder-info.in: + + Add specs to all folders. + +2001-11-28 Seth Nickell + + * modules/programs.vfolder-info.in: + + Add specification + +2001-11-27 Seth Nickell + + * modules/programs.vfolder-info.in: + + And Unallocated query works! :-) + + Turn it on for the Applications folder. + +Tue Nov 27 20:06:00 2001 George Lebl + + * modules/vfolder-desktop-method.c: add the Unallocated query. + that is a special query which can only be used once in a + vfolder-info file which matches all the elsewhere unallocated + items. + +2001-11-27 Seth Nickell + + * modules/vfolder-desktop-method.c: (readitem_entry): + + Fix incorrect boolean comparison, makes readitem_entry + actually work. + +2001-11-27 Seth Nickell + + * modules/vfolder-desktop-method.c: + (vfolder_info_read_items_merge): + + Change "Utility" to "Utilities" looking for + vfolders based on current location. + +2001-11-27 Seth Nickell + + * George Lebl + + Give him a hug. + + * modules/programs.vfolder-info.in: + + Use on standard folders + except for Settings. If there's nothing in + Settings, its an actual problem, and we + shouldn't just have the folder disappear. + + +Tue Nov 27 16:55:34 2001 George Lebl + + * modules/vfolder-desktop-method.c: implement ReadOnly and + DontShowIfEmpty flags on folders and a ReadOnly flag on + the main info xml tree. + +2001-11-27 Seth Nickell + + * modules/programs.vfolder-info.in: + + Add/Remove/Rename categories to comply with current + HIG spec. + +Mon Nov 26 21:52:01 2001 George Lebl + + * modules/vfolder-desktop-method.c: always avoid mime-type checks + on real file and just force the right mime types. If a scheme + starts with 'all-', then this is just a flat listing of all + the .desktops in that scheme. And fix a leak or two. + + * modules/default-modules.conf: add all-programs: scheme for + vfolder-desktop-method + +2001-11-26 Seth Nickell + + * NEWS: + + Update news... + +2001-11-26 Seth Nickell + + * configure.in: + + Bump version to 1.9.4, tag, release (rinse repeat). + +2001-11-22 Seth Nickell + + * doc/gnome-vfs-docs.sgml + + Add reference to section on "installing MIME data" + + * doc/installing-mime-data.sgml + + Blurb moved from the HIG. + +2001-11-21 Wang Jian + + * configure.in(ALL_LINGUAS): Added zh_CN for Simplified Chinese. + +Tue Nov 20 19:32:11 2001 Owen Taylor + + * configure.in (FAM_LIBS): Add some more quoting that + is needed for some autoconf versions. + + * libgnomevfs/gnome-vfs-mime-monitor.c: Remove gobject/gsignal.h. + +2001-11-18 Miles Lane + + * libgnomevfs/gnome-vfs-mime-monitor.h: + replace include of gobject/gobject.h + with glib-object.h, due to a change in gobject/gobject.h + that forces an #error for all direct includes. + This checkin was approved by Havoc. + +2001-11-13 Frederic Crozat + + * configure.in: + + Fix default detection of OpenSSL libraries + + +2001-11-08 Maciej Stachowiak + + * libgnomevfs/gnome-vfs-helpers.c, + libgnomevfs/gnome-vfs-helpers.h, libgnomevfs/Makefile.am: Removed + because we don't want to lock in this messy API and there is no + time for proper cleanup. Some eel functions will probably migrate + to gnome-vfs later. + +2001-11-06 Maciej Stachowiak + + * libgnomevfs/Makefile.am: Make gnome-vfs-mime.h a module header + again. + + * libgnomevfs/gnome-vfs-mime-utils.h: New public header. + * libgnomevfs/gnome-vfs-mime-handlers.h: Include + gnome-vfs-mime-utils.h + + * libgnomevfs/gnome-vfs-mime.h, libgnomevfs/gnome-vfs-mime.c: + Rename gnome_vfs_get_mime_type to + gnome_vfs_get_mime_type_common. Add new gnome_vfs_get_mime_type + function which takes a string URI and uses gnome_vfs_get_file_info + under the covers. + +2001-11-05 Seth Nickell + + * doc/tmpl/gnome-vfs-unused.sgml: + * libgnomevfs/Makefile.am: + + Make gnome-vfs-mime-monitor.h a public header. + + Make gnome-vfs-mime.h a public header, maybe only + temporarily but a number of the functions declared + here should be public. For now just make sure we + aren't breaking Nautilus needlessly. + +2001-11-05 Maciej Stachowiak + + * test/test-shell.c: Add a header now needed due to the below + changes. + * doc/tmpl/gnome-vfs-unused.sgml: More mystery changes. + +2001-11-05 Maciej Stachowiak + + * libgnomevfs/check-headers.pl: New script to check that module + API headers do not include private headers, and public headers do + not include private or module API headers. + + * libgnomevfs/Makefile.am: Run check-headers.pl on `make check'. + + * libgnomevfs/Makefile.am, + libgnomevfs/gnome-vfs-cancellable-ops.c, + libgnomevfs/gnome-vfs-context.h, libgnomevfs/gnome-vfs-handle.c, + libgnomevfs/gnome-vfs-handle.h, libgnomevfs/gnome-vfs-method.h, + libgnomevfs/gnome-vfs-ops.h, libgnomevfs/gnome-vfs-types.h, + libgnomevfs/gnome-vfs-uri.c, libgnomevfs/gnome-vfs.h: Fix problems + found by check-headers.pl + + * doc/tmpl/gnome-vfs-unused.sgml: the mystery of gtk-doc strikes + again. + +2001-11-03 Darin Adler + + * .cvsignore: Ignore gnome-vfs-module-2.0.pc. + +2001-11-02 Maciej Stachowiak + + * NEWS, configure.in: Updated for 1.9.3. + +2001-11-02 Maciej Stachowiak + + * libgnomevfs/Makefile.am: Fix module header install location. + + * Makefile.am, configure.in: install gnome-vfs-module-2.0.pc (I + think Darin made the same changes, but I forgot to commit, too + tired to untangle it now) + +2001-11-02 Darin Adler + + * configure.in: We need to generate gnome-vfs-module-2.0.pc, if + we're going to install it. Sorry for the 3 check-ins in a row. + +2001-11-02 Darin Adler + + * Makefile.am: Oops. ".pc" not ".pc.in". + +2001-11-02 Darin Adler + + * Makefile.am: Install gnome-vfs-module-2.0.pc. + * libgnomevfs/gnome-vfs.h: One file was out of alphabetical order. + +2001-11-02 Maciej Stachowiak + + * NEWS, configure.in: Updated for 1.9.2. + +2001-11-02 Maciej Stachowiak + + * libgnomevfs/gnome-vfs-uri.h, libgnomevfs/gnome-vfs-uri.c: Remove + gnome_vfs_get_basename, fixing bug 40822 + + Remove a bunch of uses of gnome_vfs_uri_get_basename and replace + mostly with extract_short_path_name. All appeared to be buggy as + written! + + * libgnomevfs/gnome-vfs-mime.c: + (gnome_vfs_get_mime_type_from_uri_internal), + (gnome_vfs_get_mime_type): + * libgnomevfs/gnome-vfs-xfer.c: (gnome_vfs_xfer_private): + * modules/cdda-method.c: (cdda_set_file_info_for_root), + (get_track_index_from_uri), (do_open), (is_file_is_on_disc), + (do_get_file_info), (do_open_directory), (get_data_size_from_uri): + * modules/nfs-method.c: (fhandle_recurse_lookup), (nfs_create), + (nfs_export_list), (do_get_file_info), + (do_get_file_info_from_handle), (nfs_mkdir), (nfs_rmdir), + (nfs_unlink), (nfs_rename): + * modules/vfolder-desktop-method.c: (get_basename, do_create, + do_move, do_unlink): + + * doc/tmpl/gnome-vfs-unused.sgml, doc/tmpl/process.sgml, + doc/tmpl/uri.sgml: gtk-doc works its magic. + +2001-11-02 Maciej Stachowiak + + * libgnomevfs/Makefile.am: Move a few more headers into the module + API. + +2001-11-02 Seth Nickell + + * Makefile.am: + + Build gnome-vfs-module-2.0.pc + + * libgnomevfs/Makefile.am: + + Start splitting header files between private, public and module + includes. + + * gnome-vfs-module-2.0.pc.in: + + Add a new .pc file for modules. + +2001-11-02 Maciej Stachowiak + + * doc/Makefile.am: Ignore new private headers in libgnomevfs + directory. + +2001-11-02 Maciej Stachowiak + + * Makefile.am: + * configure.in: + * doc/tmpl/gnome-vfs-unused.sgml: + * libgnomevfs-pthread/Makefile.am: + * libgnomevfs-pthread/gnome-vfs-async-job-map.c: + * libgnomevfs-pthread/gnome-vfs-async-job-map.h: + * libgnomevfs-pthread/gnome-vfs-async-ops.c: + * libgnomevfs-pthread/gnome-vfs-job-queue.c: + * libgnomevfs-pthread/gnome-vfs-job-queue.h: + * libgnomevfs-pthread/gnome-vfs-job-slave.c: + * libgnomevfs-pthread/gnome-vfs-job-slave.h: + * libgnomevfs-pthread/gnome-vfs-job.c: + * libgnomevfs-pthread/gnome-vfs-job.h: + * libgnomevfs-pthread/gnome-vfs-pthread.c: + * libgnomevfs-pthread/gnome-vfs-pthread.h: + * libgnomevfs-pthread/gnome-vfs-thread-pool.c: + * libgnomevfs-pthread/gnome-vfs-thread-pool.h: + * libgnomevfs/Makefile.am: + * libgnomevfs/gnome-vfs-async-ops.c: + * libgnomevfs/gnome-vfs-init.c: + * test/test-async-cancel.c: + * test/test-queue.c: Move contents of libgnomevfs-pthread into + libgnome-vfs. + + * modules/Makefile.am, modules/default-modules.conf, + modules/gconf-method.c, modules/gconf-method.h: Remove gconf + method. + +2001-11-01 Seth Nickell + + * data/mime/WHERE_IS_THE_MIME_REGISTRY?: + + Add file informing the unwashed of the new location + of the registry. + + * check-mime.pl: + * data/Makefile.am: + * data/mime/ChangeLog: + * data/mime/Makefile.am: + * data/mime/gnome-vfs-mime-magic: + * data/mime/gnome-vfs.applications: + * data/mime/gnome-vfs.keys.in: + * data/mime/gnome-vfs.mime: + + Remove the mime registry. + + * Makefile.am: + * configure.in: + * gnome-vfs.spec.in: + + Remove references to the mime registry. + + * doc/tmpl/gnome-vfs-unused.sgml: + + Apparently gtk-doc had some changes it wanted + to make, don't look at me ;-) + +2001-10-30 Laszlo Peter + * libgnomevfs/gnome-vfs.h: remove duplicated include line + +2001-10-29 jacob berkman + + * libgnomevfs/gnome-vfs-i18n.h (_): use GETTEXT_PACAKGE + + * configure.in: set GETTEXT_PACKAGE and use AM_GLIB_GNU_GETTEXT + + * acconfig.h: add GETTEXT_PACAKGE + +2001-10-27 jacob berkman + + * libgnomevfs/gnome-vfs-async-ops.h: + * libgnomevfs-pthread/gnome-vfs-async-ops.c: + * libgnomevfs-pthread/gnome-vfs-job-queue.c: rename + GNOME_VFS_*_PRIORITY to GNOME_VFS_PRIORITY_* + +2001-10-26 Laszlo Peter + + * modules/vfolder-desktop-method.c: fix undefined symbol. + +2001-10-24 Havoc Pennington + + * modules/file-method.c (get_stat_info): fix memory leak of + file_info->symlink_name for multiply-nested symlinks, and avoid + infinite loop for symlink cycles. Bug #62494 + +Mon Oct 22 23:18:38 2001 George Lebl + + * modules/vfolder-desktop-method.c: fix reading of keywords, + preserve implicit keywords on privatize, reread keywords + after we changed the file, when keywords may have changed, + invalidate the entire directory strucutre. + +Mon Oct 22 21:47:00 2001 George Lebl + + * modules/vfolder-desktop-method.c: fix creation of files, fix usage + of basenames, fix long moving, don't write vfolder more then once on + long move, fix quick moves. Actually this makes moves actually + work. Also add some FIXMEs which I didn't think of before. + +Mon Oct 22 19:01:21 2001 George Lebl + + * modules/vfolder-desktop-method.c: implement long_move and folder + move + +Mon Oct 22 19:10:57 2001 George Lebl + + * modules/test-method.c: add includes for sys/time and sys/types + +Sun Oct 21 16:14:33 2001 George Lebl + + * modules/vfolder-desktop-method.c: implement saving of the vfolder + info, and fix locations for saving per-user files. + +2001-10-21 Gregory Leblanc + + * gnome-vfs.spec.in: Bunch of updates, still not quite right. + Asked for some help from the gnome-vfs hackers. + +Sun Oct 21 02:52:48 2001 George Lebl + + * modules/vfolder-desktop-method.c: implement create and some + fixes to saving vfolder doc (though of course that bit isn't + done yet) + +Fri Oct 19 23:24:06 2001 George Lebl + + * modules/vfolder-desktop-method.c: implement make/remove_directory, + do proper checking of schemes as a way to do "same fs" check + +Thu Oct 18 20:14:02 2001 George Lebl + + * modules/vfolder-desktop-method.c: Rewrite the path resolution bits, + rewrite the move method to be saner, but still incomplete, + implement open for write and sanitized things all over. + +2001-10-17 jacob berkman + + * configure.in: remove gdk dependency + + * modules/file-method.c (monitor_setup): + (fam_callback): use GIOChannels directly rather than through + gdk_input calls (removes an unnecessary gdk dependency) + +Tue Oct 16 00:30:27 2001 George Lebl + + * modules/vfolder-desktop-method.c: not all systems have the + d_type dirent thingie, so don't use it, implement unlink and + move (mostly), though changes are not yet written to disk, + add a bunch of fixmes and some more code to the writing functions. + also remove some debugging output. + +2001-10-15 Laszlo Peter + + Patch for 48545 - add prioritized versions of all async calls + + * libgnomevfs/gnome-vfs-async-ops.h, + libgnomevfs-pthread/gnome-vfs-async-ops.c, + libgnomevfs/gnome-vfs-helpers.h, + libgnomevfs/gnome-vfs-helpers.c: + added a new argument to all async operations, the job priority, + which comes just before the callback. Priority is an int, valid + range is GNOME_VFS_MIN_PRIORITY (-10) to GNOME_VFS_MAX_PRIORITY + (+10). Use GNOME_VFS_DEFAULT_PRIORITY (0) if you don't care. + + * libgnomevfs-pthread/gnome-vfs-job-queue.h, + libgnomevfs-pthread/gnome-vfs-job-queue.c: (new files) + Put async jobs in a queue if the number of concurrent jobs + exceeds a limit. Start jobs based on the priority. + Public functions gnome_vfs_async_{get,set}_job_limit can be + used to change the default job limit. + + * libgnomevfs/gnome-vfs-job-limit.h: (new file) public prototypes + of the functions to get/set the job limit. + + * libgnomevfs-pthread/gnome-vfs-job-slave.c: + (gnome_vfs_thread_backend_shutdown): shut down the job queue + + * libgnomevfs-pthread/gnome-vfs-job.h: added the priority to + GnomeVFSJob. + + * libgnomevfs-pthread/gnome-vfs-job.c: (gnome_vfs_job_new): + added the priority argument. (gnome_vfs_job_go): call the + job scheduler instead of starting the job immediately. + + * libgnomevfs-pthread/gnome-vfs-pthread.c: (gnome_vfs_pthread_init): + initialize the job queue. + + * libgnomevfs-pthread/gnome-vfs-thread-pool.c (thread_entry): + check the job queue when a job is finished. + + * modules/test-method.c: (vfs_module_init): take the config file + from GNOME_VFS_TEST_CONFIG_FILE env. variable if defined. + (start_operation): use select() instead of usleep(). + + * test/test-async-cancel.c, test/test-async-directory.c, + test/test-async.c, test/test-callback.c, test/test-channel.c, + test/test-symlinks.c: added 0 priority to all async calls. + + * test/test-queue.c: (new file): test program for the job queue. + + * queue-test-config.xml: (new file): config file for the test + method. Used by test-queue. + + * doc/tmpl/async-ops.sgml: added docs on priority and scheduling. + + * libgnomevfs/Makefile.am, libgnomevfs-pthread/Makefile.am, + test/Makefile.am: added the new files. + +Sun Oct 14 23:25:41 2001 George Lebl + + * modules/Makefile.am, modules/programs.vfolder-info.in, + modules/default-modules.conf: Make the vfolder-desktop-method + the default for programs: and install the programs.vfolder-info + file which now is basically the same as the current scheme + of directories. It needs to be modified to be like nils's + proposal which is cooler. + + * modules/vfolder-desktop-method.c: Change to use + .vfolder-info, to make it possible to use it for other + schemes then programs:. Read override vfolder-info from users + directory if it exists in preparation for writing. Implement + SortOrder. Fix reading 'Not' queries. + +Sun Oct 14 02:31:58 2001 George Lebl + + * modules/vfolder-desktop-method.c: Implement most of the read-only + functionality, the only thing missing is understanding sort order. + Still not added to the build, however it now actually works. + +Sat Oct 13 01:47:44 2001 George Lebl + + * modules/vfolder-desktop-method.c: A piece of not-yet-working + code to do the "programs:" scheme but with vfolders. Aimed + to complement the desktop-method, not to replace it for + everything. Doesn't even compile, but I'm paranoid so I want + to commit things. + +2001-10-07 Maciej Stachowiak + + * modules/nfs-method.c: (rpc_init_tcp): Fix bug 55805 (mistake in + gnome-vfs/modules/nfs-method.c), patch from Martin Pool + . + +2001-10-02 Darin Adler + + * modules/http-method.c: (build_request), (make_request): + * test/test-shell.c: (do_cd): + g_string_printfa -> g_string_append_printf + +2001-10-02 Darin Adler + + * .cvsignore: + * Makefile.am: + * configure.in: + Changed from xml-i18n-tools to intltool. + + * doc/tmpl/gnome-vfs-unused.sgml: Regenerated by gtk-doc. + (Do we have a version mismatch?) + +2001-09-30 Anders Carlsson + + * libgnomevfs/gnome-vfs-module-callback.c: + (gnome_vfs_module_callback_free_stack_info): Free the stack info + structure too. + +2001-09-28 Darin Adler + + * modules/file-method.c: (do_read_directory): + Add back MIME type code that we accidentally removed when + we removed directory filtering. + +2001-09-26 Maciej Stachowiak + + * configure.in, NEWS: updated for 1.9.1 + +2001-09-26 Maciej Stachowiak + + * doc/tmpl/gnome-vfs-unused.sgml: Regenerated by gtk-doc + + Merged some changes from the stable branch: + + 2001-09-10 Maciej Stachowiak + + * libgnomevfs/gnome-vfs-uri.h, libgnomevfs/gnome-vfs-uri.c + (gnome_vfs_uri_resolve_relative): Renamed from + gnome_vfs_uri_relative_new; reversed argument order. + + 2001-09-08 Maciej Stachowiak + + Fix make distcheck: + + * libgnomevfs/gnome-vfs-configuration.c: (configuration_load), + (install_path_list), (gnome_vfs_configuration_init): + * test/Makefile.am: Set environment variables so that `make check' + can find the uninstalled modules and configuration. + +2001-09-25 Darin Adler + + * modules/cdda-cddb.c: (CDDBProcessLine): + * modules/http-authn.c: (http_authn_glist_find_header), + (http_authn_parse_response_header_basic): + * modules/nfs-method.c: (server_connection_acquire): + Switched to new ascii version of strcasecmp family. + +2001-09-25 Darin Adler + + * configure.in: Require glib 1.3.9. + + * libgnomevfs/gnome-vfs-mime.c: + (gnome_vfs_mime_type_from_name_or_default): + * libgnomevfs/gnome-vfs-uri.c: (split_toplevel_uri), + (get_method_string): + Fix for changed signature of g_ascii_strup/strdown. + +2001-09-25 Darin Adler + + * modules/gzip-method.c: (skip): + * modules/translate-method.c: (my_poptParseArgvString), + (tr_args_parse): + Use g_alloca instead of alloca for better portability. + +2001-09-20 Havoc Pennington + + * modules/file-method.c (find_trash_in_hierarchy): remove the + trash search stuff + (create_trash_near): ditto + + * modules/Makefile.am, desktop-method.c, desktop-module.conf: Add + desktop method for desktop URIs such as start-here + +2001-09-18 Havoc Pennington + + * libgnomevfs/gnome-vfs-private.h: update modules locations + + * modules/Makefile.am (modulesdir): put modules in a new directory + (modulesconfdir): put modules conf in a new directory + + * gnome-vfs-2.0.pc.in (Cflags): update + + * libgnomevfs/Makefile.am (libgnomevfsincludedir): move headers + into gnome-vfs-2.0 subdir + +2001-09-10 Frank Belew + + * configure.in: add check for librt for semaphore functions + (fixes undefined references on solaris) + +2001-09-07 Darin Adler + + * libgnomevfs-pthread/gnome-vfs-job.c: Remove a stray include. + +2001-09-07 Maciej Stachowiak + + * doc/Makefile.am: Fix stamp creation so the docs get built only + when something actually changes, not every single time. + +2001-09-06 Darin Adler + + * modules/ftp-method.c: (do_path_command): Fix leak. + (do_transfer_command): Simplify code. + (do_path_transfer_command): Fix leak. + (ftp_connection_create): Fix leak of uri in many cases and of + response_buffer in one case. + (my_str_hash): Simplify code. + (my_str_equal): Simplify code. + (ftp_connection_acquire): Formatting tweak. + (do_get_file_info): Fix leak in the ERROR_NOT_FOUND case. + (vfs_module_init): Remove gconf initialization since this module + doesn't use gconf. + +2001-09-07 Maciej Stachowiak + + Fixed many problems in the in-line and out-of-line docs that were + causing doc build warnings (most indicative of problems in the + genrated docs). Recategorize things a bit. + + * doc/Makefile.am: + * doc/about.sgml: + * doc/gnome-vfs-docs.sgml: + * doc/gnome-vfs-sections.txt: + * doc/tmpl/backend.sgml: + * doc/tmpl/directory.sgml: + * doc/tmpl/find-directory.sgml: + * doc/tmpl/fnmatch.sgml: + * doc/tmpl/gnome-vfs-unused.sgml: + * doc/tmpl/init.sgml: + * doc/tmpl/mime-info.sgml: + * doc/tmpl/module-callback-private.sgml: + * doc/tmpl/seekable.sgml: + * doc/tmpl/standard-callbacks.sgml: + * doc/tmpl/xfer.sgml: + * doc/writing-modules.sgml: + * libgnomevfs/gnome-vfs-application-registry.c: + * libgnomevfs/gnome-vfs-directory.c: + * libgnomevfs/gnome-vfs-directory.h: + * libgnomevfs/gnome-vfs-file-info.c: + * libgnomevfs/gnome-vfs-find-directory.c: + * libgnomevfs/gnome-vfs-mime-info.c: + * libgnomevfs/gnome-vfs-mime-info.h: + * libgnomevfs/gnome-vfs-mime.c: + * libgnomevfs/gnome-vfs-module-callback.c: + +2001-09-03 Maciej Stachowiak + + Simplification of the callback API, in the process fixing bugs + 8447 ([API] Authentication callback API is not threadsafe) and + 8448 ([API] Authentication callbacks require explicit threading + when using async API) and documenting all of it. + + * libgnomevfs/gnome-vfs-module-callback.h, + libgnomevfs/gnome-vfs-module-callback.c: + (gnome_vfs_module_callback_set_default, + gnome_vfs_module_callback_push, gnome_vfs_module_callback_pop): + New callback interface, replacing gnome-vfs-app-context. + (gnome_vfs_async_module_callback_set_default, + gnome_vfs_async_module_callback_push, + gnome_vfs_async_module_callback_pop): Calls for managing async + callbacks. + (gnome_vfs_module_callback_invoke): Function to be used by modules + to invoke a callback. + (gnome_vfs_module_callback_get_stack_info, + gnome_vfs_module_callback_free_stack_info, + gnome_vfs_module_callback_use_stack_info, + gnome_vfs_module_callback_clear_stacks, + gnome_vfs_module_callback_set_in_async_thread): Private calls used + by gnome-vfs-job to make sure async jobs are called with the same + set of callbacks as the thread that launches them. + (callback_info_new, callback_info_ref, callback_info_unref, + async_callback_response, async_callback_invoke, + async_callback_destroy, async_callback_info_new, + insert_callback_into_table, push_callback_into_stack_table, + pop_stack_table, copy_one_callback, copy_one_stack_top, + copy_one_callback_to_stack, duplicate_callback_table, + copy_callback_stack_tops, copy_callback_table_to_stack_table, + callback_info_unref_x, remove_one_stack, remove_one_callback, + clear_stack_table, clear_callback_table, stack_table_destroy, + stack_keys_alloc, free_default_callbacks, + initialize_global_if_needed, initialize_per_thread_if_needed): + Helper functions for the above. + * libgnomevfs/gnome-vfs-module-callback-module-api.h: Prototypes + for module-only calls relating to callbacks. + * libgnomevfs/gnome-vfs-module-callback-private.h: Prototypes + for internal calls relating to callbacks. + * libgnomevfs/gnome-vfs-module-callback-private.c, + libgnomevfs/gnome-vfs-module-callback-module-api.c: Files that + only include the corresponding headers to make sure they are + standalone includable. + * libgnomevfs/gnome-vfs-standard-callbacks.h: Changed some names + to fit better with the new API. + + * libgnomevfs/gnome-vfs-app-context.c, + libgnomevfs/gnome-vfs-app-context.h, + libgnomevfs/gnome-vfs-callbacks.c, + libgnomevfs/gnome-vfs-callbacks.h, + libgnomevfs/gnome-vfs-context.h, + libgnomevfs/gnome-vfs-module-api.c, + libgnomevfs/gnome-vfs-module-api.h: Removed. + + * libgnomevfs/gnome-vfs-private-types.h, + libgnomevfs/gnome-vfs-private.h, libgnomevfs/gnome-vfs-types.h, + libgnomevfs/gnome-vfs.h: Pull in new headers where appropriate. + * libgnomevfs/gnome-vfs-backend-private.h, + libgnomevfs/gnome-vfs-backend.c + (gnome_vfs_backend_dispatch_module_callback): Adjust for new + interface of async module callbacks. + * libgnomevfs/gnome-vfs-context.c: (gnome_vfs_context_new, + gnome_vfs_context_unref, + gnome_vfs_context_check_cancellation_current): Remove app-context + code. + * libgnomevfs/gnome-vfs-messages.h: Move typedef of + GnomeVFSStatusCallback here. + * libgnomevfs/Makefile.am: Add new files to build, remove ones + that are gone. + + * libgnomevfs-pthread/gnome-vfs-job.h, + libgnomevfs-pthread/gnome-vfs-job.c: + (gnome_vfs_job_set, set_current_job, clear_current_job, + gnome_vfs_op_destroy): Copy callback state so async jobs get the + same set of callbacks as the calling thread. + (gnome_vfs_job_execute, + pthread_gnome_vfs_dispatch_module_callback, + dispatch_module_callback, dispatch_sync_job_callback): Adjust for + new interface of module callbacks. + + * modules/http-method.c + (connect_to_uri, + invoke_callback_basic_authn): Adjusted for above API changes. + * modules/http-authn.c: + (http_authentication_test_flush_credentials): Renamed to + authentication from authn. + * modules/Makefile.am: Remove a stray trailing slash (caused + problems with newer automake). + + * test/test-callback.c: (authentication_callback, + destroy_notify, main): Adjusted for API changes. + + * configure.in: Don't check gtk-doc version (I have an older + version, it seems to work fine) and remove redundant checks. + + * doc/gnome-vfs-docs.sgml, doc/gnome-vfs-sections.txt: Add new + module callback stuff. + + * doc/tmpl/module-callback-module-api.sgml, + doc/tmpl/module-callback-private.sgml, + doc/tmpl/module-callback.sgml, doc/tmpl/standard-callbacks.sgml, + doc/tmpl/context.sgml: New and updated out-of-line part of the + docs for the module callback interface. + + * doc/tmpl/app-context.sgml, doc/tmpl/constants.sgml, + doc/tmpl/module-api.sgml: Removed (corresponding sections are + gone). + + * doc/tmpl/gnome-vfs-unused.sgml, doc/tmpl/list-sort.sgml, + doc/tmpl/shellpattern-filter.sgml, doc/tmpl/types.sgml, + doc/tmpl/xfer.sgml: Mysteriously changed by gtk-doc. + + * doc/Makefile.am, doc/about.sgml, doc/gnome-vfs-docs.sgml, + doc/gnome-vfs-sections.txt, doc/tmpl/app-context.sgml, + doc/tmpl/async-ops.sgml, doc/tmpl/cancellable-ops.sgml, + doc/tmpl/constants.sgml, doc/tmpl/context.sgml, + doc/tmpl/directory-filter.sgml, doc/tmpl/directory.sgml, + doc/tmpl/gnome-vfs-unused.sgml, doc/tmpl/list-sort.sgml, + doc/tmpl/regexp-filter.sgml, doc/tmpl/shellpattern-filter.sgml, + doc/tmpl/standard-callbacks.sgml, doc/tmpl/types.sgml, + doc/tmpl/xfer.sgml: Rescanned, cleaned up assorted doc problems, + removed docs for APIs that are gone. + +2001-09-04 Darin Adler + + Remove more of the obsolete back-end machinery. + + * Makefile.am: Build libgnomevfs-pthread first, so we can link + it into libgnomevfs. + + * libgnomevfs-pthread/Makefile.am: Make a convenience library + instead of a shared library. Also put all the headers in + SOURCES instead of noinst_HEADERS, as recommended by automake + experts. + + * libgnomevfs-pthread/gnome-vfs-async-ops.c: + * libgnomevfs-pthread/gnome-vfs-job.c: + Remove pthread_ prefix from all the names of entry points since we + now link to these directly. + + * libgnomevfs/Makefile.am: Link in the new convenience library + and remove gnome-vfs-backend.c. + + * libgnomevfs/gnome-vfs-app-context.c: + (gnome_vfs_callback_call_hook), (dispatch_destroy_notify): + * libgnomevfs/gnome-vfs-context.c: + (gnome_vfs_context_peek_current): + * libgnomevfs/gnome-vfs-init.c: (gnome_vfs_init), + (gnome_vfs_shutdown), (gnome_vfs_loadinit), (gnome_vfs_preinit), + (gnome_vfs_postinit): + Call functions by their real names in the pthread library, + rather than using back-end wrapper names. + + * libgnomevfs/gnome-vfs-backend.c: Removed. + * libgnomevfs/gnome-vfs-backend.h: Removed most of the + contents of this file. Later we can delete it completely. + + * test/Makefile.am: Removed the environment setup that made it + so tests could find the back end. + + * test/test-async-cancel.c: Renamed things to reflect the fact + that we count "jobs" not "threads". + + * libgnomevfs/gnome-vfs-async-ops.h: Get rid of "const GList *". + + * libgnomevfs-pthread/gnome-vfs-pthread.c: Formatting tweak. + +2001-09-04 jacob berkman + + * modules/*.conf: remove lib prefix and .so suffix from the + libraries as g_module_build_path() will add these for us + + * libgnomevfs/gnome-vfs-method.c (load_module_in_path_list): use + g_module_build_path() to correctly get library suffix + +2001-09-03 Maciej Stachowiak + + Put gnome-vfs-backend stuff all in one header and make it private. + + * libgnomevfs/Makefile.am: + * libgnomevfs/gnome-vfs-app-context.c: + * libgnomevfs/gnome-vfs-backend-private.h: + * libgnomevfs/gnome-vfs-backend.c: + * libgnomevfs/gnome-vfs-backend.h: + +2001-09-03 Maciej Stachowiak + + Fix bug 8514 ([API] kill gnome-vfs-seekable) + + * libgnomevfs/Makefile.am: + * libgnomevfs/gnome-vfs-handle.c: (gnome_vfs_handle_new): + * libgnomevfs/gnome-vfs-seekable.c: + * libgnomevfs/gnome-vfs-seekable.h: + +2001-09-02 Maciej Stachowiak + + * libgnomevfs/gnome-vfs-init.c: (gnome_vfs_init): Don't warn on + re-init (it's a harmless no-op) + * libgnomevfs/gnome-vfs-init.h: Remove gnome_vfs_options + declaration, since it's not defined anywhere anyway. + +2001-09-01 Darin Adler + + * idl/.cvsignore: Remove this now that this directory is empty. + * libgnomevfs/.cvsignore: No need to ignore metafile-related + generated files since those files are gone. + * libgnomevfs/Makefile.am: Remove more code that was part of + the metafile support. + + * libgnomevfs/eel-cut-n-paste.c: + * libgnomevfs/eel-cut-n-paste.h: + * libgnomevfs/stolen-glib-extensions.c: + * libgnomevfs/stolen-glib-extensions.h: + Removed. + +2001-09-01 Maciej Stachowiak + + * OUTSTANDING_API_ISSUES: Updated. + +2001-09-01 Maciej Stachowiak + + * Makefile.am: + * configure.in: + * idl/Makefile.am: + * idl/gnome-vfs-metafile-server.idl: + * libgnomevfs/Makefile.am: + * libgnomevfs/gnome-vfs-metadata.c: + * libgnomevfs/gnome-vfs-metadata.h: + * libgnomevfs/gnome-vfs-metafile-backend.c: + * libgnomevfs/gnome-vfs-metafile-backend.h: + * libgnomevfs/gnome-vfs-metafile-factory.c: + * libgnomevfs/gnome-vfs-metafile-factory.h: + Remove metadata code from HEAD, with Seth's approval. + +2001-08-31 Darin Adler + + * libgnomevfs/Makefile.am: + * libgnomevfs/fnmatch.c: + * libgnomevfs/fnmatch.h: + Remove this unused code. + + * libgnomevfs/eel-cut-n-paste.c: + * libgnomevfs/gnome-vfs-application-registry.c: + (strip_trailing_whitespace): + * libgnomevfs/gnome-vfs-configuration.c: (parse_line): + * libgnomevfs/gnome-vfs-helpers.c: + * libgnomevfs/gnome-vfs-i18n.c: + * libgnomevfs/gnome-vfs-mime-info.c: + * libgnomevfs/gnome-vfs-mime-magic.c: (read_string_val), + (read_num_val), (eat_white_space), (gnome_vfs_mime_magic_parse), + (print_escaped_string), (gnome_vfs_sniff_buffer_looks_like_text): + * libgnomevfs/gnome-vfs-mime.c: (add_to_key), + (mime_fill_from_file): + * libgnomevfs/gnome-vfs-mime.h: + * libgnomevfs/gnome-vfs-private-utils.c: (check_end): + * libgnomevfs/gnome-vfs-uri.c: (split_toplevel_uri): + * libgnomevfs/gnome-vfs-utils.c: + * libgnomevfs/stolen-glib-extensions.c: + * modules/cdda-cddb.c: (ChopWhite): + * modules/cdda-method.c: + * modules/ftp-method.c: (get_response), (do_read_directory): + * modules/http-method.c: (parse_status), (header_value_to_number), + (unescape_unreserved_chars): + * modules/translate-method.c: (my_poptParseArgvString): + * test/test-shell.c: + Get rid of any use of and replace with the new g_ascii_* + calls in glib. + +2001-08-31 Darin Adler + + * libgnomevfs/gnome-vfs-uri.c: (gnome_vfs_uri_list_parse): + Use g_ascii_isspace instead of isspace. This fixes the char + subscript problem in an even better way, and makes sure we don't + interpret spaces with locale-specific rules. + + * test/.cvsignore: Ignore this. + +2001-08-27 Sander Vesik + + * libgnomevfs/gnome-vfs-uri.c: cast argument to isspace so -Werror + does not cause breakage on solaris - using char as a subscript + generates a warning. + +2001-08-27 Martin Baulig + + * modules/file-method.c: Only #include if we HAVE_FAM. + +2001-08-26 Maciej Stachowiak + + * OUTSTANDING_API_ISSUES: Added the rest of the bugs. + +2001-08-26 Maciej Stachowiak + + * OUTSTANDING_API_ISSUES: Added a bunch of entries for bug reports + in the gnome-vfs bug database that have API impact, and bug + numbers for some things I filed. + +2001-08-27 Abel Cheung + + * configure.in(ALL_LINGUAS): Rename zh_TW.Big5 to zh_TW. + +2001-08-25 Ian McKellar + + * Makefile.am: + * acconfig.h: + * configure.in: + * libgnomevfs/Makefile.am: + * libgnomevfs/gnome-vfs-method.h: + * libgnomevfs/gnome-vfs-monitor-private.h: + * libgnomevfs/gnome-vfs-monitor.c: (init_hash_table), + (gnome_vfs_monitor_do_add), (destroy_monitor_handle), + (gnome_vfs_monitor_do_cancel), (actually_dispatch_callback), + (gnome_vfs_monitor_callback): + * libgnomevfs/gnome-vfs-monitor.h: + * libgnomevfs/gnome-vfs-ops.c: (gnome_vfs_monitor_add), + (gnome_vfs_monitor_cancel): + * libgnomevfs/gnome-vfs-ops.h: + * libgnomevfs/gnome-vfs-uri.c: (gnome_vfs_uri_relative_new): + * libgnomevfs/gnome-vfs.h: + Added a file/directory monitoring API based off the FAM api. + + * modules/Makefile.am: + * modules/file-method.c: (fam_callback), (monitor_setup), + (do_monitor_add), (do_monitor_cancel): + Added monitoring support to the file method using FAM. + + * test/Makefile.am: + * test/test-monitor.c: (show_result), (callback), (main): + Test program for monitoring support. + + * test/test-directory.c: (main): + Build fix stuff. + +2001-08-25 Darin Adler + + * libgnomevfs/Makefile.am: No such thing as $(builddir), so it + makes no sense to pass -I$(builddir). + +2001-08-25 Jim Garrison + + * doc/tmpl/async-ops.sgml: documented most commonly used + async-ops + +Fri Aug 24 22:17:25 2001 George Lebl + + * libgnomevfs/gnome-vfs-uri.[ch]: Add function + gnome_vfs_uri_list_parse, which is like the original gnome + function gnome_uri_list_extract_uris. It parses text/uri-list + and returns a GList of GnomeVFSURIs. Actually it is not just + like that function it is basically exactly that function thanks + to CutAndPaste(tm) technology. + +Thu Aug 23 11:33:48 2001 George Lebl + + * test/test-channel.c (io_channel_callback): Another s/guint/gsize/ + 64bit fix + +Thu Aug 23 11:12:36 2001 George Lebl + + * libgnomevfs/gnome-vfs-process.c (wake_up), + libgnomevfs-pthread/gnome-vfs-job.c (serve_channel_read) + (serve_channel_write): 64bitness issues fixed. GIOChannel + functions have size done in 'gsize' (64bit) and not 'guint' (32bit) + +2001-08-21 Maciej Stachowiak + + * OUTSTANDING_API_ISSUES: Removed the filtering item, added one + for renaming gnome-vfs-method. + + All changes below: removed the non-working and undesirable + directory filtering feature. + + * libgnomevfs-pthread/gnome-vfs-async-ops.c: + (async_load_directory), (pthread_gnome_vfs_async_load_directory), + (pthread_gnome_vfs_async_load_directory_uri): + * libgnomevfs-pthread/gnome-vfs-job.c: (gnome_vfs_op_destroy), + (load_directory_details), (execute_load_directory): + * libgnomevfs-pthread/gnome-vfs-job.h: + * libgnomevfs/Makefile.am: + * libgnomevfs/gnome-vfs-async-ops.h: + * libgnomevfs/gnome-vfs-backend.c: + (gnome_vfs_async_load_directory_uri), + (gnome_vfs_async_load_directory): + * libgnomevfs/gnome-vfs-cancellable-ops.h: + * libgnomevfs/gnome-vfs-directory-filter.c: + * libgnomevfs/gnome-vfs-directory-filter.h: + * libgnomevfs/gnome-vfs-directory.c: + (gnome_vfs_directory_handle_new), (open_from_uri), (open), + (gnome_vfs_directory_open), (gnome_vfs_directory_open_from_uri), + (gnome_vfs_directory_open_from_uri_cancellable), + (directory_visit_internal), (gnome_vfs_directory_visit_uri), + (gnome_vfs_directory_visit), + (gnome_vfs_directory_visit_files_at_uri), + (gnome_vfs_directory_visit_files), (gnome_vfs_directory_list_load): + * libgnomevfs/gnome-vfs-directory.h: + * libgnomevfs/gnome-vfs-method.h: + * libgnomevfs/gnome-vfs-regexp-filter.c: + * libgnomevfs/gnome-vfs-regexp-filter.h: + * libgnomevfs/gnome-vfs-shellpattern-filter.c: + * libgnomevfs/gnome-vfs-shellpattern-filter.h: + * libgnomevfs/gnome-vfs-types.h: + * libgnomevfs/gnome-vfs-xfer.c: (empty_directory), + (non_recursive_empty_directory), (gnome_vfs_visit_list), + (directory_add_items_and_size), (create_directory), + (copy_directory): + * libgnomevfs/gnome-vfs.h: + * modules/cdda-method.c: (do_open), (do_open_directory): + * modules/extfs-method.c: (do_open_directory), (do_get_file_info): + * modules/file-method.c: (directory_handle_new), + (do_open_directory), (do_read_directory): + * modules/ftp-method.c: (do_get_file_info), (do_open_directory): + * modules/gconf-method.c: (directory_handle_new), + (do_open_directory), (do_read_directory): + * modules/http-method.c: (do_open_directory): + * modules/ssh-method.c: (do_open_directory): + * modules/test-method.c: (do_open_directory): + * modules/translate-method.c: (tr_do_open_directory): + * monikers/bonobo-storage-vfs.c: (vfs_list_contents): + * test/test-async-cancel.c: (test_load_directory_cancel), + (test_load_directory_fail): + * test/test-async-directory.c: (main): + * test/test-directory-visit.c: (main): + * test/test-directory.c: (main): + * test/test-shell.c: (do_ls), (validate_path), (get_regexp_name): + +2001-08-21 Theo van Klaveren + + * libgnomevfs/gnome-vfs-inet-connection.c, + libgnomevfs/gnome-vfs-mime.h, libgnomevfs/gnome-vfs-ls-parse.c, + modules/file-method.c, modules/ftp-method.c, modules/http-method.c: + Fix includes on FreeBSD by adding where needed, + moving includes to below , moving + above and replacing by + . + +2001-08-20 Maciej Stachowiak + + * configure.in: Check for bonobo-activation's IDL directory, not + libbonobo's. + + * idl/Makefile.am, idl/gnome-vfs-slave.idl, + idl/gnome-vfs-types.idl: Remove obsolete idl files. + + * idl/gnome-vfs-metafile-server.idl: Include Bonobo_Unknown.idl, + not all of Bonobo.idl. + +2001-08-19 Sri Ramkrishna + + * libgnomevfs/gnome-vfs-xfer.c: (gnome_vfs_xfer_private), + (gnome_vfs_xfer_uri): + + Added new API docs to gnome-vfs-xfer. + +2001-08-14 Michael Meeks + + * configure.in (BONOBO_ACTIVATION_REQUIRED): require 0.9.1 + +2001-08-10 Abel Cheung + + * configure.in: added zh_TW.Big5 to ALL_LINGUAS. (Please tell me + if there is problem, the file is checked against gettext >= 0.10.36, + and will produce error if gettext <= 0.10.35 is used) + +2001-08-07 Martin Baulig + + * configure.in: Fix all the PKG_CHECK_MODULES checks. + You need to check for all dependencies for any given target in a + single PKG_CHECK_MODULES command, otherwise you'll get duplicate + -ldl etc. into your *.la files. + + * */Makefile.am: Use the correct _LIBS and _CFLAGS. + +2001-08-06 jacob berkman + + * modules/ftp-method.c (do_open_directory): do a CWD command so we + can correctly return an error code when trying to open a file. + +2001-08-06 Frederic Crozat + + * libgnomevfs/gnome-vfs-mime-magic.c: + (gnome_vfs_sniff_buffer_looks_like_gzip): + Fix detection of Koffice files (ie seen as gzipped files) + +2001-08-03 Darin Adler + + * libgnomevfs/gnome-vfs.h: Remove extern "C" guards. + The individual files take care of this. + +2001-08-03 Darin Adler + + Made builds noticeably faster by not using catch-all includes + like inside gnome-vfs sources. + + * libgnomevfs/Makefile.am: Add gnome-vfs-i18n.h, add + G_DISABLE_DEPRECATED, get rid of unneeded -I directives. + + * libgnomevfs-pthread/Makefile.am: Add G_DISABLE_DEPRECATED, get + rid of unneeded -I directives. + + * modules/Makefile.am: Add G_DISABLE_DEPRECATED, get rid of + unneeded -I directives. Remove cdda-method.h, extfs-method.h, + file-method.h, ssh-method.h, test-method.h, ftp-method.h, + gconf-method.h, pipe-method.h, efs-method.h. + + * test/Makefile.am: Add G_DISABLE_DEPRECATED, get rid of unneeded + -I directives. + + * libgnomevfs/gnome-vfs-app-context.c: (inherit_from_current): + Don't use obsolete g_hash_table_freeze/thaw. + + * libgnomevfs/eel-cut-n-paste.c: (stolen_strcasecmp), + (stolen_istr_has_prefix): + * libgnomevfs/gnome-vfs-backend.c: (gnome_vfs_backend_name), + (gnome_vfs_backend_loadinit): + * libgnomevfs/gnome-vfs-file-info.c: (gnome_vfs_file_info_matches): + * libgnomevfs/gnome-vfs-helpers.c: (istr_has_prefix), + (is_valid_scheme_character), (gnome_vfs_x_make_uri_canonical): + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_get_default_action_type), (sort_application_list): + * libgnomevfs/gnome-vfs-mime-info.c: (does_string_contain_caps): + * libgnomevfs/gnome-vfs-mime-magic.c: (read_hex_byte), + (read_num_val): + * libgnomevfs/gnome-vfs-mime.c: (list_find_type), + (gnome_vfs_mime_type_from_name_or_default): + * libgnomevfs/gnome-vfs-private-utils.c: + (gnome_vfs_istr_has_prefix), (gnome_vfs_istr_has_suffix): + * libgnomevfs/gnome-vfs-uri.c: (split_toplevel_uri), + (get_method_string): + * libgnomevfs/gnome-vfs-utils.c: (gnome_vfs_get_volume_free_space): + * modules/http-method.c: (check_header), + (proxy_should_for_hostname), (connect_to_uri), (build_request), + (make_request), (process_propfind_propstat): + * modules/test-method.c: (get_operation_settings), + (parse_result_text), (load_settings): + * modules/translate-method.c: (tr_args_parse): + * test/test-mime-handlers-set.c: (str_to_action_type), + (str_to_bool): + * test/test-shell.c: (simple_regexp), (do_cd), (main): + Use new g_ascii calls instead of locale-sensitive ones from the + standard library or the old deprecated glib ones. + + * libgnomevfs/gnome-vfs-process.c: (wake_up): + * libgnomevfs-pthread/gnome-vfs-job.c: (serve_channel_read), + (serve_channel_write): + * test/test-channel.c: (io_channel_callback): + Use g_io_channel_write_chars, g_io_channel_shutdown, and + g_io_channel_read_chars instead of g_io_channel_write, + g_io_channel_close, and g_io_channel_read. + + * libgnomevfs/gnome-vfs-private.h: Remove everything but the two + path defines in here. + + * libgnomevfs/gnome-vfs-i18n.h: + New file, contains i18n funtions that were previously in + gnome-vfs-private.h. (They are still private.) + + * libgnomevfs-pthread/gnome-vfs-job-slave.c: + (gnome_vfs_thread_backend_shutdown): + Use g_main_context_iteration instead of g_main_iteration. + + * modules/extfs-method.c: (get_basename): + * modules/ftp-method.c: (ls_to_file_info): + Use g_path_get_basename instead of g_basename. + + * libgnomevfs/eel-cut-n-paste.c: + * libgnomevfs/gnome-vfs-application-registry.c: + * libgnomevfs/gnome-vfs-backend.c: + * libgnomevfs/gnome-vfs-cancellable-ops.c: + * libgnomevfs/gnome-vfs-cancellation.c: + * libgnomevfs/gnome-vfs-configuration.c: + * libgnomevfs/gnome-vfs-directory-filter.c: + * libgnomevfs/gnome-vfs-directory.c: + * libgnomevfs/gnome-vfs-file-info.c: + * libgnomevfs/gnome-vfs-find-directory.c: + * libgnomevfs/gnome-vfs-handle.c: + * libgnomevfs/gnome-vfs-helpers.c: + * libgnomevfs/gnome-vfs-i18n.c: + * libgnomevfs/gnome-vfs-inet-connection.c: + * libgnomevfs/gnome-vfs-init.c: + * libgnomevfs/gnome-vfs-iobuf.c: + * libgnomevfs/gnome-vfs-method.c: + * libgnomevfs/gnome-vfs-ops.c: + * libgnomevfs/gnome-vfs-parse-ls.c: + * libgnomevfs/gnome-vfs-process.c: + * libgnomevfs/gnome-vfs-regexp-filter.c: + * libgnomevfs/gnome-vfs-result.c: + * libgnomevfs/gnome-vfs-seekable.c: + * libgnomevfs/gnome-vfs-shellpattern-filter.c: + * libgnomevfs/gnome-vfs-ssl.c: + * libgnomevfs/gnome-vfs-uri.c: + * libgnomevfs/gnome-vfs-utils.c: + * libgnomevfs/gnome-vfs-xfer.c: + * libgnomevfs/stolen-glib-extensions.c: + * libgnomevfs-pthread/gnome-vfs-async-job-map.c: + * libgnomevfs-pthread/gnome-vfs-async-job-map.h: + * libgnomevfs-pthread/gnome-vfs-async-ops.c: + * libgnomevfs-pthread/gnome-vfs-job-slave.c: + * libgnomevfs-pthread/gnome-vfs-job.c: + * libgnomevfs-pthread/gnome-vfs-job.h: + * libgnomevfs-pthread/gnome-vfs-thread-pool.c: + * modules/bzip2-method.c: + * modules/cdda-cddb.c: + * modules/cdda-cddb.h: + * modules/cdda-method.c: + * modules/efs-method.c: + * modules/extfs-method.c: + * modules/file-method.c: + * modules/ftp-method.c: + * modules/gconf-method.c: + * modules/gzip-method.c: + * modules/http-authn.c: + * modules/http-cache.c: + * modules/http-method.c: + * modules/http-method.h: + * modules/nfs-method.c: + * modules/pipe-method.c: + * modules/ssh-method.c: + * modules/test-method.c: + * modules/translate-method.c: + * test/test-async-cancel.c: + * test/test-async-directory.c: + * test/test-async.c: + * test/test-callback.c: + * test/test-channel.c: + * test/test-directory-visit.c: + * test/test-directory.c: + * test/test-dirop.c: + * test/test-escape.c: + * test/test-find-directory.c: + * test/test-info.c: + * test/test-mime-handlers-set.c: + * test/test-mime-handlers.c: + * test/test-mime-info.c: + * test/test-mime.c: + * test/test-module-selftest.c: + * test/test-seek.c: + * test/test-shell.c: + * test/test-ssl.c: + * test/test-symlinks.c: + * test/test-sync-create.c: + * test/test-sync-write.c: + * test/test-sync.c: + * test/test-unlink.c: + * test/test-uri.c: + * test/test-xfer.c: + Fix includes. + + * modules/cdda-method.h: Removed. + * modules/efs-method.h: Removed. + * modules/extfs-method.h: Removed. + * modules/file-method.h: Removed. + * modules/ftp-method.h: Removed. + * modules/gconf-method.h: Removed. + * modules/pipe-method.h: Removed. + * modules/ssh-method.h: Removed. + +2001-08-02 Darin Adler + + * Makefile.am: + Added the test directory back in. Got rid of the cases for GNOME + 1, removed vfsConf.sh and gnome-vfs-config. Remove intl directory. + + * OUTSTANDING_API_ISSUES: Added some new issues. + + * acconfig.h: Removed HAVE_GCONF. + * configure.in: Removed the EAZEL_VERSION macros since we use + pkgconfig now. Removed the GNOME platform autodetect. Removed all + the GNOME 1 cases. Use PKG_CHECK_MODULES instead of + GNOME_PKGCONFIG_CHEC_MODULES. Remove lots of unused CFLAGS and + LIBS defines. Remove intl directory. Removed HAVE_GCONF. + + * gnome-vfs-config.in: Removed. + * vfsConf.sh.in: Removed. + + * libgnomevfs/Makefile.am: Put non-installed headers into + SOURCES rather than noinst_HEADERS as recommended by automake + documentation. + + * libgnomevfs-pthread/gnome-vfs-pthread.h: + * libgnomevfs/eel-cut-n-paste.h: + * libgnomevfs/gnome-vfs-app-context.h: + * libgnomevfs/gnome-vfs-application-registry.h: + * libgnomevfs/gnome-vfs-async-ops.h: + * libgnomevfs/gnome-vfs-backend.h: + * libgnomevfs/gnome-vfs-callbacks.h: + * libgnomevfs/gnome-vfs-cancellable-ops.h: + * libgnomevfs/gnome-vfs-cancellation.h: + * libgnomevfs/gnome-vfs-configuration.h: + * libgnomevfs/gnome-vfs-context.h: + * libgnomevfs/gnome-vfs-directory-filter.h: + * libgnomevfs/gnome-vfs-directory.h: + * libgnomevfs/gnome-vfs-file-info.h: + * libgnomevfs/gnome-vfs-find-directory.h: + * libgnomevfs/gnome-vfs-handle.h: + * libgnomevfs/gnome-vfs-helpers.h: + * libgnomevfs/gnome-vfs-inet-connection.h: + * libgnomevfs/gnome-vfs-init.h: + * libgnomevfs/gnome-vfs-iobuf.h: + * libgnomevfs/gnome-vfs-method.h: + * libgnomevfs/gnome-vfs-mime-handlers.h: + * libgnomevfs/gnome-vfs-mime-info.h: + * libgnomevfs/gnome-vfs-mime-magic.h: + * libgnomevfs/gnome-vfs-mime-private.h: + * libgnomevfs/gnome-vfs-mime-sniff-buffer.h: + * libgnomevfs/gnome-vfs-mime.h: + * libgnomevfs/gnome-vfs-module-api.h: + * libgnomevfs/gnome-vfs-module-shared.h: + * libgnomevfs/gnome-vfs-module.h: + * libgnomevfs/gnome-vfs-ops.h: + * libgnomevfs/gnome-vfs-parse-ls.h: + * libgnomevfs/gnome-vfs-private-utils.h: + * libgnomevfs/gnome-vfs-private.h: + * libgnomevfs/gnome-vfs-process.h: + * libgnomevfs/gnome-vfs-regexp-filter.h: + * libgnomevfs/gnome-vfs-result.h: + * libgnomevfs/gnome-vfs-seekable.h: + * libgnomevfs/gnome-vfs-shellpattern-filter.h: + * libgnomevfs/gnome-vfs-socket-buffer.h: + * libgnomevfs/gnome-vfs-socket.h: + * libgnomevfs/gnome-vfs-ssl-private.h: + * libgnomevfs/gnome-vfs-ssl.h: + * libgnomevfs/gnome-vfs-standard-callbacks.h: + * libgnomevfs/gnome-vfs-transform.h: + * libgnomevfs/gnome-vfs-types.h: + * libgnomevfs/gnome-vfs-uri.h: + * libgnomevfs/gnome-vfs-utils.h: + * libgnomevfs/gnome-vfs-xfer.h: + * libgnomevfs/stolen-glib-extensions.h: + Added G_BEGIN_DECLS and G_END_DECLS to all public headers. + Removed unnecessary includes. + + * libgnomevfs/gnome-vfs-app-context.c: + * libgnomevfs/gnome-vfs-helpers.c: + * libgnomevfs/gnome-vfs-mime-magic.c: + * libgnomevfs/gnome-vfs-private-utils.c: + * libgnomevfs/gnome-vfs-socket-buffer.c: + * libgnomevfs/gnome-vfs-socket.c: + * libgnomevfs/stolen-glib-extensions.c: + * modules/bzip2-method.c: + * modules/cdda-cddb.c: + * modules/gzip-method.c: + * modules/http-authn.c: + * modules/http-authn.h: + * modules/http-cache.c: + * modules/pipe-method.c: + * modules/ssh-method.c: + Added includes that are needed now that headers drag fewer of them + in. + + * modules/cdda-cddb.h: + * modules/cdda-method.h: + Got rid of include of gtk.h. + + * libgnomevfs/gnome-vfs-mime-handlers.c: (unref_gconf_engine), + (get_user_level): + * modules/ftp-method.c: (vfs_module_init): + Removed HAVE_GCONF. + + * modules/file-method.c: + * modules/http-method.c: + * modules/test-method.c: + Removed GNOME_PLATFORM_VERSION. + + * test/Makefile.am: + Removed VFS_GNOMEUI_CFLAGS and VFS_GNOMEGNORBA_LIBS. + + * test/test-async-cancel.c: (wait_for_boolean), + (wait_until_vfs_threads_gone), (wait_until_file_descriptors_gone), + (my_yield), (main): + * test/test-async-directory.c: (directory_load_callback), (main): + * test/test-async.c: (close_callback), (read_callback), + (open_callback), (main): + * test/test-callback.c: (main): + * test/test-channel.c: (io_channel_callback), (main): + * test/test-directory-visit.c: + * test/test-directory.c: (main): + * test/test-escape.c: + * test/test-info.c: + * test/test-mime-handlers-set.c: (main): + * test/test-mime-handlers.c: (print_component), (main): + * test/test-mime-info.c: + * test/test-shell.c: (main): + * test/test-symlinks.c: (create_link_callback), (main): + * test/test-uri.c: + * test/test-xfer.c: (main): + Converted tests so they no longer require gtk+ or libgnomeui. + +2001-08-02 Maciej Stachowiak + + * OUTSTANDING_API_ISSUES: Add a fe bug numbers. + * doc/outstanding-api-issues.txt: Actually remove this. + +==== gnome-vfs 1.1 ==== + +2001-08-02 Seth Nickell + + * OUTSTANDING_API_ISSUES: + + Add more descriptive text so application developers have + a better idea what to avoid using. + + * modules/cdda-cddb.h: + * modules/cdda-method.h: + + Remove gtk includes. + + +2001-08-02 Seth Nickell + + * OUTSTANDING_API_ISSUES: + * doc/outstanding-api-issues.txt: + + Move outstanding-api-issues.txt to the main directory. + + * README: + + Contain notice of OUTSTANDING_API_ISSUES. + +2001-08-02 Seth Nickell + + * libgnomevfs/gnome-vfs-metafile-backend.c: (corba_get_list), + (corba_set_list), (find_monitor_node), (corba_register_monitor), + (corba_unregister_monitor), + (gnome_vfs_metafile_notify_metafile_ready), + (call_metafile_changed), (file_list_filler_ghfunc), + (call_metafile_changed_for_all_files_mentioned_in_metafile), + (call_metafile_changed_for_one_file): + * libgnomevfs/gnome-vfs-metafile-backend.h: + + Sigh. Compile happily...(rename to new idl namespace). + +2001-08-02 Michael Meeks + + * doc/Makefile.am (dist-hook): fix directory creation + brokenness. + + * modules/ssh-method.c: kill gtk include. + + * modules/ftp-method.c: ditto. + + * modules/cdda-method.c: kill gtk crud. + + * modules/http-method.c: ditto. + + * modules/gconf-method.c (vfs_module_init): kill curious gtk + type inits - gconf doesn't use gtk anymore. + (vfs_module_shutdown): ditto. + + * libgnomevfs-pthread/gnome-vfs-job-slave.c: kill gtk include + (gnome_vfs_thread_backend_shutdown): and gtk cruft. + + * libgnomevfs/gnome-vfs-metafile-backend.c: basic port to GObject, + try and contain the madness a little. + + * libgnomevfs/gnome-vfs-mime-info.c: don't include gtkmain.h + + * libgnomevfs/gnome-vfs-mime-monitor.c: remove curious unused + parent class setting, port to GObject, clean hard core cruft. + + * libgnomevfs/gnome-vfs-mime-monitor.h: include a class structure, + what was someone smoking here ? + + * configure.in: don't depend on Gtk+ - that's just broken. + + * libgnomevfs/Makefile.am (noinst_HEADERS): add eel-cut-n-paste.h, + stolen-glib-extensions.h and gnome-vfs-metafile-backend.h + (libgnomevfsinclude_HEADERS): install gnome-vfs-metafile.h + + * Makefile.am (SUBDIRS): add 'intl'. + +2001-08-01 Seth Nickell + + * idl/gnome-vfs-metafile-server.idl: + + Change from GnomeVFS_ namespace to GNOME_VFS_. + + * libgnomevfs/gnome-vfs-metadata.c: (get_factory), + (gnome_vfs_metafile_load), (gnome_vfs_metafile_unref), + (gnome_vfs_metadata_get_string), (gnome_vfs_metadata_get_integer), + (gnome_vfs_metadata_get_boolean), (gnome_vfs_metadata_set_string), + (gnome_vfs_metadata_set_integer), (gnome_vfs_metadata_set_boolean): + * libgnomevfs/gnome-vfs-metadata.h: + + Add an initial cut at a Metadata API. DO NOT DEPEND ON THIS + API, IT IS NOT FROZEN (and won't even work right now, so you + won't get very far, headers are not installed and it is not + compiled in...checking in so Ian and I can work together better). + Known changes will occur in the API. Also, the IDL file will + be renamed to better match its module scopes (changes suggested + by Michael). + +2001-08-02 Michael Meeks + + * port to bonobo-activation. + +2001-08-01 Jonas Borgström + + * libgnomevfs/gnome-vfs-ssl.c (gnome_vfs_ssl_create): + Split the HAVE_OPENSSL #ifdef into two. So + the function gnome_vfs_ssl_create_from_fd will exist + (but only return GNOME_VFS_ERROR_NOT_SUPPORTED) even if + HAVE_OPENSSL isn't defined. Or else we will get + unresolved symbols in libhttp.so + +2001-07-29 Maciej Stachowiak + + * doc/outstanding-api-issues.txt: Added a few more issues. + +2001-07-29 Maciej Stachowiak + + * doc/outstanding-api-issues.txt: Add list of outstnading API + issues (perhaps not all of these are for GNOME 2). + +2001-07-29 Seth Nickell + + * bonobo-storage-fs.c: + * bonobo-storage-vfs.c: + * bonobo-stream-fs.c: + * bonobo-stream-vfs.c: + + Make it actually compile ;-) Still had includes to parts + of libgnome. + +2001-07-29 Seth Nickell + + * libgnomevfs/Makefile.am: + + Remove link and include variables that were no longer in use. + +2001-07-29 Seth Nickell + + * doc/about.sgml: + + Change some of the text a little, add a few programming + examples. + +2001-07-29 Michael Meeks + + * Makefile.am (SUBDIRS_GNOME): add monikers. + + * configure.in: add monikers/ + +2001-07-27 Darin Adler + + Get things compiling again. + + * idl/gnome-vfs-metafile-server.idl: Don't use a typedef for URI, + just use "string" directly. The IDL compiler doesn't handle the + typedef case properly. + + * libgnomevfs/.cvsignore: Ignore the new generated files. + + * libgnomevfs/eel-cut-n-paste.c: Add missing include. + + * libgnomevfs/gnome-vfs-metafile-backend.h: Change xml includes to + use , not . + + * libgnomevfs/gnome-vfs-metafile-backend.c: Add missing + include. Change xml includes to use , not . + (destroy), (gnome_vfs_metafile_get), (corba_get_list), + (corba_copy), (metadata_value_new_list), (metadata_value_destroy), + (metadata_value_equal), (get_metadata_list_from_table), + (can_use_public_metafile), + (metafile_read_check_for_directory_callback), + (metafile_read_restart), (metafile_read_start), + (directory_request_write_metafile): + Put code that's not ready yet inside "#ifdef METAFILE_CODE_READY". + + * configure.in: Turn -Werror back on and get rid of lame old + $(WERROR) hack. + + * libgnomevfs-pthread/Makefile.am: + * libgnomevfs/Makefile.am: + * modules/Makefile.am: + * test/Makefile.am: + Get rid of the lame old $(WERROR) hack. + +2001-07-26 Seth Nickell + + * configure.in: + + Add Bonobo dependency. Comment out -Werror because ORBit2 + or libidl is generating stubs with a few warnings. Should + be the only warnings though, so watch carefully when you + compile!. + + * doc/tmpl/gnome-vfs-unused.sgml: + * doc/tmpl/shellpattern-filter.sgml: + * doc/tmpl/xfer.sgml: + + Ask the documentation system! + + * idl/Makefile.am: + + Add gnome-vfs-metafile-server.idl + + * idl/gnome-vfs-metafile-server.idl: + + err. Add gnome-vfs-metafile-server.idl + + * libgnomevfs/Makefile.am: + + Add the eel cut-n-paste code, and the new metafile + stuff, as well as actually using the idl file. + + * libgnomevfs/gnome-vfs-metafile-backend.c: + (gnome_vfs_metafile_class_init), (gnome_vfs_metafile_init), + (destroy), (construct_private_metafile_vfs_uri), + (gnome_vfs_metafile_set_directory_uri), (gnome_vfs_metafile_new), + (gnome_vfs_metafile_make_uri_canonical), (gnome_vfs_metafile_get), + (schedule_next_read), (async_read_start), (async_read_done), + (async_read_cancel), (corba_is_read), (corba_get), + (corba_get_list), (corba_set), (corba_set_list), (corba_copy), + (corba_remove), (corba_rename), (corba_rename_directory), + (find_monitor_node), (corba_register_monitor), + (corba_unregister_monitor), + (gnome_vfs_metafile_notify_metafile_ready), + (call_metafile_changed), (file_list_filler_ghfunc), + (call_metafile_changed_for_all_files_mentioned_in_metafile), + (call_metafile_changed_for_one_file), (get_metadata_from_node), + (get_metadata_list_from_node), (create_metafile_root), + (get_file_node), (get_metadata_string_from_metafile), + (get_metadata_list_from_metafile), + (set_metadata_string_in_metafile), (set_metadata_list_in_metafile), + (metadata_value_new), (metadata_value_new_list), + (metadata_value_destroy), (metadata_value_equal), + (set_metadata_in_metafile), (get_metadata_string_from_table), + (get_metadata_list_from_table), (str_or_null_hash), + (str_or_null_equal), (set_metadata_eat_value), + (free_file_table_entry), (free_directory_table_entry), + (destroy_metadata_changes_hash_table), (destroy_xml_string_key), + (metafile_free_metadata), (get_file_metadata), + (get_file_metadata_list), (set_file_metadata), + (set_file_metadata_list), (rename_file_metadata), + (apply_one_change), (apply_file_changes), (apply_one_file_changes), + (gnome_vfs_metafile_apply_pending_changes), (copy_file_metadata), + (remove_file_metadata), (gnome_vfs_metafile_set_metafile_contents), + (metafile_read_cancel), (can_use_public_metafile), + (metafile_read_mark_done), (metafile_read_done), + (metafile_read_try_public_metafile), + (metafile_read_check_for_directory_callback), + (metafile_read_check_for_directory), (metafile_read_failed), + (metafile_read_done_callback), (metafile_read_restart), + (metafile_read_start), (metafile_write_done), + (metafile_write_failed), (metafile_write_failure_close_callback), + (metafile_write_success_close_callback), (metafile_write_callback), + (metafile_write_create_callback), (metafile_write_start), + (metafile_write), (metafile_write_idle_callback), + (directory_request_write_metafile): + * libgnomevfs/gnome-vfs-metafile-backend.h: + + Add the metafile backend from Nautilus and hack it up so + it works in GnomeVFS. Interfaces should be the same, and + it shouldn't depend on eel (whew, that was a pile of boring + work). + + * libgnomevfs/gnome-vfs-metafile-factory.c: + (nautilus_metafile_factory_class_init), + (nautilus_metafile_factory_init), (destroy), + (nautilus_metafile_factory_new), (free_factory_instance), + (nautilus_metafile_factory_get_instance), (corba_open): + * libgnomevfs/gnome-vfs-metafile-factory.h: + + Add the metafile factory from Nautilus and hack it up so + it works in GnomeVFS. Interfaces should be the same, and + it shouldn't depend on eel (whew, that was a pile of boring + work). + + * libgnomevfs/gnome-vfs-uri.c: (gnome_vfs_uri_list_free), + (is_uri_partial), (gnome_vfs_uri_make_full_from_relative): + * libgnomevfs/gnome-vfs-uri.h: + + Add some code that was formerly in eel-vfs-extensions but + really belongs in GnomeVFSURI. + + * po/ChangeLog: + + * libgnomevfs/eel-cut-n-paste.c: (stolen_strcasecmp), + (stolen_strcmp_case_breaks_ties), (stolen_strcoll), + (stolen_xml_remove_node), (stolen_str_has_prefix), + (stolen_istr_has_prefix), (stolen_str_strip_trailing_chr), + (stolen_strcmp), (stolen_str_is_empty), + (stolen_xml_get_root_children), (stolen_xml_get_children), + (stolen_xml_get_property_for_children): + * libgnomevfs/eel-cut-n-paste.h: + + Functions snitched from eel to make the metafile backend + compile. + + * libgnomevfs/gnome-vfs-helpers.c: (stolen_strcmp), (str_is_equal), + (str_has_prefix), (istr_has_prefix), + (gnome_vfs_x_read_entire_file), (read_file_close_callback), + (read_file_close), (read_file_succeeded), (read_file_failed), + (read_file_read_callback), (read_file_read_chunk), + (read_file_open_callback), + (pthread_gnome_vfs_x_read_file_callback_idle_binder), + (pthread_gnome_vfs_x_read_file_callback_common), + (pthread_gnome_vfs_x_read_file_synchronous_callback), + (pthread_gnome_vfs_x_read_file_asynchronous_callback), + (pthread_gnome_vfs_x_read_file_thread_entry), + (pthread_gnome_vfs_x_read_file_async), + (pthread_gnome_vfs_x_read_file_async_cancel), + (gnome_vfs_x_read_file_async), + (gnome_vfs_x_read_entire_file_async), + (gnome_vfs_x_read_file_cancel), (gnome_vfs_x_uri_is_trash), + (gnome_vfs_x_uri_is_trash_folder), (gnome_vfs_x_uri_is_in_trash), + (gnome_vfs_x_format_uri_for_display), (is_valid_scheme_character), + (has_valid_scheme), (gnome_vfs_x_make_uri_from_input), + (file_uri_from_local_relative_path), + (gnome_vfs_x_make_uri_from_shell_arg), + (gnome_vfs_x_uri_get_basename), (gnome_vfs_x_uri_get_scheme), + (gnome_vfs_x_uri_is_local_scheme), + (gnome_vfs_x_handle_trailing_slashes), + (gnome_vfs_x_make_uri_canonical), + (gnome_vfs_x_make_uri_canonical_strip_fragment), + (gnome_vfs_x_make_uri_from_half_baked_uri), (uris_match), + (gnome_vfs_x_uris_match), + (gnome_vfs_x_uris_match_ignore_fragments), + (gnome_vfs_x_is_remote_uri), + (gnome_vfs_x_make_directory_and_parents), + (gnome_vfs_x_copy_uri_simple): + * libgnomevfs/gnome-vfs-helpers.h: + + GnomeVFSHelpers used to be eel-vfs-extensions. Now moved into + GnomeVFS. It needs to have the checks re-enabled...but I'm + working on that. + + * libgnomevfs/stolen-glib-extensions.c: + (stolen_g_list_exactly_one_item), + (stolen_g_list_more_than_one_item), (stolen_g_list_equal), + (stolen_g_list_copy), (stolen_g_str_list_equal), + (stolen_g_str_list_copy), (stolen_g_str_list_alphabetize), + (stolen_g_list_free_deep_custom), (stolen_g_list_free_deep), + (stolen_g_list_safe_for_each), (stolen_g_list_sort_merge), + (stolen_g_list_is_already_sorted), (stolen_g_list_sort_custom), + (compare_pointers), + (stolen_g_lists_sort_and_check_for_intersection), + (stolen_g_list_partition), (print_key_string), + (free_hash_tables_at_exit), (stolen_g_hash_table_new_free_at_exit), + (flatten_hash_table_element), (stolen_g_hash_table_safe_for_each), + (stolen_g_hash_table_remove_deep_custom), + (stolen_g_hash_table_remove_deep), (destroy_deep_helper), + (stolen_g_hash_table_destroy_deep_custom), + (stolen_g_hash_table_destroy_deep): + * libgnomevfs/stolen-glib-extensions.h: + + Snitched some necessary hash table and list glib extensions + from eel and made them work without the rest of eel. :-P + +2001-07-25 Maciej Stachowiak + + Fix bug 8296 (News Sidebar crashes when not connected to network), + a bunch of other News panel instability, and a bug where Nautilus + would totally crash on entering an invalid http URI in the + location bar: + + * modules/http-method.c: (make_request): initialize socket_buffer + to NULL; if this is not done it will be left set to garbage if + `connect_to_uri' fails so that subsequent attempts to close the + destroy the socket buffer will crash. + +2001-07-18 Martin Baulig + + * libgnomevfs/gnome-vfs-module-shared.c: Move the #include + "gnome-vfs-module-shared.h" after the #define of _BSD_SOURCE + and _LARGEFILE64_SOURCE. + + * libgnomevfs/gnome-vfs-utils.c: #include before + . + +2001-07-17 Chema Celorio + + * configure.in: add a message that displays the target + GNOME platform, either 1.x or 2.0 + +2001-07-16 Darin Adler + + Finished deprecating gnome-vfs-types.h. + + * libgnomevfs/fnmatch.c: + * libgnomevfs/gnome-vfs-app-context.c: + * libgnomevfs/gnome-vfs-app-context.h: + * libgnomevfs/gnome-vfs-application-registry.c: + * libgnomevfs/gnome-vfs-application-registry.h: + * libgnomevfs/gnome-vfs-async-ops.h: + * libgnomevfs/gnome-vfs-backend-private.h: + * libgnomevfs/gnome-vfs-backend.c: + * libgnomevfs/gnome-vfs-callbacks.h: + * libgnomevfs/gnome-vfs-cancellable-ops.c: + * libgnomevfs/gnome-vfs-cancellable-ops.h: + * libgnomevfs/gnome-vfs-cancellation.c: + * libgnomevfs/gnome-vfs-context.c: + * libgnomevfs/gnome-vfs-directory-filter.c: + * libgnomevfs/gnome-vfs-directory-filter.h: + * libgnomevfs/gnome-vfs-directory.c: + * libgnomevfs/gnome-vfs-directory.h: + * libgnomevfs/gnome-vfs-file-info.c: + * libgnomevfs/gnome-vfs-file-info.h: + * libgnomevfs/gnome-vfs-file-size.h.in: + * libgnomevfs/gnome-vfs-find-directory.c: + * libgnomevfs/gnome-vfs-find-directory.h: + * libgnomevfs/gnome-vfs-handle.c: + * libgnomevfs/gnome-vfs-handle.h: + * libgnomevfs/gnome-vfs-inet-connection.c: + * libgnomevfs/gnome-vfs-inet-connection.h: + * libgnomevfs/gnome-vfs-init.c: + * libgnomevfs/gnome-vfs-init.h: + * libgnomevfs/gnome-vfs-iobuf.c: + * libgnomevfs/gnome-vfs-iobuf.h: + * libgnomevfs/gnome-vfs-method-type.h: + * libgnomevfs/gnome-vfs-method.c: (load_module): + * libgnomevfs/gnome-vfs-method.h: + * libgnomevfs/gnome-vfs-mime-handlers.h: + * libgnomevfs/gnome-vfs-mime-info.c: + * libgnomevfs/gnome-vfs-mime-info.h: + * libgnomevfs/gnome-vfs-mime-magic.c: + * libgnomevfs/gnome-vfs-mime-private.h: + * libgnomevfs/gnome-vfs-mime-sniff-buffer-private.h: + * libgnomevfs/gnome-vfs-mime-sniff-buffer.c: + * libgnomevfs/gnome-vfs-mime-sniff-buffer.h: + * libgnomevfs/gnome-vfs-mime.c: + * libgnomevfs/gnome-vfs-mime.h: + * libgnomevfs/gnome-vfs-module-api.h: + * libgnomevfs/gnome-vfs-module-shared.c: + * libgnomevfs/gnome-vfs-module.h: + * libgnomevfs/gnome-vfs-ops.c: + * libgnomevfs/gnome-vfs-ops.h: + * libgnomevfs/gnome-vfs-parse-ls.c: + * libgnomevfs/gnome-vfs-parse-ls.h: + * libgnomevfs/gnome-vfs-private-utils.c: + * libgnomevfs/gnome-vfs-private-utils.h: + * libgnomevfs/gnome-vfs-private.h: + * libgnomevfs/gnome-vfs-process.c: + * libgnomevfs/gnome-vfs-process.h: + * libgnomevfs/gnome-vfs-regexp-filter.c: + * libgnomevfs/gnome-vfs-result.c: + * libgnomevfs/gnome-vfs-seekable.c: + * libgnomevfs/gnome-vfs-seekable.h: + * libgnomevfs/gnome-vfs-shellpattern-filter.c: + * libgnomevfs/gnome-vfs-shellpattern-filter.h: + * libgnomevfs/gnome-vfs-socket-buffer.c: + * libgnomevfs/gnome-vfs-socket.c: + * libgnomevfs/gnome-vfs-socket.h: + * libgnomevfs/gnome-vfs-ssl.c: + * libgnomevfs/gnome-vfs-ssl.h: + * libgnomevfs/gnome-vfs-standard-callbacks.h: + * libgnomevfs/gnome-vfs-transform.h: + * libgnomevfs/gnome-vfs-types.h: + * libgnomevfs/gnome-vfs-uri.c: + * libgnomevfs/gnome-vfs-uri.h: + * libgnomevfs/gnome-vfs-utils.c: + * libgnomevfs/gnome-vfs-utils.h: + * libgnomevfs/gnome-vfs-xfer.c: + * libgnomevfs/gnome-vfs-xfer.h: + * libgnomevfs/gnome-vfs.h: + * modules/Makefile.am: + * modules/bzip2-method.c: + * modules/cdda-method.c: + * modules/ftp-method.c: + * modules/gzip-method.c: + * modules/http-authn.h: + * modules/http-cache.h: + * modules/translate-method.c: + * test/test-module-selftest.c: + * test/test-uri.c: + More changes to includes so that nothing inside gnome-vfs itself + ever includes gnome-vfs-types.h. Also make sure that all .c files + include the corresponding .h file first, so we know that the + files have enough includes to stand alone. Also switched from + size_t and ssize_t to gsize and gssize in most places. + + * libgnomevfs/gnome-vfs-async-ops.c: + * libgnomevfs/gnome-vfs-callbacks.c: + * libgnomevfs/gnome-vfs-module-api.c: + * libgnomevfs/gnome-vfs-module.c: + * libgnomevfs/gnome-vfs-private.c: + * libgnomevfs/gnome-vfs-transform.c: + For testing purposes, made files that just include a particular + header for public headers that have no corresponding .c file. This + tests that the headers have enough includes to stand alone. + + * libgnomevfs/gnome-vfs-configuration.c: (configuration_load): + Change code to not use alloca any more, and handle a too-big + configuration file without resulting in buffer overflow. + + * libgnomevfs/gnome-vfs-method-type.h: + * libgnomevfs/gnome-vfs-private-types.h: + * libgnomevfs/gnome-vfs-socket-private.h: + * modules/bzip2-method.h: + * modules/gzip-method.h: + Removed some unneeded files. + + * libgnomevfs/Makefile.am: + Updated to reflect changes above. + +2001-07-16 Darin Adler + + * modules/gconf-method.c: Fix const bug in code that was not + being compiled because HAVE_GCONF was off. + +2001-07-16 Darin Adler + + * modules/Makefile.am: Had to remove HAVE_GCONF from here to + make things build again. + + * AUTHORS: Updated my email address. + +2001-07-15 Darin Adler + + The checks for gconf were always coming out false due to + differences in name (gconf vs. gconf-2, etc.). So I re-enabled + the dependency on gconf. Since gconf seems to be working for + GNOME 2 now I hope this is not a problem. + + * configure.in: Always require GCONF and define HAVE_GCONF. + +2001-07-14 Anders Carlsson + + * libgnomevfs/gnome-vfs-mime-handlers.c (join_str_list): Remove a + duplicate call to g_new. + +2001-07-12 Darin Adler + + * .cvsignore: Ignore sgml directory too. + +2001-07-12 Laszlo Peter + + Fix some portability issues. + + * libgnomevfs/gnome-vfs-ssl.c: a struct needs to have a member. + + * libgnomevfs/gnome-vfs-context.c: use G_GNUC_FUNCTION instead + of __FUNCTION__. + +2001-07-11 Martin Baulig + + We now require autoconf 2.50b on the GNOME 2 platform. + You can get it from either alpha.gnu.org or + ftp://master.gnome.org/people/martin/vicious-bootstraps. + + * acinclude.m4: Make this work with autoconf 2.50b. + + * configure.in: Require autoconf 2.50b. + +2001-07-06 Havoc Pennington + + * libgnomevfs/gnome-vfs-uri.c (uri_matches_as_parent): handle case + where uri->text is NULL + +2001-07-09 Ramiro Estrugo + + * libgnomevfs/gnome-vfs-file-info.h: + Include some needed dependencies to fix breakage caused by the + last bunch of checkins. + +2001-07-07 Seth Nickell + + * libgnomevfs/gnome-vfs-method.h: + * libgnomevfs/gnome-vfs-types.h: + + Tweak includes a little more. + + * modules/pipe-method.c: + * modules/ssh-method.c: + + Make modules include more cleanly. + +2001-07-07 Seth Nickell + + Deprecate (other than a couple structs I didn't find a home + for) gnome-vfs-types.h in favour of having types distributed + throughout corresponding .h files. The primary motivation for + this is to achieve better docs: rather than clustering all the + type declarations into a big muddy section called "Types", + types are defined in relavent sections. Secondary effects are + a more obvious include path and the ability to include more + files independently. + + * doc/tmpl/gnome-vfs-unused.sgml: + * doc/tmpl/types.sgml: + * doc/tmpl/uri.sgml: + * doc/tmpl/utils.sgml: + * doc/tmpl/xfer.sgml: + + gtk-doc has updated the base sgml files to deal with the new + locations of declarations. + + * libgnomevfs/Makefile.am: + + Add gnome-vfs-callbacks.h, gnome-vfs-transform.h, and + gnome-vfs-method-type.h to the include header list. + + * libgnomevfs/gnome-vfs-app-context.c: + * libgnomevfs/gnome-vfs-app-context.h: + * libgnomevfs/gnome-vfs-application-registry.h: + * libgnomevfs/gnome-vfs-async-ops.h: + * libgnomevfs/gnome-vfs-backend.c: + * libgnomevfs/gnome-vfs-callbacks.h: + * libgnomevfs/gnome-vfs-cancellable-ops.h: + * libgnomevfs/gnome-vfs-cancellation.h: + * libgnomevfs/gnome-vfs-context.c: + * libgnomevfs/gnome-vfs-context.h: + * libgnomevfs/gnome-vfs-directory-filter.h: + * libgnomevfs/gnome-vfs-file-info.h: + * libgnomevfs/gnome-vfs-find-directory.h: + * libgnomevfs/gnome-vfs-handle.h: + * libgnomevfs/gnome-vfs-inet-connection.h: + * libgnomevfs/gnome-vfs-iobuf.h: + * libgnomevfs/gnome-vfs-method-type.h: + * libgnomevfs/gnome-vfs-method.c: + * libgnomevfs/gnome-vfs-method.h: + * libgnomevfs/gnome-vfs-mime-info.h: + * libgnomevfs/gnome-vfs-mime-sniff-buffer.c: + * libgnomevfs/gnome-vfs-mime-sniff-buffer.h: + * libgnomevfs/gnome-vfs-mime.h: + * libgnomevfs/gnome-vfs-module-shared.h: + * libgnomevfs/gnome-vfs-ops.h: + * libgnomevfs/gnome-vfs-private-types.h: + * libgnomevfs/gnome-vfs-private-utils.h: + * libgnomevfs/gnome-vfs-regexp-filter.h: + * libgnomevfs/gnome-vfs-result.h: + * libgnomevfs/gnome-vfs-shellpattern-filter.h: + * libgnomevfs/gnome-vfs-socket.h: + * libgnomevfs/gnome-vfs-transform.h: + * libgnomevfs/gnome-vfs-types.h: + * libgnomevfs/gnome-vfs-uri.c: + * libgnomevfs/gnome-vfs-uri.h: + * libgnomevfs/gnome-vfs-utils.h: + * libgnomevfs/gnome-vfs-xfer.h: + * libgnomevfs/gnome-vfs.h: + + Shuffling around includes and struct declerations + to achieve the cleanest arrangement that also minimizes + changes to applications like Nautilus that already heavily + depend on GnomeVFS. + +2001-07-05 Darin Adler + + * libgnomevfs/gnome-vfs-ssl.c: Added missing + include. + +2001-07-04 Ramiro Estrugo + + * configure.in: + Dont use 'glib-config-2.0' when building in the GNOME2 platform. + There is no such config script anymore because these are history + in the GNOME2 platform. Use pkgconfig technology instead. + Continue to use 'glib-config' for the GNOME1 platform. + +2001-07-02 Seth Nickell + + * configure.in: + + Fix ORBit configuration problem on GNOME1 platform. + + * po/ChangeLog: + Long live stupid gettext. + +2001-06-26 Darin Adler + + * .cvsignore: Ignore ABOUT-NLS, but not obsolete *Conf.sh files. + * Makefile.am: Eliminate vfspthreadConf.sh. + * vfscorbaConf.sh.in: Remove. + * vfspthreadConf.sh.in: Remove. + * devel-docs/.cvsignore: Remove since this is now an empty directory. + * devel-docs/gnome-vfs/.cvsignore: Remove since this is now an empty + directory. + + * libgnomevfs/gnome-vfs-ops.h: Add include of gnome-vfs-types.h so + you can include this header on its own. + +2001-06-25 Sri Ramkrishna + + Rolled changes from HEAD. + + * libgnomevfs/gnome-vfs-application-registry.c: + Added gtkdocs for gnome_vfs_application_registry_* + +2001-06-20 Peter Williams + + * configure.in (autodetected_gnome_2): Fix a syntax error in the test + expression. + +2001-06-19 Peter Williams + + * gnome-vfs-2.0.pc.in (prefix): Fix totally + broken prefix=/gnome/head/INSTALL. Whoops. + +2001-06-15 Havoc Pennington + + * modules/gconf-method.c (do_get_file_info): fix one mem leak and + one use of uninitialized memory. + (do_open_directory): compensate for GConf's + list-absolute-paths-in-directories braindamage + +2001-06-15 Martin Baulig + + If we ever need to revert this (for instance, when GConf is fixed for GNOME 2), + the patch is at http://cip.uni-trier.de/baulig/misc/gnome-vfs.optional-gconf.patch. + + * configure.in: Made the GConf dependency optional. At least temporarily, + we need to make GConf optional in the GNOME 2.0 core libraries as it blocks + testing on a GNOME 1.x desktop. + (HAVE_GCONF): New automake conditional. + + * libgnomevfs/gnome-vfs-mime-handlers.c (get_user_level): Always return "novice" + if we don't HAVE_GCONF. + + * modules/Makefile.am: Only compile the gconf and http modules if we HAVE_GCONF. + + * modules/ftp-method.c (vfs_module_init): Don't initialize GConf if we don't have it. + +2001-06-11 Carlos Perelló Marín + + * modules/cdda-method.c: Fixed to compile with Gtk 2.0 + +2001-06-10 Ian McKellar + + * libgnomevfs/gnome-vfs-standard-callbacks.h: + Initial work to add a status-message callback. + + * libgnomevfs/gnome-vfs-uri.c: (is_uri_relative), + (remove_internal_relative_components), + (make_full_uri_from_relative), (gnome_vfs_uri_relative_new): + * libgnomevfs/gnome-vfs-uri.h: + Added gnome_vfs_uri_relative_new which does relative URI resolution. + + * modules/Makefile.am: + * modules/default-modules.conf: + * modules/ssh-method.c: (ssh_connect), (ssh_destroy), (ssh_read), + (ssh_write), (ssh_escape), (ssh_send), (do_open), (do_create), + (do_close), (do_read), (do_write), (do_open_directory), + (do_close_directory), (do_read_directory), (do_get_file_info), + (do_get_file_info_from_handle), (do_is_local), (vfs_module_init), + (vfs_module_shutdown): + * modules/ssh-method.h: + Added ssl-method. Its currently quite primitive and only works if you + don't need password authentication (ie: you are running ssh-agent and + have your key in the remote machine's authorized keys) + + * modules/ssl-modules.conf: + I forgot to upload this before :( Thanks Robin. + + * test/test-callback.c: (main): + Allow the test URI to be specified. + +2001-06-07 Robin * Slomkowski + + * modules/ssl-modules.conf: created this so the build would + work. + +2001-06-06 Glynn Foster + + * libgnomevfs/gnome-vfs-directory.c: + gnome_vfs_directory_list_load (..) Add a petty code comment + so that people looking at the API's don't have to root around + the code trying to figure what is returned in the GList + +2001-06-06 Seth Nickell + + * doc/about.sgml: + * doc/tmpl/gnome-vfs-unused.sgml: + + ... thanks Havoc. + +2001-06-03 Maciej Stachowiak + + * libgnomevfs/gnome-vfs-socket-buffer.h, + libgnomevfs/gnome-vfs-socket-buffer.c (buffer_init, + gnome_vfs_socket_buffer_new, gnome_vfs_socket_buffer_destroy, + refill_input_buffer, gnome_vfs_socket_buffer_read, + gnome_vfs_socket_buffer_peekc, flush, + gnome_vfs_socket_buffer_write, gnome_vfs_socket_buffer_flush): + Completed reverse-engineering. + + * libgnomevfs/gnome-vfs-socket.h, + libgnomevfs/gnome-vfs-socket.c (gnome_vfs_socket_write, + (gnome_vfs_socket_read: Related cleanups. + + * modules/http-method.c (xmit_request, http_handle_close): Style + fixes. + +2001-06-03 Maciej Stachowiak + + * libgnomevfs/gnome-vfs-socket.h, libgnomevfs/gnome-vfs-socket.c + (gnome_vfs_socket_new, gnome_vfs_socket_write, + gnome_vfs_socket_close, gnome_vfs_socket_read): Continued Seth's + reverse-engineering of the missing pieces of Ian's SSL code. + + * libgnomevfs/gnome-vfs-inet-connection.c + (gnome_vfs_inet_connection_destroy, + gnome_vfs_inet_connection_close): Minor tweaks. + * libgnomevfs/gnome-vfs-ssl.c (gnome_vfs_ssl_destroy): Likewise. + + * ABOUT-NLS: Removed (this is added by autogen). + +2001-06-03 Seth Nickell + + * doc/Makefile.am: + * doc/gnome-vfs-docs.sgml: + * doc/gnome-vfs-sections.txt: + * doc/tmpl/uri.sgml: + * doc/writing-modules.sgml: + + Start writing more "tutorial like" documentation for basic + I/O operations. + + * libgnomevfs/gnome-vfs-socket-buffer.c: + (gnome_vfs_socket_buffer_new), (gnome_vfs_socket_buffer_read), + (gnome_vfs_socket_buffer_peekc), (gnome_vfs_socket_buffer_write), + (gnome_vfs_socket_buffer_flush), (gnome_vfs_socket_buffer_destroy): + * libgnomevfs/gnome-vfs-socket-buffer.h: + * libgnomevfs/gnome-vfs-socket.c: (gnome_vfs_socket_write), + (gnome_vfs_socket_close), (gnome_vfs_socket_read): + * libgnomevfs/gnome-vfs-socket.h: + + Write skeletons for functions to get http-method to compile. + ***WARNING*** - http is probably broken at this point!!! + +2001-06-02 Seth Nickell + + * doc/gnome-vfs-docs.sgml: + * doc/gnome-vfs-sections.txt: + * doc/tmpl/directory.sgml: + * doc/tmpl/find-directory.sgml: + * doc/tmpl/gnome-vfs-unused.sgml: + * doc/tmpl/ssl.sgml: + * doc/tmpl/types.sgml: + * doc/tmpl/uri.sgml: + + Add some more descrptions, shuffle functions around + between files to reduce the number of sections. + + * libgnomevfs/gnome-vfs-constants.h: + + Move the four constants contained in this file to + gnome-vfs-uri.h (which is a better home anyway) and + remove the file. + + * libgnomevfs/gnome-vfs-uri.h: + + Move some constants here from gnome-vfs-constants.h + + * libgnomevfs/gnome-vfs.h: + * libgnomevfs/gnome-vfs-private-utils.c: + * libgnomevfs/Makefile.am: + + Change includes and build to remove gnome-vfs-constants.h. + +2001-06-02 Seth Nickell + + * libgnomevfs/gnome-vfs-socket-buffer.c: + * libgnomevfs/gnome-vfs-socket-buffer.h: + * libgnomevfs/gnome-vfs-socket-private.h: + * libgnomevfs/gnome-vfs-socket.c: (gnome_vfs_socket_new): + * libgnomevfs/gnome-vfs-socket.h: + + I think Ian forgot these in his checkin. WARNING!!! These + are not the actual files but skeleton with enough declarations + to get GnomeVFS compiling again. Must get the real things + checked in :-) + +2001-06-01 Seth Nickell + + * configure.in: + + Removed cruft directories. + +2001-05-31 Ian McKellar + + * libgnomevfs/Makefile.am: + * libgnomevfs/gnome-vfs-inet-connection.c: + (gnome_vfs_inet_connection_create), + (gnome_vfs_inet_connection_get_iobuf), + (gnome_vfs_inet_connection_get_fd), + (gnome_vfs_inet_connection_read), + (gnome_vfs_inet_connection_write), + (gnome_vfs_inet_connection_to_socket): + * libgnomevfs/gnome-vfs-inet-connection.h: + * libgnomevfs/gnome-vfs-iobuf.c: (gnome_vfs_iobuf_flush): + * libgnomevfs/gnome-vfs-result.c: + * libgnomevfs/gnome-vfs-ssl.c: (gnome_vfs_ssl_create), + (gnome_vfs_ssl_create_from_fd), (gnome_vfs_ssl_write), + (gnome_vfs_ssl_destroy), (gnome_vfs_ssl_to_socket): + * libgnomevfs/gnome-vfs-ssl.h: + * libgnomevfs/gnome-vfs-types.h: + * modules/Makefile.am: + * modules/file-method.c: (do_read): + * modules/http-method.c: (http_file_handle_new), (get_header), + (create_handle), (https_proxy), (connect_to_uri), (xmit_request), + (make_request), (http_handle_close), (do_open), (do_read), + (propfind_href_to_vfs_uri), (do_open_directory): + * test/test-ssl.c: (show_result), (main): + Added SSL and HTTPS support. + +2001-05-31 Robin * Slomkowski + + * gnome-vfs.spec.in:removed html/*.txt line as it doesn't seem + to get populated. + +2001-05-30 Seth Nickell + + * devel-docs/gnome-vfs/tmpl/libgnome-vfs.sgml: + + Get a stray file that missed the delet. + +2001-05-30 Seth Nickell + + * devel-docs/Makefile.am: + * devel-docs/gnome-vfs/Makefile.am: + * devel-docs/gnome-vfs/gnome-vfs-docs.sgml: + * devel-docs/gnome-vfs/gnome-vfs-sections.txt: + * devel-docs/gnome-vfs/tmpl/gnome-vfs-mime-info.sgml: + * devel-docs/gnome-vfs/tmpl/gnome-vfs-mime.sgml: + + Nix the duplicate api docs since we've been actively working + on doc/ instead. + +2001-05-30 Seth Nickell + + * doc/gnome-vfs-docs.sgml: + + Start organizing higher level documentation structure + and preparing sections on the most common parts application + developers will have to use. Hopefully at this point + somebody could use the docs as an API reference to the + POSIX like synchronous calls. + + * doc/tmpl/application-registry.sgml: + * doc/tmpl/async-ops.sgml: + * doc/tmpl/directory.sgml: + * doc/tmpl/find-directory.sgml: + * doc/tmpl/mime-handlers.sgml: + * doc/tmpl/mime-magic.sgml: + * doc/tmpl/mime-sniff-buffer.sgml: + * doc/tmpl/mime.sgml: + * doc/tmpl/ops.sgml: + * doc/tmpl/result.sgml: + * doc/tmpl/types.sgml: + * doc/tmpl/uri.sgml: + * doc/tmpl/utils.sgml: + * doc/tmpl/xfer.sgml: + + Write descriptions, titles, and short descriptions as + well as perform some re-organization of the documentation. + +2001-05-28 Seth Nickell + + * doc/gnome-vfs-docs.sgml: + + Fix entities so all subcategories are generated, and in alphabetical order. + + * doc/tmpl/mime-handlers.sgml: + + Add a better title (yah, whatever). + +Mon May 28 15:49:55 2001 Jonathan Blandford + + * doc/gnome-vfs-docs.sgml: fix case problem. + +2001-05-27 Seth Nickell + + * devel-docs/gnome-vfs/tmpl/gnome-vfs-mime-info.sgml: + * devel-docs/gnome-vfs/tmpl/gnome-vfs-mime.sgml: + * doc/tmpl/gnome-vfs-unused.sgml: + * doc/tmpl/list-sort.sgml: + * doc/tmpl/mime-handlers.sgml: + + gtk-doc apparently wants to change these files from its + auto-scans (found some new functions). Owen thinks I should + just check in the changes. I don't know gtk-doc procedure, so + I'm trusting his judgement. + + * libgnomevfs/gnome-vfs-mime-handlers.c: + + Documented all public functions. + + * libgnomevfs/gnome-vfs-mime-handlers.h: + + Changed some arguments to match their name/usage within the + corresponding declarations within gnome-vfs-mime-handlers.c. + +2001-05-27 Maciej Stachowiak + + reviewed by: Seth Nickell + + * modules/http-method.c (parse_status): Handle technically invalid + http replies from ShoutCast and IceCast. + +2001-05-25 Seth Nickell + + * HACKING: Fix typos, bring it up-to-date. + + * TODO: Started a preliminary GnomeVFS 2.0 TODO list. + Removed some crufty TODO items. + +2001-05-23 Robin * Slomkowski + + * data/mime/gnome-vfs.keys.in: changed non-ascii mu to "mu" + * po/ChangeLog: + * po/az.po: + * po/ca.po: + * po/da.po: + * po/de.po: + * po/el.po: + * po/es.po: + * po/fi.po: + * po/fr.po: + * po/ga.po: + * po/gl.po: + * po/hu.po: + * po/it.po: + * po/ja.po: + * po/ko.po: + * po/lt.po: + * po/nl.po: + * po/nn.po: + * po/no.po: + * po/pl.po: + * po/pt_BR.po: + * po/ro.po: + * po/ru.po: + * po/sk.po: + * po/sl.po: + * po/sv.po: + * po/tr.po: + * po/uk.po: + * po/wa.po: + changed non-ascii mu to "mu" in the msgid + +2001-05-23 Chema Celorio + + * autogen.sh (PKG_NAME): typo + +2001-05-17 Robin * Slomkowski + + * libgnomevfs/gnome-vfs-private.h: removed #include for + gnome-vfs-list-sort.h + +2001-05-17 Robin * Slomkowski + + * doc/Makefile.am: + (dist-hook): checked for the existence of dirs + before creating them. + (dist-hook-local): commented out this whole section + as it broke make dist as there are no TEXT dirs. + +2001-05-17 Jonathan Blandford + + * configure.in: + * Makefile.am: + * docs/*/*: + Initial support for gtk-doc documentation. + +2001-05-17 Darin Adler + + * libgnomevfs/Makefile.am: + * libgnomevfs/gnome-vfs-list-sort.c: + * libgnomevfs/gnome-vfs-list-sort.h: + Removed the unused gnome_vfs_list_sort function. The good news + is that glib 2 has this same function (g_list_sort_with_data). + + * test/.cvsignore: Ignore the new test-ssl test program. + +2001-05-14 Ian McKellar + + * libgnomevfs/Makefile.am: + Build fix. + +2001-05-14 Ian McKellar + + * README.SSL: + * acconfig.h: + * configure.in: + * libgnomevfs/Makefile.am: + * libgnomevfs/gnome-vfs-init.c: (gnome_vfs_init): + * libgnomevfs/gnome-vfs-ssl-private.h: + * libgnomevfs/gnome-vfs-ssl.c: + (gnome_vfs_ssl_init), (gnome_vfs_ssl_enabled), (gnome_vfs_ssl_new), + (gnome_vfs_ssl_new_from_uri), (gnome_vfs_ssl_read), + (gnome_vfs_ssl_write), (gnome_vfs_ssl_destroy): + * libgnomevfs/gnome-vfs-ssl.h: + Added an OpenSSL based SSL abstraction to gnome-vfs. This is so that + modules (particularly the http module) will be able to implement SSL + support. + + * test/Makefile.am: + * test/test-ssl.c: (show_result), (main): + Added a very simple test program for the SSL routines. + +2001-05-16 Michael K. Fleming + + gnome_vfs_app_context_get_current was not addref'ing + the context it returned if it had to create a default context. + This caused crashes in async operations in apps that do not use + the app context mechanism. + + * libgnomevfs/gnome-vfs-app-context.c: + (gnome_vfs_app_context_peek_current_internal), + (gnome_vfs_app_context_peek_current), + (gnome_vfs_app_context_get_current): + +2001-05-16 Darin Adler + + * libgnomevfs/gnome-vfs-app-context.c: + (gnome_vfs_app_context_unref): Fix double-free. + +2001-05-15 Maciej Stachowiak + + * libgnomevfs-pthread/gnome-vfs-async-ops.c, + libgnomevfs/gnome-vfs-app-context.c, + libgnomevfs/gnome-vfs-app-context.h, libgnomevfs/gnome-vfs-init.c, + libgnomevfs/gnome-vfs-module-api.h, modules/http-authn.h, + test/test-ssl.c: Add trailing newlines to files that didn't have + them, and include headers needed to compile on my system. + +2001-05-14 Michael K. Fleming + + reviewed by: Ian McKellar + + GnomeVFSAppContext and GnomeVFSCallback implementation. + + Allows application to register for module-defined synchronous callbacks. + + * libgnomevfs-pthread/gnome-vfs-async-job-map.c: + (gnome_vfs_async_job_add_callback): + * libgnomevfs-pthread/gnome-vfs-async-ops.c: + * libgnomevfs-pthread/gnome-vfs-job.c: + (dispatch_callback_callback), (dispatch_sync_job_callback), + (gnome_vfs_job_execute), (gnome_vfs_job_module_cancel), + (set_current_job), (clear_current_job), + (pthread_gnome_vfs_get_current_context), + (pthread_gnome_vfs_dispatch_callback): + * libgnomevfs-pthread/gnome-vfs-job.h: + * libgnomevfs/Makefile.am: + * libgnomevfs/gnome-vfs-app-context.c: + * libgnomevfs/gnome-vfs-app-context.h: + * libgnomevfs/gnome-vfs-async-ops.h: + * libgnomevfs/gnome-vfs-backend-private.h: + * libgnomevfs/gnome-vfs-backend.c: + (gnome_vfs_backend_get_current_context), + (gnome_vfs_backend_dispatch_callback): + * libgnomevfs/gnome-vfs-cancellation.c: + (gnome_vfs_cancellation_cancel): + * libgnomevfs/gnome-vfs-context.c: (gnome_vfs_context_new), + (gnome_vfs_context_ref), (gnome_vfs_context_unref), + (gnome_vfs_context_get_cancellation), + (gnome_vfs_context_peek_current), + (gnome_vfs_context_check_cancellation_current), + (gnome_vfs_context_peek_app_context), + (gnome_vfs_context_peek_app_context_current): + * libgnomevfs/gnome-vfs-context.h: + * libgnomevfs/gnome-vfs-init.c: (gnome_vfs_init), + (gnome_vfs_is_primary_thread): + * libgnomevfs/gnome-vfs-messages.c: + * libgnomevfs/gnome-vfs-messages.h: + * libgnomevfs/gnome-vfs-module-api.h: + * libgnomevfs/gnome-vfs-module-shared.h: + * libgnomevfs/gnome-vfs-private.h: + * libgnomevfs/gnome-vfs-standard-callbacks.h: + * libgnomevfs/gnome-vfs-types.h: + * libgnomevfs/gnome-vfs-utils.h: + * modules/Makefile.am: + * modules/http-authn.c: + * modules/http-authn.h: + * modules/http-cache.c: + * modules/http-cache.h: + * modules/http-method.c: + * modules/http-method.h: + + Split http module into 3 files; implemented basic and proxy + authentication callbacks and a simple authentication jar. + + * test/.cvsignore: + * test/Makefile.am: + * test/test-callback.c: (authn_callback), + (app_context_destroy_notify), (open_callback), (close_callback), + (stop_after_log), (make_asserts_break), (main): + * test/test-module-selftest.c: (stop_after_log), + (make_asserts_break), (main): + +2001-05-13 Maciej Stachowiak + + * modules/http-method.c: Cleaned up formatting, minor style + issues; fixed a bug in `do_check_same_fs'. + +2001-05-12 Maciej Stachowiak + + * devel-docs/gnome-vfs/Makefile.am: Fix build for people who don't + have gtk-doc installed. + +2001-05-09 Darin Adler + + * libgnomevfs-pthread/gnome-vfs-job.h: Added dummy member to + avoid having an empty struct. + +2001-05-08 Ian McKellar + + * devel-docs/gnome-vfs/Makefile.am: + * devel-docs/gnome-vfs/gnome-vfs-decl.txt: + * devel-docs/gnome-vfs/gnome-vfs-docs.sgml: + * devel-docs/gnome-vfs/gnome-vfs-sections.txt: + Told gtkdoc to pick up (almost) all the header files. + + * libgnomevfs/gnome-vfs-process.h: + Made some changes to make gtkdoc happy. + +==== gnome-vfs 1.0.1 ==== + +2001-05-07 Darin Adler + + reviewed by: Ramiro Estrugo + + * modules/Makefile.am: + * po/POTFILES.in: + Removed some dead code and fixed build so that CDDA module source + files are included in the tarball even if it's made on a system + without CDDA installed. + +2001-05-07 Darin Adler + + * libgnomevfs/gnome-vfs-mime-info.c: (write_back_mime_user_file): + Remove message that threatens users with death. + +2001-05-03 John Sullivan + + reviewed by: Darin Adler + + Fixed bug 8240 (Help document viewing is broken) + + * modules/pipe-method.c: (do_open): Added more characters + to the "safe characters" set. + +2001-05-02 Ian McKellar + + reviewed by: Darin Adler + + * modules/pipe-method.c: (do_open): + Only pass known safe characters to popen. + +2001-05-02 Ramiro Estrugo + + * configure.in: + Cant use pkgconfig for detecting libxml unless we are sure that + the libxml we are using exports libxml.pc. Currently + gnome-vfs/nautilus hackers use libxml 1.8.10 which doesnt export + libxml.pc. Do the libxml check the "old fashioned" way for now. + +2001-05-01 Darin Adler + + Fixes to make documentation work again after the "pipe" method + fix. + + * libgnomevfs/gnome-vfs-private-utils.h: + * libgnomevfs/gnome-vfs-uri.c: (set_uri_element): Add more methods + to the list that are allowed to have ? characters in them. This is + required to make help work right now that we don't translate so + early. I'm starting to think it should be "file" that's special + cased. + (gnome_vfs_uri_new): Allow transformation. + (gnome_vfs_uri_new_private): Add a flag to control whether + transformation can happen. + + * libgnomevfs/gnome-vfs-utils.c: (gnome_vfs_make_uri_canonical): + Don't do any transformation. + + * modules/translate-method.c: (tr_handle_exec), + (tr_uri_translate): Allow transformation. + +2001-05-01 Darin Adler + + reviewed by: Mike Fleming + + Plugged the security hole created by the "pipe" method. It's now + only allowed indirectly through the translate method. + + * libgnomevfs/gnome-vfs-private-utils.h: + * libgnomevfs/gnome-vfs-uri.c: (gnome_vfs_uri_new): Don't allow + unsafe URIs. + (gnome_vfs_uri_new_private): Take a parameter which determines if + unsafe URIs are allowed, and don't allow any "pipe" URIs unless + unsafe ones are explicitly allowed. + * libgnomevfs/gnome-vfs-utils.c: (gnome_vfs_make_uri_canonical): + Allow unsafe URIs. + * modules/translate-method.c: (tr_handle_exec), + (tr_uri_translate): Call gnome_vfs_uri_new_private so that the + result of a translate is allowed to be an unsafe URI. + + * libgnomevfs/gnome-vfs-mime-info.c: (does_string_contain_caps): + Renamed from does_string_contains_caps. + + * test/test-uri.c: (main): Updated tests affected by the fact that + gnome_vfs_uri_new won't accept "pipe" URIs any more. + + * doc/mime-data-specification.txt: Remove trailing keys. + +2001-05-01 Seth Nickell + + * test/mime-test-files/somepage.php: + * test/mime-test-files/ + + Add a directory for placing files for doing checks on how + GnomeVFS recognizes their MIME type. + +Fri Apr 27 13:32:32 2001 Jonathan Blandford + + * libgnomevfs/gnome-vfs-configuration.c + (gnome_vfs_configuration_init): load from GNOME_VFS_MODULE_CFGDIR, + and ~/.gnome/vfs/modules. + (configuration_load): Change behaviour to not create the + configuration anymore, but just load it. + (maybe_reload): potentially reload the config files if they + change. + +2001-04-25 Darin Adler + + * check-mime.pl: Check that the applications file entries are in + alphabetical order. + +2001-04-25 Darin Adler + + reviewed by: Pavel Cisler + + * modules/file-method.c: (get_stat_info): Fix bug where it would + return GNOME_VFS_NOT_FOUND for broken links, even though it went + to the trouble of handling them properly. + +2001-04-17 Darin Adler + + * libgnomevfs/gnome-vfs-utils.c: + (gnome_vfs_get_local_path_from_uri): Loosen rule so that URLs that + say "file:/etc/passwd" will be accepted. + * test/test-uri.c: (main): Update test to match. + +2001-04-14 Dan Winship + + * libgnomevfs/gnome-vfs-mime-info.c (get_value_real): Plug a + memory leak. + + * libgnomevfs/gnome-vfs-mime-handlers.c + (gnome_vfs_mime_get_short_list_applications): Ditto. + +2001-04-14 Maciej Stachowiak + + * modules/translate-method.c (tr_uri_translate): Be less tricky so + that translate patterns that include a hostname, port, user, etc + will work properly. + +2001-04-13 Darin Adler + + * gnome-vfs.spec.in: Remove the slave program from the spec + file, now that we don't use it any more. + +2001-04-13 Darin Adler + + * configure.in: Missed Makefile list. + +2001-04-13 Darin Adler + + * acconfig.h: + * configure.in: + Eliminate --disable-libefs, --with-default-backend, and + GNOME_VFS_DEFAULT_BACKEND. + + * libgnomevfs/gnome-vfs-xfer.c: (init_progress): Initialize the + file index to 0, since we now increment before each item. + (at_end): Helper function. + (call_progress_often_internal): Shared code for the two "often" + versions of the call_progress function. The only change is to + always send out progress once at the end. + (call_progress_often), (call_progress_with_uris_often): Use new + function to share most of the code. + (remove_file): Bump the file index before dealing with the file. + (remove_directory): Bump the file index before dealing with the + directory. + (copy_file): Don't bump the file index, because that's now the + caller's responsibility. + (copy_directory): Don't bump the file index for the directory + itself, because that's now the caller's responsibility, but do + bump the file index before calling copy_file, copy_directory, + or copy_symlink. + (copy_items): Bump the file index before calling copy_file, + copy_directory, or copy_symlink. + (gnome_vfs_xfer_uri_internal): Reset the file index to 0, since we + now increment before each item. + + * libgnomevfs/gnome-vfs-mime.h: + * libgnomevfs/gnome-vfs-mime.c: Removed gnome_uri functions that + were in here without gnome_vfs-prefixed names. No one was using + these versions. + + * Makefile.am: + * libgnomevfs-corba/.cvsignore: + * libgnomevfs-corba/Makefile.am: + * libgnomevfs-corba/gnome-vfs-async-ops.c: + * libgnomevfs-corba/gnome-vfs-corba.c: + * libgnomevfs-corba/gnome-vfs-corba.h: + * libgnomevfs-corba/gnome-vfs-slave-launch.c: + * libgnomevfs-corba/gnome-vfs-slave-launch.h: + * libgnomevfs-corba/gnome-vfs-slave-notify.c: + * libgnomevfs-corba/gnome-vfs-slave-notify.h: + * libgnomevfs-corba/gnome-vfs-slave-process.c: + * libgnomevfs-corba/gnome-vfs-slave-process.h: + * libgnomevfs-corba/gnome-vfs-slave.c: + Remove CORBA back end. + + * libgnomevfs/gnome-vfs-backend.c: (gnome_vfs_backend_loadinit): + Hard-code "pthread" instead of using GNOME_VFS_DEFAULT_BACKEND. + Soon we might get rid of the separate backend completely. + + * test/.cvsignore: + * test/Makefile.am: + Remove special cases for tests that used to run on both back ends, + and make them build in a normal simple way instead. + + * mime-type-capplet/.cvsignore: + * mime-type-capplet/Makefile.am: + * mime-type-capplet/file-types-capplet.desktop.in: + * mime-type-capplet/libuuid/.cvsignore: + * mime-type-capplet/libuuid/Makefile.am: + * mime-type-capplet/libuuid/clear.c: + * mime-type-capplet/libuuid/compare.c: + * mime-type-capplet/libuuid/copy.c: + * mime-type-capplet/libuuid/gen_uuid.c: + * mime-type-capplet/libuuid/gen_uuid_nt.c: + * mime-type-capplet/libuuid/isnull.c: + * mime-type-capplet/libuuid/pack.c: + * mime-type-capplet/libuuid/parse.c: + * mime-type-capplet/libuuid/tst_uuid.c: + * mime-type-capplet/libuuid/unpack.c: + * mime-type-capplet/libuuid/unparse.c: + * mime-type-capplet/libuuid/uuid.h: + * mime-type-capplet/libuuid/uuidP.h: + * mime-type-capplet/libuuid/uuid_time.c: + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.c: + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.h: + * mime-type-capplet/nautilus-mime-type-capplet.c: + * mime-type-capplet/nautilus-mime-type-capplet.h: + * mime-type-capplet/nautilus-mime-type-icon-entry.c: + * mime-type-capplet/nautilus-mime-type-icon-entry.h: + Remove this code. It's already been moved to the control center + and we don't need to keep two copies of it. + + * test/gnome-file-selection/.cvsignore: + * test/gnome-file-selection/Makefile.am: + * test/gnome-file-selection/dir-close.xpm: + * test/gnome-file-selection/dir-open.xpm: + * test/gnome-file-selection/gicon.c: + * test/gnome-file-selection/gicon.h: + * test/gnome-file-selection/gnome-file-selection-history.c: + * test/gnome-file-selection/gnome-file-selection-history.h: + * test/gnome-file-selection/gnome-file-selection.c: + * test/gnome-file-selection/gnome-file-selection.h: + * test/gnome-file-selection/listing-iconic.xpm: + * test/gnome-file-selection/main.c: + Remove the file selector (which was not compiled). This is now + being developed elsewhere. + + * po/POTFILES.in: + Remove file names from CORBA back end and file selector. + + * libgnomevfs/gnome-vfs-private-types.h: Fix includes. + * libgnomevfs/gnome-vfs-private-utils.c: Fix includes. + * libgnomevfs/gnome-vfs-private-utils.h: Fix includes. + * libgnomevfs/gnome-vfs-process.c: Fix includes. + + * NEWS: Remove long-obsolete news. + + * README: Update. + * TODO: Tweak words a bit. + + * libgnomevfs/Makefile.am: Tweaks. + +2001-04-12 Darin Adler + + * libgnomevfs/gnome-vfs-xfer.c: (gnome_vfs_xfer_uri_internal): + Fix bug where it file indices start from 1 during the preflight + but from 0 during the actual copy. + +2001-03-30 Michael K. Fleming + + reviewed by: Pavel Cisler + + Portion of bug 4832: Add support for HTTP proxies that require + authentication. + + Note that if an HTTP proxy is set, but the proxy credentials are + configured incorrectly, the application will get a + GNOME_VFS_ERROR_ACCESS_DENIED, which isn't very descriptive + + Also expunged some of my bad coding habits + (constant-on-left-side-of-compare) + + * modules/http-method.c: (cache_shutdown), (cache_entry_new), + (cache_check_directory), (cache_add_uri_and_children), + (sig_gconf_value_changed), (http_proxy_for_host_port), + (make_request), (vfs_module_init): + +2001-03-29 Darin Adler + + reviewed by: Pavel Cisler + + * libgnomevfs/gnome-vfs-cancellable-ops.c: + (gnome_vfs_move_uri_cancellable): Make a move where both the from + and to are identical succeed without involving the module. + * libgnomevfs/gnome-vfs-xfer.c: (handle_name_conflicts): Don't + treat a file that's being moved on top of itself as a conflict. + +2001-03-24 Martin Baulig + + * gnomevfs-2.0.pc.in: Renamed to gnome-vfs-2.0.pc.in. + +2001-03-24 Martin Baulig + + * modules/file-method.c: Only #include + and for GNOME 1.x. Define `_' and `N_' + to be a noop for GNOME 2.0 [FIXME: need a better solution for this]. + + * libgnomevfs-corba/*.[ch]: #include for GNOME 1.x + and for GNOME 2.0. + +2001-03-24 Martin Baulig + + * autogen.sh: Check whether gnome-autogen.sh is in the PATH + and print an error message otherwise. + + * configure.in: Unconditionally require OAF on both platforms; + for GNOME 2.0: check for GTK+, but don't check for ORBit. + +2001-03-23 Martin Baulig + + Added support for the GNOME 2.0 platform. + + We try to autodetect the GNOME Platform in configure.in, but + you may need to use the --enable-platform-gnome-2 or + --disable-platform-gnome-2 argument if this fails. + + * autogen.sh: Use gnome-common. + + * configure.in: Use pkg-config to check for things; removed + the USING_OAF conditional. + + * Makefile.am: Removed the USING_OAF conditional. + + * libgnomevfs/gnome-vfs-i18n.c: New file. + (gnome_vfs_i18n_get_language_list): Moved the implementation of + this function from gnome-libs/libgnome/gnome-i18n.c here. + + * libgnomevfs/gnome-vfs-private-utils.c + (gnome_vfs_i18n_get_language_list): Moved to gnome-vfs-i18n.c. + +2001-03-23 Darin Adler + + * test/test-uri.c: (main): Added some tests to demonstrate + behavior when a URI starting with "." or ".." is passed to + gnome_vfs_uri_new. + +2001-03-22 Pavel Cisler + + reviewed by: Darin Adler + + * modules/file-method.c: (get_stat_info): + Fix a bug that caused symlink_name to never be read. + Add support for retrieving the symlink_name for a multi-level + symlink. + +2001-03-17 Gene Z. Ragan + + * modules/Makefile.am: + I am clueless. Maybe adding this header file + to the list of files in the cdda module listing + will fix the build. + +2001-03-17 Gene Z. Ragan + + * modules/Makefile.am: + Another attempt to fix tinderbox. + +2001-03-16 Gene Z. Ragan + + * configure.in: + Another try to get this right. Check for the presence of the + cdparanoia headers instead of the library. The use of an + underscore in the library name seems to confuse the AM_CHECK_LIB + macro. + +2001-03-15 Gene Z. Ragan + + * configure.in: + Fix tinderbox breakage. This is what happens when I pretend to be a build + engineer. + + * modules/cdda-method.c: (do_open), (do_close), (do_get_file_info), + (do_close_directory): + Removed some debug messages. + +2001-03-15 Gene Z. Ragan + + * modules/cdda-cddb.c: + Added a workaround for the strangely defined, but unused, + static arrays of chars in cdparanoia headers that causes + a compiler error due to our strict error checking. + +2001-03-15 Gene Z. Ragan + + * modules/cdda-module.conf: + Add new cdda configuration file to build. + +2001-03-15 Gene Z. Ragan + + * configure.in: + * modules/Makefile.am: + * modules/cdda-cddb.c: + * modules/cdda-method.c: (cdda_context_new): + * modules/default-modules.conf: + Add cdda module to build using configure conditionals that depend + on the presence of libcdparanoia. + +2001-03-15 John Sullivan + + reviewed by: Darin Adler + + * libgnomevfs/gnome-vfs-types.h: Reverted this part of + my eralier checkin after Darin convinced me that the + change I made here could actually make things worse. + Added a FIXME about how it should be changed later. + +2001-03-14 Pavel Cisler + + Fix 7339: (dragging file inside ftp window causes "replace self" + dialog to appear) + * libgnomevfs/gnome-vfs-uri.c: (uri_matches_as_parent), + (gnome_vfs_uri_is_parent): + Fix a problem where ftp://foo.com and ftp://foo.com/ were + not both considered the parent of ftp://foo.com/bar + + * test/test-uri.c: (test_uri_is_parent_common), + (test_uri_is_parent_deep), (test_uri_is_parent_shallow), (main): + Add tests for the above change. + + * test/test-find-directory.c: (main): + Add some error handling. + + * libgnomevfs-pthread/gnome-vfs-job.c: (job_notify), + (gnome_vfs_job_set), (gnome_vfs_op_destroy): + Add some asserts and fix some debugging messages. + +2001-03-14 John Sullivan + + reviewed by: Pavel Cisler + + Fixed bug 3337 (Sticky bit doesn't display correctly) + + * libgnomevfs/gnome-vfs-types.h: Set the sticky bit + mask to 0 if S_ISVTX isn't defined, so we don't stomp + on other unknown uses of this bit. + * libgnomevfs/gnome-vfs-module-shared.c: + (gnome_vfs_stat_to_file_info): Use GNOME_VFS style + constants; #define _BSD_SOURCE so the sticky bit + is defined. + +2001-03-07 Maciej Stachowiak + + reviewed by: Robin Slomkowski + + * gnome-vfs-config.in: Tweak so output is 1.1, not gnome-vfs-1.1 + to be consistent with other -config scripts and stop confusing + control-center's configure; fixes tinderbox. + +2001-03-07 Maciej Stachowiak + + * gnome-vfs.spec.in: Add gnome-vfs-config to silence tinderbox. + +2001-03-07 Darin Adler + + * gnome-vfs.spec.in: Remove file-types-capplet too. + +2001-03-07 Maciej Stachowiak + + reviewed by: Darin Adler + Gene Z. Ragan + + Part of the fix for bugzilla.eazel.com bug 588 (Remove old "MIME + types" capplet from control center) + + * Makefile.am: Remove mime-type-capplet subdir. + + * configure.in: Don't create mime-type-capplet Makefiles or check + for control-center. + + * gnome-vfs.spec.in: remove control-center dependency. + + * mime-type-capplet/*: removed. + + * po/POTFILES.in: Remove mime-type-capplet files + +2001-03-07 Pavel Cisler + + reviewed by: Darin Adler (reluctantly) + + Fixed 7495 (Need to test condition after pthread_cond_wait) + + * libgnomevfs-pthread/gnome-vfs-thread-pool.c: + (gnome_vfs_thread_pool_wait_for_work), (thread_entry): + Work around what is described as a spurious wakeup of + condition variables in the Pthread standard. + Added a while loop around pthread_cond_wait checking if + an entry_point is lined up. + +2001-03-06 Darin Adler + + * configure.in: Updated version number to 1.1. + +2001-03-06 Darin Adler + + Created the gnome-vfs-1-0 branch, for 1.0 development. + HEAD is now for post-1.0. + +2001-03-06 Darin Adler + + Merged all changes back here from the gnome-vfs-1 branch. + +=== start of changes from gnome-vfs-1 branch === + +2001-03-04 Dan Winship + + reviewed by: Maciej Stachowiak + + * mime-type-capplet/libuuid/Makefile.am (NULL): Remove "SUBDIRS=" + line, which causes automake (1.4 at least) to generate a Makefile + containing invalid sh script that bash (2.03.0(1) at least) won't + parse. + +2001-03-04 Ramiro Estrugo + + reviewed by: Pavel Cisler + + * data/mime/gnome-vfs-mime-magic: + Make Postscript Fonts magic work for all fonts versioned 1.x, not + just 1.0. + +2001-03-04 Pavel Cisler + + reviewed by: Darin Adler + + Fixed 7333: leak in gnome_vfs_mime_get_default_component + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_get_default_component): + Fix a leak by adding a missing + gnome_vfs_mime_component_list_free. + +2001-02-28 Maciej Stachowiak + + reviewed by: Darin Adler + + * Makefile.am, configure.in: Include macros dir in dist tarball + for the benefit of those building the module with + --enable-maintainer-mode + +2001-03-02 Eric Fischer + + reviewed by: Gregory Leblanc + + * configure.in: + Add version-checking macros from nautilus's configure.in + Add check for control-center version number + Parameterize checks for glib, oaf, gconf + + * gnome-vfs.spec.in: + Substitute prerequisite version numbers from configure script + +2001-03-01 Don Melton + + reviewed by: Pavel Cisler + + * libgnomevfs/gnome-vfs-mime-magic.c: (get_mp3_frame_length), + (get_4_byte_value), (gnome_vfs_sniff_buffer_looks_like_mp3): + + Re-fixed bug 6612 (Non-music files misidentified as MP3) + Fixed bug 7212 (".sys" file misidentified as MP3) + Fixed bug 7213 (".ico" file misidentified as MP3) + Fixed bug 7214 (".1st" file misidentified as MP3) + + Rewrote "gnome_vfs_sniff_buffer_looks_like_mp3" to narrow MP3 + sniffing to streams containing AT LEAST TWO frames of layer 3 MPEG + audio. Note: free format and MPEG version 2.5 MP3s are ignored, + + Removed the hack to ignore StarOffice and Microsoft Office files + which contain seemingly valid (but totally false) MPEG audio + headers starting 68 bytes into the file, because the new sniffing + code makes this unnecessary. + +2001-03-01 Gene Z. Ragan + + reviewed by: Mike Engber + + Fixed bug 6964, gtv not associated with video/mpeg + + * data/mime/gnome-vfs.applications: + * data/mime/gnome-vfs.keys.in: + Add gtv to the short list of applications for + type video/mpeg. + +2001-03-01 Rebecca Schulman + + reviewed by: Robin Slomkowski + + * gnome-vfs.spec.in: + Attempt to fix tinderbox -- install the moved + desktop file to the new location in the spec file + too. + +2001-03-01 Mike Fleming + + reviewed by: + + Bug 7192: split_toplevel_uri now allows URI's with a username + but no hostname in the authority field. In the future, we should + figure out how to avoid having split_toplevel_uri involved with + made-up URI schemes like eazel-install: + + * libgnomevfs/gnome-vfs-uri.c: (split_toplevel_uri): + * test/test-uri.c: (main): + +2001-03-01 Gene Z. Ragan + + reviewed by: Pavel Cisler + + * mime-type-capplet/Makefile.am: + The capplet .desktop should be copied to the Documents + directory of the control-center .desktop files directory, + not the root level. + +2001-02-28 Andy Hertzfeld + + * data/mime/gnome-vfs.keys.in: + fixed bug 7179, lots of text files are missing their embedded text; + fixed by deleting the icon-filename entry for around a dozen types. + +2001-02-28 Eric Fischer + + reviewed by: Robin * Slomkowski + + * gnome-vfs.spec.in: (Bug 7166) + Add dependency for control-center 1.2.3, because the mime-type + capplet will crash without the latest version. I think this can + go away once the capplet gets moved into control-center where it + belongs, but it's necessary for the moment. + +2001-02-28 Darin Adler + + Moved the ChangeLog entries into data/mime/ChangeLog. + +2001-02-27 Pavel Cisler + + reviewed by: Gene Z. Ragan + + * modules/file-method.c: (do_find_directory): + Fix a bug where calling gnome_vfs_find_directory near + a cross-file system symlink would return Trash corresponding + to the link target not the link itself, causing an error when + trying to delete the link. + +2001-02-27 Josh Barrow + + * AUTHORS: + s/helixcode/ximian/ + +2001-02-27 Pavel Cisler + + * AUTHORS: + * HACKING: + * NEWS: + Getting these ready for a release. + +2001-02-27 Maciej Stachowiak + + another unreviewed change to fix tinderox + + * mime-type-capplet/Makefile.am: Install .desktop file in both the + places the .spec file expects it. Not sure if it was removed + intentionally or not. + +2001-02-27 Maciej Stachowiak + + unreviewed change to fix tinderox + + * mime-type-capplet/Makefile.am: Add .desktop.in file to + EXTRA_DIST. + +2001-02-27 Maciej Stachowiak + + reviewed by: Kjartan Maraas + + * po/POTFILES.in: Remove entries spuriously added by + xml-i18n-prepare + +2001-02-26 Rebecca Schulman + + Fixed bugzilla.eazel.com bug 7010, that the + file types capplet should use .desktop.in + xml-i18-tools stuff. + + reviewed by: Maciej Stachowiak + + * libgnomevfs/gnome-vfs-mime.c: + * libgnomevfs/gnome-vfs-mime.h: + Add a FIXME and a comment about functions + in this file; no code changes + + * mime-type-capplet/.cvsignore: + Add file-types-capplet.desktop + * mime-type-capplet/file-types-capplet.desktop.in: + Add this with new nifty xml-18n technology + * mime-type-capplet/file-types-capplet.desktop: + Remove the old file + + * mime-type-capplet/Makefile.am: + Fix the build to build and install the new desktop file + instead of the old one + +2001-02-26 Gene Z. Ragan + + reviewed by: Rebecca Schulman + + Forgot to add libuuid/Makefile + + * configure.in: + +2001-02-26 Robin * Slomkowski + + * configure.in: upped version to 0.6.2.0 for development + +2001-02-26 Robin * Slomkowski + + * configure.in: upped version to 0.6.2 for release + +2001-02-26 Gene Z. Ragan + + reviewed by: Pavel Cisler + + Fixed bug 7039, User-entered application that matches + built-in application can't be deleted + + Fixed bug 7040, User-entered application that matches built-in + application doesn't go away when "all user changes" reverted + + Fixed bug 7064, New mime types added by user using the capplet + do not appear when capplet is launched again. + + * mime-type-capplet/Makefile.am: + Add libuuid to build. + + * mime-type-capplet/libuuid/Makefile.am: + * mime-type-capplet/libuuid/clear.c: (uuid_clear): + * mime-type-capplet/libuuid/compare.c: (uuid_compare): + * mime-type-capplet/libuuid/copy.c: (uuid_copy): + * mime-type-capplet/libuuid/gen_uuid.c: (get_random_bytes), + (get_node_id), (get_clock), (uuid_generate_time), + (uuid_generate_random), (uuid_generate): + * mime-type-capplet/libuuid/gen_uuid_nt.c: (Nt5), (uuid_generate): + * mime-type-capplet/libuuid/isnull.c: (uuid_is_null): + * mime-type-capplet/libuuid/pack.c: (uuid_pack): + * mime-type-capplet/libuuid/parse.c: (uuid_parse): + * mime-type-capplet/libuuid/tst_uuid.c: (main): + * mime-type-capplet/libuuid/unpack.c: (uuid_unpack): + * mime-type-capplet/libuuid/unparse.c: (uuid_unparse): + * mime-type-capplet/libuuid/uuid.h: + * mime-type-capplet/libuuid/uuidP.h: + * mime-type-capplet/libuuid/uuid_time.c: (uuid_time), (uuid_type), + (uuid_variant), (variant_string), (main): + Add libuuid to capplet and link statically. This is sort of sad. It would + be nice if gnome had a uuid library, but at this time it does not. + + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.c: + (nautilus_mime_type_capplet_show_new_mime_window): + Call proper API to ensure that new mime type is added to the database. + + (add_or_update_application), (add_item_to_application_list), + (run_edit_or_new_application_dialog): + Create and assign a uuid to user defined application so that we never + conflict with system defined types that use the application name + as the application id. + +2001-02-26 Darin Adler + + reviewed by: Ramiro Estrugo + + * check-mime.pl: Added more checks, including a check for + unexpected keys, check for repeated keys, check for key format in + .mime file, check for icon names mentioned against icon files, and + code to make it communicate failure to the shell with "exit 1". + +2001-02-25 John Sullivan + + reviewed by: Gene Ragan + + Fixed bug 6675 (Capplet allows user to add application for + non-existent program (or not in path). + + * libgnomevfs/gnome-vfs-utils.h: + * libgnomevfs/gnome-vfs-utils.c: (strdup_to), (is_executable_file), + (executable_in_path), (get_executable_name_from_command_string), + (gnome_vfs_is_executable_command_string): Moved code that tests + for executable commands from -mime-handlers.c to here. Made + gnome_vfs_is_executable_command_string public. Added FIXMEs + and tweaked full-path handling code to work in more cases. + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (application_known_to_be_nonexistent): Replaced the code testing + for executable commands with call to + gnome_vfs_is_executable_command_string. + + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.c: + (initialize_edit_applications_dialog): Added FIXME. + (handle_invalid_application_input): New function, handles bad + name or command string with explanatory error message. + (run_edit_or_new_application_dialog): New function, guts of both + show_ and edit_new_application_window, which formerly had nearly + identical copy/pasted code. Now doesn't close dialog if input + is bad and user clicks OK; other minor cleanup. + (show_new_application_window), (show_edit_application_window): + Each of these now calls run_edit_or_new_application_dialog. + + * mime-type-capplet/nautilus-mime-type-capplet.c: + (add_mime_clicked), (update_mime_list_action), + (populate_mime_list): Added tests for missing icon files to + avoid zillions of GTK-CRITICALs from gdk_pixbuf if you run + the capplet without installing Nautilus firt (discovered during + clean rebuild); fixed a couple of leaking strings. + +2001-02-24 Marius Andreiana + + * configure.in: Added ro (Romanian) to ALL_LINGUAS. + +2001-02-24 Gene Z. Ragan + + reviewed by: John Harper + + Fixed bug 6904, Full paths can't be used when adding + applications in capplet (and failure is silent) + + I fixed the full paths issue. The failure is silent issue + is reflected in a soon to be closed bug. + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (application_known_to_be_nonexistent): + Check and see if the command string store in the + mime database is actually a full path to an + executable. + +2001-02-23 Pavel Cisler + + reviewed by: Mike Fleming + + Fix 6391 nautilus crashes on any \ in the homedir preference + + * test/test-uri.c: (main): + Add a test that broke before the fix. + + * libgnomevfs/gnome-vfs-private-utils.c: (find_next_slash): + Remove the confused '\' unescaping. + +2001-02-23 Pavel Cisler + + reviewed by: Gene Ragan + + Fixed 5786 the sequence of async open->read->cancel->close + can crash. + + * libgnomevfs-pthread/gnome-vfs-async-ops.c: + (pthread_gnome_vfs_async_close): + Before scheduling a close, wait for read/write to complete. If + read/write is still executing, wait for a tiny bit. + + * libgnomevfs-pthread/gnome-vfs-job.c: (gnome_vfs_job_complete), + (gnome_vfs_op_destroy), (gnome_vfs_job_execute): + * libgnomevfs-pthread/gnome-vfs-job.h: + Add a new job op state - GNOME_VFS_OP_READ_WRITE_DONE. + Set it when read/write is done so that close can tell it can + proceed. + +2001-02-23 Don Melton + + reviewed by: Maciej Stachowiak + + Fixed bug 6831 (extensions shouldn't take precedence over MP3 files) + * libgnomevfs/gnome-vfs-mime.c: (gnome_vfs_get_mime_type_internal): + Removed call to "gnome_vfs_mime_type_from_name_or_default" after + call to "gnome_vfs_sniff_buffer_looks_like_mp3" so filename + extensions don't take precendence over actual MPEG audio content. + + Re-fixed bug 6612 (".doc", ".sdw", etc. are not MP3 files) + * libgnomevfs/gnome-vfs-mime-magic.c: + (gnome_vfs_sniff_buffer_looks_like_mp3): + Added hack to ignore StarOffice and Microsoft Office files which + contain seemingly valid (but totally false) MPEG audio headers + starting 68 bytes into the file. Do this here because adding mime + magic entry is really, really hard. + + Re-fixed bug 5477 ("linux-2.4.0.tar.bz2" is not MP3 file) + * data/mime/gnome-vfs-mime-magic: + Corrected string pattern to detect bzip2 files. Changed "Bzh" to + "BZh". + +2001-02-22 Mike Fleming + + * modules/default-modules.conf: + + Removed nfs from default-modules.conf (see bug 6666) + +2001-02-22 John Sullivan + + reviewed by: Gene Ragan + + Fixed bug 6524 (No default icons for MIME types) + + Fixed bug 6525 (capplet will only let you pick icons + from a single directory) + + Fixed bug 6596 ("We need a good explanation here" + isn't a good explanation) + + I didn't fix all the fundamental brokenness about Nautilus + themes vs. the MIME database, but I fixed the most obvious + problems and added some FIXMEs to help clarify some of the + remaining issues. I also did a tiny fraction of the cleanup + that could be done in this code. Users can now browse around + to choose icons from anywhere, and they will all work in + Nautilus (no change required in Nautilus). + + * mime-type-capplet/files-types-capplet.desktop: + Replaced placeholder description string with Vera's. + + * mime-type-capplet/nautilus-mime-type-capplet.c: + Removed bogus but relatively harmless initial slashes + from two DEFAULT_REGULAR_ICON and DEFAULT_ACTION_ICON. + (really_change_icon): Handle full as well as relative + filenames; update displayed info here instead of relying + on the icon_entry widget doing it. + (icon_chosen_callback): Renamed from gil_icon_selected_cb; + hide the dialog here so we can eliminate the almost-identical + code in nautilus-mime-type-icon-entry.c that did that one + extra thing. + (change_icon_clicked_cb_real): use GNOME_OK instead of 0 + (change_icon_clicked): Update for name change. + (is_full_path): Little bitty helper function that checks for + initial slash, mainly separated for clarity. + (capplet_get_icon_path): New function used to get a full icon + path from a file name, icon name, relative path, or + possibly non-existent full path. + (nautilus_mime_type_capplet_update_info): Simplify logic, + use capplet_get_icon_path. + (add_mime_clicked), (update_mime_list_action), + (populate_mime_list): + Use capplet_get_icon_path; use generic + executable icon for app instead of repeating MIME-type icon. + (capplet_get_icon_pixbuf): Simplify logic; use capplet_get_icon_path; + Add FIXME about future code cleanup + + * mime-type-capplet/nautilus-mime-type-icon-entry.h: + * mime-type-capplet/nautilus-mime-type-icon-entry.c: + (nautilus_mime_type_icon_entry_get_full_filename): Renamed from + _get_filename for clarity + (entry_activated): Made behavior match comment (act like OK + button was hit) + (icon_selected_cb): Removed this function; this was redundant with + code in nautilus-mime-type-capplet.c. + (gil_icon_selected_cb): Removed this function; it was redundant + with a function in nautilus-mime-type-capplet.c except that this one + hid the dialog and that one didn't (now that one does). + (nautilus_mime_type_show_icon_selection): Remove commented-out + line that implemented the Browse button that let the user choose + from different directories; removed redundant signal handlers; + added FIXME. + (nautilus_mime_type_icon_entry_get_relative_filename): Simplify + logic; made it return NULL instead of "" and a g_warning when + it can't create a relative path from the full path. + + * libgnomevfs/gnome-vfs-utils.c: Added FIXME + +2001-02-22 Gene Z. Ragan + + reviewed by: John Sullivan + + Fixed bug 6568, Closing capplet right away warns + about uncommitted changes + + * mime-type-capplet/nautilus-mime-type-capplet.c: + (init_mime_capplet): + Use new winterface that I added to control-center + that informs the control center that changes are immediate. + The control center now behaves properly. + +2001-02-21 Pavel Cisler + + reviewed by: Darin Adler + + Fixed 5633: MIME type for gzipped XML formats such as gnumeric + are not detected. + Fixed 6803: gcc complaining about mktemp and suggesting mkstemp. + + * libgnomevfs/gnome-vfs-mime.c: + (gnome_vfs_get_mime_type_internal): + Rework to get rid of duplicated logic. Add a new call that + covers both the data and suffix based file type recognition, + optionally accepting NULL for either of the two. Add a call to + the special gzip handler. For now hardcode gnumeric.gz and + pdf.gz, we may add more later. + + * libgnomevfs/gnome-vfs-mime.c: + (gnome_vfs_get_mime_type), + (gnome_vfs_get_file_mime_type), + (gnome_vfs_get_mime_type_from_file_data), + (gnome_vfs_get_mime_type_for_data): + Make it call the new common routine. + + * libgnomevfs/gnome-vfs-mime-sniff-buffer-private.h: + * libgnomevfs/gnome-vfs-mime-sniff-buffer.h: + * libgnomevfs/gnome-vfs-mime-magic.c: + (gnome_vfs_mime_get_type_from_magic_table), + (gnome_vfs_get_mime_type_for_buffer), + (file_name_ends_with), + (gnome_vfs_sniff_buffer_looks_like_gzip): + Add a special-case recognizer for gzip files that considers + file names before identifying a file as gzip and leaving a + hard-coded set of types to fall back on the suffix based type + identification. + + * libgnomevfs/gnome-vfs-mime.c: (get_priority), (list_find_type), + (add_to_key), (mime_fill_from_file), (mime_load), + (gnome_vfs_mime_type_from_name_or_default), + (gnome_vfs_get_mime_type_from_uri_internal), + (gnome_vfs_get_mime_type_internal), + (gnome_vfs_mime_type_is_supertype), (extract_prefix_add_suffix), + (gnome_uri_list_extract_uris), (gnome_uri_list_extract_filenames), + (gnome_uri_extract_filename): + Tweaks. + + * libgnomevfs/gnome-vfs-mime-magic.c: + (gnome_vfs_sniff_buffer_looks_like_mp3): + Tweaks. + + * data/mime/gnome-vfs-mime-magic: + Remove the magic pattern for gzip. + + * libgnomevfs/gnome-vfs-private-utils.c: + (gnome_vfs_i18n_get_language_list), (gnome_vfs_istr_has_prefix), + (gnome_vfs_istr_has_suffix): + * libgnomevfs/gnome-vfs-private-utils.h: + Copy-paste these from Nautilus. + + * libgnomevfs-corba/gnome-vfs-slave.c: (setup_and_serve_channel): + Switch to using mkstemp. + +2001-02-22 Seth Nickell + + reviewed by: Mathieu Lacage + + * modules/test-method.c: (load_settings), (vfs_module_init): + + Fix test module to look in the PREFIX for its configuration file + rather than hardcoding. Deal with missing or invalid settings files + gracefully, returning a sane error rather than segfaulting :-) + +2001-02-22 Seth Nickell + + reviewed by: Pavel Císler + + * libgnomevfs/gnome-vfs-application-registry.c: + (strip_trailing_whitespace): + * libgnomevfs/gnome-vfs-uri.c: (split_toplevel_uri): + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.c: + (nautilus_mime_type_capplet_show_new_mime_window): + + Add casts to is* functions as necessary when chars are + used to fix Solaris warnings. + +2001-02-21 Mike Fleming + + reviewed by: + + * data/mime/gnome-vfs.applications: + * data/mime/gnome-vfs.keys.in: + + added x-directory/webdav-prefer-directory to gnome-vfs.keys.in + I must have edited the wrong file before :) + +2001-02-21 Darin Adler + + reviewed by: Pavel Cisler + + * libgnomevfs/gnome-vfs-uri.c: (split_toplevel_uri): Move code + to lower-case the host name down so it's always run, even in + cases that exit via "goto done". + * test/test-uri.c: (main): Fix test cases that were broken by + the above bug. + +2001-02-21 John Sullivan + + reviewed by: Pavel Cisler + + Fixed bug 6654 (after deleting MIME type from database, + info about that MIME type still appears in Nautilus) + + Turns out the support for MIME type deletion was skin deep. + The info was stored, but the only place respecting it was + the code to return a complete list of MIME types. + + * libgnomevfs/gnome-vfs-mime-info.c: + (is_mime_type_deleted): New function, extracted from + get_key_name + (get_key_name): Now calls extracted function + (get_value_from_hash_table): New function, holds some code + that was repeated 4 times in get_value_real + (get_value_real): Return NULL if MIME type is deleted (unless + we're checking DELETED_KEY itself); use get_value_from_hash_table + to save code. + +2001-02-21 Gene Z. Ragan + + reviewed by: John Sullivan + + Fixed bug 6626, Applications deleted from the + short list reappear (unchecked) + + The original intent of this dialog button was to allow the user to + delete their custom added applications. The logic has been + added to handle this and update the control properly. + There is a larger issue that if the user wants to delete system + level applications, the current API makes it impossible to do + so. + + * libgnomevfs/gnome-vfs-application-registry.c: + * libgnomevfs/gnome-vfs-application-registry.h: + (application_lookup_or_create), (application_lookup), + (application_remove), (gnome_vfs_application_registry_init), + (gnome_vfs_application_registry_clear), + (gnome_vfs_application_registry_shutdown), + (gnome_vfs_application_registry_sync), + (gnome_vfs_application_registry_save_mime_application): + Renamed a potentially confusing global variable. + + + (gnome_vfs_application_is_user_owned_application): + New function that returns a value indicating if this + is a user owned or system owned application. + + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.c: + (create_application_list_item), + (populate_default_applications_list), + (initialize_edit_applications_dialog), + (show_new_application_window), (delete_selected_application), + (add_or_update_application), (add_item_to_application_list): + Determine if application data is user owned and act accordingly. + + (check_button_status): + Remove delete button handling in certain cases and use new + update_delete_button function instead. + + (update_delete_button): + New function to that sensitizes the delete button + based on user ownership of the selected application item. + +2001-02-20 Pavel Cisler + + reviewed by: Mike Fleming + (except for build breakage fixes) + + Fix 5798 Cancelling a slow medusa search locks up nautilus + Fix 6309 Stopping Nautilus while navigating to an unreachable + http server can block nautilus indefinitely. + + * libgnomevfs-pthread/gnome-vfs-async-job-map.c: + (gnome_vfs_async_job_add_callback), + (gnome_vfs_async_job_cancel_job_and_callbacks): + * libgnomevfs-pthread/gnome-vfs-async-ops.c: + (pthread_gnome_vfs_async_cancel): + Switch from using the job->access_lock to make setting + job->cancelled and cancelling the callbacks in the callback map + atomic to using the async_job_callback_map_lock. + + * libgnomevfs-pthread/gnome-vfs-async-ops.c: + (pthread_gnome_vfs_async_cancel): + No need to acquire job->access_lock -- this makes the cancellation + not block while the async job is executing. + + * libgnomevfs-pthread/gnome-vfs-async-job-map.h: + * libgnomevfs-pthread/gnome-vfs-job.c: (job_oneway_notify), + (job_notify): + Use the result of gnome_vfs_async_job_add_callback to handle getting cancelled + while scheduling an idle callback. + + * libgnomevfs-pthread/gnome-vfs-job.c: (job_notify): + Fix a mistake where gnome_vfs_async_job_add_callback was being called twice. + + * libgnomevfs-pthread/gnome-vfs-job.c: (gnome_vfs_job_module_cancel): + * libgnomevfs-pthread/gnome-vfs-job.h: + Rename to make things clearer. + + * libgnomevfs-pthread/gnome-vfs-job.c: (execute_read), (execute_xfer): + Fix whitespace. + + + * libgnomevfs/gnome-vfs-method.c: + * libgnomevfs/gnome-vfs-method.h: + * libgnomevfs/gnome-vfs-module-shared.c: + * libgnomevfs/gnome-vfs-module.h: + * libgnomevfs/gnome-vfs-private-types.h: + * libgnomevfs/gnome-vfs-types.h: + * modules/file-method.c: + * modules/ftp-method.c: + * modules/gconf-method.c: + * modules/pipe-method.c: + * modules/translate-method.c: + + Fix build breakage, part 2. + +2001-02-20 Mike Fleming + + reviewed by: Pavel Cisler + + Bug 6770 -- URI's with @'s in the path break split_toplevel_uri + Fixed and added test cases + + * libgnomevfs/gnome-vfs-uri.c: (split_toplevel_uri): + * test/test-uri.c: (main): + +2001-02-20 Pavel Cisler + + reviewed by: Rebecca Schulman + + * libgnomevfs/gnome-vfs-cancellable-ops.h: + * libgnomevfs/gnome-vfs-context.h: + * libgnomevfs/gnome-vfs-private-types.h: + * libgnomevfs/gnome-vfs-types.h: + + Fix Medusa build breakage, part 1. + +2001-02-20 Darin Adler + + reviewed by: Mike Fleming + + * libgnomevfs/gnome-vfs-process.c: (sigchld_handler): Fix + uninitialized variable problem (reported by danw I think). + * libgnomevfs/gnome-vfs-utils.c: + (gnome_vfs_get_local_path_from_uri): Simplify function and make it + return NULL with # characters. + + * test/test-uri.c: (main): Update tests to match the change to + gnome_vfs_get_local_path_from_uri. + + * libgnomevfs-pthread/gnome-vfs-job.c: Improve a variable name. + + * mime-type-capplet/.cvsignore: Ignore the executable under its + new name, not its old name. + +2001-02-20 John Sullivan + + * mime-type-capplet/nautilus-mime-type-capplet.c: + (init_mime_capplet): Changed "Delete this MIME type..." + to "Delete This MIME Type" because that follows the + capitalization rules, and because there's no dialog + involved so the "..." is a lie. + +2001-02-20 John Sullivan + + reviewed by: Seth Nickell + + Fixed various small capplet bugs while pondering the + big scary icon-related ones, including: + + Fixed bug 4768 (hardcoded icon file name in + nautilus-mime-type-capplet.c) + + Fixed bug 6636 (Text descenders clipped for selected item in mime list) + + Fixed bug 6641 (Icons clipped in mime list) + + Fixed bug 6647 ("Change Icon" dialog has silly title) + + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.c: + (nautilus_mime_type_capplet_show_new_mime_window): Simplified + widgetry, tweaked layout and wording to look halfway decent and + be clear. + + * mime-type-capplet/nautilus-mime-type-capplet.c: + Added constants for icon height/width in list. Added FIXME for + huge hunks of copy/pasted code. + (init_mime_capplet): Removed two set_usize calls; replaced one + with a gtk_misc_set_padding call so "Edit List" button isn't + too cramped. + (add_mime_clicked), + (nautilus_mime_type_capplet_update_mime_list_icon_and_description): + Use icon size constants instead of magic numbers. + (update_mime_list_action), (populate_mime_list): + Use icon size constants; use + gnome_vfs_icon_path_from_filename to avoid hard-coded path. + (mime_list_reset_row_height): New function, sets the row height + based on font size and image height. + (create_mime_list_and_scroller): Reset row height at the right time. + + * mime-type-capplet/nautilus-mime-type-icon-entry.c: + (nautilus_mime_type_show_icon_selection): Set icon selection window + title; add FIXME for (at long last discovered) code that prevents + user from choosing icons in arbitrary directories. + +2001-02-20 Rebecca Schulman + Fix build issues caused by making gnome-vfs-process.h + private + + reviewed by: Darin Adler + + * libgnomevfs/gnome-vfs.h: + Remove gnome-vfs-process.h, which is now private + * libgnomevfs/gnome-vfs-private-utils.h: + Add gnome-vfs-process.h + * test/test-escape.c: Add a signal.h which + was needed after remove gnome-vfs-process.h + from gnome-vfs.h + +2001-02-20 Mike Fleming + + reviewed by: + + Bug 5325: Eazel Vault directories default to icon view, but other + DAV sites do not. + + Added "x-directory/webdav-prefer-directory" mime type to allow this + to happen. + + Also added checking of the multistatus "status" value for + propstat + + * data/mime/gnome-vfs.applications: + * modules/http-method.c: (process_propfind_propstat), + (find_child_node_named), (get_propstat_status), + (process_propfind_response), (make_propfind_request), + (do_get_file_info): + +2001-02-20 Ian McKellar + + reviewed by: Pavel Cisler + + * libgnomevfs/gnome-vfs-xfer.c: (copy_file_data), (move_items), + (link_items): + Don't add overhead to the transfer total for each file. + This fixes bug 6769. + + * test/test-uri.c: + Fix a compile problem with the Debian compiler. + +2001-02-20 John Sullivan + + reviewed by: Darin Adler + + Finished bug 5777 (Nautilus doesn't pick up MIME database + changes right away). It still requires a Refresh or a visit + to another directory, but it no longer requires a relaunch. + + Fixed bug 4798 (Nautilus doesn't update icons right away). This + was a special case of bug 5777, but worth verifying separately so + not marked duplicate. + + To fix these two bugs, I made a new set of calls that let a client + check whether the mod date of any file from a set has changed + "recently". There was code to do this (copy & pasted in two places) + but it didn't correctly handle changes in existing files, only + new files added/removed. + + * libgnomevfs/Makefile.am: Moved gnome-vfs-process.h and + gnome-vfs-mime-sniff-buffer-private.h to noinst_HEADERS + where they belonged (unrelated to bug fixes). + + * libgnomevfs/gnome-vfs-mime-private.h: Added prototypes for + new FileDateTracker operations. + + * libgnomevfs/gnome-vfs-mime.c: + (file_date_record_update_mtime), (file_date_record_new), + (file_date_record_free): New functions, keep track of a single + file and its last recorded mod date. + (gnome_vfs_file_date_tracker_new): New function, returns a + new FileDateTracker struct. + (release_key_and_value): New function, used when freeing + FileDateTracker. + (gnome_vfs_file_date_tracker_free): New function. + (gnome_vfs_file_date_tracker_start_tracking_file): New function, + remembers a file (if not already known) and records its current + mod date. + (check_and_update_one): New hashtable iterator, checks whether + a file's mod date has changed since last recorded. + (gnome_vfs_tracked_date_has_changed): New function, checks whether + any tracked file's date has changed since last recorded. + + (mime_fill_from_file): start tracking the mod date of the file we + just loaded. + (mime_load): start tracking the mod date of the directory we just + iterated through. + (maybe_reload): replace old date-checking code with call to + gnome_vfs_tracked_date_has_changed. + (mime_init): create global hash table for mime data date tracker. + (gnome_vfs_mime_shutdown): free global hash table. + + * libgnomevfs/gnome-vfs-application-registry.c: + (remove_mime_type_for_application): Fixed crashing bug (part of + bug 5777) by reordering code to avoid accessing freed string. + (load_application_info_from): start tracking the mod date of the + file we just loaded. + (application_info_load): start tracking the mod date of the + directory we just iterated through. + (maybe_reload): replace old date-checking code with call to + gnome_vfs_tracked_date_has_changed + (gnome_vfs_application_registry_init): create global hash table for + registry date tracker. + (gnome_vfs_application_registry_shutdown): free global hash table. + +2001-02-20 Robin * Slomkowski + + * gnome-vfs.spec.in: changed nautilus-mime-type-capplet + to file-types-capplet + +2001-02-16 Michael K. Fleming + + reviewed by: + + * libgnomevfs/gnome-vfs-types.h: + * libgnomevfs/gnome-vfs-uri.c: (gnome_vfs_uri_get_parent): + * libgnomevfs/gnome-vfs-utils.c: + (gnome_vfs_get_local_path_from_uri): + * test/test-uri.c: (main): + + Part of 2057: URI's with fragments behave oddly + + gnome_vfs_uri_get_parent no longer copies the child's fragment + onto the parent (which certainly makes no sense to do) + + Added a warning for gnome_vfs_unescape_string_for_display, since + it can cause bug 6694 + + gnome_vfs_get_local_path_from_uri now strips fragments from the + string it resturns. + + Added test cases for new behaviour + + * libgnomevfs/gnome-vfs-mime-sniff-buffer.c: + (gnome_vfs_mime_sniff_buffer_new_from_existing_data): + * libgnomevfs/gnome-vfs-types.h: + + Fixed crasher in mime sniff buffer that can happen when + gnome_vfs_mime_sniff_buffer_new_from_existing_data is used + with a buffer too small for some of the magic number patterns. + By setting "read_whole_file" to TRUE, no further attempts will be + made to read from the buffer (which doesn't have a read function + defined) + + * modules/Makefile.am: + + Bug 6666, removed nfs module from build for nautilus v1 + +2001-02-20 Gene Z. Ragan + + Fix bug 6384, Nautilus program chooser uses + "nautilus-mime-type-capplet" to launch capplet + + * mime-type-capplet/Makefile.am: + * mime-type-capplet/files-types-capplet.desktop: + * mime-type-capplet/nautilus-mime-type.desktop: + Rename the capplet binary and change the name and + contents of the .desktop file to reflect the new name. + +2001-02-19 Don Melton + + reviewed by: Maciej Stachowiak + + * libgnomevfs/gnome-vfs-mime-magic.c: + (gnome_vfs_get_mime_type_for_buffer): + * libgnomevfs/gnome-vfs-mime.c: (gnome_vfs_get_mime_type), + (gnome_vfs_get_file_mime_type), + (gnome_vfs_get_mime_type_from_file_data): + + Fixed bug 5477 ("linux-2.4.0.tar.bz2" is not MP3 file) + Fixed bug 6612 (".doc", ".sdw", etc. are not MP3 files) + + Now call "gnome_vfs_sniff_buffer_looks_like_mp3" just like its text + sniffing counterpart so that it is _not_ called only on failure of + "gnome_vfs_mime_try_one_magic_pattern". + +2001-02-19 Ian McKellar + + reviewed by: Eskil Olsen + + * modules/file-method.c: (do_find_directory): + Changed lstat to stat so that the device ID can be correctly + determined (fixing bug 4980). + +2001-02-16 Gene Z. Ragan + + reviewed by: Mike Enger + + Fixed bug 6624, Selected mime type/description displayed + below the list is incorrect after reverting to system defaults. + + Fixed bug 6644, List sorting after using "revert to system defaults" + is inconsistent. + + * mime-type-capplet/nautilus-mime-type-capplet.c: + (revert_real_cb): + Sort the list using current sort column and select the + first item to force an update of the dialog contents. + Also freeze and thaw list to avoid annoying flicker while + list is being repopulated. + +2001-02-16 John Sullivan + + reviewed by: Gene Z. Ragan + + Fixed bug 6635 (in MIME capplet, descriptions can't be + edited though they look editable) + + * libgnomevfs/gnome-vfs-mime-handlers.c: + * libgnomevfs/gnome-vfs-mime-handlers.h: + (gnome_vfs_mime_set_description): New function, + just like existing _set_icon. + + * mime-type-capplet/nautilus-mime-type-capplet.h: + * mime-type-capplet/nautilus-mime-type-capplet.c: + (nautilus_mime_type_capplet_update_mime_list_icon_and_description): + Changed name to add the _and_description part. It already handled + the description properly but the name was misleading. + (really_change_icon): Updated for name change. + (update_description_from_input): New function, sets the description + in database and UI (list) from what's in the field. + (description_entry_changed): Set dirty flag. + (description_entry_activate), (description_entry_lost_focus): + If dirty flag set, update. + (init_mime_capplet): Hook up text field signal handlers, make + field editable, remove "No Description" case since putting status + text in editable field is wrong. + (nautilus_mime_type_capplet_update_info): Clear dirty flag + when description is updated due to selection change. + + * mime-type-capplet/nautilus-mime-type-icon-entry.c: + (icon_selected_cb): Updated for name change. + +2001-02-16 Gene Z. Ragan + + reviewed by: John Sullivan + + Fixed bug 6648, Able to add mime type even if "mime type" + and description fields are blank. + + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.c: + (validate_text_and_update_button), + (nautilus_mime_type_capplet_show_new_mime_window): + Set sensitive state of OK button based on content of + text entry item in dialog box. + + * mime-type-capplet/nautilus-mime-type-capplet.c: + (nautilus_mime_type_capplet_add_extension), (init_mime_capplet), + (add_mime_clicked): + Check for '\0' instead of ' ' to avoid empty strings + +2001-02-16 Rebecca Schulman + Fixed bugzilla.eazel.com 6220, that incorrect + file counts messed up the progress bar during FTP + copies. + + reviewed by: Gene Regan + + * libgnomevfs/gnome-vfs-directory.c: (lookup_ancestor), + (directory_visit_internal): + Only rely on valid inodes to determine if a link is + circular. Otherwise, use a hard limit for symbolic links + of 256, which should be greater than or equal too all + systems we'll work with. + * libgnomevfs/gnome-vfs-xfer.c: Fix spelling error in a comment + * modules/ftp-method.c: (ls_to_file_info): + Don't rely on inode and device information being valid. + + +2001-02-15 John Sullivan + + reviewed by: No one explicitly, but Darin said this change was + worth doing. + + Addressed part of bug 6666 (Nautilus crashes when you type "nfs://" + in the location bar) + + * libgnomevfs/gnome-vfs-file-info.c: (gnome_vfs_file_info_matches): + Added g_return_val_if_fails so it won't crash when fed a NULL + file_info, or a file_info with a NULL name. + +2001-02-15 John Sullivan + + reviewed by: Gene Ragan + + Fixed some problems and cleaned up some code + that I ran into while investigating bug 5777 (Nautilus + does not pick up MIME preferences right away) + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_get_short_list_applications): + Prune user's short list additions of nonexistent + applications (already pruned other lists); removed + mysteriously incorrect FIXME; deployed + gnome_vfs_mime_type_is_supertype() one more place. + + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.c: + (insert_item), (create_application_list_item): + New helper functions used for dialogs showing lists + of applications, extracted and simplified from existing + code. + (populate_default_applications_list): Use helper functions + instead of repeating all the code here. + (initialize_edit_applications_dialog): Swapped order of two + lines for clarity & slight efficiency gain. + (add_item_to_application_list): Use helper functions instead + of repeating all the code here; select newly-added item. + (show_new_application_window): Removed two initialized but + never used variables. + (show_edit_applications_dialog), (show_edit_components_dialog), + (nautilus_mime_type_capplet_show_new_mime_window), + (nautilus_mime_type_capplet_show_change_extension_window), + (nautilus_mime_type_capplet_show_new_extension_window), + (show_new_application_window), (show_edit_application_window): + Cleaned up all callers of gnome_dialog_run; some were not + handling the close box properly; others were just using more + lines of code than needed; none were using GNOME_OK for clarity. + + * mime-type-capplet/nautilus-mime-type-capplet.c: + (revert_mime_clicked): Improved some error message text a little. + +2001-02-15 John Sullivan + + reviewed by: Darin Adler + + Fixed bug 6660 (list of all apps for text/xml + doesn't include text/* handlers) + + * libgnomevfs/gnome-vfs-mime.h: + * libgnomevfs/gnome-vfs-mime.c: + (gnome_vfs_mime_type_is_supertype): New public function. + (extract_prefix_add_suffix): Utility function used + by _get_supertype_from_mime_type, moved from another file. + (gnome_vfs_get_supertype_from_mime_type): New public + function (formerly private in mime-handlers.c under + the name "mime_type_from_supertype". + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_get_default_component), + (gnome_vfs_mime_get_short_list_applications), + (gnome_vfs_mime_get_short_list_components), + (gnome_vfs_mime_get_all_components), + (gnome_vfs_mime_component_list_free): + Update for renaming; remove mime_type_from_supertype. + + * libgnomevfs/gnome-vfs-application-registry.c: + (gnome_vfs_application_registry_get_applications): + Use new functions to fix completely broken code to + get supertype's list of apps. + + (add_application_to_mime_type_table), + (remove_application_from_mime_type_table): Use + new is_supertype function instead of using strstr. + +2001-02-14 Gene Z. Ragan + + Fixed bug 6629, Default action icon disappears when switching + from application->viewer->application + + Fixed bug 6630, Default action icon not drawn when changing + the default application + + * mime-type-capplet/nautilus-mime-type-capplet.c: + (init_mime_capplet), (update_mime_list_action): + Call handy utility function to get custom or default + action icon based on mime tpye and type of action. + + (column_clicked): + Remove some debugging cruft. + +2001-02-14 Gene Z. Ragan + + Fixed bug 6570, Initial tab order in "Add application" + dialog is broken. + + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.c: + (nautilus_mime_type_capplet_show_new_mime_window), + (add_extension_clicked), + (nautilus_mime_type_capplet_show_new_extension_window), + (show_new_application_window), (show_edit_application_window): + Set focus to proper widget in all of these functions. + +2001-02-13 Gene Z. Ragan + + Fixed bug 6579, Clicking on a column for sorting performs + descending sort first. + + * mime-type-capplet/nautilus-mime-type-capplet.c: + (init_mime_capplet): + Create a global array that tracks the initial first time click + state of the columns. + + (column_clicked): + Check click state of column and decide initial sort mode based + on value. + +2001-02-13 Gene Z. Ragan + + Fixed bug 6577, New mime type isn't highlighted after creation. + + * mime-type-capplet/nautilus-mime-type-capplet.c: + (find_row_for_mime_type): + Return index of row if mime type is found in list + or -1 if it is not. + + (init_mime_capplet): + Call find_row_for_mime_type() + + (nautilus_mime_type_capplet_update_info), (add_mime_clicked): + Sort, select and scroll to new mime type. + +2001-02-13 Ian McKellar + + * modules/http-method.c: (do_close): + Added mime-sniffing to PUT to resolve bug 4102. + +2001-02-12 Don Melton + + reviewed by: Maciej Stachowiak + + * libgnomevfs/gnome-vfs-mime-magic.c: + (gnome_vfs_sniff_buffer_looks_like_mp3): + + Fixed bug 5570 (bmp file sometimes appears as an mp3 file) + + Basically I re-wrote the entire function to be much smarter + about detecting an MPEG audio header and it now also checks + for the existence of an ID3 version 2 tag. + +2001-02-12 Gene Z. Ragan + + Fixed bug 6447, "Change file extensions" erases all extensions + + * mime-type-capplet/nautilus-mime-type-capplet.c: + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.h: + (nautilus_mime_type_capplet_show_change_extension_window): + Add a variable to function that tells if returned list + is to be used to replace existing extension mapping for + mime type. + + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.c: + (add_extension_clicked), (change_file_extensions_clicked): + Do some sanity checking for empty or NULL new extensions + +2001-02-12 Gene Z. Ragan + + Fixed bug 6471, wrong text in "add extension" dialog + + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.c: + (nautilus_mime_type_capplet_show_new_extension_window): + Update text using new language from Vera. + +2001-02-12 John Sullivan + + reviewed by: Gene Z. Ragan (under protest, + since Gene hates the use of "MIME") + + Changed all uses of "Mime" or "mime" in the UI to be + "MIME". Also improved the wording for the "revert" + dialog, though it still could use Verafication. Also, + using "MIME" in the UI at all rather sucks. It would + be nice if we could avoid this nerd terminology someday. + + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.c: + (initialize_edit_applications_dialog), + (initialize_edit_components_dialog), + (nautilus_mime_type_capplet_show_new_mime_window): + * mime-type-capplet/nautilus-mime-type-capplet.c: + (init_mime_capplet), (revert_mime_clicked), + (create_mime_list_and_scroller): + +2001-02-08 Gene Z. Ragan + + Fixed bug 6329, Typing gconf: and pressing ENTER in the + navigation bar crashes Nautilus. + + * modules/gconf-method.c: + (make_absolute): + Replace dangerous macro with a function that error checks. + + (get_value_size), + (set_stat_info_value), (do_open_directory), (do_read_directory), + (do_get_file_info), (vfs_module_shutdown): + Do error checking. + +2001-02-08 Robey Pointer + + * libgnomevfs/gnome-vfs-utils.c: (gnome_vfs_get_volume_free_space): + + Fix build bustage (declare 'ret'). + +2001-02-08 Michael K. Fleming + + Bug 6451: Copying file into folder with space in it fails with + "out of space" error. + + gnome_vfs_get_volume_free_space was calling statfs() with escaped + paths and returning the wrong error code. + + * libgnomevfs/gnome-vfs-utils.c: (gnome_vfs_get_volume_free_space): + +2001-02-08 Ian McKellar + + reviewed by: Robey Pointer + + * libgnomevfs/gnome-vfs-parse-ls.c: (gnome_vfs_parse_ls_lga): + Fixing bug 6214 - the ls parser now correctly handles filenames + with spaces in them. + +=== end of changes from gnome-vfs-1 branch === + +2001-02-28 Gene Z. Ragan + + reviewed by: Pavel Cisler + + Fixed bug 7148, Flash files identified as mp3 + + * data/mime/gnome-vfs-mime-magic: + * data/mime/gnome-vfs.keys.in: + * data/mime/gnome-vfs.mime: + Add application/x-shockwave-flash information. + +2001-02-24 Marius Andreiana + + * configure.in: Added ro (Romanian) to ALL_LINGUAS. + +2001-02-16 Seth Nickell + + * modules/test-method.c: (translate_uri): + + Make test-method.c not bite ass on "test://" + +2001-02-13 Dan Winship + + * libgnomevfs/gnome-vfs-process.c (sigchld_handler): Initialize + found to FALSE. + +2001-02-07 Robin * Slomkowski + + * configure.in: Changed version to 2.0 + FIRST COMMIT AFTER BRANCHING gnome-vfs-1 + +2001-02-06 Pavel Cisler + + reviewed by: Mike Fleming + + Fix 3451 (Loading a directory with a circular symbolic link + causes the load to be interrupted) + + Fix 6221 (Nautilus shows only 6 of the 56 items in my home directory) + + * libgnomevfs/gnome-vfs-types.h: + * modules/file-method.c: (get_stat_info), + (get_stat_info_from_handle), (read_directory), (do_get_file_info), + (do_get_file_info_from_handle): + Make erors while obtaining stat info and mime type not interrupt + directory loading. + Make do_get_file_info not give up as easily when dealing with + recursive links. + + * libgnomevfs/gnome-vfs-xfer.c: (gnome_vfs_xfer_empty_directories): + Fix a problem where an error in directory emptying preflight or + emptying itself would cause the operation to stop rather than + continue with deleting the remaining items. + +2001-02-06 Gene Z. Ragan + + Fixed bug 6258, Determine initial capplet sort column + + * mime-type-capplet/nautilus-mime-type-capplet.c: + (init_mime_capplet): + Sort based on first column in list. + +2001-02-06 Maciej Stachowiak + + * Makefile.am, .cvsignore: Updated for new xml-i18n-tools. + +2001-02-05 Pavel Cisler + + reviewed by: Seth Nickell + + Fix 5930 (Copy dialog often shows "1" as total number of + fields in operation) + Fix a ton of problems with the progress calculation. + + * libgnomevfs/gnome-vfs-xfer.c: (remove_file), (remove_directory), + (count_each_file_size_one), (gnome_vfs_xfer_empty_directories), + (gnome_vfs_xfer_delete_items), (gnome_vfs_xfer_uri_internal), + (gnome_vfs_xfer_private): + When removing during a copy conflict, do not update the progress. + Store and retireve the preflight results when doing a conflict + handling during copy. + Properly calculate removed file size -- use a nominal per-file + overhead rather than the file size. + Properly calculate progress for files with zero or near-zero + size. + Fix numerous wrong uses of total_bytes_copied and bytes_total. + + * configure.in: + Bump GnomeVFS version. + +2001-02-05 Gene Z. Ragan + + Work done to improve the mime tpye capplet. + Enable the capplet to be launched with a mime type. + If a mime type is an argument, have the capplet scroll + to that item in the list before the user begins interaction. + + * mime-type-capplet/nautilus-mime-type-capplet.c: (main), + (list_move_vertical), (list_moveto), (list_reveal_row), + (init_mime_capplet), (populate_mime_list): + +2001-02-05 Rebecca Schulman + Fix problem that the mozilla view was the default for webdav + directories (should be icon view) and that the music view was + always first on the short list. The problem was that the default + component for the supertype to the short list was first on the + short list, instead of being after all of the regular mime type's + short list components. We now only use the supertype's default + if it is explicitly set by the user. + + reviewed by: Mike Fleming + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_get_default_component): + Only use the supertype's default if it is explicitly added + by the user. Otherwise add the supertype shortlist components + to the end of the short list. + +2001-02-05 Rebecca Schulman + + reviewed by: Maciej Stachowiak + + * data/mime/gnome-vfs-mime-magic: + Add bzip as a magic pattern + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_get_default_component), + (gnome_vfs_mime_get_short_list_components): + Return short list components in order of + their appearance on the short list rather than + in alphabetical order + +2001-02-05 Michael K. Fleming + + * modules/http-method.c: (vfs_module_init): + + Bug 6303: GError was potentially being re-used after being free'd + +2001-02-03 Michael K. Fleming + + reviewed by: + + Bug 6299: gnome_vfs_get_volume_free_space has never worked= + + But it works now, as cheesy as it is. + + * libgnomevfs/gnome-vfs-utils.c: (gnome_vfs_get_volume_free_space): + +2001-02-03 Pavel Cisler + + reviewed by: + + * modules/http-method.c: (cache_check_directory), + (vfs_module_init), (vfs_module_shutdown): + Use an explicit mutex initializer instead of a static initializer to make + things more portable. + +2001-02-03 Rolf Grossmann + + reviewed by: Pavel Cisler + + Make it build on FreeBSD. + + * modules/ftp-method.c: + Add includes. + + * modules/nfs-method.c: (nfs_clnt_call): + #ifdef an unsupported define + +2001-02-03 Pavel Cisler + + reviewed by: Mike Fleming + + Fix 3075 (gnome-vfs dumps core on FreeBSD 4.1-STABLE when you start + Nautilus) + * libgnomevfs-pthread/gnome-vfs-async-job-map.c: + (gnome_vfs_async_job_map_init): + * libgnomevfs-pthread/gnome-vfs-async-job-map.h: + * libgnomevfs-pthread/gnome-vfs-pthread.c: + (gnome_vfs_pthread_init), (gnome_vfs_pthread_recursive_mutex_init): + * libgnomevfs-pthread/gnome-vfs-pthread.h: + * libgnomevfs-pthread/gnome-vfs-thread-pool.c: + (gnome_vfs_thread_pool_init): + * libgnomevfs-pthread/gnome-vfs-thread-pool.h: + Get rid of recursive mutex static initialization. Add an + initializer call that is called during backend init. + + * libgnomevfs-pthread/gnome-vfs-async-ops.c: + (pthread_gnome_vfs_async_cancel): + * libgnomevfs-pthread/gnome-vfs-job-slave.c: (thread_routine): + * libgnomevfs-pthread/gnome-vfs-job.c: (job_notify), + (gnome_vfs_job_set), (gnome_vfs_job_new), (gnome_vfs_job_destroy), + (gnome_vfs_job_go): + * libgnomevfs-pthread/gnome-vfs-job.h: + Get rid of using "fast" pthread_mutex as a semaphore, use a real + semaphore instead. + + * libgnomevfs/gnome-vfs-xfer.c: (copy_file_data): + Fix a bug with not respecting "Retry" properly. + +2001-02-02 Rebecca Schulman + Fix bugs 6241 and 6171, that the default viewer + was wrong for various types of files + + reviewed by: Gene Regan + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_get_short_list_components): + Use the new oaf query that will preserve iid list + order in the short list. + Also remove a fixme for bug 1142 that has now been fixed. + +2001-02-02 Darin Adler + + reviewed by: Mike Fleming + + * libgnomevfs/gnome-vfs-result.h: Add include so you can include + this file alone. + * libgnomevfs/gnome-vfs-utils.c: (gnome_vfs_get_volume_free_space): + Change "file" check to check for scheme == "file" instead of any + scheme that starts with file. Also got rid of the case-sensitive + version of "str_has_prefix" since the one case that was using it + could use the case-insensitive one instead. + +2001-02-01 Ramiro Estrugo + + reviewed by: Maciej Stachowiak + + * data/mime/gnome-vfs.keys.in: + * doc/mime-data-specification.txt: + * libgnomevfs/gnome-vfs-mime-handlers.c: (get_user_level): + * test/test-mime-info.c: (main): + Change 'hacker' to 'advanced' for the advanced user level so that + the names used for storage match those used for display. + +2001-02-01 Ian McKellar + + reviewed by: Eskil Olsen + + * modules/ftp-method.c: (do_path_command), + (do_path_transfer_command): + Decode path before doing operations. + + (do_open_directory): + Removed debugging output. + + * test/test-remote: + * test/test-sync-create.c: (main): + Fixed bugs in test code. + +2001-01-31 Maciej Stachowiak + + reviewed by: Rebecca Schulman + + * libgnomevfs/gnome-vfs-mime-handlers.c + (gnome_vfs_mime_get_default_component): Remove FIXME 1142 (OAF + queries don't precisely match those used in Nautilus), upon + further review I decided this was OK. + +2001-01-31 Pavel Cisler + + reviewed by: Gene Z. Ragan + + Fix 5324 (Should get rid of stack-based GnomeVFSFileInfo) + + * libgnomevfs-pthread/gnome-vfs-async-ops.c: + (pthread_gnome_vfs_async_set_file_info): + * libgnomevfs-pthread/gnome-vfs-job.c: + (dispatch_set_file_info_callback), + (gnome_vfs_job_destroy_notify_result), (gnome_vfs_op_destroy), + (execute_set_file_info): + * libgnomevfs-pthread/gnome-vfs-job.h: + * libgnomevfs/gnome-vfs-file-info.c: (gnome_vfs_file_info_ref), + (gnome_vfs_file_info_unref), (gnome_vfs_file_info_clear): + * libgnomevfs/gnome-vfs-file-info.h: + * libgnomevfs/gnome-vfs-ops.c: (gnome_vfs_uri_exists): + * libgnomevfs/gnome-vfs-xfer.c: (empty_directory), + (non_recursive_empty_directory), (gnome_vfs_visit_list), + (handle_name_conflicts), (copy_directory), (copy_items), + (gnome_vfs_xfer_delete_items_common): + * test/test-info.c: (main): + Get rid of gnome_vfs_file_info_init. + Replace all instances of stack-based GnomeVFSFileInfo + structures, replace all calls to gnome_vfs_file_info_init + with gnome_vfs_file_info_new. + Replace most calls to gnome_vfs_file_info_clear with + gnome_vfs_file_info_unref. + + * libgnomevfs/gnome-vfs-file-info.c: (gnome_vfs_file_info_ref), + (gnome_vfs_file_info_unref): + Get rid of FILE_INFO_REFCOUNT_STACK. + + +2001-01-30 John Sullivan + + reviewed by: Darin Adler + + Fixed bug 5842 ("file://home" converted to "home") + + Now "file://home" is left as "file://home". There's a + related bug where "file://home" isn't recognized as + an invalid URI, which I'll write up and fix separately. + + * libgnomevfs/gnome-vfs-utils.c: + (gnome_vfs_get_local_path_from_uri): + Only strip "file://" if uri starts with "file:///" + + * modules/file-method.c: (get_path_from_uri): + Take out evil code that was prepending a "/" to file: + URIs that were missing the initial "/". + +2001-01-30 Darin Adler + + reviewed by: John Sullivan + + * data/mime/gnome-vfs-mime-magic: Change magic so it recognizes + Nautilus links with lower-case XML tags instead of upper-case. + +2001-01-30 Rebecca Schulman + Removed all instances of "default_application_id" + and "default_component_id" from the system + gnome-vfs keys file, and fixed short list ordering + where the current order would incorrectly determine the + correct default application. + Added documentation to the mime data specification about + how exactly user and system configuration .keys files + are used. We need to record this information about + other mime data files as well. + + * data/mime/gnome-vfs.keys.in: + * doc/mime-data-specification.txt: + +2001-01-29 Mike Fleming + + reviewed by: + + Bug 5011: New versionable GnomeVFS module interface + + The GnomeVFSMethod now has a "method_table_size" as its first + member, which should be set to sizeof (GnomeVFSMethod) so that + GnomeVFS knows what version of the interface the method is using. + + Old modules will get compile-time warnings and will more than likely + be not loaded at runtime. (If they do manage to load, they will break) + + Also: fixed cdda module to use new gconf HTTP proxy format + + * libgnomevfs/gnome-vfs-cancellable-ops.c: + (gnome_vfs_open_uri_cancellable), + (gnome_vfs_create_uri_cancellable), + (gnome_vfs_get_file_info_uri_cancellable), + (gnome_vfs_truncate_uri_cancellable), + (gnome_vfs_make_directory_for_uri_cancellable), + (gnome_vfs_find_directory_cancellable), + (gnome_vfs_remove_directory_from_uri_cancellable), + (gnome_vfs_unlink_from_uri_cancellable), + (gnome_vfs_create_symbolic_link_cancellable), + (gnome_vfs_move_uri_cancellable), + (gnome_vfs_check_same_fs_uris_cancellable), + (gnome_vfs_set_file_info_cancellable): + * libgnomevfs/gnome-vfs-directory.c: + * libgnomevfs/gnome-vfs-handle.c: (gnome_vfs_handle_new): + * libgnomevfs/gnome-vfs-method.c: (load_module): + * libgnomevfs/gnome-vfs-module.h: + * libgnomevfs/gnome-vfs-private-types.h: + * libgnomevfs/gnome-vfs-seekable.c: (gnome_vfs_seek_emulate): + * libgnomevfs/gnome-vfs-uri.c: (gnome_vfs_uri_is_local): + * modules/bzip2-method.c: + * modules/cdda-method.c: (cdda_context_new): + * modules/efs-method.c: + * modules/extfs-method.c: + * modules/file-method.c: + * modules/ftp-method.c: + * modules/gconf-method.c: + * modules/gzip-method.c: + * modules/http-method.c: + * modules/nfs-method.c: + * modules/pipe-method.c: + * modules/test-method.c: + * modules/translate-method.c: (vfs_module_init), + (vfs_module_shutdown): + +2001-01-17 Mike Fleming + + * modules/http-method.c: (sig_gconf_value_changed), + (vfs_module_init): + + Changed gconf http proxy format + + Old: + + /system/gnome-vfs/use-http-proxy (bool) + /system/gnome-vfs/http-proxy (string; host:port) + + New: + /system/gnome-vfs/use-http-proxy (bool) + /system/gnome-vfs/http-proxy-host (string) + /system/gnome-vfs/http-proxy-port (int) + +2001-01-29 Pavel Cisler + + reviewed by: Gene Z. Ragan + + Fixed 5781 (results of load_directory must be passed in chunks + instead of the entire list) + Fixed 1438 (use plain GList instead of GnomeVFSDirectoryList) + + * libgnomevfs/Makefile.am: + Got rid of gnome-vfs-directory-list.c and gnome-vfs-directory-list.h + + * idl/gnome-vfs-slave.idl: + * libgnomevfs-corba/gnome-vfs-async-ops.c: + (corba_gnome_vfs_async_load_directory), + (corba_gnome_vfs_async_load_directory_uri): + * libgnomevfs-corba/gnome-vfs-slave-notify.c: + (impl_Notify_load_directory): + * libgnomevfs-corba/gnome-vfs-slave-process.h: + * libgnomevfs-corba/gnome-vfs-slave.c: (load_directory), + (impl_Request_load_directory): + * libgnomevfs-pthread/gnome-vfs-async-ops.c: + (async_load_directory), (pthread_gnome_vfs_async_load_directory), + (pthread_gnome_vfs_async_load_directory_uri): + * libgnomevfs-pthread/gnome-vfs-job.c: + (dispatch_load_directory_callback), + (gnome_vfs_job_destroy_notify_result), (gnome_vfs_op_destroy), + (load_directory_details), (execute_load_directory): + * libgnomevfs-pthread/gnome-vfs-job.h: + * libgnomevfs/gnome-vfs-async-ops.h: + * libgnomevfs/gnome-vfs-backend.c: + (gnome_vfs_async_load_directory_uri), + (gnome_vfs_async_load_directory): + * libgnomevfs/gnome-vfs-directory-list.c: + * libgnomevfs/gnome-vfs-directory-list.h: + * libgnomevfs/gnome-vfs-directory.c: (load_from_handle), + (gnome_vfs_directory_list_load): + * libgnomevfs/gnome-vfs-directory.h: + * libgnomevfs/gnome-vfs-file-info.c: + * libgnomevfs/gnome-vfs-file-info.h: + * libgnomevfs/gnome-vfs-types.h: + * libgnomevfs/gnome-vfs.h: + * test/gnome-file-selection/gnome-file-selection.c: + (populate_callback), (start_populating): + * test/test-async-cancel.c: (directory_load_callback), + (directory_load_failed_callback), (test_load_directory_cancel), + (test_load_directory_fail): + * test/test-async-directory.c: (directory_load_callback), (main): + * test/test-directory.c: (print_list), (main): + * test/test-shell.c: (do_ls), (validate_path), (get_regexp_name): + Switched all the users of GnomeVFSDirectoryList to use a GList + instead. Got rid of gnome_vfs_load_directory_sorted. Got rif of + sorting rules. Move gnome_vfs_directory_list_load to gnome-vfs-directory.c + and change it to use a GList. + +2001-01-29 Rebecca Schulman + Change the value of the "expects_uris" attribute + of applications to have 3 possible values: + "yes", "no", and "non-file". This change will + allow applications to understand how to launch programs + that expect local paths for local files, but uris + for non-file locations. + + reviewed by: Darin Adler + + * data/mime/gnome-vfs.applications: + Change expects_uris to "non-file" where appropriate + (for now mpg123), and added supported_uri_schemes + in places where "expects_uris" was "yes" but no + supported uri schemes were listed. This information + is not yet complete. + + * doc/mime-data-specification.txt: Remove the "[to be + implemented]" tag from fields that are now fully implemented + (supported_uri_schemes and expects_uris) + + * libgnomevfs/gnome-vfs-mime-handlers.h: + * libgnomevfs/gnome-vfs-application-registry.h: + * libgnomevfs/gnome-vfs-application-registry.c: (application_new), + (value_looks_true), (get_bool_value), (application_add_key), + (gnome_vfs_application_registry_get_mime_application), + (gnome_vfs_application_registry_save_mime_application): + Parse, set and get the new "expects_uris" + attribute, and represent its set of possible values using + an enum, rather than a gboolean. + + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.c: + (show_new_application_window), (show_edit_application_window): + Add the right bug number to fixmes about updates need in the capplet + to reflect the new application attributes + + * test/test-mime-handlers.c: + (format_mime_application_argument_type_for_display), + (print_application): + Print the "expects_uris" attribute as part of the test + program for application information parsing. + +2001-01-29 Gene Z. Ragan + + Fixed bug 5847, MIME type capplet alphabetical order case sensitive + + * mime-type-capplet/nautilus-mime-type-capplet.c: + (sort_case_insensitive), (column_clicked), + (create_mime_list_and_scroller): + Create a sort routine that is not case sensitive. + +2001-01-29 Rebecca Schulman + + * test/test-mime-handlers.c: (print_application): + Remove changes that won't work until the new + type GnomeVFSMimeApplicationArgumentType is added. + +2001-01-29 Rebecca Schulman + Add new test output, first to debug the + mime info test, that fails, and second + to add a descrption test to the mime handlers + test. The mime info test needs to + be updated so that it works independent of + locale. + + * test/test-mime-info.c: (main): + * test/test-mime-handlers.c: + (format_mime_application_argument_type_for_display), + (print_application), (main): + +2001-01-29 Robin * Slomkowski + + * configure.in: upped version to 0.5.0 + +2001-01-27 Robin * Slomkowski + + * Makefile.am: added xml-i18n files to EXTRA_DISTS + +2001-01-26 Rebecca Schulman + Add support for the "supported_uri_schemes" + attributes in the mime applications file, + and changed can_open_uris to "expects_uris" + because this attribute is more about + the way arguments should be specified than + about its capabilities of understanding + locations. + The supported uri schemes attributes is + optional, and if it is not included, the + value is assumed to be file. + + reviewed by: Pavel Cisler + + * libgnomevfs/gnome-vfs-application-registry.h: + Add the new function + gnome_vfs_application_registry_supports_uri_scheme to the + public api + + * libgnomevfs/gnome-vfs-application-registry.c: (application_new), + (add_application_to_mime_type_table), + (add_mime_type_to_application), + (add_supported_uri_scheme_to_application), + (remove_application_from_mime_type_table), + (remove_mime_type_for_application), + (supported_uri_scheme_list_copy), + (gnome_vfs_application_registry_supports_uri_scheme), + (gnome_vfs_application_registry_supports_mime_type), + (gnome_vfs_application_registry_add_mime_type), + (gnome_vfs_application_registry_remove_mime_type), + Add supported uri schemes functions to complement + the current mime type functions + and refactor the mime_type functions to share code with + the new supported_uri_schemes functions where + appropriate + (application_clear_mime_types), + (application_add_key), + Add ability to parse the supported_uri_schemes attribute + (gnome_vfs_application_registry_get_mime_application), + (gnome_vfs_application_registry_save_mime_application): + Add supported_uri_schemes to these functions + + * libgnomevfs/gnome-vfs-mime-handlers.h: + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_get_short_list_applications), + (gnome_vfs_mime_application_copy), + (gnome_vfs_mime_application_free), + (copy_str_list): + Add supported_uri_schemes to the MimeApplication + structure + + * data/mime/gnome-vfs.applications: + Add some new "supported_uri_schemes". + What I have added is not complete. + * doc/mime-data-specification.txt: + Add information about how user files can augment, but + not replace information about applications' accepted mime + types and supported uri schemes. Add FIXMEs about + how this isn't clearly correct. + + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.c: + (add_or_update_application), (show_new_application_window), + (show_edit_application_window): + Change can_open_uris to "Expects URIs" + + * test/test-mime-handlers-set.c: (main): + * test/test-mime-handlers.c: (append_comma_and_scheme), + (format_supported_uri_schemes_for_display), (print_application): + Update tests, by adding new attribute + +2001-01-26 Seth Nickell + + reviewed by: Gene Z. Ragan + + * modules/efs-method.h: + * modules/file-method.h: + Fix messed up header guards. + +2001-01-25 Pavel Cisler + + reviewed by: Gene Z. Ragan + + * libgnomevfs/gnome-vfs-xfer.c: (gnome_vfs_xfer_private): + Make new folder operation call GNOME_VFS_XFER_PHASE_COMPLETED like + the other file operations to make it easier for callers to clean + up their state. + Simplify a bit. + +2001-01-25 Darin Adler + + * test/test-uri.c: (main): Added some tests to + help demonstrate aspects of bug 6022. + +2001-01-24 Rebecca Schulman + + * doc/mime-data-specification.txt: + Add documentation about new features we + plan to add for 1.0. Most of them + were already in the document, but I've + also cleaned it up and added a new + possible feature addition for the future + that takes care of a few of our design + concerns: the "handled_uri_schemes" + attribute that will list uri schemes + that an application can handle regardless of + mime types. This will allow applications + to accept uris that are not necessarily + understood by gnome-vfs + +2001-01-22 Darin Adler + + * check-mime.pl: Added lots of white space checks. + +2001-01-22 Darin Adler + + * check-mime.pl: Added check for i-regular. + +2001-01-22 Rebecca Schulman + + Fixed bugzilla.eazel.com bug 5498 about + symbolic links across file systems caused + copies instead of drags in nautilus. + This change makes the order uris are + passed to check_same_fs important. + The first uri is now the "source + uri," and the second is the "target uri." + + reviewed by: Pavel Cisler + + * libgnomevfs/gnome-vfs-ops.h: + Change the argument names of check_same_fs to + reflect the new argument names + * modules/file-method.c: (do_check_same_fs): + Do a stat on the "target uri" but an lstat + on the "source uri" + * doc/mime-data-specification.txt: + Added bug number references to the + problems that we list in the specification + +2001-01-20 Pavel Cisler + + reviewed by: Rebecca Schulman + + Work on making Search cancellable. + + * libgnomevfs-pthread/gnome-vfs-async-ops.c: + (pthread_gnome_vfs_async_cancel), (gnome_vfs_job_cancel): + Move the job cancellation outside the job->access_lock to avoid + having to have the load_directory call completely finish before + cancellation takes effect. Move the setting of the cancelled + flag outside gnome_vfs_job_cancel and into the access_lock so that + cancellation of the job and cancellation of the callbacks is atomic. + + * libgnomevfs/gnome-vfs-cancellable-ops.h: + * libgnomevfs/gnome-vfs-directory.c: + (gnome_vfs_directory_open_from_uri_cancellable), + (gnome_vfs_directory_read_next_cancellable): + Add new cancellable versions of gnome_vfs_directory_open and + gnome_vfs_directory_read_next. + + * libgnomevfs-pthread/gnome-vfs-job.c: + (execute_load_directory_not_sorted), + Use the new cancellable open and read_next calls in + execute_load_directory_not_sorted. Pass in the cancellation context. + +2001-01-19 Darin Adler + + * check-mime.pl: Update so it works with the new keys.in file. + +2001-01-19 Pavel Cisler + + reviewed by: Michael Engber + + Fix 1200: count_items_and_size needs to deal with errors. + Fix 4577: File copying that fills a partition will cause an unescapable + loop of error dialogs. + Fix 5518: Nautilus hits assert in build_error_string during some + large copy operation. + + * libgnomevfs/gnome-vfs-xfer.c: (handle_name_conflicts), + (copy_file_data), (gnome_vfs_xfer_delete_items), + (gnome_vfs_xfer_uri_internal): + Make copy loop in copy_file_data properly bail when an error happens + and retry is not requested. + Make count_item_and_size ignore any errors except for cancellations of + the copy -- we will deal with all the errors nicely either in the other + parts of the preflight or during the copy itself. + Pass in the target directory uri to the error handling code that reports + that we have no space on the destination. + + HACKING: + Add some more comments. + +2001-01-19 Darin Adler + + reviewed by: John Sullivan + + Fix bug 5816 (Clicking "Refresh" in View as Image crashes + Nautilus) by getting rid of a "free non-malloc'd memory" problem. + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_get_all_applications): Fixed problem where the + prune function was freeing application IDs that we don't own. + (prune_ids_for_nonexistent_applications): Used g_list_free_1 for + clarity. The old code used g_list_free, which will also work, + since the removed node is a list of length 1. + +2001-01-19 Darin Adler + + reviewed by: John Sullivan + + * .cvsignore: Ignore the xml-i18n-tools files. + * libgnomevfs-pthread/gnome-vfs-async-job-map.c: + (callback_map_cancel_one), (gnome_vfs_async_job_cancel_callbacks): + Use %u instead of %d to format unsigned ints. + * libgnomevfs/gnome-vfs-process.c: (gnome_vfs_process_init): Take + advantage of defaults for the hash and key comparison functions. + * test/gnome-file-selection/gicon.c: (gicon_init): Take advantage + of defaults for the hash and key comparison functions. + +2001-01-19 Pavel Cisler + + reviewed by: Ramiro Estrugo + + Fix 5430: Duplicate a link -> Nautilus won't display without refresh. + + * libgnomevfs/gnome-vfs-xfer.c: (copy_symlink), (copy_directory), + (copy_items): + Replaced a call to gnome_vfs_create_link to a new copy_symlink call + that properly updates progress and sends notifications about the + link being created. + +2001-01-18 Kenneth Christiansen + + * configure.in: Added AM_PROG_XML_I18N_TOOLS to support + my changes to the i18n system. Requires cvs release of + xml-i18n-tools. + +2001-01-18 John Sullivan + + * libgnomevfs/gnome-vfs-utils.c: (gnome_vfs_expand_initial_tilde): + Made this new function never return NULL, after discussing with + Darin. Now it just returns (a copy of) the original path if it + can't expand ~some_user_name/xxx. + +2001-01-18 Pavel Cisler + + * libgnomevfs/gnome-vfs-directory-list.c: + (gnome_vfs_directory_list_new): + Get rid of an unused field. + +2001-01-18 Pavel Cisler + + Part of fix to 4221 (Pressing Cancel button does not cancel) + * libgnomevfs-pthread/gnome-vfs-job.c: (job_notify), + (dispatch_xfer_callback), (dispatch_sync_job_callback): + Make the xfer job notify callback return the same result + when it gets cancelled by gnome_vfs_async_cancel as if + the callback requested a cancellation. + + * libgnomevfs/gnome-vfs-xfer.c: (call_progress), + (call_progress_with_current_names), (call_progress_uri), + (call_progress_with_uris_often), (remove_file), (empty_directory), + (remove_directory): + Fixed a lot of white space. + +2001-01-18 Mike Fleming + + reviewed by: Ramiro Estrugo + + * modules/http-method.c: (sig_gconf_value_changed), + (vfs_module_init): + Proxy preferences are now split into host and port rather than + using one string. + +2001-01-17 Pavel Cisler + + * test/test-async-cancel.c: (test_load_directory_cancel), + (test_find_directory_callback), (test_find_directory), (main): + Add more async tests. + +2001-01-17 Pavel Cisler + + reviewed by: Rebecca Schulman + + Fix 5732 (Cancelling a File Copy dialog crashes Nautilus) + * libgnomevfs-pthread/gnome-vfs-job.c: (job_notify): + Fix a deadlock and a crash when xfer notify callback gets called + repeatedly after the copy operation was cancelled (a separate + bug). + + * libgnomevfs-pthread/gnome-vfs-async-job-map.c: + (gnome_vfs_async_job_cancel_callbacks): + Fix a debug build problem. + + * libgnomevfs-pthread/gnome-vfs-job.h: + Removed an unused field. + +2001-01-17 John Sullivan + + reviewed by: Rebecca Schulman + + Fixed problems that were part of bug 5581 (Can't make + StarOffice the default application for file types). There + were three problems, of which two are now fixed: + (1) Installing StarOffice (at least using Sun's installer) + doesn't add its directory to $PATH, and it isn't installed + in a directory already in $PATH. This is not fixed. + (2) Applications not in $PATH were not stripped from the + complete list, but should be since they can't be used (the + same reason they are stripped from the short list and + default). This is fixed. + (3) The code that checked whether applications were in $PATH + didn't handle paths starting with ~. This is fixed. + + * libgnomevfs/gnome-vfs-utils.h: + * libgnomevfs/gnome-vfs-utils.c: + (gnome_vfs_expand_initial_tilde): Function moved here and + renamed from expand_tilde in nautilus-file-utilities.c. Next + I'll make Nautilus use this function. + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_get_all_applications): Prune nonexistent + applications (including ones not in the path) from here + also, since they can't be used by Nautilus. + (executable_in_path): Handle parts of $PATH that start with ~ + +2001-01-17 Ian McKellar + + * test/test-dirop.c: (main): + Allow the initial permissions for a directory to be + specified on the test tool command line. + +2001-01-17 Pavel Cisler + + reviewed by: Darin Adler + + * libgnomevfs-pthread/gnome-vfs-async-ops.c: + (pthread_gnome_vfs_async_cancel): + Fix a typo (g_mutex_lock->g_mutex_unlock) that caused a race + condition where async callbacks could have been scheduled after + a cancellation. + + * libgnomevfs-pthread/gnome-vfs-job.c: + (execute_load_directory_not_sorted): + Whitespace tweak. + +2001-01-16 Pavel Cisler + + * libgnomevfs-pthread/gnome-vfs-job.c: + (dispatch_load_directory_callback), + (gnome_vfs_shared_directory_list_unref), + (execute_load_directory_not_sorted): + Fix several crashes when load directory hits an error and ends + up with an empty directory list. + + * test/test-async-cancel.c: (directory_load_failed_callback), + (test_load_directory_fail), (main): + Add a test to the test rig that catches the bug I fixed. + + +2001-01-16 Seth Nickell + + reviewed by: Pavel Cisler + + * libgnomevfs/gnome-vfs-application-registry.c: (get_keys_foreach), + (gnome_vfs_application_registry_get_applications): + * libgnomevfs/gnome-vfs-mime-info.c: (mime_list_sort): + + Add casts to strcmp's performed on gpointers so they will + not generate warnings. + +2001-01-16 Pavel Cisler + + reviewed by: Darin Adler + + Fix 5399: Callbacks need a better way to find out if they are still needed. + Fix 5401: Decouple async jobs and callbacks. + Fix 5402: DGnomeVFSAsyncJob cleanup needs to be simplified. + Fix 5677: File copy operation crashes Nautilus. + Fix 1129: Storage leak while cancelling an async operation. + + * libgnomevfs-pthread/Makefile.am: + * libgnomevfs-pthread/gnome-vfs-async-job-map.c: + (gnome_vfs_async_job_map_get_job), + (gnome_vfs_async_job_map_add_job), + (gnome_vfs_async_job_map_remove_job), + (gnome_vfs_async_job_map_destroy), (gnome_vfs_async_job_completed), + (gnome_vfs_async_job_map_shutdown), (gnome_vfs_async_job_map_lock), + (gnome_vfs_async_job_map_unlock), + (gnome_vfs_async_job_map_assert_locked), + (gnome_vfs_async_job_callback_valid), + (gnome_vfs_async_job_add_callback), + (gnome_vfs_async_job_remove_callback), (callback_map_cancel_one), + (gnome_vfs_async_job_cancel_callbacks), + (async_job_callback_map_destroy): + * libgnomevfs-pthread/gnome-vfs-async-job-map.h: + * libgnomevfs-pthread/gnome-vfs-async-ops.c: + Move gnome_vfs_async_job_map calls to their new file. + Add a async job callback map. + Switch to using a static recursive mutext for locking the job map. + Add support for cancelling callbacks. + + + * libgnomevfs-pthread/gnome-vfs-async-ops.c: + (pthread_gnome_vfs_async_cancel): Handle cancelling of + both the job and it's callbacks. + (async_open), + (async_open_as_channel), (async_create), + (pthread_gnome_vfs_async_create_as_channel), + (pthread_gnome_vfs_async_close), (pthread_gnome_vfs_async_read), + (pthread_gnome_vfs_async_write), + (pthread_gnome_vfs_async_create_symbolic_link), + (pthread_gnome_vfs_async_get_file_info), + (pthread_gnome_vfs_async_set_file_info), + (pthread_gnome_vfs_async_find_directory), (copy_sort_rules), + (async_load_directory), (pthread_gnome_vfs_async_xfer), + (pthread_gnome_vfs_async_add_status_callback), + (pthread_gnome_vfs_async_remove_status_callback): + gnome_vfs_job_new now gets called with parameters for the op. + Cache the job handle before starting the job to avoid accessing + the job structure after it has been unlocked and possibly deleted. + Get rid of gnome_vfs_async_job_expired, use gnome_vfs_async_job_completed + instead. + + * libgnomevfs-pthread/gnome-vfs-job-slave.c: (thread_routine), + (gnome_vfs_job_create_slave): + Redo the way jobs are destroyed after they complete. Pass the + job handle instead of the job structure itself to the thread_routine + and check for the job being invalid by the time the thread_routine + runs. + + * libgnomevfs-pthread/gnome-vfs-job.h: + * libgnomevfs-pthread/gnome-vfs-job.c: (gnome_vfs_job_complete), + (job_oneway_notify), (job_notify), (dispatch_open_callback), + (dispatch_create_callback), (dispatch_open_as_channel_callback), + (dispatch_create_as_channel_callback), (dispatch_close_callback), + (dispatch_read_callback), (dispatch_write_callback), + (dispatch_load_directory_callback), + (dispatch_get_file_info_callback), + (dispatch_find_directory_callback), + (dispatch_set_file_info_callback), (dispatch_xfer_callback), + (empty_close_callback), (handle_cancelled_open), + (free_get_file_info_notify_result), + (free_find_directory_notify_result), + (gnome_vfs_job_destroy_notify_result), + (dispatch_sync_job_callback), (dispatch_job_callback), + (gnome_vfs_job_set), (gnome_vfs_job_new), (gnome_vfs_job_destroy), + (gnome_vfs_op_destroy), (gnome_vfs_job_go), (serve_channel_read), + (execute_open), (execute_open_as_channel), (execute_create), + (execute_create_symbolic_link), (execute_create_as_channel), + (execute_close), (execute_read), (execute_write), + (execute_load_directory_not_sorted), + (execute_load_directory_sorted), (execute_get_file_info), + (execute_set_file_info), (execute_find_directory), + (execute_load_directory), (xfer_callback), (execute_xfer), + (gnome_vfs_job_execute), (gnome_vfs_job_cancel): + Remove most of the synchronization between the async thread and the + callbacks, now that the two share no state. + Add a mechanism to figure out if a job is to expire after completing the + current op or not. + Switch to using g_idle_add for scheduling calbacks instead of g_io_channel. + Get rid of tons of casts in the notify callback routines. + dispatch_job_callback now deals with notify_results that belong to operations + that have been canceled while the notification was being dispatched. + Handle job cancellation in execute_xfer. + + * test/test-async-cancel.c: (make_asserts_break), + (directory_load_callback), (test_open_read_close), + (test_open_close), (my_yield), (test_load_directory_cancel), + (main): + Add more tests. + + * libgnomevfs-pthread/gnome-vfs-thread-pool.c: + (gnome_vfs_thread_pool_wait_for_work): + Augument profiler results a bit. + + * libgnomevfs/gnome-vfs-directory-list.c: + Some small tweaks. + +2001-01-15 Michael K. Fleming + + reviewed by: + + * libgnomevfs/gnome-vfs-xfer.c: (move_items), + (gnome_vfs_xfer_uri_internal): + + More fun with bug 5250. Same-filesystem moves that failed from an error + during a move would be deleted even if the user "skipped" them. + + move_items no longer gives progress callback GNOME_VFS_XFER_PHASE_MOVING + for URI's that are skipped (prevents faulty copying of metadata) + + gnome_vfs_xfer_uri_internal returns an error if both move and link conditions + are indicated (obvious contradiction) + + GNOME_VFS_XFER_PHASE_CLEANUP and associated item deletion no longer occurs + for move or link case. I confirmed that this didn't mess up the Nautilus + sync_transfer_callback metadata copying and update mechanism. + + +2001-01-12 Gene Z. Ragan + + Fixed bug 3229, Clean up appearance of File Types and Programs capplet + + * mime-type-capplet/nautilus-mime-type-capplet.c: + (init_mime_capplet): + Adjust positions of widgets for better look and feel. + +2001-01-12 Gene Z. Ragan + + Fix bug 4797, user can choose an icon anywhere on his filesystem + to associate it to a given mime type but the icon will not be used. + + * mime-type-capplet/nautilus-mime-type-icon-entry.c: + (entry_changed), (ientry_destroy), (browse_clicked), + (nautilus_mime_type_show_icon_selection), + (nautilus_mime_type_icon_entry_init), + (nautilus_mime_type_icon_entry_set_pixmap_subdir): + Remove ability to navigate to directories outside of the + shared pixmap path. + +2001-01-09 Pavel Cisler + + * libgnomevfs-pthread/gnome-vfs-job.h: + Oops, turn off spew that I enabled and checked in by accident. + +2001-01-09 Pavel Cisler + + reviewed by: Darin Adler + + Fixed 5398 (Async callbacks need to be passed over ownership of data) + + * libgnomevfs-pthread/gnome-vfs-async-ops.c: (async_open), + (async_open_as_channel), (async_create), + (pthread_gnome_vfs_async_create_as_channel), + (pthread_gnome_vfs_async_read), (pthread_gnome_vfs_async_write), + (pthread_gnome_vfs_async_create_symbolic_link), + (pthread_gnome_vfs_async_get_file_info), + (pthread_gnome_vfs_async_set_file_info), + (pthread_gnome_vfs_async_find_directory), (async_load_directory), + (pthread_gnome_vfs_async_xfer): + * libgnomevfs-pthread/gnome-vfs-job.c: (wakeup), + (job_oneway_notify), (job_notify), (job_oneway_notify_and_close), + (job_notify_and_close), (dispatch_open_callback), + (dispatch_create_callback), (dispatch_open_as_channel_callback), + (dispatch_create_as_channel_callback), (dispatch_close_callback), + (dispatch_read_callback), (dispatch_write_callback), + (dispatch_load_directory_callback), + (free_get_file_info_notify_result), + (dispatch_get_file_info_callback), + (free_find_directory_notify_result), + (dispatch_find_directory_callback), + (dispatch_set_file_info_callback), (dispatch_xfer_callback), + (gnome_vfs_job_destroy_notify_result), (dispatch_job_callback), + (gnome_vfs_job_destroy), (gnome_vfs_op_destroy), + (serve_channel_read), (serve_channel_write), (execute_open), + (execute_open_as_channel), (execute_create), + (execute_create_symbolic_link), (execute_create_as_channel), + (execute_close), (execute_read), (execute_write), + (execute_load_directory_not_sorted), + (execute_load_directory_sorted), (execute_get_file_info), + (execute_set_file_info), (execute_find_directory), + (execute_load_directory), (xfer_callback), (execute_xfer): + * libgnomevfs-pthread/gnome-vfs-job.h: + Allocate a new struct for notification results for all async callbacks + except for xfer. Pass the notification results as data when waking up + the notification callback. Delete the notification results once the + callback is done. Remove notification result fields from the different + op structures. + +2001-01-09 Aaron Brick + + * added MIME description guidelines in + doc/mime-descriptions-guidelines.txt, superceding old rules + in data/mime/gnome-vfs.keys. + + * referred to the new file twice in mime-data-specification.txt + and in the comments of data/mime/gnome-vfs.keys. + +2001-01-08 Ian McKellar + + reviewed by: mfleming@eazel.com + + * modules/ftp-method.h: + * modules/ftp-method.c: (ftp_response_to_vfs_result), + (get_response), (do_basic_command), (do_path_command_completely), + (ftp_connection_release), (do_open), (do_make_directory), + (do_remove_directory), (do_move), (do_unlink): + The meaning of an FTP 550 response depends on what call was made. + The GnomeVFSError to be returned for a 550 may now be specified + at a higher level. + + (ftp_connection_create), (ftp_connection_destroy), + (internal_get_file_info), (do_open_directory): + Store the response of SYST (operating system) for each connection. + Don't request server-side symlink expansion for MacOS servers, + because they get confused. + + (do_read_directory): + Unset the permissions bit of file info valid fields. + +2001-01-08 Gene Z. Ragan + + Fixed bug 3041, "Action" column text is confusing + + * mime-type-capplet/nautilus-mime-type-capplet.c: + (add_mime_clicked), (update_mime_list_action), + (populate_mime_list), (create_mime_list_and_scroller): + Made changes according to input from John and Arlo. + Changed "Action" column to "Default Action." + Changed action text when a viewer is specified to + "View as" preprended to the action type. + +2001-01-08 Mike Fleming + + reviewed by: pavel@eazel.com + + * libgnomevfs/gnome-vfs-xfer.c: (xfer_create_target), (copy_file), + (copy_directory), (copy_items), (gnome_vfs_xfer_uri_internal): + + Bug 5250 (Hitting "skip" during a move operation across filesystems + causes skipped file not to be copied but still to be deleted). + + The new behaviour builds a list of successfully copied URI's. It + is these files that are deleted, not all of the original source URI's. + + Also: fix bug where files and directories copied from HTTP DAV server + to local filesystem would have permissions of 000 set. Now, files + and directories are left with permissions set according to the user's + umask + +2001-01-05 John Sullivan + + reviewed by: Darin Adler + + Fixed bug 5337 (MIME code hits disk every few seconds + to check for changed data) + + I tried a gconf-based approach but was thwarted (see + bug 5460). So I just removed the polling code that hits + the disk. This leaves behind fairly minor bug 5459. Oh + well. + + * libgnomevfs/gnome-vfs-mime-info.c: (gnome_vfs_mime_init), + (reload_if_needed_idle_function): + Removed the polling mechanism for checking whether data on + disk has changed. + (gnome_vfs_mime_info_reload): Added numbered FIXME comment + about bugs 5459 and 5460. + + * libgnomevfs/gnome-vfs-mime-monitor.c: + (gnome_vfs_mime_monitor_emit_data_changed): + Removed debugging spam accidentally left in earlier. + + * modules/http-method.c: (vfs_module_init): Removed FIXME + comment for bug that I fixed recently. + +2001-01-05 Rebecca Schulman + + reviewed by: Pavel Cisler + + * doc/mime-data-specification.txt: + Add attribution to Darin Adler for his work on the + document. + * libgnomevfs-pthread/gnome-vfs-async-ops.c: + (gnome_vfs_async_job_map_shutdown): + Remove a bogus assert that crashed when exiting + if no async calls had been made. + +2001-01-03 Pavel Cisler + + * libgnomevfs-pthread/gnome-vfs-job-slave.c: (thread_routine): + + Fix a problem in my previous change -- in a certain sequence the + job would expire and never call the last callback which in turn + would cause the job spawner to try to cancel it or otherwise + misbehave. + +2001-01-03 Pavel Cisler + + reviewed by: Darin Adler + + Fix bug 5397 (use unique job IDs instead of GnomeVFSAsyncHandles) + + * libgnomevfs-pthread/gnome-vfs-async-ops.c: + * libgnomevfs-pthread/gnome-vfs-job.h: + * libgnomevfs-pthread/gnome-vfs-job.c: (dispatch_open_callback), + (dispatch_create_callback), (dispatch_open_as_channel_callback), + (dispatch_create_as_channel_callback), (dispatch_close_callback), + (dispatch_read_callback), (dispatch_write_callback), + (dispatch_load_directory_callback), + (dispatch_get_file_info_callback), + (dispatch_find_directory_callback), + (dispatch_set_file_info_callback), (dispatch_xfer_callback), + (gnome_vfs_job_new): + (gnome_vfs_async_job_map_add_job), + (gnome_vfs_async_job_map_destroy), (async_job_map_remove_job), + (gnome_vfs_async_job_expired), (async_job_map_get_job), + (gnome_vfs_async_job_map_shutdown), + (pthread_gnome_vfs_async_cancel), (async_open), + (async_open_as_channel), (async_create), + (pthread_gnome_vfs_async_create_as_channel), + (pthread_gnome_vfs_async_close), (pthread_gnome_vfs_async_read), + (pthread_gnome_vfs_async_write), + (pthread_gnome_vfs_async_create_symbolic_link), + (pthread_gnome_vfs_async_get_file_info), + (pthread_gnome_vfs_async_set_file_info), + (pthread_gnome_vfs_async_find_directory), (copy_sort_rules), + (async_load_directory), (pthread_gnome_vfs_async_load_directory), + (pthread_gnome_vfs_async_xfer), + (pthread_gnome_vfs_async_add_status_callback), + (pthread_gnome_vfs_async_remove_status_callback): + assign jobs unique id's. Use a map to map job ids to job structs. + + * libgnomevfs-pthread/gnome-vfs-job-slave.c: (thread_routine), + (gnome_vfs_job_create_slave): + Add new jobs to the job id map as they get created. Remove them + when a thread expires. + + * libgnomevfs-pthread/gnome-vfs-job-slave.c: + (gnome_vfs_thread_backend_shutdown): + Get rid of the job id map when we quit. + + * libgnomevfs-pthread/gnome-vfs-thread-pool.c: + Make some debugging code better. + + * libgnomevfs-pthread/gnome-vfs-job-slave.c: + (gnome_vfs_job_create_slave): + Remove some code that was ifdefd out now that new thread pool code + seems to be working fine. + +2001-01-02 John Sullivan + + reviewed by: Darin Adler + + Fixed bug 5339 (http proxy value reset when any Nautilus + preference changes). This is a low-priority bug but I + was working on another related bug and couldn't help + fixing this. + + * libgnomevfs/gnome-vfs-mime-monitor.c: Fixed a copy/paste + error in a comment. + + * modules/http-method.c: (sig_gconf_value_changed): + Ignore keys other than the ones we care about. + +2001-01-03 Rebecca Schulman + + reviewed by: + + * doc/mime-data-specification.txt: + +2000-12-29 Darin Adler + + reviewed by: Pavel Cisler + + Fixed bug 3117 (Certain files incorrectly get the core file icon + in icon-view mode). + + * data/mime/gnome-vfs.mime: Changed the regular expression for core + files to match only files named "core", not all files with "core" in + their names. Added some FIXMEs. + +2000-12-28 Darin Adler + + reviewed by: Maciej Stachowiak + + * libgnomevfs/gnome-vfs-utils.c: + (gnome_vfs_format_file_size_for_display): Changed format from + "1.1M" to "1.1 MB". For kilobytes, I decided to do the same thing + we did for the Macintosh Finder, and use "123 K" instead of the + correct but obscure "123 kB". These strings are marked for + translation as before, so it can be changed for different + countries. One reason these have to be changed is that they are + currently inconsistent with the hard-drive size numbers displayed + in the Nautilus hardware view (so one or the other had to change). + +2000-12-22 John Sullivan + + * modules/http-method.c: (vfs_module_init): + Added a FIXME with bug number for a bug I noticed here. + +2000-12-22 John Sullivan + + * libgnomevfs/gnome-vfs-mime-info.c: + (reload_if_needed_idle_function): Saved the terminal by + removing a debug g_message. + +gno2000-12-22 Pavel Cisler + + * libgnomevfs/gnome-vfs-mime-monitor.c: + (gnome_vfs_mime_monitor_emit_data_changed): + Save the world by adding a newline to the end of file. + New gcc 2.96 is picky about that. + +2000-12-22 John Sullivan + + reviewed by: Pavel Cisler + + GNOME_VFS part of fix for bug 4798 (icon changes in MIME + type capplet aren't reflected automatically in Nautilus) + + I invented an object that emits signals when the MIME + data changes. Clients can connect to the signal to do + their evil deeds. Unfortunately, the granularity of the + signal is just "some MIME data changed", but we can live + with that for now. + + * libgnomevfs/gnome-vfs-mime-monitor.h: + * libgnomevfs/gnome-vfs-mime-monitor.c: + (gnome_vfs_mime_monitor_get_type), + (gnome_vfs_mime_monitor_get), + (gnome_vfs_mime_monitor_initialize), + (gnome_vfs_mime_monitor_initialize_class), + (gnome_vfs_mime_monitor_emit_data_changed): + New files that define new class GnomeVFSMIMEMonitor. + Its only purpose is to emit signals, and its only + public function is gnome_vfs_mime_monitor_get (), which + returns the one global GnomeVFSMIMEMonitor object so you + can connect to its signals. The only signal it emits is + "data_changed". + + * libgnomevfs/gnome-vfs-mime-private.h: Added prototype + for gnome_vfs_mime_monitor_emit_data_changed so it can + be called by other gnome-vfs-mime code. + + * libgnomevfs/Makefile.am: Add new .c & .h files to build. + + * libgnomevfs/gnome-vfs-mime-info.c: + (reload_if_needed_idle_function), + (gnome_vfs_mime_init): Poll every 5 seconds to reload if + any data on disk has changed. It was already checking + every time someone asked for data, but this lets clients + be notified without them having to ask. + (gnome_vfs_mime_info_reload): + Call gnome_vfs_mime_monitor_emit_data_changed + +2000-12-21 Pavel Cisler + + reviewed by: Gene Z. Ragan + + * libgnomevfs-pthread/Makefile.am: + * libgnomevfs-pthread/gnome-vfs-job-slave.c: + (gnome_vfs_job_create_slave), (gnome_vfs_thread_backend_shutdown): + * libgnomevfs-pthread/gnome-vfs-thread-pool.c: (new_thread_state), + (destroy_thread_state), (make_thread_available), (thread_entry), + (gnome_vfs_thread_create), (gnome_vfs_thread_pool_shutdown): + * libgnomevfs-pthread/gnome-vfs-thread-pool.h: + Add a simple thread pool to avoid the overhead of creating new + threads. Use the new thread pool calls when creating threads in + gnome-vfs-job-slave. + Left the old, non-thread pool thread creation in disabled by an + #ifdef for now. I'll take it out later when we know everyting is + OK about the new code. + +2000-12-21 Maciej Stachowiak + + reviewed by: Pavel Cisler + + * data/mime/gnome-vfs.keys: Update IID for the nautilus text + component. + + * libgnomevfs/gnome-vfs-utils.c + (gnome_vfs_format_file_size_for_display): Fix some bugs Darin + pointed out long ago (forgot to check this in somehow). + +2000-12-21 Pavel Cisler + + * configure.in: + Turn -Werror back on. + + * HACKING: + Tell contributors not to turn -Werror off. + + * libgnomevfs/gnome-vfs-mime-info.c: + (gnome_vfs_mime_type_is_known): + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.c: + (display_upper_case_dialog): + * modules/ftp-method.c: + Fix all the warnings that crept in while -Werror was off. + +2000-12-20 Lutz Müller + + * libgnomevfs/gnome-vfs-uri.c: (gnome_vfs_uri_set_host_name), + (gnome_vfs_uri_set_user_name), (gnome_vfs_uri_set_password): + Fix two copy-paste bugs. + +2000-12-19 Darin Adler + + reviewed by: John Sullivan + + Quick rewrite of pieces of the test module. + + * modules/test-method.c: (get_operation_settings): Changed name + and design of the function. Also fixed backwards logic that had + this returning results for the last setting that does not match + a function name, rather than for the setting that does match. + (start_operation), (finish_operation): Moved most of the work + of the macros into these functions. + (parse_result_text): Separated out the "name not found" result + from the error code result. + (load_settings): Rewrote the parsing code to be simpler. + (do_open), (do_close), (do_read), (do_write), (do_seek), + (do_tell), (do_open_directory), (do_close_directory), + (do_read_directory), (do_get_file_info), + (do_get_file_info_from_handle), (do_make_directory), + (do_remove_directory) (do_unlink), (do_set_file_info), + (do_truncate), (do_truncate_handle), (do_find_directory), + (do_create_symbolic_link): Use new simpler macros. Also got rid of + "do_" prefix on names of calls. + (do_create), (do_is_local), (do_move), (do_check_same_fs): Update + FIXME, since these are still not implemented correctly. + (vfs_module_init): Minor style change. + (vfs_module_shutdown): Free storage on shutdown. + +2000-12-18 Andy Hertzfeld + + * data/mime/gnome-vfs.keys: + added explicit i-regular icons to text-oriented mime-types, so + you can see embedded text even when the standard gnome icons are + present. + +2000-12-18 John Sullivan + + reviewed by: Rebecca Schulman + + Fixed gnome-vfs half of bug 2109 (Images (and any other + files) with "execute" bit set will try to be executed + instead of viewed when activated). The change here is + support for querying whether it makes sense to execute + a file of a given MIME type. I'll check in the Nautilus + code that calls this shortly. + + * libgnomevfs/gnome-vfs-mime-info.h: + * libgnomevfs/gnome-vfs-mime-info.c: + (gnome_vfs_mime_type_is_known): New function, returns + TRUE if a given MIME type has an entry in any of the + hashtables. + + * libgnomevfs/gnome-vfs-mime-handlers.h: + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_can_be_executable): New function, returns + whether or not a file of a given MIME type could sensibly + be executable. Default is TRUE for unknown types (so we + don't prevent new types from executing), but FALSE for + known types (since the vast majority of MIME types cannot + be directly executed). + (gnome_vfs_mime_set_can_be_executable): New function, + setter for this new feature. + + * data/mime/gnome-vfs-mime-magic: Changed + "application/x-executable-file" to "application/x-executable-binary" + since there are other types of executable files. + + * data/mime/gnome-vfs.keys: Made can-be-executable TRUE for + the following MIME types: + + application/octet-stream + application/x-csh + application/x-executable-binary + application/x-perl + text/plain + text/x-csh + text/x-ksh + text/x-perl + + Also changed "icon-filename" to "icon_filename" and "vfs-method" to + "vfs_method" so we consistently use underscores in MIME data keys. + Also improved the instructions at the top of the file a little. + + * test/gnome-file-selection/gicon.c: (get_icon_from_metadata), + (gicon_get_icon_for_file_2), + * libgnomevfs/gnome-vfs-mime-handlers.c: (gnome_vfs_mime_get_icon), + (gnome_vfs_mime_set_icon): Updated for underscore name change. + +2000-12-18 Darin Adler + + * modules/bzip2-method.c: (do_open), (do_get_file_info): Applied + the same 3 fixes that John Sullivan made to the gzip method to the + bzip2 method, since it is just a copy. An example of the evils of + copy and paste code. + +2000-12-18 Darin Adler + + reviewed by: Pavel Cisler + + Fixed bug 5217 (Nautilus crashes if you type cdda: in the + navigation bar.) + + * libgnomevfs/gnome-vfs-method.c: (load_module): Fixed bug where + it was freeing the result of g_module_error. + * modules/default-modules.conf: Disable both the cdda and the efs + modules since compiling them is currently disabled. It's important + to keep this file in sync. with the libraries it points to. + + * libgnomevfs/gnome-vfs-xfer.c: + (gnome_vfs_new_directory_with_unique_name): A new directory that + we are creating now qualifies as a top-level item. This makes + logical sense, and helps the code in Nautilus handle metadata + properly. This is a piece of my fix for bug 2199 -- the rest was + checked into Nautilus the other day. + +2000-12-18 John Sullivan + + Fixed bug 5216 (typing "deb:" in the uri text field + crashes Nautilus) + + * modules/extfs-method.c: (do_get_file_info): + + Another place in a different module that needed to + return GNOME_VFS_ERROR_INVALID_URI when the parent + URI is NULL. + +2000-12-15 John Sullivan + + reviewed by: Mike Fleming + + Fixed bug 4810 (typing "gzip:" in the uri text field + crashes Nautilus) + + * modules/gzip-method.c: + changed VALID_URI to check uri->parent, since all the code + that uses it assumes the parent is good. + (do_open), (do_get_file_info): return GNOME_VFS_ERROR_INVALID_URI + instead of GNOME_VFS_ERROR_NOT_FOUND, to match other modules' + behavior. + +2000-12-14 Rebecca Schulman + + * doc/mime-data-specification.txt: + Added initial draft of the mime data + specification to the documentation directory. + +2000-12-11 Mike Fleming + + * libgnomevfs/gnome-vfs-mime-info.c: (hack_getc): + Changed to return int instead of char so it won't bust\ + on systems that default to unsigned chars + +2000-12-11 Mike Fleming + + * modules/http-method.c: (create_handle), (make_propfind_request), + (resolve_409): + + Changed all protocol-related error returns to GNOME_VFS_ERROR_GENERIC + (they were CORRUPTED_DATA which was clearly wrong) + + Fixed bug in resolve_409 that didn't handle URI's that have no parents. + + Got rid of a FIXME that had been fixed. + +2000-12-11 Mike Fleming + + * libgnomevfs/gnome-vfs-result.c: + * libgnomevfs/gnome-vfs-types.h: + * modules/http-method.c: (do_make_directory), (do_move): + + bugzilla.eazel.com 3942 -- renaming file to illegal name produces + confusing response. + + do_move now returns GNOME_VFS_ERROR_BAD_PARAMETERS when the destination + filename contains invalid characters. This is really an unfortunate + mapping, but it mirrors what Linux's FAT drivers seem to do (they return + EINVAL). + +2000-12-11 Darin Adler + + reviewed by: John Sullivan + + * libgnomevfs/Makefile.am: + * libgnomevfs/gnome-vfs-gen-mimedb.c: + Removed the source and build rules for the obsolete + gen-mime-db tool. We have parsed the MIME text files on + when the library first needs the DB instead of saving + a preparsed memory image for some time now. + +2000-12-08 Pavel Cisler + + * modules/ftp-method.c: (do_read_directory): + Oops. Fix the build. + +2000-12-08 Pavel Cisler + + reviewed by: Gene Z. Ragan + + * libgnomevfs/gnome-vfs-mime.c: (gnome_vfs_mime_type_from_name), + (gnome_vfs_get_mime_type), (gnome_vfs_get_file_mime_type), + (gnome_vfs_get_mime_type_from_uri), + (gnome_vfs_get_mime_type_from_file_data): + * libgnomevfs/gnome-vfs-mime.h: + * modules/ftp-method.c: (ls_to_file_info): + * modules/gconf-method.c: (set_mime_type_value): + * modules/pipe-method.c: (mime_from_uri): + * modules/translate-method.c: (tr_apply_default_mime_type): + Replace all cases of "application/octet-stream" with a new symbolic + name, GNOME_VFS_MIME_TYPE_UNKNOWN. + +2000-12-08 Gene Z. Ragan + + * modules/ftp-method.c: (do_read_directory): + Removed fixme for bug 3925. This was fixed in Nautilus. + Resolving sym links during a directory read in the ftp module + is resource intensive and probably not desired. + +2000-12-08 Gene Z. Ragan + + reviewed by: Pavel Cisler + + Fixed bug 4660, Descrption lost when adding mime types + + Bug was caused by a failure to write out a mime type + with caps in the string. I now convert all caps to lower + case and inform the user what has happened. + + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.c: + (find_message_label_callback), (find_message_label), + (show_message_box), (display_upper_case_dialog): + New routines to display a nice dialog taken from Nautilus. + + (nautilus_mime_type_capplet_show_new_mime_window): + Convert mime string to lower case if caps are present. + +2000-12-08 Andy Hertzfeld + + * data/mime/gnome-vfs.keys: + replaced all references to the old bonobo-text-plain component + with the newer nautilus-text-view component + +2000-12-07 Mike Fleming + + * modules/http-method.c: (process_propfind_propstat), + (vfs_module_init): + + bugzilla.eazel.com 4317, 2795 : Implemented ctime/mtime file + attributes for DAV + +2000-12-06 Mike Fleming + + * modules/ftp-method.c: (ftp_response_to_vfs_result), + (do_make_directory): + + Added FIXME. + + Translated error returned from do_make_directory to compensate + for bad error mapping deeper in the module. + +2000-12-06 Pavel Cisler + + reviewed by: + + Fixed 4736: Nautilus doesn't respect umask when creating a new + folder. + * libgnomevfs/gnome-vfs-xfer.c: (create_directory), + Easy fix, we already do respect umask, just need to create new + folders with 0777 instead of just 0700. + + Fixed 4324: modification date doesn't get preserved during copy: + + * libgnomevfs/gnome-vfs-xfer.c: + (copy_file), (copy_directory), (copy_items): + Added a gnome_vfs_file_info_set_type to the end of copy_file + and copy_items, copying over the mod date, permissions and owner. + +2000-12-06 Mike Fleming + + reviewed by: pavel@eazel.com + + * modules/ftp-method.c: (do_move): + + bugzilla.eazel.com 4224: + ftp rename always overwrites -- ignores "force" parameter + + Just a drop in the bucket. + +2000-12-05 Pavel Cisler + + reviewed by: Gene Ragan + + * libgnomevfs/gnome-vfs-types.h: + * libgnomevfs/gnome-vfs-xfer.c: (progress_set_source_target), + (remove_file), (empty_directory), (non_recursive_empty_directory), + (gnome_vfs_visit_list), (count_each_file_size_one), + (handle_name_conflicts), (gnome_vfs_xfer_delete_items_common), + (copy_directory), (copy_items) (gnome_vfs_xfer_uri_internal): + Part of fix 4894 "Dragging /proc from the tree view to /home causes + a file not found". + Part of fix to 3232 "Error message when copying rwx file from + r-x folder to rwx folder". + Part of fix to 3237 "No error occurs if move file to folder w/o + write access". + Part of fix to 3748 "misleading file operation error dialog" + Made each of these properly set up the name of the copied item + to fix all the cases where we got "Error moving (NULL) ..." + messages that I came across while fixing the other bugs. + Added a new phase, GNOME_VFS_XFER_CHECKING_DESTINATION and used + it in gnome_vfs_xfer_uri_internal so I can distinguish between + failures on read and failures on write. + + * libgnomevfs/gnome-vfs-xfer.c: + (copy_directory), (copy_items): + Fixed 4895 Copying /dev into my home directory crashes Nautilus. + + * libgnomevfs/gnome-vfs-xfer.c: + (gnome_vfs_xfer_empty_trash), (gnome_vfs_xfer_delete_items), + (gnome_vfs_xfer_uri_internal), (gnome_vfs_xfer_private), + (gnome_vfs_xfer_uri_list), (gnome_vfs_xfer_delete_list): + Moved calls to initial and last call_progress to the calling + routine. + + +2000-12-05 Rebecca Schulman + + reviewed by: Pavel Cisler + + * libgnomevfs/gnome-vfs-mime-magic.c: (gnome_vfs_mime_magic_parse): + Remove this change: what we fixed this morning avoided the huge leak, but + did not fix the real problem. This change isn't compatible with the real + fix (see Darin's change below), and in fact it was amazing that it worked + at all. + +2000-12-04 Darin Adler + + * libgnomevfs/gnome-vfs-mime-magic.c: + (gnome_vfs_mime_get_magic_table): Added missing NULL check that + made gnome_vfs very slow since it kept reading the MIME database + over and over again! My apologies. + +2000-12-04 Rebecca Schulman + + reviewed by: Pavel Cisler + + * libgnomevfs/gnome-vfs-mime-magic.c: (gnome_vfs_mime_magic_parse): + Fix a large leak in gnome-vfs mime, that resulted from not freeing + a g_array segment during mime lookups + +2000-12-03 Maciej Stachowiak + + reviewed by: Pavel Cisler + + * libgnomevfs/gnome-vfs-utils.c + (gnome_vfs_format_file_size_for_display): Changed factor for + kilobytes to 1024 from 1000, megabytes to 1024*1024 from 1,000,000 + and gigabytes to 1024*1024*1024 from 1,000,000,000. + +2000-11-29 Darin Adler + + reviewed by: Mike Fleming + + * libgnomevfs/gnome-vfs-mime-magic.c: + (gnome_vfs_mime_get_magic_table), + (gnome_vfs_mime_clear_magic_table): Eliminate the unused "mmap" + optimization. We haven't been generating the binary file for a + while, and we've determined there's no real speed issue. + + * data/mime/gnome-vfs.applications: Use tabs consistently instead + of some tabs and some spaces. Get rid of some extra whitespace on + some lines. Fix some "can_open_uris" lines that said + "can_open_urls" instead. + + * data/mime/gnome-vfs.keys: Use tabs consistently instead of some + tabs and some spaces. + +2000-11-29 Pavel Cisler + + * test/test-mime.c: (main): + Oops, make it build. + +2000-11-29 Rebecca Schulman + + reviewed by: Pavel Cisler + + * test/test-mime.c: (main): + Added a --help argument that lists available arguments, + and made the script understand both paths and uris, + and report the case where a uri or path is not valid. + +2000-11-29 Rebecca Schulman + + * modules/file-method.c: (rename_helper): + Fixed bug 1185, that removing a directory + always returns NOT_EMPTY on an error. + +2000-11-22 Michael K. Fleming + + * modules/http-method.c: (sig_gconf_value_changed): + Fixed bug where setting "/system/gnome-vfs/use-http-proxy" + wouldn't cause the new http proxy to be used + +2000-11-21 Mike Fleming + + reviewed by: pavel@eazel.com + + * modules/http-method.c: (cache_add_no_strdup), (cache_add), + (cache_add_uri_and_children), (cache_add_uri), + (make_propfind_request), (do_open_directory), (do_get_file_info): + + Now caches non-DAV get_file_info's. Mostly improves the situation + by allowing a subsequent do_open_directory to return an error + based on the file info in cache. + + Also added more "is_dav" bit to the cache records + +2000-11-20 Mathieu Lacage + + reviewed by: + + Fix bug 4812. Also, make the capplet work by fixing + random bugs here and there. It was the first time I could test + it for true so, of course, got a bunch of small-border-effect bugs. + * libgnomevfs/gnome-vfs-mime-info.c: + (hack_getc): the most evil function I ever wrote. + It recursively gets rid of the comment lines before + the parsers ever get them. (iunstead of fixing thew parsers....) + (load_mime_type_info_from): make it use nerw hack_gets function + instead of getc_unlocked. + (load_mime_list_info_from): idem. + (gnome_vfs_mime_get_extensions_list): avoid returning the extensions + of the system settings if the user has set the user extensions. + (get_key_name): make it remove duplicates for true. + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.c: + (nautilus_mime_type_capplet_show_new_mime_window): fix bug 4812 + by replacing "char *text[3]" by "char *text[4]". + (nautilus_mime_type_capplet_show_change_extension_window): + spaces. + * mime-type-capplet/nautilus-mime-type-capplet.c: + (update_extensions_list): fix border-effect bugs. (ie: when you + have no extension for a mime type for example...) + (add_mime_clicked): idem. + +2000-11-20 Mike Fleming + + reviewed by: pavel@eazel.com + + * modules/http-method.c: (unhex_char), (unescape_unreserved_chars), + (process_propfind_response): + + Fix HTTP attribute caching to work correctly with inconsistantly + escaped URI strings. (note that the unescape_unreserved_chars function + is ifdef'd out and not used) + +2000-11-20 Matt Bissiri + + * libgnomevfs/gnome-vfs-utils.c: + (gnome_vfs_icon_path_from_filename): + Do not free the return value of g_getenv. + (fixes a segfault that occurs if GNOME_PATH is set) + +2000-11-19 Michael K. Fleming + + * modules/http-method.c: + oops. fixed debug macro that didn't have a disabled version + +2000-11-19 Mathieu Lacage + + Fix bug 4811 + * libgnomevfs/gnome-vfs-mime-info.c: + (gnome_vfs_mime_set_extensions_list): add new function. + Ultimately, I wished we could get rid of the direct access + to the internal hastables but this is at least a first step. + * libgnomevfs/gnome-vfs-mime-info.h: add prototype. + + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.c: + (add_extension_clicked): implement + (remove_extension_clicked): implement + (extension_list_selected): grey/ungrey delete button when selecting/unselecting + (extension_list_deselected): idem + (get_extensions_from_gtk_list): helper function. + (nautilus_mime_type_capplet_show_change_extension_window): implement. + (nautilus_mime_type_capplet_show_new_extension_window): fix a number of segfaults. + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.h: change prototypes. + * mime-type-capplet/nautilus-mime-type-capplet.c: + (get_selected_row_number),helper function. + (get_selected_mime_type), helper function (refactoring :) + (really_change_icon): fix segfault. + (update_extensions_list): update extensions when you change them. + (change_file_extensions_clicked): create dialog. + (init_mime_capplet): spaces. + (nautilus_mime_type_capplet_update_info): make it use get_selected_mime_type. + +2000-11-17 Mike Fleming + + * modules/http-method.c: (my_debug_printf), (get_header), + (create_handle), (make_request), (http_handle_close), (do_open), + (do_create), (do_close), (do_write), (do_read), + (make_propfind_request), (do_open_directory), (do_close_directory), + (do_read_directory), (do_get_file_info), (do_make_directory), + (do_remove_directory), (do_move), (do_unlink): + * test/http-postanalyze.pl: + + Added timing debug code. + +2000-11-17 Mathieu Lacage + + reviewed by: Sullivan + + fix Bug 4768. Reported 3 bugs about separate issues: 4796, 4797, 4798. + * data/mime/gnome-vfs.keys: change icon filenames to relative paths. + * libgnomevfs/Makefile.am: add GNOME_VFS_PREFIX + * libgnomevfs/gnome-vfs-mime-info.c: (gnome_vfs_mime_info_reload): + add initialition code if the mime stuff is not initalized when doing + a reload. This avoids a segfault. + * libgnomevfs/gnome-vfs-utils.c: (hack_file_exists): new function + copied from gnome-libs: prviously named g_file_exists. + (gnome_vfs_icon_path_from_filename): new API function. It looks + in GNOME_PATH to find the icons and defaults to the gnome-vfs prefix + one. It accepts only relative paths and returns an absolute path. + * libgnomevfs/gnome-vfs-utils.h: add prototype. + * mime-type-capplet/nautilus-mime-type-capplet.c: + (really_change_icon), changes the icon used by a mime type. + (gil_icon_selected_cb): changes the icon when you double-click. + (change_icon_clicked_cb_real): changes the icon when you click on ok. + (change_icon_clicked): connect to the clicked and select_icon signals + to know when the user has made up his mind about hte new icon. + (nautilus_mime_type_capplet_update_info), spaces. + (add_mime_clicked): spaces. + (nautilus_mime_type_capplet_update_mime_list_icon): spaces. + (capplet_get_icon_pixbuf): spaces. + (populate_mime_list): spaces. + * mime-type-capplet/nautilus-mime-type-icon-entry.c: + (icon_selected_cb): spaces. + (nautilus_mime_type_show_icon_selection): spaces. + (nautilus_mime_type_icon_entry_get_relative_filename): new function. + returns a relative filename instead of an abosulte one. + * mime-type-capplet/nautilus-mime-type-icon-entry.h: add relative + function prototype + +2000-11-17 Gene Z. Ragan + + Fixed bug 2966, Fix cancellation support in FTP + + * modules/ftp-method.c: (do_path_command_completely), + (do_transfer_command), (do_path_transfer_command), + (host_port_from_string), + (ftp_connection_create), (ftp_connection_acquire), (do_open), + (internal_get_file_info), (do_get_file_info), (do_open_directory), + (do_make_directory), (do_remove_directory), (do_move), (do_unlink), + (vfs_module_init): + Modified several functions to allow context to be passed in. + We can then check the context for cancellation. + + * modules/http-method.c: (make_request): + Code cleanup. + +2000-11-16 Rebecca Schulman + + * modules/ftp-method.c: + Change the formatting of some fixmes so that + check-fixme will keep track of them + +2000-11-16 Mathieu Lacage + + fix bug 4769 + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.c: + (nautilus_mime_type_capplet_show_new_mime_window): tweak to + look slightly better. fix a potential segfault too. + * mime-type-capplet/nautilus-mime-type-capplet.c: (revert_real_cb), + (revert_mime_clicked), (add_mime_clicked): add dialog hook. + +2000-11-16 Gene Z. Ragan + + Fixed bug 4528, http method does not listen for + 'use-http-proxy' preference. + + * modules/http-method.c: + (vfs_module_init): + Listen to changes in 'use-http-proxy' settings. + + (sig_gconf_value_changed), + Check for status of 'use-http-proxy' system setting before + setting proxy to new modified value. This allows a user to edit + the text of the proxy without actually resetting the proxy to + this value if the "Use Proxy" checkbox is unset. + +2000-11-16 Mathieu Lacage + + Fix bugs 2767 and 3228 + * mime-type-capplet/nautilus-mime-type-capplet.c: + (nautilus_stop_in_debugger), + (nautilus_stop_after_default_log_handler), + (nautilus_set_stop_after_default_log_handler), + (nautilus_make_warnings_and_criticals_stop_in_debugger), + add debugging functions. They are disabled by default. + (main), add call to debuggin funcitons if they are enabled. + (change_icon_clicked), implement. + (init_mime_capplet), tweaks, cleanups + (nautilus_mime_type_capplet_update_info), update icon. + (revert_mime_clicked), implement correctly. + (delete_mime_clicked), implement correctly. + (add_mime_clicked), cleanups + (capplet_get_icon_pixbuf), new function to get the pixbuf for + a given mime type + (populate_mime_list): use the new function above, refactor. + (update_mime_list_action): idem. + +2000-11-15 Mathieu Lacage + + * mime-type-capplet/nautilus-mime-type-capplet.c: + (init_mime_capplet), make it look like what Arlo wanted. + (revert_mime_clicked): new callback to reset user settings. + +2000-11-15 Pavel Cisler + + * test/test-uri.c: (main): + Tweak a test to verify that bug 3401 is fixed. No reviewer, sorry. + +2000-11-15 Mathieu Lacage + + * libgnomevfs/gnome-vfs-mime-info.c: + (context_new), cleanups. + (load_mime_type_info_from), cleanups + (load_mime_list_info_from), cleanups + (reload_if_needed), rename from maybe_reload + (set_value_real), new function. + (gnome_vfs_mime_set_value), make it use funiton above. + (get_value_real), new function + (gnome_vfs_mime_get_value), make it use funciton above + (gnome_vfs_mime_get_key_list), cleanups + (gnome_vfs_mime_get_extensions_list), cleanups + (gnome_vfs_mime_get_extensions_pretty_string), cleanups + (gnome_vfs_get_registered_mime_types), cleanups + (gnome_vfs_mime_set_registered_type_key), make it use + set_value_real. + (gnome_vfs_mime_get_registered_mime_type_key): make it + use get_value_real. + +2000-11-15 Mathieu Lacage + + Buddy: pavel + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_get_default_action_type): fix a compilation warning. + remove a unused variable. + * libgnomevfs/gnome-vfs-mime-info.c: + (load_mime_list_info_from), spaces... + (get_key_name), add checks not to return deleted mime types and + not to return comments as mime types. + (gnome_vfs_mime_reset), new API function: resets to system defaults. + (gnome_vfs_mime_registered_mime_type_delete), new API fution: deletes + a mime type. + (gnome_vfs_mime_get_registered_mime_type_key), new non-exported function. + (write_back_mime_user_file_context_callback): spaces... + * libgnomevfs/gnome-vfs-mime-info.h: new prototypes. + * test/test-mime-info.c: (main): add testing code for teh new API. + +2000-11-15 Mathieu Lacage + + Buddy: pavel + + Fix bug 2650. remove *_without_fallback code. + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_get_default_action_type), + (gnome_vfs_mime_get_default_action), + (gnome_vfs_mime_get_default_application), + (gnome_vfs_mime_get_icon), + (gnome_vfs_mime_get_default_component): + remove code trying to test for the supertype + of a mime type because the first lookup always + checks for the supertype anyway so the code was + useless. + * libgnomevfs/gnome-vfs-mime-handlers.h: remove + *_without_fallback functions. + +2000-11-14 Pavel Cisler + + Reviewed by: Mathieu Lacage + + * libgnomevfs/gnome-vfs-uri.c: (split_toplevel_uri): + Fix 820, treating case-insensitive parts of URIs as such. + + * test/test-uri.c: (test_uri_match), (main): + Add test suites for the case-insensitive handling. + + * data/mime/gnome-vfs-mime-magic: + Removed an obsolete comment. + + * README: + Add some instructions. + +2000-11-14 Maciej Stachowiak + + reviewed by: Rebecca Schulman + + * data/mime/gnome-vfs.applications: Remove trailing whitespace + from `abiword' and `galeon'. + + * libgnomevfs/gnome-vfs-application-registry.c + (load_application_info_from): strip trailing whitespace from + application IDs. + (strip_trailing_whitespace): helper function + +2000-11-13 Rebecca Schulman + + Reviewed by: Maciej Stachowiak + + * libgnomevfs/gnome-vfs-result.c: + * libgnomevfs/gnome-vfs-types.h: + Add a new gnome vfs error, about the problem of the search + index being out of date enough that no results could + possibly come back, called GNOME_VFS_ERROR_SERVICE_OBSOLETE + +2000-11-13 Darin Adler + + * gnome-vfs.spec.in: Turn "make check" off again. + It doesn't work because the front end can't find the + back end when it's not installed. + +2000-11-13 Gene Z. Ragan + + Some more capplet work. The mime list now updates + to reflect changes made to the default action button + and menu item list. + + * mime-type-capplet/nautilus-mime-type-capplet.c: + (application_button_toggled), (viewer_button_toggled), + (application_menu_activated), (component_menu_activated), + (add_mime_clicked), + (nautilus_mime_type_capplet_update_mime_list_icon), + (update_mime_list_action), (populate_mime_list): + + * mime-type-capplet/nautilus-mime-type-icon-entry.c: + (entry_changed): + Fixed a case where a NULL widget would cause an assertion. + +2000-11-13 Gene Z. Ragan + + Fixed bug 3107, Setting na icon for a mime type does not work. + + * mime-type-capplet/nautilus-mime-type-capplet.c: + * mime-type-capplet/nautilus-mime-type-capplet.h: + (nautilus_mime_type_capplet_update_mime_list_icon): + New function that sets/updates the icon in the mime list. + + * mime-type-capplet/nautilus-mime-type-icon-entry.c: + (icon_selected_cb), (nautilus_mime_type_show_icon_selection): + Add call to new nautilus_mime_type_capplet_update_mime_list_icon + function. + +2000-11-13 Martin Baulig + + * modules/file-method.c (read_saved_cached_trash_entries): + Use g_free() to free the `trash_path' and `mount_path'. + +2000-11-11 Kjartan Maraas + + * mime-type-capplet/nautilus-mime-type.desktop: Added norwegian translation. + * mime-type-capplet/nautilus-mime-type-capplet.c: Marked all strings for translation. + +2000-11-11 Maciej Stachowiak + + Part of the fix to 4051. + + * data/mime/gnome-vfs.applications: Uncomment vi and lynx + + * libgnomevfs/gnome-vfs-mime-handlers.c + (gnome_vfs_mime_application_copy): Copy the + requires_terminal_flag. + + Unrelated bug fix: + + * modules/test-method.c: Use usleep(3), not usleep(1). + +2000-11-11 Ali Abdin + + * data/mime/gnome-vfs-mime-magic: + * data/mime/gnome-vfs.keys: + * data/mime/gnome-vfs.applications: + * data/mime/gnome-vfs.mime: + Change audio/x-ogg to application/x-ogg + +2000-11-09 Darin Adler + + * gnome-vfs.spec.in: Turn on "make check" for RPM builds. This is + especially good for the Tinderbox. + + * modules/http-method.c: (process_propfind_propstat), + (process_propfind_response), (make_propfind_request), + (vfs_module_init): + * modules/test-method.c: (load_config_file), (vfs_module_init): + Use LIBXML_TEST_VERSION and the new macros to make gnome-vfs + ready for gnome-xml 2.X or gnome-xml 1.X, as DV suggests. + + * modules/Makefile.am: + * libgnomevfs/gnome-vfs-application-registry.c: + * libgnomevfs/gnome-vfs-mime-handlers.c: + Formatting tweaks. + +2000-11-08 Gene Z. Ragan + + Fixed an error where access count was not reset + during a close_directory call. + + * modules/cdda-method.c: (do_open), (do_get_file_info), + (do_open_directory), (do_close_directory), (do_read_directory): + +2000-11-08 John Sullivan + + * libgnomevfs-pthread/gnome-vfs-job.c: (execute_find_directory): + Changed a g_new to g_new0 to fix problem where result_item->uri + was sometimes uninitialized. Darin somehow found this bug when + I couldn't figure out why make check in Nautilus was crashing. + Hooray! + +2000-11-08 Ramiro Estrugo + + * data/mime/gnome-vfs.applications: + XMMS can open uris. + +2000-11-06 Robin * Slomkowski + + * configure.in: upped development version to 0.4.2.0 + +2000-11-06 Robin * Slomkowski + + * configure.in: upped version to 0.4.2 + +2000-11-06 Robin * Slomkowski + + * configure.in: upped version 0.4.1.1 + for internal incrimental release + +2000-11-06 Darin Adler + + Fix bug 4490 (web sites with bad last modified dates (like + www.centerbeam.com) result in "not found"). + + * modules/http-method.c: (create_handle): Change code so that + headers that can't be parsed don't result in NOT_FOUND. They are + instead ignored. + + * test/test-shell.c: (list_commands), (main): Fix some small + problems in the test shell that I encountered while dealing with + the bug. + +2000-11-06 Maciej Stachowiak + + * data/mime/gnome-vfs.applications: Commented out entries for vi + and lynx. This is the fix for 4468. + +2000-11-06 Maciej Stachowiak + + * data/mime/gnome-vfs.applications, data/mime/gnome-vfs.keys: Some + minor changes. Added Electric Eyes and made it the most preferred + image viewer. Added ggv and made it more preferred than gv or + ghostview for PDF viewing. Added proper entry for ogg123. Made + mpg123 not require a terminal. Made mpg123 and xmms kmow that they + handle secondary versions of various mime types. Made Acrobat the + most preferred PDF viewer (if you've gone to the trouble of + installing it, it's proably what you want). Changed editor + preference order around a bit. + +2000-11-05 Yukihiro Nakai + + * configure.in: Add sk(Slovak) to ALL_LINGUAS. + +2000-11-03 Aaron Brick + + * gnome-vfs.applications: + adobe acrobat can open multiple files. + +2000-11-03 Mike Fleming + + * libgnomevfs/gnome-vfs-uri.c: (set_uri_element): + Do it right this time + +2000-11-03 Mike Fleming + + * libgnomevfs/gnome-vfs-uri.c: (set_uri_element): + * test/test-uri.c: (main): + "eazel-services:" needs to be treated like "http:" in Pavel's evil + escaping fix. + +2000-11-03 Robin * Slomkowski + + * configure.in: upped development version to 0.4.1.0 + +2000-11-03 Robin * Slomkowski + + * configure.in: upped version to 0.4.1 for release + +2000-11-03 Darin Adler + + * modules/http-method.c: (do_get_file_info): Improved comments + in here. + +2000-11-03 Maciej Stachowiak + + Fix bugs 4445 and 2756. + + * libgnomevfs/gnome-vfs-mime-handlers.c + (gnome_vfs_mime_get_default_application): Make + `gnome_vfs_mime_get-default_application' fall back to the short + list if the default application is not found in the path. + + * data/mime/gnome-vfs.keys: Set StarOffice as the default for + "application/msword" and "application/vnd.ms-excel"; set the short + list preference order to StarOffice, then Applix, then AbiWord and + Gnumeric respectively (on the assumption that if you have the + proprietary apps installed, you probably wnat to use them). + +2000-11-02 Mike Fleming + + * libgnomevfs/gnome-vfs-uri.c: + * modules/http-method.c: (http_status_to_vfs_result), (do_move): + bugzilla.eazel.com bug 4225, http-method now correctly obeys + force_replace (being FALSE) in do_move. Users can't accidentally delete + files by naming them the same. + +2000-11-02 Andy Hertzfeld + + * data/mime/gnome-vfs.keys: + removed web browsers from the short list for webdav directories, + since we don't want the buttons for launching web browsers to + show up when looking at directories. + +2000-11-02 Robin * Slomkowski + + * gnome-vfs.spec.in: updated summary and added + junk fields for vendor and distribution + +2000-11-02 Pavel Cisler + + * gnome-vfs.spec.in: + Fill out the description fields. + +2000-11-02 Robin * Slomkowski + + * configure.in: gnome-vfs 0.4 has been tagged + as GNOME-VFS_0_4 and the version of cvs has been upped + to 0.4.0 + +2000-11-02 Robin * Slomkowski + + configure.in: upped version number for release + +2000-11-02 Aaron Brick + + * gnome-vfs.[ak]*s + added support for adobe acrobat + removed staroffice as default for MS files (pending bug 4372) + +2000-11-02 Gene Z. Ragan + + Some more capplet cleanup. + + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.c: + (check_button_status), (initialize_edit_applications_dialog), + (initialize_edit_components_dialog): + Have the Add, Edit and Delete buttons in the Edit Applications + dialog be enabled/disabled properly based on the contents + of the application list. + + Remove Cancel button from the Edit Component and Edit Application + dialog, as we currently do not have a way to roll back the changed + made. + +2000-11-02 Andy Hertzfeld + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_get_short_list_applications): + made it only include applications from the supertype on the + short list if there were no applications assigned to the + specific type. + + * data/mime/gnome-vfs.keys: + removed "lynx" from the text/html short list for novice and + intermediate users. + +2000-11-02 Darin Adler + + Fix bug 4377 (Crash in the http method as a result of a redirect). + + * modules/http-method.c: (do_get_file_info): Add missing check for + NULL. + +2000-11-02 Rebecca Schulman + + Fixed bug 4121, that the vault will ... + + * libgnomevfs/gnome-vfs-xfer.c: (copy_file): + handle errors on closing, which is when the http module + actually does the write back to the server + * modules/http-method.c: (create_handle), (make_request): + Check for the case when a put fails with eof, and assume + it's because there was insufficient space; the xythos server + isn't correctly reporting 507 (http protocol insufficient space) + yet. + +2000-11-02 Gene Z. Ragan + + Fixed bug 4319, Edit and Delete actions in Application + List do not function + + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.c: + (populate_default_applications_list), + (initialize_edit_applications_dialog), + (nautilus_mime_type_capplet_show_new_mime_window), + (add_or_update_application), (add_item_to_application_list), + (show_new_application_window), (show_edit_application_window), + (delete_selected_application): + Bunches of code to handle adding, editing and deletion of + application/mime type mapping. + + * mime-type-capplet/nautilus-mime-type-capplet.c: + (nautilus_mime_type_capplet_get_selected_item_mime_type): + +2000-11-01 Aaron Brick + + * data/mime/gnome-vfs.[ak]*: + added support for applixware + changed default for .doc/.xls to staroffice + added a handler (xanim) for video/[x-]msvideo + +2000-11-01 Darin Adler + + Fix bug 4287 (Zope Studio-authored sites default to Icon View). + + * modules/http-method.c: (process_propfind_propstat), + (process_propfind_response), (make_propfind_request): At Gene's + request, rolled out his change. + (do_get_file_info): New version of hack: don't do a propstat at + all for root directories. + +2000-11-02 Mathieu Lacage + + Fix bug 4299 hopefully. Need to test on my desktop + machine first. + * modules/http-method.c: (cache_check_directory), + (do_get_file_info): make it always return text/html + if we did a GET and there was a redirect. + * test/test-shell.c: (do_info): add ability to + display mime type. + +2000-11-01 Gene Z. Ragan + + * modules/http-method.c: (process_propfind_propstat), + (process_propfind_response), (make_propfind_request): + Add hack variable to detect if x-directory/webdav has been returned for + a root directory URL. If this is the case, return a value that causes + HEAD to be called. + +2000-11-01 Mathieu Lacage + + * configure.in: tweak efs configure. + +2000-11-01 Aaron Brick + + * data/mime/gnome-vfs.keys: + added handling for application/postscript + +2000-11-01 Pavel Cisler + + Work on handling '?' in URIs properly, helping Darin with a + broken URI query bug he is working on. + + * libgnomevfs/gnome-vfs-private-utils.h: + * libgnomevfs/gnome-vfs-uri.c: (set_uri_element), + (gnome_vfs_uri_new), (gnome_vfs_uri_new_private): + Add a private version of gnome_vfs_uri_new that can optionally + accept unknown uri schemes (methods). + Added a very simple and hacky scheme-dependent URI escaping code. + For now just made it escape reserved characters such as "?&=+", etc. + get escaped for every scheme but "http", in which they are used as + query separators, etc. Will need to redo this, having the individual + modules handle the specifics at some point. For now this should + help with our friendly website bugs. + Added a call to the new routine that removes escaping from characters + that don't need it. This will make uri matching, hashing, etc. + work better for URIs that we originally receive in different escaped + modes. + + * libgnomevfs/gnome-vfs-utils.h: + * libgnomevfs/gnome-vfs-utils.c: (gnome_vfs_escape_set), + (unescape_character), (gnome_vfs_unescape_string), + (gnome_vfs_remove_optional_escapes), + (gnome_vfs_make_uri_canonical), + (gnome_vfs_make_path_name_canonical): + Add new escaping call. + Share existing escaping code with other routines. + Simplify the existing gnome_vfs_unescape_string call a bit. + Add a call that can be used by the URI "make canonical" machinery + to un-escape characters that do not need to be escaped. + Add a new gnome_vfs_make_uri_canonical call. + remanmed gnome_vfs_make_canonical_pathname to + gnome_vfs_make_path_name_canonical. + + * test/test-uri.c: (test_make_canonical_path), + (test_make_canonical), (main): + Add new tests for the features that I added. + +2000-11-01 Gene Z. Ragan + + * modules/cdda-method.c: (do_check_same_fs): + Return TRUE always. + +2000-10-31 Mathieu Lacage + + * modules/http-method.c: (do_get_file_info): + remove support for HEAD. We now do only a PROPFIND + and a GET to get the information on a file. + +2000-10-31 Pavel Cisler + + * libgnomevfs/gnome-vfs-xfer.c: (remove_file), (remove_directory), + (copy_file), (move_items), (link_items): + Fix 848 - Failed copy operations still cause an icon to appear. + Made xfer callbacks only get called when items were successfully + moved, created and removed. + +2000-10-31 Gene Z. Ragan + + Fixed offset glitch. Now files are extracted properly. + Disabled paranoia to improve speed. Only basic ripping + is done with no error checking. + + * modules/cdda-method.c: + (do_open), (do_read), (get_data_size): + +2000-10-31 Pavel Cisler + + * AUTHORS: + * NEWS: + Updates for the upcoming release. + + * libgnomevfs/gnome-vfs-uri.c: + Take out an old FIXME that has been fixed. + + * libgnomevfs/gnome-vfs-xfer.c: (gnome_vfs_xfer_uri_internal): + Set up the target uri so that an alert about a target not being + writable can actually display the name. + + * test/test-shell.c: (main): + Make the test-shell not cause GConf to display the super-annoying + "Failed to respond to the SaveYourself ..." dialogs. + +2000-10-31 Gene Z. Ragan + + * modules/cdda-method.c: (cdda_context_new), + (get_track_index_from_uri), (do_open), (is_file_is_on_disc), + (do_get_file_info), (do_open_directory): + Unescape basenames when performing comparison operations + on cached cddb data. + +2000-10-31 Darin Adler + + * gnome-vfs.spec.in: Got rid of vendor again. Checking this in is + a bad idea. See discussion in bug 3461 for details. + +2000-10-31 Ali Abdin + + * data/mime/gnome-vfs-mime-magic: + * data/mime/gnome-vfs.keys: + * data/mime/gnome-vfs.mime: + Temporary support for "audio/x-ogg" (until the mime issue is cleared + up with the Ogg Vorbis crew) + +2000-10-31 Darin Adler + + * gnome-vfs.spec.in: Add vendor. + +2000-10-31 Gene Z. Ragan + + * modules/cdda-cddb.c: + * modules/cdda-method.c: + (cdda_context_new): + Get proxy info using gconf. We are using the system keys that + are shared by nautilus and ammonite. The only UI to change these + values is in Nautolis right now. + + (do_is_local): + Return TRUE + + (put_num), (write_wav_header): + More cleanup. + +2000-11-01 Ian McKellar + + * libgnomevfs/gnome-vfs-method.c: (load_module): + Provide more verbose information when a module fails to load. + + * modules/http-method.c: (do_get_file_info): + Fall back to using GET when PROPFIND and HEAD fail to return useful + file info. See bug 4310. + +2000-10-31 Gene Z. Ragan + + Made copying work. There is still an issue with more + data being copied than requested. Will research problem more. + + * modules/cdda-method.c: + (get_track_index_from_uri): + Return index of uri in cdda table. + + (write_wav_header): + Write wav format header data into a memory buffer. + + (do_open), (do_read): + Call new routines above. + + * modules/Makefile.am: + Remove module from official build + +2000-10-30 Gene Z. Ragan + + * modules/Makefile.am: + * modules/cdda-method.c: (do_open), (do_read), (get_data_size), + (do_check_same_fs), (do_is_local), (put_num), (write_wav_header): + * modules/default-modules.conf: + More work in progress on cdda module. + +2000-10-30 Darin Adler + + Fixed bug 4169 (Visiting "Services" several times causes future + navigation to hang). + + * libgnomevfs/gnome-vfs-async-ops.h: Got rid of the error code + result from gnome_vfs_async_cancel. + + * libgnomevfs-pthread/gnome-vfs-async-ops.c: + (pthread_gnome_vfs_async_cancel): Got rid of the error code result + from gnome_vfs_async_cancel. + (async_open), (pthread_gnome_vfs_async_open_uri), + (pthread_gnome_vfs_async_open), (async_open_as_channel), + (pthread_gnome_vfs_async_open_uri_as_channel), + (pthread_gnome_vfs_async_open_as_channel), (async_create), + (pthread_gnome_vfs_async_create_uri), + (pthread_gnome_vfs_async_create), + (pthread_gnome_vfs_async_create_as_channel), + (pthread_gnome_vfs_async_close), (pthread_gnome_vfs_async_read), + (pthread_gnome_vfs_async_write), + (pthread_gnome_vfs_async_create_symbolic_link), + (pthread_gnome_vfs_async_get_file_info), + (pthread_gnome_vfs_async_set_file_info), + (pthread_gnome_vfs_async_find_directory), (async_load_directory), + (pthread_gnome_vfs_async_load_directory), + (pthread_gnome_vfs_async_load_directory_uri): Changed all the ops + to not return error codes right away, and do all error reporting + through callbacks. + + * libgnomevfs-pthread/gnome-vfs-job.h: Got rid of the error code + result from gnome_vfs_async_cancel. + + * libgnomevfs-pthread/gnome-vfs-job.c: (gnome_vfs_op_destroy), + (execute_open), (execute_open_as_channel), (execute_create), + (execute_create_symbolic_link), (execute_create_as_channel), + (execute_load_directory_not_sorted), + (execute_load_directory_sorted): For all the operations that now + might have NULL for the URI, report an + GNOME_VFS_ERROR_INVALID_URI. + (gnome_vfs_job_cancel): Got rid of the error code result from + gnome_vfs_async_cancel. + + * libgnomevfs/gnome-vfs-backend.c: (gnome_vfs_async_open), + (gnome_vfs_async_open_uri), (gnome_vfs_async_open_as_channel), + (gnome_vfs_async_create), (gnome_vfs_async_create_as_channel), + (gnome_vfs_async_create_uri), + (gnome_vfs_async_create_symbolic_link), (gnome_vfs_async_close), + (gnome_vfs_async_read), (gnome_vfs_async_write), + (gnome_vfs_async_get_file_info), (gnome_vfs_async_find_directory), + (gnome_vfs_async_set_file_info), + (gnome_vfs_async_load_directory_uri), + (gnome_vfs_async_load_directory), (gnome_vfs_async_cancel), + (gnome_vfs_async_remove_status_callback): Don't expect a result + from the back end for most functions. Get rid of error checking + and the fake idle-based callbacks for the errors noticed before + entering the back end. + + * modules/http-method.c: (get_utime), (cache_init), + (cache_shutdown), (cache_entry_new), (cache_trim), + (defaults_file_info_new): Use (void) instead of () for functions + with no parameters. + + * test/test-find-directory.c: Add missing #include . + +2000-10-30 Gene Z. Ragan + + Added cdda module files to CVS. They are not currently built by + default. The module is not yet complete. If you want to build it + and see it break, you need to have libcdparanoia installed. You can + download this at www.xiph.org. I have not yet done the debugging + work to try and build against different install locations of the + lib. I would reccomend not hacking on this until I clean up + the rough edges. + + * modules/Makefile.am: + Added comented out entries for cdda module + + * modules/default-modules.conf: + Added comented out entry for cdda module + + * modules/cdda-cddb.c: + * modules/cdda-cddb.h: + (CDDBSum), (CDDBDiscid), (CDDBGenre), + (CDDBGenreValue): + + * modules/cdda-cdrom-extensions.h: + * modules/cdda-method.c: + * modules/cdda-method.h: + (cdda_context_new), (cdda_context_free), + (cdda_set_file_info_for_root), (read_handle_new), + (read_handle_destroy), (do_is_local), (do_open), (do_create), + (do_close), (paranoia_callback), (do_read), (do_write), + (display_toc), (open_cdda_device), (is_file_is_on_disc), + (get_file_info_for_basename), (do_get_file_info), + (do_open_directory), (do_close_directory), (get_data_size), + (get_data_size_from_uri), (do_read_directory), (do_check_same_fs), + (do_make_directory), (do_remove_directory), (do_move), (do_unlink), + (vfs_module_init), (vfs_module_shutdown), (PutNum), + (write_wav_header): + +2000-10-29 Dan Winship + + * libgnomevfs/gnome-vfs-mime-sniff-buffer.c + (gnome_vfs_mime_sniff_buffer_new_from_memory): Set read_whole_file + to TRUE so it doesn't try to call the (non-existent) read + callback. + +2000-10-30 Pavel Cisler + + * libgnomevfs/gnome-vfs-utils.c: + (gnome_vfs_unescape_string_for_display), + (gnome_vfs_make_canonical_pathname): + * libgnomevfs/gnome-vfs-utils.h: + Add a public "make canonical path" call for callers that do their + own uri disection. + +2000-10-29 Pavel Cisler + + * libgnomevfs/gnome-vfs-uri.c: (gnome_vfs_uri_to_string): + Make gnome_vfs_uri_to_string not interpret uris in the form + foo:bar as foo://bar. This fixes a bug Mathieu is working on and + fixes 2802. + Get rid of an extra comma. + + * modules/file-method.c: (do_read): + Tiny tweak. + + * test/test-uri.c: (test_uri_to_path), (main): + Add some tests and tweak others to match the proper // handling. + +2000-10-29 Eskil Heyn Olsen + + * gnome-vfs.spec.in: + if $prefix/lib not in /etc/ld.so.conf, add it. + +2000-10-28 Pavel Cisler + + * libgnomevfs/gnome-vfs-xfer.c: (progress_set_source_target_uris): + Fix 4059 - Duplicated fiels don't appear in WebDAV until refres. + This happened on any uris that required a name/password pair. + It was a stupid bug where the notification callbacks were passed + the name without a password. This was because the uri was used in + the progress dialog display. It's no longer displayed in a raw form + so fixing this is a simple matter of passing back the entire uri. + +2000-10-28 Pavel Cisler + + * modules/http-method.c: (sig_gconf_value_changed), + (http_proxy_for_host_port), (process_propfind_propstat), + (propfind_href_to_vfs_uri), (null_handling_strcmp), + (match_unescaped_uri_text), (process_propfind_response), + (make_propfind_request), (do_open_directory), (do_read_directory), + (do_get_file_info), (do_is_local), (do_make_directory), + (do_remove_directory), (is_same_fs), (do_move), (do_unlink), + (do_check_same_fs), (vfs_module_init), (vfs_module_shutdown): + Fix 4110 - document icon instead of folder icon for subfolder... + I found a fix to this one while working on 4059. + The problem was that the webdav server was overzealous about + escaping and was returning urls that had '(' escaped. This + is not needed according to the RFC. A uri text compare was failing + because of this. Changed the test to unescape before the comparison. + I also took a stab at cleaning up the three or so formatting styles + throught the code into the required style in at least a part of the file. + +2000-10-27 Darin Adler + + Fixed bugs in set_file_info enough to make it suitable for use + renaming files in Nautilus. + + Also fixed problems in the MIME data so Aaron has a clean starting + point to add things and check them with the check-mime.pl script. + + * data/mime/gnome-vfs-mime-magic: Fix an entry that had a stray + plus sign at the beginning of the line. + * data/mime/gnome-vfs.applications: Fixed misspelled MIME types (I + think Andy just introduced these). + * data/mime/gnome-vfs.keys: The type must be text/htmlh, even if + people think of it as text/htmlH, because we use all lower-case in + the MIME files and MIME types are not case sensitive. + + * libgnomevfs-pthread/gnome-vfs-async-ops.c: + (pthread_gnome_vfs_async_set_file_info): Allow FOLLOW_LINKS + option. There was no good reason to disallow it and we need it now + in Nautilus. + + * libgnomevfs-pthread/gnome-vfs-job.c: (serve_channel_write): Get + rid of gratuitous use of alloca. + (execute_set_file_info): Use the correct URI to get info if the + set info call renamed the file. Before, it would try to use the + old URI even though the file had been renamed. + + * modules/ftp-method.c: (do_path_command): Add FIXME about bad + handling of paths with escape sequences. + (do_get_file_info_from_handle): Implemented this. + (do_move): Add FIXME about ignoring force_replace. + (do_set_file_info): Implement. + * modules/http-method.c: (do_move): Add FIXME about ignoring + force_replace. + (do_set_file_info): Implement. + + * libgnomevfs/gnome-vfs-xfer.c: + (call_progress_with_current_names): Make the action default to + abort if you don't pass a callback instead of defaulting to + retry. This caused an infinite loop when failing to rename a + file. Also remove gratuitous include of alloca.h. + + * modules/file-method.c: (do_set_file_info): Add FIXME about file + names with "/" in them. + + * modules/bzip2-method.c: Fix list of function pointers to include + set_file_info (was out of sync.). + * modules/gconf-method.c: Fix list of function pointers to include + set_file_info (was out of sync.). + * modules/gzip-method.c: Fix list of function pointers to include + set_file_info (was out of sync.). + * modules/pipe-method.c: Fix list of function pointers to include + set_file_info (was out of sync.). + + * libgnomevfs/gnome-vfs-uri.c: Remove gratuitous include of + alloca.h. + + * modules/ftp-method.h: Tweak. + * libgnomevfs/gnome-vfs-private.h: Whitespace. + * test/test-uri.c: Fixed a comment. + +2000-10-26 Andy Hertzfeld + + * data/mime/gnome-vfs.keys: + at Bart's request, made star office the default application + for star office documents. + + * data/mime/gnome-vfs.applications: + changed the path for invoking star office from "office52/soffice" + to "soffice" so it works with a broader range of versions + +2000-10-26 John Sullivan + + * test/test-uri.c: (main): Added test case and two + FIXME bugs for test cases with odd results. + +2000-10-26 John Sullivan + + * modules/http-method.c: (make_propfind_request): + More cleanup of *handle_return handling. This + stuff was revealed when I temporarily #defined + DAV_NO_CACHE to investigate another bug. + +2000-10-26 John Sullivan + + Crashed while fiddling around in WebDAV looking at some other + bug. Found cause of crash, and cleaned up various callers + of offending routine (make_request). Maybe this will improve + general stability for WebDAV. + + * modules/http-method.c: + (make_request): Fixed case where failure in + gnome_vfs_inet_connection_create would cause this routine to + leave *handle_return uninitialized (now it sets it to NULL); + rearranged code a little to fix leaks. + (do_create): Rearranged code slightly for clarity. + (do_close): Fixed leak of handle. + (make_propfind_request): combined handle and handle_return + into single variable for clarity and to avoid leaks. + (do_get_file_info): added assert, removed unnecessary handle = NULL + line. + (do_make_directory): clarified use of handle + +2000-10-26 Darin Adler + + * libgnomevfs-corba/Makefile.am: + * libgnomevfs-pthread/Makefile.am: + * libgnomevfs/Makefile.am: + * modules/Makefile.am: + Use INCLUDES instead of CPPFLAGS like the automake + documentation says. + +2000-10-25 Rebecca Schulman + + * modules/http-method.c: (do_create): + Fixed bugzilla bug 3865, that you couldn't duplicate + vault files. The problem was that the do_create + method was ignoring the "exclusive" flag, and + so a copy would create a file and the create + method would silently be ok and overwrite + the file, as per http protocol defaults. + We now check for existence first, by doing + a "HEAD" request. + +2000-10-25 Darin Adler + + * libgnomevfs/gnome-vfs-mime-sniff-buffer.c: + (gnome_vfs_mime_sniff_buffer_get): More fixes to this function. + Made it no longer do the "no op" seeks. Got rid of the problem + where it would only read one chunk if the buffer's seek pointer + was NULL. Make the check at the end of the function be based on + the actual size requested, rather than on the amount of data + we decided to read (which could be more than the request). + +2000-10-25 Mathieu Lacage + + * configure.in: + fix LIBEFS check. add gtkdoc check. + + * devel-docs/gnome-vfs/gnome-vfs-decl.txt: + * devel-docs/gnome-vfs/gnome-vfs-docs.sgml: + avoid an obvious error when compiling. + + * devel-docs/gnome-vfs/tmpl/gnome-vfs-mime-info.sgml: + * devel-docs/gnome-vfs/tmpl/gnome-vfs-mime.sgml: + * devel-docs/gnome-vfs/tmpl/libgnome-vfs.sgml: + regenerate templates... + +2000-10-25 Darin Adler + + * libgnomevfs/gnome-vfs-mime-sniff-buffer.c: + * libgnomevfs/gnome-vfs-mime-sniff-buffer.c: + (gnome_vfs_mime_sniff_buffer_get): Oops, got it wrong. This fixes + another case that I missed. + +2000-10-25 Darin Adler + + * libgnomevfs/gnome-vfs-mime-sniff-buffer.c: + (gnome_vfs_mime_sniff_buffer_get): Fixed error with the handling + of a case where the file is smaller than the requested sniff + buffer. The check was broken, and it also didn't set an error + code to let the caller know there's insufficient data. + + * configure.in: Fixed check of gcc command-line switches to work + properly even with -O. + +2000-10-24 John Sullivan + + * data/mime/gnome-vfs.mime: Added extension-based MIME type + entries for Word and Excel, since we want them to play nice + with StarOffice at least. + +2000-10-24 Rebecca Schulman + + Fixed a bug in the gnome vfs mime magic that we weren't + actually seeking and reading the right chunks of files. + Fixing this exposed a large performance problem related to + mime types with magic numbers far into the file, so with + Pavel's agreement, I remooved the microsoft mime types that + are a 2x performance issue for the mime code. apparently, + we never noticed they were working in the first place, but this + really isn't an appropriate thing to do in the future. + Also fixed a bug that the mime stuff was trying to reread after + the end of the file again and again, but I don't think this + helped performance as much as we first hoped. + + * data/mime/gnome-vfs-mime-magic: + removed the microsoft mime types + * libgnomevfs/gnome-vfs-mime-magic.c: (gnome_vfs_mime_magic_parse), + redid this to detect the end of file case, + (try_one_pattern_on_buffer), + (gnome_vfs_mime_try_one_magic_pattern), + (gnome_vfs_mime_get_magic_table), + (gnome_vfs_sniff_buffer_looks_like_text): + fixed indenting + + * libgnomevfs/gnome-vfs-mime-sniff-buffer-private.h: + added the "read_whole_file" entry to the sniff buffer struct + * libgnomevfs/gnome-vfs-mime-sniff-buffer.c: + (gnome_vfs_mime_sniff_buffer_get): + don't read if we've already read the whole file + * libgnomevfs/gnome-vfs-mime.c: (file_seek_binder): + Fix mistake where we'd swapped two arguments of + fseek. Amazingly, it worked anyways, that way. :) + +2000-10-24 John Sullivan + + * modules/ftp-method.c: (do_read_directory): + added FIXME about not following symlinks + +2000-10-24 John Sullivan + + * data/mime/gnome-vfs.keys: Added entry for + audio/x-mpeg, which is returned by some web servers + instead of the audio/x-mp3 that gnome-vfs knew about. + +2000-10-23 Pavel Cisler + + More work on 2989, this should conclude the GnomeVFS portion of the work. + + * libgnomevfs/gnome-vfs-find-directory.c: + Add comments about the meaning of the parameters. + + * modules/file-method.c: (find_trash_in_hierarchy), + (try_creating_trash_in), (save_trash_entry_cache), + (update_one_cached_trash_entry), (add_local_cached_trash_entry), + (read_saved_cached_trash_entries), (create_trash_near), + (find_locally_cached_trash_entry_for_device_id), + (find_or_create_trash_near), (find_trash_directory), + (do_find_directory): + Add a logic where the create_if needed flag can be specified + without the find_if_needed to signify that we want to just create + the Trash in the right place without first searching for an existing + one. + Fix a bug where a newly created Trash item would not get cached. + Fix a leak in read_saved_cached_trash_entries. + Fix a bug in create_trash_near that would cause the call to try + create in one directory above the disk we asked to create it. + Added some debugging code. + Tons of cleanup and comments. + +2000-10-24 Grahame Bowland + + * AUTHORS: + * modules/Makefile.am: + * modules/default-modules.conf: + * modules/nfs-method.c: + * modules/nfs-method.h: + * modules/nfs-method_mount.h: + * modules/nfs-method_mount_xdr.c: + * modules/nfs-method_nfs_prot.h: + * modules/nfs-method_nfs_prot_xdr.c: + Added initial NFS support to gnome-vfs. Read-only support reasonably stable; + write support is not. Symlinks are one notable problem that will be fixed in + the near future. + +2000-10-23 Mike Fleming + + * modules/http-method.c: + Turn off debugging spew, add myself to the "Authors" comment + +2000-10-22 Mike Fleming + + * modules/http-method.c: (cache_add_uri_and_children), + (process_propfind_response), (make_propfind_request): + + Caching and processing propfind requests now actually works with + filenames containing escape characters (bugzilla.eazel.com bug 3875) + +2000-10-22 Kjartan Maraas + + * data/mime/gnome-vfs.keys: Started adding Norwegian + translations to this. + +2000-10-20 Pavel Cisler + + * modules/file-method.c: (mkdir_recursive), + (update_one_cached_trash_entry), (add_local_cached_trash_entry), + (read_saved_cached_trash_entries): + Fix mkdir_recursive to not bail before creating the last directory level. + Fix find_directory trash entry caching to update an existing cache entry + when new Trash gets created instead of just adding a new entry. + Fix a test that checked if a trash directory existed and was backwards. + + * libgnomevfs/gnome-vfs-uri.c: (gnome_vfs_uri_extract_short_name): + Small unescaping tweak. + +2000-10-20 Pavel Cisler + + * modules/file-method.c: (mkdir_recursive): + Fix an "extra increment" bug and a memory leak. + Tweak the path for saving the trach entry cache file. + + * modules/file-method.c: (read_saved_cached_trash_entries): + Removed a confused g_warning for a case that is legal. + +2000-10-20 Pavel Cisler + + * libgnomevfs/gnome-vfs-uri.c: (gnome_vfs_uri_new): + Fix a memory trasher Mathieu found. + +2000-10-20 Michael Engber + + * libgnomevfs/gnome-vfs-xfer.c: (copy_directory): + progress callbacks used to get called in situations + when they shouldn't (error or skip cases). + +2000-10-20 John Sullivan + + * data/mime/gnome-vfs.keys: + * data/mime/gnome-vfs.mime: Changed staroffice types + from "x-soffice-*" to "x-staroffice-*" after user reported + such a MIME type. + +2000-10-20 John Sullivan + + * data/mime/gnome-vfs.keys: Added text/htmlH, which is used + by the help system; also moved application/mime-type-test to + alphabetical order so check-mime.pl doesn't gripe about it. + +2000-10-20 John Sullivan + + * libgnomevfs/gnome-vfs-async-ops.h: Added missing include + that was making this not standalone. This was uncovered by + a Nautilus extra-includes-removing pass that caused build + breakage. + +2000-10-20 Pavel Cisler + + Work on bug 2989, not done yet. + + * modules/file-method.c: (mkdir_recursive), + (match_trash_item_by_device_id), (find_disk_top_directory), + (save_trash_entry_cache), (add_local_cached_trash_entry), + (add_cached_trash_entry), (destroy_cached_trash_entry), + (read_saved_cached_trash_entries), (create_trash_near), + (cached_trash_entry_exists), + (find_locally_cached_trash_entry_for_device_id), + (find_cached_trash_entry_for_device), (find_trash_near), + (find_trash_directory), (do_find_directory): + Add a two level caching scheme for remembering trash folder locations. + This will help us only do the long search for a Trash directory do + the first time Nautilus ever runs or if a Trash directory gets moved + manually by the user to a different place. + In addition to caching the locations in a list in memory we now + also save them into a file in the user home settings directory. + Disks that have not had a Trash directory created on them are + marked as such and next time Nautilus is run, they are not searched + unless the user specifically requests a Trash directory to get created + (by throwing something from the respective directory to the Trash). + I still need to test/fix bugs in this. + + * test/test-find-directory.c: (main): + Tweak test code to help debug the new code. + +2000-10-19 Pavel Cisler + + * libgnomevfs/gnome-vfs-xfer.c: (empty_directory): + Fix bugs 3861 and 3882 - emptying the Trash containing + items with fancy names. + Neither was PR2 but I noticed the bug and it was trivial to fix. + +2000-10-18 Mike Fleming + + * modules/http-method.c: (make_propfind_request): + See John, I told you that EOF change would break stuff :) + (minor case of internal use of do_read not expecting the EOF error) + +2000-10-18 Mike Fleming + + * libgnomevfs/gnome-vfs-utils.c: (gnome_vfs_get_volume_free_space): + Return GNOME_VFS_ERROR_NOT_SUPPORTED instead of ERROR_GENERIC when + this call is attempted on a non-local filesystem. + + * libgnomevfs/gnome-vfs-xfer.c: (gnome_vfs_xfer_uri_internal): + Ignore errors from gnome_vfs_get_volume_free_space, which doesn't + work on non-local filesystems + + * modules/http-method.c: (http_status_to_vfs_result), + (make_propfind_request), (do_make_directory), + (do_remove_directory): + + Enhance HTTP error to GNOME VFS error mapping + Make MKCOL return correct code when directory already exists + (was preventing Nautilus Duplicate from working) + + This should fix bugzilla.eazel.com 3735 + + +2000-10-18 John Sullivan + + * modules/http-method.c: (do_read): + Made http module return GNOME_VFS_ERROR_EOF when it reads + 0 bytes. It was confusing clients by returning GNOME_VFS_OK + in this state. + +2000-10-17 Pavel Cisler + + * libgnomevfs/gnome-vfs-uri.c: (gnome_vfs_uri_extract_short_name): + Fix 1087 - gnome_vfs_uri_extract_short_name should probably unescape. + It already was but it was using the wrong unescape funciton. + +2000-10-18 Pavel Cisler + + Fix 2763 - "the uri code does not handle ../ and ./ like + the RFC says it should" + + * libgnomevfs/gnome-vfs-private-utils.c: (find_next_slash), + (find_slash_before_offset), (collapse_slash_runs), + (gnome_vfs_canonicalize_pathname): + Redo the routine that converts paths to a canonical form, + fix all the bugs I found. + + * test/test-uri.c: (test_canonicalize), (main): + Add a test suite for converting paths to canonical form and + converting uris to canonical form. + + * libgnomevfs/gnome-vfs-uri.c: (split_toplevel_uri), + (set_uri_element): + Get rid of unused macros, testing code that is no longer needed + and some incorrect commented out code. + +2000-10-17 Darin Adler + + * libgnomevfs-pthread/gnome-vfs-job.c: (gnome_vfs_job_new): + * modules/http-method.c: (make_propfind_request), + (do_get_file_info): + * modules/test-method.c: (load_config_file), (do_move), + (do_check_same_fs), (vfs_module_init): + * test/test-uri.c: (main): + Marked FIXMEs with bug numbers. + +2000-10-17 Pavel Cisler + + * libgnomevfs/gnome-vfs-uri.c: + (gnome_vfs_uri_new): + Fix bug 2840 - URI parsing works wrong for URIs with # characters. + The substring after '#' was being improperly parsed. + + * libgnomevfs/gnome-vfs-types.h: + * libgnomevfs/gnome-vfs-uri.c: + (gnome_vfs_uri_append_string), (gnome_vfs_uri_append_path): + * libgnomevfs/gnome-vfs-xfer.c: (empty_directory), + (PrependOneURIToList), (copy_items), (move_items), (link_items), + (gnome_vfs_new_directory_with_unique_name): + Made gnome_vfs_uri_append_path escape the supplied path for convenience. + New gnome_vfs_uri_append_string now replaces the original behavior that + expects the supplied uri part to be properly escaped. Hopefully this will + be somewhat less confusing and easier to use. + Used gnome_vfs_uri_append_string as needed in code that relied on + old gnome_vfs_uri_append_path behavior. + + * libgnomevfs/gnome-vfs-types.h: + * libgnomevfs/gnome-vfs-uri.c: + (gnome_vfs_uri_new), (destroy_element), (gnome_vfs_uri_dup), + (gnome_vfs_uri_to_string), (gnome_vfs_uri_get_fragment_identifier): + Added proper support for uri fragment identifiers, this seemed like + a necessary addition to fixing bug 2840 properly. + Fragment identifiers are now stored in a special field of GnomeVFSURI + and they no longer get returned as a part or the uri path or stripped. + They can be optionally excluded by gnome_vfs_uri_to_string using the + new GNOME_VFS_URI_HIDE_FRAGMENT_IDENTIFIER flag. + + * libgnomevfs/gnome-vfs-uri.c: + (split_toplevel_uri): + Fix a bug where host_return was incorrectly checked causing "/" to + always get appened to the resulting uri text. + + * libgnomevfs/gnome-vfs-types.h: + * libgnomevfs/gnome-vfs-uri.c: + (split_toplevel_uri_old), (uri_strspn_to), (split_toplevel_uri), + (parse_uri_substring), (gnome_vfs_uri_new), (gnome_vfs_uri_dup), + (gnome_vfs_uri_append_string), (gnome_vfs_uri_append_path), + (gnome_vfs_uri_append_file_name), (gnome_vfs_uri_to_string), + (string_match), (compare_elements), (gnome_vfs_uri_equal), + (gnome_vfs_uri_is_parent), (gnome_vfs_uri_get_path), + (gnome_vfs_uri_get_basename), (gnome_vfs_uri_extract_dirname), + (gnome_vfs_uri_extract_short_name), + (gnome_vfs_uri_extract_short_path_name) + Ton of cleanups. + + * test/test-uri.c: (test_file_path_to_uri_string), + (test_uri_has_fragment_id), (main): + Add tests for new fragment identifier support. + Fix up/extend tests for extended uri support. + Add test for path escaping/unescaping. + Eliminate FIXMEs that were fixed by this. + +2000-10-17 Jarkko Ranta + + * configure.in: added fi to all_linguas + +2000-10-16 Ramiro Estrugo + + * gnome-vfs.spec.in: + Add gnome-vfs.applications. This fixes the problem where users + using snapshot rpms where not getting sidebar buttons or "Open + With" menu items. Thanks for Jurgen for pointing this out. + +2000-10-16 Gene Z. Ragan + + Fixed bug 3042, Adding new mime type doesn't work. + + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.c: + (nautilus_mime_type_capplet_show_new_mime_window): + + * mime-type-capplet/nautilus-mime-type-capplet.c: + (add_mime_clicked): + Write proper description key. + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_add_extension): + Work in progress on adding user defined extensions + +2000-10-16 Gene Z. Ragan + + Fixed bug 3040, Action column has wrong contents + + Corrected an instance where text was not getting freed + and reset. Also fixed a few leaks in the list + population code. + + * mime-type-capplet/nautilus-mime-type-capplet.c: + (populate_application_menu), (populate_viewer_menu), + (add_mime_clicked), (populate_mime_list): + +2000-10-16 Ramiro Estrugo + + * modules/file-method.c: + Include to get the prototype for rename(). + +2000-10-14 Ian McKellar + + * modules/ftp-method.c: (dircache_setup), (dircache_expire): + Initial caching support. Currently disabled. + + (do_path_transfer_command): + Fix for empty paths. + + (ftp_connection_create), (ftp_connection_destroy), + (ftp_connection_aquire), (ftp_connection_release): + Count connections for debugging purposes. + + (ls_to_file_info), (do_get_file_info), + (do_open_directory), (do_read_directory): + * modules/ftp-method.h: + Initial symlink expansion support + + * test/test-directory.c: (print_list): + Better symlink debugging output. + +2000-10-12 Mike Fleming + + * modules/http-method.c: + Added define from GMan to make it compile under Solaris (hopefully) + +2000-10-12 Martin Baulig + + * libgnomevfs-corba/gnome-vfs-slave.c (impl_Request_get_file_info): + Call CORBA_string_dup() on p->name, p->symlink_name and p->mime_type. + +2000-10-12 Grahame Bowland + + * libgnomevfs/gnome-vfs-result.c: + (gnome_vfs_result_from_errno_code), (gnome_vfs_result_from_errno): + * libgnomevfs/gnome-vfs-result.h: + Added a gnome_vfs_result_from_errno_code convenience call. + +2000-10-11 Mike Fleming + + * modules/http-method.c: + Oops. I left the debug messages on + +2000-10-11 Mike Fleming + + * modules/http-method.c: (propfind_href_to_vfs_uri): + Forgoet a NULL on g_strconcat, as I'm prone to. + +2000-10-11 Darin Adler + + Fixed broken remnants of support for building without GConf. + + * libgnomevfs/gnome-vfs-mime-handlers.c: (unref_gconf_engine), + (get_user_level): Fixed code to work with new GConf. It was still + using the pre-0.9 GConf API, but it was inside HAVE_GCONF + conditionals which were always false. + * Makefile.am: Removed HAVE_GCONF conditionals.. + * configure.in: Removed broken code to set up HAVE_GCONF and + GCONF_CONFIG. + * modules/Makefile.am: Removed HAVE_GCONF conditionals. + +2000-10-10 Mike Fleming + + * modules/http-method.c: (propfind_href_to_vfs_uri), + (process_propfind_response): + ugly hack: Eazel Vault returns "https" URI's in propfind requests, + which was causing DAV to choke. + +2000-10-09 Pavel Cisler + + * libgnomevfs/gnome-vfs-xfer.c: (PrependOneURIToList), + (non_recursive_empty_directory), (remove_directory), + (gnome_vfs_xfer_empty_trash): + work on 825 - Inability to empty Trash after trashing a deeply + nested directory. Added a fallback call that builds a uri list + first without keeping directory file descriptors opened. + +2000-10-09 Glynn Foster + + * configure.in: + * libgnomevfs/gnome-vfs-utils.c: (istr_has_prefix), + (gnome_vfs_get_volume_free_space): + Added Solaris-specific changes to needed for getting the + free volume space. + +2000-10-09 Robin * Slomkowski + + * configure.in: upped the version to 0.3.1.0 as 0.3.1 has already been + released many moons ago + +2000-10-05 Mike Fleming + + * modules/http-method.c: (http_proxy_for_host_port), + (vfs_module_init): + + When HTTP proxy is enabled, proxy is explicitly bypassed for "localhost" + and "127.x.x.x.". We'd like to have a general configuration mechanism for + non-proxy URL's in the future. This was causing bugzilla.eazel.com 3492 + + Also fixed some debug messages to work with the new gconf + +2000-10-05 Ramiro Estrugo + + * modules/http-method.c: (vfs_module_init): + Workaround a bug in gconf by not preloading a directory that is + monitored. + +2000-10-04 Pavel Cisler + + * libgnomevfs/gnome-vfs-utils.c: + Move includes around to unbreak the build on Linux. + +2000-09-21 Chris Toshok + + * configure.in: add checks for sys/vfs.h and sys/mount.h + + * libgnomevfs/gnome-vfs-utils.c: sys/vfs.h doesn't exist on some + systems, so wrap #if HAVE_SYS_VFS_H. if there's no sys/vfs.h, try + sys/mount.h. also, include sys/param.h if it's available (since + including sys/mount.h on freebsd without first including + sys/param.h breaks, at least in some versions of 4.x.) + +2000-10-04 Ramiro Estrugo + + * acconfig.h: + * configure.in: + Add profiling support via --enable-profiler. + +2000-10-03 Mike Fleming + + * data/mime/gnome-vfs.keys: + bugzilla.eazel.com 2854 + Icon view is now the default Nautilus view for viewing DAV-enabled + HTTP directories + +2000-10-03 Ramiro Estrugo + + * configure.in: + * gnome-vfs.spec.in: + * modules/gconf-method.c: (read_directory): + * modules/http-method.c: (sig_gconf_value_changed), + (vfs_module_init): + Update for GConf HEAD (0.9) + +2000-10-03 Christophe Merlet + + * data/mime/gnome-vfs.keys: Added french strings. + +2000-10-02 Mike Fleming + + More file info caching stuff. Now caches the contents of directories + (for a fairly short time). This still doesn't squeeze out as much + performance as I had hoped, mostly because of Nautilus's habit of + hitting ".nautilus-metafile.xml"'s . Negative caching and updating + of the cache following method invocation (rather than just invalidating) + could improve performance greatly. + + * modules/http-method.c: (cache_init), (cache_shutdown), + (cache_entry_free), (cache_uri_to_string), (cache_check_directory), + (cache_check_directory_uri), (cache_add_no_strdup), (cache_add), + (cache_add_uri_and_children), + (cache_invalidate_entry_and_children), + (cache_invalidate_uri_and_children), (cache_invalidate_uri_parent), + (make_request), (do_create), (do_close), (make_propfind_request), + (do_open_directory), (do_make_directory), (do_remove_directory), + (do_move): + +2000-10-02 Mike Fleming + + * modules/http-method.c: (do_open_directory): + Fix foolish crasher + +2000-10-02 Mike Fleming + + * libgnomevfs/gnome-vfs-file-info.c: (gnome_vfs_file_info_clear), + (gnome_vfs_file_info_ref), (gnome_vfs_file_info_unref), + (gnome_vfs_file_info_copy): + Made the GnomeVFSFileInfo ref count mechanism thread-safe + (increments and decrements are not guarenteed to be atomic) + + * modules/http-method.c: (my_debug_printf), (get_utime), + (cache_init), (cache_shutdown), (cache_entry_new), + (cache_entry_free), (cache_trim), (cache_check), + (cache_uri_to_string), (cache_check_uri), (cache_check_directory), + (cache_add_no_strdup), (cache_add), (cache_add_uri_and_children), + (cache_add_uri), (cache_invalidate), (cache_invalidate_uri), + (cache_invalidate_entry_and_children), (check_header), + (parse_header), (get_header), (create_handle), (make_request), + (process_propfind_propstat), (process_propfind_response), + (make_propfind_request), (do_open_directory), (do_read_directory), + (do_get_file_info), (do_move), (vfs_module_init), + (vfs_module_shutdown): + Add the first phase of file info caching for DAV. (These code paths + are not executing for non-DAV sites). Caching is on by default now. + +2000-10-02 Kjartan Maraas + + * gnome-vfs.spec.in: Really fix installation of the + man page with rpm-4.0. The newer version compresses the + man pages by default. Used *.5* instead of *.5.gz + +2000-09-30 Pavel Cisler + + * libgnomevfs/gnome-vfs-mime-magic.c: + (gnome_vfs_sniff_buffer_looks_like_text): + Fix a MIME sniffing bug that Bud was seeing where 0-byte files + would show up as text/plain. + + * libgnomevfs/gnome-vfs-xfer.c: (remove_directory): + Part I of fix to 1314 - Move to Trash faild if name conflict in + trash. + + * libgnomevfs/gnome-vfs-xfer.c: (empty_directory): + Handle errors during emptying directories properly. + + * libgnomevfs/gnome-vfs-xfer.c: (xfer_create_target), + (move_items), (link_items): + Cleanups. Rework the duplicate handling code. + + * libgnomevfs/gnome-vfs-xfer.c: (gnome_vfs_destination_is_writable), + (gnome_vfs_xfer_uri_internal): + Cleanups. Make the non-writable destination error and out of space on + disk error get reported. Make the non-writable destination check only + check on local file systems. Make the non-writable destination check + clean up after a botched previous check that left behind a temporary + file. + +2000-09-29 Darin Adler + + * gnome-vfs.spec.in: Turn off "make check" again. For some reason + it still fails on the Tinderbox, even with the LD_LIBRARY_PATH + problem fixed. + +2000-09-29 Eskil Heyn Olsen + + * libgnomevfs/gnome-vfs-xfer.c: (gnome_vfs_xfer_uri_list), + (gnome_vfs_xfer_uri), (gnome_vfs_xfer_delete_list): + Fixed the g_return_val_if_fails. + +2000-09-29 John Sullivan + + Fixed bug I ran into where I would crash at Nautilus startup + due to the presence of a NautilusDirectory for + "file://.Trash-sullivan" + + * modules/file-method.c: + (append_trash_path): Special-case "/" to avoid creating + non-canonical "//.Trash" uris. + (do_find_directory): convert path to uri before calling + gnome_vfs_uri_new. + +2000-09-29 Darin Adler + + * test/test-uri.c: (main): Added a test to demonstrate how badly + gnome_vfs_uri_new handles paths that start with "//". + +2000-09-29 Darin Adler + + * gnome-vfs.spec.in: Turn "make check" back on. + * test/Makefile.am: Fix tests so they work even before gnome-vfs + is installed for the first time. This has a nice side effect of + making the test actually test the compiled code, not a previously + installed version. + +2000-09-29 J Shane Culpepper + + * test/gnome-file-selection/gnome-file-selection-history.c: + * test/test-dirop.c: + * test/test-escape.c: + * test/test-mime-handlers-set.c: + * test/test-mime-handlers.c: + * test/test-mime-info.c: + * test/test-mime.c: + * test/test-sync-create.c: + * test/test-sync-write.c: + * test/test-sync.c: + * test/test-unlink.c: + * test/test-uri.c: + + Fixing heaps of inlined function errors. The new redhat compilers + do not recognize functions like exit, strcmp, etc without the correct + header anymore. gnome-vfs now builds happily on RedHat 7.0. + +2000-09-29 J Shane Culpepper + + * libgnomevfs/gnome-vfs-directory-filter.c: + + Adding include so that above file builds right on + newer compilers. + +2000-09-29 Darin Adler + + * gnome-vfs.spec.in: Turn off "make check" since it doesn't work + until the library is installed because of the back end. + * test/test-uri.c: (main): Add some test cases. + +2000-09-29 Darin Adler + + * gnome-vfs.spec.in: Make RPM builds do "make check" and also make + them compile with warnings on. This make the Tinderbox more + strict. Also use "make -k" so we get more errors at once on the + Tinderbox. Errors are still errors, we just see more of them. + + * libgnomevfs/gnome-vfs-xfer.c: (system_time), (init_progress): + Fix code to not use LL explicitly since that's not as portable as + gint64 is. + (init_progress): Got rid of code initializing the same fields to + NULL twice. + (empty_directory), (copy_items), (move_items), (link_items), + (gnome_vfs_new_directory_with_unique_name): Change code to use + file names in URI encoded form throughout. No unescaping in here. + This was all done by changing which GnomeVFSURI calls we use. + +2000-09-28 Ramiro Estrugo + + * configure.in: + Switch the order of assignment of warnings to CFLAGS so that they + can be overridden by the user at configure time. + +2000-09-28 Mike Fleming + + Fixed file_info refcounting issues associated with _clear and + _copy. (_clear retains the refcount; _copy leaves the refcount of + the destination alone). + + Changed _init, _ref, and _unref to clarify that ref-counting a + file_info that was allocated on the stack is illegal. + + Added _dup function. + + * libgnomevfs/gnome-vfs-file-info.c: (gnome_vfs_file_info_init), + (gnome_vfs_file_info_clear), (gnome_vfs_file_info_ref), + (gnome_vfs_file_info_unref), (gnome_vfs_file_info_copy), + (gnome_vfs_file_info_dup): + * libgnomevfs/gnome-vfs-file-info.h: + +2000-09-28 Pavel Cisler + + * libgnomevfs-pthread/gnome-vfs-job.c: + * libgnomevfs/gnome-vfs-xfer.c: (gnome_vfs_xfer_delete_items), + (gnome_vfs_xfer_uri_list), (gnome_vfs_xfer_uri), + (gnome_vfs_xfer_delete_list): + * libgnomevfs/gnome-vfs-xfer.h: + Add a gnome_vfs_xfer_delete_list call to match the feature + that already exists in gnome_vfs_xfer_async. Andy needed this code + for theme deleting. + +2000-09-28 Mike Fleming + + * libgnomevfs/gnome-vfs-iobuf.c: (gnome_vfs_iobuf_read): + * modules/http-method.c: (http_file_handle_new), (get_header): + + I decided that the previous fix wasn't that great of an idea and + fixed the caller of gnome_vfs_iobuf-read. + +2000-09-28 Mike Fleming + + * libgnomevfs/gnome-vfs-iobuf.c: (gnome_vfs_iobuf_read): + + gnome_vfs_iobuf_read was returning GNOME_VFS_OK if a read was attempted + at the end of file. It now correctly returhns GNOME_VFS_ERROR_EOF. + +2000-09-29 Ian McKellar + + * modules/ftp-method.c: (ls_to_file_info), (do_read_directory): + Fixed a bug where NULL was being returned for the mime-type for + files whose type was unknown. Fixed a bug where a reading a + directory would busy-loop forever on an empty string. + +2000-07-28 Christophe Merlet + + * mime-type-capplet/nautilus-mime-type.desktop: Added the + French strings. + +2000-09-27 Mike Fleming + + get_file_info now makes a PROPFIND before a HEAD request, and does not + make HEAD requests if the PROPFIND succeeds. This cuts down the number + of HTTP requests made when working against a DAV server. + Did some additional cleanup while I was at it. + + * modules/http-method.c: (defaults_file_info_new), + (http_file_handle_new), (http_file_handle_destroy), + (set_content_length), (set_content_type), (set_last_modified), + (set_access_time), (create_handle), (make_request), + (http_handle_close), (do_open), (do_create), (do_close), + (do_write), (do_read), (process_propfind_response), + (make_propfind_request), (do_open_directory), (do_close_directory), + (do_read_directory), (do_get_file_info), + (do_get_file_info_from_handle), (do_is_local), (do_make_directory), + (do_remove_directory), (do_move), (do_unlink): + +2000-09-27 Darin Adler + + * libgnomevfs-pthread/gnome-vfs-job.c: (execute_xfer): + Fix a double-destroy I introduced with my change to + gnome_vfs_op_destroy yesterday. + +2000-09-27 Pavel Cisler + + * libgnomevfs/gnome-vfs-mime-magic.c: (try_one_pattern_on_buffer), + (gnome_vfs_mime_try_one_magic_pattern): + * libgnomevfs/gnome-vfs-mime-sniff-buffer.c: + Some micro optimizations for calls that get executed a lot and show + up high in profiles. + +2000-09-26 Darin Adler + + More storage leak fixes. + + * libgnomevfs-pthread/gnome-vfs-job.c: (free_get_file_info_data): + Free the URI list. + (free_find_directory_data): Free the URI list. + (gnome_vfs_op_destroy): Free the reference string in the + create_symbolic_link case, the sort rules and pattern in the + load_directory case, and the source and target URI lists in the + xfer case. + (execute_load_directory): Don't free the sort rules and pattern + here any more since it's now done in the common cleanup (for both + successful and cancelled operations). + + * libgnomevfs-pthread/gnome-vfs-async-ops.c: + (pthread_gnome_vfs_async_create_symbolic_link): Whitespace. + +2000-09-26 Darin Adler + + Fixed some quit time deallocation stuff to be better for leak + checking purposes. + + * libgnomevfs-pthread/gnome-vfs-job-slave.h: + * libgnomevfs-pthread/gnome-vfs-job-slave.c: (thread_routine): + (gnome_vfs_job_create_slave), (gnome_vfs_thread_backend_shutdown): + Got rid of the thread count and the related mutex, since we use a + job count instead. Since the job count is manipulated only on the + main thread, we don't need volatiles or mutexes. + + * libgnomevfs-pthread/gnome-vfs-job.h: + * libgnomevfs-pthread/gnome-vfs-job.c: (gnome_vfs_job_new): + Increment the job count. + (gnome_vfs_job_finish_destroy): Decrement the job count. + (gnome_vfs_job_get_count): Return the job count. + + * libgnomevfs/gnome-vfs-backend.h: + * libgnomevfs/gnome-vfs-backend.c: + (gnome_vfs_backend_get_job_count): Add a way to get the job count + from the back end to replace the old way of getting a thread count + from the back end. + * test/test-async-cancel.c: (wait_until_vfs_threads_gone), + (wait_until_vfs_threads_gone_no_main), (main): Use the job count + instead of the thread count. + +2000-09-25 John Sullivan + + * modules/http-method.c: (make_request): + This routine was assuming there was a valid hostname, but + for cases like "http://foo:" there was not. Now checks for + NULL hostname and returns GNOME_VFS_ERROR_INVALID_URI. + +2000-09-25 Pavel Cisler + + * test/test-async-directory.c: (test_read_file_close_callback), + (test_read_file_succeeded), (test_read_file_failed), + (test_read_file_read_callback), (test_read_file_read_chunk), + (test_read_file_open_callback), (test_read_file_async), + (directory_load_callback), (main): + Add optional file read testing to the directory async test for + performance measurement. + +2000-09-25 Pavel Cisler + + * libgnomevfs-pthread/gnome-vfs-job-slave.c: (thread_routine): + * libgnomevfs-pthread/gnome-vfs-job.c: + (dispatch_job_callback), (gnome_vfs_job_new): + Remove some unnecessary thread startup synchronization to speed up + job creation. + + * libgnomevfs/gnome-vfs-mime-magic.c: (try_one_pattern_on_buffer): + Tweak a routine that gets called a lot to gain a bit of performance. + + * test/test-async-directory.c: (directory_load_callback), (main): + Some small tweaks. + +2000-09-23 Mike Fleming + + * modules/translate-method.c: (tr_uri_translate): + Removed dead FIXME (bugzilla.eazel.com 2798) + +2000-09-23 Mike Fleming + + * modules/translate-method.c: (tr_exec_open_child), + (tr_exec_do_retain), (tr_handle_exec): + + Make vfs-translate's -exec -retain more robust. Leaking processes + is less likely; processes are restarted if they die + +2000-09-22 Mike Fleming + + * modules/http-method.c: (http_handle_close): + + A NULL iobuf was being destroyed, which caused an assertion + to be raised. + +2000-09-22 Darin Adler + + * libgnomevfs-pthread/gnome-vfs-job.c: (dispatch_open_callback), + (dispatch_create_callback), (dispatch_open_as_channel_callback), + (dispatch_create_as_channel_callback), + (dispatch_load_directory_callback), + (dispatch_get_file_info_callback), (free_get_file_info_data), + (dispatch_find_directory_callback), (free_find_directory_data), + (dispatch_set_file_info_callback), (dispatch_job_callback), + (gnome_vfs_op_destroy), (execute_get_file_info), + (execute_set_file_info): Fixed tons of storage leaks that happened + when an operation was cancelled by freeing things stored in the + GnomeVFSOp when the GnomeVFSOp is deleted instead of at callback + time. Fixes bug 2746 (leak in cancelled gnome_vfs_xfer call). + (execute_load_directory_not_sorted): Fixed a storage leak caused + by allocating an info before checking for cancellation and then + exiting without freeing it. + + * libgnomevfs/gnome-vfs-method.c: + (gnome_vfs_add_module_to_hash_table), (gnome_vfs_method_get), + (gnome_vfs_transform_get): Changed the name of "fill_hash_table" + to "gnome_vfs_add_module_to_hash_table" to make the it easier for + the leak checker (currently in the Nautilus source module, but + useful for any program) to recognize this as an exception to the + normal rules about what leaks are. A bit of a hack; alternatives + include adding code to free things at exit time. + +2000-09-22 Mike Fleming + + * modules/http-method.c: (http_file_handle_new), + (http_file_handle_destroy), (do_close): + + Fixed lack-of-URI-refcounting problem and deleted a misplaced + iobuf_write call. Markedly increases stability of DAV under vfs-translate. + +2000-09-21 Andy Hertzfeld + + * data/mime/gnome-vfs.keys: + dropped the prefix on the newly added icons names for music and + spreadsheet, so it can choose the right icon to use + +2000-09-22 Ian McKellar + + * modules/http-method.c: (make_propfind_request): + Fixed bug 2655: Only request the WebDAV properties we're interested + in. + +2000-09-21 Andy Hertzfeld + + * data/mime/gnome-vfs.keys: + tweaked the mime-types to use Susan's new icons for music and + spreadsheet files. + +2000-09-21 Mathieu Lacage + + * libgnomevfs/gnome-vfs-private-utils.c: + (gnome_vfs_canonicalize_pathname): make it not transform + 'method://foo' to 'method://foo.' + * libgnomevfs/gnome-vfs-uri.c: (split_toplevel_uri): + make it differentiate 'method://foo/' from 'method://foo' + * modules/ftp-method.c: (do_path_command), + (do_path_transfer_command), (ftp_connection_create), + (ls_to_file_info), (do_open_directory): + fix to handle the fact the gnome_vfs_uri_get_path can + return a string of length zero. + * modules/http-method.c: (make_request): handle the same + special case as above. + * test/test-uri.c: (main): add tests to test my new stuff. + +2000-09-21 Darin Adler + + Fixed code that was creating a separate "job slave" object that + was never really used. Fixes a storage leak. + + * libgnomevfs-pthread/gnome-vfs-job-slave.h: + * libgnomevfs-pthread/gnome-vfs-job-slave.c: (thread_routine): + Changed to take a GnomeVFSJob pointer instead of GnomeVFSJobSlave. + (gnome_vfs_job_create_slave): Replaced the old + gnome_vfs_job_slave_new with this simpler function. + Also removed a lot of unused functions. + * libgnomevfs-pthread/gnome-vfs-job.h: + * libgnomevfs-pthread/gnome-vfs-job.c: (gnome_vfs_job_new): + Use the new gnome_vfs_job_create_slave instead of + gnome_vfs_job_slave_new and don't even try to keep a slave pointer + around. + +2000-09-21 Rebecca Schulman + + * libgnomevfs/gnome-vfs-directory-filter.c: (common_filter): + * libgnomevfs/gnome-vfs-types.h: + Added the filter type no dot files + +2000-09-21 Pavel Cisler + + * libgnomevfs/gnome-vfs-xfer.c: (copy_file_data): + Properly handle GNOME_VFS_ERROR_EOF. + Fixes bugzilla 3225. + +2000-09-21 Mike Fleming + + * gnome-vfs.spec.in: + * configure.in: Added dependency to gconf-gtk; Moved GConf dependency to 0.8.0 + + * modules/Makefile.am: + * modules/http-method.c: (sig_gconf_value_changed), + (host_port_from_string), (http_proxy_for_host_port), + (make_request), (make_propfind_request), (vfs_module_init), + (vfs_module_shutdown): + + HTTP module now supports HTTP proxies. HTTP proxy is gotten from GConf + key /system/gnome-vfs/http-proxy. This makes the HTTP module dependent + on GConf. + +2000-09-21 John Sullivan + + * mime-type-capplet/nautilus-mime-type-capplet.c: + (mime_list_selected_row_callback): Removed an outdated FIXME. + +2000-09-20 Gene Z. Ragan + + Found a case where a URI was used unitialized. + + * libgnomevfs/gnome-vfs-xfer.c: + (gnome_vfs_xfer_uri_internal): + +2000-09-20 Gene Z. Ragan + + Fixed a bug where transferring symbolic links from an ftp + site would crash nautilus. Links are now properly identified. + + * libgnomevfs/gnome-vfs-module-shared.c: + (gnome_vfs_stat_to_file_info): + Handle symbolic links. + + * libgnomevfs/gnome-vfs-xfer.c: (copy_directory), (copy_items): + Replace some plain asserts with assert_unreachable + + * modules/ftp-method.c: (get_response), (do_control_write), + (ftp_connection_aquire), (ftp_connection_release), + (ls_to_file_info), (do_get_file_info): + +2000-09-20 Darin Adler + + * data/mime/gnome-vfs.applications: Both EOG and The Gimp had + entries that claim they can handle URIs, but the versions of these + programs that I have can't. + + * libgnomevfs/gnome-vfs-configuration.c: (parse_line): + * libgnomevfs/gnome-vfs-mime-info.c: (does_string_contains_caps): + On IRC, gmorten pointed out that we must cast to unsigned char before + calling functions like isspace and isupper. There are probably other + cases of this mistake here and in Nautilus, but here are some fixes. + + * libgnomevfs/gnome-vfs-gen-mimedb.c: Removed an unnecessary + include of . + + * test/test-uri.c: (main): Fixed some typos and enabled some + tests. We like to put the "wrong" results in here with a FIXME + instead of commenting out the tests altogether. + +2000-09-20 Gene Z. Ragan + + Renabled and cleaned up read only volume check. + + * libgnomevfs/gnome-vfs-xfer.c: + (gnome_vfs_xfer_uri_internal): + +2000-09-20 Gene Z. Ragan + + Fixed bug 1214, check if copy destination has enough room. + + This only works for local file systems. + + * libgnomevfs/gnome-vfs-uri.c: + * libgnomevfs/gnome-vfs-utils.c: + (gnome_vfs_get_volume_free_space): + New function that gets free space on volume + + * libgnomevfs/gnome-vfs-xfer.c: + (gnome_vfs_xfer_uri_internal): + Call gnome_vfs_get_volume_free_space () before copy. + +2000-09-20 Maciej Stachowiak + + * modules/file-method.c (do_read): Report EOF on EOF. + +2000-09-20 Ian McKellar + + * modules/Makefile.am: + * modules/test-method.c: (load_config_file): + Little fixes for test-method. + + * modules/ftp-method.c: (do_path_command_completely), + (do_transfer_command), (end_transfer), (do_create), (do_write): + * test/test-remote: + Fixing FTP issues raised by test-remote. + +2000-09-19 Gene Z. Ragan + + Backing out previous change until current work on + free space calculation is done as well. + + Work in progress on verifying free space on target copy + location. + + * libgnomevfs/gnome-vfs-utils.c: (str_has_prefix), + * libgnomevfs/gnome-vfs-utils.h: + (gnome_vfs_get_volume_free_space): + New function to return free space on destination volume. + + * libgnomevfs/gnome-vfs-xfer.c: + (gnome_vfs_xfer_uri_internal): + Commented out checks until code is complete. + +2000-09-19 Gene Z. Ragan + + Fixed bug 1213, add a check to figure out if destination + is writable. + + Call gnome_vfs_open_uri () on destination and return error + if one is returned. + + * libgnomevfs/gnome-vfs-xfer.c: (gnome_vfs_xfer_uri_internal): + +2000-09-18 Mathieu Lacage + + * libgnomevfs/gnome-vfs-mime-info.c: (context_new), + (load_mime_list_info_from): fix on fixup on fix on + my previous commit. This parser code is truly evil + but it now works both for me and dan. + Remove the ":" at the end of old .mime file format + when reading. + +2000-09-18 Maciej Stachowiak + + Rename "foobar" module to "test". + + * modules/Makefile.am: + * modules/default-modules.conf: + * modules/foobar-method.c: + * modules/test-method.c: (translate_uri), + (get_operation_configuration), (parse_results_text), + (load_config_file), (vfs_module_init): + +2000-09-18 Dan Winship + + * libgnomevfs/gnome-vfs-mime-info.c (context_new): Fix up previous + fix. It wasn't the ":"s, it was the "*"s. + +2000-09-18 Mathieu Lacage + + * libgnomevfs/gnome-vfs-mime-info.c: (context_new): + fix bug which made us unable to read old mime database + format. the ":" was taken into account when reading the + old database. + +2000-09-18 Mathieu Lacage + + * libgnomevfs/gnome-vfs-mime-info.c: + (ensure_user_directory_exist): add new function to create the + user's home directory ~/gnome/mime-info if it does not exists + (write_back_mime_user_file), (write_back_keys_user_file): use + this new function here. + +2000-09-16 Gene Z. Ragan + + Fixed bug 3042, Adding new mime type doesn't work + + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.c: + (nautilus_mime_type_capplet_show_new_mime_window): + Return the new mime type if one was created + + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.h: + * mime-type-capplet/nautilus-mime-type-capplet.c: + (nautilus_mime_type_capplet_update_info), (add_mime_clicked): + Add info to main list. + +2000-09-15 Gene Z. Ragan + + * data/mime/gnome-vfs.keys: + Replaced EOG image component with the NautilusImageView + +2000-09-15 Darin Adler + + * libgnomevfs/gnome-vfs-backend.c: (gnome_vfs_backend_shutdown): + Fixed a typo that crept in here a while back. It was preventing + the shutdown code from running. + +2000-09-15 Andy Hertzfeld + + * data/mime/gnome-vfs.keys: + fixed bug 1870, images files don't have the right icons when + thumbnailing is turned off. Fixed by defining icons in gnome-vfs.keys + for all of the common image types. I also defined icons for the + common audio types while I was at it. + +2000-09-15 Mathieu Lacage + + * libgnomevfs/gnome-vfs-mime-info.c: (get_key_name), + (gnome_vfs_get_registered_mime_types): fix bug 2759. + no duplicates are returned anymore. + +2000-09-15 Ali Abdin + + * modules/pipe-method.c, + * modules/translate-method.c: + Added a comment at the top saying it is licensed under the LGPL and + Copyright to Red Hat Inc. (I checked with Sopwith first) + + * AUTHORS: + "help" method is in Nautilus, not gnome-vfs so we shouldn't mention it + here. + +2000-09-14 Mathieu Lacage + + Fix bug 2758. remove a bunch of unused functions + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_get_description): move there. + * libgnomevfs/gnome-vfs-mime-handlers.h: move get_description + there. + * libgnomevfs/gnome-vfs-mime-info.c: remove old functions. + * libgnomevfs/gnome-vfs-mime-info.h: remove prototypes. + * test/test-mime-info.c: (main): fix the test for these changes. + +2000-09-13 John Sullivan + + Added StarOffice information to the MIME data. + It's not well tested, because (A) I don't have + StarOffice installed, and (B) the File Types + & Programs capplet seems horribly broken in + numerous unreported ways. + + * data/mime/gnome-vfs.applications: + * data/mime/gnome-vfs.keys: + * data/mime/gnome-vfs.mime: + +2000-09-13 Pavel Cisler + + * modules/file-method.c: (do_create_symbolic_link): + Make it handle invalid URI with a returned error value rather + than with an assert. + +2000-09-13 Pavel Cisler + + * libgnomevfs/gnome-vfs-xfer.c: (copy_items), (move_items), + (link_items): + Fix a problem where file names would get escaped twice in the + copy engine and caused files to get moved/copied with an + escaped path. + + * modules/file-method.c: (get_path_from_uri): + Tweak some white space. + +2000-09-12 Darin Adler + + * libgnomevfs/gnome-vfs-mime-magic.c: + (gnome_vfs_mime_get_magic_table): Add the missing call to actually + parse the text file. We never noticed it was missing, because we + were getting the binary form of that table until recently. + +2000-09-12 Seth Nickell + + * modules/Makefile.am: + add building of foobar-method.c + + * modules/default-modules.conf: + register foobar-method.c to handle "foobar:" + + * modules/foobar-method.c: (translate_uri), + (get_operation_configuration), (parse_results_text), + (load_config_file), (do_open), (do_create), (do_close), (do_read), + (do_write), (do_seek), (do_tell), (do_open_directory), + (do_close_directory), (do_read_directory), (do_get_file_info), + (do_get_file_info_from_handle), (do_is_local), (do_make_directory), + (do_remove_directory), (do_move), (do_unlink), (do_check_same_fs), + (do_set_file_info), (do_truncate), (do_truncate_handle), + (do_find_directory), (do_create_symbolic_link), (vfs_module_init), + (vfs_module_shutdown): + Foobar is a gnome-vfs debug module that allows you to redirect + calls to another underlying method, and intercept and manipulate + the calls, adding delays or returning errors to the client. + +2000-09-11 Mathieu Lacage + + * test/test-uri.c: (main): remove the tests from compilation folowing + pavel and Darin advices. + +2000-09-11 Mathieu Lacage + + * test/test-uri.c: (main): add 2 new tests which fail and should be + fixed somehow. I dunno how to fix them but they cause crashes in nautilus. + /tmp/#test# is not taken into account by gnome_vfs_uri_new. + +2000-09-10 Maciej Stachowiak + + Build fixes for latest Gtk+ + + * configure.in: Add AM_PATH_GTK check + * libgnomevfs-pthread/Makefile.am: Use $(GTK_CFLAGS) in compiler flags + * mime-type-capplet/Makefile.am: likewise + * modules/Makefile.am: likewise + * test/Makefile.am: likewise + * test/gnome-file-selection/Makefile.am: likewise + +2000-09-10 Maciej Stachowiak + + * gnome-vfs.spec.in: Revert kmaraas's last change, because it + breaks rpm building for me (and for tinderbox). I wonder why man + pages are apparently installed gzipped on Kjartan's system but not + mine. + +2000-09-09 Kjartan Maraas + + * gnome-vfs.spec.in: Fixed installation of man page. + +2000-09-09 Gene Z. Ragan + + * libgnomevfs/Makefile.am: + * libgnomevfs/gnome-vfs-mime-handlers.c: (sort_application_list), + (gnome_vfs_mime_get_short_list_applications), + (sort_component_list), (gnome_vfs_mime_get_short_list_components): + Sort application and component lists alphabetically + before returning them. + +2000-09-08 Pavel Cisler + + * libgnomevfs-pthread/gnome-vfs-job.c: (gnome_vfs_job_new): + Performance improvement Darin and I found: + Change the priority of callbacks to G_PRIORITY_DEFAULT from + G_PRIORITY_LOW to prevent serious performance drain where + callbacks do not get scheduled early enough. + This speeds up Nautilus directory update by 30% or so. + +2000-09-08 Gene Z. Ragan + + * mime-type-capplet/nautilus-mime-type-capplet.c: + (populate_mime_list): + Fixed a couple of leaks and instances where + gdk_pixbuf_new_from_file was being passed a NULL char *. + +2000-09-08 Gene Z. Ragan + + Fixed bug 2839, setting icons for mime type is not remembered + + * mime-type-capplet/nautilus-mime-type-capplet.c: (main), + (init_mime_capplet), (nautilus_mime_type_capplet_update_info), + (populate_mime_list), + (nautilus_mime_type_capplet_get_selected_item_mime_type): + Removed icon setting code callback from Change Icon button. + + * mime-type-capplet/nautilus-mime-type-icon-entry.c: + (icon_selected_cb), (cancel_pressed), (gil_icon_selected_cb), + (nautilus_mime_type_show_icon_selection): + Added gnome-vfs icon setting code to OK button callback. + +2000-09-08 Maciej Stachowiak + + * data/mime/Makefile.am: Don't attempt to build binary version of + mime database. + + * gnome-vfs.spec.in: Don't include gnome-vfs-genmimedb or the + binary version of the mime database that it generates. + +2000-09-08 Gene Z. Ragan + + Fixed bug 2766, viewer menu code is not finished. + + Enjoy your Content Loser. + + * mime-type-capplet/nautilus-mime-type-capplet.c: + (populate_viewer_menu): + Made function work. + +2000-09-08 Gene Z. Ragan + + Fixed bug 2789, Need to cancel non-file drags in icon + entry field. + + * mime-type-capplet/nautilus-mime-type-icon-entry.c: + (drag_data_get): + +2000-09-07 Dan Winship + + * data/mime/gnome-vfs.keys: lowercasify the handful of + descriptions that started with a capital letter that wasn't part + of a proper name. Rewrite a few descriptions to be more correct or + more user-friendly. Add comments pointing out duplicated entries + (like image/png and image/x-png) that need to be kept in sync. + +2000-09-08 Ian McKellar + + * modules/http-method.c: (make_request): + Implemented custom user-agent headers - specified by the + GNOME_VFS_HTTP_USER_AGENT environment variable. + +2000-09-06 Pavel Cisler + + * configure.in: + Get rid of -Wno-uninitialized. This way we will get uninitialized + variable warnings when we do a release build (with optimizations + -O1 or higher). + +2000-09-06 Darin Adler + + * test/test-uri.c: (main): Added tests for URIs with "#" + characters in them. Not sure what "correct" is, so they are marked + with FIXME. + * libgnomevfs/gnome-vfs-uri.c: (gnome_vfs_uri_new): Removed + extraneous g_print. + +2000-09-05 Robin * Slomkowski + + * libgnomevfs/Makefile.am: made gnome-vfs-mimedb statically + link on Pavel's suggestion. This solves the make install + problem in a chrooted environment. + +2000-09-05 Mathieu Lacage + + * mime-type-capplet/nautilus-mime-type-capplet.c: + (populate_viewer_menu): initialize found_match to TRUE + to avoid a segfault in certain non-obvious cases. this + is a temporary hack waiting for bug 2766. + +2000-09-05 John Sullivan + + Wrote bugs for the last (for now) 18 unbugged FIXMEs. + + * mime-type-capplet/nautilus-mime-type-icon-entry.c: + (drag_data_get): + * modules/bzip2-method.c: (do_get_file_info): + * modules/extfs-method.c: + * modules/file-method.c: (do_create_symbolic_link): + * modules/ftp-method.c: (internal_get_file_info): + * modules/gconf-method.c: + * modules/gzip-method.c: (do_get_file_info): + * modules/http-method.c: (process_propfind_propstat): + * modules/translate-method.c: (tr_apply_default_mime_type), + (tr_handle_exec), (tr_uri_translate): + * test/test-shell.c: (do_info): + * test/test-uri.c: (main): + +2000-09-05 Martin Baulig + + * Makefile.am (SUBDIRS): Remove unconditional listing of the + mime-type-capplet, it is already contained in $(SUBDIRS_GNOME) for + the GNOME 1.x platform. + +2000-09-05 Maciej Stachowiak + + * libgnomevfs/gnome-vfs-mime-magic.c: Fixed spelling in a FIXME. + + * modules/ftp-method.c: (ls_to_file_info): Fixed another minor + formatting problem. + +2000-09-04 Mathieu Lacage + + Add bugs to bugzilla.eazel.com for FIXMEs... + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_get_default_action_type), + (gnome_vfs_mime_get_default_application), + (get_executable_name_from_command_string): + * libgnomevfs/gnome-vfs-mime-info.c: (gnome_vfs_mime_get_value), + (gnome_vfs_get_registered_mime_types): + * libgnomevfs/gnome-vfs-mime-magic.c: + * libgnomevfs/gnome-vfs-uri.c: + * mime-type-capplet/nautilus-mime-type-capplet.c: + (mime_list_selected_row_callback), (init_mime_capplet), + (populate_viewer_menu), (delete_mime_clicked), (pixmap_file): + +2000-09-03 Mathieu Lacage + + * libgnomevfs/gnome-vfs-mime-info.c: (write_back_keys_user_file): + fix evil bug. forgot to fclose the file opened for user.keys + file. All bugs are evil. I hate bugs. I HATE THEM. + +2000-09-03 Mathieu Lacage + + * test/test-mime-info.c: (main): change directory to folder + as in gnome-vfs.keys. bad boy who did not updated the tests + and changed the data. + +2000-09-03 Maciej Stachowiak + + * modules/ftp-method.c: Reformat to match gnome-vfs coding style. + +2000-09-03 Maciej Stachowiak + + * libgnomevfs-pthread/gnome-vfs-job.c: (execute_set_file_info): + * modules/file-method.c: (find_trash_directory): + + Added bug numbers to FIXMEs. + +2000-09-03 Pavel Cisler + + * libgnomevfs/gnome-vfs-types.h: + * libgnomevfs/gnome-vfs-xfer.c: (init_progress), (copy_directory), + (copy_items), (move_items), (link_items): + Add a flag to the xfer progress indicating a top-level item to + allow triggering metadata copies. + + * libgnomevfs-pthread/gnome-vfs-job.c: + (execute_create_symbolic_link): + * libgnomevfs/gnome-vfs-mime-info.c: (gnome_vfs_mime_set_value): + * libgnomevfs/gnome-vfs-uri.c: (gnome_vfs_uri_new): + * mime-type-capplet/nautilus-mime-type-capplet.c: + (populate_viewer_menu): + * modules/translate-method.c: (tr_uri_translate): + * test/test-uri.c: (test_uri_host_port): + Fix a bunch of uninitialized variables that Michael Meeks found. + +2000-09-02 Mathieu Lacage + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_get_default_component), + (gnome_vfs_mime_do_short_list_processing), + (gnome_vfs_mime_get_short_list_components): fix small typo + but evil bug. + +2000-09-01 Mathieu Lacage + + * mime-type-capplet/nautilus-mime-type-capplet.c: (main), + (init_mime_capplet), (populate_mime_list), + (create_mime_list_and_scroller): + remove debugging output. fix many run-time warnings. + Now, can go into fixing real bugs. + +2000-09-01 Mathieu Lacage + + * libgnomevfs/gnome-vfs-init.c: (gnome_vfs_init): + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_get_default_action_without_fallback), + (gnome_vfs_mime_get_default_component), (join_str_list), + (gnome_vfs_mime_get_short_list_components), + (gnome_vfs_mime_get_all_components), + (gnome_vfs_mime_id_in_component_list), + (gnome_vfs_mime_id_list_from_component_list), + (gnome_vfs_mime_remove_component_from_list), + (gnome_vfs_mime_action_free), (gnome_vfs_mime_component_list_free), + (OAF_ServerInfoList_to_ServerInfo_g_list): + * libgnomevfs/gnome-vfs-mime-handlers.h: + * test/test-mime-handlers-set.c: (main): + * test/test-mime-handlers.c: (print_component), (print_action), + (print_component_list), (main): + remove test on OAF compile. + + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_get_default_application): fix bug: we were passing + a NULL to some subroutine. + + * mime-type-capplet/nautilus-mime-type-capplet.c: + (init_mime_capplet), (nautilus_mime_type_capplet_update_info), + (populate_mime_list), (create_mime_list_and_scroller): + fix misc warning at runtime. add debugging output. will remove soon. + + * test/.cvsignore: chuuut. + +2000-09-01 Christopher James Lahey + + * libgnomevfs/gnome-vfs-mime-handlers.h: Removed #ifdef USING_OAF. + +2000-09-01 Ian McKellar + + * test/.cvsignore: + Added new binaries to .cvsignore. + +2000-09-01 Ian McKellar + + * libgnomevfs/gnome-vfs-context.c: + (gnome_vfs_context_emit_message): + The fallback error message that is sent if context==NULL is now sent + to stderr rather than stdout. It was confusing test programs before. + + * modules/http-method.c: (create_handle): + Don't emit message if context==NULL + + * test/Makefile.am: + Added some test programs... + + * test/test-dirop.c: + New test to test make_directory and remove_directory. + + * test/test-unlink.c: + New test to test unlink. + + * test/test-info.c: (main): + Now returns a result so get_file_info's success can be tested from + shell scripts. + + * test/test-sync-create.c: (main): + * test/test-sync-write.c: (main): + Removed superflous debugging info. + + * test/test-sync.c: (main): + Cleaned up code a bit so this is 8 bit clean. + + * test/test-remote: + A shell script that calls many of the test programs to check that + a filesystem behaves in a sensible fasion. Its geared towards + testing remote filesystems such as FTP and WebDAV. + +2000-09-01 Pavel Cisler + + Bugzilla task 2186 -- Move/Copy/Link from multiple directories fails. + Reworked the copy engine to use lists of URIs instead of pairs of + directory URIs and file name lists. + + * libgnomevfs/gnome-vfs-xfer.c: (gnome_vfs_visit_list), + (count_items_and_size), (directory_add_items_and_size), + (handle_name_conflicts), (copy_file_data), (xfer_open_source), + (xfer_create_target), (copy_file), (copy_directory), (copy_items), + (move_items), (link_items), (gnome_vfs_xfer_empty_trash), + (gnome_vfs_xfer_delete_items_common), + (gnome_vfs_xfer_delete_items), + (gnome_vfs_new_directory_with_unique_name), + (gnome_vfs_xfer_uri_internal), (gnome_vfs_xfer_private), + (gnome_vfs_xfer_uri_list), (gnome_vfs_xfer_uri): + Completely reworked to support the new URI list APIs + + * libgnomevfs/gnome-vfs-xfer.h: + * libgnomevfs/gnome-vfs-xfer.c: + Renamed xfer calls to represent new APIs better. + + * libgnomevfs/gnome-vfs-async-ops.h: + * libgnomevfs/gnome-vfs-backend.c: (gnome_vfs_async_xfer): + * libgnomevfs/gnome-vfs-cancellable-ops.h: + * libgnomevfs/gnome-vfs-uri.c: + Update to support new APIs. + Got rid of copy_string_list that is no longer needed. + + * idl/gnome-vfs-slave.idl: + * libgnomevfs-corba/gnome-vfs-async-ops.c: + (corba_gnome_vfs_async_xfer): + * libgnomevfs-corba/gnome-vfs-slave.c: (file_list_to_uri_g_list), + (impl_Request_xfer): + Update corba backend for new xfer APIs. + + * libgnomevfs-pthread/gnome-vfs-async-ops.c: + (pthread_gnome_vfs_async_xfer): + * libgnomevfs-pthread/gnome-vfs-job.c: (execute_load_directory), + (execute_xfer): + * libgnomevfs-pthread/gnome-vfs-job.h: + Updated pthread backend to support new xfer APIs. + Fixed some leaks. + + * test/test-xfer.c: (main): + Update tests to use new APIs. + + * libgnomevfs/gnome-vfs-xfer.c: + Fixed FIXME 1193. + + * libgnomevfs/gnome-vfs-xfer.c: + (g_string_list_deep_copy): + No longer needed. + + * libgnomevfs/gnome-vfs-ops.c: + * libgnomevfs/gnome-vfs-ops.h: + * libgnomevfs/gnome-vfs-xfer.c: + (gnome_vfs_uri_exists): + Added a new convenience call. + Fixes FIXME 1201. + + * libgnomevfs/gnome-vfs-utils.h: + Fixed some spelling. + +2000-09-01 Maciej Stachowiak + + * po/Makefile.in.in: removed since gettextize auto-generates it. + + * configure.in: Turn off libefs more thoroughly. + +2000-08-31 Robey Pointer + + * libgnomevfs/gnome-vfs-init.c: (gnome_vfs_initialized): + * libgnomevfs/gnome-vfs-init.h: + + Add gnome_vfs_initialized so you can check if gnome-vfs has been + initialized already, without it whining. + +2000-08-31 Gene Z. Ragan + + * libgnomevfs/gnome-vfs-backend.c: (gnome_vfs_backend_loadinit), + (gnome_vfs_backend_shutdown), (func_lookup): + * libgnomevfs/gnome-vfs-init.c: (gnome_vfs_init): + Checking on some Pavel code cleanup. + +2000-08-31 John Sullivan + + Work towards bug 1037 (use "folder" rather than "directory" + consistently) + + * data/mime/gnome-vfs.keys: Change "directory" to "folder" + and "web directory" to "web folder" + +2000-08-31 Gene Z. Ragan + + * Makefile.am: + Added capplet to sub-directories to fix tinderbox build. + +2000-08-31 Ramiro Estrugo + + * libgnomevfs/gnome-vfs-mime-info.c: + (gnome_vfs_mime_info_shutdown): + Fix two typos. The same 2 hash tables were being freed twice. + Also make the hash tables NULL after freeing them. + +2000-08-31 Martin Baulig + + * modules/Makefile.am (INCLUDES): Added $(GLIB_CFLAGS). + * libgnomevfs-pthread/Makefile.am (INCLUDES): Likewise. + * libgnomevfs-corba/Makefile.am (INCLUDES): Likewise. + + * configure.in: Don't modify CFLAGS but set VFS_CLFAGS instead. + Otherwise CFLAGS gets longer every time config.status is run. + * */Makefile.am (INCLUDES): Add $(VFS_CFLAGS). + + * configure.in: Don't put -Werror into CFLAGS but into WERROR + and AC_SUBST it. Some configure checks don't work with -Werror. + * */Makefile.am (INCLUDES): Add $(WERROR). + + * test/.cvsignore: Added test-mime-info. + +2000-08-31 Martin Baulig + + * libgnomevfs-pthread/gnome-vfs-job-slave.c + (gnome_vfs_thread_backend_shutdown): Use g_main_iteration() instead + of gtk_main_iteration_do() if `GNOME_PLATFORM_VERSION >= 1095000' + (as preprocessor conditional). + + * libgnomevfs/gnome-vfs-private-utils.c + (gnome_vfs_i18n_get_language_list): New function. This calls + gnome_i18n_get_language_list() if `GNOME_PLATFORM_VERSION < 1095000' + and g_i18n_get_language_list() otherwise. + + * libgnomevfs/gnome-vfs-mime-info.c: Remove the + includes which were previously required for gnome_i18n_get_language_list. + (gnome_vfs_mime_init): Use gnome_vfs_i18n_get_language_list() instead + of gnome_i18n_get_language_list(). + + * libgnomevfs/gnome-vfs-application-registry.c: Remove the + includes which were previously required for gnome_i18n_get_language_list. + (gnome_vfs_application_registry_init): Use + gnome_vfs_i18n_get_language_list() instead of + gnome_i18n_get_language_list(). + +2000-08-31 Martin Baulig + + * configure.in: Only check for GNOME if we're on the GNOME 1.2 + platform. + (VFS_GNOME_CFLAGS, VFS_GNOMEUI_CFLAGS, VFS_CAPPLET_CFLAGS): Added. + (VFS_GNOME_LIBS, VFS_GNOMEUI_LIBS, VFS_CAPPLET_LIBS): Added. + For the GNOME 1.2 platform, they contain the appropriate GNOME cflags + and libs (set with `gnome-config --cflags/--libs'); for the GNOME 2 + platform they only contain the appropriate GLIB cflags and libs + (set with `glib-config-2.0 --cflags/--libs'). + (VFS_GLIB_CONFIG): Added. This is either `glib-config' for the GNOME 1.2 + platform or `glib-config-2.0' for the GNOME 2 platform. + + * gnome-vfs-config.in: New file. Template for gnome-vfs-config. + We can't use gnome-config for the GNOME 2 platform since gnome-vfs + doesn't depend on gnome-libs on it; this gnome-vfs-config script + works for both platforms, however using gnome-config may be saner + for the GNOME 1.2 one. + * Makefile.am: Create a gnome-vfs-config script. + * .cvsignore: Added gnome-vfs-config. + +2000-08-31 Martin Baulig + + * acconfig.h (GNOME_PLATFORM_VERSION): #define this in config.h + to be a number constant which is currently 1002000 for the GNOME 1.2.x + platform. When compiling for the GNOME 2 platform, we patch + configure.in to set this to 1095000. + + * configure.in (PLATFORM_GNOME_2): New automake conditional; true + if `GNOME_PLATFORM_VERSION >= 1095000' (you need to patch configure.in + to make this happen, ie. when compiling for gnome-libs HEAD). + + * acinclude.m4: New file. + (AM_GNOME_SIZE_T, AM_GNOME_OFF_T): New autoconf macros which provide + better checks for `size_t' and `off_t'; they also work when they're + typedef'ed in and not #defined. + * configure.in: Use AM_GNOME_SIZE_T and AM_GNOME_OFF_T. + + * Makefile.am: Disable the mime-type-capplet and test subdirectories + if we're compiling for the GNOME 2 platform. + +2000-08-31 Mathieu Lacage + + fixes bugs 1119 and 1839 + + * data/mime/gnome-vfs.keys: add a mime type for testing. + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_get_default_action_type), + (gnome_vfs_mime_edit_user_file_full), + (gnome_vfs_mime_add_extension), (gnome_vfs_mime_remove_extension): + update to API changes below. move saving code to gnome-vfs-mime-info.c + * libgnomevfs/gnome-vfs-mime-info.c: (does_string_contains_caps), + (context_new), (context_destroy_and_unlink), (language_level), + (context_add_key), (load_mime_type_info_from), + (load_mime_list_info_from), (mime_info_load), (mime_list_load), + (load_mime_type_info), (gnome_vfs_mime_init), + (gnome_vfs_mime_info_clear), (gnome_vfs_mime_info_shutdown), + (gnome_vfs_mime_freeze), (gnome_vfs_mime_thaw), + (gnome_vfs_mime_set_value), (gnome_vfs_mime_get_value), + (gnome_vfs_mime_keys_list_free), (gnome_vfs_mime_get_key_list), + (gnome_vfs_mime_get_program), (gnome_vfs_mime_get_program_name), + (gnome_vfs_mime_get_description), (str_cmp_callback), + (gnome_vfs_mime_get_extensions_list), + (gnome_vfs_mime_get_extensions_string), + (gnome_vfs_mime_get_extensions_pretty_string), + (gnome_vfs_mime_extensions_list_free), (gnome_vfs_mime_get_test), + (gnome_vfs_mime_get_composetyped), + (gnome_vfs_mime_get_copiousoutput), + (gnome_vfs_mime_get_needsterminal), (get_key_name), + (gnome_vfs_get_registered_mime_types), + (gnome_vfs_mime_registered_mime_type_list_free), + (gnome_vfs_mime_set_registered_type_key), + (write_back_mime_user_file_context_callback), + (write_back_mime_user_file_callback), (write_back_mime_user_file), + (write_back_keys_user_file_context_callback), + (write_back_keys_user_file_callback), (write_back_keys_user_file): + Basically, make it work. update copyright. + * libgnomevfs/gnome-vfs-mime-info.h: change some API. + * mime-type-capplet/nautilus-mime-type-capplet.c: update to new API. + (nautilus_mime_type_capplet_update_info), (populate_mime_list): + * test/Makefile.am: add tests. + * test/test-mime-info.c: (main): actual tests. + +Wed Aug 30 22:51:47 2000 George Lebl + + * libgnomevfs/gnome-vfs-handle.c, + libgnomevfs/gnome-vfs-mime-handlers.c, libgnomevfs/gnome-vfs-mime.c: + Remove the includes as they are not used and they mess + with compilation with gnome-libs2 (this change is completely + neutral otherwise) + +2000-08-30 Darin Adler + + * libgnomevfs/gnome-vfs-utils.h: + * libgnomevfs/gnome-vfs-utils.c: + (gnome_vfs_escape_slashes): Moved this function in here from Nautilus. + Two advantages: 1) It can be used by other programs. 2) It can share + code with all the other escaping functions. + + * test/.cvsignore: Ignore the test-sync-create file. + +2000-08-29 Ian McKellar + + * modules/http-method.c: (make_request), (do_create): + The create method now attempts to create a zero-length file as part + of the opening process. This will allow errors to be detected. Create + creates a zero-length file with the standard unix semantics anyway. + + * test/Makefile.am: + * test/test-sync-create.c: (show_result), (main): + Added a test-sync-create to allow testing of the create method. + +2000-08-29 Ian McKellar + + * modules/http-method.c: (process_propfind_response): + Fixed bug 2525 - host and port are now ignored in href comparisons + in the WebDAV PROPFIND code. + +2000-08-29 Ian McKellar + + * modules/http-method.c: (http_handle_close), (do_read): + Fixed bug 2524 - extra debugging output removed. + +2000-08-28 Gene Z. Ragan + + * libgnomevfs/gnome-vfs-uri.c: (gnome_vfs_uri_new): + Pavel here. + Refactored a bit making it more beautiful. + +2000-08-28 Robin * Slomkowski + + * gnome-vfs.spec.in: fixed config file globs + +2000-08-28 John Sullivan + + * data/mime/gnome-vfs.keys: + Added application/x-palm-database, reported by a + Nautilus user. + +2000-08-27 Alastair McKinstry + + * ga.po: Added Irish translation. + +2000-08-25 John Sullivan + + Fixed bug 1388 (some MIME types have no description) + + * data/mime/gnome-vfs.mime: + * data/mime/gnome-vfs.keys: + Added descriptions for all un-descriptioned MIME types + from gnome-vfs.mime and mime-magic. The check-mime + script now finds no problems. Also added a couple of + missing MIME types that were reported by Nautilus users. + +2000-08-25 Robin * Slomkowski + + * modules/Makefile.am: added efs-method.c efs-method.h + forgotten files for make dist + +2000-08-25 John Sullivan + + Fixed bug 2311 (sort by date should put most recent dates first). + Also made the same change for size. + Also fixed some bugs in trash-directory locating, and added + testing code for this. + + * libgnomevfs/gnome-vfs-file-info.c: + (gnome_vfs_file_info_compare_for_sort): Added comment clarifying + that the sort order should be the natural order for each type, + not necessarily strict "small to large". Then changed size + and date orderings to go the opposite way. + * modules/file-method.c: (find_trash_directory): Fixed a couple + of problems Darin and I discovered that involved trying to + find Trash on "/". + * test/test-shell.c: (do_findtrash), (main): Added findtrash + command to test shell, and made it put the prompt on a new + line instead of appending it to the most recent output. + +Fri Aug 25 09:15:15 2000 Dietmar Maurer + + * modules/efs-method.c: minor changes for new libefs code. + +2000-08-24 Ali Abdin + + * modules/pipe-method.c: + (do_close): Removed a FIXME because Darin says (in a prior cvs-commit) + that we should destroy the handle even if it doesn't return + GNOME_VFS_OK. Besides - this functions always returns GNOME_VFS_OK (if + file_handle is allocated) + +2000-08-24 Darin Adler + + * libgnomevfs-pthread/gnome-vfs-job.c: + (dispatch_find_directory_callback): Fixed NULL-unref problem. + + * libgnomevfs/gnome-vfs-utils.h: + * libgnomevfs/gnome-vfs-utils.c: (istr_has_prefix), + (gnome_vfs_get_local_path_from_uri), + (gnome_vfs_get_uri_from_local_path): Added the local path + functions that are so widely used in Nautilus so they can be + used in medusa too, for example. + + * modules/file-method.c: (find_trash_directory): Fixed storage + leak, added FIXME about poor error handling. + +2000-08-24 Maciej Stachowiak + + * modules/Makefile.am: Disable efs module since it doesn't + compile any more with the latest changes to libefs. + +2000-08-23 Darin Adler + + * check-mime.pl: Added a check of the .applications file. + * data/mime/gnome-vfs.applications: Fixed a lingering use of + the old x-special/directory-webdav, which was superceded by + x-directory/webdav. + +2000-08-23 Darin Adler + + * data/mime/gnome-vfs.keys: Added a description for ksh scripts. + +2000-08-23 Darin Adler + + * libgnomevfs/gnome-vfs-handle.c: (gnome_vfs_handle_do_close): + * modules/bzip2-method.c: (do_close): + * modules/gzip-method.c: (do_close): + Removed FIXMEs about close behavior. It's now clear that the + correct behavior on close is to always get rid of the handle, even + if the close returns a non-GNOME_VFS_OK result, which indicates a + failure of I/O, not necessarily of the close as a while. + + * check-mime.pl: Fixed a typo in a message. + +2000-08-22 John Sullivan + + * check-mime.pl: Fixed small bug that was reporting a + false out-of-order error for the first MIME type in + gnome-vfs.mime. + + * data/mime/gnome-vfs.keys, + * data/mime/gnome-vfs.mime: Fixed many of the problems + found by check-mime.pl. I didn't add descriptions for all + of the undescribed types yet because that will take a couple + of hours of research that I'd rather spend later. + +2000-08-21 Darin Adler + + * check-mime.pl: Added script to check if the MIME files have + certain desirable properties. There are 69 errors reported now, + and I bet John will fix them now that they are easy to spot. + +2000-08-21 John Sullivan + + More tweaks to match MIME identification problems + users have run into. + + * data/mime/gnome-vfs-mime-magic: + changed audio/midi to audio/x-midi to match .keys file + (and usage rules) + * data/mime/gnome-vfs.keys: Added descriptions for + application/x-smil, audio/x-it, and text/x-credits. + Also moved one entry that was out of order. + +2000-08-17 John Sullivan + + * data/mime/gnome-vfs.keys: + + Another missing description, for image/x-ico + +2000-08-17 John Sullivan + + Fixed bug 1724 (some MIME types without descriptions) + + * data/mime/gnome-vfs.keys: + + Added descriptions for the following MIME types that users + had run into: + + application/x-php + application/x-toutdoux + audio/x-mp3-playlist + image/vnd.dwg + text/abiword + +2000-08-14 Pavel Cisler + + * libgnomevfs/gnome-vfs-backend.c: + (gnome_vfs_async_find_directory): + Fix a crasher in the new gnome_vfs_async_find_directory. + +2000-08-13 Pavel Cisler + + * libgnomevfs-pthread/gnome-vfs-async-ops.c: + (pthread_gnome_vfs_async_find_directory): + * libgnomevfs-pthread/gnome-vfs-job.c: + (dispatch_get_file_info_callback), + (dispatch_find_directory_callback), (dispatch_job_callback), + (execute_find_directory), (gnome_vfs_job_execute): + * libgnomevfs-pthread/gnome-vfs-job.h: + * libgnomevfs/gnome-vfs-async-ops.h: + * libgnomevfs/gnome-vfs-backend.c: + (report_failure_get_file_info_callback), + (report_failure_get_file_info), (gnome_vfs_async_get_file_info), + (report_faliure_find_directory_callback), + (report_failure_find_directory), (gnome_vfs_async_find_directory): + * libgnomevfs/gnome-vfs-types.h: + + Add async version of gnome_vfs_find_directory. pthread backend only for now. + +2000-08-12 Robin * Slomkowski + + * configure.in: just bumped the version on HEAD + +2000-08-12 Ali Abdin + + * modules/Makefile.am: + * libgnomevfs-corba/Makefile.am: + Actually remove the linking to gnome-libs from the Makefile's now + + * libgnomevfs-pthread/gnome-vfs-job-slave.c: + Replaced include of to + +2000-08-11 Ettore Perazzoli + + * configure.in: Generate `devel-docs' first. + +2000-08-11 Dan Winship + + * data/mime/gnome-vfs.applications: gnumeric can open Excel files. + + * data/mime/gnome-vfs.keys: Excel files can be opened by gnumeric. + +2000-08-11 Ali Abdin + + * libgnomevfs/gnome-vfs-mime-snif-buffer.h: + * libgnomevfs/gnome-vfs-application-registry.h: + Remove unneeded #include (libgnome dependency) + +2000-08-10 Darin Adler + + * data/mime/gnome-vfs.keys: Fix the default for directories. It + was supposed to be the icon view, but had "ntl" instead of "nautilus". + + * test/.cvsignore: Ignore the new file generated (the test Pavel added). + +2000-08-10 Maciej Stachowiak + + * libgnomevfs-corba/gnome-vfs-corba.c (gnome_vfs_corba_init): + removed gratuitous call to gnome_init_with_popt_table + + * modules/efs-method.c: Removed gratuitous include of , + replaced with + +2000-08-10 Darin Adler + + * libgnomevfs/gnome-vfs-gen-mimedb.c: (main): + * modules/file-method.c: (do_find_directory): Fixed backwards use + of access. Access's result has the opposite sense of + g_file_exists. + +2000-08-10 Ali Abdin + + * libgnomevfs/gnome-vfs-gen-mimedb.c: + (main): + Replace gnomelib_init with gnome_vfs_init and replace + Replace g_file_exists with access(,F_OK) + + Remove #include of gnome-libs file + + * modules/file-method.c: + (do_find_directory): + Replace g_file_exists with access(,F_OK) + (do_set_file_info): Remove usage of g_concat_dir_and_file (to avoid + gnome-libs dependency). + + Also #include + + * libgnomevfs-corba.c: + #include + +2000-08-10 Maciej Stachowiak + + * libgnomevfs/gnome-vfs-uri.c (parse_uri_substring, + gnome_vfs_uri_new): Tolerate fragment identifiers by just ignoring + them; differentiate them from the gnome-vfs method chaning syntax + by checking for a colon past the pound sign. + +Wed Aug 09 23:26:17 2000 George Lebl + + * libgnomevfs/gnome-vfs-application-registry.[ch] + (application_info_load) (gnome_vfs_application_registry_init) + (gnome_vfs_application_registry_sync) + libgnomevfs/gnome-vfs-mime-handlers.c + (gnome_vfs_mime_edit_user_file_full) + libgnomevfs/gnome-vfs-mime-info.[ch] (mime_info_load) + (mime_list_load) (gnome_vfs_mime_init) (write_registered_mime_data) + libgnomevfs/gnome-vfs-mime-magic.h + libgnomevfs/gnome-vfs-mime-private.h + libgnomevfs/gnome-vfs-mime.[ch] (mime_load) (mime_init) + libgnomevfs/gnome-vfs.h, libgnomevfs/gnome-vfs-private.h: + Remove all the simple gnome dependencies. All the gnome-utils + dependencies which can be replaced by about the same amount of + non-gnome code. Also replace all BEGIN/END_GNOME_DECLS with the + standard extern "C" foo. + + * libgnomevfs/gnome-vfs-private.h: Add NLS defines N_ and _ because + those are handled by gnome normally. Also this uses the "private" + defines from gnome-i18nP.h which is apparently the way to do this + inside the library. + +2000-08-09 Robin * Slomkowski + + * gnome-vfs.spec.in: should work again + +2000-08-09 Pavel Cisler + + * modules/file-method.c: (find_trash_in_one_hierarchy_level), + (find_trash_in_hierarchy), (try_creating_trash_in), + (find_trash_directory), (do_find_directory): + Add checks for cancellation at every level of trash lookup. + Make it so that we start looking a good place for a new directory + right in the top disk level rather than on level deeper. + Check if entries returned from the cached Trash list still exist + when find_if_needed is on. If they no longer do, flush them from the + list. + +2000-08-09 Ali Abdin + + * modules/extfs-method.c: + * modules/pipe-method.c: + Remove gratuitous gnome-libs dependency + + * modules/pipe-method.c: + #include + +2000-08-09 Ali Abdin + + * libgnomevfs-corba/gnome-vfs-slave.c: + Remove gratiutous gnome-libs dependency. + +2000-08-09 Ali Abdin + + * libgnomevfs/gnome-vfs-modules-shared.c, + * libgnomevfs/gnome-vfs-mime-magic.c: + Remove gratiutous gnome-libs dependency. + +2000-08-09 Pavel Cisler + + * modules/file-method.c: (append_trash_path), + (find_trash_in_one_hierarchy_level), (find_trash_in_hierarchy), + (try_creating_trash_in), (find_trash_directory), + (do_find_directory): + Fix a ton of bugs in the new find directory calls. + + * test/Makefile.am: + * test/test-find-directory.c: + Mini test tool for the gnome_vfs_find_directory call. + +2000-08-09 Pavel Cisler + + * libgnomevfs/gnome-vfs-cancellable-ops.c: + (gnome_vfs_find_directory_cancellable): + * libgnomevfs/gnome-vfs-cancellable-ops.h: + * libgnomevfs/gnome-vfs-find-directory.c: + (gnome_vfs_find_directory): + * libgnomevfs/gnome-vfs-find-directory.h: + * libgnomevfs/gnome-vfs-private-types.h: + * modules/efs-method.c: (do_find_directory): + * modules/extfs-method.c: (do_find_directory): + * modules/translate-method.c: (tr_do_find_directory): + Add a find_if_needed parameter to find_directory calls. + + * libgnomevfs/gnome-vfs-utils.c: (gnome_vfs_list_deep_free): + * libgnomevfs/gnome-vfs-utils.h: + * libgnomevfs/gnome-vfs-xfer.c: (gnome_vfs_xfer_uri_internal): + Add a new utility call, moving it from gnome-vfs-xfer.c so I + can share it with others. + + * modules/file-method.c: (GET_PATH_MAX), (get_path_from_uri), + (get_base_from_uri), (append_to_path), (append_trash_path), + (find_trash_in_one_hierarchy_level), (find_trash_in_hierarchy), + (match_trash_item_by_device_id), (try_creating_trash_in), + (find_trash_directory), (do_find_directory), (do_set_file_info): + Work in progress on finding/creating Trash on non-home volumes. + +Tue Aug 08 23:18:49 2000 George Lebl + + * libgnomevfs/Makefile.am, + libgnomevfs/gnome-vfs-application-registry.[ch]: + A new application registry. The parsing is based upon + mime-info. The interface completely hides any structures + and is based entierly on querying string keys. Handles + user settings as a delta against the system settings. Also + adds mime_types list support to the registry instead of this + being read from the keys file. + + * libgnomevfs/gnome-vfs-mime-handlers.[ch] + (gnome_vfs_mime_get_default_application) + (gnome_vfs_mime_get_short_list_applications) + (gnome_vfs_mime_get_all_applications) + (gnome_vfs_mime_extend_all_applications) + (gnome_vfs_mime_remove_from_all_applications) + (gnome_vfs_mime_application_new_from_id) + (application_known_to_be_nonexistent): + Use the application registry API internally. Remove the + gnome_vfs_mime_define_application call as it doesn't + make any sesnse any more and is replaced by an application + registry call. The all_applications calls now use the + registry api for all their work. + + * libgnomevfs/gnome-vfs-mime-info.c (load_mime_type_info_from): + Fix a bug where comments would only be ignored on the first + line which would add nonsense mime types if comments were + elsewhere in the file. + + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.c + (add_new_application) + test/test-mime-handlers-set.c (main): + Use the application registry for adding new applications + + * data/mime/Makefile.am, data/mime/gnome-vfs.keys, + data/mime/gnome-vfs.applications, + data/mime/application-registry-hack.keys: + Remove the registry hack stuff, remove all_applications + stuff from gnome-vfs.keys and add the applications from + the registry hack to gnome-vfs.applications including + the mime types they read. + +2000-08-08 Maciej Stachowiak + + * mime-type-capplet/nautilus-mime-type-capplet.c: Move include of + sys/types.h above include of regex.h to fix building on + FreeBSD. Fix from Bill Huey . + +2000-08-08 Maciej Stachowiak + + * acconfig.h: + * configure.in: + * modules/bzip2-method.c + (bzip2_method_handle_init_for_decompress), + (bzip2_method_handle_init_for_compress), (flush_write), (do_read), + (do_write): + + Handle both bzip2 1.0, which adds BZ2_ to the front of all + function names, and the older version. Problem reported by Bill + Huey . + +2000-08-08 Maciej Stachowiak + + * libgnomevfs/gnome-vfs-parse-ls.c (gnome_vfs_parse_ls_lga): Avoid + a warning and potential bug on systems (such as FreeBSD) where the + st_nlink field of struct stat is unsigned. Problem reported by Bill + Huey . + +2000-08-08 Robin * Slomkowski + + * mime-type-capplet/Makefile.am: added + nautilus-mime-type-icon-entry.h as it was forgotten + +2000-08-09 Ian McKellar + + * modules/http-method.c: (make_propfind_request): + Fixed another WebDAV directory listing bug. If the current URI + contained escaped characters (%20 for example) it would not be + culled. Now it is. + +2000-08-09 Ian McKellar + + * modules/http-method.c: (process_propfind_response): + Fixed a bug where the current directory could show up in WebDAV + directory listings. + +2000-08-08 John Sullivan + + * data/mime/gnome-vfs.keys: + Added description for application/x-java-byte-code; changed + "search results virtual directory" to "search results". + +2000-08-07 Maciej Stachowiak + + * data/mime/gnome-vfs.keys: + * libgnomevfs/gnome-vfs-mime.c: (gnome_vfs_get_file_mime_type): + * libgnomevfs/gnome-vfs-module-shared.c: + (gnome_vfs_mime_type_from_mode), (gnome_vfs_get_special_mime_type): + * modules/extfs-method.c: (do_get_file_info): + * modules/ftp-method.c: (do_get_file_info): + * modules/gconf-method.c: (set_mime_type_dir): + * modules/http-method.c: (process_propfind_propstat): + + Renamedirectory mime types: + + x-special/directory => x-directory/normal + x-special/webdav-directory => x-directory/webdav + x-special/virtual-directory => x-directory/search + + +2000-08-07 Maciej Stachowiak + + * CVSVERSION: New file, used to detect whether we are configuring + a cvs version or a release tarball. + + * configure.in: Default -Werror to off when configuring a release + tarball, and to on when configuring a cvs version. + +2000-08-07 Maciej Stachowiak + + * test/test-escape.c (main): Fix to match new escaping logic for + paths. + +2000-08-07 Darin Adler + + * libgnomevfs/gnome-vfs-uri.c: (gnome_vfs_uri_has_parent): + Fixed so it matches the _get_parent function by just calling + _get_parent. It would be hard to get the corresponding result + otherwise. Someone performance-obsessed could move the common + code out into a separate function if they like. + + * test/test-uri.c: (test_uri_has_parent), (main): + Added a test of gnome_vfs_uri_has_parent to this tool. + + * modules/http-method.c: (make_propfind_request): + Changed a g_warning to a g_message. Maybe yakk will change it + back or something, but it happens too often to be a drop-into- + the-debugger warning. + +2000-08-07 Rebecca Schulman + + * libgnomevfs/gnome-vfs-result.c: + * libgnomevfs/gnome-vfs-types.h: + added a new error code GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE + +2000-08-07 Maciej Stachowiak + + * libgnomevfs/gnome-vfs-utils.c: Do not escape `?', `&', or `=' in + paths, to avoid messing up http queries. + +2000-08-08 Ian McKellar + + * modules/http-method.c: (process_propfind_propstat), + (process_propfind_response): + Fixed a memory leak in WebDAV PROPFIND response parsing. + +Sun Aug 06 15:10:01 2000 George Lebl + + * libgnomevfs/gnome-vfs-mime-info.c (load_mime_type_info_from) + (load_mime_list_info_from) (gnome_vfs_mime_init): Be more correct + in function prototypes + (gnome_vfs_mime_init): gnome_i18n_get_language_list returns a + "constant" list. So make a copy before inverting it. + + * bzip2-method.c, gzip-method.c: #include to make it + compile on alpha + +2000-08-07 Ian McKellar + + * modules/http-method.c: (process_propfind_propstat), + (do_get_file_info): + Fixed a bug that affected Xythos interoperability. + +2000-08-06 Ian McKellar + + * modules/ftp-method.c: (do_get_file_info): + Changed the do_get_file_info behaviour to be more portable. I believe + this resolves bug #1981. + +2000-08-05 Michael K. Fleming + + * libgnomevfs/gnome-vfs-uri.c: (split_toplevel_uri), + (split_toplevel_uri_old), (uri_strspn_to), (split_toplevel_uri): + * test/test-uri.c: (test_uri_part), (test_uri_host_port), (main): + + Re-implemented split_toplevel_uri to fix some parsing bugs in the old one. + (Most signficantly, 'http://localhost:80' would be parsed as + hostname 'localhost:80' rather than hostname 'localhost' port '80') + + ****Note that the new code is necessarally not bug-for-bug compatible with + the original implementation, and therefore may expose bugs in existing + applications!**** + + Added new test cases for URI parsing. + + The old split_toplevel_uri code is ifdef'd out. If you disable + NO_MKF_DEBUG, you can get warnings when a differences between the old + version and the new version is encountered. Of course, the code in this + block should be removed before the next release. + +2000-08-04 John Sullivan + + * data/mime/gnome-vfs-mime-magic: changed text/rtf to + application/rtf to match both the .keys file and reality. + + * data/mime/gnome-vfs.keys: added description for + audio/x-riff. + +2000-08-04 Robey Pointer + + * libgnomevfs/gnome-vfs-utils.c: + (gnome_vfs_escape_string_internal), (gnome_vfs_escape_path_string), + (gnome_vfs_escape_host_and_path_string): + * libgnomevfs/gnome-vfs-utils.h: + + Add an _escape_host_and_path_string() call to cope intelligently + with uri's that have a host:port section before the path. + +2000-08-05 Ian McKellar + + * modules/http-method.c: (process_propfind_response), + (do_open_directory), (do_get_file_info): + Make open_directory and do_get_file_info try http://foo/bar/ if + http://foo/bar fails with a file not found error. See: + http://bugzilla.eazel.com/show_bug.cgi?id=1904 + +2000-08-04 Darin Adler + + * libgnomevfs/gnome-vfs-mime.c: (add_to_key): + Added a workaround for a bug in Solaris regcomp. + +2000-08-03 Seth Nickell + + * libgnomevfs/gnome-vfs-xfer.c: (count_items_and_size), + (link_items), (gnome_vfs_xfer_delete_items), + (gnome_vfs_xfer_uri_internal): + A rewrite of the code that CVS (or me?) lost for some strange bizarre reason... + Adds symbolic link abilities to gnome-vfs-xfer. + +2000-08-03 Ramiro Estrugo + + * data/mime/gnome-vfs.keys: + + Add the mozilal component as a content handler for + x-special/webdav-directory. Also move the gtkhtml web browser up + in the food chain. + +2000-08-03 John Sullivan + + * data/mime/gnome-vfs.keys: Added a couple of description-less + types that people had run into (image/x-xfig and application/x-compress). + Also removed one of the two different descriptions for image/x-xpixmap. + Also alphabetized the entries again -- someone changed some MIME + type names without re-alphabetizing. + +2000-08-03 Mathieu Lacage + + * libgnomevfs/gnome-vfs-mime-info.c: (gnome_vfs_mime_init): + remove FIXMEs for bug 796. + * libgnomevfs/gnome-vfs-mime.c: (mime_init): idem. + +2000-08-02 Pavel Cisler + + Seth forgot to check in changes Nautilus relies on and + unfortunately they are nowhere to be found on his machine. + This change will make Nautilus build again. Seth needs to check + in his missing changes to make symlink creation work properly. + + * libgnomevfs/gnome-vfs-types.h: + +2000-08-02 Gene Z. Ragan + + Fixed bug 1837, The icon in the action list item + should represent the item in the list. + + * mime-type-capplet/nautilus-mime-type-capplet.c: + (populate_mime_list): + Load icon and display based on action. + +2000-08-02 Darin Adler + + * libgnomevfs/gnome-vfs-module-shared.c: + (gnome_vfs_mime_type_from_mode), (gnome_vfs_get_special_mime_type): + Removed some old FIXMEs that were left after the bug was fixed. + +2000-08-02 Gene Z. Ragan + + Fixed bug 1836, Description list item icon wrong. + + * mime-type-capplet/nautilus-mime-type-capplet.c: + (populate_mime_list), (gdk_font_get_bold), + Set up proper and scaled description column icon. + + (capplet_gdk_pixbuf_scale_to_fit): + New function that scales an gdk-pixbuf to the requested + width and height. Copied from libnautilus. + +2000-08-01 Darin Adler + + * data/mime/gnome-vfs.keys: + Added description for "x-special/virtual-directory", which + will probably be renamed soon. + +2000-08-01 Ian McKellar + + * AUTHORS: + Updated ftp method info. + + * modules/http-method.c: (process_propfind_response), + (make_propfind_request), (do_read_directory): + Fixed the PROPFIND response parsing to handle Xythos servers + better. + +2000-07-30 ERDI Gergo + + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.c + (name_from_oaf_server_info): changed oaf_server_info_attr_lookup + calls to oaf_server_info_prop_lookup + +2000-07-28 Gene Z. Ragan + + * mime-type-capplet/nautilus-mime-type-capplet.c: + (init_mime_capplet), (pixmap_file), (gtk_widget_make_bold), + (gtk_widget_set_font), (gtk_style_set_font), (gdk_font_get_bold): + New function to set the font of a widget to bold. These were + borrowed from libnautilus-extensions. + +2000-07-28 Gene Z. Ragan + + * data/mime/gnome-vfs-mime-magic: + * data/mime/gnome-vfs.keys: + Added magic and mime type for GMC links. + application/x-gmc-link + +2000-07-27 Seth Nickell + + * libgnomevfs/gnome-vfs-file-info.h: + Added SYMLINK macros. + + * libgnomevfs/gnome-vfs-types.h: + Added GNOME_VFS_FILE_FLAGS_SYMLINK + + * modules/file-method.c: (get_stat_info): + Changed code around to properly stat and lstat, and use flags. + + * test/gnome-file-selection/gnome-file-selection.c: + (populate_callback): + * test/test-async-directory.c: (print_list): + * test/test-directory-visit.c: (directory_visit_callback): + * test/test-directory.c: (print_list): + Changed to use flags properly. + +2000-07-26 Gene Z. Ragan + + * data/mime/gnome-vfs-mime-magic: + * data/mime/gnome-vfs.keys: + Added mime magic and mime type key for application/x-nautilus-link + +2000-07-25 Mike Fleming + + * modules/translate-method.c: (tr_exec_open_child), + (tr_exec_pass_uri), (tr_exec_do_retain), (tr_handle_exec), + (tr_exec_init), (tr_exec_cleanup), (tr_args_parse), + (vfs_module_init), (vfs_module_shutdown): + + Added -retain option to translate's -exec mode + Fixed method-table initialization problem + +2000-07-25 Dan Winship + + * libgnomevfs/gnome-vfs-mime-handlers.c + (gnome_vfs_mime_get_default_action_without_fallback): New function + to get the default action for a MIME type without falling back to + its supertype if there is nothing available for the full type. + +2000-07-25 Darin Adler + + * modules/pipe-method.c: (mime_from_uri): + Handle the case where the URI is NULL (can happen with some bad + URIs that can't be unescaped). + +2000-07-25 John Sullivan + + Made async set_file_info pass back newly-retrieved + file info, since setting some info changes other + info (e.g., setting owner can change permissions). + + * libgnomevfs-pthread/gnome-vfs-async-ops.c: + (pthread_gnome_vfs_async_set_file_info): New options parameter + to use when getting file info, changed callback type. + * libgnomevfs-pthread/gnome-vfs-job.h: + Add get_file_info options field to request struct, and file_info & + get_file_info_result fields to notify struct. + * libgnomevfs-pthread/gnome-vfs-job.c: + (execute_set_file_info): Fetch file_info after setting. + (dispatch_set_file_info_callback): Pass to caller newly-fetched + file_info, or NULL if it couldn't be read. + + * libgnomevfs/gnome-vfs-async-ops.h: + Change signature of gnome_vfs_async_set_file_info to take options + for get_file and to use a GnomeVFSAsyncSetFileInfoCallback + * libgnomevfs/gnome-vfs-backend.c: + (report_failure_set_file_info_callback), + (report_failure_set_file_info): New functions that handle the new + intricacies of set_file_info failures. + (gnome_vfs_async_set_file_info): Updated for parameter changes. + * libgnomevfs/gnome-vfs-types.h: + Changed GnomeVFSAsyncCloseCallback to just a #define; + added new GnomeVFSAsyncSetFileInfoCallback + +2000-07-25 Pavel Cisler + + * modules/file-method.c: (do_find_directory), (do_check_same_fs): + Use lstat instead of stat to correctly treat symbolic links. + +2000-07-24 Fatih Demir + + * mime-type-capplet/nautilus-mime-type.desktop: Added the + Turkish desktop entries. + +2000-07-21 Mathieu Lacage + + Closes bug 1120, 1118, 1176 from buzilla.eazel.com + source incompatible change. Removes metadata support. + Basically, it changes the signature of all the functions which + had metadata support and removes one parameter. To take this change + into account, you basically need to remove one NULL parameter from + the calls which have changed. + + * idl/gnome-vfs-slave.idl: + * idl/gnome-vfs-types.idl: + * libgnomevfs-corba/gnome-vfs-async-ops.c: + (corba_gnome_vfs_async_get_file_info), + (corba_gnome_vfs_async_load_directory), + (corba_gnome_vfs_async_load_directory_uri): + * libgnomevfs-corba/gnome-vfs-slave-notify.c: + (impl_Notify_load_directory), (impl_Notify_get_file_info): + * libgnomevfs-corba/gnome-vfs-slave.c: (allocate_info_list), + (copy_file_info), (load_directory_not_sorted), + (load_directory_sorted), (impl_Request_get_file_info), + (impl_Request_load_directory): + * libgnomevfs-pthread/gnome-vfs-async-ops.c: + (pthread_gnome_vfs_async_get_file_info), + (pthread_gnome_vfs_async_load_directory), + (pthread_gnome_vfs_async_load_directory_uri): + * libgnomevfs-pthread/gnome-vfs-job.c: + (execute_load_directory_not_sorted), + (execute_load_directory_sorted), (execute_get_file_info), + (execute_load_directory): + * libgnomevfs-pthread/gnome-vfs-job.h: + * libgnomevfs/gnome-vfs-async-ops.h: + * libgnomevfs/gnome-vfs-backend.c: (gnome_vfs_async_get_file_info), + (gnome_vfs_async_load_directory_uri), + (gnome_vfs_async_load_directory): + * libgnomevfs/gnome-vfs-cancellable-ops.c: + (gnome_vfs_get_file_info_uri_cancellable), + (gnome_vfs_get_file_info_from_handle_cancellable): + * libgnomevfs/gnome-vfs-cancellable-ops.h: + * libgnomevfs/gnome-vfs-directory-list.c: + (gnome_vfs_directory_list_load), + (gnome_vfs_directory_list_load_from_uri): + * libgnomevfs/gnome-vfs-directory-list.h: + * libgnomevfs/gnome-vfs-directory.c: + (gnome_vfs_directory_handle_new), + (gnome_vfs_directory_handle_destroy), (open_from_uri), (open), + (gnome_vfs_directory_open), (gnome_vfs_directory_open_from_uri), + (directory_visit_internal), (gnome_vfs_directory_visit_uri), + (gnome_vfs_directory_visit), + (gnome_vfs_directory_visit_files_at_uri), + (gnome_vfs_directory_visit_files): + * libgnomevfs/gnome-vfs-directory.h: + * libgnomevfs/gnome-vfs-file-info.c: (gnome_vfs_file_info_clear), + (gnome_vfs_file_info_copy): + * libgnomevfs/gnome-vfs-file-info.h: + * libgnomevfs/gnome-vfs-handle.c: + (gnome_vfs_handle_do_get_file_info): + * libgnomevfs/gnome-vfs-handle.h: + * libgnomevfs/gnome-vfs-module-shared.c: + (gnome_vfs_get_special_mime_type): + * libgnomevfs/gnome-vfs-ops.c: (gnome_vfs_get_file_info), + (gnome_vfs_get_file_info_uri), + (gnome_vfs_get_file_info_from_handle): + * libgnomevfs/gnome-vfs-ops.h: + * libgnomevfs/gnome-vfs-private-types.h: + * libgnomevfs/gnome-vfs-types.h: + * libgnomevfs/gnome-vfs-xfer.c: (empty_directory), + (gnome_vfs_visit_list), (directory_add_items_and_size), + (handle_name_conflicts), (create_directory), (copy_directory), + (copy_items), (gnome_vfs_xfer_delete_items_common): + * modules/bzip2-method.c: (do_get_file_info): + * modules/efs-method.c: (do_open_directory), (do_get_file_info): + * modules/extfs-method.c: (do_open_directory), (do_get_file_info), + (do_get_file_info_from_handle): + * modules/file-method.c: (directory_handle_new), + (do_open_directory), (read_directory), (do_get_file_info), + (do_get_file_info_from_handle): + * modules/ftp-method.c: (internal_get_file_info), + (do_get_file_info), (do_open_directory): + * modules/gconf-method.c: (directory_handle_new), + (set_stat_info_value), (set_stat_info_dir), (do_open_directory), + (read_directory), (do_get_file_info), + (do_get_file_info_from_handle): + * modules/gzip-method.c: (do_get_file_info): + * modules/http-method.c: (do_open_directory), + (get_file_info_from_http_handle), (do_get_file_info), + (do_get_file_info_from_handle): + * modules/pipe-method.c: (do_get_file_info), + (do_get_file_info_from_handle): + * modules/translate-method.c: (tr_do_open_directory), + (tr_do_get_file_info), (tr_do_get_file_info_from_handle): + * test/gnome-file-selection/gnome-file-selection.c: + (start_populating): + * test/test-async-cancel.c: (wait_until_vfs_threads_gone), + (first_get_file_info), (test_get_file_info), + (test_load_directory_cancel): + * test/test-async-directory.c: (main): + * test/test-directory-visit.c: (main): + * test/test-directory.c: (main): + * test/test-info.c: (print_file_info), (main): + * test/test-shell.c: (do_ls), (validate_path), (get_regexp_name), + (do_info): + * test/test-symlinks.c: (deal_with_result): + +2000-07-19 Ali Abdin + + * modules/translate-method.c: (tr_apply_default_mime_type): + Modified to also apply default mime-type if the mime-type is + application/octet-stream + +2000-07-19 Darin Adler + + * libgnomevfs/gnome-vfs-uri.c: (get_method_string): Schemes are + not case-sensitive according to the RFC, so make them all + lower-case with g_strdown when we parse. + (gnome_vfs_uri_get_parent): Change logic so that URIs with no "/" + have no parent. + + * test/test-uri.c: (test_uri_parent): Added a function for testing + gnome_vfs_uri_get_parent. + (main): Moved "FILE:" test out of the FIXME section since it's fixed. + Added lots of parent tests. Corrected the "add // incorrectly" test + to match the new version of gnome_vfs_uri_new. + + * modules/pipe-method.c: Removed some bad casts of function + pointers to (gpointer) that were also completely unnecessary. + + * libgnomevfs/Makefile.am (INCLUDES): Ettore meant + "-I$(top_builddir)", since it's a generated file. + + * test/auto-test: Pass "-a" option to diff so it treats the files + as text files. + + * test/test.output: Updated to match what the program currently + writes out. Someone needs to look it over and see if it's correct + or if it reflects bugs. + +2000-07-19 Ettore Perazzoli + + * libgnomevfs/Makefile.am (INCLUDES): Add `-I$(top_srcdir)'. + Otherwise `#include ' doesn't work. + +2000-07-19 Kjartan Maraas + + * configure.in: Added nl to ALL_LINGUAS. + +2000-07-18 Mike Fleming + + * modules/translate-method.c: (tr_forkexec_cb), (tr_getline), + (tr_handle_exec), (tr_uri_translate), (tr_do_open), (tr_do_create), + (tr_do_open_directory), (tr_do_get_file_info), (tr_do_truncate), + (tr_do_is_local), (tr_do_make_directory), (tr_do_find_directory), + (tr_do_remove_directory), (tr_do_move), (tr_do_unlink), + (tr_do_check_same_fs), (tr_do_set_file_info), + (my_poptParseArgvString), (tr_args_parse), (tr_args_free): + + Added a -exec option to vfs-translate, which allows a child + process to filter URI's. + +2000-07-18 Maciej Stachowiak + + * libgnomevfs/gnome-vfs-private-utils.c + (gnome_vfs_string_list_from_string_array): Handle a zero-length + non-NULL array properly by turning a gratuitous do ... while loop + into a while loop. + +2000-07-17 Maciej Stachowiak + + * modules/search-method.c, modules/search-method.h: Removed (moved + to medusa). + + * libgnomevfs/gnome-vfs-private-ops.c, + libgnomevfs/gnome-vfs-private-ops.h: Renamed to + gnome-vfs-cancellable-ops.[ch] + * libgnomevfs/Makefile.am, libgnomevfs/gnome-vfs-private.h: Deal + with the renaming. + +2000-07-17 Mathieu Lacage + + This should fix bug 796. + + * libgnomevfs/Makefile.am: add -DGNOME_VFS_DATADIR and + -DGNOME_VFS_CONFDIR. + * libgnomevfs/gnome-vfs-mime.c:(mime_init) look into gnome_vfs + prefix instead of gnome-libs one. + * libgnomevfs/gnome-vfs-mime-magic.c:(gnome_vfs_mime_get_magic_table) + idem. + * libgnomevfs/gnome-vfs-gen-mimedb.c:(main) idem. + * libgnomevfs/gnome-vfs-mime-info.c:(gnome_vfs_mime_init) idem. + +2000-07-17 Seth Nickell + + * modules/search-method.c: (search_directory_handle_new), + (search_directory_handle_destroy), (parse_search_uri), (do_open), + (do_create), (do_close), (do_read), (do_write), (do_write), + (do_seek), (do_tell), (do_truncate_handle), (do_open_directory), + (do_close_directory), (do_read_directory), (do_get_file_info), + (do_get_file_info_from_handle), (do_is_local), (do_make_directory), + (do_remove_directory), (do_move), (do_unlink), (do_check_same_fs), + (do_set_file_info), (do_truncate), (do_find_directory), + (do_create_symbolic_link): + * modules/search-method.h: + + Create module for interfacing Gnome-VFS and the medusa search service. + Write skeletons, draft basic functionality. + +2000-07-17 Jonathan Blandford + + * modules/bzip2-method.c: #include + + * libgnomevfs/gnome-vfs-private-ops.c: #include + + * libgnomevfs/gnome-vfs-xfer.c: #include + + * libgnomevfs/gnome-vfs-mime-sniff-buffer-private.h: Add newline + to the end of the file. + * libgnomevfs/gnome-vfs-find-directory.h: Add newline to the end + of the file. + +2000-07-17 Pavel Cisler + + * libgnomevfs/gnome-vfs-xfer.c: (gnome_vfs_xfer_delete_items): + Added a missing READYTOGO progress that caused asserts to + get fired during a delete operation. + +2000-07-15 Ali Abdin + + * modules/pipe-methpd.c: + (mime_from_uri), (str_without_suffix), (do_get_file_info), + (do_get_file_info_from_handle), (do_open): + We are now allowed to specify mime-type over the URI using the pipe + method (as in pipe:command;mime-type=text/html) + + Also - you can now escape strings passed to the pipe method (before + they had to be unescaped) + + This closes bug #1322. (We still need a test-suite for this though). + + Also - expect a commit for a 'fix' to libvfs-translate.so + +2000-07-14 Gene Z. Ragan + + * libgnomevfs/gnome-vfs-mime-handlers.c: + * libgnomevfs/gnome-vfs-mime-handlers.h: + (gnome_vfs_mime_get_icon), (gnome_vfs_mime_set_icon): + New API to get and set icon data. + + * mime-type-capplet/Makefile.am: + Added new file + mime-type-capplet/nautilus-mime-type-icon-entry.c + + * mime-type-capplet/nautilus-mime-type-icon-entry.c: + * mime-type-capplet/nautilus-mime-type-icon-entry.h: + (nautilus_mime_type_icon_entry_get_type), + (nautilus_mime_type_icon_entry_class_init), (entry_changed), + (entry_activated), (setup_preview), (ientry_destroy), + (browse_clicked), (icon_selected_cb), (cancel_pressed), + (gil_icon_selected_cb), (nautilus_mime_type_show_icon_selection), + (drag_data_received), (drag_data_get), + (nautilus_mime_type_icon_entry_init), + (nautilus_mime_type_icon_entry_new), + (nautilus_mime_type_icon_entry_gnome_file_entry), + (nautilus_mime_type_icon_entry_gnome_entry), + (nautilus_mime_type_icon_entry_gtk_entry), + (nautilus_mime_type_icon_entry_set_pixmap_subdir), + (nautilus_mime_type_icon_entry_set_icon), + (nautilus_mime_type_icon_entry_get_filename): + New file. This is a new verison of GnomeIconEntry. + I am customizing it to look and bahve in a way that + is compatible with Arlo's UI reccomendations. + + * mime-type-capplet/nautilus-mime-type-capplet.c: + (mime_list_selected_row_callback), (icon_changed), + (change_icon_clicked), (init_mime_capplet), + (nautilus_mime_type_capplet_update_info), (populate_mime_list): + More UI cleanups. Removed GnomeIconEntry and replaced + with new NautilusMimeTypeIconEntry. + +2000-07-14 Mathieu Lacage + + * mime-type-capplet/Makefile.am: add OAF_CFLAGS and OAF_LIBS + where it is needed to make it compile with strange prefixes. + +2000-07-13 Gene Z. Ragan + + Fixed bug 1158, GnomeVFSMimeHandlers code needs error handling + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_add_extension), + (gnome_vfs_mime_remove_extension): + These functions now return a valid GNomeVFSResult. + + * libgnomevfs/gnome-vfs-mime-info.c: + * libgnomevfs/gnome-vfs-mime-info.h: + (gnome_vfs_mime_commit_registered_types), + (write_registered_mime_data): + These functions now return a valid GNomeVFSResult. + +2000-07-13 Pavel Cisler + + * libgnomevfs-pthread/gnome-vfs-job.c: + * libgnomevfs/gnome-vfs-xfer.c: (remove_file), (remove_directory), + (count_each_file_size_one), (gnome_vfs_xfer_empty_trash), + (gnome_vfs_xfer_delete_items): + First part of fix for Bugzilla bug 1549 - Empty Trash progress dialog + doesn't work. Made it so that both preflight calculation and + the erase loop both weight each erased file/directory as if it + were a file copy of a file 1024 bytes large. + +2000-07-13 Ian McKellar + + * libgnomevfs/gnome-vfs-seekable.c: (read_file), (init_seek), + (gnome_vfs_seek_emulate), (do_seek): + Various fixes related to tmpfile changes and also random bug fixes + to make seekable emulation actually work. + + * modules/http-method.c: (do_open): + Fix to http-method so it works with the gnome-vfs-seekable code. + +2000-07-12 Ian McKellar + + * libgnomevfs/gnome-vfs-uri.c: (gnome_vfs_uri_to_string): + Fixed a bug that added an extra '/'. + +2000-07-12 Robin * Slomkowski + + * gnome-vfs.spec.in: changed *.so.* to *.so* + +2000-07-12 Ramiro Estrugo + + * modules/gconf-method.c: (vfs_module_init): + Update for GConf api changes. + +2000-07-11 Robin Slomkowski + + * gnome-vfs.spec.in: removed a '.' + +2000-07-11 Darin Adler + + * test/.cvsignore: + * test/test-uri.c: (test_uri_to_string), (main): + Added some more tests that demonstrate some more problems with the + GnomeVFSURI functions. A lot of FIXMEs in here now about the + problems. + + * libgnomevfs/gnome-vfs-uri.c: (gnome_vfs_uri_to_string): + Added a check for uri->text of NULL so that URIs like "http:" + would not cause a core dump. But perhaps they should return NULL + instead of creating a legal URI? Also fixed a little of the + formatting to fit the gnome-vfs standard. + +2000-07-12 Ian McKellar + + * data/mime/gnome-vfs.keys: + Added `vfs-method' keys to a few mime types. This key indicates the + name of a GNOME VFS method that can be used to decode a file of this + type. + + * libgnomevfs/gnome-vfs-uri.c: (gnome_vfs_uri_to_string): + Essentially rewrote gnome_vfs_uri_to_string. It was very broken + (especially for chained URIs). + + * modules/bzip2-method.c: (do_open), (do_get_file_info): + * modules/gzip-method.c: (do_open), (do_get_file_info): + Fiddled with invalid URI detection. + + * modules/extfs-method.c: (strip_separators), (get_basename), + (get_dirname), (do_open), (read_directory_list), + (do_open_directory), (do_close_directory), (do_read_directory), + (do_get_file_info): + Made it work - basically changed the way a bunch of the functions + do their stuff. + + * modules/extfs/Makefile.am: + * modules/extfs/tar: + Added a `tar' extfs module - it isn't a good long-term solution for + tar file access, but it works for now. + + * test/Makefile.am: + * test/test-uri.c: (stop_after_log), (make_asserts_break), + (test_failed), (test_uri_to_string), (main): + Added a test-uri program. + +2000-07-07 Michael Meeks + + * modules/efs-method.c (do_create): remove serious locking bug. + +2000-07-10 Darin Adler + + Added async. set_file_info. Sadly, I didn't yet write a test + for it and I haven't yet added it to the CORBA back end. + + * libgnomevfs-pthread/gnome-vfs-async-ops.c: + (pthread_gnome_vfs_async_set_file_info): + * libgnomevfs-pthread/gnome-vfs-job.h: + * libgnomevfs-pthread/gnome-vfs-job.c: + (dispatch_set_file_info_callback), (dispatch_job_callback), + (execute_get_file_info), (execute_set_file_info), + (gnome_vfs_job_execute): + Added set_file_info to the thread back end. + + * libgnomevfs/gnome-vfs-types.h: + Made the standard callback that just returns a result code have + the name GnomeVFSAsyncCallback since it can be used for any number + of simple calls. + + * libgnomevfs/gnome-vfs-async-ops.h: + Added async. set_file_info to the async. ops list. + + * libgnomevfs/gnome-vfs-backend.c: + (report_failure_simple_callback), (report_failure_simple): Make + the open-specific callback helper into something that can be + shared by multiple calls. + (gnome_vfs_async_open), (gnome_vfs_async_open_uri), + (gnome_vfs_async_create), (gnome_vfs_async_create_uri), + (gnome_vfs_async_create_symbolic_link): Use the callback helper by + its new name. + (gnome_vfs_async_set_file_info): Add async. set_file_info. + + * modules/newftp-method.c: [removed] + * modules/newftp-method.h: [removed] + +2000-07-09 Ian McKellar + + * libgnomevfs/gnome-vfs-private-types.h: + Renamed GnomeVFSMethodCreateSymbolicLink to + GnomeVFSMethodCreateSymbolicLinkFunc to match + + * modules/bzip2-method.c: (do_open), (do_read): + Bugfixes. + + (do_get_file_info): + Implemented do_get_file_info - needed by Nautilus + + * modules/gzip-method.c: (do_open), (do_read): + Bugfixes. + + (do_get_file_info): + Implemented do_get_file_info - needed by Nautilus + + * modules/http-method.c: (base64), (make_request): + Implement minimal basic authorization support. + + (do_get_file_info), (do_close), (do_move): + Bugfixes. + +2000-07-07 Gene Z. Ragan + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_add_extension), (gnome_vfs_mime_remove_extension): + Changed code to used renamed gnome_vfs_mime_extensions_list_free + + * libgnomevfs/gnome-vfs-mime-info.c: + * libgnomevfs/gnome-vfs-mime-info.h: + (gnome_vfs_mime_get_extensions_pretty_string): + Return a list with period prepended, comma seperated items. + + (gnome_vfs_mime_extensions_list_free): + Changed name form gnome_vfs_mime_extension_list_free + + * mime-type-capplet/nautilus-mime-type-capplet.c: + (populate_extension_list), (init_mime_capplet), + (nautilus_mime_type_capplet_update_info), (populate_mime_list), + (create_mime_list_and_scroller): + More exciting UI layout work and feature completion. + +2000-07-07 Seth Nickell + + * libgnomevfs/gnome-vfs-xfer.c: (copy_directory), (copy_items): + Add proper copy support for symlinks. + + * modules/file-method.c: (get_stat_info): + Fix get_stat_info to return symbolic type correctly. + + * test/test-symlinks.c: (deal_with_result): + Add more tests. + +2000-07-07 Robin * Slomkowski + + * gnome-vfs.spec.in: moved *.so* out of devel section + +2000-07-06 Gene Z. Ragan + + * mime-type-capplet/nautilus-mime-type-capplet.c: (column_clicked), + (create_mime_list_and_scroller): + Added sorting functionality to the column buttons. Enabled + columns to respond to a click. Clicking a column header + toggles between ascending and descending sort for that column. + +2000-07-06 Dan Winship + + * libgnomevfs/gnome-vfs-mime-sniff-buffer.c + (gnome_vfs_mime_sniff_buffer_get): don't try to seek if the sniff + buffer has no seek function (eg, because it's memory based). + +2000-07-05 Robin * Slomkowski + + * mime-type-capplet/Makefile.am: fixed libgdk_pixbuf + dependency. + +2000-07-05 Dan Winship + + * modules/gconf-method.c: add #ifdef HAVE_ALLOCA_H + +2000-07-05 Jeffrey Stedfast + + * libgnomevfs/gnome-vfs-types.h: Changed + '#include ' to + '#include ' + + * libgnomevfs/Makefile.am: Added gnome-vfs-file-size.h to + libgnomevfsinclude_HEADERS + +2000-07-06 Ian McKellar + + * libgnomevfs/gnome-vfs-private-utils.c: (gnome_vfs_create_temp): + * libgnomevfs/gnome-vfs-seekable.c: (init_seek): + Changed to use safe temp file functions. (bugzilla.eazel.com: 1001) + + * modules/http-method.c: (http_status_to_vfs_result): + Updated HTTP result -> GnomeVFSResult mapping. + + * (do_create): + Fixed create method a bit. + + +2000-07-05 Ian McKellar + + * modules/extfs-method.c: (get_dirname), (do_open_directory), + (match), (find_next): + SEGV fixes. + + (do_get_file_info): + Implement a useful get_file_info (based off the existing + (open|read|close)_directory code. + + * modules/http-method.c: (my_strcmp), (do_move): + Implement MOVE (using the HTTP/DAV MOVE method) + + * test/test-info.c: (print_file_info): + Only print valid info fields. + +2000-07-04 Pavel Cisler + + * libgnomevfs/gnome-vfs-xfer.c: + (gnome_vfs_new_directory_with_unique_name): + Make it possible for the unique name handling callback to detect + a file system that supports only short names and supply an + 8.3 name. + +2000-07-04 Pavel Cisler + + * libgnomevfs/gnome-vfs-types.h: + * libgnomevfs/gnome-vfs-utils.h: + * libgnomevfs/gnome-vfs-xfer.c: (copy_file_data), (copy_file), + (gnome_vfs_xfer_delete_items_common), + (gnome_vfs_xfer_delete_items), (gnome_vfs_xfer_uri_internal): + Add support for removing source files during an inter-volume move. + Split up deletion code into a common routine for reuse. + Introduce a new progress phase to allow us to reset the progress + state when done copying and when starting remove source files. + Fixed bug 1215. + +2000-07-04 Gene Z. Ragan + More capplet work in progress. Modifying applet and code + to support UI work done by Arlo. + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_add_extension), (gnome_vfs_mime_remove_extension): + API changes to support new layout. + + * libgnomevfs/gnome-vfs-mime-info.c: + * libgnomevfs/gnome-vfs-mime-info.h: + (gnome_vfs_mime_get_extensions_list), + (gnome_vfs_mime_get_extensions_string): + API changes to support new layout. + + * mime-type-capplet/Makefile.am: + Added dependency to GdkPixbuf. + + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.c: + (show_edit_components_dialog), (add_new_application), + (show_new_application_window), (show_edit_application_window): + API changes to support new layout. + + * mime-type-capplet/nautilus-mime-type-capplet.c: + * mime-type-capplet/nautilus-mime-type-capplet.h: + (populate_extension_list), (extension_list_deselected), + (application_button_toggled), (viewer_button_toggled), + (icon_changed), (init_mime_capplet), + (nautilus_mime_type_capplet_update_info), + (populate_application_menu), (populate_viewer_menu), + (edit_default_clicked), + (nautilus_mime_type_capplet_update_application_info), + (nautilus_mime_type_capplet_update_viewer_info), + (insert_mime_vals_into_clist), (create_mime_list_and_scroller), + (nautilus_mime_type_capplet_get_selected_item_mime_type), + (make_path), (pixmap_file): + API changes to support new layout. + + +2000-07-03 Ettore Perazzoli + + * libgnomevfs-pthread/Makefile.am (INCLUDES): Add + `-I$(top_builddir)/libgnomevfs' so that it works with builddir != + srcdir. + * libgnomevfs-corba/Makefile.am (INCLUDES): Likewise. + * libgnomevfs/Makefile.am (INCLUDES): Likewise. + * modules/Makefile.am (INCLUDES): Likewise. + +2000-07-03 Pavel Cisler + + * HACKING: + * NEWS: + * TODO: + More tweaks for the release. + +2000-07-03 Eskil Heyn Olsen + + * libgnomevfs/Makefile.am: + * mime-type-capplet/Makefile.am: + Making gnome-vfs rpm'able + +2000-07-03 Pavel Cisler + + * AUTHORS: + * HACKING: + * README: + * TODO: + Update these for an upcomming release. + + * libgnomevfs/gnome-vfs-private-ops.c: + (gnome_vfs_find_directory_cancellable): + Fix a leak. + +2000-07-03 Seth Nickell + + * libgnomevfs-pthread/gnome-vfs-async-ops.c: + (pthread_gnome_vfs_async_create_uri), + (pthread_gnome_vfs_async_create_symbolic_link): + * libgnomevfs-pthread/gnome-vfs-job.c: (dispatch_job_callback), + (execute_create), (execute_create_symbolic_link), + (gnome_vfs_job_execute): + * libgnomevfs-pthread/gnome-vfs-job.h: + * libgnomevfs/gnome-vfs-async-ops.h: + * libgnomevfs/gnome-vfs-backend.c: + (gnome_vfs_async_create_symbolic_link): + * libgnomevfs/gnome-vfs-file-info.h: + Added asynchronous calls for the creation of symbolic links. + + * libgnomevfs/gnome-vfs-types.h: + Rename GNOME_VFS_FILE_TYPE_BROKEN_SYMLINK to GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK, remove + GNOME_VFS_FILE_FLAGS_SYMLINK. + + * test/gnome-file-selection/gnome-file-selection.c: + (populate_callback): + * test/test-async-directory.c: (type_to_string), (print_list): + * test/test-directory-visit.c: (type_to_string), + (directory_visit_callback): + * test/test-directory.c: (type_to_string), (print_list): + * test/test-info.c: (type_to_string): + * test/test-shell.c: (do_ls), (do_info): + Update pieces of GnomeVFS to reflect the aforementioned change, and check behaviors + to reduce breakage regarding the change from a symbolic link as a flag to a type. + + * modules/file-method.c: (get_mime_type), (get_stat_info): + Add handling for GNOME_VFS_INFO_FOLLOW_LINKS. + + * test/test-symlinks.c: (deal_with_result), (create_link_callback), + (make_link), (make_link_async), (check_broken_links), (main): + Add tests for link following, broken symbolic link checking, and async. link + creation checking to the symbolic link checking program. + +2000-06-27 Michael Meeks + + * modules/efs-method.c (gnome_vfs_file_system_*): Create in-file + file system code. + Totaly re-write internals to use the new in-file filing system code. + + * test/test.cmds: Expand regression tests to do new things. + +2000-07-03 Ian McKellar + + * libgnomevfs/gnome-vfs-xfer.c: (call_progress_often), + (copy_file_data), (copy_file): + Fixes to supply a default IO block size of 4096 for xfers when none + is supplied by the module. + + * modules/extfs-method.c: + Segfault fix. + + * modules/ftp-method.c: (ls_to_file_info), + (internal_get_file_info): + Fix get_file_info response to not contain a default IO block size. + + * test/test-xfer.c: (xfer_progress_callback): + Update test-xfer to understand a couple more xfer phases. + +2000-07-02 Ian McKellar + + * libgnomevfs/gnome-vfs-uri.h: + * libgnomevfs/gnome-vfs-uri.c: (gnome_vfs_uri_get_path): + Added gnome_vfs_uri_get_path function. + + (gnome_vfs_uri_get_basename): + Added FIXME bug id 1472. + + * modules/ftp-method.h: + * modules/ftp-method.c: (FTP_DEBUG), (read_response_line), + (do_path_command), (do_path_command_completely), + (do_path_transfer_command), (ftp_connection_create), + (ftp_connection_destroy), (my_str_hash), (my_str_equal), + (ftp_connection_uri_hash), (ftp_connection_uri_equal), + (ftp_connection_aquire), (ftp_connection_release), (do_open), + (do_read), (do_write), (internal_get_file_info), + (do_get_file_info), (do_open_directory), (do_check_same_fs), + (do_make_directory), (do_remove_directory), (do_move), (do_unlink): + Rewrote the FTP method to use GnomeVFSURIs internally rather than + FtpUris. Also defined the semantics and memory management of URIs + more clearly (closing bug 1465). Some general sanitisation. + + * modules/http-method.c: (set_content_type): + Ignore encoding. + + (do_close), (do_read), (do_open_directory), (do_read_directory), + (do_get_file_info), (do_make_directory), (do_remove_directory), + (do_unlink): + Add convenience routines to make adding methods easier. + Implement mkdir, rmdir, rm (much of bugs 1480, 1485). + + (process_propfind_propstat), (process_propfind_response), + (make_propfind_request), + Fixed URI handling a bit (decode returned filenames, strip trailing + '/'s, etc). + +2000-06-29 Pavel Cisler + + Fix a bunch of leaks. + + * libgnomevfs-pthread/gnome-vfs-job.c: + (execute_load_directory_not_sorted): + Unref allocated GnomeVFSFileInfo when read fails properly. + Delete the list of file info structs when we are done with them properly. + + * libgnomevfs/gnome-vfs-directory-filter.c: + (gnome_vfs_directory_filter_destroy): + Free filter object properly. + + * libgnomevfs/gnome-vfs-mime-sniff-buffer.c: + (gnome_vfs_mime_sniff_buffer_new_generic): + Set up buffer ownership for generic sniffers properly so the buffer + gets freed when it should. + +2000-06-27 Pavel Cisler + + * data/mime/gnome-vfs-mime-magic: + * data/mime/gnome-vfs.keys: + Fix magic rules and mime type for image/x-xpixmap + +2000-06-27 Michael Meeks + + * modules/efs-method.c: Kill redundant fields. + (directory_handle_new): kill; redundant. + (do_open_directory): implement handle creation. + (directory_handle_destroy): remove redundant free. + (GET_PATH_MAX): remove; unneeded & ugly. + remove old redundant macros. + remove redundant includes. + +2000-06-27 Michael Meeks + + * mime-type-capplet/Makefile.am (INCLUDES): add libgnomevfs + +2000-06-27 Michael Meeks + + * vfsConf.sh.in: touch to force script re-build. + + * test/gnome-file-selection/Makefile.am (INCLUDES): add + -I$(top_srcdir)/libgnomevfs + + * libgnomevfs/Makefile.am (libgnomevfsplatofrmincludedir): make path + slightly less gratuitous. + + * libgnomevfs/gnome-vfs-types.h: rename include to gnome-vfs-file-size.h + +2000-06-26 Pavel Cisler + + * libgnomevfs/gnome-vfs-mime-magic.c: (gnome_vfs_mime_magic_parse): + Fix patterns with mask to apply the mask on the patterns -- this makes + it allows the masked out bits to be anything. + + * test/test-mime.c: (main): + Remove a bogus setting of the suffix_only flag. + + * data/mime/gnome-vfs-mime-magic: + Fixed the mime type for compress files. + Remove ambiguous magic rule for application/x-font-tex-tfm that was + misfiring on .Xauthority files. + Change photoshop rules to use the rule with a mask. + + * data/mime/gnome-vfs.keys: + Change application/x-patch to text/x-patch + +Mon Jun 26 16:04:48 2000 George Lebl + + * configure.in: Test the sizes of int, long, and long long to figure + out if we have a 64bit type. Then set up some variables and build + libgnomevfs/gnome-vfs-file-size.h with this information and a bunch + of defines about the types used. Also since this header will be + installed into /lib/vfs/include/libgnomevfs, the + VFS*_INCLUDEDIR's now add this directory + + * libgnomevfs/Makefile.am: install gnome-vfs-file-size.h to + $(libdir)/vfs/include/libgnomevfs + + * gnome-vfs-constants.h: Remove the GNOME_VFS_*_FORMAT_STR macros as + they are replaced by ones in gnome-vfs-file-size.h + + * gnome-vfs-types.h: include gnome-vfs-file-size.h and remove the + GnomeVFSFileSize and GnomeVFSFileOffset typedefs + + * gnome-vfs-file-size.h.in: Skeleton file created by configure to + typedef GnomeVFSFileSize and GnomeVFSFileOffset, + GNOME_VFS_*_FORMAT_STR macros and GNOME_VFS_*_IS_ macros + +2000-06-26 Michael Meeks + + * doc/uri.txt: update. + + * test/Makefile.am: Add automatic regression testing. + + * test/test.input: Plaintext to test vs. + + * test/test.output: Standard good output + + * test/test.cmds: test-shell commands to execute. + + * test/test-shell.c (close_file, kill_file_cb, register_file), + (close_files): mange named file handles. + (get_handle, do_create, do_open, get_int, do_read, do_close): implement. + (do_seek): implement. (main): allow comments in the input stream, + s/stderr/vfserr/ (main): Setup vfserr to be stdout for regression tests. + + * libgnomevfs/gnome-vfs-uri.c (gnome_vfs_uri_new): kill redundant + check on ref_count. + +2000-06-26 Pavel Cisler + + * data/mime/gnome-vfs-mime-magic: + Added a sniff rule for svg files. + Got rid of questionable sgml sniff rules. + +2000-06-26 Michael Meeks + + * modules/efs-method.c (do_make_directory): add error handling + on efs close. (do_make_directory): commit. + (do_close): re-write, adding commit. + (do_unlink): add commit. + + * Makefile.am (SUBDIRS): move SUBDIRS_OAF up the build so + it is made in time for the tests. + + * test/test-shell.c (list_commands): expand help. + (syntax_error): kill. (main): update argument handling. + +2000-06-26 Pavel Cisler + + * Makefile.am: + Fix broken build - recent changes to Makefile.am put libraries + in wrong order. + +2000-06-25 Pavel Cisler + + * configure.in: + Turn -Werror back on. + + * libgnomevfs/gnome-vfs-mime-handlers.c: (join_str_list), + (bool_to_str): + Fix code that breaks if USING_OAF is undefined. + +2000-06-25 Morten Welinder + + * test/test-mime-handlers.c: conditionalise on USING_OAF and + HAVE_GCONF as needed. + + * libgnomevfs/gnome-vfs-mime-handlers.c: conditionalise on + USING_OAF and HAVE_GCONF as needed. + (gnome_vfs_mime_action_free): Add a few "break;"s to this piece of + untested code. + + * test/Makefile.am (noinst_PROGRAMS): Only make oaf-depedent tests + when we have oaf. + + * test/gnome-file-selection/Makefile.am (noinst_PROGRAMS): Ditto. + + * modules/default-modules.conf (ftp): Remove Yakk's newftp hack. + + * acconfig.h (HAVE_GCONF): Add. + + * libgnomevfs/gnome-vfs-init.c (gnome_vfs_init): Only initialise + oaf if we have it. + + * configure.in (set_more_warnings): Don't add -Wsign-promo and + -Wno-sign-compare unless the compiler understands them. Don't add + -Werror at all. + + * test/test-async-cancel.c (my_yield): renamed from yield to avoid + name clash. + + * libgnomevfs/gnome-vfs-mime.c (add_to_key): Fix arguments to + isspace (etc.) + (mime_fill_from_file): Ditto. + + * libgnomevfs/gnome-vfs-mime-magic.c (read_string_val): Ditto. + (read_num_val): Ditto. + (eat_white_space): Ditto. + (gnome_vfs_mime_magic_parse): Ditto. + + * modules/translate-method.c (my_poptParseArgvString): Ditto. + + * modules/ftp-method.c (get_response): Ditto. + (do_read_directory): Ditto. + + * modules/http-method.c (parse_status): Ditto. + (header_value_to_number): Ditto. + + * libgnomevfs/fnmatch.c (FOLD): Ditto. + + * libgnomevfs/gnome-vfs-uri.c (get_method_string): Ditto. + + * libgnomevfs/gnome-vfs-private-utils.c (check_end): Ditto. + +2000-06-26 Ian McKellar + + * modules/ftp-method.c: (ftp_response_to_vfs_result), + (do_control_write), (do_basic_command), (do_transfer_command), + (ftp_connection_create), (ftp_connection_release), (do_open), + (internal_get_file_info), (do_read_directory): + Added FIXMEs to bugzilla, removed some fixed FIXMEs and fixed some + of the things mentioned in some of the FIXMEs. + +2000-06-24 Morten Welinder + + * libgnomevfs/gnome-vfs-parse-ls.c (vfs_parse_filedate): Actually + get the time, don't use an undefined one. + + * libgnomevfs/gnome-vfs-uri.c (gnome_vfs_uri_new): Avoid double + free of method string. + + * modules/http-method.c (make_request): Feee uri_string in all + cases. + +2000-06-24 Michael Meeks + + * modules/efs-method.c (do_make_directory): create if not found. + + * test/test-shell.c (do_mv, do_rmdir, do_mkdir, do_rm): implement. + (main): use g_get_current_dir. + +2000-06-24 Michael Meeks + + * modules/efs-method.c (open_efs_file): split. + (do_open, do_create): update. (do_unlink): implement. + (do_open_directory,do_get_file_info, do_make_directory): update. + Elimiate all uses of MAKE_ABSOLUTE, it leaks badly. + (directory_handle_new): clean for no MAKE_ABSOLUTE. + (do_open_directory): add param checks on uri. + +2000-06-24 Michael Meeks + + * libgnomevfs/gnome-vfs-uri.c (gnome_vfs_uri_new): re-order to make + (parse_uri_substring): Add parent arg, since set_uri_element will + trample on memory unless uri->parent != NULL before call. update. + (gnome_vfs_uri_new): update. + + * modules/efs-method.c (MAKE_ABSOLUTE): add catch for non-existant + parents. (do_tell): implement. (do_open_directory): open only for read + and use (transfer_dir_to_info): split (do_get_file_info): implement. + (do_get_file_info_from_handle): remove, should be a fallback in the vfs + anyway. + + * configure.in: enable libefs by default. + + * doc/uri.txt: revert a daftness. + +2000-06-24 Pavel + + * modules/file-method.c: (file_handle_new), (do_close), + (directory_handle_new), (get_mime_type), + (do_get_file_info), + (do_get_file_info_from_handle), (do_make_directory), + (do_remove_directory), (rename_helper), (do_move), (do_unlink), + (do_set_file_info): + Fixed 1312 - Need to plug in sniff buffer mime magic API into methods. + Fixed 1183 - Made the get_mime_type call correctly handle symlinks. + Fixed 1184 - removed an extra stat call. + Bunch of renamings and cleanup. + + * libgnomevfs/gnome-vfs-mime-magic.c: + (gnome_vfs_sniff_buffer_looks_like_text): + Fixed a bug where only text files larger than 256 would get recognized properly. + Get rid of gnome_vfs_mime_magic_matches_p. + Get rid of gnome_vfs_mime_type_from_magic. + + * libgnomevfs/gnome-vfs-mime-magic.h: + Get rid of obsolete comment. + + * libgnomevfs/gnome-vfs-mime.c: + * libgnomevfs/gnome-vfs-mime.h: + (gnome_vfs_mime_type_from_name_or_default), + (gnome_vfs_mime_type_from_name), + (gnome_vfs_get_mime_type_from_uri_internal), + (gnome_vfs_get_mime_type), (file_seek_binder), (file_read_binder), + (gnome_vfs_get_file_mime_type), (gnome_vfs_get_mime_type_from_uri), + (gnome_vfs_get_mime_type_for_data): + New call gnome_vfs_get_file_mime_type used to detect mime types by the + file method. + Renamed a number of routines. + + * libgnomevfs/gnome-vfs-types.h: + * libgnomevfs/gnome-vfs-xfer.c: (count_items_and_size), + * modules/extfs-method.c: (read_directory_list): + (directory_add_items_and_size): + * modules/file-method.c: (get_stat_info), (read_directory): + * modules/gconf-method.c: (set_mime_type_value), (file_info_value), + (file_info_dir): + Renamed some of GnomeVFSFileInfoOptions. + Added new GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE option. + Renamed GNOME_VFS_XFER_FOLLOWLINKS to GNOME_VFS_XFER_FOLLOW_LINKS. + + * modules/ftp-method.c: (get_response), (do_transfer_command), + (ls_to_file_info), (internal_get_file_info), (do_get_file_info): + Fixed some leaks, got rid of checks for NULL before g_free, + switched to use new gnome_vfs_mime_type_from_name_or_default, + cleaned up. + + * modules/gconf-method.c: (set_mime_type_value): + Fixed bad mime type. + + * test/gnome-file-selection/gicon.c: (gicon_get_icon_for_file_2): + * test/gnome-file-selection/gnome-file-selection.c: + (start_populating): + * test/test-async-cancel.c: (test_load_directory_cancel): + * test/test-async-directory.c: (main): + * test/test-directory-visit.c: (main): + * test/test-directory.c: (main): + * test/test-info.c: (main): + * test/test-mime.c: (main): + Changed to match new renamings. + + * data/mime/gnome-vfs.keys: + Added description for application/x-executable-file. + +2000-06-24 Fatih Demir + + * mime-type-capplet: Removed this install-data-local target and + made another normal rule to install the .desktop file + also to the "Settings" menu-tree. + + [ PS: Some `install' variants don't support the -D flag, so you'd + avoid whereever it's possible. ] + +2000-06-23 Darin Adler + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_edit_user_file_full): Added code to handle NULL + for value and write out an empty string. The old code wrote out + "(NULL)" because of the help of glibc, but then I had added checks + for NULL. Now we handle it intentionally. + (gnome_vfs_mime_edit_user_file_args): Got rid of check for NULL + that made it illegal. Fixed a bug that would trash memory where I + was doing the wrong list. + (gnome_vfs_mime_edit_user_file): Make NULL legal here too. + +2000-06-23 Michael Meeks + + * test/test-shell.c (do_info): implement. + (main): hook in. + +2000-06-23 Michael Meeks + + * test/test-shell.c (get_fname): updates. + + * modules/efs-method.c (do_read_directory): implement. + (directory_handle_new): setup new->efs. + Begin to loathe efs. + + * doc/uri.txt: update. + + * test/Makefile.am (libraries): add LIBEFS_LIBS + + * libgnomevfs/gnome-vfs-uri.c (gnome_vfs_uri_new): fix from + Rajit, this still looks rather limited to me. + + * configure.in: Add efs check. + + * modules/default-modules.conf (efs): add. + +2000-06-22 Michael Meeks + + * configure.in: add --enable-libefs. + +2000-06-22 Gene Z. Ragan + + Fixed bug #581. UI for specifying whether applicaition + can open multiple files at once. + + * libgnomevfs/gnome-vfs-mime-handlers.c: + * libgnomevfs/gnome-vfs-mime-handlers.h: + (gnome_vfs_mime_define_application): + Added const char * argument for mime type. Removed placeholder + mime type. + + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.c: + (populate_default_applications_list), + (populate_default_components_box), + (initialize_edit_applications_dialog), (add_new_application), + (show_new_application_window), (show_edit_application_window): + Modified edit applicaiton list dialog to use a GtkList with + embedded check buttons and labels. This allows single list items + to be selected so that individual items can be edited or deleted. + + * test/test-mime-handlers-set.c: (main): + Fixed call to gnome_vfs_mime_define_application to use + new argument. + +2000-06-22 Darin Adler + + * libgnomevfs/gnome-vfs-mime-handlers.h: + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_edit_user_file_full), + (gnome_vfs_mime_edit_user_file_args), + (gnome_vfs_mime_edit_user_file_multiple), + (gnome_vfs_mime_edit_user_file), + (gnome_vfs_mime_set_default_action_type), + (gnome_vfs_mime_set_default_application), + (gnome_vfs_mime_set_default_component), + (gnome_vfs_mime_set_short_list_applications), + (gnome_vfs_mime_set_short_list_components), + (gnome_vfs_mime_id_in_application_list), + (gnome_vfs_mime_id_in_component_list), + (gnome_vfs_mime_add_application_to_short_list), + (gnome_vfs_mime_remove_application_from_list), + (gnome_vfs_mime_remove_application_from_short_list), + (gnome_vfs_mime_add_component_to_short_list), + (gnome_vfs_mime_remove_component_from_list), + (gnome_vfs_mime_remove_component_from_short_list), + (gnome_vfs_mime_add_extension), (gnome_vfs_mime_remove_extension), + (gnome_vfs_mime_extend_all_applications), + (gnome_vfs_mime_remove_from_all_applications), + (gnome_vfs_mime_define_application): + Added some rudimentary error handling. + + * test/.cvsignore: + Some new files are generated but not yet ignored. + +2000-06-22 Gene Z. Ragan + + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.c: + (show_new_application_window), (show_edit_application_window): + Clean up work on layout of capplet dialogs. + +2000-06-22 John Sullivan + + Moved SUID, SGID, and Sticky bits from flags + field to permissions field because (1) it's + conventional to treat them as permission bits, + especially for display purposes, and (2) there was + no way to set them before. + + * libgnomevfs/gnome-vfs-types.h: Added new + GNOME_VFS_PERM_xxx constants for these three bits; + removed old GNOME_VFS_FILE_FLAGS_xxx constants. + * libgnomevfs/gnome-vfs-file-info.h: + updated GNOME_VFS_FILE_INFO_xxx macros for these + three bits to look in permissions field instead of + flags field. + * libgnomevfs/gnome-vfs-module-shared.c: + (gnome_vfs_stat_to_file_info): Put these bits in + permissions field instead of flags field when + converting from stat result. + + Added a few more MIME type descriptions. + + * data/mime/gnome-vfs.keys: Added descriptions + for x-special/device-char and friends. + +2000-06-22 Rajit Singh + + * modules/efs-method.[ch]: Create. + +2000-06-22 Michael Meeks + + * test/test-shell.c (get_fname): use regexps. + (ms_ole_dump, do_dump): implement. + +2000-06-22 Michael Meeks + + * test/Makefile.am: Add test-shell setup + + * test/test-shell.c: Small lightweight gnome-vfs shell for testing. + +2000-06-21 Gene Z. Ragan + + Fixed bug #1434, Fix alignment of widgets in main capplet view. + + * mime-type-capplet/nautilus-mime-type-capplet.c: + (init_mime_capplet): + Replaced use of multiple pack boxes with a table. Things + look much better now. + +2000-06-21 Seth Nickell + + Added more complete symlink support to gnome-vfs. + + * libgnomevfs/gnome-vfs-ops.c: (gnome_vfs_create_symbolic_link): + * libgnomevfs/gnome-vfs-ops.h: + * libgnomevfs/gnome-vfs-private-ops.c: + (gnome_vfs_create_symbolic_link_cancellable), + * libgnomevfs/gnome-vfs-private-ops.h: + * libgnomevfs/gnome-vfs-private-types.h: + Added the generic gnome-vfs functions and declarations for + gnome_vfs_create_symbolic_link and children that end up calling + method specific functions. + + (gnome_vfs_remove_directory_from_uri_cancellable), + (gnome_vfs_unlink_from_uri_cancellable), + (check_same_fs_in_uri): + Cleaned up formatting in some of the functions. + + * modules/file-method.c: (do_create_symbolic_link): + Implemented symlinking for the file-method, with a place-holder + for possible (eventual, post 1.0?) addition of URI links. + + * modules/bzip2-method.c: + * modules/extfs-method.c: + * modules/ftp-method.c: + * modules/gzip-method.c: + * modules/pipe-method.c: + * modules/translate-method.c: + Added NULL placeholders for other methods that do not implement + create_symbolic_link. + + * test/Makefile.am: + * test/test-symlinks.c: (make_link), (main): + Wrote test code for the new gnome-vfs symlink support. Verifies + by writing data to the new links and checking the target uri. + + * libgnomevfs/gnome-vfs-uri.h: + * libgnomevfs/gnome-vfs-uri.c: (gnome_vfs_uri_get_scheme): + Fixed bug 821 by providing a method for querying a URI's + scheme. (as featured in the addition of symlink support) + +2000-06-21 Seth Nickell + + * modules/http-method.c: (http_file_handle_new), + (http_file_handle_destroy), (http_handle_close), (do_close): + Pavel here. Fixed a number of memory thrashers in http_handle_close. + Fixed some white space. + +2000-06-21 Gene Z. Ragan + + Final stage in renaming. + + * modules/ftp-method.c: + * modules/ftp-method.h: + Changed internal references form new-ftp-method to new-ftp-method. + +2000-06-21 Gene Z. Ragan + + Added renamed new-ftp module files as ftp modules. + + * modules/ftp-method.c: (FTP_DEBUG), (ftp_response_to_vfs_result), + * modules/ftp-method.h: + (read_response_line), (get_response), (do_control_write), + (do_basic_command), (do_transfer_command), (end_transfer), + (ftp_connection_create), (ftp_connection_uri_hash), + (ftp_connection_uri_equal), (ftp_connection_uri_to_string), + (ftp_uri_to_string), (ftp_connection_aquire), + (ftp_connection_release), (ftp_uri_create), (do_is_local), + (do_open), (do_close), (do_read), (do_write), (ls_to_file_info), + (internal_get_file_info), (do_get_file_info), + (do_get_file_info_from_handle), (do_open_directory), + (do_close_directory), (do_read_directory), (do_check_same_fs), + (do_make_directory), (do_remove_directory), (do_move), (do_unlink), + (vfs_module_init), (vfs_module_shutdown): + + +2000-06-21 Gene Z. Ragan + + Part of renaming and replacing of old + ftp module with new ftp module. + + * modules/Makefile.am: + * modules/ftp-method.c: + * modules/ftp-method.h: + Removed references to new-ftp. + +2000-06-21 Rebecka Schulman + + * test/test-async-directory.c: (type_to_string): + Fixed constant errors that were uncaught in previous + name changes + +2000-06-21 Darin Adler + + Improved the API of the utils (bug 1210). + + * libgnomevfs/gnome-vfs-utils.h: + * libgnomevfs/gnome-vfs-utils.c: + (gnome_vfs_format_file_size_for_display): Changed name from + gnome_vfs_file_size_as_string. + (gnome_vfs_escape_string_internal), (gnome_vfs_escape_string), + (gnome_vfs_escape_path_string): Replaced the old parameterized + escape_string function with 2 parameter-free versions for paths + and for other strings respectively. + (gnome_vfs_unescape_string_for_display): Added string to the name + to make it more like the other names. + + * libgnomevfs/gnome-vfs-uri.c: (gnome_vfs_uri_append_file_name), + (gnome_vfs_uri_extract_short_name): + * modules/http-method.c: (create_handle), (do_read): + * test/test-async-cancel.c: (test_load_directory_cancel): + * test/test-escape.c: (test_escape), (test_escape_path), + (test_unescape_display), (main): + Updated callers to use calls by their new names. + +2000-06-21 Gene Z. Ragan + + Fixed bug #583 + + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.c: + (initialize_edit_applications_dialog), + (show_new_application_window), (show_edit_application_window): + New dialog and items to indicate and allow user to + set application behavior concerning multiple launch and + URI handling. + + * mime-type-capplet/nautilus-mime-type-capplet.c: + (init_mime_capplet): + Removed old UI code and migrated to dialog. + +2000-06-21 Gene Z. Ragan + + Follow up to bug #1162. + + GnomeVFSFilePermissions had some items to be renamed as well. + + * libgnomevfs/gnome-vfs-module-shared.c: + (gnome_vfs_get_special_mime_type), (gnome_vfs_stat_to_file_info): + * libgnomevfs/gnome-vfs-types.h: + * modules/file-method.c: (set_mime_type), (get_stat_info): + * modules/ftp-method.c: (_ftpfs_read_directory), (fill_file_info): + * test/test-directory-visit.c: (type_to_string): + * test/test-directory.c: (type_to_string): + * test/test-info.c: (type_to_string): + +2000-06-21 Gene Z. Ragan + + Fixed bug #1162. + + Changed naming of gnome-vfs errors to seperate words with + underscore and replace abbreviations with full words. + + * libgnomevfs-corba/gnome-vfs-async-ops.c: + (corba_gnome_vfs_async_open), + (corba_gnome_vfs_async_open_as_channel), + (corba_gnome_vfs_async_create), + (corba_gnome_vfs_async_create_as_channel), + (corba_gnome_vfs_async_close), (corba_gnome_vfs_async_read), + (corba_gnome_vfs_async_write), + (corba_gnome_vfs_async_get_file_info), + (corba_gnome_vfs_async_load_directory), + (corba_gnome_vfs_async_xfer), (corba_gnome_vfs_async_cancel): + * libgnomevfs-pthread/gnome-vfs-async-ops.c: + (pthread_gnome_vfs_async_cancel), + (pthread_gnome_vfs_async_open_uri), (pthread_gnome_vfs_async_open), + (pthread_gnome_vfs_async_open_uri_as_channel), + (pthread_gnome_vfs_async_open_as_channel), + (pthread_gnome_vfs_async_create_uri), + (pthread_gnome_vfs_async_create), + (pthread_gnome_vfs_async_create_as_channel), + (pthread_gnome_vfs_async_close), (pthread_gnome_vfs_async_read), + (pthread_gnome_vfs_async_write), + (pthread_gnome_vfs_async_get_file_info), + (pthread_gnome_vfs_async_load_directory), + (pthread_gnome_vfs_async_load_directory_uri), + (pthread_gnome_vfs_async_xfer): + * libgnomevfs-pthread/gnome-vfs-job.c: (gnome_vfs_job_cancel): + * libgnomevfs/gnome-vfs-directory.c: (open), + (gnome_vfs_directory_open), (gnome_vfs_directory_open_from_uri), + (directory_visit_internal), (gnome_vfs_directory_visit_uri), + (gnome_vfs_directory_visit), + (gnome_vfs_directory_visit_files_at_uri): + * libgnomevfs/gnome-vfs-handle.c: + * libgnomevfs/gnome-vfs-inet-connection.c: + (gnome_vfs_inet_connection_create): + * libgnomevfs/gnome-vfs-iobuf.c: (gnome_vfs_iobuf_read), + (gnome_vfs_iobuf_peekc), (gnome_vfs_iobuf_write), + (gnome_vfs_iobuf_flush): + * libgnomevfs/gnome-vfs-method.h: + * libgnomevfs/gnome-vfs-ops.c: (gnome_vfs_open), + (gnome_vfs_create), (gnome_vfs_tell), (gnome_vfs_get_file_info), + (gnome_vfs_truncate), (gnome_vfs_make_directory), + (gnome_vfs_remove_directory), (gnome_vfs_unlink), (gnome_vfs_move), + (gnome_vfs_check_same_fs), (gnome_vfs_set_file_info): + * libgnomevfs/gnome-vfs-private-ops.c: + (gnome_vfs_open_uri_cancellable), + (gnome_vfs_create_uri_cancellable), (gnome_vfs_close_cancellable), + (gnome_vfs_read_cancellable), (gnome_vfs_write_cancellable), + (gnome_vfs_seek_cancellable), + (gnome_vfs_get_file_info_uri_cancellable), + (gnome_vfs_get_file_info_from_handle_cancellable), + (gnome_vfs_truncate_uri_cancellable), + (gnome_vfs_truncate_handle_cancellable), + (gnome_vfs_make_directory_for_uri_cancellable), + (gnome_vfs_find_directory_cancellable), + (gnome_vfs_remove_directory_from_uri_cancellable), + (gnome_vfs_unlink_from_uri_cancellable), + (gnome_vfs_move_uri_cancellable), + (gnome_vfs_check_same_fs_uris_cancellable), + (gnome_vfs_set_file_info_cancellable): + * libgnomevfs/gnome-vfs-private-utils.c: (gnome_vfs_create_temp): + * libgnomevfs/gnome-vfs-result.c: (gnome_vfs_result_from_errno), + (gnome_vfs_result_from_h_errno): + * libgnomevfs/gnome-vfs-seekable.c: (read_file), (write_file), + (init_seek), (do_open), (do_create), (do_truncate_handle): + * libgnomevfs/gnome-vfs-types.h: + * libgnomevfs/gnome-vfs-xfer.c: (handle_overwrite), + (create_directory), (xfer_create_target), (copy_items), + (move_items), (gnome_vfs_new_directory_with_unique_name), + (gnome_vfs_xfer_uri), (gnome_vfs_xfer_private): + * modules/bzip2-method.c: (result_from_bz_result), (do_open), + (do_create): + * modules/extfs-method.c: (do_open), (do_create), (do_write), + (do_truncate_handle), (do_truncate), (do_open_directory), + (do_get_file_info), (do_get_file_info_from_handle), + (do_make_directory), (do_find_directory), (do_remove_directory), + (do_move), (do_unlink), (do_check_same_fs): + * modules/file-method.c: (do_open), (do_create), (do_seek), + (do_tell), (do_truncate_handle), (do_truncate), + (do_open_directory), (do_get_file_info), + (do_get_file_info_from_handle), (do_make_directory), + (do_remove_directory), (do_find_directory), (rename_helper), + (do_move), (do_unlink), (do_set_file_info): + * modules/ftp-method.c: (ftpfs_open_socket), + (ftpfs_connection_connect), (login_server), (linear_start), + (send_ftp_command), (retrieve_file), (get_file_entry), + (ftpfs_open), (ftpfs_create), (ftpfs_open_directory), + (ftpfs_get_file_info): + * modules/gconf-method.c: (do_open), (do_create), (do_close), + (do_read), (do_write), (do_get_file_info_from_handle): + * modules/gzip-method.c: (result_from_z_result), (skip_string), + (skip), (read_guint32), (read_gzip_header), (do_open), (do_create): + * modules/http-method.c: (http_status_to_vfs_result), + (create_handle), (do_open), (make_propfind_request): + * modules/newftp-method.c: (ftp_response_to_vfs_result), + (do_transfer_command), (do_open), (do_read), (do_write), + (internal_get_file_info), (do_move): + * modules/pipe-method.c: (do_open): + * test/test-async-cancel.c: (file_open_fail_callback): + +2000-06-21 Gene Z. Ragan + + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.c: + (initialize_edit_applications_dialog), + (nautilus_mime_type_capplet_show_new_extension_window), + (add_new_application), (show_new_application_window): + More work on adding applications and extension. + + * mime-type-capplet/nautilus-mime-type-capplet.c: + (nautilus_mime_type_capplet_add_extension), + (remove_extension_clicked), (none_button_toggled), + (application_button_toggled), (component_button_toggled), + (init_mime_capplet), + (nautilus_mime_type_capplet_get_selected_item_mime_type): + Changed use of GtkFixed to use layout. Layout is now messy + again, but I should be able to get it looking right. + +2000-06-20 Pavel Cisler + + * libgnomevfs/gnome-vfs-mime-magic.c: + (gnome_vfs_mime_magic_matches_p): + Fix a memory thrasher in my new code. + + * data/mime/gnome-vfs-mime-magic: + * data/mime/gnome-vfs.keys: + Add proper key entries to Photoshop file type. + +2000-06-20 Pavel Cisler + + * libgnomevfs/gnome-vfs-mime-magic.h: + * libgnomevfs/gnome-vfs-mime-magic.c: (is_octal_digit), + (is_hex_digit), (read_octal_byte), (read_hex_byte), + (read_string_val), (read_hex_pattern), (read_num_val), + (eat_white_space), (match_pattern), (gnome_vfs_mime_magic_parse), + (endian_swap), (try_one_pattern_on_buffer), + (gnome_vfs_mime_magic_matches_p), + (gnome_vfs_mime_try_one_magic_pattern), + (gnome_vfs_mime_get_magic_table), + (gnome_vfs_mime_test_get_magic_table), (print_escaped_string), + (print_hex_pattern), (gnome_vfs_mime_dump_magic_table): + Rewrote most of the mime rule parser, cleaning it up and fixing + a ton of problems. + Added support for patterns with masks. + Added support for offset ranges. + Added support for comments in the magic rule file. + Got rid of unused entries in the GnomeMagicEntry struct. + Fixed mask support in gnome_vfs_mime_magic_matches_p. + Made gnome_vfs_mime_magic_matches_p and + gnome_vfs_mime_try_one_magic_pattern share code. + Added a way to dump the MIME magic table and to load an + arbitrary table for debugging purposes. + + * libgnomevfs/gnome-vfs-mime-magic.c: + (gnome_vfs_sniff_buffer_looks_like_text): + Added support for UTF-8 text. + + * libgnomevfs/gnome-vfs-mime-magic.c: + (gnome_vfs_sniff_buffer_looks_like_mp3): + Added an algorithmic sniffer for audio/x-mp3. + + * test/test-mime.c: (main): + Added a way to load and dump a specific file with magic rules. + + * data/mime/gnome-vfs-mime-magic: + Added comments. + Added sniff rule for Photoshop documents using a pattern with a mask. + Changed html rules to work on an offset range. + Added sniff rules for C and C++ files. + Reordered rules placing ones that require a seek deep into the + examined file last. + +2000-06-20 Darin Adler + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_get_default_action_type): Another place we need to + handle NULL. + +2000-06-20 Gene Z. Ragan + + * mime-type-capplet/nautilus-mime-type-capplet.c: + (mime_list_selected_row_callback), (none_button_toggled), + (application_button_toggled), (component_button_toggled), + (init_mime_capplet), (nautilus_mime_type_capplet_update_info): + Added frame and set of radio buttons to indicate and allow the + user to change the default action that will occur when a file + is clicked/double-clicked in Nautilus. We have three choices that + map to the three types of actions we currently support. + +2000-06-20 Gene Z. Ragan + + Fixed bug #1221 + + * mime-type-capplet/nautilus-mime-type-capplet.c: + (application_menu_activated), (populate_application_menu), + (component_menu_activated), (populate_component_menu): + Add handling of the case where a default application or + component is not in the default applicaiton or component list. + This involved some UI work and adding the default app to + the default list. Hopefully the gnome-vfs-mime-handler API + will not allow this to happen, but we handle it just in case. + + Cleaned up the way the menu items for the default application + and component are set and added a signal handler to set + the user's choice of application or component to be the default. + +2000-06-20 Gene Z. Ragan + + Fixed bug #1055 + + * libgnomevfs/gnome-vfs-mime-handlers.c: + * libgnomevfs/gnome-vfs-mime-handlers.h: + (gnome_vfs_mime_add_extension): + Renamed function to be more in accordance with other function + in file. + + (gnome_vfs_mime_remove_extension): + New function to remove mapped extension from mime type. + + * libgnomevfs/gnome-vfs-mime-info.c: (load_mime_list_info_from), + (gnome_vfs_mime_get_extensions), (mime_list_sort), (get_key_name), + (gnome_vfs_mime_commit_registered_types), + (write_mime_data_foreach), (write_registered_mime_data): + A couple of things done here. One was work on the tokenizer + so that it handled a variety of cases when reading in + key data form .mime files. Another was work on saving and + deleting mapped extensions from the .mime file. + + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.c: + (nautilus_mime_type_capplet_show_new_extension_window): + Work on saving and deleting mapped extensions from the .mime file. + + * mime-type-capplet/nautilus-mime-type-capplet.c: + (populate_extension_list), + (nautilus_mime_type_capplet_add_extension), + (remove_extension_clicked): + Work on saving and deleting mapped extensions from the .mime file. + +2000-06-20 John Sullivan + + * data/mime/gnome-vfs.keys: Finished renaming of some types + from application/x-foo to text/x-foo. + * data/mime/gnome-vfs.mime: Removed mysterious colons at the + ends of some mime type names that was causing them not to match + the keys. + +2000-06-19 Ramiro Estrugo + + * data/mime/gnome-vfs.keys: + Make mozilla the default + +2000-06-19 Darin Adler + + * libgnomevfs/gnome-vfs-mime-handlers.c: (mime_type_get_supertype): + Made another function tolerant of NULL since we use NULL to mean + unknown MIME type all the time. + +2000-06-19 Darin Adler + + * po/POTFILES.in: Removed mime-data.c to fix build. + +2000-06-19 Gene Z. Ragan + + * mime-type-capplet/mime-data.c: + * mime-type-capplet/mime-data.h: + Removed obsolete files. + + * mime-type-capplet/Makefile.am: + Removed above files from Makefile. + + * libgnomevfs/gnome-vfs-mime-handlers.c: + * libgnomevfs/gnome-vfs-mime-handlers.h: + (gnome_vfs_mime_add_extension_to_mime_type): + New function. Add extension mapping to named mime type + and save to .mime file. + + * libgnomevfs/gnome-vfs-mime-info.c: + * libgnomevfs/gnome-vfs-mime-info.h: + (load_mime_list_info_from), + (load_mime_type_info), (gnome_vfs_mime_get_extensions), + + (gnome_vfs_mime_extension_list_free): + New function to deep free the list returned + by gnome_vfs_mime_get_extensions() + + (gnome_vfs_mime_registered_mime_type_list_free), + New function to deep free the list returned + by gnome_vfs_mime_get_extensions() + + (gnome_vfs_mime_commit_registered_types): + Public function to commit internal hash table + of mime data to disk. + + (gnome_vfs_mime_set_registered_type_key): + This functions sets the key data for the registered mime + type's hash table. + + (write_mime_data_foreach), (write_mime_data): + New functions to write out mime data from hash table. + + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.c: + (nautilus_mime_type_capplet_show_new_mime_window), + (nautilus_mime_type_capplet_show_new_extension_window): + Clean up work on dialogs. + + * mime-type-capplet/nautilus-mime-type-capplet.c: + (ok_callback), + (populate_extension_list), + (nautilus_mime_type_capplet_add_extension), + (remove_extension_clicked), (init_mime_capplet), + (delete_mime_clicked), (create_mime_list_and_scroller), + (get_selected_item_mime_type): + Clean up work on main capplet view. + +2000-06-17 Gene Z. Ragan + + File Types and Programs capplet work in progress. + + * mime-type-capplet/mime-info.c: + * mime-type-capplet/mime-info.h: + Removed obsolete files from capplet. + + * mime-type-capplet/Makefile.am: + Remove above files form makefile. + + * libgnomevfs/gnome-vfs-mime-info.c: + * libgnomevfs/gnome-vfs-mime-info.h: + (list_context_new), (context_destroy_and_unlink), + (load_mime_type_info_from), + (load_mime_list_info_from), (mime_list_load), + (load_mime_type_info), (gnome_vfs_mime_init), + (gnome_vfs_mime_info_clear), (gnome_vfs_mime_info_shutdown), + (get_key_name), (gnome_vfs_get_registered_mime_types): + Various fixes and modifications. Fixed a bug in the + mime key database parser that caused comments to be + read in incorrectly. + + * mime-type-capplet/mime-data.c: + (add_to_key), (add_mime_vals_to_clist), + (add_new_mime_type), (add_new_mime_type), + (write_mime_foreach): + Capplet work in progress. + + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.c: + (nautilus_mime_type_capplet_show_new_mime_window): + Capplet work in progress. + + * mime-type-capplet/nautilus-mime-type-capplet.c: + * mime-type-capplet/nautilus-mime-type-capplet.h: + (main), (g_list_free_deep), (try_callback), (revert_callback), + (ok_callback), (cancel_callback), (populate_extension_list), + (mime_list_selected_row_callback), (init_mime_capplet), + (nautilus_mime_type_capplet_update_info), (delete_mime_clicked), + (edit_applications_clicked), (edit_components_clicked), + (insert_mime_vals_into_clist), (create_mime_list_and_scroller): + Capplet work in progress. + +2000-06-16 Pavel Cisler + + * data/mime/gnome-vfs.mime: + Fix two incorrect mime types. + +2000-06-16 Pavel Cisler + + * libgnomevfs/gnome-vfs-mime-magic.c: + (gnome_vfs_sniff_buffer_looks_like_text), + * libgnomevfs/gnome-vfs-mime-sniff-buffer.h: + Fix bug 1168 - add UTF-8 support to the text mime sniffer. + + * libgnomevfs/gnome-vfs-mime-magic.c: + * libgnomevfs/gnome-vfs-mime-sniff-buffer.h: + (gnome_vfs_get_mime_type_for_buffer), + (gnome_vfs_sniff_buffer_looks_like_mp3): + Fix bug 960 - add algorithmic sniffer for detecting audi/x-mp3 files. + + * libgnomevfs/gnome-vfs-private-ops.c: + (gnome_vfs_open_uri_cancellable): + Fix bug 1189 - removed retry code in open and made it respect the + RANDOM flag as set by the caller. + +2000-06-16 Darin Adler + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_get_default_application): Added a FIXME to note + that we need to enhance the "default-application" feature. + (gnome_vfs_mime_get_default_component): Use the new exported + liboaf.h OAF_ServerInfo_duplicate instead of our own, local, + flawed function. + (gnome_vfs_mime_get_short_list_applications), + (gnome_vfs_mime_get_all_applications), + Prune the list to only ones with applications that "exist" + by calling the new prune_ids_for_nonexistent_applications + function. + (strdup_to), (is_executable_file), (executable_in_path), + (get_executable_name_from_command_string), + (application_known_to_be_nonexistent), + (prune_ids_for_nonexistent_applications): + Write the functions needed for a clean implementation of + prune_ids_for_nonexistent_applications. + (OAF_ServerInfoList_to_ServerInfo_g_list): Use the new exported + liboaf.h OAF_ServerInfo_duplicate instead of our own, local, + flawed function. + +2000-06-16 John Sullivan + + * data/mime/gnome-vfs.keys, + * data/mime/gnome-vfs.mime: + Changed illegal audio/midi to legal audio/x-midi, + and fixed up some font keys that didn't get + updated in synch earlier. + +Fri Jun 16 12:11:32 2000 George Lebl + + * libgnomevfs/gnome-vfs-constants.h: When the long is actually + 64bit, use "ld" and "lu" for the format. + + * libgnomevfs/gnome-vfs-mime-sniff-buffer.c: Include + to fix warnings + + * modules/gconf-method.c: Include and to + fix warnings + + * test/test-async-directory.c (print_list): + test/test-async.c (read_callback): Use the + GNOME_VFS_SIZE_FORMAT_STR format constant to print out sizes + +2000-06-16 Darin Adler + + * libgnomevfs/gnome-vfs-mime-info.c: (gnome_vfs_mime_get_value), + (gnome_vfs_mime_get_keys): Change to support MIME types of NULL + which will make code simpler since NULL is commonly used to mean + "unknown MIME type". + +2000-06-15 Pavel Cisler + + * data/mime/gnome-vfs-mime-magic: + Add mime magic for shell scripts. + +2000-06-15 Pavel Cisler + + * libgnomevfs/gnome-vfs-module-shared.c: + (gnome_vfs_mime_type_from_mode), (gnome_vfs_get_special_mime_type): + * modules/gconf-method.c: (set_mime_type_dir): + * modules/http-method.c: (process_propfind_propstat): + Convert illegal "special/..." mime types to legal ones. + + * data/mime/gnome-vfs-mime-magic: + * data/mime/gnome-vfs.keys: + * data/mime/gnome-vfs.mime: + * libgnomevfs/gnome-vfs-mime-magic.c: + (gnome_vfs_mime_type_from_magic): + Fix all illegal mime types. Reformat the magic table a bit and reorder it + to put ambiguous rules last. + + * modules/http-method.c: (process_propfind_propstat): + Change a TODO: to a FIXME: + Get rid of an extra if before a g_free. + +2000-06-15 Darin Adler + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_get_default_action_type): Fix bug where we would + not fall back to the supertype action if the action type string + was NULL. + (gnome_vfs_mime_get_default_component): Fix bug where we would + free an uninitialized variable. + +2000-06-15 Gene Z. Ragan + + Work in progress on the FIle Types and Programs Capplet + * mime-type-capplet/Makefile.am: + Removed obsolete files form build. + + * mime-type-capplet/edit-window.c: + * mime-type-capplet/edit-window.h: + Obsolete. Removed. + + * mime-type-capplet/new-mime-window.c: + * mime-type-capplet/new-mime-window.h: + Obsolete. Removed. + + * mime-type-capplet/mime-data.c: (add_mime_vals_to_clist), + (selected_row_callback): + + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.c: + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.h: + (edit_applications_dialog_destroy), (application_is_in_list), + (application_button_toggled_callback), + (populate_default_applications_box), + (populate_default_components_box), + (initialize_edit_applications_dialog), + (show_edit_applications_dialog), (show_edit_components_dialog), + (nautilus_mime_type_capplet_show_new_mime_window), + (nautilus_mime_type_capplet_show_new_extension_window): + + * mime-type-capplet/nautilus-mime-type-capplet.c: + * mime-type-capplet/nautilus-mime-type-capplet.h: + (revert_callback), (populate_extension_list), + (nautilus_mime_type_capplet_add_extension), + (add_extension_clicked), (remove_extension), + (extension_list_selected), (extension_list_deselected), + (init_mime_capplet), (nautilus_mime_type_capplet_update_info), + (add_mime_clicked), (edit_components_clicked), + (nautilus_mime_type_capplet_update_application_info), + (nautilus_mime_type_capplet_update_component_info): + +2000-06-15 Darin Adler + + * libgnomevfs/gnome-vfs-gen-mimedb.c: (main): + * libgnomevfs/gnome-vfs-mime-info.c: (gnome_vfs_mime_init): + * libgnomevfs/gnome-vfs-mime-magic.c: + (gnome_vfs_mime_get_magic_table): + * libgnomevfs/gnome-vfs-mime.c: (mime_init): + * mime-type-capplet/mime-data.c: (init_mime_type): + Added FIXMEs to places that get MIME info from the gnome-libs + prefix since we install this stuff in the gnome-vfs prefix. + We already had a bug report about this. + +2000-06-15 John Sullivan + + * data/mime/gnome-vfs.mime, + * data/mime/gnome-vfs.keys: Added description for .lha, + and extension + description for .lhz. + +2000-06-14 Gene Z. Ragan + + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.c: + * mime-type-capplet/nautilus-mime-type-capplet-dialogs.h: + New files. Trying to clean up current capplet source and + organize it in a sensible way. + + (edit_application_dialog_destroy), (edit_component_dialog_destroy), + (populate_default_applications_list), + (populate_preferred_applications_list), (component_is_in_list), + (component_button_toggled_callback), + (populate_default_components_box), + (populate_preferred_components_list), + (initialize_edit_applications_dialog), + (initialize_edit_components_dialog), + (show_edit_applications_dialog), (show_edit_components_dialog), + Brand new functions. + + * mime-type-capplet/Makefile.am: + Added new source file listed above. + + * mime-type-capplet/nautilus-mime-type-capplet.c: + (init_mime_capplet), (populate_application_menu), + (populate_component_menu), (edit_applications_clicked), + (edit_components_clicked): + Work on setting up info view. + +2000-06-14 Maciej Stachowiak + + Part of task 1057: Terminal-based programs should open into a new + terminal window + + * data/mime/application-registry-hack.keys: Set requires_terminal + setting for everything. + * libgnomevfs/gnome-vfs-mime-handlers.h, + libgnomevfs/gnome-vfs-mime-handlers.c + (gnome_vfs_mime_application_new_from_id): Add requires_terminal + field to the GnomeVFSMimeApplication structure and initialize it + appropriately. + * test/test-mime-handlers.c (print_application): Print the + require_terminal setting. + +2000-06-14 John Sullivan + + * data/mime/gnome-vfs.keys: + Maciej meant to change application/x-sh to + text/x-sh, but didn't quite finish the job; + also removed application/x-sh and application/x-tcl. + +2000-06-14 Pavel Cisler + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_application_list_free), + (gnome_vfs_mime_component_list_free): + Fix two leaks John and I found. + +2000-06-13 Gene Z. Ragan + + More work in progress and added a new file to the capplet build. + + * mime-type-capplet/nautilus-mime-type-capplet.c: (main), + (init_mime_capplet), (edit_applications_clicked), + (edit_components_clicked), (edit_application_dialog_destroy), + (initialize_edit_application_dialog), + (show_edit_applications_dialog), (show_edit_components_dialog): + + * mime-type-capplet/nautilus-mime-type-capplet.h: + New file + +2000-06-13 Gene Z. Ragan + + Work in progress on the File Types and Program capplet + + * mime-type-capplet/edit-window.c: (initialize_main_win): + * mime-type-capplet/mime-data.c: (get_priority), (add_to_key), + (mime_fill_from_file), (add_mime_vals_to_clist), + (selected_row_callback), (create_mime_clist), (add_new_mime_type): + + * mime-type-capplet/mime-data.h: + * mime-type-capplet/nautilus-mime-type-capplet.c: + (init_mime_capplet), (nautilus_mime_type_capplet_update_info), + (populate_application_menu), (populate_component_menu), + (free_mime_info), (delete_mime_clicked), (add_mime_clicked), + (edit_applications_clicked), (edit_components_clicked): + +2000-06-13 Maciej Stachowiak + + * data/mime/gnome-vfs.keys, data/mime/gnome-vfs.mime: Update file + manager view IIDs, and use text/x-foo as the preferred mime type + for more things that used to be application/x-foo. + + * libgnomevfs/gnome-vfs-mime-handlers.c + (gnome_vfs_mime_get_default_component): Fix type inserted when + adding sort conditions. + + * libgnomevfs/gnome-vfs-mime-handlers.c + (gnome_vfs_mime_get_default_component):FIx part of FIXME 1145; + prefer a component of the short list as a fallback default if no + explicit default. + (gnome_vfs_mime_get_short_list_components): Fix a bug in the query. + +2000-06-13 Maciej Stachowiak + + Bugzilla task #1074 + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_get_default_action_type, + gnome_vfs_mime_get_default_application, + gnome_vfs_mime_get_default_component, + gnome_vfs_mime_get_short_list_applications, + gnome_vfs_mime_get_short_list_components, + gnome_vfs_mime_get_all_applications): Added support for trying the + supertype. + (gnome_vfs_mime_str_list_merge, + gnome_vfs_mime_str_list_apply_delta, + gnome_vfs_mime_do_short_list_processing): New or modified helper + functions. + (process_app_list): Changed to take a GList of IDs instead of a + comma-separated string. + * data/mime/gnome-vfs.keys: Added text/* entry. + +2000-06-13 Maciej Stachowiak + + * libgnomevfs/gnome-vfs-mime-handlers.c + (gnome_vfs_mime_get_all_components): Fix broken query. + +2000-06-13 Maciej Stachowiak + + * data/mime/gnome-vfs.keys, data/mime/gnome-vfs.mime: Made + canonical mime types for shell and c-shell scripts text/x-sh and + text/x-csh, not application/x-sh and application/x-csh. + +2000-06-12 Maciej Stachowiak + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_set_default_application), + (gnome_vfs_mime_set_default_component): + Set the default action type if it had no + previous value. + +2000-06-12 Ramiro Estrugo + + * libgnomevfs/Makefile.am: + Make the private header really private by not installing it. + +2000-06-12 Eskil Heyn Olsen + + * gnome-vfs.spec.in: Changed the Requires to what the configure.in + is actually checking for. + * libgnomevfs/Makefile.am: Added + gnome-vfs-mime-sniff-buffer-private.h to HEADERS. + * mime-type-capplet/Makefile.am: added a -D to install of the + .desktop file. Ensures that the dir is there during rpm -ta. + + Can now build a gnome-vfs rpm. + +2000-06-09 John Sullivan + + Fixed bug 1302: can't undo mmap with g_free. Nautilus was + sometimes crashing on exit due to this bug. + + * libgnomevfs/gnome-vfs-mime-magic.c: + Added global variables to keep track of mmap size and + whether mmap was used. + (gnome_vfs_mime_get_magic_table): + #ifdef declarations of variables only used in _POSIX_MAPPED_FILES + case; use new globals to keep track of mmap size and + whether mmap was used; check for MAP_FAILED case. + (gnome_vfs_mime_clear_magic_table): Call munmap and not g_free + if mmap was used. + +2000-06-10 Sung-Hyun Nam + + * configure.in (ALL_LINGUAS): added ko + +2000-06-08 Maciej Stachowiak + + * libgnomevfs/gnome-vfs-mime-handlers.c + (gnome_vfs_mime_get_default_component, + gnome_vfs_mime_get_short_list_components, + gnome_vfs_mime_get_all_components): Fix the queries + +2000-06-08 Darin Adler + + * libgnomevfs/gnome-vfs-uri.c: (gnome_vfs_uri_get_basename), + (gnome_vfs_uri_extract_short_path_name): + * libgnomevfs/gnome-vfs-utils.c: (gnome_vfs_escape_string), + (gnome_vfs_unescape_string), (gnome_vfs_unescape_for_display): + Added code to handle NULL for the text of a URI. The old code + would overreact and segfault. + +2000-06-08 Maciej Stachowiak + + * libgnomevfs/gnome-vfs-mime-handlers.c + (gnome_vfs_mime_get_short_list_components, + gnome_vfs_mime_get_all_components): Expand the queries to be + closer to giving a superset of what Nautilus does. + +2000-06-08 Darin Adler + + More leak fixes. + + * libgnomevfs/Makefile.am: + * libgnomevfs/gnome-vfs-mime-private.h: + Added a private header for some new calls. Made it really + private, meaning it's not installed into the prefix include + directory, unlike the old "private" files which are installed. + + * libgnomevfs/gnome-vfs-mime-info.c: + (gnome_vfs_mime_info_shutdown): Added this new function which + calls gnome_vfs_mime_info_clear and then does the rest of the + cleanup which can only be done at shutdown time. + + * libgnomevfs/gnome-vfs-mime-info.h: gnome_vfs_mime_info_clear + is now a private call. + + * libgnomevfs/gnome-vfs-mime-magic.c: + (gnome_vfs_mime_get_magic_table): Put the mmap call inside an + ifdef _POSIX_MAPPED_FILES for better portability. + (gnome_vfs_mime_clear_magic_table): Added a FIXME because we + can't undo an mmap call with a g_free call! + + * libgnomevfs/gnome-vfs-mime.c: + (remove_one_mime_hash_entry): Fixed leak by freeing the items + in the list, not just the list. + (gnome_vfs_mime_shutdown): Fixed leak by destroying the hash + tables and the directory names. + (gnome_vfs_mime_type_or_default): Simplified logic for freeing + the upext. + + * libgnomevfs/gnome-vfs-mime-handlers.h: Some formatting and + cleanup. + +2000-06-08 Maciej Stachowiak + + * libgnomevfs/gnome-vfs-init.c: (gnome_vfs_shutdown): + * libgnomevfs/gnome-vfs-mime-info.c: (gnome_vfs_mime_info_clear), + (gnome_vfs_mime_info_reload): + * libgnomevfs/gnome-vfs-mime-info.h: + * libgnomevfs/gnome-vfs-mime-magic.c: + (gnome_vfs_mime_clear_magic_table): + * libgnomevfs/gnome-vfs-mime-sniff-buffer.h: + * libgnomevfs/gnome-vfs-mime.c: (mime_extensions_empty), + (maybe_reload), (gnome_vfs_mime_shutdown): + * libgnomevfs/gnome-vfs-mime.h: + Add calls that clear the different mime type tables and call them + from gnome_vfs_shutdown. + + * libgnomevfs/gnome-vfs-mime.c: + (gnome_vfs_mime_type_or_default): + Fix a leak. + +2000-06-07 Darin Adler + + * libgnomevfs/gnome-vfs-backend.c: (func_lookup): + Fixed a storage leak. + + * test/test-async-cancel.c: (file_open_fail_callback), + (test_open_fail), (main): Added a test. + +2000-06-06 Pavel Cisler + + * libgnomevfs/gnome-vfs-directory-list.c: + (gnome_vfs_directory_list_load), + (gnome_vfs_directory_list_load_from_uri): + Fix a storage and file descriptor leak. + + * libgnomevfs/gnome-vfs-mime.c: (gnome_vfs_mime_type_or_default): + Fix a leak. + +2000-06-06 Ramiro Estrugo + + * libgnomevfs/gnome-vfs-mime-handlers.c: (get_user_level): + Use "/apps/nautilus" instead of "/nautilus" to conform to the + gconf "standard" + + Thanks to andersca@gnu.org for pointing this out. + +2000-06-06 Ramiro Estrugo + + * configure.in: + Require only "gconf" not "gconf-gtk" + +2000-06-06 Maciej Stachowiak + + * libgnomevfs/gnome-vfs-mime-info.h, + libgnomevfs/gnome-vfs-mime-info.c + (gnome_vfs_mime_info_reload): New call to force reloading of the + MIME database. + (maybe_reload): Use gnome_vfs_mime_info_reload if we decide to + reload. + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_get_short_list_applications), + (gnome_vfs_mime_set_default_action_type), + (gnome_vfs_mime_set_default_application), + (gnome_vfs_mime_set_default_component), + (gnome_vfs_mime_set_short_list_applications), + (gnome_vfs_mime_set_short_list_components), + (gnome_vfs_mime_extend_all_applications), + (gnome_vfs_mime_remove_from_all_applications), + (gnome_vfs_mime_define_application): call + gnome_vfs_mime_info_reload when done reloading. + (gnome_vfs_mime_set_short_list_applications): Rewritten for + correct memory management and improved clarity. + +2000-06-06 John Sullivan + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_remove_component_from_short_list): + Fixed an application -> component typo. + +2000-06-06 Pavel + + * libgnomevfs-corba/gnome-vfs-slave.c: (copy_metadata): + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_get_all_applications): + * libgnomevfs/gnome-vfs-module-shared.c: + * modules/extfs-method.c: (do_open_directory): + Renumber some FIXMEs after marking them as duplicates. + Fix a wrong FIXME number. + +2000-06-06 Pavel + + * devel-docs/gnome-vfs-tutorial/gnome-vfs-tutorial.sgml: + * doc/writing-modules.sgml: + * modules/extfs-method.c: (do_open): + Added more bug numbers to FIXMEs. + Changed some mentions of FIXMEs to FixMes to make them + not trigger the FIXME tool. + +2000-06-05 Seth Nickell + + * libgnomevfs/gnome-vfs-uri.c: (gnome_vfs_uri_extract_short_name): + Modified to call gnome_vfs_unescape_string on the "short_name" + before returning. + * libgnomevfs/gnome-vfs-utils.c: (gnome_vfs_unescape_string): + Added a g_assert to make sure length of returned string is correct + (gnome_vfs_unescape_for_display): + * libgnomevfs/gnome-vfs-utils.h: + New function similar to unescape_string except that it returns + the string formatted better for display - i.e. with "invalid" + escape sequences and ASCII 0 still escaped + * test/test-escape.c: (test_unescape), (test_unescape_display), + (main): + Added more test cases for escape code, improve output, added + test code for gnome_vfs_unescape_for_display + +2000-06-05 Pavel Cisler + + * libgnomevfs-corba/gnome-vfs-slave.c: (serve_channel_read), + (serve_channel_write): + * libgnomevfs-pthread/gnome-vfs-job-slave.c: + * mime-type-capplet/edit-window.c: (populate_application_menu): + * mime-type-capplet/mime-data.c: (add_to_key): + * modules/extfs-method.c: (do_open), (read_directory_list), + (do_open_directory), (match): + * modules/extfs/cpio.in: + * modules/extfs/lha.in: + * modules/file-method.c: (read_directory): + * modules/gconf-method.c: (directory_handle_destroy): + Added more bug numbers to FIXMEs. + Fixed one misspelled FIXME that made it show up in the check-FIXME.pl tool. + +2000-06-05 Pavel Cisler + + * libgnomevfs/gnome-vfs-xfer.c: (call_progress), + (count_items_and_size), (handle_name_conflicts), (copy_file), + (copy_directory), (copy_items), (gnome_vfs_xfer_uri_internal), + (gnome_vfs_xfer_private): + Added more bug numbers to FIXMEs. + +2000-06-05 Darin Adler + + * libgnomevfs-corba/gnome-vfs-async-ops.c: + * libgnomevfs-corba/gnome-vfs-corba.c: (gnome_vfs_corba_init): + * libgnomevfs-corba/gnome-vfs-slave-notify.c: + (impl_Notify_load_directory): + * libgnomevfs-corba/gnome-vfs-slave-process.c: + (gnome_vfs_slave_process_reset), (gnome_vfs_slave_process_destroy): + * libgnomevfs/gnome-vfs-directory-list.c: + * libgnomevfs/gnome-vfs-handle.c: (gnome_vfs_handle_do_close): + * libgnomevfs/gnome-vfs-parse-ls.c: + * libgnomevfs/gnome-vfs-private-ops.c: + (gnome_vfs_open_uri_cancellable): + * libgnomevfs/gnome-vfs-private-utils.c: + * libgnomevfs/gnome-vfs-result.c: (gnome_vfs_result_from_errno), + (gnome_vfs_result_from_h_errno): + * libgnomevfs/gnome-vfs-seekable.c: (do_open), (do_create), + (do_truncate_handle): + * libgnomevfs/gnome-vfs-shellpattern-filter.c: + (gnome_vfs_shellpattern_filter_new): + * libgnomevfs/gnome-vfs-types.h: + * libgnomevfs/gnome-vfs-uri.c: (get_method_string), + (parse_uri_substring), (gnome_vfs_uri_append_path), + (gnome_vfs_uri_to_string), (gnome_vfs_uri_is_local): + * libgnomevfs/gnome-vfs-utils.h: + Added more bug numbers to FIXMEs. + +2000-06-05 John Sullivan + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_set_default_application): + Tiny reformatting. + +2000-06-05 John Sullivan + + Refactored and made some helper functions public so + clients that modify the program lists don't need to + replicate a bunch of code. + + * libgnomevfs/gnome-vfs-mime-handlers.h: + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_id_in_application_list), + (gnome_vfs_mime_id_in_component_list): + Made these functions public. + + (gnome_vfs_mime_id_list_from_application_list), + (gnome_vfs_mime_id_list_from_component_list): + Gave these existing functions more public-sounding + names and made them public. + + (gnome_vfs_mime_remove_application_from_list), + (gnome_vfs_mime_remove_component_from_list): + New public helper functions, extracted from the + _short_list versions. + + (gnome_vfs_mime_add_application_to_short_list), + (gnome_vfs_mime_add_component_to_short_list), + (gnome_vfs_mime_remove_application_from_short_list), + (gnome_vfs_mime_remove_component_from_short_list): + Modified to call the new helper functions and + reflect the renamings. + +2000-06-05 Darin Adler + + * modules/bzip2-method.c: + (bzip2_method_handle_init_for_decompress), + (bzip2_method_handle_init_for_compress), (do_close), (do_read): + * modules/file-method.c: (do_close), (set_mime_type), + (do_find_directory), (rename_helper): + * modules/ftp-method.c: + * modules/gconf-method.c: (directory_handle_destroy), + (get_value_size): + * modules/gzip-method.c: (gzip_method_handle_init_for_deflate), + (result_from_z_result), (do_open), (do_create), (do_close), + (do_read): + * modules/http-method.c: (http_file_handle_new), + (http_status_to_vfs_result), (create_handle), (do_create): + Added more bug numbers to FIXMEs. + +2000-06-05 Pavel Cisler + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_action_free): + * libgnomevfs/gnome-vfs-mime-handlers.h: + * libgnomevfs/gnome-vfs-mime-magic.c: + (gnome_vfs_mime_magic_matches_p), + (gnome_vfs_sniff_buffer_looks_like_text): + * libgnomevfs/gnome-vfs-module-shared.c: + (gnome_vfs_mime_type_from_mode), + (gnome_vfs_get_special_mime_type): + * libgnomevfs/gnome-vfs-parse-ls.c: + Added more bug numbers to FIXMEs. + +2000-06-05 Darin Adler + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_get_default_component), + (gnome_vfs_mime_get_short_list_components), + (gnome_vfs_mime_get_all_components), + (gnome_vfs_mime_set_default_action_type), + (gnome_vfs_mime_set_default_application), + (gnome_vfs_mime_set_default_component), + (gnome_vfs_mime_set_short_list_applications), + (gnome_vfs_mime_set_short_list_components), + (gnome_vfs_mime_extend_all_applications), + (gnome_vfs_mime_remove_from_all_applications), + (gnome_vfs_mime_define_application), (get_user_level): + * modules/extfs-method.c: (do_open_directory): + Added bug numbers to FIXMEs. + + * libgnomevfs-corba/gnome-vfs-async-ops.c: + (corba_gnome_vfs_async_xfer): + Fixed the formatting of a FIXME bug. + +2000-06-05 John Sullivan + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_application_copy), + (gnome_vfs_mime_application_free): Made these + two routines accept NULL parameters. + +2000-06-05 Pavel Cisler + + * libgnomevfs-corba/gnome-vfs-async-ops.c: + (corba_gnome_vfs_async_xfer): + * libgnomevfs-corba/gnome-vfs-slave-notify.c: (impl_Notify_reset): + * libgnomevfs-corba/gnome-vfs-slave-process.c: + * libgnomevfs-corba/gnome-vfs-slave-process.h: + * libgnomevfs-corba/gnome-vfs-slave.c: (copy_metadata): + * libgnomevfs-pthread/gnome-vfs-async-ops.c: + (pthread_gnome_vfs_async_cancel): + * libgnomevfs-pthread/gnome-vfs-job-slave.c: + (gnome_vfs_job_slave_new): + * libgnomevfs-pthread/gnome-vfs-job.c: + * libgnomevfs-pthread/gnome-vfs-job.h: + * libgnomevfs/gnome-vfs-configuration.c: + * libgnomevfs/gnome-vfs-directory.c: + * libgnomevfs/gnome-vfs-messages.h: + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_get_default_component), + (gnome_vfs_mime_get_short_list_components), + (gnome_vfs_mime_get_all_applications), + (gnome_vfs_mime_get_all_components), + (gnome_vfs_mime_extend_all_applications), + (gnome_vfs_mime_remove_from_all_applications), (join_str_list), + (get_user_level): + Added bug numbers to FIXMEs. + +2000-06-05 Mathieu Lacage + + * libgnomevfs/Makefile.am: add OAF_CFLAGS to include + so that oaf.h is picked up when oaf is not in GNOME prefix. + * test/Makefile.am : idem. + +2000-06-05 Darin Adler + + * modules/http-method.c: + * modules/newftp-method.c: (do_open_directory), + (do_make_directory): + * modules/pipe-method.c: (do_close): + * test/gnome-file-selection/gicon.c: (get_stock_icon), + (get_stock_overlay), (get_default_icon), + (gicon_get_icon_for_file_2): + * test/gnome-file-selection/gnome-file-selection-history.c: + * test/gnome-file-selection/gnome-file-selection.c: + (update_directory_combo_list), (setup_directory_combo_and_toolbar), + (destroy), (class_init), (init): + * test/test-info.c: + Added bug numbers to FIXMEs. + + * mime-type-capplet/edit-window.c: (destruction_handler), + (initialize_main_win), (launch_edit_window), + (populate_application_menu): + Got rid of the fixed-length mime_string field. + + * modules/file-method.c: (read_link), (get_stat_info): + Some minor tweaks on the code Rebecca just checked in. + There was a little problem with unsigned integers. + +2000-06-05 Rebecca Schulman + + * modules/file-method.c + Fixed lack of error handling for readlink call in read_link. + +2000-06-05 Darin Adler + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_get_default_component), + (gnome_vfs_mime_get_short_list_applications), + (gnome_vfs_mime_get_short_list_components), + (gnome_vfs_mime_get_all_applications), + (gnome_vfs_mime_get_all_components), + (gnome_vfs_mime_set_default_action_type), + (gnome_vfs_mime_set_default_application), + (gnome_vfs_mime_set_default_component), + (gnome_vfs_mime_set_short_list_applications), + (gnome_vfs_mime_set_short_list_components), + (id_list_from_component_list), + (gnome_vfs_mime_add_application_to_short_list), + (gnome_vfs_mime_remove_application_from_short_list), + (gnome_vfs_mime_add_component_to_short_list), + (gnome_vfs_mime_remove_component_from_short_list), + (gnome_vfs_mime_extend_all_applications), + (gnome_vfs_mime_remove_from_all_applications), + (gnome_vfs_mime_define_application), (gnome_vfs_mime_action_free), + (gnome_vfs_mime_application_list_free), + (gnome_vfs_mime_component_list_free), (str_to_bool), (bool_to_str), + (join_str_list): + Added free calls to get rid of many storage leaks. + Added more FIXMEs. + Replaced lots of use of \' with just plain '. + Replaced retval with variable names that are words in many places. + Other reformatting and tweaking. + +2000-06-05 Ramiro Estrugo + + * data/mime/gnome-vfs.keys: + +2000-06-04 Ian McKellar + + * modules/newftp-method.c: (read_response_line), + (ftp_connection_aquire), (do_open), (internal_get_file_info), + (do_open_directory), (do_make_directory), (do_remove_directory), + (do_move), (do_unlink): + Fixed this lots. It should now fail gracefully if it can't connect or + log into a server, and it should reconnect if a connection times out. + +2000-06-02 John Sullivan + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_add_application_to_short_list), + (gnome_vfs_mime_remove_application_from_short_list), + (gnome_vfs_mime_add_component_to_short_list), + (gnome_vfs_mime_remove_component_from_short_list): + Added implementations for these formerly empty functions. + + (gnome_vfs_mime_application_has_id), + (gnome_vfs_mime_id_matches_application), + (gnome_vfs_mime_id_matches_component), + (gnome_vfs_mime_application_matches_id), + (gnome_vfs_mime_component_matches_id), + (gnome_vfs_mime_id_in_application_list), + (gnome_vfs_mime_id_in_component_list), + (id_list_from_application_list), (id_list_from_component_list), + (g_list_free_deep): New helper functions used in the + implementations of the add/remove functions. Most of these + are replicated in nautilus_mime_action.c. I will make another + pass to share code later. + + (gnome_vfs_mime_get_short_list_applications), + (gnome_vfs_mime_get_short_list_components): Fixed mistakes + where the wrong list items were compared against, and added + clarifying parentheses. There is still a bug that I couldn't + find where these routines do not correctly include user additions + to the lists. I'm writing this up. + +2000-06-02 Darin Adler + + * libgnomevfs/gnome-vfs-xfer.c: + (gnome_vfs_new_directory_with_unique_name): + Fixed a URI leak. + + * libgnomevfs/gnome-vfs-mime-handlers.c: (get_user_level): + Tweaked gconf_init and some formatting. + +2000-06-02 Gene Z. Ragan + + * mime-type-capplet/edit-window.c: + (populate_application_menu): + More work on handling the logic of populating the menu + and handling special cases where short list, default application + and applicaiton list may be NULL or empty. + +2000-06-02 John Sullivan + + * libgnomevfs/gnome-vfs-mime-handlers.h, + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_add_application_to_short_list), + (gnome_vfs_mime_remove_application_from_short_list), + (gnome_vfs_mime_add_component_to_short_list), + (gnome_vfs_mime_remove_component_from_short_list): + Added prototypes and empty bodies for these new + convenience functions. Implementations coming soon. + +2000-06-02 Gene Z. Ragan + + More work in progress on the capplet. Still incomplete. + + * mime-type-capplet/edit-window.c: + (initialize_main_win), + (populate_application_menu): + The Application window now displays the shortlist and selected + the default application if it is present in the short list. + + (add_application): + All of the mchinery is hooked up, but the API does not seem to + be registering the new choice. + +2000-06-02 Gene Z. Ragan + + More work in progress on the capplet. Still incomplete. + + * mime-type-capplet/edit-window.c: (initialize_main_win_vals), + (show_edit_window), (populate_application_menu), + (populate_component_menu), (application_menu_activate), + (add_application), (show_file_selector): + Work in progress. + + * mime-type-capplet/mime-data.c: (add_to_key): + Work in progress. + +2000-06-02 John Sullivan + + * data/mime/gnome-vfs.keys: + * data/mime/gnome-vfs.mime: + Added application/x-gnumeric at andersca's suggestion. + +2000-06-02 Darin Adler + + * libgnomevfs/gnome-vfs-utils.c: + * libgnomevfs/gnome-vfs-utils.h: + * test/test-escape.c: (main): + Updated escape and test to not escape "+" except if explicitly + asked. This makes the path escape function more useful for the + real case of converting a path to a URI. + + * test/.cvsignore: Ignore test-mime-handlers-set. + +2000-06-02 Ramiro Estrugo + + * libgnomevfs/gnome-vfs-mime-handlers.c: (get_user_level): + Use a GConfEngine directly to avoid depending on the Gtk object + system. + +2000-06-01 Maciej Stachowiak + + * data/mime/gnome-vfs.keys: Define short-list components for + text/plain + + First half of task 370 (write APIs for mime handler stuff) + + * libgnomevfs/gnome-vfs-mime-handlers.h, + libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_set_default_action_type, + gnome_vfs_mime_set_default_application, + gnome_vfs_mime_set_default_component, + gnome_vfs_mime_set_short_list_applications, + gnome_vfs_mime_set_short_list_components, + gnome_vfs_mime_extend_all_applications, + gnome_vfs_mime_remove_from_all_applications): Implemented (w/ some + slight interface changes relative to old headers/stubs. + + (gnome_vfs_mime_define_application): New function. + + (bool_to_str, gnome_vfs_strsplit_to_list, + gnome_vfs_strjoin_from_list, comma_separated_str_to_str_list, + str_list_to_comma_separated_str, str_list_difference): More helper functions. + + * test/test-mime-handlers-set.c: Test for mime handler setter + APIs. + * test/Makefile.am: Build it. + + * mime-type-capplet/edit-window.c (add_application): Remove + now-invalid call to gnome_vfs_mime_set_default_application w/ + comment on how to do it better. + +2000-06-01 Darin Adler + + * libgnomevfs/gnome-vfs-utils.h: + * libgnomevfs/gnome-vfs-utils.c: (gnome_vfs_escape_string), + (hex_to_int), (gnome_vfs_unescape_string): Fixed escape string to + handle characters in a way that matches the URI RFC instead of + being "conservative" and escaping everything. Also fixed to escape + some characters it wasn't escaping and did code cleanup. Changed + the API to gnome_vfs_unescape_string and made it handle cases where + there are bad escape sequences or bad characters by returning NULL. + + * modules/file-method.c: (get_path_from_uri), (get_base_from_uri), + (do_open), (do_create), (do_close), (do_read), (do_write), + (do_truncate), (directory_handle_new), (do_open_directory), + (do_get_file_info), (do_get_file_info_from_handle), + (do_make_directory), (do_remove_directory), (do_find_directory), + (rename_helper), (do_move), (do_unlink), (do_check_same_fs), + (do_set_file_info): Handled URI escaping in every call. This + involved unescaping URIs and handling the cases where there are + bad characters. + + * test/test-escape.c: (test_escape), (test_unescape), (main): + Added code to test both the escape and unescape functions. It's a + lot easier to get it right if it's tested :-) This test gets run + as part of make check. + + * libgnomevfs/gnome-vfs-uri.c: (gnome_vfs_uri_append_file_name), + (gnome_vfs_uri_extract_short_name): Update for the new name of the + parameter to gnome_vfs_escape_string. + +2000-06-01 John Sullivan + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_application_copy): Oops, this wasn't + updated to copy the new id field, wreaking havoc on + my Nautilus code. + +2000-06-01 John Sullivan + + * data/mime/gnome-vfs.keys: Fixed the application short + lists for text/plain, text/html, and special/webdav-directory. + +2000-06-01 Darin Adler + + * libgnomevfs/gnome-vfs-mime-handlers.c: (get_user_level): Added + fake parameters to the gconf_init call. It just won't put up with + 0/NULL as argc/argv. + + * test/test-escape.c: (test_escape), (main): More test code (work + in progress). + +2000-06-01 John Sullivan + + * data/mime/application-registry-hack.keys: + added entry for eog. + * data/mime/gnome-vfs.keys: + added a couple of text applications to the complete list + for text/html, so we can test full-list-longer-than-short-list. + +2000-06-01 Darin Adler + + * data/mime/gnome-vfs.keys: Checked in a full version. I + accidentally truncated this with my last check-in. Also forgot to + mention in my last check-in that I had changed the name from + componet to component for xpdf (which I also updated). + + * test/Makefile.am: + * test/.cvsignore: + * test/test-escape.c: (stop_after_log), (make_asserts_break), + (test_failed), (main): Started a new test for the escape/unescape + functions. + +2000-06-01 Maciej Stachowiak + + * libgnomevfs/gnome-vfs-mime-handlers.c (OAF_ServerInfo__copy): + Implement copying of the attribute list properly by jumping + through all the CORBA hoops. + +2000-06-01 Darin Adler + + A set of changes to make the short lists be based on the user + level. I'm not wild about adding the GConf dependency nor about + the 3 identical lists for every MIME type, but for now this is + what we designed. + + * configure.in: Changed to always require GConf, not just + conditionally. + + * data/mime/gnome-vfs.keys: Updated the short list keys to have + a separate list for each user level. + + * libgnomevfs/Makefile.am: Added GConf to what's linked with the + gnome-vfs library. + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_get_short_list_applications), + (gnome_vfs_mime_get_short_list_components), (get_user_level): + Added code to get the user level and include the user level name + in the attribute name that's sought ought in the MIME data. + + * modules/gconf-method.c: Fixed build warnings. + +2000-06-01 Maciej Stachowiak + + * data/mime/gnome-vfs.keys: Added short list and default + components to all appropriate types. Expanded application info for + some types. + +2000-06-01 Maciej Stachowiak + + * libgnomevfs/gnome-vfs-mime-handlers.c + (gnome_vfs_mime_application_new_from_id): Get + "can_open_multiple_files" and "can_open_uris" from the right + properties. + +2000-06-01 JP Rosevear + + * mime-type-capplet/Makefile.am: Make the capplet build if gnomevfs + isn't already installed. + + * libgnomevfs-corba/gnome-vfs-corba.c: Use only the oaf stuff + + * libgnomevfs-corba/gnome-vfs-slave.c: ditto + + * libgnomevfs/Makefile.am: Remove oaf conditionals since we require + oaf now + + * libgnomevfs-corba/Makefile.am: + + * configure.in: Check for oaf >= 0.3.0 and make it mandatory + +2000-06-01 Maciej Stachowiak + + * libgnomevfs/gnome-vfs-mime-handlers.h: Added `id' field to + GnomeVFSMimeApplication struct. + * libgnomevfs/gnome-vfs-mime-handlers.c + (gnome_vfs_mime_application_new_from_id): Set the id field. + + * libgnomevfs/gnome-vfs-mime-handlers.h, + libgnomevfs/gnome-vfs-mime-handlers.c + (gnome_vfs_mime_get_default_action_type): New function which only + determines and returns the default action type. Needed for + _for_uri versions of stuff in nautilus. + (gnome_vfs_mime_get_default_action): Use it. + + * data/mime/gnome-vfs.keys: Populated with a bit more data. + +2000-05-31 Maciej Stachowiak + + * libgnomevfs/gnome-vfs-mime-handlers.h, + libgnomevfs/gnome-vfs-mime-handlers.c: Removed the _for_uri + versions of these calls; they've been moved to Nautilus for now + since they will require reading metadata. + +2000-05-31 Darin Adler + + * libgnomevfs/gnome-vfs-directory.c: (directory_visit_internal), + (gnome_vfs_directory_visit_files_at_uri): + * libgnomevfs/gnome-vfs-uri.h: + * libgnomevfs/gnome-vfs-uri.c: (gnome_vfs_uri_append_file_name): + * libgnomevfs/gnome-vfs-xfer.c: (empty_directory), + (gnome_vfs_visit_list), (handle_name_conflicts), (copy_directory), + (copy_items), (move_items), (gnome_vfs_xfer_delete_items), + (gnome_vfs_new_directory_with_unique_name): + A quick fix to Seth's check-in. He also forgot a ChangeLog. + The change was to adda new append_file_name call that handles + escaping correctly for combining a file name with a URI. + + * test/.cvsignore: Ignore some new test programs. + +2000-05-31 John Sullivan + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_get_short_list_applications), + (gnome_vfs_mime_get_short_list_components), + (gnome_vfs_mime_get_all_applications), + (gnome_vfs_mime_get_all_components): Made these + routines bail out immediately when passed NULL + as the mime type. Maciej can flog me and change + them back if he wants. (This prevents lots of + spam when dealing with files that don't have + any MIME type.) + +2000-05-31 John Sullivan + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (get_mime_type_from_uri_hack), + (gnome_vfs_mime_get_short_list_applications_for_uri), + (gnome_vfs_mime_get_short_list_components_for_uri), + (gnome_vfs_mime_get_all_applications_for_uri), + (gnome_vfs_mime_get_all_components_for_uri): Added some + temporary hacks so the _for_uri calls "work" by calling + through to the mime-type-based ones. + +2000-05-31 John Sullivan + + Couldn't wait for Maciej for a few bits here. + + * libgnomevfs/gnome-vfs-mime-handlers.h: + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_application_copy): New function + (gnome_vfs_mime_application_free): Supplied implementation. + (gnome_vfs_mime_application_list_free), + (gnome_vfs_mime_component_list_free): New functions. + +2000-05-31 Gene Z. Ragan + + Work in progress for the modified Files and Programs + capplet that is relacing the old mime types capplet + in the Gnome Control Center. + + * mime-type-capplet/Makefile.am: + Added link dependeny to libgnomevfs. + + * mime-type-capplet/edit-window.c: + (add_extension), (remove_extension): + Rename functions to be more coherent. + + (initialize_main_win), (initialize_main_win_vals): + Modified functions to remove dialog items + that are obsolete in our new designs. Added new + items such as the application and component menus. + + (populate_application_menu), + (populate_component_menu), (application_menu_activate): + Application menu functions that list the short + list of applications for a mime type and allow a user + to add applications to the short list. + + (add_application), (show_file_selector): + Menu callback and function to display GtkFileSelection to + allow user to locate an application to be associated with + mime type. + + * mime-type-capplet/mime-data.c: + (add_new_mime_type): + Modified functions for new mime APIs. + + * mime-type-capplet/new-mime-window.c: (launch_new_mime_window): + Modified functions for new mime APIs. + + * modules/file-method.c: (file_handle_new): + Modified functions for new mime APIs. + +2000-05-31 Dan Winship + + * data/mime/gnome-vfs-mime-magic: + * data/mime/gnome-vfs.keys: application/postscript doesn't have an + x-, the registered type for Word is application/msword, and word + processing formats in general are application/*, not text/* + (because text/ means you can read it raw if you have to). Also, + make some descriptions more consistent, and sync some types + between the files where they differed. + +2000-05-31 Pablo Saratxaga + + * data/mime/gnome-vfs-mime-magic: + * data/mime/gnome-vfs.mime: + * data/mime/gnome-vfs.keys: + add new mime types. + + +2000-05-31 Ramiro Estrugo + + * Makefile.am: + * configure.in: + + Now hook up the documentation generation up. + +2000-05-31 Ramiro Estrugo + + * devel-docs/.cvsignore: + * devel-docs/Makefile.am: + * devel-docs/gnome-vfs-mime-type-handling.txt: + * devel-docs/gnome-vfs-tutorial/.cvsignore: + * devel-docs/gnome-vfs-tutorial/Makefile.am: + * devel-docs/gnome-vfs-tutorial/gnome-vfs-tutorial.sgml: + * devel-docs/gnome-vfs/.cvsignore: + * devel-docs/gnome-vfs/Makefile.am: + * devel-docs/gnome-vfs/gnome-vfs-decl.txt: + * devel-docs/gnome-vfs/gnome-vfs-docs.sgml: + * devel-docs/gnome-vfs/gnome-vfs-sections.txt: + * devel-docs/gnome-vfs/tmpl/gnome-vfs-mime-info.sgml: + * devel-docs/gnome-vfs/tmpl/gnome-vfs-mime.sgml: + * devel-docs/gnome-vfs/tmpl/libgnome-vfs.sgml: + * man/.cvsignore: + * man/Makefile.am: + * man/gnome-vfs-mime.5.in: + + Import gnome mime documentation from gnome-libs so that it can be + properly updated over here in gnome-vfs. + +2000-05-31 Maciej Stachowiak + + * libgnomevfs/Makefile.am: Conditionally compile in oaf-based + stuff. + + Complete bugzilla task #586 in a functional albeit somewhat + hackish way that is in need of much code cleanup and some + internals redesign. + + * libgnomevfs/gnome-vfs-mime-handlers.c + (gnome_vfs_mime_get_short_list_applications, + gnome_vfs_mime_get_short_list_components): Implemented. + (gnome_vfs_mime_get_default_application, + gnome_vfs_mime_get_all_applications): Updated to expect mime + records to only point to app IDs, which point to app info in an + external registry. + (str_to_bool, join_str_list, strv_contains_str, + extract_prefix_add_suffix, mime_type_get_supertype, + strsplit_handle_null, gnome_vfs_mime_application_new_from_id, + OAF_ServerInfo__copy, OAF_ServerInfoList_to_ServerInfo_g_list, + process_app_list): New and modified helper functions. + * test/test-mime-handlers.c (main): Add tests for short_list + functions. + * data/mime/gnome-vfs.keys: More test data; fix for new data + representation. + * data/mime/application-registry-hack.keys: Total hack using bogus + mime types to create an application registry. Need a better + solution than this long-term. + * data/mime/Makefile.am: Install `application-registry-hack.keys'. + +2000-05-30 Pavel Cisler + + * libgnomevfs/gnome-vfs-types.h: + * libgnomevfs/gnome-vfs-xfer.c: + (gnome_vfs_xfer_private): + Removed some obsolete xfer options. Added new ones to make + new copy engine functions not depend so much on subtle values + of input source/target lists of items. + + * libgnomevfs/gnome-vfs-xfer.c: + (gnome_vfs_new_directory_with_unique_name): + Darin and mjs hated the old name. + + * libgnomevfs/gnome-vfs-xfer.c: + (gnome_vfs_xfer_delete_items): + New call to support a fallback delete for files that cannot be moved + to Trash. + +2000-05-30 Maciej Stachowiak + + * libgnomevfs/gnome-vfs-mime-handlers.c: + (gnome_vfs_mime_get_all_applications, + gnome_vfs_mime_get_all_components): Implemented + + (gnome_vfs_mime_get_short_list_applications), + (gnome_vfs_mime_get_short_list_components), + + (parse_app_lists, OAF_ServerInfoList_to_ServerInfo_g_list): New + helper functions. + + * test/test-mime-handlers.c: Expanded to test the all_applications + and all_components calls. + + * libgnomevfs/gnome-vfs-init.c: (gnome_vfs_init): Fix oaf + initialization to use a better dummy argv. + + * data/mime/gnome-vfs.keys: Added more test data. + +2000-05-30 Pavel Cisler + + * libgnomevfs/gnome-vfs-xfer.c: (gnome_vfs_new_folder), + (gnome_vfs_xfer_private): + Add yet another flavor to the copy engine to allow creating + new directories. + + * libgnomevfs-corba/gnome-vfs-async-ops.c: + (corba_gnome_vfs_async_xfer): + * libgnomevfs-pthread/gnome-vfs-async-ops.c: + (pthread_gnome_vfs_async_xfer): + Get rid of an assert that no longer applies. + +2000-05-30 Maciej Stachowiak + + * libgnomevfs/Makefile.am: Add OAF_CLAGS. + * libgnomevfs/gnome-vfs-init.c (gnome_vfs_init): oaf_init if it + hasn't been done already. + + * libgnomevfs/gnome-vfs-mime-handlers.c + (gnome_vfs_mime_get_default_action, + gnome_vfs_mime_get_default_application, + gnome_vfs_mime_get_default_component): Implemented more or less + correctly (I hope). + + (extract_prefix_add_suffix, mime_type_get_supertype, + OAF_ServerInfo__copy) : Helper functions cut & pasted from + elsewhere. + + * test/test-mime-handlers.c: Test for gnome-vfs-mime-handlers API. + * test/Makefile.am: Add the above to the build. + + * data/mime/gnome-vfs.keys: Put in some default + ation/application/component data for testing purposes. + +2000-05-27 Pavel Cisler + + * libgnomevfs-pthread/gnome-vfs-job-slave.c: + (gnome_vfs_job_slave_new), (gnome_vfs_thread_backend_shutdown), + (gnome_vfs_debug_get_thread_count): + Made gnome_vfs_thread_backend_shutdown work properly by adding the + right call to yield to the gtk idle task that is needed to allow + all the task callbacks to finish. This simplifies the application + quit. + Tweaked some debugging messages. + + * libgnomevfs-pthread/gnome-vfs-job.c: (job_signal_ack_condition), + (job_ack_notify), (job_notify), (gnome_vfs_job_finish_destroy), + (gnome_vfs_job_prepare), (execute_load_directory_not_sorted), + (execute_load_directory_sorted), (gnome_vfs_job_execute), + (gnome_vfs_job_cancel): + Added a cancel check to job_notify to make sure someone is still + expecting a notification before we start notifying. Add checks + to the return value of job_notify, bailing from all the calls + during cancel. + Added the same check to execute_load_directory_not_sorted to make + it bail out earlier during a cancel. + When cancelling, signal to the possibly waiting job_ack_notify + to make it give up waiting. + Added a lot more debugging code to help me chase down the problems. + + * test/test-async-cancel.c: (stop_after_log), (make_asserts_break), + (directory_load_callback), (yield), (test_load_directory_cancel), + (main): + Made the test stop in the debugger during an assert. + Added tests for load_directory cancellations. + +2000-05-27 Dan Winship + + * libgnomevfs-corba/gnome-vfs-slave-notify.c + (impl_Notify_open_as_channel): cast "struct sockaddr_un *" + argument to connect to "struct sockaddr *". + + * libgnomevfs/gnome-vfs-private.h: Fix the getdelim prototype. + +2000-05-26 Maciej Stachowiak + + * libgnomevfs/gnome-vfs-mime-handlers.h, + libgnomevfs/gnome-vfs-mime-handlers.c: Add stub implementations + for all functions. Add `gnome_vfs_mime_application_free' function. + + * libgnomevfs/Makefile.am: Add + `libgnomevfs/gnome-vfs-mime-handlers.c' to the build. + + * libgnomevfs/gnome-vfs-mime-handlers.h: Add a "name" field to the + GnomeVFSMimeApplication struct, as John and I discussed. + + * libgnomevfs/gnome-vfs-types.h: include , not jsut + (glibconfig is really supposed to be an internal + header anyway). + +2000-05-26 Gene Z. Ragan + + All of the below is work in progress on the Files and Programs + capplet. I am currently retro-fitting jrb's capplet to use + our modified capplet layout and new gnome-vfs mime API. + This capplet does not currently work properly, but does build and + causes no harm if run. + + * mime-type-capplet/edit-window.c: (ext_remove), (apply_changes), + (initialize_main_win), (initialize_main_win_vals), + (launch_edit_window), (hide_edit_window), (show_edit_window), + (populate_application_menu), (populate_component_menu): + + * mime-type-capplet/mime-data.c: (selected_row_callback), + (edit_clicked): + + * mime-type-capplet/nautilus-mime-type.desktop: + Changed entries so capplet would register itself as "Files and Programs" + +2000-05-26 John Sullivan + + * data/mime/gnome-vfs.keys: Added one more description. + This had been sitting around on my disk for awhile but + I forgot. + +2000-05-26 Maciej Stachowiak + + * libgnomevfs/gnome-vfs-mime-handlers.h: Header for upcoming mime + handler API. + * libgnomevfs/Makefile.am: Install the new header. + +2000-05-24 Pavel Cisler + + * libgnomevfs/gnome-vfs-mime-magic.c: + (gnome_vfs_sniff_buffer_looks_like_text): + * libgnomevfs/gnome-vfs-mime-sniff-buffer.h: + * libgnomevfs/gnome-vfs-mime.c: (gnome_vfs_get_mime_type): + Implement a simple version of the call. Rename to a better + name. + + * libgnomevfs/gnome-vfs-mime.c: + (gnome_vfs_get_mime_type_from_file_data): + Add detecting text files. + +2000-05-24 Pavel Cisler + + * data/mime/gnome-vfs-mime-magic: + Add a magic rule for rpm files. + + * libgnomevfs/gnome-vfs-file-info.c: + (gnome_vfs_file_info_matches): + Fix a bug that would make the routine fail most of the times. + + * libgnomevfs/gnome-vfs-mime-magic.c: + * libgnomevfs/gnome-vfs-mime-sniff-buffer.c: + * libgnomevfs/gnome-vfs-mime-sniff-buffer-private.h: + * libgnomevfs/gnome-vfs-mime-sniff-buffer.h: + * libgnomevfs/gnome-vfs-mime.c: + (handle_seek_glue), (handle_read_glue), + (gnome_vfs_mime_sniff_buffer_new_from_handle), + (gnome_vfs_mime_sniff_buffer_new_generic), + (gnome_vfs_mime_sniff_buffer_get): + Add callback vectors to mime shiff buffer to allow providing + any seek and read calls to make it work on anything, not just + GnomeVFSHandles. Reworked gnome_vfs_mime_sniff_buffer_get to + use the callback vectors. + Rewrite gnome_vfs_mime_sniff_buffer_new_from_handle to use the + callback vectors. + + * libgnomevfs/gnome-vfs-mime.c: + * libgnomevfs/gnome-vfs-module-shared.c: + (gnome_vfs_mime_type_from_mode), + (gnome_vfs_get_special_mime_type), + (libgnomevfs/gnome-vfs-module-shared.h): + Move the routine close to an existing call that has similar logic. + + * modules/file-method.c: + (read_directory): + Tweak a comment. + +2000-05-24 Ramiro Estrugo + + * mime-type-capplet/.cvsignore, + mime-type-capplet/Makefile.am + mime-type-capplet/mime-type-capplet.c + mime-type-capplet/mime-type.desktop + mime-type-capplet/nautilus-mime-type-capplet.c + mime-type-capplet/nautilus-mime-type.desktop: + Rename the 'mime-type' capplet to 'nautilus-mime-capplet' to avoid + clobbering the control-center's one. + +2000-05-23 Maciej Stachowiak + + * libgnomevfs/gnome-vfs-uri.c (get_method_string): Allow digits, + `+', `-' and `.' in the uri scheme name. + +2000-05-23 Pavel Cisler + + * libgnomevfs/gnome-vfs-mime-magic.c: + * libgnomevfs/gnome-vfs-mime-magic.h: + * libgnomevfs/gnome-vfs-mime.c: + * libgnomevfs/gnome-vfs-mime.h: + (gnome_vfs_mime_try_one_magic_pattern), (gnome_vfs_get_mime_type_for_buffer), + (gnome_vfs_mime_magic_db_load), (gnome_vfs_mime_get_magic_table), + (gnome_vfs_mime_type_from_magic), (gnome_vfs_get_special_mime_type), + (gnome_vfs_get_mime_type_from_name_internal), + (gnome_vfs_get_mime_type_from_name), (gnome_vfs_get_mime_type), + (gnome_vfs_get_mime_type_from_file_data), (gnome_vfs_get_mime_type_for_data), + (gnome_vfs_get_sniff_buffer_looks_like_text): + Add new magic MIME sniffing APIs that can work on a URI as well as + on an in-memory buffer. Fix the broken use of mask. + Fix a bug where octal numbers were not parsed properly -- pretty much + half the rules that used octal numbers never worked. Make the + loading of the MIME-magic entry database thread-safe. Change the + MIME-type lookup sequence for the default call. + + * libgnomevfs/Makefile.am: + * libgnomevfs/gnome-vfs-mime-sniff-buffer.h: + * libgnomevfs/gnome-vfs-mime-sniff-buffer.c: + Lazy-reading buffer that can wrap either a file or a memory buffer + and that is passed to the new magic MIME type sniffing calls. + + * libgnomevfs/gnome-vfs-mime-magic.c: + (read_hex_str): + Fix a bug Darin helped me find where uppercase hex numbers weren't + converted properly. + + * libgnomevfs/gnome-vfs-mime-magic.c: + (read_string_val): + Fix a bug where octal numbers were not parsed properly -- pretty much + half the rules that used octal numbers never worked. + + * data/mime/gnome-vfs-mime-magic: + Re-did the whole file. We'll add more entries in the future, + for now start with a good set of magic rules that are correct + and that are for file types you are actually likely see on your + machine. Ordered the rules such that the more-ambiguous ones + are at the end of the file to minimize the chance of getting + false positive. Fixed a number of incorrect rules in some of + the entries I kept from the old file. + + * test/Makefile.am: + * test/test-mime.c: + New testing tool to test the new MIME-magic sniffing routines. + In addition to testing the main gnome_vfs_get_mime_type allows + testing magic-only MIME sniffing (good for verifying that + a new magic entry is correct) and suffix-only MIME sniffing. + +2000-05-23 Ramiro Estrugo + + * configure.in: + Removed -lgnomevfs from CAPPLET_LIBS. + +2000-05-23 Ramiro Estrugo + + * Makefile.am: + * configure.in: + * mime-type-capplet/.cvsignore: + * mime-type-capplet/Makefile.am: + * mime-type-capplet/edit-window.c, + * mime-type-capplet/edit-window.h, + * mime-type-capplet/mime-data.c, + * mime-type-capplet/mime-data.h, + * mime-type-capplet/mime-info.c, + * mime-type-capplet/mime-info.h, + * mime-type-capplet/mime-type-capplet.c, + * mime-type-capplet/mime-type.desktop, + * mime-type-capplet/new-mime-window.c, + * mime-type-capplet/new-mime-window.h: + Copy mime-type capplet from the control-center so that it can be + improved and made to use gnome-vfs. + + This has the unfortunate side-effect of introducing a dependency + on libcapplet. This is temporary until the capplet can move back + to the control-center. At that time, the control-center will + depend on gnome-vfs and eveyone will live happily ever after. + +2000-05-19 Pavel Cisler + + * libgnomevfs-pthread/gnome-vfs-job.c: + * libgnomevfs-pthread/gnome-vfs-job.h: + (dispatch_job_callback), (serve_channel_write), + (gnome_vfs_job_new): Fixed up the rest of the g_io_channel_read + calls to prevent them from returning without reading any input + when a thread is signalled. Added more debugging code. + +2000-05-19 Pavel Cisler + + * libgnomevfs-pthread/gnome-vfs-job.c: + (dispatch_job_callback): Handle a bug where g_io_channel_read + would sometimes return with an error and without any characters + read, failing to synchronize with the slave thread. I need to + figure out why this is happening (probably a race condition in + the g_io_channel setup code) for now added code that forces the + read to be repeated. + Fixes a problem Ettore and Andy were running into. + + * libgnomevfs-pthread/gnome-vfs-job-slave.c: + * libgnomevfs-pthread/gnome-vfs-job.c: + * libgnomevfs-pthread/gnome-vfs-job.h: + Clean up debugging code a ton. + +2000-05-19 Darin Adler + + * modules/file-method.c: (set_mime_type): Fixed to get the fast + type if the slow type returns NULL. + + * modules/pipe-method.c: Got rid of commented out copy of + set_mime_type, since it will just get out of sync. with the real + copy. + +2000-05-19 Darin Adler + + * libgnomevfs/gnome-vfs-uri.c: (gnome_vfs_uri_new): There was + a bug in the change to free method_string. This should fix it. + + * libgnomevfs/gnome-vfs.h: Fixed a FIXME. + * test/gnome-file-selection/Makefile.am: Fixed a FIXME. + +2000-05-19 Maciej Stachowiak + + * libgnomevfs/gnome-vfs-uri.c: (gnome_vfs_uri_new): Actually, now + it looks like Rebecca's change had nothing to do with the problem + I'm seeing, so I'm reverting my change. + + * libgnomevfs/gnome-vfs-uri.c: (gnome_vfs_uri_new): Commented out + Rebecca's memory leak fix for now; it looks correct to me but it + must be triggering some other bug because it makes Nautilus do + strange things for me and others. + +2000-05-18 Rebecca Schulman + + * libgnomevfs/gnome-vfs-uri.c + Fixed a memory leak in gnome_vfs_uri_new. (method_string + sometime was never freed) + +2000-05-18 Maciej Stachowiak + + * data/mime/gnome-vfs-mime-magic: Replaced mime type of "X pixmap + image text" to "image/x-xpm". + +2000-05-17 Pavel Cisler + + * libgnomevfs/gnome-vfs-uri.c: + * libgnomevfs/gnome-vfs-uri.h: + (gnome_vfs_uri_is_parent): + Added a new utility call. + + * libgnomevfs/gnome-vfs-uri.c: + (my_streq): + Fixed it up to treat NULL and "" the same and cleaning it up. + This fixes a bug in gnome_vfs_uri_equal making it fail on + URIs that should have been evaluated as equal. + + * libgnomevfs/gnome-vfs-xfer.c: + (move_items): + Fix a bug where in some cases the error callback would get called + without the names of the files it failed on. + +2000-05-17 John Sullivan + + * data/mime/gnome-vfs.keys: + Added application/x-asp + +2000-05-16 Gene Z. Ragan + + * libgnomevfs/gnome-vfs-uri.c: + Reverted due to accidental check-in during last commit. + +2000-05-16 Gene Z. Ragan + + * test/gnome-file-selection/main.c: #include + "libgnomevfs/gnome-vfs.h", not "gnome-vfs.h". + +2000-05-16 Ettore Perazzoli + + * test/gnome-file-selection/gnome-file-selection.c: #include + "libgnomevfs/gnome-vfs.h", not "gnome-vfs.h". + + * test/gnome-file-selection/Makefile.am (INCLUDES): Replace + `-I$(top_srcdir)/libgnomevfs' with `-I$(top_srcdir)'. + +2000-05-16 Ettore Perazzoli + + * libgnomevfs/gnome-vfs-mime-info.c (language_level): Correctly + cast the `void *' pointer before passing to `strcmp()'. Also, + made const-safe and re-indented a bit. + +2000-05-16 Ian McKellar + + * modules/newftp-method.c: + Fixed warning. + +2000-05-16 Ian McKellar + + * modules/Makefile.am: + * modules/default-modules.conf: + * modules/newftp-method.c: + * modules/newftp-method.h: + New FTP method. It doesn't currently work with Netpresenz servers, but + it is thread safe. Play with it, break it, mail me the addresses of FTP + servers that don't work. This is a complete reimplementation, so I've + left the old ftp-method in cvs as a reference. + + * test/test-info.c: (main): + Accept multiple URIs on the command line. + +2000-05-11 Pavel Cisler + + * libgnomevfs/gnome-vfs-xfer.c: + (gnome_vfs_xfer_uri_internal): + Fix bug 435: gnome_vfs_async_xfer does not report errors that + Darin was running into. + +2000-05-11 Pavel Cisler + + * libgnomevfs-pthread/gnome-vfs-job-slave.c: + Add debugging code to help me fix deadlocks caused by gnome vfs + not shutting down properly. + + * libgnomevfs-pthread/gnome-vfs-job.c: + Make the JOB_DEBUG debugging print atomic. + + * libgnomevfs/gnome-vfs-backend.h: + * libgnomevfs/gnome-vfs-backend.c: + * libgnomevfs/gnome-vfs-init.h: + * libgnomevfs/gnome-vfs-init.c: + * libgnomevfs-pthread/gnome-vfs-job-slave.c: + * libgnomevfs-pthread/gnome-vfs-job-slave.h: + (gnome_vfs_thread_backend_shutdown), + (gnome_vfs_debug_get_thread_count): + Add a call that will allow apps to synchronize with the slave threads + that are finishing up. + +2000-05-10 Dan Winship + + * data/mime/gnome-vfs.keys: Add message/* and multipart/* mime + types. They aren't useful for identifying files, but they may be + useful for mail programs, and it would be dumb to have a separate + MIME type database for that. Also fix up some descriptions, add + some more types, and remove text/vnd.latex-z, because it's not + what you think (and not useful). + + * data/mime/gnome-vfs.mime: Sync. + +2000-05-09 Pavel Cisler + + * libgnomevfs/gnome-vfs-gen-mimedb: Removed from CVS. + Oops, checked this in by accident. + +2000-05-09 Pavel Cisler + + * libgnomevfs-pthread/gnome-vfs-job.c: + (execute_xfer): + Add a missing job_close that was triggering an assert for + various file system operations. + +2000-05-09 Pavel Cisler + + * libgnomevfs-pthread/gnome-vfs-job.c: + (job_oneway_notify): + Handle the case where job_oneway_notify gets called from + gnome_vfs_job_destroy properly - the current_op is NULL + but we may still have a pending notify_op. + + * libgnomevfs-pthread/gnome-vfs-job.c: + (gnome_vfs_job_cancel): + Fix a crash during cancellation - the call was dereferencing + a null job when cancelling. + +2000-05-08 Darin Adler + + A fix for canceling. Cancels can still be done until the caller + is notified, even if the work is done. + + * libgnomevfs-pthread/gnome-vfs-job.c: (gnome_vfs_job_cancel): + Allow the caller to cancel a task even if we are done with it. + * test/test-async-cancel.c: (test_get_file_info): Tweak message. + +2000-05-08 Darin Adler + + Another cut at fixing the pthread back end for GNOME VFS. + + * libgnomevfs-pthread/gnome-vfs-async-ops.c: + (pthread_gnome_vfs_async_cancel), + (pthread_gnome_vfs_async_open_uri), (pthread_gnome_vfs_async_open), + (pthread_gnome_vfs_async_open_uri_as_channel), + (pthread_gnome_vfs_async_open_as_channel), + (pthread_gnome_vfs_async_create_uri), + (pthread_gnome_vfs_async_create), + (pthread_gnome_vfs_async_create_as_channel), + (pthread_gnome_vfs_async_close), (pthread_gnome_vfs_async_read), + (pthread_gnome_vfs_async_write), + (pthread_gnome_vfs_async_get_file_info), + (pthread_gnome_vfs_async_load_directory), + (pthread_gnome_vfs_async_load_directory_uri), + (pthread_gnome_vfs_async_xfer), + (pthread_gnome_vfs_async_add_status_callback), + (pthread_gnome_vfs_async_remove_status_callback): + Changed to use the separate op structure so we can support starting + a new operation before we have notified about the last one. + + * libgnomevfs-pthread/gnome-vfs-job-slave.c: (thread_routine): + Re-enabled destroying the GnomeVFSJob objects, although the actual + destroying takes place on the main thread after a subsequent notify. + (gnome_vfs_job_slave_new), (gnome_vfs_job_slave_destroy), + (pthread_gnome_vfs_debug_get_thread_count): + Added thread count interface for testing and debugging. + + * libgnomevfs-pthread/gnome-vfs-job.h: + * libgnomevfs-pthread/gnome-vfs-job.c: (job_oneway_notify), + (job_notify), (dispatch_open_callback), (dispatch_create_callback), + (dispatch_open_as_channel_callback), + (dispatch_create_as_channel_callback), (dispatch_close_callback), + (dispatch_read_callback), (dispatch_write_callback), + (dispatch_load_directory_callback), + (dispatch_get_file_info_callback), (dispatch_xfer_callback), + (close_callback), (handle_cancelled_open), (dispatch_job_callback), + (gnome_vfs_job_new), (gnome_vfs_job_destroy), + (gnome_vfs_job_finish_destroy), (gnome_vfs_op_destroy), + (gnome_vfs_job_release_current_op), + (gnome_vfs_job_release_notify_op), (gnome_vfs_job_prepare), + (serve_channel_read), (execute_open), (execute_open_as_channel), + (execute_create), (execute_create_as_channel), (execute_close), + (execute_read), (execute_write), + (execute_load_directory_not_sorted), + (execute_load_directory_sorted), (execute_get_file_info), + (execute_load_directory), (xfer_callback), (execute_xfer), + (gnome_vfs_job_execute), (gnome_vfs_job_cancel): + Changed to use the separate op structure so we can support starting + a new operation before we have notified about the last one. Also added + code to handle the case of an open that's cancelled after the file is + opened, but before the callback has been called. + + * libgnomevfs/gnome-vfs-backend.c: + (gnome_vfs_debug_get_thread_count): Added thread count interface for + testing and debugging. + + * libgnomevfs/gnome-vfs-utils.h: + * libgnomevfs/gnome-vfs-utils.c: (gnome_vfs_file_size_to_string), + (gnome_vfs_escape_string), (gnome_vfs_ascii_hex_to_char), + (gnome_vfs_unescape_string): Remove the "_ht" and HT from the names. + + * test/.cvsignore: + * test/Makefile.am: + * test/test-async-cancel.c: (get_free_file_descriptor_count), + (get_used_file_descriptor_count), (wait_for_boolean), + (wait_until_vfs_threads_gone), + (wait_until_vfs_threads_gone_no_main), + (wait_until_file_descriptors_gone), (test_failed), + (get_file_info_callback), (first_get_file_info), + (test_get_file_info), (file_open_callback), (file_close_callback), + (file_read_callback), (test_open_read_cancel_close), + (test_open_cancel), (main): + Added a new test, test-async-cancel. This one is run as part of make + check and it checks for all the problems I was trying to fix. + + * configure.in: Turned on -Werror for all directories. Also turned + on extra warnings like in Nautilus. + * libgnomevfs/gnome-vfs-parse-ls.c: (finduid), (findgid): + Fixed warnings. + * test/gnome-file-selection/gnome-file-selection.c: Fixed a warning. + + * libgnomevfs-corba/Makefile.am: + * libgnomevfs-pthread/Makefile.am: + * libgnomevfs/Makefile.am: + * modules/Makefile.am: + Took out now-unnecessary $(WERROR) lines. + +2000-05-08 Ettore Perazzoli + + * libgnomevfs-corba/Makefile.am: Don't use `GNOME_CFLAGS'. + +2000-05-08 Pavel Cisler + + * libgnomevfs/gnome-vfs-xfer.c: + (system_time): + Fix it to return a correct value. + +2000-05-07 Maciej Stachowiak + + * libgnomevfs/gnome-vfs-backend.c + (report_failure_get_file_info_callback), + libgnomevfs/gnome-vfs-xfer.c (gnome_vfs_xfer_empty_trash): Fixed + some uninitialized variable warnings. + +2000-05-07 Maciej Stachowiak + + * data/mime/gnome-vfs-mime: Fixed some of the broken mime types. + +2000-05-07 Pavel Cisler + + * gnome-vfs/configure.in: + * libgnomevfs/Makefile.am: + * libgnomevfs-corba/Makefile.am: + * libgnomevfs-pthread/Makefile.am: + * modules/Makefile.am: + * test/Makefile.am: + Turn on a flag to treat warnings as errors. This would have caught + the two bugs I fixed in my previous checkin. + + * libgnomevfs/gnome-vfs-mime-info.c: + * libgnomevfs/gnome-vfs.h: + * modules/extfs-method.c: + * test/test-async-directory.c: + Fix all warnings in gnome-vfs. + +2000-05-07 Pavel Cisler + + * modules/translate-method.c: (tr_args_parse): + Fixed the translate module that got broken recently. + (b_strcasecmp->g_strcasecmp). This broke viewing + man pages, etc. in Nautilus. + + * modules/translate-method.c: (tr_do_find_directory): + Fixed an obvious bug in parameter passing that was + triggering a warning. + +2000-05-06 Darin Adler + + * libgnomevfs-pthread/gnome-vfs-job-slave.c: (thread_routine): + Turned off the call to gnome_vfs_destroy, reintroducing the + leak. Hopefully this makes things work again, but the leak + is back until I get a real fix. + + * libgnomevfs/gnome-vfs-context.h: Fixed a typo in the macro + that made it work only on variables named "context". + +2000-05-05 Darin Adler + + * libgnomevfs-pthread/gnome-vfs-job.c: (gnome_vfs_job_destroy): + Oops. One loose end. Gotta avoid a little race condition. + +2000-05-05 Darin Adler + + Fixed the leak of a ton of objects and 4 file descriptors for + every async. call. + + * libgnomevfs-pthread/gnome-vfs-job-slave.c: (thread_routine): + Destroy jobs when we are done with them. + + * libgnomevfs-pthread/gnome-vfs-job.c: (dispatch_close_callback): + Took out the bogus call to destroy the job in here. + (dispatch_job_callback): Added logic to get rid of the callback + when we are done with it. Since there's no remove call, we need + to send an additional notify just to get the call to remove + itself. + (gnome_vfs_job_new): Initialize want_notify_ack which had a + random value in the old code. Also initialize the new "done" + flag which is used to kill the above callback. + (gnome_vfs_job_destroy): Got rid of bogus code in here that + acquired the access lock, since this is only called from code + that already has it. Added a call to job_notify so the callback + can release itself. Removed the call to cancel the slave since + the job is destroyed by the slave. Uncommented the code to free + the execution condition, since that was an artifact of the old + bad way the code was structured. + * libgnomevfs-pthread/gnome-vfs-job.h: Added the "done" field. + + * libgnomevfs/.cvsignore: Ignore gnome-vfs-gen-mimedb. + +2000-05-05 John Sullivan + + * libgnomevfs/gnome-vfs-gen-mimedb: Removed from CVS. This + is a generated file and I shouldn't have checked it in earlier. + + * libgnomevfs/gnome-vfs-mime-info.h, + * libgnomevfs/gnome-vfs-mime-info.c: + (gnome_vfs_mime_program_list), (gnome_vfs_mime_program_name_list), + (gnome_vfs_mime_program_name_list_free): Removed these + list-based functions with Miguel's blessing. They shouldn't + have gotten into the old gnome-mime.c, and they're not + needed for Nautilus or apparently anything else. + * libgnomevfs/gnome-vfs-mime.h, + * libgnomevfs/gnome-vfs-mime.c: + Added #include to shut up warning. + (gnome_vfs_mime_type_list), (gnome_vfs_mime_type_list_or_default), + (gnome_vfs_mime_type_list_of_file), + (gnome_vfs_mime_type_list_or_default_of_file): Removed these + list-based functions with Miguel's blessing. They shouldn't + have gotten into the old gnome-mime.c, and they're not + needed for Nautilus or apparently anything else. + +2000-05-03 Pavel Cisler + + * libgnomevfs/gnome-vfs-xfer.c (remove_file), (remove_directory), + (gnome_vfs_xfer_empty_trash), (gnome_vfs_xfer_uri_internal): + Make emptying Trash update the progress_info structure properly + to allow the progress dialog to display the right numbers. + + * libgnomevfs/gnome-vfs-xfer.c (gnome_vfs_xfer_uri_internal): + Call progress with GNOME_VFS_XFER_PHASE_READYTOGO when emptying + the Trash properly. + + * libgnomevfs/gnome-vfs-xfer.c (gnome_vfs_xfer_private): + Fix broken const. + +2000-05-03 Dave Camp + + * modules/gconf-method.c (do_open): + (do_create): + (do_close): + (do_open_directory): + (do_close_directory): + (do_read_directory): + (do_get_file_info): Fixed prototypes to match the current gnome-vfs + api. + (MAKE_ABSOLUTE): Make sure there is no trailing '/', as gconf doesn't + like them. + (directory_handle_new): Create a mutex for accessing the pairs. + (directory_handle_destroy): Free the pair mutex. + (set_mime_type_value): Change the mime-types. + (set_stat_info_dir): + (set_stat_info_value): Reflect changes in gnome-vfs api. + (do_get_file_info): + (do_open_directory): Perform locking for gconf accesses, and reflect + gconf api changes. + (read_directory): Perform locking when accessing the pairs, and + correctly free the gconf pairs. + (vfs_module_init): Reflect gconf api changes, and initialize a mutex + for locking gconf. + (vfs_module_shutdown): Free the gconf mutex. + +2000-05-03 Michael Meeks + + * libgnomevfs/gnome-vfs-file-info.c: s/strcasecmp/g_strcasecmp/ + + * modules/translate-method.c: s/strcasecmp/g_strcasecmp/, + indent. + +2000-05-02 John Sullivan + + * data/mime/gnome-vfs.mime: + Added a bunch of MIME types that were in the 1.0 branch + of gnome-libs but not in HEAD. + + * data/mime/gnome-vfs.keys: + Added a few missing keys that people had run into, and + put the icon for core files here so it doesn't need to + be special-cased in Nautilus. + +2000-05-02 John Sullivan + + * data/mime/gnome-vfs.keys: Added description for + image/svg. + +2000-05-02 Dave Camp + + * libgnomevfs/gnome-vfs-ops.h (gnome_vfs_move_uri): + * libgnomevfs/gnome-vfs-ops.h (gnome_vfs_move): + * libgnomevfs/gnome-vfs-ops.c (gnome_vfs_move_uri): + * libgnomevfs/gnome-vfs-ops.c (gnome_vfs_move): Renamed parameters, + as the 'new' parameter was causing problems with C++ compilers. + +2000-05-02 John Sullivan + + * data/mime/gnome-vfs.mime: Alphabetized the mime types, + and removed the duplicate entry for video/x-msvideo (avi) + +2000-05-02 John Sullivan + + Another step towards getting all the MIME handling code + into gnome-vfs and out of gnome-libs. This step gets the + data files and mime-magic stuff into gnome-vfs. + + * data/mime/gnome-vfs-mime-magic, + * data/mime/gnome-vfs.mime, + * data/mime/gnome-vfs.keys: + New data files, cloned from "mime-magic", "gnome.mime", + and "nautilus.keys", which these ones obviate. + + * Makefile.am, + * configure.in, + * data/.cvsignore:, + * data/Makefile.am, + * data/mime/.cvsignore, + * data/mime/Makefile.am: New files -- build system fu to + get the new data files installed in the right places + + * gnome-vfs.spec.in: Added new data files to RPM. Not sure + I got this part right, will ask Ramiro about it. + + * libgnomevfs/gnome-vfs-gen-mimedb, + * libgnomevfs/gnome-vfs-gen-mimedb.c: New files, copied + over from gnome-libs. These are used so a tool can be + called to compile the mime-magic data into a database form. + * libgnomevfs/Makefile.am: Build system fu to handle + gnome-vfs-gen-mimedb. + + * libgnomevfs/gnome-vfs-mime-info.c (mime_info_load): Use + gnome-vfs.keys and skip gnome.keys if found. + + * libgnomevfs/gnome-vfs-mime-magic.c: + (gnome_vfs_mime_magic_db_load): Use gnome-vfs-mime-magic.dat + instead of mime-magic.dat. + (gnome_vfs_mime_type_from_magic): Use gnome-vfs-mime-magic + instead of mime-magic. + + * libgnomevfs/gnome-vfs-mime.c (mime_load): Use gnome-vfs.mime + and skip gnome.mime if found. + +2000-05-01 John Sullivan + + First steps at the grand move-MIME-handling-code-to- + gnome-vfs plan. + + * libgnomevfs/gnome-vfs-mime-info.c, + * libgnomevfs/gnome-vfs-mime-info.h, + * libgnomevfs/gnome-vfs-mime-magic.c, + * libgnomevfs/gnome-vfs-mime-magic.h, + * libgnomevfs/gnome-vfs-mime.c, + * libgnomevfs/gnome-vfs-mime.h: + New files, cloned from similarly-named ones in gnome-libs. + I started with the HEAD versions of these files, which + include some mime-list API that I'm not sure yet if we + actually need (but is currently sitting there uncalled, + so no biggie for now). All code should now start using + these instead of the code in gnome-libs, which will + eventually be obsoleted. + + * libgnomevfs/Makefile.am: + Put these new files into the build. + + * modules/extfs-method.c (read_directory_list): + * modules/file-method.c (set_mime_type): + * modules/ftp-method.c (_ftpfs_read_directory), (fill_file_info): + * modules/pipe-method.c (set_mime_type): + * test/gnome-file-selection/gicon.c (gicon_get_icon_for_file_2): + Update all callers in gnome-vfs to use the new gnome-vfs mime + calls. + +2000-05-01 Ian McKellar + + * modules/ftp-method.c: + (ftpfs_chdir_internal): Assume path=="" is equivalent to path=="/". + (ftpfs_open_directory): Check return value of retrieve_dir. + + FTP URIs should now work. Miguel says that ftp-method needs to be made + thread-safe, but I'm not sure how to do this. + +2000-04-26 Pavel Cisler + + * libgnomevfs/gnome-vfs-xfer.c: + (gnome_vfs_xfer_empty_trash): + Set up progress phase properly. This fixes a problem with the + progress dialog getting instantiated twice. + + * libgnomevfs/gnome-vfs-xfer.c: + (remove_directory): + Properly initialize and return result. + + +2000-04-26 Darin Adler + + * gnome-vfs-private-ops.c: + (gnome_vfs_open_uri_cancellable), + (gnome_vfs_create_uri_cancellable), (gnome_vfs_close_cancellable), + (gnome_vfs_read_cancellable), (gnome_vfs_write_cancellable), + (gnome_vfs_seek_cancellable), + (gnome_vfs_get_file_info_uri_cancellable), + (gnome_vfs_get_file_info_from_handle_cancellable), + (gnome_vfs_truncate_uri_cancellable), + (gnome_vfs_truncate_handle_cancellable), + (gnome_vfs_make_directory_for_uri_cancellable), + (gnome_vfs_find_directory_cancellable), + (gnome_vfs_remove_directory_from_uri_cancellable), + (gnome_vfs_unlink_from_uri_cancellable), + (gnome_vfs_move_uri_cancellable), + (gnome_vfs_check_same_fs_uris_cancellable), + (gnome_vfs_set_file_info_cancellable): + Changed these all so they will handle the case where the are + cancelled before they even begin. + +2000-04-26 Darin Adler + + * libgnomevfs/gnome-vfs-job.c: (execute_get_file_info): + Fixed bug that would result in a thread that never dies. + +2000-04-26 Pavel Cisler + + * libgnomevfs/gnome-vfs-xfer.c + Fix a crash caused by using the wrong call to free a uri_list. + +2000-04-26 Pavel Cisler + + Added gnome_vfs_find_directory to return well known directories. + For now only returns Trash. + * libgnomevfs/gnome-vfs-find-directory.c: + * libgnomevfs/gnome-vfs-find-directory.h: + * libgnomevfs/gnome-vfs-private-ops.c: + * libgnomevfs/gnome-vfs-private-ops.h: + * libgnomevfs/gnome-vfs-private-types.h: + * libgnomevfs/gnome-vfs-types.h: + * libgnomevfs/Makefile.am: + (gnome_vfs_find_directory_cancellable), + (gnome_vfs_find_directory): + Added gnome_vfs_find_directory to return well known directories. + For now only returns Trash. + + * modules/file-method.c: + * modules/translate-method.c: + (do_find_directory), (tr_do_find_directory): + Add support for find_directory. + + * modules/bzip2-method.c: + * modules/extfs-method.c: + * modules/ftp-method.c: + * modules/gconf-method.c: + * modules/gzip-method.c: + * modules/http-method.c: + * modules/pipe-method.c: + Add empty support for find_directory to the remaining methods. + + * libgnomevfs/gnome-vfs-xfer.c: + (remove_directory), (empty_directory), (remove_file), + (directory_add_items_and_size), (calc_items_and_size), + (gnome_vfs_xfer_empty_trash), (gnome_vfs_xfer_uri_internal), + (libgnomevfs-corba/gnome-vfs-async-ops.c), + (libgnomevfs-pthread/gnome-vfs-async-ops.c): + Add support for emptying Trash (or any other list of directories). + +2000-04-26 Ian McKellar + + Fixed bug #489 (http://bugzilla.eazel.com/show_bug.cgi?id=489) + + * modules/http-method.c: checked for handle==NULL in + http_file_handle_destroy and http_handle_close. + +2000-04-25 Darin Adler + + Changed the async. get_file_info to do multiple files at a time. + We don't even have a single-file version any more. We can always + re-add it if it turns out to be useful. + + * idl/gnome-vfs-slave.idl: + * libgnomevfs/gnome-vfs-async-ops.h: + * libgnomevfs/gnome-vfs-backend.c + (report_failure_get_file_info_callback), + (report_failure_get_file_info), (gnome_vfs_async_get_file_info): + * libgnomevfs/gnome-vfs-types.h: + * libgnomevfs-corba/gnome-vfs-async-ops.c + (gnome_vfs_uri_list_to_corba_uri_list), + (corba_gnome_vfs_async_get_file_info): + * libgnomevfs-corba/gnome-vfs-slave-notify.c + (strdup_or_null), (impl_Notify_get_file_info): + * libgnomevfs-corba/gnome-vfs-slave.c (impl_Request_get_file_info): + * libgnomevfs-pthread/gnome-vfs-async-ops.c + (pthread_gnome_vfs_async_get_file_info): + * libgnomevfs-pthread/gnome-vfs-job.h: + * libgnomevfs-pthread/gnome-vfs-job.c + (dispatch_get_file_info_callback), (execute_get_file_info): + Changed get_file_info to work for multiple files. + + * libgnomevfs/gnome-vfs-file-info.h: + Removed gnome_vfs_file_info_destroy macro. + * libgnomevfs/gnome-vfs-file-info.c: + (gnome_vfs_file_info_list_ref), (gnome_vfs_file_info_list_unref), + (gnome_vfs_file_info_list_copy), (gnome_vfs_file_info_list_free): + Added utility functions for manipulating a GList that contains + GnomeVFSFileInfo pointers in it. + + * libgnomevfs/gnome-vfs-uri.h: + * libgnomevfs/gnome-vfs-uri.c: + (gnome_vfs_uri_list_ref), (gnome_vfs_uri_list_unref), + (gnome_vfs_uri_list_copy), (gnome_vfs_uri_list_free): + Added utility functions for manipulating a GList that contains + GnomeVFSURI pointers in it. + + * libgnomevfs/gnome-vfs-utils.c (gnome_vfs_unescape_string): + Fixed a warning. + * libgnomevfs-corba/gnome-vfs-corba.c (gnome_vfs_corba_init): + Fixed a warning. + * libgnomevfs-corba/gnome-vfs-slave.c (init_corba): + Fixed a warning (bad OAF init call). + * modules/http-method.c (do_write): Fixed a warning. + * libgnomevfs-corba/gnome-vfs-slave.c (xfer_progress_callback): + Fixed a warning. + + * modules/extfs-method.c (free_directory_entries): + Replaced a lingering gnome_vfs_file_info_destroy with a call to + gnome_vfs_file_info_unref. + (do_open_directory): Got rid of #warning which was redundant with + a FIXME. (We'll be making all FIXME into bug reports.) + + * modules/ftp-method.c (ftpfs_open_socket), (retrieve_file), + (ftpfs_open), (ftpfs_create): Turned #warning into FIXME. (We'll + be making all FIXME into bug reports.) + (_ftpfs_read_directory): Fixed a bad bug where the mime type was + filled in without g_strdup. Potential memory trasher. + + * libgnomevfs-corba/gnome-vfs-slave.c (load_directory_not_sorted): + Replaced a lingering gnome_vfs_file_info_destroy with a call to + gnome_vfs_file_info_unref. + + * libgnomevfs/gnome-vfs-backend.c + (gnome_vfs_async_load_directory): + * libgnomevfs/gnome-vfs-directory-list.c: + * libgnomevfs/gnome-vfs-directory-list.h: + (gnome_vfs_directory_list_load), (gnome_vfs_directory_list_load_from_uri): + * libgnomevfs/gnome-vfs-directory.h: + * libgnomevfs/gnome-vfs-directory.c (open_from_uri), (open), + (gnome_vfs_directory_open), (gnome_vfs_directory_open_from_uri) + (directory_visit_internal), (gnome_vfs_directory_visit_uri), + (gnome_vfs_directory_visit), + (gnome_vfs_directory_visit_files_at_uri), + (gnome_vfs_directory_visit_files): + * libgnomevfs/gnome-vfs-ops.h: + * libgnomevfs/gnome-vfs-ops.c: + (gnome_vfs_get_file_info), (gnome_vfs_get_file_info_uri), + (gnome_vfs_get_file_info_from_handle): + * libgnomevfs/gnome-vfs-private-ops.h: + * libgnomevfs/gnome-vfs-private-ops.c: + (gnome_vfs_get_file_info_uri_cancellable): + (gnome_vfs_get_file_info_from_handle_cancellable): + * libgnomevfs/gnome-vfs-private-utils.h: + * libgnomevfs/gnome-vfs-private-utils.c + (gnome_vfs_string_list_from_string_array) + (gnome_vfs_forkexec), + (gnome_vfs_process_run_cancellable): + * libgnomevfs/gnome-vfs-process.h: + * libgnomevfs/gnome-vfs-process.c (gnome_vfs_process_new): + * libgnomevfs-corba/gnome-vfs-async-ops.c + (corba_gnome_vfs_async_load_directory), + (corba_gnome_vfs_async_load_directory_uri): + * libgnomevfs-corba/gnome-vfs-slave-launch.c + (gnome_vfs_slave_launch): + * modules/extfs-method.c (do_open): + * libgnomevfs-pthread/gnome-vfs-async-ops.c (copy_meta_keys), + (pthread_gnome_vfs_async_get_file_info): + Added const as needed. + + * libgnomevfs/gnome-vfs-cancellation.c: + * libgnomevfs/gnome-vfs-context.c: + * libgnomevfs/gnome-vfs-directory-filter.c: + * libgnomevfs/gnome-vfs-directory-list.c: + * libgnomevfs/gnome-vfs-directory.c: + * libgnomevfs/gnome-vfs-directory.h: + * libgnomevfs/gnome-vfs-file-info.h: + * libgnomevfs/gnome-vfs-handle.c: + * libgnomevfs/gnome-vfs-handle.h: + * libgnomevfs/gnome-vfs-inet-connection.c: + * libgnomevfs/gnome-vfs-iobuf.c: + * libgnomevfs/gnome-vfs-messages.c: + * libgnomevfs/gnome-vfs-private-types.h: + * libgnomevfs/gnome-vfs-private.h: + * libgnomevfs/gnome-vfs-regexp-filter.c: + * libgnomevfs/gnome-vfs-shellpattern-filter.c: + * libgnomevfs/gnome-vfs-types.h: + * libgnomevfs/gnome-vfs-utils.h: + * libgnomevfs-pthread/gnome-vfs-job.h: + Got rid of leading underscores in many places where they were + unnecessary and violate the ANSI C standard. There are still more. + +2000-04-25 Ettore Perazzoli + + * libgnomevfs-corba/Makefile.am: Use `OAF_CFLAGS' too to make sure + we get the right `CFLAGS'. + +2000-04-20 Pavel Cisler + + * libgnomevfs/gnome-vfs-xfer.c: + (move_items): + Move the call_progress call after where the file was moved, that way the + file is in guaranteed to be in it's final destination when the callback + kicks in for it. + +2000-04-19 Pavel Cisler + + * libgnomevfs/gnome-vfs-file-info.c: + * libgnomevfs/gnome-vfs-file-info.h: + (gnome_vfs_file_info_matches): + Added a new call. + + * libgnomevfs/gnome-vfs-xfer.c: + Added a bunch of call_progress calls to ensure we can follow all + the file system changes during a copy. + +2000-04-19 Pablo Saratxaga + + * configure.in (ALL_LINGUAS): added Catalan + +2000-04-18 Pavel Cisler + + Fixed two bugs Darin ran into. + + * libgnomevfs/gnome-vfs-xfer.c: + (call_progress_with_current_names), (handle_error), + (handle_overwrite): + Made error/overwrite dialogs properly show the file that was being copied + while an error ocurred. + + * libgnomevfs/gnome-vfs-xfer.c: + (handle_name_conflicts): + Add a way for the progress callback to find out if a single or multiple + items ended up conflicting. That way the progress callback can determine + if to add a Replace All option or not. + + * libgnomevfs/gnome-vfs-xfer.c: + (gnome_vfs_xfer_private): + Added a workaround for a bug that happens when the caller of the + routine tries to handle a returned error by calling the progress + callback -- the problem is that that at that point the progress + could have already cleaned up after itself knwong that the copy + operation is over and could have deleted it's user data. + + * libgnomevfs/gnome-vfs-xfer.c: + * test/test-xfer.c: + Fixed warnings. + +2000-04-18 Pavel Cisler + + * libgnomevfs/gnome-vfs-xfer.c: + (handle_error): + Made the error return value get set to GNOME_VFS_OK after + Skip is selected -- This caused gnome_vfs_xfer_private to + return an unexpected error that execute_xfer didn't know how + to deal with. + + * libgnomevfs-pthread/gnome-vfs-job.c: + (execute_xfer): + Properly set up the dummy progress_info and progress_state + structs used for reporting unexpexted error results returned + by gnome_vfs_xfer_private. + +2000-04-18 Pavel Cisler + + Fixed a bug in error reporting that I introduced in my + previous checkin. + + * libgnomevfs/gnome-vfs-xfer.c: + (handle_error): + Set the progress_info->status value to the correct error value. + (move_items): + Fix a bug in a retry case - the result value needs to get reset to + GNOME_VFS_OK after Retry is selected. + +2000-04-17 Maciej Stachowiak + + Work with either OAF or GOAD: + + * libgnomevfs-corba/gnome-vfs-corba.c, + libgnomevfs-corba/gnome-vfs-salve.c: initialize appropriately for + GOAD or OAF. + * libgnomevfs-corba/gnome-vfs-async-ops.c, + libgnomevfs-corba/gnome-vfs-slave-notify.c, + libgnomevfs-corba/gnome-vfs-slave-process.c: Remove gratuitous + include of + * libgnomevfs-corba/Makefile.am: Link against the appropriate + choice of OAF or GNORBA. + * configure.in, acconfig.h: Add --enable-oaf option and if used, + check for OAF. + +2000-04-17 Pavel Cisler + + Made it possible for the gnome-vfs async copy engine to have + two kinds of progress callbacks - one that gets called every + hundred milliseconds or when user response is required and one + that gets called for every single copy operation primitive. + The latter is not called in the context of the master process + and is much lighterweight to invoke. Nautilus will be using + this callback mechanism to queue up notification records during + a copy. + + * libgnomevfs/gnome-vfs-async-ops.h: + * libgnomevfs/gnome-vfs-backend.c: + * libgnomevfs-corba/gnome-vfs-async-ops.c: + * libgnomevfs-pthread/gnome-vfs-job.c: + * libgnomevfs-pthread/gnome-vfs-job.h: + (gnome_vfs_xfer_async), (corba_gnome_vfs_async_xfer), + (pthread_gnome_vfs_async_xfer): + Add optional sync callback and parameters. Pass the new + parameters around. + + * libgnomevfs/gnome-vfs-private-ops.h: + * libgnomevfs/gnome-vfs-xfer.c: + (gnome_vfs_xfer_private): + Add new private common copy engine entry point. + + * libgnomevfs/gnome-vfs-private-types.h: + * libgnomevfs/gnome-vfs-xfer.c: + Add new GnomeVFSProgressCallbackState that contains the + two callback, their user data, the timing logic for calling the + update callback often. + (handle_error), (remove_file), (remove_directory), (copy_file_data), + (xfer_open_source), (xfer_create_target), (gnome_vfs_xfer_uri_internal), + (gnome_vfs_xfer_uri), (gnome_vfs_xfer), (gnome_vfs_xfer_private) + Rework xfer calls to pass around the new GnomeVFSProgressCallbackState + structure. + + * libgnomevfs/gnome-vfs-private-types.h: + * libgnomevfs/gnome-vfs-xfer.c: + (call_progress), (progress_set_source_target_uris), + (progress_set_source_target_names), (init_progress), + (call_progress_uri), (call_progress_often), + (call_progress_with_uris_often): + Reworked progress calls to use GnomeVFSProgressCallbackState. + + * libgnomevfs/gnome-vfs-types.h + * libgnomevfs-corba/gnome-vfs-slave-notify.c: + * libgnomevfs-corba/gnome-vfs-slave.c: + * libgnomevfs-pthread/gnome-vfs-async-ops.c: + * test/test-xfer.c: + Add new enum values so that progress callbacks can + detect whether a copy, move or remove operations is being performed. + Got rid of the GNOME_VFS_XFER_PHASE_XFERRING enum value. + + * gnome-vfs/libgnomevfs/gnome-vfs-xfer.h + Got rid of an obsolete comment. + +2000-04-13 Darin Adler + + * libgnomevfs/gnome-vfs-async-ops.h: + * libgnomevfs/gnome-vfs-backend.c: + Changed the async. operations so they report their errors through + the callbacks all the time instead of sometimes returning an error + code immediately. This is more convenient for callers, although + it's a bit more complex to implement. + + * libgnomevfs-pthread/gnome-vfs-async-ops.c + (pthread_gnome_vfs_async_load_directory): + * test/test-async-directory.c (main): + * test/test-async.c (main): + * test/test-channel.c (main): + Fix callers so they no longer expect a result code. + + * .cvsignore: Another generated file to ignore. + +2000-04-12 Pavel Cisler + + * libgnomevfs/gnome-vfs-xfer.c.c: + (gnome_vfs_xfer_uri_internal), (count_items_and_size): + Make the move operation properly preflight by only adding up + the items to move nonrecursively. + +2000-04-11 Pavel Cisler + + * libgnomevfs/gnome-vfs-xfer.c.c: + (gnome_vfs_xfer_uri), (gnome_vfs_xfer_uri_internal), + (handle_name_conflicts): + Fixed problems with using "Skip" during a move/copy conflict. + The first problem was that a skip flag wasn't being checked properly. + The second, bigger problem, was that the handle_name_conflicts + had no good way of telling the rest of the copy engine that + a given file was skipped. Now it gets a copy of the source/ + targe item lists and optionally removes the items the user + chose to skip. + +2000-04-11 John Sullivan + + * modules/file-method.c: + (do_get_file_info): statbuf was passed to set_mime_type + uninitialized. Fixed by passing &statbuf to get_stat_info, + which was obviously the original intention. + +2000-04-11 Darin Adler + + * libgnomevfs/gnome-vfs-backend.c (gnome_vfs_async_create_uri): + Added another missing async. cover routine. + +2000-04-06 Pavel Cisler + + * libgnomevfs/gnome-vfs-xfer.c: + * libgnomevfs/gnome-vfs-types.h: + Fixed up the copy engine. + Added an option to create duplicate items with the help of + the progress_callback. + Worked around a problem where calling progress_callback in async + mode was causing context switches each time and degreaded performance. + For now made it only call the callback every 200 ms for cases where + response is not important. This will get reworked eventually. + (progress_set_source_target_names), (progress_set_source_target_uris), + (call_progress), (call_progress_uri), (call_progress_often), + (call_progress_with_uris_often): + Added a bunch of convenience calls for calling the progress callback. + (gnome_vfs_visit_list): + Convenience call to iterate a base uri and a list of name, similar to + the visit directory calls. + (count_items_and_size): + New preflight call - calculates the sum and total size of copied files. + Made all preflight operations call progress_info and be interruptible. + (handle_name_conflicts): + New preflight call - finds out if there are conflicts in the target + destination and optionally prompts the user to remove them. + (create_directory), (copy_directory), (gnome_vfs_xfer_uri): + Reworked the copy engine to use a recursive directory copy instead + one that first creates a flat list. This way the copy will be able to + deal with directories being moved from under the copy operation + properly. + (remove_file), (remove_directory): + Call progress callback to make them interruptible, make remove_directory + optionally recursive. + + * libgnomevfs-pthread/gnome-vfs-job.c: + (xfer_callback):Fixed a bug where notify.progress_info was not being + initialized. + + * libgnomevfs-pthread/gnome-vfs-job.c: + * libgnomevfs-corba/gnome-vfs-slave.c: + Renamed the GNOME_VFS_XFER_PHASE_UNKNOWN to GNOME_VFS_XFER_PHASE_INITIAL + (the phase is always known and an initial phase was needed). + +2000-04-06 Ian McKellar + + * modules/http-method.c: + Added code to recognise stupid web servers that return an invalid + reply to PROPFIND requests. + +2000-04-05 Darin Adler + + * libgnomevfs/gnome-vfs-xfer.c (fast_move): Fixed an infinite + loop. (It even had a comment that said it was an infinite loop.) + + * libgnomevfs/gnome-vfs-seekable.c (init_seek): Got rid of \n + in a g_warning. + +2000-04-05 Ian McKellar + + * modules/http-method.c: + Added a create method, and fixed the write/close method so that + Nautilus can successfully store metafiles, and so writing to WebDAV + repositories will work in the future. + +2000-04-04 Andy Hertzfeld + + * libgnomevfs/gnome-vfs-uri.c: + fixed critical assertion that Nautilus was encountering using + non-filesystem uris by making sure the uri was reference before + calling unref. + +2000-04-04 Ian McKellar + + * modules/http-method.c: + Fixed WebDAV directory code to remove leading "/" from filenames. + +2000-03-29 Darin Adler + + * libgnomevfs/gnome-vfs-directory.c (open_from_uri): + Use CHECK_IF_SUPPORTED macro to be consistent with the rest of the file. + + * libgnomevfs/gnome-vfs-private-ops.c: + (gnome_vfs_open_uri_cancellable), (gnome_vfs_create_uri_cancellable), + (gnome_vfs_set_file_info_cancellable): + Added missing checks for NULL in the module. The rest of the operations + had checks for NULL. + + * libgnomevfs/gnome-vfs-uri.c: + (gnome_vfs_uri_is_local): Check for a NULL is_local pointer. Unlike the + other operations, for this one it's illegal to be NULL since there is + no way to return the NOTSUPPORTED error code. + + * test/.cvsignore: Missing file. + +2000-03-28 Pavel Cisler + + * libgnomevfs/gnome-vfs-xfer.c: + (move_file): initialize "skip" properly. + + * libgnomevfs/gnome-vfs-uri.c: + (gnome_vfs_uri_get_parent): strip trailing slashes. Handle + multiple slashes properly. + + * libgnomevfs-pthread/gnome-vfs-job.c: + (execute_xfer): pass the proper job structure. + + * libgnomevfs-pthread/gnome-vfs-async-ops.c: + (pthread_gnome_vfs_async_xfer): pass the proper job type selector. + +2000-03-28 John Sullivan + * gnome-vfs-uri.c: + (gnome_vfs_uri_extract_short_name): Check for empty-string + host name as well as NULL. + +2000-03-28 John Sullivan + + * gnome-vfs-uri.h, + * gnome-vfs-uri.c: + (gnome_vfs_uri_extract_short_name): Made this function return the + host name (if any) when there's no path. Formerly it just returned + "/" in that case. + (gnome_vfs_uri_extract_short_path_name): New function, really a + renaming of the old gnome_vfs_uri_extract_short_name. There are those + who argue that this should be renamed extract_basename and the current + get_basename (which doesn't handle trailing path separators according + to XPG spec) should be abolished. + +2000-03-25 Yukihiro Nakai + + * configure.in: Added Japanese translation from Akira Tagoh. + +2000-03-20 Pablo Saratxaga + + * configure.in,po/lt.po: Added Lithuanian language file + +2000-03-13 Elliot Lee + + * modules/Makefile.am: Finish the help-method move. Move module-shared stuff to + libgnomevfs. + * libgnomevfs/Makefile.am: Install our "private" headers for use by modules. + + * modules/http-method.c: #if 0 debug messages. + * libgnomevfs/gnome-vfs-uri.c: Fix split_toplevel_uri for URIs with a hostname but no path. + * modules/Makefile.am: Move help-method over to nautilus. + +2000-03-10 Ian McKellar + + * modules/http-method.c + Added made do_get_file_info* understand WebDAV servers. + Also, made WebDAV collections return the mime-type special/webdav-directory. + +2000-03-10 Pavel Machek + + * TODO: added pointers to other similar projects + +2000-03-09 Jonathan Blandford + + * libgnomevfs/gnome-vfs-types.h: Add a urn field to + GnomeVFSToplevelURI. This will let us add VFS modules that simply + change a totally virtual name to a actual URL. + + * modules/help-method.c: New module to allow for "help:*" URL's. + * modules/help-method.h: + + * modules/Makefile.am: added help module. + + * libgnomevfs/gnome-vfs-method.c (gnome_vfs_transform_get): Allow + Transformations. Clean up the code a little. + + * libgnomevfs/gnome-vfs-uri.c (gnome_vfs_uri_new): changed to + allow for translations. Also, code cleaned up a lot. + +2000-03-09 Ian McKellar + + * modules/http-method.c + Added (open|read|close)_directory support for WebDAV servers. + + * configure.in, modules/Makefile.am + Added checks for gnome-xml as are required for the WebDAV directory + code. + +2000-03-07 Ian McKellar + + * modules/http-method.c + Added PUT support (i.e. WebDAV or HTTP/1.1 file upload). + + * test/test-sync-write.c + Added a test program which writes from stdin to a URI. + + * test/test-sync.c + Patched test-sync.c to handle larger files. + +2000-03-06 Ettore Perazzoli + + * libgnomevfs/gnome-vfs-private-ops.c + (gnome_vfs_get_file_info_uri_cancellable): If the `get_file_info' + method is not implemented, return `GNOME_VFS_ERROR_NOTSUPPORTED' + instead of crashing. + + * configure.in: Generate `gnome-vfs.spec' from + `gnome-vfs.spec.in'. + + * gnome-vfs.spec.in: New file. From Ross Golder + . + +2000-03-03 Maciej Stachowiak + + * libgnomevfs/gnome-vfs-utils.c, libgnomevfs/gnome-vfs-utils.h + (gnome_vfs_escape_string, gnome_vfs_unescape_string): New + functions to escape and unescape URI strings; patch from Gene + Z. Ragan . + +2000-03-02 Maciej Stachowiak + + * modules/http-method.c (get_file_info_from_http_handle): Don't + pretend we know the file size when we don't. + +2000-02-24 Ettore Perazzoli + + * test/test-directory.c (print_list): Deal with a NULL MIME type. + + Patch from Marcus Nilsson : + * modules/file-method.c (struct _DirectoryHandle): Made + `current_entry' a pointer to a `struct dirent *' instead of just a + `struct dirent'. + (read_directory): Updated accordingly. + (directory_handle_new): Allocate `current_entry' with + `g_malloc()', allocating extra space as required by `readdir_r()'. + (directory_handle_destroy): Free `current_entry'. + +2000-02-22 Ettore Perazzoli + + * Version 0.1 is released. + +2000-02-21 Ettore Perazzoli + + * libgnomevfs/gnome-vfs-cancellation.c + (gnome_vfs_cancellation_check): If the cancellation is NULL, just + return FALSE. + (gnome_vfs_cancellation_ack): If the cancellation is NULL, just + return. + + * test/test-xfer.c (xfer_progress_callback): Use + `GNOME_VFS_SIZE_FORMAT_STR' to match the types. + + * test/test-async-directory.c (main) [!WITH_CORBA]: Do not define + `ev', so that we don't get annoying compiler warnings. + + * test/test-xfer.c (xfer_progress_callback): Add casts. + + * test/test-directory-visit.c (directory_visit_callback): Add + cast. + + * test/test-directory.c (print_list): Add cast. + + * test/test-async-directory.c (main): Removed unused variable. + + * modules/translate-method.c (tr_do_read_directory): Added cast to + placate the compiler. + + * modules/file-method.c (do_get_file_info_from_handle): + s/gnome_vfs_extract_short_name/gnome_vfs_uri_extract_short_name/. + `gnome_vfs_extract_short_name' does not even exist! + + * modules/extfs-method.c: Add missing NULL pointer in + initialization of `method'. + + * libgnomevfs-corba/gnome-vfs-slave.c (serve_channel_read): Use + `GNOMEVFSFileSize' instead of `gulong'. + (serve_channel_write): Likewise. + + * modules/Makefile.am (libhttp_la_LIBADD): Do not link the HTTP + module with `-lghttp' (we don't actually use it). + +2000-02-21 Jonathan Blandford + + * libgnomevfs/gnome-vfs-cancellation.c + (gnome_vfs_cancellation_check): change g_return_if_fail to be a + g_return_val_if_fail. I don't know if the g_ function is right + here, but until that gets straightened out, make it compile. + +2000-02-21 Elliot Lee + * libgnomevfs/gnome-vfs-configuration.c: "Home made check" is supposed to be there. + g_return_if_fail inappropriate, change reverted. + +2000-02-20 Mathieu Lacage + + * libgnomevfs/gnome-vfs-configuration.c: plug memory leak in + module_path_element_free intorduced by someone who forgot + the arg element. Change a home-made check in g_return_if_fail. + * libgnomevfs/gnome-vfs-cancelation.c: Change home-made check + in g_return_if_fail. + +2000-02-18 Maciej Stachowiak + + * modules/file-method.c (do_get_file_info, + do_get_file_info_from_handle): Use gnome_vfs_extract_short_name on + the URI rather than g_basename on the filename to get the + basename. g_basename is broken. + +2000-02-17 Jonathan Blandford + + * modules/default-modules.conf (ghelp): add ghelp to the list of + known domains. + +2000-02-16 Elliot Lee + * test/test-async.c: Exit after receiving read(), no matter what result is received. + * modules/pipe-method.c: Check fread() result for being > 0, not !EOF + * libgnomevfs/gnome-vfs-uri.c: Don't add leading / + * libgnomevfs/gnome-vfs-backend.c: Add assert to ensure initialization. + * modules/default-methods.conf: Pass filename to gnome-man2html2 instead of redirecting + it as input. + +2000-02-15 John Sullivan + + * libgnomevfs/gnome-vfs-configuration.c: + (gnome_vfs_configuration_get_module_path): Just clarified an + error message. + +2000-02-14 Maciej Stachowiak + + * libgnomevfs/gnome-vfs-types.h: Added a GnomeVFSFIleInfoFields + enumeration, and added a field of this type (valid_fields) to + GnomeVFSFileInfo, so that cases where get_file_info returns + incomplete information can be handled gracefully. + * modules/extfs-method.c, modules/file-method.c, + modules/ftp-method.c, modules/http-method.c, + modules/module-shared.c, modules/pipe-method.c, + modules/translate-method.c: Set the valid_fields + +2000-02-09 Elliot Lee + + * libgnomevfs/gnome-vfs-messages.c, libgnomevfs/gnome-vfs-method.c, + libgnomevfs/gnome-vfs-process.c, libgnomevfs-corba/gnome-vfs-async-ops.c, + libgnomevfs-corba/gnome-vfs-slave-launch.c, libgnomevfs-corba/gnome-vfs-slave-notify.c, + libgnomevfs-corba/gnome-vfs-slave-process.c, modules/ftp-method.c: Remove excess + debugging output. + + * libgnomevfs/gnome-vfs-handle.c, libgnomevfs/gnome-vfs-handle.h, + libgnomevfs/gnome-vfs-ops.c, libgnomevfs/gnome-vfs-ops.h, + libgnomevfs/gnome-vfs-private-ops.c, + libgnomevfs/gnome-vfs-private-ops.h, + libgnomevfs/gnome-vfs-private-types.h, + libgnomevfs/gnome-vfs-seekable.c: Add gnome_vfs_truncate and gnome_vfs_truncate_handle. + * modules/bzip2-method.c, modules/extfs-method.c, + modules/file-method.c, modules/ftp-method.c, + modules/gconf-method.c, modules/gzip-method.c, + modules/http-method.c, modules/pipe-method.c, + modules/translate-method.c: Implement truncate (or don't). + * libgnomevfs-corba/gnome-vfs-corba.c: putenv("GNOME_DISABLE_CRASH_DIALOG=1") so we don't get stupid crash dialogs. + * libgnomevfs-pthread/gnome-vfs-async-ops.c: Fix obvious get_file_info bug. + +2000-02-07 Elliot Lee + + * libgnomevfs-corba/gnome-vfs-slave-notify.c: When memcpy'ing over a new GnomeVFSFileInfo, reset the refcount to 1 + so that we can unref it later. + * libgnomevfs-corba/gnome-vfs-slave.c: Fix stupid cut & paste bug that was using the wrong loop variable. + Also unref the file_info instead of destroying it. + +2000-02-02 Elliot Lee + + * idl/gnome-vfs-slave.idl, libgnomevfs/gnome-vfs-async-ops.h, + libgnomevfs/gnome-vfs-backend.c, libgnomevfs/gnome-vfs-types.h, libgnomevfs-corba/*.[ch], libgnomevfs-pthread/*.[ch]: + Implement asynchronous get_file_info operation. Compiles but is untested. + + * libgnomevfs/gnome-vfs-method.c: Pass method_name and config options to the module. + * libgnomevfs/gnome-vfs-private-types.h: Pass GnomeVFSMethod + pointer as first arg to all method implementation routines. + * libgnomevfs/*.c, modules/*.c: Reflect above changes. + * libgnomevfs/gnome-vfs-configuration.[ch]: Parse and return + module arguments from config file. Fix miscellaneous bugs. + * modules/translate-method.c, modules/Makefile.am: Implement a + 'URI translation' module that just translates URIs according to configuration options, then passes them + on to the real module. + +2000-02-01 Darin Adler + + * libgnomevfs-corba/gnome-vfs-slave-notify.c: + Make more-easily-understood g_warning messages for + cases where the wrong operation is in progress. + + * libgnomevfs/gnome-vfs-uri.c: Use defines instead of + hard-coded '/' characters consistently. + +2000-01-28 Elliot Lee + + * libgnomevfs/gnome-vfs-configuration.c: Support reading multiple configuration files from multiple directories. + * libgnomevfs/gnome-vfs-{configuration,private}.h: Move #defines from gnome-vfs-configuration.h to gnome-vfs-private.h + * libgnomevfs/Makefile.am: Add defines of sysconfdir and libdir to cflags, remove prefix define. + * modules/Makefile.am: Rename modules.conf to default-modules.conf, and install into $(sysconfdir)/vfs/modules instead. + +2000-01-27 Elliot Lee + + * modules/pipe-method.[ch]: Implement a stupid one-cent trick pipe method - produces output of a pipe. + +2000-01-27 John Sullivan + + Moved, renamed, and made public GnomeVFSFileInfo-comparing routines. + + * libgnomevfs/gnome-vfs-file-info.c: + * libgnomevfs/gnome-vfs-file-info.h: + (gnome_vfs_file_info_compare_for_sort), + (gnome_vfs_file_info_compare_for_sort_reversed): + New functions, moved & renamed from static functions in + gnome-vfs-directory-list.c. Changed third parameter from + constgpointer to const GnomeVFSDirectorySortRule * for clarity. + + * libgnomevfs/gnome-vfs-directory-list.c: + (compare_for_sort), (compare_for_sort_reversed): Removed. + (gnome_vfs_directory_list_sort): Updated to reflect name change. + +2000-01-18 Ettore Perazzoli + + * libgnomevfs/gnome-vfs-directory.c (directory_visit_internal): + Unref instead of destroying the file info. + (directory_visit_internal): Likewise. + (directory_visit_internal): Likewise. + (directory_visit_internal): Likewise. + (gnome_vfs_directory_visit_files_at_uri): Likewise. + + * libgnomevfs/gnome-vfs-directory-list.c (remove_entry): Unref + instead of destroying the file info. + (gnome_vfs_directory_list_destroy): Likewise. + (load_from_handle): Likewise. + +2000-01-18 John Sullivan + + * libgnomevfs/gnome-vfs-directory-list.c: (compare_for_sort): + Made sorting by mime type handle NULL mime types (e.g. directories). + +2000-01-18 Federico Mena Quintero + + * libgnomevfs/gnome-vfs-uri.c (gnome_vfs_uri_destroy): Removed. + It does not make sense to have this function, as we have proper + reference counting of URIs. + (gnome_vfs_uri_new): Use gnome_vfs_uri_unref() instead of + destroy() for the new_uri. + (gnome_vfs_uri_unref): Added a sanity check for the reference + count. + +2000-01-18 Elliot Lee + + * configure.in: We want ORBit, not gnorba. + +2000-01-16 John Sullivan + + Split utils into public and private, and moved file-size-as-string + method into new public utils. + + * libgnomevfs/gnome-vfs-private-utils.h: + * libgnomevfs/gnome-vfs-private-utils.c: + New files, containing most of what was in gnome-vfs-utils.h/c. + + * libgnomevfs/gnome-vfs-utils.h: + * libgnomevfs/gnome-vfs-utils.c: + Moved everything from here to gnome-vfs-private-utils.h/c, except... + (gnome_vfs_size_as_string): Renamed to gnome_vfs_file_size_as_string, + changed parameter from ulong to GnomeVFSFileSize, replaced + implementation with similar but slightly cleaner code written by Havoc + in nautilus/src/file-manager/fm-directory-view.c + + * Makefile.am: Moved gnome-vfs-utils.h to public headers, added + gnome-vfs-private-utils.h/.c to the build. + + * modules/http-method.c: (create_handle), (do_read): Updated all + callers of gnome_vfs_size_as_string to reflect new name. + +2000-01-16 Federico Mena Quintero + + * libgnomevfs-pthread/Makefile.am: Do not put $(VFS_LIBS) in the + library LDADD. + +2000-01-14 Darin Adler + + * libgnomevfs/gnome-vfs-uri.h: libgnomevfs/gnome-vfs-uri.c: + (gnome_vfs_uri_extract_short_name): Added a new function to get the + short form of a uri. This is the same as the XPG version of basename, + and the basename tool, but g_basename, gnome_vfs_uri_get_basename, and + gnome_vfs_uri_extract_dirname use a different definition, where the + basename of a uri that points to a directory with a trailing '/' is + NULL. The short_name variant is useful when you want to know the name + of a directory even though the uri might end in '/'. + +2000-01-11 Darin Adler + + * libgnomevfs-corba/gnome-vfs-slave-notify: + (impl_Notify_dying): Changed the messages to use g_message instead + of g_warning, since they are normal. + +2000-01-11 Ettore Perazzoli + + * libgnomevfs/gnome-vfs-uri.c (gnome_vfs_uri_get_basename): Do not + strdup. + +2000-01-06 Darin Adler + + * libgnomevfs/gnome-vfs-backend.c: (gnome_vfs_async_open_uri): + Implemented this missing routine. + +2000-01-04 John Sullivan + + * libgnomevfs/gnome-vfs-uri.c: (gnome-vfs-uri-new): + Removed g_return_val_if_fail() for empty string case, + since rest of routine handles empty string identically + to any other bogus string. + * libgnomevfs/gnome-vfs-ops.c: (gnome_vfs_get_file_info): + Avoid calling gnome_vfs_uri_unref on NULL uri, to avoid + g_return_if_fail. + +2000-01-02 Tomasz K³oczko + * configure.in, po/pl.po: added Polish translation + (based on GNOME PL translation resources). + +1999-12-30 Miguel de Icaza + + * libgnomevfs-corba/gnome-vfs-async-ops.c + (corba_gnome_vfs_async_cancel): Removed C++ comment. + +1999-12-29 Elliot Lee + + * acconfig.h, libgnomevfs/gnome-vfs-backend.[ch], + libgnomevfs/gnome-vfs-init.[ch], libgnomevfs-{pthread,corba}/*: + Load the corba & pthread backends via gmodule instead of linking + them in. + * modules/*-method.c: Fix warnings. + +1999-12-29 Jesus Bravo Alvarez + + * configure.in: (ALL_LINGUAS) Added Galician (gl). + +1999-12-28 Martin Norbäck + + * configure.in: Added sv to ALL_LINGUAS. + +1999-12-28 Yuri Syrota + + * configure.in: Added "uk" to ALL_LINGUAS. + +1999-12-27 Matthias Warkus + + * configure.in: Added de to ALL_LINGUAS. + +1999-12-21 Elliot Lee + + * modules/ftp-method.c: Fix get_file_info so MIME type gets filled in. + + * modules/http-method.c: Don't pass the full URL, since this violates the HTTP spec. + * libgnomevfs/gnome-vfs-uri.c: Properly implement handling of all the hide_options. + + * modules/http-method.c: Don't treat redirections as an error. + + This is not quite the "right" solution, since redirections are + similar to symlinks, and this change doesn't check for the + GNOME_VFS_FILE_INFO_FOLLOW_SYMLINKS flag. It's also possible that + the MIME type returned from a redirection is different than the + MIME type of the target. + +1999-12-18 Havoc Pennington + + * libgnomevfs/gnome-vfs-file-info.c (gnome_vfs_file_info_new): + init refcount + (gnome_vfs_file_info_init): init refcount + (gnome_vfs_file_info_destroy): remove in favor of unref(), + with compatibility #define + (gnome_vfs_file_info_unref): new function + (gnome_vfs_file_info_ref): new function + + * libgnomevfs/gnome-vfs-types.h: Add refcount to GnomeVFSFileInfo. + The refcount won't be used if the object is on the stack of course. + +1999-12-16 Maciej Stachowiak + + * libgnomevfs-corba/gnome-vfs-async-ops.c, + libgnomevfs-corba/gnome-vfs-slave-process.c : Avoid leaving around + gnome-vfs-slave processes. + + * libgnomevfs/gnome-vfs-method.c (gnome_vfs_method_get): Avoid + reinitializing the method table (nautilus was causing this to + happen). + +1999-12-16 Ettore Perazzoli + + * libgnomevfs-corba/gnome-vfs-slave-notify.c + (impl_Notify_load_directory): Actually set the list in the + `GnomeVFSAsyncDirectoryOpInfo' struct when creating it from + scratch. + +1999-12-15 Elliot Lee + + * libgnomevfs*/*.c: Fix warnings. + * configure.in: Add --with-default-backend=... + +1999-12-15 Darin Adler + + * libgnomevfs/gnome-vfs-method.c: (load_module): + Changed "Loading module" message to a g_message, since we + want to ignore it, and we don't want to ignore g_warnings. + * libgnomevfs/gnome-vfs-process.c: (wake_up): + Changed "Process died" message to a g_message, since we + want to ignore it, and we don't want to ignore g_warnings. + (gnome_vfs_process_new): Changed "Process died" message to + a g_message, since we want to ignore it, and we don't want + to ignore g_warnings. + +1999-12-15 Elliot Lee + * libgnomevfs/gnome-vfs-ops.c: Sanity check for an invalid URI. + * libgnomevfs/gnome-vfs-ops.[ch]: Use char instead of gchar. + * libgnomevfs-corba/gnome-vfs-slave-process.c: Use g_message instead + of the incorrect g_warning. + +1999-12-15 Darin Adler + + * libgnomevfs/gnome-vfs-async-ops.h + * libgnomevfs/gnome-vfs-context.c + * libgnomevfs/gnome-vfs-directory-list.c + * libgnomevfs/gnome-vfs-directory-list.h + * libgnomevfs/gnome-vfs-directory.c + * libgnomevfs/gnome-vfs-directory.h + * libgnomevfs/gnome-vfs-messages.c + * libgnomevfs/gnome-vfs-ops.c + * libgnomevfs/gnome-vfs-ops.h + * libgnomevfs/gnome-vfs-private-ops.c + * libgnomevfs/gnome-vfs-private-ops.h + * libgnomevfs/gnome-vfs-utils.c + * libgnomevfs/gnome-vfs-utils.h + * libgnomevfs-corba/gnome-vfs-async-ops.c + * libgnomevfs-corba/gnome-vfs-slave-notify.c + * libgnomevfs-pthread/gnome-vfs-async-ops.c + * test/test-seek.c + Made meta_keys[] take const char* instead of char*. + Fixed some warnings. + +1999-12-14 Darin Adler + + * .cvsignore: Ignore more generated files. + * libgnomevfs-corba/.cvsignore: Ignore more generated files. + * modules/extfs/.cvsignore: Ignore more generated files. + * test/.cvsignore: Ignore more generated files. + +1999-12-14 Elliot Lee + + * libgnomevfs-corba/gnome-vfs-async-ops.c: Implement gnome_vfs_async_load_directory_uri + in terms of gnome_vfs_async_load_directory by converting the GnomeVFSURI to a string. + Also, fill in the 'op_info' in gnome_vfs_async_load_directory. + +1999-12-09 Havoc Pennington + + * modules/gconf-method.c (vfs_module_init): Some updates, the + GConf stuff is updated but it still doesn't match the latest + virtual table that modules are expected to have. + + * modules/Makefile.am (libgconf_la_LIBADD): add GTK_LIBS + (INCLUDES): add GCONF_CFLAGS + + * configure.in (VFS_LIBS): use the located $GCONF_CONFIG instead + of just "gconf-config", look for GTK to use the GConfClient + GtkObject. + +1999-12-08 Ramiro Estrugo + + * modules/extfs/Makefile.am + take out non existance extfs.ini from EXTRA_DIST to unbreak + 'make dist' + +1999-12-07 Havoc Pennington + + * libgnomevfs-pthread/gnome-vfs-job.c (serve_channel_read): handle + cancellation during the read, and then check for it before we + write, and after each write. + + * libgnomevfs/gnome-vfs-iobuf.c (gnome_vfs_iobuf_read): Return + immediately if the number of bytes to read is 0. + + * libgnomevfs-pthread/gnome-vfs-job.c (serve_channel_read): + Rewrite this to use nonblocking writes; allows us to + keep reading while the main thread is blocked. + + * libgnomevfs/gnome-vfs-utils.c (gnome_vfs_size_to_string): fix + operator precedence problem + + * libgnomevfs-pthread/gnome-vfs-job.c (serve_channel_write): Take + a context argument, and then use gnome_vfs_write_cancellable() so + status messages can trickle up. The messages are coming from the + slave thread; so the status message callback setup is supposed to + be thread safe. The one in Explorer is indeed. + (serve_channel_read): Parallel change, add the context object. + +1999-12-06 Havoc Pennington + + * libgnomevfs-corba/gnome-vfs-slave-process.c + (gnome_vfs_slave_process_new): Creates a context object. + + * libgnomevfs/gnome-vfs-async-ops.h + (gnome_vfs_async_remove_status_callback): declare status callback + add/remove functions. + + * libgnomevfs-pthread/gnome-vfs-async-ops.c + (gnome_vfs_async_add_status_callback): implement status callback ops + + * libgnomevfs-corba/gnome-vfs-async-ops.c + (gnome_vfs_async_remove_status_callback): implement status + callback ops + + * libgnomevfs/gnome-vfs-messages.c: Add ID numbers for callback + removal + + * modules/http-method.c (create_handle): Emit message about # of + bytes to retrieve. + (do_close): emit message saying "closing" + (do_read): emit message about bytes read. + + * libgnomevfs/gnome-vfs-utils.c (gnome_vfs_size_to_string): New + function, returns a string representing a size in bytes + + * libgnomevfs-pthread/gnome-vfs-job.h: replace cancellation with context + + * modules/gzip-method.c: replace cancellation with context + + * modules/bzip2-method.c: replace cancellation with context + + * modules/ftp-method.c: replace cancellation with context + + * modules/http-method.c: replace cancellation with context + + * modules/file-method.c: replace cancellation with context + + * modules/extfs-method.c: replace cancellation with context + +1999-12-03 Havoc Pennington + + * libgnomevfs/gnome-vfs-private-ops.h: replace cancellation with + context + + * libgnomevfs/gnome-vfs-handle.h: replace cancellation with + context + + * libgnomevfs/gnome-vfs-private-ops.c: replace cancellation with + context + + * libgnomevfs/gnome-vfs-seekable.c: replace cancellation with + context + + * libgnomevfs/gnome-vfs-directory.c: Replace cancellation with + context + + * libgnomevfs/gnome-vfs-private.h: add gnome-vfs-context.h, + include too + + * libgnomevfs/gnome-vfs.h: add gnome-vfs-messages.h + + * libgnomevfs/gnome-vfs-private-types.h: typedef the + GnomeVFSContext type; change GnomeVFSCancellation to + GnomeVFSContext for all functions in the GnomeVFSMethod vtable + + * libgnomevfs/gnome-vfs-context.c, + libgnomevfs/gnome-vfs-context.h: Proposed API for a context object + to be passed to VFS module functions. + +1999-12-04 Ettore Perazzoli + + * libgnomevfs-pthread/gnome-vfs-async-ops.c + (gnome_vfs_async_cancel): Added comment about the need for freeing + the handle. + +1999-12-02 Havoc Pennington + + * libgnomevfs/gnome-vfs-messages.c: all my filter predicates were + backward + +1999-12-02 Havoc Pennington + + * libgnomevfs/gnome-vfs-messages.h, + libgnomevfs/gnome-vfs-messages.c: New file, a simple data type to + manage status-message callback lists. Untested, not in the build. + +1999-11-29 Elliot Lee + + * libgnomevfs-corba/*.c: Don't __alloc() buffers for temporary usage only. + * libgnomevfs/gnome-vfs-cancellation.c (gnome_vfs_cancellation_cancel): Now guaranteed signal-safe. + + * libgnomevfs/gnome-vfs-method.c: If init_path_list() has already been called, return TRUE to indicate success. + + * libgnomevfs/gnome-vfs-result.c: I declare the errno->GnomeVFSResult translation function "complete enough". + +1999-11-24 Elliot Lee + + * modules/Makefile.am: Try using $(GLIB_LIBS) to pick up the -L thingie for -lghttp + * Makefile.am: Remove 'intl' dir from build. + +1999-11-19 Kjartan Maraas + + * configure.in: Added "no" to ALL_LINGUAS. + +1999-11-18 Ettore Perazzoli + + * modules/file-method.c: Removed the static function prototypes + and moved the method struct to the end of the file so that they + are not needed anymore. + (rename_helper): New helper function, cut & paste from + `do_move()'. + (do_move): Use it. + (do_set_file_info): New function, implementing the `set_file_info' + method. + (do_make_directory): Use `MAKE_ABSOLUTE' to make sure the path we + use is absolute. + (do_move): Likewise. + (do_unlink): Likewise. + (do_check_same_fs): Likewise. + (directory_handle_new): Likewise. + (do_get_file_info): Likewise. + (do_create): Likewise (forgot to use `file_name' instead of + `uri->text' here). + + * libgnomevfs/gnome-vfs-ops.c (gnome_vfs_check_same_fs): Check + that `same_fs_return' is not NULL. + + * libgnomevfs/gnome-vfs-ops.c (gnome_vfs_set_file_info_uri): New + function. + (gnome_vfs_set_file_info): New function. + * libgnomevfs/gnome-vfs-ops.h: Prototypes here. + + * libgnomevfs/gnome-vfs-private-ops.c + (gnome_vfs_set_file_info_cancellable): New function. + * libgnomevfs/gnome-vfs-private-ops.h: Prototype here. + + * libgnomevfs/gnome-vfs-private-types.h: New function typedef + `GnomeVFSMethodSetFileInfo'. New member `set_file_info' in + `GnomeVFSMethod'. + + * libgnomevfs/gnome-vfs-types.h: New enum + `GnomeVFSSetFileInfoMask'. + + * libgnomevfs/gnome-vfs-types.h: Renamed + `GNOME_VFS_FILE_INFO_NOOPTION' to `GNOME_VFS_FILE_INFO_DEFAULT'. + * libgnomevfs/gnome-vfs-xfer.c (create_xfer_file_list): Updated + accordingly. + + * libgnomevfs/gnome-vfs-uri.c (gnome_vfs_uri_extract_dirname): New + function. + +1999-11-12 Ettore Perazzoli + + * libgnomevfs/gnome-vfs-uri.c (gnome_vfs_uri_append_path): Make sure + `uri_string' is always freed. + + * libgnomevfs/gnome-vfs-configuration.c (parse_file): Free the + line buffer on exit. + +1999-11-08 Ettore Perazzoli + + * libgnomevfs/gnome-vfs-xfer.c (xfer_create_target): Set `retry' + to `FALSE' at the start of the `while' loop. + (xfer_open_source): Likewise. + (xfer_file): Likewise. + (copy_directory): Likewise. + (move_file): Likewise. + +1999-10-29 Elliot Lee + + * test/test-somethingorother.c: Make it use the file info flags + instead of ->is_symlink. + + * libgnomevfs/Makefile.am: Put our build tree on the include path + before installed stuff. + +1999-10-23 Ettore Perazzoli + + * libgnomevfs/gnome-vfs-directory-filter.c + (gnome_vfs_directory_filter_apply): If `filter' is NULL, just + return `TRUE'. + + * libgnomevfs/gnome-vfs-iobuf.c (gnome_vfs_iobuf_read): Only read + as much bytes as the stream gives us; not more. + + * modules/ftp-method.c (_ftpfs_read_directory): Set the "local" + flag in the info to `FALSE'. + (fill_file_info): Likewise. + + * modules/file-method.c (get_stat_info): Set the "local" flag to + `TRUE'. + (get_stat_info_from_handle): Likewise. + + * modules/extfs-method.c (read_directory_list): Set the "local" + flag in the info object to FALSE. + + * modules/module-shared.c (gnome_vfs_stat_to_file_info): Do not + set the "local" flag anymore. + + * modules/ftp-method.c (print_vfs_message): Made static. + (insert_dots): Use `gnome_vfs_parse_ls_lga()' instead of + `vfs_parse_ls_lga()', which does not exist anymore. + (retrieve_dir): Likewise. + + * libgnomevfs/gnome-vfs-directory.c (directory_visit_internal): + Updated to match the `GnomeVFSFileInfo' changes. + * modules/module-shared.c (gnome_vfs_stat_to_file_info): Likewise. + * modules/file-method.c (get_stat_info): Likewise. + * modules/http-method.c (get_file_info_from_http_handle): Likewise. + * modules/ftp-method.c (fill_file_info): Likewise. + (_ftpfs_read_directory): Likewise. + * test/gnome-file-selection/gnome-file-selection.c + (populate_callback): Likewise. + * test/test-directory.c (print_list): Likewise. + * test/test-directory-visit.c (directory_visit_callback): Likewise. + * test/test-info.c (print_file_info): Likewise. + + * libgnomevfs/gnome-vfs-file-info.h (GNOME_VFS_FILE_INFO_SYMLINK): + New macro. + (GNOME_VFS_FILE_INFO_LOCAL): New macro. + (GNOME_VFS_FILE_INFO_SUID): New macro. + (GNOME_VFS_FILE_INFO_SGID): New macro. + (GNOME_VFS_FILE_INFO_STICKY): New macro. + (GNOME_VFS_FILE_INFO_SET_SYMLINK): New macro. + (GNOME_VFS_FILE_INFO_SET_LOCAL): New macro. + (GNOME_VFS_FILE_INFO_SET_SUID): New macro. + (GNOME_VFS_FILE_INFO_SET_SGID): New macro. + (GNOME_VFS_FILE_INFO_SET_STICKY): New macro. + + * libgnomevfs/gnome-vfs-types.h: New enum + `GnomeVFSFileFlags'. + (struct _GnomeVFSFileInfo): Replaced the various gboolean 1-bit flags + with a single `GnomeVFSFileFlags' member called `flags'. + + * test/test-info.c (main): Follow links. + + * modules/file-method.c (read_link): Zero-terminate the returned + string. + + * modules/module-shared.c (gnome_vfs_stat_to_file_info): + Unconditionally set the type to `GNOME_VFS_FILE_TYPE_UNKNOWN' if + all else fails, even if `file_info' refers to a symlink. + + * modules/ftp-method.c: #include , "gnome-vfs.h" and + "gnome-vfs-private.h". + + * libgnomevfs/gnome-vfs-ops.c (gnome_vfs_get_file_info): If the + `get_file_info' function is not implemented, return + `GNOME_VFS_ERROR_NOTSUPPORTED'. + + * test/test-info.c: New program for testing the + `gnome_vfs_get_file_info()' API call. + + * libgnomevfs/gnome-vfs-iobuf.c (gnome_vfs_iobuf_read): Argh. + Don't put more than `bytes' bytes in `buffer'! + +1999-10-22 Ettore Perazzoli + + * libgnomevfs/gnome-vfs-iobuf.c (gnome_vfs_iobuf_read): Do not use + `bytes_read' if NULL. + (gnome_vfs_iobuf_write): Likewise with `bytes_written'. + (flush): Flush output, not input. :-P + (refill_input_buffer): Changed to return a `GnomeVFSResult'. + Return `GNOME_VFS_ERROR_EOF' at EOF. + (gnome_vfs_iobuf_read): Updated accordingly. + + * libgnomevfs/gnome-vfs-method.c (load_module): Don't check for + the `create' function anymore. + + * libgnomevfs/gnome-vfs-private.h: #include + "gnome-vfs-inet-connection.h". + + * libgnomevfs/gnome-vfs-inet-connection.c: New file implementing + Internet connections. + * libgnomevfs/gnome-vfs-inet-connection.h: Corresponding header file. + + * libgnomevfs/gnome-vfs-private-types.h: New opaque typedef + `GnomeVFSInetConnection'. + + * modules/Makefile.am: Compile the HTTP method again. + + * modules/http-method.c: New re-implementation from scratch, with + great help from the GNU Wget sources. + * modules/http-method.h: Corresponding header file. + + * libgnomevfs/gnome-vfs-utils.c: #include . + (gnome_vfs_atotm): New function, from GNU Wget. + * libgnomevfs/gnome-vfs-utils.h (gnome_vfs_atotm): Prototype here. + +1999-10-21 Ettore Perazzoli + + * libgnomevfs/gnome-vfs-iobuf.c (refill_input_buffer): New helper + function. + (gnome_vfs_iobuf_read): Changed to use it. + (gnome_vfs_iobuf_peekc): New function. + + * libgnomevfs/gnome-vfs-private-types.h: New opaque + `GnomeVFSIOBuf' typedef for the struct defined in + `gnome-vfs-iobuf.c'. + + * libgnomevfs/gnome-vfs-private.h: #include "gnome-vfs-iobuf.h". + + * libgnomevfs/gnome-vfs-iobuf.h: New header file for + `gnome-vfs-iobuf.c'. + + * libgnomevfs/gnome-vfs-iobuf.c: New file implementing buffered + I/O on top of low-level Unix file descriptors. + +1999-10-20 Ettore Perazzoli + + * modules/extfs-method.c (match): Apply filter. + (vfs_module_shutdown): Close all the handles. + (do_close): Remove the handle from the handle list. + + * README: Added some info about the `vfs-run' wrapper. + + * configure.in: Subst `@TOP_BUILDDIR@' with the path to the top + building directory. Build `$(top_builddir)/test/vfs-run' from + `$(top_srcdir)/test/vfs-run.in'. + + * test/vfs-run.in (GNOME_VFS_MODULE_PATH): New file. + + * libgnomevfs/gnome-vfs-method.c (gnome_vfs_method_get): Set the + effective UID/GID to the real UID/GID when loading the module, and + restore them afterwards. This should prevent exploits to + setuid/setgid applications by using `GNOME_VFS_MODULE_PATH'. + (module_get_sane_handle): Renamed to `load_module'. Added + debugging message displaying the complete name of the module that + is being loaded. + + * libgnomevfs/gnome-vfs-method.c: New variable `module_path_list'. + (init_hash_table): New helper function. + (gnome_vfs_method_init): Use it. + (init_path_list): New helper function to initialize + `module_path_list' through the `GNOME_VFS_MODULE_PATH' environment + variable. + (install_path_list): New helper function used by `init_path_list'. + (gnome_vfs_method_init): Use it. + (load_module_in_path_list): New function to search for a module in + the path list. + (gnome_vfs_method_get): Use it. + (module_get_sane_handle): Made const-safe. + +1999-10-19 Ettore Perazzoli + + * modules/extfs-method.c (read_directory_list): New parameter + `info_options'. If the `GNOME_VFS_FILE_INFO_GETMIMETYPE' bit is + set, set the MIME type in the file information struct according to + the file name. + (do_open_directory): Updated accordingly. + + * modules/ftp-method.c: Do not #include "parse.h" anymore. + + * libgnomevfs/gnome-vfs-cancellation.c [HAVE_CONFIG_H]: #include + . + + * modules/Makefile.am (CPPFLAGS): #define `_GNU_SOURCE'. + * libgnomevfs-pthread/Makefile.am (CPPFLAGS): Likewise. + * libgnomevfs-corba/Makefile.am (CPPFLAGS): Likewise. + * libgnomevfs/Makefile.am (CPPFLAGS): Likewise. + + * modules/extfs-method.c: Implemented directory reading. + + * modules/extfs-method.c (get_script_path): New helper function. + (do_open): Use it. + (ERROR_IF_NOT_LOCAL): New macro. + (do_open): Use it. + + * libgnomevfs/gnome-vfs-uri.c (gnome_vfs_uri_hequal): New function. + (gnome_vfs_uri_hash): New function. + * libgnomevfs/gnome-vfs-uri.h (gnome_vfs_uri_hash): Prototypes here. + + * modules/ftp-method.c (resolve_symlink_with_ls_options): Use + `gnome_vfs_parse_ls_lga()' instead of `vfs_parse_ls_lga()', which + does not exist anymore. + + * modules/parse.c: Removed. + * modules/parse.h: Removed. + + * libgnomevfs/gnome-vfs-parse-ls.c: Removed global variables + `columns', `column_ptr'. + (vfs_split_text): New parameters `columns', `column_ptr'. + (gnome_vfs_vfs_parse_ls_lga): Updated accordingly. + (is_num): Get a string as the single parameter. + (gnome_vfs_vfs_parse_ls_lga): Updated accordingly. + (vfs_parse_filedate): New parameter `columns'. + (gnome_vfs_vfs_parse_ls_lga): Updated accordingly. + + * configure.in: Check for `getdelim' and use our version if + not available. + + * libgnomevfs/Makefile.am: Added `getdelim' to `EXTRA_DIST'. + + * libgnomevfs/gnome-vfs-private.h [! HAVE_GETDELIM]: Declare + prototype for `getdelim()'. + + * libgnomevfs/getdelim.c: New file, implementing `getdelim()' for + non-GNU systems. + +1999-10-18 Ettore Perazzoli + + * libgnomevfs/gnome-vfs-parse-ls.c: New file, derived from former + `modules/parse.c'. Reindented; made all the helper functions + static; glibified a bit. + * libgnomevfs/gnome-vfs-parse-ls.h: Corresponding header file. + +1999-10-17 Ettore Perazzoli + + * modules/extfs-method.c (do_open): If the return value from the + script is nonzero, return `GNOME_VFS_ERROR_NOTFOUND'. Check that + the parent URI is accessed through the `file' method. Completed + parameters passed to the extfs script. + + * modules/modules.conf: Added entries for `extfs'. + + * modules/extfs/README: New file. + * modules/extfs/a: New file. + * modules/extfs/deb.in: New file. + * modules/extfs/hp48: New file. + * modules/extfs/mailfs: New file. + * modules/extfs/patchfs: New file. + * modules/extfs/rpm: New file. + * modules/extfs/rpms: New file. + * modules/extfs/trpm: New file. + * modules/extfs/ar.in: New file. + * modules/extfs/arj: New file. + * modules/extfs/cpio.in: New file. + * modules/extfs/lha.in: New file. + * modules/extfs/rar.in: New file. + * modules/extfs/zip.in: New file. + * modules/extfs/zoo.in: New file. + * configure.in: Generate scripts from the `.in' files. + + * configure.in: Check for `awk' using `AC_PROG_AWK'. + + * modules/extfs: New subdirectory. + * modules/extfs/Makefile.am: New file. + * modules/Makefile.am: Updated accordingly. + + * modules/extfs-method.c: Replaced member `fd' in `ExtfsHandle' + with `vfs_handle' (i.e. we use a VFS handle instead of a UNIX file + descriptor). #include . + (VFS_HANDLE): New helper macro. + (extfs_handle_close): Updated accordingly. Return value changed + from `void' to `GnomeVFSResult', so that we can return the result + of the `close' operation. Also, remove `local_path'. + (do_open): Updated accordingly. Also updated for the new version + of `gnome_vfs_create_temp()'. + (do_close): Implementated (`close' operation). + (do_read): Implemented (`read' operation). + (do_tell): Implemented (`tell') operation. + (do_write): Return `GNOME_VFS_ERROR_READONLYFS' instead of + `GNOME_VFS_ERROR_NOTSUPPORTED'. + + * libgnomevfs/gnome-vfs-utils.c (gnome_vfs_create_temp): Changed + so that it returns a GnomeVFSHandle instead of a plain Unix file + descriptor. Abort if creating the file fails with something + different from a "file exists" error. + +1999-10-15 Ettore Perazzoli + + * modules/Makefile.am (CPPFLAGS): #define `PREFIX'. + + * libgnomevfs/gnome-vfs-process.c (gnome_vfs_process_new): Use + `gnome_fs_forkexec()'. + + * libgnomevfs/gnome-vfs-process.c (get_max_fds): Removed. + (shut_down_file_descriptors): Removed. + * libgnomevfs/gnome-vfs-utils.c: Moved here. + + * libgnomevfs/gnome-vfs-utils.c + (gnome_vfs_process_run_cancellable): New function. + (gnome_vfs_forkexec): New function, cut & paste from + `gnome_vfs_process_new()'. + (gnome_vfs_create_temp): New function. + * libgnomevfs/gnome-vfs-utils.h: Prototypes here. + + * libgnomevfs/gnome-vfs-process.c: #include "gnome-vfs.h" and + "gnome-vfs-private.h", instead of just "gnome-vfs-process.h". + + * libgnomevfs/gnome-vfs-process.h + (gnome_vfs_process_run_cancellable): Prototype. + + * libgnomevfs/gnome-vfs-process.h: New enum + `GnomeVFSProcessRunResult'. + +1999-10-14 Ettore Perazzoli + + * modules/extfs-method.c: New file, implementing MC-style extfs. + * modules/extfs-method.h: Corresponding header. + * modules/Makefile.am: Compile it in `libextfs.so'. + + * libgnomevfs/gnome-vfs-xfer.c (gnome_vfs_xfer_uri): Report + progress for the operation of deleting the source directories. + Free progress info at each iteration. + + * libgnomevfs/gnome-vfs-types.h: New GnomeVFSXferPhase value + `GNOME_VFS_XFER_PHASE_DELETESOURCE'. + + * libgnomevfs/gnome-vfs-xfer.c (gnome_vfs_xfer_uri): Report + `GNOME_VFS_XFER_PHASE_FILECOMPLETED' for the last file too. + (remove_directory): New helper function. + (gnome_vfs_xfer_uri): Use it. + + * libgnomevfs/gnome-vfs-xfer.c (fast_move): New function, + implementing fast moving through `gnome_vfs_move()'. + (gnome_vfs_xfer_uri): Use it if we are transferring files between + two directories on the same file system and we are requested to + remove the sources. + +1999-10-13 Ettore Perazzoli + + * libgnomevfs/gnome-vfs-xfer.c (init_progress): New helper + function. + (gnome_vfs_xfer_uri): Use it. Leak fix: free progress info if the + progress callback returns `FALSE' in the `READYTOGO' or `XFERRING' + phases. + + * modules/Makefile.am: Add `modules.conf' to `EXTRA_DIST'. + + * libgnomevfs/gnome-vfs-cancellation.c + (gnome_vfs_cancellation_check): Do not complain if `cancellation' + is NULL. + + * libgnomevfs/gnome-vfs-ops.c (gnome_vfs_move_uri): New function. + (gnome_vfs_move): New function. + (gnome_vfs_check_same_fs_uris): New function. + (gnome_vfs_check_same_fs): New function. + * libgnomevfs/gnome-vfs-ops.h (gnome_vfs_move): Prototypes here. + + * libgnomevfs/gnome-vfs-private-ops.c + (gnome_vfs_move_uri_cancellable): New function. + (gnome_vfs_check_same_fs_uris_cancellable): New function. + * libgnomevfs/gnome-vfs-private-ops.h + (gnome_vfs_move_uri_cancellable): Prototypes here. + + * modules/file-method.c (do_check_same_fs): New function, + installed as the `check_same_fs' op implementation. + + * libgnomevfs/gnome-vfs-private-types.h: New type + `GnomeVFSCheckSameFSFunc'. New member `check_same_fs' in + `GnomeVFSMethod'. + + * modules/file-method.c (do_move): New function, implementing the + `move' operation. + + * libgnomevfs/gnome-vfs-private-types.h: `GnomeVFSMethodRenameFunc' + removed; replaced by `GnomeVFSMethodMoveFunc' with different + parameters. `rename' member in `struct _GnomeVFSMethod' removed; + replaced by `move'. + + * libgnomevfs/gnome-vfs-uri.c (gnome_vfs_uri_get_basename): New + function. + * libgnomevfs/gnome-vfs-uri.h: Prototype here. + + * test/test-xfer.c: New file, implementing a test for the xfer + functionality. + * test/Makefile.am: Compile it as `test-xfer'. + + * test/test-copy.c: Removed. + + * libgnomevfs/gnome-vfs-xfer.c (gnome_vfs_xfer_uri): Honour + `GNOME_VFS_XFER_REMOVESOURCE'. This needs to be optimized for the + "files are in the same file system" case of course. + + * libgnomevfs/gnome-vfs-ops.c (gnome_vfs_open): Doc'ed. + (gnome_vfs_open_uri): Doc'ed. + (gnome_vfs_create): Doc'ed. + (gnome_vfs_create_uri): Doc'ed. + (gnome_vfs_close): Doc'ed. + (gnome_vfs_read): Doc'ed. + (gnome_vfs_write): Doc'ed. + (gnome_vfs_seek): Doc'ed. + (gnome_vfs_tell): Doc'ed. + (gnome_vfs_get_file_info): Doc'ed. + (gnome_vfs_get_file_info_uri): Doc'ed. + (gnome_vfs_get_file_info_from_handle): Doc'ed. + (gnome_vfs_make_directory_for_uri): Doc'ed. + (gnome_vfs_make_directory): Doc'ed. + (gnome_vfs_remove_directory_from_uri): Doc'ed. + (gnome_vfs_remove_directory): Doc'ed. + (gnome_vfs_unlink_from_uri): Doc'ed. + (gnome_vfs_unlink): Doc'ed. + + * test/test-directory.c (main): Local variable `args' made const. + + * test/test-directory.c (filter_list): `#if 0'ed out just to make + the compiler happy. + + * libgnomevfs/gnome-vfs-result.c (gnome_vfs_result_from_errno): + Re-indented to make sorting easier. Convert `EBUSY', `ENOTEMPTY', + `EROFS', `EMLINK', `EXDEV', `EFAULT', `ELOOP', as well, using the + new GnomeVFSResult values. + + * libgnomevfs/gnome-vfs-types.h: New errors + `GNOME_VFS_ERROR_DIRECTORYBUSY', `GNOME_VFS_ERROR_DIRECTORYNOTEMPTY', + `GNOME_VFS_ERROR_TOOMANYLINKS', `GNOME_VFS_ERROR_READONLYFS', + `GNOME_VFS_ERROR_NOTSAMEFS', `GNOME_VFS_ERROR_NAMETOOLONG'. + * libgnomevfs/gnome-vfs-result.c: Added corresponding string + descriptions. + +1999-10-12 Ettore Perazzoli + + * modules/file-method.c (do_open): When getting `EINTR', do not + restart the operation if a cancellation is pending. + (do_create): Likewise. + (do_close): Likewise. + (do_read): Likewise. + + * libgnomevfs-pthread/gnome-vfs-job.c (dispatch_job_callback): + Slightly made cleaner. + + * TODO: Updated. + + * libgnomevfs-pthread/gnome-vfs-job.c (execute_open): Use + cancellable version of the primitive. + (execute_open_as_channel): Likewise. + (execute_create): Likewise. + (execute_create_as_channel): Likewise. + (execute_close): Likewise + (execute_read): Likewise. + + * libgnomevfs/gnome-vfs-configuration.c [HAVE_CONFIG_H]: #include + . + + * libgnomevfs/gnome-vfs-private.h: #include "gnome-vfs-private-ops.h". + + * libgnomevfs/gnome-vfs-ops.c (gnome_vfs_open_uri): Made a simple + wrapper for the cancellable version in `gnome-vfs-private-ops.c'. + (gnome_vfs_create_uri): Likewise. + (gnome_vfs_close): Likewise. + (gnome_vfs_read): Likewise. + (gnome_vfs_write): Likewise. + (gnome_vfs_seek): Likewise. + (gnome_vfs_get_file_info_uri): Likewise. + (gnome_vfs_get_file_info_from_handle): Likewise. + (gnome_vfs_make_directory_for_uri): Likewise. + (gnome_vfs_remove_directory_from_uri): Likewise. + (gnome_vfs_unlink_from_uri): Likewise. + + * libgnomevfs/gnome-vfs-private-ops.h: New file. + + * libgnomevfs/gnome-vfs-private-ops.c: New file. + + * libgnomevfs/gnome-vfs-result.c: New error description for + `GNOME_VFS_ERROR_CANCELLED'. + + * libgnomevfs/gnome-vfs-types.h: New error `GNOME_VFS_ERROR_CANCELLED'. + + * libgnomevfs-pthread/gnome-vfs-job.c (gnome_vfs_job_cancel): Use + the new `cancellation' member instead of `cancelled'. + (dispatch_job_callback): Likewise. + (gnome_vfs_job_new): Initialize `cancellation'. + (gnome_vfs_job_destroy): Destroy it. + (execute_open): Do not check `cancelled' anymore. + (execute_create): Likewise. + (execute_load_directory_not_sorted): Likewise. + (execute_load_directory_sorted): Likewise. + (xfer_callback): Likewise. + + * libgnomevfs-pthread/gnome-vfs-job.h (struct _GnomeVFSJob): + Removed member `cancelled'. Replaced by new member + `cancellation', of type `GnomeVFSCancellation'. + + * modules/bzip2-method.c: Updated all the method implementation + functions to accept the `cancellation' parameter. It is not + honoured yet though. + * modules/file-method.c: Likewise. + * modules/gzip-method.c: Likewise. + * modules/http-method.c: Likewise. + + * libgnomevfs/gnome-vfs-seekable.c: Updated to accept the + `cancellation' parameter. It does not honour it yet though. + (read_file): Pass `NULL' as the `cancellation' parameter for + `read'. + (write_file): Likewise for `write'. + (do_close): Likewise for `close'. + + * libgnomevfs/gnome-vfs-ops.c (gnome_vfs_open_uri): Pass `NULL' as + the `cancellation' parameter to the `open' implementation. + (gnome_vfs_open_uri): Likewise. + (gnome_vfs_create_uri): Pass `NULL' as the `cancellation' + parameter to the `create' implementation. + (gnome_vfs_close): Pass `NULL' as the `cancellation' parameter to + `gnome_vfs_handle_do_close()'. + (gnome_vfs_read): Likewise with `gnome_vfs_handle_do_read()'. + (gnome_vfs_write): Likewise with `gnome_vfs_handle_do_write()'. + (gnome_vfs_seek): Likewise with `gnome_vfs_handle_do_seek()'. + (gnome_vfs_get_file_info): Likewise with the `get_file_info' + implementation. + (gnome_vfs_get_file_info_uri): Likewise. + (gnome_vfs_get_file_info_from_handle): Likewise with + `gnome_vfs_handle_do_get_file_info()'. + (gnome_vfs_make_directory_for_uri): Likewise with the + `make_directory' implementation. + (gnome_vfs_make_directory): Likewise. + (gnome_vfs_remove_directory_from_uri): Likewise with the + `remove_directory'implementation. + (gnome_vfs_unlink_from_uri): Likewise for `unlink'. + + * libgnomevfs/gnome-vfs-handle.c (gnome_vfs_handle_do_close): New + parameter `cancellation'. + (gnome_vfs_handle_do_read): Likewise. + (gnome_vfs_handle_do_write): Likewise. + (gnome_vfs_handle_do_seek): Likewise. + (gnome_vfs_handle_do_get_file_info): Likewise. + * libgnomevfs/gnome-vfs-handle.h: Updated prototypes accordingly. + + * libgnomevfs/gnome-vfs-directory.c (open): New parameter + `cancellation'. + (open_from_uri): Likewise. Pass it to the `open_directory' + implementation. + (gnome_vfs_directory_open): Updated accordingly. + (gnome_vfs_directory_open_from_uri): Update accordingly. + (gnome_vfs_directory_read_next): Pass `NULL' as the `cancellation' + parameter in the call to the `read_directory' implementation. + (gnome_vfs_directory_close): Pass `NULL' as the `cancellation' + parameter in the call to the `close_directory' implementation. + + * libgnomevfs/gnome-vfs-private-types.h: New opaque typedef + `GnomeVFSCancellation'. Added new `cancellation' parameter to all + the method implementation typedefs. + + * libgnomevfs/gnome-vfs-private.h: #include + "gnome-vfs-cancellation.h". + + * libgnomevfs/gnome-vfs-cancellation.c: New file, implementing + cancellation for the VFS method implementations. + + * libgnomevfs/gnome-vfs-cancellation.h: New file. + + * modules/modules.conf: Added `ugzip' for compatibility with the + Midnight Commander's VFS. + + * libgnomevfs/gnome-vfs-configuration.c (parse_line): Set + `method_start' again after saving a method name. + +1999-10-11 Ettore Perazzoli + + * test/test-sync.c (main): Abort reporting an error if + `gnome_vfs_uri_new()' returns NULL. + + * modules/modules.conf: New file: configuration for the current VFS + modules. + * modules/Makefile.am: Install it in the `modulesdir'. + + * libgnomevfs/gnome-vfs-method.c (gnome_vfs_method_get): Use + `gnome_vfs_configuration_get_module_path()' to retrieve the module + name. This also fixes a memory leak introduced by Michael's + commit of 1999-08-31. + + * libgnomevfs/gnome-vfs-init.c (gnome_vfs_init): Initialize the + configuration system by calling `gnome_vfs_configuration_init()'. + + * libgnomevfs/gnome-vfs-constants.h: New constant + `GNOME_VFS_MODULE_CFGFILE', `GNOME_VFS_MODULE_DIR'. + + * libgnomevfs/gnome-vfs-private.h: #include + "gnome-vfs-configuration.h". + + * libgnomevfs/gnome-vfs-configuration.c: New file. + + * libgnomevfs/gnome-vfs-configuration.h: New file. + +1999-10-10 Ettore Perazzoli + + * libgnomevfs/gnome-vfs-file-info.c: Doc'ed. + + * libgnomevfs/gnome-vfs-directory.c: Doc'ed. + + * libgnomevfs/gnome-vfs-directory-list.c: Doc'ed. + + * libgnomevfs/gnome-vfs-directory-filter.c: Doc'ed. + + * doc/writing-modules.sgml: New file. + +1999-10-08 Ettore Perazzoli + + * modules/Makefile.am (CPPFLAGS): #define + `_POSIX_PTHREAD_SEMANTICS'. + * libgnomevfs/Makefile.am (CPPFLAGS): Likewise. + + * libgnomevfs-corba/gnome-vfs-slave-notify.c: #define `SUN_LEN()' + if not already #defined. + + * libgnomevfs-corba/gnome-vfs-slave.c (setup_and_serve_channel): + Change `socklen_t' into `int'. + (setup_and_serve_channel): Use `[AP]F_UNIX' instead of + `[AP]F_LOCAL' if the latter are not available. + + * libgnomevfs-corba/gnome-vfs-slave-process.c: #include + first, afterwards as pointed out by + Michael. + * libgnomevfs-corba/gnome-vfs-slave-notify.c: Likewise. + +1999-10-07 Ettore Perazzoli + + * libgnomevfs/gnome-vfs-process.c: If the + `GNOME_VFS_PROCESS_SETSID' option is set, call `setsid()' + after forking and calling the user-specified function. + + * libgnomevfs/gnome-vfs-private.h: Do not #include + "gnome-vfs-process.h". + + * libgnomevfs/gnome-vfs.h: #include "gnome-vfs-process.h". This + makes the GnomeVFSProcess stuff public, thus making my work on the + file manager slightly easier. It should not be public in the + final version though; instead, I would like to have something like + this in glib or gnome-libs. + + * libgnomevfs/Makefile.am: Install `gnome-vfs-process.h'. + + * libgnomevfs/gnome-vfs-process.h (gnome_vfs_process_new): Update + prototype. + + * libgnomevfs/gnome-vfs-process.c (gnome_vfs_process_new): New + parameter `options' instead of `use_search_path' and + `close_file_descriptors'. + * libgnomevfs-corba/gnome-vfs-slave-launch.c + (gnome_vfs_slave_launch): Updated accordingly. + + * libgnomevfs/gnome-vfs-process.h: New enum + `GnomeVFSProcessOptions'. + + * libgnomevfs/gnome-vfs-types.h: New value + `GNOME_VFS_URI_HIDE_TOPLEVEL_METHOD' in `GnomeVFSURIHideOptions'. + * libgnomevfs/gnome-vfs-uri.c (gnome_vfs_uri_to_string): Honour + it. + +1999-10-07 Miguel de Icaza + + * modules/ftp-method.c (linear_read): Close first to comply to + RFC959. + +1999-10-04 Ettore Perazzoli + + * modules/module-shared.c (gnome_vfs_set_meta_for_list): Use + `gnome_vfs_set_meta()' instead of `set_meta()'. + + * libgnomevfs/gnome-vfs-seekable.c (init_seek): Removed local + variable `txt_uri'. + + * libgnomevfs-corba/gnome-vfs-slave.c (load_directory_sorted): + Updated to use `gnome_vfs_directory_list_load()' instead of + `gnome_vfs_directory_load()'. + * libgnomevfs-pthread/gnome-vfs-job.c + (execute_load_directory_sorted): Likewise. + * test/test-directory.c (main): Likewise. + + * libgnomevfs/gnome-vfs-directory-list.c + (gnome_vfs_directory_list_load): New version of + `gnome_vfs_directory_load', for consistency. + (gnome_vfs_directory_list_load_from_uri): Likewise for + `gnome_vfs_directory_load_from_uri'. + + * libgnomevfs/gnome-vfs-directory.c (gnome_vfs_directory_load): + Removed. + (gnome_vfs_directory_load_from_uri): Removed. + (gnome_vfs_uri_append_path): If the original URI is empty, return + the URI from the new path. + +1999-09-30 Ettore Perazzoli + + * libgnomevfs/gnome-vfs-uri.c (my_streq): New function. + (compare_elements): Use it instead of `strcmp' so that it works + even with NULL fields. + (gnome_vfs_uri_equal): Likewise. + +1999-09-29 Rodrigo Stulzer Lopes + + * configure.in: add pt_BR to ALL_LINGUAS + +1999-09-29 Ettore Perazzoli + + * modules/ftp-method.c (MUTEX_LOCK): New macro to lock a mutex. + Defined to empty if `G_THREADS_ENABLED' is not defined. + (MUTEX_UNLOCK): New macro to unlock a mutex. Defined to empty if + `G_THREADS_ENABLED' is not defined. + (ftpfs_connection_new) [G_THREADS_ENABLED]: Initialize + `access_mutex'. + (ftpfs_connection_unref): Perform locking. Free the lock if + refcounting is zero. + + * modules/ftp-method.h [G_THREADS_ENABLED]: New member + `access_lock' in `ftpfs_connection_t'. + + * modules/ftp-method.c: Define a static lock for + `connections_hash'. + (ftpfs_connection_destroy): Removed. + (ftpfs_connection_unref): Perform locking on `connections_hash'. + (lookup_conn): Likewise. + (ftpfs_connection_new): Likewise. + + * modules/ftp-method.c (ftpfs_open_directory): Use the raw URI + path, without using `g_dirname()'. + +1999-09-28 Ettore Perazzoli + + * modules/bzip2-method.c: Re-indented in GNOME style. + + * configure.in: Added `--enable-gconf' option to explicitly enable + the GConf module backend; if not specified, GConf support is not + compiled even if GConf is available. For now, the GConf API is + too much of a moving target to rely on it by default. + + * modules/ftp-method.c (ftpfs_get_file_info): `#if 0'ed completely + to get it to compile. Always return `GNOME_VFS_ERROR_NOTSUPPORTED'. + +1999-09-27 Miguel de Icaza + + * modules/module-shared.c (gnome_vfs_set_meta_for_list, + gnome_vfs_set_meta, gnome_vfs_stat_to_file_info, + gnome_vfs_mime_type_from_mode): moved here some code from the file + backend that can be reused by the ftp backend. + + * modules/ftp-method.c: directory listings work. Still some work + is required. + +1999-09-27 Cody Russell + + * modules/bzip2-method.c: At Ettore's request, reformatted the + code to look more like the rest of the code. Function return + values are now on the preceeding line of the function name. + +1999-09-27 Ettore Perazzoli + + * libgnomevfs-pthread/gnome-vfs-job.c (dispatch_open_callback): + Unref before calling the callback, not after that. + (dispatch_create_callback): Likewise. + (dispatch_open_as_channel_callback): Likewise. + + * modules/bzip2-method.c (do_open): Removed unused variables. + + * libgnomevfs/gnome-vfs-uri.c (gnome_vfs_uri_equal): New function. + + * libgnomevfs/gnome-vfs-ops.c (gnome_vfs_open_from_uri): Renamed + to `gnome_vfs_open_uri'. + (gnome_vfs_create_for_uri): Renamed to `gnome_vfs_create_uri'. + (gnome_vfs_get_file_info_from_uri): Renamed to + `gnome_vfs_get_file_info_uri'. + + * libgnomevfs-pthread/gnome-vfs-job.c (execute_open_as_channel): + Close and unref channels. + (execute_create_as_channel): Likewise. + (gnome_vfs_job_destroy): Use `g_io_channel_close()' instead of + `close()'. + (execute_open_as_channel): Wait for ack from the notification. + (execute_create_as_channel): Likewise. + + * libgnomevfs/gnome-vfs-init.c (gnome_vfs_init): Ignore SIGPIPE. + +1999-09-26 Dave Camp + + * modules/gconf-method.c (do_get_file_info_from_handle): New method. + (vfs_module_init): Don't pass the "application" parameter to + g_conf_init(). + +11999-09-25 Cody Russell + + * modules/bzip2-method.c: Removed MAKE_ABSOLUTE(). + +1999-09-25 Ettore Perazzoli + + * libgnomevfs/gnome-vfs-constants.h (GNOME_VFS_OFFSET_FORMAT_STR) + [!HAVE_GINT64]: Change "L" to "l". + + * modules/bzip2-method.c (struct _Bzip2MethodHandle): Removed + `modification_time' member. + (bzip2_method_handle_new): Removed `modification_time' parameter. + (do_open): Do not pass it as an uninitialized value nor zero + anymore. Open the file using the parent URI correctly. + (bzip2_read_open): Removed bogus static prototype. + (do_open): Write mode `#if 0'ed out as it wouldn't work anyway. + + * modules/Makefile.am: Enable compilation of the bzip2 module. + +1999-09-25 Kjartan Maraas + + * configure.in: Added da to ALL_LINGUAS. + +1999-09-18 Cody Russell + + * modules/bzip2-method.[ch]: Added. Note that this method is not + currently finished, and so I've disabled building of it for now. + + * modules/Makefile.am: Added Bzip2, but it's currently commented + out. + + * configure.in: Fixed a typo. "gconf will not be build" + s/build/built. + +1999-09-18 Ettore Perazzoli + + * libgnomevfs-pthread/gnome-vfs-job.c (gnome_vfs_job_new): + Initialize the `cancelled' member to `FALSE'. + (gnome_vfs_job_cancel): Set `cancelled' to `TRUE'. + (dispatch_job_callback): If the job was cancelled, do not dispatch + the callback. + (execute_open): If the job was cancelled, return FALSE so that the + thread dies. + (execute_create): Likewise. + (execute_load_directory_not_sorted): Interrupt if job is + cancelled. Also, close the directory handle on exit. + (execute_load_directory_sorted): Likewise. + (xfer_callback): If the job is cancelled, return FALSE. + + * libgnomevfs-pthread/gnome-vfs-job.h (struct _GnomeVFSJob): New + member `cancelled'. + +1999-09-18 Michael Meeks + + * libgnomevfs/gnome-vfs-uri.c (gnome_vfs_uri_has_parent): remove + unused 'p' + + * modules/ftp-method.c, gzip-method.c, gconf-method.c: + pad method structure. + + * modules/http-method.c: Add comment explaining the coding stall. + + * modules/file-method.c (do_unlink): implement. + + * libgnomevfs/gnome-vfs-seekable.c (do_close, init_seek): do unlink of + tmp file. + + * libgnomevfs/gnome-vfs-ops.c (gnome_vfs_unlink), + (gnome_vfs_unlink_for_uri): Added. + + * libgnomevfs/gnome-vfs-ops.h: add unlinks. + + * libgnomevfs/gnome-vfs-private-types.h: Add unlink, update truncate. + +1999-09-17 Ettore Perazzoli + + * libgnomevfs/gnome-vfs-constants.h: #include "gnome-vfs-types.h" + and . #define `GNOME_VFS_SIZE_FORMAT_STR' and + `GNOME_VFS_OFFSET_FORMAT_STR' according to the size of + `GnomeVFSFileSize' and `GnomeVFSFileOffset' + (i.e. according to whether gint64 exists or not). + + * libgnomevfs/gnome-vfs-types.h: #include . + +1999-09-16 Ettore Perazzoli + + * libgnomevfs-pthread/gnome-vfs-job.c + (execute_load_directory_sorted): If the directory is empty, notify + one single EOF. + + * libgnomevfs/gnome-vfs-uri.c (gnome_vfs_uri_has_parent): New function. + (gnome_vfs_uri_get_parent): New function. + (set_uri_element): Make sure there is a slash at the beginning of + the string. + + * libgnomevfs/gnome-vfs-uri.c (gnome_vfs_uri_to_string): Do not + try to copy `toplevel_info' if it is NULL. + (gnome_vfs_uri_dup): If `uri' is NULL, do not spit out a warning. + + * libgnomevfs-pthread/gnome-vfs-job.c + (dispatch_load_directory_callback): Do not unref the URI here + unless we are reporting an error! + (execute_open): Return FALSE if the operation failed, so that the + thread is killed. + (execute_create): Likewise. + (execute_open_as_channel): Return FALSE on any error, and after closing + the file. + (execute_create_as_channel): Likewise. + + * libgnomevfs/gnome-vfs-directory.c (directory_visit_internal): Use new + `gnome_vfs_uri_append_path()' instead of old + `gnome_vfs_uri_append_text()'. + (gnome_vfs_directory_visit_files_at_uri): Likewise. + (CHECK_IF_SUPPORTED): Removed bogus `vfs' parameter. All + occurrences updated. + + * libgnomevfs/gnome-vfs-xfer.c (create_xfer_file_list): Use new + `gnome_vfs_uri_append_path()' instead of old + `gnome_vfs_uri_append_text()'. + (gnome_vfs_xfer_uri): Likewise. + + * libgnomevfs/gnome-vfs-uri.c (gnome_vfs_uri_dup): Handle the + toplevel URI element correctly. + (gnome_vfs_uri_append_text): Removed. + (gnome_vfs_uri_append_path): New function. + +1999-09-15 Ettore Perazzoli + + * test/Makefile.am (EXTRA_DIST): Add all the `.c' files. + + * libgnomevfs-corba/Makefile.am (gnome_vfs_slave_SOURCES): List + built sources on top. + (libgnomevfs_corba_la_SOURCES): Likewise. + + * libgnomevfs/Makefile.am (noinst_HEADERS): Add + `gnome-vfs-module.h'. + +1999-09-14 Ettore Perazzoli + + * libgnomevfs-pthread/gnome-vfs-job.c (dispatch_open_callback): + Unref the URI. + (dispatch_create_callback): Likewise. + (dispatch_open_as_channel_callback): Likewise. + (dispatch_create_as_channel_callback): Likewise. + (dispatch_load_directory_callback): Likewise. + + * libgnomevfs-pthread/gnome-vfs-async-ops.c + (gnome_vfs_async_open_uri): New function. + (gnome_vfs_async_open_uri_as_channel): New function. + (gnome_vfs_async_create_uri): New function. + (gnome_vfs_async_load_directory_uri): New function. + (gnome_vfs_async_open): Updated to work with the GnomeVFSJob + changes using the GnomeVFSURI-based counterpart. + (gnome_vfs_async_open_as_channel): Likewise. + (gnome_vfs_async_create): Likewise. + (gnome_vfs_async_create_as_channel): Likewise. + (gnome_vfs_async_load_directory): Likewise. + + * libgnomevfs-pthread/gnome-vfs-job.c (execute_open): Updated to + work with the GnomeVFSJob changes. + (execute_open_as_channel): Likewise. + (execute_create): Likewise. + (execute_create_as_channel): Likewise. + (execute_load_directory_not_sorted): Likewise. + (execute_load_directory_sorted): Likewise. + + * libgnomevfs-pthread/gnome-vfs-job.h: Use a `GnomeVFSURI' instead + of a string for all the jobs, except for the xfer one. + + * libgnomevfs/gnome-vfs-async-ops.h (gnome_vfs_async_open_uri): + New function prototype. + (gnome_vfs_async_open_uri_as_channel): New function prototype. + (gnome_vfs_async_create_uri): New function prototype. + (gnome_vfs_async_create_uri_as_channel): New function prototype. + (gnome_vfs_async_load_directory_uri): New function prototype. + + * libgnomevfs/gnome-vfs-directory-list.c + (gnome_vfs_directory_list_sort): Re-assign `entries' to sort the + list, and set the current position to "none". + (gnome_vfs_directory_list_set_position): Allow setting a NULL + position. + + * libgnomevfs/gnome-vfs-directory-filter.c + (gnome_vfs_directory_filter_new): Do not return NULL if type is + "none", but some option is specified. + + * libgnomevfs/gnome-vfs-types.h: New GnomeVFSDirectoryFilterOption + `GNOME_VFS_DIRECTORY_FILTER_NOSELFDIR' to skip `.' and + `GNOME_VFS_DIRECTORY_FILTER_NOPARENTDIR' to skip `..'. + * libgnomevfs/gnome-vfs-directory-filter.c (common_filter): Honour + them. + + * test/test-directory.c (sort_list): Measure sorting speed if + `--measure-speed' is specified. + (main): Sort the list even if `--measure-speed' is specified. + Removed bogus filtering (it did not fit with the popt argument + parsing). + + * test/test-async-directory.c: New option `--sort' (`-s'). + (main): Do not sort the directory unless it is specified. + + * test/test-async-directory.c: Changed alias for `--measure-speed' + from `-s' to `-m'. + * test/test-directory.c: Likewise. + + * idl/gnome-vfs-slave.idl + (GNOME::VFS:Slave::Notify::load_directory): The problem with + `oneway' notifications was an ORBit bug, and has now been + fixed: make this method `oneway' again. + + * libgnomevfs/gnome-vfs-directory-list.c + (gnome_vfs_directory_list_get): New function. + * libgnomevfs/gnome-vfs-directory-list.h: Prototype here. + +1999-09-13 Ettore Perazzoli + + * idl/gnome-vfs-slave.idl: Made all the Notify methods non-oneway. + [No matter what Sopwith says, ORBit does seem to discard oneway + calls. Too bad, this could give us up to 20% more speed in + `load_directory'.] + +1999-09-12 Ettore Perazzoli + + * libgnomevfs-corba/gnome-vfs-async-ops.c + (gnome_vfs_async_cancel): New function. Just a stub for now. + + * libgnomevfs-pthread/gnome-vfs-job.c (gnome_vfs_job_cancel): New + function. Just a stub for now. + + * libgnomevfs-pthread/gnome-vfs-job.h (gnome_vfs_job_cancel): + New prototype. + + * libgnomevfs-pthread/gnome-vfs-async-ops.c + (gnome_vfs_async_cancel): New function. + + * libgnomevfs/gnome-vfs-async-ops.h (gnome_vfs_async_cancel): New + prototype. + + * libgnomevfs-pthread/gnome-vfs-job.c (execute_close): Notify with + ack and return `FALSE' so that the thread is killed. + (execute_load_directory_not_sorted): Always return FALSE. + (execute_load_directory_sorted): Likewise. + (gnome_vfs_job_new): Start the slave only when the `GnomeVFSJob' + structure has all the members filled. + + * libgnomevfs-corba/gnome-vfs-slave.c: Do not #define + `SLAVE_DEBUG'. + (DPRINTF): Flush stdout. + + * test/test-directory.c: Added speed measurement options. + (main): Honour them. + + * libgnomevfs/gnome-vfs-directory-list.h + (gnome_vfs_directory_list_get_num_entries): New Prototype. + + * libgnomevfs/gnome-vfs-directory-list.c + (struct _GnomeVFSDirectoryList): New member `num_entries'. + (remove_entry): Decrement it. + (gnome_vfs_directory_list_new): Initialize it. + (gnome_vfs_directory_list_prepend): Increment it. + (gnome_vfs_directory_list_append): Increment it. + (gnome_vfs_directory_list_get_num_entries): New function, returning + `num_entries'. + + * libgnomevfs/gnome-vfs-utils.c: #include . + +1999-09-11 Ettore Perazzoli + + * test/test-async-directory.c (print_list): Flush stdout after + each line. + + * libgnomevfs-pthread/gnome-vfs-job.c + (execute_load_directory_sorted): Set result to + `GNOME_VFS_ERROR_EOF' for the last notification. + + * test/test-async-directory.c: Added command-line options to + control the number of items per notification and measure speed. + (main): Set them up and honour them. + (directory_load_callback): Do not print anything if measuring speed. + + * test/test-async-directory.c (main): Initialize the libraries + correctly according to the version we are compiling (CORBA or + pthread). + (print_list): New parameter `num_entries'. Only print out the + first `num_entries' elements. + (directory_load_callback): Pass the number of entries. + + * test/Makefile.am: Compile `test-async-directory' in two + versions: a CORBA and a pthread one. + + * libgnomevfs-pthread/gnome-vfs-job.c (JOB_DEBUG): Debugging + macro, normally disabled. + (job_notify): Set `want_notify_ack' before calling `wakeup'. + (job_ack_notify): Debugging messages. + (wakeup): Likewise. + (job_oneway_notify): Likewise. + (job_notify): Likewise. + (job_close): Likewise. + + * test/gnome-file-selection/Makefile.am: Compile the pthread + version of `gnome-file-selection-test' as well. + + * test/gnome-file-selection/gnome-file-selection.c (struct + _GnomeFileSelectionPrivate): Removed `GnomeVFSAsyncContext' + member, replaced by a `GnomeVFSAsyncHandle' member. + (destroy): Don't free the context as it does not exist anymore. + (init): Do not initialize the context. Instead, set the handle to + NULL. + (start_populating): Load the directory with the new API. + (populate_callback): Updated for the new API (get a + GnomeVFSAsyncHandle, not a GnomeVFSAsyncContext). + + * test/Makefile.am (SUBDIRS): Compile `gnome-file-selection' + again. + + * modules/ftp-method.c: Do not #include "util-url.h" anymore. + + * modules/util-url.c: Removed. + * modules/util-url.h: Removed. + + * modules/ftp-method.c (ftpfs_chdir_internal): Ooops. Use `TRUE' + instead of `WAIT_REPLY'. + (ftpfs_get_current_directory): Use `FALSE' instead of `NONE'. + +1999-09-10 Ettore Perazzoli + + * modules/ftp-method.c: Removed `reply_str' global. Removed + `NONE', `WAIT_REPLY', `WANT_STRING' #defines. + (command): New parameters `reply_string' and `reply_string_len': + copy the response in there instead of using the silly global. + (login_server): Pass `TRUE' instead of `WAIT_REPLY' to `command()' + for the `wait_reply' parameter. Pass NULL, 0 as `reply_string', + `reply_string_len'. + (ftpfs_chdir_internal): Likewise. + (open_data_connection): Likewise. + (changetype): Likewise. + (initconn): Likewise. + (abort_transfer): Pass `FALSE' instead of `NONE' to `command()' + for the `wait_reply' parameter. Pass NULL, 0 as `reply_string', + `reply_string_len'. + (ftpfs_get_current_directory): Likewise. + (setup_passive): Allocate the reply in a local buffer, update the + call to `command()'. + + * modules/ftp-method.c: Removed variable `force_expiration', it + does not seem to be have meaningful use. #define `logfile' to + `stdout' so that we get some useful debugging messages. Removed + `code' global (this was *evil*). Removed `got_sigpipe' global. + (retrieve_dir): Do not reference it anymore. + (get_reply): Return the code without dividing it by 100. + (command): Return 421 for a transient error. Return `COMPLETE * + 100' instead of `COMPLETE'. + (login_server): Divide return values from `get_reply' and + `command' by 100 before comparing with the `ftp.h' constants. + (abort_transfer): Compare `get_reply()' return value with 426 + instead of comparing it with 4 and checking the global `code' with + 426. + (store_file): Divide return value from `get_reply()' by 100. + (linear_read): Likewise. + (ftpfs_get_current_directory): Likewise. + (retrieve_dir): Likewise. + (abort_transfer): Divide return value from `command()' by 100. + (login_server): Likewise. + (setup_passive): Likewise. + (ftpfs_get_current_directory): Likewise. + (ftpfs_chdir_internal): Likewise. + (open_data_connection): Likewise. + (changetype): Likewise. + (initconn): Likewise. + (is_connection_closed): Removed unused function. + (sig_pipe): Do not set `got_sigpipe' anymore. + (net_init): Likewise. + (command): Likewise. + + * modules/ftp-method.c (ftpfs_connection_new): New parameter + `result_return' used to return the VFS error code for a failure. + (ftpfs_uri_new): Likewise. + (ftpfs_open_socket): Return a GnomeVFSResult, and set the + connection on `conn' directly. Return + `GNOME_VFS_ERROR_INVALIDHOSTNAME' if the host name is not valid. + If `gethostbyname()' fails, translate `h_errno' using + `gnome_vfs_result_from_h_errno()'. If any of the other Unix + functions fails, return a sensible error code using + `gnome_vfs_result_from_errno()'. + (login_server): Return value changed to `GnomeVFSResult'. Return + `GNOME_VFS_ERROR_LOGINFAILED' on error. Use login "anonymous" if + user name is NULL. + (ftpfs_open): Use the new result parameter in `ftpfs_uri_new()'. + (ftpfs_create): Likewise. + (command): Adapted to the new `ftpfs_connection_connect()'. + (ftpfs_connection_connect): Return type changed to + `GnomeVFSResult'. Return an appropriate result value. + (hash_conn): Deal with NULL host/user names gracefully. + (get_file_entry): Return `GNOME_VFS_ERROR_NOTFOUND' if the file is + not found, instead of `GNOME_VFS_ERROR_GENERIC'. + + * libgnomevfs/gnome-vfs-result.c: #include and declare + `h_errno' as extern + (gnome_vfs_result_from_h_errno): New function. + * libgnomevfs/gnome-vfs-result.h (gnome_vfs_result_from_h_errno): + Prototype here. + + * libgnomevfs/gnome-vfs-types.h: New errors + `GNOME_VFS_ERROR_HOSTNOTFOUND', `GNOME_VFS_ERROR_INVALIDHOSTNAME', + `GNOME_VFS_ERROR_HOSTHASNOADDRESS', `GNOME_VFS_ERROR_LOGINFAILED'. + * libgnomevfs/gnome-vfs-result.c: Added the corresponding + description strings. + + * modules/ftp-method.c (resolve_symlink_without_ls_options): Use + `gnome_vfs_canonicalize_pathname()' instead of + `canonicalize_pathname' from `util-url.c'. + (ftpfs_open): Return `GNOME_VFS_ERROR_INVALIDURI' instead of + `GNOME_VFS_ERROR_WRONGFORMAT'. + (ftpfs_create): Likewise. + (ftpfs_connection_new): Get const string parameters, and + g_strdup() all of them when filling the connection struct. + (ftpfs_parse_uri): Renamed to `ftpfs_uri_new'. Use the new + members in `GnomeVFSToplevelURI' instead of parsing the string. + (ftpfs_connection_new): Removed unused parameter `path'; callers + updated. + (lookup_conn): If the specified port is zero, use the default FTP + port. + (ftpfs_connection_new): Likewise. + + * test/test-sync.c (main): Do things through a GnomeVFSURI and use + `gnome_vfs_uri_to_string()', so that we can debug the new stuff. + + * libgnomevfs/gnome-vfs-xfer.c (gnome_vfs_xfer_uri): Hide password + when setting source/target URIs in the progress info. + + * libgnomevfs/gnome-vfs-uri.c (set_uri_element): New helper + function. It sets the URI element canonicalizing it as well. + (gnome_vfs_uri_new): Changed to use `set_uri_element' and allocate + the special toplevel URI element. + (gnome_vfs_uri_to_string): New parameter `hide_options'. Add + host/user information to the string, hiding the information + specified in `hide_options'. + + * libgnomevfs/gnome-vfs-types.h: New enum `GnomeVFSURIHideOptions'. + + * libgnomevfs/gnome-vfs-utils.c (gnome_vfs_canonicalize_pathname): + New function, stolen from `util-url.c'. Slightly changed so that + it does not remove trailing slashes anymore (we do want them!). + + * libgnomevfs/gnome-vfs-uri.c: Use the constants defined in + `gnome-vfs-constants.h'. + + * libgnomevfs/gnome-vfs.h: #include `gnome-vfs-constants.h'. + + * libgnomevfs/gnome-vfs-constants.h: New file defining VFS + constants. + +1999-09-09 Ettore Perazzoli + + * libgnomevfs/gnome-vfs-uri.c (gnome_vfs_uri_new): Allocate the + toplevel URI as a `GnomeVFSToplevelURI'. + (gnome_vfs_uri_get_toplevel): New function. + (gnome_vfs_uri_get_host_name): New function. + (gnome_vfs_uri_get_host_port): New function. + (gnome_vfs_uri_get_user_name): New function. + (gnome_vfs_uri_get_password): New function. + (gnome_vfs_uri_set_host_name): New function. + (gnome_vfs_uri_set_host_port): New function. + (gnome_vfs_uri_set_user_name): New function. + (gnome_vfs_uri_set_password): New function. + (destroy_element): If it's a toplevel URI, free its extra strings + as well. + (string_head): New helper function. + (split_toplevel_uri): New function, derived from the Midnight + Commander code in `util-url.c'. Changed semantics and parameters, + optimized and prettified a little bit. + + * libgnomevfs/gnome-vfs-types.h: New type `GnomeVFSToplevelURI'. + +1999-09-08 Ettore Perazzoli + + * libgnomevfs-pthread/gnome-vfs-job.c (execute_open): Do not set + `handle' on the notification. + (execute_create): Likewise. + (execute_close): Likewise. + + * libgnomevfs-pthread/gnome-vfs-async-ops.c + (gnome_vfs_async_close): Do not set `handle' on the request. + (gnome_vfs_async_read): Likewise. + (gnome_vfs_async_write): Likewise. + + * libgnomevfs-pthread/gnome-vfs-job.c (gnome_vfs_job_new): + Initialize the `handle' member to NULL. + (execute_open): Set `handle'. + (execute_create): Likewise. + (execute_close): Use `job->handle' instead of the (now gone) + request-specific member. + (execute_read): Likewise. + (execute_write): Likewise. + (execute_close): Set `handle' to NULL. + + * libgnomevfs-pthread/gnome-vfs-job.h: Removed `handle' members + from all the `*Job' structs. + (struct _GnomeVFSJob): New member `handle'. + + * libgnomevfs-pthread/gnome-vfs-job.c (execute_xfer): Return FALSE. + (execute_load_directory): Return FALSE; + + * libgnomevfs-pthread/gnome-vfs-async-ops.c + (gnome_vfs_async_context_new): Removed. + (gnome_vfs_async_context_destroy): Removed. + (struct _GnomeVFSAsyncContext): Removed. + (struct _GnomeVFSAsyncHandle): Removed. + (gnome_vfs_async_open): Updated for the new API. Create a new job + for this file and return it as the handle. + (gnome_vfs_async_open_as_channel): Likewise. + (gnome_vfs_async_create): Likewise. + (gnome_vfs_async_create_as_channel): Likewise. + (gnome_vfs_async_close): Updated for the new API. + (gnome_vfs_async_read): Updated for the new API. + (gnome_vfs_async_write): Updated for the new API. + (gnome_vfs_async_load_directory): Updated for the new API. Create + a new job for this file and return it as the handle. + (gnome_vfs_async_xfer): Likewise. + + * libgnomevfs-pthread/gnome-vfs-job.c (gnome_vfs_job_new): Removed + parameter `context'. + (dispatch_open_callback): Updated to match the new number of + parameters of callback functions. Pass the job as the + `GnomeVFSAsyncHandle' parameter. + (dispatch_create_callback): Likewise. + (dispatch_open_as_channel_callback): Likewise. + (dispatch_create_as_channel_callback): Likewise. + (dispatch_read_callback): Likewise. + (dispatch_write_callback): Likewise. + (dispatch_xfer_callback): Likewise. + (dispatch_close_callback): Likewise. Destroy the job on return. + (dispatch_load_directory_callback): Likewise. + + * libgnomevfs-pthread/gnome-vfs-job.h (struct _GnomeVFSJob): + Removed member `context'. + + * libgnomevfs-pthread/gnome-vfs-job.c (gnome_vfs_job_new): Create + new slave first. If this fails, return NULL. + + * test/test-channel.c (io_channel_callback): Handle combined + conditions. + + * libgnomevfs/gnome-vfs-types.h: Removed `GnomeVFSAsyncContext' + definition. + + * libgnomevfs-corba/gnome-vfs-slave-notify.c (impl_Notify_open): + Duplicate the file handle object. + (impl_Notify_close): Relese the file handle object. + + * test/test-async.c: Adapted to the new API. + * test/test-async-channel.c: Likewise. + * test/test-channel.c: Likewise. + + * test/Makefile.am: Do not compile the pthread versions of the + tests anymore. Do not compile the gnome-file-selection test for + now. + + * libgnomevfs-corba/gnome-vfs-async-ops.c: Updated all the + functions to handle the new parameters and use the new modules. + (gnome_vfs_async_context_destroy): Removed. + (gnome_vfs_async_context_reset): Removed. + (gnome_vfs_async_context_new): Removed. + (create_notify_object): Removed. + (context_from_servant): Removed. + + * libgnomevfs-corba/gnome-vfs-slave-notify.c: New file, + implementing the `GNOME::VFS::Slave::Notify' interface. + * libgnomevfs-corba/gnome-vfs-slave-notify.h: Header for it. + + * libgnomevfs-corba/gnome-vfs-slave-process.c: New file, + replacing GnomeVFSAsyncContext handling. + * libgnomevfs-corba/gnome-vfs-slave-process.h: Header for it. + + * libgnomevfs/gnome-vfs-types.h: Removed + `GnomeVFSAsyncContextResetCallback' typedef. + + * libgnomevfs/gnome-vfs-types.h: The callbacks no longer take a + `GnomeVFSAsyncContext *' parameter. Instead, they now take a + `GnomeVFSAsyncHandle *' parameter. + + * libgnomevfs/gnome-vfs-async-ops.h: Removed prototypes for + (gnome_vfs_async_context_new): Removed prototype. + (gnome_vfs_async_context_reset): Removed prototype. + (gnome_vfs_async_context_destroy): Remove prototype. + (gnome_vfs_async_open): Removed parameter `context'; new parameter + `handle_return'. + (gnome_vfs_async_open_as_channel): Likewise. + (gnome_vfs_async_create): Likewise. + (gnome_vfs_async_create_as_channel): Likewise. + (gnome_vfs_async_load_directory): Likewise. + (gnome_vfs_async_xfer): Likewise. + +1999-09-08 Michael Meeks + + * libgnomevfs/gnome-vfs-seekable.c (init_seek): Split out file read + (read_file): to here & added (write_file): to put back the cache. + (do_close): write file back. (init_seek): Add dirty bit. + NB. dirt bit could cause problems with 0 length created files. + +1999-09-07 Michael Meeks + + * libgnomevfs/gnome-vfs-ops.c (gnome_vfs_open_from_uri): Added new + improved re-open for non-random capable file methods. + + * doc/writing-modules.txt: Updated. + + * libgnomevfs/gnome-vfs-seekable.c: Actualy does something now. + + * modules/file-method.c (do_create): Fixed unix_mode on created file + to allow reading from a created file. + +1999-09-06 Ettore Perazzoli + + * libgnomevfs-pthread/gnome-vfs-job.c (gnome_vfs_job_new): + Initialize `wakeup_channel_lock'. + (gnome_vfs_job_destroy): Free it. + (wakeup): New helper function. + (job_oneway_notify): Use it. Lock the channel mutex before doing + the notification. + (job_notify): Likewise. + (job_ack_notify): Unlock the channel mutex. + + * libgnomevfs-pthread/gnome-vfs-job.h: New member + `wakeup_channel_lock' in `GnomeVFSJob'. + + * libgnomevfs-pthread/gnome-vfs-job.c (job_notify): Set + `want_notify_ack' to TRUE before waiting for the acknowledgment + condition. + (job_ack_notify): Signal the acknowledgment condition only if + `want_notify_ack' is TRUE. + + * libgnomevfs-pthread/gnome-vfs-job.h: New member + `want_notify_ack' in `GnomeVFSJob'. + +1999-09-06 Michael Meeks + + * libgnomevfs/gnome-vfs-private.h: Add include gnome-vfs-seekable.h + + * libgnomevfs/gnome-vfs-seekable.[ch]: Created. + + * libgnomevfs/Makefile.am: Include them. + + * libgnomevfs/gnome-vfs-handle.c (gnome_vfs_handle_new): Added + OPEN_RANDOM hook here. + + * libgnomevfs/gnome-vfs-ops.c (gnome_vfs_open_from_uri): and removed + hook from here. + + * test/test-seek.c: Implemented fully. + + * modules/file-method.c (do_tell, do_seek): correct order to offset + then whence. + + * test/gnome-file-selection/gicon.c (gicon_get_icon_for_file): Add + precondition. + +1999-09-06 Ettore Perazzoli + + * libgnomevfs-corba/gnome-vfs-async-ops.c + (impl_Notify_open_as_channel): If the operation fails, the context + is not busy anymore. + + * libgnomevfs/gnome-vfs-method.c: New type `MethodElement'. + (gnome_vfs_method_get): Put `MethodElement's in the hash table + instead of `GnomeVFSMethod's. + (module_get_sane_handle): Do not check for get_file_info. + + * modules/file-method.c (do_open): Removed wrong directory test. + (do_create): Removed stupid stat check. + (do_seek): Call LSEEK() correctly. + (do_tell): Likewise. + +1999-09-05 Michael Meeks + + * test/Makefile.am (noinst_PROGRAMS): Added test_seek. + + * libgnomevfs/gnome-vfs-method.c (module_get_sane_handle): + Add check for 'seek' and no 'tell'. + +1999-09-05 Ettore Perazzoli + + * modules/file-method.c (do_open): Fstat the file; if it's a + directory, return `GNOME_VFS_ERROR_ISDIRECTORY'. + (do_create): Likewise. + +1999-09-04 Ettore Perazzoli + + * modules/file-method.c (stat_to_file_info): New helper function. + (get_stat_info_from_handle): New function to get GnomeVFSFileInfo + from an existing handle. + (do_get_file_info_from_handle): New function, implementing the + `get_file_info_from_handle' method. + + * modules/ftp-method.c: Likewise. + * modules/gconf-method.c: Likewise. + * modules/http-method.c: Likewise. + + * modules/gzip-method.c: Set the `get_file_info_from_handle' + method to NULL. + + * libgnomevfs/gnome-vfs-private-types.h: New member + `get_file_info_from_handle' in `GnomeVFSMethod'. + + * libgnomevfs/gnome-vfs-handle.c + (gnome_vfs_handle_do_get_file_info): New function. + + * libgnomevfs/gnome-vfs-ops.c + (gnome_vfs_get_file_info_from_handle): New function. + + * libgnomevfs/gnome-vfs-private-types.h: New typedef. + `GnomeVFSMethodGetFileInfoFromHandleFunc'. + + * modules/file-method.c (do_create): Renamed `file_method' to + `file_handle'. + +1999-09-02 Ettore Perazzoli + + * libgnomevfs/gnome-vfs-process.c: Improved SIGCHLD handling. + (sigchld_handler): Instead of waking the GLIB loop up once for + every dead child, wake it up only for registered children. + (foreach_pid_func): Helper function for `sigchld_handler'. It + sends a pointer to the process struct and the exit status to the + wake up GIOChannel. + (wake_up): Handle the information as sent by `foreach_pid_func'. + +1999-09-01 Dave Camp + + * modules/gconf-method.c: Explicitly set the `remove_directory' + method to NULL. + +1999-09-01 Ettore Perazzoli + + * modules/http-method.c: Explicitly set the `remove_directory' + method to NULL. + + * modules/ftp-method.c (ftpfs_remove_directory): New function, for + future implementation of the `remove_directory' method. + + * modules/gzip-method.c: Explicitly set the `remove_directory' and + `rename' methods to NULL. + + * modules/file-method.c (do_remove_directory): New function, + implementing the `remove_directory' method. + + * libgnomevfs/gnome-vfs-ops.c + (gnome_vfs_remove_directory_from_uri): New function. + (gnome_vfs_remove_directory): New function. + + * libgnomevfs/gnome-vfs-private-types.h: New typedef + `GnomeVFSMethodRemoveDirectoryFunc'. Added member + `remove_directory' to `GnomeVFSMethod'. + + * libgnomevfs/gnome-vfs-ops.c (gnome_vfs_tell): Removed parameter + `whence'. + + * libgnomevfs/gnome-vfs-handle.c (gnome_vfs_handle_do_tell): + Removed parameter `whence'. + + * libgnomevfs/gnome-vfs-private-types.h: Removed parameter + `whence' from the `GnomeVFSMethodTellFunc' function typedef. + * modules/file-method.c: Updated accordingly. + * modules/ftp-method.c: Updated accordingly. + * modules/http-method.c: Updated accordingly. + +1999-09-01 Dave Camp + + * modules/gconf-method.c (set_mime_type_value): Return a + GnomeVFSResult, check return value of calls. + (set_mime_type_dir): Ditto. + (set_stat_info_dir): Ditto. + (file_info_value): Ditto. + (file_info_dir): Ditto. + (read_directory): Ditto. + +1999-09-01 Dave Camp + + * configure.in: Check for GConf. + + * modules/Makefile.am: Build libgconf.la if HAVE_GCONF is set. + + * modules/gconf-method.c: New file. + +1999-09-01 Ettore Perazzoli + + * test/test-async-directory.c (directory_load_callback): Added + cast for printf. + + * modules/file-method.c: Removed `init()' prototype. + * modules/gzip-method.c: Likewise. + + * libgnomevfs-pthread/gnome-vfs-job.c (serve_channel_read): Use + `GnomeVFSFileSize' appropriately. + (serve_channel_write): Likewise. + + * test/test-async-directory.c (print_list): Fix format string to + handle long longs. + * test/test-async.c (read_callback): Likewise. + * test/test-copy.c (xfer_progress_callback): Likewise. + * test/test-directory.c (print_list): Likewise. + * test/test-directory-visit.c (directory_visit_callback): Likewise. + + * modules/file-method.c: #define `_LARGEFILE64_SOURCE' before + including anything. #define `OPEN' to `open64' if available, to + `open' otherwise. #define `LSEEK' to `lseek64' if available, to + `lseek' otherwise. Likewise, #define `OFF_T' to either `off_t' or + `off64_t', accordingly. + (do_open): Use the `OPEN' macro instead of `open()'. + (do_create): Likewise. + (do_seek): Use the `LSEEK' macro instead of `lseek()'. + (do_tell): Likewise. + (do_tell): Use the `OFF_T' instead of `off_t'. + + * libgnomevfs/gnome-vfs-types.h: Define `GnomeVFSFileSize' as + `guint64' and `GnomeVFSFileOffset' to `gint64' if we have gint64 + support + + * configure.in: Check for `open64' and `lseek64'. + + * libgnomevfs/gnome-vfs-types.h: Added comment with instructions + for modifying the GnomeVFSResult properly. + + * libgnomevfs/gnome-vfs-result.c: Added status strings for + `GNOME_VFS_ERROR_INTERRUPTED' and `GNOME_VFS_ERROR_FILEEXISTS'. + +1999-08-31 Michael Meeks + + * modules/file-method.c: Rename module init and add shutdown & include. + * modules/ftp-method.c: ditto. + * modules/gzip-method.c: ditto. + * modules/http-method.c: ditto. + + * libgnomevfs/gnome-vfs-module.h: Create. + + * libgnomevfs/gnome-vfs-method.c (module_get_sane_handle): Add & + use new function name macros. + (gnome_vfs_method_get): move some stuff & call get_sane_handle. + +1999-08-31 Miguel de Icaza + + * modules/ftp-method.c: new global: got_sigpipe. + (ftpfs_connection_connect): Init sigpipe handler; Only connect if + connection is invalid. + (get_file_entry): Apply IS_LINEAR on proper flags. + (ftpfs_open): Use the linear state as computed in get_file_entry. + (ftpfs_read): Implemented. + (ftpfs_close): Implemented. + (ftpfs_create): Implemented. + (ftpfs_seek): Implemented. + (ftpfs_tell): Implemented. + +1999-08-30 Miguel de Icaza + + * modules/ftp-method.c (ftpfs_dir_unref): New method. + +1999-08-29 Miguel de Icaza + + * libgnomevfs/gnome-vfs-types.h: New error types. + + * libgnomevfs/gnome-vfs-result.c: Return nice results for it. + +1999-08-30 Miguel de Icaza + + * modules/ftp-method.c (IS_LINEAR): Define macro. + GNOME_VFS_OPEN_RANDOM means we need seek support, otherwise we are + a linear transfer. Cool. + +1999-08-28 Ettore Perazzoli + + * libgnomevfs-corba/gnome-vfs-async-ops.c + (impl_Notify_load_directory): Copy `name' and allocate it + dynamically. + + * libgnomevfs-corba/gnome-vfs-slave.c (allocate_info_list): + Initialize `name' to NULL. + (copy_file_info): Copy `name' into the CORBA `FileInfo' struct + using `set_corba_string'. + + * idl/gnome-vfs-slave.idl: Added member `name' to `FileInfo'. + + * modules/file-method.c (read_directory): Allocate the name in the + `GnomeVFSFileInfo' struct dynamically. + (do_get_file_info): Set `name' in the info using `g_basename'. + + * libgnomevfs/gnome-vfs-file-info.c (gnome_vfs_file_info_clear): + Free `name'. + (gnome_vfs_file_info_copy): Realloc `name' in the destination + `GnomeVFSFileInfo'. + + * libgnomevfs/gnome-vfs-types.h: Removed #definition of + `GNOME_VFS_FILE_NAME_LEN'. Member `name' of `GnomeVFSFileInfo' + changed from `char []' to `char *'. + +1999-08-27 Miguel de Icaza + + * modules/util-url.c, modules/ftp-method.c: New files for the + implementation of the FTP backend. + +1999-08-26 Miguel de Icaza + + * test/gnome-file-selection/gnome-file-selection.c + (setup_directory_clist): Also push the colormap and pop the + colormap. + +1999-08-27 Ettore Perazzoli + + * test/gnome-file-selection/gicon.c: Do not #define `ICONDIR' + manually anymore. + + * test/gnome-file-selection/Makefile.am (INCLUDES): Added quick & + dirty `-DICONDIR' definition. + +1999-08-26 Ettore Perazzoli + + * libgnomevfs-pthread/gnome-vfs-job.h: Changed `is_empty' member + of `GnomeVFSJob' from 1-bit wide gboolean to plain gboolean. + + * modules/Makefile.am (modules_LTLIBRARIES): Removed previously + commented HTTP module. + + * test/Makefile.am: Minor cleanup. + (noinst_PROGRAMS): Replace `test-async-pthread' with + `test-async_pthread' and `test-async-corba' with + `test-async_corba'. Added `test-channel_corba' and + `test-channel_pthread'. + (test-channel_corba): New target, compiling `test-channel.c' with + the CORBA-based VFS. + (test-channel_pthread): New target, compiling `test-channel.c' + with the PThread-based VFS. + + * libgnomevfs-pthread/gnome-vfs-job.c (serve_channel_write): New + function. + (serve_channel_read): New function. + (execute_open_as_channel): New function. + (execute_create_as_channel): New function. + (gnome_vfs_job_execute): Call `execute_open_as_channel()' and + `execute_create_as_channel()' for jobs + `GNOME_VFS_JOB_OPEN_AS_CHANNEL' and + `GNOME_VFS_JOB_CREATE_AS_CHANNEL', respectively. + (dispatch_open_or_create_as_channel_callback): New function. + (dispatch_job_callback): Handle `GNOME_VFS_JOB_OPEN_AS_CHANNEL' + and `GNOME_VFS_JOB_CREATE_AS_CHANNEL' through it. + + * libgnomevfs-pthread/gnome-vfs-async-ops.c + (gnome_vfs_async_open_as_channel): New function. + (gnome_vfs_async_create_as_channel): New function. + + * libgnomevfs-pthread/gnome-vfs-job.h: New structs + `GnomeVFSOpenAsChannelJob', `GnomeVFSCreateAsChannelJob'; added + corresponding members to `GnomeVFSJob'. New values + `GNOME_VFS_JOB_OPEN_AS_CHANNEL' and + `GNOME_VFS_JOB_CREATE_AS_CHANNEL' in `GnomeVFSJobType'. + + * test/test-async-directory.c: Removed translation marks. + * test/test-async.c: Likewise. + * test/test-directory-visit.c: Likewise. + * test/test-directory.c: Likewise. + + * libgnomevfs/gnome-vfs-result.c (gnome_vfs_result_from_errno): + Translate `EPERM' with `GNOME_VFS_ERROR_NOTPERMITTED'. + + * libgnomevfs/gnome-vfs-types.h: Added value + `GNOME_VFS_ERROR_NOTPERMITTED' to GnomeVFSError. + + * test/test-channel.c: New test program. + + * libgnomevfs-corba/gnome-vfs-slave.h (setup_and_serve_channel): + New function. + (serve_channel_read): New function. + (serve_channel_write): New function. + (impl_Request_open_as_channel): New function. + (impl_Request_create_as_channel): New function. + (init_Request): Install `impl_Request_open_as_channel' and + `impl_Request_create_as_channel' as the implementations for + `Request::open_as_channel' and `Request::create_as_channel', + respectively. + + * libgnomevfs-corba/gnome-vfs-async-ops.c: New values + `GNOME_VFS_ASYNC_OP_OPEN_AS_CHANNEL', + `GNOME_VFS_ASYNC_OP_CREATE_AS_CHANNEL' + `GNOME_VFS_ASYNC_OP_CHANNEL' in enum `GnomeVFSAsyncOperation'. + Sorted values in alphabetical order. + (gnome_vfs_async_open_as_channel): New function. + (gnome_vfs_async_create_as_channel): New function. + (impl_Notify_open_as_channel): New function. + (create_notify_object): Install it as the implementation of + `Notify::open_as_channel'. + + * idl/gnome-vfs-slave.idl (Request::open_as_channel): New method. + (Request::create_as_channel): New method. + (Notify::open_as_channel): New method. + + * libgnomevfs/gnome-vfs-async-ops.h + (gnome_vfs_async_open_as_channel): Declare new function. + (gnome_vfs_async_create_as_channel): Declare new function. + + * libgnomevfs/gnome-vfs-types.h: New typedefs + `GnomeVFSAsyncOpenAsChannelCallback', + `GnomeVFSAsyncCreateAsChannelCallback'. + + * libgnomevfs-corba/gnome-vfs-async-ops.c + (gnome_vfs_async_create): Added precondition that file must be + open for writing. + (impl_Notify_reset): Oops. Removed typo (`*' before parameter + `servant'). + +1999-08-26 Michael Meeks + + * test/gnome-file-selection/gnome-file-selection.c + (clean_file_list): Added. (change_dir): Clean list. + (populate_callback): Add only files. + +1999-08-26 Michael Meeks + + * test/gnome-file-selection/gnome-file-selection.c (destroy): + Destroy file_list. + (GnomeFileSelectionPrivate): Changed file_list to GList. + (select_icon_callback): use this list, add lots of preconditions. + +1999-08-26 Michael Meeks + + * libgnomevfs/gnome-vfs-types.h: Add GnomeVFSFileSize, and + GnomeVFSFileOffset ( unsigned, signed ). and push through the + whole API - How will CORBA deal with this ? + +1999-08-25 Michael Meeks + + * doc/writing-modules.txt: Started. + +1999-08-25 Michael Meeks + + * http-method.[ch]: First pass at implementing. + + * modules/file-method.c: Add NULL RenameFunc to methods, and + remove const from do_make_directory's GnomeVFSURI. + + * modules/Makefile.am: Add libhttp.la, commented out. + +1999-08-25 Ettore Perazzoli + + * modules/file-method.c: Preconditions return `GNOME_VFS_INTERNAL' + instead of `GNOME_VFS_BAD_POINTER'. + + * libgnomevfs/gnome-vfs-types.h: Removed value + `GNOME_VFS_BAD_POINTER' from the `GnomeVFSResult' enum. + +1999-08-25 Michael Meeks + + * modules/file-method.c: Update all preconditions to return BAD_POINTER + as their GnomeVFSResult instead of FALSE. + + * libgnomevfs/gnome-vfs-types.h: Added GNOME_VFS_ERROR_BAD_POINTER. + + * modules/gzip-method.h: Rename conditional include + from _FILE_H to _GZIP_H + +1999-08-25 Ettore Perazzoli + + * configure.in: Add gnomeui libs to `VFSCORBA_LIBS'. +> + + * libgnomevfs/gnome-vfs-types.h: Add GnomeVFSFileSize, and + GnomeVFSFileOffset ( unsigned, signed ). and push through the + whole API - How will CORBA deal with this ? + +1999-08-25 Michael Meeks + + * doc/writing-modules.txt: Started. + +1999-08-25 Michael Meeks + + * http-method.[ch]: First pass at implementing. + + * modules/file-method.c: Add NULL RenameFunc to methods, and + remove const from do_make_directory's GnomeVFSURI. + + * modules/Makefile.am: Add libhttp.la, commented out. + +1999-08-25 Ettore Perazzoli + + * modules/file-method.c: Preconditions return `GNOME_VFS_INTERNAL' + instead of `GNOME_VFS_BAD_POINTER'. + + * libgnomevfs/gnome-vfs-types.h: Removed value + `GNOME_VFS_BAD_POINTER' from the `GnomeVFSResult' enum. + +1999-08-25 Michael Meeks + + * modules/file-method.c: Update all preconditions to return BAD_POINTER + as their GnomeVFSResult instead of FALSE. + + * libgnomevfs/gnome-vfs-types.h: Added GNOME_VFS_ERROR_BAD_POINTER. + + * modules/gzip-method.h: Rename conditional include + from _FILE_H to _GZIP_H + +1999-08-25 Ettore Perazzoli + + * configure.in: Add gnomeui libs to `VFSCORBA_LIBS'. diff --git a/HACKING b/HACKING new file mode 100644 index 0000000..40051b8 --- /dev/null +++ b/HACKING @@ -0,0 +1,54 @@ +===Commit Permissions== +Build sherrif commits are welcome. + +If you are an experienced GNOME hacker and confident that your code is right, +you don't need maintainer approval to commit to HEAD. You still need to get your patch +reviewed by some other (competent) GNOME hacker. + +If you are unsure of your change, please feel free to send the patch to +gnome-vfs@gnome.org and get our approval so we won't execute you when it breaks +things / does them wrong. + +Please get approval for commits to the gnome-2-0 branch. + + +===Prior to Checkin=== +Create a ChangeLog entry + +Get your code reviewed by an experienced GNOME hacker, who's participation you should +cite in the ChangeLog entry by including a "Reviewed by:" line at the top of the entry. + +Make sure that any API additions or changes are reflected correctly in the documentation. + +Make sure your code does not generate warnings. Do not turn any warnings off, do not +turn -Werror off in configure.in. If you have problems with the existing warnings building +on your environment, please contact the maintainers. + +Make sure your changes are properly tested, ammong other things run a "make check". + +Please make sure components that depend on Gnome VFS (eg Nautilus, Evolution) +do not break with your change or arrange that an update to the dependent +components gets submitted at the same time. + + +===Style=== +Please use a coding style that is consistent with the existing Gnome VFS code. +Gnome VFS uses the GNOME Programming Guidelines with 8-space tabs and a +"K&R" indentation style. + + +===FIXMEs=== +Use "FIXME" to augument code that needs more work, that is missing functionality or +in general needs attention. Include a comprehensive comment explaining what is +missing, why you think something is broken, what you suggest as a fix, etc. +FIXME entries are periodically converted into bugzilla bugs. +Do not use any other format to draw attention to problems, comments that do +not contain "FIXME" are not going to be found by our problem tracking tools. + + +===Feedback=== +GnomeVFS bugs and open tasks are tracked in http://bugzilla.gnome.org + +For IRC help/feedback use irc.gnome.org/#nautilus. + +A GnomeVFS mailing list is available at http://lists.gnome.org/ \ No newline at end of file diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..b42a17a --- /dev/null +++ b/INSTALL @@ -0,0 +1,182 @@ +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.in' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..449adab --- /dev/null +++ b/Makefile.am @@ -0,0 +1,27 @@ +SUBDIRS_GNOME=monikers doc schemas + +SUBDIRS = \ + libgnomevfs \ + modules \ + schemas \ + devel-docs \ + doc \ + programs \ + test \ + monikers \ + po + +EXTRA_DIST = \ + HACKING \ + TODO \ + autogen.sh \ + gnome-vfs.spec \ + gnome-vfs-2.0.pc.in \ + gnome-vfs-module-2.0.pc.in \ + intltool-extract.in \ + intltool-merge.in \ + intltool-update.in + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = gnome-vfs-2.0.pc gnome-vfs-module-2.0.pc + diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..44ed48e --- /dev/null +++ b/Makefile.in @@ -0,0 +1,520 @@ +# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = . + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ +AS = @AS@ +AWK = @AWK@ +BONOBO_ACTIVATION_REQUIRED = @BONOBO_ACTIVATION_REQUIRED@ +BONOBO_IDLDIR = @BONOBO_IDLDIR@ +BONOBO_REQUIRED = @BONOBO_REQUIRED@ +BZ2_LIBS = @BZ2_LIBS@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +DATADIRNAME = @DATADIRNAME@ +DB2HTML = @DB2HTML@ +DLLTOOL = @DLLTOOL@ +ECHO = @ECHO@ +ENABLE_PROFILER = @ENABLE_PROFILER@ +EXEEXT = @EXEEXT@ +FAM_LIBS = @FAM_LIBS@ +GCONFTOOL = @GCONFTOOL@ +GCONF_REQUIRED = @GCONF_REQUIRED@ +GCONF_SCHEMA_CONFIG_SOURCE = @GCONF_SCHEMA_CONFIG_SOURCE@ +GCONF_SCHEMA_FILE_DIR = @GCONF_SCHEMA_FILE_DIR@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GLIB_REQUIRED = @GLIB_REQUIRED@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GNOME_ACLOCAL_DIR = @GNOME_ACLOCAL_DIR@ +GNOME_ACLOCAL_FLAGS = @GNOME_ACLOCAL_FLAGS@ +GNOME_VFS_DIR = @GNOME_VFS_DIR@ +GTKDOC = @GTKDOC@ +HAVE_GTK_DOC = @HAVE_GTK_DOC@ +HTML_DIR = @HTML_DIR@ +INSTOBJEXT = @INSTOBJEXT@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_CAVES_RULE = @INTLTOOL_CAVES_RULE@ +INTLTOOL_DESKTOP_RULE = @INTLTOOL_DESKTOP_RULE@ +INTLTOOL_DIRECTORY_RULE = @INTLTOOL_DIRECTORY_RULE@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_KEYS_RULE = @INTLTOOL_KEYS_RULE@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_OAF_RULE = @INTLTOOL_OAF_RULE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_PONG_RULE = @INTLTOOL_PONG_RULE@ +INTLTOOL_PROP_RULE = @INTLTOOL_PROP_RULE@ +INTLTOOL_SCHEMAS_RULE = @INTLTOOL_SCHEMAS_RULE@ +INTLTOOL_SERVER_RULE = @INTLTOOL_SERVER_RULE@ +INTLTOOL_SHEET_RULE = @INTLTOOL_SHEET_RULE@ +INTLTOOL_SOUNDLIST_RULE = @INTLTOOL_SOUNDLIST_RULE@ +INTLTOOL_THEME_RULE = @INTLTOOL_THEME_RULE@ +INTLTOOL_UI_RULE = @INTLTOOL_UI_RULE@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTLTOOL_XML_RULE = @INTLTOOL_XML_RULE@ +LDFLAGS = @LDFLAGS@ +LIBEFS_CFLAGS = @LIBEFS_CFLAGS@ +LIBEFS_LIBS = @LIBEFS_LIBS@ +LIBGNOMEVFS_AGE = @LIBGNOMEVFS_AGE@ +LIBGNOMEVFS_CFLAGS = @LIBGNOMEVFS_CFLAGS@ +LIBGNOMEVFS_CURRENT = @LIBGNOMEVFS_CURRENT@ +LIBGNOMEVFS_LIBS = @LIBGNOMEVFS_LIBS@ +LIBGNOMEVFS_REVISION = @LIBGNOMEVFS_REVISION@ +LIBGNUTLS_CFLAGS = @LIBGNUTLS_CFLAGS@ +LIBGNUTLS_CONFIG = @LIBGNUTLS_CONFIG@ +LIBGNUTLS_LIBS = @LIBGNUTLS_LIBS@ +LIBIDL_REQUIRED = @LIBIDL_REQUIRED@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MODULES_CFLAGS = @MODULES_CFLAGS@ +MODULES_FILE_CFLAGS = @MODULES_FILE_CFLAGS@ +MODULES_FILE_LIBS = @MODULES_FILE_LIBS@ +MODULES_GCONF_CFLAGS = @MODULES_GCONF_CFLAGS@ +MODULES_GCONF_LIBS = @MODULES_GCONF_LIBS@ +MODULES_LIBS = @MODULES_LIBS@ +MODULES_XML_CFLAGS = @MODULES_XML_CFLAGS@ +MODULES_XML_GCONF_CFLAGS = @MODULES_XML_GCONF_CFLAGS@ +MODULES_XML_GCONF_LIBS = @MODULES_XML_GCONF_LIBS@ +MODULES_XML_LIBS = @MODULES_XML_LIBS@ +MONIKERS_CFLAGS = @MONIKERS_CFLAGS@ +MONIKERS_LIBS = @MONIKERS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ORBIT_IDL = @ORBIT_IDL@ +ORBIT_REQUIRED = @ORBIT_REQUIRED@ +PACKAGE = @PACKAGE@ +PKG_CONFIG = @PKG_CONFIG@ +POFILES = @POFILES@ +POPT_LIBS = @POPT_LIBS@ +POSUB = @POSUB@ +PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ +PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ +RANLIB = @RANLIB@ +STRIP = @STRIP@ +TEST_CFLAGS = @TEST_CFLAGS@ +TEST_LIBS = @TEST_LIBS@ +TOP_BUILDDIR = @TOP_BUILDDIR@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +VFS_CFLAGS = @VFS_CFLAGS@ +VFS_INCLUDEDIR = @VFS_INCLUDEDIR@ +VFS_LIBDIR = @VFS_LIBDIR@ +VFS_LIBS = @VFS_LIBS@ +VFS_OFFSET = @VFS_OFFSET@ +VFS_OFFSET_IS = @VFS_OFFSET_IS@ +VFS_OFFSET_PRINTF = @VFS_OFFSET_PRINTF@ +VFS_SIZE = @VFS_SIZE@ +VFS_SIZE_IS = @VFS_SIZE_IS@ +VFS_SIZE_PRINTF = @VFS_SIZE_PRINTF@ +WARN_CFLAGS = @WARN_CFLAGS@ +XML_REQUIRED = @XML_REQUIRED@ +cxxflags_set = @cxxflags_set@ + +SUBDIRS_GNOME = monikers doc schemas + +SUBDIRS = \ + libgnomevfs \ + modules \ + schemas \ + devel-docs \ + doc \ + programs \ + test \ + monikers \ + po + + +EXTRA_DIST = \ + HACKING \ + TODO \ + autogen.sh \ + gnome-vfs.spec \ + gnome-vfs-2.0.pc.in \ + gnome-vfs-module-2.0.pc.in \ + intltool-extract.in \ + intltool-merge.in \ + intltool-update.in + + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = gnome-vfs-2.0.pc gnome-vfs-module-2.0.pc +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = gnome-vfs.spec gnome-vfs-2.0.pc \ +gnome-vfs-module-2.0.pc +DATA = $(pkgconfig_DATA) + +DIST_COMMON = README ./stamp-h.in AUTHORS COPYING COPYING.LIB ChangeLog \ +INSTALL Makefile.am Makefile.in NEWS TODO acconfig.h acinclude.m4 \ +aclocal.m4 config.guess config.h.in config.sub configure configure.in \ +gnome-vfs-2.0.pc.in gnome-vfs-module-2.0.pc.in gnome-vfs.spec.in \ +install-sh ltmain.sh missing mkinstalldirs + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +all: all-redirect +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status + +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.in acinclude.m4 + cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) + +config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck +$(srcdir)/configure: @MAINTAINER_MODE_TRUE@$(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) + cd $(srcdir) && $(AUTOCONF) + +config.h: stamp-h + @if test ! -f $@; then \ + rm -f stamp-h; \ + $(MAKE) stamp-h; \ + else :; fi +stamp-h: $(srcdir)/config.h.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES= CONFIG_HEADERS=config.h \ + $(SHELL) ./config.status + @echo timestamp > stamp-h 2> /dev/null +$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@$(srcdir)/stamp-h.in + @if test ! -f $@; then \ + rm -f $(srcdir)/stamp-h.in; \ + $(MAKE) $(srcdir)/stamp-h.in; \ + else :; fi +$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) acconfig.h + cd $(top_srcdir) && $(AUTOHEADER) + @echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null + +mostlyclean-hdr: + +clean-hdr: + +distclean-hdr: + -rm -f config.h + +maintainer-clean-hdr: +gnome-vfs.spec: $(top_builddir)/config.status gnome-vfs.spec.in + cd $(top_builddir) && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status +gnome-vfs-2.0.pc: $(top_builddir)/config.status gnome-vfs-2.0.pc.in + cd $(top_builddir) && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status +gnome-vfs-module-2.0.pc: $(top_builddir)/config.status gnome-vfs-module-2.0.pc.in + cd $(top_builddir) && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status + +install-pkgconfigDATA: $(pkgconfig_DATA) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(pkgconfigdir) + @list='$(pkgconfig_DATA)'; for p in $$list; do \ + if test -f $(srcdir)/$$p; then \ + echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(pkgconfigdir)/$$p"; \ + $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(pkgconfigdir)/$$p; \ + else if test -f $$p; then \ + echo " $(INSTALL_DATA) $$p $(DESTDIR)$(pkgconfigdir)/$$p"; \ + $(INSTALL_DATA) $$p $(DESTDIR)$(pkgconfigdir)/$$p; \ + fi; fi; \ + done + +uninstall-pkgconfigDATA: + @$(NORMAL_UNINSTALL) + list='$(pkgconfig_DATA)'; for p in $$list; do \ + rm -f $(DESTDIR)$(pkgconfigdir)/$$p; \ + done + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. + +@SET_MAKE@ + +all-recursive install-data-recursive install-exec-recursive \ +installdirs-recursive install-recursive uninstall-recursive \ +check-recursive installcheck-recursive info-recursive dvi-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ + rev="$$subdir $$rev"; \ + test "$$subdir" != "." || dot_seen=yes; \ + done; \ + test "$$dot_seen" = "no" && rev=". $$rev"; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)config.h.in$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags config.h.in $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + -rm -rf $(distdir) + GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz + mkdir $(distdir)/=build + mkdir $(distdir)/=inst + dc_install_base=`cd $(distdir)/=inst && pwd`; \ + cd $(distdir)/=build \ + && ../configure --srcdir=.. --prefix=$$dc_install_base \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) dist + -rm -rf $(distdir) + @banner="$(distdir).tar.gz is ready for distribution"; \ + dashes=`echo "$$banner" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + echo "$$dashes" +dist: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +dist-all: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +distdir: $(DISTFILES) + -rm -rf $(distdir) + mkdir $(distdir) + -chmod 777 $(distdir) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + for subdir in $(SUBDIRS); do \ + if test "$$subdir" = .; then :; else \ + test -d $(distdir)/$$subdir \ + || mkdir $(distdir)/$$subdir \ + || exit 1; \ + chmod 777 $(distdir)/$$subdir; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \ + || exit 1; \ + fi; \ + done +info-am: +info: info-recursive +dvi-am: +dvi: dvi-recursive +check-am: all-am +check: check-recursive +installcheck-am: +installcheck: installcheck-recursive +all-recursive-am: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +install-exec-am: +install-exec: install-exec-recursive + +install-data-am: install-pkgconfigDATA +install-data: install-data-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-recursive +uninstall-am: uninstall-pkgconfigDATA +uninstall: uninstall-recursive +all-am: Makefile $(DATA) config.h +all-redirect: all-recursive-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: installdirs-recursive +installdirs-am: + $(mkinstalldirs) $(DESTDIR)$(pkgconfigdir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-hdr mostlyclean-tags mostlyclean-generic + +mostlyclean: mostlyclean-recursive + +clean-am: clean-hdr clean-tags clean-generic mostlyclean-am + +clean: clean-recursive + +distclean-am: distclean-hdr distclean-tags distclean-generic clean-am + -rm -f libtool + +distclean: distclean-recursive + -rm -f config.status + +maintainer-clean-am: maintainer-clean-hdr maintainer-clean-tags \ + maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-recursive + -rm -f config.status + +.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \ +uninstall-pkgconfigDATA install-pkgconfigDATA install-data-recursive \ +uninstall-data-recursive install-exec-recursive \ +uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \ +all-recursive check-recursive installcheck-recursive info-recursive \ +dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \ +maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir info-am info \ +dvi-am dvi check check-am installcheck-am installcheck all-recursive-am \ +install-exec-am install-exec install-data-am install-data install-am \ +install uninstall-am uninstall all-redirect all-am all installdirs-am \ +installdirs mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..9b66a04 --- /dev/null +++ b/NEWS @@ -0,0 +1,267 @@ +gnome-vfs 2.3.8 + + * Bugs fixed: + + CDE menu fixes + + IPV6 build fixes for non-linux + + removed usage of ngettext (for now) + + fix fam crash + * Featurelets: + + add dav schema for webdav usage + + Make gnome_vfs_make_uri_from_input be smarter about + when to make http: uris + +gnome-vfs 2.3.7 + + * Bugs fixed: + + Test fixes + + translation fixes + * Featurelets: + + ignore_hosts gconf key for proxies + +gnome-vfs 2.3.6 + + * Bugs fixed: + + Fixes in CDE menu handling + + Shrink default gnome-vfs stack size + + Small API doc updates + + Properly read .mime and .keys file not ending with \n + + Compilation fixes when using gcc 3.3 + + Compilation fixes for Solaris + + Leak fixes in URI and mime-type handling + + When an unknown app is added to a mime-type short list, + also add it to this mime-type global list + + * Featurelets: + + Added an Accessibility submenu in the Applications menu + + Improve parsing of URIs (wrongly) containing UTF-8 chars + + Translation updates + +gnome-vfs 2.3.5: + * Features: + + added a startup notification application registry key + * Bugs fixed: + + Fix memory handling in mime handlers. + + Make job_private static in gnome-vfs-job.c + + Fixed CDE menu crash + +gnome-vfs 2.3.4: + * Bugs fixed: + + Get Names of vfolder directories right + +gnome-vfs 2.3.3: + * Bugs fixed: + + Fix potential crashes for uris with %2F in them + + solaris libnsl/libsocket build fixes + + Fix fam threadsafe issue + + Handle fam connection going away better + + Fixed doc building + +gnome-vfs 2.3.2 + * Features: + + ipv6 uris supported + + add some command line applications for gnome-vfs + + * Bugs fixed: + + mp3 mimetype is audio/mpeg, not audio/x-mp3 + + build issues fixed + + fix ncpfs filesystem + +gnome-vfs 2.3.1 + * Features: + + New API gnome_vfs_url_show() and related calls + + New function gnome_vfs_make_uri_from_input_with_dirs + + Cygwin port + + IPV6 support + + * Bugs fixed: + + Some mime fixes + + Correctly handle symlinks to symlinks + + hpux fixes + + CDE menu translation fixes + + Webdav PROPFIND details + + Fixed locale aliases handling + + call bindtextlocale to get translation working + + Fixes to mtab handling + +gnome-vfs 2.2.4 + + * Bugs fixed: + + Remove spew in destroy_notify (Dave Camp) + + Throttle FAM change even rate to avoid applications + using 100% cpu when a file is written + + Don't silently fail whole operation when symlink copy + fails + + Fix for crash when canceling in bug-buddy + + Fix bug in sample program (Murray Cumming) + + Fix gnome_vfs_get_volume_free_space to work on NFS mounts + + Fix start directory on some ftp servers (Christophe Fergeau) + + Look for user-installed modules in ~/.gnome2/vfs/modules + instead of ~/.gnome/vfs/modules + * Featurelets + + Some translation updates. + +gnome-vfs 2.2.3 + + * Bugs fixed: + + Fix Strange smb: crash with module callbacks + + Fix for systems without readdir_r + + Fix race in monitor code + + Handle ogg files with id3 data in mp3 sniffer + + Use cached data data for get_info_from_handle in the + http method + + Various ssh-method fixes (Bastien Nocera) + + Fix memleak (Frederic Crozat) + * Featurelets + + Try pkg-config to detect openssl if installed + + add --enable-gnutls switch to allow you to enable the + new gnutls code + + +gnome-vfs 2.2.2 + + * Bugs fixed: + + fixed memleak in monitors + + fixed some ssh method problems + + fixed some vfs moniker bugs + +gnome-vfs 2.2.1 + + * Bugs fixed: + + Fixed deadlock wrt fam while adding many monitors + + fixed memleak + +gnome-vfs 2.2.0 + + * Bugs fixed: + + races and bugs in the GIOChannel support (Josh Parsons) + * Featurelets + + Added (disabled for now) gnutls ssl lib (Andrew McDonald) + This will be enabled later when its been tested more. + +gnome-vfs 2.1.91 + + * Bugs fixed: + + gzip header creation time + + gnome_vfs_uri_extract_dirname crash + + gnome_vfs_socket_buffer_peekc corrected + +gnome-vfs 2.1.6 + + * Bugs fixed: + + fixed -lpthreads build failure (Owen Taylor) + + Handle directory moves overwriting themselves (Alex Larsson) + + Correct libdir handling (Frederic Crozat) + * Featurelets + + Deprecated gnome_vfs_mime_shutdown, gnome_vfs_loadinit, + gnome_vfs_preinit and gnome_vfs_postinit. (Alex Larsson) + + Lots of docs updates (Diego Gonzalez) + + _ prefix internal functions. (Tim Janik) + +gnome-vfs 2.1.5 + + * Featurelets + + Added GNOME_VFS_ERROR_NO_MASTER_BROWSER to GnomeVFSResult + +gnome-vfs 2.1.4 + + * Featurelets + + gnome_vfs_open_fd() replaced console: method (Giovanni Corriga) + * Bugs fixed: + + Avoid polling when user mime dir doesn't exist (Frederic Crozat) + + Fix memleak in mime data directory handling (Frederic Crozat) + +gnome-vfs 2.1.2,3 + + * Featurelets + + vfolder re-write (Alex Graveley) + + add access check API (Christophe Fergeau) + + funky network: scheme (Bastien Nocera) + + symlink following cp -R (Colin Walters) + + async performance improvements (Brian Cameron) + + favorites updates (Seth Nickell) + + eel vfs utils merged (James Willcox) + + 'uses_gnomevfs' in .application (Christophe Fergeau) + + update docs (Ian McKellar) + * Bugs fixed + + URI canonicalization (Frederic Crozat) + + config source fix (Ian McKellar) + + vfolder misc, lots. (Alex, Damon Chaplin) + + turn off vfolder debug (Mark McLouglin) + + CDE integration fixes (Stephen Browne, + Arvind Samptur, HideToshi Tajima) + + remove hard-coding (Seth) + + ssh quoting fixes (Christophe) + + several ERROR_EOF fixes (Christophe) + + buffer overflow fix (Christophe) + + http fd leak (Ghee Teo) + + OP_XFER leak fix (Jody Goldberg) + + fix trash locking, and IO (Michael Meeks) + + g_memory management fix (Dave Camp) + + newer findutils fixes (Federico Mena) + + build fixes (Michael, Yanko Kaneti, Jacob Berkman) + +gnome-vfs 2.0.2 + + * Bugs fixed + + gcc 3.1 build (Frederic Crozat) + + don't leak async pipes (Frederic) + + kill 5 second bug (Jody Goldberg, Michael Meeks) + + major locking re-hash (Jacob Berkman, Michael) + + cancellation efficiency (Michael) + + init threads earlier (Michael) + + URI canonicalization (Frederic) + + more trash security (Rohit R, Laavanya KR) + + 40% MIME parsing speedup (Michael) + + O_TRUNC fixage, UMR fix (Alex Larsson) + + CDE desktop method updates (Stephen Browne) + + async job map locking fixes (Damon Chaplin) + + MIME file monitoring tracking (Jody) + + configure cleans (Michael) + + async job / dirinfo on cancel leaks (Michael) + + * Featurelets + + more / fixed auto-regression tests (Michael) + + doc update (Dave Camp) + +gnome-vfs 2.0.1 + + * Bugs fixed + + monitor failure mode fix (Damon Chaplin) + + i18n fix (Alex Graveley) + + module link fixage (James Henstridge) + + ~/.gnome init fixes (Alex) + + Trash security fix (Damon) + + * Featurelets + + ABI padding (Seth) + +gnome-vfs 2.0.0 +--------------- + +What's New: + + * NNTP method for browsing network news + * "vfolder" method for handling the panel's virtual menu structure + * TAR method can read into tarballs + * Control Center now based on preferences module + * Support for file monitoring through FAM + * Support for Portuguese and Malay locales + * FreeBSD support + +What's Changed: + + * Ported to the GNOME 2 platform + * API cleanups and consistency fixes + * Split header files between module APIs and public APIs + * Better API coverage in documentation + * 64-bit clean + * Better Solaris support + * Don't leak memory! + * Trash doesn't cause performance problems on NFS + * Performance and memory improvements to the file & ftp modules + * Dramatic performance improvements to the ssh module + * Removed GDK dependency + * Split MIME data into a seperate module (gnome-mime-data) + * Various bug fixes to the MIME database including loading much faster + * Authentication prompts less, caches better + * XFer more accurately reports progress throughout operations diff --git a/README b/README new file mode 100644 index 0000000..6a6e6d5 --- /dev/null +++ b/README @@ -0,0 +1,18 @@ +This is the GNOME Virtual File System. + +GNOME VFS is currently used as one of the foundations of the Nautilus +file manager. + +For instructions on submitting patches, etc. check out the 'HACKING' file. + +Please read OUTSTANDING_API_ISSUES for a list of things that are not +frozen. + +Special configure options: + +--with-afs + Handle afs. Requires /afs, /usr/afsws/lib, and /usr/afsws/include. + configure doesn't add AFS support automatically because it adds considerably + to yet another module, and the AFS libraries need -lucb on Solaris, which + breaks things. + diff --git a/TODO b/TODO new file mode 100644 index 0000000..d1375e3 --- /dev/null +++ b/TODO @@ -0,0 +1,127 @@ + + GnomeVFS 2.4 TODO (Michael's wishlist) + ================= + + * backend test / validation framework + + nail down woolly semantics: + + if open SEEKABLE, then seek + shouldn't return 'not supported' + + consistant error return values for misc. + methods. + + URI / name escaping tests. + + + GnomeVFS 2.0 TODO + ================= + +This TODO attempts to cover the larger changes that we +might want in a GnomeVFS 2.0 release accompanying GNOME 2.0. +Specific details on bugs, fixes, features should be found +in GNOME bugzilla, this is just intended to serve as a +roadmap of larger work-chunks. + +Pretty much everything here is tenatively an "it would be nice" +sort of feature or change. We should highlight any changes +that are really critical. + +--GNOME 2.0 platform-- + + * Communicate with application developers and get feedback + on changes or additions they'd like to see in GnomeVFS APIs. + +-----New Features----- + + * SSL support, particularly for the HTTP module + + * Documentation, documentation documentation. We should gun + for 100% documented status for 2.0. + + * gzip, bzip2, tar, etc. Figure out how to properly handle + these and implement it. It would be best if it can be + application transparent. + +----Enchancements----- + + * Make the MIME database return the "correct information" + for a file. e.g. user selected icons, handling programs, + actions, etc. This will require the metadata API support. + (this may entail API changes to do it the "best way") + +------New APIs------- + + * Add a file metadata API. Adopt some convention + for storing metadata on filesystems without such (almost + all of the currently supported filesystems except WebDAV). + We probably want to use a large chunk of the Nautilus + metadata system for this. + + * Add a filesystem event notification API. Write backends for + fam/imon and the Linux Kernel 2.4 directory monitor. + + * Add helper functions to solve problems that application + programmers will run into frequently using GnomeVFS. For example, + parsing user input with relative paths and detecting + if they are URIs, URI fragments, plain paths...etc. Much + code of this nature needs to be refactored out of Nautilus. + +-------Modules------- + + * SMB module (Windows Filesharing) + + * CVS module + + * SSH module + + +======================================================================= + +Items from an older TODO. I've removed a bunch of outdated items already, +but I suspect even more of these are invalid. + + -Seth + + +* tar method, cpio method. + +* GZIP write support might be broken. + +* Implement SMB support through Wayne's cool librarified Samba client +stuff (Wayne Roberts ). + +* Add some kind of conversation function, so that e.g. we can know +what step the op is performing. (E.g for `open()': "connecting to +ftp.some.site.net", "logging in", "getting dir listing", "retrieving +file.tar", "extracting file.c".) + +* Make sure that only one module is initialized at a given time +(i.e. add a lock that must be obtained before calling the +`vfs_module_init()' function). + +* Complete cancellation code, to make sure every operation can be +cancelled. We need to be able to send signals to the helper +threads/processes. + +API issues +---------- + +* Better hiding of private stuff. + +* We definitely need an `URI context', which is basically a URI prefix +which is used for subsequent calls. When creating a context, backends +can assume they are going to get several requests for sub-URIs +starting from that URI, and can try to optimize things. OR maybe we +can just have a function to "lock" a certain URI. This will make +everything easier to implement. + +* Make directory/xfer calls cancellable as well. + +* Specific issues + gnome_vfs_monitor_callback's info_uri should be const. + +Installation issues +------------------- + +* We need to install the private headers: otherwise, it is not +possible to write new modules without the full gnome-vfs source code. +Maybe we need to have more than two levels (i.e. more than just +"private" and "public" headers). diff --git a/acconfig.h b/acconfig.h new file mode 100644 index 0000000..7575adf --- /dev/null +++ b/acconfig.h @@ -0,0 +1,43 @@ +#undef PACKAGE +#undef VERSION +#undef HAVE_LIBSM +#undef HAVE_CATGETS +#undef HAVE_GETTEXT +#undef HAVE_LC_MESSAGES +#undef HAVE_STPCPY +#undef ENABLE_NLS +#undef USE_PTHREAD +#undef HAVE_SOCKET +#undef HAVE_STRUCT_LINGER +#undef HAVE_NSL +#undef HAVE_OLDER_BZIP2 +#undef GNOME_PLATFORM_VERSION +#undef ENABLE_PROFILER +#undef HAVE_OPENSSL +#undef HAVE_FAM +#undef HAVE_OFF64_T +#undef GETTEXT_PACKAGE + +/* Define if you have the Andrew File System. */ +#undef AFS + +/* Define to use SVR4 statvfs to get filesystem type. */ +#undef FSTYPE_STATVFS + +/* Define to use SVR3.2 statfs to get filesystem type. */ +#undef FSTYPE_USG_STATFS + +/* Define to use AIX3 statfs to get filesystem type. */ +#undef FSTYPE_AIX_STATFS + +/* Define to use 4.3BSD getmntent to get filesystem type. */ +#undef FSTYPE_MNTENT + +/* Define to use 4.4BSD and OSF1 statfs to get filesystem type. */ +#undef FSTYPE_STATFS + +/* Define to use Ultrix getmnt to get filesystem type. */ +#undef FSTYPE_GETMNT + +#undef HAVE_GNUTLS +#undef ENABLE_IPV6 diff --git a/acinclude.m4 b/acinclude.m4 new file mode 100644 index 0000000..9aa712c --- /dev/null +++ b/acinclude.m4 @@ -0,0 +1,185 @@ +AC_DEFUN(AM_GNOME_CHECK_TYPE, + [AC_CACHE_CHECK([$1 in ], ac_cv_type_$1, + [AC_TRY_COMPILE([ +#include +#if STDC_HEADERS +#include +#include +#endif +],[$1 foo;], + ac_cv_type_$1=yes, ac_cv_type_$1=no)]) + if test $ac_cv_type_$1 = no; then + AC_DEFINE($1, $2, $1) + fi +]) + +AC_DEFUN(AM_GNOME_SIZE_T, + [AM_GNOME_CHECK_TYPE(size_t, unsigned) + AC_PROVIDE([AC_TYPE_SIZE_T]) +]) + +AC_DEFUN(AM_GNOME_OFF_T, + [AM_GNOME_CHECK_TYPE(off_t, long) + AC_PROVIDE([AC_TYPE_OFF_T]) +]) + +dnl Autoconf macros for libgnutls + +# Modified for LIBGNUTLS -- nmav +# Configure paths for LIBGCRYPT +# Shamelessly stolen from the one of XDELTA by Owen Taylor +# Werner Koch 99-12-09 + +dnl AM_PATH_LIBGNUTLS([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) +dnl Test for libgnutls, and define LIBGNUTLS_CFLAGS and LIBGNUTLS_LIBS +dnl +AC_DEFUN(AM_PATH_LIBGNUTLS, +[dnl +dnl Get the cflags and libraries from the libgnutls-config script +dnl +AC_ARG_WITH(libgnutls-prefix, + [ --with-libgnutls-prefix=PFX Prefix where libgnutls is installed (optional)], + libgnutls_config_prefix="$withval", libgnutls_config_prefix="") + + if test x$libgnutls_config_prefix != x ; then + libgnutls_config_args="$libgnutls_config_args --prefix=$libgnutls_config_prefix" + if test x${LIBGNUTLS_CONFIG+set} != xset ; then + LIBGNUTLS_CONFIG=$libgnutls_config_prefix/bin/libgnutls-config + fi + fi + + AC_PATH_PROG(LIBGNUTLS_CONFIG, libgnutls-config, no) + min_libgnutls_version=ifelse([$1], ,0.1.0,$1) + AC_MSG_CHECKING(for libgnutls - version >= $min_libgnutls_version) + no_libgnutls="" + if test "$LIBGNUTLS_CONFIG" = "no" ; then + no_libgnutls=yes + else + LIBGNUTLS_CFLAGS=`$LIBGNUTLS_CONFIG $libgnutls_config_args --cflags` + LIBGNUTLS_LIBS=`$LIBGNUTLS_CONFIG $libgnutls_config_args --libs` + libgnutls_config_version=`$LIBGNUTLS_CONFIG $libgnutls_config_args --version` + + + ac_save_CFLAGS="$CFLAGS" + ac_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $LIBGNUTLS_CFLAGS" + LIBS="$LIBS $LIBGNUTLS_LIBS" +dnl +dnl Now check if the installed libgnutls is sufficiently new. Also sanity +dnl checks the results of libgnutls-config to some extent +dnl + rm -f conf.libgnutlstest + AC_TRY_RUN([ +#include +#include +#include +#include + +int +main () +{ + system ("touch conf.libgnutlstest"); + + if( strcmp( gnutls_check_version(NULL), "$libgnutls_config_version" ) ) + { + printf("\n*** 'libgnutls-config --version' returned %s, but LIBGNUTLS (%s)\n", + "$libgnutls_config_version", gnutls_check_version(NULL) ); + printf("*** was found! If libgnutls-config was correct, then it is best\n"); + printf("*** to remove the old version of LIBGNUTLS. You may also be able to fix the error\n"); + printf("*** by modifying your LD_LIBRARY_PATH enviroment variable, or by editing\n"); + printf("*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\n"); + printf("*** required on your system.\n"); + printf("*** If libgnutls-config was wrong, set the environment variable LIBGNUTLS_CONFIG\n"); + printf("*** to point to the correct copy of libgnutls-config, and remove the file config.cache\n"); + printf("*** before re-running configure\n"); + } + else if ( strcmp(gnutls_check_version(NULL), LIBGNUTLS_VERSION ) ) + { + printf("\n*** LIBGNUTLS header file (version %s) does not match\n", LIBGNUTLS_VERSION); + printf("*** library (version %s)\n", gnutls_check_version(NULL) ); + } + else + { + if ( gnutls_check_version( "$min_libgnutls_version" ) ) + { + return 0; + } + else + { + printf("no\n*** An old version of LIBGNUTLS (%s) was found.\n", + gnutls_check_version(NULL) ); + printf("*** You need a version of LIBGNUTLS newer than %s. The latest version of\n", + "$min_libgnutls_version" ); + printf("*** LIBGNUTLS is always available from ftp://gnutls.hellug.gr/pub/gnutls.\n"); + printf("*** \n"); + printf("*** If you have already installed a sufficiently new version, this error\n"); + printf("*** probably means that the wrong copy of the libgnutls-config shell script is\n"); + printf("*** being found. The easiest way to fix this is to remove the old version\n"); + printf("*** of LIBGNUTLS, but you can also set the LIBGNUTLS_CONFIG environment to point to the\n"); + printf("*** correct copy of libgnutls-config. (In this case, you will have to\n"); + printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n"); + printf("*** so that the correct libraries are found at run-time))\n"); + } + } + return 1; +} +],, no_libgnutls=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + + if test "x$no_libgnutls" = x ; then + AC_MSG_RESULT(yes) + ifelse([$2], , :, [$2]) + else + if test -f conf.libgnutlstest ; then + : + else + AC_MSG_RESULT(no) + fi + if test "$LIBGNUTLS_CONFIG" = "no" ; then + echo "*** The libgnutls-config script installed by LIBGNUTLS could not be found" + echo "*** If LIBGNUTLS was installed in PREFIX, make sure PREFIX/bin is in" + echo "*** your path, or set the LIBGNUTLS_CONFIG environment variable to the" + echo "*** full path to libgnutls-config." + else + if test -f conf.libgnutlstest ; then + : + else + echo "*** Could not run libgnutls test program, checking why..." + CFLAGS="$CFLAGS $LIBGNUTLS_CFLAGS" + LIBS="$LIBS $LIBGNUTLS_LIBS" + AC_TRY_LINK([ +#include +#include +#include +#include +], [ return !!gnutls_check_version(NULL); ], + [ echo "*** The test program compiled, but did not run. This usually means" + echo "*** that the run-time linker is not finding LIBGNUTLS or finding the wrong" + echo "*** version of LIBGNUTLS. If it is not finding LIBGNUTLS, you'll need to set your" + echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" + echo "*** to the installed location Also, make sure you have run ldconfig if that" + echo "*** is required on your system" + echo "***" + echo "*** If you have an old version installed, it is best to remove it, although" + echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" + echo "***" ], + [ echo "*** The test program failed to compile or link. See the file config.log for the" + echo "*** exact error that occured. This usually means LIBGNUTLS was incorrectly installed" + echo "*** or that you have moved LIBGNUTLS since it was installed. In the latter case, you" + echo "*** may want to edit the libgnutls-config script: $LIBGNUTLS_CONFIG" ]) + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + LIBGNUTLS_CFLAGS="" + LIBGNUTLS_LIBS="" + ifelse([$3], , :, [$3]) + fi + rm -f conf.libgnutlstest + AC_SUBST(LIBGNUTLS_CFLAGS) + AC_SUBST(LIBGNUTLS_LIBS) +]) + +dnl end of Autoconf macros for libgnutls diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 0000000..8d6736c --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,4913 @@ +dnl aclocal.m4 generated automatically by aclocal 1.4-p6 + +dnl Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without +dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A +dnl PARTICULAR PURPOSE. + +AC_DEFUN(AM_GNOME_CHECK_TYPE, + [AC_CACHE_CHECK([$1 in ], ac_cv_type_$1, + [AC_TRY_COMPILE([ +#include +#if STDC_HEADERS +#include +#include +#endif +],[$1 foo;], + ac_cv_type_$1=yes, ac_cv_type_$1=no)]) + if test $ac_cv_type_$1 = no; then + AC_DEFINE($1, $2, $1) + fi +]) + +AC_DEFUN(AM_GNOME_SIZE_T, + [AM_GNOME_CHECK_TYPE(size_t, unsigned) + AC_PROVIDE([AC_TYPE_SIZE_T]) +]) + +AC_DEFUN(AM_GNOME_OFF_T, + [AM_GNOME_CHECK_TYPE(off_t, long) + AC_PROVIDE([AC_TYPE_OFF_T]) +]) + +dnl Autoconf macros for libgnutls + +# Modified for LIBGNUTLS -- nmav +# Configure paths for LIBGCRYPT +# Shamelessly stolen from the one of XDELTA by Owen Taylor +# Werner Koch 99-12-09 + +dnl AM_PATH_LIBGNUTLS([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) +dnl Test for libgnutls, and define LIBGNUTLS_CFLAGS and LIBGNUTLS_LIBS +dnl +AC_DEFUN(AM_PATH_LIBGNUTLS, +[dnl +dnl Get the cflags and libraries from the libgnutls-config script +dnl +AC_ARG_WITH(libgnutls-prefix, + [ --with-libgnutls-prefix=PFX Prefix where libgnutls is installed (optional)], + libgnutls_config_prefix="$withval", libgnutls_config_prefix="") + + if test x$libgnutls_config_prefix != x ; then + libgnutls_config_args="$libgnutls_config_args --prefix=$libgnutls_config_prefix" + if test x${LIBGNUTLS_CONFIG+set} != xset ; then + LIBGNUTLS_CONFIG=$libgnutls_config_prefix/bin/libgnutls-config + fi + fi + + AC_PATH_PROG(LIBGNUTLS_CONFIG, libgnutls-config, no) + min_libgnutls_version=ifelse([$1], ,0.1.0,$1) + AC_MSG_CHECKING(for libgnutls - version >= $min_libgnutls_version) + no_libgnutls="" + if test "$LIBGNUTLS_CONFIG" = "no" ; then + no_libgnutls=yes + else + LIBGNUTLS_CFLAGS=`$LIBGNUTLS_CONFIG $libgnutls_config_args --cflags` + LIBGNUTLS_LIBS=`$LIBGNUTLS_CONFIG $libgnutls_config_args --libs` + libgnutls_config_version=`$LIBGNUTLS_CONFIG $libgnutls_config_args --version` + + + ac_save_CFLAGS="$CFLAGS" + ac_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $LIBGNUTLS_CFLAGS" + LIBS="$LIBS $LIBGNUTLS_LIBS" +dnl +dnl Now check if the installed libgnutls is sufficiently new. Also sanity +dnl checks the results of libgnutls-config to some extent +dnl + rm -f conf.libgnutlstest + AC_TRY_RUN([ +#include +#include +#include +#include + +int +main () +{ + system ("touch conf.libgnutlstest"); + + if( strcmp( gnutls_check_version(NULL), "$libgnutls_config_version" ) ) + { + printf("\n*** 'libgnutls-config --version' returned %s, but LIBGNUTLS (%s)\n", + "$libgnutls_config_version", gnutls_check_version(NULL) ); + printf("*** was found! If libgnutls-config was correct, then it is best\n"); + printf("*** to remove the old version of LIBGNUTLS. You may also be able to fix the error\n"); + printf("*** by modifying your LD_LIBRARY_PATH enviroment variable, or by editing\n"); + printf("*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\n"); + printf("*** required on your system.\n"); + printf("*** If libgnutls-config was wrong, set the environment variable LIBGNUTLS_CONFIG\n"); + printf("*** to point to the correct copy of libgnutls-config, and remove the file config.cache\n"); + printf("*** before re-running configure\n"); + } + else if ( strcmp(gnutls_check_version(NULL), LIBGNUTLS_VERSION ) ) + { + printf("\n*** LIBGNUTLS header file (version %s) does not match\n", LIBGNUTLS_VERSION); + printf("*** library (version %s)\n", gnutls_check_version(NULL) ); + } + else + { + if ( gnutls_check_version( "$min_libgnutls_version" ) ) + { + return 0; + } + else + { + printf("no\n*** An old version of LIBGNUTLS (%s) was found.\n", + gnutls_check_version(NULL) ); + printf("*** You need a version of LIBGNUTLS newer than %s. The latest version of\n", + "$min_libgnutls_version" ); + printf("*** LIBGNUTLS is always available from ftp://gnutls.hellug.gr/pub/gnutls.\n"); + printf("*** \n"); + printf("*** If you have already installed a sufficiently new version, this error\n"); + printf("*** probably means that the wrong copy of the libgnutls-config shell script is\n"); + printf("*** being found. The easiest way to fix this is to remove the old version\n"); + printf("*** of LIBGNUTLS, but you can also set the LIBGNUTLS_CONFIG environment to point to the\n"); + printf("*** correct copy of libgnutls-config. (In this case, you will have to\n"); + printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n"); + printf("*** so that the correct libraries are found at run-time))\n"); + } + } + return 1; +} +],, no_libgnutls=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + + if test "x$no_libgnutls" = x ; then + AC_MSG_RESULT(yes) + ifelse([$2], , :, [$2]) + else + if test -f conf.libgnutlstest ; then + : + else + AC_MSG_RESULT(no) + fi + if test "$LIBGNUTLS_CONFIG" = "no" ; then + echo "*** The libgnutls-config script installed by LIBGNUTLS could not be found" + echo "*** If LIBGNUTLS was installed in PREFIX, make sure PREFIX/bin is in" + echo "*** your path, or set the LIBGNUTLS_CONFIG environment variable to the" + echo "*** full path to libgnutls-config." + else + if test -f conf.libgnutlstest ; then + : + else + echo "*** Could not run libgnutls test program, checking why..." + CFLAGS="$CFLAGS $LIBGNUTLS_CFLAGS" + LIBS="$LIBS $LIBGNUTLS_LIBS" + AC_TRY_LINK([ +#include +#include +#include +#include +], [ return !!gnutls_check_version(NULL); ], + [ echo "*** The test program compiled, but did not run. This usually means" + echo "*** that the run-time linker is not finding LIBGNUTLS or finding the wrong" + echo "*** version of LIBGNUTLS. If it is not finding LIBGNUTLS, you'll need to set your" + echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" + echo "*** to the installed location Also, make sure you have run ldconfig if that" + echo "*** is required on your system" + echo "***" + echo "*** If you have an old version installed, it is best to remove it, although" + echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" + echo "***" ], + [ echo "*** The test program failed to compile or link. See the file config.log for the" + echo "*** exact error that occured. This usually means LIBGNUTLS was incorrectly installed" + echo "*** or that you have moved LIBGNUTLS since it was installed. In the latter case, you" + echo "*** may want to edit the libgnutls-config script: $LIBGNUTLS_CONFIG" ]) + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + LIBGNUTLS_CFLAGS="" + LIBGNUTLS_LIBS="" + ifelse([$3], , :, [$3]) + fi + rm -f conf.libgnutlstest + AC_SUBST(LIBGNUTLS_CFLAGS) + AC_SUBST(LIBGNUTLS_LIBS) +]) + +dnl end of Autoconf macros for libgnutls + +# Like AC_CONFIG_HEADER, but automatically create stamp file. + +AC_DEFUN([AM_CONFIG_HEADER], +[AC_PREREQ([2.12]) +AC_CONFIG_HEADER([$1]) +dnl When config.status generates a header, we must update the stamp-h file. +dnl This file resides in the same directory as the config header +dnl that is generated. We must strip everything past the first ":", +dnl and everything past the last "/". +AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl +ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>, +<>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>, +<>; do + case " <<$>>CONFIG_HEADERS " in + *" <<$>>am_file "*<<)>> + echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx + ;; + esac + am_indx=`expr "<<$>>am_indx" + 1` +done<<>>dnl>>) +changequote([,]))]) + +# Do all the work for Automake. This macro actually does too much -- +# some checks are only needed if your package does certain things. +# But this isn't really a big deal. + +# serial 1 + +dnl Usage: +dnl AM_INIT_AUTOMAKE(package,version, [no-define]) + +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL]) +PACKAGE=[$1] +AC_SUBST(PACKAGE) +VERSION=[$2] +AC_SUBST(VERSION) +dnl test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi +ifelse([$3],, +AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) +AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])) +AC_REQUIRE([AM_SANITY_CHECK]) +AC_REQUIRE([AC_ARG_PROGRAM]) +dnl FIXME This is truly gross. +missing_dir=`cd $ac_aux_dir && pwd` +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}, $missing_dir) +AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}, $missing_dir) +AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir) +AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir) +AC_REQUIRE([AC_PROG_MAKE_SET])]) + +# Copyright 2002 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +AC_DEFUN([AM_AUTOMAKE_VERSION],[am__api_version="1.4"]) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION so it can be traced. +# This function is AC_REQUIREd by AC_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], + [AM_AUTOMAKE_VERSION([1.4-p6])]) + +# +# Check to make sure that the build environment is sane. +# + +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftestfile +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` + if test "[$]*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "[$]*" != "X $srcdir/configure conftestfile" \ + && test "[$]*" != "X conftestfile $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "[$]2" = conftestfile + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +rm -f conftest* +AC_MSG_RESULT(yes)]) + +dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY) +dnl The program must properly implement --version. +AC_DEFUN([AM_MISSING_PROG], +[AC_MSG_CHECKING(for working $2) +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if ($2 --version) < /dev/null > /dev/null 2>&1; then + $1=$2 + AC_MSG_RESULT(found) +else + $1="$3/missing $2" + AC_MSG_RESULT(missing) +fi +AC_SUBST($1)]) + +# Add --enable-maintainer-mode option to configure. +# From Jim Meyering + +# serial 1 + +AC_DEFUN([AM_MAINTAINER_MODE], +[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + dnl maintainer-mode is disabled by default + AC_ARG_ENABLE(maintainer-mode, +[ --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer], + USE_MAINTAINER_MODE=$enableval, + USE_MAINTAINER_MODE=no) + AC_MSG_RESULT($USE_MAINTAINER_MODE) + AM_CONDITIONAL(MAINTAINER_MODE, test $USE_MAINTAINER_MODE = yes) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST(MAINT)dnl +] +) + +# Define a conditional. + +AC_DEFUN([AM_CONDITIONAL], +[AC_SUBST($1_TRUE) +AC_SUBST($1_FALSE) +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi]) + +# gnome-common.m4 +# + +dnl GNOME_COMMON_INIT + +AC_DEFUN([GNOME_COMMON_INIT], +[ + AC_CACHE_VAL(ac_cv_gnome_aclocal_dir, + [ac_cv_gnome_aclocal_dir="$GNOME_COMMON_MACROS_DIR"]) + AC_CACHE_VAL(ac_cv_gnome_aclocal_flags, + [ac_cv_gnome_aclocal_flags="$ACLOCAL_FLAGS"]) + GNOME_ACLOCAL_DIR="$ac_cv_gnome_aclocal_dir" + GNOME_ACLOCAL_FLAGS="$ac_cv_gnome_aclocal_flags" + AC_SUBST(GNOME_ACLOCAL_DIR) + AC_SUBST(GNOME_ACLOCAL_FLAGS) + + ACLOCAL="$ACLOCAL $GNOME_ACLOCAL_FLAGS" + + AM_CONDITIONAL(INSIDE_GNOME_DOCU, false) +]) + +AC_DEFUN([GNOME_DEBUG_CHECK], +[ + AC_ARG_ENABLE(debug, [ --enable-debug turn on debugging [default=no]], enable_debug="$enableval", enable_debug=no) + + if test x$enable_debug = xyes ; then + AC_DEFINE(GNOME_ENABLE_DEBUG,1, + [Enable additional debugging at the expense of performance and size]) + fi +]) + +-*- mode: autoconf -*- + +# GNOME_AUTOGEN_OBSOLETE +# this marker is checked for in the aclocal.m4 file to check for bad macros ... + +AU_DEFUN([AM_GNOME2_GETTEXT], [AM_GLIB_GNU_GETTEXT]) +AU_DEFUN([GNOME_GTKDOC_CHECK], [GTK_DOC_CHECK]) +AU_DEFUN([GNOME2_X_CHECKS], []) +AU_DEFUN([GNOME_PTHREAD_CHECK], []) +AU_DEFUN([GNOME_CHECK_PKGCONFIG], []) +AU_DEFUN([GNOME_REQUIRE_PKGCONFIG], []) +AU_DEFUN([GNOME_PLATFORM_GNOME_2], []) + +AU_DEFUN([GNOME_CHECK_CXX], +[ + # see if a C++ compiler exists and works + AC_PROG_CXX + if test "x$ac_cv_prog_cxx_works" = xno; then + AC_MSG_WARN(ifelse([$1], , "No C++ compiler", [$1])) + fi + AM_CONDITIONAL(CXX_PRESENT, test "x$ac_cv_prog_cxx_works" != xno) +]) + +# for aclocal-1.4's benefit +# AC_DEFUN([AM_GNOME2_GETTEXT], []) +# AC_DEFUN([GNOME_GTKDOC_CHECK], []) +# AC_DEFUN([GNOME2_X_CHECKS], []) +# AC_DEFUN([GNOME_PTHREAD_CHECK], []) +# AC_DEFUN([GNOME_CHECK_PKGCONFIG], []) +# AC_DEFUN([GNOME_REQUIRE_PKGCONFIG], []) +# AC_DEFUN([GNOME_PLATFORM_GNOME_2], []) +# AC_DEFUN([GNOME_CHECK_CXX], []) + +dnl -*- mode: autoconf -*- + +# serial 1 + +dnl Usage: +dnl GTK_DOC_CHECK([minimum-gtk-doc-version]) +AC_DEFUN([GTK_DOC_CHECK], +[ + AC_BEFORE([AC_PROG_LIBTOOL],[$0])dnl setup libtool first + AC_BEFORE([AM_PROG_LIBTOOL],[$0])dnl setup libtool first + dnl for overriding the documentation installation directory + AC_ARG_WITH(html-dir, + AC_HELP_STRING([--with-html-dir=PATH], [path to installed docs]),, + [with_html_dir='${datadir}/gtk-doc/html']) + HTML_DIR="$with_html_dir" + AC_SUBST(HTML_DIR) + + dnl enable/disable documentation building + AC_ARG_ENABLE(gtk-doc, + AC_HELP_STRING([--enable-gtk-doc], + [use gtk-doc to build documentation [default=no]]),, + enable_gtk_doc=no) + + have_gtk_doc=no + if test -z "$PKG_CONFIG"; then + AC_PATH_PROG(PKG_CONFIG, pkg-config, no) + fi + if test "$PKG_CONFIG" != "no" && $PKG_CONFIG --exists gtk-doc; then + have_gtk_doc=yes + fi + + dnl do we want to do a version check? +ifelse([$1],[],, + [gtk_doc_min_version=$1 + if test "$have_gtk_doc" = yes; then + AC_MSG_CHECKING([gtk-doc version >= $gtk_doc_min_version]) + if $PKG_CONFIG --atleast-version $gtk_doc_min_version gtk-doc; then + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + have_gtk_doc=no + fi + fi +]) + if test x$enable_gtk_doc = xyes; then + if test "$have_gtk_doc" != yes; then + enable_gtk_doc=no + fi + fi + + AM_CONDITIONAL(ENABLE_GTK_DOC, test x$enable_gtk_doc = xyes) + AM_CONDITIONAL(GTK_DOC_USE_LIBTOOL, test -n "$LIBTOOL") +]) + +# libtool.m4 - Configure libtool for the host system. -*-Shell-script-*- + +# serial 46 AC_PROG_LIBTOOL + +AC_DEFUN([AC_PROG_LIBTOOL], +[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +# Prevent multiple expansion +define([AC_PROG_LIBTOOL], []) +]) + +AC_DEFUN([AC_LIBTOOL_SETUP], +[AC_PREREQ(2.13)dnl +AC_REQUIRE([AC_ENABLE_SHARED])dnl +AC_REQUIRE([AC_ENABLE_STATIC])dnl +AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_LD])dnl +AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl +AC_REQUIRE([AC_PROG_NM])dnl +AC_REQUIRE([LT_AC_PROG_SED])dnl + +AC_REQUIRE([AC_PROG_LN_S])dnl +AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl +AC_REQUIRE([AC_OBJEXT])dnl +AC_REQUIRE([AC_EXEEXT])dnl +dnl + +_LT_AC_PROG_ECHO_BACKSLASH +# Only perform the check for file, if the check method requires it +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + AC_PATH_MAGIC + fi + ;; +esac + +AC_CHECK_TOOL(RANLIB, ranlib, :) +AC_CHECK_TOOL(STRIP, strip, :) + +ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no) +ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL], +enable_win32_dll=yes, enable_win32_dll=no) + +AC_ARG_ENABLE(libtool-lock, + [ --disable-libtool-lock avoid locking (might break parallel builds)]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line __oline__ "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_SAVE + AC_LANG_C + AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_RESTORE]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; + +ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL], +[*-*-cygwin* | *-*-mingw* | *-*-pw32*) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + + # recent cygwin and mingw systems supply a stub DllMain which the user + # can override, but on older systems we have to supply one + AC_CACHE_CHECK([if libtool should supply DllMain function], lt_cv_need_dllmain, + [AC_TRY_LINK([], + [extern int __attribute__((__stdcall__)) DllMain(void*, int, void*); + DllMain (0, 0, 0);], + [lt_cv_need_dllmain=no],[lt_cv_need_dllmain=yes])]) + + case $host/$CC in + *-*-cygwin*/gcc*-mno-cygwin*|*-*-mingw*) + # old mingw systems require "-dll" to link a DLL, while more recent ones + # require "-mdll" + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -mdll" + AC_CACHE_CHECK([how to link DLLs], lt_cv_cc_dll_switch, + [AC_TRY_LINK([], [], [lt_cv_cc_dll_switch=-mdll],[lt_cv_cc_dll_switch=-dll])]) + CFLAGS="$SAVE_CFLAGS" ;; + *-*-cygwin* | *-*-pw32*) + # cygwin systems need to pass --dll to the linker, and not link + # crt.o which will require a WinMain@16 definition. + lt_cv_cc_dll_switch="-Wl,--dll -nostartfiles" ;; + esac + ;; + ]) +esac + +_LT_AC_LTCONFIG_HACK + +]) + +# AC_LIBTOOL_HEADER_ASSERT +# ------------------------ +AC_DEFUN([AC_LIBTOOL_HEADER_ASSERT], +[AC_CACHE_CHECK([whether $CC supports assert without backlinking], + [lt_cv_func_assert_works], + [case $host in + *-*-solaris*) + if test "$GCC" = yes && test "$with_gnu_ld" != yes; then + case `$CC --version 2>/dev/null` in + [[12]].*) lt_cv_func_assert_works=no ;; + *) lt_cv_func_assert_works=yes ;; + esac + fi + ;; + esac]) + +if test "x$lt_cv_func_assert_works" = xyes; then + AC_CHECK_HEADERS(assert.h) +fi +])# AC_LIBTOOL_HEADER_ASSERT + +# _LT_AC_CHECK_DLFCN +# -------------------- +AC_DEFUN([_LT_AC_CHECK_DLFCN], +[AC_CHECK_HEADERS(dlfcn.h) +])# _LT_AC_CHECK_DLFCN + +# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE +# --------------------------------- +AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], +[AC_REQUIRE([AC_CANONICAL_HOST]) +AC_REQUIRE([AC_PROG_NM]) +AC_REQUIRE([AC_OBJEXT]) +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [dnl + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Transform the above into a raw symbol and a C symbol. +symxfrm='\1 \2\3 \3' + +# Transform an extracted symbol line into a proper C declaration +lt_cv_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) # Its linker distinguishes data from code symbols + lt_cv_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris* | sysv5*) + symcode='[[BDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# Handle CRLF in mingw tool chain +opt_cr= +case $host_os in +mingw*) + opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then + symcode='[[ABCDGISTW]]' +fi + +# Try without a prefix undercore, then with it. +for ac_symprfx in "" "_"; do + + # Write the raw and C identifiers. +lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'" + + # Check to see that the pipe works correctly. + pipe_works=no + rm -f conftest* + cat > conftest.$ac_ext < $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if egrep ' nm_test_var$' "$nlist" >/dev/null; then + if egrep ' nm_test_func$' "$nlist" >/dev/null; then + cat < conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + eval "$lt_cv_global_symbol_to_cdecl"' < "$nlist" >> conftest.$ac_ext' + + cat <> conftest.$ac_ext +#if defined (__STDC__) && __STDC__ +# define lt_ptr void * +#else +# define lt_ptr char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr address; +} +lt_preloaded_symbols[[]] = +{ +EOF + sed "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr) \&\2},/" < "$nlist" >> conftest.$ac_ext + cat <<\EOF >> conftest.$ac_ext + {0, (lt_ptr) 0} +}; + +#ifdef __cplusplus +} +#endif +EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$no_builtin_flag" + if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then + pipe_works=yes + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&AC_FD_CC + fi + else + echo "cannot find nm_test_var in $nlist" >&AC_FD_CC + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AC_FD_CC + fi + else + echo "$progname: failed program was:" >&AC_FD_CC + cat conftest.$ac_ext >&5 + fi + rm -f conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +global_symbol_pipe="$lt_cv_sys_global_symbol_pipe" +if test -z "$lt_cv_sys_global_symbol_pipe"; then + global_symbol_to_cdecl= + global_symbol_to_c_name_address= +else + global_symbol_to_cdecl="$lt_cv_global_symbol_to_cdecl" + global_symbol_to_c_name_address="$lt_cv_global_symbol_to_c_name_address" +fi +if test -z "$global_symbol_pipe$global_symbol_to_cdec$global_symbol_to_c_name_address"; +then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi +]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE + +# _LT_AC_LIBTOOL_SYS_PATH_SEPARATOR +# --------------------------------- +AC_DEFUN([_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR], +[# Find the correct PATH separator. Usually this is `:', but +# DJGPP uses `;' like DOS. +if test "X${PATH_SEPARATOR+set}" != Xset; then + UNAME=${UNAME-`uname 2>/dev/null`} + case X$UNAME in + *-DOS) lt_cv_sys_path_separator=';' ;; + *) lt_cv_sys_path_separator=':' ;; + esac + PATH_SEPARATOR=$lt_cv_sys_path_separator +fi +])# _LT_AC_LIBTOOL_SYS_PATH_SEPARATOR + +# _LT_AC_PROG_ECHO_BACKSLASH +# -------------------------- +# Add some code to the start of the generated configure script which +# will find an echo command which doesn't interpret backslashes. +AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH], +[ifdef([AC_DIVERSION_NOTICE], [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], + [AC_DIVERT_PUSH(NOTICE)]) +_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR + +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} + +case X$ECHO in +X*--fallback-echo) + # Remove one level of quotation (which was required for Make). + ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` + ;; +esac + +echo=${ECHO-echo} +if test "X[$]1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X[$]1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : +else + # Restart under the correct shell. + exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} +fi + +if test "X[$]1" = X--fallback-echo; then + # used as fallback echo + shift + cat </dev/null && + echo_test_string="`eval $cmd`" && + (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null + then + break + fi + done +fi + +if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + : +else + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + IFS="${IFS= }"; save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for dir in $PATH /usr/ucb; do + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$dir/echo" + break + fi + done + IFS="$save_ifs" + + if test "X$echo" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + echo='print -r' + elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running configure again with it. + ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} + else + # Try using printf. + echo='printf %s\n' + if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # Cool, printf works + : + elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + echo="$CONFIG_SHELL [$]0 --fallback-echo" + elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$CONFIG_SHELL [$]0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do + if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null + then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "[$]0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} + else + # Oops. We lost completely, so just stick with echo. + echo=echo + fi + fi + fi + fi +fi +fi + +# Copy echo and quote the copy suitably for passing to libtool from +# the Makefile, instead of quoting the original, which is used later. +ECHO=$echo +if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then + ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" +fi + +AC_SUBST(ECHO) +AC_DIVERT_POP +])# _LT_AC_PROG_ECHO_BACKSLASH + +# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ------------------------------------------------------------------ +AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF], +[if test "$cross_compiling" = yes; then : + [$4] +else + AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + + exit (status); +}] +EOF + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_unknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_AC_TRY_DLOPEN_SELF + +# AC_LIBTOOL_DLOPEN_SELF +# ------------------- +AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], +[if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + cygwin* | mingw* | pw32*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen="shl_load"], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_AC_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test "x$lt_cv_dlopen_self" = xyes; then + LDFLAGS="$LDFLAGS $link_static_flag" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_AC_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +])# AC_LIBTOOL_DLOPEN_SELF + +AC_DEFUN([_LT_AC_LTCONFIG_HACK], +[AC_REQUIRE([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])dnl +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e s/^X//' +sed_quote_subst='s/\([[\\"\\`$\\\\]]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([[\\"\\`\\\\]]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Constants: +rm="rm -f" + +# Global variables: +default_ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except M$VC, +# which needs '.lib'). +libext=a +ltmain="$ac_aux_dir/ltmain.sh" +ofile="$default_ofile" +with_gnu_ld="$lt_cv_prog_gnu_ld" +need_locks="$enable_libtool_lock" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru +test -z "$AS" && AS=as +test -z "$CC" && CC=cc +test -z "$DLLTOOL" && DLLTOOL=dlltool +test -z "$LD" && LD=ld +test -z "$LN_S" && LN_S="ln -s" +test -z "$MAGIC_CMD" && MAGIC_CMD=file +test -z "$NM" && NM=nm +test -z "$OBJDUMP" && OBJDUMP=objdump +test -z "$RANLIB" && RANLIB=: +test -z "$STRIP" && STRIP=: +test -z "$ac_objext" && ac_objext=o + +if test x"$host" != x"$build"; then + ac_tool_prefix=${host_alias}- +else + ac_tool_prefix= +fi + +# Transform linux* to *-*-linux-gnu*, to support old configure scripts. +case $host_os in +linux-gnu*) ;; +linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'` +esac + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds" + ;; + *) + old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +# Allow CC to be a program name with arguments. +set dummy $CC +compiler="[$]2" + +AC_MSG_CHECKING([for objdir]) +rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + objdir=_libs +fi +rmdir .libs 2>/dev/null +AC_MSG_RESULT($objdir) + + +AC_ARG_WITH(pic, +[ --with-pic try to use only PIC/non-PIC objects [default=use both]], +pic_mode="$withval", pic_mode=default) +test -z "$pic_mode" && pic_mode=default + +# We assume here that the value for lt_cv_prog_cc_pic will not be cached +# in isolation, and that seeing it set (from the cache) indicates that +# the associated values are set (in the cache) correctly too. +AC_MSG_CHECKING([for $compiler option to produce PIC]) +AC_CACHE_VAL(lt_cv_prog_cc_pic, +[ lt_cv_prog_cc_pic= + lt_cv_prog_cc_shlib= + lt_cv_prog_cc_wl= + lt_cv_prog_cc_static= + lt_cv_prog_cc_no_builtin= + lt_cv_prog_cc_can_build_shared=$can_build_shared + + if test "$GCC" = yes; then + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static='-static' + + case $host_os in + aix*) + # Below there is a dirty hack to force normal static linking with -ldl + # The problem is because libdl dynamically linked with both libc and + # libC (AIX C++ library), which obviously doesn't included in libraries + # list by gcc. This cause undefined symbols with -static flags. + # This hack allows C programs to be linked with "-static -ldl", but + # not sure about C++ programs. + lt_cv_prog_cc_static="$lt_cv_prog_cc_static ${lt_cv_prog_cc_wl}-lC" + ;; + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_cv_prog_cc_pic='-m68020 -resident32 -malways-restore-a4' + ;; + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_cv_prog_cc_pic='-fno-common' + ;; + cygwin* | mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_cv_prog_cc_pic='-DDLL_EXPORT' + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_cv_prog_cc_pic=-Kconform_pic + fi + ;; + *) + lt_cv_prog_cc_pic='-fPIC' + ;; + esac + else + # PORTME Check for PIC flags for the system compiler. + case $host_os in + aix3* | aix4* | aix5*) + lt_cv_prog_cc_wl='-Wl,' + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_cv_prog_cc_static='-Bstatic' + else + lt_cv_prog_cc_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + hpux9* | hpux10* | hpux11*) + # Is there a better lt_cv_prog_cc_static that works with the bundled CC? + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static="${lt_cv_prog_cc_wl}-a ${lt_cv_prog_cc_wl}archive" + lt_cv_prog_cc_pic='+Z' + ;; + + irix5* | irix6* | nonstopux*) + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static='-non_shared' + # PIC (with -KPIC) is the default. + ;; + + cygwin* | mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_cv_prog_cc_pic='-DDLL_EXPORT' + ;; + + newsos6) + lt_cv_prog_cc_pic='-KPIC' + lt_cv_prog_cc_static='-Bstatic' + ;; + + osf3* | osf4* | osf5*) + # All OSF/1 code is PIC. + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static='-non_shared' + ;; + + sco3.2v5*) + lt_cv_prog_cc_pic='-Kpic' + lt_cv_prog_cc_static='-dn' + lt_cv_prog_cc_shlib='-belf' + ;; + + solaris*) + lt_cv_prog_cc_pic='-KPIC' + lt_cv_prog_cc_static='-Bstatic' + lt_cv_prog_cc_wl='-Wl,' + ;; + + sunos4*) + lt_cv_prog_cc_pic='-PIC' + lt_cv_prog_cc_static='-Bstatic' + lt_cv_prog_cc_wl='-Qoption ld ' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + lt_cv_prog_cc_pic='-KPIC' + lt_cv_prog_cc_static='-Bstatic' + lt_cv_prog_cc_wl='-Wl,' + ;; + + uts4*) + lt_cv_prog_cc_pic='-pic' + lt_cv_prog_cc_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_cv_prog_cc_pic='-Kconform_pic' + lt_cv_prog_cc_static='-Bstatic' + fi + ;; + + *) + lt_cv_prog_cc_can_build_shared=no + ;; + esac + fi +]) +if test -z "$lt_cv_prog_cc_pic"; then + AC_MSG_RESULT([none]) +else + AC_MSG_RESULT([$lt_cv_prog_cc_pic]) + + # Check to make sure the pic_flag actually works. + AC_MSG_CHECKING([if $compiler PIC flag $lt_cv_prog_cc_pic works]) + AC_CACHE_VAL(lt_cv_prog_cc_pic_works, [dnl + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $lt_cv_prog_cc_pic -DPIC" + AC_TRY_COMPILE([], [], [dnl + case $host_os in + hpux9* | hpux10* | hpux11*) + # On HP-UX, both CC and GCC only warn that PIC is supported... then + # they create non-PIC objects. So, if there were any warnings, we + # assume that PIC is not supported. + if test -s conftest.err; then + lt_cv_prog_cc_pic_works=no + else + lt_cv_prog_cc_pic_works=yes + fi + ;; + *) + lt_cv_prog_cc_pic_works=yes + ;; + esac + ], [dnl + lt_cv_prog_cc_pic_works=no + ]) + CFLAGS="$save_CFLAGS" + ]) + + if test "X$lt_cv_prog_cc_pic_works" = Xno; then + lt_cv_prog_cc_pic= + lt_cv_prog_cc_can_build_shared=no + else + lt_cv_prog_cc_pic=" $lt_cv_prog_cc_pic" + fi + + AC_MSG_RESULT([$lt_cv_prog_cc_pic_works]) +fi + +# Check for any special shared library compilation flags. +if test -n "$lt_cv_prog_cc_shlib"; then + AC_MSG_WARN([\`$CC' requires \`$lt_cv_prog_cc_shlib' to build shared libraries]) + if echo "$old_CC $old_CFLAGS " | egrep -e "[[ ]]$lt_cv_prog_cc_shlib[[ ]]" >/dev/null; then : + else + AC_MSG_WARN([add \`$lt_cv_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure]) + lt_cv_prog_cc_can_build_shared=no + fi +fi + +AC_MSG_CHECKING([if $compiler static flag $lt_cv_prog_cc_static works]) +AC_CACHE_VAL([lt_cv_prog_cc_static_works], [dnl + lt_cv_prog_cc_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_cv_prog_cc_static" + AC_TRY_LINK([], [], [lt_cv_prog_cc_static_works=yes]) + LDFLAGS="$save_LDFLAGS" +]) + +# Belt *and* braces to stop my trousers falling down: +test "X$lt_cv_prog_cc_static_works" = Xno && lt_cv_prog_cc_static= +AC_MSG_RESULT([$lt_cv_prog_cc_static_works]) + +pic_flag="$lt_cv_prog_cc_pic" +special_shlib_compile_flags="$lt_cv_prog_cc_shlib" +wl="$lt_cv_prog_cc_wl" +link_static_flag="$lt_cv_prog_cc_static" +no_builtin_flag="$lt_cv_prog_cc_no_builtin" +can_build_shared="$lt_cv_prog_cc_can_build_shared" + + +# Check to see if options -o and -c are simultaneously supported by compiler +AC_MSG_CHECKING([if $compiler supports -c -o file.$ac_objext]) +AC_CACHE_VAL([lt_cv_compiler_c_o], [ +$rm -r conftest 2>/dev/null +mkdir conftest +cd conftest +echo "int some_variable = 0;" > conftest.$ac_ext +mkdir out +# According to Tom Tromey, Ian Lance Taylor reported there are C compilers +# that will create temporary files in the current directory regardless of +# the output directory. Thus, making CWD read-only will cause this test +# to fail, enabling locking or at least warning the user not to do parallel +# builds. +chmod -w . +save_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -o out/conftest2.$ac_objext" +compiler_c_o=no +if { (eval echo configure:__oline__: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s out/conftest.err; then + lt_cv_compiler_c_o=no + else + lt_cv_compiler_c_o=yes + fi +else + # Append any errors to the config.log. + cat out/conftest.err 1>&AC_FD_CC + lt_cv_compiler_c_o=no +fi +CFLAGS="$save_CFLAGS" +chmod u+w . +$rm conftest* out/* +rmdir out +cd .. +rmdir conftest +$rm -r conftest 2>/dev/null +]) +compiler_c_o=$lt_cv_compiler_c_o +AC_MSG_RESULT([$compiler_c_o]) + +if test x"$compiler_c_o" = x"yes"; then + # Check to see if we can write to a .lo + AC_MSG_CHECKING([if $compiler supports -c -o file.lo]) + AC_CACHE_VAL([lt_cv_compiler_o_lo], [ + lt_cv_compiler_o_lo=no + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -c -o conftest.lo" + save_objext="$ac_objext" + ac_objext=lo + AC_TRY_COMPILE([], [int some_variable = 0;], [dnl + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + lt_cv_compiler_o_lo=no + else + lt_cv_compiler_o_lo=yes + fi + ]) + ac_objext="$save_objext" + CFLAGS="$save_CFLAGS" + ]) + compiler_o_lo=$lt_cv_compiler_o_lo + AC_MSG_RESULT([$compiler_o_lo]) +else + compiler_o_lo=no +fi + +# Check to see if we can do hard links to lock some files if needed +hard_links="nottested" +if test "$compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test "$hard_links" = no; then + AC_MSG_WARN([\`$CC' does not support \`-c -o', so \`make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi + +if test "$GCC" = yes; then + # Check to see if options -fno-rtti -fno-exceptions are supported by compiler + AC_MSG_CHECKING([if $compiler supports -fno-rtti -fno-exceptions]) + echo "int some_variable = 0;" > conftest.$ac_ext + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.$ac_ext" + compiler_rtti_exceptions=no + AC_TRY_COMPILE([], [int some_variable = 0;], [dnl + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + compiler_rtti_exceptions=no + else + compiler_rtti_exceptions=yes + fi + ]) + CFLAGS="$save_CFLAGS" + AC_MSG_RESULT([$compiler_rtti_exceptions]) + + if test "$compiler_rtti_exceptions" = "yes"; then + no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions' + else + no_builtin_flag=' -fno-builtin' + fi +fi + +# See if the linker supports building shared libraries. +AC_MSG_CHECKING([whether the linker ($LD) supports shared libraries]) + +allow_undefined_flag= +no_undefined_flag= +need_lib_prefix=unknown +need_version=unknown +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +archive_cmds= +archive_expsym_cmds= +old_archive_from_new_cmds= +old_archive_from_expsyms_cmds= +export_dynamic_flag_spec= +whole_archive_flag_spec= +thread_safe_flag_spec= +hardcode_into_libs=no +hardcode_libdir_flag_spec= +hardcode_libdir_separator= +hardcode_direct=no +hardcode_minus_L=no +hardcode_shlibpath_var=unsupported +runpath_var= +link_all_deplibs=unknown +always_export_symbols=no +export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols' +# include_expsyms should be a list of space-separated symbols to be *always* +# included in the symbol list +include_expsyms= +# exclude_expsyms can be an egrep regular expression of symbols to exclude +# it will be wrapped by ` (' and `)$', so one must not match beginning or +# end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', +# as well as any symbol that contains `d'. +exclude_expsyms="_GLOBAL_OFFSET_TABLE_" +# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out +# platforms (ab)use it in PIC code, but their linkers get confused if +# the symbol is explicitly referenced. Since portable code cannot +# rely on this symbol name, it's probably fine to never include it in +# preloaded symbol tables. +extract_expsyms_cmds= + +case $host_os in +cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; +openbsd*) + with_gnu_ld=no + ;; +esac + +ld_shlibs=yes +if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # See if GNU ld supports shared libraries. + case $host_os in + aix3* | aix4* | aix5*) + # On AIX, the GNU linker is very broken + # Note:Check GNU linker on AIX 5-IA64 when/if it becomes available. + ld_shlibs=no + cat <&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + ;; + + amigaos*) + archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can use + # them. + ld_shlibs=no + ;; + + beos*) + if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32*) + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + allow_undefined_flag=unsupported + always_export_symbols=yes + + extract_expsyms_cmds='test -f $output_objdir/impgen.c || \ + sed -e "/^# \/\* impgen\.c starts here \*\//,/^# \/\* impgen.c ends here \*\// { s/^# //;s/^# *$//; p; }" -e d < $''0 > $output_objdir/impgen.c~ + test -f $output_objdir/impgen.exe || (cd $output_objdir && \ + if test "x$HOST_CC" != "x" ; then $HOST_CC -o impgen impgen.c ; \ + else $CC -o impgen impgen.c ; fi)~ + $output_objdir/impgen $dir/$soroot > $output_objdir/$soname-def' + + old_archive_from_expsyms_cmds='$DLLTOOL --as=$AS --dllname $soname --def $output_objdir/$soname-def --output-lib $output_objdir/$newlib' + + # cygwin and mingw dlls have different entry points and sets of symbols + # to exclude. + # FIXME: what about values for MSVC? + dll_entry=__cygwin_dll_entry@12 + dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12~ + case $host_os in + mingw*) + # mingw values + dll_entry=_DllMainCRTStartup@12 + dll_exclude_symbols=DllMain@12,DllMainCRTStartup@12,DllEntryPoint@12~ + ;; + esac + + # mingw and cygwin differ, and it's simplest to just exclude the union + # of the two symbol sets. + dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12,DllMainCRTStartup@12,DllEntryPoint@12 + + # recent cygwin and mingw systems supply a stub DllMain which the user + # can override, but on older systems we have to supply one (in ltdll.c) + if test "x$lt_cv_need_dllmain" = "xyes"; then + ltdll_obj='$output_objdir/$soname-ltdll.'"$ac_objext " + ltdll_cmds='test -f $output_objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $''0 > $output_objdir/$soname-ltdll.c~ + test -f $output_objdir/$soname-ltdll.$ac_objext || (cd $output_objdir && $CC -c $soname-ltdll.c)~' + else + ltdll_obj= + ltdll_cmds= + fi + + # Extract the symbol export list from an `--export-all' def file, + # then regenerate the def file from the symbol export list, so that + # the compiled dll only exports the symbol export list. + # Be careful not to strip the DATA tag left be newer dlltools. + export_symbols_cmds="$ltdll_cmds"' + $DLLTOOL --export-all --exclude-symbols '$dll_exclude_symbols' --output-def $output_objdir/$soname-def '$ltdll_obj'$libobjs $convenience~ + sed -e "1,/EXPORTS/d" -e "s/ @ [[0-9]]*//" -e "s/ *;.*$//" < $output_objdir/$soname-def > $export_symbols' + + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is. + # If DATA tags from a recent dlltool are present, honour them! + archive_expsym_cmds='if test "x`sed 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname-def; + else + echo EXPORTS > $output_objdir/$soname-def; + _lt_hint=1; + cat $export_symbols | while read symbol; do + set dummy \$symbol; + case \[$]# in + 2) echo " \[$]2 @ \$_lt_hint ; " >> $output_objdir/$soname-def;; + 4) echo " \[$]2 \[$]3 \[$]4 ; " >> $output_objdir/$soname-def; _lt_hint=`expr \$_lt_hint - 1`;; + *) echo " \[$]2 @ \$_lt_hint \[$]3 ; " >> $output_objdir/$soname-def;; + esac; + _lt_hint=`expr 1 + \$_lt_hint`; + done; + fi~ + '"$ltdll_cmds"' + $CC -Wl,--base-file,$output_objdir/$soname-base '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~ + $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp~ + $CC -Wl,--base-file,$output_objdir/$soname-base $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~ + $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp --output-lib $output_objdir/$libname.dll.a~ + $CC $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags' + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris* | sysv5*) + if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = yes; then + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + case $host_os in + cygwin* | mingw* | pw32*) + # dlltool doesn't understand --whole-archive et. al. + whole_archive_flag_spec= + ;; + *) + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | egrep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + ;; + esac + fi +else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes && test -z "$link_static_flag"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + hardcode_direct=yes + archive_cmds='' + hardcode_libdir_separator=':' + if test "$GCC" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + hardcode_direct=yes + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + esac + + shared_flag='-shared' + else + # not using gcc + if test "$host_cpu" = ia64; then + shared_flag='${wl}-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall can do strange things, so it is better to + # generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:/usr/lib:/lib' + archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname ${wl}-h$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + else + hardcode_libdir_flag_spec='${wl}-bnolibpath ${wl}-blibpath:$libdir:/usr/lib:/lib' + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='${wl}-berok' + # This is a bit strange, but is similar to how AIX traditionally builds + # it's shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"' ~$AR -crlo $objdir/$libname$release.a $objdir/$soname' + fi + fi + ;; + + amigaos*) + archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + # see comment about different semantics on the GNU ld section + ld_shlibs=no + ;; + + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path='`cygpath -w "$srcfile"`' + ;; + + darwin* | rhapsody*) + case "$host_os" in + rhapsody* | darwin1.[[012]]) + allow_undefined_flag='-undefined suppress' + ;; + *) # Darwin 1.3 on + allow_undefined_flag='-flat_namespace -undefined suppress' + ;; + esac + # FIXME: Relying on posixy $() will cause problems for + # cross-compilation, but unfortunately the echo tests do not + # yet detect zsh echo's removal of \ escapes. Also zsh mangles + # `"' quotes if we put them in here... so don't! + archive_cmds='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs && $CC $(test .$module = .yes && echo -bundle || echo -dynamiclib) $allow_undefined_flag -o $lib ${lib}-master.o $deplibs$linker_flags $(test .$module != .yes && echo -install_name $rpath/$soname $verstring)' + # We need to add '_' to the symbols in $export_symbols first + #archive_expsym_cmds="$archive_cmds"' && strip -s $export_symbols' + hardcode_direct=yes + hardcode_shlibpath_var=no + whole_archive_flag_spec='-all_load $convenience' + ;; + + freebsd1*) + ld_shlibs=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd*) + archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9* | hpux10* | hpux11*) + case $host_os in + hpux9*) archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ;; + *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ;; + esac + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_minus_L=yes # Not in the search PATH, but as the default + # location of the library. + export_dynamic_flag_spec='${wl}-E' + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='-rpath $libdir' + fi + hardcode_libdir_separator=: + link_all_deplibs=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + openbsd*) + hardcode_direct=yes + hardcode_shlibpath_var=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + else + case "$host_os" in + openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "-exported_symbol " >> $lib.exp; echo "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp' + + #Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + hardcode_libdir_separator=: + ;; + + sco3.2v5*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + export_dynamic_flag_spec='${wl}-Bexport' + ;; + + solaris*) + # gcc --version < 3.0 without binutils cannot create self contained + # shared libraries reliably, requiring libgcc.a to resolve some of + # the object symbols generated in some cases. Libraries that use + # assert need libgcc.a to resolve __eprintf, for example. Linking + # a copy of libgcc.a into every shared library to guarantee resolving + # such symbols causes other problems: According to Tim Van Holder + # , C++ libraries end up with a separate + # (to the application) exception stack for one thing. + no_undefined_flag=' -z defs' + if test "$GCC" = yes; then + case `$CC --version 2>/dev/null` in + [[12]].*) + cat <&2 + +*** Warning: Releases of GCC earlier than version 3.0 cannot reliably +*** create self contained shared libraries on Solaris systems, without +*** introducing a dependency on libgcc.a. Therefore, libtool is disabling +*** -no-undefined support, which will at least allow you to build shared +*** libraries. However, you may find that when you link such libraries +*** into an application without using GCC, you have to manually add +*** \`gcc --print-libgcc-file-name\` to the link command. We urge you to +*** upgrade to a newer version of GCC. Another option is to rebuild your +*** current GCC to use the GNU linker from GNU binutils 2.9.1 or newer. + +EOF + no_undefined_flag= + ;; + esac + fi + # $CC -shared without GNU ld will not create a library from C++ + # object files and a static libstdc++, better avoid it by now + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv5*) + no_undefined_flag=' -z text' + # $CC -shared without GNU ld will not create a library from C++ + # object files and a static libstdc++, better avoid it by now + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + hardcode_libdir_flag_spec= + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4.2uw2*) + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=no + hardcode_shlibpath_var=no + hardcode_runpath_var=yes + runpath_var=LD_RUN_PATH + ;; + + sysv5uw7* | unixware7*) + no_undefined_flag='${wl}-z ${wl}text' + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac +fi +AC_MSG_RESULT([$ld_shlibs]) +test "$ld_shlibs" = no && can_build_shared=no + +# Check hardcoding attributes. +AC_MSG_CHECKING([how to hardcode library paths into programs]) +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || \ + test -n "$runpath_var"; then + + # We can hardcode non-existant directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$hardcode_shlibpath_var" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +AC_MSG_RESULT([$hardcode_action]) + +striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi + +reload_cmds='$LD$reload_flag -o $output$reload_objs' +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +# PORTME Fill in your ld.so characteristics +AC_MSG_CHECKING([dynamic linker characteristics]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}.so$major' + ;; + +aix4* | aix5*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}.so$major ${libname}${release}.so$versuffix $libname.so' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can + # not hardcode correct soname into executable. Probably we can + # add versioning support to collect2, so additional links can + # be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}.so$major' + fi + shlibpath_var=LIBPATH + fi + hardcode_into_libs=yes + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}.so' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi4*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + export_dynamic_flag_spec=-rdynamic + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + need_version=no + need_lib_prefix=no + case $GCC,$host_os in + yes,cygwin*) + library_names_spec='$libname.dll.a' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | sed -e 's/[[.]]/-/g'`${versuffix}.dll' + postinstall_cmds='dlpath=`bash 2>&1 -c '\''. $dir/${file}i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog .libs/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`bash 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + ;; + yes,mingw*) + library_names_spec='${libname}`echo ${release} | sed -e 's/[[.]]/-/g'`${versuffix}.dll' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | sed -e "s/^libraries://" -e "s/;/ /g" -e "s,=/,/,g"` + ;; + yes,pw32*) + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll' + ;; + *) + library_names_spec='${libname}`echo ${release} | sed -e 's/[[.]]/-/g'`${versuffix}.dll $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + # FIXME: Relying on posixy $() will cause problems for + # cross-compilation, but unfortunately the echo tests do not + # yet detect zsh echo's removal of \ escapes. + library_names_spec='${libname}${release}${versuffix}.$(test .$module = .yes && echo so || echo dylib) ${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib) ${libname}.$(test .$module = .yes && echo so || echo dylib)' + soname_spec='${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib)' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd*) + objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + *) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + dynamic_linker="$host_os dld.sl" + version_type=sunos + need_lib_prefix=no + need_version=no + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl' + soname_spec='${libname}${release}.sl$major' + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) version_type=irix ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}.so$major' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so $libname.so' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux-gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + + # Find out which ABI we are using (multilib Linux x86_64 hack). + libsuff= + case "$host_cpu" in + x86_64*|s390x*) + echo '[#]line __oline__ "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *64-bit*) + libsuff=64 + ;; + esac + fi + rm -rf conftest* + ;; + *) + ;; + esac + sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff}" + sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}" + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so' + soname_spec='${libname}${release}.so$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case "$host_os" in + openbsd2.[[89]] | openbsd2.[[89]].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + ;; + +os2*) + libname_spec='$name' + need_lib_prefix=no + library_names_spec='$libname.dll $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_version=no + soname_spec='${libname}${release}.so$major' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + hardcode_into_libs=yes + ;; + +sco3.2v5*) + version_type=osf + soname_spec='${libname}${release}.so$major' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + shlibpath_var=LD_LIBRARY_PATH + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so' + soname_spec='$libname.so.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no + +# Report the final consequences. +AC_MSG_CHECKING([if libtool supports shared libraries]) +AC_MSG_RESULT([$can_build_shared]) + +AC_MSG_CHECKING([whether to build shared libraries]) +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case "$host_os" in +aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + +aix4*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; +esac +AC_MSG_RESULT([$enable_shared]) + +AC_MSG_CHECKING([whether to build static libraries]) +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes +AC_MSG_RESULT([$enable_static]) + +if test "$hardcode_action" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +AC_LIBTOOL_DLOPEN_SELF + +if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_MSG_CHECKING([whether -lc should be explicitly linked in]) + AC_CACHE_VAL([lt_cv_archive_cmds_need_lc], + [$rm conftest* + echo 'static int dummy;' > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile); then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_cv_prog_cc_wl + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if AC_TRY_EVAL(archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi]) + AC_MSG_RESULT([$lt_cv_archive_cmds_need_lc]) + ;; + esac +fi +need_lc=${lt_cv_archive_cmds_need_lc-yes} + +# The second clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + : +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + test -f Makefile && make "$ltmain" +fi + +if test -f "$ltmain"; then + trap "$rm \"${ofile}T\"; exit 1" 1 2 15 + $rm -f "${ofile}T" + + echo creating $ofile + + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS SED \ + AR AR_FLAGS CC LD LN_S NM SHELL \ + reload_flag reload_cmds wl \ + pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \ + thread_safe_flag_spec whole_archive_flag_spec libname_spec \ + library_names_spec soname_spec \ + RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \ + old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds \ + postuninstall_cmds extract_expsyms_cmds old_archive_from_expsyms_cmds \ + old_striplib striplib file_magic_cmd export_symbols_cmds \ + deplibs_check_method allow_undefined_flag no_undefined_flag \ + finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \ + global_symbol_to_c_name_address \ + hardcode_libdir_flag_spec hardcode_libdir_separator \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do + + case $var in + reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + export_symbols_cmds | archive_cmds | archive_expsym_cmds | \ + extract_expsyms_cmds | old_archive_from_expsyms_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + cat <<__EOF__ > "${ofile}T" +#! $SHELL + +# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996-2000 Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit , 1996 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# A sed that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="${SED} -e s/^X//" + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi + +# ### BEGIN LIBTOOL CONFIG + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$need_lc + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# The default C compiler. +CC=$lt_CC + +# Is the compiler the GNU C compiler? +with_gcc=$GCC + +# The linker used to build libraries. +LD=$lt_LD + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_wl + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_pic_flag +pic_mode=$pic_mode + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_compiler_c_o + +# Can we write directly to a .lo ? +compiler_o_lo=$lt_compiler_o_lo + +# Must we lock files when doing compilation ? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_link_static_flag + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_no_builtin_flag + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Compile-time system search path for libraries +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$fix_srcfile_path" + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# ### END LIBTOOL CONFIG + +__EOF__ + + case $host_os in + aix3*) + cat <<\EOF >> "${ofile}T" + +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +EOF + ;; + esac + + case $host_os in + cygwin* | mingw* | pw32* | os2*) + cat <<'EOF' >> "${ofile}T" + # This is a source program that is used to create dlls on Windows + # Don't remove nor modify the starting and closing comments +# /* ltdll.c starts here */ +# #define WIN32_LEAN_AND_MEAN +# #include +# #undef WIN32_LEAN_AND_MEAN +# #include +# +# #ifndef __CYGWIN__ +# # ifdef __CYGWIN32__ +# # define __CYGWIN__ __CYGWIN32__ +# # endif +# #endif +# +# #ifdef __cplusplus +# extern "C" { +# #endif +# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved); +# #ifdef __cplusplus +# } +# #endif +# +# #ifdef __CYGWIN__ +# #include +# DECLARE_CYGWIN_DLL( DllMain ); +# #endif +# HINSTANCE __hDllInstance_base; +# +# BOOL APIENTRY +# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) +# { +# __hDllInstance_base = hInst; +# return TRUE; +# } +# /* ltdll.c ends here */ + # This is a source program that is used to create import libraries + # on Windows for dlls which lack them. Don't remove nor modify the + # starting and closing comments +# /* impgen.c starts here */ +# /* Copyright (C) 1999-2000 Free Software Foundation, Inc. +# +# This file is part of GNU libtool. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# */ +# +# #include /* for printf() */ +# #include /* for open(), lseek(), read() */ +# #include /* for O_RDONLY, O_BINARY */ +# #include /* for strdup() */ +# +# /* O_BINARY isn't required (or even defined sometimes) under Unix */ +# #ifndef O_BINARY +# #define O_BINARY 0 +# #endif +# +# static unsigned int +# pe_get16 (fd, offset) +# int fd; +# int offset; +# { +# unsigned char b[2]; +# lseek (fd, offset, SEEK_SET); +# read (fd, b, 2); +# return b[0] + (b[1]<<8); +# } +# +# static unsigned int +# pe_get32 (fd, offset) +# int fd; +# int offset; +# { +# unsigned char b[4]; +# lseek (fd, offset, SEEK_SET); +# read (fd, b, 4); +# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); +# } +# +# static unsigned int +# pe_as32 (ptr) +# void *ptr; +# { +# unsigned char *b = ptr; +# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); +# } +# +# int +# main (argc, argv) +# int argc; +# char *argv[]; +# { +# int dll; +# unsigned long pe_header_offset, opthdr_ofs, num_entries, i; +# unsigned long export_rva, export_size, nsections, secptr, expptr; +# unsigned long name_rvas, nexp; +# unsigned char *expdata, *erva; +# char *filename, *dll_name; +# +# filename = argv[1]; +# +# dll = open(filename, O_RDONLY|O_BINARY); +# if (dll < 1) +# return 1; +# +# dll_name = filename; +# +# for (i=0; filename[i]; i++) +# if (filename[i] == '/' || filename[i] == '\\' || filename[i] == ':') +# dll_name = filename + i +1; +# +# pe_header_offset = pe_get32 (dll, 0x3c); +# opthdr_ofs = pe_header_offset + 4 + 20; +# num_entries = pe_get32 (dll, opthdr_ofs + 92); +# +# if (num_entries < 1) /* no exports */ +# return 1; +# +# export_rva = pe_get32 (dll, opthdr_ofs + 96); +# export_size = pe_get32 (dll, opthdr_ofs + 100); +# nsections = pe_get16 (dll, pe_header_offset + 4 +2); +# secptr = (pe_header_offset + 4 + 20 + +# pe_get16 (dll, pe_header_offset + 4 + 16)); +# +# expptr = 0; +# for (i = 0; i < nsections; i++) +# { +# char sname[8]; +# unsigned long secptr1 = secptr + 40 * i; +# unsigned long vaddr = pe_get32 (dll, secptr1 + 12); +# unsigned long vsize = pe_get32 (dll, secptr1 + 16); +# unsigned long fptr = pe_get32 (dll, secptr1 + 20); +# lseek(dll, secptr1, SEEK_SET); +# read(dll, sname, 8); +# if (vaddr <= export_rva && vaddr+vsize > export_rva) +# { +# expptr = fptr + (export_rva - vaddr); +# if (export_rva + export_size > vaddr + vsize) +# export_size = vsize - (export_rva - vaddr); +# break; +# } +# } +# +# expdata = (unsigned char*)malloc(export_size); +# lseek (dll, expptr, SEEK_SET); +# read (dll, expdata, export_size); +# erva = expdata - export_rva; +# +# nexp = pe_as32 (expdata+24); +# name_rvas = pe_as32 (expdata+32); +# +# printf ("EXPORTS\n"); +# for (i = 0; i> "${ofile}T" || (rm -f "${ofile}T"; exit 1) + + mv -f "${ofile}T" "$ofile" || \ + (rm -f "$ofile" && cp "${ofile}T" "$ofile" && rm -f "${ofile}T") + chmod +x "$ofile" +fi + +])# _LT_AC_LTCONFIG_HACK + +# AC_LIBTOOL_DLOPEN - enable checks for dlopen support +AC_DEFUN([AC_LIBTOOL_DLOPEN], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])]) + +# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's +AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])]) + +# AC_ENABLE_SHARED - implement the --enable-shared flag +# Usage: AC_ENABLE_SHARED[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN([AC_ENABLE_SHARED], +[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(shared, +changequote(<<, >>)dnl +<< --enable-shared[=PKGS] build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case $enableval in +yes) enable_shared=yes ;; +no) enable_shared=no ;; +*) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl +]) + +# AC_DISABLE_SHARED - set the default shared flag to --disable-shared +AC_DEFUN([AC_DISABLE_SHARED], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_SHARED(no)]) + +# AC_ENABLE_STATIC - implement the --enable-static flag +# Usage: AC_ENABLE_STATIC[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN([AC_ENABLE_STATIC], +[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(static, +changequote(<<, >>)dnl +<< --enable-static[=PKGS] build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case $enableval in +yes) enable_static=yes ;; +no) enable_static=no ;; +*) + enable_static=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_static=AC_ENABLE_STATIC_DEFAULT)dnl +]) + +# AC_DISABLE_STATIC - set the default static flag to --disable-static +AC_DEFUN([AC_DISABLE_STATIC], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_STATIC(no)]) + + +# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag +# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN([AC_ENABLE_FAST_INSTALL], +[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(fast-install, +changequote(<<, >>)dnl +<< --enable-fast-install[=PKGS] optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case $enableval in +yes) enable_fast_install=yes ;; +no) enable_fast_install=no ;; +*) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl +]) + +# AC_DISABLE_FAST_INSTALL - set the default to --disable-fast-install +AC_DEFUN([AC_DISABLE_FAST_INSTALL], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_FAST_INSTALL(no)]) + +# AC_LIBTOOL_PICMODE - implement the --with-pic flag +# Usage: AC_LIBTOOL_PICMODE[(MODE)] +# Where MODE is either `yes' or `no'. If omitted, it defaults to +# `both'. +AC_DEFUN([AC_LIBTOOL_PICMODE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +pic_mode=ifelse($#,1,$1,default)]) + + +# AC_PATH_TOOL_PREFIX - find a file program which can recognise shared library +AC_DEFUN([AC_PATH_TOOL_PREFIX], +[AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in + /*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; + ?:/*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path. + ;; + *) + ac_save_MAGIC_CMD="$MAGIC_CMD" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="ifelse([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + egrep "$file_magic_regex" > /dev/null; then + : + else + cat <&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$ac_save_ifs" + MAGIC_CMD="$ac_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +]) + + +# AC_PATH_MAGIC - find a file program which can recognise a shared library +AC_DEFUN([AC_PATH_MAGIC], +[AC_REQUIRE([AC_CHECK_TOOL_PREFIX])dnl +AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin:$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + AC_PATH_TOOL_PREFIX(file, /usr/bin:$PATH) + else + MAGIC_CMD=: + fi +fi +]) + + +# AC_PROG_LD - find the path to the GNU or non-GNU linker +AC_DEFUN([AC_PROG_LD], +[AC_ARG_WITH(gnu-ld, +[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]], +test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no) +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR])dnl +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by GCC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | [[A-Za-z]]:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$lt_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$ac_save_ifs" +else + lt_cv_path_LD="$LD" # Let the user override the test with a path. +fi]) +LD="$lt_cv_path_LD" +if test -n "$LD"; then + AC_MSG_RESULT($LD) +else + AC_MSG_RESULT(no) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +AC_PROG_LD_GNU +]) + +# AC_PROG_LD_GNU - +AC_DEFUN([AC_PROG_LD_GNU], +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld, +[# I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 &5; then + lt_cv_prog_gnu_ld=yes +else + lt_cv_prog_gnu_ld=no +fi]) +with_gnu_ld=$lt_cv_prog_gnu_ld +]) + +# AC_PROG_LD_RELOAD_FLAG - find reload flag for linker +# -- PORTME Some linkers may need a different reload flag. +AC_DEFUN([AC_PROG_LD_RELOAD_FLAG], +[AC_CACHE_CHECK([for $LD option to reload object files], lt_cv_ld_reload_flag, +[lt_cv_ld_reload_flag='-r']) +reload_flag=$lt_cv_ld_reload_flag +test -n "$reload_flag" && reload_flag=" $reload_flag" +]) + +# AC_DEPLIBS_CHECK_METHOD - how to check for library dependencies +# -- PORTME fill in with the dynamic library characteristics +AC_DEFUN([AC_DEPLIBS_CHECK_METHOD], +[AC_CACHE_CHECK([how to recognise dependent libraries], +lt_cv_deplibs_check_method, +[lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given egrep regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix4* | aix5*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi4*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin* | mingw* | pw32*) + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library' + lt_cv_file_magic_cmd='/usr/bin/file -L' + case "$host_os" in + rhapsody* | darwin1.[[012]]) + lt_cv_file_magic_test_file=`echo /System/Library/Frameworks/System.framework/Versions/*/System | head -1` + ;; + *) # Darwin 1.3 on + lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib' + ;; + esac + ;; + +freebsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20*|hpux11*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + irix5* | nonstopux*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1" + ;; + *) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[[1234]] dynamic lib MIPS - version 1" + ;; + esac + lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*` + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux-gnu*) + case $host_cpu in + alpha* | hppa* | i*86 | mips | mipsel | powerpc* | sparc* | ia64* | s390* | x86_64*) + lt_cv_deplibs_check_method=pass_all ;; + *) + # glibc up to 2.1.1 does not perform some relocations on ARM + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; + esac + lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so` + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/\.]]+\.so\.[[0-9]]+\.[[0-9]]+$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/\.]]+\.so$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +openbsd*) + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB shared object' + else + lt_cv_deplibs_check_method='file_magic OpenBSD.* shared library' + fi + ;; + +osf3* | osf4* | osf5*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method='file_magic COFF format alpha shared library' + lt_cv_file_magic_test_file=/shlib/libc.so + lt_cv_deplibs_check_method=pass_all + ;; + +sco3.2v5*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + lt_cv_file_magic_test_file=/lib/libc.so + ;; + +sysv5uw[[78]]* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; +esac +]) +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +]) + + +# AC_PROG_NM - find the path to a BSD-compatible name lister +AC_DEFUN([AC_PROG_NM], +[AC_REQUIRE([_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR])dnl +AC_MSG_CHECKING([for BSD-compatible nm]) +AC_CACHE_VAL(lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/${ac_tool_prefix}nm + if test -f $tmp_nm || test -f $tmp_nm$ac_exeext ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then + lt_cv_path_NM="$tmp_nm -B" + break + elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + lt_cv_path_NM="$tmp_nm -p" + break + else + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + fi + fi + done + IFS="$ac_save_ifs" + test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm +fi]) +NM="$lt_cv_path_NM" +AC_MSG_RESULT([$NM]) +]) + +# AC_CHECK_LIBM - check for math library +AC_DEFUN([AC_CHECK_LIBM], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cygwin* | *-*-pw32*) + # These system don't have libm + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, main, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, main, LIBM="-lm") + ;; +esac +]) + +# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for +# the libltdl convenience library and LTDLINCL to the include flags for +# the libltdl header and adds --enable-ltdl-convenience to the +# configure arguments. Note that LIBLTDL and LTDLINCL are not +# AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If DIR is not +# provided, it is assumed to be `libltdl'. LIBLTDL will be prefixed +# with '${top_builddir}/' and LTDLINCL will be prefixed with +# '${top_srcdir}/' (note the single quotes!). If your package is not +# flat and you're not using automake, define top_builddir and +# top_srcdir appropriately in the Makefiles. +AC_DEFUN([AC_LIBLTDL_CONVENIENCE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + case $enable_ltdl_convenience in + no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; + "") enable_ltdl_convenience=yes + ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; + esac + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la + LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + # For backwards non-gettext consistent compatibility... + INCLTDL="$LTDLINCL" +]) + +# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for +# the libltdl installable library and LTDLINCL to the include flags for +# the libltdl header and adds --enable-ltdl-install to the configure +# arguments. Note that LIBLTDL and LTDLINCL are not AC_SUBSTed, nor is +# AC_CONFIG_SUBDIRS called. If DIR is not provided and an installed +# libltdl is not found, it is assumed to be `libltdl'. LIBLTDL will +# be prefixed with '${top_builddir}/' and LTDLINCL will be prefixed +# with '${top_srcdir}/' (note the single quotes!). If your package is +# not flat and you're not using automake, define top_builddir and +# top_srcdir appropriately in the Makefiles. +# In the future, this macro may have to be called after AC_PROG_LIBTOOL. +AC_DEFUN([AC_LIBLTDL_INSTALLABLE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + AC_CHECK_LIB(ltdl, main, + [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no], + [if test x"$enable_ltdl_install" = xno; then + AC_MSG_WARN([libltdl not installed, but installation disabled]) + else + enable_ltdl_install=yes + fi + ]) + if test x"$enable_ltdl_install" = x"yes"; then + ac_configure_args="$ac_configure_args --enable-ltdl-install" + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la + LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + else + ac_configure_args="$ac_configure_args --enable-ltdl-install=no" + LIBLTDL="-lltdl" + LTDLINCL= + fi + # For backwards non-gettext consistent compatibility... + INCLTDL="$LTDLINCL" +]) + +# old names +AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL]) +AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) +AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) +AC_DEFUN([AM_PROG_LD], [AC_PROG_LD]) +AC_DEFUN([AM_PROG_NM], [AC_PROG_NM]) + +# This is just to silence aclocal about the macro not being used +ifelse([AC_DISABLE_FAST_INSTALL]) + +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +# LT_AC_PROG_SED +# -------------- +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +AC_DEFUN([LT_AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_executable_p="test -f" +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + _sed_list="$_sed_list $as_dir/$ac_prog$ac_exec_ext" + fi + done + done +done + + # Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. +: ${TMPDIR=/tmp} +{ + tmp=`(umask 077 && mktemp -d -q "$TMPDIR/sedXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=$TMPDIR/sed$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in $TMPDIR" >&2 + { (exit 1); exit 1; } +} + _max=0 + _count=0 + # Add /usr/xpg4/bin/sed as it is typically found on Solaris + # along with /bin/sed that truncates output. + for _sed in $_sed_list /usr/xpg4/bin/sed; do + test ! -f ${_sed} && break + cat /dev/null > "$tmp/sed.in" + _count=0 + echo ${ECHO_N-$ac_n} "0123456789${ECHO_C-$ac_c}" >"$tmp/sed.in" + # Check for GNU sed and select it if it is found. + if "${_sed}" --version 2>&1 < /dev/null | egrep '(GNU)' > /dev/null; then + lt_cv_path_SED=${_sed} + break + fi + while true; do + cat "$tmp/sed.in" "$tmp/sed.in" >"$tmp/sed.tmp" + mv "$tmp/sed.tmp" "$tmp/sed.in" + cp "$tmp/sed.in" "$tmp/sed.nl" + echo >>"$tmp/sed.nl" + ${_sed} -e 's/a$//' < "$tmp/sed.nl" >"$tmp/sed.out" || break + cmp -s "$tmp/sed.out" "$tmp/sed.nl" || break + # 40000 chars as input seems more than enough + test $_count -gt 10 && break + _count=`expr $_count + 1` + if test $_count -gt $_max; then + _max=$_count + lt_cv_path_SED=$_sed + fi + done + done + rm -rf "$tmp" +]) +if test "X$SED" != "X"; then + lt_cv_path_SED=$SED +else + SED=$lt_cv_path_SED +fi +AC_MSG_RESULT([$SED]) +]) + +# isc-posix.m4 serial 2 (gettext-0.11.2) +dnl Copyright (C) 1995-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +# This file is not needed with autoconf-2.53 and newer. Remove it in 2005. + +# This test replaces the one in autoconf. +# Currently this macro should have the same name as the autoconf macro +# because gettext's gettext.m4 (distributed in the automake package) +# still uses it. Otherwise, the use in gettext.m4 makes autoheader +# give these diagnostics: +# configure.in:556: AC_TRY_COMPILE was called before AC_ISC_POSIX +# configure.in:556: AC_TRY_RUN was called before AC_ISC_POSIX + +undefine([AC_ISC_POSIX]) + +AC_DEFUN([AC_ISC_POSIX], + [ + dnl This test replaces the obsolescent AC_ISC_POSIX kludge. + AC_CHECK_LIB(cposix, strerror, [LIBS="$LIBS -lcposix"]) + ] +) + + +dnl AC_PROG_INTLTOOL([MINIMUM-VERSION]) +# serial 1 AC_PROG_INTLTOOL +AC_DEFUN(AC_PROG_INTLTOOL, +[ + +if test -n "$1"; then + AC_MSG_CHECKING(for intltool >= $1) + + INTLTOOL_REQUIRED_VERSION_AS_INT=`echo $1 | awk -F. '{ printf "%d", $[1] * 100 + $[2]; }'` + INTLTOOL_APPLIED_VERSION=`awk -F\" '/\\$VERSION / { printf $[2]; }' < ${srcdir}/intltool-update.in` + changequote({{,}}) + INTLTOOL_APPLIED_VERSION_AS_INT=`awk -F\" '/\\$VERSION / { split(${{2}}, VERSION, "."); printf "%d\n", VERSION[1] * 100 + VERSION[2];}' < ${srcdir}/intltool-update.in` + changequote([,]) + + if test "$INTLTOOL_APPLIED_VERSION_AS_INT" -ge "$INTLTOOL_REQUIRED_VERSION_AS_INT"; then + AC_MSG_RESULT([$INTLTOOL_APPLIED_VERSION found]) + else + AC_MSG_RESULT([$INTLTOOL_APPLIED_VERSION found. Your intltool is too old. You need intltool $1 or later.]) + exit 1 + fi +fi + + INTLTOOL_DESKTOP_RULE='%.desktop: %.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) $(top_srcdir)/po $< [$]@ -d -u -c $(top_builddir)/po/.intltool-merge-cache' +INTLTOOL_DIRECTORY_RULE='%.directory: %.directory.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) $(top_srcdir)/po $< [$]@ -d -u -c $(top_builddir)/po/.intltool-merge-cache' + INTLTOOL_KEYS_RULE='%.keys: %.keys.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) $(top_srcdir)/po $< [$]@ -k -u -c $(top_builddir)/po/.intltool-merge-cache' + INTLTOOL_PROP_RULE='%.prop: %.prop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) $(top_srcdir)/po $< [$]@ -d -u -c $(top_builddir)/po/.intltool-merge-cache' + INTLTOOL_OAF_RULE='%.oaf: %.oaf.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) $(top_srcdir)/po $< [$]@ -o -p' + INTLTOOL_PONG_RULE='%.pong: %.pong.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) $(top_srcdir)/po $< [$]@ -x -u -c $(top_builddir)/po/.intltool-merge-cache' + INTLTOOL_SERVER_RULE='%.server: %.server.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) $(top_srcdir)/po $< [$]@ -o -u -c $(top_builddir)/po/.intltool-merge-cache' + INTLTOOL_SHEET_RULE='%.sheet: %.sheet.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) $(top_srcdir)/po $< [$]@ -x -u -c $(top_builddir)/po/.intltool-merge-cache' +INTLTOOL_SOUNDLIST_RULE='%.soundlist: %.soundlist.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) $(top_srcdir)/po $< [$]@ -d -u -c $(top_builddir)/po/.intltool-merge-cache' + INTLTOOL_UI_RULE='%.ui: %.ui.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) $(top_srcdir)/po $< [$]@ -x -u -c $(top_builddir)/po/.intltool-merge-cache' + INTLTOOL_XML_RULE='%.xml: %.xml.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) $(top_srcdir)/po $< [$]@ -x -u -c $(top_builddir)/po/.intltool-merge-cache' + INTLTOOL_CAVES_RULE='%.caves: %.caves.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) $(top_srcdir)/po $< [$]@ -d -u -c $(top_builddir)/po/.intltool-merge-cache' + INTLTOOL_SCHEMAS_RULE='%.schemas: %.schemas.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) $(top_srcdir)/po $< [$]@ -s -u -c $(top_builddir)/po/.intltool-merge-cache' + INTLTOOL_THEME_RULE='%.theme: %.theme.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) $(top_srcdir)/po $< [$]@ -d -u -c $(top_builddir)/po/.intltool-merge-cache' + +AC_SUBST(INTLTOOL_DESKTOP_RULE) +AC_SUBST(INTLTOOL_DIRECTORY_RULE) +AC_SUBST(INTLTOOL_KEYS_RULE) +AC_SUBST(INTLTOOL_PROP_RULE) +AC_SUBST(INTLTOOL_OAF_RULE) +AC_SUBST(INTLTOOL_PONG_RULE) +AC_SUBST(INTLTOOL_SERVER_RULE) +AC_SUBST(INTLTOOL_SHEET_RULE) +AC_SUBST(INTLTOOL_SOUNDLIST_RULE) +AC_SUBST(INTLTOOL_UI_RULE) +AC_SUBST(INTLTOOL_XML_RULE) +AC_SUBST(INTLTOOL_CAVES_RULE) +AC_SUBST(INTLTOOL_SCHEMAS_RULE) +AC_SUBST(INTLTOOL_THEME_RULE) + +# Use the tools built into the package, not the ones that are installed. + +INTLTOOL_EXTRACT='$(top_builddir)/intltool-extract' +INTLTOOL_MERGE='$(top_builddir)/intltool-merge' +INTLTOOL_UPDATE='$(top_builddir)/intltool-update' + +AC_SUBST(INTLTOOL_EXTRACT) +AC_SUBST(INTLTOOL_MERGE) +AC_SUBST(INTLTOOL_UPDATE) + +AC_PATH_PROG(INTLTOOL_PERL, perl) +if test -z "$INTLTOOL_PERL"; then + AC_MSG_ERROR([perl not found; required for intltool]) +fi +if test -z "`$INTLTOOL_PERL -v | fgrep '5.' 2> /dev/null`"; then + AC_MSG_ERROR([perl 5.x required for intltool]) +fi + +# Remove file type tags (using []) from po/POTFILES. + +ifdef([AC_DIVERSION_ICMDS],[ + AC_DIVERT_PUSH(AC_DIVERSION_ICMDS) + changequote(,) + mv -f po/POTFILES po/POTFILES.tmp + sed -e 's/\[.*\] *//' < po/POTFILES.tmp > po/POTFILES + rm -f po/POTFILES.tmp + changequote([,]) + AC_DIVERT_POP() +],[ + ifdef([AC_CONFIG_COMMANDS_PRE],[ + AC_CONFIG_COMMANDS_PRE([ + changequote(,) + mv -f po/POTFILES po/POTFILES.tmp + sed -e 's/\[.*\] *//' < po/POTFILES.tmp > po/POTFILES + rm -f po/POTFILES.tmp + changequote([,]) + ]) + ]) +]) + +# Manually sed perl in so people don't have to put the intltool scripts in AC_OUTPUT. + +AC_OUTPUT_COMMANDS([ + +sed -e "s:@INTLTOOL_PERL@:${INTLTOOL_PERL}:;" < ${srcdir}/intltool-extract.in > intltool-extract.out +if cmp -s intltool-extract intltool-extract.out 2>/dev/null; then + rm -f intltool-extract.out +else + mv -f intltool-extract.out intltool-extract +fi +chmod ugo+x intltool-extract +chmod u+w intltool-extract + +sed -e "s:@INTLTOOL_PERL@:${INTLTOOL_PERL}:;" < ${srcdir}/intltool-merge.in > intltool-merge.out +if cmp -s intltool-merge intltool-merge.out 2>/dev/null; then + rm -f intltool-merge.out +else + mv -f intltool-merge.out intltool-merge +fi +chmod ugo+x intltool-merge +chmod u+w intltool-merge + +sed -e "s:@INTLTOOL_PERL@:${INTLTOOL_PERL}:;" < ${srcdir}/intltool-update.in > intltool-update.out +if cmp -s intltool-update intltool-update.out 2>/dev/null; then + rm -f intltool-update.out +else + mv -f intltool-update.out intltool-update +fi +chmod ugo+x intltool-update +chmod u+w intltool-update + +], INTLTOOL_PERL=${INTLTOOL_PERL}) + +]) + + +dnl PKG_CHECK_MODULES(GSTUFF, gtk+-2.0 >= 1.3 glib = 1.3.4, action-if, action-not) +dnl defines GSTUFF_LIBS, GSTUFF_CFLAGS, see pkg-config man page +dnl also defines GSTUFF_PKG_ERRORS on error +AC_DEFUN(PKG_CHECK_MODULES, [ + succeeded=no + + if test -z "$PKG_CONFIG"; then + AC_PATH_PROG(PKG_CONFIG, pkg-config, no) + fi + + if test "$PKG_CONFIG" = "no" ; then + echo "*** The pkg-config script could not be found. Make sure it is" + echo "*** in your path, or set the PKG_CONFIG environment variable" + echo "*** to the full path to pkg-config." + echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config." + else + PKG_CONFIG_MIN_VERSION=0.9.0 + if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then + AC_MSG_CHECKING(for $2) + + if $PKG_CONFIG --exists "$2" ; then + AC_MSG_RESULT(yes) + succeeded=yes + + AC_MSG_CHECKING($1_CFLAGS) + $1_CFLAGS=`$PKG_CONFIG --cflags "$2"` + AC_MSG_RESULT($$1_CFLAGS) + + AC_MSG_CHECKING($1_LIBS) + $1_LIBS=`$PKG_CONFIG --libs "$2"` + AC_MSG_RESULT($$1_LIBS) + else + $1_CFLAGS="" + $1_LIBS="" + ## If we have a custom action on failure, don't print errors, but + ## do set a variable so people can do so. + $1_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"` + ifelse([$4], ,echo $$1_PKG_ERRORS,) + fi + + AC_SUBST($1_CFLAGS) + AC_SUBST($1_LIBS) + else + echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer." + echo "*** See http://www.freedesktop.org/software/pkgconfig" + fi + fi + + if test $succeeded = yes; then + ifelse([$3], , :, [$3]) + else + ifelse([$4], , AC_MSG_ERROR([Library requirements ($2) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them.]), [$4]) + fi +]) + + + +dnl GNOME_COMPILE_WARNINGS +dnl Turn on many useful compiler warnings +dnl For now, only works on GCC +AC_DEFUN([GNOME_COMPILE_WARNINGS],[ + dnl ****************************** + dnl More compiler warnings + dnl ****************************** + + if test -z "$1" ; then + default_compile_warnings=yes + else + default_compile_warnings="$1" + fi + + AC_ARG_ENABLE(compile-warnings, + [ --enable-compile-warnings=[no/minimum/yes/maximum/error] Turn on compiler warnings.],, [enable_compile_warnings="$default_compile_warnings"]) + + warnCFLAGS= + if test "x$GCC" != xyes; then + enable_compile_warnings=no + fi + + warning_flags= + realsave_CFLAGS="$CFLAGS" + + case "$enable_compile_warnings" in + no) + warning_flags= + ;; + minimum) + warning_flags="-Wall" + ;; + yes) + warning_flags="-Wall -Wmissing-prototypes" + ;; + maximum|error) + warning_flags="-Wall -Wmissing-prototypes -Wnested-externs -Wpointer-arith" + CFLAGS="$warning_flags $CFLAGS" + for option in -Wno-sign-compare; do + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $option" + AC_MSG_CHECKING([whether gcc understands $option]) + AC_TRY_COMPILE([], [], + has_option=yes, + has_option=no,) + CFLAGS="$SAVE_CFLAGS" + AC_MSG_RESULT($has_option) + if test $has_option = yes; then + warning_flags="$warning_flags $option" + fi + unset has_option + unset SAVE_CFLAGS + done + unset option + if test "$enable_compile_warnings" = "error" ; then + warning_flags="$warning_flags -Werror" + fi + ;; + *) + AC_MSG_ERROR(Unknown argument '$enable_compile_warnings' to --enable-compile-warnings) + ;; + esac + CFLAGS="$realsave_CFLAGS" + AC_MSG_CHECKING(what warning flags to pass to the C compiler) + AC_MSG_RESULT($warning_flags) + + AC_ARG_ENABLE(iso-c, + [ --enable-iso-c Try to warn if code is not ISO C ],, + enable_iso_c=no) + + AC_MSG_CHECKING(what language compliance flags to pass to the C compiler) + complCFLAGS= + if test "x$enable_iso_c" != "xno"; then + if test "x$GCC" = "xyes"; then + case " $CFLAGS " in + *[\ \ ]-ansi[\ \ ]*) ;; + *) complCFLAGS="$complCFLAGS -ansi" ;; + esac + case " $CFLAGS " in + *[\ \ ]-pedantic[\ \ ]*) ;; + *) complCFLAGS="$complCFLAGS -pedantic" ;; + esac + fi + fi + AC_MSG_RESULT($complCFLAGS) + + WARN_CFLAGS="$warning_flags $complCFLAGS" + AC_SUBST(WARN_CFLAGS) +]) + +dnl For C++, do basically the same thing. + +AC_DEFUN([GNOME_CXX_WARNINGS],[ + AC_ARG_ENABLE(cxx-warnings, + [ --enable-cxx-warnings=[no/minimum/yes] Turn on compiler warnings.],,enable_cxx_warnings=minimum) + + AC_MSG_CHECKING(what warning flags to pass to the C++ compiler) + warnCXXFLAGS= + if test "x$GCC" != xyes; then + enable_compile_warnings=no + fi + if test "x$enable_cxx_warnings" != "xno"; then + if test "x$GCC" = "xyes"; then + case " $CXXFLAGS " in + *[\ \ ]-Wall[\ \ ]*) ;; + *) warnCXXFLAGS="-Wall -Wno-unused" ;; + esac + + ## -W is not all that useful. And it cannot be controlled + ## with individual -Wno-xxx flags, unlike -Wall + if test "x$enable_cxx_warnings" = "xyes"; then + warnCXXFLAGS="$warnCXXFLAGS -Wmissing-declarations -Wshadow -Woverloaded-virtual" + fi + fi + fi + AC_MSG_RESULT($warnCXXFLAGS) + + AC_ARG_ENABLE(iso-cxx, + [ --enable-iso-cxx Try to warn if code is not ISO C++ ],, + enable_iso_cxx=no) + + AC_MSG_CHECKING(what language compliance flags to pass to the C++ compiler) + complCXXFLAGS= + if test "x$enable_iso_cxx" != "xno"; then + if test "x$GCC" = "xyes"; then + case " $CXXFLAGS " in + *[\ \ ]-ansi[\ \ ]*) ;; + *) complCXXFLAGS="$complCXXFLAGS -ansi" ;; + esac + + case " $CXXFLAGS " in + *[\ \ ]-pedantic[\ \ ]*) ;; + *) complCXXFLAGS="$complCXXFLAGS -pedantic" ;; + esac + fi + fi + AC_MSG_RESULT($complCXXFLAGS) + if test "x$cxxflags_set" != "xyes"; then + CXXFLAGS="$CXXFLAGS $warnCXXFLAGS $complCXXFLAGS" + cxxflags_set=yes + AC_SUBST(cxxflags_set) + fi +]) + +# Copyright (C) 1995-2002 Free Software Foundation, Inc. +# Copyright (C) 2001-2003 Red Hat, Inc. +# +# This file is free software, distributed under the terms of the GNU +# General Public License. As a special exception to the GNU General +# Public License, this file may be distributed as part of a program +# that contains a configuration script generated by Autoconf, under +# the same distribution terms as the rest of that program. +# +# This file can be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU Public License +# but which still want to provide support for the GNU gettext functionality. +# +# Macro to add for using GNU gettext. +# Ulrich Drepper , 1995, 1996 +# +# Modified to never use included libintl. +# Owen Taylor , 12/15/1998 +# +# Major rework to remove unused code +# Owen Taylor , 12/11/2002 +# +# Added better handling of ALL_LINGUAS from GNU gettext version +# written by Bruno Haible, Owen Taylor 5/30/3002 + +# +# We need this here as well, since someone might use autoconf-2.5x +# to configure GLib then an older version to configure a package +# using AM_GLIB_GNU_GETTEXT +AC_PREREQ(2.53) + +dnl +dnl We go to great lengths to make sure that aclocal won't +dnl try to pull in the installed version of these macros +dnl when running aclocal in the glib directory. +dnl +m4_copy([AC_DEFUN],[glib_DEFUN]) +m4_copy([AC_REQUIRE],[glib_REQUIRE]) +dnl +dnl At the end, if we're not within glib, we'll define the public +dnl definitions in terms of our private definitions. +dnl + +# GLIB_LC_MESSAGES +#-------------------- +glib_DEFUN([GLIB_LC_MESSAGES], + [AC_CHECK_HEADERS([locale.h]) + if test $ac_cv_header_locale_h = yes; then + AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES, + [AC_TRY_LINK([#include ], [return LC_MESSAGES], + am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)]) + if test $am_cv_val_LC_MESSAGES = yes; then + AC_DEFINE(HAVE_LC_MESSAGES, 1, + [Define if your file defines LC_MESSAGES.]) + fi + fi]) + +# GLIB_PATH_PROG_WITH_TEST +#---------------------------- +dnl GLIB_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, +dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) +glib_DEFUN([GLIB_PATH_PROG_WITH_TEST], +[# Extract the first word of "$2", so it can be a program name with args. +set dummy $2; ac_word=[$]2 +AC_MSG_CHECKING([for $ac_word]) +AC_CACHE_VAL(ac_cv_path_$1, +[case "[$]$1" in + /*) + ac_cv_path_$1="[$]$1" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in ifelse([$5], , $PATH, [$5]); do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if [$3]; then + ac_cv_path_$1="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" +dnl If no 4th arg is given, leave the cache variable unset, +dnl so AC_PATH_PROGS will keep looking. +ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" +])dnl + ;; +esac])dnl +$1="$ac_cv_path_$1" +if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then + AC_MSG_RESULT([$]$1) +else + AC_MSG_RESULT(no) +fi +AC_SUBST($1)dnl +]) + +# GLIB_WITH_NLS +#----------------- +glib_DEFUN([GLIB_WITH_NLS], + dnl NLS is obligatory + [USE_NLS=yes + AC_SUBST(USE_NLS) + + gt_cv_have_gettext=no + + CATOBJEXT=NONE + XGETTEXT=: + INTLLIBS= + + AC_CHECK_HEADER(libintl.h, + [gt_cv_func_dgettext_libintl="no" + libintl_extra_libs="" + + # + # First check in libc + # + AC_CACHE_CHECK([for dgettext in libc], gt_cv_func_dgettext_libc, + [AC_TRY_LINK([ +#include +], + [return (int) dgettext ("","")], + gt_cv_func_dgettext_libc=yes, + gt_cv_func_dgettext_libc=no) + ]) + + if test "$gt_cv_func_dgettext_libc" = "yes" ; then + AC_CHECK_FUNCS(bind_textdomain_codeset) + fi + + # + # If we don't have everything we want, check in libintl + # + if test "$gt_cv_func_dgettext_libc" != "yes" \ + || test "$ac_cv_func_bind_textdomain_codeset" != "yes" ; then + + AC_CHECK_LIB(intl, bindtextdomain, + [AC_CHECK_LIB(intl, dgettext, + gt_cv_func_dgettext_libintl=yes)]) + + if test "$gt_cv_func_dgettext_libintl" != "yes" ; then + AC_MSG_CHECKING([if -liconv is needed to use gettext]) + AC_MSG_RESULT([]) + AC_CHECK_LIB(intl, dcgettext, + [gt_cv_func_dgettext_libintl=yes + libintl_extra_libs=-liconv], + :,-liconv) + fi + + # + # If we found libintl, then check in it for bind_textdomain_codeset(); + # we'll prefer libc if neither have bind_textdomain_codeset(), + # and both have dgettext + # + if test "$gt_cv_func_dgettext_libintl" = "yes" ; then + glib_save_LIBS="$LIBS" + LIBS="$LIBS -lintl $libintl_extra_libs" + unset ac_cv_func_bind_textdomain_codeset + AC_CHECK_FUNCS(bind_textdomain_codeset) + LIBS="$glib_save_LIBS" + + if test "$ac_cv_func_bind_textdomain_codeset" = "yes" ; then + gt_cv_func_dgettext_libc=no + else + if test "$gt_cv_func_dgettext_libc" = "yes"; then + gt_cv_func_dgettext_libintl=no + fi + fi + fi + fi + + if test "$gt_cv_func_dgettext_libc" = "yes" \ + || test "$gt_cv_func_dgettext_libintl" = "yes"; then + gt_cv_have_gettext=yes + fi + + if test "$gt_cv_func_dgettext_libintl" = "yes"; then + INTLLIBS="-lintl $libintl_extra_libs" + fi + + if test "$gt_cv_have_gettext" = "yes"; then + AC_DEFINE(HAVE_GETTEXT,1, + [Define if the GNU gettext() function is already present or preinstalled.]) + GLIB_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl + if test "$MSGFMT" != "no"; then + AC_CHECK_FUNCS(dcgettext) + AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) + GLIB_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) + AC_TRY_LINK(, [extern int _nl_msg_cat_cntr; + return _nl_msg_cat_cntr], + [CATOBJEXT=.gmo + DATADIRNAME=share], + [case $host in + *-*-solaris*) + dnl On Solaris, if bind_textdomain_codeset is in libc, + dnl GNU format message catalog is always supported, + dnl since both are added to the libc all together. + dnl Hence, we'd like to go with DATADIRNAME=share and + dnl and CATOBJEXT=.gmo in this case. + AC_CHECK_FUNC(bind_textdomain_codeset, + [CATOBJEXT=.gmo + DATADIRNAME=share], + [CATOBJEXT=.mo + DATADIRNAME=lib]) + ;; + *) + CATOBJEXT=.mo + DATADIRNAME=lib + ;; + esac]) + INSTOBJEXT=.mo + else + gt_cv_have_gettext=no + fi + fi + ]) + + if test "$gt_cv_have_gettext" = "yes" ; then + AC_DEFINE(ENABLE_NLS, 1, + [always defined to indicate that i18n is enabled]) + fi + + dnl Test whether we really found GNU xgettext. + if test "$XGETTEXT" != ":"; then + dnl If it is not GNU xgettext we define it as : so that the + dnl Makefiles still can work. + if $XGETTEXT --omit-header /dev/null 2> /dev/null; then + : ; + else + AC_MSG_RESULT( + [found xgettext program is not GNU xgettext; ignore it]) + XGETTEXT=":" + fi + fi + + # We need to process the po/ directory. + POSUB=po + + AC_OUTPUT_COMMANDS( + [case "$CONFIG_FILES" in *po/Makefile.in*) + sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile + esac]) + + dnl These rules are solely for the distribution goal. While doing this + dnl we only have to keep exactly one list of the available catalogs + dnl in configure.in. + for lang in $ALL_LINGUAS; do + GMOFILES="$GMOFILES $lang.gmo" + POFILES="$POFILES $lang.po" + done + + dnl Make all variables we use known to autoconf. + AC_SUBST(CATALOGS) + AC_SUBST(CATOBJEXT) + AC_SUBST(DATADIRNAME) + AC_SUBST(GMOFILES) + AC_SUBST(INSTOBJEXT) + AC_SUBST(INTLLIBS) + AC_SUBST(PO_IN_DATADIR_TRUE) + AC_SUBST(PO_IN_DATADIR_FALSE) + AC_SUBST(POFILES) + AC_SUBST(POSUB) + ]) + +# AM_GLIB_GNU_GETTEXT +# ------------------- +# Do checks necessary for use of gettext. If a suitable implementation +# of gettext is found in either in libintl or in the C library, +# it will set INTLLIBS to the libraries needed for use of gettext +# and AC_DEFINE() HAVE_GETTEXT and ENABLE_NLS. (The shell variable +# gt_cv_have_gettext will be set to "yes".) It will also call AC_SUBST() +# on various variables needed by the Makefile.in.in installed by +# glib-gettextize. +dnl +glib_DEFUN(GLIB_GNU_GETTEXT, + [AC_REQUIRE([AC_PROG_CC])dnl + AC_REQUIRE([AC_HEADER_STDC])dnl + + GLIB_LC_MESSAGES + GLIB_WITH_NLS + + if test "$gt_cv_have_gettext" = "yes"; then + if test "x$ALL_LINGUAS" = "x"; then + LINGUAS= + else + AC_MSG_CHECKING(for catalogs to be installed) + NEW_LINGUAS= + for presentlang in $ALL_LINGUAS; do + useit=no + if test "%UNSET%" != "${LINGUAS-%UNSET%}"; then + desiredlanguages="$LINGUAS" + else + desiredlanguages="$ALL_LINGUAS" + fi + for desiredlang in $desiredlanguages; do + # Use the presentlang catalog if desiredlang is + # a. equal to presentlang, or + # b. a variant of presentlang (because in this case, + # presentlang can be used as a fallback for messages + # which are not translated in the desiredlang catalog). + case "$desiredlang" in + "$presentlang"*) useit=yes;; + esac + done + if test $useit = yes; then + NEW_LINGUAS="$NEW_LINGUAS $presentlang" + fi + done + LINGUAS=$NEW_LINGUAS + AC_MSG_RESULT($LINGUAS) + fi + + dnl Construct list of names of catalog files to be constructed. + if test -n "$LINGUAS"; then + for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done + fi + fi + + dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly + dnl find the mkinstalldirs script in another subdir but ($top_srcdir). + dnl Try to locate is. + MKINSTALLDIRS= + if test -n "$ac_aux_dir"; then + MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" + fi + if test -z "$MKINSTALLDIRS"; then + MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" + fi + AC_SUBST(MKINSTALLDIRS) + + dnl Generate list of files to be processed by xgettext which will + dnl be included in po/Makefile. + test -d po || mkdir po + if test "x$srcdir" != "x."; then + if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then + posrcprefix="$srcdir/" + else + posrcprefix="../$srcdir/" + fi + else + posrcprefix="../" + fi + rm -f po/POTFILES + sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \ + < $srcdir/po/POTFILES.in > po/POTFILES + ]) + +# AM_GLIB_DEFINE_LOCALEDIR(VARIABLE) +# ------------------------------- +# Define VARIABLE to the location where catalog files will +# be installed by po/Makefile. +glib_DEFUN(GLIB_DEFINE_LOCALEDIR, +[glib_REQUIRE([GLIB_GNU_GETTEXT])dnl +glib_save_prefix="$prefix" +glib_save_exec_prefix="$exec_prefix" +test "x$prefix" = xNONE && prefix=$ac_default_prefix +test "x$exec_prefix" = xNONE && exec_prefix=$prefix +if test "x$CATOBJEXT" = "x.mo" ; then + localedir=`eval echo "${libdir}/locale"` +else + localedir=`eval echo "${datadir}/locale"` +fi +prefix="$glib_save_prefix" +exec_prefix="$glib_save_exec_prefix" +AC_DEFINE_UNQUOTED($1, "$localedir", + [Define the location where the catalogs will be installed]) +]) + +dnl +dnl Now the definitions that aclocal will find +dnl +ifdef(glib_configure_in,[],[ +AC_DEFUN(AM_GLIB_GNU_GETTEXT,[GLIB_GNU_GETTEXT($@)]) +AC_DEFUN(AM_GLIB_DEFINE_LOCALEDIR,[GLIB_DEFINE_LOCALEDIR($@)]) +])dnl + +dnl AM_GCONF_SOURCE_2 +dnl Defines GCONF_SCHEMA_CONFIG_SOURCE which is where you should install schemas +dnl (i.e. pass to gconftool-2 +dnl Defines GCONF_SCHEMA_FILE_DIR which is a filesystem directory where +dnl you should install foo.schemas files +dnl + +AC_DEFUN(AM_GCONF_SOURCE_2, +[ + if test "x$GCONF_SCHEMA_INSTALL_SOURCE" = "x"; then + GCONF_SCHEMA_CONFIG_SOURCE=`gconftool-2 --get-default-source` + else + GCONF_SCHEMA_CONFIG_SOURCE=$GCONF_SCHEMA_INSTALL_SOURCE + fi + + AC_ARG_WITH(gconf-source, + [ --with-gconf-source=sourceaddress Config database for installing schema files.],GCONF_SCHEMA_CONFIG_SOURCE="$withval",) + + AC_SUBST(GCONF_SCHEMA_CONFIG_SOURCE) + AC_MSG_RESULT([Using config source $GCONF_SCHEMA_CONFIG_SOURCE for schema installation]) + + if test "x$GCONF_SCHEMA_FILE_DIR" = "x"; then + GCONF_SCHEMA_FILE_DIR='$(sysconfdir)/gconf/schemas/' + else + GCONF_SCHEMA_FILE_DIR=$GCONF_SCHEMA_FILE_DIR + fi + + AC_ARG_WITH(gconf-schema-file-dir, + [ --with-gconf-schema-file-dir=dir Directory for installing schema files.],GCONF_SCHEMA_FILE_DIR="$withval",) + + AC_SUBST(GCONF_SCHEMA_FILE_DIR) + AC_MSG_RESULT([Using $GCONF_SCHEMA_FILE_DIR as install directory for schema files]) + + AC_ARG_ENABLE(schemas-install, + [ --disable-schemas-install Disable the schemas installation], + [case "${enableval}" in + yes) schemas_install=true ;; + no) schemas_install=false ;; + *) AC_MSG_ERROR(bad value ${enableval} for --disable-schemas-install) ;; + esac],[schemas_install=true]) + AM_CONDITIONAL(GCONF_SCHEMAS_INSTALL, test x$schemas_install = xtrue) +]) + diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..08f51a4 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,21 @@ +#!/bin/sh +# Run this to generate all the initial makefiles, etc. + +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +PKG_NAME="GNOME VFS" + +(test -f $srcdir/configure.in \ + && test -f $srcdir/HACKING \ + && test -d $srcdir/libgnomevfs) || { + echo -n "**Error**: Directory "\`$srcdir\'" does not look like the" + echo " top-level $PKG_NAME directory" + exit 1 +} + +which gnome-autogen.sh || { + echo "You need to install gnome-common from the GNOME CVS" + exit 1 +} +USE_GNOME2_MACROS=1 . gnome-autogen.sh diff --git a/config.guess b/config.guess new file mode 100755 index 0000000..78f6b92 --- /dev/null +++ b/config.guess @@ -0,0 +1,1409 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + +timestamp='2003-01-10' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit 0 ;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + macppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvmeppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mipseb-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sun3:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:MicroBSD:*:*) + echo ${UNAME_MACHINE}-unknown-microbsd${UNAME_RELEASE} + exit 0 ;; + alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + eval $set_cc_for_build + cat <$dummy.s + .data +\$Lformat: + .byte 37,100,45,37,120,10,0 # "%d-%x\n" + + .text + .globl main + .align 4 + .ent main +main: + .frame \$30,16,\$26,0 + ldgp \$29,0(\$27) + .prologue 1 + .long 0x47e03d80 # implver \$0 + lda \$2,-1 + .long 0x47e20c21 # amask \$2,\$1 + lda \$16,\$Lformat + mov \$0,\$17 + not \$1,\$18 + jsr \$26,printf + ldgp \$29,0(\$26) + mov 0,\$16 + jsr \$26,exit + .end main +EOF + $CC_FOR_BUILD -o $dummy $dummy.s 2>/dev/null + if test "$?" = 0 ; then + case `$dummy` in + 0-0) + UNAME_MACHINE="alpha" + ;; + 1-0) + UNAME_MACHINE="alphaev5" + ;; + 1-1) + UNAME_MACHINE="alphaev56" + ;; + 1-101) + UNAME_MACHINE="alphapca56" + ;; + 2-303) + UNAME_MACHINE="alphaev6" + ;; + 2-307) + UNAME_MACHINE="alphaev67" + ;; + 2-1307) + UNAME_MACHINE="alphaev68" + ;; + 3-1307) + UNAME_MACHINE="alphaev7" + ;; + esac + fi + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit 0;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + DRS?6000:UNIX_SV:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7 && exit 0 ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c \ + && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && exit 0 + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit 0 ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + # avoid double evaluation of $set_cc_for_build + test -n "$CC_FOR_BUILD" || eval $set_cc_for_build + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + *:UNICOS/mp:*:*) + echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + # Determine whether the default compiler uses glibc. + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #if __GLIBC__ >= 2 + LIBC=gnu + #else + LIBC= + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC} + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit 0 ;; + x86:Interix*:3*) + echo i586-pc-interix3 + exit 0 ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit 0 ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 + ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit 0 ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit 0 ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit 0 ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit 0 ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit 0 ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit 0 ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit 0 ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit 0 ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #ifdef __INTEL_COMPILER + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 + test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit 0 ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit 0 ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit 0 ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit 0 ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit 0 ;; + i*86:*:5:[78]*) + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit 0 ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit 0 ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit 0 ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + case `uname -p` in + *86) UNAME_PROCESSOR=i686 ;; + powerpc) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit 0 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit 0 ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit 0 ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit 0 ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit 0 ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit 0 ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0 + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..490db3a --- /dev/null +++ b/config.h.in @@ -0,0 +1,238 @@ +/* config.h.in. Generated from configure.in by autoheader. */ +#undef PACKAGE +#undef VERSION +#undef HAVE_LIBSM +#undef HAVE_CATGETS +#undef HAVE_GETTEXT +#undef HAVE_LC_MESSAGES +#undef HAVE_STPCPY +#undef ENABLE_NLS +#undef USE_PTHREAD +#undef HAVE_SOCKET +#undef HAVE_STRUCT_LINGER +#undef HAVE_NSL +#undef HAVE_OLDER_BZIP2 +#undef GNOME_PLATFORM_VERSION +#undef ENABLE_PROFILER +#undef HAVE_OPENSSL +#undef HAVE_FAM +#undef HAVE_OFF64_T +#undef GETTEXT_PACKAGE + +/* Define if you have the Andrew File System. */ +#undef AFS + +/* Define to use SVR4 statvfs to get filesystem type. */ +#undef FSTYPE_STATVFS + +/* Define to use SVR3.2 statfs to get filesystem type. */ +#undef FSTYPE_USG_STATFS + +/* Define to use AIX3 statfs to get filesystem type. */ +#undef FSTYPE_AIX_STATFS + +/* Define to use 4.3BSD getmntent to get filesystem type. */ +#undef FSTYPE_MNTENT + +/* Define to use 4.4BSD and OSF1 statfs to get filesystem type. */ +#undef FSTYPE_STATFS + +/* Define to use Ultrix getmnt to get filesystem type. */ +#undef FSTYPE_GETMNT + +#undef HAVE_GNUTLS +#undef ENABLE_IPV6 + +/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP + systems. This function is required for `alloca.c' support on those systems. + */ +#undef CRAY_STACKSEG_END + +/* Define to 1 if using `alloca.c'. */ +#undef C_ALLOCA + +/* always defined to indicate that i18n is enabled */ +#undef ENABLE_NLS + +/* Define to 1 if you have `alloca', as a function or macro. */ +#undef HAVE_ALLOCA + +/* Define to 1 if you have and it should be used (not on Ultrix). + */ +#undef HAVE_ALLOCA_H + +/* Define to 1 if you have the `bind_textdomain_codeset' function. */ +#undef HAVE_BIND_TEXTDOMAIN_CODESET + +/* Define to 1 if you have the header file. */ +#undef HAVE_BZLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_CDDA_INTERFACE_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_CDDA_PARANOIA_H + +/* Define to 1 if you have the `dcgettext' function. */ +#undef HAVE_DCGETTEXT + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_FAM_H + +/* Define to 1 if you have the `getdelim' function. */ +#undef HAVE_GETDELIM + +/* Define to 1 if you have the `getdtablesize' function. */ +#undef HAVE_GETDTABLESIZE + +/* Define if the GNU gettext() function is already present or preinstalled. */ +#undef HAVE_GETTEXT + +/* Define to 1 if you have the `inet_pton' function. */ +#undef HAVE_INET_PTON + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define if your file defines LC_MESSAGES. */ +#undef HAVE_LC_MESSAGES + +/* Define to 1 if you have the `nsl' library (-lnsl). */ +#undef HAVE_LIBNSL + +/* Define to 1 if you have the `rt' library (-lrt). */ +#undef HAVE_LIBRT + +/* Define to 1 if you have the `socket' library (-lsocket). */ +#undef HAVE_LIBSOCKET + +/* Define to 1 if you have the header file. */ +#undef HAVE_LOCALE_H + +/* Define to 1 if you have the `lseek64' function. */ +#undef HAVE_LSEEK64 + +/* Define to 1 if you have the `mbrtowc' function. */ +#undef HAVE_MBRTOWC + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `open64' function. */ +#undef HAVE_OPEN64 + +/* Define to 1 if you have the header file. */ +#undef HAVE_OPENSSL_SSL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_OPENSSL_X509_H + +/* Define to 1 if you have the `readdir_r' function. */ +#undef HAVE_READDIR_R + +/* Define to 1 if you have the `setegid' function. */ +#undef HAVE_SETEGID + +/* Define to 1 if you have the `seteuid' function. */ +#undef HAVE_SETEUID + +/* Define to 1 if you have the `setresgid' function. */ +#undef HAVE_SETRESGID + +/* Define to 1 if you have the `setresuid' function. */ +#undef HAVE_SETRESUID + +/* Define to 1 if you have the `socket' function. */ +#undef HAVE_SOCKET + +/* Define to 1 if you have the `statvfs' function. */ +#undef HAVE_STATVFS + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_MOUNT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_PARAM_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_RESOURCE_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STATVFS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_VFS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_WCTYPE_H + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* The size of a `int', as computed by sizeof. */ +#undef SIZEOF_INT + +/* The size of a `long', as computed by sizeof. */ +#undef SIZEOF_LONG + +/* The size of a `long long', as computed by sizeof. */ +#undef SIZEOF_LONG_LONG + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at run-time. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ +#undef STACK_DIRECTION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION + +/* off_t */ +#undef off_t + +/* size_t */ +#undef size_t diff --git a/config.sub b/config.sub new file mode 100755 index 0000000..d6d67c3 --- /dev/null +++ b/config.sub @@ -0,0 +1,1469 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + +timestamp='2003-01-03' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit 0;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | freebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k \ + | m32r | m68000 | m68k | m88k | mcore \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | msp430 \ + | ns16k | ns32k \ + | openrisc | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | s390 | s390x \ + | sh | sh[1234] | sh3e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* \ + | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* \ + | clipper-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* \ + | m32r-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | msp430-* \ + | none-* | np1-* | nv1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | s390-* | s390x-* \ + | sh-* | sh[1234]-* | sh3e-* | sh[34]eb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ + | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* | tic30-* | tic4x-* | tic54x-* | tic80-* | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ + | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + mmix*) + basic_machine=mmix-knuth + os=-mmixware + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nv1) + basic_machine=nv1-cray + os=-unicosmp + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + or32 | or32-*) + basic_machine=or32-unknown + os=-coff + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2) + basic_machine=i686-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic4x | c4x*) + basic_machine=tic4x-unknown + os=-coff + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh3 | sh4 | sh3eb | sh4eb | sh[1234]le | sh3ele) + basic_machine=sh-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparc | sparcv9 | sparcv9b) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -microbsd*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/configure b/configure new file mode 100755 index 0000000..9548522 --- /dev/null +++ b/configure @@ -0,0 +1,16861 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.57. +# +# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 +# Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi + +# Support unset when possible. +if (FOO=FOO; unset FOO) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + + +# Find the correct PATH separator. Usually this is `:', but +# DJGPP uses `;' like DOS. +if test "X${PATH_SEPARATOR+set}" != Xset; then + UNAME=${UNAME-`uname 2>/dev/null`} + case X$UNAME in + *-DOS) lt_cv_sys_path_separator=';' ;; + *) lt_cv_sys_path_separator=':' ;; + esac + PATH_SEPARATOR=$lt_cv_sys_path_separator +fi + + +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} + +case X$ECHO in +X*--fallback-echo) + # Remove one level of quotation (which was required for Make). + ECHO=`echo "$ECHO" | sed 's,\\\\\$\\$0,'$0','` + ;; +esac + +echo=${ECHO-echo} +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : +else + # Restart under the correct shell. + exec $SHELL "$0" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat </dev/null && + echo_test_string="`eval $cmd`" && + (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null + then + break + fi + done +fi + +if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + : +else + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + IFS="${IFS= }"; save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for dir in $PATH /usr/ucb; do + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$dir/echo" + break + fi + done + IFS="$save_ifs" + + if test "X$echo" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + echo='print -r' + elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running configure again with it. + ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} + else + # Try using printf. + echo='printf %s\n' + if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # Cool, printf works + : + elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + echo="$CONFIG_SHELL $0 --fallback-echo" + elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$CONFIG_SHELL $0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do + if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null + then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "$0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} + else + # Oops. We lost completely, so just stick with echo. + echo=echo + fi + fi + fi + fi +fi +fi + +# Copy echo and quote the copy suitably for passing to libtool from +# the Makefile, instead of quoting the original, which is used later. +ECHO=$echo +if test "X$ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then + ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" +fi + + + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +exec 6>&1 + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_config_libobj_dir=. +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Maximum number of lines to put in a shell here document. +# This variable seems obsolete. It should probably be removed, and +# only ac_max_sed_lines should be used. +: ${ac_max_here_lines=38} + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= + +ac_unique_file="libgnomevfs/gnome-vfs.h" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#if HAVE_SYS_TYPES_H +# include +#endif +#if HAVE_SYS_STAT_H +# include +#endif +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +#endif +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include +# endif +# include +#endif +#if HAVE_STRINGS_H +# include +#endif +#if HAVE_INTTYPES_H +# include +#else +# if HAVE_STDINT_H +# include +# endif +#endif +#if HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS LIBGNOMEVFS_CURRENT LIBGNOMEVFS_REVISION LIBGNOMEVFS_AGE INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO SET_MAKE ACLOCAL_AMFLAGS MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT GNOME_ACLOCAL_DIR GNOME_ACLOCAL_FLAGS INSIDE_GNOME_DOCU_TRUE INSIDE_GNOME_DOCU_FALSE CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP AWK build build_cpu build_vendor build_os host host_cpu host_vendor host_os LN_S ECHO RANLIB ac_ct_RANLIB STRIP ac_ct_STRIP EGREP LIBTOOL INTLTOOL_DESKTOP_RULE INTLTOOL_DIRECTORY_RULE INTLTOOL_KEYS_RULE INTLTOOL_PROP_RULE INTLTOOL_OAF_RULE INTLTOOL_PONG_RULE INTLTOOL_SERVER_RULE INTLTOOL_SHEET_RULE INTLTOOL_SOUNDLIST_RULE INTLTOOL_UI_RULE INTLTOOL_XML_RULE INTLTOOL_CAVES_RULE INTLTOOL_SCHEMAS_RULE INTLTOOL_THEME_RULE INTLTOOL_EXTRACT INTLTOOL_MERGE INTLTOOL_UPDATE INTLTOOL_PERL BONOBO_ACTIVATION_REQUIRED BONOBO_REQUIRED GCONF_REQUIRED GLIB_REQUIRED LIBIDL_REQUIRED ORBIT_REQUIRED XML_REQUIRED PKG_CONFIG MODULES_XML_CFLAGS MODULES_XML_LIBS MODULES_CFLAGS MODULES_LIBS MODULES_FILE_CFLAGS MODULES_FILE_LIBS MODULES_GCONF_CFLAGS MODULES_GCONF_LIBS MODULES_XML_GCONF_CFLAGS MODULES_XML_GCONF_LIBS MONIKERS_CFLAGS MONIKERS_LIBS TEST_CFLAGS TEST_LIBS ORBIT_IDL BONOBO_IDLDIR WARN_CFLAGS GETTEXT_PACKAGE USE_NLS MSGFMT GMSGFMT XGETTEXT CATALOGS CATOBJEXT DATADIRNAME GMOFILES INSTOBJEXT INTLLIBS PO_IN_DATADIR_TRUE PO_IN_DATADIR_FALSE POFILES POSUB MKINSTALLDIRS ALLOCA GCONFTOOL GCONF_SCHEMA_CONFIG_SOURCE GCONF_SCHEMA_FILE_DIR GCONF_SCHEMAS_INSTALL_TRUE GCONF_SCHEMAS_INSTALL_FALSE VFS_SIZE VFS_OFFSET VFS_SIZE_IS VFS_OFFSET_IS VFS_SIZE_PRINTF VFS_OFFSET_PRINTF ENABLE_PROFILER ENABLE_PROFILER_TRUE ENABLE_PROFILER_FALSE VFS_CFLAGS GNOME_VFS_DIR VFS_LIBDIR VFS_INCLUDEDIR VFS_LIBS HAVE_LIBEFS_TRUE HAVE_LIBEFS_FALSE LIBEFS_LIBS LIBEFS_CFLAGS BZ2_LIBS HAVE_CDDA_TRUE HAVE_CDDA_FALSE BUILD_CDEMENU_MODULE_TRUE BUILD_CDEMENU_MODULE_FALSE HAVE_SSL_TRUE HAVE_SSL_FALSE OPENSSL_CFLAGS OPENSSL_LIBS LIBGNUTLS_CONFIG LIBGNUTLS_CFLAGS LIBGNUTLS_LIBS LIBGNOMEVFS_CFLAGS LIBGNOMEVFS_LIBS FAM_LIBS HTML_DIR GTKDOC DB2HTML HAVE_DOCBOOK_TRUE HAVE_DOCBOOK_FALSE HAVE_GTK_DOC_TRUE HAVE_GTK_DOC_FALSE HAVE_GTK_DOC ENABLE_GTK_DOC_TRUE ENABLE_GTK_DOC_FALSE POPT_LIBS TOP_BUILDDIR LIBOBJS LTLIBOBJS' +ac_subst_files='' + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +ac_prev= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_option in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + eval "enable_$ac_feature=no" ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "enable_$ac_feature='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package| sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "with_$ac_package='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/-/_/g'` + eval "with_$ac_package=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` + eval "$ac_envvar='$ac_optarg'" + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute paths. +for ac_var in exec_prefix prefix +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* | NONE | '' ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# Be sure to have absolute paths. +for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ + localstatedir libdir includedir oldincludedir infodir mandir +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_confdir=`(dirname "$0") 2>/dev/null || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 + { (exit 1); exit 1; }; } + else + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } + fi +fi +(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || + { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 + { (exit 1); exit 1; }; } +srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` +ac_env_build_alias_set=${build_alias+set} +ac_env_build_alias_value=$build_alias +ac_cv_env_build_alias_set=${build_alias+set} +ac_cv_env_build_alias_value=$build_alias +ac_env_host_alias_set=${host_alias+set} +ac_env_host_alias_value=$host_alias +ac_cv_env_host_alias_set=${host_alias+set} +ac_cv_env_host_alias_value=$host_alias +ac_env_target_alias_set=${target_alias+set} +ac_env_target_alias_value=$target_alias +ac_cv_env_target_alias_set=${target_alias+set} +ac_cv_env_target_alias_value=$target_alias +ac_env_CC_set=${CC+set} +ac_env_CC_value=$CC +ac_cv_env_CC_set=${CC+set} +ac_cv_env_CC_value=$CC +ac_env_CFLAGS_set=${CFLAGS+set} +ac_env_CFLAGS_value=$CFLAGS +ac_cv_env_CFLAGS_set=${CFLAGS+set} +ac_cv_env_CFLAGS_value=$CFLAGS +ac_env_LDFLAGS_set=${LDFLAGS+set} +ac_env_LDFLAGS_value=$LDFLAGS +ac_cv_env_LDFLAGS_set=${LDFLAGS+set} +ac_cv_env_LDFLAGS_value=$LDFLAGS +ac_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_env_CPPFLAGS_value=$CPPFLAGS +ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_cv_env_CPPFLAGS_value=$CPPFLAGS +ac_env_CPP_set=${CPP+set} +ac_env_CPP_value=$CPP +ac_cv_env_CPP_set=${CPP+set} +ac_cv_env_CPP_value=$CPP + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +_ACEOF + + cat <<_ACEOF +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data [PREFIX/share] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --infodir=DIR info documentation [PREFIX/info] + --mandir=DIR man documentation [PREFIX/man] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer + --enable-shared=PKGS build shared libraries default=yes + --enable-static=PKGS build static libraries default=yes + --enable-fast-install=PKGS optimize for fast installation default=yes + --disable-libtool-lock avoid locking (might break parallel builds) + --enable-compile-warnings=no/minimum/yes/maximum/error Turn on compiler warnings. + --enable-iso-c Try to warn if code is not ISO C + --disable-schemas-install Disable the schemas installation + --enable-profiler Enable profiler + --enable-more-warnings Maximum compiler warnings + --disable-openssl build without openssl support + --enable-gnutls build with gnutls support + --enable-gtk-doc Use gtk-doc to build documentation default=auto + --enable-ipv6 enable IPv6 extensions + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-gnu-ld assume the C compiler uses GNU ld default=no + --with-pic try to use only PIC/non-PIC objects default=use both + --with-gconf-source=sourceaddress Config database for installing schema files. + --with-gconf-schema-file-dir=dir Directory for installing schema files. + --with-openssl-includes=PREFIX Location of OpenSSL includes. + --with-openssl-libs=PREFIX Location of OpenSSL libs. + --with-libgnutls-prefix=PFX Prefix where libgnutls is installed (optional) + --with-html-dir=PATH path to installed docs + --with-afs support -fstype afs + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have + headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +_ACEOF +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + ac_popdir=`pwd` + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d $ac_dir || continue + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac +# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be +# absolute. +ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` +ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` +ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` +ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` + + cd $ac_dir + # Check for guested configure; otherwise get Cygnus style configure. + if test -f $ac_srcdir/configure.gnu; then + echo + $SHELL $ac_srcdir/configure.gnu --help=recursive + elif test -f $ac_srcdir/configure; then + echo + $SHELL $ac_srcdir/configure --help=recursive + elif test -f $ac_srcdir/configure.ac || + test -f $ac_srcdir/configure.in; then + echo + $ac_configure --help + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi + cd $ac_popdir + done +fi + +test -n "$ac_init_help" && exit 0 +if $ac_init_version; then + cat <<\_ACEOF + +Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 +Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit 0 +fi +exec 5>config.log +cat >&5 <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.57. Invocation command line was + + $ $0 $@ + +_ACEOF +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +hostinfo = `(hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_sep= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" + # Get rid of the leading space. + ac_sep=" " + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Be sure not to use single quotes in there, as some shells, +# such as our DU 5.0 friend, will then `close' the trap. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +{ + (set) 2>&1 | + case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in + *ac_space=\ *) + sed -n \ + "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" + ;; + *) + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------- ## +## Output files. ## +## ------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + sed "/^$/d" confdefs.h | sort + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core core.* *.core && + rm -rf conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status + ' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo >confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . $cache_file;; + *) . ./$cache_file;; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in `(set) 2>&1 | + sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val="\$ac_cv_env_${ac_var}_value" + eval ac_new_val="\$ac_env_${ac_var}_value" + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + + + + + + + + + +# Making releases: +# LIBGNOMEVFS_MICRO_VERSION += 1; +# LIBGNOMEVFS_INTERFACE_AGE += 1; +# if any functions have been added, set LIBGNOMEVFS_INTERFACE_AGE to 0. +# if backwards compatibility has been broken, +# set LIBGNOMEVFS_BINARY_AGE and LIBGNOMEVFS_INTERFACE_AGE to 0. +# +LIBGNOMEVFS_MAJOR_VERSION=2 +LIBGNOMEVFS_MINOR_VERSION=3 +LIBGNOMEVFS_MICRO_VERSION=8 +LIBGNOMEVFS_INTERFACE_AGE=8 +# If you need a modifier for the version number. +# Normally empty, but can be used to make "fixup" releases. +LIBGNOMEVFS_EXTRAVERSION= + + +LIBGNOMEVFS_CURRENT=`expr 100 '*' $LIBGNOMEVFS_MINOR_VERSION + $LIBGNOMEVFS_MICRO_VERSION - $LIBGNOMEVFS_INTERFACE_AGE` +LIBGNOMEVFS_BINARY_AGE=`expr 100 '*' $LIBGNOMEVFS_MINOR_VERSION + $LIBGNOMEVFS_MICRO_VERSION` +LIBGNOMEVFS_REVISION=$LIBGNOMEVFS_INTERFACE_AGE +LIBGNOMEVFS_AGE=`expr $LIBGNOMEVFS_BINARY_AGE - $LIBGNOMEVFS_INTERFACE_AGE` +LIBGNOMEVFS_VERSION=$LIBGNOMEVFS_MAJOR_VERSION.$LIBGNOMEVFS_MINOR_VERSION.$LIBGNOMEVFS_MICRO_VERSION$LIBGNOMEVFS_EXTRAVERSION + + + + + + + + ac_config_headers="$ac_config_headers config.h" + + ac_config_commands="$ac_config_commands default-1" + +am__api_version="1.4" +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f $ac_dir/shtool; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 +echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} + { (exit 1); exit 1; }; } +fi +ac_config_guess="$SHELL $ac_aux_dir/config.guess" +ac_config_sub="$SHELL $ac_aux_dir/config.sub" +ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL=$ac_install_sh + fi +fi +echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +echo "$as_me:$LINENO: checking whether build environment is sane" >&5 +echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6 +# Just in case +sleep 1 +echo timestamp > conftestfile +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "$*" != "X $srcdir/configure conftestfile" \ + && test "$*" != "X conftestfile $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&5 +echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&2;} + { (exit 1); exit 1; }; } + fi + + test "$2" = conftestfile + ) +then + # Ok. + : +else + { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! +Check your system clock" >&5 +echo "$as_me: error: newly created file is older than distributed files! +Check your system clock" >&2;} + { (exit 1); exit 1; }; } +fi +rm -f conftest* +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +test "$program_prefix" != NONE && + program_transform_name="s,^,$program_prefix,;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s,\$,$program_suffix,;$program_transform_name" +# Double any \ or $. echo might interpret backslashes. +# By default was `s,x,x', remove it if useless. +cat <<\_ACEOF >conftest.sed +s/[\\$]/&&/g;s/;s,x,x,$// +_ACEOF +program_transform_name=`echo $program_transform_name | sed -f conftest.sed` +rm conftest.sed + +echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,./+-,__p_,'` +if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.make <<\_ACEOF +all: + @echo 'ac_maketemp="$(MAKE)"' +_ACEOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftest.make +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + SET_MAKE= +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + + +PACKAGE=gnome-vfs + +VERSION=$LIBGNOMEVFS_VERSION + +if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then + { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 +echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} + { (exit 1); exit 1; }; } +fi + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + + + +missing_dir=`cd $ac_aux_dir && pwd` +echo "$as_me:$LINENO: checking for working aclocal-${am__api_version}" >&5 +echo $ECHO_N "checking for working aclocal-${am__api_version}... $ECHO_C" >&6 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (aclocal-${am__api_version} --version) < /dev/null > /dev/null 2>&1; then + ACLOCAL=aclocal-${am__api_version} + echo "$as_me:$LINENO: result: found" >&5 +echo "${ECHO_T}found" >&6 +else + ACLOCAL="$missing_dir/missing aclocal-${am__api_version}" + echo "$as_me:$LINENO: result: missing" >&5 +echo "${ECHO_T}missing" >&6 +fi + +echo "$as_me:$LINENO: checking for working autoconf" >&5 +echo $ECHO_N "checking for working autoconf... $ECHO_C" >&6 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (autoconf --version) < /dev/null > /dev/null 2>&1; then + AUTOCONF=autoconf + echo "$as_me:$LINENO: result: found" >&5 +echo "${ECHO_T}found" >&6 +else + AUTOCONF="$missing_dir/missing autoconf" + echo "$as_me:$LINENO: result: missing" >&5 +echo "${ECHO_T}missing" >&6 +fi + +echo "$as_me:$LINENO: checking for working automake-${am__api_version}" >&5 +echo $ECHO_N "checking for working automake-${am__api_version}... $ECHO_C" >&6 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (automake-${am__api_version} --version) < /dev/null > /dev/null 2>&1; then + AUTOMAKE=automake-${am__api_version} + echo "$as_me:$LINENO: result: found" >&5 +echo "${ECHO_T}found" >&6 +else + AUTOMAKE="$missing_dir/missing automake-${am__api_version}" + echo "$as_me:$LINENO: result: missing" >&5 +echo "${ECHO_T}missing" >&6 +fi + +echo "$as_me:$LINENO: checking for working autoheader" >&5 +echo $ECHO_N "checking for working autoheader... $ECHO_C" >&6 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (autoheader --version) < /dev/null > /dev/null 2>&1; then + AUTOHEADER=autoheader + echo "$as_me:$LINENO: result: found" >&5 +echo "${ECHO_T}found" >&6 +else + AUTOHEADER="$missing_dir/missing autoheader" + echo "$as_me:$LINENO: result: missing" >&5 +echo "${ECHO_T}missing" >&6 +fi + +echo "$as_me:$LINENO: checking for working makeinfo" >&5 +echo $ECHO_N "checking for working makeinfo... $ECHO_C" >&6 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (makeinfo --version) < /dev/null > /dev/null 2>&1; then + MAKEINFO=makeinfo + echo "$as_me:$LINENO: result: found" >&5 +echo "${ECHO_T}found" >&6 +else + MAKEINFO="$missing_dir/missing makeinfo" + echo "$as_me:$LINENO: result: missing" >&5 +echo "${ECHO_T}missing" >&6 +fi + + + +ACLOCAL_AMFLAGS="$ACLOCAL_FLAGS" + + +echo "$as_me:$LINENO: checking whether to enable maintainer-specific portions of Makefiles" >&5 +echo $ECHO_N "checking whether to enable maintainer-specific portions of Makefiles... $ECHO_C" >&6 + # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then + enableval="$enable_maintainer_mode" + USE_MAINTAINER_MODE=$enableval +else + USE_MAINTAINER_MODE=no +fi; + echo "$as_me:$LINENO: result: $USE_MAINTAINER_MODE" >&5 +echo "${ECHO_T}$USE_MAINTAINER_MODE" >&6 + + +if test $USE_MAINTAINER_MODE = yes; then + MAINTAINER_MODE_TRUE= + MAINTAINER_MODE_FALSE='#' +else + MAINTAINER_MODE_TRUE='#' + MAINTAINER_MODE_FALSE= +fi + MAINT=$MAINTAINER_MODE_TRUE + + + + + if test "${ac_cv_gnome_aclocal_dir+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_gnome_aclocal_dir="$GNOME_COMMON_MACROS_DIR" +fi + + if test "${ac_cv_gnome_aclocal_flags+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_gnome_aclocal_flags="$ACLOCAL_FLAGS" +fi + + GNOME_ACLOCAL_DIR="$ac_cv_gnome_aclocal_dir" + GNOME_ACLOCAL_FLAGS="$ac_cv_gnome_aclocal_flags" + + + + ACLOCAL="$ACLOCAL $GNOME_ACLOCAL_FLAGS" + + + +if false; then + INSIDE_GNOME_DOCU_TRUE= + INSIDE_GNOME_DOCU_FALSE='#' +else + INSIDE_GNOME_DOCU_TRUE='#' + INSIDE_GNOME_DOCU_FALSE= +fi + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_CC" && break +done + + CC=$ac_ct_CC +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO:" \ + "checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +echo "$as_me:$LINENO: checking for C compiler default output" >&5 +echo $ECHO_N "checking for C compiler default output... $ECHO_C" >&6 +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 + (eval $ac_link_default) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Find the output, starting from the most likely. This scheme is +# not robust to junk in `.', hence go to wildcards (a.*) only as a last +# resort. + +# Be careful to initialize this variable, since it used to be cached. +# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. +ac_cv_exeext= +# b.out is created by i960 compilers. +for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) + ;; + conftest.$ac_ext ) + # This is the source file. + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + # FIXME: I believe we export ac_cv_exeext for Libtool, + # but it would be cool to find out if it's true. Does anybody + # maintain Libtool? --akim. + export ac_cv_exeext + break;; + * ) + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6 + +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6 + +echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + export ac_cv_exeext + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6 + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6 +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_compiler_gnu=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +CFLAGS="-g" +echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_prog_cc_g=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 +echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_stdc=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +# Don't try gcc -ansi; that turns off useful extensions and +# breaks some systems' header files. +# AIX -qlanglvl=ansi +# Ultrix and OSF/1 -std1 +# HP-UX 10.20 and later -Ae +# HP-UX older versions -Aa -D_HPUX_SOURCE +# SVR4 -Xc -D__EXTENSIONS__ +for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_stdc=$ac_arg +break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.$ac_objext +done +rm -f conftest.$ac_ext conftest.$ac_objext +CC=$ac_save_CC + +fi + +case "x$ac_cv_prog_cc_stdc" in + x|xno) + echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6 ;; + *) + echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 + CC="$CC $ac_cv_prog_cc_stdc" ;; +esac + +# Some people use a C++ compiler to compile C. Since we use `exit', +# in C++ we need to declare it. In case someone uses the same compiler +# for both compiling C and C++ we need to have the C++ compiler decide +# the declaration of exit, since it's the most demanding environment. +cat >conftest.$ac_ext <<_ACEOF +#ifndef __cplusplus + choke me +#endif +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + for ac_declaration in \ + ''\ + '#include ' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +continue +fi +rm -f conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.$ac_objext conftest.$ac_ext +done +rm -f conftest* +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h +fi + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.$ac_objext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + echo "$as_me:$LINENO: checking for strerror in -lcposix" >&5 +echo $ECHO_N "checking for strerror in -lcposix... $ECHO_C" >&6 +if test "${ac_cv_lib_cposix_strerror+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcposix $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char strerror (); +int +main () +{ +strerror (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_cposix_strerror=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_cposix_strerror=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_cposix_strerror" >&5 +echo "${ECHO_T}$ac_cv_lib_cposix_strerror" >&6 +if test $ac_cv_lib_cposix_strerror = yes; then + LIBS="$LIBS -lcposix" +fi + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_CC" && break +done + + CC=$ac_ct_CC +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO:" \ + "checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_compiler_gnu=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +CFLAGS="-g" +echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_prog_cc_g=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 +echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_stdc=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +# Don't try gcc -ansi; that turns off useful extensions and +# breaks some systems' header files. +# AIX -qlanglvl=ansi +# Ultrix and OSF/1 -std1 +# HP-UX 10.20 and later -Ae +# HP-UX older versions -Aa -D_HPUX_SOURCE +# SVR4 -Xc -D__EXTENSIONS__ +for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_stdc=$ac_arg +break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.$ac_objext +done +rm -f conftest.$ac_ext conftest.$ac_objext +CC=$ac_save_CC + +fi + +case "x$ac_cv_prog_cc_stdc" in + x|xno) + echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6 ;; + *) + echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 + CC="$CC $ac_cv_prog_cc_stdc" ;; +esac + +# Some people use a C++ compiler to compile C. Since we use `exit', +# in C++ we need to declare it. In case someone uses the same compiler +# for both compiling C and C++ we need to have the C++ compiler decide +# the declaration of exit, since it's the most demanding environment. +cat >conftest.$ac_ext <<_ACEOF +#ifndef __cplusplus + choke me +#endif +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + for ac_declaration in \ + ''\ + '#include ' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +continue +fi +rm -f conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.$ac_objext conftest.$ac_ext +done +rm -f conftest* +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h +fi + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.$ac_objext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6 +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_AWK+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + echo "$as_me:$LINENO: result: $AWK" >&5 +echo "${ECHO_T}$AWK" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$AWK" && break +done + + +# Check whether --enable-shared or --disable-shared was given. +if test "${enable_shared+set}" = set; then + enableval="$enable_shared" + p=${PACKAGE-default} +case $enableval in +yes) enable_shared=yes ;; +no) enable_shared=no ;; +*) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac +else + enable_shared=yes +fi; +# Check whether --enable-static or --disable-static was given. +if test "${enable_static+set}" = set; then + enableval="$enable_static" + p=${PACKAGE-default} +case $enableval in +yes) enable_static=yes ;; +no) enable_static=no ;; +*) + enable_static=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac +else + enable_static=yes +fi; +# Check whether --enable-fast-install or --disable-fast-install was given. +if test "${enable_fast_install+set}" = set; then + enableval="$enable_fast_install" + p=${PACKAGE-default} +case $enableval in +yes) enable_fast_install=yes ;; +no) enable_fast_install=no ;; +*) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac +else + enable_fast_install=yes +fi; +# Make sure we can run config.sub. +$ac_config_sub sun4 >/dev/null 2>&1 || + { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5 +echo "$as_me: error: cannot run $ac_config_sub" >&2;} + { (exit 1); exit 1; }; } + +echo "$as_me:$LINENO: checking build system type" >&5 +echo $ECHO_N "checking build system type... $ECHO_C" >&6 +if test "${ac_cv_build+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_build_alias=$build_alias +test -z "$ac_cv_build_alias" && + ac_cv_build_alias=`$ac_config_guess` +test -z "$ac_cv_build_alias" && + { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 +echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } +ac_cv_build=`$ac_config_sub $ac_cv_build_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_build" >&5 +echo "${ECHO_T}$ac_cv_build" >&6 +build=$ac_cv_build +build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + +echo "$as_me:$LINENO: checking host system type" >&5 +echo $ECHO_N "checking host system type... $ECHO_C" >&6 +if test "${ac_cv_host+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_host_alias=$host_alias +test -z "$ac_cv_host_alias" && + ac_cv_host_alias=$ac_cv_build_alias +ac_cv_host=`$ac_config_sub $ac_cv_host_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_host" >&5 +echo "${ECHO_T}$ac_cv_host" >&6 +host=$ac_cv_host +host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + +# Find the correct PATH separator. Usually this is `:', but +# DJGPP uses `;' like DOS. +if test "X${PATH_SEPARATOR+set}" != Xset; then + UNAME=${UNAME-`uname 2>/dev/null`} + case X$UNAME in + *-DOS) lt_cv_sys_path_separator=';' ;; + *) lt_cv_sys_path_separator=':' ;; + esac + PATH_SEPARATOR=$lt_cv_sys_path_separator +fi + + +# Check whether --with-gnu-ld or --without-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then + withval="$with_gnu_ld" + test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi; +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + echo "$as_me:$LINENO: checking for ld used by GCC" >&5 +echo $ECHO_N "checking for ld used by GCC... $ECHO_C" >&6 + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | [A-Za-z]:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + echo "$as_me:$LINENO: checking for GNU ld" >&5 +echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6 +else + echo "$as_me:$LINENO: checking for non-GNU ld" >&5 +echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6 +fi +if test "${lt_cv_path_LD+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$lt_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$ac_save_ifs" +else + lt_cv_path_LD="$LD" # Let the user override the test with a path. +fi +fi + +LD="$lt_cv_path_LD" +if test -n "$LD"; then + echo "$as_me:$LINENO: result: $LD" >&5 +echo "${ECHO_T}$LD" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi +test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5 +echo "$as_me: error: no acceptable ld found in \$PATH" >&2;} + { (exit 1); exit 1; }; } +echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5 +echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6 +if test "${lt_cv_prog_gnu_ld+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 &5; then + lt_cv_prog_gnu_ld=yes +else + lt_cv_prog_gnu_ld=no +fi +fi +echo "$as_me:$LINENO: result: $lt_cv_prog_gnu_ld" >&5 +echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6 +with_gnu_ld=$lt_cv_prog_gnu_ld + + +echo "$as_me:$LINENO: checking for $LD option to reload object files" >&5 +echo $ECHO_N "checking for $LD option to reload object files... $ECHO_C" >&6 +if test "${lt_cv_ld_reload_flag+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_ld_reload_flag='-r' +fi +echo "$as_me:$LINENO: result: $lt_cv_ld_reload_flag" >&5 +echo "${ECHO_T}$lt_cv_ld_reload_flag" >&6 +reload_flag=$lt_cv_ld_reload_flag +test -n "$reload_flag" && reload_flag=" $reload_flag" + +echo "$as_me:$LINENO: checking for BSD-compatible nm" >&5 +echo $ECHO_N "checking for BSD-compatible nm... $ECHO_C" >&6 +if test "${lt_cv_path_NM+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/${ac_tool_prefix}nm + if test -f $tmp_nm || test -f $tmp_nm$ac_exeext ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then + lt_cv_path_NM="$tmp_nm -B" + break + elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + lt_cv_path_NM="$tmp_nm -p" + break + else + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + fi + fi + done + IFS="$ac_save_ifs" + test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm +fi +fi + +NM="$lt_cv_path_NM" +echo "$as_me:$LINENO: result: $NM" >&5 +echo "${ECHO_T}$NM" >&6 + +echo "$as_me:$LINENO: checking for a sed that does not truncate output" >&5 +echo $ECHO_N "checking for a sed that does not truncate output... $ECHO_C" >&6 +if test "${lt_cv_path_SED+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_executable_p="test -f" +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + _sed_list="$_sed_list $as_dir/$ac_prog$ac_exec_ext" + fi + done + done +done + + # Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. +: ${TMPDIR=/tmp} +{ + tmp=`(umask 077 && mktemp -d -q "$TMPDIR/sedXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=$TMPDIR/sed$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in $TMPDIR" >&2 + { (exit 1); exit 1; } +} + _max=0 + _count=0 + # Add /usr/xpg4/bin/sed as it is typically found on Solaris + # along with /bin/sed that truncates output. + for _sed in $_sed_list /usr/xpg4/bin/sed; do + test ! -f ${_sed} && break + cat /dev/null > "$tmp/sed.in" + _count=0 + echo ${ECHO_N-$ac_n} "0123456789${ECHO_C-$ac_c}" >"$tmp/sed.in" + # Check for GNU sed and select it if it is found. + if "${_sed}" --version 2>&1 < /dev/null | egrep '(GNU)' > /dev/null; then + lt_cv_path_SED=${_sed} + break + fi + while true; do + cat "$tmp/sed.in" "$tmp/sed.in" >"$tmp/sed.tmp" + mv "$tmp/sed.tmp" "$tmp/sed.in" + cp "$tmp/sed.in" "$tmp/sed.nl" + echo >>"$tmp/sed.nl" + ${_sed} -e 's/a$//' < "$tmp/sed.nl" >"$tmp/sed.out" || break + cmp -s "$tmp/sed.out" "$tmp/sed.nl" || break + # 40000 chars as input seems more than enough + test $_count -gt 10 && break + _count=`expr $_count + 1` + if test $_count -gt $_max; then + _max=$_count + lt_cv_path_SED=$_sed + fi + done + done + rm -rf "$tmp" + +fi + +if test "X$SED" != "X"; then + lt_cv_path_SED=$SED +else + SED=$lt_cv_path_SED +fi +echo "$as_me:$LINENO: result: $SED" >&5 +echo "${ECHO_T}$SED" >&6 + +echo "$as_me:$LINENO: checking whether ln -s works" >&5 +echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6 +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +else + echo "$as_me:$LINENO: result: no, using $LN_S" >&5 +echo "${ECHO_T}no, using $LN_S" >&6 +fi + +echo "$as_me:$LINENO: checking how to recognise dependent libraries" >&5 +echo $ECHO_N "checking how to recognise dependent libraries... $ECHO_C" >&6 +if test "${lt_cv_deplibs_check_method+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given egrep regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix4* | aix5*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi4*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin* | mingw* | pw32*) + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library' + lt_cv_file_magic_cmd='/usr/bin/file -L' + case "$host_os" in + rhapsody* | darwin1.[012]) + lt_cv_file_magic_test_file=`echo /System/Library/Frameworks/System.framework/Versions/*/System | head -1` + ;; + *) # Darwin 1.3 on + lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib' + ;; + esac + ;; + +freebsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20*|hpux11*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + irix5* | nonstopux*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1" + ;; + *) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1" + ;; + esac + lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*` + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux-gnu*) + case $host_cpu in + alpha* | hppa* | i*86 | mips | mipsel | powerpc* | sparc* | ia64* | s390* | x86_64*) + lt_cv_deplibs_check_method=pass_all ;; + *) + # glibc up to 2.1.1 does not perform some relocations on ARM + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; + esac + lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so` + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +openbsd*) + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB shared object' + else + lt_cv_deplibs_check_method='file_magic OpenBSD.* shared library' + fi + ;; + +osf3* | osf4* | osf5*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method='file_magic COFF format alpha shared library' + lt_cv_file_magic_test_file=/shlib/libc.so + lt_cv_deplibs_check_method=pass_all + ;; + +sco3.2v5*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + lt_cv_file_magic_test_file=/lib/libc.so + ;; + +sysv5uw[78]* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; +esac + +fi +echo "$as_me:$LINENO: result: $lt_cv_deplibs_check_method" >&5 +echo "${ECHO_T}$lt_cv_deplibs_check_method" >&6 +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method + + + + + + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +echo "$as_me:$LINENO: checking command to parse $NM output" >&5 +echo $ECHO_N "checking command to parse $NM output... $ECHO_C" >&6 +if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Transform the above into a raw symbol and a C symbol. +symxfrm='\1 \2\3 \3' + +# Transform an extracted symbol line into a proper C declaration +lt_cv_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32*) + symcode='[ABCDGISTW]' + ;; +hpux*) # Its linker distinguishes data from code symbols + lt_cv_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris* | sysv5*) + symcode='[BDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# Handle CRLF in mingw tool chain +opt_cr= +case $host_os in +mingw*) + opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then + symcode='[ABCDGISTW]' +fi + +# Try without a prefix undercore, then with it. +for ac_symprfx in "" "_"; do + + # Write the raw and C identifiers. +lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'" + + # Check to see that the pipe works correctly. + pipe_works=no + rm -f conftest* + cat > conftest.$ac_ext <&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { (eval echo "$as_me:$LINENO: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\"") >&5 + (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if egrep ' nm_test_var$' "$nlist" >/dev/null; then + if egrep ' nm_test_func$' "$nlist" >/dev/null; then + cat < conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + eval "$lt_cv_global_symbol_to_cdecl"' < "$nlist" >> conftest.$ac_ext' + + cat <> conftest.$ac_ext +#if defined (__STDC__) && __STDC__ +# define lt_ptr void * +#else +# define lt_ptr char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr address; +} +lt_preloaded_symbols[] = +{ +EOF + sed "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr) \&\2},/" < "$nlist" >> conftest.$ac_ext + cat <<\EOF >> conftest.$ac_ext + {0, (lt_ptr) 0} +}; + +#ifdef __cplusplus +} +#endif +EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$no_builtin_flag" + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest$ac_exeext; then + pipe_works=yes + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -f conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +global_symbol_pipe="$lt_cv_sys_global_symbol_pipe" +if test -z "$lt_cv_sys_global_symbol_pipe"; then + global_symbol_to_cdecl= + global_symbol_to_c_name_address= +else + global_symbol_to_cdecl="$lt_cv_global_symbol_to_cdecl" + global_symbol_to_c_name_address="$lt_cv_global_symbol_to_c_name_address" +fi +if test -z "$global_symbol_pipe$global_symbol_to_cdec$global_symbol_to_c_name_address"; +then + echo "$as_me:$LINENO: result: failed" >&5 +echo "${ECHO_T}failed" >&6 +else + echo "$as_me:$LINENO: result: ok" >&5 +echo "${ECHO_T}ok" >&6 +fi + + +echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6 +if test "${ac_cv_prog_egrep+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | (grep -E '(a|b)') >/dev/null 2>&1 + then ac_cv_prog_egrep='grep -E' + else ac_cv_prog_egrep='egrep' + fi +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 +echo "${ECHO_T}$ac_cv_prog_egrep" >&6 + EGREP=$ac_cv_prog_egrep + + +echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_header_stdc=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + exit(2); + exit (0); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6 +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_Header=no" +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + +for ac_header in dlfcn.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc in + yes:no ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to bug-autoconf@gnu.org. ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; + no:yes ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to bug-autoconf@gnu.org. ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + + + +# Only perform the check for file, if the check method requires it +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + echo "$as_me:$LINENO: checking for ${ac_tool_prefix}file" >&5 +echo $ECHO_N "checking for ${ac_tool_prefix}file... $ECHO_C" >&6 +if test "${lt_cv_path_MAGIC_CMD+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $MAGIC_CMD in + /*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; + ?:/*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path. + ;; + *) + ac_save_MAGIC_CMD="$MAGIC_CMD" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="/usr/bin:$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/${ac_tool_prefix}file; then + lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + egrep "$file_magic_regex" > /dev/null; then + : + else + cat <&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$ac_save_ifs" + MAGIC_CMD="$ac_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5 +echo "${ECHO_T}$MAGIC_CMD" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + echo "$as_me:$LINENO: checking for file" >&5 +echo $ECHO_N "checking for file... $ECHO_C" >&6 +if test "${lt_cv_path_MAGIC_CMD+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $MAGIC_CMD in + /*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; + ?:/*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path. + ;; + *) + ac_save_MAGIC_CMD="$MAGIC_CMD" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="/usr/bin:$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/file; then + lt_cv_path_MAGIC_CMD="$ac_dir/file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + egrep "$file_magic_regex" > /dev/null; then + : + else + cat <&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$ac_save_ifs" + MAGIC_CMD="$ac_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5 +echo "${ECHO_T}$MAGIC_CMD" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + echo "$as_me:$LINENO: result: $RANLIB" >&5 +echo "${ECHO_T}$RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +echo "${ECHO_T}$ac_ct_RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + RANLIB=$ac_ct_RANLIB +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + echo "$as_me:$LINENO: result: $STRIP" >&5 +echo "${ECHO_T}$STRIP" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":" +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 +echo "${ECHO_T}$ac_ct_STRIP" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + STRIP=$ac_ct_STRIP +else + STRIP="$ac_cv_prog_STRIP" +fi + + +enable_dlopen=no +enable_win32_dll=no + +# Check whether --enable-libtool-lock or --disable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then + enableval="$enable_libtool_lock" + +fi; +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +*-*-irix6*) + # Find out which ABI we are using. + echo '#line 5176 "configure"' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + echo "$as_me:$LINENO: checking whether the C compiler needs -belf" >&5 +echo $ECHO_N "checking whether the C compiler needs -belf... $ECHO_C" >&6 +if test "${lt_cv_cc_needs_belf+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + lt_cv_cc_needs_belf=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +lt_cv_cc_needs_belf=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $lt_cv_cc_needs_belf" >&5 +echo "${ECHO_T}$lt_cv_cc_needs_belf" >&6 + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; + + +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e s/^X//' +sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Constants: +rm="rm -f" + +# Global variables: +default_ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except M$VC, +# which needs '.lib'). +libext=a +ltmain="$ac_aux_dir/ltmain.sh" +ofile="$default_ofile" +with_gnu_ld="$lt_cv_prog_gnu_ld" +need_locks="$enable_libtool_lock" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru +test -z "$AS" && AS=as +test -z "$CC" && CC=cc +test -z "$DLLTOOL" && DLLTOOL=dlltool +test -z "$LD" && LD=ld +test -z "$LN_S" && LN_S="ln -s" +test -z "$MAGIC_CMD" && MAGIC_CMD=file +test -z "$NM" && NM=nm +test -z "$OBJDUMP" && OBJDUMP=objdump +test -z "$RANLIB" && RANLIB=: +test -z "$STRIP" && STRIP=: +test -z "$ac_objext" && ac_objext=o + +if test x"$host" != x"$build"; then + ac_tool_prefix=${host_alias}- +else + ac_tool_prefix= +fi + +# Transform linux* to *-*-linux-gnu*, to support old configure scripts. +case $host_os in +linux-gnu*) ;; +linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'` +esac + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds" + ;; + *) + old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +# Allow CC to be a program name with arguments. +set dummy $CC +compiler="$2" + +echo "$as_me:$LINENO: checking for objdir" >&5 +echo $ECHO_N "checking for objdir... $ECHO_C" >&6 +rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + objdir=_libs +fi +rmdir .libs 2>/dev/null +echo "$as_me:$LINENO: result: $objdir" >&5 +echo "${ECHO_T}$objdir" >&6 + + + +# Check whether --with-pic or --without-pic was given. +if test "${with_pic+set}" = set; then + withval="$with_pic" + pic_mode="$withval" +else + pic_mode=default +fi; +test -z "$pic_mode" && pic_mode=default + +# We assume here that the value for lt_cv_prog_cc_pic will not be cached +# in isolation, and that seeing it set (from the cache) indicates that +# the associated values are set (in the cache) correctly too. +echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 +echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 +if test "${lt_cv_prog_cc_pic+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_cc_pic= + lt_cv_prog_cc_shlib= + lt_cv_prog_cc_wl= + lt_cv_prog_cc_static= + lt_cv_prog_cc_no_builtin= + lt_cv_prog_cc_can_build_shared=$can_build_shared + + if test "$GCC" = yes; then + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static='-static' + + case $host_os in + aix*) + # Below there is a dirty hack to force normal static linking with -ldl + # The problem is because libdl dynamically linked with both libc and + # libC (AIX C++ library), which obviously doesn't included in libraries + # list by gcc. This cause undefined symbols with -static flags. + # This hack allows C programs to be linked with "-static -ldl", but + # not sure about C++ programs. + lt_cv_prog_cc_static="$lt_cv_prog_cc_static ${lt_cv_prog_cc_wl}-lC" + ;; + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_cv_prog_cc_pic='-m68020 -resident32 -malways-restore-a4' + ;; + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_cv_prog_cc_pic='-fno-common' + ;; + cygwin* | mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_cv_prog_cc_pic='-DDLL_EXPORT' + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_cv_prog_cc_pic=-Kconform_pic + fi + ;; + *) + lt_cv_prog_cc_pic='-fPIC' + ;; + esac + else + # PORTME Check for PIC flags for the system compiler. + case $host_os in + aix3* | aix4* | aix5*) + lt_cv_prog_cc_wl='-Wl,' + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_cv_prog_cc_static='-Bstatic' + else + lt_cv_prog_cc_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + hpux9* | hpux10* | hpux11*) + # Is there a better lt_cv_prog_cc_static that works with the bundled CC? + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static="${lt_cv_prog_cc_wl}-a ${lt_cv_prog_cc_wl}archive" + lt_cv_prog_cc_pic='+Z' + ;; + + irix5* | irix6* | nonstopux*) + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static='-non_shared' + # PIC (with -KPIC) is the default. + ;; + + cygwin* | mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_cv_prog_cc_pic='-DDLL_EXPORT' + ;; + + newsos6) + lt_cv_prog_cc_pic='-KPIC' + lt_cv_prog_cc_static='-Bstatic' + ;; + + osf3* | osf4* | osf5*) + # All OSF/1 code is PIC. + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static='-non_shared' + ;; + + sco3.2v5*) + lt_cv_prog_cc_pic='-Kpic' + lt_cv_prog_cc_static='-dn' + lt_cv_prog_cc_shlib='-belf' + ;; + + solaris*) + lt_cv_prog_cc_pic='-KPIC' + lt_cv_prog_cc_static='-Bstatic' + lt_cv_prog_cc_wl='-Wl,' + ;; + + sunos4*) + lt_cv_prog_cc_pic='-PIC' + lt_cv_prog_cc_static='-Bstatic' + lt_cv_prog_cc_wl='-Qoption ld ' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + lt_cv_prog_cc_pic='-KPIC' + lt_cv_prog_cc_static='-Bstatic' + lt_cv_prog_cc_wl='-Wl,' + ;; + + uts4*) + lt_cv_prog_cc_pic='-pic' + lt_cv_prog_cc_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_cv_prog_cc_pic='-Kconform_pic' + lt_cv_prog_cc_static='-Bstatic' + fi + ;; + + *) + lt_cv_prog_cc_can_build_shared=no + ;; + esac + fi + +fi + +if test -z "$lt_cv_prog_cc_pic"; then + echo "$as_me:$LINENO: result: none" >&5 +echo "${ECHO_T}none" >&6 +else + echo "$as_me:$LINENO: result: $lt_cv_prog_cc_pic" >&5 +echo "${ECHO_T}$lt_cv_prog_cc_pic" >&6 + + # Check to make sure the pic_flag actually works. + echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_cv_prog_cc_pic works" >&5 +echo $ECHO_N "checking if $compiler PIC flag $lt_cv_prog_cc_pic works... $ECHO_C" >&6 + if test "${lt_cv_prog_cc_pic_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $lt_cv_prog_cc_pic -DPIC" + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + case $host_os in + hpux9* | hpux10* | hpux11*) + # On HP-UX, both CC and GCC only warn that PIC is supported... then + # they create non-PIC objects. So, if there were any warnings, we + # assume that PIC is not supported. + if test -s conftest.err; then + lt_cv_prog_cc_pic_works=no + else + lt_cv_prog_cc_pic_works=yes + fi + ;; + *) + lt_cv_prog_cc_pic_works=yes + ;; + esac + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + lt_cv_prog_cc_pic_works=no + +fi +rm -f conftest.$ac_objext conftest.$ac_ext + CFLAGS="$save_CFLAGS" + +fi + + + if test "X$lt_cv_prog_cc_pic_works" = Xno; then + lt_cv_prog_cc_pic= + lt_cv_prog_cc_can_build_shared=no + else + lt_cv_prog_cc_pic=" $lt_cv_prog_cc_pic" + fi + + echo "$as_me:$LINENO: result: $lt_cv_prog_cc_pic_works" >&5 +echo "${ECHO_T}$lt_cv_prog_cc_pic_works" >&6 +fi + +# Check for any special shared library compilation flags. +if test -n "$lt_cv_prog_cc_shlib"; then + { echo "$as_me:$LINENO: WARNING: \`$CC' requires \`$lt_cv_prog_cc_shlib' to build shared libraries" >&5 +echo "$as_me: WARNING: \`$CC' requires \`$lt_cv_prog_cc_shlib' to build shared libraries" >&2;} + if echo "$old_CC $old_CFLAGS " | egrep -e "[ ]$lt_cv_prog_cc_shlib[ ]" >/dev/null; then : + else + { echo "$as_me:$LINENO: WARNING: add \`$lt_cv_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure" >&5 +echo "$as_me: WARNING: add \`$lt_cv_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure" >&2;} + lt_cv_prog_cc_can_build_shared=no + fi +fi + +echo "$as_me:$LINENO: checking if $compiler static flag $lt_cv_prog_cc_static works" >&5 +echo $ECHO_N "checking if $compiler static flag $lt_cv_prog_cc_static works... $ECHO_C" >&6 +if test "${lt_cv_prog_cc_static_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_cc_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_cv_prog_cc_static" + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + lt_cv_prog_cc_static_works=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + +fi + + +# Belt *and* braces to stop my trousers falling down: +test "X$lt_cv_prog_cc_static_works" = Xno && lt_cv_prog_cc_static= +echo "$as_me:$LINENO: result: $lt_cv_prog_cc_static_works" >&5 +echo "${ECHO_T}$lt_cv_prog_cc_static_works" >&6 + +pic_flag="$lt_cv_prog_cc_pic" +special_shlib_compile_flags="$lt_cv_prog_cc_shlib" +wl="$lt_cv_prog_cc_wl" +link_static_flag="$lt_cv_prog_cc_static" +no_builtin_flag="$lt_cv_prog_cc_no_builtin" +can_build_shared="$lt_cv_prog_cc_can_build_shared" + + +# Check to see if options -o and -c are simultaneously supported by compiler +echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 +echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 +if test "${lt_cv_compiler_c_o+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + +$rm -r conftest 2>/dev/null +mkdir conftest +cd conftest +echo "int some_variable = 0;" > conftest.$ac_ext +mkdir out +# According to Tom Tromey, Ian Lance Taylor reported there are C compilers +# that will create temporary files in the current directory regardless of +# the output directory. Thus, making CWD read-only will cause this test +# to fail, enabling locking or at least warning the user not to do parallel +# builds. +chmod -w . +save_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -o out/conftest2.$ac_objext" +compiler_c_o=no +if { (eval echo configure:5705: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s out/conftest.err; then + lt_cv_compiler_c_o=no + else + lt_cv_compiler_c_o=yes + fi +else + # Append any errors to the config.log. + cat out/conftest.err 1>&5 + lt_cv_compiler_c_o=no +fi +CFLAGS="$save_CFLAGS" +chmod u+w . +$rm conftest* out/* +rmdir out +cd .. +rmdir conftest +$rm -r conftest 2>/dev/null + +fi + +compiler_c_o=$lt_cv_compiler_c_o +echo "$as_me:$LINENO: result: $compiler_c_o" >&5 +echo "${ECHO_T}$compiler_c_o" >&6 + +if test x"$compiler_c_o" = x"yes"; then + # Check to see if we can write to a .lo + echo "$as_me:$LINENO: checking if $compiler supports -c -o file.lo" >&5 +echo $ECHO_N "checking if $compiler supports -c -o file.lo... $ECHO_C" >&6 + if test "${lt_cv_compiler_o_lo+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + lt_cv_compiler_o_lo=no + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -c -o conftest.lo" + save_objext="$ac_objext" + ac_objext=lo + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +int some_variable = 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + lt_cv_compiler_o_lo=no + else + lt_cv_compiler_o_lo=yes + fi + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.$ac_objext conftest.$ac_ext + ac_objext="$save_objext" + CFLAGS="$save_CFLAGS" + +fi + + compiler_o_lo=$lt_cv_compiler_o_lo + echo "$as_me:$LINENO: result: $compiler_o_lo" >&5 +echo "${ECHO_T}$compiler_o_lo" >&6 +else + compiler_o_lo=no +fi + +# Check to see if we can do hard links to lock some files if needed +hard_links="nottested" +if test "$compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 +echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6 + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + echo "$as_me:$LINENO: result: $hard_links" >&5 +echo "${ECHO_T}$hard_links" >&6 + if test "$hard_links" = no; then + { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + +if test "$GCC" = yes; then + # Check to see if options -fno-rtti -fno-exceptions are supported by compiler + echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6 + echo "int some_variable = 0;" > conftest.$ac_ext + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.$ac_ext" + compiler_rtti_exceptions=no + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +int some_variable = 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + compiler_rtti_exceptions=no + else + compiler_rtti_exceptions=yes + fi + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.$ac_objext conftest.$ac_ext + CFLAGS="$save_CFLAGS" + echo "$as_me:$LINENO: result: $compiler_rtti_exceptions" >&5 +echo "${ECHO_T}$compiler_rtti_exceptions" >&6 + + if test "$compiler_rtti_exceptions" = "yes"; then + no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions' + else + no_builtin_flag=' -fno-builtin' + fi +fi + +# See if the linker supports building shared libraries. +echo "$as_me:$LINENO: checking whether the linker ($LD) supports shared libraries" >&5 +echo $ECHO_N "checking whether the linker ($LD) supports shared libraries... $ECHO_C" >&6 + +allow_undefined_flag= +no_undefined_flag= +need_lib_prefix=unknown +need_version=unknown +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +archive_cmds= +archive_expsym_cmds= +old_archive_from_new_cmds= +old_archive_from_expsyms_cmds= +export_dynamic_flag_spec= +whole_archive_flag_spec= +thread_safe_flag_spec= +hardcode_into_libs=no +hardcode_libdir_flag_spec= +hardcode_libdir_separator= +hardcode_direct=no +hardcode_minus_L=no +hardcode_shlibpath_var=unsupported +runpath_var= +link_all_deplibs=unknown +always_export_symbols=no +export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols' +# include_expsyms should be a list of space-separated symbols to be *always* +# included in the symbol list +include_expsyms= +# exclude_expsyms can be an egrep regular expression of symbols to exclude +# it will be wrapped by ` (' and `)$', so one must not match beginning or +# end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', +# as well as any symbol that contains `d'. +exclude_expsyms="_GLOBAL_OFFSET_TABLE_" +# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out +# platforms (ab)use it in PIC code, but their linkers get confused if +# the symbol is explicitly referenced. Since portable code cannot +# rely on this symbol name, it's probably fine to never include it in +# preloaded symbol tables. +extract_expsyms_cmds= + +case $host_os in +cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; +openbsd*) + with_gnu_ld=no + ;; +esac + +ld_shlibs=yes +if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # See if GNU ld supports shared libraries. + case $host_os in + aix3* | aix4* | aix5*) + # On AIX, the GNU linker is very broken + # Note:Check GNU linker on AIX 5-IA64 when/if it becomes available. + ld_shlibs=no + cat <&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + ;; + + amigaos*) + archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can use + # them. + ld_shlibs=no + ;; + + beos*) + if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32*) + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + allow_undefined_flag=unsupported + always_export_symbols=yes + + extract_expsyms_cmds='test -f $output_objdir/impgen.c || \ + sed -e "/^# \/\* impgen\.c starts here \*\//,/^# \/\* impgen.c ends here \*\// { s/^# //;s/^# *$//; p; }" -e d < $''0 > $output_objdir/impgen.c~ + test -f $output_objdir/impgen.exe || (cd $output_objdir && \ + if test "x$HOST_CC" != "x" ; then $HOST_CC -o impgen impgen.c ; \ + else $CC -o impgen impgen.c ; fi)~ + $output_objdir/impgen $dir/$soroot > $output_objdir/$soname-def' + + old_archive_from_expsyms_cmds='$DLLTOOL --as=$AS --dllname $soname --def $output_objdir/$soname-def --output-lib $output_objdir/$newlib' + + # cygwin and mingw dlls have different entry points and sets of symbols + # to exclude. + # FIXME: what about values for MSVC? + dll_entry=__cygwin_dll_entry@12 + dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12~ + case $host_os in + mingw*) + # mingw values + dll_entry=_DllMainCRTStartup@12 + dll_exclude_symbols=DllMain@12,DllMainCRTStartup@12,DllEntryPoint@12~ + ;; + esac + + # mingw and cygwin differ, and it's simplest to just exclude the union + # of the two symbol sets. + dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12,DllMainCRTStartup@12,DllEntryPoint@12 + + # recent cygwin and mingw systems supply a stub DllMain which the user + # can override, but on older systems we have to supply one (in ltdll.c) + if test "x$lt_cv_need_dllmain" = "xyes"; then + ltdll_obj='$output_objdir/$soname-ltdll.'"$ac_objext " + ltdll_cmds='test -f $output_objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $''0 > $output_objdir/$soname-ltdll.c~ + test -f $output_objdir/$soname-ltdll.$ac_objext || (cd $output_objdir && $CC -c $soname-ltdll.c)~' + else + ltdll_obj= + ltdll_cmds= + fi + + # Extract the symbol export list from an `--export-all' def file, + # then regenerate the def file from the symbol export list, so that + # the compiled dll only exports the symbol export list. + # Be careful not to strip the DATA tag left be newer dlltools. + export_symbols_cmds="$ltdll_cmds"' + $DLLTOOL --export-all --exclude-symbols '$dll_exclude_symbols' --output-def $output_objdir/$soname-def '$ltdll_obj'$libobjs $convenience~ + sed -e "1,/EXPORTS/d" -e "s/ @ [0-9]*//" -e "s/ *;.*$//" < $output_objdir/$soname-def > $export_symbols' + + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is. + # If DATA tags from a recent dlltool are present, honour them! + archive_expsym_cmds='if test "x`sed 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname-def; + else + echo EXPORTS > $output_objdir/$soname-def; + _lt_hint=1; + cat $export_symbols | while read symbol; do + set dummy \$symbol; + case \$# in + 2) echo " \$2 @ \$_lt_hint ; " >> $output_objdir/$soname-def;; + 4) echo " \$2 \$3 \$4 ; " >> $output_objdir/$soname-def; _lt_hint=`expr \$_lt_hint - 1`;; + *) echo " \$2 @ \$_lt_hint \$3 ; " >> $output_objdir/$soname-def;; + esac; + _lt_hint=`expr 1 + \$_lt_hint`; + done; + fi~ + '"$ltdll_cmds"' + $CC -Wl,--base-file,$output_objdir/$soname-base '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~ + $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp~ + $CC -Wl,--base-file,$output_objdir/$soname-base $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~ + $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp --output-lib $output_objdir/$libname.dll.a~ + $CC $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags' + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris* | sysv5*) + if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = yes; then + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + case $host_os in + cygwin* | mingw* | pw32*) + # dlltool doesn't understand --whole-archive et. al. + whole_archive_flag_spec= + ;; + *) + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | egrep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + ;; + esac + fi +else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes && test -z "$link_static_flag"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix5*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + hardcode_direct=yes + archive_cmds='' + hardcode_libdir_separator=':' + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + hardcode_direct=yes + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + esac + + shared_flag='-shared' + else + # not using gcc + if test "$host_cpu" = ia64; then + shared_flag='${wl}-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall can do strange things, so it is better to + # generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:/usr/lib:/lib' + archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname ${wl}-h$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + else + hardcode_libdir_flag_spec='${wl}-bnolibpath ${wl}-blibpath:$libdir:/usr/lib:/lib' + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='${wl}-berok' + # This is a bit strange, but is similar to how AIX traditionally builds + # it's shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"' ~$AR -crlo $objdir/$libname$release.a $objdir/$soname' + fi + fi + ;; + + amigaos*) + archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + # see comment about different semantics on the GNU ld section + ld_shlibs=no + ;; + + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path='`cygpath -w "$srcfile"`' + ;; + + darwin* | rhapsody*) + case "$host_os" in + rhapsody* | darwin1.[012]) + allow_undefined_flag='-undefined suppress' + ;; + *) # Darwin 1.3 on + allow_undefined_flag='-flat_namespace -undefined suppress' + ;; + esac + # FIXME: Relying on posixy $() will cause problems for + # cross-compilation, but unfortunately the echo tests do not + # yet detect zsh echo's removal of \ escapes. Also zsh mangles + # `"' quotes if we put them in here... so don't! + archive_cmds='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs && $CC $(test .$module = .yes && echo -bundle || echo -dynamiclib) $allow_undefined_flag -o $lib ${lib}-master.o $deplibs$linker_flags $(test .$module != .yes && echo -install_name $rpath/$soname $verstring)' + # We need to add '_' to the symbols in $export_symbols first + #archive_expsym_cmds="$archive_cmds"' && strip -s $export_symbols' + hardcode_direct=yes + hardcode_shlibpath_var=no + whole_archive_flag_spec='-all_load $convenience' + ;; + + freebsd1*) + ld_shlibs=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd*) + archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9* | hpux10* | hpux11*) + case $host_os in + hpux9*) archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ;; + *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ;; + esac + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_minus_L=yes # Not in the search PATH, but as the default + # location of the library. + export_dynamic_flag_spec='${wl}-E' + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='-rpath $libdir' + fi + hardcode_libdir_separator=: + link_all_deplibs=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + openbsd*) + hardcode_direct=yes + hardcode_shlibpath_var=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + else + case "$host_os" in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "-exported_symbol " >> $lib.exp; echo "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp' + + #Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + hardcode_libdir_separator=: + ;; + + sco3.2v5*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + export_dynamic_flag_spec='${wl}-Bexport' + ;; + + solaris*) + # gcc --version < 3.0 without binutils cannot create self contained + # shared libraries reliably, requiring libgcc.a to resolve some of + # the object symbols generated in some cases. Libraries that use + # assert need libgcc.a to resolve __eprintf, for example. Linking + # a copy of libgcc.a into every shared library to guarantee resolving + # such symbols causes other problems: According to Tim Van Holder + # , C++ libraries end up with a separate + # (to the application) exception stack for one thing. + no_undefined_flag=' -z defs' + if test "$GCC" = yes; then + case `$CC --version 2>/dev/null` in + [12].*) + cat <&2 + +*** Warning: Releases of GCC earlier than version 3.0 cannot reliably +*** create self contained shared libraries on Solaris systems, without +*** introducing a dependency on libgcc.a. Therefore, libtool is disabling +*** -no-undefined support, which will at least allow you to build shared +*** libraries. However, you may find that when you link such libraries +*** into an application without using GCC, you have to manually add +*** \`gcc --print-libgcc-file-name\` to the link command. We urge you to +*** upgrade to a newer version of GCC. Another option is to rebuild your +*** current GCC to use the GNU linker from GNU binutils 2.9.1 or newer. + +EOF + no_undefined_flag= + ;; + esac + fi + # $CC -shared without GNU ld will not create a library from C++ + # object files and a static libstdc++, better avoid it by now + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv5*) + no_undefined_flag=' -z text' + # $CC -shared without GNU ld will not create a library from C++ + # object files and a static libstdc++, better avoid it by now + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + hardcode_libdir_flag_spec= + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4.2uw2*) + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=no + hardcode_shlibpath_var=no + hardcode_runpath_var=yes + runpath_var=LD_RUN_PATH + ;; + + sysv5uw7* | unixware7*) + no_undefined_flag='${wl}-z ${wl}text' + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac +fi +echo "$as_me:$LINENO: result: $ld_shlibs" >&5 +echo "${ECHO_T}$ld_shlibs" >&6 +test "$ld_shlibs" = no && can_build_shared=no + +# Check hardcoding attributes. +echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 +echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6 +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || \ + test -n "$runpath_var"; then + + # We can hardcode non-existant directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$hardcode_shlibpath_var" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +echo "$as_me:$LINENO: result: $hardcode_action" >&5 +echo "${ECHO_T}$hardcode_action" >&6 + +striplib= +old_striplib= +echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5 +echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6 +if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +reload_cmds='$LD$reload_flag -o $output$reload_objs' +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +# PORTME Fill in your ld.so characteristics +echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 +echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6 +library_names_spec= +libname_spec='lib$name' +soname_spec= +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}.so$major' + ;; + +aix4* | aix5*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}.so$major ${libname}${release}.so$versuffix $libname.so' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can + # not hardcode correct soname into executable. Probably we can + # add versioning support to collect2, so additional links can + # be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}.so$major' + fi + shlibpath_var=LIBPATH + fi + hardcode_into_libs=yes + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}.so' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi4*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + export_dynamic_flag_spec=-rdynamic + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + need_version=no + need_lib_prefix=no + case $GCC,$host_os in + yes,cygwin*) + library_names_spec='$libname.dll.a' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll' + postinstall_cmds='dlpath=`bash 2>&1 -c '\''. $dir/${file}i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog .libs/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`bash 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + ;; + yes,mingw*) + library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | sed -e "s/^libraries://" -e "s/;/ /g" -e "s,=/,/,g"` + ;; + yes,pw32*) + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | sed -e 's/./-/g'`${versuffix}.dll' + ;; + *) + library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + # FIXME: Relying on posixy $() will cause problems for + # cross-compilation, but unfortunately the echo tests do not + # yet detect zsh echo's removal of \ escapes. + library_names_spec='${libname}${release}${versuffix}.$(test .$module = .yes && echo so || echo dylib) ${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib) ${libname}.$(test .$module = .yes && echo so || echo dylib)' + soname_spec='${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib)' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd*) + objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + *) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + dynamic_linker="$host_os dld.sl" + version_type=sunos + need_lib_prefix=no + need_version=no + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl' + soname_spec='${libname}${release}.sl$major' + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) version_type=irix ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}.so$major' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so $libname.so' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux-gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + + # Find out which ABI we are using (multilib Linux x86_64 hack). + libsuff= + case "$host_cpu" in + x86_64*|s390x*) + echo '#line 6889 "configure"' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + case `/usr/bin/file conftest.$ac_objext` in + *64-bit*) + libsuff=64 + ;; + esac + fi + rm -rf conftest* + ;; + *) + ;; + esac + sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff}" + sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}" + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so' + soname_spec='${libname}${release}.so$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case "$host_os" in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + ;; + +os2*) + libname_spec='$name' + need_lib_prefix=no + library_names_spec='$libname.dll $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_version=no + soname_spec='${libname}${release}.so$major' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + hardcode_into_libs=yes + ;; + +sco3.2v5*) + version_type=osf + soname_spec='${libname}${release}.so$major' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + shlibpath_var=LD_LIBRARY_PATH + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so' + soname_spec='$libname.so.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +*) + dynamic_linker=no + ;; +esac +echo "$as_me:$LINENO: result: $dynamic_linker" >&5 +echo "${ECHO_T}$dynamic_linker" >&6 +test "$dynamic_linker" = no && can_build_shared=no + +# Report the final consequences. +echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5 +echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: $can_build_shared" >&5 +echo "${ECHO_T}$can_build_shared" >&6 + +echo "$as_me:$LINENO: checking whether to build shared libraries" >&5 +echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6 +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case "$host_os" in +aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + +aix4*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; +esac +echo "$as_me:$LINENO: result: $enable_shared" >&5 +echo "${ECHO_T}$enable_shared" >&6 + +echo "$as_me:$LINENO: checking whether to build static libraries" >&5 +echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6 +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes +echo "$as_me:$LINENO: result: $enable_static" >&5 +echo "${ECHO_T}$enable_static" >&6 + +if test "$hardcode_action" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + cygwin* | mingw* | pw32*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + *) + echo "$as_me:$LINENO: checking for shl_load" >&5 +echo $ECHO_N "checking for shl_load... $ECHO_C" >&6 +if test "${ac_cv_func_shl_load+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char shl_load (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ +#ifdef __STDC__ +# include +#else +# include +#endif +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char shl_load (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_shl_load) || defined (__stub___shl_load) +choke me +#else +char (*f) () = shl_load; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != shl_load; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_shl_load=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_shl_load=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 +echo "${ECHO_T}$ac_cv_func_shl_load" >&6 +if test $ac_cv_func_shl_load = yes; then + lt_cv_dlopen="shl_load" +else + echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 +echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6 +if test "${ac_cv_lib_dld_shl_load+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char shl_load (); +int +main () +{ +shl_load (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dld_shl_load=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dld_shl_load=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 +echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6 +if test $ac_cv_lib_dld_shl_load = yes; then + lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld" +else + echo "$as_me:$LINENO: checking for dlopen" >&5 +echo $ECHO_N "checking for dlopen... $ECHO_C" >&6 +if test "${ac_cv_func_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char dlopen (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ +#ifdef __STDC__ +# include +#else +# include +#endif +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_dlopen) || defined (__stub___dlopen) +choke me +#else +char (*f) () = dlopen; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != dlopen; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_dlopen=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5 +echo "${ECHO_T}$ac_cv_func_dlopen" >&6 +if test $ac_cv_func_dlopen = yes; then + lt_cv_dlopen="dlopen" +else + echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 +echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 +if test "${ac_cv_lib_dl_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main () +{ +dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dl_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dl_dlopen=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 +if test $ac_cv_lib_dl_dlopen = yes; then + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5 +echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6 +if test "${ac_cv_lib_svld_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main () +{ +dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_svld_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_svld_dlopen=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6 +if test $ac_cv_lib_svld_dlopen = yes; then + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" +else + echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5 +echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6 +if test "${ac_cv_lib_dld_dld_link+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dld_link (); +int +main () +{ +dld_link (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dld_dld_link=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dld_dld_link=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5 +echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6 +if test $ac_cv_lib_dld_dld_link = yes; then + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld" +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5 +echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6 +if test "${lt_cv_dlopen_self+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + + exit (status); +} +EOF + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_unknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5 +echo "${ECHO_T}$lt_cv_dlopen_self" >&6 + + if test "x$lt_cv_dlopen_self" = xyes; then + LDFLAGS="$LDFLAGS $link_static_flag" + echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5 +echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6 +if test "${lt_cv_dlopen_self_static+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + + exit (status); +} +EOF + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_unknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5 +echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6 + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + +if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 +echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6 + if test "${lt_cv_archive_cmds_need_lc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + $rm conftest* + echo 'static int dummy;' > conftest.$ac_ext + + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_cv_prog_cc_wl + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { (eval echo "$as_me:$LINENO: \"$archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 + (eval $archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi +fi + + echo "$as_me:$LINENO: result: $lt_cv_archive_cmds_need_lc" >&5 +echo "${ECHO_T}$lt_cv_archive_cmds_need_lc" >&6 + ;; + esac +fi +need_lc=${lt_cv_archive_cmds_need_lc-yes} + +# The second clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + : +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + test -f Makefile && make "$ltmain" +fi + +if test -f "$ltmain"; then + trap "$rm \"${ofile}T\"; exit 1" 1 2 15 + $rm -f "${ofile}T" + + echo creating $ofile + + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS SED \ + AR AR_FLAGS CC LD LN_S NM SHELL \ + reload_flag reload_cmds wl \ + pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \ + thread_safe_flag_spec whole_archive_flag_spec libname_spec \ + library_names_spec soname_spec \ + RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \ + old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds \ + postuninstall_cmds extract_expsyms_cmds old_archive_from_expsyms_cmds \ + old_striplib striplib file_magic_cmd export_symbols_cmds \ + deplibs_check_method allow_undefined_flag no_undefined_flag \ + finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \ + global_symbol_to_c_name_address \ + hardcode_libdir_flag_spec hardcode_libdir_separator \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do + + case $var in + reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + export_symbols_cmds | archive_cmds | archive_expsym_cmds | \ + extract_expsyms_cmds | old_archive_from_expsyms_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + cat <<__EOF__ > "${ofile}T" +#! $SHELL + +# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996-2000 Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit , 1996 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# A sed that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="${SED} -e s/^X//" + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi + +# ### BEGIN LIBTOOL CONFIG + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$need_lc + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# The default C compiler. +CC=$lt_CC + +# Is the compiler the GNU C compiler? +with_gcc=$GCC + +# The linker used to build libraries. +LD=$lt_LD + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_wl + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_pic_flag +pic_mode=$pic_mode + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_compiler_c_o + +# Can we write directly to a .lo ? +compiler_o_lo=$lt_compiler_o_lo + +# Must we lock files when doing compilation ? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_link_static_flag + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_no_builtin_flag + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Compile-time system search path for libraries +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$fix_srcfile_path" + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# ### END LIBTOOL CONFIG + +__EOF__ + + case $host_os in + aix3*) + cat <<\EOF >> "${ofile}T" + +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +EOF + ;; + esac + + case $host_os in + cygwin* | mingw* | pw32* | os2*) + cat <<'EOF' >> "${ofile}T" + # This is a source program that is used to create dlls on Windows + # Don't remove nor modify the starting and closing comments +# /* ltdll.c starts here */ +# #define WIN32_LEAN_AND_MEAN +# #include +# #undef WIN32_LEAN_AND_MEAN +# #include +# +# #ifndef __CYGWIN__ +# # ifdef __CYGWIN32__ +# # define __CYGWIN__ __CYGWIN32__ +# # endif +# #endif +# +# #ifdef __cplusplus +# extern "C" { +# #endif +# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved); +# #ifdef __cplusplus +# } +# #endif +# +# #ifdef __CYGWIN__ +# #include +# DECLARE_CYGWIN_DLL( DllMain ); +# #endif +# HINSTANCE __hDllInstance_base; +# +# BOOL APIENTRY +# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) +# { +# __hDllInstance_base = hInst; +# return TRUE; +# } +# /* ltdll.c ends here */ + # This is a source program that is used to create import libraries + # on Windows for dlls which lack them. Don't remove nor modify the + # starting and closing comments +# /* impgen.c starts here */ +# /* Copyright (C) 1999-2000 Free Software Foundation, Inc. +# +# This file is part of GNU libtool. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# */ +# +# #include /* for printf() */ +# #include /* for open(), lseek(), read() */ +# #include /* for O_RDONLY, O_BINARY */ +# #include /* for strdup() */ +# +# /* O_BINARY isn't required (or even defined sometimes) under Unix */ +# #ifndef O_BINARY +# #define O_BINARY 0 +# #endif +# +# static unsigned int +# pe_get16 (fd, offset) +# int fd; +# int offset; +# { +# unsigned char b[2]; +# lseek (fd, offset, SEEK_SET); +# read (fd, b, 2); +# return b[0] + (b[1]<<8); +# } +# +# static unsigned int +# pe_get32 (fd, offset) +# int fd; +# int offset; +# { +# unsigned char b[4]; +# lseek (fd, offset, SEEK_SET); +# read (fd, b, 4); +# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); +# } +# +# static unsigned int +# pe_as32 (ptr) +# void *ptr; +# { +# unsigned char *b = ptr; +# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); +# } +# +# int +# main (argc, argv) +# int argc; +# char *argv[]; +# { +# int dll; +# unsigned long pe_header_offset, opthdr_ofs, num_entries, i; +# unsigned long export_rva, export_size, nsections, secptr, expptr; +# unsigned long name_rvas, nexp; +# unsigned char *expdata, *erva; +# char *filename, *dll_name; +# +# filename = argv[1]; +# +# dll = open(filename, O_RDONLY|O_BINARY); +# if (dll < 1) +# return 1; +# +# dll_name = filename; +# +# for (i=0; filename[i]; i++) +# if (filename[i] == '/' || filename[i] == '\\' || filename[i] == ':') +# dll_name = filename + i +1; +# +# pe_header_offset = pe_get32 (dll, 0x3c); +# opthdr_ofs = pe_header_offset + 4 + 20; +# num_entries = pe_get32 (dll, opthdr_ofs + 92); +# +# if (num_entries < 1) /* no exports */ +# return 1; +# +# export_rva = pe_get32 (dll, opthdr_ofs + 96); +# export_size = pe_get32 (dll, opthdr_ofs + 100); +# nsections = pe_get16 (dll, pe_header_offset + 4 +2); +# secptr = (pe_header_offset + 4 + 20 + +# pe_get16 (dll, pe_header_offset + 4 + 16)); +# +# expptr = 0; +# for (i = 0; i < nsections; i++) +# { +# char sname[8]; +# unsigned long secptr1 = secptr + 40 * i; +# unsigned long vaddr = pe_get32 (dll, secptr1 + 12); +# unsigned long vsize = pe_get32 (dll, secptr1 + 16); +# unsigned long fptr = pe_get32 (dll, secptr1 + 20); +# lseek(dll, secptr1, SEEK_SET); +# read(dll, sname, 8); +# if (vaddr <= export_rva && vaddr+vsize > export_rva) +# { +# expptr = fptr + (export_rva - vaddr); +# if (export_rva + export_size > vaddr + vsize) +# export_size = vsize - (export_rva - vaddr); +# break; +# } +# } +# +# expdata = (unsigned char*)malloc(export_size); +# lseek (dll, expptr, SEEK_SET); +# read (dll, expdata, export_size); +# erva = expdata - export_rva; +# +# nexp = pe_as32 (expdata+24); +# name_rvas = pe_as32 (expdata+32); +# +# printf ("EXPORTS\n"); +# for (i = 0; i> "${ofile}T" || (rm -f "${ofile}T"; exit 1) + + mv -f "${ofile}T" "$ofile" || \ + (rm -f "$ofile" && cp "${ofile}T" "$ofile" && rm -f "${ofile}T") + chmod +x "$ofile" +fi + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + +# Prevent multiple expansion + + + + +if test -n ""; then + echo "$as_me:$LINENO: checking for intltool >= " >&5 +echo $ECHO_N "checking for intltool >= ... $ECHO_C" >&6 + + INTLTOOL_REQUIRED_VERSION_AS_INT=`echo | awk -F. '{ printf "%d", $1 * 100 + $2; }'` + INTLTOOL_APPLIED_VERSION=`awk -F\" '/\\$VERSION / { printf $2; }' < ${srcdir}/intltool-update.in` + + INTLTOOL_APPLIED_VERSION_AS_INT=`awk -F\" '/\\$VERSION / { split($2, VERSION, "."); printf "%d\n", VERSION[1] * 100 + VERSION[2];}' < ${srcdir}/intltool-update.in` + + + if test "$INTLTOOL_APPLIED_VERSION_AS_INT" -ge "$INTLTOOL_REQUIRED_VERSION_AS_INT"; then + echo "$as_me:$LINENO: result: $INTLTOOL_APPLIED_VERSION found" >&5 +echo "${ECHO_T}$INTLTOOL_APPLIED_VERSION found" >&6 + else + echo "$as_me:$LINENO: result: $INTLTOOL_APPLIED_VERSION found. Your intltool is too old. You need intltool or later." >&5 +echo "${ECHO_T}$INTLTOOL_APPLIED_VERSION found. Your intltool is too old. You need intltool or later." >&6 + exit 1 + fi +fi + + INTLTOOL_DESKTOP_RULE='%.desktop: %.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache' +INTLTOOL_DIRECTORY_RULE='%.directory: %.directory.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache' + INTLTOOL_KEYS_RULE='%.keys: %.keys.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -k -u -c $(top_builddir)/po/.intltool-merge-cache' + INTLTOOL_PROP_RULE='%.prop: %.prop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache' + INTLTOOL_OAF_RULE='%.oaf: %.oaf.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -o -p' + INTLTOOL_PONG_RULE='%.pong: %.pong.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -x -u -c $(top_builddir)/po/.intltool-merge-cache' + INTLTOOL_SERVER_RULE='%.server: %.server.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -o -u -c $(top_builddir)/po/.intltool-merge-cache' + INTLTOOL_SHEET_RULE='%.sheet: %.sheet.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -x -u -c $(top_builddir)/po/.intltool-merge-cache' +INTLTOOL_SOUNDLIST_RULE='%.soundlist: %.soundlist.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache' + INTLTOOL_UI_RULE='%.ui: %.ui.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -x -u -c $(top_builddir)/po/.intltool-merge-cache' + INTLTOOL_XML_RULE='%.xml: %.xml.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -x -u -c $(top_builddir)/po/.intltool-merge-cache' + INTLTOOL_CAVES_RULE='%.caves: %.caves.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache' + INTLTOOL_SCHEMAS_RULE='%.schemas: %.schemas.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -s -u -c $(top_builddir)/po/.intltool-merge-cache' + INTLTOOL_THEME_RULE='%.theme: %.theme.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache' + + + + + + + + + + + + + + + + +# Use the tools built into the package, not the ones that are installed. + +INTLTOOL_EXTRACT='$(top_builddir)/intltool-extract' +INTLTOOL_MERGE='$(top_builddir)/intltool-merge' +INTLTOOL_UPDATE='$(top_builddir)/intltool-update' + + + + + +# Extract the first word of "perl", so it can be a program name with args. +set dummy perl; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_path_INTLTOOL_PERL+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $INTLTOOL_PERL in + [\\/]* | ?:[\\/]*) + ac_cv_path_INTLTOOL_PERL="$INTLTOOL_PERL" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_INTLTOOL_PERL="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + ;; +esac +fi +INTLTOOL_PERL=$ac_cv_path_INTLTOOL_PERL + +if test -n "$INTLTOOL_PERL"; then + echo "$as_me:$LINENO: result: $INTLTOOL_PERL" >&5 +echo "${ECHO_T}$INTLTOOL_PERL" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +if test -z "$INTLTOOL_PERL"; then + { { echo "$as_me:$LINENO: error: perl not found; required for intltool" >&5 +echo "$as_me: error: perl not found; required for intltool" >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "`$INTLTOOL_PERL -v | fgrep '5.' 2> /dev/null`"; then + { { echo "$as_me:$LINENO: error: perl 5.x required for intltool" >&5 +echo "$as_me: error: perl 5.x required for intltool" >&2;} + { (exit 1); exit 1; }; } +fi + +# Remove file type tags (using []) from po/POTFILES. + + + + + + + +# Manually sed perl in so people don't have to put the intltool scripts in AC_OUTPUT. + + ac_config_commands="$ac_config_commands default-2" + + + + +BONOBO_ACTIVATION_REQUIRED=1.0.0 +BONOBO_REQUIRED=2.0.0 +GCONF_REQUIRED=1.1.1 +GLIB_REQUIRED=2.0.0 +ORBIT_REQUIRED=2.4.0 +XML_REQUIRED=2.2.8 + + + + + + + + + + + succeeded=no + + if test -z "$PKG_CONFIG"; then + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_path_PKG_CONFIG+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no" + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG + +if test -n "$PKG_CONFIG"; then + echo "$as_me:$LINENO: result: $PKG_CONFIG" >&5 +echo "${ECHO_T}$PKG_CONFIG" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + fi + + if test "$PKG_CONFIG" = "no" ; then + echo "*** The pkg-config script could not be found. Make sure it is" + echo "*** in your path, or set the PKG_CONFIG environment variable" + echo "*** to the full path to pkg-config." + echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config." + else + PKG_CONFIG_MIN_VERSION=0.9.0 + if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then + echo "$as_me:$LINENO: checking for glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED libxml-2.0 >= $XML_REQUIRED" >&5 +echo $ECHO_N "checking for glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED libxml-2.0 >= $XML_REQUIRED... $ECHO_C" >&6 + + if $PKG_CONFIG --exists "glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED libxml-2.0 >= $XML_REQUIRED" ; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + succeeded=yes + + echo "$as_me:$LINENO: checking MODULES_XML_CFLAGS" >&5 +echo $ECHO_N "checking MODULES_XML_CFLAGS... $ECHO_C" >&6 + MODULES_XML_CFLAGS=`$PKG_CONFIG --cflags "glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED libxml-2.0 >= $XML_REQUIRED"` + echo "$as_me:$LINENO: result: $MODULES_XML_CFLAGS" >&5 +echo "${ECHO_T}$MODULES_XML_CFLAGS" >&6 + + echo "$as_me:$LINENO: checking MODULES_XML_LIBS" >&5 +echo $ECHO_N "checking MODULES_XML_LIBS... $ECHO_C" >&6 + MODULES_XML_LIBS=`$PKG_CONFIG --libs "glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED libxml-2.0 >= $XML_REQUIRED"` + echo "$as_me:$LINENO: result: $MODULES_XML_LIBS" >&5 +echo "${ECHO_T}$MODULES_XML_LIBS" >&6 + else + MODULES_XML_CFLAGS="" + MODULES_XML_LIBS="" + ## If we have a custom action on failure, don't print errors, but + ## do set a variable so people can do so. + MODULES_XML_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED libxml-2.0 >= $XML_REQUIRED"` + echo $MODULES_XML_PKG_ERRORS + fi + + + + else + echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer." + echo "*** See http://www.freedesktop.org/software/pkgconfig" + fi + fi + + if test $succeeded = yes; then + : + else + { { echo "$as_me:$LINENO: error: Library requirements (glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED libxml-2.0 >= $XML_REQUIRED) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them." >&5 +echo "$as_me: error: Library requirements (glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED libxml-2.0 >= $XML_REQUIRED) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them." >&2;} + { (exit 1); exit 1; }; } + fi + + + + + + succeeded=no + + if test -z "$PKG_CONFIG"; then + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_path_PKG_CONFIG+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no" + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG + +if test -n "$PKG_CONFIG"; then + echo "$as_me:$LINENO: result: $PKG_CONFIG" >&5 +echo "${ECHO_T}$PKG_CONFIG" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + fi + + if test "$PKG_CONFIG" = "no" ; then + echo "*** The pkg-config script could not be found. Make sure it is" + echo "*** in your path, or set the PKG_CONFIG environment variable" + echo "*** to the full path to pkg-config." + echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config." + else + PKG_CONFIG_MIN_VERSION=0.9.0 + if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then + echo "$as_me:$LINENO: checking for glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED" >&5 +echo $ECHO_N "checking for glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED... $ECHO_C" >&6 + + if $PKG_CONFIG --exists "glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED" ; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + succeeded=yes + + echo "$as_me:$LINENO: checking MODULES_CFLAGS" >&5 +echo $ECHO_N "checking MODULES_CFLAGS... $ECHO_C" >&6 + MODULES_CFLAGS=`$PKG_CONFIG --cflags "glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED"` + echo "$as_me:$LINENO: result: $MODULES_CFLAGS" >&5 +echo "${ECHO_T}$MODULES_CFLAGS" >&6 + + echo "$as_me:$LINENO: checking MODULES_LIBS" >&5 +echo $ECHO_N "checking MODULES_LIBS... $ECHO_C" >&6 + MODULES_LIBS=`$PKG_CONFIG --libs "glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED"` + echo "$as_me:$LINENO: result: $MODULES_LIBS" >&5 +echo "${ECHO_T}$MODULES_LIBS" >&6 + else + MODULES_CFLAGS="" + MODULES_LIBS="" + ## If we have a custom action on failure, don't print errors, but + ## do set a variable so people can do so. + MODULES_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED"` + echo $MODULES_PKG_ERRORS + fi + + + + else + echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer." + echo "*** See http://www.freedesktop.org/software/pkgconfig" + fi + fi + + if test $succeeded = yes; then + : + else + { { echo "$as_me:$LINENO: error: Library requirements (glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them." >&5 +echo "$as_me: error: Library requirements (glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them." >&2;} + { (exit 1); exit 1; }; } + fi + + + + + + succeeded=no + + if test -z "$PKG_CONFIG"; then + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_path_PKG_CONFIG+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no" + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG + +if test -n "$PKG_CONFIG"; then + echo "$as_me:$LINENO: result: $PKG_CONFIG" >&5 +echo "${ECHO_T}$PKG_CONFIG" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + fi + + if test "$PKG_CONFIG" = "no" ; then + echo "*** The pkg-config script could not be found. Make sure it is" + echo "*** in your path, or set the PKG_CONFIG environment variable" + echo "*** to the full path to pkg-config." + echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config." + else + PKG_CONFIG_MIN_VERSION=0.9.0 + if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then + echo "$as_me:$LINENO: checking for glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED" >&5 +echo $ECHO_N "checking for glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED... $ECHO_C" >&6 + + if $PKG_CONFIG --exists "glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED" ; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + succeeded=yes + + echo "$as_me:$LINENO: checking MODULES_FILE_CFLAGS" >&5 +echo $ECHO_N "checking MODULES_FILE_CFLAGS... $ECHO_C" >&6 + MODULES_FILE_CFLAGS=`$PKG_CONFIG --cflags "glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED"` + echo "$as_me:$LINENO: result: $MODULES_FILE_CFLAGS" >&5 +echo "${ECHO_T}$MODULES_FILE_CFLAGS" >&6 + + echo "$as_me:$LINENO: checking MODULES_FILE_LIBS" >&5 +echo $ECHO_N "checking MODULES_FILE_LIBS... $ECHO_C" >&6 + MODULES_FILE_LIBS=`$PKG_CONFIG --libs "glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED"` + echo "$as_me:$LINENO: result: $MODULES_FILE_LIBS" >&5 +echo "${ECHO_T}$MODULES_FILE_LIBS" >&6 + else + MODULES_FILE_CFLAGS="" + MODULES_FILE_LIBS="" + ## If we have a custom action on failure, don't print errors, but + ## do set a variable so people can do so. + MODULES_FILE_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED"` + echo $MODULES_FILE_PKG_ERRORS + fi + + + + else + echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer." + echo "*** See http://www.freedesktop.org/software/pkgconfig" + fi + fi + + if test $succeeded = yes; then + : + else + { { echo "$as_me:$LINENO: error: Library requirements (glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them." >&5 +echo "$as_me: error: Library requirements (glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them." >&2;} + { (exit 1); exit 1; }; } + fi + + + + + + succeeded=no + + if test -z "$PKG_CONFIG"; then + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_path_PKG_CONFIG+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no" + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG + +if test -n "$PKG_CONFIG"; then + echo "$as_me:$LINENO: result: $PKG_CONFIG" >&5 +echo "${ECHO_T}$PKG_CONFIG" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + fi + + if test "$PKG_CONFIG" = "no" ; then + echo "*** The pkg-config script could not be found. Make sure it is" + echo "*** in your path, or set the PKG_CONFIG environment variable" + echo "*** to the full path to pkg-config." + echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config." + else + PKG_CONFIG_MIN_VERSION=0.9.0 + if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then + echo "$as_me:$LINENO: checking for glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED gconf-2.0 >= $GCONF_REQUIRED" >&5 +echo $ECHO_N "checking for glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED gconf-2.0 >= $GCONF_REQUIRED... $ECHO_C" >&6 + + if $PKG_CONFIG --exists "glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED gconf-2.0 >= $GCONF_REQUIRED" ; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + succeeded=yes + + echo "$as_me:$LINENO: checking MODULES_GCONF_CFLAGS" >&5 +echo $ECHO_N "checking MODULES_GCONF_CFLAGS... $ECHO_C" >&6 + MODULES_GCONF_CFLAGS=`$PKG_CONFIG --cflags "glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED gconf-2.0 >= $GCONF_REQUIRED"` + echo "$as_me:$LINENO: result: $MODULES_GCONF_CFLAGS" >&5 +echo "${ECHO_T}$MODULES_GCONF_CFLAGS" >&6 + + echo "$as_me:$LINENO: checking MODULES_GCONF_LIBS" >&5 +echo $ECHO_N "checking MODULES_GCONF_LIBS... $ECHO_C" >&6 + MODULES_GCONF_LIBS=`$PKG_CONFIG --libs "glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED gconf-2.0 >= $GCONF_REQUIRED"` + echo "$as_me:$LINENO: result: $MODULES_GCONF_LIBS" >&5 +echo "${ECHO_T}$MODULES_GCONF_LIBS" >&6 + else + MODULES_GCONF_CFLAGS="" + MODULES_GCONF_LIBS="" + ## If we have a custom action on failure, don't print errors, but + ## do set a variable so people can do so. + MODULES_GCONF_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED gconf-2.0 >= $GCONF_REQUIRED"` + echo $MODULES_GCONF_PKG_ERRORS + fi + + + + else + echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer." + echo "*** See http://www.freedesktop.org/software/pkgconfig" + fi + fi + + if test $succeeded = yes; then + : + else + { { echo "$as_me:$LINENO: error: Library requirements (glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED gconf-2.0 >= $GCONF_REQUIRED) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them." >&5 +echo "$as_me: error: Library requirements (glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED gconf-2.0 >= $GCONF_REQUIRED) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them." >&2;} + { (exit 1); exit 1; }; } + fi + + + + + + succeeded=no + + if test -z "$PKG_CONFIG"; then + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_path_PKG_CONFIG+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no" + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG + +if test -n "$PKG_CONFIG"; then + echo "$as_me:$LINENO: result: $PKG_CONFIG" >&5 +echo "${ECHO_T}$PKG_CONFIG" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + fi + + if test "$PKG_CONFIG" = "no" ; then + echo "*** The pkg-config script could not be found. Make sure it is" + echo "*** in your path, or set the PKG_CONFIG environment variable" + echo "*** to the full path to pkg-config." + echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config." + else + PKG_CONFIG_MIN_VERSION=0.9.0 + if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then + echo "$as_me:$LINENO: checking for glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED libxml-2.0 >= $XML_REQUIRED gconf-2.0 >= $GCONF_REQUIRED" >&5 +echo $ECHO_N "checking for glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED libxml-2.0 >= $XML_REQUIRED gconf-2.0 >= $GCONF_REQUIRED... $ECHO_C" >&6 + + if $PKG_CONFIG --exists "glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED libxml-2.0 >= $XML_REQUIRED gconf-2.0 >= $GCONF_REQUIRED" ; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + succeeded=yes + + echo "$as_me:$LINENO: checking MODULES_XML_GCONF_CFLAGS" >&5 +echo $ECHO_N "checking MODULES_XML_GCONF_CFLAGS... $ECHO_C" >&6 + MODULES_XML_GCONF_CFLAGS=`$PKG_CONFIG --cflags "glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED libxml-2.0 >= $XML_REQUIRED gconf-2.0 >= $GCONF_REQUIRED"` + echo "$as_me:$LINENO: result: $MODULES_XML_GCONF_CFLAGS" >&5 +echo "${ECHO_T}$MODULES_XML_GCONF_CFLAGS" >&6 + + echo "$as_me:$LINENO: checking MODULES_XML_GCONF_LIBS" >&5 +echo $ECHO_N "checking MODULES_XML_GCONF_LIBS... $ECHO_C" >&6 + MODULES_XML_GCONF_LIBS=`$PKG_CONFIG --libs "glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED libxml-2.0 >= $XML_REQUIRED gconf-2.0 >= $GCONF_REQUIRED"` + echo "$as_me:$LINENO: result: $MODULES_XML_GCONF_LIBS" >&5 +echo "${ECHO_T}$MODULES_XML_GCONF_LIBS" >&6 + else + MODULES_XML_GCONF_CFLAGS="" + MODULES_XML_GCONF_LIBS="" + ## If we have a custom action on failure, don't print errors, but + ## do set a variable so people can do so. + MODULES_XML_GCONF_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED libxml-2.0 >= $XML_REQUIRED gconf-2.0 >= $GCONF_REQUIRED"` + echo $MODULES_XML_GCONF_PKG_ERRORS + fi + + + + else + echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer." + echo "*** See http://www.freedesktop.org/software/pkgconfig" + fi + fi + + if test $succeeded = yes; then + : + else + { { echo "$as_me:$LINENO: error: Library requirements (glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED libxml-2.0 >= $XML_REQUIRED gconf-2.0 >= $GCONF_REQUIRED) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them." >&5 +echo "$as_me: error: Library requirements (glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED libxml-2.0 >= $XML_REQUIRED gconf-2.0 >= $GCONF_REQUIRED) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them." >&2;} + { (exit 1); exit 1; }; } + fi + + + + + + succeeded=no + + if test -z "$PKG_CONFIG"; then + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_path_PKG_CONFIG+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no" + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG + +if test -n "$PKG_CONFIG"; then + echo "$as_me:$LINENO: result: $PKG_CONFIG" >&5 +echo "${ECHO_T}$PKG_CONFIG" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + fi + + if test "$PKG_CONFIG" = "no" ; then + echo "*** The pkg-config script could not be found. Make sure it is" + echo "*** in your path, or set the PKG_CONFIG environment variable" + echo "*** to the full path to pkg-config." + echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config." + else + PKG_CONFIG_MIN_VERSION=0.9.0 + if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then + echo "$as_me:$LINENO: checking for libbonobo-2.0 >= $BONOBO_REQUIRED" >&5 +echo $ECHO_N "checking for libbonobo-2.0 >= $BONOBO_REQUIRED... $ECHO_C" >&6 + + if $PKG_CONFIG --exists "libbonobo-2.0 >= $BONOBO_REQUIRED" ; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + succeeded=yes + + echo "$as_me:$LINENO: checking MONIKERS_CFLAGS" >&5 +echo $ECHO_N "checking MONIKERS_CFLAGS... $ECHO_C" >&6 + MONIKERS_CFLAGS=`$PKG_CONFIG --cflags "libbonobo-2.0 >= $BONOBO_REQUIRED"` + echo "$as_me:$LINENO: result: $MONIKERS_CFLAGS" >&5 +echo "${ECHO_T}$MONIKERS_CFLAGS" >&6 + + echo "$as_me:$LINENO: checking MONIKERS_LIBS" >&5 +echo $ECHO_N "checking MONIKERS_LIBS... $ECHO_C" >&6 + MONIKERS_LIBS=`$PKG_CONFIG --libs "libbonobo-2.0 >= $BONOBO_REQUIRED"` + echo "$as_me:$LINENO: result: $MONIKERS_LIBS" >&5 +echo "${ECHO_T}$MONIKERS_LIBS" >&6 + else + MONIKERS_CFLAGS="" + MONIKERS_LIBS="" + ## If we have a custom action on failure, don't print errors, but + ## do set a variable so people can do so. + MONIKERS_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "libbonobo-2.0 >= $BONOBO_REQUIRED"` + echo $MONIKERS_PKG_ERRORS + fi + + + + else + echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer." + echo "*** See http://www.freedesktop.org/software/pkgconfig" + fi + fi + + if test $succeeded = yes; then + : + else + { { echo "$as_me:$LINENO: error: Library requirements (libbonobo-2.0 >= $BONOBO_REQUIRED) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them." >&5 +echo "$as_me: error: Library requirements (libbonobo-2.0 >= $BONOBO_REQUIRED) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them." >&2;} + { (exit 1); exit 1; }; } + fi + + + + + + succeeded=no + + if test -z "$PKG_CONFIG"; then + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_path_PKG_CONFIG+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no" + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG + +if test -n "$PKG_CONFIG"; then + echo "$as_me:$LINENO: result: $PKG_CONFIG" >&5 +echo "${ECHO_T}$PKG_CONFIG" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + fi + + if test "$PKG_CONFIG" = "no" ; then + echo "*** The pkg-config script could not be found. Make sure it is" + echo "*** in your path, or set the PKG_CONFIG environment variable" + echo "*** to the full path to pkg-config." + echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config." + else + PKG_CONFIG_MIN_VERSION=0.9.0 + if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then + echo "$as_me:$LINENO: checking for bonobo-activation-2.0 >= $BONOBO_ACTIVATION_REQUIRED gconf-2.0 >= $GCONF_REQUIRED gthread-2.0 >= $GLIB_REQUIRED" >&5 +echo $ECHO_N "checking for bonobo-activation-2.0 >= $BONOBO_ACTIVATION_REQUIRED gconf-2.0 >= $GCONF_REQUIRED gthread-2.0 >= $GLIB_REQUIRED... $ECHO_C" >&6 + + if $PKG_CONFIG --exists "bonobo-activation-2.0 >= $BONOBO_ACTIVATION_REQUIRED gconf-2.0 >= $GCONF_REQUIRED gthread-2.0 >= $GLIB_REQUIRED" ; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + succeeded=yes + + echo "$as_me:$LINENO: checking TEST_CFLAGS" >&5 +echo $ECHO_N "checking TEST_CFLAGS... $ECHO_C" >&6 + TEST_CFLAGS=`$PKG_CONFIG --cflags "bonobo-activation-2.0 >= $BONOBO_ACTIVATION_REQUIRED gconf-2.0 >= $GCONF_REQUIRED gthread-2.0 >= $GLIB_REQUIRED"` + echo "$as_me:$LINENO: result: $TEST_CFLAGS" >&5 +echo "${ECHO_T}$TEST_CFLAGS" >&6 + + echo "$as_me:$LINENO: checking TEST_LIBS" >&5 +echo $ECHO_N "checking TEST_LIBS... $ECHO_C" >&6 + TEST_LIBS=`$PKG_CONFIG --libs "bonobo-activation-2.0 >= $BONOBO_ACTIVATION_REQUIRED gconf-2.0 >= $GCONF_REQUIRED gthread-2.0 >= $GLIB_REQUIRED"` + echo "$as_me:$LINENO: result: $TEST_LIBS" >&5 +echo "${ECHO_T}$TEST_LIBS" >&6 + else + TEST_CFLAGS="" + TEST_LIBS="" + ## If we have a custom action on failure, don't print errors, but + ## do set a variable so people can do so. + TEST_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "bonobo-activation-2.0 >= $BONOBO_ACTIVATION_REQUIRED gconf-2.0 >= $GCONF_REQUIRED gthread-2.0 >= $GLIB_REQUIRED"` + echo $TEST_PKG_ERRORS + fi + + + + else + echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer." + echo "*** See http://www.freedesktop.org/software/pkgconfig" + fi + fi + + if test $succeeded = yes; then + : + else + { { echo "$as_me:$LINENO: error: Library requirements (bonobo-activation-2.0 >= $BONOBO_ACTIVATION_REQUIRED gconf-2.0 >= $GCONF_REQUIRED gthread-2.0 >= $GLIB_REQUIRED) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them." >&5 +echo "$as_me: error: Library requirements (bonobo-activation-2.0 >= $BONOBO_ACTIVATION_REQUIRED gconf-2.0 >= $GCONF_REQUIRED gthread-2.0 >= $GLIB_REQUIRED) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them." >&2;} + { (exit 1); exit 1; }; } + fi + + + + +ORBIT_IDL="`$PKG_CONFIG --variable=orbit_idl ORBit-2.0`" + + +BONOBO_IDLDIR="`$PKG_CONFIG --variable=idldir bonobo-activation-2.0`" + + +cflags_set=yes + + + if test -z "" ; then + default_compile_warnings=yes + else + default_compile_warnings="" + fi + + # Check whether --enable-compile-warnings or --disable-compile-warnings was given. +if test "${enable_compile_warnings+set}" = set; then + enableval="$enable_compile_warnings" + +else + enable_compile_warnings="$default_compile_warnings" +fi; + + warnCFLAGS= + if test "x$GCC" != xyes; then + enable_compile_warnings=no + fi + + warning_flags= + realsave_CFLAGS="$CFLAGS" + + case "$enable_compile_warnings" in + no) + warning_flags= + ;; + minimum) + warning_flags="-Wall" + ;; + yes) + warning_flags="-Wall -Wmissing-prototypes" + ;; + maximum|error) + warning_flags="-Wall -Wmissing-prototypes -Wnested-externs -Wpointer-arith" + CFLAGS="$warning_flags $CFLAGS" + for option in -Wno-sign-compare; do + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $option" + echo "$as_me:$LINENO: checking whether gcc understands $option" >&5 +echo $ECHO_N "checking whether gcc understands $option... $ECHO_C" >&6 + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + has_option=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +has_option=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext + CFLAGS="$SAVE_CFLAGS" + echo "$as_me:$LINENO: result: $has_option" >&5 +echo "${ECHO_T}$has_option" >&6 + if test $has_option = yes; then + warning_flags="$warning_flags $option" + fi + unset has_option + unset SAVE_CFLAGS + done + unset option + if test "$enable_compile_warnings" = "error" ; then + warning_flags="$warning_flags -Werror" + fi + ;; + *) + { { echo "$as_me:$LINENO: error: Unknown argument '$enable_compile_warnings' to --enable-compile-warnings" >&5 +echo "$as_me: error: Unknown argument '$enable_compile_warnings' to --enable-compile-warnings" >&2;} + { (exit 1); exit 1; }; } + ;; + esac + CFLAGS="$realsave_CFLAGS" + echo "$as_me:$LINENO: checking what warning flags to pass to the C compiler" >&5 +echo $ECHO_N "checking what warning flags to pass to the C compiler... $ECHO_C" >&6 + echo "$as_me:$LINENO: result: $warning_flags" >&5 +echo "${ECHO_T}$warning_flags" >&6 + + # Check whether --enable-iso-c or --disable-iso-c was given. +if test "${enable_iso_c+set}" = set; then + enableval="$enable_iso_c" + +else + enable_iso_c=no +fi; + + echo "$as_me:$LINENO: checking what language compliance flags to pass to the C compiler" >&5 +echo $ECHO_N "checking what language compliance flags to pass to the C compiler... $ECHO_C" >&6 + complCFLAGS= + if test "x$enable_iso_c" != "xno"; then + if test "x$GCC" = "xyes"; then + case " $CFLAGS " in + *\ \ -ansi\ \ *) ;; + *) complCFLAGS="$complCFLAGS -ansi" ;; + esac + case " $CFLAGS " in + *\ \ -pedantic\ \ *) ;; + *) complCFLAGS="$complCFLAGS -pedantic" ;; + esac + fi + fi + echo "$as_me:$LINENO: result: $complCFLAGS" >&5 +echo "${ECHO_T}$complCFLAGS" >&6 + + WARN_CFLAGS="$warning_flags $complCFLAGS" + + +VFS_CFLAGS="$warnCFLAGS $complCFLAGS" + + + +echo "$as_me:$LINENO: checking for sem_wait in -lrt" >&5 +echo $ECHO_N "checking for sem_wait in -lrt... $ECHO_C" >&6 +if test "${ac_cv_lib_rt_sem_wait+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lrt $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char sem_wait (); +int +main () +{ +sem_wait (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_rt_sem_wait=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_rt_sem_wait=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_rt_sem_wait" >&5 +echo "${ECHO_T}$ac_cv_lib_rt_sem_wait" >&6 +if test $ac_cv_lib_rt_sem_wait = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBRT 1 +_ACEOF + + LIBS="-lrt $LIBS" + +fi + + +echo "$as_me:$LINENO: checking size_t in " >&5 +echo $ECHO_N "checking size_t in ... $ECHO_C" >&6 +if test "${ac_cv_type_size_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#if STDC_HEADERS +#include +#include +#endif + +int +main () +{ +size_t foo; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_size_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_size_t=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 +echo "${ECHO_T}$ac_cv_type_size_t" >&6 + if test $ac_cv_type_size_t = no; then + +cat >>confdefs.h <<\_ACEOF +#define size_t unsigned +_ACEOF + + fi + + + +echo "$as_me:$LINENO: checking off_t in " >&5 +echo $ECHO_N "checking off_t in ... $ECHO_C" >&6 +if test "${ac_cv_type_off_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#if STDC_HEADERS +#include +#include +#endif + +int +main () +{ +off_t foo; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_off_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_off_t=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_off_t" >&5 +echo "${ECHO_T}$ac_cv_type_off_t" >&6 + if test $ac_cv_type_off_t = no; then + +cat >>confdefs.h <<\_ACEOF +#define off_t long +_ACEOF + + fi + + + + +echo "$as_me:$LINENO: checking for off64_t" >&5 +echo $ECHO_N "checking for off64_t... $ECHO_C" >&6 +if test "${ac_cv_have_off64_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +# define _LARGEFILE64_SOURCE +# include +int +main () +{ +off64_t testoffset + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_have_off64_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_have_off64_t=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_have_off64_t" >&5 +echo "${ECHO_T}$ac_cv_have_off64_t" >&6 +if test x"$ac_cv_have_off64_t" = "xyes" ; then + cat >>confdefs.h <<\_ACEOF +#define HAVE_OFF64_T 1 +_ACEOF + +fi + +GETTEXT_PACKAGE=gnome-vfs-2.0 + +cat >>confdefs.h <<_ACEOF +#define GETTEXT_PACKAGE "$GETTEXT_PACKAGE" +_ACEOF + + +ALL_LINGUAS="am ar az be bg bn bs ca cs cy da de el eo es et eu fa fi fr ga gl he hi hu id is it ja ko li lt lv mk ml mn ms nl nn no pl pt pt_BR ro ru sk sl sq sr sr@Latn sv tr uk vi wa yi zh_CN zh_TW" + + +for ac_header in locale.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc in + yes:no ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to bug-autoconf@gnu.org. ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; + no:yes ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to bug-autoconf@gnu.org. ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + if test $ac_cv_header_locale_h = yes; then + echo "$as_me:$LINENO: checking for LC_MESSAGES" >&5 +echo $ECHO_N "checking for LC_MESSAGES... $ECHO_C" >&6 +if test "${am_cv_val_LC_MESSAGES+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ +return LC_MESSAGES + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + am_cv_val_LC_MESSAGES=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +am_cv_val_LC_MESSAGES=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $am_cv_val_LC_MESSAGES" >&5 +echo "${ECHO_T}$am_cv_val_LC_MESSAGES" >&6 + if test $am_cv_val_LC_MESSAGES = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_LC_MESSAGES 1 +_ACEOF + + fi + fi + USE_NLS=yes + + + gt_cv_have_gettext=no + + CATOBJEXT=NONE + XGETTEXT=: + INTLLIBS= + + if test "${ac_cv_header_libintl_h+set}" = set; then + echo "$as_me:$LINENO: checking for libintl.h" >&5 +echo $ECHO_N "checking for libintl.h... $ECHO_C" >&6 +if test "${ac_cv_header_libintl_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: $ac_cv_header_libintl_h" >&5 +echo "${ECHO_T}$ac_cv_header_libintl_h" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking libintl.h usability" >&5 +echo $ECHO_N "checking libintl.h usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking libintl.h presence" >&5 +echo $ECHO_N "checking libintl.h presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc in + yes:no ) + { echo "$as_me:$LINENO: WARNING: libintl.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: libintl.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: libintl.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: libintl.h: proceeding with the preprocessor's result" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to bug-autoconf@gnu.org. ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; + no:yes ) + { echo "$as_me:$LINENO: WARNING: libintl.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: libintl.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: libintl.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: libintl.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: libintl.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: libintl.h: proceeding with the preprocessor's result" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to bug-autoconf@gnu.org. ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for libintl.h" >&5 +echo $ECHO_N "checking for libintl.h... $ECHO_C" >&6 +if test "${ac_cv_header_libintl_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_libintl_h=$ac_header_preproc +fi +echo "$as_me:$LINENO: result: $ac_cv_header_libintl_h" >&5 +echo "${ECHO_T}$ac_cv_header_libintl_h" >&6 + +fi +if test $ac_cv_header_libintl_h = yes; then + gt_cv_func_dgettext_libintl="no" + libintl_extra_libs="" + + # + # First check in libc + # + echo "$as_me:$LINENO: checking for dgettext in libc" >&5 +echo $ECHO_N "checking for dgettext in libc... $ECHO_C" >&6 +if test "${gt_cv_func_dgettext_libc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include + +int +main () +{ +return (int) dgettext ("","") + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + gt_cv_func_dgettext_libc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +gt_cv_func_dgettext_libc=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext + +fi +echo "$as_me:$LINENO: result: $gt_cv_func_dgettext_libc" >&5 +echo "${ECHO_T}$gt_cv_func_dgettext_libc" >&6 + + if test "$gt_cv_func_dgettext_libc" = "yes" ; then + +for ac_func in bind_textdomain_codeset +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ +#ifdef __STDC__ +# include +#else +# include +#endif +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + fi + + # + # If we don't have everything we want, check in libintl + # + if test "$gt_cv_func_dgettext_libc" != "yes" \ + || test "$ac_cv_func_bind_textdomain_codeset" != "yes" ; then + + echo "$as_me:$LINENO: checking for bindtextdomain in -lintl" >&5 +echo $ECHO_N "checking for bindtextdomain in -lintl... $ECHO_C" >&6 +if test "${ac_cv_lib_intl_bindtextdomain+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lintl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char bindtextdomain (); +int +main () +{ +bindtextdomain (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_intl_bindtextdomain=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_intl_bindtextdomain=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_intl_bindtextdomain" >&5 +echo "${ECHO_T}$ac_cv_lib_intl_bindtextdomain" >&6 +if test $ac_cv_lib_intl_bindtextdomain = yes; then + echo "$as_me:$LINENO: checking for dgettext in -lintl" >&5 +echo $ECHO_N "checking for dgettext in -lintl... $ECHO_C" >&6 +if test "${ac_cv_lib_intl_dgettext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lintl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dgettext (); +int +main () +{ +dgettext (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_intl_dgettext=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_intl_dgettext=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_intl_dgettext" >&5 +echo "${ECHO_T}$ac_cv_lib_intl_dgettext" >&6 +if test $ac_cv_lib_intl_dgettext = yes; then + gt_cv_func_dgettext_libintl=yes +fi + +fi + + + if test "$gt_cv_func_dgettext_libintl" != "yes" ; then + echo "$as_me:$LINENO: checking if -liconv is needed to use gettext" >&5 +echo $ECHO_N "checking if -liconv is needed to use gettext... $ECHO_C" >&6 + echo "$as_me:$LINENO: result: " >&5 +echo "${ECHO_T}" >&6 + echo "$as_me:$LINENO: checking for dcgettext in -lintl" >&5 +echo $ECHO_N "checking for dcgettext in -lintl... $ECHO_C" >&6 +if test "${ac_cv_lib_intl_dcgettext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lintl -liconv $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dcgettext (); +int +main () +{ +dcgettext (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_intl_dcgettext=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_intl_dcgettext=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_intl_dcgettext" >&5 +echo "${ECHO_T}$ac_cv_lib_intl_dcgettext" >&6 +if test $ac_cv_lib_intl_dcgettext = yes; then + gt_cv_func_dgettext_libintl=yes + libintl_extra_libs=-liconv +else + : +fi + + fi + + # + # If we found libintl, then check in it for bind_textdomain_codeset(); + # we'll prefer libc if neither have bind_textdomain_codeset(), + # and both have dgettext + # + if test "$gt_cv_func_dgettext_libintl" = "yes" ; then + glib_save_LIBS="$LIBS" + LIBS="$LIBS -lintl $libintl_extra_libs" + unset ac_cv_func_bind_textdomain_codeset + +for ac_func in bind_textdomain_codeset +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ +#ifdef __STDC__ +# include +#else +# include +#endif +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + LIBS="$glib_save_LIBS" + + if test "$ac_cv_func_bind_textdomain_codeset" = "yes" ; then + gt_cv_func_dgettext_libc=no + else + if test "$gt_cv_func_dgettext_libc" = "yes"; then + gt_cv_func_dgettext_libintl=no + fi + fi + fi + fi + + if test "$gt_cv_func_dgettext_libc" = "yes" \ + || test "$gt_cv_func_dgettext_libintl" = "yes"; then + gt_cv_have_gettext=yes + fi + + if test "$gt_cv_func_dgettext_libintl" = "yes"; then + INTLLIBS="-lintl $libintl_extra_libs" + fi + + if test "$gt_cv_have_gettext" = "yes"; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_GETTEXT 1 +_ACEOF + + # Extract the first word of "msgfmt", so it can be a program name with args. +set dummy msgfmt; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_path_MSGFMT+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case "$MSGFMT" in + /*) + ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then + ac_cv_path_MSGFMT="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="no" + ;; +esac +fi +MSGFMT="$ac_cv_path_MSGFMT" +if test "$MSGFMT" != "no"; then + echo "$as_me:$LINENO: result: $MSGFMT" >&5 +echo "${ECHO_T}$MSGFMT" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + if test "$MSGFMT" != "no"; then + +for ac_func in dcgettext +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ +#ifdef __STDC__ +# include +#else +# include +#endif +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + # Extract the first word of "gmsgfmt", so it can be a program name with args. +set dummy gmsgfmt; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_path_GMSGFMT+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $GMSGFMT in + [\\/]* | ?:[\\/]*) + ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_GMSGFMT="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT" + ;; +esac +fi +GMSGFMT=$ac_cv_path_GMSGFMT + +if test -n "$GMSGFMT"; then + echo "$as_me:$LINENO: result: $GMSGFMT" >&5 +echo "${ECHO_T}$GMSGFMT" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + # Extract the first word of "xgettext", so it can be a program name with args. +set dummy xgettext; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_path_XGETTEXT+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case "$XGETTEXT" in + /*) + ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then + ac_cv_path_XGETTEXT="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":" + ;; +esac +fi +XGETTEXT="$ac_cv_path_XGETTEXT" +if test "$XGETTEXT" != ":"; then + echo "$as_me:$LINENO: result: $XGETTEXT" >&5 +echo "${ECHO_T}$XGETTEXT" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +extern int _nl_msg_cat_cntr; + return _nl_msg_cat_cntr + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + CATOBJEXT=.gmo + DATADIRNAME=share +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +case $host in + *-*-solaris*) + echo "$as_me:$LINENO: checking for bind_textdomain_codeset" >&5 +echo $ECHO_N "checking for bind_textdomain_codeset... $ECHO_C" >&6 +if test "${ac_cv_func_bind_textdomain_codeset+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char bind_textdomain_codeset (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ +#ifdef __STDC__ +# include +#else +# include +#endif +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char bind_textdomain_codeset (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_bind_textdomain_codeset) || defined (__stub___bind_textdomain_codeset) +choke me +#else +char (*f) () = bind_textdomain_codeset; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != bind_textdomain_codeset; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_bind_textdomain_codeset=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_bind_textdomain_codeset=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_bind_textdomain_codeset" >&5 +echo "${ECHO_T}$ac_cv_func_bind_textdomain_codeset" >&6 +if test $ac_cv_func_bind_textdomain_codeset = yes; then + CATOBJEXT=.gmo + DATADIRNAME=share +else + CATOBJEXT=.mo + DATADIRNAME=lib +fi + + ;; + *) + CATOBJEXT=.mo + DATADIRNAME=lib + ;; + esac +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext + INSTOBJEXT=.mo + else + gt_cv_have_gettext=no + fi + fi + +fi + + + + if test "$gt_cv_have_gettext" = "yes" ; then + +cat >>confdefs.h <<\_ACEOF +#define ENABLE_NLS 1 +_ACEOF + + fi + + if test "$XGETTEXT" != ":"; then + if $XGETTEXT --omit-header /dev/null 2> /dev/null; then + : ; + else + echo "$as_me:$LINENO: result: found xgettext program is not GNU xgettext; ignore it" >&5 +echo "${ECHO_T}found xgettext program is not GNU xgettext; ignore it" >&6 + XGETTEXT=":" + fi + fi + + # We need to process the po/ directory. + POSUB=po + + ac_config_commands="$ac_config_commands default-3" + + + for lang in $ALL_LINGUAS; do + GMOFILES="$GMOFILES $lang.gmo" + POFILES="$POFILES $lang.po" + done + + + + + + + + + + + + + + if test "$gt_cv_have_gettext" = "yes"; then + if test "x$ALL_LINGUAS" = "x"; then + LINGUAS= + else + echo "$as_me:$LINENO: checking for catalogs to be installed" >&5 +echo $ECHO_N "checking for catalogs to be installed... $ECHO_C" >&6 + NEW_LINGUAS= + for presentlang in $ALL_LINGUAS; do + useit=no + if test "%UNSET%" != "${LINGUAS-%UNSET%}"; then + desiredlanguages="$LINGUAS" + else + desiredlanguages="$ALL_LINGUAS" + fi + for desiredlang in $desiredlanguages; do + # Use the presentlang catalog if desiredlang is + # a. equal to presentlang, or + # b. a variant of presentlang (because in this case, + # presentlang can be used as a fallback for messages + # which are not translated in the desiredlang catalog). + case "$desiredlang" in + "$presentlang"*) useit=yes;; + esac + done + if test $useit = yes; then + NEW_LINGUAS="$NEW_LINGUAS $presentlang" + fi + done + LINGUAS=$NEW_LINGUAS + echo "$as_me:$LINENO: result: $LINGUAS" >&5 +echo "${ECHO_T}$LINGUAS" >&6 + fi + + if test -n "$LINGUAS"; then + for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done + fi + fi + + MKINSTALLDIRS= + if test -n "$ac_aux_dir"; then + MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" + fi + if test -z "$MKINSTALLDIRS"; then + MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" + fi + + + test -d po || mkdir po + if test "x$srcdir" != "x."; then + if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then + posrcprefix="$srcdir/" + else + posrcprefix="../$srcdir/" + fi + else + posrcprefix="../" + fi + rm -f po/POTFILES + sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \ + < $srcdir/po/POTFILES.in > po/POTFILES + + + +echo "$as_me:$LINENO: checking for t_accept in -lnsl" >&5 +echo $ECHO_N "checking for t_accept in -lnsl... $ECHO_C" >&6 +if test "${ac_cv_lib_nsl_t_accept+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lnsl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char t_accept (); +int +main () +{ +t_accept (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_nsl_t_accept=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_nsl_t_accept=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_t_accept" >&5 +echo "${ECHO_T}$ac_cv_lib_nsl_t_accept" >&6 +if test $ac_cv_lib_nsl_t_accept = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBNSL 1 +_ACEOF + + LIBS="-lnsl $LIBS" + +fi + + +echo "$as_me:$LINENO: checking for socket in -lsocket" >&5 +echo $ECHO_N "checking for socket in -lsocket... $ECHO_C" >&6 +if test "${ac_cv_lib_socket_socket+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char socket (); +int +main () +{ +socket (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_socket_socket=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_socket_socket=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_socket_socket" >&5 +echo "${ECHO_T}$ac_cv_lib_socket_socket" >&6 +if test $ac_cv_lib_socket_socket = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSOCKET 1 +_ACEOF + + LIBS="-lsocket $LIBS" + +fi + + +# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works +# for constant arguments. Useless! +echo "$as_me:$LINENO: checking for working alloca.h" >&5 +echo $ECHO_N "checking for working alloca.h... $ECHO_C" >&6 +if test "${ac_cv_working_alloca_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ +char *p = (char *) alloca (2 * sizeof (int)); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_working_alloca_h=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_working_alloca_h=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_working_alloca_h" >&5 +echo "${ECHO_T}$ac_cv_working_alloca_h" >&6 +if test $ac_cv_working_alloca_h = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_ALLOCA_H 1 +_ACEOF + +fi + +echo "$as_me:$LINENO: checking for alloca" >&5 +echo $ECHO_N "checking for alloca... $ECHO_C" >&6 +if test "${ac_cv_func_alloca_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __GNUC__ +# define alloca __builtin_alloca +#else +# ifdef _MSC_VER +# include +# define alloca _alloca +# else +# if HAVE_ALLOCA_H +# include +# else +# ifdef _AIX + #pragma alloca +# else +# ifndef alloca /* predefined by HP cc +Olibcalls */ +char *alloca (); +# endif +# endif +# endif +# endif +#endif + +int +main () +{ +char *p = (char *) alloca (1); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_alloca_works=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_alloca_works=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_alloca_works" >&5 +echo "${ECHO_T}$ac_cv_func_alloca_works" >&6 + +if test $ac_cv_func_alloca_works = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_ALLOCA 1 +_ACEOF + +else + # The SVR3 libPW and SVR4 libucb both contain incompatible functions +# that cause trouble. Some versions do not even contain alloca or +# contain a buggy version. If you still want to use their alloca, +# use ar to extract alloca.o from them instead of compiling alloca.c. + +ALLOCA=alloca.$ac_objext + +cat >>confdefs.h <<\_ACEOF +#define C_ALLOCA 1 +_ACEOF + + +echo "$as_me:$LINENO: checking whether \`alloca.c' needs Cray hooks" >&5 +echo $ECHO_N "checking whether \`alloca.c' needs Cray hooks... $ECHO_C" >&6 +if test "${ac_cv_os_cray+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#if defined(CRAY) && ! defined(CRAY2) +webecray +#else +wenotbecray +#endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "webecray" >/dev/null 2>&1; then + ac_cv_os_cray=yes +else + ac_cv_os_cray=no +fi +rm -f conftest* + +fi +echo "$as_me:$LINENO: result: $ac_cv_os_cray" >&5 +echo "${ECHO_T}$ac_cv_os_cray" >&6 +if test $ac_cv_os_cray = yes; then + for ac_func in _getb67 GETB67 getb67; do + as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ +#ifdef __STDC__ +# include +#else +# include +#endif +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + +cat >>confdefs.h <<_ACEOF +#define CRAY_STACKSEG_END $ac_func +_ACEOF + + break +fi + + done +fi + +echo "$as_me:$LINENO: checking stack direction for C alloca" >&5 +echo $ECHO_N "checking stack direction for C alloca... $ECHO_C" >&6 +if test "${ac_cv_c_stack_direction+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_c_stack_direction=0 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +int +find_stack_direction () +{ + static char *addr = 0; + auto char dummy; + if (addr == 0) + { + addr = &dummy; + return find_stack_direction (); + } + else + return (&dummy > addr) ? 1 : -1; +} + +int +main () +{ + exit (find_stack_direction () < 0); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_stack_direction=1 +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_c_stack_direction=-1 +fi +rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_c_stack_direction" >&5 +echo "${ECHO_T}$ac_cv_c_stack_direction" >&6 + +cat >>confdefs.h <<_ACEOF +#define STACK_DIRECTION $ac_cv_c_stack_direction +_ACEOF + + +fi + + + + + + + + + + + + + +for ac_func in getdtablesize open64 lseek64 statvfs seteuid setegid setresuid setresgid readdir_r mbrtowc inet_pton getdelim +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ +#ifdef __STDC__ +# include +#else +# include +#endif +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + + +# Extract the first word of "gconftool-2", so it can be a program name with args. +set dummy gconftool-2; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_path_GCONFTOOL+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $GCONFTOOL in + [\\/]* | ?:[\\/]*) + ac_cv_path_GCONFTOOL="$GCONFTOOL" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_GCONFTOOL="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_path_GCONFTOOL" && ac_cv_path_GCONFTOOL="no" + ;; +esac +fi +GCONFTOOL=$ac_cv_path_GCONFTOOL + +if test -n "$GCONFTOOL"; then + echo "$as_me:$LINENO: result: $GCONFTOOL" >&5 +echo "${ECHO_T}$GCONFTOOL" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + +if test x"$GCONFTOOL" = xno; then + { { echo "$as_me:$LINENO: error: gconftool-2 executable not found in your path - should be installed with GConf" >&5 +echo "$as_me: error: gconftool-2 executable not found in your path - should be installed with GConf" >&2;} + { (exit 1); exit 1; }; } +fi + + + if test "x$GCONF_SCHEMA_INSTALL_SOURCE" = "x"; then + GCONF_SCHEMA_CONFIG_SOURCE=`gconftool-2 --get-default-source` + else + GCONF_SCHEMA_CONFIG_SOURCE=$GCONF_SCHEMA_INSTALL_SOURCE + fi + + +# Check whether --with-gconf-source or --without-gconf-source was given. +if test "${with_gconf_source+set}" = set; then + withval="$with_gconf_source" + GCONF_SCHEMA_CONFIG_SOURCE="$withval" +fi; + + + echo "$as_me:$LINENO: result: Using config source $GCONF_SCHEMA_CONFIG_SOURCE for schema installation" >&5 +echo "${ECHO_T}Using config source $GCONF_SCHEMA_CONFIG_SOURCE for schema installation" >&6 + + if test "x$GCONF_SCHEMA_FILE_DIR" = "x"; then + GCONF_SCHEMA_FILE_DIR='$(sysconfdir)/gconf/schemas/' + else + GCONF_SCHEMA_FILE_DIR=$GCONF_SCHEMA_FILE_DIR + fi + + +# Check whether --with-gconf-schema-file-dir or --without-gconf-schema-file-dir was given. +if test "${with_gconf_schema_file_dir+set}" = set; then + withval="$with_gconf_schema_file_dir" + GCONF_SCHEMA_FILE_DIR="$withval" +fi; + + + echo "$as_me:$LINENO: result: Using $GCONF_SCHEMA_FILE_DIR as install directory for schema files" >&5 +echo "${ECHO_T}Using $GCONF_SCHEMA_FILE_DIR as install directory for schema files" >&6 + + # Check whether --enable-schemas-install or --disable-schemas-install was given. +if test "${enable_schemas_install+set}" = set; then + enableval="$enable_schemas_install" + case "${enableval}" in + yes) schemas_install=true ;; + no) schemas_install=false ;; + *) { { echo "$as_me:$LINENO: error: bad value ${enableval} for --disable-schemas-install" >&5 +echo "$as_me: error: bad value ${enableval} for --disable-schemas-install" >&2;} + { (exit 1); exit 1; }; } ;; + esac +else + schemas_install=true +fi; + + +if test x$schemas_install = xtrue; then + GCONF_SCHEMAS_INSTALL_TRUE= + GCONF_SCHEMAS_INSTALL_FALSE='#' +else + GCONF_SCHEMAS_INSTALL_TRUE='#' + GCONF_SCHEMAS_INSTALL_FALSE= +fi + + +echo "$as_me:$LINENO: checking for int" >&5 +echo $ECHO_N "checking for int... $ECHO_C" >&6 +if test "${ac_cv_type_int+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if ((int *) 0) + return 0; +if (sizeof (int)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_int=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_int=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_int" >&5 +echo "${ECHO_T}$ac_cv_type_int" >&6 + +echo "$as_me:$LINENO: checking size of int" >&5 +echo $ECHO_N "checking size of int... $ECHO_C" >&6 +if test "${ac_cv_sizeof_int+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$ac_cv_type_int" = yes; then + # The cast to unsigned long works around a bug in the HP C Compiler + # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects + # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. + # This bug is HP SR number 8606223364. + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (int))) >= 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lo=0 ac_mid=0 + while :; do + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (int))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi +rm -f conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (int))) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=-1 ac_mid=-1 + while :; do + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (int))) >= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi +rm -f conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_lo= ac_hi= +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (int))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_lo=`expr '(' $ac_mid ')' + 1` +fi +rm -f conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof_int=$ac_lo;; +'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (int), 77 +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (int), 77 +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } ;; +esac +else + if test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run test program while cross compiling +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +long longval () { return (long) (sizeof (int)); } +unsigned long ulongval () { return (long) (sizeof (int)); } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + exit (1); + if (((long) (sizeof (int))) < 0) + { + long i = longval (); + if (i != ((long) (sizeof (int)))) + exit (1); + fprintf (f, "%ld\n", i); + } + else + { + unsigned long i = ulongval (); + if (i != ((long) (sizeof (int)))) + exit (1); + fprintf (f, "%lu\n", i); + } + exit (ferror (f) || fclose (f) != 0); + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof_int=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +{ { echo "$as_me:$LINENO: error: cannot compute sizeof (int), 77 +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (int), 77 +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi +rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +rm -f conftest.val +else + ac_cv_sizeof_int=0 +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_sizeof_int" >&5 +echo "${ECHO_T}$ac_cv_sizeof_int" >&6 +cat >>confdefs.h <<_ACEOF +#define SIZEOF_INT $ac_cv_sizeof_int +_ACEOF + + +echo "$as_me:$LINENO: checking for long" >&5 +echo $ECHO_N "checking for long... $ECHO_C" >&6 +if test "${ac_cv_type_long+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if ((long *) 0) + return 0; +if (sizeof (long)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_long=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_long=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_long" >&5 +echo "${ECHO_T}$ac_cv_type_long" >&6 + +echo "$as_me:$LINENO: checking size of long" >&5 +echo $ECHO_N "checking size of long... $ECHO_C" >&6 +if test "${ac_cv_sizeof_long+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$ac_cv_type_long" = yes; then + # The cast to unsigned long works around a bug in the HP C Compiler + # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects + # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. + # This bug is HP SR number 8606223364. + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (long))) >= 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lo=0 ac_mid=0 + while :; do + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (long))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi +rm -f conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (long))) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=-1 ac_mid=-1 + while :; do + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (long))) >= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi +rm -f conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_lo= ac_hi= +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (long))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_lo=`expr '(' $ac_mid ')' + 1` +fi +rm -f conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof_long=$ac_lo;; +'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (long), 77 +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (long), 77 +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } ;; +esac +else + if test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run test program while cross compiling +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +long longval () { return (long) (sizeof (long)); } +unsigned long ulongval () { return (long) (sizeof (long)); } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + exit (1); + if (((long) (sizeof (long))) < 0) + { + long i = longval (); + if (i != ((long) (sizeof (long)))) + exit (1); + fprintf (f, "%ld\n", i); + } + else + { + unsigned long i = ulongval (); + if (i != ((long) (sizeof (long)))) + exit (1); + fprintf (f, "%lu\n", i); + } + exit (ferror (f) || fclose (f) != 0); + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof_long=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +{ { echo "$as_me:$LINENO: error: cannot compute sizeof (long), 77 +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (long), 77 +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi +rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +rm -f conftest.val +else + ac_cv_sizeof_long=0 +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_sizeof_long" >&5 +echo "${ECHO_T}$ac_cv_sizeof_long" >&6 +cat >>confdefs.h <<_ACEOF +#define SIZEOF_LONG $ac_cv_sizeof_long +_ACEOF + + +echo "$as_me:$LINENO: checking for long long" >&5 +echo $ECHO_N "checking for long long... $ECHO_C" >&6 +if test "${ac_cv_type_long_long+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if ((long long *) 0) + return 0; +if (sizeof (long long)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_long_long=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_long_long=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_long_long" >&5 +echo "${ECHO_T}$ac_cv_type_long_long" >&6 + +echo "$as_me:$LINENO: checking size of long long" >&5 +echo $ECHO_N "checking size of long long... $ECHO_C" >&6 +if test "${ac_cv_sizeof_long_long+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$ac_cv_type_long_long" = yes; then + # The cast to unsigned long works around a bug in the HP C Compiler + # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects + # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. + # This bug is HP SR number 8606223364. + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (long long))) >= 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lo=0 ac_mid=0 + while :; do + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (long long))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi +rm -f conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (long long))) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=-1 ac_mid=-1 + while :; do + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (long long))) >= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi +rm -f conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_lo= ac_hi= +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (long long))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_lo=`expr '(' $ac_mid ')' + 1` +fi +rm -f conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof_long_long=$ac_lo;; +'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (long long), 77 +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (long long), 77 +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } ;; +esac +else + if test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run test program while cross compiling +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +long longval () { return (long) (sizeof (long long)); } +unsigned long ulongval () { return (long) (sizeof (long long)); } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + exit (1); + if (((long) (sizeof (long long))) < 0) + { + long i = longval (); + if (i != ((long) (sizeof (long long)))) + exit (1); + fprintf (f, "%ld\n", i); + } + else + { + unsigned long i = ulongval (); + if (i != ((long) (sizeof (long long)))) + exit (1); + fprintf (f, "%lu\n", i); + } + exit (ferror (f) || fclose (f) != 0); + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof_long_long=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +{ { echo "$as_me:$LINENO: error: cannot compute sizeof (long long), 77 +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (long long), 77 +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi +rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +rm -f conftest.val +else + ac_cv_sizeof_long_long=0 +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_sizeof_long_long" >&5 +echo "${ECHO_T}$ac_cv_sizeof_long_long" >&6 +cat >>confdefs.h <<_ACEOF +#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long +_ACEOF + + + +VFS_SIZE="unsigned long" +VFS_OFFSET="long" +VFS_SIZE_IS="UNSIGNED_LONG" +VFS_OFFSET_IS="LONG" +VFS_SIZE_PRINTF="lu" +VFS_OFFSET_PRINTF="ld" + +case 8 in +$ac_cv_sizeof_int) + VFS_SIZE="unsigned int" + VFS_OFFSET="int" + VFS_SIZE_IS="UNSIGNED_INT" + VFS_OFFSET_IS="INT" + VFS_SIZE_PRINTF="u" + VFS_OFFSET_PRINTF="d" + ;; +$ac_cv_sizeof_long) + # Nothing happens here, we are already using a long + ;; +$ac_cv_sizeof_long_long) + VFS_SIZE="unsigned long long" + VFS_OFFSET="long long" + VFS_SIZE_IS="UNSIGNED_LONG_LONG" + VFS_OFFSET_IS="LONG_LONG" + VFS_SIZE_PRINTF="Lu" + VFS_OFFSET_PRINTF="Ld" + ;; +esac + + + + + + + + + + + + + + +for ac_header in sys/param.h sys/resource.h sys/vfs.h sys/mount.h sys/statvfs.h wctype.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc in + yes:no ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to bug-autoconf@gnu.org. ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; + no:yes ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to bug-autoconf@gnu.org. ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +ENABLE_PROFILER= +# Check whether --enable-profiler or --disable-profiler was given. +if test "${enable_profiler+set}" = set; then + enableval="$enable_profiler" + ENABLE_PROFILER=1 +cat >>confdefs.h <<\_ACEOF +#define ENABLE_PROFILER 1 +_ACEOF + +fi; + +if test "x$ENABLE_PROFILER" = "x1" +then + CFLAGS="-g -O -gdwarf-2 -finstrument-functions -D__NO_STRING_INLINES" + LDFLAGS="/gnome/PROFILE/lib/libprofiler.so -lpthread" +fi + + + + +if test "x$ENABLE_PROFILER" = "x1"; then + ENABLE_PROFILER_TRUE= + ENABLE_PROFILER_FALSE='#' +else + ENABLE_PROFILER_TRUE='#' + ENABLE_PROFILER_FALSE= +fi + + +# Check whether --enable-more-warnings or --disable-more-warnings was given. +if test "${enable_more_warnings+set}" = set; then + enableval="$enable_more_warnings" + set_more_warnings="$enableval" +else + +if test -f $srcdir/CVSVERSION; then + set_more_warnings=yes +else + set_more_warnings=no +fi + +fi; + +if test "$GCC" = "yes" -a "$set_more_warnings" != "no"; then + echo "enable compile warnings = $set_more_warnings" + VFS_CFLAGS="-Wall -Werror \ + -Wchar-subscripts -Wmissing-declarations -Wmissing-prototypes \ + -Wnested-externs -Wpointer-arith" + + for option in -Wno-strict-aliasing -Wno-sign-compare; do + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$VFS_CFLAGS $option $CFLAGS" + echo "$as_me:$LINENO: checking whether gcc understands $option" >&5 +echo $ECHO_N "checking whether gcc understands $option... $ECHO_C" >&6 + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + has_option=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +has_option=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext + CFLAGS="$SAVE_CFLAGS" + if test $has_option = yes; then + VFS_CFLAGS="$VFS_CFLAGS $option" + fi + echo "$as_me:$LINENO: result: $has_option" >&5 +echo "${ECHO_T}$has_option" >&6 + unset has_option + unset SAVE_CFLAGS + done + unset option +fi + + +GNOME_VFS_DIR=`(cd $srcdir; pwd)` + + +VFS_LIBS="-lgnomevfs $VFS_GLIB_LIBS" +VFS_LIBDIR='-L${libdir}' +VFS_INCLUDEDIR='-I${includedir} -I${libdir}/vfs/include'" $VFS_GLIB_CFLAGS" + + + + + + + + +if false; then + HAVE_LIBEFS_TRUE= + HAVE_LIBEFS_FALSE='#' +else + HAVE_LIBEFS_TRUE='#' + HAVE_LIBEFS_FALSE= +fi +LIBEFS_LIBS="" +LIBEFS_CFLAGS="" + + + + + +have_socket=no + +for ac_func in socket +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ +#ifdef __STDC__ +# include +#else +# include +#endif +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + have_socket=yes +fi +done + +if test $have_socket = no; then + # socket is not in the default libraries. See if it's in some other. + for lib in bsd socket inet; do + as_ac_Lib=`echo "ac_cv_lib_$lib''_socket" | $as_tr_sh` +echo "$as_me:$LINENO: checking for socket in -l$lib" >&5 +echo $ECHO_N "checking for socket in -l$lib... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Lib+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-l$lib $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char socket (); +int +main () +{ +socket (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_Lib=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_Lib=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Lib'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Lib'}'`" >&6 +if test `eval echo '${'$as_ac_Lib'}'` = yes; then + + LIBS="$LIBS -l$lib" + have_socket=yes + cat >>confdefs.h <<\_ACEOF +#define HAVE_SOCKET 1 +_ACEOF + + break +fi + + done +fi + +have_gethostbyname=no +echo "$as_me:$LINENO: checking for gethostbyname" >&5 +echo $ECHO_N "checking for gethostbyname... $ECHO_C" >&6 +if test "${ac_cv_func_gethostbyname+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char gethostbyname (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ +#ifdef __STDC__ +# include +#else +# include +#endif +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gethostbyname (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_gethostbyname) || defined (__stub___gethostbyname) +choke me +#else +char (*f) () = gethostbyname; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != gethostbyname; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_gethostbyname=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_gethostbyname=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_gethostbyname" >&5 +echo "${ECHO_T}$ac_cv_func_gethostbyname" >&6 +if test $ac_cv_func_gethostbyname = yes; then + have_gethostbyname=yes +fi + +if test $have_gethostbyname = no; then + # gethostbyname is not in the default libraries. See if it's in some other. + for lib in bsd socket inet; do + as_ac_Lib=`echo "ac_cv_lib_$lib''_gethostbyname" | $as_tr_sh` +echo "$as_me:$LINENO: checking for gethostbyname in -l$lib" >&5 +echo $ECHO_N "checking for gethostbyname in -l$lib... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Lib+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-l$lib $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gethostbyname (); +int +main () +{ +gethostbyname (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_Lib=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_Lib=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Lib'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Lib'}'`" >&6 +if test `eval echo '${'$as_ac_Lib'}'` = yes; then + LIBS="$LIBS -l$lib"; have_gethostbyname=yes; break +fi + + done +fi + +echo "$as_me:$LINENO: checking for bzCompressInit in -lbz2" >&5 +echo $ECHO_N "checking for bzCompressInit in -lbz2... $ECHO_C" >&6 +if test "${ac_cv_lib_bz2_bzCompressInit+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lbz2 $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char bzCompressInit (); +int +main () +{ +bzCompressInit (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_bz2_bzCompressInit=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_bz2_bzCompressInit=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_bz2_bzCompressInit" >&5 +echo "${ECHO_T}$ac_cv_lib_bz2_bzCompressInit" >&6 +if test $ac_cv_lib_bz2_bzCompressInit = yes; then + cat >>confdefs.h <<\_ACEOF +#define HAVE_OLDER_BZIP2 1 +_ACEOF + +fi + + +for ac_header in bzlib.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc in + yes:no ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to bug-autoconf@gnu.org. ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; + no:yes ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to bug-autoconf@gnu.org. ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + BZ2_LIBS="$BZ2_LIBS -lbz2" +else + { { echo "$as_me:$LINENO: error: Gnome-vfs requires libbz2 to compile." >&5 +echo "$as_me: error: Gnome-vfs requires libbz2 to compile." >&2;} + { (exit 1); exit 1; }; } + +fi + +done + + + +if test $have_socket = yes; then + +av_struct_linger=no +echo "$as_me:$LINENO: checking struct linger is available" >&5 +echo $ECHO_N "checking struct linger is available... $ECHO_C" >&6 +if test "$cross_compiling" = yes; then + +av_struct_linger=no + +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#include + +struct linger li; + +main () +{ + li.l_onoff = 1; + li.l_linger = 120; + exit (0); +} + +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_STRUCT_LINGER 1 +_ACEOF + +av_struct_linger=yes + +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) + +av_struct_linger=no + +fi +rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $av_struct_linger" >&5 +echo "${ECHO_T}$av_struct_linger" >&6 + +fi + + + + +if false; then + HAVE_CDDA_TRUE= + HAVE_CDDA_FALSE='#' +else + HAVE_CDDA_TRUE='#' + HAVE_CDDA_FALSE= +fi + + +for ac_header in cdda_interface.h cdda_paranoia.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc in + yes:no ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to bug-autoconf@gnu.org. ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; + no:yes ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to bug-autoconf@gnu.org. ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + + CDDA_LIBS="$CDDA_LIBS -lcdda_paranoia, -lcdda_interface" + + +if true; then + HAVE_CDDA_TRUE= + HAVE_CDDA_FALSE='#' +else + HAVE_CDDA_TRUE='#' + HAVE_CDDA_FALSE= +fi + +fi + +done + + + +echo "$as_me:$LINENO: checking for Solaris platform" >&5 +echo $ECHO_N "checking for Solaris platform... $ECHO_C" >&6 +case "$host" in + *solaris*) build_cdemenu_module=yes ;; + *) build_cdemenu_module=no ;; +esac +echo "$as_me:$LINENO: result: $build_cdemenu_module" >&5 +echo "${ECHO_T}$build_cdemenu_module" >&6 + + +if test "$build_cdemenu_module" = "yes"; then + BUILD_CDEMENU_MODULE_TRUE= + BUILD_CDEMENU_MODULE_FALSE='#' +else + BUILD_CDEMENU_MODULE_TRUE='#' + BUILD_CDEMENU_MODULE_FALSE= +fi + + +# Check whether --enable-openssl or --disable-openssl was given. +if test "${enable_openssl+set}" = set; then + enableval="$enable_openssl" + +fi; +if test "x$enable_openssl" != "xno"; then + + succeeded=no + + if test -z "$PKG_CONFIG"; then + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_path_PKG_CONFIG+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no" + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG + +if test -n "$PKG_CONFIG"; then + echo "$as_me:$LINENO: result: $PKG_CONFIG" >&5 +echo "${ECHO_T}$PKG_CONFIG" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + fi + + if test "$PKG_CONFIG" = "no" ; then + echo "*** The pkg-config script could not be found. Make sure it is" + echo "*** in your path, or set the PKG_CONFIG environment variable" + echo "*** to the full path to pkg-config." + echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config." + else + PKG_CONFIG_MIN_VERSION=0.9.0 + if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then + echo "$as_me:$LINENO: checking for openssl" >&5 +echo $ECHO_N "checking for openssl... $ECHO_C" >&6 + + if $PKG_CONFIG --exists "openssl" ; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + succeeded=yes + + echo "$as_me:$LINENO: checking OPENSSL_CFLAGS" >&5 +echo $ECHO_N "checking OPENSSL_CFLAGS... $ECHO_C" >&6 + OPENSSL_CFLAGS=`$PKG_CONFIG --cflags "openssl"` + echo "$as_me:$LINENO: result: $OPENSSL_CFLAGS" >&5 +echo "${ECHO_T}$OPENSSL_CFLAGS" >&6 + + echo "$as_me:$LINENO: checking OPENSSL_LIBS" >&5 +echo $ECHO_N "checking OPENSSL_LIBS... $ECHO_C" >&6 + OPENSSL_LIBS=`$PKG_CONFIG --libs "openssl"` + echo "$as_me:$LINENO: result: $OPENSSL_LIBS" >&5 +echo "${ECHO_T}$OPENSSL_LIBS" >&6 + else + OPENSSL_CFLAGS="" + OPENSSL_LIBS="" + ## If we have a custom action on failure, don't print errors, but + ## do set a variable so people can do so. + OPENSSL_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "openssl"` + + fi + + + + else + echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer." + echo "*** See http://www.freedesktop.org/software/pkgconfig" + fi + fi + + if test $succeeded = yes; then + + +if true; then + HAVE_SSL_TRUE= + HAVE_SSL_FALSE='#' +else + HAVE_SSL_TRUE='#' + HAVE_SSL_FALSE= +fi + else + + +# Check whether --with-openssl-includes or --without-openssl-includes was given. +if test "${with_openssl_includes+set}" = set; then + withval="$with_openssl_includes" + with_openssl_includes="$withval" +else + with_openssl_includes="/usr/include" +fi; + have_openssl_includes="no" + if test "x${with_openssl_includes}" != "xno"; then + CPPFLAGS_save="$CPPFLAGS" + + echo "$as_me:$LINENO: checking for OpenSSL includes" >&5 +echo $ECHO_N "checking for OpenSSL includes... $ECHO_C" >&6 + echo "$as_me:$LINENO: result: \"\"" >&5 +echo "${ECHO_T}\"\"" >&6 + + CPPFLAGS="$CPPFLAGS -I$with_openssl_includes" + + +for ac_header in openssl/ssl.h openssl/x509.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc in + yes:no ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to bug-autoconf@gnu.org. ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; + no:yes ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to bug-autoconf@gnu.org. ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + openssl_includes="yes" +fi + +done + + CPPFLAGS="$CPPFLAGS_save" + + if test "x{$openssl_includes}" != "xno" -a "x{$openssl_includes}" != "x"; then + have_openssl_includes="yes" + if test "${with_openssl_includes}" != "/usr/include" ; then + OPENSSL_CFLAGS="-I$with_openssl_includes" + else + OPENSSL_CFLAGS="" + fi + else + OPENSSL_CFLAGS="" + fi + else + echo "$as_me:$LINENO: checking for OpenSSL includes" >&5 +echo $ECHO_N "checking for OpenSSL includes... $ECHO_C" >&6 + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + fi + + +# Check whether --with-openssl-libs or --without-openssl-libs was given. +if test "${with_openssl_libs+set}" = set; then + withval="$with_openssl_libs" + with_openssl_libs="$withval" +else + with_openssl_libs="/usr/lib" +fi; + msg_openssl="no" + if test "x${with_openssl_libs}" != "xno" -a "x${have_openssl_includes}" != "xno"; then + LDFLAGS_save="$LDFLAGS" + + echo "$as_me:$LINENO: checking for OpenSSL libraries" >&5 +echo $ECHO_N "checking for OpenSSL libraries... $ECHO_C" >&6 +if test "${openssl_libs+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + LDFLAGS="$LDFLAGS -L$with_openssl_libs -lssl -lcrypto -ldl" + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char SSL_read (); +int +main () +{ +SSL_read (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + openssl_libs="yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +openssl_libs="no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$LDFLAGS_save" + +fi +echo "$as_me:$LINENO: result: $openssl_libs" >&5 +echo "${ECHO_T}$openssl_libs" >&6 + if test "x${openssl_libs}" != "xno"; then + cat >>confdefs.h <<\_ACEOF +#define HAVE_OPENSSL 1 +_ACEOF + + msg_openssl="yes" + if test x$with_openssl_libs != x/usr/lib; then + OPENSSL_LIBS="-L$with_openssl_libs -lssl -lcrypto" + else + OPENSSL_LIBS="-lssl -lcrypto" + fi + + +if true; then + HAVE_SSL_TRUE= + HAVE_SSL_FALSE='#' +else + HAVE_SSL_TRUE='#' + HAVE_SSL_FALSE= +fi + else + OPENSSL_CFLAGS="" + OPENSSL_LIBS="" + + +if false; then + HAVE_SSL_TRUE= + HAVE_SSL_FALSE='#' +else + HAVE_SSL_TRUE='#' + HAVE_SSL_FALSE= +fi + fi + else + echo "$as_me:$LINENO: checking for OpenSSL libraries" >&5 +echo $ECHO_N "checking for OpenSSL libraries... $ECHO_C" >&6 + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + fi + + fi + + fi + + + +# Check whether --enable-gnutls or --disable-gnutls was given. +if test "${enable_gnutls+set}" = set; then + enableval="$enable_gnutls" + +fi; +if test "x$enable_gnutls" = "xyes"; then + if test "x${OPENSSL_LIBS}" != "x"; then + { { echo "$as_me:$LINENO: error: *** Can't use both openssl and gnutls at the same time. Please pick one only. ***" >&5 +echo "$as_me: error: *** Can't use both openssl and gnutls at the same time. Please pick one only. ***" >&2;} + { (exit 1); exit 1; }; } + else + +# Check whether --with-libgnutls-prefix or --without-libgnutls-prefix was given. +if test "${with_libgnutls_prefix+set}" = set; then + withval="$with_libgnutls_prefix" + libgnutls_config_prefix="$withval" +else + libgnutls_config_prefix="" +fi; + + if test x$libgnutls_config_prefix != x ; then + libgnutls_config_args="$libgnutls_config_args --prefix=$libgnutls_config_prefix" + if test x${LIBGNUTLS_CONFIG+set} != xset ; then + LIBGNUTLS_CONFIG=$libgnutls_config_prefix/bin/libgnutls-config + fi + fi + + # Extract the first word of "libgnutls-config", so it can be a program name with args. +set dummy libgnutls-config; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_path_LIBGNUTLS_CONFIG+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $LIBGNUTLS_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_LIBGNUTLS_CONFIG="$LIBGNUTLS_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_LIBGNUTLS_CONFIG="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_path_LIBGNUTLS_CONFIG" && ac_cv_path_LIBGNUTLS_CONFIG="no" + ;; +esac +fi +LIBGNUTLS_CONFIG=$ac_cv_path_LIBGNUTLS_CONFIG + +if test -n "$LIBGNUTLS_CONFIG"; then + echo "$as_me:$LINENO: result: $LIBGNUTLS_CONFIG" >&5 +echo "${ECHO_T}$LIBGNUTLS_CONFIG" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + min_libgnutls_version=0.5.1 + echo "$as_me:$LINENO: checking for libgnutls - version >= $min_libgnutls_version" >&5 +echo $ECHO_N "checking for libgnutls - version >= $min_libgnutls_version... $ECHO_C" >&6 + no_libgnutls="" + if test "$LIBGNUTLS_CONFIG" = "no" ; then + no_libgnutls=yes + else + LIBGNUTLS_CFLAGS=`$LIBGNUTLS_CONFIG $libgnutls_config_args --cflags` + LIBGNUTLS_LIBS=`$LIBGNUTLS_CONFIG $libgnutls_config_args --libs` + libgnutls_config_version=`$LIBGNUTLS_CONFIG $libgnutls_config_args --version` + + + ac_save_CFLAGS="$CFLAGS" + ac_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $LIBGNUTLS_CFLAGS" + LIBS="$LIBS $LIBGNUTLS_LIBS" + rm -f conf.libgnutlstest + if test "$cross_compiling" = yes; then + echo $ac_n "cross compiling; assumed OK... $ac_c" +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#include +#include +#include + +int +main () +{ + system ("touch conf.libgnutlstest"); + + if( strcmp( gnutls_check_version(NULL), "$libgnutls_config_version" ) ) + { + printf("\n*** 'libgnutls-config --version' returned %s, but LIBGNUTLS (%s)\n", + "$libgnutls_config_version", gnutls_check_version(NULL) ); + printf("*** was found! If libgnutls-config was correct, then it is best\n"); + printf("*** to remove the old version of LIBGNUTLS. You may also be able to fix the error\n"); + printf("*** by modifying your LD_LIBRARY_PATH enviroment variable, or by editing\n"); + printf("*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\n"); + printf("*** required on your system.\n"); + printf("*** If libgnutls-config was wrong, set the environment variable LIBGNUTLS_CONFIG\n"); + printf("*** to point to the correct copy of libgnutls-config, and remove the file config.cache\n"); + printf("*** before re-running configure\n"); + } + else if ( strcmp(gnutls_check_version(NULL), LIBGNUTLS_VERSION ) ) + { + printf("\n*** LIBGNUTLS header file (version %s) does not match\n", LIBGNUTLS_VERSION); + printf("*** library (version %s)\n", gnutls_check_version(NULL) ); + } + else + { + if ( gnutls_check_version( "$min_libgnutls_version" ) ) + { + return 0; + } + else + { + printf("no\n*** An old version of LIBGNUTLS (%s) was found.\n", + gnutls_check_version(NULL) ); + printf("*** You need a version of LIBGNUTLS newer than %s. The latest version of\n", + "$min_libgnutls_version" ); + printf("*** LIBGNUTLS is always available from ftp://gnutls.hellug.gr/pub/gnutls.\n"); + printf("*** \n"); + printf("*** If you have already installed a sufficiently new version, this error\n"); + printf("*** probably means that the wrong copy of the libgnutls-config shell script is\n"); + printf("*** being found. The easiest way to fix this is to remove the old version\n"); + printf("*** of LIBGNUTLS, but you can also set the LIBGNUTLS_CONFIG environment to point to the\n"); + printf("*** correct copy of libgnutls-config. (In this case, you will have to\n"); + printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n"); + printf("*** so that the correct libraries are found at run-time))\n"); + } + } + return 1; +} + +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +no_libgnutls=yes +fi +rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + + if test "x$no_libgnutls" = x ; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + cat >>confdefs.h <<\_ACEOF +#define HAVE_GNUTLS 1 +_ACEOF + + else + if test -f conf.libgnutlstest ; then + : + else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + fi + if test "$LIBGNUTLS_CONFIG" = "no" ; then + echo "*** The libgnutls-config script installed by LIBGNUTLS could not be found" + echo "*** If LIBGNUTLS was installed in PREFIX, make sure PREFIX/bin is in" + echo "*** your path, or set the LIBGNUTLS_CONFIG environment variable to the" + echo "*** full path to libgnutls-config." + else + if test -f conf.libgnutlstest ; then + : + else + echo "*** Could not run libgnutls test program, checking why..." + CFLAGS="$CFLAGS $LIBGNUTLS_CFLAGS" + LIBS="$LIBS $LIBGNUTLS_LIBS" + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#include +#include +#include + +int +main () +{ + return !!gnutls_check_version(NULL); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + echo "*** The test program compiled, but did not run. This usually means" + echo "*** that the run-time linker is not finding LIBGNUTLS or finding the wrong" + echo "*** version of LIBGNUTLS. If it is not finding LIBGNUTLS, you'll need to set your" + echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" + echo "*** to the installed location Also, make sure you have run ldconfig if that" + echo "*** is required on your system" + echo "***" + echo "*** If you have an old version installed, it is best to remove it, although" + echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" + echo "***" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + echo "*** The test program failed to compile or link. See the file config.log for the" + echo "*** exact error that occured. This usually means LIBGNUTLS was incorrectly installed" + echo "*** or that you have moved LIBGNUTLS since it was installed. In the latter case, you" + echo "*** may want to edit the libgnutls-config script: $LIBGNUTLS_CONFIG" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + LIBGNUTLS_CFLAGS="" + LIBGNUTLS_LIBS="" + { { echo "$as_me:$LINENO: error: Unable to find GNUTLS" >&5 +echo "$as_me: error: Unable to find GNUTLS" >&2;} + { (exit 1); exit 1; }; } + fi + rm -f conf.libgnutlstest + + + + fi +fi + + + succeeded=no + + if test -z "$PKG_CONFIG"; then + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_path_PKG_CONFIG+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no" + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG + +if test -n "$PKG_CONFIG"; then + echo "$as_me:$LINENO: result: $PKG_CONFIG" >&5 +echo "${ECHO_T}$PKG_CONFIG" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + fi + + if test "$PKG_CONFIG" = "no" ; then + echo "*** The pkg-config script could not be found. Make sure it is" + echo "*** in your path, or set the PKG_CONFIG environment variable" + echo "*** to the full path to pkg-config." + echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config." + else + PKG_CONFIG_MIN_VERSION=0.9.0 + if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then + echo "$as_me:$LINENO: checking for glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED gconf-2.0 >= $GCONF_REQUIRED bonobo-activation-2.0 >= $BONOBO_ACTIVATION_REQUIRED ORBit-2.0 >= $ORBIT_REQUIRED libxml-2.0 >= $XML_REQUIRED gnome-mime-data-2.0" >&5 +echo $ECHO_N "checking for glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED gconf-2.0 >= $GCONF_REQUIRED bonobo-activation-2.0 >= $BONOBO_ACTIVATION_REQUIRED ORBit-2.0 >= $ORBIT_REQUIRED libxml-2.0 >= $XML_REQUIRED gnome-mime-data-2.0... $ECHO_C" >&6 + + if $PKG_CONFIG --exists "glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED gconf-2.0 >= $GCONF_REQUIRED bonobo-activation-2.0 >= $BONOBO_ACTIVATION_REQUIRED ORBit-2.0 >= $ORBIT_REQUIRED libxml-2.0 >= $XML_REQUIRED gnome-mime-data-2.0" ; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + succeeded=yes + + echo "$as_me:$LINENO: checking LIBGNOMEVFS_CFLAGS" >&5 +echo $ECHO_N "checking LIBGNOMEVFS_CFLAGS... $ECHO_C" >&6 + LIBGNOMEVFS_CFLAGS=`$PKG_CONFIG --cflags "glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED gconf-2.0 >= $GCONF_REQUIRED bonobo-activation-2.0 >= $BONOBO_ACTIVATION_REQUIRED ORBit-2.0 >= $ORBIT_REQUIRED libxml-2.0 >= $XML_REQUIRED gnome-mime-data-2.0"` + echo "$as_me:$LINENO: result: $LIBGNOMEVFS_CFLAGS" >&5 +echo "${ECHO_T}$LIBGNOMEVFS_CFLAGS" >&6 + + echo "$as_me:$LINENO: checking LIBGNOMEVFS_LIBS" >&5 +echo $ECHO_N "checking LIBGNOMEVFS_LIBS... $ECHO_C" >&6 + LIBGNOMEVFS_LIBS=`$PKG_CONFIG --libs "glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED gconf-2.0 >= $GCONF_REQUIRED bonobo-activation-2.0 >= $BONOBO_ACTIVATION_REQUIRED ORBit-2.0 >= $ORBIT_REQUIRED libxml-2.0 >= $XML_REQUIRED gnome-mime-data-2.0"` + echo "$as_me:$LINENO: result: $LIBGNOMEVFS_LIBS" >&5 +echo "${ECHO_T}$LIBGNOMEVFS_LIBS" >&6 + else + LIBGNOMEVFS_CFLAGS="" + LIBGNOMEVFS_LIBS="" + ## If we have a custom action on failure, don't print errors, but + ## do set a variable so people can do so. + LIBGNOMEVFS_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED gconf-2.0 >= $GCONF_REQUIRED bonobo-activation-2.0 >= $BONOBO_ACTIVATION_REQUIRED ORBit-2.0 >= $ORBIT_REQUIRED libxml-2.0 >= $XML_REQUIRED gnome-mime-data-2.0"` + echo $LIBGNOMEVFS_PKG_ERRORS + fi + + + + else + echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer." + echo "*** See http://www.freedesktop.org/software/pkgconfig" + fi + fi + + if test $succeeded = yes; then + : + else + { { echo "$as_me:$LINENO: error: Library requirements (glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED gconf-2.0 >= $GCONF_REQUIRED bonobo-activation-2.0 >= $BONOBO_ACTIVATION_REQUIRED ORBit-2.0 >= $ORBIT_REQUIRED libxml-2.0 >= $XML_REQUIRED gnome-mime-data-2.0) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them." >&5 +echo "$as_me: error: Library requirements (glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED gconf-2.0 >= $GCONF_REQUIRED bonobo-activation-2.0 >= $BONOBO_ACTIVATION_REQUIRED ORBit-2.0 >= $ORBIT_REQUIRED libxml-2.0 >= $XML_REQUIRED gnome-mime-data-2.0) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them." >&2;} + { (exit 1); exit 1; }; } + fi + +LIBGNOMEVFS_CFLAGS="$LIBGNOMEVFS_CFLAGS $OPENSSL_CFLAGS $LIBGNUTLS_CFLAGS" +LIBGNOMEVFS_LIBS="$LIBGNOMEVFS_LIBS $OPENSSL_LIBS $LIBGNUTLS_LIBS" + + + + + +FAM_MISSING_WARNING="Gnome-vfs depends on FAM to provide notification when files are altered (either through filesystem polling, or a kernel notification mechanism). If Gnome-vfs is built without FAM support, directories viewed with Nautilus or other applications will not remain in synch with the actual filesystem when they are altered by external processes. Particularly if you are a distributor please compile Nautilus with FAM support. FAM is available from http://oss.sgi.com/projects/fam/. A patch to add Linux Kernel 2.4 directory notify support to FAM (highly desirable) is available from http://people.redhat.com/alexl/files/" +FAM_LIBS= +echo "$as_me:$LINENO: checking for FAMOpen in -lfam" >&5 +echo $ECHO_N "checking for FAMOpen in -lfam... $ECHO_C" >&6 +if test "${ac_cv_lib_fam_FAMOpen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lfam $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char FAMOpen (); +int +main () +{ +FAMOpen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_fam_FAMOpen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_fam_FAMOpen=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_fam_FAMOpen" >&5 +echo "${ECHO_T}$ac_cv_lib_fam_FAMOpen" >&6 +if test $ac_cv_lib_fam_FAMOpen = yes; then + +for ac_header in fam.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc in + yes:no ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to bug-autoconf@gnu.org. ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; + no:yes ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to bug-autoconf@gnu.org. ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + cat >>confdefs.h <<\_ACEOF +#define HAVE_FAM 1 +_ACEOF + + FAM_LIBS="-lfam" +else + { echo "$as_me:$LINENO: WARNING: *** FAM support will not be built (header files not found) $FAM_MISSING_WARNING ***" >&5 +echo "$as_me: WARNING: *** FAM support will not be built (header files not found) $FAM_MISSING_WARNING ***" >&2;} +fi + +done + +else + { echo "$as_me:$LINENO: WARNING: *** FAM support will not be built (FAM library not found) $FAM_MISSING_WARNING ***" >&5 +echo "$as_me: WARNING: *** FAM support will not be built (FAM library not found) $FAM_MISSING_WARNING ***" >&2;} +fi + + + + + + + + +# Check whether --with-html-dir or --without-html-dir was given. +if test "${with_html_dir+set}" = set; then + withval="$with_html_dir" + +fi; + +if test "x$with_html_dir" = "x" ; then + HTML_DIR='${datadir}/gtk-doc/html' +else + HTML_DIR=$with_html_dir +fi + + + +# Extract the first word of "gtkdoc-mkdb", so it can be a program name with args. +set dummy gtkdoc-mkdb; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_GTKDOC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$GTKDOC"; then + ac_cv_prog_GTKDOC="$GTKDOC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_GTKDOC="true" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_GTKDOC" && ac_cv_prog_GTKDOC="false" +fi +fi +GTKDOC=$ac_cv_prog_GTKDOC +if test -n "$GTKDOC"; then + echo "$as_me:$LINENO: result: $GTKDOC" >&5 +echo "${ECHO_T}$GTKDOC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + +gtk_doc_min_version=0.10 +if $GTKDOC ; then + gtk_doc_version=`gtkdoc-mkdb --version` + echo "$as_me:$LINENO: checking gtk-doc version ($gtk_doc_version) >= $gtk_doc_min_version" >&5 +echo $ECHO_N "checking gtk-doc version ($gtk_doc_version) >= $gtk_doc_min_version... $ECHO_C" >&6 + + IFS="${IFS= }"; gnome_vfs_save_IFS="$IFS"; IFS="." + set $gtk_doc_version + for min in $gtk_doc_min_version ; do + cur=$1; shift + if test -z $min ; then break; fi + if test -z $cur ; then GTKDOC=false; break; fi + if test $cur -gt $min ; then break ; fi + if test $cur -lt $min ; then GTKDOC=false; break ; fi + done + IFS="$gnome_vfs_save_IFS" + + if $GTKDOC ; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + fi +fi + +# Extract the first word of "db2html", so it can be a program name with args. +set dummy db2html; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_DB2HTML+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$DB2HTML"; then + ac_cv_prog_DB2HTML="$DB2HTML" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DB2HTML="true" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_DB2HTML" && ac_cv_prog_DB2HTML="false" +fi +fi +DB2HTML=$ac_cv_prog_DB2HTML +if test -n "$DB2HTML"; then + echo "$as_me:$LINENO: result: $DB2HTML" >&5 +echo "${ECHO_T}$DB2HTML" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + + +if $DB2HTML; then + HAVE_DOCBOOK_TRUE= + HAVE_DOCBOOK_FALSE='#' +else + HAVE_DOCBOOK_TRUE='#' + HAVE_DOCBOOK_FALSE= +fi + + + +if $GTKDOC; then + HAVE_GTK_DOC_TRUE= + HAVE_GTK_DOC_FALSE='#' +else + HAVE_GTK_DOC_TRUE='#' + HAVE_GTK_DOC_FALSE= +fi + + +# Check whether --enable-gtk-doc or --disable-gtk-doc was given. +if test "${enable_gtk_doc+set}" = set; then + enableval="$enable_gtk_doc" + enable_gtk_doc="$enableval" +else + enable_gtk_doc=auto +fi; + +if test "x$enable_gtk_doc" = xauto ; then + if test "x$GTKDOC" = xtrue ; then + enable_gtk_doc=yes + else + enable_gtk_doc=no + fi +fi + + + +if test x$enable_gtk_doc = xyes; then + ENABLE_GTK_DOC_TRUE= + ENABLE_GTK_DOC_FALSE='#' +else + ENABLE_GTK_DOC_TRUE='#' + ENABLE_GTK_DOC_FALSE= +fi + + + + + +# Check whether --with-afs or --without-afs was given. +if test "${with_afs+set}" = set; then + withval="$with_afs" + cat >>confdefs.h <<\_ACEOF +#define AFS 1 +_ACEOF + + CPPFLAGS="$CPPFLAGS -I/usr/afsws/include" + LIBS="$LIBS -L/usr/afsws/lib -L/usr/afsws/lib/afs -lsys -lrx -llwp" +fi; + +echo "$as_me:$LINENO: checking how to get filesystem type" >&5 +echo $ECHO_N "checking how to get filesystem type... $ECHO_C" >&6 +fstype=no +# The order of these tests is important. +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + cat >>confdefs.h <<\_ACEOF +#define FSTYPE_STATVFS 1 +_ACEOF + fstype=SVR4 +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi +rm -f conftest.err conftest.$ac_ext +if test $fstype = no; then +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + cat >>confdefs.h <<\_ACEOF +#define FSTYPE_USG_STATFS 1 +_ACEOF + fstype=SVR3 +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi +rm -f conftest.err conftest.$ac_ext +fi +if test $fstype = no; then +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + cat >>confdefs.h <<\_ACEOF +#define FSTYPE_AIX_STATFS 1 +_ACEOF + fstype=AIX +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi +rm -f conftest.err conftest.$ac_ext +fi +if test $fstype = no; then +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + cat >>confdefs.h <<\_ACEOF +#define FSTYPE_MNTENT 1 +_ACEOF + fstype=4.3BSD +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi +rm -f conftest.err conftest.$ac_ext +fi +if test $fstype = no; then +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "f_type;" >/dev/null 2>&1; then + cat >>confdefs.h <<\_ACEOF +#define FSTYPE_STATFS 1 +_ACEOF + fstype=4.4BSD/OSF1 +fi +rm -f conftest* + +fi +if test $fstype = no; then +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + cat >>confdefs.h <<\_ACEOF +#define FSTYPE_GETMNT 1 +_ACEOF + fstype=Ultrix +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi +rm -f conftest.err conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $fstype" >&5 +echo "${ECHO_T}$fstype" >&6 + + +echo "$as_me:$LINENO: checking for poptGetArg in -lpopt" >&5 +echo $ECHO_N "checking for poptGetArg in -lpopt... $ECHO_C" >&6 +if test "${ac_cv_lib_popt_poptGetArg+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpopt $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char poptGetArg (); +int +main () +{ +poptGetArg (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_popt_poptGetArg=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_popt_poptGetArg=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_popt_poptGetArg" >&5 +echo "${ECHO_T}$ac_cv_lib_popt_poptGetArg" >&6 +if test $ac_cv_lib_popt_poptGetArg = yes; then + POPT_LIBS=-lpopt +else + if test "${ac_cv_header_popt_h+set}" = set; then + echo "$as_me:$LINENO: checking for popt.h" >&5 +echo $ECHO_N "checking for popt.h... $ECHO_C" >&6 +if test "${ac_cv_header_popt_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: $ac_cv_header_popt_h" >&5 +echo "${ECHO_T}$ac_cv_header_popt_h" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking popt.h usability" >&5 +echo $ECHO_N "checking popt.h usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking popt.h presence" >&5 +echo $ECHO_N "checking popt.h presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc in + yes:no ) + { echo "$as_me:$LINENO: WARNING: popt.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: popt.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: popt.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: popt.h: proceeding with the preprocessor's result" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to bug-autoconf@gnu.org. ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; + no:yes ) + { echo "$as_me:$LINENO: WARNING: popt.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: popt.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: popt.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: popt.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: popt.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: popt.h: proceeding with the preprocessor's result" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to bug-autoconf@gnu.org. ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for popt.h" >&5 +echo $ECHO_N "checking for popt.h... $ECHO_C" >&6 +if test "${ac_cv_header_popt_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_popt_h=$ac_header_preproc +fi +echo "$as_me:$LINENO: result: $ac_cv_header_popt_h" >&5 +echo "${ECHO_T}$ac_cv_header_popt_h" >&6 + +fi +if test $ac_cv_header_popt_h = yes; then + : +else + { { echo "$as_me:$LINENO: error: +*** Couldn't find popt. Please download and install from +*** ftp://ftp.rpm.org/pub/rpm/dist/rpm-4.0.x/ and try again." >&5 +echo "$as_me: error: +*** Couldn't find popt. Please download and install from +*** ftp://ftp.rpm.org/pub/rpm/dist/rpm-4.0.x/ and try again." >&2;} + { (exit 1); exit 1; }; } +fi + + +fi + + + + + + + + +TOP_BUILDDIR="`pwd`" + + +echo "$as_me:$LINENO: checking whether to enable ipv6" >&5 +echo $ECHO_N "checking whether to enable ipv6... $ECHO_C" >&6 +# Check whether --enable-ipv6 or --disable-ipv6 was given. +if test "${enable_ipv6+set}" = set; then + enableval="$enable_ipv6" + +else + enable_ipv6=yes +fi; +if test $enable_ipv6 = yes; then + save_libs=$LIBS + + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + #include + #include +int +main () +{ + + socket(AF_INET6, SOCK_STREAM, 0) + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + have_ipv6=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +have_ipv6=no + +fi +rm -f conftest.$ac_objext conftest.$ac_ext + echo "$as_me:$LINENO: result: $have_ipv6" >&5 +echo "${ECHO_T}$have_ipv6" >&6 + + have_getaddrinfo=no + if test $have_ipv6 = yes; then + echo "$as_me:$LINENO: checking for getaddrinfo" >&5 +echo $ECHO_N "checking for getaddrinfo... $ECHO_C" >&6 +if test "${ac_cv_func_getaddrinfo+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char getaddrinfo (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ +#ifdef __STDC__ +# include +#else +# include +#endif +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getaddrinfo (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_getaddrinfo) || defined (__stub___getaddrinfo) +choke me +#else +char (*f) () = getaddrinfo; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != getaddrinfo; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_getaddrinfo=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_getaddrinfo=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_getaddrinfo" >&5 +echo "${ECHO_T}$ac_cv_func_getaddrinfo" >&6 +if test $ac_cv_func_getaddrinfo = yes; then + have_getaddrinfo=yes +fi + + if test $have_getaddrinfo != yes; then + # getaddrinfo is not in the default libraries. See if it's in some other. + for lib in bsd socket inet; do + as_ac_Lib=`echo "ac_cv_lib_$lib''_getaddrinfo" | $as_tr_sh` +echo "$as_me:$LINENO: checking for getaddrinfo in -l$lib" >&5 +echo $ECHO_N "checking for getaddrinfo in -l$lib... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Lib+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-l$lib $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getaddrinfo (); +int +main () +{ +getaddrinfo (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_Lib=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_Lib=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Lib'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Lib'}'`" >&6 +if test `eval echo '${'$as_ac_Lib'}'` = yes; then + LIBS="$LIBS -l$lib";have_getaddrinfo=yes; break +fi + + done + fi + if test $have_getaddrinfo = yes; then + cat >>confdefs.h <<\_ACEOF +#define ENABLE_IPV6 1 +_ACEOF + + fi + fi +fi + + ac_config_files="$ac_config_files Makefile gnome-vfs.spec libgnomevfs/gnome-vfs-file-size.h libgnomevfs/Makefile modules/Makefile modules/extfs/Makefile modules/extfs/ar modules/extfs/cpio modules/extfs/deb modules/extfs/lha modules/extfs/rar modules/extfs/zip modules/extfs/zoo modules/vfolder/Makefile monikers/Makefile schemas/Makefile devel-docs/Makefile devel-docs/gnome-vfs-tutorial/Makefile po/Makefile.in programs/Makefile test/Makefile test/vfs-run doc/Makefile gnome-vfs-2.0.pc gnome-vfs-module-2.0.pc" +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +{ + (set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} | + sed ' + t clear + : clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + : end' >>confcache +if diff $cache_file confcache >/dev/null 2>&1; then :; else + if test -w $cache_file; then + test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" + cat confcache >$cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/; +s/:*\${srcdir}:*/:/; +s/:*@srcdir@:*/:/; +s/^\([^=]*=[ ]*\):*/\1/; +s/:*$//; +s/^[^=]*=[ ]*$//; +}' +fi + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_i=`echo "$ac_i" | + sed 's/\$U\././;s/\.o$//;s/\.obj$//'` + # 2. Add them. + ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + + + mv -f po/POTFILES po/POTFILES.tmp + sed -e 's/\[.*\] *//' < po/POTFILES.tmp > po/POTFILES + rm -f po/POTFILES.tmp + + + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi + +# Support unset when possible. +if (FOO=FOO; unset FOO) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 +echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 +echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + +exec 6>&1 + +# Open the log real soon, to keep \$[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. Logging --version etc. is OK. +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX +} >&5 +cat >&5 <<_CSEOF + +This file was extended by $as_me, which was +generated by GNU Autoconf 2.57. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +_CSEOF +echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 +echo >&5 +_ACEOF + +# Files that config.status was made for. +if test -n "$ac_config_files"; then + echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_headers"; then + echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_links"; then + echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_commands"; then + echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS +fi + +cat >>$CONFIG_STATUS <<\_ACEOF + +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to ." +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.57, + with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" + +Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." +srcdir=$srcdir +INSTALL="$INSTALL" +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "x$1" : 'x\([^=]*\)='` + ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + ac_shift=: + ;; + -*) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + *) # This is not an option, so the user has probably given explicit + # arguments. + ac_option=$1 + ac_need_defaults=false;; + esac + + case $ac_option in + # Handling of the options. +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --vers* | -V ) + echo "$ac_cs_version"; exit 0 ;; + --he | --h) + # Conflict between --help and --header + { { echo "$as_me:$LINENO: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +if \$ac_cs_recheck; then + echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +# +# INIT-COMMANDS section. +# + + +INTLTOOL_PERL=${INTLTOOL_PERL} + + +_ACEOF + + + +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_config_target in $ac_config_targets +do + case "$ac_config_target" in + # Handling of arguments. + "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "gnome-vfs.spec" ) CONFIG_FILES="$CONFIG_FILES gnome-vfs.spec" ;; + "libgnomevfs/gnome-vfs-file-size.h" ) CONFIG_FILES="$CONFIG_FILES libgnomevfs/gnome-vfs-file-size.h" ;; + "libgnomevfs/Makefile" ) CONFIG_FILES="$CONFIG_FILES libgnomevfs/Makefile" ;; + "modules/Makefile" ) CONFIG_FILES="$CONFIG_FILES modules/Makefile" ;; + "modules/extfs/Makefile" ) CONFIG_FILES="$CONFIG_FILES modules/extfs/Makefile" ;; + "modules/extfs/ar" ) CONFIG_FILES="$CONFIG_FILES modules/extfs/ar" ;; + "modules/extfs/cpio" ) CONFIG_FILES="$CONFIG_FILES modules/extfs/cpio" ;; + "modules/extfs/deb" ) CONFIG_FILES="$CONFIG_FILES modules/extfs/deb" ;; + "modules/extfs/lha" ) CONFIG_FILES="$CONFIG_FILES modules/extfs/lha" ;; + "modules/extfs/rar" ) CONFIG_FILES="$CONFIG_FILES modules/extfs/rar" ;; + "modules/extfs/zip" ) CONFIG_FILES="$CONFIG_FILES modules/extfs/zip" ;; + "modules/extfs/zoo" ) CONFIG_FILES="$CONFIG_FILES modules/extfs/zoo" ;; + "modules/vfolder/Makefile" ) CONFIG_FILES="$CONFIG_FILES modules/vfolder/Makefile" ;; + "monikers/Makefile" ) CONFIG_FILES="$CONFIG_FILES monikers/Makefile" ;; + "schemas/Makefile" ) CONFIG_FILES="$CONFIG_FILES schemas/Makefile" ;; + "devel-docs/Makefile" ) CONFIG_FILES="$CONFIG_FILES devel-docs/Makefile" ;; + "devel-docs/gnome-vfs-tutorial/Makefile" ) CONFIG_FILES="$CONFIG_FILES devel-docs/gnome-vfs-tutorial/Makefile" ;; + "po/Makefile.in" ) CONFIG_FILES="$CONFIG_FILES po/Makefile.in" ;; + "programs/Makefile" ) CONFIG_FILES="$CONFIG_FILES programs/Makefile" ;; + "test/Makefile" ) CONFIG_FILES="$CONFIG_FILES test/Makefile" ;; + "test/vfs-run" ) CONFIG_FILES="$CONFIG_FILES test/vfs-run" ;; + "doc/Makefile" ) CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; + "gnome-vfs-2.0.pc" ) CONFIG_FILES="$CONFIG_FILES gnome-vfs-2.0.pc" ;; + "gnome-vfs-module-2.0.pc" ) CONFIG_FILES="$CONFIG_FILES gnome-vfs-module-2.0.pc" ;; + "default-1" ) CONFIG_COMMANDS="$CONFIG_COMMANDS default-1" ;; + "default-2" ) CONFIG_COMMANDS="$CONFIG_COMMANDS default-2" ;; + "default-3" ) CONFIG_COMMANDS="$CONFIG_COMMANDS default-3" ;; + "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason to put it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./confstat$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF + +# +# CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "\$CONFIG_FILES"; then + # Protect against being on the right side of a sed subst in config.status. + sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; + s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF +s,@SHELL@,$SHELL,;t t +s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t +s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t +s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t +s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t +s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t +s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t +s,@exec_prefix@,$exec_prefix,;t t +s,@prefix@,$prefix,;t t +s,@program_transform_name@,$program_transform_name,;t t +s,@bindir@,$bindir,;t t +s,@sbindir@,$sbindir,;t t +s,@libexecdir@,$libexecdir,;t t +s,@datadir@,$datadir,;t t +s,@sysconfdir@,$sysconfdir,;t t +s,@sharedstatedir@,$sharedstatedir,;t t +s,@localstatedir@,$localstatedir,;t t +s,@libdir@,$libdir,;t t +s,@includedir@,$includedir,;t t +s,@oldincludedir@,$oldincludedir,;t t +s,@infodir@,$infodir,;t t +s,@mandir@,$mandir,;t t +s,@build_alias@,$build_alias,;t t +s,@host_alias@,$host_alias,;t t +s,@target_alias@,$target_alias,;t t +s,@DEFS@,$DEFS,;t t +s,@ECHO_C@,$ECHO_C,;t t +s,@ECHO_N@,$ECHO_N,;t t +s,@ECHO_T@,$ECHO_T,;t t +s,@LIBS@,$LIBS,;t t +s,@LIBGNOMEVFS_CURRENT@,$LIBGNOMEVFS_CURRENT,;t t +s,@LIBGNOMEVFS_REVISION@,$LIBGNOMEVFS_REVISION,;t t +s,@LIBGNOMEVFS_AGE@,$LIBGNOMEVFS_AGE,;t t +s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t +s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t +s,@INSTALL_DATA@,$INSTALL_DATA,;t t +s,@PACKAGE@,$PACKAGE,;t t +s,@VERSION@,$VERSION,;t t +s,@ACLOCAL@,$ACLOCAL,;t t +s,@AUTOCONF@,$AUTOCONF,;t t +s,@AUTOMAKE@,$AUTOMAKE,;t t +s,@AUTOHEADER@,$AUTOHEADER,;t t +s,@MAKEINFO@,$MAKEINFO,;t t +s,@SET_MAKE@,$SET_MAKE,;t t +s,@ACLOCAL_AMFLAGS@,$ACLOCAL_AMFLAGS,;t t +s,@MAINTAINER_MODE_TRUE@,$MAINTAINER_MODE_TRUE,;t t +s,@MAINTAINER_MODE_FALSE@,$MAINTAINER_MODE_FALSE,;t t +s,@MAINT@,$MAINT,;t t +s,@GNOME_ACLOCAL_DIR@,$GNOME_ACLOCAL_DIR,;t t +s,@GNOME_ACLOCAL_FLAGS@,$GNOME_ACLOCAL_FLAGS,;t t +s,@INSIDE_GNOME_DOCU_TRUE@,$INSIDE_GNOME_DOCU_TRUE,;t t +s,@INSIDE_GNOME_DOCU_FALSE@,$INSIDE_GNOME_DOCU_FALSE,;t t +s,@CC@,$CC,;t t +s,@CFLAGS@,$CFLAGS,;t t +s,@LDFLAGS@,$LDFLAGS,;t t +s,@CPPFLAGS@,$CPPFLAGS,;t t +s,@ac_ct_CC@,$ac_ct_CC,;t t +s,@EXEEXT@,$EXEEXT,;t t +s,@OBJEXT@,$OBJEXT,;t t +s,@CPP@,$CPP,;t t +s,@AWK@,$AWK,;t t +s,@build@,$build,;t t +s,@build_cpu@,$build_cpu,;t t +s,@build_vendor@,$build_vendor,;t t +s,@build_os@,$build_os,;t t +s,@host@,$host,;t t +s,@host_cpu@,$host_cpu,;t t +s,@host_vendor@,$host_vendor,;t t +s,@host_os@,$host_os,;t t +s,@LN_S@,$LN_S,;t t +s,@ECHO@,$ECHO,;t t +s,@RANLIB@,$RANLIB,;t t +s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t +s,@STRIP@,$STRIP,;t t +s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t +s,@EGREP@,$EGREP,;t t +s,@LIBTOOL@,$LIBTOOL,;t t +s,@INTLTOOL_DESKTOP_RULE@,$INTLTOOL_DESKTOP_RULE,;t t +s,@INTLTOOL_DIRECTORY_RULE@,$INTLTOOL_DIRECTORY_RULE,;t t +s,@INTLTOOL_KEYS_RULE@,$INTLTOOL_KEYS_RULE,;t t +s,@INTLTOOL_PROP_RULE@,$INTLTOOL_PROP_RULE,;t t +s,@INTLTOOL_OAF_RULE@,$INTLTOOL_OAF_RULE,;t t +s,@INTLTOOL_PONG_RULE@,$INTLTOOL_PONG_RULE,;t t +s,@INTLTOOL_SERVER_RULE@,$INTLTOOL_SERVER_RULE,;t t +s,@INTLTOOL_SHEET_RULE@,$INTLTOOL_SHEET_RULE,;t t +s,@INTLTOOL_SOUNDLIST_RULE@,$INTLTOOL_SOUNDLIST_RULE,;t t +s,@INTLTOOL_UI_RULE@,$INTLTOOL_UI_RULE,;t t +s,@INTLTOOL_XML_RULE@,$INTLTOOL_XML_RULE,;t t +s,@INTLTOOL_CAVES_RULE@,$INTLTOOL_CAVES_RULE,;t t +s,@INTLTOOL_SCHEMAS_RULE@,$INTLTOOL_SCHEMAS_RULE,;t t +s,@INTLTOOL_THEME_RULE@,$INTLTOOL_THEME_RULE,;t t +s,@INTLTOOL_EXTRACT@,$INTLTOOL_EXTRACT,;t t +s,@INTLTOOL_MERGE@,$INTLTOOL_MERGE,;t t +s,@INTLTOOL_UPDATE@,$INTLTOOL_UPDATE,;t t +s,@INTLTOOL_PERL@,$INTLTOOL_PERL,;t t +s,@BONOBO_ACTIVATION_REQUIRED@,$BONOBO_ACTIVATION_REQUIRED,;t t +s,@BONOBO_REQUIRED@,$BONOBO_REQUIRED,;t t +s,@GCONF_REQUIRED@,$GCONF_REQUIRED,;t t +s,@GLIB_REQUIRED@,$GLIB_REQUIRED,;t t +s,@LIBIDL_REQUIRED@,$LIBIDL_REQUIRED,;t t +s,@ORBIT_REQUIRED@,$ORBIT_REQUIRED,;t t +s,@XML_REQUIRED@,$XML_REQUIRED,;t t +s,@PKG_CONFIG@,$PKG_CONFIG,;t t +s,@MODULES_XML_CFLAGS@,$MODULES_XML_CFLAGS,;t t +s,@MODULES_XML_LIBS@,$MODULES_XML_LIBS,;t t +s,@MODULES_CFLAGS@,$MODULES_CFLAGS,;t t +s,@MODULES_LIBS@,$MODULES_LIBS,;t t +s,@MODULES_FILE_CFLAGS@,$MODULES_FILE_CFLAGS,;t t +s,@MODULES_FILE_LIBS@,$MODULES_FILE_LIBS,;t t +s,@MODULES_GCONF_CFLAGS@,$MODULES_GCONF_CFLAGS,;t t +s,@MODULES_GCONF_LIBS@,$MODULES_GCONF_LIBS,;t t +s,@MODULES_XML_GCONF_CFLAGS@,$MODULES_XML_GCONF_CFLAGS,;t t +s,@MODULES_XML_GCONF_LIBS@,$MODULES_XML_GCONF_LIBS,;t t +s,@MONIKERS_CFLAGS@,$MONIKERS_CFLAGS,;t t +s,@MONIKERS_LIBS@,$MONIKERS_LIBS,;t t +s,@TEST_CFLAGS@,$TEST_CFLAGS,;t t +s,@TEST_LIBS@,$TEST_LIBS,;t t +s,@ORBIT_IDL@,$ORBIT_IDL,;t t +s,@BONOBO_IDLDIR@,$BONOBO_IDLDIR,;t t +s,@WARN_CFLAGS@,$WARN_CFLAGS,;t t +s,@GETTEXT_PACKAGE@,$GETTEXT_PACKAGE,;t t +s,@USE_NLS@,$USE_NLS,;t t +s,@MSGFMT@,$MSGFMT,;t t +s,@GMSGFMT@,$GMSGFMT,;t t +s,@XGETTEXT@,$XGETTEXT,;t t +s,@CATALOGS@,$CATALOGS,;t t +s,@CATOBJEXT@,$CATOBJEXT,;t t +s,@DATADIRNAME@,$DATADIRNAME,;t t +s,@GMOFILES@,$GMOFILES,;t t +s,@INSTOBJEXT@,$INSTOBJEXT,;t t +s,@INTLLIBS@,$INTLLIBS,;t t +s,@PO_IN_DATADIR_TRUE@,$PO_IN_DATADIR_TRUE,;t t +s,@PO_IN_DATADIR_FALSE@,$PO_IN_DATADIR_FALSE,;t t +s,@POFILES@,$POFILES,;t t +s,@POSUB@,$POSUB,;t t +s,@MKINSTALLDIRS@,$MKINSTALLDIRS,;t t +s,@ALLOCA@,$ALLOCA,;t t +s,@GCONFTOOL@,$GCONFTOOL,;t t +s,@GCONF_SCHEMA_CONFIG_SOURCE@,$GCONF_SCHEMA_CONFIG_SOURCE,;t t +s,@GCONF_SCHEMA_FILE_DIR@,$GCONF_SCHEMA_FILE_DIR,;t t +s,@GCONF_SCHEMAS_INSTALL_TRUE@,$GCONF_SCHEMAS_INSTALL_TRUE,;t t +s,@GCONF_SCHEMAS_INSTALL_FALSE@,$GCONF_SCHEMAS_INSTALL_FALSE,;t t +s,@VFS_SIZE@,$VFS_SIZE,;t t +s,@VFS_OFFSET@,$VFS_OFFSET,;t t +s,@VFS_SIZE_IS@,$VFS_SIZE_IS,;t t +s,@VFS_OFFSET_IS@,$VFS_OFFSET_IS,;t t +s,@VFS_SIZE_PRINTF@,$VFS_SIZE_PRINTF,;t t +s,@VFS_OFFSET_PRINTF@,$VFS_OFFSET_PRINTF,;t t +s,@ENABLE_PROFILER@,$ENABLE_PROFILER,;t t +s,@ENABLE_PROFILER_TRUE@,$ENABLE_PROFILER_TRUE,;t t +s,@ENABLE_PROFILER_FALSE@,$ENABLE_PROFILER_FALSE,;t t +s,@VFS_CFLAGS@,$VFS_CFLAGS,;t t +s,@GNOME_VFS_DIR@,$GNOME_VFS_DIR,;t t +s,@VFS_LIBDIR@,$VFS_LIBDIR,;t t +s,@VFS_INCLUDEDIR@,$VFS_INCLUDEDIR,;t t +s,@VFS_LIBS@,$VFS_LIBS,;t t +s,@HAVE_LIBEFS_TRUE@,$HAVE_LIBEFS_TRUE,;t t +s,@HAVE_LIBEFS_FALSE@,$HAVE_LIBEFS_FALSE,;t t +s,@LIBEFS_LIBS@,$LIBEFS_LIBS,;t t +s,@LIBEFS_CFLAGS@,$LIBEFS_CFLAGS,;t t +s,@BZ2_LIBS@,$BZ2_LIBS,;t t +s,@HAVE_CDDA_TRUE@,$HAVE_CDDA_TRUE,;t t +s,@HAVE_CDDA_FALSE@,$HAVE_CDDA_FALSE,;t t +s,@BUILD_CDEMENU_MODULE_TRUE@,$BUILD_CDEMENU_MODULE_TRUE,;t t +s,@BUILD_CDEMENU_MODULE_FALSE@,$BUILD_CDEMENU_MODULE_FALSE,;t t +s,@HAVE_SSL_TRUE@,$HAVE_SSL_TRUE,;t t +s,@HAVE_SSL_FALSE@,$HAVE_SSL_FALSE,;t t +s,@OPENSSL_CFLAGS@,$OPENSSL_CFLAGS,;t t +s,@OPENSSL_LIBS@,$OPENSSL_LIBS,;t t +s,@LIBGNUTLS_CONFIG@,$LIBGNUTLS_CONFIG,;t t +s,@LIBGNUTLS_CFLAGS@,$LIBGNUTLS_CFLAGS,;t t +s,@LIBGNUTLS_LIBS@,$LIBGNUTLS_LIBS,;t t +s,@LIBGNOMEVFS_CFLAGS@,$LIBGNOMEVFS_CFLAGS,;t t +s,@LIBGNOMEVFS_LIBS@,$LIBGNOMEVFS_LIBS,;t t +s,@FAM_LIBS@,$FAM_LIBS,;t t +s,@HTML_DIR@,$HTML_DIR,;t t +s,@GTKDOC@,$GTKDOC,;t t +s,@DB2HTML@,$DB2HTML,;t t +s,@HAVE_DOCBOOK_TRUE@,$HAVE_DOCBOOK_TRUE,;t t +s,@HAVE_DOCBOOK_FALSE@,$HAVE_DOCBOOK_FALSE,;t t +s,@HAVE_GTK_DOC_TRUE@,$HAVE_GTK_DOC_TRUE,;t t +s,@HAVE_GTK_DOC_FALSE@,$HAVE_GTK_DOC_FALSE,;t t +s,@HAVE_GTK_DOC@,$HAVE_GTK_DOC,;t t +s,@ENABLE_GTK_DOC_TRUE@,$ENABLE_GTK_DOC_TRUE,;t t +s,@ENABLE_GTK_DOC_FALSE@,$ENABLE_GTK_DOC_FALSE,;t t +s,@POPT_LIBS@,$POPT_LIBS,;t t +s,@TOP_BUILDDIR@,$TOP_BUILDDIR,;t t +s,@LIBOBJS@,$LIBOBJS,;t t +s,@LTLIBOBJS@,$LTLIBOBJS,;t t +CEOF + +_ACEOF + + cat >>$CONFIG_STATUS <<\_ACEOF + # Split the substitutions into bite-sized pieces for seds with + # small command number limits, like on Digital OSF/1 and HP-UX. + ac_max_sed_lines=48 + ac_sed_frag=1 # Number of current file. + ac_beg=1 # First line for current file. + ac_end=$ac_max_sed_lines # Line after last line for current file. + ac_more_lines=: + ac_sed_cmds= + while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + else + sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + fi + if test ! -s $tmp/subs.frag; then + ac_more_lines=false + else + # The purpose of the label and of the branching condition is to + # speed up the sed processing (if there are no `@' at all, there + # is no need to browse any of the substitutions). + # These are the two extra sed commands mentioned above. + (echo ':t + /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" + else + ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" + fi + ac_sed_frag=`expr $ac_sed_frag + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_lines` + fi + done + if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat + fi +fi # test -n "$CONFIG_FILES" + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac +# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be +# absolute. +ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` +ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` +ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` +ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` + + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_builddir$INSTALL ;; + esac + + if test x"$ac_file" != x-; then + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + configure_input= + else + configure_input="$ac_file. " + fi + configure_input=$configure_input"Generated from `echo $ac_file_in | + sed 's,.*/,,'` by configure." + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo $f;; + *) # Relative + if test -f "$f"; then + # Build tree + echo $f + elif test -f "$srcdir/$f"; then + # Source tree + echo $srcdir/$f + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s,@configure_input@,$configure_input,;t t +s,@srcdir@,$ac_srcdir,;t t +s,@abs_srcdir@,$ac_abs_srcdir,;t t +s,@top_srcdir@,$ac_top_srcdir,;t t +s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t +s,@builddir@,$ac_builddir,;t t +s,@abs_builddir@,$ac_abs_builddir,;t t +s,@top_builddir@,$ac_top_builddir,;t t +s,@abs_top_builddir@,$ac_abs_top_builddir,;t t +s,@INSTALL@,$ac_INSTALL,;t t +" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out + rm -f $tmp/stdin + if test x"$ac_file" != x-; then + mv $tmp/out $ac_file + else + cat $tmp/out + rm -f $tmp/out + fi + +done +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + +# +# CONFIG_HEADER section. +# + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='[ ].*$,\1#\2' +ac_dC=' ' +ac_dD=',;t' +# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='$,\1#\2define\3' +ac_uC=' ' +ac_uD=',;t' + +for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo $f;; + *) # Relative + if test -f "$f"; then + # Build tree + echo $f + elif test -f "$srcdir/$f"; then + # Source tree + echo $srcdir/$f + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } + # Remove the trailing spaces. + sed 's/[ ]*$//' $ac_file_inputs >$tmp/in + +_ACEOF + +# Transform confdefs.h into two sed scripts, `conftest.defines' and +# `conftest.undefs', that substitutes the proper values into +# config.h.in to produce config.h. The first handles `#define' +# templates, and the second `#undef' templates. +# And first: Protect against being on the right side of a sed subst in +# config.status. Protect against being in an unquoted here document +# in config.status. +rm -f conftest.defines conftest.undefs +# Using a here document instead of a string reduces the quoting nightmare. +# Putting comments in sed scripts is not portable. +# +# `end' is used to avoid that the second main sed command (meant for +# 0-ary CPP macros) applies to n-ary macro definitions. +# See the Autoconf documentation for `clear'. +cat >confdef2sed.sed <<\_ACEOF +s/[\\&,]/\\&/g +s,[\\$`],\\&,g +t clear +: clear +s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp +t end +s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp +: end +_ACEOF +# If some macros were called several times there might be several times +# the same #defines, which is useless. Nevertheless, we may not want to +# sort them, since we want the *last* AC-DEFINE to be honored. +uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines +sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs +rm -f confdef2sed.sed + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >>conftest.undefs <<\_ACEOF +s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, +_ACEOF + +# Break up conftest.defines because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS +echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS +echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS +echo ' :' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.defines >/dev/null +do + # Write a limited-size here document to $tmp/defines.sed. + echo ' cat >$tmp/defines.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#define' lines. + echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/defines.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines +echo ' fi # grep' >>$CONFIG_STATUS +echo >>$CONFIG_STATUS + +# Break up conftest.undefs because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #undef templates' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.undefs >/dev/null +do + # Write a limited-size here document to $tmp/undefs.sed. + echo ' cat >$tmp/undefs.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#undef' + echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/undefs.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail + rm -f conftest.undefs + mv conftest.tail conftest.undefs +done +rm -f conftest.undefs + +cat >>$CONFIG_STATUS <<\_ACEOF + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + echo "/* Generated by configure. */" >$tmp/config.h + else + echo "/* $ac_file. Generated by configure. */" >$tmp/config.h + fi + cat $tmp/in >>$tmp/config.h + rm -f $tmp/in + if test x"$ac_file" != x-; then + if diff $ac_file $tmp/config.h >/dev/null 2>&1; then + { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + rm -f $ac_file + mv $tmp/config.h $ac_file + fi + else + cat $tmp/config.h + rm -f $tmp/config.h + fi +done +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + +# +# CONFIG_COMMANDS section. +# +for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue + ac_dest=`echo "$ac_file" | sed 's,:.*,,'` + ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_dir=`(dirname "$ac_dest") 2>/dev/null || +$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_dest" : 'X\(//\)[^/]' \| \ + X"$ac_dest" : 'X\(//\)$' \| \ + X"$ac_dest" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_dest" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac +# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be +# absolute. +ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` +ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` +ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` +ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` + + + { echo "$as_me:$LINENO: executing $ac_dest commands" >&5 +echo "$as_me: executing $ac_dest commands" >&6;} + case $ac_dest in + default-1 ) test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h ;; + default-2 ) + +sed -e "s:@INTLTOOL_PERL@:${INTLTOOL_PERL}:;" < ${srcdir}/intltool-extract.in > intltool-extract.out +if cmp -s intltool-extract intltool-extract.out 2>/dev/null; then + rm -f intltool-extract.out +else + mv -f intltool-extract.out intltool-extract +fi +chmod ugo+x intltool-extract +chmod u+w intltool-extract + +sed -e "s:@INTLTOOL_PERL@:${INTLTOOL_PERL}:;" < ${srcdir}/intltool-merge.in > intltool-merge.out +if cmp -s intltool-merge intltool-merge.out 2>/dev/null; then + rm -f intltool-merge.out +else + mv -f intltool-merge.out intltool-merge +fi +chmod ugo+x intltool-merge +chmod u+w intltool-merge + +sed -e "s:@INTLTOOL_PERL@:${INTLTOOL_PERL}:;" < ${srcdir}/intltool-update.in > intltool-update.out +if cmp -s intltool-update intltool-update.out 2>/dev/null; then + rm -f intltool-update.out +else + mv -f intltool-update.out intltool-update +fi +chmod ugo+x intltool-update +chmod u+w intltool-update + + ;; + default-3 ) case "$CONFIG_FILES" in *po/Makefile.in*) + sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile + esac ;; + esac +done +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + + +chmod u+x test/vfs-run + + +echo "<= gnome-vfs configuration summary :" +case "X$ENABLE_PROFILER" in +X1) +echo " +Enable profiler : YES" +;; +*) +echo " +Enable profiler : NO" +echo +;; +esac + +echo " +CFLAGS : $CFLAGS +LDFLAGS : $LDFLAGS" +echo diff --git a/configure.in b/configure.in new file mode 100644 index 0000000..7724f72 --- /dev/null +++ b/configure.in @@ -0,0 +1,695 @@ +AC_INIT(libgnomevfs/gnome-vfs.h) + +# Making releases: +# LIBGNOMEVFS_MICRO_VERSION += 1; +# LIBGNOMEVFS_INTERFACE_AGE += 1; +# if any functions have been added, set LIBGNOMEVFS_INTERFACE_AGE to 0. +# if backwards compatibility has been broken, +# set LIBGNOMEVFS_BINARY_AGE and LIBGNOMEVFS_INTERFACE_AGE to 0. +# +LIBGNOMEVFS_MAJOR_VERSION=2 +LIBGNOMEVFS_MINOR_VERSION=3 +LIBGNOMEVFS_MICRO_VERSION=8 +LIBGNOMEVFS_INTERFACE_AGE=8 +# If you need a modifier for the version number. +# Normally empty, but can be used to make "fixup" releases. +LIBGNOMEVFS_EXTRAVERSION= + +dnl libtool versioning from libgnome + +LIBGNOMEVFS_CURRENT=`expr 100 '*' $LIBGNOMEVFS_MINOR_VERSION + $LIBGNOMEVFS_MICRO_VERSION - $LIBGNOMEVFS_INTERFACE_AGE` +LIBGNOMEVFS_BINARY_AGE=`expr 100 '*' $LIBGNOMEVFS_MINOR_VERSION + $LIBGNOMEVFS_MICRO_VERSION` +LIBGNOMEVFS_REVISION=$LIBGNOMEVFS_INTERFACE_AGE +LIBGNOMEVFS_AGE=`expr $LIBGNOMEVFS_BINARY_AGE - $LIBGNOMEVFS_INTERFACE_AGE` +LIBGNOMEVFS_VERSION=$LIBGNOMEVFS_MAJOR_VERSION.$LIBGNOMEVFS_MINOR_VERSION.$LIBGNOMEVFS_MICRO_VERSION$LIBGNOMEVFS_EXTRAVERSION + +AC_SUBST(LIBGNOMEVFS_CURRENT) +AC_SUBST(LIBGNOMEVFS_REVISION) +AC_SUBST(LIBGNOMEVFS_AGE) + + +AM_CONFIG_HEADER(config.h) +AM_INIT_AUTOMAKE(gnome-vfs, $LIBGNOMEVFS_VERSION) + +dnl make sure we keep ACLOCAL_FLAGS around for maintainer builds to work +AC_SUBST(ACLOCAL_AMFLAGS, "$ACLOCAL_FLAGS") + +AM_MAINTAINER_MODE + +GNOME_COMMON_INIT +GNOME_PLATFORM_GNOME_2(yes, force) + +dnl touch NOINST_GOB +dnl AC_CONFIG_SUBDIRS(gob) + +AC_ISC_POSIX +AC_PROG_CC +AC_PROG_CPP +AC_PROG_AWK +AC_LIBTOOL_WIN32_DLL +AM_PROG_LIBTOOL +AC_PROG_INTLTOOL + +dnl Versions shared with the .spec file. +BONOBO_ACTIVATION_REQUIRED=1.0.0 +BONOBO_REQUIRED=2.0.0 +GCONF_REQUIRED=1.1.1 +GLIB_REQUIRED=2.0.0 +ORBIT_REQUIRED=2.4.0 +XML_REQUIRED=2.2.8 + +AC_SUBST(BONOBO_ACTIVATION_REQUIRED) +AC_SUBST(BONOBO_REQUIRED) +AC_SUBST(GCONF_REQUIRED) +AC_SUBST(GLIB_REQUIRED) +AC_SUBST(LIBIDL_REQUIRED) +AC_SUBST(ORBIT_REQUIRED) +AC_SUBST(XML_REQUIRED) + +PKG_CHECK_MODULES(MODULES_XML, glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED libxml-2.0 >= $XML_REQUIRED) +AC_SUBST(MODULES_XML_CFLAGS) +AC_SUBST(MODULES_XML_LIBS) + +PKG_CHECK_MODULES(MODULES, glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED) +AC_SUBST(MODULES_LIBS) +AC_SUBST(MODULES_CFLAGS) + +PKG_CHECK_MODULES(MODULES_FILE, glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED) +AC_SUBST(MODULES_FILE_LIBS) +AC_SUBST(MODULES_FILE_CFLAGS) + +PKG_CHECK_MODULES(MODULES_GCONF, glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED gconf-2.0 >= $GCONF_REQUIRED) +AC_SUBST(MODULES_GCONF_CFLAGS) +AC_SUBST(MODULES_GCONF_LIBS) + +PKG_CHECK_MODULES(MODULES_XML_GCONF, glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED libxml-2.0 >= $XML_REQUIRED gconf-2.0 >= $GCONF_REQUIRED) +AC_SUBST(MODULES_XML_GCONF_CFLAGS) +AC_SUBST(MODULES_XML_GCONF_LIBS) + +PKG_CHECK_MODULES(MONIKERS, libbonobo-2.0 >= $BONOBO_REQUIRED) +AC_SUBST(MONIKERS_CFLAGS) +AC_SUBST(MONIKERS_LIBS) + +PKG_CHECK_MODULES(TEST, bonobo-activation-2.0 >= $BONOBO_ACTIVATION_REQUIRED gconf-2.0 >= $GCONF_REQUIRED gthread-2.0 >= $GLIB_REQUIRED) +AC_SUBST(TEST_LIBS) +AC_SUBST(TEST_CFLAGS) + +ORBIT_IDL="`$PKG_CONFIG --variable=orbit_idl ORBit-2.0`" +AC_SUBST(ORBIT_IDL) + +BONOBO_IDLDIR="`$PKG_CONFIG --variable=idldir bonobo-activation-2.0`" +AC_SUBST(BONOBO_IDLDIR) + +cflags_set=yes +GNOME_COMPILE_WARNINGS +VFS_CFLAGS="$warnCFLAGS $complCFLAGS" + +GNOME_PTHREAD_CHECK +dnl semaphore functions are in librt.so on solaris +AC_CHECK_LIB(rt, sem_wait) + +dnl Don't blindly #define them if they're typedef'ed in +AM_GNOME_SIZE_T +AM_GNOME_OFF_T + +AC_CACHE_CHECK([for off64_t], + ac_cv_have_off64_t, + AC_TRY_COMPILE([ +# define _LARGEFILE64_SOURCE +# include ], + [off64_t testoffset], + ac_cv_have_off64_t=yes, + ac_cv_have_off64_t=no)) +if test x"$ac_cv_have_off64_t" = "xyes" ; then + AC_DEFINE(HAVE_OFF64_T) +fi + +GETTEXT_PACKAGE=gnome-vfs-2.0 +AC_SUBST(GETTEXT_PACKAGE) +AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE") + +ALL_LINGUAS="am ar az be bg bn bs ca cs cy da de el eo es et eu fa fi fr ga gl he hi hu id is it ja ko li lt lv mk ml mn ms nl nn no pl pt pt_BR ro ru sk sl sq sr sr@Latn sv tr uk vi wa yi zh_CN zh_TW" +AM_GLIB_GNU_GETTEXT + +AC_CHECK_LIB(nsl, t_accept) +AC_CHECK_LIB(socket, socket) + +AC_FUNC_ALLOCA +AC_CHECK_FUNCS(getdtablesize open64 lseek64 statvfs seteuid setegid setresuid setresgid readdir_r mbrtowc inet_pton getdelim) + +dnl Specify the gconf configuration source, +dnl default to xml::$(sysconfdir)/gconf/gconf.xml.defaults + +AC_PATH_PROG(GCONFTOOL, gconftool-2, no) + +if test x"$GCONFTOOL" = xno; then + AC_MSG_ERROR([gconftool-2 executable not found in your path - should be installed with GConf]) +fi + +AM_GCONF_SOURCE_2 + +dnl +dnl This is so that we find the 64bit type +dnl +AC_CHECK_SIZEOF(int) +AC_CHECK_SIZEOF(long) +AC_CHECK_SIZEOF(long long) + +VFS_SIZE="unsigned long" +VFS_OFFSET="long" +VFS_SIZE_IS="UNSIGNED_LONG" +VFS_OFFSET_IS="LONG" +VFS_SIZE_PRINTF="lu" +VFS_OFFSET_PRINTF="ld" + +dnl +dnl See if any of the types is 64 bits, and in case it is, use it +dnl Note: We test an (int) even though I think using (long) would be fine. +dnl This is because glib does it this way for gint64 and so there +dnl is probably a reason behind it +dnl +case 8 in +$ac_cv_sizeof_int) + VFS_SIZE="unsigned int" + VFS_OFFSET="int" + VFS_SIZE_IS="UNSIGNED_INT" + VFS_OFFSET_IS="INT" + VFS_SIZE_PRINTF="u" + VFS_OFFSET_PRINTF="d" + ;; +$ac_cv_sizeof_long) + # Nothing happens here, we are already using a long + ;; +$ac_cv_sizeof_long_long) + VFS_SIZE="unsigned long long" + VFS_OFFSET="long long" + VFS_SIZE_IS="UNSIGNED_LONG_LONG" + VFS_OFFSET_IS="LONG_LONG" + VFS_SIZE_PRINTF="Lu" + VFS_OFFSET_PRINTF="Ld" + ;; +esac + +AC_SUBST(VFS_SIZE) +AC_SUBST(VFS_OFFSET) +AC_SUBST(VFS_SIZE_IS) +AC_SUBST(VFS_OFFSET_IS) +AC_SUBST(VFS_SIZE_PRINTF) +AC_SUBST(VFS_OFFSET_PRINTF) + +AC_CHECK_HEADERS(sys/param.h sys/resource.h sys/vfs.h sys/mount.h sys/statvfs.h wctype.h) + +dnl ==================================== +dnl = +dnl = Profiling support +dnl = +dnl ==================================== +ENABLE_PROFILER= +AC_ARG_ENABLE(profiler, +[ --enable-profiler Enable profiler], +ENABLE_PROFILER=1 +AC_DEFINE(ENABLE_PROFILER)) + +if test "x$ENABLE_PROFILER" = "x1" +then + CFLAGS="-g -O -gdwarf-2 -finstrument-functions -D__NO_STRING_INLINES" + LDFLAGS="/gnome/PROFILE/lib/libprofiler.so -lpthread" +fi + +AC_SUBST(ENABLE_PROFILER) +AM_CONDITIONAL(ENABLE_PROFILER, test "x$ENABLE_PROFILER" = "x1") +dnl ==================================== + +dnl turn warnings into errors to enforce clean code for cvs users (not in tarball) + +AC_ARG_ENABLE(more-warnings, +[ --enable-more-warnings Maximum compiler warnings], +set_more_warnings="$enableval",[ +if test -f $srcdir/CVSVERSION; then + set_more_warnings=yes +else + set_more_warnings=no +fi +]) + +if test "$GCC" = "yes" -a "$set_more_warnings" != "no"; then + echo "enable compile warnings = $set_more_warnings" + VFS_CFLAGS="-Wall -Werror \ + -Wchar-subscripts -Wmissing-declarations -Wmissing-prototypes \ + -Wnested-externs -Wpointer-arith" + + for option in -Wno-strict-aliasing -Wno-sign-compare; do + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$VFS_CFLAGS $option $CFLAGS" + AC_MSG_CHECKING([whether gcc understands $option]) + AC_TRY_COMPILE([], [], + has_option=yes, + has_option=no,) + CFLAGS="$SAVE_CFLAGS" + if test $has_option = yes; then + VFS_CFLAGS="$VFS_CFLAGS $option" + fi + AC_MSG_RESULT($has_option) + unset has_option + unset SAVE_CFLAGS + done + unset option +fi +AC_SUBST(VFS_CFLAGS) + +dnl +dnl gnome vfs Documentation +dnl +GNOME_VFS_DIR=`(cd $srcdir; pwd)` +AC_SUBST(GNOME_VFS_DIR) + +VFS_LIBS="-lgnomevfs $VFS_GLIB_LIBS" +VFS_LIBDIR='-L${libdir}' +VFS_INCLUDEDIR='-I${includedir} -I${libdir}/vfs/include'" $VFS_GLIB_CFLAGS" +AC_SUBST(VFS_LIBDIR) +AC_SUBST(VFS_INCLUDEDIR) +AC_SUBST(VFS_LIBS) + +dnl +dnl efs-method.c +dnl + +dnl if test "x$libefs_disabled" = xyes; then +dnl LIBEFS_CONFIG=no +dnl else +dnl AC_PATH_PROG(LIBEFS_CONFIG, libefs-config, no) +dnl fi +dnl +dnl if test "x$LIBEFS_CONFIG" != xno; then +dnl LIBEFS_LIBS=`$LIBEFS_CONFIG --libs` +dnl LIBEFS_CFLAGS=`$LIBEFS_CONFIG --cflags` +dnl fi +dnl + +AM_CONDITIONAL(HAVE_LIBEFS, false) +LIBEFS_LIBS="" +LIBEFS_CFLAGS="" +AC_SUBST(LIBEFS_LIBS) +AC_SUBST(LIBEFS_CFLAGS) + +dnl +dnl ftp-method.c +dnl +AC_DEFUN(AC_STRUCT_LINGER, [ +av_struct_linger=no +AC_MSG_CHECKING(struct linger is available) +AC_TRY_RUN([ +#include +#include + +struct linger li; + +main () +{ + li.l_onoff = 1; + li.l_linger = 120; + exit (0); +} +],[ +AC_DEFINE(HAVE_STRUCT_LINGER) +av_struct_linger=yes +],[ +av_struct_linger=no +],[ +av_struct_linger=no +]) +AC_MSG_RESULT($av_struct_linger) +]) + +have_socket=no +AC_CHECK_FUNCS(socket, have_socket=yes) +if test $have_socket = no; then + # socket is not in the default libraries. See if it's in some other. + for lib in bsd socket inet; do + AC_CHECK_LIB($lib, socket, [ + LIBS="$LIBS -l$lib" + have_socket=yes + AC_DEFINE(HAVE_SOCKET) + break]) + done +fi + +have_gethostbyname=no +AC_CHECK_FUNC(gethostbyname, have_gethostbyname=yes) +if test $have_gethostbyname = no; then + # gethostbyname is not in the default libraries. See if it's in some other. + for lib in bsd socket inet; do + AC_CHECK_LIB($lib, gethostbyname, [LIBS="$LIBS -l$lib"; have_gethostbyname=yes; break]) + done +fi + +AC_CHECK_LIB(bz2, bzCompressInit, AC_DEFINE(HAVE_OLDER_BZIP2)) +AC_CHECK_HEADERS(bzlib.h, + BZ2_LIBS="$BZ2_LIBS -lbz2", + AC_MSG_ERROR([Gnome-vfs requires libbz2 to compile.]) + ) +AC_SUBST(BZ2_LIBS) + +if test $have_socket = yes; then + AC_STRUCT_LINGER +fi + +dnl modules/cdda + +AM_CONDITIONAL(HAVE_CDDA, false) +AC_CHECK_HEADERS(cdda_interface.h cdda_paranoia.h, [ + CDDA_LIBS="$CDDA_LIBS -lcdda_paranoia, -lcdda_interface" + AM_CONDITIONAL(HAVE_CDDA, true) +]) + +dnl modules/cdemenu-desktop + +AC_MSG_CHECKING(for Solaris platform) +case "$host" in + *solaris*) build_cdemenu_module=yes ;; + *) build_cdemenu_module=no ;; +esac +AC_MSG_RESULT([$build_cdemenu_module]) +AM_CONDITIONAL(BUILD_CDEMENU_MODULE, test "$build_cdemenu_module" = "yes") + +dnl ****************************** +dnl OpenSSL +dnl ****************************** + +AC_ARG_ENABLE(openssl, [ --disable-openssl build without openssl support]) +if test "x$enable_openssl" != "xno"; then + PKG_CHECK_MODULES(OPENSSL, openssl, AM_CONDITIONAL(HAVE_SSL, true),[ + AC_ARG_WITH(openssl-includes, [ --with-openssl-includes=PREFIX Location of OpenSSL includes.], + with_openssl_includes="$withval", with_openssl_includes="/usr/include") + have_openssl_includes="no" + if test "x${with_openssl_includes}" != "xno"; then + CPPFLAGS_save="$CPPFLAGS" + + AC_MSG_CHECKING(for OpenSSL includes) + AC_MSG_RESULT("") + + CPPFLAGS="$CPPFLAGS -I$with_openssl_includes" + AC_CHECK_HEADERS(openssl/ssl.h openssl/x509.h, [ openssl_includes="yes" ]) + CPPFLAGS="$CPPFLAGS_save" + + if test "x{$openssl_includes}" != "xno" -a "x{$openssl_includes}" != "x"; then + have_openssl_includes="yes" + if test "${with_openssl_includes}" != "/usr/include" ; then + OPENSSL_CFLAGS="-I$with_openssl_includes" + else + OPENSSL_CFLAGS="" + fi + else + OPENSSL_CFLAGS="" + fi + else + AC_MSG_CHECKING(for OpenSSL includes) + AC_MSG_RESULT(no) + fi + + AC_ARG_WITH(openssl-libs, [ --with-openssl-libs=PREFIX Location of OpenSSL libs.], + with_openssl_libs="$withval", with_openssl_libs="/usr/lib") + msg_openssl="no" + if test "x${with_openssl_libs}" != "xno" -a "x${have_openssl_includes}" != "xno"; then + LDFLAGS_save="$LDFLAGS" + + AC_CACHE_CHECK([for OpenSSL libraries], openssl_libs, + [ +dnl How can we test to see if we need to link to libld for sure?? +dnl RedHat 6.2 seems to need to but Debian Woody doesn't + LDFLAGS="$LDFLAGS -L$with_openssl_libs -lssl -lcrypto -ldl" + AC_TRY_LINK_FUNC(SSL_read, openssl_libs="yes", openssl_libs="no") + LDFLAGS="$LDFLAGS_save" + ]) + if test "x${openssl_libs}" != "xno"; then + AC_DEFINE(HAVE_OPENSSL) + msg_openssl="yes" + if test x$with_openssl_libs != x/usr/lib; then + OPENSSL_LIBS="-L$with_openssl_libs -lssl -lcrypto" + else + OPENSSL_LIBS="-lssl -lcrypto" + fi + AM_CONDITIONAL(HAVE_SSL, true) + else + OPENSSL_CFLAGS="" + OPENSSL_LIBS="" + AM_CONDITIONAL(HAVE_SSL, false) + fi + else + AC_MSG_CHECKING(for OpenSSL libraries) + AC_MSG_RESULT(no) + fi + ]) + dnl end of PKG_CHECK_MODULES(openssl) +fi + + +dnl **************************** +dnl GNUTLS +dnl **************************** + +AC_ARG_ENABLE(gnutls, [ --enable-gnutls build with gnutls support]) +if test "x$enable_gnutls" = "xyes"; then + if test "x${OPENSSL_LIBS}" != "x"; then + AC_MSG_ERROR([*** Can't use both openssl and gnutls at the same time. Please pick one only. ***]) + else + AM_PATH_LIBGNUTLS(0.5.1, AC_DEFINE(HAVE_GNUTLS), + AC_MSG_ERROR([Unable to find GNUTLS])) + fi +fi + +PKG_CHECK_MODULES(LIBGNOMEVFS, glib-2.0 >= $GLIB_REQUIRED gmodule-2.0 >= $GLIB_REQUIRED gthread-2.0 >= $GLIB_REQUIRED gconf-2.0 >= $GCONF_REQUIRED bonobo-activation-2.0 >= $BONOBO_ACTIVATION_REQUIRED ORBit-2.0 >= $ORBIT_REQUIRED libxml-2.0 >= $XML_REQUIRED gnome-mime-data-2.0) +LIBGNOMEVFS_CFLAGS="$LIBGNOMEVFS_CFLAGS $OPENSSL_CFLAGS $LIBGNUTLS_CFLAGS" +LIBGNOMEVFS_LIBS="$LIBGNOMEVFS_LIBS $OPENSSL_LIBS $LIBGNUTLS_LIBS" +AC_SUBST(LIBGNOMEVFS_CFLAGS) +AC_SUBST(LIBGNOMEVFS_LIBS) + + +dnl ********************** +dnl *** Checks for FAM *** +dnl ********************** + +FAM_MISSING_WARNING="Gnome-vfs depends on FAM to provide notification when files are altered (either through filesystem polling, or a kernel notification mechanism). If Gnome-vfs is built without FAM support, directories viewed with Nautilus or other applications will not remain in synch with the actual filesystem when they are altered by external processes. Particularly if you are a distributor please compile Nautilus with FAM support. FAM is available from http://oss.sgi.com/projects/fam/. A patch to add Linux Kernel 2.4 directory notify support to FAM (highly desirable) is available from http://people.redhat.com/alexl/files/" +FAM_LIBS= +AC_CHECK_LIB(fam, FAMOpen, + [AC_CHECK_HEADERS(fam.h, + [AC_DEFINE(HAVE_FAM) + FAM_LIBS="-lfam"], + AC_MSG_WARN(*** FAM support will not be built (header files not found) $FAM_MISSING_WARNING ***))], + AC_MSG_WARN(*** FAM support will not be built (FAM library not found) $FAM_MISSING_WARNING ***)) +AC_SUBST(FAM_LIBS) + + + + +dnl ************************** +dnl *** Checks for gtk-doc *** +dnl ************************** + +AC_ARG_WITH(html-dir, [ --with-html-dir=PATH path to installed docs ]) + +if test "x$with_html_dir" = "x" ; then + HTML_DIR='${datadir}/gtk-doc/html' +else + HTML_DIR=$with_html_dir +fi + +AC_SUBST(HTML_DIR) + +AC_CHECK_PROG(GTKDOC, gtkdoc-mkdb, true, false) + +gtk_doc_min_version=0.10 +if $GTKDOC ; then + gtk_doc_version=`gtkdoc-mkdb --version` + AC_MSG_CHECKING([gtk-doc version ($gtk_doc_version) >= $gtk_doc_min_version]) + + IFS="${IFS= }"; gnome_vfs_save_IFS="$IFS"; IFS="." + set $gtk_doc_version + for min in $gtk_doc_min_version ; do + cur=$1; shift + if test -z $min ; then break; fi + if test -z $cur ; then GTKDOC=false; break; fi + if test $cur -gt $min ; then break ; fi + if test $cur -lt $min ; then GTKDOC=false; break ; fi + done + IFS="$gnome_vfs_save_IFS" + + if $GTKDOC ; then + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi +fi + +AC_CHECK_PROG(DB2HTML, db2html, true, false) +AM_CONDITIONAL(HAVE_DOCBOOK, $DB2HTML) + +AM_CONDITIONAL(HAVE_GTK_DOC, $GTKDOC) +AC_SUBST(HAVE_GTK_DOC) + +dnl Let people disable the gtk-doc stuff. +AC_ARG_ENABLE(gtk-doc, [ --enable-gtk-doc Use gtk-doc to build documentation [default=auto]], enable_gtk_doc="$enableval", enable_gtk_doc=auto) + +if test "x$enable_gtk_doc" = xauto ; then + if test "x$GTKDOC" = xtrue ; then + enable_gtk_doc=yes + else + enable_gtk_doc=no + fi +fi + +dnl NOTE: We need to use a separate automake conditional for this +dnl to make this work with the tarballs. +AM_CONDITIONAL(ENABLE_GTK_DOC, test x$enable_gtk_doc = xyes) + +dnl ****************************** +dnl *** End checks for gtk-doc *** +dnl ****************************** + + +dnl borrowed from gnu findutils +dnl and relicensed as LGPL by the FSF + +AC_ARG_WITH(afs, +[ --with-afs support -fstype afs], +[ AC_DEFINE(AFS) + CPPFLAGS="$CPPFLAGS -I/usr/afsws/include" + LIBS="$LIBS -L/usr/afsws/lib -L/usr/afsws/lib/afs -lsys -lrx -llwp"]) + +AC_MSG_CHECKING(how to get filesystem type) +fstype=no +# The order of these tests is important. +AC_TRY_CPP([#include +#include ], AC_DEFINE(FSTYPE_STATVFS) fstype=SVR4) +if test $fstype = no; then +AC_TRY_CPP([#include +#include ], AC_DEFINE(FSTYPE_USG_STATFS) fstype=SVR3) +fi +if test $fstype = no; then +AC_TRY_CPP([#include +#include ], AC_DEFINE(FSTYPE_AIX_STATFS) fstype=AIX) +fi +if test $fstype = no; then +AC_TRY_CPP([#include ], AC_DEFINE(FSTYPE_MNTENT) fstype=4.3BSD) +fi +if test $fstype = no; then +AC_EGREP_HEADER(f_type;, sys/mount.h, AC_DEFINE(FSTYPE_STATFS) fstype=4.4BSD/OSF1) +fi +if test $fstype = no; then +AC_TRY_CPP([#include +#include ], AC_DEFINE(FSTYPE_GETMNT) fstype=Ultrix) +fi +AC_MSG_RESULT($fstype) + +dnl Check for libpopt + +AC_CHECK_LIB(popt, poptGetArg, POPT_LIBS=-lpopt, + [AC_CHECK_HEADER(popt.h, , AC_MSG_ERROR([[ +*** Couldn't find popt. Please download and install from +*** ftp://ftp.rpm.org/pub/rpm/dist/rpm-4.0.x/ and try again.]]))]) +AC_SUBST(POPT_LIBS) + +dnl Final touch + +AC_SUBST(CFLAGS) +AC_SUBST(CPPFLAGS) +AC_SUBST(LDFLAGS) + +dnl This is needed by `test/vfs-run.in' +TOP_BUILDDIR="`pwd`" +AC_SUBST(TOP_BUILDDIR) + +dnl ==================================================================== +dnl Code for checking whether IPv6 is enabled on the system.... +dnl ==================================================================== +AC_MSG_CHECKING([whether to enable ipv6]) +AC_ARG_ENABLE(ipv6, [ --enable-ipv6 enable IPv6 extensions], ,enable_ipv6=yes) +if test $enable_ipv6 = yes; then + save_libs=$LIBS + + dnl ==================================================================== + dnl Code for checking presence of AF_INET6 on the system.... + dnl ==================================================================== + AC_TRY_COMPILE([ + #include + #include ], [ + socket(AF_INET6, SOCK_STREAM, 0) + ], + have_ipv6=yes, + have_ipv6=no + ) + AC_MSG_RESULT($have_ipv6) + + dnl ================================================================= + dnl Now we would check for specific functions like getaddrinfo. + dnl ================================================================= + have_getaddrinfo=no + if test $have_ipv6 = yes; then + AC_CHECK_FUNC(getaddrinfo, have_getaddrinfo=yes) + if test $have_getaddrinfo != yes; then + # getaddrinfo is not in the default libraries. See if it's in some other. + for lib in bsd socket inet; do + AC_CHECK_LIB($lib, getaddrinfo, [LIBS="$LIBS -l$lib";have_getaddrinfo=yes; break]) + done + fi + if test $have_getaddrinfo = yes; then + AC_DEFINE(ENABLE_IPV6) + fi + fi +fi +dnl ============================================================================== +dnl End of IPv6 checks +dnl ============================================================================== +dnl Output files + +AC_OUTPUT([ +Makefile +gnome-vfs.spec +libgnomevfs/gnome-vfs-file-size.h +libgnomevfs/Makefile +modules/Makefile +modules/extfs/Makefile +modules/extfs/ar +modules/extfs/cpio +modules/extfs/deb +modules/extfs/lha +modules/extfs/rar +modules/extfs/zip +modules/extfs/zoo +modules/vfolder/Makefile +monikers/Makefile +schemas/Makefile +devel-docs/Makefile +devel-docs/gnome-vfs-tutorial/Makefile +po/Makefile.in +programs/Makefile +test/Makefile +test/vfs-run +doc/Makefile +gnome-vfs-2.0.pc +gnome-vfs-module-2.0.pc +]) + +chmod u+x test/vfs-run + +dnl <= Configuration summary => + +echo "<= gnome-vfs configuration summary :" +dnl <= Profile support? => +case "X$ENABLE_PROFILER" in +X1) +echo " +Enable profiler : YES" +;; +*) +echo " +Enable profiler : NO" +echo +;; +esac + +dnl <= CFLAGS and LDFLAGS => +echo " +CFLAGS : $CFLAGS +LDFLAGS : $LDFLAGS" +echo diff --git a/devel-docs/Makefile.am b/devel-docs/Makefile.am new file mode 100644 index 0000000..8a9a346 --- /dev/null +++ b/devel-docs/Makefile.am @@ -0,0 +1,9 @@ +SUBDIRS = gnome-vfs-tutorial + +TEXT_FILES = \ + gnome-vfs-mime-type-handling.txt + +docdir = $(prefix)/doc +doc_DATA = + +# devel-docs/Makefile.am ends here diff --git a/devel-docs/Makefile.in b/devel-docs/Makefile.in new file mode 100644 index 0000000..fda45f6 --- /dev/null +++ b/devel-docs/Makefile.in @@ -0,0 +1,416 @@ +# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ +AS = @AS@ +AWK = @AWK@ +BONOBO_ACTIVATION_REQUIRED = @BONOBO_ACTIVATION_REQUIRED@ +BONOBO_IDLDIR = @BONOBO_IDLDIR@ +BONOBO_REQUIRED = @BONOBO_REQUIRED@ +BZ2_LIBS = @BZ2_LIBS@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +DATADIRNAME = @DATADIRNAME@ +DB2HTML = @DB2HTML@ +DLLTOOL = @DLLTOOL@ +ECHO = @ECHO@ +ENABLE_PROFILER = @ENABLE_PROFILER@ +EXEEXT = @EXEEXT@ +FAM_LIBS = @FAM_LIBS@ +GCONFTOOL = @GCONFTOOL@ +GCONF_REQUIRED = @GCONF_REQUIRED@ +GCONF_SCHEMA_CONFIG_SOURCE = @GCONF_SCHEMA_CONFIG_SOURCE@ +GCONF_SCHEMA_FILE_DIR = @GCONF_SCHEMA_FILE_DIR@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GLIB_REQUIRED = @GLIB_REQUIRED@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GNOME_ACLOCAL_DIR = @GNOME_ACLOCAL_DIR@ +GNOME_ACLOCAL_FLAGS = @GNOME_ACLOCAL_FLAGS@ +GNOME_VFS_DIR = @GNOME_VFS_DIR@ +GTKDOC = @GTKDOC@ +HAVE_GTK_DOC = @HAVE_GTK_DOC@ +HTML_DIR = @HTML_DIR@ +INSTOBJEXT = @INSTOBJEXT@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_CAVES_RULE = @INTLTOOL_CAVES_RULE@ +INTLTOOL_DESKTOP_RULE = @INTLTOOL_DESKTOP_RULE@ +INTLTOOL_DIRECTORY_RULE = @INTLTOOL_DIRECTORY_RULE@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_KEYS_RULE = @INTLTOOL_KEYS_RULE@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_OAF_RULE = @INTLTOOL_OAF_RULE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_PONG_RULE = @INTLTOOL_PONG_RULE@ +INTLTOOL_PROP_RULE = @INTLTOOL_PROP_RULE@ +INTLTOOL_SCHEMAS_RULE = @INTLTOOL_SCHEMAS_RULE@ +INTLTOOL_SERVER_RULE = @INTLTOOL_SERVER_RULE@ +INTLTOOL_SHEET_RULE = @INTLTOOL_SHEET_RULE@ +INTLTOOL_SOUNDLIST_RULE = @INTLTOOL_SOUNDLIST_RULE@ +INTLTOOL_THEME_RULE = @INTLTOOL_THEME_RULE@ +INTLTOOL_UI_RULE = @INTLTOOL_UI_RULE@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTLTOOL_XML_RULE = @INTLTOOL_XML_RULE@ +LDFLAGS = @LDFLAGS@ +LIBEFS_CFLAGS = @LIBEFS_CFLAGS@ +LIBEFS_LIBS = @LIBEFS_LIBS@ +LIBGNOMEVFS_AGE = @LIBGNOMEVFS_AGE@ +LIBGNOMEVFS_CFLAGS = @LIBGNOMEVFS_CFLAGS@ +LIBGNOMEVFS_CURRENT = @LIBGNOMEVFS_CURRENT@ +LIBGNOMEVFS_LIBS = @LIBGNOMEVFS_LIBS@ +LIBGNOMEVFS_REVISION = @LIBGNOMEVFS_REVISION@ +LIBGNUTLS_CFLAGS = @LIBGNUTLS_CFLAGS@ +LIBGNUTLS_CONFIG = @LIBGNUTLS_CONFIG@ +LIBGNUTLS_LIBS = @LIBGNUTLS_LIBS@ +LIBIDL_REQUIRED = @LIBIDL_REQUIRED@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MODULES_CFLAGS = @MODULES_CFLAGS@ +MODULES_FILE_CFLAGS = @MODULES_FILE_CFLAGS@ +MODULES_FILE_LIBS = @MODULES_FILE_LIBS@ +MODULES_GCONF_CFLAGS = @MODULES_GCONF_CFLAGS@ +MODULES_GCONF_LIBS = @MODULES_GCONF_LIBS@ +MODULES_LIBS = @MODULES_LIBS@ +MODULES_XML_CFLAGS = @MODULES_XML_CFLAGS@ +MODULES_XML_GCONF_CFLAGS = @MODULES_XML_GCONF_CFLAGS@ +MODULES_XML_GCONF_LIBS = @MODULES_XML_GCONF_LIBS@ +MODULES_XML_LIBS = @MODULES_XML_LIBS@ +MONIKERS_CFLAGS = @MONIKERS_CFLAGS@ +MONIKERS_LIBS = @MONIKERS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ORBIT_IDL = @ORBIT_IDL@ +ORBIT_REQUIRED = @ORBIT_REQUIRED@ +PACKAGE = @PACKAGE@ +PKG_CONFIG = @PKG_CONFIG@ +POFILES = @POFILES@ +POPT_LIBS = @POPT_LIBS@ +POSUB = @POSUB@ +PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ +PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ +RANLIB = @RANLIB@ +STRIP = @STRIP@ +TEST_CFLAGS = @TEST_CFLAGS@ +TEST_LIBS = @TEST_LIBS@ +TOP_BUILDDIR = @TOP_BUILDDIR@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +VFS_CFLAGS = @VFS_CFLAGS@ +VFS_INCLUDEDIR = @VFS_INCLUDEDIR@ +VFS_LIBDIR = @VFS_LIBDIR@ +VFS_LIBS = @VFS_LIBS@ +VFS_OFFSET = @VFS_OFFSET@ +VFS_OFFSET_IS = @VFS_OFFSET_IS@ +VFS_OFFSET_PRINTF = @VFS_OFFSET_PRINTF@ +VFS_SIZE = @VFS_SIZE@ +VFS_SIZE_IS = @VFS_SIZE_IS@ +VFS_SIZE_PRINTF = @VFS_SIZE_PRINTF@ +WARN_CFLAGS = @WARN_CFLAGS@ +XML_REQUIRED = @XML_REQUIRED@ +cxxflags_set = @cxxflags_set@ + +SUBDIRS = gnome-vfs-tutorial + +TEXT_FILES = \ + gnome-vfs-mime-type-handling.txt + + +docdir = $(prefix)/doc +doc_DATA = +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../config.h +CONFIG_CLEAN_FILES = +DATA = $(doc_DATA) + +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +all: all-redirect +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps devel-docs/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +install-docDATA: $(doc_DATA) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(docdir) + @list='$(doc_DATA)'; for p in $$list; do \ + if test -f $(srcdir)/$$p; then \ + echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(docdir)/$$p"; \ + $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(docdir)/$$p; \ + else if test -f $$p; then \ + echo " $(INSTALL_DATA) $$p $(DESTDIR)$(docdir)/$$p"; \ + $(INSTALL_DATA) $$p $(DESTDIR)$(docdir)/$$p; \ + fi; fi; \ + done + +uninstall-docDATA: + @$(NORMAL_UNINSTALL) + list='$(doc_DATA)'; for p in $$list; do \ + rm -f $(DESTDIR)$(docdir)/$$p; \ + done + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. + +@SET_MAKE@ + +all-recursive install-data-recursive install-exec-recursive \ +installdirs-recursive install-recursive uninstall-recursive \ +check-recursive installcheck-recursive info-recursive dvi-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ + rev="$$subdir $$rev"; \ + test "$$subdir" != "." || dot_seen=yes; \ + done; \ + test "$$dot_seen" = "no" && rev=". $$rev"; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = devel-docs + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + for subdir in $(SUBDIRS); do \ + if test "$$subdir" = .; then :; else \ + test -d $(distdir)/$$subdir \ + || mkdir $(distdir)/$$subdir \ + || exit 1; \ + chmod 777 $(distdir)/$$subdir; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(top_distdir) distdir=../$(distdir)/$$subdir distdir) \ + || exit 1; \ + fi; \ + done +info-am: +info: info-recursive +dvi-am: +dvi: dvi-recursive +check-am: all-am +check: check-recursive +installcheck-am: +installcheck: installcheck-recursive +install-exec-am: +install-exec: install-exec-recursive + +install-data-am: install-docDATA +install-data: install-data-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-recursive +uninstall-am: uninstall-docDATA +uninstall: uninstall-recursive +all-am: Makefile $(DATA) +all-redirect: all-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: installdirs-recursive +installdirs-am: + $(mkinstalldirs) $(DESTDIR)$(docdir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-tags mostlyclean-generic + +mostlyclean: mostlyclean-recursive + +clean-am: clean-tags clean-generic mostlyclean-am + +clean: clean-recursive + +distclean-am: distclean-tags distclean-generic clean-am + -rm -f libtool + +distclean: distclean-recursive + +maintainer-clean-am: maintainer-clean-tags maintainer-clean-generic \ + distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-recursive + +.PHONY: uninstall-docDATA install-docDATA install-data-recursive \ +uninstall-data-recursive install-exec-recursive \ +uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \ +all-recursive check-recursive installcheck-recursive info-recursive \ +dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \ +maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir info-am info \ +dvi-am dvi check check-am installcheck-am installcheck install-exec-am \ +install-exec install-data-am install-data install-am install \ +uninstall-am uninstall all-redirect all-am all installdirs-am \ +installdirs mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +# devel-docs/Makefile.am ends here + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/devel-docs/gnome-vfs-tutorial/Makefile.am b/devel-docs/gnome-vfs-tutorial/Makefile.am new file mode 100644 index 0000000..7b11ae0 --- /dev/null +++ b/devel-docs/gnome-vfs-tutorial/Makefile.am @@ -0,0 +1,2 @@ +EXTRA_DIST = \ + gnome-vfs-tutorial.sgml diff --git a/devel-docs/gnome-vfs-tutorial/Makefile.in b/devel-docs/gnome-vfs-tutorial/Makefile.in new file mode 100644 index 0000000..1c259c5 --- /dev/null +++ b/devel-docs/gnome-vfs-tutorial/Makefile.in @@ -0,0 +1,283 @@ +# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = ../.. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ +AS = @AS@ +AWK = @AWK@ +BONOBO_ACTIVATION_REQUIRED = @BONOBO_ACTIVATION_REQUIRED@ +BONOBO_IDLDIR = @BONOBO_IDLDIR@ +BONOBO_REQUIRED = @BONOBO_REQUIRED@ +BZ2_LIBS = @BZ2_LIBS@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +DATADIRNAME = @DATADIRNAME@ +DB2HTML = @DB2HTML@ +DLLTOOL = @DLLTOOL@ +ECHO = @ECHO@ +ENABLE_PROFILER = @ENABLE_PROFILER@ +EXEEXT = @EXEEXT@ +FAM_LIBS = @FAM_LIBS@ +GCONFTOOL = @GCONFTOOL@ +GCONF_REQUIRED = @GCONF_REQUIRED@ +GCONF_SCHEMA_CONFIG_SOURCE = @GCONF_SCHEMA_CONFIG_SOURCE@ +GCONF_SCHEMA_FILE_DIR = @GCONF_SCHEMA_FILE_DIR@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GLIB_REQUIRED = @GLIB_REQUIRED@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GNOME_ACLOCAL_DIR = @GNOME_ACLOCAL_DIR@ +GNOME_ACLOCAL_FLAGS = @GNOME_ACLOCAL_FLAGS@ +GNOME_VFS_DIR = @GNOME_VFS_DIR@ +GTKDOC = @GTKDOC@ +HAVE_GTK_DOC = @HAVE_GTK_DOC@ +HTML_DIR = @HTML_DIR@ +INSTOBJEXT = @INSTOBJEXT@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_CAVES_RULE = @INTLTOOL_CAVES_RULE@ +INTLTOOL_DESKTOP_RULE = @INTLTOOL_DESKTOP_RULE@ +INTLTOOL_DIRECTORY_RULE = @INTLTOOL_DIRECTORY_RULE@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_KEYS_RULE = @INTLTOOL_KEYS_RULE@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_OAF_RULE = @INTLTOOL_OAF_RULE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_PONG_RULE = @INTLTOOL_PONG_RULE@ +INTLTOOL_PROP_RULE = @INTLTOOL_PROP_RULE@ +INTLTOOL_SCHEMAS_RULE = @INTLTOOL_SCHEMAS_RULE@ +INTLTOOL_SERVER_RULE = @INTLTOOL_SERVER_RULE@ +INTLTOOL_SHEET_RULE = @INTLTOOL_SHEET_RULE@ +INTLTOOL_SOUNDLIST_RULE = @INTLTOOL_SOUNDLIST_RULE@ +INTLTOOL_THEME_RULE = @INTLTOOL_THEME_RULE@ +INTLTOOL_UI_RULE = @INTLTOOL_UI_RULE@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTLTOOL_XML_RULE = @INTLTOOL_XML_RULE@ +LDFLAGS = @LDFLAGS@ +LIBEFS_CFLAGS = @LIBEFS_CFLAGS@ +LIBEFS_LIBS = @LIBEFS_LIBS@ +LIBGNOMEVFS_AGE = @LIBGNOMEVFS_AGE@ +LIBGNOMEVFS_CFLAGS = @LIBGNOMEVFS_CFLAGS@ +LIBGNOMEVFS_CURRENT = @LIBGNOMEVFS_CURRENT@ +LIBGNOMEVFS_LIBS = @LIBGNOMEVFS_LIBS@ +LIBGNOMEVFS_REVISION = @LIBGNOMEVFS_REVISION@ +LIBGNUTLS_CFLAGS = @LIBGNUTLS_CFLAGS@ +LIBGNUTLS_CONFIG = @LIBGNUTLS_CONFIG@ +LIBGNUTLS_LIBS = @LIBGNUTLS_LIBS@ +LIBIDL_REQUIRED = @LIBIDL_REQUIRED@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MODULES_CFLAGS = @MODULES_CFLAGS@ +MODULES_FILE_CFLAGS = @MODULES_FILE_CFLAGS@ +MODULES_FILE_LIBS = @MODULES_FILE_LIBS@ +MODULES_GCONF_CFLAGS = @MODULES_GCONF_CFLAGS@ +MODULES_GCONF_LIBS = @MODULES_GCONF_LIBS@ +MODULES_LIBS = @MODULES_LIBS@ +MODULES_XML_CFLAGS = @MODULES_XML_CFLAGS@ +MODULES_XML_GCONF_CFLAGS = @MODULES_XML_GCONF_CFLAGS@ +MODULES_XML_GCONF_LIBS = @MODULES_XML_GCONF_LIBS@ +MODULES_XML_LIBS = @MODULES_XML_LIBS@ +MONIKERS_CFLAGS = @MONIKERS_CFLAGS@ +MONIKERS_LIBS = @MONIKERS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ORBIT_IDL = @ORBIT_IDL@ +ORBIT_REQUIRED = @ORBIT_REQUIRED@ +PACKAGE = @PACKAGE@ +PKG_CONFIG = @PKG_CONFIG@ +POFILES = @POFILES@ +POPT_LIBS = @POPT_LIBS@ +POSUB = @POSUB@ +PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ +PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ +RANLIB = @RANLIB@ +STRIP = @STRIP@ +TEST_CFLAGS = @TEST_CFLAGS@ +TEST_LIBS = @TEST_LIBS@ +TOP_BUILDDIR = @TOP_BUILDDIR@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +VFS_CFLAGS = @VFS_CFLAGS@ +VFS_INCLUDEDIR = @VFS_INCLUDEDIR@ +VFS_LIBDIR = @VFS_LIBDIR@ +VFS_LIBS = @VFS_LIBS@ +VFS_OFFSET = @VFS_OFFSET@ +VFS_OFFSET_IS = @VFS_OFFSET_IS@ +VFS_OFFSET_PRINTF = @VFS_OFFSET_PRINTF@ +VFS_SIZE = @VFS_SIZE@ +VFS_SIZE_IS = @VFS_SIZE_IS@ +VFS_SIZE_PRINTF = @VFS_SIZE_PRINTF@ +WARN_CFLAGS = @WARN_CFLAGS@ +XML_REQUIRED = @XML_REQUIRED@ +cxxflags_set = @cxxflags_set@ + +EXTRA_DIST = \ + gnome-vfs-tutorial.sgml + +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../../config.h +CONFIG_CLEAN_FILES = +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +all: all-redirect +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps devel-docs/gnome-vfs-tutorial/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + +tags: TAGS +TAGS: + + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = devel-docs/gnome-vfs-tutorial + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: +install-exec: install-exec-am + +install-data-am: +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: +uninstall: uninstall-am +all-am: Makefile +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-generic clean-am + -rm -f libtool + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: tags distdir info-am info dvi-am dvi check check-am \ +installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/devel-docs/gnome-vfs-tutorial/gnome-vfs-tutorial.sgml b/devel-docs/gnome-vfs-tutorial/gnome-vfs-tutorial.sgml new file mode 100644 index 0000000..87ac742 --- /dev/null +++ b/devel-docs/gnome-vfs-tutorial/gnome-vfs-tutorial.sgml @@ -0,0 +1,3752 @@ + + + +Application Programming Using the GNOME Libraries + + + George + Lebl + + The GNOME Project +
+ jirka@5z.com +
+
+
+
+ + 1999 + George Lebl + + + + +In this tutorial, you will receive an overview of the GNOME libraries. +You will learn how to speed up development of applications by using the +many utility routines and objects available through the GNOME libraries, +and how to make the GUI more consistent by using standard GNOME UI +components. Focus will also be given to C applications using the GTK+ +toolkit. + +
+ + +Credits, Copyrights and Other Such Informations + + +All of the code given in this tutorial is under the GNU General +Public License or the GNU Library General Public License. It +was written by me or the rest of the Gnome core team. + + +Also I would like to apologize if some of my English is not +correct, as English is not my first language. I hope that +my C is better then my English. + + +GNOME Libraries Overview + + +Where do GNOME Libraries Fit + + +Before going into the specifics of the GNOME libraries, it is important +to see where do they fit in the picture of all the different libraries +that are used in a GNOME application. The GNOME libraries are the most +high level. GTK+ with it's two parts, GTK and GDK, comes next. +GTK level provides an object model for C and a UI toolkit with the basic +widgets to provide the generic basis for a GUI. GTK depends on GDK, which +is a low-level wrapper around Xlib, the library directly talking to the +X server. Everything (except for Xlib) depends on GLib which is a very +useful C library with many utility and portability functions as well as +a range of easy to use containers for C. + +
+GNOME application library hierarchy + +
+ +
+ +
+ + +Structure of GNOME Libraries + + +We now look at the structure of the GNOME libraries to +see what they can offer. Here is a listing of the different libraries +that are present in the gnome-libs package: + + + +libgnome + +Toolkit independent utility library + + +libgnomeui + +Toolkit dependent library + + +libgnorba + +Library for using ORBit corba implementation with gnome + + +gtk-xmhtml + +xmHTML widget ported to gtk, used in the help browser + + +zvt + +A very lean and mean terminal emulator widget + + +libvfs + +A virtual file-system library used in Midnight Commander + + +libart_lgpl + +A library used for nice anti-aliased graphics + + + + +We will not cover gtk-xmhtml, +zvt, libvfs, libart_lgpl and libgnorba as they are mostly specialty +libraries and some, notably the libvfs and gtk-xmhtml will most likely +be phased out and replaced by better components. + + +We can see a clear division between the libgnome +and libgnomeui +libraries. The former is used in a toolkit independent fashion and could +even be used for command line programs that never use X. The latter is +the library which supplies the standard widgets and an application framework +for applications written using GTK+. It is +conceivable to write applications with other toolkits, but nobody as of +yet has written a libgnomeui with a different +toolkit, and I doubt it will happen +soon, as GTK+ is a really great toolkit. + +
+ + +GTK+ Programming + +Overview + + +GTK+ is a C based toolkit for programming graphical applications in X +windows. It is highly object oriented and has bindings to many popular +languages, such as C++, Objective C, Perl, TOM, Guile, Python, etc ... +GTK+ also uses GLib, which is a very useful C library, and includes +things to help porting to different architectures, and containers +such as a linked list or a hash. If you are already familiar with GTK+, +you are now free to get bored. + + +GLib + +Naming Conventions + + +GLib is a utility library which is heavily used in GTK+ and most of GNOME. +GLib's functions are named starting with g_ (such as +g_strdup), GLib's typedefs for common types are just +prefixed with a g (such as gint32), +and GLib's structures are capitalized and start with G +(such as GHashTable). + + +Typedefs + + +GLib provides some typedefs for portability, simplification of code, +clarity of code and yet others just to keep consistent. The +following table lists these typedefs. If the +Equivalent, field is blank, there is no platform +independent equivalent. + + + +GLib typedefs + + + + + +Name +Equivalent +Description + + + + +gint8 +8bit wide signed integer +guint8 +8bit wide unsigned integer + +gint16 +16bit wide signed integer +guint16 +16bit wide unsigned integer + +gint32 +32bit wide signed integer +guint32 +32bit wide unsigned integer + +gint64 +64bit wide signed integer (see note below) +guint64 +64bit wide unsigned integer (see note below) + +gcharchar +Standard character value +gucharunsigned char +Standard unsigned character value +gshortshort +Standard short integer +gushortunsigned short +Standard unsigned short integer +glonglong +Standard long integer +gulongunsigned long +Standard unsigned long integer +gintint +Standard integer +guintunsigned int +Standard unsigned integer + +gfloatfloat +Standard float number type + +gdoubledouble +Standard float number type + +gbooleanint +Type for storing TRUE/FALSE values + +gpointervoid * +Type for storing pointers to arbitrary objects + +gconstpointerconst void * +Type for storing pointers to arbitrary immutable objects + + +
+
+ +It should be noted that gint64 and +guint64 might not be available on all platforms. You can +check for this in your code by checking to see if the macro +G_HAVE_GINT64 is defined. + + +As you can see, some of the typedefs such as gint +seem to have no other meaning in life then that of having a 'g' prefix and +looking the same as the other typedefs. The logic behind this is to make the +code look more consistent and clear. While it is no crime not to use these +typedefs, you should really be consistent in your code. Some of the typedefs +such as gboolean are only for improving code clarity +and you could just as well use int to do exactly the +same thing, but the former method clearly indicates that you are talking +about a value that can only take TRUE or FALSE. + +
+ + +Portability and Utility Functions + + +There are some functions that have different implementations across +different systems or are not extremely safe, or don't exist at all on some +systems, so GLib provides it's own implementations or wrappers that have a +constant behavior and usually check their arguments. + +Here are some of the more useful functions that fit this category. +Note that the prototype is more of an informative one, as some of these +might be macros in reality. + + + +Few GLib Portability Functions + + + + + +Prototype +Description + + + + +gchar * g_strdup (const gchar *) +Returns a newly allocated string which is a copy of the argument, +if the argument is NULL, NULL is returned +gpointer g_malloc (int size) +Returns a newly region of memory with 'size' bytes +void g_free (gpointer p) +Frees memory pointed to by 'p', and only returns if 'p' is +NULL +gint g_snprintf (gchar *string, gulong n, gchar const *format, ...) + +Works just like sprintf by printing the arguments according to the +'format' into string, however it will only use 'n' bytes of the string and +will thus truncate the result if it needed more. It returns the number +of bytes actually printed into 'string' + +void g_usleep (gulong count) +Suspend execution for at least 'count' microseconds + + + +
+ +
+ +And there are also some utility functions and macros that are not +really found in the normal c library. Here is a very short list of some +of the more important and useful ones. + + + +Few GLib Utility Functions + + + + + +Prototype +Description + + + + +g_new (type,count) +A macro which will allocate new memory for 'count' items +of type 'type' and cast the result to 'type'. It is equivalent to +'(type) g_malloc(count * sizeof(type))' + +g_new0 (type,count) +Same semantics as g_new, except that the returned memory will +be set to all zeros. Note that you should not assume that setting the +memory to zeros will zero out floating point types + +gchar * g_strconcat (const gchar *str, ...) +When passed any number of arguments of the type (const char *) and +a NULL after the last argument, it will return a newly allocated string +that results by concatenation of all the arguments. + +gchar * g_strdup_printf (const gchar *format, ...) +A printf like function that will return a newly allocated string +with the result of the printf operation + +gchar * g_strstrip (gchar *string) +Will strip leading and trailing whitespace from the string. It will +not allocate new memory, but will modify the original string and return +a pointer to it. If you wish to allocate new memory use a construction such as: +'string2 = g_strstrip(g_strdup(string1));' + + + + +
+ +
+ + +There are many other useful methods in GLib, and I urge you to study GLib +documentation and the GLib header file (glib.h), and +you may be able to save a lot of time by not re-implementing some basic +functionality. +
+ + +Containers + + +Probably the best part of GLib are its containers. Here's a list of +GLib's containers. + + + +Common GLib containers + + + + + +Name +Description + + + + +GList +Doubly linked list +GSList +Singly linked list +GHashTable +Hash table +GCache +Cache +GTree +Balanced binary tree +GNode +n-ary tree +GString +Dynamically sized string +GArray +Dynamically sized array +GPtrArray +Dynamically sized array of pointers +GByteArray +Dynamically sized array of bytes (guint8) + + + +
+ +
+ + +GList + + +The easiest to use are GList's. +The basic GList structure is just a single node +of the linked list and you can put your data into the data pointer +in the GList +structure. To store a linked list you just store a pointer to the +first node of the list. Here is the list of functions that operate on +a GList. The functions usually take in a pointer and return the new +pointer of the list, since the first node could now be a different one. + + + +Most important GList functions + + + + + +Prototype +Description + + + + +GList* g_list_append (GList *list, gpointer data) +Append 'data' to a list. 'list' can be NULL to make a new list. + +GList* g_list_prepend (GList *list, gpointer data) +Prepend 'data' to a list. 'list' can be NULL to make a new list. + +GList* g_list_remove (GList *list, gpointer data) +Remove the node containing 'data' from the list. + +GList* g_list_find (GList *list, gpointer data) +Find the GList node that contains the 'data' + +GList* g_list_next (GList *list) +A macro that returns a pointer to the next node + +GList* g_list_previous (GList *list) +A macro that returns a pointer to the next node + +void g_list_free(GList *list) +Free the entire list. + + + +
+ +
+ + +To access the data from a particular GList node +You look at the data member in the +GList structure. +So code that would create a linked list of +two elements which are strdup'ed strings, and later free that list +and the strings would look like: + + +GList *list = NULL; /*the actual list pointer*/ +GList *li; /*just a temporary pointer to a node used for iterating + over the list*/ +... +/*here we add two strings to the list*/ +list = g_list_append(list,g_strdup("String 1")); +list = g_list_append(list,g_strdup("String 2")); +... +/*here we loop though the list, freeing all the strings and then + we free the list itself*/ +for(li = list; li!= NULL; li = g_list_next(li)) { + char *string = li->data; + g_free(string); +} +g_list_free(list); + +
+ + +GString + +Another simple to use and useful container is the +GString container. +It's a dynamically sized string container for the times when you don't +know how large the string you will need will be. Here's a list of the +most important functions. + + + +Most important GString functions + + + + + +Prototype +Description + + + + +GString* g_string_new (const gchar *init) +Create a new GString with initial value of 'init' + +void g_string_free (GString *string, int free_segment) +Free the GString structure and optionally also the string data segment + +GString* g_string_append (GString *string, const gchar *val) +Append 'val' to 'string' + +GString* g_string_prepend (GString *string, const gchar *val) +Prepend 'val' to 'string' + +void g_string_sprintf (GString *string, const gchar *format, ...) +A sprintf like function for GString + +void g_string_sprintfa (GString *string, const gchar *format, ...) +A sprintf like function for GString, but appends the string instead of overwriting it + + + +
+ +
+ + +To access the string data for use as a char *, just +access the str element of the +GString structure. You can actually free the +GString structure without freeing this data segment. +This is useful if you want to create a normal C string. The following example +is a function that takes an array of integers and sprintfs them into a string +and returns a char *. + + +char * +create_number_list(int array[], int array_len) +{ + int i; /* the array iterator */ + GString *string; /* the GString */ + char *ret; /* the return value */ + + /* make a new GString that is empty */ + string = g_string_new(""); + + /* iterate over the integer array */ + for(i=0; i<array_len; i++) { + /* append the number to the string in parenthesis */ + g_string_sprintfa(string, "(%d)", array[i]); + } + + /* setup the return value */ + ret = string->str; + + /* free the GString structure, but not the data */ + g_string_free(string,FALSE); + + /* return the string */ + return ret; +} + + +
+ + +GHashTable + + +Though less often used then GList's and GString's. The hash table container +is a very useful one. Usually by a hash table one would mean an object +(in GLib's terms a gpointer) would have a string +key, by which we could recall the object at a later time. GLib takes this +a step further, making the key a gpointer as well, +and letting you provide a hashing and a comparison function yourself. +While this makes GHashTable much more flexible, it +can lead to some confusion with respect to memory allocation for the +keys. Let's give some important functions and deal with the details +later: + + + +Most important GHashTable functions + + + + + +Prototype +Description + + + + +GHashTable* g_hash_table_new (GHashFunc hash_func, +GCompareFunc key_compare_func) +Creates a new hash table using the specified hash function and +comparison function + +void g_hash_table_destroy (GHashTable *hash_table) +Destroy the hash table and free memory. This does not however free +neither the data, nor the keys, you have to do this +yourself + +void g_hash_table_insert (GHashTable *hash_table, gpointer +key, gpointer value) +Insert a new 'value' with a key of 'key'. + +void g_hash_table_remove (GHashTable *hash_table, +gconstpointer key) +Remove the value with the key of 'key' from the table. Doesn't +free neither the key nor the value. + +gpointer g_hash_table_lookup (GHashTable *hash_table, +gconstpointer key) +Fetch the pointer of the value, with the key of 'key'. Returns +NULL if it isn't found + + +gboolean g_hash_table_lookup_extended (GHashTable *hash_table, +gconstpointer lookup_key, gpointer *orig_key, gpointer *value) +Lookup the data with the key of 'value_key', store the original +key pointer in 'orig_key' and the value in 'value'. Returns TRUE if the +lookup was successful else it returns FALSE. You should use this +function when removing an item to get rid of the original key in memory. + + +void g_hash_table_foreach (GHashTable *hash_table, GHFunc +func, gpointer user_data) +Run a function for each data stored in the hash table. The +'user_data' will be passed to the function as the last argument. The +GHFunc prototype follows. + +void (*GHFunc) (gpointer key, gpointer value, gpointer +user_data) +This is the function prototype that you will use for the function +that is passed to g_hash_table_foreach. It gets passed the key, the value +and the user_data specified in the g_hash_table_foreach +call. + +guint g_str_hash (gconstpointer v) +A standard string hash function for string hash +tables + +gint g_str_equal (gconstpointer v, gconstpointer v2) +A standard string compare function for string hash tables + + + +
+ +
+ + +To create a hash table, you pass the hash and key compare functions +to g_hash_table_new. There are standard functions +defined for strings (g_str_hash and +g_str_equal) and others. However +if you pass NULL as the hash and compare functions, you will get a direct +pointer hash, where pointers will be actually themselves used as keys. + + + +The problem of memory allocation becomes apparent when we start using +string hashes. GHashTable doesn't store the string, +all it stores is a pointer. Therefore, when inserting a value into the +hash, you have to create a new copy of the key for that value. +This is an important thing to remember as otherwise things are not going +to behave really nice for you. The other problem is how to then get rid +of the key. If you do a g_hash_table_remove, you +give as a key a string with the same contents as the original key, but +not the same memory location. After then a pointer to the original key +would be lost and unless you stored a pointer to it somewhere, you just +created a memory leak. What you need to do instead is to do a +g_hash_table_lookup_extended first to get both +the value and the original key pointer and then do the +g_hash_table_remove. + + + +The following example will make a new string hash, insert a couple of strings +into it, retrieve them, and then destroy the hash and the values stored +in it: + + +/* function we use for freeing the keys and data in the hash before + we destroy the hash */ +static void +free_key_value(gpointer key, gpointer value, gpointer user_data) +{ + g_free(key); + g_free(value); +} + +... + +/* somewhere else in the code */ + +GHashTable *ht; + +/* create a new hash table with strings as keys */ +ht = g_hash_table_new(g_str_hash, g_str_equal); + +/* insert a couple of strings (say colors keyed by shape) */ +g_hash_table_insert(ht, g_strdup("triangle"), g_strdup("green")); +g_hash_table_insert(ht, g_strdup("square"), g_strdup("red")); +g_hash_table_insert(ht, g_strdup("circle"), g_strdup("blue")); + +/* again, somewhere else in the code */ +... +/* now here we wish to print out the color of a square */ +char *color; + +/* get the color of a square */ +color = g_hash_table_lookup(ht, "square"); + +printf("The color of a square is: %s\n",color); + +/* yet again somewhere else */ +... +/* Now here we just want to destroy the hash table and free all the + * memory associated with it. We use the free_key_value function and + * have it run over all the values in the hash table. */ +g_hash_foreach(ht, free_key_value, NULL); + +/* now we can destroy the actual hash table */ +g_hash_table_destroy(ht); + + +
+ +
+ + + +More GLib information + +For more information look at the glib.h header file and at +the documentation on the www.gtk.org +web site.
+ + +GTK+ + +GUI Basics + + +Writing a GTK+ based GUI application is in essence extremely simple, and +we'll use the Hello World example from Ian Main's excellent GTK+ tutorial, +which is a very useful guide to writing gnome applications. But first we'll +talk about the basic philosophy behind GTK+. + + +GTK+ is a container based toolkit, meaning you don't specify where the +widget is, but you specify in what container it is. Some widgets, +such as a window or a frame or a button, are containers that hold only +one other widget. For example a button with a label is actually a button +into which we added a label widget. If you need to put more widgets into +that container, you will need to add another container into them, one +that holds more then one widget such as a horizontal box. + + +In fact most layout of windows is usually done with containers such as +horizontal boxes, vertical boxes and tables, those are the most important +to learn. A horizontal box is a widget that you can add several widgets +into and they will be added in a horizontal row. The height of the +horizontal box is the height of the highest widget added, and the +length is the length of all widgets combined. Vertical box behaves exactly +the same, except that it's vertical instead of horizontal. A table +can take in widgets at different rows and columns. + +
+Example window hierarchy + +
+ +
+ + +GTK+ Object Model + + +Gtk's object model is an object oriented framework for C. It includes +singular object inheritance, virtual methods, signals, runtime object +modification, runtime type checking, and other goodies. While writing +a GTK+ object is more involved then say writing an object in something +like Java, it does have many advantages. GTK+ is an object model which +doesn't require inheritance for most things you do with objects. For one, +since methods are just functions that take the pointer to the object +as the first argument, it's easy to write more methods in your own code, +which are missing in the original object. + + +Data on Objects + + +There is a way to store arbitrary named data in objects to extend the object. +This is done with the method, gtk_object_set_data (or +gtk_object_set_user_data for a single unnamed pointer). To +retrieve data, one uses gtk_object_get_data. Example: + + +GtkObject *obj; +void *some_pointer; +... +/*here we set "some_data" data on obj to point to some_pointer*/ +gtk_object_set_data(obj,"some_data",some_pointer); +... +/*retrieve pointer to some_data from obj and store it in + some_pointer*/ +some_pointer = gtk_object_get_data(obj,"some_data"); + +The pointer can be a pointer to anything since it's manipulated as a (void *). + + +GTK+/GNOME Naming Conventions + + +Both GTK+ and GNOME use the same naming convention when naming objects and +functions. GTK+ uses a prefix of gtk_ for functions, and +Gtk for objects, and GNOME uses +gnome_ and Gnome. When a function is +a method for an object, the name (lower case) is appended to the prefix. For +example the button object is named GtkButton (that is the +name of the C struct holding the data for the object), and say the +"new" method for GtkButton is then +called gtk_button_new. Macros associated with objects use +the same naming convention as functions, but are all capitalized. For example a +macro that casts an object to a GtkButton is called +GTK_BUTTON. There are exceptions, notably the type +checking macro, which is called GTK_IS_BUTTON for +GtkButton. + + +Using GTK+ Methods + + +Since GTK+ is object oriented, it uses inheritance for it's widgets. For +example GtkHBox and GtkVBox are +derived from GtkBox. And thus you can use any +GtkBox method on a GtkVBox or +GtkHBox. However you need to cast the +GtkVBox object to GtkBox before you +call the function. This could be done with standard C casts such as: + + +GtkVBox *vbox; +... +gtk_box_pack_start((GtkBox *)vbox, ...); +... + +This would work, however it is unsafe. GTK+ provides a mechanism of checking +the types, so that it can warn you if you are casting an object which +does not derive from the object you are casting to, or if you try to +cast a NULL pointer. The macro is all capital name of the widget. For example +the above code snippet would be + + +GtkVBox *vbox; +... +gtk_box_pack_start(GTK_BOX(vbox), ...); +... + + + +GNOME uses the exact same form so anything you learn about GTK+ can be used +for GNOME widgets, you just replace the GTK prefix with GNOME. + + +Example Hello World Program + + +Here is the promised example code for the hello world program. +It doesn't use any advanced containers, just a window and a button +onto which a label is added. It illustrates the basic workings +of a GUI program written in GTK+. Don't be scared by it's size, +it's mostly comments. + + +/* example-start helloworld helloworld.c */ + +#include <gtk/gtk.h> + +/* this is a callback function. the data arguments are ignored in + * this example.. More on callbacks below. */ +void +hello (GtkWidget *widget, gpointer data) +{ + g_print ("Hello World\n"); +} + +gint +delete_event(GtkWidget *widget, GdkEvent *event, gpointer data) +{ + g_print ("delete event occurred\n"); + /* if you return FALSE in the "delete_event" signal + * handler, GTK will emit the "destroy" signal. + * Returning TRUE means you don't want the window + * to be destroyed. This is useful for popping up + * 'are you sure you want to quit ?' type dialogs. */ + + /* Change TRUE to FALSE and the main window will + * be destroyed with a "delete_event". */ + + return (TRUE); +} + +/* another callback */ +void +destroy (GtkWidget *widget, gpointer data) +{ + gtk_main_quit (); +} + +int +main (int argc, char *argv[]) +{ + /* GtkWidget is the storage type for widgets */ + GtkWidget *window; + GtkWidget *button; + + /* this is called in all GTK applications. + * arguments are parsed from the command line and + * are returned to the application. */ + gtk_init (&argc, &argv); + + /* create a new window */ + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + + /* when the window is given the "delete_event" signal + * (this is given by the window manager, usually by + * the 'close' option, or on the titlebar), we ask + * it to call the delete_event () function as defined + * above. The data passed to the callback function + * is NULL and is ignored in the callback function. */ + gtk_signal_connect (GTK_OBJECT (window), "delete_event", + GTK_SIGNAL_FUNC (delete_event), NULL); + + /* here we connect the "destroy" event to a signal + * handler. This event occurs when we call + * gtk_widget_destroy() on the window, or if we + * return 'FALSE' in the "delete_event" callback. */ + gtk_signal_connect (GTK_OBJECT (window), "destroy", + GTK_SIGNAL_FUNC (destroy), NULL); + + /* sets the border width of the window. */ + gtk_container_border_width (GTK_CONTAINER (window), 10); + + /* creates a new button with the label "Hello World". */ + button = gtk_button_new_with_label ("Hello World"); + + /* When the button receives the "clicked" signal, it + * will call the function hello() passing it NULL as + * it's argument. The hello() function is defined + * above. */ + gtk_signal_connect (GTK_OBJECT (button), "clicked", + GTK_SIGNAL_FUNC (hello), NULL); + + /* This will cause the window to be destroyed by + * calling gtk_widget_destroy(window) when "clicked". + * Again, the destroy signal could come from here, + * or the window manager. */ + gtk_signal_connect_object (GTK_OBJECT (button), "clicked", + GTK_SIGNAL_FUNC (gtk_widget_destroy), + GTK_OBJECT (window)); + + /* this packs the button into the window + * (a gtk container). */ + gtk_container_add (GTK_CONTAINER (window), button); + + /* the final step is to display this newly created + * widget... */ + gtk_widget_show (button); + + /* and the window */ + gtk_widget_show (window); + + /* all GTK applications must have a gtk_main(). + * Control ends here and waits for an event to occur + * (like a key press or mouse event). */ + gtk_main (); + + return 0; +} +/* example-end */ + + + +For more information look at the header files in <prefix>/include/gtk/ +and <prefix>/include/gdk/ and at the documentation on the +www.gtk.org web site. +
+ + +GNOME Programming + +Introduction + +What Is a GNOME Program + + +A GNOME program is a GTK+ GUI application, which makes use of the +GNOME libraries. The GNOME libraries make it possible to have similar +look and feel among applications, and to make simple things, simple +to program. Plus the GNOME libraries add a whole bunch of widgets that +simply don't fit into GTK+. + + + + +Very Basic GNOME Program + + +The following program creates a basic gnome window and adds a horizontal box +into which it packs two buttons, which (when pressed) print a string onto the +stdout of the terminal you started the application from. The semantics and +structure of a GNOME program is very similar to a pure GTK+ program. + + +/* + * A simple Gnome program, outside of GNOME tree, not using i18n + * buttons.c + */ +/* the very basic gnome include */ +#include <gnome.h> + +/* a callback for the buttons */ +static void +button_clicked(GtkWidget *button, gpointer data) +{ + /* the string to print is passed though the data field + (which is a void *) */ + char *string = data; + /* print a string on the standard output */ + g_print(string); +} + +/* called when the user closes the window */ +static gint +delete_event(GtkWidget *widget, GdkEvent *event, gpointer data) +{ + /* signal the main loop to quit */ + gtk_main_quit(); + /* return FALSE to continue closing the window */ + return FALSE; +} + +int +main(int argc, char *argv[]) +{ + GtkWidget *app; + GtkWidget *button; + GtkWidget *hbox; + + /* Initialize GNOME, this is very similar to gtk_init */ + gnome_init ("buttons-basic-example", "0.1", argc, argv); + + /* Create a Gnome app widget, which sets up a basic window + for your application */ + app = gnome_app_new ("buttons-basic-example", + "Basic GNOME Application"); + + /* bind "delete_event", which is the event we get when + the user closes the window with the window manager, + to gtk_main_quit, which is a function that causes + the gtk_main loop to exit, and consequently to quit + the application */ + gtk_signal_connect (GTK_OBJECT (app), "delete_event", + GTK_SIGNAL_FUNC (delete_event), + NULL); + + /* create a horizontal box for the buttons and add it + into the app widget */ + hbox = gtk_hbox_new (FALSE,5); + gnome_app_set_contents (GNOME_APP (app), hbox); + + /* make a button and add it into the horizontal box, + and bind the clicked event to call button_clicked */ + button = gtk_button_new_with_label("Button 1"); + gtk_box_pack_start (GTK_BOX(hbox), button, FALSE, FALSE, 0); + gtk_signal_connect (GTK_OBJECT (button), "clicked", + GTK_SIGNAL_FUNC (button_clicked), + "Button 1\n"); + + /* and another button */ + button = gtk_button_new_with_label("Button 2"); + gtk_box_pack_start (GTK_BOX(hbox), button, FALSE, FALSE, 0); + gtk_signal_connect (GTK_OBJECT (button), "clicked", + GTK_SIGNAL_FUNC (button_clicked), + "Button 2\n"); + + /* show everything inside this app widget and the app + widget itself */ + gtk_widget_show_all(app); + + /* enter the main loop */ + gtk_main (); + + return 0; +} + + + +Please note the use of gnome_init instead of +gtk_init, and GnomeApp widget instead +of just a regular GtkWindow. We will go into detail of +these later. + + + + + +Overview + + +OK now we look at what the different libraries that we are going to cover do. +First we look at the libgnome library and it's +functionality, then we'll cover libgnomeui to complete all +the basic functionality of a gnome program. We will take a look at the +gnome-canvas in detail, as it is extremely powerful and +useful widget. We'll also say a few things about drag and drop. + + + + +Using the libgnome Library + + +The libgnome library is the non-toolkit specific utility +library for GNOME applications, and includes things like configuration file +reading, .desktop file handling, special GLib like utility routines, getting +the standard file locations for GNOME, handling mime types, handling meta-data +on files, sound, "triggers", and other useful things one could want to use. +Also say that you are writing an application in say motif, but you want your +app to be more GNOME friendly. Then you could use this library to make your +application work well with other GNOME programs. + + +Configuration Files + + +The gnome-config routines provide an easy way to store +configuration info in files. To see a full list of the routines, look in the +libgnome/gnome-config.h header file. + + +The routines all working with a path. The path is a Unix like path, but the +root is set to the ~/.gnome/ directory. So +/some/config/path/file/sectionA/keyB, refers to the file +~/.gnome/some/config/path/file, and inside the file using +section sectionA and key keyB. + + +Reading Configuration Info + + +To read configuration information gnome_config_get_* +functions are used. the * is replaced by the type of the +data, it can be int, float, +string, bool and +vector. The int functions work with +gint, float functions work with +gdouble, string functions work with +gchar *, bool functions work with +gboolean and vector work with an argc +like array of strings (gint and gchar +**). For the gnome_config_get_* functions, the +default to be returned if the file section or key are not found can be appended +to the path after an equals sign. If you need to know if the default was used, +you can append _with_default to the function name and add +a parameter which is a gboolean *, though which the +function returns whether it used the default or if it actually found a real +value. Example follows: + + +int counter; +char *text; +gboolean def; +... +counter = gnome_config_get_int_with_default("/example/section/counter=1", + &def); +if(def) g_print("Default used for counter!\n"); +text = gnome_config_get_string("/example/section/text=TEXT"); +... +g_free(text); + +Note that the string returned by gnome_config_get_string +should be freed with g_free, the vector from +gnome_config_get_vector should also be freed with +g_free. + + + + +Writing Configuration Info + + +To write configuration info to files, the +gnome_config_set_* functions are used. The use is very +similar to above to the gnome_config_get_* functions. The +types used are exactly the same. Except with the "set" functions, you pass the +data you want to store after the path, and there is no default inside the path. +If the directory in the path doesn't exist it will get created when the +functions are written to disk. After you set all your data, you need to call +gnome_config_sync to actually write your data to file. The +library will not write the data to file immediately for efficiency reasons. +Example follows: + + +char *text; +int counter; +... +/*after we have set text and counter to some values we can + write them to our config location*/ +gnome_config_set_int("/example/section/counter",counter); +gnome_config_set_string("/example/section/text",text); +gnome_config_sync(); + + + +Privacy Functions + + +If you want to store sensitive data, that other users should not read, use the +gnome_config_private_* functions, which have exactly the +same behavior as the above functions, with the exception of +gnome_config_sync (and a few others) which doesn't have a +private equivalent since it works for both. The difference is that these +functions write to a directory called ~/.gnome_private on +which 0700 permissions are enforced. This is not extremely secure, but because +of the highly brain-dead US export restrictions, we can't really use +encryption. + + + + +Using gnome-config for Arbitrary Files + + +If you wish to use gnome-config for reading and writing of +arbitrary files on the file-system (as long as those files are in the +gnome-config format), you can just prepend +'=' to the beginning of the path and another +'=' to the end of the file name. Example follows: + + +char buf[256]; +... +/*write some bogus data to a temporary file*/ +g_snprintf(buf,256,"=%s=/section/key",tmpnam(tmpnam)); +gnome_config_set_int(buf,999); +gnome_config_sync(); + +Note that it doesn't really make sense to use the private versions when +using an arbitrary absolute path, as there will be absolutely no difference +between the two. + + +Automatic Prefixes + + +Sometime, especially if you have a long path, would be much easier to say have +the config automatically prefix the path with a given string. This is what +gnome_config_push_prefix and +gnome_config_pop_prefix are for. You pass the string you +want to prefix to gnome_config_push_prefix and call +gnome_config_pop_prefix when you are done. Note that these +functions are common between private and normal config functions. Example: + + +gnome_config_push_prefix("/file/section/"); +gnome_config_set_int("key1",1); +gnome_config_set_int("key2",2); +gnome_config_set_int("key3",-88); +gnome_config_pop_prefix(); + + + +Misc gnome-config Stuff + + +If you need to remove a file in your configuration file, you will use +gnome_config_clean_file. This function will schedule that +file to be deleted on the next gnome_config_sync. You can +do a gnome_config_clean_file and then use the file and +then do gnome_config_sync, and it will have the expected +behavior. + + + +If you have written to a file or read from a file and want +gnome-config to drop it from memory, use +gnome_config_drop_file. This is used if you want to forget +changes done to that file, or to simply conserve memory, since +gnome-config will otherwise keep a copy of the data in +memory for faster access. + + + + + +.desktop Files + + +The .desktop files are the files that contain information about +programs. The files are in the gnome-config format and are internally +read using gnome-config. Your app definitely needs one of these +files installed in the system menu paths if it wants to be added to the menu. + + +You can use gnome_desktop_entry_* functions to manipulate these files. +These functions work with a structure called GnomeDesktopEntry and +you should look at the libgnome/gnome-dentry.h header file for the format +of this structure. + + +The basic functions that you use to manipulate these files are +gnome_desktop_entry_load which returns a newly allocated +GnomeDesktopEntry structure, gnome_desktop_entry_launch +which takes the GnomeDesktopEntry structure as an argument and +launches the program it describes and gnome_desktop_entry_free +which frees the allocated memory with the structure. + + +An example .desktop file for your app might look like: + + +[Desktop Entry] +Name=Clock +Name[cz]=Hodiny +Comment=Digital Clock +Comment[cz]=Digitalni Hodiny +Exec=digital-clock +Icon=clock.png +Terminal=0 +Type=Application + +You will notice that there are translations for Name and Comment +fields in Czech. For gnome programs to notice your .desktop file, +it is usually located somewhere under <prefix>/share/apps/, which +contains the hierarchy of the system menus. For the system to find +your icon, your icon should be placed inside the +<prefix>/share/pixmaps directory. Note that the prefix refers +to the location where GNOME was installed. + + +Utility and Files + +Files + + +There is a standard way to find files that belong to gnome installation, +you shouldn't really be using your own logic to find them and you should +use these functions to get filenames for icons, sounds or other data. +Also these functions are only for finding files that were installed with +the GNOME libraries. There is not at this time functions to deal with +data installed by your application. The functions are: + + + +File finding functions + + + + + +Prototype +Description + + + + +char *gnome_libdir_file (const char *filename) +Get a full path of a file in the library directory or NULL if the file doesn't exist +char *gnome_unconditional_libdir_file (const char *filename) +Get a full path of a file in the library directory + +char *gnome_datadir_file (const char *filename) +Get a full path of a file in the data director or NULL if the file doesn't exist +char *gnome_unconditional_datadir_file (const char *filename) +Get a full path of a file in the data director + +char *gnome_sound_file (const char *filename) +Get a full path of a file in the sound directory or NULL if the file doesn't exist +char *gnome_unconditional_sound_file (const char *filename) +Get a full path of a file in the sound directory + +char *gnome_pixmap_file (const char *filename) +Get a full path of a file in the pixmap directory or NULL if the file doesn't exist +char *gnome_unconditional_pixmap_file (const char *filename) +Get a full path of a file in the pixmap directory + +char *gnome_config_file (const char *filename) +Get a full path of a file in the config directory or NULL if the file doesn't exist +char *gnome_unconditional_config_file (const char *filename) +Get a full path of a file in the config directory + + + +
+
+ + +These functions return a newly g_malloced string and you +should use g_free on the string when you are done. The +gnome_unconditional_* functions don't check if the file +actually exist and will just return a file name. The normal functions will +check and return NULL if the file doesn't exist. So you +shouldn't use those functions when you will do saving. As an example we want to +get a pixmap from the standard pixmap directory, for example we need to get the +"gnome-help.png" icon: + + +char *name; +... +name = gnome_pixmap_file("gnome-help.png"); +if(!name) { + g_warning("gnome-help.png doesn't exist!"); +} else { + /*here we use the file*/ + ... + g_free(name); +} + + + +Also of interest are the functions (actually macros) +gnome_util_home_file and +gnome_util_user_home. +gnome_util_home_file takes one argument (string) and +returns a newly allocated string with the home directory and .gnome prepended +to the file. So for example if you pass it say +someconfigfile, it would return +/home/jirka/.gnome/someconfigfile. Similar is the +gnome_util_user_home, it takes one argument and returns +the file with just the home directory added. So if you pass it +.dotfile, it would return +/home/jirka/.dotfile.
+ + +Utility + + +There are also a number of GLib like named functions to make your life easier, +of note would be g_file_exists which takes a filename and +returns TRUE if it exists or FALSE if +it doesn't, or g_concat_dir_and_file which takes a +directory name and a file name, and takes care of the '/' +issue, this is useful when working with strings where you don't want to check +for the '/', you just want to append a directory to some file, or another +directory. Note that you should g_free the string you get +as usual. For more utility functions, look into +libgnome/gnome-util.h, it is well +commented. + + +
+ + +Mime Types + + +Sometimes it's useful to know the mime-type of a file. You can do this by using +the gnome_mime_type_or_default function, which takes two +arguments, the filename and a default mime-type string which it will return if +it can't figure out the mime type from the filename. This call doesn't +actually look into the file, it tries to guess the type by looking at the +filename itself. Also the string it returns is a pointer to it's internal +database and you should not free it as that would likely result in a segfault +later on. You can also use gnome_mime_type which will +return NULL if it can't guess the mime-type. + + +It is also possible to work with URI lists, such as the ones used sometimes in +Drag and Drop. Usually from an URI list you want to extract a list of filenames +that you just received. For that you use the +gnome_uri_list_extract_filenames function, which takes the +URI list as a string argument, and returns a GList * of +newly allocated strings. Once you are done with the files, you should free the +strings and the list. You can use the utility routine +gnome_uri_list_free_strings to do this for you. + + + +In the following example I write a drag and drop handler +that takes the files and finds out their mime information, then you +could just write code that can do things based on the mime type +of the files. + + +/*this is the handler for the drag_data_receive signal, assuming our + widget only accepts the "text/uri-list" mime type of data, drag and + drop is a more complicated topic and you should read up on GTK+ + documentation for better treatment*/ +static void +dnd_drop_internal (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + GtkSelectionData *selection_data, + guint info, + guint time) +{ + GList *files, *li; + + /*here we extract the filenames from the URI-list we received*/ + files = gnome_uri_list_extract_filenames(selection_data->data); + + /*here we loop though the files and get their mime-type*/ + for(li = files; li!=NULL ; li = g_list_next(li)) { + char *mimetype; + char *filename = li->data; + + /*guess the mime type of the file*/ + mimetype = gnome_mime_type(filename); + + /*if we can't guess it, just loop to the + next filename*/ + if(!mimetype) continue; + + /*here comes code that can actually do something + based on the mime-type of the file we received*/ + ... + } + /*free the list of files we got*/ + gnome_uri_list_free_strings (files); +} + +Note how easy it is to find out what files you got, and what type +they are. You would just need to add some code instead of the three +dots that actually compares the mime strings you got to some you have +to figure out what you can do with the files. + + +Meta Data + + +Sometimes it is useful to store some information along with a filename, this +can be done easily with the gnome-metadata. It is a set of +functions to manage this data. Since Unix doesn't natively support meta-data, +you have to help it yourself. For example if your app copies, renames or +deletes files, use the following functions. + + + +Metadata functions + + + + + +Prototype +Description + + + + +int gnome_metadata_rename (const char *from, const char *to) +Notify the metadata database that a file has been renamed + +int gnome_metadata_copy (const char *from, const char *to) +Notify the metadata database that a file has been copied + +int gnome_metadata_delete (const char *file) +Notify the metadata database that a file has been deleted + +int gnome_metadata_set (const char *file, const char *name, int size, const char *data) +Set data associated with the file 'file', and key 'name'. The data is +pointed to by 'data' and is 'size' bytes long. GNOME_METADATA_OK is returned on success. + +int gnome_metadata_get (const char *file, const char *name, int *size, char **buffer) +Get data associated with file 'file' and key 'name'. Data will be copied to a buffer and 'buffer' will be set to point to it, and 'size' will be set to the size of the buffer. GNOME_METADATA_OK is returned on success. + +char **gnome_metadata_list (const char *file) +Get a list of the keys for which there is some data set on 'file'. The list will be a newly allocated, NULL terminated string vector and should be freed with g_strfreev + + + +
+ + + +Metadata return values + + + + + +Name +Description + + + + +GNOME_METADATA_OKNo error (this is actually 0) +GNOME_METADATA_IO_ERRORIO or other low-level communications/storage error. +GNOME_METADATA_NOT_FOUNDInformation not found. + + + +
+ + +
+ + +These functions don't actually do the operations on the files, they just +change the meta-data accordingly. So if your app does any of these +operations, it is nicer towards other apps, that it notifies the +meta-data database of the changes. You shouldn't rely on the data +being stored. Only non-critical data should be stored in the +meta-data, since apps that do not notify the database with these +functions will make you loose your data for the file. These functions will +return 0 or GNOME_METADATA_OK if there was no error, +or an error-code (described above). + + +Now if you actually want to use the meta-data to store information about files, +you will most likely use the functions gnome_metadata_set, +gnome_metadata_remove and +gnome_metadata_get. Again these functions return an +integer, which is GNOME_METADATA_OK in case there was no +error, or they use the same error codes as the previous functions. + + +The functions work with a a key string for which they store a piece of data. +The data is represented by a size integer and a character pointer. +gnome_metadata_set takes the filename as the first +argument, the name or key of the data as the second argument, the size as the +third and the pointer to the actual data as the forth argument. This function +just sets that data for that file and key. +gnome_metadata_remove will clear a particular data item on +a file, so it takes a file and then the key name as the second argument. +gnome_metadata_get takes the filename as the first +argument and the key name as the second, then it returns data size though an +integer pointer you pass though the third argument and the actual data though a +pointer to a pointer you pass as the fourth argument. The data returned is +newly allocated and should be freed after use. Small example follows (in real +life you should also check the return of the functions for errors): + + +int size; +char *data; +... +/*set some bogus data on a file*/ +gnome_metadata_set("/some/file/name","bogus",5,"BLAH"); +... +/*retrieve the data back*/ +gnome_metadata_get("/some/file/name","bogus",&size,&data); + + +
+
+ + +Using the libgnomeui Library + + +The libgnomeui library is the library you'll be using most, it includes +the basic UI framework of your application and other X and GTK+ specific +things, such as session management, and many utility widgets. It also +contains the GnomeCanvas widget, which deserves separate treatment. +This is the library that makes the programmers life easy. With +plain GTK+ you have to do a lot of things by yourself, reinventing +the wheel every time, but this library takes care of the UI setup for +you and still allows the user to configure that behavior and have it +be consistent over different applications. + + +GnomeApp Widget Basics + +Overview + + +GnomeApp is the basic widget behind each app. It is the main window of +the application, containing the document being worked on and the applications +menus, tool-bars and status bars. It also remembers the docked positions +of menu bars and tool-bars and such for you so that the user gets the window +the way he left it when he left the application last time. + + +Creating + + +Creating a new GnomeApp widget is as easy as calling +gnome_app_new with the application name, which is usually the name +of the executable or something else that is unique to your application and +the title of the main window. Then you create the content of the main window +and add it to the GnomeApp widget by calling gnome_app_set_contents +with your contents as the argument. + + +Adding menu-bars, tool-bars and status-bars is equally easy, you call +gnome_app_set_toolbar, gnome_app_set_menus or +gnome_app_set_statusbar. gnome_app_set_toolbar is for simple +applications that have only one tool-bar, for more complicated applications +you need to use gnome_app_add_toolbar, which allows you to add as +many docked tool-bars as you need. + + +Menu and Tool-bar Creation + + +Automatic Menu and Tool-bar Creation + + +Most of the time, you don't really want to create your menu-bars +and tool-bars by yourself. You can use functions from +libgnomeui/gnome-app-helper.h to construct menus and tool-bars for you. +All you need is to fill in a couple of structures with the your +information, and call gnome_app_create_menus or +gnome_app_create_toolbar with that structure and voila, +your application has menus and tool-bars. Sometimes you wish to pass +a data pointer to all the callbacks from those structures to work with, +then you'd use the gnome_app_create_toolbar_with_data and +gnome_app_create_menus_with_data, and pass an extra parameter which +will be passed in the data field of the callbacks. + + + +GnomeUIInfo Structure Definition + + +Here is the definition of +the structure you need to fill (actually you fill in an array of +such structures). Also note I included the enums that you will need +to fill that structure. + + +/* These values identify the type of pixmap used in an item */ +typedef enum { + GNOME_APP_PIXMAP_NONE, /* No pixmap specified */ + GNOME_APP_PIXMAP_STOCK, /* Use a stock pixmap + (GnomeStock) */ + GNOME_APP_PIXMAP_DATA, /* Use a pixmap from inline + xpm data */ + GNOME_APP_PIXMAP_FILENAME /* Use a pixmap from the + specified filename */ +} GnomeUIPixmapType; + +/* This is the structure that defines an item in a menu bar + * or tool-bar. The idea is to create an array of such + * structures with the information needed to create menus or + * tool-bars. The most convenient way to create such a structure + * is to use the GNOMEUIINFO_* macros provided below. */ +typedef struct { + GnomeUIInfoType type; /* Type of item */ + gchar *label; /* String to use in the label */ + gchar *hint; /* For tool-bar items, the + tool-tip. For menu items, the + status bar message */ + gpointer moreinfo; /* For an item, toggle-item, or + radio-item, this is a pointer + to the function to call when + the item is activated. For + a subtree, a pointer to + another array of GnomeUIInfo + structures. For a radio-item + lead entry, a pointer to an + array of GnomeUIInfo + structures for the radio + item group. For a help item, + specifies the help node to + load (i.e. the application's + identifier) or NULL for the + main program's name. For + builder data, points to the + GnomeUIBuilderData structure + for the following items */ + gpointer user_data; /* Data pointer to pass to + callbacks */ + gpointer unused_data; /* Reserved for future expansion, + should be NULL */ + GnomeUIPixmapType pixmap_type; /* Type of pixmap for the item */ + gpointer pixmap_info; /* Pointer to the pixmap + * information: + * + * For GNOME_APP_PIXMAP_STOCK, a + * pointer to the stock icon name. + * + * For GNOME_APP_PIXMAP_DATA, a + * pointer to the inline xpm data. + * + * For GNOME_APP_PIXMAP_FILENAME, a + * pointer to the filename string. + */ + guint accelerator_key; /* Accelerator key, or 0 for none */ + GdkModifierType ac_mods; /* Mask of modifier keys for the + accelerator */ + + GtkWidget *widget; /* Filled in by gnome_app_create*, + you can use this to tweak the + widgets once they have been + created */ +} GnomeUIInfo; + +Don't worry if you don't know all the items or what they mean. If you don't +know what it is, just leave it NULL or 0. Most of the time, it's easiest +to copy the menu's from another app and just modify them for your +needs, that way you will also know much better what does what then +by just looking at the structure. + + +Helper Macros + + +Most of the time, menu entries are very simple, so one can just use one +of the simple macros provided. For example, for the end of a menu, +one would use the GNOMEUIINFO_END macro, for a separator one uses the +GNOMEUIINFO_SEPARATOR macro. Now for the actual items there +are also macros, which require you to fill in less info. For example +if you have an item that you provide an xpm format data for, you can +use the GNOMEUIINFO_ITEM(label, tooltip, callback, xpm_data) +macro, where label is the text of the label, tool-tip is the tool-tip +that the user gets when he goes over that item (or it can be NULL), +callback is the function that gets called when the user presses that item, +and the xpm_data is a pointer to an xpm data you want to use as the +icon. If you have no icon you can just use the +GNOMEUIINFO_ITEM_NONE(label, tooltip, callback) macro. If what you +are adding is a standard item for which there is a stock icon (we'll talk +about those next), you can use the +GNOMEUIINFO_ITEM_STOCK(label, tooltip, callback, stock_id) macro +where the stock_id is the id of the stock icon you want to use. +Then for your +main menu bar, or to put sub-menus inside your menus, you can use +GNOMEUIINFO_SUBTREE(label, tree) and +GNOMEUIINFO_SUBTREE_STOCK(label, tree, stock_id), where the +tree is the array of GnomeUIInfo structures that you want to use as +that sub-menu. There are a few other macros, but most of the time you will +get by with just these macros, so you don't need to learn the entire +structure of the GnomeUIInfo. + + + +Standard Menu Item Macros + + +Just about all application contain a couple of standard menu items, so to +keep things more consistent there are a bunch of macros that fill in +everything for you except for the callback function and the data. The +advantage of using the macros is consistency across applications, user +customization, and translation. + + +Menu Items + + +Most of these macros have the form: +GNOMEUIINFO_MENU_<name>_ITEM (callback, data). +However, there is an exception, the "New xxx" item. The GNOME style guide +Requires that you put what the "New" thing is into the item name. Not to +mention that it will have a different hint as well. So the "New xxx" item +has the structure of: +GNOMEUIINFO_MENU_NEW_ITEM(label, hint, callback, data). +The "label" should start with "New ". Also note that if you have more new +items, you need to use the "New" subtree macro, which is explained later. + + + + +the File menu + +GNOMEUIINFO_MENU_NEW_ITEM(label, hint, cb, data) +"New" menu item (you need to provide label and hint +yourself here) + +GNOMEUIINFO_MENU_OPEN_ITEM(cb, data) +"Open" menu item + +GNOMEUIINFO_MENU_SAVE_ITEM(cb, data) +"Save" menu item + +GNOMEUIINFO_MENU_SAVE_AS_ITEM(cb, data) +"Save as..." menu item + +GNOMEUIINFO_MENU_REVERT_ITEM(cb, data) +"Revert" menu item + +GNOMEUIINFO_MENU_PRINT_ITEM(cb, data) +"Print" menu item + +GNOMEUIINFO_MENU_PRINT_SETUP_ITEM(cb, data) +"Print Setup" menu item + +GNOMEUIINFO_MENU_CLOSE_ITEM(cb, data) +"Close" menu item + +GNOMEUIINFO_MENU_EXIT_ITEM(cb, data) +"Exit" menu item + + + + + +the Edit menu + +GNOMEUIINFO_MENU_CUT_ITEM(cb, data) +"Cut" menu item + +GNOMEUIINFO_MENU_COPY_ITEM(cb, data) +"Copy" menu item + +GNOMEUIINFO_MENU_PASTE_ITEM(cb, data) +"Paste" menu item + +GNOMEUIINFO_MENU_SELECT_ALL_ITEM(cb, data) +"Select" menu item + +GNOMEUIINFO_MENU_CLEAR_ITEM(cb, data) +"Clear" menu item + +GNOMEUIINFO_MENU_UNDO_ITEM(cb, data) +"Undo" menu item + +GNOMEUIINFO_MENU_REDO_ITEM(cb, data) +"Redo" menu item + +GNOMEUIINFO_MENU_FIND_ITEM(cb, data) +"Find" menu item + +GNOMEUIINFO_MENU_FIND_AGAIN_ITEM(cb, data) +"Find Again" menu item + +GNOMEUIINFO_MENU_REPLACE_ITEM(cb, data) +"Replace" menu item + +GNOMEUIINFO_MENU_PROPERTIES_ITEM(cb, data) +"Properties" menu item + + + + +the Settings menu + +GNOMEUIINFO_MENU_PREFERENCES_ITEM(cb, data) +"Preferences" menu item + + + + +the Windows menu + +GNOMEUIINFO_MENU_NEW_WINDOW_ITEM(cb, data) +"New window" menu item + +GNOMEUIINFO_MENU_CLOSE_WINDOW_ITEM(cb, data) +"Close window" menu item + + + + +the Help menu + +GNOMEUIINFO_MENU_ABOUT_ITEM(cb, data) +"About" menu item + + + + +the Game menu + +GNOMEUIINFO_MENU_NEW_GAME_ITEM(cb, data) +"New game" menu item + +GNOMEUIINFO_MENU_PAUSE_GAME_ITEM(cb, data) +"Pause game" menu item + +GNOMEUIINFO_MENU_RESTART_GAME_ITEM(cb, data) +"Restart game" menu item + +GNOMEUIINFO_MENU_UNDO_MOVE_ITEM(cb, data) +"Undo move" menu item + +GNOMEUIINFO_MENU_REDO_MOVE_ITEM(cb, data) +"Redo move" menu item + +GNOMEUIINFO_MENU_HINT_ITEM(cb, data) +"Hint" menu item + +GNOMEUIINFO_MENU_SCORES_ITEM(cb, data) +"Scores" menu item + +GNOMEUIINFO_MENU_END_GAME_ITEM(cb, data) +"End game" menu item + + + +Menu trees and subtrees + + +We have already mentioned a "New" subtree. For this you should use the +GNOMEUIINFO_MENU_NEW_SUBTREE (tree) macro, where +the tree argument is another GnomeUIInfo structure array of the different +new items. + + +There are also the standard top level menus. Again you pass the array of +GnomeUIInfo structures to the macro. + + + +GNOMEUIINFO_MENU_FILE_TREE (tree) +"File" menu + +GNOMEUIINFO_MENU_EDIT_TREE (tree) +"Edit" menu + +GNOMEUIINFO_MENU_VIEW_TREE (tree) +"View" menu + +GNOMEUIINFO_MENU_SETTINGS_TREE (tree) +"Settings" menu + +GNOMEUIINFO_MENU_FILES_TREE (tree) +"Files" menu + +GNOMEUIINFO_MENU_WINDOWS_TREE (tree) +"Windows" menu + +GNOMEUIINFO_MENU_HELP_TREE (tree) +"Help" menu + +GNOMEUIINFO_MENU_GAME_TREE (tree) +"Game" menu + + + +Sometimes you may want to refer to menu path of these menus, such as +for adding items to a "Windows" menu. For this you should use the macros +of the form GNOME_MENU_<name>_STRING and +GNOME_MENU_<name>_PATH. These will expand to the +appropriate string. The macro ending with _STRING +will expand to just the menu name, and the macro ending with +_PATH to the menu name followed by a "/". The +<name> can be one of the following: FILE, EDIT, VIEW, SETTINGS, +NEW, FILES or WINDOWS. + + + +Help menu + + +Your application should contain a help menu, the help menu can be defined +as: + + + GNOMEUIINFO_HELP("app_name"), + GNOMEUIINFO_MENU_ABOUT_ITEM(callback, data), + GNOMEUIINFO_END + + +The GNOMEUIINFO_HELP macro takes the name of your application and expects +the help files to be installed as per normal gnome procedures. +FixMe: we need to add some section on help files and stuff + + + + + +Example + + +Here is a very simple application that makes use of these: + + +/* + * A simple Gnome program, outside of GNOME tree, not using i18n + * uiinfo.c + */ +/* the very basic gnome include */ +#include <gnome.h> + +/* a callback for the buttons */ +static void +a_callback(GtkWidget *button, gpointer data) +{ + /*just print a string so that we know we got there*/ + g_print("Inside Callback\n"); +} + +GnomeUIInfo file_menu[] = { + GNOMEUIINFO_MENU_EXIT_ITEM(gtk_main_quit,NULL), + GNOMEUIINFO_END +}; + +GnomeUIInfo some_menu[] = { + GNOMEUIINFO_ITEM_NONE("_Menuitem","Just a menuitem", + a_callback), + GNOMEUIINFO_SEPARATOR, + GNOMEUIINFO_ITEM_NONE("M_enuitem2","Just a menuitem", + a_callback), + GNOMEUIINFO_END +}; + +GnomeUIInfo menubar[] = { + GNOMEUIINFO_MENU_FILE_TREE(file_menu), + GNOMEUIINFO_SUBTREE("_Some menu",some_menu), + GNOMEUIINFO_END +}; + +GnomeUIInfo toolbar[] = { + GNOMEUIINFO_ITEM_STOCK("Exit","Exit the application", + gtk_main_quit, + GNOME_STOCK_PIXMAP_EXIT), + GNOMEUIINFO_END +}; + +int +main(int argc, char *argv[]) +{ + GtkWidget *app; + GtkWidget *button; + GtkWidget *hbox; + GtkWidget *label; + + /* Initialize GNOME, this is very similar to gtk_init */ + gnome_init ("menu-basic-example", "0.1", argc, argv); + + /* Create a Gnome app widget, which sets up a basic + window for your application */ + app = gnome_app_new ("menu-basic-example", + "Basic GNOME Application"); + + /* bind "delete_event", which is the event we get when + the user closes the window with the window manager, + to gtk_main_quit, which is a function that causes + the gtk_main loop to exit, and consequently to quit + the application */ + gtk_signal_connect (GTK_OBJECT (app), "delete_event", + GTK_SIGNAL_FUNC (gtk_main_quit), + NULL); + + /*make a label as the contents*/ + label = gtk_label_new("BLAH BLAH BLAH BLAH BLAH"); + + /*add the label as contents of the window*/ + gnome_app_set_contents (GNOME_APP (app), label); + + /*create the menus for the application*/ + gnome_app_create_menus (GNOME_APP (app), menubar); + + /*create the tool-bar for the application*/ + gnome_app_create_toolbar (GNOME_APP (app), toolbar); + + /* show everything inside this app widget and the app + widget itself */ + gtk_widget_show_all(app); + + /* enter the main loop */ + gtk_main (); + + return 0; +} + +Voila, an application with a menu and a tool-bar. As you see, adding +extra menu items is just adding extra definitions to the GnomeUIInfo +structure array. + + +Accelerator keys + + +You have probably noticed the underlines in the labels for the menu items, +these specify the accelerators for that menu. That's really all you need +to do to add accelerators for menu items. The way accelerators work +is very similar to the other windowing systems out there, alt-<key> +if you are not browsing the menus or just the <key> if you have the +menu open. + + +Stock Icons + + +Since most of the time you will want to use standard buttons and menu items +(such as Open or Save as...), and you want to provide icons +with the menu items or tool-bar buttons or just dialog buttons, to make +it easier to navigate, you can use some of the predefined icons from +gnome-libs. These are called Stock Icons. You have already +seen an example of how to use stock menu icons and regular stock icons +in menus and tool-bars (you just use the proper define from +libgnomeui/gnome-stock.h). There are also stock buttons, where +you can get back a button widget based on a stock description. + + +Here is a list of the normal gnome stock icons, these are regular +sized for use in tool-bars and other places where you need a normal sized +icon. They are given as defines of string constants and their meaning +should be obvious. + + +#define GNOME_STOCK_PIXMAP_NEW "New" +#define GNOME_STOCK_PIXMAP_OPEN "Open" +#define GNOME_STOCK_PIXMAP_CLOSE "Close" +#define GNOME_STOCK_PIXMAP_REVERT "Revert" +#define GNOME_STOCK_PIXMAP_SAVE "Save" +#define GNOME_STOCK_PIXMAP_SAVE_AS "Save As" +#define GNOME_STOCK_PIXMAP_CUT "Cut" +#define GNOME_STOCK_PIXMAP_COPY "Copy" +#define GNOME_STOCK_PIXMAP_PASTE "Paste" +#define GNOME_STOCK_PIXMAP_PROPERTIES "Properties" +#define GNOME_STOCK_PIXMAP_PREFERENCES "Preferences" +#define GNOME_STOCK_PIXMAP_HELP "Help" +#define GNOME_STOCK_PIXMAP_SCORES "Scores" +#define GNOME_STOCK_PIXMAP_PRINT "Print" +#define GNOME_STOCK_PIXMAP_SEARCH "Search" +#define GNOME_STOCK_PIXMAP_SRCHRPL "Search/Replace" +#define GNOME_STOCK_PIXMAP_BACK "Back" +#define GNOME_STOCK_PIXMAP_FORWARD "Forward" +#define GNOME_STOCK_PIXMAP_FIRST "First" +#define GNOME_STOCK_PIXMAP_LAST "Last" +#define GNOME_STOCK_PIXMAP_HOME "Home" +#define GNOME_STOCK_PIXMAP_STOP "Stop" +#define GNOME_STOCK_PIXMAP_REFRESH "Refresh" +#define GNOME_STOCK_PIXMAP_UNDO "Undo" +#define GNOME_STOCK_PIXMAP_REDO "Redo" +#define GNOME_STOCK_PIXMAP_TIMER "Timer" +#define GNOME_STOCK_PIXMAP_TIMER_STOP "Timer Stopped" +#define GNOME_STOCK_PIXMAP_MAIL "Mail" +#define GNOME_STOCK_PIXMAP_MAIL_RCV "Receive Mail" +#define GNOME_STOCK_PIXMAP_MAIL_SND "Send Mail" +#define GNOME_STOCK_PIXMAP_MAIL_RPL "Reply to Mail" +#define GNOME_STOCK_PIXMAP_MAIL_FWD "Forward Mail" +#define GNOME_STOCK_PIXMAP_MAIL_NEW "New Mail" +#define GNOME_STOCK_PIXMAP_TRASH "Trash" +#define GNOME_STOCK_PIXMAP_TRASH_FULL "Trash Full" +#define GNOME_STOCK_PIXMAP_UNDELETE "Undelete" +#define GNOME_STOCK_PIXMAP_SPELLCHECK "Spellchecker" +#define GNOME_STOCK_PIXMAP_MIC "Microphone" +#define GNOME_STOCK_PIXMAP_LINE_IN "Line In" +#define GNOME_STOCK_PIXMAP_CDROM "Cdrom" +#define GNOME_STOCK_PIXMAP_VOLUME "Volume" +#define GNOME_STOCK_PIXMAP_BOOK_RED "Book Red" +#define GNOME_STOCK_PIXMAP_BOOK_GREEN "Book Green" +#define GNOME_STOCK_PIXMAP_BOOK_BLUE "Book Blue" +#define GNOME_STOCK_PIXMAP_BOOK_YELLOW "Book Yellow" +#define GNOME_STOCK_PIXMAP_BOOK_OPEN "Book Open" +#define GNOME_STOCK_PIXMAP_ABOUT "About" +#define GNOME_STOCK_PIXMAP_QUIT "Quit" +#define GNOME_STOCK_PIXMAP_MULTIPLE "Multiple" +#define GNOME_STOCK_PIXMAP_NOT "Not" +#define GNOME_STOCK_PIXMAP_CONVERT "Convert" +#define GNOME_STOCK_PIXMAP_JUMP_TO "Jump To" +#define GNOME_STOCK_PIXMAP_UP "Up" +#define GNOME_STOCK_PIXMAP_DOWN "Down" +#define GNOME_STOCK_PIXMAP_TOP "Top" +#define GNOME_STOCK_PIXMAP_BOTTOM "Bottom" +#define GNOME_STOCK_PIXMAP_ATTACH "Attach" +#define GNOME_STOCK_PIXMAP_INDEX "Index" +#define GNOME_STOCK_PIXMAP_FONT "Font" +#define GNOME_STOCK_PIXMAP_EXEC "Exec" + +#define GNOME_STOCK_PIXMAP_ALIGN_LEFT "Left" +#define GNOME_STOCK_PIXMAP_ALIGN_RIGHT "Right" +#define GNOME_STOCK_PIXMAP_ALIGN_CENTER "Center" +#define GNOME_STOCK_PIXMAP_ALIGN_JUSTIFY "Justify" + +#define GNOME_STOCK_PIXMAP_TEXT_BOLD "Bold" +#define GNOME_STOCK_PIXMAP_TEXT_ITALIC "Italic" +#define GNOME_STOCK_PIXMAP_TEXT_UNDERLINE "Underline" +#define GNOME_STOCK_PIXMAP_TEXT_STRIKEOUT "Strikeout" + +#define GNOME_STOCK_PIXMAP_EXIT GNOME_STOCK_PIXMAP_QUIT + +If you need to use these outside of GnomeUIInfo, you need +to get the widget with the pixmap. What you do is you call the +gnome_stock_pixmap_widget function with your main window +as the first argument (so that it can copy it's style) and +the icon name (one of the above defines) as the second argument. +It returns a new widget which you can just use as a pixmap. + + +For menus you want to use the _MENU_ variety of the stock +pixmaps. These are smaller and these should be the ones you use +for the stock menu items in your GnomeUIInfo definitions. + + +#define GNOME_STOCK_MENU_BLANK "Menu_" +#define GNOME_STOCK_MENU_NEW "Menu_New" +#define GNOME_STOCK_MENU_SAVE "Menu_Save" +#define GNOME_STOCK_MENU_SAVE_AS "Menu_Save As" +#define GNOME_STOCK_MENU_REVERT "Menu_Revert" +#define GNOME_STOCK_MENU_OPEN "Menu_Open" +#define GNOME_STOCK_MENU_CLOSE "Menu_Close" +#define GNOME_STOCK_MENU_QUIT "Menu_Quit" +#define GNOME_STOCK_MENU_CUT "Menu_Cut" +#define GNOME_STOCK_MENU_COPY "Menu_Copy" +#define GNOME_STOCK_MENU_PASTE "Menu_Paste" +#define GNOME_STOCK_MENU_PROP "Menu_Properties" +#define GNOME_STOCK_MENU_PREF "Menu_Preferences" +#define GNOME_STOCK_MENU_ABOUT "Menu_About" +#define GNOME_STOCK_MENU_SCORES "Menu_Scores" +#define GNOME_STOCK_MENU_UNDO "Menu_Undo" +#define GNOME_STOCK_MENU_REDO "Menu_Redo" +#define GNOME_STOCK_MENU_PRINT "Menu_Print" +#define GNOME_STOCK_MENU_SEARCH "Menu_Search" +#define GNOME_STOCK_MENU_SRCHRPL "Menu_Search/Replace" +#define GNOME_STOCK_MENU_BACK "Menu_Back" +#define GNOME_STOCK_MENU_FORWARD "Menu_Forward" +#define GNOME_STOCK_MENU_FIRST "Menu_First" +#define GNOME_STOCK_MENU_LAST "Menu_Last" +#define GNOME_STOCK_MENU_HOME "Menu_Home" +#define GNOME_STOCK_MENU_STOP "Menu_Stop" +#define GNOME_STOCK_MENU_REFRESH "Menu_Refresh" +#define GNOME_STOCK_MENU_MAIL "Menu_Mail" +#define GNOME_STOCK_MENU_MAIL_RCV "Menu_Receive Mail" +#define GNOME_STOCK_MENU_MAIL_SND "Menu_Send Mail" +#define GNOME_STOCK_MENU_MAIL_RPL "Menu_Reply to Mail" +#define GNOME_STOCK_MENU_MAIL_FWD "Menu_Forward Mail" +#define GNOME_STOCK_MENU_MAIL_NEW "Menu_New Mail" +#define GNOME_STOCK_MENU_TRASH "Menu_Trash" +#define GNOME_STOCK_MENU_TRASH_FULL "Menu_Trash Full" +#define GNOME_STOCK_MENU_UNDELETE "Menu_Undelete" +#define GNOME_STOCK_MENU_TIMER "Menu_Timer" +#define GNOME_STOCK_MENU_TIMER_STOP "Menu_Timer Stopped" +#define GNOME_STOCK_MENU_SPELLCHECK "Menu_Spellchecker" +#define GNOME_STOCK_MENU_MIC "Menu_Microphone" +#define GNOME_STOCK_MENU_LINE_IN "Menu_Line In" +#define GNOME_STOCK_MENU_CDROM "Menu_Cdrom" +#define GNOME_STOCK_MENU_VOLUME "Menu_Volume" +#define GNOME_STOCK_MENU_BOOK_RED "Menu_Book Red" +#define GNOME_STOCK_MENU_BOOK_GREEN "Menu_Book Green" +#define GNOME_STOCK_MENU_BOOK_BLUE "Menu_Book Blue" +#define GNOME_STOCK_MENU_BOOK_YELLOW "Menu_Book Yellow" +#define GNOME_STOCK_MENU_BOOK_OPEN "Menu_Book Open" +#define GNOME_STOCK_MENU_CONVERT "Menu_Convert" +#define GNOME_STOCK_MENU_JUMP_TO "Menu_Jump To" +#define GNOME_STOCK_MENU_UP "Menu_Up" +#define GNOME_STOCK_MENU_DOWN "Menu_Down" +#define GNOME_STOCK_MENU_TOP "Menu_Top" +#define GNOME_STOCK_MENU_BOTTOM "Menu_Bottom" +#define GNOME_STOCK_MENU_ATTACH "Menu_Attach" +#define GNOME_STOCK_MENU_INDEX "Menu_Index" +#define GNOME_STOCK_MENU_FONT "Menu_Font" +#define GNOME_STOCK_MENU_EXEC "Menu_Exec" + +#define GNOME_STOCK_MENU_ALIGN_LEFT "Menu_Left" +#define GNOME_STOCK_MENU_ALIGN_RIGHT "Menu_Right" +#define GNOME_STOCK_MENU_ALIGN_CENTER "Menu_Center" +#define GNOME_STOCK_MENU_ALIGN_JUSTIFY "Menu_Justify" + +#define GNOME_STOCK_MENU_TEXT_BOLD "Menu_Bold" +#define GNOME_STOCK_MENU_TEXT_ITALIC "Menu_Italic" +#define GNOME_STOCK_MENU_TEXT_UNDERLINE "Menu_Underline" +#define GNOME_STOCK_MENU_TEXT_STRIKEOUT "Menu_Strikeout" + +#define GNOME_STOCK_MENU_EXIT GNOME_STOCK_MENU_QUIT + +If you are building the menu yourself and just want to get a menu-item +that's built with the stock icon and a label, you can use the +gnome_stock_menu_item convenience routine. It takes the stock +icon type (one of the defines above) as the first argument, and the menu +text as the second argument, and it returns a newly created menu-item +widget. + + +Then there are stock buttons. These are for use in your dialogs (see the next +section). + + +#define GNOME_STOCK_BUTTON_OK "Button_Ok" +#define GNOME_STOCK_BUTTON_CANCEL "Button_Cancel" +#define GNOME_STOCK_BUTTON_YES "Button_Yes" +#define GNOME_STOCK_BUTTON_NO "Button_No" +#define GNOME_STOCK_BUTTON_CLOSE "Button_Close" +#define GNOME_STOCK_BUTTON_APPLY "Button_Apply" +#define GNOME_STOCK_BUTTON_HELP "Button_Help" +#define GNOME_STOCK_BUTTON_NEXT "Button_Next" +#define GNOME_STOCK_BUTTON_PREV "Button_Prev" +#define GNOME_STOCK_BUTTON_UP "Button_Up" +#define GNOME_STOCK_BUTTON_DOWN "Button_Down" +#define GNOME_STOCK_BUTTON_FONT "Button_Font" + +To get a button widget with the stock icon and text, you can just use the +function gnome_stock_button with the button type (one of the above +defines) as the argument. Now sometimes you want to create a mixture of +stock or ordinary buttons, what you can do is call the +gnome_stock_or_ordinary_button function with either the type of +a stock button or just a text for the button label. The function checks +if it is one of the above strings, and if it's not it creates an +ordinary button widget with the text as the label. + + +Dialogs + +Generic Dialogs + + +If you need to create you own custom dialog, gnome-dialog is the +way to do it. It can handle both modal and non-modal dialogs, although, +it's definitely much more friendly to the users of your program if +you use a non-modal dialog box, if at all possible, although non-modal +dialog boxes tend to have problems associated with them, and sometimes +can cause strange bugs, for example if a non-modal dialog box is associated +with a window, you'd better bind the destroy signal of the window +and set it to destroy the dialog box as well, since otherwise it could +hang around even though the window or document it was supposed to act on +is already dead. However modal dialogs (while definitely easier to program) +are usually pretty annoying to use, so avoid them if you at all can. + + +To make a new GnomeDialog widget, just use the gnome_dialog_new +function. You pass the title of the dialog as the first argument, and then +multiple arguments as the button titles terminated by a NULL. The button +titles can also be the GNOME_STOCK_BUTTON_* definitions if you want +stock buttons on your dialog. Then you need to add content to the dialog, +the dialog is created with a vertical box (GtkVBox) for you to use, +just by using GNOME_DIALOG(dialog)->vbox. Into that you add your +content. At this point you have to decide if you want to do a modal dialog +or a non-modal dialog. + + +In case you want to do a modal dialog, all you need to do is to call +gnome_dialog_run_and_close function and it will run the dialog, +wait for a user to press a button or close the dialog, and then close +the dialog. This function will return the number of the button that was +pressed or -1 if the dialog was just closed. In case you don't want to +close the dialog when just any button is pressed, you use the +gnome_dialog_run function, and after you get a result, do what you +need to do for that particular button press. Then if you want to run +the dialog more, you just loop back to gnome_dialog_run, and if +you want to close, you run gnome_dialog_close. Here's an example +of the second scheme. + + +GtkWidget *dlg; +int i; +... +/*create a new dialog, DON'T forget the NULL on the end, + it is very important!*/ +dlg = gnome_dialog_new("A Dialog", + GNOME_STOCK_BUTTON_OK, + GNOME_STOCK_BUTTON_APPLY, + GNOME_STOCK_BUTTON_CLOSE, + NULL); +... +/*add some content to the dialog here*/ +... +/*set up an infinite loop*/ +for(;;) { + i = gnome_dialog_run(GNOME_DIALOG(dlg)); + if(i == 0 || i == 2) { + /*the user pressed OK or close, so we will get + out of the loop and close the dialog, or the + user pressed */ + gnome_dialog_close(GNOME_DIALOG(dlg)); + break; + } else if(i < 0) { + /*the user closed the dialog from the window + manager*/ + break; + } else if(i == 1) { + /*user pressed apply we don't want to close*/ + ... + } +} + +By default the dialog is destroyed when closed, so you don't have to worry +about it's destruction. You can change this behavior if you wish though. + + +If you are doing a non-modal dialog box, things get a little more complicated. +You create the dialog as above, but then you bind the clicked signal +of the GnomeDialog widget. That signal has as it's second argument +the button number that was pressed. After that you should use the +gnome_dialog_set_close function to tell GnomeDialog that +we want to close the dialog when the user first presses any button, if +you want that behavior, otherwise you'll have to do gnome_dialog_close +in the clicked signal handler for the buttons you want to close on. +After that is set up you just gtk_widget_show the dialog. An +example follows: + + +/*the clicked signal handler*/ +static void +dialog_clicked(GnomeDialog *dlg, int button, gpointer data) +{ + switch(button) { + case 1: + /*user pressed apply*/ + ... + return; + case 0: + /*user pressed OK*/ + ... + /*fall though to close*/ + case 2: + /*user pressed close*/ + gnome_dialog_close(dlg); + break; + } +} + +/*somewhere else in the source file*/ +... +GtkWidget *dlg; +... +/*create a new dialog, DON'T forget the NULL on the end, it + is very important!*/ +dlg = gnome_dialog_new("A Dialog", + GNOME_STOCK_BUTTON_OK, + GNOME_STOCK_BUTTON_APPLY, + GNOME_STOCK_BUTTON_CLOSE, + NULL); +... +/*add some content to the dialog here*/ +... +/*bind the clicked handler*/ +gtk_signal_connect(GTK_OBJECT(dlg),"clicked", + GTK_SIGNAL_FUNC(dialog_clicked), + NULL); +/*show the dialog, note that this is not a modal dialog, + so the program doesn't block here, but continues*/ +gtk_widget_show(dlg); + +This implements the same dialog as the modal example above, only non modal. + + +Message Box + + +GnomeMessageBox is an object derived from GnomeDialog. As such +you use it in the exact same manner, the only difference here is that +it automatically sets up the insides of the dialog to be a single label +and an icon of the selected message box type. The message box types are +as follows: + + +#define GNOME_MESSAGE_BOX_INFO "info" +#define GNOME_MESSAGE_BOX_WARNING "warning" +#define GNOME_MESSAGE_BOX_ERROR "error" +#define GNOME_MESSAGE_BOX_QUESTION "question" +#define GNOME_MESSAGE_BOX_GENERIC "generic" + +To create a message box, you use the function gnome_message_box_new +with the first argument being the message text, the second argument being the +type of the message box (one of the defines above), and then any number +of buttons terminated by a NULL exactly as in the GnomeDialog's case. +After created it is again used exactly the same as GnomeDialog. + + +Property Dialogs + + +If you have some properties to set in your application, you should use +a GnomePropertyBox dialog for the preferences to make the +applications more consistent. Again this object is derived from +GnomeDialog so it's use is similar. But GnomePropertyBox +defines some new signals, namely apply and help. They both +get passed the page number as the second argument. For help you should +use this to display the proper help page, however for apply, this was +created for adding a per-page apply button, which was not realized yet, +so you should ignore any apply signal with the page number other +then -1, which is the global apply. This can be done with a simple +if statement at the top of your apply routine. You can choose to be +per-page apply ready, by doing a per-page apply in your code, but +it is not sure if this code will ever get completed. It should be +safe to do just the global apply as that is the only thing implemented +in gnome-libs 1.0. + + +To use property dialogs, you call gnome_property_box_new, +which will create a completely new dialog for you with a notebook and the four +buttons. OK, which will call your apply handler for all +pages and then for the -1 page, and then it will close the dialog, +Apply, which will call the apply handler for all pages and +then for the -1 page, Close, which will just close the +dialog, and Help which will call your help handler if you +bound it. You then connect the apply signal to your apply +handler, and most likely the destroy signal on the +property box to destroy the data associated with the property box when it +closes. You then create the different pages for your property box and add them +with, gnome_property_box_append_page, which takes your +page as the second argument and a label as the third (usually this will be just +a GtkLabel). You also want to connect the different +signals for the widgets on your pages, to mark the property box as changed +(otherwise the Apply and OK buttons will not be sensitive). You do this by +calling gnome_property_box_changed every time the user +changed something with the widgets. For example on entry (and derived) widgets +you connect to the changed signal. Example follows: + + +/*apply handler*/ +static void +property_apply(GnomePropertyBox *box, int page_num, gpointer data) +{ + /*ignore page numbers other then -1*/ + if(page_num!=-1) + return; + /*do your apply routine here*/ + ... +} +... +/*somewhere else in the source file*/ +GtkWidget *pbox; +GtkWidget *widget; +... +pbox = gnome_property_box_new(); +gtk_signal_connect(GTK_OBJECT(pbox),"apply", + GTK_SIGNAL_FUNC(property_apply),NULL); +... +/*you create a page for the property box and added it to the + container called widget*/ +gnome_property_box_append_page(GNOME_PROPERTY_BOX(pbox), + widget, + gtk_label_new("SomePage")); +/*then add other pages in similar manner*/ +... +/*we show the dialog box*/ +gtk_widget_show_all(pbox); + + + +File Picking Dialog + + +Gnome doesn't have it's own file picking dialog, although this is planned for +the future, for now you need to use the regular GTK+ file +dialog. + + +Use of the file dialog is very simple. You create the dialog with +gtk_file_selection_new, passing it the title of the dialog +box as the argument. After this you bind the clicked signal on the +OK and Cancel buttons. For example +for a loading dialog box, you could check that the file is of the correct type +when the user presses OK and if so then close the dialog (usually with +gtk_widget_destroy). Or for saving dialog, you could ask +if the file exists. File selection dialog boxes are usually safe and simple to +do non-modal. Just make sure you'd destroy the file dialog box when the object +or window it's supposed to work with. Here's the routine that invokes the save +as dialog for Achtung, which is a presentation program +we're working on. + + +void +presentation_save_as (AchtungPresentation *p) +{ + GtkFileSelection *fsel; + + g_return_if_fail (p != NULL); + g_return_if_fail (p->doc != NULL); + + fsel = (GtkFileSelection *) + gtk_file_selection_new (_("Save presentation as")); + if (p->real_file && p->filename) + gtk_file_selection_set_filename (fsel, p->filename); + + gtk_object_set_data(GTK_OBJECT(fsel),"p",p); + + /* Connect the signals for Ok and Cancel */ + gtk_signal_connect (GTK_OBJECT (fsel->ok_button), "clicked", + GTK_SIGNAL_FUNC (save_ok), fsel); + gtk_signal_connect_object + (GTK_OBJECT (fsel->cancel_button), "clicked", + GTK_SIGNAL_FUNC (gtk_widget_destroy), + GTK_OBJECT(fsel)); + + gtk_window_position (GTK_WINDOW (fsel), GTK_WIN_POS_MOUSE); + + /*if the presentation dies so do it's dialogs*/ + gtk_signal_connect_object_while_alive + (GTK_OBJECT (p), "destroy", + GTK_SIGNAL_FUNC (gtk_widget_destroy), + GTK_OBJECT(fsel)); + + gtk_widget_show (GTK_WIDGET (fsel)); +} + +This is actually a save_as method for AchtungPresentation +object in object oriented speak. AchtungPresentation is a +GtkObject we use for storing all the presentation data (This is a nice example +of how to use GtkObject for things not directly related to widgets or GUI +programming). First we check the arguments to the function with +g_return_if_fail which is for debugging purposes. Then we +create a new GtkFileSelection with a title of "Save +presentation as". Ignore the _() macro around the string +for now, it's used for internationalization. Afterwards we check if the +presentation already has a filename associated with it, and if so we set the +filename on the file selection dialog to that. After that we connect the the +OK button to a routine called save_ok +defined elsewhere in the file and pass the file selection dialog as a data +argument. Then we use connect_object to bind the +Cancel button to destroying the file selection dialog. The +connect_object method is similar to regular +connect but when it calls the function itself it will pass +the object from the data field as the first argument of the function. So +connecting to gtk_widget_destroy will destroy the object +passed in the data field, which is the file selection dialog. Then we position +the dialog near the mouse button. In the future when this dialog is derived +from GnomeDialog, you will not need to and actually should +not do that, as that will be done according to use preferences as for all the +other gnome dialogs. After this we use yet another signal connection method ... +this time gtk_signal_connect_object_while_alive, which is +similar to connect_object, but has a nice twist to it. The +signal will be disconnected when the object passed in the data field dies. This +needs to happen as the file dialog will most likely be destroyed before the the +presentation itself is, then when the presentation is destroyed itself, it +would try to destroy an already non-existent file selection dialog and most +likely cause a segmentation fault and crash. This way it is safe and if the +file selection dialog is still around when the presentation is destroyed, it is +destroyed with it. + + +Entries + + +Sometimes, especially in properties dialogs, you want fields for entering +text, files, pixmaps, icons or double precision numbers. This is what the +gnome-*entry widgets do. + + +GnomeEntry + + +This is an entry for regular text, but it includes history of previously +entered values. Note that this widget is not derived from +GtkEntry, but owns such a widget. This means that you +can't use GtkEntry methods on this object directly, but +you need to get a pointer to the GtkEntry object inside +GnomeEntry. When you call +gnome_entry_new, you pass a +history_id string to it. This is a unique identifier to +identify this entry, or this type of entries in your application. All the +entries that share this history_id will have common +history of values. After you create a GnomeEntry you use +the gnome_entry_gtk_entry function to get a pointer to the +GtkEntry object inside and bind any signals or manipulate +text with that instead. Here is an example: + + +GtkWidget *gnome_e; +GtkWidget *gtk_e; +... +gnome_entry_new("text1"); +gtk_e = gnome_entry_gtk_entry(GNOME_ENTRY(gnome_e)); +gtk_signal_connect(GTK_OBJECT(gtk_e),"changed", + GTK_SIGNAL_FUNC(entry_changed), NULL); + + + +GnomeFileEntry + + +GnomeEntry is a basis for +GnomeFileEntry. Again it is not derived, but +GnomeEntry is owned by +GnomeFileEntry. This type of hierarchy is throughout all +the gnome entry widgets. GnomeFileEntry adds a browse +button on the right side of the entry, and also accepts file drops from the +file manager for example. It's use is extremely similar to +GnomeEntry. You create the entry with +gnome_file_entry_new. The first argument is the +history_id of the GnomeEntry, and the +second argument is the title of the browse dialog box. To get the +GtkEntry, you again use the gtk_entry method, named +gnome_file_entry_gtk_entry. To finally get the filename, +you can get the exact text from the GtkEntry, or you might +use a convenience method, gnome_file_entry_get_full_path, +which takes a flag file_must_exist as it's second +argument. If this flag is set, the function returns NULL if the file doesn't +exists. If the flag is not set or the file does exist, the function returns the +full path to the file. + + +GnomePixmapEntry + + +This is an entry for entering pixmaps (Images) of any size. It again includes +(not derives from) GnomeFileEntry, so it can do everything +the file entry can (including accepting drops). However this entry adds a +preview box for the pixmap above the entry. Also it's file selection dialog +includes a preview box to the right side of the file list. It's use is again +very similar to the entries above. You call +gnome_pixmap_entry_new with the same arguments as +GnomeFileEntry, with an added flag, +do_preview. This flag specifies if the preview box is +visible or not. But be careful, it doesn't save memory not to show the preview, +it just saves space. Again you use a +gnome_pixmap_entry_gtk_entry to get the +GtkEntry widget. To get a filename of the the pixmap, if +it could be loaded as an image for the preview (using imlib), you can use +gnome_pixmap_entry_get_filename, which returns NULL if the +pixmap files doesn't exist or could not be loaded, and the full filename +otherwise. + + + + +GnomeIconEntry + + +The icon entry is very similar to the GnomePixmapEntry, +but it is meant for images in the standard 48x48 icon size. Also instead of the +preview box, there is a button with the image scaled to 48x48. If you press the +button you get a listing of images from the same directory as the current icon. +To create an icon entry use gnome_icon_entry_new with +history_id and browse_dialog_title +string arguments. Once you need an existing icon that is a real image, you use +gnome_icon_entry_get_filename which works just like +gnome_pixmap_entry_get_filename. You can also get the +GtkEntry by using +gnome_icon_entry_gtk_entry. + + + + +GnomeNumberEntry + + +GnomeNumberEntry is an entry widget for entering double +precision numbers with a calculator. Most of the time for number entries you +want to use the GtkSpinButton widget, however for +applications such as mortgage calculators, or finance programs, where +calculations are necessary, you will want to use this entry type. Basically +it's a GnomeEntry widget with a button on the right side +of it which calls up a dialog with a calculator. The user can use the +calculator and press OK and the number entry is updated to what it was on the +calculator. To create a number entry widget, just use +gnome_number_entry_new, passing it the +history_id as the first argument and the title of the +calculator dialog as the second argument. To get the +GtkEntry widget just use +gnome_number_entry_gtk_entry. To get the number as a +double value, use +gnome_number_entry_get_number +method. + + + + + +Using Images + + +When you need to use images in your apps, most likely you'll want the +GnomePixmap widget. It's advantage is that it makes using +images much easier without having to learn imlib, which is the image library +used by this widget. + + +There are numerous new functions for +GnomePixmap, depending on the source of the pixmap. The +most used will probably be gnome_pixmap_new_from_file +which takes a filename which is an image loadable by imlib and creates a pixmap +widget for you. There is also +gnome_pixmap_new_from_file_at_size to which you pass also +the size to which the image should be scaled. If you have already loaded the +image with imlib (in case you wanted to do other things to the pixmap first), +you can use gnome_pixmap_new_from_imlib and +gnome_pixmap_new_from_imlib_at_size. Which take a +GdkImlibImage as the first argument. If you already have a +pixmap widget and want to change the image inside it, you can use the +gnome_pixmap_load_* which have almost the same syntax as +the new functions, except that you pass the GnomePixmap as +the first argument, and then the rest of the arguments as above, and of course +replace the _new_from_ for _load_. + + +Here's an example of it's use: + + +GtkWidget *pix; +... +/*load somefile.png and scale it to 48x48*/ +pix = gnome_pixmap_new_from_file_at_size("somefile.png",48,48); +/*now you can pack pix somewhere just like any other widget*/ +... +/*now we want to change the files to otherfile.png and do no + scaling*/ +gnome_pixmap_load_file(GNOME_PIXMAP(pix),"otherfile.png"); + + + +Session Management + + +Your app should be able to save it's settings and restore them when the user +restarts your application, it should also be able to do this for several +different sessions. For instance the user might have a normal session, but +sometimes log into a special session where he has different settings in +applications. gnome-libs actually hides the ugly details +of this. For the most part you do not need to worry about the real details of +session management, unless you wish to do something very clever or if your app +does some complicated state saving. To do simple session saving all you need is +the following code (mostly taken from gnome-hello-4-SM example program): + + +/*the save_yourself handler, you can safely ignore most of the + parameters, and just save your session and return TRUE*/ +static int +save_yourself(GnomeClient *client, int phase, + GnomeSaveStyle save_style, int shutdown, + GnomeInteractStyle interact_style, int fast, + gpointer client_data) +{ + /*get the prefix for our config*/ + char *prefix= gnome_client_get_config_prefix (client); + + /*this is a "discard" command for discarding data from + a saved session, usually this will work*/ + char *argv[]= { "rm", "-r", NULL }; + + /* Save the state using gnome-config stuff. */ + gnome_config_push_prefix (prefix); + + gnome_config_set_int("Section/Key",some_value); + ... + gnome_config_pop_prefix (); + gnome_config_sync(); + + /* Here is the real SM code. We set the argv to the + parameters needed to restart/discard the session that + we've just saved and call the + gnome_session_set_*_command to tell the session + manager it. */ + argv[2]= gnome_config_get_real_path (prefix); + gnome_client_set_discard_command (client, 3, argv); + + /* Set commands to clone and restart this application. + Note that we use the same values for both -- the + session management code will automatically add + whatever magic option is required to set the session + id on startup. The client_data was set to the + command used to start this application when + save_yourself handler was connected. */ + argv[0]= (gchar*) client_data; + gnome_client_set_clone_command (client, 1, argv); + gnome_client_set_restart_command (client, 1, argv); + + return TRUE; +} + +static void +die (GnomeClient *client, gpointer client_data) +{ + /* Just exit in a friendly way. We don't need to + save any state here, because the session manager + should have sent us a save_yourself-message + before. */ + gtk_exit (0); +} + +... +GnomeClient *client; +... +/*this is somewhere in your main function presumably. + make sure this is done AFTER the gnome_init call!*/ + +/* Get the master client, that was hopefully connected to the + session manager int the 'gnome_init' call. All communication + to the session manager will be done with this master client. */ +client = gnome_master_client (); + +/* Arrange to be told when something interesting happens. */ +gtk_signal_connect (GTK_OBJECT (client), "save_yourself", + GTK_SIGNAL_FUNC (save_yourself), + (gpointer) argv[0]); +gtk_signal_connect (GTK_OBJECT (client), "die", + GTK_SIGNAL_FUNC (die), NULL); + +/*check if we are connected to a session manager*/ +if (GNOME_CLIENT_CONNECTED (client)) { + /*we are connected, we will get the prefix under which + we saved our session last time and load up our data*/ + gnome_config_push_prefix + (gnome_client_get_config_prefix (client)); + + some_value = gnome_config_get_int("Section/Key=0"); + + gnome_config_pop_prefix (); +} else { + /*we are not connected to any session manager, here you + will just initialize your session like you normally + do without a session manager*/ + ... +} + +This is a very simple session management which will be enough for most +programs, for more information on session management, you should consult the +gnome developer documentation which should be available by now. + + +Multiple Document Interface + +The Main MDI Window + + +If your app handles documents, most likely you will want it to handle multiple +documents at one time. Gnome provides an MDI model that is customizable by the +user and simple to use. They can use three models of the document display. +Either a notebook style which is the most useful one, where documents can be +docked in notebooks, and can be dragged out into separate windows if desired. +Or a toplevel style where each document is a separate toplevel window. Or +finally a modal style where there is only one window and the documents must be +switched though a menu. (Note that the examples here are taken from the +gnome-hello-7-mdi example app in +gnome-libs, slightly modified) + + +To use the MDI features. You basically replace the the +gnome_app_new call with gnome_mdi_new +with the same arguments as gnome_app_new. To add menus +and tool-bar, you use gnome_mdi_set_menubar_template and +gnome_mdi_set_toolbar_template with the GnomeUIInfo as the +argument. For MDI, these aren't the actual menus, as it will add it's own +items to the menus of each child. After this you set where the menu additions +take place. You call gnome_mdi_set_child_menu_path to the +toplevel menu name after which the child's own menus are inserted. This is the +"File" menu in most cases. Then you want to specify the path (menu name) to the +menu into which you want to insert a list of the children, you do this by +calling gnome_mdi_set_child_list_path with the name of the +menu and add a '/' on the end of it to specify that you want to insert those +items into the menu, not after the menu. Example: + + +GtkWidget *mdi; +... +mdi = gnome_mdi_new("gnome-hello-7-mdi", "GNOME MDI Hello"); +... +/*main_menu and toolbar_info are the menu and tool-bar + descriptions*/ +gnome_mdi_set_menubar_template(mdi, main_menu); +gnome_mdi_set_toolbar_template(mdi, toolbar_info); + +/* and document menu and document list paths (see + gnome-app-helper menu insertion routines for details) */ +gnome_mdi_set_child_menu_path(GNOME_MDI(mdi), "File"); +gnome_mdi_set_child_list_path(GNOME_MDI(mdi), "Children/"); + +In our GnomeUIInfo structures we have defined a menu named "File" and a +menu named "Children". The children menu was not given any items, it's +just an empty menu. + + +Then you should open the main toplevel window with +gnome_mdi_open_toplevel. This will open a toplevel window +without any children. If you wish to use MDI's session management +functionality, you can define a function that creates a child given it's name. +This is done with the gnome_mdi_restore_state method, +which takes the config path as the second argument and a function pointer to a +function which takes a string and returns a new +GnomeMDIChild widget (a widget sub-classed from +GnomeMDIChild actually). Say for example you are using the +session management shown above, so you could use: + + +gnome_config_push_prefix (gnome_client_get_config_prefix (client)); +restart_ok = gnome_mdi_restore_state(GNOME_MDI(mdi), "MDI Session", + my_child_new_from_config); +gnome_config_pop_prefix (); + +The restart_ok is a boolean value telling you if the loading actually loaded +all the data correctly. + + +You should also bind the destroy signal of the mdi object +to do gtk_main_quit when the mdi is +destroyed. + + +The MDI Children + + +For complicated apps, all children should be derived from the virtual +GnomeMDIChild object. For simple apps, you don't need to +derive a new object, you can just use the +GnomeMDIGenericChild, and use the fact that you can store +arbitrary data on arbitrary GtkObjects to store your own +data on the object. + + +To use the generic child object, you create it with +gnome_mdi_generic_child_new to which you pass the name of +the child. When you get the object, you will need to set it up for your use. +First you add a function for creating new views of the same data. A view is +just a different window displaying the same file or data. This is done with a +call to gnome_mdi_generic_child_set_view_creator to which +you pass a pointer to a creator function which takes the child widget and a +data pointer as arguments and returns a data widget, which is not the actual +child widget, but actually the child of the +GnomeMDIGenericChild widget. After this you set the +template for the child's menus with +gnome_mdi_child_set_menu_template, to which you pass the +GnomeUIInfo array pointer of the child menu definitions. +Then you should call +gnome_mdi_generic_child_set_config_func to set a function +which returns a newly allocated string to save in the config file. This string +will be used to load up the child next time you start and do the +gnome_mdi_restore_state call. It should probably be a +filename of the document, or some string from which you can completely recreate +that window/document. Then you need to call +gnome_mdi_generic_child_set_label_func with a pointer to a +function that takes the GnomeMDIGenericChild as the first +argument, the old label widget pointer as the second argument, which would be +null if no label widget was yet set, and a data argument. This function can +either create a new label and destroy the old one, or just set the label if the +label exists. The label can be any widget, for example the +gnome-hello-7-mdi example code uses a horizontal box +widget into which it adds a pixmap and a gtk label. After this if you need to +add the child to the mdi yourself, if you are loading a new file for example, +you use gnome_mdi_add_child and +gnome_mdi_add_view, to add a new child and a new view to +the mdi. If you are creating a new child from the +gnome_mdi_restore_state function, you should just return +the child, the mdi will take care of adding it and adding the appropriate +views. You also probably want to set some data on the child widget at this +time to store your data with the object. + + +Here's a short example of creating a new child, for a more complete example +you should look at the gnome-hello-7-mdi included with +the gnome-libs distribution. + + +GnomeMDI *mdi; +... +GnomeMDIGenericChild *child; +... +/*create a new child named 'name'*/ +if((child = gnome_mdi_generic_child_new(name)) != NULL) { + /*creator of a view*/ + gnome_mdi_generic_child_set_view_creator + (child, my_child_create_view, NULL); + /*set a menu template for child menu*/ + gnome_mdi_child_set_menu_template + (GNOME_MDI_CHILD(child), main_child_menu); + /*set function to get config string*/ + gnome_mdi_generic_child_set_config_func + (child, my_child_get_config_string, NULL); + /*set function that sets or creates a label*/ + gnome_mdi_generic_child_set_label_func + (child, my_child_set_label, NULL); + + /* add the child to MDI */ + gnome_mdi_add_child(mdi, GNOME_MDI_CHILD(child)); + + /* and add a new view of the child */ + gnome_mdi_add_view(mdi, GNOME_MDI_CHILD(child)); +} + + + +GnomeCanvas Widget + + +While GnomeCanvas widget is inside the libgnomeui library, +it definitely deserves a separate chapter. The canvas is a very high level high +performance graphics drawing widget and on top of that it's easy to use. It +includes support for both Xlib drawn graphics, which is faster especially over +the network, and anti-aliased drawing for better looking results. + + +Creating a Canvas Widget + + +To create a gnome canvas widget, you call the +gnome_canvas_new. You need to make sure that the canvas is +created with a proper visual and colormap. For example if you wish to draw +imlib images inside it, you should do this: + + +GtkWidget *canvas; +... +gtk_widget_push_visual(gdk_imlib_get_visual()); +gtk_widget_push_colormap(gdk_imlib_get_colormap()); +canvas = gnome_canvas_new(); +gtk_widget_pop_visual(); +gtk_widget_pop_colormap(); + +After this you also want to call +gnome_canvas_set_pixels_per_unit to set the scale of the +canvas. You can then do gtk_widget_set_usize to set the +size of the widget, and gnome_canvas_set_scroll_region to +set the region in which you can scroll around in, this is given in (x1, y1, x2, +y2). Basically it's the outer limits of your drawing. So once the canvas was +created, you could do: + + +GnomeCanvas *canvas; +... +/*already created a canvas, now set it up*/ +gnome_canvas_set_pixels_per_unit(canvas,10); +gnome_canvas_set_scroll_region(canvas,0.0,0.0,50.0,50.0); + + + +Groups and Items + + +In the canvas there are items, the actual objects that are on the canvas, and +groups, which are just groupings of items. A group is actually derived from a +base GnomeCanvasItem object, this is useful to applying +functions to all the items inside the group. Such as moving or hiding the +entire group. There is also one default group, the root group. You can get +this group by calling gnome_canvas_root. + + + + +Creating Items + + +Creating items is slightly different usual. It's using the standard +GTK+ object model argument mechanism. Basically you call +gnome_canvas_item, with the parent canvas group as the first argument, +the type of object as the second argument, and then arguments given in +pairs (argument, value), terminated with a NULL. This is best illustrated by +an example: + + +GnomeCanvas *canvas; +GnomeCanvasItem *item; +... +item = gnome_canvas_item_new(gnome_canvas_root(canvas), + GNOME_TYPE_CANVAS_RECT, + "x1", 1.0, + "y1", 1.0, + "x2", 23.0, + "y2", 20.0, + "fill_color", "black", + NULL); + +Note that it's extremely important that the value be the exact type, since +the compiler won't do the cast for you. If you're doing any calculations and +aren't sure that you get the right type, just cast it. I believe most if not +all numbers for canvas items are doubles. + + +To find out the arguments that each item takes, consult the gnome documentation +or look into the libgnomeui/gnome-canvas*.h header files. +They contain a table at the top of the file just like the one that follows +(which was taken from +libgnomeui/gnome-canvas-rect-ellipse.h). + + + +For example here are arguments for rectangle (GNOME_TYPE_CANVAS_RECT) and +ellipse (GNOME_TYPE_CANVAS_ELLIPSE): + + + +Arguments for rectangle and ellipse canvas items + + + + + +Name +Type +Read/Write +Description + + + + + +x1 +double +RW + +Leftmost coordinate of rectangle or ellipse + + + + +y1 +double +RW + +Topmost coordinate of rectangle or ellipse + + + + +x2 +double +RW + +Rightmost coordinate of rectangle or ellipse + + + + +y2 +double +RW + +Bottommost coordinate of rectangle or ellipse + + + + +fill_color +string +W + +X color specification for fill color, or NULL pointer for +no color (transparent) + + + + +fill_color_gdk +GdkColor* +RW + +Allocated GdkColor for fill + + + + +outline_color +string +W + +X color specification for outline color, or NULL pointer for +no color (transparent) + + + + +outline_color_gdk +GdkColor* +RW + +Allocated GdkColor for outline + + + + +fill_stipple +GdkBitmap* +RW + +Stipple pattern for fill + + + + +outline_stipple +GdkBitmap* +RW + +Stipple pattern for outline + + + + +width_pixels +uint +RW + +Width of the outline in pixels. The outline will not be scaled +when the canvas zoom factor is changed. + + + + +width_units +double +RW + +Width of the outline in canvas units. The outline will be scaled +when the canvas zoom factor is changed. + + + + + +
+ +
+ + +Now suppose we want to change some of these properties. This is done with a +call to gnome_canvas_item_set. The first argument to this +function is the canvas item object pointer. The next arguments are the same +argument pairs as above when creating a new canvas object. For example if we +want to set the color to red on the rectangle we created above, we can do this: + + +GnomeCanvas *canvas; +GnomeCanvasItem *item; +... +gnome_canvas_item_set(item + "fill_color", "red", + NULL); + + + +Then there are item methods for other operations on items. For example the +gnome_canvas_item_move method will take the x and y as +second and third argument, and will move the item relative to it's current +position by x and y. Or the gnome_canvas_item_hide and +gnome_canvas_item_show, which hide and show the item, +respectively. To control the z order of the items, you can use the methods +gnome_canvas_item_raise_to_top and +gnome_canvas_item_lower_to_bottom to raise or lower the +item to the top or bottom of it's parent group's z order. To have finer control +over z order you can use the gnome_canvas_item_raise and +gnome_canvas_item_lower methods which take an extra +integer argument which is 1 or larger, and specifies the number of levels the +item should move in the z order. + +
+ + +Anti-aliasing canvas + + +To create a canvas which uses anti aliasing for rendering of it's items, +instead of gnome_canvas_new function, you should use the +gnome_canvas_new_aa. You should also use the GdkRgb +visual and colormap. So you would do this to create a new anti-aliased +canvas: + + +GtkWidget *canvas; +... +gtk_widget_push_visual (gdk_rgb_get_visual ()); +gtk_widget_push_colormap (gdk_rgb_get_cmap ()); +canvas = gnome_canvas_new_aa (); +gtk_widget_pop_colormap (); +gtk_widget_pop_visual (); + +After this you can use the canvas in exactly the same manner as the normal +canvas. + + +Anti-aliased canvas items can generally do more then normal canvas items. +This is because of limitations of Xlib as a graphics library. It can for +example do any kind of affine transformation on it's objects, where on +and Xlib canvas you can only do affine transformations on some objects.
+ + +Drag and Drop + + +While drag and drop belongs into GTK+ itself, I thought it would be better +to cover it after some parts of GNOME were discussed. + + +Accepting Drops + + +You have already seen one drop handler back when we were discussing the +mime types. Basically, to accept drops, you have to decide which +mime type of data you want to be able to receive. You have already seen +one for "text/uri-list". Basically your handler will only receive data +of those mime types that you specify, so you only need to know how to +decode those. + + +To specify the mime types you want to receive, you create an array of +GtkTargetEntry structures, where the first element is a string +of mime type, the second is an integer flag and the third is an integer +info. You can leave the flags at 0. The info field can be used if you +have several entries you are accepting, as the info integer will be passed +to your drop handler, so you can create a switch statement to handle +the different types of data. If you have only one type, just leave this +at 0. + + +After this you need to set up the widget for dragging. You do this by calling +the gtk_drag_dest_set function. The first argument is the +widget you want to set up, the second is a flags argument for setting up which +types of default drag behavior to use, you can leave this at +GTK_DEST_DEFAULT_ALL. The next argument is the array of +GtkTargetEntry structures, the next argument is the number +of items in that array. The last argument is the type of action that you +accept. The types can be any of the following ORed together: +GDK_ACTION_DEFAULT, GDK_ACTION_COPY, +GDK_ACTION_MOVE, GDK_ACTION_LINK, +GDK_ACTION_PRIVATE and +GDK_ACTION_ASK. The most useful are +GDK_ACTION_COPY and GDK_ACTION_MOVE. +If you are for example passing around strings or other data, you will most +likely use GDK_ACTION_COPY only. + + +Then you need to set up and bind the drop handler. The drop handler +should have the following prototype: + + +void +target_drag_data_received (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + GtkSelectionData *data, + guint info, + guint time); + +The data you have is in the structure GtkSelectionData, +in the data field. That's all you need to do for normal +DND. Here's and example: + + +static void +target_drag_data_received (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + GtkSelectionData *data, + guint info, + guint time) +{ + g_print("Got: %s\n",data->data); +} +... +static GtkTargetEntry target_table[] = { + { "text/plain", 0, 0 } +} +... +gtk_drag_dest_set (widget, + GTK_DEST_DEFAULT_ALL, + target_table, 1, + GDK_ACTION_COPY); +gtk_signal_connect (GTK_OBJECT (widget), "drag_data_received", + GTK_SIGNAL_FUNC (target_drag_data_received), + NULL); + + + +For more information about drag and drop, you should see +GTK+ documentation at www.gtk.org. + + + + +Allowing Drags + + +Now let's look at the source side of DND. You set up the +GtkTargetEntry array, in the same manner as above. Then +instead of the flags argument you substitute a mask for +the start mouse button of the drag. This could be GDK_BUTTON1_MASK | +GDK_BUTTON3_MASK for 1st and 3rd mouse buttons. Then you need to +bind the drag_data_get signal that will send the data for +the drag on it's way, and drag_data_delete if the action +is GDK_ACTION_MOVE, to delete the data since the move was +successful. Here's a simple example that will work with the above code snippet +for drop: + + +static void +source_drag_data_get (GtkWidget *widget, + GdkDragContext *context, + GtkSelectionData *selection_data, + guint info, + guint time, + gpointer data) +{ + char string[] = "Some String!"; + gtk_selection_data_set (selection_data, + selection_data->target, + 8, string, sizeof(string)); +} +... +static GtkTargetEntry target_table[] = { + { "text/plain", 0, 0 } +}; +... +gtk_drag_source_set (widget, + GDK_BUTTON1_MASK|GDK_BUTTON3_MASK, + target_table, 1, + GDK_ACTION_COPY); +gtk_signal_connect (GTK_OBJECT (widget), "drag_data_get", + GTK_SIGNAL_FUNC (source_drag_data_get), + NULL); + +The gtk_selection_data_set function copies the data into the selection +data, which is used for the transfer.
+ + +Building GNOME Apps + +Using a Simple Makefile + + +Using a simple makefile is the fastest way to compile a small GNOME +application. If you require a more sophisticated build environment, +you should use an autoconf/automake setup, which I will briefly talk about +later. + + + +The gnome-config Script + + +The command line to the C compiler for building a GNOME application can be +quite long and would be hard to figure out by hand. So gnome-libs installs a +script to simplify this. It is called gnome-config and +it takes two options, --cflags and +--libs. The --cflags option will give you the compiler +flags, needed for the compilation step, and --libs will give you the +libraries you need to pass to the linker. You also need to pass another +set of arguments to gnome-config. It needs to know what libraries you wish +to use. For our purposes, this is gnome and +gnomeui. So for example to get the compiler flags +for some program using the standard gnome and gnomeui libraries, you would +call "gnome-config --cflags gnome gnomeui". + + + + + +A Simple Example Makefile + + +Now to build a simple makefile, you can use variables +CFLAGS and LDFLAGS and the implicit +rules that at least GNU make supports (others probably do as well, but I'm +not familiar with other makes). So for example let's say you have an +application that has a main.c, main.h, extra.c and extra.h and the executable +is called gnome-foo.Now let's build a small Makefile for this app. + +CFLAGS=-g -Wall `gnome-config --cflags gnome gnomeui` +LDFLAGS=`gnome-config --libs gnome gnomeui` + +all: gnome-foo + +gnome-foo: main.o extra.o +main.o: main.c main.h extra.h +extra.o: extra.c extra.h + +clean: + rm -f core *.o gnome-foo + +This is an extremely simple makefile, but it should get you started. + + + + + + +Using automake/autoconf + + +Using automake and autoconf is really beyond the scope of this document, +but you should go read manuals online at + +http://www.gnu.org/manual/manual.html, or read the info pages if +you have them installed with gnome-help-browser. + + + +There is now an example application which can help you get started with +autoconf/automake, the internationalization setup, and other build issues, +as well as serve as a good hello world example. You can get it at +any gnome ftp site mirror (go to + +http://www.gnome.org/ftpmirrors.shtml for a list of mirrors) in the +sources/GnomeHello/ directory. + + + + + + + +Conclusion + +Getting Further Help + + +One of the best ways to get help with programming in gnome is probably +to first read the available documentation at +www.gnome.org, or the developer +web site at developer.gnome.org +. You should also subscribe to the +gnome-devel-list@gnome.org +, to subscribe, send a message with subscribe +in the subject line to +gnome-devel-list-request@gnome.org. To reduce the traffic on the +list you should first consult the documentation before asking a question. +Also look at +www.gnome.org/mailing-lists/ for a list of all GNOME relevant +mailing lists, including the GTK+ list. + + +However I still consider the header files for the libraries most helpful. +This is mostly as there isn't yet as much documentation out there as there +should be, but also the header files will always contain all of the +definitions and they will be up to date with the current version, +which a manual might not be. Most GTK+ and GNOME function names are very +descriptive and it's easy to figure out what they do. I use the header files +only. It's much easier to just look at the function prototype and figure out +what it does, then to hunt around in a reference manual. Then again you +usually have to know what header file to look at, which is not all +that hard, given that the header files are named by the objects or modules +they represent. For example the header file for gnome-config is +libgnome/gnome-config.h. The header file for GnomeCanvas +is libgnomeui/gnome-canvas.h. + + +Future GNOME Library Developments + + +This tutorial covers programming with version 1.0 of the gnome libraries. +But of course there is life after 1.0. There are many things still planned +for the libraries. But don't worry, we will try to keep as much compatibility +with the 1.0 version as humanely possible. + + +Here's a short list of things that will be or currently is worked on. + + + + + +More common dialogs, such as a native gnome file picker dialog. + + +More corba integration of the entire desktop. This is including much +more corba support from the core libraries. + + +Better canvas, including better alpha channel support and printing directly +from the canvas. + + +Rewrite of the configuration setup. + + +Much much more! ... Stuff we haven't even thought of yet! + + +
diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 0000000..3d36e7c --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,208 @@ +NULL = +## Process this file with automake to create Makefile.in. + +# The name of the module. +DOC_MODULE=gnome-vfs-2.0 + +# The top-level SGML file. +DOC_MAIN_SGML_FILE=gnome-vfs-2.0-docs.sgml + +# The directory containing the source code. Relative to $(srcdir) +DOC_SOURCE_DIR=../libgnomevfs + +# Extra options to supply to gtkdoc-scan +SCAN_OPTIONS= + +# Extra options to supply to gtkdoc-mkdb +MKDB_OPTIONS=--output-format=xml + +# Extra options to supply to gtkdoc-fixref +FIXXREF_OPTIONS= + +# Used for dependencies +HFILE_GLOB=$(top_srcdir)/libgnomevfs/*.h +CFILE_GLOB=$(top_srcdir)/libgnomevfs/*.c + +# Headers to ignore +IGNORE_HFILES= \ + gnome-vfs-async-job-map.h \ + gnome-vfs-backend.h \ + gnome-vfs-cancellable-ops.h \ + gnome-vfs-configuration.h \ + gnome-vfs-handle-private.h \ + gnome-vfs-i18n.h \ + gnome-vfs-job-queue.h \ + gnome-vfs-job-slave.h \ + gnome-vfs-job.h \ + gnome-vfs-metadata-private.h \ + gnome-vfs-mime-magic.h \ + gnome-vfs-mime-private.h \ + gnome-vfs-mime-sniff-buffer.h \ + gnome-vfs-mime-sniff-buffer-private.h \ + gnome-vfs-module-callback-private.h \ + gnome-vfs-monitor-private.h \ + gnome-vfs-private-utils.h \ + gnome-vfs-private.h \ + gnome-vfs-process.h \ + gnome-vfs-pthread.h \ + gnome-vfs-ssl-private.h \ + gnome-vfs-thread-pool.h + $(NULL) + +# Extra files to add when scanning +EXTRA_HFILES= + +# Images to copy into HTML directory +HTML_IMAGES = + +# Non-autogenerated SGML files to be included in $(DOC_MAIN_SGML_FILE) +content_files = \ + writing-modules.sgml \ + about.sgml + +extra_files = + +# CFLAGS and LDFLAGS for compiling scan program. Only needed +# if $(DOC_MODULE).types is non-empty. +GTKDOC_CFLAGS = +GTKDOC_LIBS = + +# Commands for compiling and linking +GTKDOC_CC=$(LIBTOOL) --mode=compile $(CC) +GTKDOC_LD=$(LIBTOOL) --mode=link $(CC) + +dist-hook-local: +# mkdir $(distdir)/TEXT; \ +# for f in $(srcdir)/TEXT/* ; do \ +# test -f $$f && cp -p $$f $(distdir)/TEXT; \ +# done + + +#################################### +# Everything below here is generic # +#################################### + +# ... except for TARGET_DIR, which we override + +TARGET_DIR=$(HTML_DIR)/$(DOC_MODULE) + +EXTRA_DIST = \ + $(content_files) \ + $(extra_files) \ + $(HTML_IMAGES) \ + $(DOC_MAIN_SGML_FILE) \ + $(DOC_MODULE).types \ + $(DOC_MODULE)-sections.txt \ + $(DOC_MODULE)-overrides.txt + +DOC_STAMPS=scan-build.stamp tmpl-build.stamp sgml-build.stamp html-build.stamp \ + $(srcdir)/tmpl.stamp $(srcdir)/sgml.stamp + +SCANOBJ_FILES = \ + $(DOC_MODULE).args \ + $(DOC_MODULE).hierarchy \ + $(DOC_MODULE).signals + +if ENABLE_GTK_DOC +all-local: html-build.stamp + +#### scan #### + +scan-build.stamp: $(HFILE_GLOB) + @echo '*** Scanning header files ***' + if grep -l '^..*$$' $(srcdir)/$(DOC_MODULE).types > /dev/null ; then \ + CC="$(GTKDOC_CC)" LD="$(GTKDOC_LD)" CFLAGS="$(GTKDOC_CFLAGS)" LDFLAGS="$(GTKDOC_LIBS)" gtkdoc-scangobj --module=$(DOC_MODULE) --output-dir=$(srcdir) ; \ + else \ + cd $(srcdir) ; \ + for i in $(SCANOBJ_FILES) ; do \ + test -f $$i || touch $$i ; \ + done \ + fi + cd $(srcdir) && \ + gtkdoc-scan --module=$(DOC_MODULE) --source-dir=$(DOC_SOURCE_DIR) --ignore-headers="$(IGNORE_HFILES)" $(SCAN_OPTIONS) $(EXTRA_HFILES) + touch scan-build.stamp + +$(DOC_MODULE)-decl.txt $(SCANOBJ_FILES): scan-build.stamp + @true + +#### templates #### + +tmpl-build.stamp: $(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(DOC_MODULE)-sections.txt $(DOC_MODULE)-overrides.txt + @echo '*** Rebuilding template files ***' + cd $(srcdir) && gtkdoc-mktmpl --module=$(DOC_MODULE) + touch tmpl-build.stamp + +tmpl.stamp: tmpl-build.stamp + touch $(srcdir)/tmpl.stamp + +#### sgml #### + +sgml-build.stamp: tmpl.stamp $(CFILE_GLOB) $(srcdir)/tmpl/*.sgml + @echo '*** Building SGML ***' + cd $(srcdir) && \ + gtkdoc-mkdb --module=$(DOC_MODULE) --source-dir=$(DOC_SOURCE_DIR) $(MKDB_OPTIONS) + touch sgml-build.stamp + +sgml.stamp: sgml-build.stamp + touch $(srcdir)/sgml.stamp + +#### html #### + +html-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files) + @echo '*** Building HTML ***' + test -d $(srcdir)/html || mkdir $(srcdir)/html + cd $(srcdir)/html && gtkdoc-mkhtml $(DOC_MODULE) ../$(DOC_MAIN_SGML_FILE) + test "x$(HTML_IMAGES)" = "x" || ( cd $(srcdir) && cp $(HTML_IMAGES) html ) + @echo '-- Fixing Crossreferences' + cd $(srcdir) && gtkdoc-fixxref --module-dir=html --html-dir=$(HTML_DIR) $(FIXXREF_OPTIONS) + touch html-build.stamp +endif + +############## + +clean-local: + rm -f *~ *.bak $(SCANOBJ_FILES) *-unused.txt $(DOC_STAMPS) + +maintainer-clean-local: clean + cd $(srcdir) && rm -rf xml html $(DOC_MODULE)-decl-list.txt $(DOC_MODULE)-decl.txt + +install-data-local: + $(mkinstalldirs) $(DESTDIR)$(TARGET_DIR) + (installfiles=`echo $(srcdir)/html/*`; \ + if test "$$installfiles" = '$(srcdir)/html/*'; \ + then echo '-- Nothing to install' ; \ + else \ + for i in $$installfiles; do \ + echo '-- Installing '$$i ; \ + $(INSTALL_DATA) $$i $(DESTDIR)$(TARGET_DIR); \ + done; \ + echo '-- Installing $(srcdir)/html/index.sgml' ; \ + $(INSTALL_DATA) $(srcdir)/html/index.sgml $(DESTDIR)$(TARGET_DIR); \ + fi) + +# +# Require gtk-doc when making dist +# +if ENABLE_GTK_DOC +dist-check-gtkdoc: +else +dist-check-gtkdoc: + @echo "*** gtk-doc must be installed and enabled in order to make dist" + @false +endif + +dist-hook: dist-check-gtkdoc dist-hook-local + test -d $(distdir)/tmpl || mkdir $(distdir)/tmpl + test -d $(distdir)/xml || mkdir $(distdir)/xml + test -d $(distdir)/html || mkdir $(distdir)/html + -cp $(srcdir)/tmpl/*.sgml $(distdir)/tmpl + -cp $(srcdir)/xml/*.xml $(distdir)/xml + -cp $(srcdir)/html/index.sgml $(distdir)/html + -cp $(srcdir)/html/*.html $(srcdir)/html/*.css $(distdir)/html + + images=$(HTML_IMAGES) ; \ + for i in $$images ; do \ + cp $(srcdir)/$$i $(distdir)/html ; \ + done + +.PHONY : dist-hook-local diff --git a/doc/Makefile.in b/doc/Makefile.in new file mode 100644 index 0000000..7797b03 --- /dev/null +++ b/doc/Makefile.in @@ -0,0 +1,488 @@ +# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ +AS = @AS@ +AWK = @AWK@ +BONOBO_ACTIVATION_REQUIRED = @BONOBO_ACTIVATION_REQUIRED@ +BONOBO_IDLDIR = @BONOBO_IDLDIR@ +BONOBO_REQUIRED = @BONOBO_REQUIRED@ +BZ2_LIBS = @BZ2_LIBS@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +DATADIRNAME = @DATADIRNAME@ +DB2HTML = @DB2HTML@ +DLLTOOL = @DLLTOOL@ +ECHO = @ECHO@ +ENABLE_PROFILER = @ENABLE_PROFILER@ +EXEEXT = @EXEEXT@ +FAM_LIBS = @FAM_LIBS@ +GCONFTOOL = @GCONFTOOL@ +GCONF_REQUIRED = @GCONF_REQUIRED@ +GCONF_SCHEMA_CONFIG_SOURCE = @GCONF_SCHEMA_CONFIG_SOURCE@ +GCONF_SCHEMA_FILE_DIR = @GCONF_SCHEMA_FILE_DIR@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GLIB_REQUIRED = @GLIB_REQUIRED@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GNOME_ACLOCAL_DIR = @GNOME_ACLOCAL_DIR@ +GNOME_ACLOCAL_FLAGS = @GNOME_ACLOCAL_FLAGS@ +GNOME_VFS_DIR = @GNOME_VFS_DIR@ +GTKDOC = @GTKDOC@ +HAVE_GTK_DOC = @HAVE_GTK_DOC@ +HTML_DIR = @HTML_DIR@ +INSTOBJEXT = @INSTOBJEXT@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_CAVES_RULE = @INTLTOOL_CAVES_RULE@ +INTLTOOL_DESKTOP_RULE = @INTLTOOL_DESKTOP_RULE@ +INTLTOOL_DIRECTORY_RULE = @INTLTOOL_DIRECTORY_RULE@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_KEYS_RULE = @INTLTOOL_KEYS_RULE@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_OAF_RULE = @INTLTOOL_OAF_RULE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_PONG_RULE = @INTLTOOL_PONG_RULE@ +INTLTOOL_PROP_RULE = @INTLTOOL_PROP_RULE@ +INTLTOOL_SCHEMAS_RULE = @INTLTOOL_SCHEMAS_RULE@ +INTLTOOL_SERVER_RULE = @INTLTOOL_SERVER_RULE@ +INTLTOOL_SHEET_RULE = @INTLTOOL_SHEET_RULE@ +INTLTOOL_SOUNDLIST_RULE = @INTLTOOL_SOUNDLIST_RULE@ +INTLTOOL_THEME_RULE = @INTLTOOL_THEME_RULE@ +INTLTOOL_UI_RULE = @INTLTOOL_UI_RULE@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTLTOOL_XML_RULE = @INTLTOOL_XML_RULE@ +LDFLAGS = @LDFLAGS@ +LIBEFS_CFLAGS = @LIBEFS_CFLAGS@ +LIBEFS_LIBS = @LIBEFS_LIBS@ +LIBGNOMEVFS_AGE = @LIBGNOMEVFS_AGE@ +LIBGNOMEVFS_CFLAGS = @LIBGNOMEVFS_CFLAGS@ +LIBGNOMEVFS_CURRENT = @LIBGNOMEVFS_CURRENT@ +LIBGNOMEVFS_LIBS = @LIBGNOMEVFS_LIBS@ +LIBGNOMEVFS_REVISION = @LIBGNOMEVFS_REVISION@ +LIBGNUTLS_CFLAGS = @LIBGNUTLS_CFLAGS@ +LIBGNUTLS_CONFIG = @LIBGNUTLS_CONFIG@ +LIBGNUTLS_LIBS = @LIBGNUTLS_LIBS@ +LIBIDL_REQUIRED = @LIBIDL_REQUIRED@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MODULES_CFLAGS = @MODULES_CFLAGS@ +MODULES_FILE_CFLAGS = @MODULES_FILE_CFLAGS@ +MODULES_FILE_LIBS = @MODULES_FILE_LIBS@ +MODULES_GCONF_CFLAGS = @MODULES_GCONF_CFLAGS@ +MODULES_GCONF_LIBS = @MODULES_GCONF_LIBS@ +MODULES_LIBS = @MODULES_LIBS@ +MODULES_XML_CFLAGS = @MODULES_XML_CFLAGS@ +MODULES_XML_GCONF_CFLAGS = @MODULES_XML_GCONF_CFLAGS@ +MODULES_XML_GCONF_LIBS = @MODULES_XML_GCONF_LIBS@ +MODULES_XML_LIBS = @MODULES_XML_LIBS@ +MONIKERS_CFLAGS = @MONIKERS_CFLAGS@ +MONIKERS_LIBS = @MONIKERS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ORBIT_IDL = @ORBIT_IDL@ +ORBIT_REQUIRED = @ORBIT_REQUIRED@ +PACKAGE = @PACKAGE@ +PKG_CONFIG = @PKG_CONFIG@ +POFILES = @POFILES@ +POPT_LIBS = @POPT_LIBS@ +POSUB = @POSUB@ +PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ +PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ +RANLIB = @RANLIB@ +STRIP = @STRIP@ +TEST_CFLAGS = @TEST_CFLAGS@ +TEST_LIBS = @TEST_LIBS@ +TOP_BUILDDIR = @TOP_BUILDDIR@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +VFS_CFLAGS = @VFS_CFLAGS@ +VFS_INCLUDEDIR = @VFS_INCLUDEDIR@ +VFS_LIBDIR = @VFS_LIBDIR@ +VFS_LIBS = @VFS_LIBS@ +VFS_OFFSET = @VFS_OFFSET@ +VFS_OFFSET_IS = @VFS_OFFSET_IS@ +VFS_OFFSET_PRINTF = @VFS_OFFSET_PRINTF@ +VFS_SIZE = @VFS_SIZE@ +VFS_SIZE_IS = @VFS_SIZE_IS@ +VFS_SIZE_PRINTF = @VFS_SIZE_PRINTF@ +WARN_CFLAGS = @WARN_CFLAGS@ +XML_REQUIRED = @XML_REQUIRED@ +cxxflags_set = @cxxflags_set@ + +NULL = + +# The name of the module. +DOC_MODULE = gnome-vfs-2.0 + +# The top-level SGML file. +DOC_MAIN_SGML_FILE = gnome-vfs-2.0-docs.sgml + +# The directory containing the source code. Relative to $(srcdir) +DOC_SOURCE_DIR = ../libgnomevfs + +# Extra options to supply to gtkdoc-scan +SCAN_OPTIONS = + +# Extra options to supply to gtkdoc-mkdb +MKDB_OPTIONS = --output-format=xml + +# Extra options to supply to gtkdoc-fixref +FIXXREF_OPTIONS = + +# Used for dependencies +HFILE_GLOB = $(top_srcdir)/libgnomevfs/*.h +CFILE_GLOB = $(top_srcdir)/libgnomevfs/*.c + +# Headers to ignore +IGNORE_HFILES = \ + gnome-vfs-async-job-map.h \ + gnome-vfs-backend.h \ + gnome-vfs-cancellable-ops.h \ + gnome-vfs-configuration.h \ + gnome-vfs-handle-private.h \ + gnome-vfs-i18n.h \ + gnome-vfs-job-queue.h \ + gnome-vfs-job-slave.h \ + gnome-vfs-job.h \ + gnome-vfs-metadata-private.h \ + gnome-vfs-mime-magic.h \ + gnome-vfs-mime-private.h \ + gnome-vfs-mime-sniff-buffer.h \ + gnome-vfs-mime-sniff-buffer-private.h \ + gnome-vfs-module-callback-private.h \ + gnome-vfs-monitor-private.h \ + gnome-vfs-private-utils.h \ + gnome-vfs-private.h \ + gnome-vfs-process.h \ + gnome-vfs-pthread.h \ + gnome-vfs-ssl-private.h \ + gnome-vfs-thread-pool.h + + +# Extra files to add when scanning +EXTRA_HFILES = + +# Images to copy into HTML directory +HTML_IMAGES = + +# Non-autogenerated SGML files to be included in $(DOC_MAIN_SGML_FILE) +content_files = \ + writing-modules.sgml \ + about.sgml + + +extra_files = + +# CFLAGS and LDFLAGS for compiling scan program. Only needed +# if $(DOC_MODULE).types is non-empty. +GTKDOC_CFLAGS = +GTKDOC_LIBS = + +# Commands for compiling and linking +GTKDOC_CC = $(LIBTOOL) --mode=compile $(CC) +GTKDOC_LD = $(LIBTOOL) --mode=link $(CC) +# mkdir $(distdir)/TEXT; \ +# for f in $(srcdir)/TEXT/* ; do \ +# test -f $$f && cp -p $$f $(distdir)/TEXT; \ +# done + +#################################### +# Everything below here is generic # +#################################### + +# ... except for TARGET_DIR, which we override + +TARGET_DIR = $(HTML_DIR)/$(DOC_MODULE) + +EXTRA_DIST = \ + $(content_files) \ + $(extra_files) \ + $(HTML_IMAGES) \ + $(DOC_MAIN_SGML_FILE) \ + $(DOC_MODULE).types \ + $(DOC_MODULE)-sections.txt \ + $(DOC_MODULE)-overrides.txt + + +DOC_STAMPS = scan-build.stamp tmpl-build.stamp sgml-build.stamp html-build.stamp \ + $(srcdir)/tmpl.stamp $(srcdir)/sgml.stamp + + +SCANOBJ_FILES = \ + $(DOC_MODULE).args \ + $(DOC_MODULE).hierarchy \ + $(DOC_MODULE).signals + +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../config.h +CONFIG_CLEAN_FILES = +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +all: all-redirect +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps doc/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + +tags: TAGS +TAGS: + + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = doc + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: +install-exec: install-exec-am + +install-data-am: install-data-local +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: +uninstall: uninstall-am +all-am: Makefile all-local +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-generic mostlyclean-am clean-local + +clean: clean-am + +distclean-am: distclean-generic clean-am + -rm -f libtool + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-generic distclean-am \ + maintainer-clean-local + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: tags distdir info-am info dvi-am dvi check check-am \ +installcheck-am installcheck install-exec-am install-exec \ +install-data-local install-data-am install-data install-am install \ +uninstall-am uninstall all-local all-redirect all-am all installdirs \ +mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + $(NULL) + +dist-hook-local: + +@ENABLE_GTK_DOC_TRUE@all-local: html-build.stamp + +#### scan #### + +@ENABLE_GTK_DOC_TRUE@scan-build.stamp: $(HFILE_GLOB) +@ENABLE_GTK_DOC_TRUE@ @echo '*** Scanning header files ***' +@ENABLE_GTK_DOC_TRUE@ if grep -l '^..*$$' $(srcdir)/$(DOC_MODULE).types > /dev/null ; then \ +@ENABLE_GTK_DOC_TRUE@ CC="$(GTKDOC_CC)" LD="$(GTKDOC_LD)" CFLAGS="$(GTKDOC_CFLAGS)" LDFLAGS="$(GTKDOC_LIBS)" gtkdoc-scangobj --module=$(DOC_MODULE) --output-dir=$(srcdir) ; \ +@ENABLE_GTK_DOC_TRUE@ else \ +@ENABLE_GTK_DOC_TRUE@ cd $(srcdir) ; \ +@ENABLE_GTK_DOC_TRUE@ for i in $(SCANOBJ_FILES) ; do \ +@ENABLE_GTK_DOC_TRUE@ test -f $$i || touch $$i ; \ +@ENABLE_GTK_DOC_TRUE@ done \ +@ENABLE_GTK_DOC_TRUE@ fi +@ENABLE_GTK_DOC_TRUE@ cd $(srcdir) && \ +@ENABLE_GTK_DOC_TRUE@ gtkdoc-scan --module=$(DOC_MODULE) --source-dir=$(DOC_SOURCE_DIR) --ignore-headers="$(IGNORE_HFILES)" $(SCAN_OPTIONS) $(EXTRA_HFILES) +@ENABLE_GTK_DOC_TRUE@ touch scan-build.stamp + +@ENABLE_GTK_DOC_TRUE@$(DOC_MODULE)-decl.txt $(SCANOBJ_FILES): scan-build.stamp +@ENABLE_GTK_DOC_TRUE@ @true + +#### templates #### + +@ENABLE_GTK_DOC_TRUE@tmpl-build.stamp: $(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(DOC_MODULE)-sections.txt $(DOC_MODULE)-overrides.txt +@ENABLE_GTK_DOC_TRUE@ @echo '*** Rebuilding template files ***' +@ENABLE_GTK_DOC_TRUE@ cd $(srcdir) && gtkdoc-mktmpl --module=$(DOC_MODULE) +@ENABLE_GTK_DOC_TRUE@ touch tmpl-build.stamp + +@ENABLE_GTK_DOC_TRUE@tmpl.stamp: tmpl-build.stamp +@ENABLE_GTK_DOC_TRUE@ touch $(srcdir)/tmpl.stamp + +#### sgml #### + +@ENABLE_GTK_DOC_TRUE@sgml-build.stamp: tmpl.stamp $(CFILE_GLOB) $(srcdir)/tmpl/*.sgml +@ENABLE_GTK_DOC_TRUE@ @echo '*** Building SGML ***' +@ENABLE_GTK_DOC_TRUE@ cd $(srcdir) && \ +@ENABLE_GTK_DOC_TRUE@ gtkdoc-mkdb --module=$(DOC_MODULE) --source-dir=$(DOC_SOURCE_DIR) $(MKDB_OPTIONS) +@ENABLE_GTK_DOC_TRUE@ touch sgml-build.stamp + +@ENABLE_GTK_DOC_TRUE@sgml.stamp: sgml-build.stamp +@ENABLE_GTK_DOC_TRUE@ touch $(srcdir)/sgml.stamp + +#### html #### + +@ENABLE_GTK_DOC_TRUE@html-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files) +@ENABLE_GTK_DOC_TRUE@ @echo '*** Building HTML ***' +@ENABLE_GTK_DOC_TRUE@ test -d $(srcdir)/html || mkdir $(srcdir)/html +@ENABLE_GTK_DOC_TRUE@ cd $(srcdir)/html && gtkdoc-mkhtml $(DOC_MODULE) ../$(DOC_MAIN_SGML_FILE) +@ENABLE_GTK_DOC_TRUE@ test "x$(HTML_IMAGES)" = "x" || ( cd $(srcdir) && cp $(HTML_IMAGES) html ) +@ENABLE_GTK_DOC_TRUE@ @echo '-- Fixing Crossreferences' +@ENABLE_GTK_DOC_TRUE@ cd $(srcdir) && gtkdoc-fixxref --module-dir=html --html-dir=$(HTML_DIR) $(FIXXREF_OPTIONS) +@ENABLE_GTK_DOC_TRUE@ touch html-build.stamp + +############## + +clean-local: + rm -f *~ *.bak $(SCANOBJ_FILES) *-unused.txt $(DOC_STAMPS) + +maintainer-clean-local: clean + cd $(srcdir) && rm -rf xml html $(DOC_MODULE)-decl-list.txt $(DOC_MODULE)-decl.txt + +install-data-local: + $(mkinstalldirs) $(DESTDIR)$(TARGET_DIR) + (installfiles=`echo $(srcdir)/html/*`; \ + if test "$$installfiles" = '$(srcdir)/html/*'; \ + then echo '-- Nothing to install' ; \ + else \ + for i in $$installfiles; do \ + echo '-- Installing '$$i ; \ + $(INSTALL_DATA) $$i $(DESTDIR)$(TARGET_DIR); \ + done; \ + echo '-- Installing $(srcdir)/html/index.sgml' ; \ + $(INSTALL_DATA) $(srcdir)/html/index.sgml $(DESTDIR)$(TARGET_DIR); \ + fi) + +# +# Require gtk-doc when making dist +# +@ENABLE_GTK_DOC_TRUE@dist-check-gtkdoc: +@ENABLE_GTK_DOC_FALSE@dist-check-gtkdoc: +@ENABLE_GTK_DOC_FALSE@ @echo "*** gtk-doc must be installed and enabled in order to make dist" +@ENABLE_GTK_DOC_FALSE@ @false + +dist-hook: dist-check-gtkdoc dist-hook-local + test -d $(distdir)/tmpl || mkdir $(distdir)/tmpl + test -d $(distdir)/xml || mkdir $(distdir)/xml + test -d $(distdir)/html || mkdir $(distdir)/html + -cp $(srcdir)/tmpl/*.sgml $(distdir)/tmpl + -cp $(srcdir)/xml/*.xml $(distdir)/xml + -cp $(srcdir)/html/index.sgml $(distdir)/html + -cp $(srcdir)/html/*.html $(srcdir)/html/*.css $(distdir)/html + + images=$(HTML_IMAGES) ; \ + for i in $$images ; do \ + cp $(srcdir)/$$i $(distdir)/html ; \ + done + +.PHONY : dist-hook-local + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/doc/about.sgml b/doc/about.sgml new file mode 100644 index 0000000..4f5aa57 --- /dev/null +++ b/doc/about.sgml @@ -0,0 +1,182 @@ + + Introduction to GnomeVFS + + + Uses and Purpose + + GnomeVFS is a filesystem abstraction library allowing applications + plugable transparent access to a variety of "real" filesystems, from + WebDAV to digital cameras, to the local filesystem. It also contains + a number of other convenient file utilities such as a comphrehensive + MIME database / Application registry, and a copy engine. Use of GnomeVFS + ensures that an application or component will be usable by Nautilus + or other GnomeVFS applications for handling the display of data from + various URIs, as well + + + User's Perspective + + From a user's perspective GnomeVFS enabled applications provide consistent + access to their data, whether it be stored on remote servers or on their + local harddisk, or even a peripheral device such as a Rio or a digital + camera. Rather than having to work around the distinction between storage + you can work off of and storage you can only "download" from or "upload" to, + GnomeVFS allows users to store their documents and data wherever it is + most convenient. + + + + Developer's Perspective + + Besides providing transparent access to data methods that you might + otherwise have to implement, GnomeVFS provides a number of convenience + libraries for processing URIs, detecting the MIME type of files, and + even figuring out which applications or components to launch to view + a file or what icon to use. Writing a GnomeVFS module may also be an + appropriate solution to some data access problems as it allows the + developer to implement a relatively small number of functions to gain + general filesystem semantics (and of course, writing a GnomeVFS module + benefits other applications too!). + + + + + + A Gentle Programming Primer + + Using GnomeVFS in an existing application, or writing a new application + with it, is actually very simple since GnomeVFS tries to mimic POSIX + file access syntax and semantics. That means that most "standard unix calls" + have a GnomeVFS equivalent that operates in a fairly similar manner. There are + a few differences to keep in mind. + + + + + + The most obvious is probably that all I/O operations return a GnomeVFSResult + indicating the success or failure of the operation. More on this later. + + + + + The types may be slightly different (but still parallel), for example rather than using an + int for a file-descriptor, GnomeVFS uses GnomeVFSHandle, a handle + to a particular URI. + + + + + Most operations come in Handle (think file descriptor) and URI form. The URI form may be + more convenient if you do not want to track handles, etc, but just be aware that both are + at your disposal and may be used interchangably. For example gnome_vfs_open + and gnome_vfs_open_uri. + + + + + + By way of example, consider the basic read command: + + ssize_t read (int fd, void *buf, size_t count); + + + + The GnomeVFS equivalent is very similar, but you will notice slightly different data types. The + consistent returning of a GnomeVFSResult also necessitated moving the return value of read into + a pass-back-value pointer bytes_read: + + GnomeVFSResult gnome_vfs_read (GnomeVFSHandle *handle, + gpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_read); + + + + So gnome_vfs_read takes a GnomeVFSHandle, which functions + like a file descriptor, and attempts to read bytes bytes out of + handle into buffer. The number of bytes succesfully + read into buffer is returned in the pointer bytes_read. + The return value of the function, a GnomeVFSResult indicates the success of the + operation or any errors that might have occurred (for example, permission denied). + GnomeVFSResult is just an enumeration. + + + Simple Sample Program + + Now lets write a simple program to copy a fixed number of bytes from one file and append + it to another file. + + + + +#include + +#define BYTES_TO_PROCESS 256 + +int print_error (GnomeVFSResult result, const char *uri_string); + +int +main (int argc, char **argv) +{ + GnomeVFSHandle *read_handle, *write_handle; + const char *input_uri_string = argv[1]; + const char *output_uri_string = argv[2]; + GnomeVFSFileSize bytes_read, bytes_written; + guint buffer[BYTES_TO_PROCESS]; + GnomeVFSResult result; + + /* remember to initialize GnomeVFS! */ + if (!gnome_vfs_init ()) { + printf ("Could not initialize GnomeVFS\n"); + return 1; + } + + /* open the input file for read access */ + result = gnome_vfs_open (&read_handle, input_uri_string, GNOME_VFS_OPEN_READ); + /* if the operation was not successful, print the error and abort */ + if (result != GNOME_VFS_OK) return print_error (result, input_uri_string); + + /* we use create instead of open, because open will not create the file if it does + not already exist. The last argument is the permissions to use if the file is created, + the second to last tells GnomeVFS that its ok if the file already exists, and just open it */ + result = gnome_vfs_create (&write_handle, output_uri_string, GNOME_VFS_OPEN_WRITE, FALSE, 0x777); + if (result != GNOME_VFS_OK) return print_error (result, output_uri_string); + + /* read data from the input uri */ + result = gnome_vfs_read (read_handle, buffer, BYTES_TO_PROCESS, &bytes_read); + if (result != GNOME_VFS_OK) return print_error (result, input_uri_string); + + /* seek to the end of the output uri so we will append rather than overwrite */ + /* therefore, we seek 0 bytes relative to the end of the file */ + result = gnome_vfs_seek (write_handle, GNOME_VFS_SEEK_END, 0); + + /* now write the data we read out to the output uri */ + result = gnome_vfs_write (write_handle, buffer, bytes_read, &bytes_written); + if (result != GNOME_VFS_OK) return print_error (result, output_uri_string); + + return 0; +} + +int +print_error (GnomeVFSResult result, const char *uri_string) +{ + const char *error_string; + /* get the string corresponding to this GnomeVFSResult value */ + error_string = gnome_vfs_result_to_string (result); + printf ("Error %s occured opening location %s\n", error_string, uri_string); + return 1; +} + +]]> + + + + + Conversion of a Sample Code Block + + + + + diff --git a/doc/gnome-vfs-2.0-docs.sgml b/doc/gnome-vfs-2.0-docs.sgml new file mode 100644 index 0000000..1f08d47 --- /dev/null +++ b/doc/gnome-vfs-2.0-docs.sgml @@ -0,0 +1,180 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]> + + + + GnomeVFS - Filesystem Abstraction library + + + Seth + Nickell + +
+ snickell@Stanford.edu +
+
+
+
+ + + + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.1 + or any later version published by the Free Software Foundation; + A copy of the license is included in the section entitled "GNU + Free Documentation License". + + + + + 2001 + The Free Software Foundation + +
+ + &gnome-vfs-about; + &gnome-vfs-init; + + + Directory Handling + + Functions for creating, removing, and listing directories. + + + &gnome-vfs-directory-basic-ops; + &gnome-vfs-directory-list-ops; + &gnome-vfs-directory-find-ops; + + + + File Handling + + GnomeVFS file operations are, for the most part, patterned after + their POSIX equivalents, with the systematic difference that they + accept URIs rather than paths on the local filesystem. This makes + them easy to learn as if you are already familiar with basic commands + such as open(), seek(), write(), etc you will feel right at home + with GnomeVFS after learning a little about URIs. + + + + GnomeVFS also provides asynchronous versions of these basic operations + for allowing application developers to provide non-blocking file I/O + without the use of threads. + + + &gnome-vfs-file-basic-ops; + &gnome-vfs-file-rw-ops; + &gnome-vfs-file-info-ops; + &gnome-vfs-file-trunc-ops; + &gnome-vfs-file-advanced-ops; + &gnome-vfs-file-async-ops; + + + + + Advanced Operations + &gnome-vfs-monitor; + &gnome-vfs-cancellation; + &gnome-vfs-xfer; + + + + Data Types + &gnome-vfs-file-info; + &gnome-vfs-file-size; + &gnome-vfs-result; + &gnome-vfs-uri; + + + + MIME Registry + + MIME types provide a standardized for denoting the content of files or + file streams. GnomeVFS exposes simple methods for both identifying the + MIME type of a particular file, and deciding how to act on it. The MIME + and application registries provide a mapping between files of a particular + mime type and applications / bonobo components which can view or edit + those files. Applications such as Nautilus use this database to generate + appropriate actions when files are activated. + + + &gnome-vfs-application-registry; + &gnome-vfs-mime-database; + &gnome-vfs-mime-monitor; + + + + Filesystem Modules + + Modules are the mechanism by which GnomeVFS accesses different filesystems, + from http, to the local disk, to smb. Module authors must implement a simple + set of filesystem operations and can provide varying degrees of service (read-only, + read-write, seeking, etc). Modules are dynamically loaded based upon the URI + scheme passed into the high-level GnomeVFS APIs. + + + &gnome-vfs-writing-modules; + &gnome-vfs-mime; + &gnome-vfs-method; + &gnome-vfs-module; + &gnome-vfs-module-shared; + &gnome-vfs-module-callback-module-api; + &gnome-vfs-ssl; + &gnome-vfs-context; + &gnome-vfs-socket; + &gnome-vfs-socket-buffer; + &gnome-vfs-transform; + &gnome-vfs-parse-ls; + + + + Other Stuff + + &gnome-vfs-utils; + &gnome-vfs-standard-callbacks; + &gnome-vfs-inet-connection; + &gnome-vfs-module-callback; + +
diff --git a/doc/gnome-vfs-2.0-overrides.txt b/doc/gnome-vfs-2.0-overrides.txt new file mode 100644 index 0000000..e69de29 diff --git a/doc/gnome-vfs-2.0-sections.txt b/doc/gnome-vfs-2.0-sections.txt new file mode 100644 index 0000000..2117352 --- /dev/null +++ b/doc/gnome-vfs-2.0-sections.txt @@ -0,0 +1,553 @@ +
+ + +gnome-vfs-mime-monitor +GNOME_VFS_MIME_MONITOR_TYPE +GnomeVFSMIMEMonitorPrivate +gnome_vfs_mime_monitor_get + +GNOME_VFS_MIME_MONITOR +GNOME_VFS_IS_MIME_MONITOR +gnome_vfs_mime_monitor_get_type +GNOME_VFS_MIME_MONITOR_CLASS +GNOME_VFS_IS_MIME_MONITOR_CLASS +
+ +
+gnome-vfs-file-size +GNOME_VFS_OFFSET_IS_LONG_LONG +GNOME_VFS_SIZE_FORMAT_STR +GNOME_VFS_OFFSET_FORMAT_STR +GnomeVFSFileSize +GnomeVFSFileOffset + +GNOME_VFS_SIZE_IS_UNSIGNED_LONG_LONG +
+ +
+gnome-vfs-utils +gnome_vfs_format_file_size_for_display +gnome_vfs_escape_string +gnome_vfs_escape_path_string +gnome_vfs_escape_host_and_path_string +gnome_vfs_escape_slashes +gnome_vfs_escape_set +gnome_vfs_unescape_string +gnome_vfs_make_uri_canonical +gnome_vfs_make_path_name_canonical +gnome_vfs_expand_initial_tilde +gnome_vfs_unescape_string_for_display +gnome_vfs_get_local_path_from_uri +gnome_vfs_get_uri_from_local_path +gnome_vfs_is_executable_command_string +gnome_vfs_list_deep_free +gnome_vfs_get_volume_free_space +gnome_vfs_icon_path_from_filename +gnome_vfs_is_primary_thread +gnome_vfs_get_uri_scheme +gnome_vfs_uris_match +GNOME_VFS_ASSERT_PRIMARY_THREAD +GNOME_VFS_ASSERT_SECONDARY_THREAD +gnome_vfs_read_entire_file +
+ +
+gnome-vfs-application-registry +GNOME_VFS_APPLICATION_REGISTRY_COMMAND +GNOME_VFS_APPLICATION_REGISTRY_NAME +GNOME_VFS_APPLICATION_REGISTRY_CAN_OPEN_MULTIPLE_FILES +GNOME_VFS_APPLICATION_REGISTRY_REQUIRES_TERMINAL +gnome_vfs_application_registry_exists +gnome_vfs_application_registry_get_keys +gnome_vfs_application_registry_peek_value +gnome_vfs_application_registry_get_bool_value +gnome_vfs_application_registry_remove_application +gnome_vfs_application_registry_set_value +gnome_vfs_application_registry_set_bool_value +gnome_vfs_application_registry_unset_key +gnome_vfs_application_registry_get_applications +gnome_vfs_application_registry_get_mime_types +gnome_vfs_application_registry_supports_mime_type +gnome_vfs_application_registry_supports_uri_scheme +gnome_vfs_application_is_user_owned_application +gnome_vfs_application_registry_clear_mime_types +gnome_vfs_application_registry_add_mime_type +gnome_vfs_application_registry_remove_mime_type +gnome_vfs_application_registry_sync +gnome_vfs_application_registry_shutdown +gnome_vfs_application_registry_reload +gnome_vfs_application_registry_get_mime_application +gnome_vfs_application_registry_save_mime_application +
+ +
+gnome-vfs-init +gnome_vfs_init +gnome_vfs_initialized +gnome_vfs_shutdown +gnome_vfs_loadinit +gnome_vfs_preinit +gnome_vfs_postinit +
+ +
+gnome-vfs-directory-basic-ops +gnome_vfs_make_directory +gnome_vfs_make_directory_for_uri +gnome_vfs_remove_directory +gnome_vfs_remove_directory_from_uri +
+ +
+gnome-vfs-directory-list-ops +GnomeVFSDirectoryVisitOptions +GnomeVFSDirectoryVisitFunc +gnome_vfs_directory_open +gnome_vfs_directory_open_from_uri +gnome_vfs_directory_read_next +gnome_vfs_directory_close +gnome_vfs_directory_visit +gnome_vfs_directory_visit_uri +gnome_vfs_directory_visit_files +gnome_vfs_directory_visit_files_at_uri +gnome_vfs_directory_list_load +
+ +
+gnome-vfs-directory-find-ops +GnomeVFSFindDirectoryKind +gnome_vfs_find_directory +
+ + +
+gnome-vfs-transform +GnomeVFSTransformInitFunc +GnomeVFSTransformFunc +
+ +
+gnome-vfs-async-ops +GNOME_VFS_PRIORITY_MIN +GNOME_VFS_PRIORITY_MAX +GNOME_VFS_PRIORITY_DEFAULT +GnomeVFSAsyncCallback +GnomeVFSAsyncOpenCallback +GnomeVFSAsyncCreateCallback +GnomeVFSAsyncCreateAsChannelCallback +GnomeVFSAsyncCloseCallback +GnomeVFSAsyncReadCallback +GnomeVFSAsyncWriteCallback +GnomeVFSFindDirectoryResult +gnome_vfs_async_set_job_limit +gnome_vfs_async_get_job_limit +gnome_vfs_async_cancel +gnome_vfs_async_open +gnome_vfs_async_open_uri +gnome_vfs_async_open_as_channel +gnome_vfs_async_open_uri_as_channel +gnome_vfs_async_create +gnome_vfs_async_create_uri +gnome_vfs_async_create_symbolic_link +gnome_vfs_async_create_as_channel +gnome_vfs_async_create_uri_as_channel +gnome_vfs_async_close +gnome_vfs_async_read +gnome_vfs_async_write +gnome_vfs_async_get_file_info +gnome_vfs_async_set_file_info +gnome_vfs_async_load_directory +gnome_vfs_async_load_directory_uri +gnome_vfs_async_xfer +gnome_vfs_async_find_directory +gnome_vfs_async_file_control +
+ +
+gnome-vfs-file-basic-ops +GnomeVFSOpenMode +gnome_vfs_create +gnome_vfs_create_uri +gnome_vfs_open +gnome_vfs_open_uri +gnome_vfs_close +gnome_vfs_unlink +gnome_vfs_unlink_from_uri +gnome_vfs_move_uri +gnome_vfs_move +gnome_vfs_check_same_fs_uris +gnome_vfs_check_same_fs +gnome_vfs_uri_exists +gnome_vfs_create_symbolic_link +
+ +
+gnome-vfs-file-rw-ops +GnomeVFSSeekPosition +gnome_vfs_read +gnome_vfs_write +gnome_vfs_seek +gnome_vfs_tell +
+ +
+gnome-vfs-file-trunc-ops +gnome_vfs_truncate +gnome_vfs_truncate_uri +gnome_vfs_truncate_handle +
+ +
+gnome-vfs-file-info-ops +gnome_vfs_get_file_info +gnome_vfs_get_file_info_uri +gnome_vfs_get_file_info_from_handle +gnome_vfs_set_file_info_uri +gnome_vfs_set_file_info +
+ +
+gnome-vfs-file-advanced-ops +gnome_vfs_file_control +
+ +
+gnome-vfs-ops +GnomeVFSMethodHandle +
+ +
+gnome-vfs-ssl +gnome_vfs_ssl_enabled +gnome_vfs_ssl_create +gnome_vfs_ssl_create_from_fd +gnome_vfs_ssl_read +gnome_vfs_ssl_write +gnome_vfs_ssl_destroy +gnome_vfs_ssl_to_socket +
+ +
+gnome-vfs-uri +GnomeVFSToplevelURI +GnomeVFSURIHideOptions +GNOME_VFS_URI_MAGIC_CHR +GNOME_VFS_URI_MAGIC_STR +GNOME_VFS_URI_PATH_CHR +GNOME_VFS_URI_PATH_STR +gnome_vfs_uri_new +gnome_vfs_uri_resolve_relative +gnome_vfs_uri_ref +gnome_vfs_uri_unref +gnome_vfs_uri_append_string +gnome_vfs_uri_append_path +gnome_vfs_uri_append_file_name +gnome_vfs_uri_to_string +gnome_vfs_uri_dup +gnome_vfs_uri_is_local +gnome_vfs_uri_has_parent +gnome_vfs_uri_get_parent +gnome_vfs_uri_get_toplevel +gnome_vfs_uri_get_host_name +gnome_vfs_uri_get_scheme +gnome_vfs_uri_get_host_port +gnome_vfs_uri_get_user_name +gnome_vfs_uri_get_password +gnome_vfs_uri_set_host_name +gnome_vfs_uri_set_host_port +gnome_vfs_uri_set_user_name +gnome_vfs_uri_set_password +gnome_vfs_uri_equal +gnome_vfs_uri_is_parent +gnome_vfs_uri_get_path +gnome_vfs_uri_get_fragment_identifier +gnome_vfs_uri_extract_dirname +gnome_vfs_uri_extract_short_name +gnome_vfs_uri_extract_short_path_name +gnome_vfs_uri_hequal +gnome_vfs_uri_hash +gnome_vfs_uri_list_parse +gnome_vfs_uri_list_ref +gnome_vfs_uri_list_unref +gnome_vfs_uri_list_copy +gnome_vfs_uri_list_free +gnome_vfs_uri_make_full_from_relative +
+ +
+gnome-vfs-standard-callbacks +GNOME_VFS_MODULE_CALLBACK_AUTHENTICATION +GNOME_VFS_MODULE_CALLBACK_HTTP_PROXY_AUTHENTICATION +GnomeVFSModuleCallbackAuthenticationIn +GnomeVFSModuleCallbackAuthenticationOut +GNOME_VFS_MODULE_CALLBACK_HTTP_SEND_ADDITIONAL_HEADERS +GnomeVFSModuleCallbackAdditionalHeadersIn +GnomeVFSModuleCallbackAdditionalHeadersOut +GNOME_VFS_MODULE_CALLBACK_HTTP_RECEIVED_HEADERS +GnomeVFSModuleCallbackReceivedHeadersIn +GnomeVFSModuleCallbackReceivedHeadersOut +GNOME_VFS_MODULE_CALLBACK_STATUS_MESSAGE +GnomeVFSModuleCallbackStatusMessageIn +GnomeVFSModuleCallbackStatusMessageOut +
+ +
+gnome-vfs-inet-connection +gnome_vfs_inet_connection_create +gnome_vfs_inet_connection_destroy +gnome_vfs_inet_connection_free +gnome_vfs_inet_connection_to_socket +gnome_vfs_inet_connection_to_socket_buffer +gnome_vfs_inet_connection_get_fd +
+ +
+gnome-vfs-socket +GnomeVFSSocketReadFunc +GnomeVFSSocketWriteFunc +GnomeVFSSocketCloseFunc +GnomeVFSSocketImpl +gnome_vfs_socket_new +gnome_vfs_socket_write +gnome_vfs_socket_close +gnome_vfs_socket_read +
+ +
+gnome-vfs-parse-ls +gnome_vfs_parse_ls_lga +
+ +
+gnome-vfs-module-callback +GnomeVFSModuleCallback +GnomeVFSModuleCallbackResponse +GnomeVFSAsyncModuleCallback +gnome_vfs_module_callback_set_default +gnome_vfs_module_callback_push +gnome_vfs_module_callback_pop +gnome_vfs_async_module_callback_set_default +gnome_vfs_async_module_callback_push +gnome_vfs_async_module_callback_pop +
+ +
+gnome-vfs-context +gnome_vfs_context_new +gnome_vfs_context_free +gnome_vfs_context_get_cancellation +gnome_vfs_context_check_cancellation +gnome_vfs_context_peek_current +gnome_vfs_context_check_cancellation_current +
+ +
+gnome-vfs-file-info +GnomeVFSFileFlags +GnomeVFSFileType +GnomeVFSFileInfoFields +GnomeVFSFilePermissions +GnomeVFSFileInfoOptions +GnomeVFSSetFileInfoMask +GnomeVFSGetFileInfoResult +GnomeVFSInodeNumber +GnomeVFSFileInfo +GNOME_VFS_FILE_INFO_SYMLINK +GNOME_VFS_FILE_INFO_SET_SYMLINK +GNOME_VFS_FILE_INFO_LOCAL +GNOME_VFS_FILE_INFO_SET_LOCAL +GNOME_VFS_FILE_INFO_SUID +GNOME_VFS_FILE_INFO_SGID +GNOME_VFS_FILE_INFO_STICKY +GNOME_VFS_FILE_INFO_SET_SUID +GNOME_VFS_FILE_INFO_SET_SGID +GNOME_VFS_FILE_INFO_SET_STICKY +gnome_vfs_file_info_new +gnome_vfs_file_info_unref +gnome_vfs_file_info_ref +gnome_vfs_file_info_clear +gnome_vfs_file_info_get_mime_type +gnome_vfs_file_info_copy +gnome_vfs_file_info_dup +gnome_vfs_file_info_matches +gnome_vfs_file_info_list_ref +gnome_vfs_file_info_list_unref +gnome_vfs_file_info_list_copy +gnome_vfs_file_info_list_free +
+ +
+gnome-vfs-method +GnomeVFSMethodInitFunc +GnomeVFSMethodShutdownFunc +GnomeVFSMethodTruncateFunc +GnomeVFSMethodTruncateHandleFunc +VFS_METHOD_HAS_FUNC +gnome_vfs_method_init +gnome_vfs_method_get +gnome_vfs_transform_get +
+ + +
+gnome-vfs-result +GnomeVFSResult +gnome_vfs_result_to_string +gnome_vfs_result_from_errno_code +gnome_vfs_result_from_errno +gnome_vfs_result_from_h_errno +
+ + +
+gnome-vfs-module +vfs_module_init +vfs_module_transform +vfs_module_shutdown +
+ +
+gnome-vfs-module-shared +gnome_vfs_mime_type_from_mode +gnome_vfs_stat_to_file_info +gnome_vfs_set_meta +gnome_vfs_set_meta_for_list +gnome_vfs_get_special_mime_type +
+ +
+gnome-vfs-module-callback-module-api +gnome_vfs_module_callback_invoke +
+ + +
+gnome-vfs-mime +gnome_vfs_mime_shutdown +gnome_vfs_mime_type_from_name +gnome_vfs_mime_type_from_name_or_default +gnome_vfs_get_mime_type_common +gnome_vfs_get_mime_type_from_uri +gnome_vfs_get_mime_type_from_file_data +gnome_vfs_get_file_mime_type +gnome_vfs_mime_type_is_supertype +gnome_vfs_get_supertype_from_mime_type +
+ +
+gnome-vfs-mime-database +GNOME_VFS_MIME_TYPE_UNKNOWN +gnome_vfs_get_mime_type_for_data +gnome_vfs_get_mime_type +GnomeVFSMimeActionType +GnomeVFSMimeApplicationArgumentType +GnomeVFSMimeApplication +GnomeVFSMimeAction +gnome_vfs_mime_application_copy +gnome_vfs_mime_get_default_action_type +gnome_vfs_mime_get_default_action +gnome_vfs_mime_get_default_application +gnome_vfs_mime_get_default_component +gnome_vfs_mime_get_short_list_applications +gnome_vfs_mime_get_short_list_components +gnome_vfs_mime_get_all_applications +gnome_vfs_mime_get_all_components +gnome_vfs_mime_set_default_action_type +gnome_vfs_mime_set_default_application +gnome_vfs_mime_set_default_component +gnome_vfs_mime_get_icon +gnome_vfs_mime_set_icon +gnome_vfs_mime_get_description +gnome_vfs_mime_set_description +gnome_vfs_mime_can_be_executable +gnome_vfs_mime_set_can_be_executable +gnome_vfs_mime_set_short_list_applications +gnome_vfs_mime_set_short_list_components +gnome_vfs_mime_add_application_to_short_list +gnome_vfs_mime_remove_application_from_short_list +gnome_vfs_mime_add_component_to_short_list +gnome_vfs_mime_remove_component_from_short_list +gnome_vfs_mime_add_extension +gnome_vfs_mime_remove_extension +gnome_vfs_mime_extend_all_applications +gnome_vfs_mime_remove_from_all_applications +gnome_vfs_mime_application_new_from_id +gnome_vfs_mime_application_free +gnome_vfs_mime_action_free +gnome_vfs_mime_application_list_free +gnome_vfs_mime_component_list_free +gnome_vfs_mime_id_in_application_list +gnome_vfs_mime_id_in_component_list +gnome_vfs_mime_remove_application_from_list +gnome_vfs_mime_remove_component_from_list +gnome_vfs_mime_id_list_from_component_list +gnome_vfs_mime_id_list_from_application_list +gnome_vfs_mime_freeze +gnome_vfs_mime_thaw +gnome_vfs_mime_info_reload +gnome_vfs_mime_type_is_known +gnome_vfs_mime_get_value +gnome_vfs_mime_set_value +gnome_vfs_mime_get_key_list +gnome_vfs_mime_keys_list_free +gnome_vfs_mime_get_extensions_list +gnome_vfs_mime_extensions_list_free +gnome_vfs_mime_get_extensions_string +gnome_vfs_mime_get_extensions_pretty_string +gnome_vfs_get_registered_mime_types +gnome_vfs_mime_registered_mime_type_list_free +gnome_vfs_mime_set_registered_type_key +gnome_vfs_mime_set_extensions_list +gnome_vfs_mime_registered_mime_type_delete +gnome_vfs_mime_reset +
+ +
+gnome-vfs +
+ +
+gnome-vfs-cancellation +gnome_vfs_cancellation_new +gnome_vfs_cancellation_destroy +gnome_vfs_cancellation_cancel +gnome_vfs_cancellation_check +gnome_vfs_cancellation_ack +gnome_vfs_cancellation_get_fd +
+ +
+gnome-vfs-xfer +GnomeVFSXferOptions +GnomeVFSXferProgressStatus +GnomeVFSXferOverwriteMode +GnomeVFSXferOverwriteAction +GnomeVFSXferErrorMode +GnomeVFSXferErrorAction +GnomeVFSXferPhase +GnomeVFSXferProgressInfo +GnomeVFSXferProgressCallback +gnome_vfs_xfer_uri_list +gnome_vfs_xfer_uri +gnome_vfs_xfer_delete_list +
+ +
+gnome-vfs-socket-buffer +gnome_vfs_socket_buffer_new +gnome_vfs_socket_buffer_destroy +gnome_vfs_socket_buffer_read +gnome_vfs_socket_buffer_peekc +gnome_vfs_socket_buffer_write +gnome_vfs_socket_buffer_flush +
+ +
+gnome-vfs-monitor +gnome_vfs_monitor_add +gnome_vfs_monitor_cancel +GnomeVFSMonitorType +GnomeVFSMonitorEventType +GnomeVFSMonitorCallback +
+ diff --git a/doc/gnome-vfs-2.0.types b/doc/gnome-vfs-2.0.types new file mode 100644 index 0000000..e69de29 diff --git a/doc/html/about.html b/doc/html/about.html new file mode 100644 index 0000000..d90c560 --- /dev/null +++ b/doc/html/about.html @@ -0,0 +1,58 @@ +Introduction to GnomeVFS

Introduction to GnomeVFS

Uses and Purpose

+ GnomeVFS is a filesystem abstraction library allowing applications + plugable transparent access to a variety of "real" filesystems, from + WebDAV to digital cameras, to the local filesystem. It also contains + a number of other convenient file utilities such as a comphrehensive + MIME database / Application registry, and a copy engine. Use of GnomeVFS + ensures that an application or component will be usable by Nautilus + or other GnomeVFS applications for handling the display of data from + various URIs, as well +

User's Perspective

+ From a user's perspective GnomeVFS enabled applications provide consistent + access to their data, whether it be stored on remote servers or on their + local harddisk, or even a peripheral device such as a Rio or a digital + camera. Rather than having to work around the distinction between storage + you can work off of and storage you can only "download" from or "upload" to, + GnomeVFS allows users to store their documents and data wherever it is + most convenient. +

Developer's Perspective

+ Besides providing transparent access to data methods that you might + otherwise have to implement, GnomeVFS provides a number of convenience + libraries for processing URIs, detecting the MIME type of files, and + even figuring out which applications or components to launch to view + a file or what icon to use. Writing a GnomeVFS module may also be an + appropriate solution to some data access problems as it allows the + developer to implement a relatively small number of functions to gain + general filesystem semantics (and of course, writing a GnomeVFS module + benefits other applications too!). +

diff --git a/doc/html/advanced-operations.html b/doc/html/advanced-operations.html new file mode 100644 index 0000000..374861a --- /dev/null +++ b/doc/html/advanced-operations.html @@ -0,0 +1,33 @@ +Advanced Operations

Advanced Operations

Table of Contents

Monitoring - +watch files for changes, and get called back if they do
Cancellation - +halt in-progress operations
File Transfers - Conveniently copy/move/delete files en masse
diff --git a/doc/html/c9456.html b/doc/html/c9456.html new file mode 100644 index 0000000..f9379e8 --- /dev/null +++ b/doc/html/c9456.html @@ -0,0 +1,239 @@ +Other Stuff
GnomeVFS - Filesystem Abstraction library
<<< Previous PageHome Next Page >>>


<<< Previous PageHome Next Page >>>
gnome-vfs-parse-lsgnome-vfs-utils
\ No newline at end of file diff --git a/doc/html/c9466.html b/doc/html/c9466.html new file mode 100644 index 0000000..e66552b --- /dev/null +++ b/doc/html/c9466.html @@ -0,0 +1,172 @@ +Other Stuff
GnomeVFS - Filesystem Abstraction library
<<< gnome-vfs-parse-lsgnome-vfs-utils >>>
\ No newline at end of file diff --git a/doc/html/ch08.html b/doc/html/ch08.html new file mode 100644 index 0000000..99c081f --- /dev/null +++ b/doc/html/ch08.html @@ -0,0 +1,31 @@ +Other Stuff

Other Stuff

Table of Contents

gnome-vfs-utils - various utilities functions to manipulate uris
gnome-vfs-standard-callbacks - standard callbacks for use by gnome-vfs module writers
gnome-vfs-inet-connection -
gnome-vfs-module-callback - functions used by apps if they want to answer to callback invocations by gnome-vfs modules
diff --git a/doc/html/data-types.html b/doc/html/data-types.html new file mode 100644 index 0000000..7f4ceb4 --- /dev/null +++ b/doc/html/data-types.html @@ -0,0 +1,34 @@ +Data Types

Data Types

Table of Contents

GnomeVFSFileInfo - +stores information about files, GnomeVFS equivalent of stat
GnomeVFSFileSize -
GnomeVFSResult - +Result of I/O operations, the equivalent of errno
GnomeVFSURI - +Functions for manipulating URIs
diff --git a/doc/html/directory-operations.html b/doc/html/directory-operations.html new file mode 100644 index 0000000..3dfdeaf --- /dev/null +++ b/doc/html/directory-operations.html @@ -0,0 +1,165 @@ +Directories
GnomeVFS - Filesystem Abstraction library

Directories

Table of Contents
Directory Operations -- reading the contents of directories
Locating Standard Directories -- utilities for locating standard directories such as the desktop and trash

Functions for manipulating, creating, and listing directories. +

<<< Asynchronous File OperationsDirectory Operations >>>
\ No newline at end of file diff --git a/doc/html/everything-else.html b/doc/html/everything-else.html new file mode 100644 index 0000000..7ca2ca6 --- /dev/null +++ b/doc/html/everything-else.html @@ -0,0 +1,249 @@ +Other APIs
GnomeVFS - Filesystem Abstraction library
<<< Previous PageHome Next Page >>>

Other APIs

Table of Contents
Cancellation
Configuration
Context
File Size
Initialization — initializing and shutting down gnome-vfs
utils
\ No newline at end of file diff --git a/doc/html/file-operations.html b/doc/html/file-operations.html new file mode 100644 index 0000000..fd1063d --- /dev/null +++ b/doc/html/file-operations.html @@ -0,0 +1,180 @@ +Files
GnomeVFS - Filesystem Abstraction library

Files

Table of Contents
Initialization/Shutdown -- starting GnomeVFS up and shutting it down
File Operations -- basic POSIX-style file operations
Asynchronous File Operations -- POSIX-style file operations that run outside your main loop

GnomeVFS file operations are, for the most part, patterned after + their POSIX equivalents, with the systematic difference that they + accept URIs rather than paths on the local filesystem. This makes + them easy to learn as if you are already familiar with basic commands + such as open(), seek(), write(), etc you will feel right at home + with GnomeVFS after learning a little about URIs. +

GnomeVFS also provides asynchronous versions of these basic operations for + allowing application developers to provide non-blocking file I/O + without the use of threads. +

<<< GnomeVFS - Filesystem Abstraction libraryInitialization/Shutdown >>>
\ No newline at end of file diff --git a/doc/html/gnome-vfs-20-gnome-vfs-application-registry.html b/doc/html/gnome-vfs-20-gnome-vfs-application-registry.html new file mode 100644 index 0000000..82bc15a --- /dev/null +++ b/doc/html/gnome-vfs-20-gnome-vfs-application-registry.html @@ -0,0 +1,344 @@ +Application Registry

Application Registry

Application Registry — +stores supported MIME types and URIs of various applications

Synopsis

+
+
+
+#define     GNOME_VFS_APPLICATION_REGISTRY_COMMAND
+#define     GNOME_VFS_APPLICATION_REGISTRY_NAME
+#define     GNOME_VFS_APPLICATION_REGISTRY_CAN_OPEN_MULTIPLE_FILES
+#define     GNOME_VFS_APPLICATION_REGISTRY_REQUIRES_TERMINAL
+gboolean    gnome_vfs_application_registry_exists
+                                            (const char *app_id);
+GList*      gnome_vfs_application_registry_get_keys
+                                            (const char *app_id);
+const char* gnome_vfs_application_registry_peek_value
+                                            (const char *app_id,
+                                             const char *key);
+gboolean    gnome_vfs_application_registry_get_bool_value
+                                            (const char *app_id,
+                                             const char *key,
+                                             gboolean *got_key);
+void        gnome_vfs_application_registry_remove_application
+                                            (const char *app_id);
+void        gnome_vfs_application_registry_set_value
+                                            (const char *app_id,
+                                             const char *key,
+                                             const char *value);
+void        gnome_vfs_application_registry_set_bool_value
+                                            (const char *app_id,
+                                             const char *key,
+                                             gboolean value);
+void        gnome_vfs_application_registry_unset_key
+                                            (const char *app_id,
+                                             const char *key);
+GList*      gnome_vfs_application_registry_get_applications
+                                            (const char *mime_type);
+GList*      gnome_vfs_application_registry_get_mime_types
+                                            (const char *app_id);
+gboolean    gnome_vfs_application_registry_supports_mime_type
+                                            (const char *app_id,
+                                             const char *mime_type);
+gboolean    gnome_vfs_application_registry_supports_uri_scheme
+                                            (const char *app_id,
+                                             const char *uri_scheme);
+gboolean    gnome_vfs_application_is_user_owned_application
+                                            (const GnomeVFSMimeApplication *application);
+void        gnome_vfs_application_registry_clear_mime_types
+                                            (const char *app_id);
+void        gnome_vfs_application_registry_add_mime_type
+                                            (const char *app_id,
+                                             const char *mime_type);
+void        gnome_vfs_application_registry_remove_mime_type
+                                            (const char *app_id,
+                                             const char *mime_type);
+GnomeVFSResult gnome_vfs_application_registry_sync
+                                            (void);
+void        gnome_vfs_application_registry_shutdown
+                                            (void);
+void        gnome_vfs_application_registry_reload
+                                            (void);
+GnomeVFSMimeApplication* gnome_vfs_application_registry_get_mime_application
+                                            (const char *app_id);
+void        gnome_vfs_application_registry_save_mime_application
+                                            (const GnomeVFSMimeApplication *application);
+

Description

+ +

Details

GNOME_VFS_APPLICATION_REGISTRY_COMMAND

#define GNOME_VFS_APPLICATION_REGISTRY_COMMAND "command"
+

+Application registry key for fetching the command to execute +an application.

+ +


GNOME_VFS_APPLICATION_REGISTRY_NAME

#define GNOME_VFS_APPLICATION_REGISTRY_NAME "name"
+

+Application registry key for fetching the name of an application.

+ +


GNOME_VFS_APPLICATION_REGISTRY_CAN_OPEN_MULTIPLE_FILES

#define GNOME_VFS_APPLICATION_REGISTRY_CAN_OPEN_MULTIPLE_FILES "can_open_multiple_files"
+

+Application registry key for determining if an application +can open multiple files in the same invocation.

+ +


GNOME_VFS_APPLICATION_REGISTRY_REQUIRES_TERMINAL

#define GNOME_VFS_APPLICATION_REGISTRY_REQUIRES_TERMINAL "requires_terminal"
+

+Application registry key for determining if an application +needs to run from within a terminal (for example, mpg123)

+ +


gnome_vfs_application_registry_exists ()

gboolean    gnome_vfs_application_registry_exists
+                                            (const char *app_id);

+This function will return TRUE if there is an entry for app_id in +the registry, otherwise FALSE.

+ +

app_id : an application ID +
Returns : TRUE if the application is in the registry, FALSE if not + +

gnome_vfs_application_registry_get_keys ()

GList*      gnome_vfs_application_registry_get_keys
+                                            (const char *app_id);

+This function wil return a list of strings which is the list of +keys set for app_id in the application registry.

+ +

app_id : the application ID for which to get keys +
Returns : A list of the keys set for app_id + +

gnome_vfs_application_registry_peek_value ()

const char* gnome_vfs_application_registry_peek_value
+                                            (const char *app_id,
+                                             const char *key);

+This will return the value associated with key for app_id in the +application registry. There is no need to free the return value.

+ +

app_id : the application ID for which to look up a value +
key : the key to look up +
Returns : the value associated with the key, or NULL if there is no +associated value + +

gnome_vfs_application_registry_get_bool_value ()

gboolean    gnome_vfs_application_registry_get_bool_value
+                                            (const char *app_id,
+                                             const char *key,
+                                             gboolean *got_key);

+This will look up a key in the structure pointed to by app_id and return the +boolean value of that key. It will return false if there are no +applications associated with the app_id.

+ +

app_id : registry id of the application +
key : key to look up +
got_key : TRUE if a setting was dound, otherwise FALSE +
Returns : TRUE if key is set to "true" or "yes" for app_id, otherwise FALSE + +

gnome_vfs_application_registry_remove_application ()

void        gnome_vfs_application_registry_remove_application
+                                            (const char *app_id);

+Given the registry id this function will remove all applications that has +been set by the user. You will need to call +gnome_vfs_application_registry_sync to save the changes.

+ +

app_id : registry id of the application +

gnome_vfs_application_registry_set_value ()

void        gnome_vfs_application_registry_set_value
+                                            (const char *app_id,
+                                             const char *key,
+                                             const char *value);

+This function will set values pertaining to registry entry pointed to by +app_id. You will need to call gnome_vfs_application_registry_sync to +realize the changes.

+ +

app_id : registry id of the application +
key : target key +
value : value to set the target key to +

gnome_vfs_application_registry_set_bool_value ()

void        gnome_vfs_application_registry_set_bool_value
+                                            (const char *app_id,
+                                             const char *key,
+                                             gboolean value);

+This function will modify those registry values that are of type boolean to +a value specified by the user. You will need to call +gnome_vfs_application_registry_sync to save your changes.

+ +

app_id : registry id of the application +
key : target key +
value : value you want to set the target key to +

gnome_vfs_application_registry_unset_key ()

void        gnome_vfs_application_registry_unset_key
+                                            (const char *app_id,
+                                             const char *key);

+This function given the application and the target will wipe the current +value that the key contains.

+ +

app_id : registry id of the application +
key : search key +

gnome_vfs_application_registry_get_applications ()

GList*      gnome_vfs_application_registry_get_applications
+                                            (const char *mime_type);

+This will return all applications from the registry that are associated with +the given mime type string, if NULL it returns all applications.

+ +

mime_type : mime type string +
Returns : a list of the application IDs for all applications which +support the given mime type. + +

gnome_vfs_application_registry_get_mime_types ()

GList*      gnome_vfs_application_registry_get_mime_types
+                                            (const char *app_id);

+This function returns a list of strings that represent the mime +types that can be handled by an application.

+ +

app_id : registry id of application +
Returns : a list of the mime types supported + +

gnome_vfs_application_registry_supports_mime_type ()

gboolean    gnome_vfs_application_registry_supports_mime_type
+                                            (const char *app_id,
+                                             const char *mime_type);

+Use this function to see if there is an application associated with a given +mime type. The function will return true or false.

+ +

app_id : registry id of application +
mime_type : mime type string +
Returns : TRUE if app_id supports mime_type, otherwise FALSE. + +

gnome_vfs_application_registry_supports_uri_scheme ()

gboolean    gnome_vfs_application_registry_supports_uri_scheme
+                                            (const char *app_id,
+                                             const char *uri_scheme);

+Given the id of the application this function will determine if the +uri scheme will given is supported.

+ +

app_id : registry id of application +
uri_scheme : uri schme string +
Returns : TRUE if app_id supports uri_scheme, otherwise FALSE + +

gnome_vfs_application_is_user_owned_application ()

gboolean    gnome_vfs_application_is_user_owned_application
+                                            (const GnomeVFSMimeApplication *application);

+This function will determine if a mime application is user owned or not. By +user ownered this means that the application is not a system application +located in the prerequisite /usr area but rather in the user's area.

+ +

application : data structure of the mime application +
Returns : gboolean +

gnome_vfs_application_registry_clear_mime_types ()

void        gnome_vfs_application_registry_clear_mime_types
+                                            (const char *app_id);

+This function will remove the mime types associated with the application. +Changes are not realized until the gnome_vfs_application_registry_sync +function is called to save the changes to the file.

+ +

app_id : Application id +

gnome_vfs_application_registry_add_mime_type ()

void        gnome_vfs_application_registry_add_mime_type
+                                            (const char *app_id,
+                                             const char *mime_type);

+This function will associate a mime type with an application given the +application registry id and the mime type. Changes are not realized until +the gnome_vfs_application_registry_sync function is called to save the +changes to the file.

+ +

app_id : registry id of application +
mime_type : mime type string +

gnome_vfs_application_registry_remove_mime_type ()

void        gnome_vfs_application_registry_remove_mime_type
+                                            (const char *app_id,
+                                             const char *mime_type);

+This function will de-associate a mime type from an application registry. +Given the application registry id and the mime type. Changes are not +realized until the gnome_vfs_application_registry_sync function is called to +save the changes to the file.

+ +

app_id : registry id of the application +
mime_type : mime type string +

gnome_vfs_application_registry_sync ()

GnomeVFSResult gnome_vfs_application_registry_sync
+                                            (void);

+This function will sync the registry. Typically you would use this function +after a modification of the registry. When you modify the registry a dirty +flag is set. Calling this function will save your modifications to disk and +reset the flag. +

+If successful, will return GNOME_VFS_OK

+ +

Returns : GnomeVFSResult + +

gnome_vfs_application_registry_shutdown ()

void        gnome_vfs_application_registry_shutdown
+                                            (void);

+Synchronize gnome-vfs application registry data to disk, and free +resources.

+ +


gnome_vfs_application_registry_reload ()

void        gnome_vfs_application_registry_reload
+                                            (void);

+If this function is called for the first time it will initialize the +registry. Subsequent calls to the function will clear out the current +registry contents and load registry contents from the save file. Make +certain that you've saved your registry before calling this function. It +will destroy unsaved changes.

+ +


gnome_vfs_application_registry_get_mime_application ()

GnomeVFSMimeApplication* gnome_vfs_application_registry_get_mime_application
+                                            (const char *app_id);

+Returns a structure that contains the application that handles +the mime type associated by the application referred by app_id.

+ +

app_id : registry id of the application +
Returns : GnomeVFSMimeApplication + +

gnome_vfs_application_registry_save_mime_application ()

void        gnome_vfs_application_registry_save_mime_application
+                                            (const GnomeVFSMimeApplication *application);

+This will save to the registry the application that will be associated with +a defined mime type. The defined mime type is located within the +GnomeVFSMimeApplication structure. Changes are not realized until the +gnome_vfs_application_registry_sync function is called.

+ +

application : application associated with the mime type +
diff --git a/doc/html/gnome-vfs-20-gnome-vfs-async-ops.html b/doc/html/gnome-vfs-20-gnome-vfs-async-ops.html new file mode 100644 index 0000000..bc211a9 --- /dev/null +++ b/doc/html/gnome-vfs-20-gnome-vfs-async-ops.html @@ -0,0 +1,978 @@ +Asynchronous File Operations

Asynchronous File Operations

Asynchronous File Operations — +POSIX-style file operations that run outside your main loop

Synopsis

+
+
+
+#define     GNOME_VFS_PRIORITY_MIN
+#define     GNOME_VFS_PRIORITY_MAX
+#define     GNOME_VFS_PRIORITY_DEFAULT
+void        (*GnomeVFSAsyncCallback)        (GnomeVFSAsyncHandle *handle,
+                                             GnomeVFSResult result,
+                                             gpointer callback_data);
+typedef     GnomeVFSAsyncOpenCallback;
+typedef     GnomeVFSAsyncCreateCallback;
+typedef     GnomeVFSAsyncCreateAsChannelCallback;
+typedef     GnomeVFSAsyncCloseCallback;
+void        (*GnomeVFSAsyncReadCallback)    (GnomeVFSAsyncHandle *handle,
+                                             GnomeVFSResult result,
+                                             gpointer buffer,
+                                             GnomeVFSFileSize bytes_requested,
+                                             GnomeVFSFileSize bytes_read,
+                                             gpointer callback_data);
+void        (*GnomeVFSAsyncWriteCallback)   (GnomeVFSAsyncHandle *handle,
+                                             GnomeVFSResult result,
+                                             gconstpointer buffer,
+                                             GnomeVFSFileSize bytes_requested,
+                                             GnomeVFSFileSize bytes_written,
+                                             gpointer callback_data);
+typedef     GnomeVFSFindDirectoryResult;
+void        gnome_vfs_async_set_job_limit   (int limit);
+int         gnome_vfs_async_get_job_limit   (void);
+void        gnome_vfs_async_cancel          (GnomeVFSAsyncHandle *handle);
+void        gnome_vfs_async_open            (GnomeVFSAsyncHandle **handle_return,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             int priority,
+                                             GnomeVFSAsyncOpenCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_open_uri        (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             int priority,
+                                             GnomeVFSAsyncOpenCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_open_as_channel (GnomeVFSAsyncHandle **handle_return,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             guint advised_block_size,
+                                             int priority,
+                                             GnomeVFSAsyncOpenAsChannelCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_open_uri_as_channel
+                                            (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             guint advised_block_size,
+                                             int priority,
+                                             GnomeVFSAsyncOpenAsChannelCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_create          (GnomeVFSAsyncHandle **handle_return,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm,
+                                             int priority,
+                                             GnomeVFSAsyncOpenCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_create_uri      (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm,
+                                             int priority,
+                                             GnomeVFSAsyncOpenCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_create_symbolic_link
+                                            (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             const gchar *uri_reference,
+                                             int priority,
+                                             GnomeVFSAsyncOpenCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_create_as_channel
+                                            (GnomeVFSAsyncHandle **handle_return,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm,
+                                             int priority,
+                                             GnomeVFSAsyncCreateAsChannelCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_create_uri_as_channel
+                                            (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm,
+                                             int priority,
+                                             GnomeVFSAsyncCreateAsChannelCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_close           (GnomeVFSAsyncHandle *handle,
+                                             GnomeVFSAsyncCloseCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_read            (GnomeVFSAsyncHandle *handle,
+                                             gpointer buffer,
+                                             guint bytes,
+                                             GnomeVFSAsyncReadCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_write           (GnomeVFSAsyncHandle *handle,
+                                             gconstpointer buffer,
+                                             guint bytes,
+                                             GnomeVFSAsyncWriteCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_get_file_info   (GnomeVFSAsyncHandle **handle_return,
+                                             GList *uri_list,
+                                             GnomeVFSFileInfoOptions options,
+                                             int priority,
+                                             GnomeVFSAsyncGetFileInfoCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_set_file_info   (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSFileInfo *info,
+                                             GnomeVFSSetFileInfoMask mask,
+                                             GnomeVFSFileInfoOptions options,
+                                             int priority,
+                                             GnomeVFSAsyncSetFileInfoCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_load_directory  (GnomeVFSAsyncHandle **handle_return,
+                                             const gchar *text_uri,
+                                             GnomeVFSFileInfoOptions options,
+                                             guint items_per_notification,
+                                             int priority,
+                                             GnomeVFSAsyncDirectoryLoadCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_load_directory_uri
+                                            (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSFileInfoOptions options,
+                                             guint items_per_notification,
+                                             int priority,
+                                             GnomeVFSAsyncDirectoryLoadCallback callback,
+                                             gpointer callback_data);
+GnomeVFSResult gnome_vfs_async_xfer         (GnomeVFSAsyncHandle **handle_return,
+                                             GList *source_uri_list,
+                                             GList *target_uri_list,
+                                             GnomeVFSXferOptions xfer_options,
+                                             GnomeVFSXferErrorMode error_mode,
+                                             GnomeVFSXferOverwriteMode overwrite_mode,
+                                             int priority,
+                                             GnomeVFSAsyncXferProgressCallback progress_update_callback,
+                                             gpointer update_callback_data,
+                                             GnomeVFSXferProgressCallback progress_sync_callback,
+                                             gpointer sync_callback_data);
+void        gnome_vfs_async_find_directory  (GnomeVFSAsyncHandle **handle_return,
+                                             GList *near_uri_list,
+                                             GnomeVFSFindDirectoryKind kind,
+                                             gboolean create_if_needed,
+                                             gboolean find_if_needed,
+                                             guint permissions,
+                                             int priority,
+                                             GnomeVFSAsyncFindDirectoryCallback callback,
+                                             gpointer user_data);
+void        gnome_vfs_async_file_control    (GnomeVFSAsyncHandle *handle,
+                                             const char *operation,
+                                             gpointer operation_data,
+                                             GDestroyNotify operation_data_destroy_func,
+                                             GnomeVFSAsyncFileControlCallback callback,
+                                             gpointer callback_data);
+

Description

+ When executing an asynchornous operation on a file the program does not + block waiting for the operation to finish, instead it keeps on running, + which means that the process and the I/O operation can be both running + concurrently. Once the I/O operation has been completed the process is + notified using a callback. +

+ Asynchronous operations are particularly good when long I/O operations + are expected, in this case the program can continue normaly, the I/O + will be performed in the background. On the other hand when operations + are expected to be short (creating a file, writing/reading small amounts + of data, etc.) synchronous operations are prefered. +

+ Within a graphical desktop asynchornous I/O operations can be used to + avoid blocking the UI (User Interface) during a long operation, and + to be able to provide some kind of feedback to the user. +

Details

GNOME_VFS_PRIORITY_MIN

#define GNOME_VFS_PRIORITY_MIN     -10
+

+The minimuum priority a job can have.

+ +


GNOME_VFS_PRIORITY_MAX

#define GNOME_VFS_PRIORITY_MAX     10
+

+The maximuum priority a job can have.

+ +


GNOME_VFS_PRIORITY_DEFAULT

#define GNOME_VFS_PRIORITY_DEFAULT 0
+

+The default job priority. Its best to use this +unless you have a reason to do otherwise.

+ +


GnomeVFSAsyncCallback ()

void        (*GnomeVFSAsyncCallback)        (GnomeVFSAsyncHandle *handle,
+                                             GnomeVFSResult result,
+                                             gpointer callback_data);

+Basic callback from an async operation that passes no data back, +informing the user of the result of the operation.

+ +

handle : handle of the operation generating the callback +
result : GNOME_VFS_OK if the operation was successful, otherwise +an error code. +
callback_data : user data defined when the callback was established +

GnomeVFSAsyncOpenCallback

typedef GnomeVFSAsyncCallback GnomeVFSAsyncOpenCallback;
+

+Basic callback from an async operation that passes no data back, +informing the user of the result of the operation.

+ +


GnomeVFSAsyncCreateCallback

typedef GnomeVFSAsyncCallback GnomeVFSAsyncCreateCallback;
+

+Basic callback from an async operation that passes no data back, +informing the user of the result of the operation.

+ +


GnomeVFSAsyncCreateAsChannelCallback

typedef GnomeVFSAsyncOpenAsChannelCallback GnomeVFSAsyncCreateAsChannelCallback;
+

+Callback for the gnome_vfs_async_create_as_channel() function.

+ +


GnomeVFSAsyncCloseCallback

typedef GnomeVFSAsyncCallback GnomeVFSAsyncCloseCallback;
+

+Basic callback from an async operation that passes no data back, +informing the user of the result of the operation.

+ +


GnomeVFSAsyncReadCallback ()

void        (*GnomeVFSAsyncReadCallback)    (GnomeVFSAsyncHandle *handle,
+                                             GnomeVFSResult result,
+                                             gpointer buffer,
+                                             GnomeVFSFileSize bytes_requested,
+                                             GnomeVFSFileSize bytes_read,
+                                             gpointer callback_data);

+Callback for the gnome_vfs_async_read() function.

+ +

handle : handle of the operation generating the callback +
result : GNOME_VFS_OK if the operation was successful, otherwise +an error code. +
buffer : buffer containing data read from handle. +
bytes_requested : the number of bytes asked for in the call to +gnome_vfs_async_read(). +
bytes_read : the number of bytes actually read from handle into buffer. +
callback_data : user data defined when the callback was established +

GnomeVFSAsyncWriteCallback ()

void        (*GnomeVFSAsyncWriteCallback)   (GnomeVFSAsyncHandle *handle,
+                                             GnomeVFSResult result,
+                                             gconstpointer buffer,
+                                             GnomeVFSFileSize bytes_requested,
+                                             GnomeVFSFileSize bytes_written,
+                                             gpointer callback_data);

+Callback for the gnome_vfs_async_write() function.

+ +

handle : handle of the operation generating the callback +
result : GNOME_VFS_OK if the operation was successful, otherwise +an error code. +
buffer : buffer containing data written to handle. +
bytes_requested : the number of bytes asked to write in the call to +gnome_vfs_async_write(). +
bytes_written : the number of bytes actually written to handle from buffer. +
callback_data : user data defined when the callback was established +

GnomeVFSFindDirectoryResult

typedef struct {
+	GnomeVFSURI *uri;
+	GnomeVFSResult result;
+
+	/* Reserved to avoid future breaks in ABI compatibility */
+	void *reserved1;
+	void *reserved2;
+} GnomeVFSFindDirectoryResult;
+

+ +


gnome_vfs_async_set_job_limit ()

void        gnome_vfs_async_set_job_limit   (int limit);

+Restrict the number of worker threads used by Async operations +to limit.

+ +

limit : maximuum number of allowable threads +

gnome_vfs_async_get_job_limit ()

int         gnome_vfs_async_get_job_limit   (void);

+Get the current maximuum allowable number of +worker threads for Asynch operations.

+ +

Returns : current maximuum number of threads +

gnome_vfs_async_cancel ()

void        gnome_vfs_async_cancel          (GnomeVFSAsyncHandle *handle);

+Cancel an asynchronous operation and close all its callbacks. +Its possible to still receive another call or two on the callback.

+ +

handle : handle of the async operation to be cancelled +

gnome_vfs_async_open ()

void        gnome_vfs_async_open            (GnomeVFSAsyncHandle **handle_return,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             int priority,
+                                             GnomeVFSAsyncOpenCallback callback,
+                                             gpointer callback_data);

+Open text_uri according to mode open_mode. On return, handle_return will +contain a pointer to the operation. Once the file has been successfully opened, +callback will be called with the GnomeVFSResult.

+ +

handle_return : A pointer to a pointer to a GnomeVFSHandle object +
text_uri : string of the URI to open +
open_mode : Open mode +
priority : a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. +
callback : function to be called when the operation is complete +
callback_data : data to pass callback +

gnome_vfs_async_open_uri ()

void        gnome_vfs_async_open_uri        (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             int priority,
+                                             GnomeVFSAsyncOpenCallback callback,
+                                             gpointer callback_data);

+Open uri according to mode open_mode. On return, handle_return will +contain a pointer to the operation. Once the file has been successfully opened, +callback will be called with the GnomeVFSResult.

+ +

handle_return : A pointer to a pointer to a GnomeVFSHandle object +
uri : URI to open +
open_mode : Open mode +
priority : a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. +
callback : function to be called when the operation is complete +
callback_data : data to pass callback +

gnome_vfs_async_open_as_channel ()

void        gnome_vfs_async_open_as_channel (GnomeVFSAsyncHandle **handle_return,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             guint advised_block_size,
+                                             int priority,
+                                             GnomeVFSAsyncOpenAsChannelCallback callback,
+                                             gpointer callback_data);

+Open text_uri as a GIOChannel. Once the channel has been established +callback will be called with callback_data, the result of the operation, +and if the result was GNOME_VFS_OK, a reference to a GIOChannel pointing +at text_uri in open_mode.

+ +

handle_return : A pointer to a pointer to a GnomeVFSHandle object +
text_uri : string of the URI to open as a GIOChannel +
open_mode : open for reading, writing, random, etc +
advised_block_size : the preferred block size for GIOChannel to read +
priority : a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. +
callback : function to be called when the operation is complete +
callback_data : data to pass callback +

gnome_vfs_async_open_uri_as_channel ()

void        gnome_vfs_async_open_uri_as_channel
+                                            (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             guint advised_block_size,
+                                             int priority,
+                                             GnomeVFSAsyncOpenAsChannelCallback callback,
+                                             gpointer callback_data);

+Open uri as a GIOChannel. Once the channel has been established +callback will be called with callback_data, the result of the operation, +and if the result was GNOME_VFS_OK, a reference to a GIOChannel pointing +at uri in open_mode.

+ +

handle_return : A pointer to a pointer to a GnomeVFSHandle object +
uri : URI to open as a GIOChannel +
open_mode : open for reading, writing, random, etc +
advised_block_size : the preferred block size for GIOChannel to read +
priority : a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. +
callback : function to be called when the operation is complete +
callback_data : data to pass callback +

gnome_vfs_async_create ()

void        gnome_vfs_async_create          (GnomeVFSAsyncHandle **handle_return,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm,
+                                             int priority,
+                                             GnomeVFSAsyncOpenCallback callback,
+                                             gpointer callback_data);

+Create a file at uri according to mode open_mode, with permissions perm (in +the standard UNIX packed bit permissions format). When the create has been completed +callback will be called with the result code and callback_data.

+ +

handle_return : A pointer to a pointer to a GnomeVFSHandle object +
text_uri : String representing the URI to create +
open_mode : mode to leave the file opened in after creation (or GNOME_VFS_OPEN_MODE_NONE +to leave the file closed after creation) +
exclusive : Whether the file should be created in "exclusive" mode: +i.e. if this flag is nonzero, operation will fail if a file with the +same name already exists. +
perm : Bitmap representing the permissions for the newly created file +(Unix style). +
priority : a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. +
callback : function to be called when the operation is complete +
callback_data : data to pass callback +

gnome_vfs_async_create_uri ()

void        gnome_vfs_async_create_uri      (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm,
+                                             int priority,
+                                             GnomeVFSAsyncOpenCallback callback,
+                                             gpointer callback_data);

+Create a file at uri according to mode open_mode, with permissions perm (in +the standard UNIX packed bit permissions format). When the create has been completed +callback will be called with the result code and callback_data.

+ +

handle_return : A pointer to a pointer to a GnomeVFSHandle object +
uri : the URI to create a file at +
open_mode : mode to leave the file opened in after creation (or GNOME_VFS_OPEN_MODE_NONE +to leave the file closed after creation) +
exclusive : Whether the file should be created in "exclusive" mode: +i.e. if this flag is nonzero, operation will fail if a file with the +same name already exists. +
perm : Bitmap representing the permissions for the newly created file +(Unix style). +
priority : a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. +
callback : function to be called when the operation is complete +
callback_data : data to pass callback +

gnome_vfs_async_create_symbolic_link ()

void        gnome_vfs_async_create_symbolic_link
+                                            (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             const gchar *uri_reference,
+                                             int priority,
+                                             GnomeVFSAsyncOpenCallback callback,
+                                             gpointer callback_data);

+Create a symbolic link at uri pointing to uri_reference. When the operation +has complete callback will be called with the result of the operation and +callback_data.

+ +

handle_return : when the function returns will point to a handle for +the async operation. +
uri : location to create the link at +
uri_reference : location to point uri to (can be a URI fragment, i.e. relative) +
priority : a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. +
callback : function to be called when the operation is complete +
callback_data : data to pass callback +

gnome_vfs_async_create_as_channel ()

void        gnome_vfs_async_create_as_channel
+                                            (GnomeVFSAsyncHandle **handle_return,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm,
+                                             int priority,
+                                             GnomeVFSAsyncCreateAsChannelCallback callback,
+                                             gpointer callback_data);

+Open text_uri as a GIOChannel, creating it as necessary. Once the channel has +been established callback will be called with callback_data, the result of the +operation, and if the result was GNOME_VFS_OK, a reference to a GIOChannel pointing +at text_uri in open_mode.

+ +

handle_return : A pointer to a pointer to a GnomeVFSHandle object +
text_uri : string of the URI to open as a GIOChannel, creating it as necessary +
open_mode : open for reading, writing, random, etc +
exclusive : replace the file if it already exists +
perm : standard POSIX-style permissions bitmask, permissions of created file +
priority : a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. +
callback : function to be called when the operation is complete +
callback_data : data to pass callback +

gnome_vfs_async_create_uri_as_channel ()

void        gnome_vfs_async_create_uri_as_channel
+                                            (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm,
+                                             int priority,
+                                             GnomeVFSAsyncCreateAsChannelCallback callback,
+                                             gpointer callback_data);

+ +

handle_return : +
uri : +
open_mode : +
exclusive : +
perm : +
priority : +
callback : +
callback_data : + + +

gnome_vfs_async_close ()

void        gnome_vfs_async_close           (GnomeVFSAsyncHandle *handle,
+                                             GnomeVFSAsyncCloseCallback callback,
+                                             gpointer callback_data);

+Close a handle opened with gnome_vfs_async_open(). When the close +has completed, callback will be called with callback_data and +the result of the operation.

+ +

handle : async handle to close +
callback : function to be called when the operation is complete +
callback_data : data to pass callback +

gnome_vfs_async_read ()

void        gnome_vfs_async_read            (GnomeVFSAsyncHandle *handle,
+                                             gpointer buffer,
+                                             guint bytes,
+                                             GnomeVFSAsyncReadCallback callback,
+                                             gpointer callback_data);

+Read bytes bytes from the file pointed to be handle into buffer. +When the operation is complete, callback will be called with the +result of the operation and callback_data.

+ +

handle : handle for the file to be read +
buffer : allocated block of memory to read into +
bytes : number of bytes to read +
callback : function to be called when the operation is complete +
callback_data : data to pass callback +

gnome_vfs_async_write ()

void        gnome_vfs_async_write           (GnomeVFSAsyncHandle *handle,
+                                             gconstpointer buffer,
+                                             guint bytes,
+                                             GnomeVFSAsyncWriteCallback callback,
+                                             gpointer callback_data);

+Write bytes bytes from buffer into the file pointed to be handle. +When the operation is complete, callback will be called with the +result of the operation and callback_data.

+ +

handle : handle for the file to be written +
buffer : block of memory containing data to be written +
bytes : number of bytes to write +
callback : function to be called when the operation is complete +
callback_data : data to pass callback +

gnome_vfs_async_get_file_info ()

void        gnome_vfs_async_get_file_info   (GnomeVFSAsyncHandle **handle_return,
+                                             GList *uri_list,
+                                             GnomeVFSFileInfoOptions options,
+                                             int priority,
+                                             GnomeVFSAsyncGetFileInfoCallback callback,
+                                             gpointer callback_data);

+Fetch information about the files indicated in uris and return the +information progressively to callback.

+ +

handle_return : when the function returns will point to a handle for +the async operation. +
uri_list : a GList of GnomeVFSURIs to fetch information about +
options : packed boolean type providing control over various details +of the get_file_info operation. +
priority : a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. +
callback : function to be called when the operation is complete +
callback_data : data to pass callback +

gnome_vfs_async_set_file_info ()

void        gnome_vfs_async_set_file_info   (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSFileInfo *info,
+                                             GnomeVFSSetFileInfoMask mask,
+                                             GnomeVFSFileInfoOptions options,
+                                             int priority,
+                                             GnomeVFSAsyncSetFileInfoCallback callback,
+                                             gpointer callback_data);

+Set "file info" details about the file at uri, such as permissions, name, +owner, and modification time.

+ +

handle_return : when the function returns will point to a handle for +the async operation. +
uri : the URI to set the file info of +
info : the struct containing new information about the file +
mask : control which fields of info are changed about the file at uri +
options : packed boolean type providing control over various details +of the set_file_info operation. +
priority : a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. +
callback : function to be called when the operation is complete +
callback_data : data to pass callback +

gnome_vfs_async_load_directory ()

void        gnome_vfs_async_load_directory  (GnomeVFSAsyncHandle **handle_return,
+                                             const gchar *text_uri,
+                                             GnomeVFSFileInfoOptions options,
+                                             guint items_per_notification,
+                                             int priority,
+                                             GnomeVFSAsyncDirectoryLoadCallback callback,
+                                             gpointer callback_data);

+Read the contents of the directory at text_uri, passing back GnomeVFSFileInfo +structs about each file in the directory to callback. items_per_notification +files will be processed between each call to callback.

+ +

handle_return : when the function returns will point to a handle for +the async operation. +
text_uri : string representing the URI of the directory to be loaded +
options : packed boolean type providing control over various details +of the get_file_info operation. +
items_per_notification : number of files to process in a row before calling callback +
priority : a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. +
callback : function to be called when the operation is complete +
callback_data : data to pass callback +

gnome_vfs_async_load_directory_uri ()

void        gnome_vfs_async_load_directory_uri
+                                            (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSFileInfoOptions options,
+                                             guint items_per_notification,
+                                             int priority,
+                                             GnomeVFSAsyncDirectoryLoadCallback callback,
+                                             gpointer callback_data);

+Read the contents of the directory at uri, passing back GnomeVFSFileInfo structs +about each file in the directory to callback. items_per_notification +files will be processed between each call to callback.

+ +

handle_return : when the function returns will point to a handle for +the async operation. +
uri : string representing the URI of the directory to be loaded +
options : packed boolean type providing control over various details +of the get_file_info operation. +
items_per_notification : number of files to process in a row before calling callback +
priority : a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. +
callback : function to be called when the operation is complete +
callback_data : data to pass callback +

gnome_vfs_async_xfer ()

GnomeVFSResult gnome_vfs_async_xfer         (GnomeVFSAsyncHandle **handle_return,
+                                             GList *source_uri_list,
+                                             GList *target_uri_list,
+                                             GnomeVFSXferOptions xfer_options,
+                                             GnomeVFSXferErrorMode error_mode,
+                                             GnomeVFSXferOverwriteMode overwrite_mode,
+                                             int priority,
+                                             GnomeVFSAsyncXferProgressCallback progress_update_callback,
+                                             gpointer update_callback_data,
+                                             GnomeVFSXferProgressCallback progress_sync_callback,
+                                             gpointer sync_callback_data);

+Perform a copy operation in a seperate thread. progress_update_callback will be periodically +polled with status of the operation (percent done, the current phase of operation, the +current file being operated upon). If the xfer engine needs to query the caller to make +a decision or report on important error it will do so on progress_sync_callback.

+ +

handle_return : when the function returns will point to a handle for +
source_uri_list : GList of GnomeVFSURI representing the files to be transferred +
target_uri_list : GList of GnomeVFSURI, the target locations for the elements +in source_uri_list +
xfer_options : various options controlling the details of the transfer. +Use GNOME_VFS_XFER_REMOUVESOURCE to make the operation a move rather than a copy. +
error_mode : report errors to the progress_sync_callback, or simply abort +
overwrite_mode : controls whether the xfer engine will overwrite automatically, +skip the file, abort the operation, or query progress_sync_callback +
priority : a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. +
progress_update_callback : called periodically to keep the client appraised of progress +in completing the XFer operation, and the current phase of operation. +
update_callback_data : user data passed to progress_update_callback +
progress_sync_callback : called when the program requires responses to interactive queries +(e.g. overwriting files, handling errors, etc) +
sync_callback_data : user data passed to progress_sync_callback +
Returns : GNOME_VFS_OK if the paramaters were in order, +or GNOME_VFS_ERROR_BAD_PARAMETERS if something was wrong in the passed in arguments. +

gnome_vfs_async_find_directory ()

void        gnome_vfs_async_find_directory  (GnomeVFSAsyncHandle **handle_return,
+                                             GList *near_uri_list,
+                                             GnomeVFSFindDirectoryKind kind,
+                                             gboolean create_if_needed,
+                                             gboolean find_if_needed,
+                                             guint permissions,
+                                             int priority,
+                                             GnomeVFSAsyncFindDirectoryCallback callback,
+                                             gpointer user_data);

+There is quite a complicated logic behind finding/creating a Trash directory +and you need to be aware of some implications: +Finding the Trash the first time when using the file method may be pretty +expensive. A cache file is used to store the location of that Trash file +for next time. +If ceate_if_needed is specified without find_if_needed, you may end up +creating a Trash file when there already is one. Your app should start out +by doing a gnome_vfs_find_directory with the find_if_needed to avoid this +and then use the create_if_needed flag to create Trash lazily when it is +needed for throwing away an item on a given disk. +

+When the operation has completed, callback will be called with the result +of the operation and user_data.

+ +

handle_return : when the function returns will point to a handle for +
near_uri_list : a GList of GnomeVFSURIs, find a special directory on the same +volume as uris +
kind : kind of special directory +
create_if_needed : If directory we are looking for does not exist, try to create it +
find_if_needed : If we don't know where the directory is yet, look for it. +
permissions : If creating, use these permissions +
priority : a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. +
callback : function to be called when the operation is complete +
user_data : data to pass callback * +Used to return special directories such as Trash and Desktop from different +file systems. +

gnome_vfs_async_file_control ()

void        gnome_vfs_async_file_control    (GnomeVFSAsyncHandle *handle,
+                                             const char *operation,
+                                             gpointer operation_data,
+                                             GDestroyNotify operation_data_destroy_func,
+                                             GnomeVFSAsyncFileControlCallback callback,
+                                             gpointer callback_data);

+Execute a backend dependent operation specified by the string operation. +This is typically used for specialized vfs backends that need additional +operations that gnome-vfs doesn't have. Compare it to the unix call ioctl(). +The format of operation_data depends on the operation. Operation that are +backend specific are normally namespaced by their module name. +

+When the operation is complete, callback will be called with the +result of the operation, operation_data and callback_data.

+ +

handle : handle of the file to affect +
operation : The operation to execute +
operation_data : The data needed to execute the operation +
operation_data_destroy_func : Called to destroy operation_data when its no longer needed +
callback : function to be called when the operation is complete +
callback_data : data to pass callback +

Since 2.2 +

diff --git a/doc/html/gnome-vfs-20-gnome-vfs-cancellation.html b/doc/html/gnome-vfs-20-gnome-vfs-cancellation.html new file mode 100644 index 0000000..5906823 --- /dev/null +++ b/doc/html/gnome-vfs-20-gnome-vfs-cancellation.html @@ -0,0 +1,93 @@ +Cancellation

Cancellation

Cancellation — +halt in-progress operations

Synopsis

+
+
+
+GnomeVFSCancellation* gnome_vfs_cancellation_new
+                                            (void);
+void        gnome_vfs_cancellation_destroy  (GnomeVFSCancellation *cancellation);
+void        gnome_vfs_cancellation_cancel   (GnomeVFSCancellation *cancellation);
+gboolean    gnome_vfs_cancellation_check    (GnomeVFSCancellation *cancellation);
+void        gnome_vfs_cancellation_ack      (GnomeVFSCancellation *cancellation);
+gint        gnome_vfs_cancellation_get_fd   (GnomeVFSCancellation *cancellation);
+

Description

+ +

Details

gnome_vfs_cancellation_new ()

GnomeVFSCancellation* gnome_vfs_cancellation_new
+                                            (void);

+Create a new GnomeVFSCancellation object for reporting cancellation to a +GNOME VFS module.

+ +

Returns : A pointer to the new GnomeVFSCancellation object. +

gnome_vfs_cancellation_destroy ()

void        gnome_vfs_cancellation_destroy  (GnomeVFSCancellation *cancellation);

+Destroy cancellation.

+ +

cancellation : A GnomeVFSCancellation object +

gnome_vfs_cancellation_cancel ()

void        gnome_vfs_cancellation_cancel   (GnomeVFSCancellation *cancellation);

+Send a cancellation request through cancellation.

+ +

cancellation : A GnomeVFSCancellation object +

gnome_vfs_cancellation_check ()

gboolean    gnome_vfs_cancellation_check    (GnomeVFSCancellation *cancellation);

+Check for pending cancellation.

+ +

cancellation : A GnomeVFSCancellation object +
Returns : TRUE if the operation should be interrupted. +

gnome_vfs_cancellation_ack ()

void        gnome_vfs_cancellation_ack      (GnomeVFSCancellation *cancellation);

+Acknowledge a cancellation. This should be called if +`gnome_vfs_cancellation_check()' returns TRUE or if `select()' reports that +input is available on the file descriptor returned by +`gnome_vfs_cancellation_get_fd()'.

+ +

cancellation : A GnomeVFSCancellation object +

gnome_vfs_cancellation_get_fd ()

gint        gnome_vfs_cancellation_get_fd   (GnomeVFSCancellation *cancellation);

+Get a file descriptor -based notificator for cancellation. When +cancellation receives a cancellation request, a character will be made +available on the returned file descriptor for input. +

+This is very useful for detecting cancellation during I/O operations: you +can use the `select()' call to check for available input/output on the file +you are reading/writing, and on the notificator's file descriptor at the +same time. If a data is available on the notificator's file descriptor, you +know you have to cancel the read/write operation.

+ +

cancellation : A GnomeVFSCancellation object +
Returns : the notificator's file descriptor, or -1 if starved of + file descriptors. +
diff --git a/doc/html/gnome-vfs-20-gnome-vfs-context.html b/doc/html/gnome-vfs-20-gnome-vfs-context.html new file mode 100644 index 0000000..a2d3f70 --- /dev/null +++ b/doc/html/gnome-vfs-20-gnome-vfs-context.html @@ -0,0 +1,83 @@ +GnomeVFSContext

GnomeVFSContext

GnomeVFSContext — +contexts allows modules to track thread usage and cancellation properly

Synopsis

+
+
+
+GnomeVFSContext* gnome_vfs_context_new      (void);
+void        gnome_vfs_context_free          (GnomeVFSContext *ctx);
+GnomeVFSCancellation* gnome_vfs_context_get_cancellation
+                                            (const GnomeVFSContext *ctx);
+#define     gnome_vfs_context_check_cancellation(x)
+const GnomeVFSContext* gnome_vfs_context_peek_current
+                                            (void);
+gboolean    gnome_vfs_context_check_cancellation_current
+                                            (void);
+

Description

+ +

Details

gnome_vfs_context_new ()

GnomeVFSContext* gnome_vfs_context_new      (void);

+Creates a new context and cancellation object. Must be called +from the main glib event loop.

+ +

Returns : a newly allocated GnomeVFSContext +

gnome_vfs_context_free ()

void        gnome_vfs_context_free          (GnomeVFSContext *ctx);

+Free ctx and destroy the associated GnomeVFSCancellation.

+ +

ctx : context to be freed +

gnome_vfs_context_get_cancellation ()

GnomeVFSCancellation* gnome_vfs_context_get_cancellation
+                                            (const GnomeVFSContext *ctx);

+Retrieve the GnomeVFSCancellation associated with ctx.

+ +

ctx : context to get the GnomeVFSCancellation from +
Returns : ctx 's GnomeVFSCancellation +

gnome_vfs_context_check_cancellation()

#define     gnome_vfs_context_check_cancellation(x)

+ +

x : + + +

gnome_vfs_context_peek_current ()

const GnomeVFSContext* gnome_vfs_context_peek_current
+                                            (void);

+Get the currently active context. It shouldn't be +manipulated but can be compared to context's the module +holds to determine whether they are active.

+ +

Returns : the currently active GnomeVFSContext +

gnome_vfs_context_check_cancellation_current ()

gboolean    gnome_vfs_context_check_cancellation_current
+                                            (void);

+Check to see if the currently active context has been cancelled.

+ +

Returns : TRUE if the currently active context has been cancelled, otherwise FALSE +
diff --git a/doc/html/gnome-vfs-20-gnome-vfs-directory-basic-ops.html b/doc/html/gnome-vfs-20-gnome-vfs-directory-basic-ops.html new file mode 100644 index 0000000..ac424a0 --- /dev/null +++ b/doc/html/gnome-vfs-20-gnome-vfs-directory-basic-ops.html @@ -0,0 +1,89 @@ +Basic Directory Operations

Basic Directory Operations

Basic Directory Operations — +Creating and removing directories.

Synopsis

+
+
+
+GnomeVFSResult gnome_vfs_make_directory     (const gchar *text_uri,
+                                             guint perm);
+GnomeVFSResult gnome_vfs_make_directory_for_uri
+                                            (GnomeVFSURI *uri,
+                                             guint perm);
+GnomeVFSResult gnome_vfs_remove_directory   (const gchar *text_uri);
+GnomeVFSResult gnome_vfs_remove_directory_from_uri
+                                            (GnomeVFSURI *uri);
+

Description

+ +

Details

gnome_vfs_make_directory ()

GnomeVFSResult gnome_vfs_make_directory     (const gchar *text_uri,
+                                             guint perm);

+Create text_uri as a directory.

+ +

text_uri : URI of the directory to be created +
perm : Unix-style permissions for the newly created directory +
Returns : An integer representing the result of the operation +

gnome_vfs_make_directory_for_uri ()

GnomeVFSResult gnome_vfs_make_directory_for_uri
+                                            (GnomeVFSURI *uri,
+                                             guint perm);

+Create a directory at uri. Only succeeds if a file or directory +does not already exist at uri.

+ +

uri : URI of the directory to be created +
perm : Unix-style permissions for the newly created directory +
Returns : An integer representing the result of the operation +

gnome_vfs_remove_directory ()

GnomeVFSResult gnome_vfs_remove_directory   (const gchar *text_uri);

+Remove text_uri. text_uri must be an empty directory.

+ +

text_uri : URI of the directory to be removed +
Returns : An integer representing the result of the operation +

gnome_vfs_remove_directory_from_uri ()

GnomeVFSResult gnome_vfs_remove_directory_from_uri
+                                            (GnomeVFSURI *uri);

+Remove uri. uri must be an empty directory.

+ +

uri : URI of the directory to be removed +
Returns : An integer representing the result of the operation +
diff --git a/doc/html/gnome-vfs-20-gnome-vfs-directory-find-ops.html b/doc/html/gnome-vfs-20-gnome-vfs-directory-find-ops.html new file mode 100644 index 0000000..76ffc29 --- /dev/null +++ b/doc/html/gnome-vfs-20-gnome-vfs-directory-find-ops.html @@ -0,0 +1,90 @@ +Locating Standard Directories

Locating Standard Directories

Locating Standard Directories — +Utilities for locating standard directories such as the desktop and trash

Synopsis

+
+
+
+enum        GnomeVFSFindDirectoryKind;
+GnomeVFSResult gnome_vfs_find_directory     (GnomeVFSURI *near_uri,
+                                             GnomeVFSFindDirectoryKind kind,
+                                             GnomeVFSURI **result,
+                                             gboolean create_if_needed,
+                                             gboolean find_if_needed,
+                                             guint permissions);
+

Description

+ +

Details

enum GnomeVFSFindDirectoryKind

typedef enum {
+	GNOME_VFS_DIRECTORY_KIND_DESKTOP = 1000,
+	GNOME_VFS_DIRECTORY_KIND_TRASH = 1001
+} GnomeVFSFindDirectoryKind;
+

+ +


gnome_vfs_find_directory ()

GnomeVFSResult gnome_vfs_find_directory     (GnomeVFSURI *near_uri,
+                                             GnomeVFSFindDirectoryKind kind,
+                                             GnomeVFSURI **result,
+                                             gboolean create_if_needed,
+                                             gboolean find_if_needed,
+                                             guint permissions);

+Used to return well known directories such as Trash, Desktop, etc. from different +file systems. +

+There is quite a complicated logic behind finding/creating a Trash directory +and you need to be aware of some implications: +Finding the Trash the first time when using the file method may be pretty +expensive. A cache file is used to store the location of that Trash file +for next time. +If ceate_if_needed is specified without find_if_needed, you may end up +creating a Trash file when there already is one. Your app should start out +by doing a gnome_vfs_find_directory with the find_if_needed to avoid this +and then use the create_if_needed flag to create Trash lazily when it is +needed for throwing away an item on a given disk.

+ +

near_uri : find a well known directory on the same volume as near_uri +
kind : kind of well known directory +
result : newly created URI of the directory we found +
create_if_needed : If directory we are looking for does not exist, try to create it +
find_if_needed : If we don't know where trash is yet, look for it. +
permissions : If creating, use these permissions +
Returns : An integer representing the result of the operation +
diff --git a/doc/html/gnome-vfs-20-gnome-vfs-directory-list-ops.html b/doc/html/gnome-vfs-20-gnome-vfs-directory-list-ops.html new file mode 100644 index 0000000..b09c6de --- /dev/null +++ b/doc/html/gnome-vfs-20-gnome-vfs-directory-list-ops.html @@ -0,0 +1,286 @@ +Listing Directory Contents

Listing Directory Contents

Listing Directory Contents — +Listing the contents of directories.

Synopsis

+
+
+
+enum        GnomeVFSDirectoryVisitOptions;
+gboolean    (*GnomeVFSDirectoryVisitFunc)   (const gchar *rel_path,
+                                             GnomeVFSFileInfo *info,
+                                             gboolean recursing_will_loop,
+                                             gpointer data,
+                                             gboolean *recurse);
+GnomeVFSResult gnome_vfs_directory_open     (GnomeVFSDirectoryHandle **handle,
+                                             const gchar *text_uri,
+                                             GnomeVFSFileInfoOptions options);
+GnomeVFSResult gnome_vfs_directory_open_from_uri
+                                            (GnomeVFSDirectoryHandle **handle,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSFileInfoOptions options);
+GnomeVFSResult gnome_vfs_directory_read_next
+                                            (GnomeVFSDirectoryHandle *handle,
+                                             GnomeVFSFileInfo *file_info);
+GnomeVFSResult gnome_vfs_directory_close    (GnomeVFSDirectoryHandle *handle);
+GnomeVFSResult gnome_vfs_directory_visit    (const gchar *uri,
+                                             GnomeVFSFileInfoOptions info_options,
+                                             GnomeVFSDirectoryVisitOptions visit_options,
+                                             GnomeVFSDirectoryVisitFunc callback,
+                                             gpointer data);
+GnomeVFSResult gnome_vfs_directory_visit_uri
+                                            (GnomeVFSURI *uri,
+                                             GnomeVFSFileInfoOptions info_options,
+                                             GnomeVFSDirectoryVisitOptions visit_options,
+                                             GnomeVFSDirectoryVisitFunc callback,
+                                             gpointer data);
+GnomeVFSResult gnome_vfs_directory_visit_files
+                                            (const gchar *text_uri,
+                                             GList *file_list,
+                                             GnomeVFSFileInfoOptions info_options,
+                                             GnomeVFSDirectoryVisitOptions visit_options,
+                                             GnomeVFSDirectoryVisitFunc callback,
+                                             gpointer data);
+GnomeVFSResult gnome_vfs_directory_visit_files_at_uri
+                                            (GnomeVFSURI *uri,
+                                             GList *file_list,
+                                             GnomeVFSFileInfoOptions info_options,
+                                             GnomeVFSDirectoryVisitOptions visit_options,
+                                             GnomeVFSDirectoryVisitFunc callback,
+                                             gpointer data);
+GnomeVFSResult gnome_vfs_directory_list_load
+                                            (GList **list,
+                                             const gchar *text_uri,
+                                             GnomeVFSFileInfoOptions options);
+

Description

+ +

Details

enum GnomeVFSDirectoryVisitOptions

typedef enum {
+	GNOME_VFS_DIRECTORY_VISIT_DEFAULT = 0,
+	GNOME_VFS_DIRECTORY_VISIT_SAMEFS = 1 << 0,
+	GNOME_VFS_DIRECTORY_VISIT_LOOPCHECK = 1 << 1
+} GnomeVFSDirectoryVisitOptions;
+

+This options control the way in which directories are visited.

+ +

GNOME_VFS_DIRECTORY_VISIT_DEFAULT +
GNOME_VFS_DIRECTORY_VISIT_SAMEFS Visit only directories on the same +file system as the parent +
GNOME_VFS_DIRECTORY_VISIT_LOOPCHECK Loop prevention +

GnomeVFSDirectoryVisitFunc ()

gboolean    (*GnomeVFSDirectoryVisitFunc)   (const gchar *rel_path,
+                                             GnomeVFSFileInfo *info,
+                                             gboolean recursing_will_loop,
+                                             gpointer data,
+                                             gboolean *recurse);

+ +

rel_path : +
info : +
recursing_will_loop : +
data : +
recurse : +
Returns : + + +

gnome_vfs_directory_open ()

GnomeVFSResult gnome_vfs_directory_open     (GnomeVFSDirectoryHandle **handle,
+                                             const gchar *text_uri,
+                                             GnomeVFSFileInfoOptions options);

+Open directory text_uri for reading. On return, @*handle will point to +a GnomeVFSDirectoryHandle object which can be used to read the directory +entries one by one.

+ +

handle : A pointer to a pointer to a GnomeVFSDirectoryHandle object +
text_uri : String representing the URI to open +
options : Options for reading file information +
Returns : An integer representing the result of the operation +

gnome_vfs_directory_open_from_uri ()

GnomeVFSResult gnome_vfs_directory_open_from_uri
+                                            (GnomeVFSDirectoryHandle **handle,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSFileInfoOptions options);

+Open directory text_uri for reading. On return, @*handle will point to +a GnomeVFSDirectoryHandle object which can be used to read the directory +entries one by one.

+ +

handle : A pointer to a pointer to a GnomeVFSDirectoryHandle object +
uri : URI to open +
options : Options for reading file information +
Returns : An integer representing the result of the operation. +

gnome_vfs_directory_read_next ()

GnomeVFSResult gnome_vfs_directory_read_next
+                                            (GnomeVFSDirectoryHandle *handle,
+                                             GnomeVFSFileInfo *file_info);

+Read the next directory entry from handle.

+ +

handle : A directory handle +
file_info : Pointer to a GnomeVFSFileInfo struct where the data about +the entry will be stored +
Returns : An integer value representing the result of the operation. +

gnome_vfs_directory_close ()

GnomeVFSResult gnome_vfs_directory_close    (GnomeVFSDirectoryHandle *handle);

+Close handle.

+ +

handle : A directory handle. +
Returns : An integer representing the result of the operation. +

gnome_vfs_directory_visit ()

GnomeVFSResult gnome_vfs_directory_visit    (const gchar *uri,
+                                             GnomeVFSFileInfoOptions info_options,
+                                             GnomeVFSDirectoryVisitOptions visit_options,
+                                             GnomeVFSDirectoryVisitFunc callback,
+                                             gpointer data);

+Visit uri, retrieving information as specified by info_options.

+ +

uri : URI to start from +
info_options : Options specifying what kind of file information must be +retrieved +
visit_options : Options specifying the type of visit +
callback : Callback to be called for every visited file +
data : Data to be passed to callback at each iteration +
Returns : +

gnome_vfs_directory_visit_uri ()

GnomeVFSResult gnome_vfs_directory_visit_uri
+                                            (GnomeVFSURI *uri,
+                                             GnomeVFSFileInfoOptions info_options,
+                                             GnomeVFSDirectoryVisitOptions visit_options,
+                                             GnomeVFSDirectoryVisitFunc callback,
+                                             gpointer data);

+Visit uri, retrieving information as specified by info_options.

+ +

uri : URI to start from +
info_options : Options specifying what kind of file information must be +retrieved +
visit_options : Options specifying the type of visit +
callback : Callback to be called for every visited file +
data : Data to be passed to callback at each iteration +
Returns : A result code indicating whether the operation succeeded. + +

gnome_vfs_directory_visit_files ()

GnomeVFSResult gnome_vfs_directory_visit_files
+                                            (const gchar *text_uri,
+                                             GList *file_list,
+                                             GnomeVFSFileInfoOptions info_options,
+                                             GnomeVFSDirectoryVisitOptions visit_options,
+                                             GnomeVFSDirectoryVisitFunc callback,
+                                             gpointer data);

+Fetches information about a list of files in a base URI uri.

+ +

text_uri : string representing the URI of a directory to "visit" the files in +
file_list : GList of char *s of file names in uri to visit +
info_options : bitmask controlling the type of information to fetch +
visit_options : options controlling e.g. loop prevention, and filesystem checks. +Affects the way visiting is done. +
callback : function to call with the file info structs +
data : data to pass to callback. +
Returns : a GnomeVFSResult indication the success of the operation +

gnome_vfs_directory_visit_files_at_uri ()

GnomeVFSResult gnome_vfs_directory_visit_files_at_uri
+                                            (GnomeVFSURI *uri,
+                                             GList *file_list,
+                                             GnomeVFSFileInfoOptions info_options,
+                                             GnomeVFSDirectoryVisitOptions visit_options,
+                                             GnomeVFSDirectoryVisitFunc callback,
+                                             gpointer data);

+Fetches information about a list of files in a base URI uri.

+ +

uri : URI of a directory to "visit" the files in +
file_list : GList of char *s of file names in uri to visit +
info_options : bitmask controlling the type of information to fetch +
visit_options : options controlling e.g. loop prevention, and filesystem checks. +Affects the way visiting is done. +
callback : function to call with the file info structs +
data : data to pass to callback. +
Returns : a GnomeVFSResult indication the success of the operation +

gnome_vfs_directory_list_load ()

GnomeVFSResult gnome_vfs_directory_list_load
+                                            (GList **list,
+                                             const gchar *text_uri,
+                                             GnomeVFSFileInfoOptions options);

+Load a directory from text_uri with the specified options +into a list.

+ +

list : An address of a pointer to a list of GnomeVFSFileInfo +
text_uri : A text URI +
options : Options for loading the directory +
Returns : An integer representing the result of the operation. +
diff --git a/doc/html/gnome-vfs-20-gnome-vfs-file-advanced-ops.html b/doc/html/gnome-vfs-20-gnome-vfs-file-advanced-ops.html new file mode 100644 index 0000000..9898854 --- /dev/null +++ b/doc/html/gnome-vfs-20-gnome-vfs-file-advanced-ops.html @@ -0,0 +1,57 @@ +Advanced File Operations

Advanced File Operations

Advanced File Operations —

Synopsis

+
+
+
+GnomeVFSResult gnome_vfs_file_control       (GnomeVFSHandle *handle,
+                                             const char *operation,
+                                             gpointer operation_data);
+

Description

+ +

Details

gnome_vfs_file_control ()

GnomeVFSResult gnome_vfs_file_control       (GnomeVFSHandle *handle,
+                                             const char *operation,
+                                             gpointer operation_data);

+Execute a backend dependent operation specified by the string operation. +This is typically used for specialized vfs backends that need additional +operations that gnome-vfs doesn't have. Compare it to the unix call ioctl(). +The format of operation_data depends on the operation. Operation that are +backend specific are normally namespaced by their module name.

+ +

handle : handle of the file to affect +
operation : The operation to execute +
operation_data : The data needed to execute the operation +
Returns : an integer representing the success of the operation +
diff --git a/doc/html/gnome-vfs-20-gnome-vfs-file-basic-ops.html b/doc/html/gnome-vfs-20-gnome-vfs-file-basic-ops.html new file mode 100644 index 0000000..d273dec --- /dev/null +++ b/doc/html/gnome-vfs-20-gnome-vfs-file-basic-ops.html @@ -0,0 +1,278 @@ +Basic File Operations

Basic File Operations

Basic File Operations —

Synopsis

+
+
+
+enum        GnomeVFSOpenMode;
+GnomeVFSResult gnome_vfs_create             (GnomeVFSHandle **handle,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm);
+GnomeVFSResult gnome_vfs_create_uri         (GnomeVFSHandle **handle,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm);
+GnomeVFSResult gnome_vfs_open               (GnomeVFSHandle **handle,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode);
+GnomeVFSResult gnome_vfs_open_uri           (GnomeVFSHandle **handle,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode);
+GnomeVFSResult gnome_vfs_close              (GnomeVFSHandle *handle);
+GnomeVFSResult gnome_vfs_unlink             (const gchar *text_uri);
+GnomeVFSResult gnome_vfs_unlink_from_uri    (GnomeVFSURI *uri);
+GnomeVFSResult gnome_vfs_move_uri           (GnomeVFSURI *old_uri,
+                                             GnomeVFSURI *new_uri,
+                                             gboolean force_replace);
+GnomeVFSResult gnome_vfs_move               (const gchar *old_text_uri,
+                                             const gchar *new_text_uri,
+                                             gboolean force_replace);
+GnomeVFSResult gnome_vfs_check_same_fs_uris (GnomeVFSURI *source_uri,
+                                             GnomeVFSURI *target_uri,
+                                             gboolean *same_fs_return);
+GnomeVFSResult gnome_vfs_check_same_fs      (const gchar *source,
+                                             const gchar *target,
+                                             gboolean *same_fs_return);
+gboolean    gnome_vfs_uri_exists            (GnomeVFSURI *uri);
+GnomeVFSResult gnome_vfs_create_symbolic_link
+                                            (GnomeVFSURI *uri,
+                                             const gchar *target_reference);
+

Description

+ +

Details

enum GnomeVFSOpenMode

typedef enum {
+        GNOME_VFS_OPEN_NONE = 0,
+        GNOME_VFS_OPEN_READ = 1 << 0,
+        GNOME_VFS_OPEN_WRITE = 1 << 1,
+        GNOME_VFS_OPEN_RANDOM = 1 << 2
+} GnomeVFSOpenMode;
+

+Mode in which files are opened. If GNOME_VFS_OPEN_RANDOM is not used, the +file will be have to be accessed sequentially.

+ +


gnome_vfs_create ()

GnomeVFSResult gnome_vfs_create             (GnomeVFSHandle **handle,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm);

+Create uri according to mode open_mode. On return, handle will then +contain a pointer to a handle for the open file.

+ +

handle : A pointer to a pointer to a GnomeVFSHandle object +
text_uri : String representing the URI to create +
open_mode : mode to leave the file opened in after creation (or GNOME_VFS_OPEN_MODE_NONE +to leave the file closed after creation) +
exclusive : Whether the file should be created in "exclusive" mode: +i.e. if this flag is nonzero, operation will fail if a file with the +same name already exists. +
perm : Bitmap representing the permissions for the newly created file +(Unix style). +
Returns : An integer representing the result of the operation +

gnome_vfs_create_uri ()

GnomeVFSResult gnome_vfs_create_uri         (GnomeVFSHandle **handle,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm);

+Create uri according to mode open_mode. On return, handle will then +contain a pointer to a handle for the open file.

+ +

handle : A pointer to a pointer to a GnomeVFSHandle object +
uri : URI for the file to create +
open_mode : Open mode +
exclusive : Whether the file should be created in "exclusive" mode: +i.e. if this flag is nonzero, operation will fail if a file with the +same name already exists. +
perm : Bitmap representing the permissions for the newly created file +(Unix style). +
Returns : An integer representing the result of the operation +

gnome_vfs_open ()

GnomeVFSResult gnome_vfs_open               (GnomeVFSHandle **handle,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode);

+Open text_uri according to mode open_mode. On return, handle will then +contain a pointer to a handle for the open file.

+ +

handle : A pointer to a pointer to a GnomeVFSHandle object +
text_uri : String representing the URI to open +
open_mode : Open mode +
Returns : An integer representing the result of the operation +

gnome_vfs_open_uri ()

GnomeVFSResult gnome_vfs_open_uri           (GnomeVFSHandle **handle,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode);

+Open uri according to mode open_mode. On return, handle will then +contain a pointer to a handle for the open file.

+ +

handle : A pointer to a pointer to a GnomeVFSHandle object +
uri : URI to open +
open_mode : Open mode +
Returns : An integer representing the result of the operation +

gnome_vfs_close ()

GnomeVFSResult gnome_vfs_close              (GnomeVFSHandle *handle);

+Close file associated with handle.

+ +

handle : A pointer to a GnomeVFSHandle object +
Returns : An integer representing the result of the operation. +

gnome_vfs_unlink ()

GnomeVFSResult gnome_vfs_unlink             (const gchar *text_uri);

+Unlink text_uri (i.e. delete the file).

+ +

text_uri : URI of the file to be unlinked +
Returns : An integer representing the result of the operation +

gnome_vfs_unlink_from_uri ()

GnomeVFSResult gnome_vfs_unlink_from_uri    (GnomeVFSURI *uri);

+Unlink uri (i.e. delete the file).

+ +

uri : URI of the file to be unlinked +
Returns : An integer representing the result of the operation +

gnome_vfs_move_uri ()

GnomeVFSResult gnome_vfs_move_uri           (GnomeVFSURI *old_uri,
+                                             GnomeVFSURI *new_uri,
+                                             gboolean force_replace);

+Move a file from URI old_uri to new_uri. This will only work if old_uri +and new_uri are on the same file system. Otherwise, it is necessary +to use the more general %gnome_vfs_xfer_uri() function.

+ +

old_uri : Source URI +
new_uri : Destination URI +
force_replace : If TRUE, move target to new_uri even if there +is already a file at new_uri. If there is a file, it will be discarded. +
Returns : An integer representing the result of the operation. +

gnome_vfs_move ()

GnomeVFSResult gnome_vfs_move               (const gchar *old_text_uri,
+                                             const gchar *new_text_uri,
+                                             gboolean force_replace);

+Move a file from URI old_text_uri to new_text_uri. This will only work +if old_text_uri and new_text_uri are on the same file system. Otherwise, +it is necessary to use the more general %gnome_vfs_xfer_uri() function.

+ +

old_text_uri : Source URI +
new_text_uri : Destination URI +
force_replace : if TRUE, perform the operation even if it unlinks an existing +file at new_text_uri +
Returns : An integer representing the result of the operation. +

gnome_vfs_check_same_fs_uris ()

GnomeVFSResult gnome_vfs_check_same_fs_uris (GnomeVFSURI *source_uri,
+                                             GnomeVFSURI *target_uri,
+                                             gboolean *same_fs_return);

+Check if source_uri and target_uri are on the same file system.

+ +

source_uri : A URI +
target_uri : Another URI +
same_fs_return : Pointer to a boolean variable which will be set to TRUE +if source_uri and target_uri are on the same file system on return. +
Returns : An integer representing the result of the operation. +

gnome_vfs_check_same_fs ()

GnomeVFSResult gnome_vfs_check_same_fs      (const gchar *source,
+                                             const gchar *target,
+                                             gboolean *same_fs_return);

+Return TRUE if source and target are on the same file system.

+ +

source : A URI +
target : Another URI +
same_fs_return : Pointer to a boolean variable which will be set to TRUE +
Returns : An integer representing the result of the operation. +

gnome_vfs_uri_exists ()

gboolean    gnome_vfs_uri_exists            (GnomeVFSURI *uri);

+Check if the URI points to an existing entity.

+ +

uri : A URI +
Returns : TRUE if URI exists. +

gnome_vfs_create_symbolic_link ()

GnomeVFSResult gnome_vfs_create_symbolic_link
+                                            (GnomeVFSURI *uri,
+                                             const gchar *target_reference);

+Creates a symbolic link, or eventually, a URI link (as necessary) +at uri pointing to target_reference

+ +

uri : URI to create a link at +
target_reference : URI "reference" to point the link to (URI or relative path) +
Returns : An integer representing the result of the operation +
diff --git a/doc/html/gnome-vfs-20-gnome-vfs-file-info-ops.html b/doc/html/gnome-vfs-20-gnome-vfs-file-info-ops.html new file mode 100644 index 0000000..3f8fdbb --- /dev/null +++ b/doc/html/gnome-vfs-20-gnome-vfs-file-info-ops.html @@ -0,0 +1,130 @@ +Getting and Setting File Information

Getting and Setting File Information

Getting and Setting File Information —

Description

+ Applications can use the gnome_vfs_get_file_info family of operations to + retrieve file information, as this operation can be quite costly in + terms of time (specilly when sniffing the MIME type) applications can + specify which information need at any time, reducing the performance + impact. +

+ All of these operations use a GnomeVFSFileInfo data structure that holds + the file information, there are several methods that can be used to + manipulate this information. See GnomeVFSFileInfo for more information. +

Details

gnome_vfs_get_file_info ()

GnomeVFSResult gnome_vfs_get_file_info      (const gchar *text_uri,
+                                             GnomeVFSFileInfo *info,
+                                             GnomeVFSFileInfoOptions options);

+Retrieve information about text_uri. The information will be stored in +info.

+ +

text_uri : URI of the file for which information will be retrieved +
info : Pointer to a GnomeVFSFileInfo object that will hold the information +for the file on return +
options : Options for retrieving file information +to retrieve for the file +
Returns : An integer representing the result of the operation +

gnome_vfs_get_file_info_uri ()

GnomeVFSResult gnome_vfs_get_file_info_uri  (GnomeVFSURI *uri,
+                                             GnomeVFSFileInfo *info,
+                                             GnomeVFSFileInfoOptions options);

+Retrieve information about text_uri. The information will be stored in +info.

+ +

uri : URI of the file for which information will be retrieved +
info : Pointer to a GnomeVFSFileInfo object that will hold the information +for the file on return +
options : Options for retrieving file information +to retrieve for the file +
Returns : An integer representing the result of the operation +

gnome_vfs_get_file_info_from_handle ()

GnomeVFSResult gnome_vfs_get_file_info_from_handle
+                                            (GnomeVFSHandle *handle,
+                                             GnomeVFSFileInfo *info,
+                                             GnomeVFSFileInfoOptions options);

+Retrieve information about an open file. The information will be stored in +info.

+ +

handle : Handle of the file for which information must be retrieved +
info : Pointer to a GnomeVFSFileInfo object that will hold the information +for the file on return +
options : Options for retrieving file information +to retrieve for the file +
Returns : An integer representing the result of the operation +

gnome_vfs_set_file_info_uri ()

GnomeVFSResult gnome_vfs_set_file_info_uri  (GnomeVFSURI *uri,
+                                             GnomeVFSFileInfo *info,
+                                             GnomeVFSSetFileInfoMask mask);

+Set file information for uri; only the information for which the +corresponding bit in mask is set is actually modified.

+ +

uri : A URI +
info : Information that must be set for the file +
mask : Bit mask representing which fields of info need to be set +
Returns : An integer representing the result of the operation. +

gnome_vfs_set_file_info ()

GnomeVFSResult gnome_vfs_set_file_info      (const gchar *text_uri,
+                                             GnomeVFSFileInfo *info,
+                                             GnomeVFSSetFileInfoMask mask);

+Set file information for uri; only the information for which the +corresponding bit in mask is set is actually modified.

+ +

text_uri : A URI +
info : Information that must be set for the file +
mask : Bit mask representing which fields of info need to be set +
Returns : An integer representing the result of the operation. +

See Also

+ +

+ +

diff --git a/doc/html/gnome-vfs-20-gnome-vfs-file-info.html b/doc/html/gnome-vfs-20-gnome-vfs-file-info.html new file mode 100644 index 0000000..5d47d8b --- /dev/null +++ b/doc/html/gnome-vfs-20-gnome-vfs-file-info.html @@ -0,0 +1,438 @@ +GnomeVFSFileInfo

GnomeVFSFileInfo

GnomeVFSFileInfo — +stores information about files, GnomeVFS equivalent of stat

Synopsis

+
+
+
+enum        GnomeVFSFileFlags;
+enum        GnomeVFSFileType;
+enum        GnomeVFSFileInfoFields;
+enum        GnomeVFSFilePermissions;
+enum        GnomeVFSFileInfoOptions;
+enum        GnomeVFSSetFileInfoMask;
+typedef     GnomeVFSGetFileInfoResult;
+typedef     GnomeVFSInodeNumber;
+typedef     GnomeVFSFileInfo;
+#define     GNOME_VFS_FILE_INFO_SYMLINK     (info)
+#define     GNOME_VFS_FILE_INFO_SET_SYMLINK (info, value)
+#define     GNOME_VFS_FILE_INFO_LOCAL       (info)
+#define     GNOME_VFS_FILE_INFO_SET_LOCAL   (info, value)
+#define     GNOME_VFS_FILE_INFO_SUID        (info)
+#define     GNOME_VFS_FILE_INFO_SGID        (info)
+#define     GNOME_VFS_FILE_INFO_STICKY      (info)
+#define     GNOME_VFS_FILE_INFO_SET_SUID    (info, value)
+#define     GNOME_VFS_FILE_INFO_SET_SGID    (info, value)
+#define     GNOME_VFS_FILE_INFO_SET_STICKY  (info, value)
+GnomeVFSFileInfo* gnome_vfs_file_info_new   (void);
+void        gnome_vfs_file_info_unref       (GnomeVFSFileInfo *info);
+void        gnome_vfs_file_info_ref         (GnomeVFSFileInfo *info);
+void        gnome_vfs_file_info_clear       (GnomeVFSFileInfo *info);
+const char* gnome_vfs_file_info_get_mime_type
+                                            (GnomeVFSFileInfo *info);
+void        gnome_vfs_file_info_copy        (GnomeVFSFileInfo *dest,
+                                             const GnomeVFSFileInfo *src);
+GnomeVFSFileInfo* gnome_vfs_file_info_dup   (const GnomeVFSFileInfo *orig);
+gboolean    gnome_vfs_file_info_matches     (const GnomeVFSFileInfo *a,
+                                             const GnomeVFSFileInfo *b);
+GList*      gnome_vfs_file_info_list_ref    (GList *list);
+GList*      gnome_vfs_file_info_list_unref  (GList *list);
+GList*      gnome_vfs_file_info_list_copy   (GList *list);
+void        gnome_vfs_file_info_list_free   (GList *list);
+

Description

+ +

Details

enum GnomeVFSFileFlags

typedef enum {
+	GNOME_VFS_FILE_FLAGS_NONE = 0,
+	GNOME_VFS_FILE_FLAGS_SYMLINK = 1 << 0,
+	GNOME_VFS_FILE_FLAGS_LOCAL = 1 << 1
+} GnomeVFSFileFlags;
+

+Packed boolean bitfield representing special +flags a GnomeVFSFileInfo struct can have.

+ +

GNOME_VFS_FILE_FLAGS_NONE no flags +
GNOME_VFS_FILE_FLAGS_SYMLINK whether the file is a symlink. +
GNOME_VFS_FILE_FLAGS_LOCAL whether the file is on a local filesystem +

enum GnomeVFSFileType

typedef enum {
+	GNOME_VFS_FILE_TYPE_UNKNOWN,
+	GNOME_VFS_FILE_TYPE_REGULAR,
+	GNOME_VFS_FILE_TYPE_DIRECTORY,
+	GNOME_VFS_FILE_TYPE_FIFO,
+	GNOME_VFS_FILE_TYPE_SOCKET,
+	GNOME_VFS_FILE_TYPE_CHARACTER_DEVICE,
+	GNOME_VFS_FILE_TYPE_BLOCK_DEVICE,
+	GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK
+} GnomeVFSFileType;
+

+Identifies the kind of file represented by a GnomeVFSFileInfo struct. (note, +use of MIME types is preferred as this field may eventually disappear)

+ +


enum GnomeVFSFileInfoFields

typedef enum {
+	GNOME_VFS_FILE_INFO_FIELDS_NONE = 0,
+	GNOME_VFS_FILE_INFO_FIELDS_TYPE = 1 << 0,
+	GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS = 1 << 1,
+	GNOME_VFS_FILE_INFO_FIELDS_FLAGS = 1 << 2,
+	GNOME_VFS_FILE_INFO_FIELDS_DEVICE = 1 << 3,
+	GNOME_VFS_FILE_INFO_FIELDS_INODE = 1 << 4,
+	GNOME_VFS_FILE_INFO_FIELDS_LINK_COUNT = 1 << 5,
+	GNOME_VFS_FILE_INFO_FIELDS_SIZE = 1 << 6,
+	GNOME_VFS_FILE_INFO_FIELDS_BLOCK_COUNT = 1 << 7,
+	GNOME_VFS_FILE_INFO_FIELDS_IO_BLOCK_SIZE = 1 << 8,
+	GNOME_VFS_FILE_INFO_FIELDS_ATIME = 1 << 9,
+	GNOME_VFS_FILE_INFO_FIELDS_MTIME = 1 << 10,
+	GNOME_VFS_FILE_INFO_FIELDS_CTIME = 1 << 11,
+	GNOME_VFS_FILE_INFO_FIELDS_SYMLINK_NAME = 1 << 12,
+	GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE = 1 << 13,
+	GNOME_VFS_FILE_INFO_FIELDS_ACCESS = 1 << 14
+} GnomeVFSFileInfoFields;
+

+Flags indicating what fields in a GnomeVFSFileInfo struct are valid. +Name is always assumed valid (how else would you have gotten a +FileInfo struct otherwise?)

+ +

GNOME_VFS_FILE_INFO_FIELDS_NONE No fields are valid +
GNOME_VFS_FILE_INFO_FIELDS_TYPE Type field is valid +
GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS Permissions field is valid +
GNOME_VFS_FILE_INFO_FIELDS_FLAGS Flags field is valid +
GNOME_VFS_FILE_INFO_FIELDS_DEVICE Device field is valid +
GNOME_VFS_FILE_INFO_FIELDS_INODE Inode field is valid +
GNOME_VFS_FILE_INFO_FIELDS_LINK_COUNT Link count field is valid +
GNOME_VFS_FILE_INFO_FIELDS_SIZE Size field is valid +
GNOME_VFS_FILE_INFO_FIELDS_BLOCK_COUNT Block count field is valid +
GNOME_VFS_FILE_INFO_FIELDS_IO_BLOCK_SIZE I/O Block Size field is valid +
GNOME_VFS_FILE_INFO_FIELDS_ATIME Access time field is valid +
GNOME_VFS_FILE_INFO_FIELDS_MTIME Modification time field is valid +
GNOME_VFS_FILE_INFO_FIELDS_CTIME Creating time field is valid +
GNOME_VFS_FILE_INFO_FIELDS_SYMLINK_NAME Symlink name field is valid +
GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE Mime type field is valid +
GNOME_VFS_FILE_INFO_FIELDS_ACCESS Access bits of the permissions +bitfield are valid +

enum GnomeVFSFilePermissions

typedef enum {
+	GNOME_VFS_PERM_SUID = S_ISUID,
+	GNOME_VFS_PERM_SGID = S_ISGID,	
+	GNOME_VFS_PERM_STICKY = 01000,	/* S_ISVTX not defined on all systems */
+	GNOME_VFS_PERM_USER_READ = S_IRUSR,
+	GNOME_VFS_PERM_USER_WRITE = S_IWUSR,
+	GNOME_VFS_PERM_USER_EXEC = S_IXUSR,
+	GNOME_VFS_PERM_USER_ALL = S_IRUSR | S_IWUSR | S_IXUSR,
+	GNOME_VFS_PERM_GROUP_READ = S_IRGRP,
+	GNOME_VFS_PERM_GROUP_WRITE = S_IWGRP,
+	GNOME_VFS_PERM_GROUP_EXEC = S_IXGRP,
+	GNOME_VFS_PERM_GROUP_ALL = S_IRGRP | S_IWGRP | S_IXGRP,
+	GNOME_VFS_PERM_OTHER_READ = S_IROTH,
+	GNOME_VFS_PERM_OTHER_WRITE = S_IWOTH,
+	GNOME_VFS_PERM_OTHER_EXEC = S_IXOTH,
+	GNOME_VFS_PERM_OTHER_ALL = S_IROTH | S_IWOTH | S_IXOTH,
+	GNOME_VFS_PERM_ACCESS_READABLE   = 1 << 16,
+	GNOME_VFS_PERM_ACCESS_WRITABLE   = 1 << 17,
+	GNOME_VFS_PERM_ACCESS_EXECUTABLE = 1 << 18
+} GnomeVFSFilePermissions;
+

+File permissions. These are the same as the Unix ones, but we wrap them +into a nicer VFS-like enum.

+ +

GNOME_VFS_PERM_SUID UID bit +
GNOME_VFS_PERM_SGID GID bit +
GNOME_VFS_PERM_STICKY Sticky bit. +
GNOME_VFS_PERM_USER_READ Owner has read permission +
GNOME_VFS_PERM_USER_WRITE Owner has write permission +
GNOME_VFS_PERM_USER_EXEC Owner has execution permission +
GNOME_VFS_PERM_USER_ALL Owner has all permissions +
GNOME_VFS_PERM_GROUP_READ Group has read permission +
GNOME_VFS_PERM_GROUP_WRITE Group has write permission +
GNOME_VFS_PERM_GROUP_EXEC Group has execution permission +
GNOME_VFS_PERM_GROUP_ALL Group has all permissions +
GNOME_VFS_PERM_OTHER_READ Others have read permission +
GNOME_VFS_PERM_OTHER_WRITE Others have write permission +
GNOME_VFS_PERM_OTHER_EXEC Others have execution permission +
GNOME_VFS_PERM_OTHER_ALL Others have all permissions +
GNOME_VFS_PERM_ACCESS_READABLE +
GNOME_VFS_PERM_ACCESS_WRITABLE +
GNOME_VFS_PERM_ACCESS_EXECUTABLE +

enum GnomeVFSFileInfoOptions

typedef enum {
+	GNOME_VFS_FILE_INFO_DEFAULT = 0,
+	GNOME_VFS_FILE_INFO_GET_MIME_TYPE = 1 << 0,
+	GNOME_VFS_FILE_INFO_FORCE_FAST_MIME_TYPE = 1 << 1,
+	GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE = 1 << 2,
+	GNOME_VFS_FILE_INFO_FOLLOW_LINKS = 1 << 3,
+	GNOME_VFS_FILE_INFO_GET_ACCESS_RIGHTS = 1 << 4
+} GnomeVFSFileInfoOptions;
+

+Packed boolean bitfield representing options that can +be passed into a gnome_vfs_get_file_info() call (or other +related calls that return file info) and affect the operation +of get_file_info.

+ +

GNOME_VFS_FILE_INFO_DEFAULT default flags +
GNOME_VFS_FILE_INFO_GET_MIME_TYPE detect the MIME type +
GNOME_VFS_FILE_INFO_FORCE_FAST_MIME_TYPE only use fast MIME type +detection (extensions) +
GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE force slow MIME type +detection where available (sniffing, algorithmic detection, etc) +
GNOME_VFS_FILE_INFO_FOLLOW_LINKS automatically follow symbolic +links and retrieve the properties of their target (recommended) +
GNOME_VFS_FILE_INFO_GET_ACCESS_RIGHTS tries to get data similar +to what would return access(2) on a local file system (ie is the +file readable, writable and/or executable). Can be really slow on +remote file systems +

enum GnomeVFSSetFileInfoMask

typedef enum {
+	GNOME_VFS_SET_FILE_INFO_NONE = 0,
+	GNOME_VFS_SET_FILE_INFO_NAME = 1 << 0,
+	GNOME_VFS_SET_FILE_INFO_PERMISSIONS = 1 << 1,
+	GNOME_VFS_SET_FILE_INFO_OWNER = 1 << 2,
+	GNOME_VFS_SET_FILE_INFO_TIME = 1 << 3
+} GnomeVFSSetFileInfoMask;
+

+Packed boolean bitfield representing the aspects of the file +to be changed in a gnome_vfs_set_file_info() call.

+ +

GNOME_VFS_SET_FILE_INFO_NONE don't set any file info fields +
GNOME_VFS_SET_FILE_INFO_NAME change the name +
GNOME_VFS_SET_FILE_INFO_PERMISSIONS change the permissions +
GNOME_VFS_SET_FILE_INFO_OWNER change the file's owner +
GNOME_VFS_SET_FILE_INFO_TIME change the file's time stamp(s) +

GnomeVFSGetFileInfoResult

typedef struct {
+	GnomeVFSURI *uri;
+	GnomeVFSResult result;
+	GnomeVFSFileInfo *file_info;
+} GnomeVFSGetFileInfoResult;
+

+ +


GnomeVFSInodeNumber

typedef GnomeVFSFileSize GnomeVFSInodeNumber;
+

+Represents the i-node of a file, this is a low level data structure +that the operating system uses to hold information about a file.

+ +


GnomeVFSFileInfo

typedef struct {
+	/* Base name of the file (no path).  */
+	char *name;
+
+	/* Fields which are actually valid in this structure. */
+	GnomeVFSFileInfoFields valid_fields;
+
+	/* File type (i.e. regular, directory, block device...).  */
+	GnomeVFSFileType type;
+
+	/* File permissions.  */
+	GnomeVFSFilePermissions permissions;
+
+	/* Flags for this file.  */
+	GnomeVFSFileFlags flags;
+
+	/* These are only valid if `is_local' is TRUE (see below).  */
+	dev_t device;
+	GnomeVFSInodeNumber inode;
+
+	/* Link count.  */
+	guint link_count;
+
+	/* UID, GID.  */
+	guint uid;
+	guint gid;
+
+	/* Size in bytes.  */
+	GnomeVFSFileSize size;
+
+	/* Size measured in units of 512-byte blocks.  */
+	GnomeVFSFileSize block_count;
+
+	/* Optimal buffer size for reading/writing the file.  */
+	guint io_block_size;
+
+	/* Access, modification and change times.  */
+	time_t atime;
+	time_t mtime;
+	time_t ctime;
+
+	/* If the file is a symlink (see `flags'), this specifies the file the
+           link points to.  */
+	char *symlink_name;
+
+	/* MIME type.  */
+	char *mime_type;
+
+	guint refcount;
+
+	/* Reserved for future expansions to GnomeVFSFileInfo without having
+	   to break ABI compatibility */
+	void *reserved1;
+	void *reserved2;
+	void *reserved3;
+	void *reserved4;
+	void *reserved5;
+} GnomeVFSFileInfo;
+

+The GnomeVFSFileInfo structure contains information about a file.

+ +


GNOME_VFS_FILE_INFO_SYMLINK()

#define     GNOME_VFS_FILE_INFO_SYMLINK(info)

+Determines whether a file is a symbolic link given info.

+ +

info : GnomeVFSFileInfo struct +

GNOME_VFS_FILE_INFO_SET_SYMLINK()

#define     GNOME_VFS_FILE_INFO_SET_SYMLINK(info, value)

+Set the symbolic link field in info to value.

+ +

info : GnomeVFSFileInfo struct +
value : if TRUE, info is set to indicate the file is a symbolic link +

GNOME_VFS_FILE_INFO_LOCAL()

#define     GNOME_VFS_FILE_INFO_LOCAL(info)

+Determines whether a file is local given info.

+ +

info : GnomeVFSFileInfo struct +

GNOME_VFS_FILE_INFO_SET_LOCAL()

#define     GNOME_VFS_FILE_INFO_SET_LOCAL(info, value)

+Set the "local file" field in info to value.

+ +

info : GnomeVFSFileInfo struct +
value : if TRUE, info is set to indicate the file is local +

GNOME_VFS_FILE_INFO_SUID()

#define     GNOME_VFS_FILE_INFO_SUID(info)

+Determines whether a file belongs to the super user.

+ +

info : GnomeVFSFileInfo struct +

GNOME_VFS_FILE_INFO_SGID()

#define     GNOME_VFS_FILE_INFO_SGID(info)

+Determines whether a file belongs to the super user's group.

+ +

info : GnomeVFSFileInfo struct +

GNOME_VFS_FILE_INFO_STICKY()

#define     GNOME_VFS_FILE_INFO_STICKY(info)

+Determines whether a file has the sticky bit set, given info

+ +

info : GnomeVFSFileInfo struct +

GNOME_VFS_FILE_INFO_SET_SUID()

#define     GNOME_VFS_FILE_INFO_SET_SUID(info, value)

+Set the SUID field in info to value.

+ +

info : GnomeVFSFileInfo struct +
value : if TRUE, info is set to indicate the file belongs to the super user +

GNOME_VFS_FILE_INFO_SET_SGID()

#define     GNOME_VFS_FILE_INFO_SET_SGID(info, value)

+Set the SGID field in info to value.

+ +

info : GnomeVFSFileInfo struct +
value : if TRUE, info is set to indicate the file belongs to the super user's group +

GNOME_VFS_FILE_INFO_SET_STICKY()

#define     GNOME_VFS_FILE_INFO_SET_STICKY(info, value)

+Set the sticky bit in info to value.

+ +

info : GnomeVFSFileInfo struct +
value : if TRUE, info is set to indicate the file has the sticky bit set +

gnome_vfs_file_info_new ()

GnomeVFSFileInfo* gnome_vfs_file_info_new   (void);

+Allocate and initialize a new file information struct.

+ +

Returns : A pointer to the new file information struct. +

gnome_vfs_file_info_unref ()

void        gnome_vfs_file_info_unref       (GnomeVFSFileInfo *info);

+Destroy info

+ +

info : Pointer to a file information struct +

gnome_vfs_file_info_ref ()

void        gnome_vfs_file_info_ref         (GnomeVFSFileInfo *info);

+Increment reference count

+ +

info : Pointer to a file information struct +

gnome_vfs_file_info_clear ()

void        gnome_vfs_file_info_clear       (GnomeVFSFileInfo *info);

+Clear info so that it's ready to accept new data. This is +supposed to be used when info already contains meaningful information which +we want to replace.

+ +

info : Pointer to a file information struct +

gnome_vfs_file_info_get_mime_type ()

const char* gnome_vfs_file_info_get_mime_type
+                                            (GnomeVFSFileInfo *info);

+Retrieve MIME type from info. There is no need to free the return +value.

+ +

info : A pointer to a file information struct +
Returns : A pointer to a string representing the MIME type. +

gnome_vfs_file_info_copy ()

void        gnome_vfs_file_info_copy        (GnomeVFSFileInfo *dest,
+                                             const GnomeVFSFileInfo *src);

+Copy information from src into dest.

+ +

dest : Pointer to a struct to copy src's information into +
src : Pointer to the information to be copied into dest +

gnome_vfs_file_info_dup ()

GnomeVFSFileInfo* gnome_vfs_file_info_dup   (const GnomeVFSFileInfo *orig);

+Duplicates orig and returns it.

+ +

orig : Pointer to a file information structure to duplicate +
Returns : a new file information struct that duplicates the information in orig. +

gnome_vfs_file_info_matches ()

gboolean    gnome_vfs_file_info_matches     (const GnomeVFSFileInfo *a,
+                                             const GnomeVFSFileInfo *b);

+Compare the two file info structs, return TRUE if they match.

+ +

a : first GnomeVFSFileInfo struct to compare +
b : second GnomeVFSFileInfo struct to compare +
Returns : TRUE if the two GnomeVFSFileInfos match, otherwise return FALSE. +

gnome_vfs_file_info_list_ref ()

GList*      gnome_vfs_file_info_list_ref    (GList *list);

+Increments the reference count of the items in list by one.

+ +

list : list of GnomeVFSFileInfo elements +
Returns : list +

gnome_vfs_file_info_list_unref ()

GList*      gnome_vfs_file_info_list_unref  (GList *list);

+Decrements the reference count of the items in list by one. +Note that the list is *not freed* even if each member of the list +is freed.

+ +

list : list of GnomeVFSFileInfo elements +
Returns : list +

gnome_vfs_file_info_list_copy ()

GList*      gnome_vfs_file_info_list_copy   (GList *list);

+Creates a duplicate of list, and references each member of +that list.

+ +

list : list of GnomeVFSFileInfo elements +
Returns : a newly referenced duplicate of list +

gnome_vfs_file_info_list_free ()

void        gnome_vfs_file_info_list_free   (GList *list);

+Decrements the reference count of each member of list by one, +and frees the list itself.

+ +

list : list of GnomeVFSFileInfo elements +
diff --git a/doc/html/gnome-vfs-20-gnome-vfs-file-rw-ops.html b/doc/html/gnome-vfs-20-gnome-vfs-file-rw-ops.html new file mode 100644 index 0000000..218bae2 --- /dev/null +++ b/doc/html/gnome-vfs-20-gnome-vfs-file-rw-ops.html @@ -0,0 +1,118 @@ +Reading and Writing

Reading and Writing

Reading and Writing —

Synopsis

+
+
+
+enum        GnomeVFSSeekPosition;
+GnomeVFSResult gnome_vfs_read               (GnomeVFSHandle *handle,
+                                             gpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_read);
+GnomeVFSResult gnome_vfs_write              (GnomeVFSHandle *handle,
+                                             gconstpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_written);
+GnomeVFSResult gnome_vfs_seek               (GnomeVFSHandle *handle,
+                                             GnomeVFSSeekPosition whence,
+                                             GnomeVFSFileOffset offset);
+GnomeVFSResult gnome_vfs_tell               (GnomeVFSHandle *handle,
+                                             GnomeVFSFileSize *offset_return);
+

Description

+ Reading and writing operations are explained, also gnome_vfs_seek, which + is used to move the file pointer inside the file. +

Details

enum GnomeVFSSeekPosition

typedef enum {
+        GNOME_VFS_SEEK_START,
+        GNOME_VFS_SEEK_CURRENT,
+        GNOME_VFS_SEEK_END
+} GnomeVFSSeekPosition;
+

+This is used to specify the start position for seek operations.

+ +

GNOME_VFS_SEEK_START Start of the file. +
GNOME_VFS_SEEK_CURRENT Current position. +
GNOME_VFS_SEEK_END End of the file. +

gnome_vfs_read ()

GnomeVFSResult gnome_vfs_read               (GnomeVFSHandle *handle,
+                                             gpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_read);

+Read bytes from handle. As with Unix system calls, the number of +bytes read can effectively be less than bytes on return and will be +stored in bytes_read.

+ +

handle : Handle of the file to read data from +
buffer : Pointer to a buffer that must be at least bytes bytes large +
bytes : Number of bytes to read +
bytes_read : Pointer to a variable that will hold the number of bytes +effectively read on return. +
Returns : An integer representing the result of the operation +

gnome_vfs_write ()

GnomeVFSResult gnome_vfs_write              (GnomeVFSHandle *handle,
+                                             gconstpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_written);

+Write bytes into the file opened through handle. As with Unix system +calls, the number of bytes written can effectively be less than bytes on +return and will be stored in bytes_written.

+ +

handle : Handle of the file to write data to +
buffer : Pointer to the buffer containing the data to be written +
bytes : Number of bytes to write +
bytes_written : Pointer to a variable that will hold the number of bytes +effectively written on return. +
Returns : An integer representing the result of the operation +

gnome_vfs_seek ()

GnomeVFSResult gnome_vfs_seek               (GnomeVFSHandle *handle,
+                                             GnomeVFSSeekPosition whence,
+                                             GnomeVFSFileOffset offset);

+Set the current position for reading/writing through handle.

+ +

handle : Handle for which the current position must be changed +
whence : Integer value representing the starting position +
offset : Number of bytes to skip from the position specified by whence +(a positive value means to move forward; a negative one to move backwards) +
Returns : +

gnome_vfs_tell ()

GnomeVFSResult gnome_vfs_tell               (GnomeVFSHandle *handle,
+                                             GnomeVFSFileSize *offset_return);

+Return the current position on handle. This is the point in the file +pointed to by handle that reads and writes will occur on.

+ +

handle : Handle for which the current position must be retrieved +
offset_return : Pointer to a variable that will contain the current position +on return +
Returns : An integer representing the result of the operation +
diff --git a/doc/html/gnome-vfs-20-gnome-vfs-file-size.html b/doc/html/gnome-vfs-20-gnome-vfs-file-size.html new file mode 100644 index 0000000..142de3b --- /dev/null +++ b/doc/html/gnome-vfs-20-gnome-vfs-file-size.html @@ -0,0 +1,58 @@ +GnomeVFSFileSize

GnomeVFSFileSize

GnomeVFSFileSize —

Description

+ +

Details

GNOME_VFS_OFFSET_IS_LONG_LONG

#define GNOME_VFS_OFFSET_IS_LONG_LONG
+

+ +


GNOME_VFS_SIZE_FORMAT_STR

#define GNOME_VFS_SIZE_FORMAT_STR "Lu"
+

+ +


GNOME_VFS_OFFSET_FORMAT_STR

#define GNOME_VFS_OFFSET_FORMAT_STR "Ld"
+

+ +


GnomeVFSFileSize

G_GNUC_EXTENSION typedef unsigned long long GnomeVFSFileSize;
+

+ +


GnomeVFSFileOffset

G_GNUC_EXTENSION typedef long long GnomeVFSFileOffset;
+

+ +

diff --git a/doc/html/gnome-vfs-20-gnome-vfs-file-trunc-ops.html b/doc/html/gnome-vfs-20-gnome-vfs-file-trunc-ops.html new file mode 100644 index 0000000..d29dbd0 --- /dev/null +++ b/doc/html/gnome-vfs-20-gnome-vfs-file-trunc-ops.html @@ -0,0 +1,70 @@ +Truncating Files

Truncating Files

Truncating Files —

Synopsis

+
+
+
+GnomeVFSResult gnome_vfs_truncate           (const gchar *text_uri,
+                                             GnomeVFSFileSize length);
+GnomeVFSResult gnome_vfs_truncate_uri       (GnomeVFSURI *uri,
+                                             GnomeVFSFileSize length);
+GnomeVFSResult gnome_vfs_truncate_handle    (GnomeVFSHandle *handle,
+                                             GnomeVFSFileSize length);
+

Description

+ +

Details

gnome_vfs_truncate ()

GnomeVFSResult gnome_vfs_truncate           (const gchar *text_uri,
+                                             GnomeVFSFileSize length);

+Truncate the file at text_uri to length bytes.

+ +

text_uri : URI of the file to be truncated +
length : length of the new file at text_uri +
Returns : An integer representing the result of the operation +

gnome_vfs_truncate_uri ()

GnomeVFSResult gnome_vfs_truncate_uri       (GnomeVFSURI *uri,
+                                             GnomeVFSFileSize length);

+Truncate the file at uri to be only length bytes. Data past length +bytes will be discarded.

+ +

uri : URI of the file to be truncated +
length : length of the new file at uri +
Returns : An integer representing the result of the operation +

gnome_vfs_truncate_handle ()

GnomeVFSResult gnome_vfs_truncate_handle    (GnomeVFSHandle *handle,
+                                             GnomeVFSFileSize length);

+Truncate the file pointed to be handle to be only length bytes. +Data past length bytes will be discarded.

+ +

handle : a handle to the file to be truncated +
length : length of the new file the handle is open to +
Returns : An integer representing the result of the operation +
diff --git a/doc/html/gnome-vfs-20-gnome-vfs-inet-connection.html b/doc/html/gnome-vfs-20-gnome-vfs-inet-connection.html new file mode 100644 index 0000000..92c3899 --- /dev/null +++ b/doc/html/gnome-vfs-20-gnome-vfs-inet-connection.html @@ -0,0 +1,107 @@ +gnome-vfs-inet-connection

gnome-vfs-inet-connection

gnome-vfs-inet-connection —

Synopsis

+
+
+
+GnomeVFSResult gnome_vfs_inet_connection_create
+                                            (GnomeVFSInetConnection **connection_return,
+                                             const gchar *host_name,
+                                             guint host_port,
+                                             GnomeVFSCancellation *cancellation);
+void        gnome_vfs_inet_connection_destroy
+                                            (GnomeVFSInetConnection *connection,
+                                             GnomeVFSCancellation *cancellation);
+void        gnome_vfs_inet_connection_free  (GnomeVFSInetConnection *connection,
+                                             GnomeVFSCancellation *cancellation);
+GnomeVFSSocket* gnome_vfs_inet_connection_to_socket
+                                            (GnomeVFSInetConnection *connection);
+GnomeVFSSocketBuffer* gnome_vfs_inet_connection_to_socket_buffer
+                                            (GnomeVFSInetConnection *connection);
+int         gnome_vfs_inet_connection_get_fd
+                                            (GnomeVFSInetConnection *connection);
+

Description

+ +

Details

gnome_vfs_inet_connection_create ()

GnomeVFSResult gnome_vfs_inet_connection_create
+                                            (GnomeVFSInetConnection **connection_return,
+                                             const gchar *host_name,
+                                             guint host_port,
+                                             GnomeVFSCancellation *cancellation);

+Creates a connection at handle_return to host_name using +port port.

+ +

connection_return : pointer to a GnomeVFSInetConnection, which will +contain an allocated GnomeVFSInetConnection object on return. +
host_name : string indicating the host to establish an internet connection with +
host_port : the port number to connect to +
cancellation : handle allowing cancellation of the operation +
Returns : GnomeVFSResult indicating the success of the operation +

gnome_vfs_inet_connection_destroy ()

void        gnome_vfs_inet_connection_destroy
+                                            (GnomeVFSInetConnection *connection,
+                                             GnomeVFSCancellation *cancellation);

+Closes/Destroys connection.

+ +

connection : connection to destroy +
cancellation : handle for cancelling the operation +

gnome_vfs_inet_connection_free ()

void        gnome_vfs_inet_connection_free  (GnomeVFSInetConnection *connection,
+                                             GnomeVFSCancellation *cancellation);

+ +

connection : +
cancellation : + + +

gnome_vfs_inet_connection_to_socket ()

GnomeVFSSocket* gnome_vfs_inet_connection_to_socket
+                                            (GnomeVFSInetConnection *connection);

+Wrapper connection inside a standard GnomeVFSSocket for convenience.

+ +

connection : connection to convert to wrapper in a GnomeVFSSocket +
Returns : a newly created GnomeVFSSocket around connection. +

gnome_vfs_inet_connection_to_socket_buffer ()

GnomeVFSSocketBuffer* gnome_vfs_inet_connection_to_socket_buffer
+                                            (GnomeVFSInetConnection *connection);

+Wrapper connection inside a standard GnomeVFSSocketBuffer for convenience.

+ +

connection : connection to convert to wrapper in a GnomeVFSSocketBuffer +
Returns : a newly created GnomeVFSSocketBuffer around connection. +

gnome_vfs_inet_connection_get_fd ()

int         gnome_vfs_inet_connection_get_fd
+                                            (GnomeVFSInetConnection *connection);

+Retrieve the UNIX file descriptor corresponding to connection.

+ +

connection : connection to get the file descriptor from +
Returns : file descriptor +
diff --git a/doc/html/gnome-vfs-20-gnome-vfs-init.html b/doc/html/gnome-vfs-20-gnome-vfs-init.html new file mode 100644 index 0000000..494b310 --- /dev/null +++ b/doc/html/gnome-vfs-20-gnome-vfs-init.html @@ -0,0 +1,117 @@ +Initialization/Shutdown

Initialization/Shutdown

Initialization/Shutdown —

Synopsis

+
+
+
+gboolean    gnome_vfs_init                  (void);
+gboolean    gnome_vfs_initialized           (void);
+void        gnome_vfs_shutdown              (void);
+void        gnome_vfs_loadinit              (gpointer app,
+                                             gpointer modinfo);
+void        gnome_vfs_preinit               (gpointer app,
+                                             gpointer modinfo);
+void        gnome_vfs_postinit              (gpointer app,
+                                             gpointer modinfo);
+

Description

+Starting GnomeVFS up and shutting it down. Usually when using the whole +GNOME framework this library is initialized and shutdown automatically +when calling gnome_init. +

Details

gnome_vfs_init ()

gboolean    gnome_vfs_init                  (void);

+If GnomeVFS is not already initialized, initialize it. This must be +called prior to performing any other GnomeVFS operations, and may +be called multiple times without error.

+ +

Returns : TRUE if GnomeVFS is successfully initialized (or was +already initialized) +

gnome_vfs_initialized ()

gboolean    gnome_vfs_initialized           (void);

+Detects if GnomeVFS has already been initialized (GnomeVFS must be +initialized prior to using any methods or operations).

+ +

Returns : TRUE if GnomeVFS has already been initialized +

gnome_vfs_shutdown ()

void        gnome_vfs_shutdown              (void);

+Cease all active GnomeVFS operations and unload the MIME +database from memory.

+ +


gnome_vfs_loadinit ()

void        gnome_vfs_loadinit              (gpointer app,
+                                             gpointer modinfo);

+ +

app : +
modinfo : + + +

gnome_vfs_preinit ()

void        gnome_vfs_preinit               (gpointer app,
+                                             gpointer modinfo);

+ +

app : +
modinfo : + + +

gnome_vfs_postinit ()

void        gnome_vfs_postinit              (gpointer app,
+                                             gpointer modinfo);

+ +

app : +
modinfo : + + +
diff --git a/doc/html/gnome-vfs-20-gnome-vfs-method.html b/doc/html/gnome-vfs-20-gnome-vfs-method.html new file mode 100644 index 0000000..89d1e83 --- /dev/null +++ b/doc/html/gnome-vfs-20-gnome-vfs-method.html @@ -0,0 +1,129 @@ +gnome-vfs-method

gnome-vfs-method

gnome-vfs-method —

Synopsis

+
+
+
+GnomeVFSMethod* (*GnomeVFSMethodInitFunc)   (const char *method_name,
+                                             const char *config_args);
+void        (*GnomeVFSMethodShutdownFunc)   (GnomeVFSMethod *method);
+GnomeVFSResult (*GnomeVFSMethodTruncateFunc)
+                                            (GnomeVFSMethod *method,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSFileSize length,
+                                             GnomeVFSContext *context);
+GnomeVFSResult (*GnomeVFSMethodTruncateHandleFunc)
+                                            (GnomeVFSMethod *method,
+                                             GnomeVFSMethodHandle *handle,
+                                             GnomeVFSFileSize length,
+                                             GnomeVFSContext *context);
+#define     VFS_METHOD_HAS_FUNC             (method,func)
+gboolean    gnome_vfs_method_init           (void);
+GnomeVFSMethod* gnome_vfs_method_get        (const gchar *name);
+GnomeVFSTransform* gnome_vfs_transform_get  (const gchar *name);
+

Description

+ +

Details

GnomeVFSMethodInitFunc ()

GnomeVFSMethod* (*GnomeVFSMethodInitFunc)   (const char *method_name,
+                                             const char *config_args);

+ +

method_name : +
config_args : +
Returns : + + +

GnomeVFSMethodShutdownFunc ()

void        (*GnomeVFSMethodShutdownFunc)   (GnomeVFSMethod *method);

+ +

method : + + +

GnomeVFSMethodTruncateFunc ()

GnomeVFSResult (*GnomeVFSMethodTruncateFunc)
+                                            (GnomeVFSMethod *method,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSFileSize length,
+                                             GnomeVFSContext *context);

+ +

method : +
uri : +
length : +
context : +
Returns : + + +

GnomeVFSMethodTruncateHandleFunc ()

GnomeVFSResult (*GnomeVFSMethodTruncateHandleFunc)
+                                            (GnomeVFSMethod *method,
+                                             GnomeVFSMethodHandle *handle,
+                                             GnomeVFSFileSize length,
+                                             GnomeVFSContext *context);

+ +

method : +
handle : +
length : +
context : +
Returns : + + +

VFS_METHOD_HAS_FUNC()

#define VFS_METHOD_HAS_FUNC(method,func) ((((char *)&((method)->func)) - ((char *)(method)) < (method)->method_table_size) && method->func != NULL)
+

+ +

method : +
func : + + +

gnome_vfs_method_init ()

gboolean    gnome_vfs_method_init           (void);

+ +

Returns : + + +

gnome_vfs_method_get ()

GnomeVFSMethod* gnome_vfs_method_get        (const gchar *name);

+ +

name : +
Returns : + + +

gnome_vfs_transform_get ()

GnomeVFSTransform* gnome_vfs_transform_get  (const gchar *name);

+ +

name : +
Returns : + + +
diff --git a/doc/html/gnome-vfs-20-gnome-vfs-mime-database.html b/doc/html/gnome-vfs-20-gnome-vfs-mime-database.html new file mode 100644 index 0000000..daf6eef --- /dev/null +++ b/doc/html/gnome-vfs-20-gnome-vfs-mime-database.html @@ -0,0 +1,818 @@ +File Types

File Types

File Types — +functions for getting information about files based on their MIME type

Synopsis

+
+
+
+#define     GNOME_VFS_MIME_TYPE_UNKNOWN
+const char* gnome_vfs_get_mime_type_for_data
+                                            (gconstpointer data,
+                                             int data_size);
+char*       gnome_vfs_get_mime_type         (const char *text_uri);
+enum        GnomeVFSMimeActionType;
+enum        GnomeVFSMimeApplicationArgumentType;
+typedef     GnomeVFSMimeApplication;
+GnomeVFSMimeApplication* gnome_vfs_mime_application_copy
+                                            (GnomeVFSMimeApplication *application);
+GnomeVFSMimeActionType gnome_vfs_mime_get_default_action_type
+                                            (const char *mime_type);
+GnomeVFSMimeAction* gnome_vfs_mime_get_default_action
+                                            (const char *mime_type);
+GnomeVFSMimeApplication* gnome_vfs_mime_get_default_application
+                                            (const char *mime_type);
+Bonobo_ServerInfo* gnome_vfs_mime_get_default_component
+                                            (const char *mime_type);
+GList*      gnome_vfs_mime_get_short_list_applications
+                                            (const char *mime_type);
+GList*      gnome_vfs_mime_get_short_list_components
+                                            (const char *mime_type);
+GList*      gnome_vfs_mime_get_all_applications
+                                            (const char *mime_type);
+GList*      gnome_vfs_mime_get_all_components
+                                            (const char *mime_type);
+GnomeVFSResult gnome_vfs_mime_set_default_action_type
+                                            (const char *mime_type,
+                                             GnomeVFSMimeActionType action_type);
+GnomeVFSResult gnome_vfs_mime_set_default_application
+                                            (const char *mime_type,
+                                             const char *application_id);
+GnomeVFSResult gnome_vfs_mime_set_default_component
+                                            (const char *mime_type,
+                                             const char *component_iid);
+const char* gnome_vfs_mime_get_icon         (const char *mime_type);
+GnomeVFSResult gnome_vfs_mime_set_icon      (const char *mime_type,
+                                             const char *filename);
+const char* gnome_vfs_mime_get_description  (const char *mime_type);
+GnomeVFSResult gnome_vfs_mime_set_description
+                                            (const char *mime_type,
+                                             const char *description);
+gboolean    gnome_vfs_mime_can_be_executable
+                                            (const char *mime_type);
+GnomeVFSResult gnome_vfs_mime_set_can_be_executable
+                                            (const char *mime_type,
+                                             gboolean new_value);
+GnomeVFSResult gnome_vfs_mime_set_short_list_applications
+                                            (const char *mime_type,
+                                             GList *application_ids);
+GnomeVFSResult gnome_vfs_mime_set_short_list_components
+                                            (const char *mime_type,
+                                             GList *component_iids);
+GnomeVFSResult gnome_vfs_mime_add_application_to_short_list
+                                            (const char *mime_type,
+                                             const char *application_id);
+GnomeVFSResult gnome_vfs_mime_remove_application_from_short_list
+                                            (const char *mime_type,
+                                             const char *application_id);
+GnomeVFSResult gnome_vfs_mime_add_component_to_short_list
+                                            (const char *mime_type,
+                                             const char *iid);
+GnomeVFSResult gnome_vfs_mime_remove_component_from_short_list
+                                            (const char *mime_type,
+                                             const char *iid);
+GnomeVFSResult gnome_vfs_mime_add_extension (const char *mime_type,
+                                             const char *extension);
+GnomeVFSResult gnome_vfs_mime_remove_extension
+                                            (const char *mime_type,
+                                             const char *extension);
+GnomeVFSResult gnome_vfs_mime_extend_all_applications
+                                            (const char *mime_type,
+                                             GList *application_ids);
+GnomeVFSResult gnome_vfs_mime_remove_from_all_applications
+                                            (const char *mime_type,
+                                             GList *application_ids);
+GnomeVFSMimeApplication* gnome_vfs_mime_application_new_from_id
+                                            (const char *id);
+void        gnome_vfs_mime_application_free (GnomeVFSMimeApplication *application);
+void        gnome_vfs_mime_action_free      (GnomeVFSMimeAction *action);
+void        gnome_vfs_mime_application_list_free
+                                            (GList *list);
+void        gnome_vfs_mime_component_list_free
+                                            (GList *list);
+gboolean    gnome_vfs_mime_id_in_application_list
+                                            (const char *id,
+                                             GList *applications);
+gboolean    gnome_vfs_mime_id_in_component_list
+                                            (const char *iid,
+                                             GList *components);
+GList*      gnome_vfs_mime_remove_application_from_list
+                                            (GList *applications,
+                                             const char *application_id,
+                                             gboolean *did_remove);
+GList*      gnome_vfs_mime_remove_component_from_list
+                                            (GList *components,
+                                             const char *iid,
+                                             gboolean *did_remove);
+GList*      gnome_vfs_mime_id_list_from_component_list
+                                            (GList *components);
+GList*      gnome_vfs_mime_id_list_from_application_list
+                                            (GList *applications);
+void        gnome_vfs_mime_freeze           (void);
+void        gnome_vfs_mime_thaw             (void);
+void        gnome_vfs_mime_info_reload      (void);
+gboolean    gnome_vfs_mime_type_is_known    (const char *mime_type);
+const char* gnome_vfs_mime_get_value        (const char *mime_type,
+                                             const char *key);
+GnomeVFSResult gnome_vfs_mime_set_value     (const char *mime_type,
+                                             const char *key,
+                                             const char *value);
+GList*      gnome_vfs_mime_get_key_list     (const char *mime_type);
+void        gnome_vfs_mime_keys_list_free   (GList *mime_type_list);
+GList*      gnome_vfs_mime_get_extensions_list
+                                            (const char *mime_type);
+void        gnome_vfs_mime_extensions_list_free
+                                            (GList *list);
+char*       gnome_vfs_mime_get_extensions_string
+                                            (const char *mime_type);
+char*       gnome_vfs_mime_get_extensions_pretty_string
+                                            (const char *mime_type);
+GList*      gnome_vfs_get_registered_mime_types
+                                            (void);
+void        gnome_vfs_mime_registered_mime_type_list_free
+                                            (GList *list);
+GnomeVFSResult gnome_vfs_mime_set_registered_type_key
+                                            (const char *mime_type,
+                                             const char *key,
+                                             const char *data);
+GnomeVFSResult gnome_vfs_mime_set_extensions_list
+                                            (const char *mime_type,
+                                             const char *extensions_list);
+void        gnome_vfs_mime_registered_mime_type_delete
+                                            (const char *mime_type);
+void        gnome_vfs_mime_reset            (void);
+

Description

+ +

Details

GNOME_VFS_MIME_TYPE_UNKNOWN

#define GNOME_VFS_MIME_TYPE_UNKNOWN "application/octet-stream"
+

+The value returned for the MIME type when a file did +not match any entries in the MIME database. May be +treated as a file of an unknown type.

+ +


gnome_vfs_get_mime_type_for_data ()

const char* gnome_vfs_get_mime_type_for_data
+                                            (gconstpointer data,
+                                             int data_size);

+Tries to guess the mime type of the data in data +using the magic patterns.

+ +

data : A pointer to data in memory. +
data_size : Size of the data. +
Returns :the mime-type for this filename. +

gnome_vfs_get_mime_type ()

char*       gnome_vfs_get_mime_type         (const char *text_uri);

+Determine the mime type of text_uri. The mime type is determined +in the same way as by gnome_vfs_get_file_info(). This is meant as +a convenience function for times when you only want the mime type.

+ +

text_uri : URI of the file for which to get the mime type +
Returns : The mime type, or NULL if there is an error reading +the file. +

enum GnomeVFSMimeActionType

typedef enum {
+	GNOME_VFS_MIME_ACTION_TYPE_NONE,
+	GNOME_VFS_MIME_ACTION_TYPE_APPLICATION,
+	GNOME_VFS_MIME_ACTION_TYPE_COMPONENT
+} GnomeVFSMimeActionType;
+

+ +


enum GnomeVFSMimeApplicationArgumentType

typedef enum {
+	GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_URIS,
+	GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_PATHS,
+	GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_URIS_FOR_NON_FILES
+} GnomeVFSMimeApplicationArgumentType;
+

+ +


GnomeVFSMimeApplication

typedef struct {
+	char *id;
+	char *name;
+	char *command;
+	gboolean can_open_multiple_files;
+	GnomeVFSMimeApplicationArgumentType expects_uris;
+	GList *supported_uri_schemes;
+	gboolean requires_terminal;
+
+	/* Padded to avoid future breaks in ABI compatibility */
+	void *reserved1;
+	void *reserved2;
+
+} GnomeVFSMimeApplication;
+

+ +


gnome_vfs_mime_application_copy ()

GnomeVFSMimeApplication* gnome_vfs_mime_application_copy
+                                            (GnomeVFSMimeApplication *application);

+Creates a newly referenced copy of a GnomeVFSMimeApplication object.

+ +

application : The GnomeVFSMimeApplication to be duplicated. +
Returns : A copy of application +

gnome_vfs_mime_get_default_action_type ()

GnomeVFSMimeActionType gnome_vfs_mime_get_default_action_type
+                                            (const char *mime_type);

+Query the MIME database for the type of action to be performed on a particular MIME type by default.

+ +

mime_type : A const char * containing a mime type, e.g. "application/x-php" +
Returns : The type of action to be performed on a file of +MIME type, mime_type by default. +

gnome_vfs_mime_get_default_action ()

GnomeVFSMimeAction* gnome_vfs_mime_get_default_action
+                                            (const char *mime_type);

+Query the MIME database for default action associated with a particular MIME type mime_type.

+ +

mime_type : A const char * containing a mime type, e.g. "application/x-php" +
Returns : A GnomeVFSMimeAction representing the default action to perform upon +file of type mime_type. +

gnome_vfs_mime_get_default_application ()

GnomeVFSMimeApplication* gnome_vfs_mime_get_default_application
+                                            (const char *mime_type);

+Query the MIME database for the application to be executed on files of MIME type +mime_type by default.

+ +

mime_type : A const char * containing a mime type, e.g. "image/png" +
Returns : A GnomeVFSMimeApplication representing the default handler of mime_type +

gnome_vfs_mime_get_default_component ()

Bonobo_ServerInfo* gnome_vfs_mime_get_default_component
+                                            (const char *mime_type);

+Query the MIME database for the default Bonobo component to be activated to +view files of MIME type mime_type.

+ +

mime_type : A const char * containing a mime type, e.g. "image/png" +
Returns : An Bonobo_ServerInfo * representing the OAF server to be activated +to get a reference to the proper component. +

gnome_vfs_mime_get_short_list_applications ()

GList*      gnome_vfs_mime_get_short_list_applications
+                                            (const char *mime_type);

+Return an alphabetically sorted list of GnomeVFSMimeApplication +data structures for the requested mime type. The short list contains +"select" applications recommended for handling this MIME type, appropriate for +display to the user.

+ +

mime_type : A const char * containing a mime type, e.g. "image/png" +
Returns : A GList * where the elements are GnomeVFSMimeApplication * +representing various applications to display in the short list for mime_type. +

gnome_vfs_mime_get_short_list_components ()

GList*      gnome_vfs_mime_get_short_list_components
+                                            (const char *mime_type);

+Return an unsorted sorted list of Bonobo_ServerInfo * +data structures for the requested mime type. The short list contains +"select" components recommended for handling this MIME type, appropriate for +display to the user.

+ +

mime_type : A const char * containing a mime type, e.g. "image/png" +
Returns : A GList * where the elements are Bonobo_ServerInfo * +representing various components to display in the short list for mime_type. +

gnome_vfs_mime_get_all_applications ()

GList*      gnome_vfs_mime_get_all_applications
+                                            (const char *mime_type);

+Return an alphabetically sorted list of GnomeVFSMimeApplication +data structures representing all applications in the MIME database registered +to handle files of MIME type mime_type (and supertypes).

+ +

mime_type : A const char * containing a mime type, e.g. "image/png" +
Returns : A GList * where the elements are GnomeVFSMimeApplication * +representing applications that handle MIME type mime_type. +

gnome_vfs_mime_get_all_components ()

GList*      gnome_vfs_mime_get_all_components
+                                            (const char *mime_type);

+Return an alphabetically sorted list of Bonobo_ServerInfo +data structures representing all Bonobo components registered +to handle files of MIME type mime_type (and supertypes).

+ +

mime_type : A const char * containing a mime type, e.g. "image/png" +
Returns : A GList * where the elements are Bonobo_ServerInfo * +representing components that can handle MIME type mime_type. +

gnome_vfs_mime_set_default_action_type ()

GnomeVFSResult gnome_vfs_mime_set_default_action_type
+                                            (const char *mime_type,
+                                             GnomeVFSMimeActionType action_type);

+Sets the default action type to be performed on files of MIME type mime_type.

+ +

mime_type : A const char * containing a mime type, e.g. "image/png" +
action_type : A GnomeVFSMimeActionType containing the action to perform by default +
Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered. +

gnome_vfs_mime_set_default_application ()

GnomeVFSResult gnome_vfs_mime_set_default_application
+                                            (const char *mime_type,
+                                             const char *application_id);

+Sets the default application to be run on files of MIME type mime_type.

+ +

mime_type : A const char * containing a mime type, e.g. "application/x-php" +
application_id : A key representing an application in the MIME database +(GnomeVFSMimeApplication->id, for example) +
Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered. +

gnome_vfs_mime_set_default_component ()

GnomeVFSResult gnome_vfs_mime_set_default_component
+                                            (const char *mime_type,
+                                             const char *component_iid);

+Sets the default component to be activated for files of MIME type mime_type.

+ +

mime_type : A const char * containing a mime type, e.g. "application/x-php" +
component_iid : The OAFIID of a component +
Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered. +

gnome_vfs_mime_get_icon ()

const char* gnome_vfs_mime_get_icon         (const char *mime_type);

+Query the MIME database for an icon representing the specified MIME type.

+ +

mime_type : A const char * containing a MIME type +
Returns : The filename of the icon as listed in the MIME database. This is +usually a filename without path information, e.g. "i-chardev.png", and sometimes +does not have an extension, e.g. "i-regular" if the icon is supposed to be image +type agnostic between icon themes. Icons are generic, and not theme specific. These +will not necessarily match with the icons a user sees in Nautilus, you have been warned. +

gnome_vfs_mime_set_icon ()

GnomeVFSResult gnome_vfs_mime_set_icon      (const char *mime_type,
+                                             const char *filename);

+Set the icon entry for a particular MIME type in the MIME database. Note that +icon entries need not necessarily contain the full path, and do not necessarily need to +specify an extension. So "i-regular", "my-special-icon.png", and "some-icon" +are all valid icon filenames.

+ +

mime_type : A const char * containing a MIME type +
filename : a const char * containing an image filename +
Returns : A GnomeVFSResult indicating the success of the operation +or any errors that may have occurred. +

gnome_vfs_mime_get_description ()

const char* gnome_vfs_mime_get_description  (const char *mime_type);

+Query the MIME database for a description of the specified MIME type.

+ +

mime_type : the mime type +
Returns : A description of MIME type mime_type +

gnome_vfs_mime_set_description ()

GnomeVFSResult gnome_vfs_mime_set_description
+                                            (const char *mime_type,
+                                             const char *description);

+Set the description of this MIME type in the MIME database. The description +should be something like "Gnumeric spreadsheet".

+ +

mime_type : A const char * containing a mime type +
description : A description of this MIME type +
Returns : GnomeVFSResult indicating the success of the operation or any +errors that may have occurred. +

gnome_vfs_mime_can_be_executable ()

gboolean    gnome_vfs_mime_can_be_executable
+                                            (const char *mime_type);

+Check whether files of this MIME type might conceivably be executable. +Default for known types if FALSE. Default for unknown types is TRUE.

+ +

mime_type : A const char * containing a mime type +
Returns : gboolean containing TRUE if some files of this MIME type +are registered as being executable, and false otherwise. +

gnome_vfs_mime_set_can_be_executable ()

GnomeVFSResult gnome_vfs_mime_set_can_be_executable
+                                            (const char *mime_type,
+                                             gboolean new_value);

+Set whether files of this MIME type might conceivably be executable.

+ +

mime_type : A const char * containing a mime type +
new_value : A boolean value indicating whether mime_type could be executable. +
Returns : GnomeVFSResult indicating the success of the operation or any +errors that may have occurred. +

gnome_vfs_mime_set_short_list_applications ()

GnomeVFSResult gnome_vfs_mime_set_short_list_applications
+                                            (const char *mime_type,
+                                             GList *application_ids);

+Set the short list of applications for the specified MIME type. The short list +contains applications recommended for possible selection by the user.

+ +

mime_type : A const char * containing a mime type, e.g. "application/x-php" +
application_ids : GList of const char * application ids +
Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered. +

gnome_vfs_mime_set_short_list_components ()

GnomeVFSResult gnome_vfs_mime_set_short_list_components
+                                            (const char *mime_type,
+                                             GList *component_iids);

+Set the short list of components for the specified MIME type. The short list +contains companents recommended for possible selection by the user. *

+ +

mime_type : A const char * containing a mime type, e.g. "application/x-php" +
component_iids : GList of const char * OAF IIDs +
Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered. +

gnome_vfs_mime_add_application_to_short_list ()

GnomeVFSResult gnome_vfs_mime_add_application_to_short_list
+                                            (const char *mime_type,
+                                             const char *application_id);

+Add an application to the short list for MIME type mime_type. The short list contains +applications recommended for display as choices to the user for a particular MIME type.

+ +

mime_type : A const char * containing a mime type, e.g. "application/x-php" +
application_id : const char * containing the application's id in the MIME database +
Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered. +

gnome_vfs_mime_remove_application_from_short_list ()

GnomeVFSResult gnome_vfs_mime_remove_application_from_short_list
+                                            (const char *mime_type,
+                                             const char *application_id);

+Remove an application from the short list for MIME type mime_type. The short list contains +applications recommended for display as choices to the user for a particular MIME type.

+ +

mime_type : A const char * containing a mime type, e.g. "application/x-php" +
application_id : const char * containing the application's id in the MIME database +
Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered. +

gnome_vfs_mime_add_component_to_short_list ()

GnomeVFSResult gnome_vfs_mime_add_component_to_short_list
+                                            (const char *mime_type,
+                                             const char *iid);

+Add a component to the short list for MIME type mime_type. The short list contains +components recommended for display as choices to the user for a particular MIME type.

+ +

mime_type : A const char * containing a mime type, e.g. "application/x-php" +
iid : const char * containing the component's OAF IID +
Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered. +

gnome_vfs_mime_remove_component_from_short_list ()

GnomeVFSResult gnome_vfs_mime_remove_component_from_short_list
+                                            (const char *mime_type,
+                                             const char *iid);

+Remove a component from the short list for MIME type mime_type. The short list contains +components recommended for display as choices to the user for a particular MIME type.

+ +

mime_type : A const char * containing a mime type, e.g. "application/x-php" +
iid : const char * containing the component's OAF IID +
Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered. +

gnome_vfs_mime_add_extension ()

GnomeVFSResult gnome_vfs_mime_add_extension (const char *mime_type,
+                                             const char *extension);

+Add a file extension to the specificed MIME type in the MIME database.

+ +

mime_type : The mime type to add the mapping to. +
extension : The extension to add (e.g. "txt") +
Returns : GnomeVFSResult indicating the success of the operation or any +errors that may have occurred. +

gnome_vfs_mime_remove_extension ()

GnomeVFSResult gnome_vfs_mime_remove_extension
+                                            (const char *mime_type,
+                                             const char *extension);

+Removes a file extension from the specificed MIME type in the MIME database.

+ +

mime_type : The mime type to remove the extension from +
extension : The extension to remove +
Returns : GnomeVFSResult indicating the success of the operation or any +errors that may have occurred. +

gnome_vfs_mime_extend_all_applications ()

GnomeVFSResult gnome_vfs_mime_extend_all_applications
+                                            (const char *mime_type,
+                                             GList *application_ids);

+Register mime_type as being handled by all applications list in application_ids.

+ +

mime_type : A const char * containing a mime type, e.g. "application/x-php" +
application_ids : a GList of const char * containing application ids +
Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered. +

gnome_vfs_mime_remove_from_all_applications ()

GnomeVFSResult gnome_vfs_mime_remove_from_all_applications
+                                            (const char *mime_type,
+                                             GList *application_ids);

+Remove mime_type as a handled type from every application in application_ids

+ +

mime_type : A const char * containing a mime type, e.g. "application/x-php" +
application_ids : a GList of const char * containing application ids +
Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered. +

gnome_vfs_mime_application_new_from_id ()

GnomeVFSMimeApplication* gnome_vfs_mime_application_new_from_id
+                                            (const char *id);

+Fetches the GnomeVFSMimeApplication associated with the specified +application ID from the MIME database.

+ +

id : A const char * containing an application id +
Returns : GnomeVFSMimeApplication * corresponding to id +

gnome_vfs_mime_application_free ()

void        gnome_vfs_mime_application_free (GnomeVFSMimeApplication *application);

+Frees a GnomeVFSMimeApplication *.

+ +

application : The GnomeVFSMimeApplication to be freed +

gnome_vfs_mime_action_free ()

void        gnome_vfs_mime_action_free      (GnomeVFSMimeAction *action);

+Frees a GnomeVFSMimeAction *.

+ +

action : The GnomeVFSMimeAction to be freed +

gnome_vfs_mime_application_list_free ()

void        gnome_vfs_mime_application_list_free
+                                            (GList *list);

+Frees lists of GnomeVFSApplications, as returned from functions such +as gnome_vfs_get_all_applications().

+ +

list : a GList of GnomeVFSApplication * to be freed +

gnome_vfs_mime_component_list_free ()

void        gnome_vfs_mime_component_list_free
+                                            (GList *list);

+Frees lists of Bonobo_ServerInfo * (as returned from functions such +as gnome_vfs_get_all_components)

+ +

list : a GList of Bonobo_ServerInfo * to be freed +

gnome_vfs_mime_id_in_application_list ()

gboolean    gnome_vfs_mime_id_in_application_list
+                                            (const char *id,
+                                             GList *applications);

+Check whether an application id is in a list of GnomeVFSMimeApplications.

+ +

id : An application id. +
applications : A GList * whose nodes are GnomeVFSMimeApplications, such as the +result of gnome_vfs_mime_get_short_list_applications(). +
Returns : TRUE if an application whose id matches id is in applications. +

gnome_vfs_mime_id_in_component_list ()

gboolean    gnome_vfs_mime_id_in_component_list
+                                            (const char *iid,
+                                             GList *components);

+Check whether a component iid is in a list of Bonobo_ServerInfos.

+ +

iid : A component iid. +
components : A GList * whose nodes are Bonobo_ServerInfos, such as the +result of gnome_vfs_mime_get_short_list_components(). +
Returns : TRUE if a component whose iid matches iid is in components. +

gnome_vfs_mime_remove_application_from_list ()

GList*      gnome_vfs_mime_remove_application_from_list
+                                            (GList *applications,
+                                             const char *application_id,
+                                             gboolean *did_remove);

+Remove an application specified by id from a list of GnomeVFSMimeApplications.

+ +

applications : A GList * whose nodes are GnomeVFSMimeApplications, such as the +result of gnome_vfs_mime_get_short_list_applications(). +
application_id : The id of an application to remove from applications. +
did_remove : If non-NULL, this is filled in with TRUE if the application +was found in the list, FALSE otherwise. +
Returns : The modified list. If the application is not found, the list will +be unchanged. +

gnome_vfs_mime_remove_component_from_list ()

GList*      gnome_vfs_mime_remove_component_from_list
+                                            (GList *components,
+                                             const char *iid,
+                                             gboolean *did_remove);

+Remove a component specified by iid from a list of Bonobo_ServerInfos.

+ +

components : A GList * whose nodes are Bonobo_ServerInfos, such as the +result of gnome_vfs_mime_get_short_list_components(). +
iid : The iid of a component to remove from components. +
did_remove : If non-NULL, this is filled in with TRUE if the component +was found in the list, FALSE otherwise. +
Returns : The modified list. If the component is not found, the list will +be unchanged. +

gnome_vfs_mime_id_list_from_component_list ()

GList*      gnome_vfs_mime_id_list_from_component_list
+                                            (GList *components);

+Create a list of component iids from a list of Bonobo_ServerInfos.

+ +

components : A GList * whose nodes are Bonobo_ServerInfos, such as the +result of gnome_vfs_mime_get_short_list_components(). +
Returns : A new list where each Bonobo_ServerInfo in the original +list is replaced by a char * with the component's iid. The original list is +not modified. +

gnome_vfs_mime_id_list_from_application_list ()

GList*      gnome_vfs_mime_id_list_from_application_list
+                                            (GList *applications);

+Create a list of application ids from a list of GnomeVFSMimeApplications.

+ +

applications : A GList * whose nodes are GnomeVFSMimeApplications, such as the +result of gnome_vfs_mime_get_short_list_applications(). +
Returns : A new list where each GnomeVFSMimeApplication in the original +list is replaced by a char * with the application's id. The original list is +not modified. +

gnome_vfs_mime_freeze ()

void        gnome_vfs_mime_freeze           (void);

+Freezes the mime data so that you can do multiple +updates to the dat in one batch without needing +to back the files to disk or readind them

+ +


gnome_vfs_mime_thaw ()

void        gnome_vfs_mime_thaw             (void);

+UnFreezes the mime data so that you can do multiple +updates to the dat in one batch without needing +to back the files to disk or readind them

+ +


gnome_vfs_mime_info_reload ()

void        gnome_vfs_mime_info_reload      (void);

+Reload the MIME database from disk and notify any listeners +holding active GnomeVFSMIMEMonitor objects.

+ +


gnome_vfs_mime_type_is_known ()

gboolean    gnome_vfs_mime_type_is_known    (const char *mime_type);

+This function returns TRUE if mime_type is in the MIME database at all.

+ +

mime_type : a mime type. +
Returns : TRUE if anything is known about mime_type, otherwise FALSE +

gnome_vfs_mime_get_value ()

const char* gnome_vfs_mime_get_value        (const char *mime_type,
+                                             const char *key);

+This function retrieves the value associated with key in +the given GnomeMimeContext. The string is private, you +should not free the result.

+ +

mime_type : a mime type. +
key : A key to lookup for the given mime-type +
Returns : GNOME_VFS_OK if the operation succeeded, otherwise an error code +

gnome_vfs_mime_set_value ()

GnomeVFSResult gnome_vfs_mime_set_value     (const char *mime_type,
+                                             const char *key,
+                                             const char *value);

+This function is going to set the value +associated to the key and it will save it +to the user' file if necessary. +You should not free the key/values passed to +this function. They are used internally.

+ +

mime_type : a mime type. +
key : a key to store the value in. +
value : the value to store in the key. +
Returns : GNOME_VFS_OK if the operation succeeded, otherwise an error code + +

gnome_vfs_mime_get_key_list ()

GList*      gnome_vfs_mime_get_key_list     (const char *mime_type);

+Gets a list of all keys associated with mime_type.

+ +

mime_type : the MIME type to lookup +
Returns : a GList of const char * representing keys associated +with mime_type +

gnome_vfs_mime_keys_list_free ()

void        gnome_vfs_mime_keys_list_free   (GList *mime_type_list);

+Frees the mime type list.

+ +

mime_type_list : A mime type list to free. +

gnome_vfs_mime_get_extensions_list ()

GList*      gnome_vfs_mime_get_extensions_list
+                                            (const char *mime_type);

+Get the file extensions associated with mime type mime_type.

+ +

mime_type : type to get the extensions of +
Returns : a GList of char *s +

gnome_vfs_mime_extensions_list_free ()

void        gnome_vfs_mime_extensions_list_free
+                                            (GList *list);

+Call this function on the list returned by gnome_vfs_mime_extensions +to free the list and all of its elements.

+ +

list : the extensions list +

gnome_vfs_mime_get_extensions_string ()

char*       gnome_vfs_mime_get_extensions_string
+                                            (const char *mime_type);

+Retrieves the extensions associated with mime_type as a single +space seperated string.

+ +

mime_type : the mime type +
Returns : a string containing space seperated extensions for mime_type +

gnome_vfs_mime_get_extensions_pretty_string ()

char*       gnome_vfs_mime_get_extensions_pretty_string
+                                            (const char *mime_type);

+Returns the supported extensions for mime_type as a comma-seperated list.

+ +

mime_type : the mime type +
Returns : a string containing comma seperated extensions for this mime-type +

gnome_vfs_get_registered_mime_types ()

GList*      gnome_vfs_get_registered_mime_types
+                                            (void);

+ +

Returns : + + +

gnome_vfs_mime_registered_mime_type_list_free ()

void        gnome_vfs_mime_registered_mime_type_list_free
+                                            (GList *list);

+Call this function on the list returned by gnome_vfs_get_registered_mime_types +to free the list and all of its elements.

+ +

list : the extensions list +

gnome_vfs_mime_set_registered_type_key ()

GnomeVFSResult gnome_vfs_mime_set_registered_type_key
+                                            (const char *mime_type,
+                                             const char *key,
+                                             const char *data);

+This function sets the key data for the registered mime +type's hash table.

+ +

mime_type : Mime type to set key for +
key : The key to set +
data : The data to set for the key +
Returns : GNOME_VFS_OK if the operation succeeded, otherwise an error code +

gnome_vfs_mime_set_extensions_list ()

GnomeVFSResult gnome_vfs_mime_set_extensions_list
+                                            (const char *mime_type,
+                                             const char *extensions_list);

+Sets the extensions for a given mime type. Overrides +the previously set extensions.

+ +

mime_type : the mime type. +
extensions_list : a whitespace-separated list of the + extensions to set for this mime type. +
Returns : GNOME_VFS_OK if the operation succeeded, otherwise an error code. +

gnome_vfs_mime_registered_mime_type_delete ()

void        gnome_vfs_mime_registered_mime_type_delete
+                                            (const char *mime_type);

+Delete a mime type for the user which runs this command. +You can undo this only by calling gnome_vfs_mime_reset

+ +

mime_type : string representing the existing type to delete +

gnome_vfs_mime_reset ()

void        gnome_vfs_mime_reset            (void);

+resets the user's mime database to the system defaults.

+ +

diff --git a/doc/html/gnome-vfs-20-gnome-vfs-mime-monitor.html b/doc/html/gnome-vfs-20-gnome-vfs-mime-monitor.html new file mode 100644 index 0000000..db8141f --- /dev/null +++ b/doc/html/gnome-vfs-20-gnome-vfs-mime-monitor.html @@ -0,0 +1,53 @@ +MIME Database Monitor

MIME Database Monitor

MIME Database Monitor — +monitor the MIME database for changes (primarily for file browsers)

Synopsis

+
+
+
+#define     GNOME_VFS_MIME_MONITOR_TYPE
+struct      GnomeVFSMIMEMonitorPrivate;
+GnomeVFSMIMEMonitor* gnome_vfs_mime_monitor_get
+                                            (void);
+
+

Description

+ +

Details

GNOME_VFS_MIME_MONITOR_TYPE

#define GNOME_VFS_MIME_MONITOR_TYPE        (gnome_vfs_mime_monitor_get_type ())
+

+ +


struct GnomeVFSMIMEMonitorPrivate

struct GnomeVFSMIMEMonitorPrivate;

+ +


gnome_vfs_mime_monitor_get ()

GnomeVFSMIMEMonitor* gnome_vfs_mime_monitor_get
+                                            (void);

+Get access to the single global monitor.

+ +

Returns : the global GnomeVFSMIMEMonitor +
diff --git a/doc/html/gnome-vfs-20-gnome-vfs-mime.html b/doc/html/gnome-vfs-20-gnome-vfs-mime.html new file mode 100644 index 0000000..8283704 --- /dev/null +++ b/doc/html/gnome-vfs-20-gnome-vfs-mime.html @@ -0,0 +1,133 @@ +MIME typing

MIME typing

MIME typing — functions to get a mime-type for a file using its name or its content

Synopsis

+
+
+
+void        gnome_vfs_mime_shutdown         (void);
+const char* gnome_vfs_mime_type_from_name   (const char *filename);
+const char* gnome_vfs_mime_type_from_name_or_default
+                                            (const char *filename,
+                                             const char *defaultv);
+const char* gnome_vfs_get_mime_type_common  (GnomeVFSURI *uri);
+const char* gnome_vfs_get_mime_type_from_uri
+                                            (GnomeVFSURI *uri);
+const char* gnome_vfs_get_mime_type_from_file_data
+                                            (GnomeVFSURI *uri);
+const char* gnome_vfs_get_file_mime_type    (const char *path,
+                                             const struct stat *optional_stat_info,
+                                             gboolean suffix_only);
+gboolean    gnome_vfs_mime_type_is_supertype
+                                            (const char *mime_type);
+char*       gnome_vfs_get_supertype_from_mime_type
+                                            (const char *mime_type);
+

Description

+ +

Details

gnome_vfs_mime_shutdown ()

void        gnome_vfs_mime_shutdown         (void);

+Unload the MIME database from memory.

+ +


gnome_vfs_mime_type_from_name ()

const char* gnome_vfs_mime_type_from_name   (const char *filename);

+Determined the mime type for filename.

+ +

filename : A filename (the file does not necessarily exist). +
Returns :the mime-type for this filename. +

gnome_vfs_mime_type_from_name_or_default ()

const char* gnome_vfs_mime_type_from_name_or_default
+                                            (const char *filename,
+                                             const char *defaultv);

+This routine tries to determine the mime-type of the filename +only by looking at the filename from the GNOME database of mime-types.

+ +

filename : A filename (the file does not necesarily exist). +
defaultv : A default value to be returned if no match is found +
Returns :the mime-type of the filename. If no value could be +determined, it will return defaultv. +

gnome_vfs_get_mime_type_common ()

const char* gnome_vfs_get_mime_type_common  (GnomeVFSURI *uri);

+Tries to guess the mime type of the file represented by uir. +Favors using the file data to the uri extension. +Handles passing uri of a non-existent file by falling back +on returning a type based on the extension. +

+FIXME: This function will not necessarily return the same mime type as doing a +get file info on the text uri.

+ +

uri : a real file or a non-existent uri. +
Returns : the mime-type for this uri. + +

gnome_vfs_get_mime_type_from_uri ()

const char* gnome_vfs_get_mime_type_from_uri
+                                            (GnomeVFSURI *uri);

+Tries to guess the mime type of the file uri by +checking the file name extension. Works on non-existent +files.

+ +

uri : A file uri. +
Returns :the mime-type for this filename. +

gnome_vfs_get_mime_type_from_file_data ()

const char* gnome_vfs_get_mime_type_from_file_data
+                                            (GnomeVFSURI *uri);

+Tries to guess the mime type of the file uri by +checking the file data using the magic patterns. Does not handle text files properly

+ +

uri : A file uri. +
Returns :the mime-type for this filename. +

gnome_vfs_get_file_mime_type ()

const char* gnome_vfs_get_file_mime_type    (const char *path,
+                                             const struct stat *optional_stat_info,
+                                             gboolean suffix_only);

+Tries to guess the mime type of the file represented by path. +If suffix_only is false, uses the mime-magic based lookup first. +Handles passing path of a non-existent file by falling back +on returning a type based on the extension.

+ +

path : a path of a file. +
optional_stat_info : optional stat buffer. +
suffix_only : whether or not to do a magic-based lookup. +
Returns : the mime-type for this path +

gnome_vfs_mime_type_is_supertype ()

gboolean    gnome_vfs_mime_type_is_supertype
+                                            (const char *mime_type);

+ +

mime_type : +
Returns : + + +

gnome_vfs_get_supertype_from_mime_type ()

char*       gnome_vfs_get_supertype_from_mime_type
+                                            (const char *mime_type);

+ +

mime_type : +
Returns : + + +
diff --git a/doc/html/gnome-vfs-20-gnome-vfs-module-callback-module-api.html b/doc/html/gnome-vfs-20-gnome-vfs-module-callback-module-api.html new file mode 100644 index 0000000..db4b9a7 --- /dev/null +++ b/doc/html/gnome-vfs-20-gnome-vfs-module-callback-module-api.html @@ -0,0 +1,89 @@ +gnome-vfs-module-callback-module-api

gnome-vfs-module-callback-module-api

gnome-vfs-module-callback-module-api — invoking callbacks from a gnome-vfs module to ask the application for necessary information (authentication, ...)

Synopsis

+
+
+
+gboolean    gnome_vfs_module_callback_invoke
+                                            (const char *callback_name,
+                                             gconstpointer in,
+                                             gsize in_size,
+                                             gpointer out,
+                                             gsize out_size);
+

Description

+ +

Details

gnome_vfs_module_callback_invoke ()

gboolean    gnome_vfs_module_callback_invoke
+                                            (const char *callback_name,
+                                             gconstpointer in,
+                                             gsize in_size,
+                                             gpointer out,
+                                             gsize out_size);

+Invoke a default callback for callback_name, with in arguments +specified by in and in_size, and out arguments specified by out +and out_size. +

+This function should only be called by gnome-vfs modules. +

+If this function is called from an async job thread, it will invoke +the current async handler for callback_name, if any. If no async +handler is set, or the function is not called from an async job +thread, the regular handler, if any, will be invoked instead. If no +handler at all is found for callback_name, the function returns +FALSE.

+ +

callback_name : The name of the module callback to set +
in : In argument - type dependent on the specific callback +
in_size : Size of the in argument +
out : Out argument - type dependent on the specific callback +
out_size : Size of the out argument +
Returns : TRUE if a callback was invoked, FALSE if none was set. + +
diff --git a/doc/html/gnome-vfs-20-gnome-vfs-module-callback.html b/doc/html/gnome-vfs-20-gnome-vfs-module-callback.html new file mode 100644 index 0000000..877e914 --- /dev/null +++ b/doc/html/gnome-vfs-20-gnome-vfs-module-callback.html @@ -0,0 +1,350 @@ +gnome-vfs-module-callback

gnome-vfs-module-callback

gnome-vfs-module-callback — functions used by apps if they want to answer to callback invocations by gnome-vfs modules

Synopsis

+
+
+
+void        (*GnomeVFSModuleCallback)       (gconstpointer in,
+                                             gsize in_size,
+                                             gpointer out,
+                                             gsize out_size,
+                                             gpointer callback_data);
+void        (*GnomeVFSModuleCallbackResponse)
+                                            (gpointer response_data);
+void        (*GnomeVFSAsyncModuleCallback)  (gconstpointer in,
+                                             gsize in_size,
+                                             gpointer out,
+                                             gsize out_size,
+                                             gpointer callback_data,
+                                             GnomeVFSModuleCallbackResponse response,
+                                             gpointer response_data);
+void        gnome_vfs_module_callback_set_default
+                                            (const char *callback_name,
+                                             GnomeVFSModuleCallback callback,
+                                             gpointer callback_data,
+                                             GDestroyNotify destroy_notify);
+void        gnome_vfs_module_callback_push  (const char *callback_name,
+                                             GnomeVFSModuleCallback callback,
+                                             gpointer callback_data,
+                                             GDestroyNotify destroy_notify);
+void        gnome_vfs_module_callback_pop   (const char *callback_name);
+void        gnome_vfs_async_module_callback_set_default
+                                            (const char *callback_name,
+                                             GnomeVFSAsyncModuleCallback callback,
+                                             gpointer callback_data,
+                                             GDestroyNotify destroy_notify);
+void        gnome_vfs_async_module_callback_push
+                                            (const char *callback_name,
+                                             GnomeVFSAsyncModuleCallback callback,
+                                             gpointer callback_data,
+                                             GDestroyNotify destroy_notify);
+void        gnome_vfs_async_module_callback_pop
+                                            (const char *callback_name);
+

Description

+ +

Details

GnomeVFSModuleCallback ()

void        (*GnomeVFSModuleCallback)       (gconstpointer in,
+                                             gsize in_size,
+                                             gpointer out,
+                                             gsize out_size,
+                                             gpointer callback_data);

+This is the type of a callback function that gets set for a module +callback. +

+When the callback is invoked, the user function is called with an +in argument, the exact type of which depends on the specific +callback. It is generally a pointer to a struct with several fields +that provide information to the callback. +

+The out argument is used to return a values from the +callback. Once again the exact type depends on the specific +callback. It is generally a pointer to a pre-allocated struct with +several fields that the callback function should fill in before +returning.

+ +

in : The in argument for this callback; the exact type depends on the specific callback +
in_size : Size of the in argument; useful for sanity-checking +
out : The out argument for this callback; the exact type depends on the specific callback +
out_size : Size of the out argument; useful for sanity-checking +
callback_data : The callback_data specified when this callback was set +

GnomeVFSModuleCallbackResponse ()

void        (*GnomeVFSModuleCallbackResponse)
+                                            (gpointer response_data);

+This is the type of the response function passed to a +GnomeVFSAsyncModuleCallback(). It should be called when the async +callback has completed.

+ +

response_data : Pass the response_data argument originally passed to the async callback +

GnomeVFSAsyncModuleCallback ()

void        (*GnomeVFSAsyncModuleCallback)  (gconstpointer in,
+                                             gsize in_size,
+                                             gpointer out,
+                                             gsize out_size,
+                                             gpointer callback_data,
+                                             GnomeVFSModuleCallbackResponse response,
+                                             gpointer response_data);

+This is the type of a callback function that gets set for an async +module callback. +

+Such callbacks are useful when you are using the API and want +callbacks to be handled from the main thread, for instance if they +need to put up a dialog. +

+Like a GnomeVFSModuleCallback(), an async callback has in and out +arguments for passing data into and out of the callback. However, +an async callback does not need to fill in the out argument before +returning. Instead, it can arrange to have the work done from a +callback on the main loop, from another thread, etc. The response +function should be called by whatever code finishes the work of the +callback with response_data as an argument once the out argument +is filled in and the callback is done. +

+The in and out arguments are guaranteed to remain valid until the +response function is called.

+ +

in : The in argument for this callback; the exact type depends on the specific callback +
in_size : Size of the in argument; useful for sanity-checking +
out : The out argument for this callback; the exact type depends on the specific callback +
out_size : Size of the out argument; useful for sanity-checking +
callback_data : The callback_data specified when this callback was set +
response : Response function to call when the callback is completed +
response_data : Argument to pass to response +

gnome_vfs_module_callback_set_default ()

void        gnome_vfs_module_callback_set_default
+                                            (const char *callback_name,
+                                             GnomeVFSModuleCallback callback,
+                                             gpointer callback_data,
+                                             GDestroyNotify destroy_notify);

+Set the default callback for callback_name to +callback. callback will be called with callback_data on the +same thread as the gnome-vfs operation that invokes it. The default +value is shared for all threads, but setting it is thread-safe. +

+Use this function if you want to set a handler to be used by your +whole application. You can use gnome_vfs_module_callback_push() to +set a callback function that will temporarily override the default +on the current thread instead. Or you can also use +gnome_vfs_async_module_callback_set_default() to set an async +callback function. +

+Note: destroy_notify may be called on any thread - it is not +guaranteed to be called on the main thread.

+ +

callback_name : The name of the module callback to set +
callback : The function to call when the callback is invoked +
callback_data : Pointer to pass as the callback_data argument to callback +
destroy_notify : Function to call when callback_data is to be freed. +

gnome_vfs_module_callback_push ()

void        gnome_vfs_module_callback_push  (const char *callback_name,
+                                             GnomeVFSModuleCallback callback,
+                                             gpointer callback_data,
+                                             GDestroyNotify destroy_notify);

+Set callback as a temprary handler for callback_name. callback +will be called with callback_data on the same thread as the +gnome-vfs operation that invokes it. The temporary handler is set +per-thread. +

+gnome_vfs_module_callback_pop() removes the most recently set +temporary handler. The temporary handlers are treated as a first-in +first-out stack. +

+Use this function to set a temporary callback handler for a single +call or a few calls. You can use +gnome_vfs_module_callback_set_default() to set a callback function +that will establish a permanent global setting for all threads +instead. +

+Note: destroy_notify may be called on any thread - it is not +guaranteed to be called on the main thread.

+ +

callback_name : The name of the module callback to set temporarily +
callback : The function to call when the callback is invoked +
callback_data : Pointer to pass as the callback_data argument to callback +
destroy_notify : Function to call when callback_data is to be freed. +

gnome_vfs_module_callback_pop ()

void        gnome_vfs_module_callback_pop   (const char *callback_name);

+Remove the temporary handler for callback_name most recently set +with gnome_vfs_module_callback_push(). If another temporary +handler was previously set on the same thread, it becomes the +current handler. Otherwise, the default handler, if any, becomes +current. +

+The temporary handlers are treated as a first-in first-out +stack.

+ +

callback_name : The name of the module callback to remove a temporary handler for +

gnome_vfs_async_module_callback_set_default ()

void        gnome_vfs_async_module_callback_set_default
+                                            (const char *callback_name,
+                                             GnomeVFSAsyncModuleCallback callback,
+                                             gpointer callback_data,
+                                             GDestroyNotify destroy_notify);

+Set the default async callback for callback_name to +callback. callback will be called with callback_data +from a callback on the main thread. It will be passed a response +function which should be called to signal completion of the callback. +The callback function itself may return in the meantime. +

+The default value is shared for all threads, but setting it is +thread-safe. +

+Use this function if you want to globally set a callback handler +for use with async operations. +

+You can use gnome_vfs_async_module_callback_push() to set an async +callback function that will temporarily override the default on the +current thread instead. Or you can also use +gnome_vfs_module_callback_set_default() to set a regular callback +function. +

+Note: destroy_notify may be called on any thread - it is not +guaranteed to be called on the main thread.

+ +

callback_name : The name of the async module callback to set +
callback : The function to call when the callback is invoked +
callback_data : Pointer to pass as the callback_data argument to callback +
destroy_notify : Function to call when callback_data is to be freed. +

gnome_vfs_async_module_callback_push ()

void        gnome_vfs_async_module_callback_push
+                                            (const char *callback_name,
+                                             GnomeVFSAsyncModuleCallback callback,
+                                             gpointer callback_data,
+                                             GDestroyNotify destroy_notify);

+Set callback_func as a temprary async handler for +callback_name. callback will be called with callback_data +from a callback on the main thread. It will be passed a response +function which should be called to signal completion of the +callback. The callback function itself may return in the meantime. +

+The temporary async handler is set per-thread. +

+gnome_vfs_async_module_callback_pop() removes the most recently set +temporary temporary handler. The temporary async handlers are +treated as a first-in first-out stack. +

+Use this function to set a temporary async callback handler for a +single call or a few calls. You can use +gnome_vfs_async_module_callback_set_default() to set an async +callback function that will establish a permanent global setting +for all threads instead. +

+Note: destroy_notify may be called on any thread - it is not +guaranteed to be called on the main thread.

+ +

callback_name : The name of the module callback to set temporarily +
callback : The function to call when the callback is invoked +
callback_data : Pointer to pass as the callback_data argument to callback +
destroy_notify : Function to call when callback_data is to be freed. +

gnome_vfs_async_module_callback_pop ()

void        gnome_vfs_async_module_callback_pop
+                                            (const char *callback_name);

+Remove the temporary async handler for callback_name most recently +set with gnome_vfs_async_module_callback_push(). If another +temporary async handler was previously set on the same thread, it +becomes the current handler. Otherwise, the default async handler, +if any, becomes current. +

+The temporary async handlers are treated as a first-in first-out +stack.

+ +

callback_name : The name of the module callback to remove a temporary handler for +
diff --git a/doc/html/gnome-vfs-20-gnome-vfs-module-shared.html b/doc/html/gnome-vfs-20-gnome-vfs-module-shared.html new file mode 100644 index 0000000..eb4a04b --- /dev/null +++ b/doc/html/gnome-vfs-20-gnome-vfs-module-shared.html @@ -0,0 +1,98 @@ +gnome-vfs-module-shared

gnome-vfs-module-shared

gnome-vfs-module-shared —

Synopsis

+
+
+
+const gchar* gnome_vfs_mime_type_from_mode  (mode_t mode);
+void        gnome_vfs_stat_to_file_info     (GnomeVFSFileInfo *file_info,
+                                             const struct stat *statptr);
+GnomeVFSResult gnome_vfs_set_meta           (GnomeVFSFileInfo *info,
+                                             const char *file_name,
+                                             const char *meta_key);
+GnomeVFSResult gnome_vfs_set_meta_for_list  (GnomeVFSFileInfo *info,
+                                             const char *file_name,
+                                             const GList *meta_keys);
+const char* gnome_vfs_get_special_mime_type (GnomeVFSURI *uri);
+

Description

+ +

Details

gnome_vfs_mime_type_from_mode ()

const gchar* gnome_vfs_mime_type_from_mode  (mode_t mode);

+Returns a MIME type based on the mode passed. It only works when mode +references a special file (directory, device, fifo, socket or symlink) +

+Returns: a string containing the MIME type, if mode is a normal file

+ +

mode : +
Returns :NULL. +

gnome_vfs_stat_to_file_info ()

void        gnome_vfs_stat_to_file_info     (GnomeVFSFileInfo *file_info,
+                                             const struct stat *statptr);

+ +

file_info : +
statptr : + + +

gnome_vfs_set_meta ()

GnomeVFSResult gnome_vfs_set_meta           (GnomeVFSFileInfo *info,
+                                             const char *file_name,
+                                             const char *meta_key);

+ +

info : +
file_name : +
meta_key : +
Returns : + + +

gnome_vfs_set_meta_for_list ()

GnomeVFSResult gnome_vfs_set_meta_for_list  (GnomeVFSFileInfo *info,
+                                             const char *file_name,
+                                             const GList *meta_keys);

+ +

info : +
file_name : +
meta_keys : +
Returns : + + +

gnome_vfs_get_special_mime_type ()

const char* gnome_vfs_get_special_mime_type (GnomeVFSURI *uri);

+Gets the MIME type for uri, this function only returns the type +when the URI points to a file that can't be sniffed (sockets, +directories, devices, and fifos).

+ +

uri : +
Returns : a string containing the mime type, NULL if the uri doesn't +present an special file. +
diff --git a/doc/html/gnome-vfs-20-gnome-vfs-module.html b/doc/html/gnome-vfs-20-gnome-vfs-module.html new file mode 100644 index 0000000..687868c --- /dev/null +++ b/doc/html/gnome-vfs-20-gnome-vfs-module.html @@ -0,0 +1,69 @@ +gnome-vfs-module

gnome-vfs-module

gnome-vfs-module —

Synopsis

+
+
+
+GnomeVFSMethod* vfs_module_init             (const char *method_name,
+                                             const char *args);
+GnomeVFSTransform* vfs_module_transform     (const char *method_name,
+                                             const char *args);
+void        vfs_module_shutdown             (GnomeVFSMethod *method);
+

Description

+ +

Details

vfs_module_init ()

GnomeVFSMethod* vfs_module_init             (const char *method_name,
+                                             const char *args);

+Standard extern call implemented by each filesystem module. This is called +to initialize the module and setup any basic structures / connections the +method requires. It also allows the module to identify the URI method it is +associated with in this instance.

+ +

method_name : name of the method that invoked this module (e.g. "http", "ftp", "file"). +
args : not used by most modules, but potential arguments for creating the module (could +be a file to point at, for example) +
Returns : the module symbol table, pointing to the appropriate calls for +this module. +

vfs_module_transform ()

GnomeVFSTransform* vfs_module_transform     (const char *method_name,
+                                             const char *args);

+Shift an already instanced module to a new method name. This call is not implemented +by most modules and is optional.

+ +

method_name : name of the method that invoked this module (e.g. "http", "ftp", "file"). +
args : not used by most modules, but potential arguments for creating the module (could +be a file to point at, for example) +
Returns : the module symbol table, pointing to the appropriate calls for +this module. +

vfs_module_shutdown ()

void        vfs_module_shutdown             (GnomeVFSMethod *method);

+Called to tell a module to end any active operations, free all used memory, +and close any connections (as appropriate) or resources.

+ +

method : the symbol table of the module being shut down +
diff --git a/doc/html/gnome-vfs-20-gnome-vfs-monitor.html b/doc/html/gnome-vfs-20-gnome-vfs-monitor.html new file mode 100644 index 0000000..e89967e --- /dev/null +++ b/doc/html/gnome-vfs-20-gnome-vfs-monitor.html @@ -0,0 +1,128 @@ +Monitoring

Monitoring

Monitoring — +watch files for changes, and get called back if they do

Synopsis

+
+
+
+GnomeVFSResult gnome_vfs_monitor_add        (GnomeVFSMonitorHandle **handle,
+                                             const gchar *text_uri,
+                                             GnomeVFSMonitorType monitor_type,
+                                             GnomeVFSMonitorCallback callback,
+                                             gpointer user_data);
+GnomeVFSResult gnome_vfs_monitor_cancel     (GnomeVFSMonitorHandle *handle);
+enum        GnomeVFSMonitorType;
+enum        GnomeVFSMonitorEventType;
+void        (*GnomeVFSMonitorCallback)      (GnomeVFSMonitorHandle *handle,
+                                             const gchar *monitor_uri,
+                                             const gchar *info_uri,
+                                             GnomeVFSMonitorEventType event_type,
+                                             gpointer user_data);
+

Description

+ +

Details

gnome_vfs_monitor_add ()

GnomeVFSResult gnome_vfs_monitor_add        (GnomeVFSMonitorHandle **handle,
+                                             const gchar *text_uri,
+                                             GnomeVFSMonitorType monitor_type,
+                                             GnomeVFSMonitorCallback callback,
+                                             gpointer user_data);

+Watch the file or directory at text_uri for changes (or the creation/deletion of the file) +and call callback when there is a change. If a directory monitor is added, callback is +notified when any file in the directory changes.

+ +

handle : after the call, handle will be a pointer to an operation handle +
text_uri : URI to monitor +
monitor_type : add a directory or file monitor +
callback : function to call when the monitor is tripped +
user_data : data to pass to callback +
Returns : an integer representing the success of the operation +

gnome_vfs_monitor_cancel ()

GnomeVFSResult gnome_vfs_monitor_cancel     (GnomeVFSMonitorHandle *handle);

+Cancel the monitor pointed to be handle.

+ +

handle : handle of the monitor to cancel +
Returns : an integer representing the success of the operation +

enum GnomeVFSMonitorType

typedef enum {
+  GNOME_VFS_MONITOR_FILE,
+  GNOME_VFS_MONITOR_DIRECTORY
+} GnomeVFSMonitorType;
+

+Type of resources that can be monitored.

+ +


enum GnomeVFSMonitorEventType

typedef enum {
+  GNOME_VFS_MONITOR_EVENT_CHANGED,
+  GNOME_VFS_MONITOR_EVENT_DELETED,
+  GNOME_VFS_MONITOR_EVENT_STARTEXECUTING,
+  GNOME_VFS_MONITOR_EVENT_STOPEXECUTING,
+  GNOME_VFS_MONITOR_EVENT_CREATED,
+  GNOME_VFS_MONITOR_EVENT_METADATA_CHANGED
+} GnomeVFSMonitorEventType;
+

+Types of events that can be monitored.

+ +

GNOME_VFS_MONITOR_EVENT_CHANGED file data changed +
GNOME_VFS_MONITOR_EVENT_DELETED file deleted event +
GNOME_VFS_MONITOR_EVENT_STARTEXECUTING +
GNOME_VFS_MONITOR_EVENT_STOPEXECUTING +
GNOME_VFS_MONITOR_EVENT_CREATED file created event +
GNOME_VFS_MONITOR_EVENT_METADATA_CHANGED file metadata changed +

GnomeVFSMonitorCallback ()

void        (*GnomeVFSMonitorCallback)      (GnomeVFSMonitorHandle *handle,
+                                             const gchar *monitor_uri,
+                                             const gchar *info_uri,
+                                             GnomeVFSMonitorEventType event_type,
+                                             gpointer user_data);

+Function called when a monitor detects a change.

+ +

handle : the handle of the monitor that created the event +
monitor_uri : the URI of the monitor that was triggered +
info_uri : the URI of the actual file this event is concerned with (this can be different +from monitor_uri if it was a directory monitor) +
event_type : what happened to info_uri +
user_data : user data passed to gnome_vfs_monitor_add() when the monitor was created +
diff --git a/doc/html/gnome-vfs-20-gnome-vfs-parse-ls.html b/doc/html/gnome-vfs-20-gnome-vfs-parse-ls.html new file mode 100644 index 0000000..4f098f8 --- /dev/null +++ b/doc/html/gnome-vfs-20-gnome-vfs-parse-ls.html @@ -0,0 +1,53 @@ +gnome-vfs-parse-ls

gnome-vfs-parse-ls

gnome-vfs-parse-ls — convenience functions for modules which want to parse a ls-like directory listing

Synopsis

+
+
+
+int         gnome_vfs_parse_ls_lga          (const char *p,
+                                             struct stat *s,
+                                             char **filename,
+                                             char **linkname);
+

Description

+ +

Details

gnome_vfs_parse_ls_lga ()

int         gnome_vfs_parse_ls_lga          (const char *p,
+                                             struct stat *s,
+                                             char **filename,
+                                             char **linkname);

+ +

p : +
s : +
filename : +
linkname : +
Returns : + + +
diff --git a/doc/html/gnome-vfs-20-gnome-vfs-result.html b/doc/html/gnome-vfs-20-gnome-vfs-result.html new file mode 100644 index 0000000..06bbb0a --- /dev/null +++ b/doc/html/gnome-vfs-20-gnome-vfs-result.html @@ -0,0 +1,118 @@ +GnomeVFSResult

GnomeVFSResult

GnomeVFSResult — +Result of I/O operations, the equivalent of errno

Description

+ +

Details

enum GnomeVFSResult

typedef enum {
+	GNOME_VFS_OK,
+	GNOME_VFS_ERROR_NOT_FOUND,
+	GNOME_VFS_ERROR_GENERIC,
+	GNOME_VFS_ERROR_INTERNAL,
+	GNOME_VFS_ERROR_BAD_PARAMETERS,
+	GNOME_VFS_ERROR_NOT_SUPPORTED,
+	GNOME_VFS_ERROR_IO,
+	GNOME_VFS_ERROR_CORRUPTED_DATA,
+	GNOME_VFS_ERROR_WRONG_FORMAT,
+	GNOME_VFS_ERROR_BAD_FILE,
+	GNOME_VFS_ERROR_TOO_BIG,
+	GNOME_VFS_ERROR_NO_SPACE,
+	GNOME_VFS_ERROR_READ_ONLY,
+	GNOME_VFS_ERROR_INVALID_URI,
+	GNOME_VFS_ERROR_NOT_OPEN,
+	GNOME_VFS_ERROR_INVALID_OPEN_MODE,
+	GNOME_VFS_ERROR_ACCESS_DENIED,
+	GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES,
+	GNOME_VFS_ERROR_EOF,
+	GNOME_VFS_ERROR_NOT_A_DIRECTORY,
+	GNOME_VFS_ERROR_IN_PROGRESS,
+	GNOME_VFS_ERROR_INTERRUPTED,
+	GNOME_VFS_ERROR_FILE_EXISTS,
+	GNOME_VFS_ERROR_LOOP,
+	GNOME_VFS_ERROR_NOT_PERMITTED,
+	GNOME_VFS_ERROR_IS_DIRECTORY,
+	GNOME_VFS_ERROR_NO_MEMORY,
+	GNOME_VFS_ERROR_HOST_NOT_FOUND,
+	GNOME_VFS_ERROR_INVALID_HOST_NAME,
+	GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS,
+	GNOME_VFS_ERROR_LOGIN_FAILED,
+	GNOME_VFS_ERROR_CANCELLED,
+	GNOME_VFS_ERROR_DIRECTORY_BUSY,
+	GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY,
+	GNOME_VFS_ERROR_TOO_MANY_LINKS,
+	GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM,
+	GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM,
+	GNOME_VFS_ERROR_NAME_TOO_LONG,
+	GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE,
+	GNOME_VFS_ERROR_SERVICE_OBSOLETE,
+	GNOME_VFS_ERROR_PROTOCOL_ERROR,
+	GNOME_VFS_ERROR_NO_MASTER_BROWSER,
+	GNOME_VFS_ERROR_NO_DEFAULT,
+	GNOME_VFS_ERROR_NO_HANDLER,
+	GNOME_VFS_ERROR_PARSE,
+	GNOME_VFS_ERROR_LAUNCH,
+	GNOME_VFS_NUM_ERRORS
+} GnomeVFSResult;
+

+ +


gnome_vfs_result_to_string ()

const char* gnome_vfs_result_to_string      (GnomeVFSResult result);

+Returns a string representation of result, useful for debugging +purposes, but probably not appropriate for passing to the user.

+ +

result : the result to convert to a string +
Returns : a string representing result +

gnome_vfs_result_from_errno_code ()

GnomeVFSResult gnome_vfs_result_from_errno_code
+                                            (int errno_code);

+Converts a system errno value to a GnomeVFSResult.

+ +

errno_code : integer of the same type as the system "errno" +
Returns : a GnomeVFSResult equivalent to errno_code +

gnome_vfs_result_from_errno ()

GnomeVFSResult gnome_vfs_result_from_errno  (void);

+Converts the system errno to a GnomeVFSResult.

+ +

Returns : a GnomeVFSResult equivalent to the current system errno +

gnome_vfs_result_from_h_errno ()

GnomeVFSResult gnome_vfs_result_from_h_errno
+                                            (void);

+Converts the system "h_errno" to a GnomeVFSResult (h_errno represents errors +accessing and finding internet hosts)

+ +

Returns : a GnomeVFSResult equivalent to the current system "h_errno" +
diff --git a/doc/html/gnome-vfs-20-gnome-vfs-socket-buffer.html b/doc/html/gnome-vfs-20-gnome-vfs-socket-buffer.html new file mode 100644 index 0000000..993b18d --- /dev/null +++ b/doc/html/gnome-vfs-20-gnome-vfs-socket-buffer.html @@ -0,0 +1,127 @@ +gnome-vfs-socket-buffer

gnome-vfs-socket-buffer

gnome-vfs-socket-buffer —

Synopsis

+
+
+
+GnomeVFSSocketBuffer* gnome_vfs_socket_buffer_new
+                                            (GnomeVFSSocket *socket);
+GnomeVFSResult gnome_vfs_socket_buffer_destroy
+                                            (GnomeVFSSocketBuffer *socket_buffer,
+                                             gboolean close_socket);
+GnomeVFSResult gnome_vfs_socket_buffer_read (GnomeVFSSocketBuffer *socket_buffer,
+                                             gpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_read);
+GnomeVFSResult gnome_vfs_socket_buffer_peekc
+                                            (GnomeVFSSocketBuffer *socket_buffer,
+                                             char *character);
+GnomeVFSResult gnome_vfs_socket_buffer_write
+                                            (GnomeVFSSocketBuffer *socket_buffer,
+                                             gconstpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_written);
+GnomeVFSResult gnome_vfs_socket_buffer_flush
+                                            (GnomeVFSSocketBuffer *socket_buffer);
+

Description

+ +

Details

gnome_vfs_socket_buffer_new ()

GnomeVFSSocketBuffer* gnome_vfs_socket_buffer_new
+                                            (GnomeVFSSocket *socket);

+Create a socket buffer around socket. A buffered +socket allows data to be poked at without reading it +as it will be buffered. A future read will retrieve +the data again.

+ +

socket : socket to be buffered +
Returns : a newly allocated GnomeVFSSocketBuffer +

gnome_vfs_socket_buffer_destroy ()

GnomeVFSResult gnome_vfs_socket_buffer_destroy
+                                            (GnomeVFSSocketBuffer *socket_buffer,
+                                             gboolean close_socket);

+Free the socket buffer.

+ +

socket_buffer : buffered socket to destray +
close_socket : if TRUE the socket being buffered will be closed too +
Returns : GnomeVFSResult indicating the success of the operation +

gnome_vfs_socket_buffer_read ()

GnomeVFSResult gnome_vfs_socket_buffer_read (GnomeVFSSocketBuffer *socket_buffer,
+                                             gpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_read);

+Read bytes bytes of data from the socket into socket_buffer.

+ +

socket_buffer : buffered socket to read data from +
buffer : allocated buffer of at least bytes bytes to be read into +
bytes : number of bytes to read from socket into socket_buffer +
bytes_read : pointer to a GnomeVFSFileSize, will contain +the number of bytes actually read from the socket on return. +
Returns : GnomeVFSResult indicating the success of the operation +

gnome_vfs_socket_buffer_peekc ()

GnomeVFSResult gnome_vfs_socket_buffer_peekc
+                                            (GnomeVFSSocketBuffer *socket_buffer,
+                                             char *character);

+Peek at the next character in socket_buffer without actually reading +the character in. The next read will retrieve c (as well as any following +data if requested).

+ +

socket_buffer : the socket buffer to read from +
character : pointer to a char, will contain a character on return from +a successful "peek" +
Returns : GnomeVFSResult indicating the success of the operation +

gnome_vfs_socket_buffer_write ()

GnomeVFSResult gnome_vfs_socket_buffer_write
+                                            (GnomeVFSSocketBuffer *socket_buffer,
+                                             gconstpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_written);

+Write bytes bytes of data from buffer to socket_buffer.

+ +

socket_buffer : buffered socket to write data to +
buffer : data to write to the socket +
bytes : number of bytes from buffer to write to socket_buffer +
bytes_written : pointer to a GnomeVFSFileSize, will contain +the number of bytes actually written to the socket on return. +
Returns : GnomeVFSResult indicating the success of the operation +

gnome_vfs_socket_buffer_flush ()

GnomeVFSResult gnome_vfs_socket_buffer_flush
+                                            (GnomeVFSSocketBuffer *socket_buffer);

+Write all outstanding data to socket_buffer.

+ +

socket_buffer : buffer to flush +
Returns : GnomeVFSResult indicating the success of the operation +
diff --git a/doc/html/gnome-vfs-20-gnome-vfs-socket.html b/doc/html/gnome-vfs-20-gnome-vfs-socket.html new file mode 100644 index 0000000..37fe952 --- /dev/null +++ b/doc/html/gnome-vfs-20-gnome-vfs-socket.html @@ -0,0 +1,161 @@ +gnome-vfs-socket

gnome-vfs-socket

gnome-vfs-socket —

Synopsis

+
+
+
+GnomeVFSResult (*GnomeVFSSocketReadFunc)    (gpointer connection,
+                                             gpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_read);
+GnomeVFSResult (*GnomeVFSSocketWriteFunc)   (gpointer connection,
+                                             gconstpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_written);
+void        (*GnomeVFSSocketCloseFunc)      (gpointer connection);
+typedef     GnomeVFSSocketImpl;
+GnomeVFSSocket* gnome_vfs_socket_new        (GnomeVFSSocketImpl *impl,
+                                             void *connection);
+GnomeVFSResult gnome_vfs_socket_write       (GnomeVFSSocket *socket,
+                                             gconstpointer buffer,
+                                             int bytes,
+                                             GnomeVFSFileSize *bytes_written);
+GnomeVFSResult gnome_vfs_socket_close       (GnomeVFSSocket *socket);
+GnomeVFSResult gnome_vfs_socket_read        (GnomeVFSSocket *socket,
+                                             gpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_read);
+

Description

+ +

Details

GnomeVFSSocketReadFunc ()

GnomeVFSResult (*GnomeVFSSocketReadFunc)    (gpointer connection,
+                                             gpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_read);

+ +

connection : +
buffer : +
bytes : +
bytes_read : +
Returns : + + +

GnomeVFSSocketWriteFunc ()

GnomeVFSResult (*GnomeVFSSocketWriteFunc)   (gpointer connection,
+                                             gconstpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_written);

+ +

connection : +
buffer : +
bytes : +
bytes_written : +
Returns : + + +

GnomeVFSSocketCloseFunc ()

void        (*GnomeVFSSocketCloseFunc)      (gpointer connection);

+ +

connection : + + +

GnomeVFSSocketImpl

typedef struct {
+  GnomeVFSSocketReadFunc read;
+  GnomeVFSSocketWriteFunc write;
+  GnomeVFSSocketCloseFunc close;
+} GnomeVFSSocketImpl;
+

+ +


gnome_vfs_socket_new ()

GnomeVFSSocket* gnome_vfs_socket_new        (GnomeVFSSocketImpl *impl,
+                                             void *connection);

+Creates a new GnomeVFS Socket using the specific implementation +impl.

+ +

impl : an implementation of a socket, e.g. GnomeVFSSSL +
connection : pointer to a connection object used by impl to track +state (the exact nature of connection varies from implementation to +implementation) +
Returns : a newly created socket +

gnome_vfs_socket_write ()

GnomeVFSResult gnome_vfs_socket_write       (GnomeVFSSocket *socket,
+                                             gconstpointer buffer,
+                                             int bytes,
+                                             GnomeVFSFileSize *bytes_written);

+Write bytes bytes of data from buffer to socket.

+ +

socket : socket to write data to +
buffer : data to write to the socket +
bytes : number of bytes from buffer to write to socket +
bytes_written : pointer to a GnomeVFSFileSize, will contain +the number of bytes actually written to the socket on return. +
Returns : GnomeVFSResult indicating the success of the operation +

gnome_vfs_socket_close ()

GnomeVFSResult gnome_vfs_socket_close       (GnomeVFSSocket *socket);

+Close socket, freeing any resources it may be using.

+ +

socket : the socket to be closed +
Returns : GnomeVFSResult indicating the success of the operation +

gnome_vfs_socket_read ()

GnomeVFSResult gnome_vfs_socket_read        (GnomeVFSSocket *socket,
+                                             gpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_read);

+Read bytes bytes of data from the socket into buffer.

+ +

socket : socket to read data from +
buffer : allocated buffer of at least bytes bytes to be read into +
bytes : number of bytes to read from socket into buffer +
bytes_read : pointer to a GnomeVFSFileSize, will contain +the number of bytes actually read from the socket on return. +
Returns : GnomeVFSResult indicating the success of the operation +
diff --git a/doc/html/gnome-vfs-20-gnome-vfs-ssl.html b/doc/html/gnome-vfs-20-gnome-vfs-ssl.html new file mode 100644 index 0000000..6e3ec1f --- /dev/null +++ b/doc/html/gnome-vfs-20-gnome-vfs-ssl.html @@ -0,0 +1,126 @@ +gnome-vfs-ssl

gnome-vfs-ssl

gnome-vfs-ssl —

Synopsis

+
+
+
+gboolean    gnome_vfs_ssl_enabled           (void);
+GnomeVFSResult gnome_vfs_ssl_create         (GnomeVFSSSL **handle_return,
+                                             const char *host,
+                                             unsigned int port);
+GnomeVFSResult gnome_vfs_ssl_create_from_fd (GnomeVFSSSL **handle_return,
+                                             gint fd);
+GnomeVFSResult gnome_vfs_ssl_read           (GnomeVFSSSL *ssl,
+                                             gpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_read);
+GnomeVFSResult gnome_vfs_ssl_write          (GnomeVFSSSL *ssl,
+                                             gconstpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_written);
+void        gnome_vfs_ssl_destroy           (GnomeVFSSSL *ssl);
+GnomeVFSSocket* gnome_vfs_ssl_to_socket     (GnomeVFSSSL *ssl);
+

Description

+ +

Details

gnome_vfs_ssl_enabled ()

gboolean    gnome_vfs_ssl_enabled           (void);

+Checks whether GnomeVFS was compiled with SSL support.

+ +

Returns : TRUE if GnomeVFS was compiled with SSL support, +otherwise FALSE. +

gnome_vfs_ssl_create ()

GnomeVFSResult gnome_vfs_ssl_create         (GnomeVFSSSL **handle_return,
+                                             const char *host,
+                                             unsigned int port);

+Creates an SSL socket connection at handle_return to host using +port port.

+ +

handle_return : pointer to a GnmoeVFSSSL struct, which will +contain an allocated GnomeVFSSSL object on return. +
host : string indicating the host to establish an SSL connection with +
port : the port number to connect to +
Returns : GnomeVFSResult indicating the success of the operation +

gnome_vfs_ssl_create_from_fd ()

GnomeVFSResult gnome_vfs_ssl_create_from_fd (GnomeVFSSSL **handle_return,
+                                             gint fd);

+Try to establish an SSL connection over the file descriptor fd.

+ +

handle_return : pointer to a GnmoeVFSSSL struct, which will +contain an allocated GnomeVFSSSL object on return. +
fd : file descriptior to try and establish an SSL connection over +
Returns : a GnomeVFSResult indicating the success of the operation +

gnome_vfs_ssl_read ()

GnomeVFSResult gnome_vfs_ssl_read           (GnomeVFSSSL *ssl,
+                                             gpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_read);

+Read bytes bytes of data from the SSL socket ssl into buffer.

+ +

ssl : SSL socket to read data from +
buffer : allocated buffer of at least bytes bytes to be read into +
bytes : number of bytes to read from ssl into buffer +
bytes_read : pointer to a GnomeVFSFileSize, will contain +the number of bytes actually read from the socket on return. +
Returns : GnomeVFSResult indicating the success of the operation +

gnome_vfs_ssl_write ()

GnomeVFSResult gnome_vfs_ssl_write          (GnomeVFSSSL *ssl,
+                                             gconstpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_written);

+Write bytes bytes of data from buffer to ssl.

+ +

ssl : SSL socket to write data to +
buffer : data to write to the socket +
bytes : number of bytes from buffer to write to ssl +
bytes_written : pointer to a GnomeVFSFileSize, will contain +the number of bytes actually written to the socket on return. +
Returns : GnomeVFSResult indicating the success of the operation +

gnome_vfs_ssl_destroy ()

void        gnome_vfs_ssl_destroy           (GnomeVFSSSL *ssl);

+Free resources used by ssl and close the connection.

+ +

ssl : SSL socket to be closed and destroyed +

gnome_vfs_ssl_to_socket ()

GnomeVFSSocket* gnome_vfs_ssl_to_socket     (GnomeVFSSSL *ssl);

+Wrapper an SSL socket inside a standard GnomeVFSSocket.

+ +

ssl : SSL socket to convert into a standard socket +
Returns : a newly allocated GnomeVFSSocket corresponding to ssl. +
diff --git a/doc/html/gnome-vfs-20-gnome-vfs-standard-callbacks.html b/doc/html/gnome-vfs-20-gnome-vfs-standard-callbacks.html new file mode 100644 index 0000000..3e30b53 --- /dev/null +++ b/doc/html/gnome-vfs-20-gnome-vfs-standard-callbacks.html @@ -0,0 +1,140 @@ +gnome-vfs-standard-callbacks

gnome-vfs-standard-callbacks

gnome-vfs-standard-callbacks — standard callbacks for use by gnome-vfs module writers

Description

+ +

Details

GNOME_VFS_MODULE_CALLBACK_AUTHENTICATION

#define GNOME_VFS_MODULE_CALLBACK_AUTHENTICATION "simple-authentication"
+

+ +


GNOME_VFS_MODULE_CALLBACK_HTTP_PROXY_AUTHENTICATION

#define GNOME_VFS_MODULE_CALLBACK_HTTP_PROXY_AUTHENTICATION "http:proxy-authentication"
+

+ +


GnomeVFSModuleCallbackAuthenticationOut

typedef struct {
+	char *username;		/* will be freed by g_free,
+				 * NULL indicates no auth should be provided;
+				 * if the request requires authn, the operation
+				 * will fail with a GNOME_VFS_ERROR_ACCESS_DENIED
+				 * code
+				 */
+	char *password;		/* will be freed by g_free */
+
+	/* Reserved "padding" to avoid future breaks in ABI compatibility */
+	void *reserved1;
+	void *reserved2;
+
+} GnomeVFSModuleCallbackAuthenticationOut;
+

+ +


GNOME_VFS_MODULE_CALLBACK_HTTP_SEND_ADDITIONAL_HEADERS

#define GNOME_VFS_MODULE_CALLBACK_HTTP_SEND_ADDITIONAL_HEADERS "http:send-additional-headers"
+

+ +


GnomeVFSModuleCallbackAdditionalHeadersIn

typedef struct {
+	GnomeVFSURI *uri;		/* URI of operation */
+
+	/* Reserved "padding" to avoid future breaks in ABI compatibility */
+	void *reserved1;
+	void *reserved2;
+} GnomeVFSModuleCallbackAdditionalHeadersIn;
+

+ +


GnomeVFSModuleCallbackAdditionalHeadersOut

typedef struct {
+	GList *headers;			/* list of headers, will be freeed */
+
+	/* Reserved "padding" to avoid future breaks in ABI compatibility */
+	void *reserved1;
+	void *reserved2;
+} GnomeVFSModuleCallbackAdditionalHeadersOut;
+

+ +


GNOME_VFS_MODULE_CALLBACK_HTTP_RECEIVED_HEADERS

#define GNOME_VFS_MODULE_CALLBACK_HTTP_RECEIVED_HEADERS "http:received-headers"
+

+ +


GnomeVFSModuleCallbackReceivedHeadersIn

typedef struct {
+	GnomeVFSURI *uri;		/* URI of operation */
+	GList *headers;			/* list of headers */
+
+	/* Reserved "padding" to avoid future breaks in ABI compatibility */
+	void *reserved1;
+	void *reserved2;
+} GnomeVFSModuleCallbackReceivedHeadersIn;
+

+ +


GnomeVFSModuleCallbackReceivedHeadersOut

typedef struct {
+	int dummy;
+
+	/* Reserved "padding" to avoid future breaks in ABI compatibility */
+	void *reserved1;
+	void *reserved2;
+} GnomeVFSModuleCallbackReceivedHeadersOut;
+

+ +


GNOME_VFS_MODULE_CALLBACK_STATUS_MESSAGE

#define GNOME_VFS_MODULE_CALLBACK_STATUS_MESSAGE "status-message"
+

+ +


GnomeVFSModuleCallbackStatusMessageIn

typedef struct {
+	char *uri;		/* Full URI of operation */
+	char *message;		/* A message indicating the current state or
+				 * NULL if there is no message */
+	int percentage;		/* Percentage indicating completeness 0-100 or
+				 * -1 if there is no progress percentage to
+				 * report */
+
+	/* Reserved "padding" to avoid future breaks in ABI compatibility */
+	void *reserved1;
+	void *reserved2;
+} GnomeVFSModuleCallbackStatusMessageIn;
+

+ +


GnomeVFSModuleCallbackStatusMessageOut

typedef struct {
+	int dummy; /* empty structs not allowed */
+
+	/* Reserved "padding" to avoid future breaks in ABI compatibility */
+	void *reserved1;
+	void *reserved2;
+} GnomeVFSModuleCallbackStatusMessageOut;
+

+ +

diff --git a/doc/html/gnome-vfs-20-gnome-vfs-transform.html b/doc/html/gnome-vfs-20-gnome-vfs-transform.html new file mode 100644 index 0000000..0ce3771 --- /dev/null +++ b/doc/html/gnome-vfs-20-gnome-vfs-transform.html @@ -0,0 +1,65 @@ +gnome-vfs-transform

gnome-vfs-transform

gnome-vfs-transform —

Synopsis

+
+
+
+GnomeVFSTransform* (*GnomeVFSTransformInitFunc)
+                                            (const char *method_name,
+                                             const char *config_args);
+GnomeVFSResult (*GnomeVFSTransformFunc)     (GnomeVFSTransform *transform,
+                                             const char *old_uri,
+                                             char **new_uri,
+                                             GnomeVFSContext *context);
+

Description

+ +

Details

GnomeVFSTransformInitFunc ()

GnomeVFSTransform* (*GnomeVFSTransformInitFunc)
+                                            (const char *method_name,
+                                             const char *config_args);

+ +

method_name : +
config_args : +
Returns : + + +

GnomeVFSTransformFunc ()

GnomeVFSResult (*GnomeVFSTransformFunc)     (GnomeVFSTransform *transform,
+                                             const char *old_uri,
+                                             char **new_uri,
+                                             GnomeVFSContext *context);

+ +

transform : +
old_uri : +
new_uri : +
context : +
Returns : + + +
diff --git a/doc/html/gnome-vfs-20-gnome-vfs-uri.html b/doc/html/gnome-vfs-20-gnome-vfs-uri.html new file mode 100644 index 0000000..e18b1b9 --- /dev/null +++ b/doc/html/gnome-vfs-20-gnome-vfs-uri.html @@ -0,0 +1,571 @@ +GnomeVFSURI

GnomeVFSURI

GnomeVFSURI — +Functions for manipulating URIs

Synopsis

+
+
+
+typedef     GnomeVFSToplevelURI;
+enum        GnomeVFSURIHideOptions;
+#define     GNOME_VFS_URI_MAGIC_CHR
+#define     GNOME_VFS_URI_MAGIC_STR
+#define     GNOME_VFS_URI_PATH_CHR
+#define     GNOME_VFS_URI_PATH_STR
+GnomeVFSURI* gnome_vfs_uri_new              (const gchar *text_uri);
+GnomeVFSURI* gnome_vfs_uri_resolve_relative (const GnomeVFSURI *base,
+                                             const gchar *relative_reference);
+GnomeVFSURI* gnome_vfs_uri_ref              (GnomeVFSURI *uri);
+void        gnome_vfs_uri_unref             (GnomeVFSURI *uri);
+GnomeVFSURI* gnome_vfs_uri_append_string    (const GnomeVFSURI *uri,
+                                             const char *uri_fragment);
+GnomeVFSURI* gnome_vfs_uri_append_path      (const GnomeVFSURI *uri,
+                                             const char *path);
+GnomeVFSURI* gnome_vfs_uri_append_file_name (const GnomeVFSURI *uri,
+                                             const gchar *filename);
+gchar*      gnome_vfs_uri_to_string         (const GnomeVFSURI *uri,
+                                             GnomeVFSURIHideOptions hide_options);
+GnomeVFSURI* gnome_vfs_uri_dup              (const GnomeVFSURI *uri);
+gboolean    gnome_vfs_uri_is_local          (const GnomeVFSURI *uri);
+gboolean    gnome_vfs_uri_has_parent        (const GnomeVFSURI *uri);
+GnomeVFSURI* gnome_vfs_uri_get_parent       (const GnomeVFSURI *uri);
+GnomeVFSToplevelURI* gnome_vfs_uri_get_toplevel
+                                            (const GnomeVFSURI *uri);
+const gchar* gnome_vfs_uri_get_host_name    (const GnomeVFSURI *uri);
+const gchar* gnome_vfs_uri_get_scheme       (const GnomeVFSURI *uri);
+guint       gnome_vfs_uri_get_host_port     (const GnomeVFSURI *uri);
+const gchar* gnome_vfs_uri_get_user_name    (const GnomeVFSURI *uri);
+const gchar* gnome_vfs_uri_get_password     (const GnomeVFSURI *uri);
+void        gnome_vfs_uri_set_host_name     (GnomeVFSURI *uri,
+                                             const gchar *host_name);
+void        gnome_vfs_uri_set_host_port     (GnomeVFSURI *uri,
+                                             guint host_port);
+void        gnome_vfs_uri_set_user_name     (GnomeVFSURI *uri,
+                                             const gchar *user_name);
+void        gnome_vfs_uri_set_password      (GnomeVFSURI *uri,
+                                             const gchar *password);
+gboolean    gnome_vfs_uri_equal             (const GnomeVFSURI *a,
+                                             const GnomeVFSURI *b);
+gboolean    gnome_vfs_uri_is_parent         (const GnomeVFSURI *possible_parent,
+                                             const GnomeVFSURI *possible_child,
+                                             gboolean recursive);
+const gchar* gnome_vfs_uri_get_path         (const GnomeVFSURI *uri);
+const gchar* gnome_vfs_uri_get_fragment_identifier
+                                            (const GnomeVFSURI *uri);
+gchar*      gnome_vfs_uri_extract_dirname   (const GnomeVFSURI *uri);
+gchar*      gnome_vfs_uri_extract_short_name
+                                            (const GnomeVFSURI *uri);
+gchar*      gnome_vfs_uri_extract_short_path_name
+                                            (const GnomeVFSURI *uri);
+gint        gnome_vfs_uri_hequal            (gconstpointer a,
+                                             gconstpointer b);
+guint       gnome_vfs_uri_hash              (gconstpointer p);
+GList*      gnome_vfs_uri_list_parse        (const gchar *uri_list);
+GList*      gnome_vfs_uri_list_ref          (GList *list);
+GList*      gnome_vfs_uri_list_unref        (GList *list);
+GList*      gnome_vfs_uri_list_copy         (GList *list);
+void        gnome_vfs_uri_list_free         (GList *list);
+char*       gnome_vfs_uri_make_full_from_relative
+                                            (const char *base_uri,
+                                             const char *relative_uri);
+

Description

+ +

Details

GnomeVFSToplevelURI

typedef struct {
+	/* Base object.  */
+	GnomeVFSURI uri;
+
+	/* Server location information.  */
+	gchar *host_name;
+	guint host_port;
+
+	/* Authorization information.  */
+	gchar *user_name;
+	gchar *password;
+
+	/* The parent URN, if it exists */
+	gchar *urn;
+
+	/* Reserved to avoid future breaks in ABI compatibility */
+	void *reserved1;
+	void *reserved2;
+
+} GnomeVFSToplevelURI;
+

+ +


enum GnomeVFSURIHideOptions

typedef enum {
+	GNOME_VFS_URI_HIDE_NONE = 0,
+	GNOME_VFS_URI_HIDE_USER_NAME = 1 << 0,
+	GNOME_VFS_URI_HIDE_PASSWORD = 1 << 1,
+	GNOME_VFS_URI_HIDE_HOST_NAME = 1 << 2,
+	GNOME_VFS_URI_HIDE_HOST_PORT = 1 << 3,
+	GNOME_VFS_URI_HIDE_TOPLEVEL_METHOD = 1 << 4,
+	GNOME_VFS_URI_HIDE_FRAGMENT_IDENTIFIER = 1 << 8
+} GnomeVFSURIHideOptions;
+

+Packed boolean bitfield controlling hiding of various elements +of a GnomeVFSURI when it is converted to a string.

+ +

GNOME_VFS_URI_HIDE_NONE don't hide anything +
GNOME_VFS_URI_HIDE_USER_NAME hide the user name +
GNOME_VFS_URI_HIDE_PASSWORD hide the password +
GNOME_VFS_URI_HIDE_HOST_NAME hide the host name +
GNOME_VFS_URI_HIDE_HOST_PORT hide the port +
GNOME_VFS_URI_HIDE_TOPLEVEL_METHOD hide the method (e.g. http, file) +
GNOME_VFS_URI_HIDE_FRAGMENT_IDENTIFIER hide the fragment identifier +

GNOME_VFS_URI_MAGIC_CHR

#define GNOME_VFS_URI_MAGIC_CHR	'#'
+

+The character used to divide location from +extra "arguments" passed to the method.

+ +


GNOME_VFS_URI_MAGIC_STR

#define GNOME_VFS_URI_MAGIC_STR "#"
+

+The character used to divide location from +extra "arguments" passed to the method.

+ +


GNOME_VFS_URI_PATH_CHR

#define GNOME_VFS_URI_PATH_CHR '/'
+

+Defines the path seperator character.

+ +


GNOME_VFS_URI_PATH_STR

#define GNOME_VFS_URI_PATH_STR "/"
+

+Defines the path seperator string.

+ +


gnome_vfs_uri_new ()

GnomeVFSURI* gnome_vfs_uri_new              (const gchar *text_uri);

+Create a new URI from text_uri. Unsupported and unsafe methods +are not allowed and will result in null% being returned. URL +transforms are allowed.

+ +

text_uri : A string representing a URI. +
Returns : The new URI. +

gnome_vfs_uri_resolve_relative ()

GnomeVFSURI* gnome_vfs_uri_resolve_relative (const GnomeVFSURI *base,
+                                             const gchar *relative_reference);

+Create a new URI from relative_reference, relative to base.

+ +

base : The base URI. +
relative_reference : A string representing a possibly relative URI reference +
Returns : The new URI. +

gnome_vfs_uri_ref ()

GnomeVFSURI* gnome_vfs_uri_ref              (GnomeVFSURI *uri);

+Increment uri's reference count.

+ +

uri : A GnomeVFSURI. +
Returns : uri. +

gnome_vfs_uri_unref ()

void        gnome_vfs_uri_unref             (GnomeVFSURI *uri);

+Decrement uri's reference count. If the reference count reaches zero, +uri is destroyed.

+ +

uri : A GnomeVFSURI. +

gnome_vfs_uri_append_string ()

GnomeVFSURI* gnome_vfs_uri_append_string    (const GnomeVFSURI *uri,
+                                             const char *uri_fragment);

+Create a new URI obtained by appending path to uri. This will take care +of adding an appropriate directory separator between the end of uri and +the start of path if necessary.

+ +

uri : A GnomeVFSURI. +
uri_fragment : A piece of a URI (ie a fully escaped partial path) +
Returns : The new URI obtained by combining uri and path. +

gnome_vfs_uri_append_path ()

GnomeVFSURI* gnome_vfs_uri_append_path      (const GnomeVFSURI *uri,
+                                             const char *path);

+Create a new URI obtained by appending path to uri. This will take care +of adding an appropriate directory separator between the end of uri and +the start of path if necessary as well as escaping path as necessary.

+ +

uri : A GnomeVFSURI. +
path : A non-escaped file path +
Returns : The new URI obtained by combining uri and path. +

gnome_vfs_uri_append_file_name ()

GnomeVFSURI* gnome_vfs_uri_append_file_name (const GnomeVFSURI *uri,
+                                             const gchar *filename);

+Create a new URI obtained by appending file_name to uri. This will take care +of adding an appropriate directory separator between the end of uri and +the start of file_name if necessary.

+ +

uri : A GnomeVFSURI. +
filename : any "regular" file name (can include #, /, etc) +
Returns : The new URI obtained by combining uri and path. +

gnome_vfs_uri_to_string ()

gchar*      gnome_vfs_uri_to_string         (const GnomeVFSURI *uri,
+                                             GnomeVFSURIHideOptions hide_options);

+Translate uri into a printable string. The string will not contain the +URI elements specified by hide_options.

+ +

uri : A GnomeVFSURI. +
hide_options : Bitmask specifying what URI elements (e.g. password, +user name etc.) should not be represented in the returned string. +
Returns : A malloced printable string representing uri. +

gnome_vfs_uri_dup ()

GnomeVFSURI* gnome_vfs_uri_dup              (const GnomeVFSURI *uri);

+Duplicate uri.

+ +

uri : A GnomeVFSURI. +
Returns : A pointer to a new URI that is exactly the same as uri. +

gnome_vfs_uri_is_local ()

gboolean    gnome_vfs_uri_is_local          (const GnomeVFSURI *uri);

+Check if uri is a local (native) file system.

+ +

uri : A GnomeVFSURI. +
Returns : FALSE if uri is not a local file system, TRUE otherwise. +

gnome_vfs_uri_has_parent ()

gboolean    gnome_vfs_uri_has_parent        (const GnomeVFSURI *uri);

+Check if URI has a parent or not.

+ +

uri : A GnomeVFSURI. +
Returns : TRUE if uri has a parent, FALSE otherwise. +

gnome_vfs_uri_get_parent ()

GnomeVFSURI* gnome_vfs_uri_get_parent       (const GnomeVFSURI *uri);

+Retrieve uri's parent URI.

+ +

uri : A GnomeVFSURI. +
Returns : A pointer to uri's parent URI. +

gnome_vfs_uri_get_toplevel ()

GnomeVFSToplevelURI* gnome_vfs_uri_get_toplevel
+                                            (const GnomeVFSURI *uri);

+Retrieve the toplevel URI in uri.

+ +

uri : A GnomeVFSURI. +
Returns : A pointer to the toplevel URI object. +

gnome_vfs_uri_get_host_name ()

const gchar* gnome_vfs_uri_get_host_name    (const GnomeVFSURI *uri);

+Retrieve the host name for uri.

+ +

uri : A GnomeVFSURI. +
Returns : A string representing the host name. +

gnome_vfs_uri_get_scheme ()

const gchar* gnome_vfs_uri_get_scheme       (const GnomeVFSURI *uri);

+Retrieve the scheme used for uri

+ +

uri : A GnomeVFSURI +
Returns : A string representing the scheme +

gnome_vfs_uri_get_host_port ()

guint       gnome_vfs_uri_get_host_port     (const GnomeVFSURI *uri);

+Retrieve the host port number in uri.

+ +

uri : A GnomeVFSURI. +
Returns : The host port number used by uri. If the value is zero, the +default port value for the specified toplevel access method is used. +

gnome_vfs_uri_get_user_name ()

const gchar* gnome_vfs_uri_get_user_name    (const GnomeVFSURI *uri);

+Retrieve the user name in uri.

+ +

uri : A GnomeVFSURI. +
Returns : A string representing the user name in uri. +

gnome_vfs_uri_get_password ()

const gchar* gnome_vfs_uri_get_password     (const GnomeVFSURI *uri);

+Retrieve the password for uri.

+ +

uri : A GnomeVFSURI. +
Returns : The password for uri. +

gnome_vfs_uri_set_host_name ()

void        gnome_vfs_uri_set_host_name     (GnomeVFSURI *uri,
+                                             const gchar *host_name);

+Set host_name as the host name accessed by uri.

+ +

uri : A GnomeVFSURI. +
host_name : A string representing a host name. +

gnome_vfs_uri_set_host_port ()

void        gnome_vfs_uri_set_host_port     (GnomeVFSURI *uri,
+                                             guint host_port);

+Set the host port number in uri. If host_port is zero, the default port +for uri's toplevel access method is used.

+ +

uri : A GnomeVFSURI. +
host_port : A TCP/IP port number. +

gnome_vfs_uri_set_user_name ()

void        gnome_vfs_uri_set_user_name     (GnomeVFSURI *uri,
+                                             const gchar *user_name);

+Set user_name as the user name for uri.

+ +

uri : A GnomeVFSURI. +
user_name : A string representing a user name on the host accessed by uri. +

gnome_vfs_uri_set_password ()

void        gnome_vfs_uri_set_password      (GnomeVFSURI *uri,
+                                             const gchar *password);

+Set password as the password for uri.

+ +

uri : A GnomeVFSURI. +
password : A password string. +

gnome_vfs_uri_equal ()

gboolean    gnome_vfs_uri_equal             (const GnomeVFSURI *a,
+                                             const GnomeVFSURI *b);

+Compare a and b.

+ +

a : A GnomeVFSURI. +
b : A GnomeVFSURI. +
Returns : TRUE if a and b are equal, FALSE otherwise. + +FIXME: This comparison should take into account the possiblity +that unreserved characters may be escaped. +...or perhaps gnome_vfs_uri_new should unescape unreserved characters? +

gnome_vfs_uri_is_parent ()

gboolean    gnome_vfs_uri_is_parent         (const GnomeVFSURI *possible_parent,
+                                             const GnomeVFSURI *possible_child,
+                                             gboolean recursive);

+Check if possible_child is contained by possible_parent. +If recursive is FALSE, just try the immediate parent directory, else +search up through the hierarchy.

+ +

possible_parent : A GnomeVFSURI. +
possible_child : A GnomeVFSURI. +
recursive : a flag to turn recursive check on. +
Returns : TRUE if possible_child is contained in possible_child. +

gnome_vfs_uri_get_path ()

const gchar* gnome_vfs_uri_get_path         (const GnomeVFSURI *uri);

+Retrieve full path name for uri.

+ +

uri : A GnomeVFSURI +
Returns : A pointer to the full path name in uri. Notice that the +pointer points to the name store in uri, so the name returned must not +be modified nor freed. +

gnome_vfs_uri_get_fragment_identifier ()

const gchar* gnome_vfs_uri_get_fragment_identifier
+                                            (const GnomeVFSURI *uri);

+ +

uri : +
Returns : + + +

gnome_vfs_uri_extract_dirname ()

gchar*      gnome_vfs_uri_extract_dirname   (const GnomeVFSURI *uri);

+Extract the name of the directory in which the file pointed to by uri is +stored as a newly allocated string. The string will end with a +GNOME_VFS_URI_PATH_CHR.

+ +

uri : A GnomeVFSURI +
Returns : A pointer to the newly allocated string representing the +parent directory. +

gnome_vfs_uri_extract_short_name ()

gchar*      gnome_vfs_uri_extract_short_name
+                                            (const GnomeVFSURI *uri);

+Retrieve base file name for uri, ignoring any trailing path separators. +This matches the XPG definition of basename, but not g_basename. This is +often useful when you want the name of something that's pointed to by a +uri, and don't care whether the uri has a directory or file form. +If uri points to the root of a domain, returns the host name. If there's +no host name, returns GNOME_VFS_URI_PATH_STR. +

+See also: gnome_vfs_uri_extract_short_path_name.

+ +

uri : A GnomeVFSURI +
Returns : A pointer to the newly allocated string representing the +unescaped short form of the name. +

gnome_vfs_uri_extract_short_path_name ()

gchar*      gnome_vfs_uri_extract_short_path_name
+                                            (const GnomeVFSURI *uri);

+Retrieve base file name for uri, ignoring any trailing path separators. +This matches the XPG definition of basename, but not g_basename. This is +often useful when you want the name of something that's pointed to by a +uri, and don't care whether the uri has a directory or file form. +If uri points to the root (including the root of any domain), +returns GNOME_VFS_URI_PATH_STR. +

+See also: gnome_vfs_uri_extract_short_name.

+ +

uri : A GnomeVFSURI +
Returns : A pointer to the newly allocated string representing the +escaped short form of the name. +

gnome_vfs_uri_hequal ()

gint        gnome_vfs_uri_hequal            (gconstpointer a,
+                                             gconstpointer b);

+Function intended for use as a hash table "are these two items +the same" comparison. Useful for creating a hash table of URIs.

+ +

a : a pointer to a GnomeVFSURI +
b : a pointer to a GnomeVFSURI +
Returns : TRUE if the URIs are the same +

gnome_vfs_uri_hash ()

guint       gnome_vfs_uri_hash              (gconstpointer p);

+Creates an integer value from a GnomeVFSURI, appropriate +for using as the key to a hash table entry.

+ +

p : a pointer to a GnomeVFSURI +
Returns : a hash key corresponding to p +

gnome_vfs_uri_list_parse ()

GList*      gnome_vfs_uri_list_parse        (const gchar *uri_list);

+Extracts a list of GnomeVFSURI objects from a standard text/uri-list, +such as one you would get on a drop operation. Use +gnome_vfs_uri_list_free when you are done with the list.

+ +

uri_list : +
Returns : A GList of GnomeVFSURIs +

gnome_vfs_uri_list_ref ()

GList*      gnome_vfs_uri_list_ref          (GList *list);

+Increments the reference count of the items in list by one.

+ +

list : list of GnomeVFSURI elements +
Returns : list +

gnome_vfs_uri_list_unref ()

GList*      gnome_vfs_uri_list_unref        (GList *list);

+Decrements the reference count of the items in list by one. +Note that the list is *not freed* even if each member of the list +is freed.

+ +

list : list of GnomeVFSURI elements +
Returns : list +

gnome_vfs_uri_list_copy ()

GList*      gnome_vfs_uri_list_copy         (GList *list);

+Creates a duplicate of list, and references each member of +that list.

+ +

list : list of GnomeVFSURI elements +
Returns : a newly referenced duplicate of list +

gnome_vfs_uri_list_free ()

void        gnome_vfs_uri_list_free         (GList *list);

+Decrements the reference count of each member of list by one, +and frees the list itself.

+ +

list : list of GnomeVFSURI elements +

gnome_vfs_uri_make_full_from_relative ()

char*       gnome_vfs_uri_make_full_from_relative
+                                            (const char *base_uri,
+                                             const char *relative_uri);

+Returns a full URI given a full base URI, and a secondary URI which may +be relative.

+ +

base_uri : a string representing the base URI +
relative_uri : a URI fragment/reference to be appended to base_uri +
Returns : a newly allocated string containing the URI +(NULL for some bad errors). +
diff --git a/doc/html/gnome-vfs-20-gnome-vfs-utils.html b/doc/html/gnome-vfs-20-gnome-vfs-utils.html new file mode 100644 index 0000000..8424fe8 --- /dev/null +++ b/doc/html/gnome-vfs-20-gnome-vfs-utils.html @@ -0,0 +1,270 @@ +gnome-vfs-utils

gnome-vfs-utils

gnome-vfs-utils — various utilities functions to manipulate uris

Synopsis

+
+
+
+char*       gnome_vfs_format_file_size_for_display
+                                            (GnomeVFSFileSize size);
+char*       gnome_vfs_escape_string         (const char *string);
+char*       gnome_vfs_escape_path_string    (const char *path);
+char*       gnome_vfs_escape_host_and_path_string
+                                            (const char *path);
+char*       gnome_vfs_escape_slashes        (const char *string);
+char*       gnome_vfs_escape_set            (const char *string,
+                                             const char *match_set);
+char*       gnome_vfs_unescape_string       (const char *escaped_string,
+                                             const char *illegal_characters);
+char*       gnome_vfs_make_uri_canonical    (const char *uri);
+char*       gnome_vfs_make_path_name_canonical
+                                            (const char *path);
+char*       gnome_vfs_expand_initial_tilde  (const char *path);
+char*       gnome_vfs_unescape_string_for_display
+                                            (const char *escaped);
+char*       gnome_vfs_get_local_path_from_uri
+                                            (const char *uri);
+char*       gnome_vfs_get_uri_from_local_path
+                                            (const char *local_full_path);
+gboolean    gnome_vfs_is_executable_command_string
+                                            (const char *command_string);
+void        gnome_vfs_list_deep_free        (GList *list);
+GnomeVFSResult gnome_vfs_get_volume_free_space
+                                            (const GnomeVFSURI *vfs_uri,
+                                             GnomeVFSFileSize *size);
+char*       gnome_vfs_icon_path_from_filename
+                                            (const char *filename);
+gboolean    gnome_vfs_is_primary_thread     (void);
+char*       gnome_vfs_get_uri_scheme        (const char *uri);
+gboolean    gnome_vfs_uris_match            (const char *uri_1,
+                                             const char *uri_2);
+#define     GNOME_VFS_ASSERT_PRIMARY_THREAD
+#define     GNOME_VFS_ASSERT_SECONDARY_THREAD
+GnomeVFSResult gnome_vfs_read_entire_file   (const char *uri,
+                                             int *file_size,
+                                             char **file_contents);
+

Description

+ +

Details

gnome_vfs_format_file_size_for_display ()

char*       gnome_vfs_format_file_size_for_display
+                                            (GnomeVFSFileSize size);

+Formats the file size passed in bytes in a way that is easy for +the user to read. Gives the size in bytes, kilobytes, megabytes or +gigabytes, choosing whatever is appropriate.

+ +

size : +
Returns : a newly allocated string with the size ready to be shown. +

gnome_vfs_escape_string ()

char*       gnome_vfs_escape_string         (const char *string);

+Escapes string, replacing any and all special characters +with equivalent escape sequences.

+ +

string : string to be escaped +
Returns : a newly allocated string equivalent to string +but with all special characters escaped +

gnome_vfs_escape_path_string ()

char*       gnome_vfs_escape_path_string    (const char *path);

+Escapes path, replacing only special characters that would not +be found in paths (so '/', '&', '=', and '?' will not be escaped by +this function).

+ +

path : string to be escaped +
Returns : a newly allocated string equivalent to path but +with non-path characters escaped +

gnome_vfs_escape_host_and_path_string ()

char*       gnome_vfs_escape_host_and_path_string
+                                            (const char *path);

+Escapes path, replacing only special characters that would not +be found in paths or host name (so '/', '&', '=', ':', '@' +and '?' will not be escaped by this function).

+ +

path : string to be escaped +
Returns : a newly allocated string equivalent to path but +with non-path/host characters escaped +

gnome_vfs_escape_slashes ()

char*       gnome_vfs_escape_slashes        (const char *string);

+Escapes only '/' and '%' characters in string, replacing +them with their escape sequence equivalents.

+ +

string : string to be escaped +
Returns : a newly allocated string equivalent to string, +but with no unescaped '/' or '%' characters +

gnome_vfs_escape_set ()

char*       gnome_vfs_escape_set            (const char *string,
+                                             const char *match_set);

+ +

string : +
match_set : +
Returns : + + +

gnome_vfs_unescape_string ()

char*       gnome_vfs_unescape_string       (const char *escaped_string,
+                                             const char *illegal_characters);

+Decodes escaped characters (i.e. PERCENTxx sequences) in escaped_string. +Characters are encoded in PERCENTxy form, where xy is the ASCII hex code +for character 16x+y.

+ +

escaped_string : an escaped URI, path, or other string +
illegal_characters : a string containing a sequence of characters +considered "illegal", '\0' is automatically in this list. +
Returns : a newly allocated string with the unescaped equivalents, +or NULL if escaped_string contained one of the characters +in illegal_characters. +

gnome_vfs_make_uri_canonical ()

char*       gnome_vfs_make_uri_canonical    (const char *uri);

+Standarizes the format of the uri being passed, so that it can be used +later in other functions that expect a canonical URI.

+ +

uri : and absolute or relative URI, it might have scheme. +
Returns : a newly allocated string that contains the canonical +representation of uri. + +

Since 2.2 +


gnome_vfs_make_path_name_canonical ()

char*       gnome_vfs_make_path_name_canonical
+                                            (const char *path);

+Calls _gnome_vfs_canonicalize_pathname, allocating storage for the +result and providing for a cleaner memory management.

+ +

path : a file path, relative or absolute +
Returns : a canonical version of path +

gnome_vfs_expand_initial_tilde ()

char*       gnome_vfs_expand_initial_tilde  (const char *path);

+If path starts with a ~, representing the user's home +directory, expand it to the actual path location.

+ +

path : a local file path which may start with a '~' +
Returns : a newly allocated string with the initial +tilde (if there was one) converted to an actual path +

gnome_vfs_unescape_string_for_display ()

char*       gnome_vfs_unescape_string_for_display
+                                            (const char *escaped);

+ +

escaped : +
Returns : + + +

gnome_vfs_get_local_path_from_uri ()

char*       gnome_vfs_get_local_path_from_uri
+                                            (const char *uri);

+Create a local path for a file:/// URI. Do not use with URIs +of other methods.

+ +

uri : URI to convert to a local path +
Returns : a newly allocated string containing the local path +NULL is returned on error or if the uri isn't a file: URI +without a fragment identifier (or chained URI). +

gnome_vfs_get_uri_from_local_path ()

char*       gnome_vfs_get_uri_from_local_path
+                                            (const char *local_full_path);

+Returns a file:/// URI for the local path local_full_path.

+ +

local_full_path : a full local filesystem path (i.e. not relative) +
Returns : a newly allocated string containing the URI corresponding +to local_full_path (NULL for some bad errors). +

gnome_vfs_is_executable_command_string ()

gboolean    gnome_vfs_is_executable_command_string
+                                            (const char *command_string);

+Checks if command_string starts with the full path of an executable file +or an executable in $PATH.

+ +

command_string : +
Returns : TRUE if command_string started with and executable file, +FALSE otherwise. +

gnome_vfs_list_deep_free ()

void        gnome_vfs_list_deep_free        (GList *list);

+Free list, and call g_free() on all data members.

+ +

list : list to be freed +

gnome_vfs_get_volume_free_space ()

GnomeVFSResult gnome_vfs_get_volume_free_space
+                                            (const GnomeVFSURI *vfs_uri,
+                                             GnomeVFSFileSize *size);

+Stores in size the amount of free space on a volume. +This only works for local file systems with the file: scheme.

+ +

vfs_uri : +
size : +
Returns : GNOME_VFS_OK on success, otherwise an error code +

gnome_vfs_icon_path_from_filename ()

char*       gnome_vfs_icon_path_from_filename
+                                            (const char *filename);

+ +

filename : +
Returns : + + +

gnome_vfs_is_primary_thread ()

gboolean    gnome_vfs_is_primary_thread     (void);

+Check if the current thread is the thread with the main glib event loop.

+ +

Returns : TRUE if the current thread is the thread with the +main glib event loop +

gnome_vfs_get_uri_scheme ()

char*       gnome_vfs_get_uri_scheme        (const char *uri);

+Retrieve the scheme used in uri

+ +

uri : a stringified URI +
Returns : A newly allocated string containing the scheme, NULL +if uri it doesn't seem to contain a scheme + +

Since 2.2 +


gnome_vfs_uris_match ()

gboolean    gnome_vfs_uris_match            (const char *uri_1,
+                                             const char *uri_2);

+Compare two URIs.

+ +

uri_1 : stringified URI to compare with uri_2. +
uri_2 : stringified URI to compare with uri_1. +
Returns : TRUE if they are the same, FALSE otherwise. + +

Since 2.2 +


GNOME_VFS_ASSERT_PRIMARY_THREAD

#define GNOME_VFS_ASSERT_PRIMARY_THREAD g_assert (gnome_vfs_is_primary_thread())
+

+Asserts that the current thread is the thread with +the main glib event loop

+ +


GNOME_VFS_ASSERT_SECONDARY_THREAD

#define GNOME_VFS_ASSERT_SECONDARY_THREAD g_assert (!gnome_vfs_is_primary_thread())
+

+Asserts that the current thread is NOT the thread with +the main glib event loop

+ +


gnome_vfs_read_entire_file ()

GnomeVFSResult gnome_vfs_read_entire_file   (const char *uri,
+                                             int *file_size,
+                                             char **file_contents);

+Reads an entire file into memory for convenience. Beware accidentally +loading large files into memory with this function.

+ +

uri : URI of the file to read +
file_size : after reading the file, contains the size of the file read +
file_contents : contains the file_size bytes, the contents of the file at uri. +
Returns : An integer representing the result of the operation + +

Since 2.2 +

diff --git a/doc/html/gnome-vfs-20-gnome-vfs-xfer.html b/doc/html/gnome-vfs-20-gnome-vfs-xfer.html new file mode 100644 index 0000000..76fff44 --- /dev/null +++ b/doc/html/gnome-vfs-20-gnome-vfs-xfer.html @@ -0,0 +1,374 @@ +File Transfers

File Transfers

File Transfers — Conveniently copy/move/delete files en masse

Synopsis

+
+
+
+enum        GnomeVFSXferOptions;
+enum        GnomeVFSXferProgressStatus;
+enum        GnomeVFSXferOverwriteMode;
+enum        GnomeVFSXferOverwriteAction;
+enum        GnomeVFSXferErrorMode;
+enum        GnomeVFSXferErrorAction;
+enum        GnomeVFSXferPhase;
+typedef     GnomeVFSXferProgressInfo;
+gint        (*GnomeVFSXferProgressCallback) (GnomeVFSXferProgressInfo *info,
+                                             gpointer data);
+GnomeVFSResult gnome_vfs_xfer_uri_list      (const GList *source_uri_list,
+                                             const GList *target_uri_list,
+                                             GnomeVFSXferOptions xfer_options,
+                                             GnomeVFSXferErrorMode error_mode,
+                                             GnomeVFSXferOverwriteMode overwrite_mode,
+                                             GnomeVFSXferProgressCallback progress_callback,
+                                             gpointer data);
+GnomeVFSResult gnome_vfs_xfer_uri           (const GnomeVFSURI *source_uri,
+                                             const GnomeVFSURI *target_uri,
+                                             GnomeVFSXferOptions xfer_options,
+                                             GnomeVFSXferErrorMode error_mode,
+                                             GnomeVFSXferOverwriteMode overwrite_mode,
+                                             GnomeVFSXferProgressCallback progress_callback,
+                                             gpointer data);
+GnomeVFSResult gnome_vfs_xfer_delete_list   (const GList *source_uri_list,
+                                             GnomeVFSXferErrorMode error_mode,
+                                             GnomeVFSXferOptions xfer_options,
+                                             GnomeVFSXferProgressCallback progress_callback,
+                                             gpointer data);
+

Description

+ +

Details

enum GnomeVFSXferOptions

typedef enum {
+	GNOME_VFS_XFER_DEFAULT = 0,
+	GNOME_VFS_XFER_UNUSED_1 = 1 << 0,
+	GNOME_VFS_XFER_FOLLOW_LINKS = 1 << 1,
+	GNOME_VFS_XFER_UNUSED_2 = 1 << 2,
+	GNOME_VFS_XFER_RECURSIVE = 1 << 3,
+	GNOME_VFS_XFER_SAMEFS = 1 << 4,
+	GNOME_VFS_XFER_DELETE_ITEMS = 1 << 5,
+	GNOME_VFS_XFER_EMPTY_DIRECTORIES = 1 << 6,
+	GNOME_VFS_XFER_NEW_UNIQUE_DIRECTORY = 1 << 7,
+	GNOME_VFS_XFER_REMOVESOURCE = 1 << 8,
+	GNOME_VFS_XFER_USE_UNIQUE_NAMES = 1 << 9,
+	GNOME_VFS_XFER_LINK_ITEMS = 1 << 10,
+	GNOME_VFS_XFER_FOLLOW_LINKS_RECURSIVE = 1 << 11
+} GnomeVFSXferOptions;
+

+ +


enum GnomeVFSXferProgressStatus

typedef enum {
+	GNOME_VFS_XFER_PROGRESS_STATUS_OK = 0,
+	GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR = 1,
+	GNOME_VFS_XFER_PROGRESS_STATUS_OVERWRITE = 2,
+	/* during the duplicate status the progress callback is asked to
+	   supply a new unique name */
+	GNOME_VFS_XFER_PROGRESS_STATUS_DUPLICATE = 3
+} GnomeVFSXferProgressStatus;
+

+ +


enum GnomeVFSXferOverwriteMode

typedef enum {
+	/* Interrupt transferring with an error (GNOME_VFS_ERROR_FILEEXISTS).  */
+	GNOME_VFS_XFER_OVERWRITE_MODE_ABORT = 0,
+	/* Invoke the progress callback with a
+	   `GNOME_VFS_XFER_PROGRESS_STATUS_OVERWRITE' status code. */
+	GNOME_VFS_XFER_OVERWRITE_MODE_QUERY = 1,
+	/* Overwrite files silently.  */
+	GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE = 2,
+	/* Ignore files silently.  */
+	GNOME_VFS_XFER_OVERWRITE_MODE_SKIP = 3
+} GnomeVFSXferOverwriteMode;
+

+ +


enum GnomeVFSXferOverwriteAction

typedef enum {
+	GNOME_VFS_XFER_OVERWRITE_ACTION_ABORT = 0,
+	GNOME_VFS_XFER_OVERWRITE_ACTION_REPLACE = 1,
+	GNOME_VFS_XFER_OVERWRITE_ACTION_REPLACE_ALL = 2,
+	GNOME_VFS_XFER_OVERWRITE_ACTION_SKIP = 3,
+	GNOME_VFS_XFER_OVERWRITE_ACTION_SKIP_ALL = 4
+} GnomeVFSXferOverwriteAction;
+

+This defines the actions to perform before a file is being overwritten +(i.e., these are the answers that can be given to a replace query).

+ +

GNOME_VFS_XFER_OVERWRITE_ACTION_ABORT abort the transfer +
GNOME_VFS_XFER_OVERWRITE_ACTION_REPLACE replace the existing file +
GNOME_VFS_XFER_OVERWRITE_ACTION_REPLACE_ALL replace the existing file, and all future files +without prompting the callback. +
GNOME_VFS_XFER_OVERWRITE_ACTION_SKIP don't copy over the existing file +
GNOME_VFS_XFER_OVERWRITE_ACTION_SKIP_ALL don't copy over the existing file, and all future +files without prompting the callback. +

enum GnomeVFSXferErrorMode

typedef enum {
+	/* Interrupt transferring with an error (code returned is code of the
+           operation that has caused the error).  */
+	GNOME_VFS_XFER_ERROR_MODE_ABORT = 0,
+	/* Invoke the progress callback with a
+	   `GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR' status code. */
+	GNOME_VFS_XFER_ERROR_MODE_QUERY = 1
+} GnomeVFSXferErrorMode;
+

+ +


enum GnomeVFSXferErrorAction

typedef enum {
+	/* Interrupt operation and return `GNOME_VFS_ERROR_INTERRUPTED'.  */
+	GNOME_VFS_XFER_ERROR_ACTION_ABORT = 0,
+	/* Try the same operation again.  */
+	GNOME_VFS_XFER_ERROR_ACTION_RETRY = 1,
+	/* Skip this file and continue normally.  */
+	GNOME_VFS_XFER_ERROR_ACTION_SKIP = 2
+} GnomeVFSXferErrorAction;
+

+ +


enum GnomeVFSXferPhase

typedef enum {
+	/* Initial phase */
+	GNOME_VFS_XFER_PHASE_INITIAL,
+	/* Checking if destination can handle move/copy */
+	GNOME_VFS_XFER_CHECKING_DESTINATION,
+	/* Collecting file list */
+	GNOME_VFS_XFER_PHASE_COLLECTING,
+	/* File list collected (*) */
+	GNOME_VFS_XFER_PHASE_READYTOGO,
+	/* Opening source file for reading */
+	GNOME_VFS_XFER_PHASE_OPENSOURCE,
+	/* Creating target file for copy */
+	GNOME_VFS_XFER_PHASE_OPENTARGET,
+	/* Copying data from source to target (*) */
+	GNOME_VFS_XFER_PHASE_COPYING,
+	/* Moving file from source to target (*) */
+	GNOME_VFS_XFER_PHASE_MOVING,
+	/* Reading data from source file */
+	GNOME_VFS_XFER_PHASE_READSOURCE,
+	/* Writing data to target file */
+	GNOME_VFS_XFER_PHASE_WRITETARGET,
+	/* Closing source file */
+	GNOME_VFS_XFER_PHASE_CLOSESOURCE,
+	/* Closing target file */
+	GNOME_VFS_XFER_PHASE_CLOSETARGET,
+	/* Deleting source file */
+	GNOME_VFS_XFER_PHASE_DELETESOURCE,
+	/* Setting attributes on target file */
+	GNOME_VFS_XFER_PHASE_SETATTRIBUTES,
+	/* Go to the next file (*) */
+	GNOME_VFS_XFER_PHASE_FILECOMPLETED,
+	/* cleaning up after a move (removing source files, etc.) */
+	GNOME_VFS_XFER_PHASE_CLEANUP,
+	/* Operation finished (*) */
+	GNOME_VFS_XFER_PHASE_COMPLETED,
+	GNOME_VFS_XFER_NUM_PHASES
+} GnomeVFSXferPhase;
+

+ +


GnomeVFSXferProgressInfo

typedef struct {
+	/* Progress status (see above for a description).  */
+	GnomeVFSXferProgressStatus status;
+
+	/* VFS status code.  If `status' is
+           `GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR', you should look at this
+           member to know what has happened.  */
+	GnomeVFSResult vfs_status;
+
+	/* Current phase in the transferring process.  */
+	GnomeVFSXferPhase phase;
+
+	/* Source URI. FIXME bugzilla.eazel.com 1206: change name? */
+	gchar *source_name;
+
+	/* Destination URI. FIXME bugzilla.eazel.com 1206: change name? */
+	gchar *target_name;
+
+	/* Index of file being copied. */
+	gulong file_index;
+
+	/* Total number of files to be copied.  */
+	gulong files_total;
+
+	/* Total number of bytes to be copied.  */
+	GnomeVFSFileSize bytes_total;
+
+	/* Total size of this file (in bytes).  */
+	GnomeVFSFileSize file_size;
+
+	/* Bytes copied for this file so far.  */
+	GnomeVFSFileSize bytes_copied;
+
+	/* Total amount of data copied from the beginning.  */
+	GnomeVFSFileSize total_bytes_copied;
+	
+	/* Target unique name used when duplicating, etc. to avoid collisions */ 
+	gchar *duplicate_name;
+
+	/* Count used in the unique name e.g. (copy 2), etc. */
+	int duplicate_count;
+
+	gboolean top_level_item;
+	/* indicates that the copied/moved/deleted item is an actual item
+	 * passed in the uri list rather than one encountered by recursively
+	 * traversing directories. Used by metadata copying.
+	 */
+
+	/* Reserved for future expansions to GnomeVFSXferProgressInfo
+	 * without having to break ABI compatibility */
+	void *reserved1;
+	void *reserved2;
+
+} GnomeVFSXferProgressInfo;
+

+ +


GnomeVFSXferProgressCallback ()

gint        (*GnomeVFSXferProgressCallback) (GnomeVFSXferProgressInfo *info,
+                                             gpointer data);

+ +

info : +
data : +
Returns : + + +

gnome_vfs_xfer_uri_list ()

GnomeVFSResult gnome_vfs_xfer_uri_list      (const GList *source_uri_list,
+                                             const GList *target_uri_list,
+                                             GnomeVFSXferOptions xfer_options,
+                                             GnomeVFSXferErrorMode error_mode,
+                                             GnomeVFSXferOverwriteMode overwrite_mode,
+                                             GnomeVFSXferProgressCallback progress_callback,
+                                             gpointer data);

+This function will transfer multiple files to a multiple targets. Given a +a source uri(s) and a destination uri(s). There are a list of options that +your application can use to control how the transfer is done.

+ +

source_uri_list : A Glist of uris (ie file;//) +
target_uri_list : A GList of uris +
xfer_options : These are options you wish to set for the transfer. For +instance by setting the xfer behavior you can either make a copy or a +move. +
error_mode : Decide how to behave if the xfer is interrupted. For instance +you could set your application to return an error code in case of an +interuption. +
overwrite_mode : How to react if a file your copying is being overwritten. +
progress_callback : This is used to monitor the progress of a transfer. +Common use would be to check to see if the transfer is asking for permission +to overwrite a file. +
data : Data to be want passed back in callbacks from the xfer engine +
Returns : If all goes well it returns GNOME_VFS_OK. Check GnomeVFSResult for +other values. +

gnome_vfs_xfer_uri ()

GnomeVFSResult gnome_vfs_xfer_uri           (const GnomeVFSURI *source_uri,
+                                             const GnomeVFSURI *target_uri,
+                                             GnomeVFSXferOptions xfer_options,
+                                             GnomeVFSXferErrorMode error_mode,
+                                             GnomeVFSXferOverwriteMode overwrite_mode,
+                                             GnomeVFSXferProgressCallback progress_callback,
+                                             gpointer data);

+This function will allow a person to copy data from one location to another. +The location is specified using a URIs as the means to describe the location +of the data. Like any copy there are several options that can be set. +These can be set using the xfer_options. In addition there are callback +mechanisms and error codes to provide feedback in the copy +process.

+ +

source_uri : This is the location of where your data resides. +
target_uri : This is the location of where you want your data to go. +
xfer_options : Set the kind of transfers you want. These are: +GNOME_VFS_XFER_DEFAULT: Default behavior. Which is to do a straight one to +one copy. +GNOME_VFS_XFER_FOLLOW_LINKS: This means follow the value of the symbolic +link when copying. (ie treat a symbolic link as a directory) +GNOME_VFS_RECURSIVE: Do a recursive copy of the source to the destination. +Equivalent to the cp -r option in GNU cp. +GNOME_VFS_XFER_SAME_FS: This only allows copying onto the same filesystem. +GNOME_VFS_DELETE_ITEM: This is equivalent to a mv. Where you will copy the +contents of the source to the destination and then remove data from the +source URI. +GNOME_VFS_XFER_EMPTY_DIRECTORIES: <TBA> +GNOME_VFS_XFER_NEW_UNIQUE_DIRECTORY: This will create a directory if it +doesn't exist in the destination area. Useful with the +GNOME_VFS_XFER_RECURSIVE xfer option. +GNOME_VFS_XFER_REMOVESOURCE: This option will remove the source data after +whatever xfer option has been taken. +GNOME_VFS_USE_UNIQUE_NAMES: This is a check ot make sure that what you copy +onto the destination is not overwritten. It will only copy the unique items +from the source to the destjnation. +GNOME_VFS_XFER_LINK_ITEMS: <TBA> +
error_mode : When this function returns you need to check the error code +for the results of the copy. The results are generally: +GNOME_VFS_XFER_ERROR_MODE_ABORT: This means that the operation was aborted +by some sort of signal that interrupted the transfer. +GNOME_VFS_ERROR_MODE_QUERY: This means that no error has occured and that +you should query with the GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR. See +
overwrite_mode : This sets the options to deal with data that are duplicate +between the source and the destination. Your choices are: +GNOME_VFS_XFER_OVERWRITE_MODE_ABORT: This means abort the transfer if you +see duplicate data. +GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE: Replace the files silently. Don't +worry be happy. +GNOME_VFS_XFER_OVERWRITE_MODE_SKIP: Skip duplicate files silenty. +target. +
progress_callback : This is an important call back because this is how you +communicate with your copy process. +
data : Data to be want passed back in callbacks from the xfer engine +
Returns : An integer representing the result of the operation. + +

gnome_vfs_xfer_delete_list ()

GnomeVFSResult gnome_vfs_xfer_delete_list   (const GList *source_uri_list,
+                                             GnomeVFSXferErrorMode error_mode,
+                                             GnomeVFSXferOptions xfer_options,
+                                             GnomeVFSXferProgressCallback progress_callback,
+                                             gpointer data);

+Unlink items in the list source_uri_list from their filesystems.

+ +

source_uri_list : This is a list containing uris +
error_mode : Decide how you want to deal with interruptions +
xfer_options : Set whatever transfer options you need. +
progress_callback : Callback to check on progress of transfer. +
data : Data to be want passed back in callbacks from the xfer engine +
Returns : GNOME_VFS_OK if successful, or the appropriate error code otherwise +
diff --git a/doc/html/gnome-vfs-application-registry.html b/doc/html/gnome-vfs-application-registry.html new file mode 100644 index 0000000..4aedc04 --- /dev/null +++ b/doc/html/gnome-vfs-application-registry.html @@ -0,0 +1,2346 @@ +Application Registry
GnomeVFS - Filesystem Abstraction library
<<< Previous PageHomeUpNext Page >>>

Application Registry

Name

Application Registry -- a database of the available applications and their capabilities

Synopsis


+
+#define     GNOME_VFS_APPLICATION_REGISTRY_COMMAND
+#define     GNOME_VFS_APPLICATION_REGISTRY_NAME
+#define     GNOME_VFS_APPLICATION_REGISTRY_CAN_OPEN_MULTIPLE_FILES
+#define     GNOME_VFS_APPLICATION_REGISTRY_REQUIRES_TERMINAL
+gboolean    gnome_vfs_application_registry_exists
+                                            (const char *app_id);
+GList*      gnome_vfs_application_registry_get_keys
+                                            (const char *app_id);
+const char* gnome_vfs_application_registry_peek_value
+                                            (const char *app_id,
+                                             const char *key);
+gboolean    gnome_vfs_application_registry_get_bool_value
+                                            (const char *app_id,
+                                             const char *key,
+                                             gboolean *got_key);
+void        gnome_vfs_application_registry_remove_application
+                                            (const char *app_id);
+void        gnome_vfs_application_registry_set_value
+                                            (const char *app_id,
+                                             const char *key,
+                                             const char *value);
+void        gnome_vfs_application_registry_set_bool_value
+                                            (const char *app_id,
+                                             const char *key,
+                                             gboolean value);
+void        gnome_vfs_application_registry_unset_key
+                                            (const char *app_id,
+                                             const char *key);
+GList*      gnome_vfs_application_registry_get_applications
+                                            (const char *mime_type);
+GList*      gnome_vfs_application_registry_get_mime_types
+                                            (const char *app_id);
+gboolean    gnome_vfs_application_registry_supports_mime_type
+                                            (const char *app_id,
+                                             const char *mime_type);
+gboolean    gnome_vfs_application_registry_supports_uri_scheme
+                                            (const char *app_id,
+                                             const char *uri_scheme);
+gboolean    gnome_vfs_application_is_user_owned_application
+                                            (const GnomeVFSMimeApplication *application);
+void        gnome_vfs_application_registry_clear_mime_types
+                                            (const char *app_id);
+void        gnome_vfs_application_registry_add_mime_type
+                                            (const char *app_id,
+                                             const char *mime_type);
+void        gnome_vfs_application_registry_remove_mime_type
+                                            (const char *app_id,
+                                             const char *mime_type);
+GnomeVFSResult gnome_vfs_application_registry_sync
+                                            (void);
+void        gnome_vfs_application_registry_shutdown
+                                            (void);
+void        gnome_vfs_application_registry_reload
+                                            (void);
+GnomeVFSMimeApplication* gnome_vfs_application_registry_get_mime_application
+                                            (const char *app_id);
+void        gnome_vfs_application_registry_save_mime_application
+                                            (const GnomeVFSMimeApplication *application);

Description

Details

GNOME_VFS_APPLICATION_REGISTRY_COMMAND

#define GNOME_VFS_APPLICATION_REGISTRY_COMMAND "command"


GNOME_VFS_APPLICATION_REGISTRY_NAME

#define GNOME_VFS_APPLICATION_REGISTRY_NAME "name"


GNOME_VFS_APPLICATION_REGISTRY_CAN_OPEN_MULTIPLE_FILES

#define GNOME_VFS_APPLICATION_REGISTRY_CAN_OPEN_MULTIPLE_FILES "can_open_multiple_files"


GNOME_VFS_APPLICATION_REGISTRY_REQUIRES_TERMINAL

#define GNOME_VFS_APPLICATION_REGISTRY_REQUIRES_TERMINAL "requires_terminal"


gnome_vfs_application_registry_exists ()

gboolean    gnome_vfs_application_registry_exists
+                                            (const char *app_id);

This function will return TRUE if there is an entry for app_id in +the registry, otherwise FALSE.

app_id : an application ID
Returns : TRUE if the application is in the registry, FALSE if not


gnome_vfs_application_registry_get_keys ()

GList*      gnome_vfs_application_registry_get_keys
+                                            (const char *app_id);

This function wil return a list of strings which is the list of +keys set for app_id in the application registry.

app_id : the application ID for which to get keys
Returns : A list of the keys set for app_id


gnome_vfs_application_registry_peek_value ()

const char* gnome_vfs_application_registry_peek_value
+                                            (const char *app_id,
+                                             const char *key);

This will return the value associated with key for app_id in the +application registry. There is no need to free the return value.

app_id : the application ID for which to look up a value
key : the key to look up
Returns : the value associated with the key, or NULL if there is no +associated value


gnome_vfs_application_registry_get_bool_value ()

gboolean    gnome_vfs_application_registry_get_bool_value
+                                            (const char *app_id,
+                                             const char *key,
+                                             gboolean *got_key);

This will look up a key in the structure pointed to by app_id and return the +boolean value of that key. It will return false if there are no +applications associated with the app_id.

app_id : registry id of the application
key : key to look up
got_key : TRUE if a setting was dound, otherwise FALSE
Returns : TRUE if key is set to "true" or "yes" for app_id, otherwise FALSE


gnome_vfs_application_registry_remove_application ()

void        gnome_vfs_application_registry_remove_application
+                                            (const char *app_id);

Given the registry id this function will remove all applications that has +been set by the user. You will need to call +gnome_vfs_application_registry_sync to save the changes.

app_id : registry id of the application


gnome_vfs_application_registry_set_value ()

void        gnome_vfs_application_registry_set_value
+                                            (const char *app_id,
+                                             const char *key,
+                                             const char *value);

This function will set values pertaining to registry entry pointed to by +app_id. You will need to call gnome_vfs_application_registry_sync to +realize the changes.

app_id : registry id of the application
key : target key
value : value to set the target key to


gnome_vfs_application_registry_set_bool_value ()

void        gnome_vfs_application_registry_set_bool_value
+                                            (const char *app_id,
+                                             const char *key,
+                                             gboolean value);

app_id : 
key : 
value : 


gnome_vfs_application_registry_unset_key ()

void        gnome_vfs_application_registry_unset_key
+                                            (const char *app_id,
+                                             const char *key);

This function given the application and the target will wipe the current +value that the key contains.

app_id : registry id of the application
key : search key


gnome_vfs_application_registry_get_applications ()

GList*      gnome_vfs_application_registry_get_applications
+                                            (const char *mime_type);

This will return all applications from the registry that are associated with +the given mime type string.

mime_type : mime type string
Returns : a list of the application IDs for all applications which +support the given mime type.


gnome_vfs_application_registry_get_mime_types ()

GList*      gnome_vfs_application_registry_get_mime_types
+                                            (const char *app_id);

This function returns a list of strings that represent the mime +types that can be handled by an application.

app_id : registry id of application
Returns : a list of the mime types supported


gnome_vfs_application_registry_supports_mime_type ()

gboolean    gnome_vfs_application_registry_supports_mime_type
+                                            (const char *app_id,
+                                             const char *mime_type);

Use this function to see if there is an application associated with a given +mime type. The function will return true or false.

app_id : registry id of application
mime_type : mime type string
Returns : TRUE if app_id supports mime_type, otherwise FALSE.


gnome_vfs_application_registry_supports_uri_scheme ()

gboolean    gnome_vfs_application_registry_supports_uri_scheme
+                                            (const char *app_id,
+                                             const char *uri_scheme);

Given the id of the application this function will determine if the +uri scheme will given is supported.

app_id : registry id of application
uri_scheme : uri schme string
Returns : TRUE if app_id supports uri_scheme, otherwise FALSE


gnome_vfs_application_is_user_owned_application ()

gboolean    gnome_vfs_application_is_user_owned_application
+                                            (const GnomeVFSMimeApplication *application);

This function will determine if a mime application is user owned or not. By +user ownered this means that the application is not a system application +located in the prerequisite /usr area but rather in the user's area.

application : data structure of the mime application
Returns : gboolean


gnome_vfs_application_registry_clear_mime_types ()

void        gnome_vfs_application_registry_clear_mime_types
+                                            (const char *app_id);

This function will remove the mime types associated with the application. +Changes are not realized until the gnome_vfs_application_registry_sync +function is called to save the changes to the file.

app_id : Application id


gnome_vfs_application_registry_add_mime_type ()

void        gnome_vfs_application_registry_add_mime_type
+                                            (const char *app_id,
+                                             const char *mime_type);

This function will associate a mime type with an application given the +application registry id and the mime type. Changes are not realized until +the gnome_vfs_application_registry_sync function is called to save the +changes to the file.

app_id : registry id of application
mime_type : mime type string


gnome_vfs_application_registry_remove_mime_type ()

void        gnome_vfs_application_registry_remove_mime_type
+                                            (const char *app_id,
+                                             const char *mime_type);

This function will de-associate a mime type from an application registry. +Given the application registry id and the mime type. Changes are not +realized until the gnome_vfs_application_registry_sync function is called to +save the changes to the file.

app_id : registry id of the application
mime_type : mime type string


gnome_vfs_application_registry_sync ()

GnomeVFSResult gnome_vfs_application_registry_sync
+                                            (void);

This function will sync the registry. Typically you would use this function +after a modification of the registry. When you modify the registry a dirty +flag is set. Calling this function will save your modifications to disk and +reset the flag.

If successful, will return GNOME_VFS_OK

Returns : GnomeVFSResult


gnome_vfs_application_registry_shutdown ()

void        gnome_vfs_application_registry_shutdown
+                                            (void);

Synchronize gnome-vfs application registry data to disk, and free +resources.


gnome_vfs_application_registry_reload ()

void        gnome_vfs_application_registry_reload
+                                            (void);

If this function is called for the first time it will initialize the +registry. Subsequent calls to the function will clear out the current +registry contents and load registry contents from the save file. Make +certain that you've saved your registry before calling this function. It +will destroy unsaved changes.


gnome_vfs_application_registry_get_mime_application ()

GnomeVFSMimeApplication* gnome_vfs_application_registry_get_mime_application
+                                            (const char *app_id);

Returns a structure that contains the application that handles +the mime type associated by the application referred by app_id.

app_id : registry id of the application
Returns : GnomeVFSMimeApplication


gnome_vfs_application_registry_save_mime_application ()

void        gnome_vfs_application_registry_save_mime_application
+                                            (const GnomeVFSMimeApplication *application);

This will save to the registry the application that will be associated with +a defined mime type. The defined mime type is located within the +GnomeVFSMimeApplication structure. Changes are not realized until the +gnome_vfs_application_registry_sync function is called.

application : application associated with the mime type



<<< Previous PageHomeUpNext Page >>>
Algorithmic Sniff BufferMagic MIME Detection
\ No newline at end of file diff --git a/doc/html/gnome-vfs-asynchronous-operations.html b/doc/html/gnome-vfs-asynchronous-operations.html new file mode 100644 index 0000000..2f3cd87 --- /dev/null +++ b/doc/html/gnome-vfs-asynchronous-operations.html @@ -0,0 +1,4066 @@ +Asynchronous File I/O
GnomeVFS - Filesystem Abstraction library
<<< Previous PageHomeUpNext Page >>>

Asynchronous File I/O

Name

Asynchronous File I/O -- allows for non-blocking file operations

Synopsis


+
+void        gnome_vfs_async_cancel          (GnomeVFSAsyncHandle *handle);
+void        gnome_vfs_async_open            (GnomeVFSAsyncHandle **handle_return,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             int priority,
+                                             GnomeVFSAsyncOpenCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_open_uri        (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             int priority,
+                                             GnomeVFSAsyncOpenCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_open_as_channel (GnomeVFSAsyncHandle **handle_return,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             guint advised_block_size,
+                                             int priority,
+                                             GnomeVFSAsyncOpenAsChannelCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_open_uri_as_channel
+                                            (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             guint advised_block_size,
+                                             int priority,
+                                             GnomeVFSAsyncOpenAsChannelCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_create          (GnomeVFSAsyncHandle **handle_return,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm,
+                                             int priority,
+                                             GnomeVFSAsyncOpenCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_create_uri      (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm,
+                                             int priority,
+                                             GnomeVFSAsyncOpenCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_create_symbolic_link
+                                            (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             const gchar *uri_reference,
+                                             int priority,
+                                             GnomeVFSAsyncOpenCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_create_as_channel
+                                            (GnomeVFSAsyncHandle **handle_return,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm,
+                                             int priority,
+                                             GnomeVFSAsyncCreateAsChannelCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_create_uri_as_channel
+                                            (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm,
+                                             int priority,
+                                             GnomeVFSAsyncCreateAsChannelCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_close           (GnomeVFSAsyncHandle *handle,
+                                             GnomeVFSAsyncCloseCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_read            (GnomeVFSAsyncHandle *handle,
+                                             gpointer buffer,
+                                             guint bytes,
+                                             GnomeVFSAsyncReadCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_write           (GnomeVFSAsyncHandle *handle,
+                                             gconstpointer buffer,
+                                             guint bytes,
+                                             GnomeVFSAsyncWriteCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_get_file_info   (GnomeVFSAsyncHandle **handle_return,
+                                             GList *uri_list,
+                                             GnomeVFSFileInfoOptions options,
+                                             int priority,
+                                             GnomeVFSAsyncGetFileInfoCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_set_file_info   (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSFileInfo *info,
+                                             GnomeVFSSetFileInfoMask mask,
+                                             GnomeVFSFileInfoOptions options,
+                                             int priority,
+                                             GnomeVFSAsyncSetFileInfoCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_load_directory  (GnomeVFSAsyncHandle **handle_return,
+                                             const gchar *text_uri,
+                                             GnomeVFSFileInfoOptions options,
+                                             guint items_per_notification,
+                                             int priority,
+                                             GnomeVFSAsyncDirectoryLoadCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_load_directory_uri
+                                            (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSFileInfoOptions options,
+                                             guint items_per_notification,
+                                             int priority,
+                                             GnomeVFSAsyncDirectoryLoadCallback callback,
+                                             gpointer callback_data);
+GnomeVFSResult gnome_vfs_async_xfer         (GnomeVFSAsyncHandle **handle_return,
+                                             GList *source_uri_list,
+                                             GList *target_uri_list,
+                                             GnomeVFSXferOptions xfer_options,
+                                             GnomeVFSXferErrorMode error_mode,
+                                             GnomeVFSXferOverwriteMode overwrite_mode,
+                                             int priority,
+                                             GnomeVFSAsyncXferProgressCallback progress_update_callback,
+                                             gpointer update_callback_data,
+                                             GnomeVFSXferProgressCallback progress_sync_callback,
+                                             gpointer sync_callback_data);
+void        gnome_vfs_async_find_directory  (GnomeVFSAsyncHandle **handle_return,
+                                             GList *near_uri_list,
+                                             GnomeVFSFindDirectoryKind kind,
+                                             gboolean create_if_needed,
+                                             gboolean find_if_needed,
+                                             guint permissions,
+                                             int priority,
+                                             GnomeVFSAsyncFindDirectoryCallback callback,
+                                             gpointer user_data);

Description

The number of concurrent asynchronous jobs is limited. +When the limit is reached jobs are put into a queue. +The priority parameter determines which job is taken +from the queue first and when.

Priority values range from -10 to 10, lower priority values +mean higher priority.

How to decide the priority of a job?

Generally speaking jobs that can wait should be low priority, +jobs that are urgent should be high priority.

Another possible approach is that jobs that potentially +take long to finish should be low priority, jobs that finish +quickly should be high priority.

For example, if your application is doing something in the +background (e.g. looking for a directory) it can wait: choose +low priority like 10. +If you need update the user interface with the contents of +a directory it should happen quickly: use a -10 priority job.

How to choose the priority value?

The scheduling algorithm reserves threads for high priority +jobs so that running low priority jobs can't block high +priority ones. +The priority value of a job determines the maximum number of +running jobs so that the job can start. E.g. if a job has +a priority of -7 then it can start if there are less then +8 jobs running (using the default thread limit of 10).

Details

gnome_vfs_async_cancel ()

void        gnome_vfs_async_cancel          (GnomeVFSAsyncHandle *handle);

Cancels an operation

handle :the handle to cancel +


gnome_vfs_async_open ()

void        gnome_vfs_async_open            (GnomeVFSAsyncHandle **handle_return,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             int priority,
+                                             GnomeVFSAsyncOpenCallback callback,
+                                             gpointer callback_data);

Opens a text-based URI according to open_mode

handle_return :a reference to where the newly created handle pointer should be stored
text_uri :string representation of the URI
open_mode :open mode
priority :job priority
callback :a callback for when the URI is opened or an error occured
callback_data :data to be passed to the callback function +


gnome_vfs_async_open_uri ()

void        gnome_vfs_async_open_uri        (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             int priority,
+                                             GnomeVFSAsyncOpenCallback callback,
+                                             gpointer callback_data);

Opens a GnomeVFSURI according to open_mode. This function exposes a public GnomeVFSURI object, which may be deprecated eventually. Therefore, use of gnome_vfs_async_open is encouraged instead of this function to minimize breakage.

handle_return :a reference to where the newly created handle pointer should be stored
uri :GnomeVFSURI to open
open_mode :open mode
priority : job priority
callback :a callback for when the URI is opened or an error occured
callback_data :data to be passed to the callback function +


gnome_vfs_async_open_as_channel ()

void        gnome_vfs_async_open_as_channel (GnomeVFSAsyncHandle **handle_return,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             guint advised_block_size,
+                                             int priority,
+                                             GnomeVFSAsyncOpenAsChannelCallback callback,
+                                             gpointer callback_data);

handle_return :a reference to where the newly created handle pointer should be stored
text_uri : 
open_mode : 
advised_block_size : 
priority : job priority
callback : 
callback_data :data to be passed to the callback function +


gnome_vfs_async_open_uri_as_channel ()

void        gnome_vfs_async_open_uri_as_channel
+                                            (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             guint advised_block_size,
+                                             int priority,
+                                             GnomeVFSAsyncOpenAsChannelCallback callback,
+                                             gpointer callback_data);

handle_return :a reference to where the newly created handle pointer should be stored
uri : 
open_mode : 
advised_block_size : 
priority : job priority
callback : 
callback_data :data to be passed to the callback function +


gnome_vfs_async_create ()

void        gnome_vfs_async_create          (GnomeVFSAsyncHandle **handle_return,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm,
+                                             int priority,
+                                             GnomeVFSAsyncOpenCallback callback,
+                                             gpointer callback_data);

handle_return :a reference to where the newly created handle pointer should be stored
text_uri : 
open_mode : 
exclusive : 
perm : 
priority : job priority
callback : 
callback_data :data to be passed to the callback function +


gnome_vfs_async_create_uri ()

void        gnome_vfs_async_create_uri      (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm,
+                                             int priority,
+                                             GnomeVFSAsyncOpenCallback callback,
+                                             gpointer callback_data);

handle_return :a reference to where the newly created handle pointer should be stored
uri : 
open_mode : 
exclusive : 
perm : 
priority : job priority
callback : 
callback_data :data to be passed to the callback function +


gnome_vfs_async_create_symbolic_link ()

void        gnome_vfs_async_create_symbolic_link
+                                            (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             const gchar *uri_reference,
+                                             int priority,
+                                             GnomeVFSAsyncOpenCallback callback,
+                                             gpointer callback_data);

handle_return :a reference to where the newly created handle pointer should be stored
uri : 
uri_reference : 
priority : job priority
callback : 
callback_data :data to be passed to the callback function +


gnome_vfs_async_create_as_channel ()

void        gnome_vfs_async_create_as_channel
+                                            (GnomeVFSAsyncHandle **handle_return,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm,
+                                             int priority,
+                                             GnomeVFSAsyncCreateAsChannelCallback callback,
+                                             gpointer callback_data);

handle_return :a reference to where the newly created handle pointer should be stored
text_uri : 
open_mode : 
exclusive : 
perm : 
priority : job priority
callback : 
callback_data :data to be passed to the callback function +


gnome_vfs_async_create_uri_as_channel ()

void        gnome_vfs_async_create_uri_as_channel
+                                            (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm,
+                                             int priority,
+                                             GnomeVFSAsyncCreateAsChannelCallback callback,
+                                             gpointer callback_data);

handle_return :a reference to where the newly created handle pointer should be stored
uri : 
open_mode : 
exclusive : 
perm : 
priority : job priority
callback : 
callback_data :data to be passed to the callback function +


gnome_vfs_async_close ()

void        gnome_vfs_async_close           (GnomeVFSAsyncHandle *handle,
+                                             GnomeVFSAsyncCloseCallback callback,
+                                             gpointer callback_data);

handle :GnomeVFSHandle to close
callback :a callback for when the handle is closed or an error has occured
callback_data :data to be passed to the callback function +


gnome_vfs_async_read ()

void        gnome_vfs_async_read            (GnomeVFSAsyncHandle *handle,
+                                             gpointer buffer,
+                                             guint bytes,
+                                             GnomeVFSAsyncReadCallback callback,
+                                             gpointer callback_data);

handle : 
buffer : 
bytes : 
callback : 
callback_data :data to be passed to the callback function +


gnome_vfs_async_write ()

void        gnome_vfs_async_write           (GnomeVFSAsyncHandle *handle,
+                                             gconstpointer buffer,
+                                             guint bytes,
+                                             GnomeVFSAsyncWriteCallback callback,
+                                             gpointer callback_data);

handle : 
buffer : 
bytes : 
callback : 
callback_data :data to be passed to the callback function +


gnome_vfs_async_get_file_info ()

void        gnome_vfs_async_get_file_info   (GnomeVFSAsyncHandle **handle_return,
+                                             GList *uri_list,
+                                             GnomeVFSFileInfoOptions options,
+                                             int priority,
+                                             GnomeVFSAsyncGetFileInfoCallback callback,
+                                             gpointer callback_data);

handle_return :a reference to where the newly created handle pointer should be stored
uri_list : 
options : 
priority : job priority
callback : 
callback_data :data to be passed to the callback function +


gnome_vfs_async_set_file_info ()

void        gnome_vfs_async_set_file_info   (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSFileInfo *info,
+                                             GnomeVFSSetFileInfoMask mask,
+                                             GnomeVFSFileInfoOptions options,
+                                             int priority,
+                                             GnomeVFSAsyncSetFileInfoCallback callback,
+                                             gpointer callback_data);

handle_return :a reference to where the newly created handle pointer should be stored
uri : 
info : 
mask : 
options : 
priority : job priority
callback : 
callback_data :data to be passed to the callback function +


gnome_vfs_async_load_directory ()

void        gnome_vfs_async_load_directory  (GnomeVFSAsyncHandle **handle_return,
+                                             const gchar *text_uri,
+                                             GnomeVFSFileInfoOptions options,
+                                             guint items_per_notification,
+                                             int priority,
+                                             GnomeVFSAsyncDirectoryLoadCallback callback,
+                                             gpointer callback_data);

handle_return :a reference to where the newly created handle pointer should be stored
text_uri : 
options : 
items_per_notification : 
priority : job priority
callback : 
callback_data :data to be passed to the callback function


gnome_vfs_async_load_directory_uri ()

void        gnome_vfs_async_load_directory_uri
+                                            (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSFileInfoOptions options,
+                                             guint items_per_notification,
+                                             int priority,
+                                             GnomeVFSAsyncDirectoryLoadCallback callback,
+                                             gpointer callback_data);

handle_return :a reference to where the newly created handle pointer should be stored
uri : 
options : 
items_per_notification : 
priority : job priority
callback : 
callback_data :data to be passed to the callback function


gnome_vfs_async_xfer ()

GnomeVFSResult gnome_vfs_async_xfer         (GnomeVFSAsyncHandle **handle_return,
+                                             GList *source_uri_list,
+                                             GList *target_uri_list,
+                                             GnomeVFSXferOptions xfer_options,
+                                             GnomeVFSXferErrorMode error_mode,
+                                             GnomeVFSXferOverwriteMode overwrite_mode,
+                                             int priority,
+                                             GnomeVFSAsyncXferProgressCallback progress_update_callback,
+                                             gpointer update_callback_data,
+                                             GnomeVFSXferProgressCallback progress_sync_callback,
+                                             gpointer sync_callback_data);

Transfers file(s) from one location to another

handle_return :a reference to where the newly created handle pointer should be stored
source_uri_list :a GList. Each element should be a pointer to a GnomeVFSURI object
target_uri_list :a GList. Each element should be a pointer to a GnomeVFSURI object
xfer_options : 
error_mode : 
overwrite_mode : 
priority : job priority
progress_update_callback : 
update_callback_data :data to be passed to the progress update callback function
progress_sync_callback : 
sync_callback_data :data to be passed to the progress sync callback function
Returns : 


gnome_vfs_async_find_directory ()

void        gnome_vfs_async_find_directory  (GnomeVFSAsyncHandle **handle_return,
+                                             GList *near_uri_list,
+                                             GnomeVFSFindDirectoryKind kind,
+                                             gboolean create_if_needed,
+                                             gboolean find_if_needed,
+                                             guint permissions,
+                                             int priority,
+                                             GnomeVFSAsyncFindDirectoryCallback callback,
+                                             gpointer user_data);

handle_return :a reference to where the newly created handle pointer should be stored
near_uri_list : 
kind : 
create_if_needed : 
find_if_needed : 
permissions : 
priority : job priority
callback : 
user_data :data to be passed to the callback function +



<<< Previous PageHomeUpNext Page >>>
Finding Special DirectoriesCopy Engine
\ No newline at end of file diff --git a/doc/html/gnome-vfs-cancellation.html b/doc/html/gnome-vfs-cancellation.html new file mode 100644 index 0000000..d8306ae --- /dev/null +++ b/doc/html/gnome-vfs-cancellation.html @@ -0,0 +1,772 @@ +Cancellation
GnomeVFS - Filesystem Abstraction library
<<< Previous PageHomeUpNext Page >>>

Cancellation

Name

Cancellation -- 

Synopsis


+
+GnomeVFSCancellation* gnome_vfs_cancellation_new
+                                            (void);
+void        gnome_vfs_cancellation_destroy  (GnomeVFSCancellation *cancellation);
+void        gnome_vfs_cancellation_cancel   (GnomeVFSCancellation *cancellation);
+gboolean    gnome_vfs_cancellation_check    (GnomeVFSCancellation *cancellation);
+void        gnome_vfs_cancellation_ack      (GnomeVFSCancellation *cancellation);
+gint        gnome_vfs_cancellation_get_fd   (GnomeVFSCancellation *cancellation);

Description

Details

gnome_vfs_cancellation_new ()

GnomeVFSCancellation* gnome_vfs_cancellation_new
+                                            (void);

Create a new GnomeVFSCancellation object for reporting cancellation to a +GNOME VFS module.

Returns : A pointer to the new GnomeVFSCancellation object.


gnome_vfs_cancellation_destroy ()

void        gnome_vfs_cancellation_destroy  (GnomeVFSCancellation *cancellation);

Destroy cancellation.

cancellation : A GnomeVFSCancellation object


gnome_vfs_cancellation_cancel ()

void        gnome_vfs_cancellation_cancel   (GnomeVFSCancellation *cancellation);

Send a cancellation request through cancellation.

cancellation : A GnomeVFSCancellation object


gnome_vfs_cancellation_check ()

gboolean    gnome_vfs_cancellation_check    (GnomeVFSCancellation *cancellation);

Check for pending cancellation.

cancellation : A GnomeVFSCancellation object
Returns : TRUE if the operation should be interrupted.


gnome_vfs_cancellation_ack ()

void        gnome_vfs_cancellation_ack      (GnomeVFSCancellation *cancellation);

Acknowledge a cancellation. This should be called if +`gnome_vfs_cancellation_check()' returns TRUE or if `select()' reports that +input is available on the file descriptor returned by +`gnome_vfs_cancellation_get_fd()'.

cancellation : A GnomeVFSCancellation object


gnome_vfs_cancellation_get_fd ()

gint        gnome_vfs_cancellation_get_fd   (GnomeVFSCancellation *cancellation);

Get a file descriptor -based notificator for cancellation. When +cancellation receives a cancellation request, a character will be made +available on the returned file descriptor for input.

This is very useful for detecting cancellation during I/O operations: you +can use the `select()' call to check for available input/output on the file +you are reading/writing, and on the notificator's file descriptor at the +same time. If a data is available on the notificator's file descriptor, you +know you have to cancel the read/write operation.

cancellation : A GnomeVFSCancellation object
Returns : the notificator's file descriptor.

\ No newline at end of file diff --git a/doc/html/gnome-vfs-configuration.html b/doc/html/gnome-vfs-configuration.html new file mode 100644 index 0000000..9814aee --- /dev/null +++ b/doc/html/gnome-vfs-configuration.html @@ -0,0 +1,555 @@ +Configuration
GnomeVFS - Filesystem Abstraction library
<<< Previous PageHomeUpNext Page >>>

Configuration

Name

Configuration -- 

Synopsis


+
+void        gnome_vfs_configuration_add_directory
+                                            (const char *dir);
+gboolean    gnome_vfs_configuration_init    (void);
+void        gnome_vfs_configuration_uninit  (void);
+const gchar* gnome_vfs_configuration_get_module_path
+                                            (const gchar *method_name,
+                                             const char **args);

Description

Details

gnome_vfs_configuration_add_directory ()

void        gnome_vfs_configuration_add_directory
+                                            (const char *dir);

dir : 


gnome_vfs_configuration_init ()

gboolean    gnome_vfs_configuration_init    (void);

Returns : 


gnome_vfs_configuration_uninit ()

void        gnome_vfs_configuration_uninit  (void);


gnome_vfs_configuration_get_module_path ()

const gchar* gnome_vfs_configuration_get_module_path
+                                            (const gchar *method_name,
+                                             const char **args);

method_name : 
args : 
Returns : 

\ No newline at end of file diff --git a/doc/html/gnome-vfs-context.html b/doc/html/gnome-vfs-context.html new file mode 100644 index 0000000..6145961 --- /dev/null +++ b/doc/html/gnome-vfs-context.html @@ -0,0 +1,764 @@ +Context
GnomeVFS - Filesystem Abstraction library
<<< Previous PageHomeUpNext Page >>>

Context

Name

Context -- 

Synopsis


+
+GnomeVFSContext* gnome_vfs_context_new      (void);
+void        gnome_vfs_context_ref           (GnomeVFSContext *ctx);
+void        gnome_vfs_context_unref         (GnomeVFSContext *ctx);
+GnomeVFSCancellation* gnome_vfs_context_get_cancellation
+                                            (const GnomeVFSContext *ctx);
+#define     gnome_vfs_context_check_cancellation(x)
+const GnomeVFSContext* gnome_vfs_context_peek_current
+                                            (void);
+gboolean    gnome_vfs_context_check_cancellation_current
+                                            (void);

Description

Details

gnome_vfs_context_new ()

GnomeVFSContext* gnome_vfs_context_new      (void);

Returns : 


gnome_vfs_context_ref ()

void        gnome_vfs_context_ref           (GnomeVFSContext *ctx);

ctx : 


gnome_vfs_context_unref ()

void        gnome_vfs_context_unref         (GnomeVFSContext *ctx);

ctx : 


gnome_vfs_context_get_cancellation ()

GnomeVFSCancellation* gnome_vfs_context_get_cancellation
+                                            (const GnomeVFSContext *ctx);

ctx : 
Returns : 


gnome_vfs_context_check_cancellation()

#define     gnome_vfs_context_check_cancellation(x)

x : 


gnome_vfs_context_peek_current ()

const GnomeVFSContext* gnome_vfs_context_peek_current
+                                            (void);

Returns : 


gnome_vfs_context_check_cancellation_current ()

gboolean    gnome_vfs_context_check_cancellation_current
+                                            (void);

Returns : 

\ No newline at end of file diff --git a/doc/html/gnome-vfs-directory-operations.html b/doc/html/gnome-vfs-directory-operations.html new file mode 100644 index 0000000..ddf4593 --- /dev/null +++ b/doc/html/gnome-vfs-directory-operations.html @@ -0,0 +1,36 @@ +Directory Handling

Directory Handling

Table of Contents

Basic Directory Operations - +Creating and removing directories.
Listing Directory Contents - +Listing the contents of directories.
Locating Standard Directories - +Utilities for locating standard directories such as the desktop and trash

+ Functions for creating, removing, and listing directories. +

diff --git a/doc/html/gnome-vfs-directory.html b/doc/html/gnome-vfs-directory.html new file mode 100644 index 0000000..fec6e36 --- /dev/null +++ b/doc/html/gnome-vfs-directory.html @@ -0,0 +1,1780 @@ +Directory Operations
GnomeVFS - Filesystem Abstraction library
<<< Previous PageHomeUpNext Page >>>

Directory Operations

Name

Directory Operations -- loading and parsing directory contents

Synopsis


+
+GnomeVFSResult gnome_vfs_directory_open     (GnomeVFSDirectoryHandle **handle,
+                                             const gchar *text_uri,
+                                             GnomeVFSFileInfoOptions options);
+GnomeVFSResult gnome_vfs_directory_open_from_uri
+                                            (GnomeVFSDirectoryHandle **handle,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSFileInfoOptions options);
+GnomeVFSResult gnome_vfs_directory_read_next
+                                            (GnomeVFSDirectoryHandle *handle,
+                                             GnomeVFSFileInfo *file_info);
+GnomeVFSResult gnome_vfs_directory_close    (GnomeVFSDirectoryHandle *handle);
+GnomeVFSResult gnome_vfs_directory_visit    (const gchar *uri,
+                                             GnomeVFSFileInfoOptions info_options,
+                                             GnomeVFSDirectoryVisitOptions visit_options,
+                                             GnomeVFSDirectoryVisitFunc callback,
+                                             gpointer data);
+GnomeVFSResult gnome_vfs_directory_visit_uri
+                                            (GnomeVFSURI *uri,
+                                             GnomeVFSFileInfoOptions info_options,
+                                             GnomeVFSDirectoryVisitOptions visit_options,
+                                             GnomeVFSDirectoryVisitFunc callback,
+                                             gpointer data);
+GnomeVFSResult gnome_vfs_directory_visit_files
+                                            (const gchar *text_uri,
+                                             GList *file_list,
+                                             GnomeVFSFileInfoOptions info_options,
+                                             GnomeVFSDirectoryVisitOptionsvisit_options,
+                                             GnomeVFSDirectoryVisitFunc callback,
+                                             gpointer data);
+GnomeVFSResult gnome_vfs_directory_visit_files_at_uri
+                                            (GnomeVFSURI *uri,
+                                             GList *file_list,
+                                             GnomeVFSFileInfoOptions info_options,
+                                             GnomeVFSDirectoryVisitOptions visit_options,
+                                             GnomeVFSDirectoryVisitFunc callback,
+                                             gpointer data);
+GnomeVFSResult gnome_vfs_directory_list_load
+                                            (GList **list,
+                                             const gchar *text_uri,
+                                             GnomeVFSFileInfoOptions options);

Description

Details

gnome_vfs_directory_open ()

GnomeVFSResult gnome_vfs_directory_open     (GnomeVFSDirectoryHandle **handle,
+                                             const gchar *text_uri,
+                                             GnomeVFSFileInfoOptions options);

Open directory text_uri for reading. On return, @*handle will point to +a GnomeVFSDirectoryHandle object which can be used to read the directory +entries one by one.

handle : A pointer to a pointer to a GnomeVFSDirectoryHandle object
text_uri : String representing the URI to open
options : Options for reading file information
Returns : An integer representing the result of the operation


gnome_vfs_directory_open_from_uri ()

GnomeVFSResult gnome_vfs_directory_open_from_uri
+                                            (GnomeVFSDirectoryHandle **handle,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSFileInfoOptions options);

Open directory text_uri for reading. On return, @*handle will point to +a GnomeVFSDirectoryHandle object which can be used to read the directory +entries one by one.

handle : A pointer to a pointer to a GnomeVFSDirectoryHandle object
uri : URI to open
options : Options for reading file information
Returns : An integer representing the result of the operation.


gnome_vfs_directory_read_next ()

GnomeVFSResult gnome_vfs_directory_read_next
+                                            (GnomeVFSDirectoryHandle *handle,
+                                             GnomeVFSFileInfo *file_info);

Read the next directory entry from handle.

handle : A directory handle
file_info : Pointer to a GnomeVFSFileInfo struct where the data about +the entry will be stored
Returns : An integer value representing the result of the operation.


gnome_vfs_directory_close ()

GnomeVFSResult gnome_vfs_directory_close    (GnomeVFSDirectoryHandle *handle);

Close handle.

handle : A directory handle.
Returns : An integer representing the result of the operation.


gnome_vfs_directory_visit ()

GnomeVFSResult gnome_vfs_directory_visit    (const gchar *uri,
+                                             GnomeVFSFileInfoOptions info_options,
+                                             GnomeVFSDirectoryVisitOptions visit_options,
+                                             GnomeVFSDirectoryVisitFunc callback,
+                                             gpointer data);

Visit uri, retrieving information as specified by info_options.

uri : URI to start from
info_options : Options specifying what kind of file information must be +retrieved
visit_options : Options specifying the type of visit
callback : Callback to be called for every visited file
data : Data to be passed to callback at each iteration
Returns : 


gnome_vfs_directory_visit_uri ()

GnomeVFSResult gnome_vfs_directory_visit_uri
+                                            (GnomeVFSURI *uri,
+                                             GnomeVFSFileInfoOptions info_options,
+                                             GnomeVFSDirectoryVisitOptions visit_options,
+                                             GnomeVFSDirectoryVisitFunc callback,
+                                             gpointer data);

Visit uri, retrieving information as specified by info_options.

uri : URI to start from
info_options : Options specifying what kind of file information must be +retrieved
visit_options : Options specifying the type of visit
callback : Callback to be called for every visited file
data : Data to be passed to callback at each iteration
Returns : A result code indicating whether the operation succeeded.


gnome_vfs_directory_visit_files ()

GnomeVFSResult gnome_vfs_directory_visit_files
+                                            (const gchar *text_uri,
+                                             GList *file_list,
+                                             GnomeVFSFileInfoOptions info_options,
+                                             GnomeVFSDirectoryVisitOptionsvisit_options,
+                                             GnomeVFSDirectoryVisitFunc callback,
+                                             gpointer data);

text_uri : 
file_list : 
info_options : 
Param4 : 
callback : 
data : 
Returns : 


gnome_vfs_directory_visit_files_at_uri ()

GnomeVFSResult gnome_vfs_directory_visit_files_at_uri
+                                            (GnomeVFSURI *uri,
+                                             GList *file_list,
+                                             GnomeVFSFileInfoOptions info_options,
+                                             GnomeVFSDirectoryVisitOptions visit_options,
+                                             GnomeVFSDirectoryVisitFunc callback,
+                                             gpointer data);

uri : 
file_list : 
info_options : 
visit_options : 
callback : 
data : 
Returns : 


gnome_vfs_directory_list_load ()

GnomeVFSResult gnome_vfs_directory_list_load
+                                            (GList **list,
+                                             const gchar *text_uri,
+                                             GnomeVFSFileInfoOptions options);

Load a directory from text_uri with the specified options +into a list.

list : An address of a pointer to a list of GnomeVFSFileInfo
text_uri : A text URI
options : Options for loading the directory
Returns : An integer representing the result of the operation.



<<< Previous PageHomeUpNext Page >>>
Basic File I/OFinding Special Directories
\ No newline at end of file diff --git a/doc/html/gnome-vfs-file-info.html b/doc/html/gnome-vfs-file-info.html new file mode 100644 index 0000000..ab8c51f --- /dev/null +++ b/doc/html/gnome-vfs-file-info.html @@ -0,0 +1,2129 @@ +File Info
GnomeVFS - Filesystem Abstraction library
<<< Previous PageHomeUpNext Page >>>

File Info

Name

File Info -- 

Synopsis


+
+#define     GNOME_VFS_FILE_INFO_SYMLINK     (info)
+#define     GNOME_VFS_FILE_INFO_SET_SYMLINK (info, value)
+#define     GNOME_VFS_FILE_INFO_LOCAL       (info)
+#define     GNOME_VFS_FILE_INFO_SET_LOCAL   (info, value)
+#define     GNOME_VFS_FILE_INFO_SUID        (info)
+#define     GNOME_VFS_FILE_INFO_SGID        (info)
+#define     GNOME_VFS_FILE_INFO_STICKY      (info)
+#define     GNOME_VFS_FILE_INFO_SET_SUID    (info, value)
+#define     GNOME_VFS_FILE_INFO_SET_SGID    (info, value)
+#define     GNOME_VFS_FILE_INFO_SET_STICKY  (info, value)
+GnomeVFSFileInfo* gnome_vfs_file_info_new   (void);
+void        gnome_vfs_file_info_unref       (GnomeVFSFileInfo *info);
+void        gnome_vfs_file_info_ref         (GnomeVFSFileInfo *info);
+void        gnome_vfs_file_info_clear       (GnomeVFSFileInfo *info);
+const gchar* gnome_vfs_file_info_get_mime_type
+                                            (GnomeVFSFileInfo *info);
+void        gnome_vfs_file_info_copy        (GnomeVFSFileInfo *dest,
+                                             const GnomeVFSFileInfo *src);
+GnomeVFSFileInfo* gnome_vfs_file_info_dup   (const GnomeVFSFileInfo *orig);
+gboolean    gnome_vfs_file_info_matches     (const GnomeVFSFileInfo *a,
+                                             const GnomeVFSFileInfo *b);
+GList*      gnome_vfs_file_info_list_ref    (GList *list);
+GList*      gnome_vfs_file_info_list_unref  (GList *list);
+GList*      gnome_vfs_file_info_list_copy   (GList *list);
+void        gnome_vfs_file_info_list_free   (GList *list);

Description

Details

GNOME_VFS_FILE_INFO_SYMLINK()

#define     GNOME_VFS_FILE_INFO_SYMLINK(info)

info : 


GNOME_VFS_FILE_INFO_SET_SYMLINK()

#define     GNOME_VFS_FILE_INFO_SET_SYMLINK(info, value)

info : 
value : 


GNOME_VFS_FILE_INFO_LOCAL()

#define     GNOME_VFS_FILE_INFO_LOCAL(info)

info : 


GNOME_VFS_FILE_INFO_SET_LOCAL()

#define     GNOME_VFS_FILE_INFO_SET_LOCAL(info, value)

info : 
value : 


GNOME_VFS_FILE_INFO_SUID()

#define     GNOME_VFS_FILE_INFO_SUID(info)

info : 


GNOME_VFS_FILE_INFO_SGID()

#define     GNOME_VFS_FILE_INFO_SGID(info)

info : 


GNOME_VFS_FILE_INFO_STICKY()

#define     GNOME_VFS_FILE_INFO_STICKY(info)

info : 


GNOME_VFS_FILE_INFO_SET_SUID()

#define     GNOME_VFS_FILE_INFO_SET_SUID(info, value)

info : 
value : 


GNOME_VFS_FILE_INFO_SET_SGID()

#define     GNOME_VFS_FILE_INFO_SET_SGID(info, value)

info : 
value : 


GNOME_VFS_FILE_INFO_SET_STICKY()

#define     GNOME_VFS_FILE_INFO_SET_STICKY(info, value)

info : 
value : 


gnome_vfs_file_info_new ()

GnomeVFSFileInfo* gnome_vfs_file_info_new   (void);

Allocate and initialize a new file information struct.

Returns : A pointer to the new file information struct.


gnome_vfs_file_info_unref ()

void        gnome_vfs_file_info_unref       (GnomeVFSFileInfo *info);

Destroy info

info : Pointer to a file information struct


gnome_vfs_file_info_ref ()

void        gnome_vfs_file_info_ref         (GnomeVFSFileInfo *info);

Increment reference count

info : Pointer to a file information struct


gnome_vfs_file_info_clear ()

void        gnome_vfs_file_info_clear       (GnomeVFSFileInfo *info);

Clear info so that it's ready to accept new data. This is +supposed to be used when info already contains meaningful information which +we want to replace.

info : Pointer to a file information struct


gnome_vfs_file_info_get_mime_type ()

const gchar* gnome_vfs_file_info_get_mime_type
+                                            (GnomeVFSFileInfo *info);

Retrieve MIME type from info. There is no need to free the return +value.

info : A pointer to a file information struct
Returns : A pointer to a string representing the MIME type.


gnome_vfs_file_info_copy ()

void        gnome_vfs_file_info_copy        (GnomeVFSFileInfo *dest,
+                                             const GnomeVFSFileInfo *src);

Copy information from src into dest.

dest : Pointer to a struct to copy src's information into
src : Pointer to the information to be copied into dest


gnome_vfs_file_info_dup ()

GnomeVFSFileInfo* gnome_vfs_file_info_dup   (const GnomeVFSFileInfo *orig);

orig : Pointer to a file information structure to duplicate
Returns :a new file information struct that duplicates the information in orig.


gnome_vfs_file_info_matches ()

gboolean    gnome_vfs_file_info_matches     (const GnomeVFSFileInfo *a,
+                                             const GnomeVFSFileInfo *b);

Compare the two file info structs, return TRUE if they match.

a : first GnomeVFSFileInfo struct to compare
b : second GnomeVFSFileInfo struct to compare
Returns : TRUE if the two GnomeVFSFileInfos match, otherwise return FALSE.


gnome_vfs_file_info_list_ref ()

GList*      gnome_vfs_file_info_list_ref    (GList *list);

list : 
Returns : 


gnome_vfs_file_info_list_unref ()

GList*      gnome_vfs_file_info_list_unref  (GList *list);

list : 
Returns : 


gnome_vfs_file_info_list_copy ()

GList*      gnome_vfs_file_info_list_copy   (GList *list);

list : 
Returns : 


gnome_vfs_file_info_list_free ()

void        gnome_vfs_file_info_list_free   (GList *list);

list : 

\ No newline at end of file diff --git a/doc/html/gnome-vfs-file-operations.html b/doc/html/gnome-vfs-file-operations.html new file mode 100644 index 0000000..9cc9229 --- /dev/null +++ b/doc/html/gnome-vfs-file-operations.html @@ -0,0 +1,43 @@ +File Handling

File Handling

+ GnomeVFS file operations are, for the most part, patterned after + their POSIX equivalents, with the systematic difference that they + accept URIs rather than paths on the local filesystem. This makes + them easy to learn as if you are already familiar with basic commands + such as open(), seek(), write(), etc you will feel right at home + with GnomeVFS after learning a little about URIs. +

+ GnomeVFS also provides asynchronous versions of these basic operations + for allowing application developers to provide non-blocking file I/O + without the use of threads. +

diff --git a/doc/html/gnome-vfs-file-size.html b/doc/html/gnome-vfs-file-size.html new file mode 100644 index 0000000..2d0ac04 --- /dev/null +++ b/doc/html/gnome-vfs-file-size.html @@ -0,0 +1,426 @@ +File Size
GnomeVFS - Filesystem Abstraction library
<<< Previous PageHomeUpNext Page >>>

File Size

Name

File Size -- 

Description

Details

GNOME_VFS_OFFSET_IS_LONG_LONG

#define GNOME_VFS_OFFSET_IS_LONG_LONG


GNOME_VFS_SIZE_FORMAT_STR

#define GNOME_VFS_SIZE_FORMAT_STR "Lu"


GNOME_VFS_OFFSET_FORMAT_STR

#define GNOME_VFS_OFFSET_FORMAT_STR "Ld"


GnomeVFSFileSize

typedef unsigned long long GnomeVFSFileSize;


GnomeVFSFileOffset

typedef long long GnomeVFSFileOffset;

\ No newline at end of file diff --git a/doc/html/gnome-vfs-finding-special-directories.html b/doc/html/gnome-vfs-finding-special-directories.html new file mode 100644 index 0000000..6a3f974 --- /dev/null +++ b/doc/html/gnome-vfs-finding-special-directories.html @@ -0,0 +1,516 @@ +Finding Special Directories
GnomeVFS - Filesystem Abstraction library
<<< Previous PageHomeUpNext Page >>>

Finding Special Directories

Name

Finding Special Directories -- how to locate special directories such as the trash and desktop

Synopsis


+
+GnomeVFSResult gnome_vfs_find_directory     (GnomeVFSURI *near_uri,
+                                             GnomeVFSFindDirectoryKind kind,
+                                             GnomeVFSURI **result,
+                                             gboolean create_if_needed,
+                                             gboolean find_if_needed,
+                                             guint permissions);

Description

Details

gnome_vfs_find_directory ()

GnomeVFSResult gnome_vfs_find_directory     (GnomeVFSURI *near_uri,
+                                             GnomeVFSFindDirectoryKind kind,
+                                             GnomeVFSURI **result,
+                                             gboolean create_if_needed,
+                                             gboolean find_if_needed,
+                                             guint permissions);

Used to return well known directories such as Trash, Desktop, etc. from different +file systems.

There is quite a complicated logic behind finding/creating a Trash directory +and you need to be aware of some implications: +Finding the Trash the first time when using the file method may be pretty +expensive. A cache file is used to store the location of that Trash file +for next time. +If ceate_if_needed is specified without find_if_needed, you may end up +creating a Trash file when there already is one. Your app should start out +by doing a gnome_vfs_find_directory with the find_if_needed to avoid this +and then use the create_if_needed flag to create Trash lazily when it is +needed for throwing away an item on a given disk.

near_uri : find a well known directory on the same volume as near_uri
kind : kind of well known directory
result : newly created URI of the directory we found
create_if_needed : If directory we are looking for does not exist, try to create it
find_if_needed : If we don't know where trash is yet, look for it.
permissions : If creating, use these permissions
Returns : An integer representing the result of the operation



<<< Previous PageHomeUpNext Page >>>
Directory OperationsAsynchronous File I/O
\ No newline at end of file diff --git a/doc/html/gnome-vfs-first-steps.html b/doc/html/gnome-vfs-first-steps.html new file mode 100644 index 0000000..4531357 --- /dev/null +++ b/doc/html/gnome-vfs-first-steps.html @@ -0,0 +1,142 @@ +A Gentle Programming Primer

A Gentle Programming Primer

+ Using GnomeVFS in an existing application, or writing a new application + with it, is actually very simple since GnomeVFS tries to mimic POSIX + file access syntax and semantics. That means that most "standard unix calls" + have a GnomeVFS equivalent that operates in a fairly similar manner. There are + a few differences to keep in mind. + +

  • + The most obvious is probably that all I/O operations return a GnomeVFSResult + indicating the success or failure of the operation. More on this later. +

  • + The types may be slightly different (but still parallel), for example rather than using an + int for a file-descriptor, GnomeVFS uses GnomeVFSHandle, a handle + to a particular URI. +

  • + Most operations come in Handle (think file descriptor) and URI form. The URI form may be + more convenient if you do not want to track handles, etc, but just be aware that both are + at your disposal and may be used interchangably. For example gnome_vfs_open + and gnome_vfs_open_uri. +

+

+ By way of example, consider the basic read command: +

+	ssize_t read (int fd, void *buf, size_t count);
+      

+

+ The GnomeVFS equivalent is very similar, but you will notice slightly different data types. The + consistent returning of a GnomeVFSResult also necessitated moving the return value of read into + a pass-back-value pointer bytes_read: +

+	GnomeVFSResult gnome_vfs_read (GnomeVFSHandle *handle,
+	                               gpointer buffer,
+                                       GnomeVFSFileSize bytes,
+                                       GnomeVFSFileSize *bytes_read);
+      

+

+ So gnome_vfs_read takes a GnomeVFSHandle, which functions + like a file descriptor, and attempts to read bytes bytes out of + handle into buffer. The number of bytes succesfully + read into buffer is returned in the pointer bytes_read. + The return value of the function, a GnomeVFSResult indicates the success of the + operation or any errors that might have occurred (for example, permission denied). + GnomeVFSResult is just an enumeration. +

Simple Sample Program

+ Now lets write a simple program to copy a fixed number of bytes from one file and append + it to another file. +

+

+
+#include <libgnomevfs/gnome-vfs.h>
+#include <gnome.h>
+
+#define BYTES_TO_PROCESS 256
+
+int print_error (GnomeVFSResult result, const char *uri_string);
+
+int
+main (int argc, char **argv)
+{
+  GnomeVFSHandle *read_handle, *write_handle;
+  const char *input_uri_string = argv[1];
+  const char *output_uri_string = argv[2];
+  GnomeVFSFileSize bytes_read, bytes_written;
+  guint buffer[BYTES_TO_PROCESS];
+  GnomeVFSResult result;
+
+  /* remember to initialize GnomeVFS! */
+  if (!gnome_vfs_init ()) {
+    printf ("Could not initialize GnomeVFS\n");
+    return 1;
+  }
+
+  /* open the input file for read access */
+  result = gnome_vfs_open (&read_handle, input_uri_string, GNOME_VFS_OPEN_READ);
+  /* if the operation was not successful, print the error and abort */
+  if (result != GNOME_VFS_OK) return print_error (result, input_uri_string);
+
+  /* we use create instead of open, because open will not create the file if it does
+     not already exist. The last argument is the permissions to use if the file is created,
+     the second to last tells GnomeVFS that its ok if the file already exists, and just open it */
+  result = gnome_vfs_create (&write_handle, output_uri_string, GNOME_VFS_OPEN_WRITE, FALSE, 0x777);
+  if (result != GNOME_VFS_OK) return print_error (result, output_uri_string);
+
+  /* read data from the input uri */
+  result = gnome_vfs_read (read_handle, buffer, BYTES_TO_PROCESS, &bytes_read);
+  if (result != GNOME_VFS_OK) return print_error (result, input_uri_string);
+
+  /* seek to the end of the output uri so we will append rather than overwrite */
+  /* therefore, we seek 0 bytes relative to the end of the file */
+  result = gnome_vfs_seek (write_handle, GNOME_VFS_SEEK_END, 0);
+
+  /* now write the data we read out to the output uri */
+  result = gnome_vfs_write (write_handle, buffer, bytes_read, &bytes_written);
+  if (result != GNOME_VFS_OK) return print_error (result, output_uri_string);
+
+  return 0;
+}
+
+int
+print_error (GnomeVFSResult result, const char *uri_string)
+{
+  const char *error_string;
+  /* get the string corresponding to this GnomeVFSResult value */
+  error_string = gnome_vfs_result_to_string (result);
+  printf ("Error %s occured opening location %s\n", error_string, uri_string);
+  return 1;
+}
+
+
+	

+

Conversion of a Sample Code Block

+

diff --git a/doc/html/gnome-vfs-gnome-vfs-application-registry.html b/doc/html/gnome-vfs-gnome-vfs-application-registry.html new file mode 100644 index 0000000..68d4df0 --- /dev/null +++ b/doc/html/gnome-vfs-gnome-vfs-application-registry.html @@ -0,0 +1,349 @@ + +Application Registry

+Application Registry

+Application Registry — +stores supported MIME types and URIs of various applications

Synopsis

+
+
+
+#define     GNOME_VFS_APPLICATION_REGISTRY_COMMAND
+#define     GNOME_VFS_APPLICATION_REGISTRY_NAME
+#define     GNOME_VFS_APPLICATION_REGISTRY_CAN_OPEN_MULTIPLE_FILES
+#define     GNOME_VFS_APPLICATION_REGISTRY_REQUIRES_TERMINAL
+gboolean    gnome_vfs_application_registry_exists
+                                            (const char *app_id);
+GList*      gnome_vfs_application_registry_get_keys
+                                            (const char *app_id);
+const char* gnome_vfs_application_registry_peek_value
+                                            (const char *app_id,
+                                             const char *key);
+gboolean    gnome_vfs_application_registry_get_bool_value
+                                            (const char *app_id,
+                                             const char *key,
+                                             gboolean *got_key);
+void        gnome_vfs_application_registry_remove_application
+                                            (const char *app_id);
+void        gnome_vfs_application_registry_set_value
+                                            (const char *app_id,
+                                             const char *key,
+                                             const char *value);
+void        gnome_vfs_application_registry_set_bool_value
+                                            (const char *app_id,
+                                             const char *key,
+                                             gboolean value);
+void        gnome_vfs_application_registry_unset_key
+                                            (const char *app_id,
+                                             const char *key);
+GList*      gnome_vfs_application_registry_get_applications
+                                            (const char *mime_type);
+GList*      gnome_vfs_application_registry_get_mime_types
+                                            (const char *app_id);
+gboolean    gnome_vfs_application_registry_supports_mime_type
+                                            (const char *app_id,
+                                             const char *mime_type);
+gboolean    gnome_vfs_application_registry_supports_uri_scheme
+                                            (const char *app_id,
+                                             const char *uri_scheme);
+gboolean    gnome_vfs_application_is_user_owned_application
+                                            (const GnomeVFSMimeApplication *application);
+void        gnome_vfs_application_registry_clear_mime_types
+                                            (const char *app_id);
+void        gnome_vfs_application_registry_add_mime_type
+                                            (const char *app_id,
+                                             const char *mime_type);
+void        gnome_vfs_application_registry_remove_mime_type
+                                            (const char *app_id,
+                                             const char *mime_type);
+GnomeVFSResult gnome_vfs_application_registry_sync
+                                            (void);
+void        gnome_vfs_application_registry_shutdown
+                                            (void);
+void        gnome_vfs_application_registry_reload
+                                            (void);
+GnomeVFSMimeApplication* gnome_vfs_application_registry_get_mime_application
+                                            (const char *app_id);
+void        gnome_vfs_application_registry_save_mime_application
+                                            (const GnomeVFSMimeApplication *application);
+

Description

+ +

Details

GNOME_VFS_APPLICATION_REGISTRY_COMMAND

#define GNOME_VFS_APPLICATION_REGISTRY_COMMAND "command"
+

+Application registry key for fetching the command to execute +an application.

+ +


GNOME_VFS_APPLICATION_REGISTRY_NAME

#define GNOME_VFS_APPLICATION_REGISTRY_NAME "name"
+

+Application registry key for fetching the name of an application.

+ +


GNOME_VFS_APPLICATION_REGISTRY_CAN_OPEN_MULTIPLE_FILES

#define GNOME_VFS_APPLICATION_REGISTRY_CAN_OPEN_MULTIPLE_FILES "can_open_multiple_files"
+

+Application registry key for determining if an application +can open multiple files in the same invocation.

+ +


GNOME_VFS_APPLICATION_REGISTRY_REQUIRES_TERMINAL

#define GNOME_VFS_APPLICATION_REGISTRY_REQUIRES_TERMINAL "requires_terminal"
+

+Application registry key for determining if an application +needs to run from within a terminal (for example, mpg123)

+ +


gnome_vfs_application_registry_exists ()

gboolean    gnome_vfs_application_registry_exists
+                                            (const char *app_id);

+This function will return TRUE if there is an entry for app_id in +the registry, otherwise FALSE.

+ +

app_id : an application ID +
Returns : TRUE if the application is in the registry, FALSE if not + +

gnome_vfs_application_registry_get_keys ()

GList*      gnome_vfs_application_registry_get_keys
+                                            (const char *app_id);

+This function wil return a list of strings which is the list of +keys set for app_id in the application registry.

+ +

app_id : the application ID for which to get keys +
Returns : A list of the keys set for app_id + +

gnome_vfs_application_registry_peek_value ()

const char* gnome_vfs_application_registry_peek_value
+                                            (const char *app_id,
+                                             const char *key);

+This will return the value associated with key for app_id in the +application registry. There is no need to free the return value.

+ +

app_id : the application ID for which to look up a value +
key : the key to look up +
Returns : the value associated with the key, or NULL if there is no +associated value + +

gnome_vfs_application_registry_get_bool_value ()

gboolean    gnome_vfs_application_registry_get_bool_value
+                                            (const char *app_id,
+                                             const char *key,
+                                             gboolean *got_key);

+This will look up a key in the structure pointed to by app_id and return the +boolean value of that key. It will return false if there are no +applications associated with the app_id.

+ +

app_id : registry id of the application +
key : key to look up +
got_key : TRUE if a setting was dound, otherwise FALSE +
Returns : TRUE if key is set to "true" or "yes" for app_id, otherwise FALSE + +

gnome_vfs_application_registry_remove_application ()

void        gnome_vfs_application_registry_remove_application
+                                            (const char *app_id);

+Given the registry id this function will remove all applications that has +been set by the user. You will need to call +gnome_vfs_application_registry_sync to save the changes.

+ +

app_id : registry id of the application +

gnome_vfs_application_registry_set_value ()

void        gnome_vfs_application_registry_set_value
+                                            (const char *app_id,
+                                             const char *key,
+                                             const char *value);

+This function will set values pertaining to registry entry pointed to by +app_id. You will need to call gnome_vfs_application_registry_sync to +realize the changes.

+ +

app_id : registry id of the application +
key : target key +
value : value to set the target key to +

gnome_vfs_application_registry_set_bool_value ()

void        gnome_vfs_application_registry_set_bool_value
+                                            (const char *app_id,
+                                             const char *key,
+                                             gboolean value);

+This function will modify those registry values that are of type boolean to +a value specified by the user. You will need to call +gnome_vfs_application_registry_sync to save your changes.

+ +

app_id : registry id of the application +
key : target key +
value : value you want to set the target key to +

gnome_vfs_application_registry_unset_key ()

void        gnome_vfs_application_registry_unset_key
+                                            (const char *app_id,
+                                             const char *key);

+This function given the application and the target will wipe the current +value that the key contains.

+ +

app_id : registry id of the application +
key : search key +

gnome_vfs_application_registry_get_applications ()

GList*      gnome_vfs_application_registry_get_applications
+                                            (const char *mime_type);

+This will return all applications from the registry that are associated with +the given mime type string, if NULL it returns all applications.

+ +

mime_type : mime type string +
Returns : a list of the application IDs for all applications which +support the given mime type. + +

gnome_vfs_application_registry_get_mime_types ()

GList*      gnome_vfs_application_registry_get_mime_types
+                                            (const char *app_id);

+This function returns a list of strings that represent the mime +types that can be handled by an application.

+ +

app_id : registry id of application +
Returns : a list of the mime types supported + +

gnome_vfs_application_registry_supports_mime_type ()

gboolean    gnome_vfs_application_registry_supports_mime_type
+                                            (const char *app_id,
+                                             const char *mime_type);

+Use this function to see if there is an application associated with a given +mime type. The function will return true or false.

+ +

app_id : registry id of application +
mime_type : mime type string +
Returns : TRUE if app_id supports mime_type, otherwise FALSE. + +

gnome_vfs_application_registry_supports_uri_scheme ()

gboolean    gnome_vfs_application_registry_supports_uri_scheme
+                                            (const char *app_id,
+                                             const char *uri_scheme);

+Given the id of the application this function will determine if the +uri scheme will given is supported.

+ +

app_id : registry id of application +
uri_scheme : uri schme string +
Returns : TRUE if app_id supports uri_scheme, otherwise FALSE + +

gnome_vfs_application_is_user_owned_application ()

gboolean    gnome_vfs_application_is_user_owned_application
+                                            (const GnomeVFSMimeApplication *application);

+This function will determine if a mime application is user owned or not. By +user ownered this means that the application is not a system application +located in the prerequisite /usr area but rather in the user's area.

+ +

application : data structure of the mime application +
Returns : gboolean +

gnome_vfs_application_registry_clear_mime_types ()

void        gnome_vfs_application_registry_clear_mime_types
+                                            (const char *app_id);

+This function will remove the mime types associated with the application. +Changes are not realized until the gnome_vfs_application_registry_sync +function is called to save the changes to the file.

+ +

app_id : Application id +

gnome_vfs_application_registry_add_mime_type ()

void        gnome_vfs_application_registry_add_mime_type
+                                            (const char *app_id,
+                                             const char *mime_type);

+This function will associate a mime type with an application given the +application registry id and the mime type. Changes are not realized until +the gnome_vfs_application_registry_sync function is called to save the +changes to the file.

+ +

app_id : registry id of application +
mime_type : mime type string +

gnome_vfs_application_registry_remove_mime_type ()

void        gnome_vfs_application_registry_remove_mime_type
+                                            (const char *app_id,
+                                             const char *mime_type);

+This function will de-associate a mime type from an application registry. +Given the application registry id and the mime type. Changes are not +realized until the gnome_vfs_application_registry_sync function is called to +save the changes to the file.

+ +

app_id : registry id of the application +
mime_type : mime type string +

gnome_vfs_application_registry_sync ()

GnomeVFSResult gnome_vfs_application_registry_sync
+                                            (void);

+This function will sync the registry. Typically you would use this function +after a modification of the registry. When you modify the registry a dirty +flag is set. Calling this function will save your modifications to disk and +reset the flag. +

+If successful, will return GNOME_VFS_OK

+ +

Returns : GnomeVFSResult + +

gnome_vfs_application_registry_shutdown ()

void        gnome_vfs_application_registry_shutdown
+                                            (void);

+Synchronize gnome-vfs application registry data to disk, and free +resources.

+ +


gnome_vfs_application_registry_reload ()

void        gnome_vfs_application_registry_reload
+                                            (void);

+If this function is called for the first time it will initialize the +registry. Subsequent calls to the function will clear out the current +registry contents and load registry contents from the save file. Make +certain that you've saved your registry before calling this function. It +will destroy unsaved changes.

+ +


gnome_vfs_application_registry_get_mime_application ()

GnomeVFSMimeApplication* gnome_vfs_application_registry_get_mime_application
+                                            (const char *app_id);

+Returns a structure that contains the application that handles +the mime type associated by the application referred by app_id.

+ +

app_id : registry id of the application +
Returns : GnomeVFSMimeApplication + +

gnome_vfs_application_registry_save_mime_application ()

void        gnome_vfs_application_registry_save_mime_application
+                                            (const GnomeVFSMimeApplication *application);

+This will save to the registry the application that will be associated with +a defined mime type. The defined mime type is located within the +GnomeVFSMimeApplication structure. Changes are not realized until the +gnome_vfs_application_registry_sync function is called.

+ +

application : application associated with the mime type +
diff --git a/doc/html/gnome-vfs-gnome-vfs-async-ops.html b/doc/html/gnome-vfs-gnome-vfs-async-ops.html new file mode 100644 index 0000000..32b7262 --- /dev/null +++ b/doc/html/gnome-vfs-gnome-vfs-async-ops.html @@ -0,0 +1,981 @@ + +Asynchronous File Operations

+Asynchronous File Operations

+Asynchronous File Operations — +POSIX-style file operations that run outside your main loop

Synopsis

+
+
+
+#define     GNOME_VFS_PRIORITY_MIN
+#define     GNOME_VFS_PRIORITY_MAX
+#define     GNOME_VFS_PRIORITY_DEFAULT
+void        (*GnomeVFSAsyncCallback)        (GnomeVFSAsyncHandle *handle,
+                                             GnomeVFSResult result,
+                                             gpointer callback_data);
+typedef     GnomeVFSAsyncOpenCallback;
+typedef     GnomeVFSAsyncCreateCallback;
+typedef     GnomeVFSAsyncCreateAsChannelCallback;
+typedef     GnomeVFSAsyncCloseCallback;
+void        (*GnomeVFSAsyncReadCallback)    (GnomeVFSAsyncHandle *handle,
+                                             GnomeVFSResult result,
+                                             gpointer buffer,
+                                             GnomeVFSFileSize bytes_requested,
+                                             GnomeVFSFileSize bytes_read,
+                                             gpointer callback_data);
+void        (*GnomeVFSAsyncWriteCallback)   (GnomeVFSAsyncHandle *handle,
+                                             GnomeVFSResult result,
+                                             gconstpointer buffer,
+                                             GnomeVFSFileSize bytes_requested,
+                                             GnomeVFSFileSize bytes_written,
+                                             gpointer callback_data);
+typedef     GnomeVFSFindDirectoryResult;
+void        gnome_vfs_async_set_job_limit   (int limit);
+int         gnome_vfs_async_get_job_limit   (void);
+void        gnome_vfs_async_cancel          (GnomeVFSAsyncHandle *handle);
+void        gnome_vfs_async_open            (GnomeVFSAsyncHandle **handle_return,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             int priority,
+                                             GnomeVFSAsyncOpenCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_open_uri        (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             int priority,
+                                             GnomeVFSAsyncOpenCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_open_as_channel (GnomeVFSAsyncHandle **handle_return,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             guint advised_block_size,
+                                             int priority,
+                                             GnomeVFSAsyncOpenAsChannelCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_open_uri_as_channel
+                                            (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             guint advised_block_size,
+                                             int priority,
+                                             GnomeVFSAsyncOpenAsChannelCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_create          (GnomeVFSAsyncHandle **handle_return,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm,
+                                             int priority,
+                                             GnomeVFSAsyncOpenCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_create_uri      (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm,
+                                             int priority,
+                                             GnomeVFSAsyncOpenCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_create_symbolic_link
+                                            (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             const gchar *uri_reference,
+                                             int priority,
+                                             GnomeVFSAsyncOpenCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_create_as_channel
+                                            (GnomeVFSAsyncHandle **handle_return,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm,
+                                             int priority,
+                                             GnomeVFSAsyncCreateAsChannelCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_create_uri_as_channel
+                                            (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm,
+                                             int priority,
+                                             GnomeVFSAsyncCreateAsChannelCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_close           (GnomeVFSAsyncHandle *handle,
+                                             GnomeVFSAsyncCloseCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_read            (GnomeVFSAsyncHandle *handle,
+                                             gpointer buffer,
+                                             guint bytes,
+                                             GnomeVFSAsyncReadCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_write           (GnomeVFSAsyncHandle *handle,
+                                             gconstpointer buffer,
+                                             guint bytes,
+                                             GnomeVFSAsyncWriteCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_get_file_info   (GnomeVFSAsyncHandle **handle_return,
+                                             GList *uri_list,
+                                             GnomeVFSFileInfoOptions options,
+                                             int priority,
+                                             GnomeVFSAsyncGetFileInfoCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_set_file_info   (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSFileInfo *info,
+                                             GnomeVFSSetFileInfoMask mask,
+                                             GnomeVFSFileInfoOptions options,
+                                             int priority,
+                                             GnomeVFSAsyncSetFileInfoCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_load_directory  (GnomeVFSAsyncHandle **handle_return,
+                                             const gchar *text_uri,
+                                             GnomeVFSFileInfoOptions options,
+                                             guint items_per_notification,
+                                             int priority,
+                                             GnomeVFSAsyncDirectoryLoadCallback callback,
+                                             gpointer callback_data);
+void        gnome_vfs_async_load_directory_uri
+                                            (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSFileInfoOptions options,
+                                             guint items_per_notification,
+                                             int priority,
+                                             GnomeVFSAsyncDirectoryLoadCallback callback,
+                                             gpointer callback_data);
+GnomeVFSResult gnome_vfs_async_xfer         (GnomeVFSAsyncHandle **handle_return,
+                                             GList *source_uri_list,
+                                             GList *target_uri_list,
+                                             GnomeVFSXferOptions xfer_options,
+                                             GnomeVFSXferErrorMode error_mode,
+                                             GnomeVFSXferOverwriteMode overwrite_mode,
+                                             int priority,
+                                             GnomeVFSAsyncXferProgressCallback progress_update_callback,
+                                             gpointer update_callback_data,
+                                             GnomeVFSXferProgressCallback progress_sync_callback,
+                                             gpointer sync_callback_data);
+void        gnome_vfs_async_find_directory  (GnomeVFSAsyncHandle **handle_return,
+                                             GList *near_uri_list,
+                                             GnomeVFSFindDirectoryKind kind,
+                                             gboolean create_if_needed,
+                                             gboolean find_if_needed,
+                                             guint permissions,
+                                             int priority,
+                                             GnomeVFSAsyncFindDirectoryCallback callback,
+                                             gpointer user_data);
+void        gnome_vfs_async_file_control    (GnomeVFSAsyncHandle *handle,
+                                             const char *operation,
+                                             gpointer operation_data,
+                                             GDestroyNotify operation_data_destroy_func,
+                                             GnomeVFSAsyncFileControlCallback callback,
+                                             gpointer callback_data);
+

Description

+ When executing an asynchornous operation on a file the program does not + block waiting for the operation to finish, instead it keeps on running, + which means that the process and the I/O operation can be both running + concurrently. Once the I/O operation has been completed the process is + notified using a callback. +

+ Asynchronous operations are particularly good when long I/O operations + are expected, in this case the program can continue normaly, the I/O + will be performed in the background. On the other hand when operations + are expected to be short (creating a file, writing/reading small amounts + of data, etc.) synchronous operations are prefered. +

+ Within a graphical desktop asynchornous I/O operations can be used to + avoid blocking the UI (User Interface) during a long operation, and + to be able to provide some kind of feedback to the user. +

Details

GNOME_VFS_PRIORITY_MIN

#define GNOME_VFS_PRIORITY_MIN     -10
+

+The minimuum priority a job can have.

+ +


GNOME_VFS_PRIORITY_MAX

#define GNOME_VFS_PRIORITY_MAX     10
+

+The maximuum priority a job can have.

+ +


GNOME_VFS_PRIORITY_DEFAULT

#define GNOME_VFS_PRIORITY_DEFAULT 0
+

+The default job priority. Its best to use this +unless you have a reason to do otherwise.

+ +


GnomeVFSAsyncCallback ()

void        (*GnomeVFSAsyncCallback)        (GnomeVFSAsyncHandle *handle,
+                                             GnomeVFSResult result,
+                                             gpointer callback_data);

+Basic callback from an async operation that passes no data back, +informing the user of the result of the operation.

+ +

handle : handle of the operation generating the callback +
result : GNOME_VFS_OK if the operation was successful, otherwise +an error code. +
callback_data : user data defined when the callback was established +

GnomeVFSAsyncOpenCallback

typedef GnomeVFSAsyncCallback GnomeVFSAsyncOpenCallback;
+

+Basic callback from an async operation that passes no data back, +informing the user of the result of the operation.

+ +


GnomeVFSAsyncCreateCallback

typedef GnomeVFSAsyncCallback GnomeVFSAsyncCreateCallback;
+

+Basic callback from an async operation that passes no data back, +informing the user of the result of the operation.

+ +


GnomeVFSAsyncCreateAsChannelCallback

typedef GnomeVFSAsyncOpenAsChannelCallback GnomeVFSAsyncCreateAsChannelCallback;
+

+Callback for the gnome_vfs_async_create_as_channel() function.

+ +


GnomeVFSAsyncCloseCallback

typedef GnomeVFSAsyncCallback GnomeVFSAsyncCloseCallback;
+

+Basic callback from an async operation that passes no data back, +informing the user of the result of the operation.

+ +


GnomeVFSAsyncReadCallback ()

void        (*GnomeVFSAsyncReadCallback)    (GnomeVFSAsyncHandle *handle,
+                                             GnomeVFSResult result,
+                                             gpointer buffer,
+                                             GnomeVFSFileSize bytes_requested,
+                                             GnomeVFSFileSize bytes_read,
+                                             gpointer callback_data);

+Callback for the gnome_vfs_async_read() function.

+ +

handle : handle of the operation generating the callback +
result : GNOME_VFS_OK if the operation was successful, otherwise +an error code. +
buffer : buffer containing data read from handle. +
bytes_requested : the number of bytes asked for in the call to +gnome_vfs_async_read(). +
bytes_read : the number of bytes actually read from handle into buffer. +
callback_data : user data defined when the callback was established +

GnomeVFSAsyncWriteCallback ()

void        (*GnomeVFSAsyncWriteCallback)   (GnomeVFSAsyncHandle *handle,
+                                             GnomeVFSResult result,
+                                             gconstpointer buffer,
+                                             GnomeVFSFileSize bytes_requested,
+                                             GnomeVFSFileSize bytes_written,
+                                             gpointer callback_data);

+Callback for the gnome_vfs_async_write() function.

+ +

handle : handle of the operation generating the callback +
result : GNOME_VFS_OK if the operation was successful, otherwise +an error code. +
buffer : buffer containing data written to handle. +
bytes_requested : the number of bytes asked to write in the call to +gnome_vfs_async_write(). +
bytes_written : the number of bytes actually written to handle from buffer. +
callback_data : user data defined when the callback was established +

GnomeVFSFindDirectoryResult

typedef struct {
+	GnomeVFSURI *uri;
+	GnomeVFSResult result;
+
+	/* Reserved to avoid future breaks in ABI compatibility */
+	void *reserved1;
+	void *reserved2;
+} GnomeVFSFindDirectoryResult;
+

+ +


gnome_vfs_async_set_job_limit ()

void        gnome_vfs_async_set_job_limit   (int limit);

+Restrict the number of worker threads used by Async operations +to limit.

+ +

limit : maximuum number of allowable threads +

gnome_vfs_async_get_job_limit ()

int         gnome_vfs_async_get_job_limit   (void);

+Get the current maximuum allowable number of +worker threads for Asynch operations.

+ +

Returns : current maximuum number of threads +

gnome_vfs_async_cancel ()

void        gnome_vfs_async_cancel          (GnomeVFSAsyncHandle *handle);

+Cancel an asynchronous operation and close all its callbacks. +Its possible to still receive another call or two on the callback.

+ +

handle : handle of the async operation to be cancelled +

gnome_vfs_async_open ()

void        gnome_vfs_async_open            (GnomeVFSAsyncHandle **handle_return,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             int priority,
+                                             GnomeVFSAsyncOpenCallback callback,
+                                             gpointer callback_data);

+Open text_uri according to mode open_mode. On return, handle_return will +contain a pointer to the operation. Once the file has been successfully opened, +callback will be called with the GnomeVFSResult.

+ +

handle_return : A pointer to a pointer to a GnomeVFSHandle object +
text_uri : string of the URI to open +
open_mode : Open mode +
priority : a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. +
callback : function to be called when the operation is complete +
callback_data : data to pass callback +

gnome_vfs_async_open_uri ()

void        gnome_vfs_async_open_uri        (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             int priority,
+                                             GnomeVFSAsyncOpenCallback callback,
+                                             gpointer callback_data);

+Open uri according to mode open_mode. On return, handle_return will +contain a pointer to the operation. Once the file has been successfully opened, +callback will be called with the GnomeVFSResult.

+ +

handle_return : A pointer to a pointer to a GnomeVFSHandle object +
uri : URI to open +
open_mode : Open mode +
priority : a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. +
callback : function to be called when the operation is complete +
callback_data : data to pass callback +

gnome_vfs_async_open_as_channel ()

void        gnome_vfs_async_open_as_channel (GnomeVFSAsyncHandle **handle_return,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             guint advised_block_size,
+                                             int priority,
+                                             GnomeVFSAsyncOpenAsChannelCallback callback,
+                                             gpointer callback_data);

+Open text_uri as a GIOChannel. Once the channel has been established +callback will be called with callback_data, the result of the operation, +and if the result was GNOME_VFS_OK, a reference to a GIOChannel pointing +at text_uri in open_mode.

+ +

handle_return : A pointer to a pointer to a GnomeVFSHandle object +
text_uri : string of the URI to open as a GIOChannel +
open_mode : open for reading, writing, random, etc +
advised_block_size : the preferred block size for GIOChannel to read +
priority : a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. +
callback : function to be called when the operation is complete +
callback_data : data to pass callback +

gnome_vfs_async_open_uri_as_channel ()

void        gnome_vfs_async_open_uri_as_channel
+                                            (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             guint advised_block_size,
+                                             int priority,
+                                             GnomeVFSAsyncOpenAsChannelCallback callback,
+                                             gpointer callback_data);

+Open uri as a GIOChannel. Once the channel has been established +callback will be called with callback_data, the result of the operation, +and if the result was GNOME_VFS_OK, a reference to a GIOChannel pointing +at uri in open_mode.

+ +

handle_return : A pointer to a pointer to a GnomeVFSHandle object +
uri : URI to open as a GIOChannel +
open_mode : open for reading, writing, random, etc +
advised_block_size : the preferred block size for GIOChannel to read +
priority : a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. +
callback : function to be called when the operation is complete +
callback_data : data to pass callback +

gnome_vfs_async_create ()

void        gnome_vfs_async_create          (GnomeVFSAsyncHandle **handle_return,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm,
+                                             int priority,
+                                             GnomeVFSAsyncOpenCallback callback,
+                                             gpointer callback_data);

+Create a file at uri according to mode open_mode, with permissions perm (in +the standard UNIX packed bit permissions format). When the create has been completed +callback will be called with the result code and callback_data.

+ +

handle_return : A pointer to a pointer to a GnomeVFSHandle object +
text_uri : String representing the URI to create +
open_mode : mode to leave the file opened in after creation (or GNOME_VFS_OPEN_MODE_NONE +to leave the file closed after creation) +
exclusive : Whether the file should be created in "exclusive" mode: +i.e. if this flag is nonzero, operation will fail if a file with the +same name already exists. +
perm : Bitmap representing the permissions for the newly created file +(Unix style). +
priority : a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. +
callback : function to be called when the operation is complete +
callback_data : data to pass callback +

gnome_vfs_async_create_uri ()

void        gnome_vfs_async_create_uri      (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm,
+                                             int priority,
+                                             GnomeVFSAsyncOpenCallback callback,
+                                             gpointer callback_data);

+Create a file at uri according to mode open_mode, with permissions perm (in +the standard UNIX packed bit permissions format). When the create has been completed +callback will be called with the result code and callback_data.

+ +

handle_return : A pointer to a pointer to a GnomeVFSHandle object +
uri : the URI to create a file at +
open_mode : mode to leave the file opened in after creation (or GNOME_VFS_OPEN_MODE_NONE +to leave the file closed after creation) +
exclusive : Whether the file should be created in "exclusive" mode: +i.e. if this flag is nonzero, operation will fail if a file with the +same name already exists. +
perm : Bitmap representing the permissions for the newly created file +(Unix style). +
priority : a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. +
callback : function to be called when the operation is complete +
callback_data : data to pass callback +

gnome_vfs_async_create_symbolic_link ()

void        gnome_vfs_async_create_symbolic_link
+                                            (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             const gchar *uri_reference,
+                                             int priority,
+                                             GnomeVFSAsyncOpenCallback callback,
+                                             gpointer callback_data);

+Create a symbolic link at uri pointing to uri_reference. When the operation +has complete callback will be called with the result of the operation and +callback_data.

+ +

handle_return : when the function returns will point to a handle for +the async operation. +
uri : location to create the link at +
uri_reference : location to point uri to (can be a URI fragment, i.e. relative) +
priority : a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. +
callback : function to be called when the operation is complete +
callback_data : data to pass callback +

gnome_vfs_async_create_as_channel ()

void        gnome_vfs_async_create_as_channel
+                                            (GnomeVFSAsyncHandle **handle_return,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm,
+                                             int priority,
+                                             GnomeVFSAsyncCreateAsChannelCallback callback,
+                                             gpointer callback_data);

+Open text_uri as a GIOChannel, creating it as necessary. Once the channel has +been established callback will be called with callback_data, the result of the +operation, and if the result was GNOME_VFS_OK, a reference to a GIOChannel pointing +at text_uri in open_mode.

+ +

handle_return : A pointer to a pointer to a GnomeVFSHandle object +
text_uri : string of the URI to open as a GIOChannel, creating it as necessary +
open_mode : open for reading, writing, random, etc +
exclusive : replace the file if it already exists +
perm : standard POSIX-style permissions bitmask, permissions of created file +
priority : a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. +
callback : function to be called when the operation is complete +
callback_data : data to pass callback +

gnome_vfs_async_create_uri_as_channel ()

void        gnome_vfs_async_create_uri_as_channel
+                                            (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm,
+                                             int priority,
+                                             GnomeVFSAsyncCreateAsChannelCallback callback,
+                                             gpointer callback_data);

+ +

handle_return : +
uri : +
open_mode : +
exclusive : +
perm : +
priority : +
callback : +
callback_data : + + +

gnome_vfs_async_close ()

void        gnome_vfs_async_close           (GnomeVFSAsyncHandle *handle,
+                                             GnomeVFSAsyncCloseCallback callback,
+                                             gpointer callback_data);

+Close a handle opened with gnome_vfs_async_open(). When the close +has completed, callback will be called with callback_data and +the result of the operation.

+ +

handle : async handle to close +
callback : function to be called when the operation is complete +
callback_data : data to pass callback +

gnome_vfs_async_read ()

void        gnome_vfs_async_read            (GnomeVFSAsyncHandle *handle,
+                                             gpointer buffer,
+                                             guint bytes,
+                                             GnomeVFSAsyncReadCallback callback,
+                                             gpointer callback_data);

+Read bytes bytes from the file pointed to be handle into buffer. +When the operation is complete, callback will be called with the +result of the operation and callback_data.

+ +

handle : handle for the file to be read +
buffer : allocated block of memory to read into +
bytes : number of bytes to read +
callback : function to be called when the operation is complete +
callback_data : data to pass callback +

gnome_vfs_async_write ()

void        gnome_vfs_async_write           (GnomeVFSAsyncHandle *handle,
+                                             gconstpointer buffer,
+                                             guint bytes,
+                                             GnomeVFSAsyncWriteCallback callback,
+                                             gpointer callback_data);

+Write bytes bytes from buffer into the file pointed to be handle. +When the operation is complete, callback will be called with the +result of the operation and callback_data.

+ +

handle : handle for the file to be written +
buffer : block of memory containing data to be written +
bytes : number of bytes to write +
callback : function to be called when the operation is complete +
callback_data : data to pass callback +

gnome_vfs_async_get_file_info ()

void        gnome_vfs_async_get_file_info   (GnomeVFSAsyncHandle **handle_return,
+                                             GList *uri_list,
+                                             GnomeVFSFileInfoOptions options,
+                                             int priority,
+                                             GnomeVFSAsyncGetFileInfoCallback callback,
+                                             gpointer callback_data);

+Fetch information about the files indicated in uris and return the +information progressively to callback.

+ +

handle_return : when the function returns will point to a handle for +the async operation. +
uri_list : a GList of GnomeVFSURIs to fetch information about +
options : packed boolean type providing control over various details +of the get_file_info operation. +
priority : a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. +
callback : function to be called when the operation is complete +
callback_data : data to pass callback +

gnome_vfs_async_set_file_info ()

void        gnome_vfs_async_set_file_info   (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSFileInfo *info,
+                                             GnomeVFSSetFileInfoMask mask,
+                                             GnomeVFSFileInfoOptions options,
+                                             int priority,
+                                             GnomeVFSAsyncSetFileInfoCallback callback,
+                                             gpointer callback_data);

+Set "file info" details about the file at uri, such as permissions, name, +owner, and modification time.

+ +

handle_return : when the function returns will point to a handle for +the async operation. +
uri : the URI to set the file info of +
info : the struct containing new information about the file +
mask : control which fields of info are changed about the file at uri +
options : packed boolean type providing control over various details +of the set_file_info operation. +
priority : a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. +
callback : function to be called when the operation is complete +
callback_data : data to pass callback +

gnome_vfs_async_load_directory ()

void        gnome_vfs_async_load_directory  (GnomeVFSAsyncHandle **handle_return,
+                                             const gchar *text_uri,
+                                             GnomeVFSFileInfoOptions options,
+                                             guint items_per_notification,
+                                             int priority,
+                                             GnomeVFSAsyncDirectoryLoadCallback callback,
+                                             gpointer callback_data);

+Read the contents of the directory at text_uri, passing back GnomeVFSFileInfo +structs about each file in the directory to callback. items_per_notification +files will be processed between each call to callback.

+ +

handle_return : when the function returns will point to a handle for +the async operation. +
text_uri : string representing the URI of the directory to be loaded +
options : packed boolean type providing control over various details +of the get_file_info operation. +
items_per_notification : number of files to process in a row before calling callback +
priority : a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. +
callback : function to be called when the operation is complete +
callback_data : data to pass callback +

gnome_vfs_async_load_directory_uri ()

void        gnome_vfs_async_load_directory_uri
+                                            (GnomeVFSAsyncHandle **handle_return,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSFileInfoOptions options,
+                                             guint items_per_notification,
+                                             int priority,
+                                             GnomeVFSAsyncDirectoryLoadCallback callback,
+                                             gpointer callback_data);

+Read the contents of the directory at uri, passing back GnomeVFSFileInfo structs +about each file in the directory to callback. items_per_notification +files will be processed between each call to callback.

+ +

handle_return : when the function returns will point to a handle for +the async operation. +
uri : string representing the URI of the directory to be loaded +
options : packed boolean type providing control over various details +of the get_file_info operation. +
items_per_notification : number of files to process in a row before calling callback +
priority : a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. +
callback : function to be called when the operation is complete +
callback_data : data to pass callback +

gnome_vfs_async_xfer ()

GnomeVFSResult gnome_vfs_async_xfer         (GnomeVFSAsyncHandle **handle_return,
+                                             GList *source_uri_list,
+                                             GList *target_uri_list,
+                                             GnomeVFSXferOptions xfer_options,
+                                             GnomeVFSXferErrorMode error_mode,
+                                             GnomeVFSXferOverwriteMode overwrite_mode,
+                                             int priority,
+                                             GnomeVFSAsyncXferProgressCallback progress_update_callback,
+                                             gpointer update_callback_data,
+                                             GnomeVFSXferProgressCallback progress_sync_callback,
+                                             gpointer sync_callback_data);

+Perform a copy operation in a seperate thread. progress_update_callback will be periodically +polled with status of the operation (percent done, the current phase of operation, the +current file being operated upon). If the xfer engine needs to query the caller to make +a decision or report on important error it will do so on progress_sync_callback.

+ +

handle_return : when the function returns will point to a handle for +
source_uri_list : GList of GnomeVFSURI representing the files to be transferred +
target_uri_list : GList of GnomeVFSURI, the target locations for the elements +in source_uri_list +
xfer_options : various options controlling the details of the transfer. +Use GNOME_VFS_XFER_REMOUVESOURCE to make the operation a move rather than a copy. +
error_mode : report errors to the progress_sync_callback, or simply abort +
overwrite_mode : controls whether the xfer engine will overwrite automatically, +skip the file, abort the operation, or query progress_sync_callback +
priority : a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. +
progress_update_callback : called periodically to keep the client appraised of progress +in completing the XFer operation, and the current phase of operation. +
update_callback_data : user data passed to progress_update_callback +
progress_sync_callback : called when the program requires responses to interactive queries +(e.g. overwriting files, handling errors, etc) +
sync_callback_data : user data passed to progress_sync_callback +
Returns : GNOME_VFS_OK if the paramaters were in order, +or GNOME_VFS_ERROR_BAD_PARAMETERS if something was wrong in the passed in arguments. +

gnome_vfs_async_find_directory ()

void        gnome_vfs_async_find_directory  (GnomeVFSAsyncHandle **handle_return,
+                                             GList *near_uri_list,
+                                             GnomeVFSFindDirectoryKind kind,
+                                             gboolean create_if_needed,
+                                             gboolean find_if_needed,
+                                             guint permissions,
+                                             int priority,
+                                             GnomeVFSAsyncFindDirectoryCallback callback,
+                                             gpointer user_data);

+There is quite a complicated logic behind finding/creating a Trash directory +and you need to be aware of some implications: +Finding the Trash the first time when using the file method may be pretty +expensive. A cache file is used to store the location of that Trash file +for next time. +If ceate_if_needed is specified without find_if_needed, you may end up +creating a Trash file when there already is one. Your app should start out +by doing a gnome_vfs_find_directory with the find_if_needed to avoid this +and then use the create_if_needed flag to create Trash lazily when it is +needed for throwing away an item on a given disk. +

+When the operation has completed, callback will be called with the result +of the operation and user_data.

+ +

handle_return : when the function returns will point to a handle for +
near_uri_list : a GList of GnomeVFSURIs, find a special directory on the same +volume as uris +
kind : kind of special directory +
create_if_needed : If directory we are looking for does not exist, try to create it +
find_if_needed : If we don't know where the directory is yet, look for it. +
permissions : If creating, use these permissions +
priority : a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. +
callback : function to be called when the operation is complete +
user_data : data to pass callback * +Used to return special directories such as Trash and Desktop from different +file systems. +

gnome_vfs_async_file_control ()

void        gnome_vfs_async_file_control    (GnomeVFSAsyncHandle *handle,
+                                             const char *operation,
+                                             gpointer operation_data,
+                                             GDestroyNotify operation_data_destroy_func,
+                                             GnomeVFSAsyncFileControlCallback callback,
+                                             gpointer callback_data);

+Execute a backend dependent operation specified by the string operation. +This is typically used for specialized vfs backends that need additional +operations that gnome-vfs doesn't have. Compare it to the unix call ioctl(). +The format of operation_data depends on the operation. Operation that are +backend specific are normally namespaced by their module name. +

+When the operation is complete, callback will be called with the +result of the operation, operation_data and callback_data.

+ +

handle : handle of the file to affect +
operation : The operation to execute +
operation_data : The data needed to execute the operation +
operation_data_destroy_func : Called to destroy operation_data when its no longer needed +
callback : function to be called when the operation is complete +
callback_data : data to pass callback +

Since 2.2 +

diff --git a/doc/html/gnome-vfs-gnome-vfs-cancellation.html b/doc/html/gnome-vfs-gnome-vfs-cancellation.html new file mode 100644 index 0000000..eb8c1a6 --- /dev/null +++ b/doc/html/gnome-vfs-gnome-vfs-cancellation.html @@ -0,0 +1,98 @@ + +Cancellation

+Cancellation

+Cancellation — +halt in-progress operations

Synopsis

+
+
+
+GnomeVFSCancellation* gnome_vfs_cancellation_new
+                                            (void);
+void        gnome_vfs_cancellation_destroy  (GnomeVFSCancellation *cancellation);
+void        gnome_vfs_cancellation_cancel   (GnomeVFSCancellation *cancellation);
+gboolean    gnome_vfs_cancellation_check    (GnomeVFSCancellation *cancellation);
+void        gnome_vfs_cancellation_ack      (GnomeVFSCancellation *cancellation);
+gint        gnome_vfs_cancellation_get_fd   (GnomeVFSCancellation *cancellation);
+

Description

+ +

Details

gnome_vfs_cancellation_new ()

GnomeVFSCancellation* gnome_vfs_cancellation_new
+                                            (void);

+Create a new GnomeVFSCancellation object for reporting cancellation to a +GNOME VFS module.

+ +

Returns : A pointer to the new GnomeVFSCancellation object. +

gnome_vfs_cancellation_destroy ()

void        gnome_vfs_cancellation_destroy  (GnomeVFSCancellation *cancellation);

+Destroy cancellation.

+ +

cancellation : A GnomeVFSCancellation object +

gnome_vfs_cancellation_cancel ()

void        gnome_vfs_cancellation_cancel   (GnomeVFSCancellation *cancellation);

+Send a cancellation request through cancellation.

+ +

cancellation : A GnomeVFSCancellation object +

gnome_vfs_cancellation_check ()

gboolean    gnome_vfs_cancellation_check    (GnomeVFSCancellation *cancellation);

+Check for pending cancellation.

+ +

cancellation : A GnomeVFSCancellation object +
Returns : TRUE if the operation should be interrupted. +

gnome_vfs_cancellation_ack ()

void        gnome_vfs_cancellation_ack      (GnomeVFSCancellation *cancellation);

+Acknowledge a cancellation. This should be called if +`gnome_vfs_cancellation_check()' returns TRUE or if `select()' reports that +input is available on the file descriptor returned by +`gnome_vfs_cancellation_get_fd()'.

+ +

cancellation : A GnomeVFSCancellation object +

gnome_vfs_cancellation_get_fd ()

gint        gnome_vfs_cancellation_get_fd   (GnomeVFSCancellation *cancellation);

+Get a file descriptor -based notificator for cancellation. When +cancellation receives a cancellation request, a character will be made +available on the returned file descriptor for input. +

+This is very useful for detecting cancellation during I/O operations: you +can use the `select()' call to check for available input/output on the file +you are reading/writing, and on the notificator's file descriptor at the +same time. If a data is available on the notificator's file descriptor, you +know you have to cancel the read/write operation.

+ +

cancellation : A GnomeVFSCancellation object +
Returns : the notificator's file descriptor, or -1 if starved of + file descriptors. +
diff --git a/doc/html/gnome-vfs-gnome-vfs-context.html b/doc/html/gnome-vfs-gnome-vfs-context.html new file mode 100644 index 0000000..7e646f4 --- /dev/null +++ b/doc/html/gnome-vfs-gnome-vfs-context.html @@ -0,0 +1,86 @@ + +GnomeVFSContext

+GnomeVFSContext

+GnomeVFSContext — +contexts allows modules to track thread usage and cancellation properly

Synopsis

+
+
+
+GnomeVFSContext* gnome_vfs_context_new      (void);
+void        gnome_vfs_context_free          (GnomeVFSContext *ctx);
+GnomeVFSCancellation* gnome_vfs_context_get_cancellation
+                                            (const GnomeVFSContext *ctx);
+#define     gnome_vfs_context_check_cancellation(x)
+const GnomeVFSContext* gnome_vfs_context_peek_current
+                                            (void);
+gboolean    gnome_vfs_context_check_cancellation_current
+                                            (void);
+

Description

+ +

Details

gnome_vfs_context_new ()

GnomeVFSContext* gnome_vfs_context_new      (void);

+Creates a new context and cancellation object. Must be called +from the main glib event loop.

+ +

Returns : a newly allocated GnomeVFSContext +

gnome_vfs_context_free ()

void        gnome_vfs_context_free          (GnomeVFSContext *ctx);

+Free ctx and destroy the associated GnomeVFSCancellation.

+ +

ctx : context to be freed +

gnome_vfs_context_get_cancellation ()

GnomeVFSCancellation* gnome_vfs_context_get_cancellation
+                                            (const GnomeVFSContext *ctx);

+Retrieve the GnomeVFSCancellation associated with ctx.

+ +

ctx : context to get the GnomeVFSCancellation from +
Returns : ctx 's GnomeVFSCancellation +

gnome_vfs_context_check_cancellation()

#define     gnome_vfs_context_check_cancellation(x)

+ +

x : + + +

gnome_vfs_context_peek_current ()

const GnomeVFSContext* gnome_vfs_context_peek_current
+                                            (void);

+Get the currently active context. It shouldn't be +manipulated but can be compared to context's the module +holds to determine whether they are active.

+ +

Returns : the currently active GnomeVFSContext +

gnome_vfs_context_check_cancellation_current ()

gboolean    gnome_vfs_context_check_cancellation_current
+                                            (void);

+Check to see if the currently active context has been cancelled.

+ +

Returns : TRUE if the currently active context has been cancelled, otherwise FALSE +
diff --git a/doc/html/gnome-vfs-gnome-vfs-directory-basic-ops.html b/doc/html/gnome-vfs-gnome-vfs-directory-basic-ops.html new file mode 100644 index 0000000..1b6f09a --- /dev/null +++ b/doc/html/gnome-vfs-gnome-vfs-directory-basic-ops.html @@ -0,0 +1,94 @@ + +Basic Directory Operations

+Basic Directory Operations

+Basic Directory Operations — +Creating and removing directories.

Synopsis

+
+
+
+GnomeVFSResult gnome_vfs_make_directory     (const gchar *text_uri,
+                                             guint perm);
+GnomeVFSResult gnome_vfs_make_directory_for_uri
+                                            (GnomeVFSURI *uri,
+                                             guint perm);
+GnomeVFSResult gnome_vfs_remove_directory   (const gchar *text_uri);
+GnomeVFSResult gnome_vfs_remove_directory_from_uri
+                                            (GnomeVFSURI *uri);
+

Description

+ +

Details

gnome_vfs_make_directory ()

GnomeVFSResult gnome_vfs_make_directory     (const gchar *text_uri,
+                                             guint perm);

+Create text_uri as a directory.

+ +

text_uri : URI of the directory to be created +
perm : Unix-style permissions for the newly created directory +
Returns : An integer representing the result of the operation +

gnome_vfs_make_directory_for_uri ()

GnomeVFSResult gnome_vfs_make_directory_for_uri
+                                            (GnomeVFSURI *uri,
+                                             guint perm);

+Create a directory at uri. Only succeeds if a file or directory +does not already exist at uri.

+ +

uri : URI of the directory to be created +
perm : Unix-style permissions for the newly created directory +
Returns : An integer representing the result of the operation +

gnome_vfs_remove_directory ()

GnomeVFSResult gnome_vfs_remove_directory   (const gchar *text_uri);

+Remove text_uri. text_uri must be an empty directory.

+ +

text_uri : URI of the directory to be removed +
Returns : An integer representing the result of the operation +

gnome_vfs_remove_directory_from_uri ()

GnomeVFSResult gnome_vfs_remove_directory_from_uri
+                                            (GnomeVFSURI *uri);

+Remove uri. uri must be an empty directory.

+ +

uri : URI of the directory to be removed +
Returns : An integer representing the result of the operation +
diff --git a/doc/html/gnome-vfs-gnome-vfs-directory-find-ops.html b/doc/html/gnome-vfs-gnome-vfs-directory-find-ops.html new file mode 100644 index 0000000..0960ca8 --- /dev/null +++ b/doc/html/gnome-vfs-gnome-vfs-directory-find-ops.html @@ -0,0 +1,95 @@ + +Locating Standard Directories

+Locating Standard Directories

+Locating Standard Directories — +Utilities for locating standard directories such as the desktop and trash

Synopsis

+
+
+
+enum        GnomeVFSFindDirectoryKind;
+GnomeVFSResult gnome_vfs_find_directory     (GnomeVFSURI *near_uri,
+                                             GnomeVFSFindDirectoryKind kind,
+                                             GnomeVFSURI **result,
+                                             gboolean create_if_needed,
+                                             gboolean find_if_needed,
+                                             guint permissions);
+

Description

+ +

Details

enum GnomeVFSFindDirectoryKind

typedef enum {
+	GNOME_VFS_DIRECTORY_KIND_DESKTOP = 1000,
+	GNOME_VFS_DIRECTORY_KIND_TRASH = 1001
+} GnomeVFSFindDirectoryKind;
+

+ +


gnome_vfs_find_directory ()

GnomeVFSResult gnome_vfs_find_directory     (GnomeVFSURI *near_uri,
+                                             GnomeVFSFindDirectoryKind kind,
+                                             GnomeVFSURI **result,
+                                             gboolean create_if_needed,
+                                             gboolean find_if_needed,
+                                             guint permissions);

+Used to return well known directories such as Trash, Desktop, etc. from different +file systems. +

+There is quite a complicated logic behind finding/creating a Trash directory +and you need to be aware of some implications: +Finding the Trash the first time when using the file method may be pretty +expensive. A cache file is used to store the location of that Trash file +for next time. +If ceate_if_needed is specified without find_if_needed, you may end up +creating a Trash file when there already is one. Your app should start out +by doing a gnome_vfs_find_directory with the find_if_needed to avoid this +and then use the create_if_needed flag to create Trash lazily when it is +needed for throwing away an item on a given disk.

+ +

near_uri : find a well known directory on the same volume as near_uri +
kind : kind of well known directory +
result : newly created URI of the directory we found +
create_if_needed : If directory we are looking for does not exist, try to create it +
find_if_needed : If we don't know where trash is yet, look for it. +
permissions : If creating, use these permissions +
Returns : An integer representing the result of the operation +
diff --git a/doc/html/gnome-vfs-gnome-vfs-directory-list-ops.html b/doc/html/gnome-vfs-gnome-vfs-directory-list-ops.html new file mode 100644 index 0000000..89c8c3f --- /dev/null +++ b/doc/html/gnome-vfs-gnome-vfs-directory-list-ops.html @@ -0,0 +1,293 @@ + +Listing Directory Contents

+Listing Directory Contents

+Listing Directory Contents — +Listing the contents of directories.

Synopsis

+
+
+
+enum        GnomeVFSDirectoryVisitOptions;
+gboolean    (*GnomeVFSDirectoryVisitFunc)   (const gchar *rel_path,
+                                             GnomeVFSFileInfo *info,
+                                             gboolean recursing_will_loop,
+                                             gpointer data,
+                                             gboolean *recurse);
+GnomeVFSResult gnome_vfs_directory_open     (GnomeVFSDirectoryHandle **handle,
+                                             const gchar *text_uri,
+                                             GnomeVFSFileInfoOptions options);
+GnomeVFSResult gnome_vfs_directory_open_from_uri
+                                            (GnomeVFSDirectoryHandle **handle,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSFileInfoOptions options);
+GnomeVFSResult gnome_vfs_directory_read_next
+                                            (GnomeVFSDirectoryHandle *handle,
+                                             GnomeVFSFileInfo *file_info);
+GnomeVFSResult gnome_vfs_directory_close    (GnomeVFSDirectoryHandle *handle);
+GnomeVFSResult gnome_vfs_directory_visit    (const gchar *uri,
+                                             GnomeVFSFileInfoOptions info_options,
+                                             GnomeVFSDirectoryVisitOptions visit_options,
+                                             GnomeVFSDirectoryVisitFunc callback,
+                                             gpointer data);
+GnomeVFSResult gnome_vfs_directory_visit_uri
+                                            (GnomeVFSURI *uri,
+                                             GnomeVFSFileInfoOptions info_options,
+                                             GnomeVFSDirectoryVisitOptions visit_options,
+                                             GnomeVFSDirectoryVisitFunc callback,
+                                             gpointer data);
+GnomeVFSResult gnome_vfs_directory_visit_files
+                                            (const gchar *text_uri,
+                                             GList *file_list,
+                                             GnomeVFSFileInfoOptions info_options,
+                                             GnomeVFSDirectoryVisitOptions visit_options,
+                                             GnomeVFSDirectoryVisitFunc callback,
+                                             gpointer data);
+GnomeVFSResult gnome_vfs_directory_visit_files_at_uri
+                                            (GnomeVFSURI *uri,
+                                             GList *file_list,
+                                             GnomeVFSFileInfoOptions info_options,
+                                             GnomeVFSDirectoryVisitOptions visit_options,
+                                             GnomeVFSDirectoryVisitFunc callback,
+                                             gpointer data);
+GnomeVFSResult gnome_vfs_directory_list_load
+                                            (GList **list,
+                                             const gchar *text_uri,
+                                             GnomeVFSFileInfoOptions options);
+

Description

+ +

Details

enum GnomeVFSDirectoryVisitOptions

typedef enum {
+	GNOME_VFS_DIRECTORY_VISIT_DEFAULT = 0,
+	GNOME_VFS_DIRECTORY_VISIT_SAMEFS = 1 << 0,
+	GNOME_VFS_DIRECTORY_VISIT_LOOPCHECK = 1 << 1
+} GnomeVFSDirectoryVisitOptions;
+

+This options control the way in which directories are visited.

+ +

GNOME_VFS_DIRECTORY_VISIT_DEFAULT +
GNOME_VFS_DIRECTORY_VISIT_SAMEFS Visit only directories on the same +file system as the parent +
GNOME_VFS_DIRECTORY_VISIT_LOOPCHECK Loop prevention +

GnomeVFSDirectoryVisitFunc ()

gboolean    (*GnomeVFSDirectoryVisitFunc)   (const gchar *rel_path,
+                                             GnomeVFSFileInfo *info,
+                                             gboolean recursing_will_loop,
+                                             gpointer data,
+                                             gboolean *recurse);

+ +

rel_path : +
info : +
recursing_will_loop : +
data : +
recurse : +
Returns : + + +

gnome_vfs_directory_open ()

GnomeVFSResult gnome_vfs_directory_open     (GnomeVFSDirectoryHandle **handle,
+                                             const gchar *text_uri,
+                                             GnomeVFSFileInfoOptions options);

+Open directory text_uri for reading. On return, @*handle will point to +a GnomeVFSDirectoryHandle object which can be used to read the directory +entries one by one.

+ +

handle : A pointer to a pointer to a GnomeVFSDirectoryHandle object +
text_uri : String representing the URI to open +
options : Options for reading file information +
Returns : An integer representing the result of the operation +

gnome_vfs_directory_open_from_uri ()

GnomeVFSResult gnome_vfs_directory_open_from_uri
+                                            (GnomeVFSDirectoryHandle **handle,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSFileInfoOptions options);

+Open directory text_uri for reading. On return, @*handle will point to +a GnomeVFSDirectoryHandle object which can be used to read the directory +entries one by one.

+ +

handle : A pointer to a pointer to a GnomeVFSDirectoryHandle object +
uri : URI to open +
options : Options for reading file information +
Returns : An integer representing the result of the operation. +

gnome_vfs_directory_read_next ()

GnomeVFSResult gnome_vfs_directory_read_next
+                                            (GnomeVFSDirectoryHandle *handle,
+                                             GnomeVFSFileInfo *file_info);

+Read the next directory entry from handle.

+ +

handle : A directory handle +
file_info : Pointer to a GnomeVFSFileInfo struct where the data about +the entry will be stored +
Returns : An integer value representing the result of the operation. +

gnome_vfs_directory_close ()

GnomeVFSResult gnome_vfs_directory_close    (GnomeVFSDirectoryHandle *handle);

+Close handle.

+ +

handle : A directory handle. +
Returns : An integer representing the result of the operation. +

gnome_vfs_directory_visit ()

GnomeVFSResult gnome_vfs_directory_visit    (const gchar *uri,
+                                             GnomeVFSFileInfoOptions info_options,
+                                             GnomeVFSDirectoryVisitOptions visit_options,
+                                             GnomeVFSDirectoryVisitFunc callback,
+                                             gpointer data);

+Visit uri, retrieving information as specified by info_options.

+ +

uri : URI to start from +
info_options : Options specifying what kind of file information must be +retrieved +
visit_options : Options specifying the type of visit +
callback : Callback to be called for every visited file +
data : Data to be passed to callback at each iteration +
Returns : +

gnome_vfs_directory_visit_uri ()

GnomeVFSResult gnome_vfs_directory_visit_uri
+                                            (GnomeVFSURI *uri,
+                                             GnomeVFSFileInfoOptions info_options,
+                                             GnomeVFSDirectoryVisitOptions visit_options,
+                                             GnomeVFSDirectoryVisitFunc callback,
+                                             gpointer data);

+Visit uri, retrieving information as specified by info_options.

+ +

uri : URI to start from +
info_options : Options specifying what kind of file information must be +retrieved +
visit_options : Options specifying the type of visit +
callback : Callback to be called for every visited file +
data : Data to be passed to callback at each iteration +
Returns : A result code indicating whether the operation succeeded. + +

gnome_vfs_directory_visit_files ()

GnomeVFSResult gnome_vfs_directory_visit_files
+                                            (const gchar *text_uri,
+                                             GList *file_list,
+                                             GnomeVFSFileInfoOptions info_options,
+                                             GnomeVFSDirectoryVisitOptions visit_options,
+                                             GnomeVFSDirectoryVisitFunc callback,
+                                             gpointer data);

+Fetches information about a list of files in a base URI uri.

+ +

text_uri : string representing the URI of a directory to "visit" the files in +
file_list : GList of char *s of file names in uri to visit +
info_options : bitmask controlling the type of information to fetch +
visit_options : options controlling e.g. loop prevention, and filesystem checks. +Affects the way visiting is done. +
callback : function to call with the file info structs +
data : data to pass to callback. +
Returns : a GnomeVFSResult indication the success of the operation +

gnome_vfs_directory_visit_files_at_uri ()

GnomeVFSResult gnome_vfs_directory_visit_files_at_uri
+                                            (GnomeVFSURI *uri,
+                                             GList *file_list,
+                                             GnomeVFSFileInfoOptions info_options,
+                                             GnomeVFSDirectoryVisitOptions visit_options,
+                                             GnomeVFSDirectoryVisitFunc callback,
+                                             gpointer data);

+Fetches information about a list of files in a base URI uri.

+ +

uri : URI of a directory to "visit" the files in +
file_list : GList of char *s of file names in uri to visit +
info_options : bitmask controlling the type of information to fetch +
visit_options : options controlling e.g. loop prevention, and filesystem checks. +Affects the way visiting is done. +
callback : function to call with the file info structs +
data : data to pass to callback. +
Returns : a GnomeVFSResult indication the success of the operation +

gnome_vfs_directory_list_load ()

GnomeVFSResult gnome_vfs_directory_list_load
+                                            (GList **list,
+                                             const gchar *text_uri,
+                                             GnomeVFSFileInfoOptions options);

+Load a directory from text_uri with the specified options +into a list.

+ +

list : An address of a pointer to a list of GnomeVFSFileInfo +
text_uri : A text URI +
options : Options for loading the directory +
Returns : An integer representing the result of the operation. +
diff --git a/doc/html/gnome-vfs-gnome-vfs-directory.html b/doc/html/gnome-vfs-gnome-vfs-directory.html new file mode 100644 index 0000000..1b32228 --- /dev/null +++ b/doc/html/gnome-vfs-gnome-vfs-directory.html @@ -0,0 +1,2318 @@ +Directory Operations
GnomeVFS - Filesystem Abstraction library

Directory Operations

Name

Directory Operations -- reading the contents of directories

Synopsis


+
+enum        GnomeVFSDirectoryVisitOptions;
+gboolean    (*GnomeVFSDirectoryVisitFunc)   (const gchar *rel_path,
+                                             GnomeVFSFileInfo *info,
+                                             gboolean recursing_will_loop,
+                                             gpointer data,
+                                             gboolean *recurse);
+GnomeVFSResult gnome_vfs_directory_open     (GnomeVFSDirectoryHandle **handle,
+                                             const gchar *text_uri,
+                                             GnomeVFSFileInfoOptions options);
+GnomeVFSResult gnome_vfs_directory_open_from_uri
+                                            (GnomeVFSDirectoryHandle **handle,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSFileInfoOptions options);
+GnomeVFSResult gnome_vfs_directory_read_next
+                                            (GnomeVFSDirectoryHandle *handle,
+                                             GnomeVFSFileInfo *file_info);
+GnomeVFSResult gnome_vfs_directory_close    (GnomeVFSDirectoryHandle *handle);
+GnomeVFSResult gnome_vfs_directory_visit    (const gchar *uri,
+                                             GnomeVFSFileInfoOptions info_options,
+                                             GnomeVFSDirectoryVisitOptions visit_options,
+                                             GnomeVFSDirectoryVisitFunc callback,
+                                             gpointer data);
+GnomeVFSResult gnome_vfs_directory_visit_uri
+                                            (GnomeVFSURI *uri,
+                                             GnomeVFSFileInfoOptions info_options,
+                                             GnomeVFSDirectoryVisitOptions visit_options,
+                                             GnomeVFSDirectoryVisitFunc callback,
+                                             gpointer data);
+GnomeVFSResult gnome_vfs_directory_visit_files
+                                            (const gchar *text_uri,
+                                             GList *file_list,
+                                             GnomeVFSFileInfoOptions info_options,
+                                             GnomeVFSDirectoryVisitOptions visit_options,
+                                             GnomeVFSDirectoryVisitFunc callback,
+                                             gpointer data);
+GnomeVFSResult gnome_vfs_directory_visit_files_at_uri
+                                            (GnomeVFSURI *uri,
+                                             GList *file_list,
+                                             GnomeVFSFileInfoOptions info_options,
+                                             GnomeVFSDirectoryVisitOptions visit_options,
+                                             GnomeVFSDirectoryVisitFunc callback,
+                                             gpointer data);
+GnomeVFSResult gnome_vfs_directory_list_load
+                                            (GList **list,
+                                             const gchar *text_uri,
+                                             GnomeVFSFileInfoOptions options);
+GnomeVFSResult gnome_vfs_make_directory_for_uri
+                                            (GnomeVFSURI *uri,
+                                             guint perm);
+GnomeVFSResult gnome_vfs_make_directory     (const gchar *text_uri,
+                                             guint perm);
+GnomeVFSResult gnome_vfs_remove_directory_from_uri
+                                            (GnomeVFSURI *uri);
+GnomeVFSResult gnome_vfs_remove_directory   (const gchar *text_uri);

Description

Details

enum GnomeVFSDirectoryVisitOptions

typedef enum {
+	GNOME_VFS_DIRECTORY_VISIT_DEFAULT = 0,
+	GNOME_VFS_DIRECTORY_VISIT_SAMEFS = 1 << 0,
+	GNOME_VFS_DIRECTORY_VISIT_LOOPCHECK = 1 << 1
+} GnomeVFSDirectoryVisitOptions;


GnomeVFSDirectoryVisitFunc ()

gboolean    (*GnomeVFSDirectoryVisitFunc)   (const gchar *rel_path,
+                                             GnomeVFSFileInfo *info,
+                                             gboolean recursing_will_loop,
+                                             gpointer data,
+                                             gboolean *recurse);

rel_path :

info :

recursing_will_loop :

data :

recurse :

Returns :


gnome_vfs_directory_open ()

GnomeVFSResult gnome_vfs_directory_open     (GnomeVFSDirectoryHandle **handle,
+                                             const gchar *text_uri,
+                                             GnomeVFSFileInfoOptions options);

Open directory text_uri for reading. On return, @*handle will point to +a GnomeVFSDirectoryHandle object which can be used to read the directory +entries one by one.

handle :

A pointer to a pointer to a GnomeVFSDirectoryHandle object

text_uri :

String representing the URI to open

options :

Options for reading file information

Returns :

An integer representing the result of the operation


gnome_vfs_directory_open_from_uri ()

GnomeVFSResult gnome_vfs_directory_open_from_uri
+                                            (GnomeVFSDirectoryHandle **handle,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSFileInfoOptions options);

Open directory text_uri for reading. On return, @*handle will point to +a GnomeVFSDirectoryHandle object which can be used to read the directory +entries one by one.

handle :

A pointer to a pointer to a GnomeVFSDirectoryHandle object

uri :

URI to open

options :

Options for reading file information

Returns :

An integer representing the result of the operation.


gnome_vfs_directory_read_next ()

GnomeVFSResult gnome_vfs_directory_read_next
+                                            (GnomeVFSDirectoryHandle *handle,
+                                             GnomeVFSFileInfo *file_info);

Read the next directory entry from handle.

handle :

A directory handle

file_info :

Pointer to a GnomeVFSFileInfo struct where the data about +the entry will be stored

Returns :

An integer value representing the result of the operation.


gnome_vfs_directory_close ()

GnomeVFSResult gnome_vfs_directory_close    (GnomeVFSDirectoryHandle *handle);

Close handle.

handle :

A directory handle.

Returns :

An integer representing the result of the operation.


gnome_vfs_directory_visit ()

GnomeVFSResult gnome_vfs_directory_visit    (const gchar *uri,
+                                             GnomeVFSFileInfoOptions info_options,
+                                             GnomeVFSDirectoryVisitOptions visit_options,
+                                             GnomeVFSDirectoryVisitFunc callback,
+                                             gpointer data);

Visit uri, retrieving information as specified by info_options.

uri :

URI to start from

info_options :

Options specifying what kind of file information must be +retrieved

visit_options :

Options specifying the type of visit

callback :

Callback to be called for every visited file

data :

Data to be passed to callback at each iteration

Returns :


gnome_vfs_directory_visit_uri ()

GnomeVFSResult gnome_vfs_directory_visit_uri
+                                            (GnomeVFSURI *uri,
+                                             GnomeVFSFileInfoOptions info_options,
+                                             GnomeVFSDirectoryVisitOptions visit_options,
+                                             GnomeVFSDirectoryVisitFunc callback,
+                                             gpointer data);

Visit uri, retrieving information as specified by info_options.

uri :

URI to start from

info_options :

Options specifying what kind of file information must be +retrieved

visit_options :

Options specifying the type of visit

callback :

Callback to be called for every visited file

data :

Data to be passed to callback at each iteration

Returns :

A result code indicating whether the operation succeeded.


gnome_vfs_directory_visit_files ()

GnomeVFSResult gnome_vfs_directory_visit_files
+                                            (const gchar *text_uri,
+                                             GList *file_list,
+                                             GnomeVFSFileInfoOptions info_options,
+                                             GnomeVFSDirectoryVisitOptions visit_options,
+                                             GnomeVFSDirectoryVisitFunc callback,
+                                             gpointer data);

Fetches information about a list of files in a base URI uri.

text_uri :

string representing the URI of a directory to "visit" the files in

file_list :

GList of char *s of file names in uri to visit

info_options :

bitmask controlling the type of information to fetch

visit_options :

options controlling e.g. loop prevention, and filesystem checks. +Affects the way visiting is done.

callback :

function to call with the file info structs

data :

data to pass to callback.

Returns :

a GnomeVFSResult indication the success of the operation


gnome_vfs_directory_visit_files_at_uri ()

GnomeVFSResult gnome_vfs_directory_visit_files_at_uri
+                                            (GnomeVFSURI *uri,
+                                             GList *file_list,
+                                             GnomeVFSFileInfoOptions info_options,
+                                             GnomeVFSDirectoryVisitOptions visit_options,
+                                             GnomeVFSDirectoryVisitFunc callback,
+                                             gpointer data);

Fetches information about a list of files in a base URI uri.

uri :

URI of a directory to "visit" the files in

file_list :

GList of char *s of file names in uri to visit

info_options :

bitmask controlling the type of information to fetch

visit_options :

options controlling e.g. loop prevention, and filesystem checks. +Affects the way visiting is done.

callback :

function to call with the file info structs

data :

data to pass to callback.

Returns :

a GnomeVFSResult indication the success of the operation


gnome_vfs_directory_list_load ()

GnomeVFSResult gnome_vfs_directory_list_load
+                                            (GList **list,
+                                             const gchar *text_uri,
+                                             GnomeVFSFileInfoOptions options);

Load a directory from text_uri with the specified options +into a list.

list :

An address of a pointer to a list of GnomeVFSFileInfo

text_uri :

A text URI

options :

Options for loading the directory

Returns :

An integer representing the result of the operation.


gnome_vfs_make_directory_for_uri ()

GnomeVFSResult gnome_vfs_make_directory_for_uri
+                                            (GnomeVFSURI *uri,
+                                             guint perm);

Create a directory at uri. Only succeeds if a file or directory +does not already exist at uri.

uri :

URI of the directory to be created

perm :

Unix-style permissions for the newly created directory

Returns :

An integer representing the result of the operation


gnome_vfs_make_directory ()

GnomeVFSResult gnome_vfs_make_directory     (const gchar *text_uri,
+                                             guint perm);

Create text_uri as a directory.

text_uri :

URI of the directory to be created

perm :

Unix-style permissions for the newly created directory

Returns :

An integer representing the result of the operation


gnome_vfs_remove_directory_from_uri ()

GnomeVFSResult gnome_vfs_remove_directory_from_uri
+                                            (GnomeVFSURI *uri);

Remove uri. uri must be an empty directory.

uri :

URI of the directory to be removed

Returns :

An integer representing the result of the operation


gnome_vfs_remove_directory ()

GnomeVFSResult gnome_vfs_remove_directory   (const gchar *text_uri);

Remove text_uri. text_uri must be an empty directory.

text_uri :

URI of the directory to be removed

Returns :

An integer representing the result of the operation

<<< DirectoriesLocating Standard Directories >>>
\ No newline at end of file diff --git a/doc/html/gnome-vfs-gnome-vfs-file-advanced-ops.html b/doc/html/gnome-vfs-gnome-vfs-file-advanced-ops.html new file mode 100644 index 0000000..524247f --- /dev/null +++ b/doc/html/gnome-vfs-gnome-vfs-file-advanced-ops.html @@ -0,0 +1,59 @@ +Advanced File Operations

Advanced File Operations

Advanced File Operations —

Synopsis

+
+
+
+GnomeVFSResult gnome_vfs_file_control       (GnomeVFSHandle *handle,
+                                             const char *operation,
+                                             gpointer operation_data);
+

Description

+ +

Details

gnome_vfs_file_control ()

GnomeVFSResult gnome_vfs_file_control       (GnomeVFSHandle *handle,
+                                             const char *operation,
+                                             gpointer operation_data);

+Execute a backend dependent operation specified by the string operation. +This is typically used for specialized vfs backends that need additional +operations that gnome-vfs doesn't have. Compare it to the unix call ioctl(). +The format of operation_data depends on the operation. Operation that are +backend specific are normally namespaced by their module name.

+ +

handle : handle of the file to affect +
operation : The operation to execute +
operation_data : The data needed to execute the operation +
Returns : an integer representing the success of the operation +
diff --git a/doc/html/gnome-vfs-gnome-vfs-file-basic-ops.html b/doc/html/gnome-vfs-gnome-vfs-file-basic-ops.html new file mode 100644 index 0000000..e7da0f7 --- /dev/null +++ b/doc/html/gnome-vfs-gnome-vfs-file-basic-ops.html @@ -0,0 +1,278 @@ +Basic File Operations

Basic File Operations

Basic File Operations —

Synopsis

+
+
+
+enum        GnomeVFSOpenMode;
+GnomeVFSResult gnome_vfs_create             (GnomeVFSHandle **handle,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm);
+GnomeVFSResult gnome_vfs_create_uri         (GnomeVFSHandle **handle,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm);
+GnomeVFSResult gnome_vfs_open               (GnomeVFSHandle **handle,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode);
+GnomeVFSResult gnome_vfs_open_uri           (GnomeVFSHandle **handle,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode);
+GnomeVFSResult gnome_vfs_close              (GnomeVFSHandle *handle);
+GnomeVFSResult gnome_vfs_unlink             (const gchar *text_uri);
+GnomeVFSResult gnome_vfs_unlink_from_uri    (GnomeVFSURI *uri);
+GnomeVFSResult gnome_vfs_move_uri           (GnomeVFSURI *old_uri,
+                                             GnomeVFSURI *new_uri,
+                                             gboolean force_replace);
+GnomeVFSResult gnome_vfs_move               (const gchar *old_text_uri,
+                                             const gchar *new_text_uri,
+                                             gboolean force_replace);
+GnomeVFSResult gnome_vfs_check_same_fs_uris (GnomeVFSURI *source_uri,
+                                             GnomeVFSURI *target_uri,
+                                             gboolean *same_fs_return);
+GnomeVFSResult gnome_vfs_check_same_fs      (const gchar *source,
+                                             const gchar *target,
+                                             gboolean *same_fs_return);
+gboolean    gnome_vfs_uri_exists            (GnomeVFSURI *uri);
+GnomeVFSResult gnome_vfs_create_symbolic_link
+                                            (GnomeVFSURI *uri,
+                                             const gchar *target_reference);
+

Description

+ +

Details

enum GnomeVFSOpenMode

typedef enum {
+        GNOME_VFS_OPEN_NONE = 0,
+        GNOME_VFS_OPEN_READ = 1 << 0,
+        GNOME_VFS_OPEN_WRITE = 1 << 1,
+        GNOME_VFS_OPEN_RANDOM = 1 << 2
+} GnomeVFSOpenMode;
+

+Mode in which files are opened. If GNOME_VFS_OPEN_RANDOM is not used, the +file will be have to be accessed sequentially.

+ +


gnome_vfs_create ()

GnomeVFSResult gnome_vfs_create             (GnomeVFSHandle **handle,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm);

+Create uri according to mode open_mode. On return, handle will then +contain a pointer to a handle for the open file.

+ +

handle : A pointer to a pointer to a GnomeVFSHandle object +
text_uri : String representing the URI to create +
open_mode : mode to leave the file opened in after creation (or GNOME_VFS_OPEN_MODE_NONE +to leave the file closed after creation) +
exclusive : Whether the file should be created in "exclusive" mode: +i.e. if this flag is nonzero, operation will fail if a file with the +same name already exists. +
perm : Bitmap representing the permissions for the newly created file +(Unix style). +
Returns : An integer representing the result of the operation +

gnome_vfs_create_uri ()

GnomeVFSResult gnome_vfs_create_uri         (GnomeVFSHandle **handle,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm);

+Create uri according to mode open_mode. On return, handle will then +contain a pointer to a handle for the open file.

+ +

handle : A pointer to a pointer to a GnomeVFSHandle object +
uri : URI for the file to create +
open_mode : Open mode +
exclusive : Whether the file should be created in "exclusive" mode: +i.e. if this flag is nonzero, operation will fail if a file with the +same name already exists. +
perm : Bitmap representing the permissions for the newly created file +(Unix style). +
Returns : An integer representing the result of the operation +

gnome_vfs_open ()

GnomeVFSResult gnome_vfs_open               (GnomeVFSHandle **handle,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode);

+Open text_uri according to mode open_mode. On return, handle will then +contain a pointer to a handle for the open file.

+ +

handle : A pointer to a pointer to a GnomeVFSHandle object +
text_uri : String representing the URI to open +
open_mode : Open mode +
Returns : An integer representing the result of the operation +

gnome_vfs_open_uri ()

GnomeVFSResult gnome_vfs_open_uri           (GnomeVFSHandle **handle,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode);

+Open uri according to mode open_mode. On return, handle will then +contain a pointer to a handle for the open file.

+ +

handle : A pointer to a pointer to a GnomeVFSHandle object +
uri : URI to open +
open_mode : Open mode +
Returns : An integer representing the result of the operation +

gnome_vfs_close ()

GnomeVFSResult gnome_vfs_close              (GnomeVFSHandle *handle);

+Close file associated with handle.

+ +

handle : A pointer to a GnomeVFSHandle object +
Returns : An integer representing the result of the operation. +

gnome_vfs_unlink ()

GnomeVFSResult gnome_vfs_unlink             (const gchar *text_uri);

+Unlink text_uri (i.e. delete the file).

+ +

text_uri : URI of the file to be unlinked +
Returns : An integer representing the result of the operation +

gnome_vfs_unlink_from_uri ()

GnomeVFSResult gnome_vfs_unlink_from_uri    (GnomeVFSURI *uri);

+Unlink uri (i.e. delete the file).

+ +

uri : URI of the file to be unlinked +
Returns : An integer representing the result of the operation +

gnome_vfs_move_uri ()

GnomeVFSResult gnome_vfs_move_uri           (GnomeVFSURI *old_uri,
+                                             GnomeVFSURI *new_uri,
+                                             gboolean force_replace);

+Move a file from URI old_uri to new_uri. This will only work if old_uri +and new_uri are on the same file system. Otherwise, it is necessary +to use the more general %gnome_vfs_xfer_uri() function.

+ +

old_uri : Source URI +
new_uri : Destination URI +
force_replace : If TRUE, move target to new_uri even if there +is already a file at new_uri. If there is a file, it will be discarded. +
Returns : An integer representing the result of the operation. +

gnome_vfs_move ()

GnomeVFSResult gnome_vfs_move               (const gchar *old_text_uri,
+                                             const gchar *new_text_uri,
+                                             gboolean force_replace);

+Move a file from URI old_text_uri to new_text_uri. This will only work +if old_text_uri and new_text_uri are on the same file system. Otherwise, +it is necessary to use the more general %gnome_vfs_xfer_uri() function.

+ +

old_text_uri : Source URI +
new_text_uri : Destination URI +
force_replace : if TRUE, perform the operation even if it unlinks an existing +file at new_text_uri +
Returns : An integer representing the result of the operation. +

gnome_vfs_check_same_fs_uris ()

GnomeVFSResult gnome_vfs_check_same_fs_uris (GnomeVFSURI *source_uri,
+                                             GnomeVFSURI *target_uri,
+                                             gboolean *same_fs_return);

+Check if source_uri and target_uri are on the same file system.

+ +

source_uri : A URI +
target_uri : Another URI +
same_fs_return : Pointer to a boolean variable which will be set to TRUE +if source_uri and target_uri are on the same file system on return. +
Returns : An integer representing the result of the operation. +

gnome_vfs_check_same_fs ()

GnomeVFSResult gnome_vfs_check_same_fs      (const gchar *source,
+                                             const gchar *target,
+                                             gboolean *same_fs_return);

+Return TRUE if source and target are on the same file system.

+ +

source : A URI +
target : Another URI +
same_fs_return : Pointer to a boolean variable which will be set to TRUE +
Returns : An integer representing the result of the operation. +

gnome_vfs_uri_exists ()

gboolean    gnome_vfs_uri_exists            (GnomeVFSURI *uri);

+Check if the URI points to an existing entity.

+ +

uri : A URI +
Returns : TRUE if URI exists. +

gnome_vfs_create_symbolic_link ()

GnomeVFSResult gnome_vfs_create_symbolic_link
+                                            (GnomeVFSURI *uri,
+                                             const gchar *target_reference);

+Creates a symbolic link, or eventually, a URI link (as necessary) +at uri pointing to target_reference

+ +

uri : URI to create a link at +
target_reference : URI "reference" to point the link to (URI or relative path) +
Returns : An integer representing the result of the operation +
diff --git a/doc/html/gnome-vfs-gnome-vfs-file-info-ops.html b/doc/html/gnome-vfs-gnome-vfs-file-info-ops.html new file mode 100644 index 0000000..5756460 --- /dev/null +++ b/doc/html/gnome-vfs-gnome-vfs-file-info-ops.html @@ -0,0 +1,130 @@ +Getting and Setting File Information

Getting and Setting File Information

Getting and Setting File Information —

Description

+ Applications can use the gnome_vfs_get_file_info family of operations to + retrieve file information, as this operation can be quite costly in + terms of time (specilly when sniffing the MIME type) applications can + specify which information need at any time, reducing the performance + impact. +

+ All of these operations use a GnomeVFSFileInfo data structure that holds + the file information, there are several methods that can be used to + manipulate this information. See GnomeVFSFileInfo for more information. +

Details

gnome_vfs_get_file_info ()

GnomeVFSResult gnome_vfs_get_file_info      (const gchar *text_uri,
+                                             GnomeVFSFileInfo *info,
+                                             GnomeVFSFileInfoOptions options);

+Retrieve information about text_uri. The information will be stored in +info.

+ +

text_uri : URI of the file for which information will be retrieved +
info : Pointer to a GnomeVFSFileInfo object that will hold the information +for the file on return +
options : Options for retrieving file information +to retrieve for the file +
Returns : An integer representing the result of the operation +

gnome_vfs_get_file_info_uri ()

GnomeVFSResult gnome_vfs_get_file_info_uri  (GnomeVFSURI *uri,
+                                             GnomeVFSFileInfo *info,
+                                             GnomeVFSFileInfoOptions options);

+Retrieve information about text_uri. The information will be stored in +info.

+ +

uri : URI of the file for which information will be retrieved +
info : Pointer to a GnomeVFSFileInfo object that will hold the information +for the file on return +
options : Options for retrieving file information +to retrieve for the file +
Returns : An integer representing the result of the operation +

gnome_vfs_get_file_info_from_handle ()

GnomeVFSResult gnome_vfs_get_file_info_from_handle
+                                            (GnomeVFSHandle *handle,
+                                             GnomeVFSFileInfo *info,
+                                             GnomeVFSFileInfoOptions options);

+Retrieve information about an open file. The information will be stored in +info.

+ +

handle : Handle of the file for which information must be retrieved +
info : Pointer to a GnomeVFSFileInfo object that will hold the information +for the file on return +
options : Options for retrieving file information +to retrieve for the file +
Returns : An integer representing the result of the operation +

gnome_vfs_set_file_info_uri ()

GnomeVFSResult gnome_vfs_set_file_info_uri  (GnomeVFSURI *uri,
+                                             GnomeVFSFileInfo *info,
+                                             GnomeVFSSetFileInfoMask mask);

+Set file information for uri; only the information for which the +corresponding bit in mask is set is actually modified.

+ +

uri : A URI +
info : Information that must be set for the file +
mask : Bit mask representing which fields of info need to be set +
Returns : An integer representing the result of the operation. +

gnome_vfs_set_file_info ()

GnomeVFSResult gnome_vfs_set_file_info      (const gchar *text_uri,
+                                             GnomeVFSFileInfo *info,
+                                             GnomeVFSSetFileInfoMask mask);

+Set file information for uri; only the information for which the +corresponding bit in mask is set is actually modified.

+ +

text_uri : A URI +
info : Information that must be set for the file +
mask : Bit mask representing which fields of info need to be set +
Returns : An integer representing the result of the operation. +

See Also

+ +

+ +

diff --git a/doc/html/gnome-vfs-gnome-vfs-file-info.html b/doc/html/gnome-vfs-gnome-vfs-file-info.html new file mode 100644 index 0000000..f35c051 --- /dev/null +++ b/doc/html/gnome-vfs-gnome-vfs-file-info.html @@ -0,0 +1,443 @@ + +GnomeVFSFileInfo

+GnomeVFSFileInfo

+GnomeVFSFileInfo — +stores information about files, GnomeVFS equivalent of stat

Synopsis

+
+
+
+enum        GnomeVFSFileFlags;
+enum        GnomeVFSFileType;
+enum        GnomeVFSFileInfoFields;
+enum        GnomeVFSFilePermissions;
+enum        GnomeVFSFileInfoOptions;
+enum        GnomeVFSSetFileInfoMask;
+typedef     GnomeVFSGetFileInfoResult;
+typedef     GnomeVFSInodeNumber;
+typedef     GnomeVFSFileInfo;
+#define     GNOME_VFS_FILE_INFO_SYMLINK     (info)
+#define     GNOME_VFS_FILE_INFO_SET_SYMLINK (info, value)
+#define     GNOME_VFS_FILE_INFO_LOCAL       (info)
+#define     GNOME_VFS_FILE_INFO_SET_LOCAL   (info, value)
+#define     GNOME_VFS_FILE_INFO_SUID        (info)
+#define     GNOME_VFS_FILE_INFO_SGID        (info)
+#define     GNOME_VFS_FILE_INFO_STICKY      (info)
+#define     GNOME_VFS_FILE_INFO_SET_SUID    (info, value)
+#define     GNOME_VFS_FILE_INFO_SET_SGID    (info, value)
+#define     GNOME_VFS_FILE_INFO_SET_STICKY  (info, value)
+GnomeVFSFileInfo* gnome_vfs_file_info_new   (void);
+void        gnome_vfs_file_info_unref       (GnomeVFSFileInfo *info);
+void        gnome_vfs_file_info_ref         (GnomeVFSFileInfo *info);
+void        gnome_vfs_file_info_clear       (GnomeVFSFileInfo *info);
+const char* gnome_vfs_file_info_get_mime_type
+                                            (GnomeVFSFileInfo *info);
+void        gnome_vfs_file_info_copy        (GnomeVFSFileInfo *dest,
+                                             const GnomeVFSFileInfo *src);
+GnomeVFSFileInfo* gnome_vfs_file_info_dup   (const GnomeVFSFileInfo *orig);
+gboolean    gnome_vfs_file_info_matches     (const GnomeVFSFileInfo *a,
+                                             const GnomeVFSFileInfo *b);
+GList*      gnome_vfs_file_info_list_ref    (GList *list);
+GList*      gnome_vfs_file_info_list_unref  (GList *list);
+GList*      gnome_vfs_file_info_list_copy   (GList *list);
+void        gnome_vfs_file_info_list_free   (GList *list);
+

Description

+ +

Details

enum GnomeVFSFileFlags

typedef enum {
+	GNOME_VFS_FILE_FLAGS_NONE = 0,
+	GNOME_VFS_FILE_FLAGS_SYMLINK = 1 << 0,
+	GNOME_VFS_FILE_FLAGS_LOCAL = 1 << 1
+} GnomeVFSFileFlags;
+

+Packed boolean bitfield representing special +flags a GnomeVFSFileInfo struct can have.

+ +

GNOME_VFS_FILE_FLAGS_NONE no flags +
GNOME_VFS_FILE_FLAGS_SYMLINK whether the file is a symlink. +
GNOME_VFS_FILE_FLAGS_LOCAL whether the file is on a local filesystem +

enum GnomeVFSFileType

typedef enum {
+	GNOME_VFS_FILE_TYPE_UNKNOWN,
+	GNOME_VFS_FILE_TYPE_REGULAR,
+	GNOME_VFS_FILE_TYPE_DIRECTORY,
+	GNOME_VFS_FILE_TYPE_FIFO,
+	GNOME_VFS_FILE_TYPE_SOCKET,
+	GNOME_VFS_FILE_TYPE_CHARACTER_DEVICE,
+	GNOME_VFS_FILE_TYPE_BLOCK_DEVICE,
+	GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK
+} GnomeVFSFileType;
+

+Identifies the kind of file represented by a GnomeVFSFileInfo struct. (note, +use of MIME types is preferred as this field may eventually disappear)

+ +


enum GnomeVFSFileInfoFields

typedef enum {
+	GNOME_VFS_FILE_INFO_FIELDS_NONE = 0,
+	GNOME_VFS_FILE_INFO_FIELDS_TYPE = 1 << 0,
+	GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS = 1 << 1,
+	GNOME_VFS_FILE_INFO_FIELDS_FLAGS = 1 << 2,
+	GNOME_VFS_FILE_INFO_FIELDS_DEVICE = 1 << 3,
+	GNOME_VFS_FILE_INFO_FIELDS_INODE = 1 << 4,
+	GNOME_VFS_FILE_INFO_FIELDS_LINK_COUNT = 1 << 5,
+	GNOME_VFS_FILE_INFO_FIELDS_SIZE = 1 << 6,
+	GNOME_VFS_FILE_INFO_FIELDS_BLOCK_COUNT = 1 << 7,
+	GNOME_VFS_FILE_INFO_FIELDS_IO_BLOCK_SIZE = 1 << 8,
+	GNOME_VFS_FILE_INFO_FIELDS_ATIME = 1 << 9,
+	GNOME_VFS_FILE_INFO_FIELDS_MTIME = 1 << 10,
+	GNOME_VFS_FILE_INFO_FIELDS_CTIME = 1 << 11,
+	GNOME_VFS_FILE_INFO_FIELDS_SYMLINK_NAME = 1 << 12,
+	GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE = 1 << 13,
+	GNOME_VFS_FILE_INFO_FIELDS_ACCESS = 1 << 14
+} GnomeVFSFileInfoFields;
+

+Flags indicating what fields in a GnomeVFSFileInfo struct are valid. +Name is always assumed valid (how else would you have gotten a +FileInfo struct otherwise?)

+ +

GNOME_VFS_FILE_INFO_FIELDS_NONE No fields are valid +
GNOME_VFS_FILE_INFO_FIELDS_TYPE Type field is valid +
GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS Permissions field is valid +
GNOME_VFS_FILE_INFO_FIELDS_FLAGS Flags field is valid +
GNOME_VFS_FILE_INFO_FIELDS_DEVICE Device field is valid +
GNOME_VFS_FILE_INFO_FIELDS_INODE Inode field is valid +
GNOME_VFS_FILE_INFO_FIELDS_LINK_COUNT Link count field is valid +
GNOME_VFS_FILE_INFO_FIELDS_SIZE Size field is valid +
GNOME_VFS_FILE_INFO_FIELDS_BLOCK_COUNT Block count field is valid +
GNOME_VFS_FILE_INFO_FIELDS_IO_BLOCK_SIZE I/O Block Size field is valid +
GNOME_VFS_FILE_INFO_FIELDS_ATIME Access time field is valid +
GNOME_VFS_FILE_INFO_FIELDS_MTIME Modification time field is valid +
GNOME_VFS_FILE_INFO_FIELDS_CTIME Creating time field is valid +
GNOME_VFS_FILE_INFO_FIELDS_SYMLINK_NAME Symlink name field is valid +
GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE Mime type field is valid +
GNOME_VFS_FILE_INFO_FIELDS_ACCESS Access bits of the permissions +bitfield are valid +

enum GnomeVFSFilePermissions

typedef enum {
+	GNOME_VFS_PERM_SUID = S_ISUID,
+	GNOME_VFS_PERM_SGID = S_ISGID,	
+	GNOME_VFS_PERM_STICKY = 01000,	/* S_ISVTX not defined on all systems */
+	GNOME_VFS_PERM_USER_READ = S_IRUSR,
+	GNOME_VFS_PERM_USER_WRITE = S_IWUSR,
+	GNOME_VFS_PERM_USER_EXEC = S_IXUSR,
+	GNOME_VFS_PERM_USER_ALL = S_IRUSR | S_IWUSR | S_IXUSR,
+	GNOME_VFS_PERM_GROUP_READ = S_IRGRP,
+	GNOME_VFS_PERM_GROUP_WRITE = S_IWGRP,
+	GNOME_VFS_PERM_GROUP_EXEC = S_IXGRP,
+	GNOME_VFS_PERM_GROUP_ALL = S_IRGRP | S_IWGRP | S_IXGRP,
+	GNOME_VFS_PERM_OTHER_READ = S_IROTH,
+	GNOME_VFS_PERM_OTHER_WRITE = S_IWOTH,
+	GNOME_VFS_PERM_OTHER_EXEC = S_IXOTH,
+	GNOME_VFS_PERM_OTHER_ALL = S_IROTH | S_IWOTH | S_IXOTH,
+	GNOME_VFS_PERM_ACCESS_READABLE   = 1 << 16,
+	GNOME_VFS_PERM_ACCESS_WRITABLE   = 1 << 17,
+	GNOME_VFS_PERM_ACCESS_EXECUTABLE = 1 << 18
+} GnomeVFSFilePermissions;
+

+File permissions. These are the same as the Unix ones, but we wrap them +into a nicer VFS-like enum.

+ +

GNOME_VFS_PERM_SUID UID bit +
GNOME_VFS_PERM_SGID GID bit +
GNOME_VFS_PERM_STICKY Sticky bit. +
GNOME_VFS_PERM_USER_READ Owner has read permission +
GNOME_VFS_PERM_USER_WRITE Owner has write permission +
GNOME_VFS_PERM_USER_EXEC Owner has execution permission +
GNOME_VFS_PERM_USER_ALL Owner has all permissions +
GNOME_VFS_PERM_GROUP_READ Group has read permission +
GNOME_VFS_PERM_GROUP_WRITE Group has write permission +
GNOME_VFS_PERM_GROUP_EXEC Group has execution permission +
GNOME_VFS_PERM_GROUP_ALL Group has all permissions +
GNOME_VFS_PERM_OTHER_READ Others have read permission +
GNOME_VFS_PERM_OTHER_WRITE Others have write permission +
GNOME_VFS_PERM_OTHER_EXEC Others have execution permission +
GNOME_VFS_PERM_OTHER_ALL Others have all permissions +
GNOME_VFS_PERM_ACCESS_READABLE +
GNOME_VFS_PERM_ACCESS_WRITABLE +
GNOME_VFS_PERM_ACCESS_EXECUTABLE +

enum GnomeVFSFileInfoOptions

typedef enum {
+	GNOME_VFS_FILE_INFO_DEFAULT = 0,
+	GNOME_VFS_FILE_INFO_GET_MIME_TYPE = 1 << 0,
+	GNOME_VFS_FILE_INFO_FORCE_FAST_MIME_TYPE = 1 << 1,
+	GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE = 1 << 2,
+	GNOME_VFS_FILE_INFO_FOLLOW_LINKS = 1 << 3,
+	GNOME_VFS_FILE_INFO_GET_ACCESS_RIGHTS = 1 << 4
+} GnomeVFSFileInfoOptions;
+

+Packed boolean bitfield representing options that can +be passed into a gnome_vfs_get_file_info() call (or other +related calls that return file info) and affect the operation +of get_file_info.

+ +

GNOME_VFS_FILE_INFO_DEFAULT default flags +
GNOME_VFS_FILE_INFO_GET_MIME_TYPE detect the MIME type +
GNOME_VFS_FILE_INFO_FORCE_FAST_MIME_TYPE only use fast MIME type +detection (extensions) +
GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE force slow MIME type +detection where available (sniffing, algorithmic detection, etc) +
GNOME_VFS_FILE_INFO_FOLLOW_LINKS automatically follow symbolic +links and retrieve the properties of their target (recommended) +
GNOME_VFS_FILE_INFO_GET_ACCESS_RIGHTS tries to get data similar +to what would return access(2) on a local file system (ie is the +file readable, writable and/or executable). Can be really slow on +remote file systems +

enum GnomeVFSSetFileInfoMask

typedef enum {
+	GNOME_VFS_SET_FILE_INFO_NONE = 0,
+	GNOME_VFS_SET_FILE_INFO_NAME = 1 << 0,
+	GNOME_VFS_SET_FILE_INFO_PERMISSIONS = 1 << 1,
+	GNOME_VFS_SET_FILE_INFO_OWNER = 1 << 2,
+	GNOME_VFS_SET_FILE_INFO_TIME = 1 << 3
+} GnomeVFSSetFileInfoMask;
+

+Packed boolean bitfield representing the aspects of the file +to be changed in a gnome_vfs_set_file_info() call.

+ +

GNOME_VFS_SET_FILE_INFO_NONE don't set any file info fields +
GNOME_VFS_SET_FILE_INFO_NAME change the name +
GNOME_VFS_SET_FILE_INFO_PERMISSIONS change the permissions +
GNOME_VFS_SET_FILE_INFO_OWNER change the file's owner +
GNOME_VFS_SET_FILE_INFO_TIME change the file's time stamp(s) +

GnomeVFSGetFileInfoResult

typedef struct {
+	GnomeVFSURI *uri;
+	GnomeVFSResult result;
+	GnomeVFSFileInfo *file_info;
+} GnomeVFSGetFileInfoResult;
+

+ +


GnomeVFSInodeNumber

typedef GnomeVFSFileSize GnomeVFSInodeNumber;
+

+Represents the i-node of a file, this is a low level data structure +that the operating system uses to hold information about a file.

+ +


GnomeVFSFileInfo

typedef struct {
+	/* Base name of the file (no path).  */
+	char *name;
+
+	/* Fields which are actually valid in this structure. */
+	GnomeVFSFileInfoFields valid_fields;
+
+	/* File type (i.e. regular, directory, block device...).  */
+	GnomeVFSFileType type;
+
+	/* File permissions.  */
+	GnomeVFSFilePermissions permissions;
+
+	/* Flags for this file.  */
+	GnomeVFSFileFlags flags;
+
+	/* These are only valid if `is_local' is TRUE (see below).  */
+	dev_t device;
+	GnomeVFSInodeNumber inode;
+
+	/* Link count.  */
+	guint link_count;
+
+	/* UID, GID.  */
+	guint uid;
+	guint gid;
+
+	/* Size in bytes.  */
+	GnomeVFSFileSize size;
+
+	/* Size measured in units of 512-byte blocks.  */
+	GnomeVFSFileSize block_count;
+
+	/* Optimal buffer size for reading/writing the file.  */
+	guint io_block_size;
+
+	/* Access, modification and change times.  */
+	time_t atime;
+	time_t mtime;
+	time_t ctime;
+
+	/* If the file is a symlink (see `flags'), this specifies the file the
+           link points to.  */
+	char *symlink_name;
+
+	/* MIME type.  */
+	char *mime_type;
+
+	guint refcount;
+
+	/* Reserved for future expansions to GnomeVFSFileInfo without having
+	   to break ABI compatibility */
+	void *reserved1;
+	void *reserved2;
+	void *reserved3;
+	void *reserved4;
+	void *reserved5;
+} GnomeVFSFileInfo;
+

+The GnomeVFSFileInfo structure contains information about a file.

+ +


GNOME_VFS_FILE_INFO_SYMLINK()

#define     GNOME_VFS_FILE_INFO_SYMLINK(info)

+Determines whether a file is a symbolic link given info.

+ +

info : GnomeVFSFileInfo struct +

GNOME_VFS_FILE_INFO_SET_SYMLINK()

#define     GNOME_VFS_FILE_INFO_SET_SYMLINK(info, value)

+Set the symbolic link field in info to value.

+ +

info : GnomeVFSFileInfo struct +
value : if TRUE, info is set to indicate the file is a symbolic link +

GNOME_VFS_FILE_INFO_LOCAL()

#define     GNOME_VFS_FILE_INFO_LOCAL(info)

+Determines whether a file is local given info.

+ +

info : GnomeVFSFileInfo struct +

GNOME_VFS_FILE_INFO_SET_LOCAL()

#define     GNOME_VFS_FILE_INFO_SET_LOCAL(info, value)

+Set the "local file" field in info to value.

+ +

info : GnomeVFSFileInfo struct +
value : if TRUE, info is set to indicate the file is local +

GNOME_VFS_FILE_INFO_SUID()

#define     GNOME_VFS_FILE_INFO_SUID(info)

+Determines whether a file belongs to the super user.

+ +

info : GnomeVFSFileInfo struct +

GNOME_VFS_FILE_INFO_SGID()

#define     GNOME_VFS_FILE_INFO_SGID(info)

+Determines whether a file belongs to the super user's group.

+ +

info : GnomeVFSFileInfo struct +

GNOME_VFS_FILE_INFO_STICKY()

#define     GNOME_VFS_FILE_INFO_STICKY(info)

+Determines whether a file has the sticky bit set, given info

+ +

info : GnomeVFSFileInfo struct +

GNOME_VFS_FILE_INFO_SET_SUID()

#define     GNOME_VFS_FILE_INFO_SET_SUID(info, value)

+Set the SUID field in info to value.

+ +

info : GnomeVFSFileInfo struct +
value : if TRUE, info is set to indicate the file belongs to the super user +

GNOME_VFS_FILE_INFO_SET_SGID()

#define     GNOME_VFS_FILE_INFO_SET_SGID(info, value)

+Set the SGID field in info to value.

+ +

info : GnomeVFSFileInfo struct +
value : if TRUE, info is set to indicate the file belongs to the super user's group +

GNOME_VFS_FILE_INFO_SET_STICKY()

#define     GNOME_VFS_FILE_INFO_SET_STICKY(info, value)

+Set the sticky bit in info to value.

+ +

info : GnomeVFSFileInfo struct +
value : if TRUE, info is set to indicate the file has the sticky bit set +

gnome_vfs_file_info_new ()

GnomeVFSFileInfo* gnome_vfs_file_info_new   (void);

+Allocate and initialize a new file information struct.

+ +

Returns : A pointer to the new file information struct. +

gnome_vfs_file_info_unref ()

void        gnome_vfs_file_info_unref       (GnomeVFSFileInfo *info);

+Destroy info

+ +

info : Pointer to a file information struct +

gnome_vfs_file_info_ref ()

void        gnome_vfs_file_info_ref         (GnomeVFSFileInfo *info);

+Increment reference count

+ +

info : Pointer to a file information struct +

gnome_vfs_file_info_clear ()

void        gnome_vfs_file_info_clear       (GnomeVFSFileInfo *info);

+Clear info so that it's ready to accept new data. This is +supposed to be used when info already contains meaningful information which +we want to replace.

+ +

info : Pointer to a file information struct +

gnome_vfs_file_info_get_mime_type ()

const char* gnome_vfs_file_info_get_mime_type
+                                            (GnomeVFSFileInfo *info);

+Retrieve MIME type from info. There is no need to free the return +value.

+ +

info : A pointer to a file information struct +
Returns : A pointer to a string representing the MIME type. +

gnome_vfs_file_info_copy ()

void        gnome_vfs_file_info_copy        (GnomeVFSFileInfo *dest,
+                                             const GnomeVFSFileInfo *src);

+Copy information from src into dest.

+ +

dest : Pointer to a struct to copy src's information into +
src : Pointer to the information to be copied into dest +

gnome_vfs_file_info_dup ()

GnomeVFSFileInfo* gnome_vfs_file_info_dup   (const GnomeVFSFileInfo *orig);

+Duplicates orig and returns it.

+ +

orig : Pointer to a file information structure to duplicate +
Returns : a new file information struct that duplicates the information in orig. +

gnome_vfs_file_info_matches ()

gboolean    gnome_vfs_file_info_matches     (const GnomeVFSFileInfo *a,
+                                             const GnomeVFSFileInfo *b);

+Compare the two file info structs, return TRUE if they match.

+ +

a : first GnomeVFSFileInfo struct to compare +
b : second GnomeVFSFileInfo struct to compare +
Returns : TRUE if the two GnomeVFSFileInfos match, otherwise return FALSE. +

gnome_vfs_file_info_list_ref ()

GList*      gnome_vfs_file_info_list_ref    (GList *list);

+Increments the reference count of the items in list by one.

+ +

list : list of GnomeVFSFileInfo elements +
Returns : list +

gnome_vfs_file_info_list_unref ()

GList*      gnome_vfs_file_info_list_unref  (GList *list);

+Decrements the reference count of the items in list by one. +Note that the list is *not freed* even if each member of the list +is freed.

+ +

list : list of GnomeVFSFileInfo elements +
Returns : list +

gnome_vfs_file_info_list_copy ()

GList*      gnome_vfs_file_info_list_copy   (GList *list);

+Creates a duplicate of list, and references each member of +that list.

+ +

list : list of GnomeVFSFileInfo elements +
Returns : a newly referenced duplicate of list +

gnome_vfs_file_info_list_free ()

void        gnome_vfs_file_info_list_free   (GList *list);

+Decrements the reference count of each member of list by one, +and frees the list itself.

+ +

list : list of GnomeVFSFileInfo elements +
diff --git a/doc/html/gnome-vfs-gnome-vfs-file-rw-ops.html b/doc/html/gnome-vfs-gnome-vfs-file-rw-ops.html new file mode 100644 index 0000000..f714d0e --- /dev/null +++ b/doc/html/gnome-vfs-gnome-vfs-file-rw-ops.html @@ -0,0 +1,118 @@ +Reading and Writing

Reading and Writing

Reading and Writing —

Synopsis

+
+
+
+enum        GnomeVFSSeekPosition;
+GnomeVFSResult gnome_vfs_read               (GnomeVFSHandle *handle,
+                                             gpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_read);
+GnomeVFSResult gnome_vfs_write              (GnomeVFSHandle *handle,
+                                             gconstpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_written);
+GnomeVFSResult gnome_vfs_seek               (GnomeVFSHandle *handle,
+                                             GnomeVFSSeekPosition whence,
+                                             GnomeVFSFileOffset offset);
+GnomeVFSResult gnome_vfs_tell               (GnomeVFSHandle *handle,
+                                             GnomeVFSFileSize *offset_return);
+

Description

+ Reading and writing operations are explained, also gnome_vfs_seek, which + is used to move the file pointer inside the file. +

Details

enum GnomeVFSSeekPosition

typedef enum {
+        GNOME_VFS_SEEK_START,
+        GNOME_VFS_SEEK_CURRENT,
+        GNOME_VFS_SEEK_END
+} GnomeVFSSeekPosition;
+

+This is used to specify the start position for seek operations.

+ +

GNOME_VFS_SEEK_START Start of the file. +
GNOME_VFS_SEEK_CURRENT Current position. +
GNOME_VFS_SEEK_END End of the file. +

gnome_vfs_read ()

GnomeVFSResult gnome_vfs_read               (GnomeVFSHandle *handle,
+                                             gpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_read);

+Read bytes from handle. As with Unix system calls, the number of +bytes read can effectively be less than bytes on return and will be +stored in bytes_read.

+ +

handle : Handle of the file to read data from +
buffer : Pointer to a buffer that must be at least bytes bytes large +
bytes : Number of bytes to read +
bytes_read : Pointer to a variable that will hold the number of bytes +effectively read on return. +
Returns : An integer representing the result of the operation +

gnome_vfs_write ()

GnomeVFSResult gnome_vfs_write              (GnomeVFSHandle *handle,
+                                             gconstpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_written);

+Write bytes into the file opened through handle. As with Unix system +calls, the number of bytes written can effectively be less than bytes on +return and will be stored in bytes_written.

+ +

handle : Handle of the file to write data to +
buffer : Pointer to the buffer containing the data to be written +
bytes : Number of bytes to write +
bytes_written : Pointer to a variable that will hold the number of bytes +effectively written on return. +
Returns : An integer representing the result of the operation +

gnome_vfs_seek ()

GnomeVFSResult gnome_vfs_seek               (GnomeVFSHandle *handle,
+                                             GnomeVFSSeekPosition whence,
+                                             GnomeVFSFileOffset offset);

+Set the current position for reading/writing through handle.

+ +

handle : Handle for which the current position must be changed +
whence : Integer value representing the starting position +
offset : Number of bytes to skip from the position specified by whence +(a positive value means to move forward; a negative one to move backwards) +
Returns : +

gnome_vfs_tell ()

GnomeVFSResult gnome_vfs_tell               (GnomeVFSHandle *handle,
+                                             GnomeVFSFileSize *offset_return);

+Return the current position on handle. This is the point in the file +pointed to by handle that reads and writes will occur on.

+ +

handle : Handle for which the current position must be retrieved +
offset_return : Pointer to a variable that will contain the current position +on return +
Returns : An integer representing the result of the operation +
diff --git a/doc/html/gnome-vfs-gnome-vfs-file-size.html b/doc/html/gnome-vfs-gnome-vfs-file-size.html new file mode 100644 index 0000000..f044909 --- /dev/null +++ b/doc/html/gnome-vfs-gnome-vfs-file-size.html @@ -0,0 +1,65 @@ + +GnomeVFSFileSize

+GnomeVFSFileSize

+GnomeVFSFileSize —

Description

+ +

Details

GNOME_VFS_OFFSET_IS_LONG_LONG

#define GNOME_VFS_OFFSET_IS_LONG_LONG
+

+ +


GNOME_VFS_SIZE_FORMAT_STR

#define GNOME_VFS_SIZE_FORMAT_STR "Lu"
+

+ +


GNOME_VFS_OFFSET_FORMAT_STR

#define GNOME_VFS_OFFSET_FORMAT_STR "Ld"
+

+ +


GnomeVFSFileSize

typedef unsigned long long GnomeVFSFileSize;
+

+ +


GnomeVFSFileOffset

typedef long long GnomeVFSFileOffset;
+

+ +

diff --git a/doc/html/gnome-vfs-gnome-vfs-file-trunc-ops.html b/doc/html/gnome-vfs-gnome-vfs-file-trunc-ops.html new file mode 100644 index 0000000..0251e8e --- /dev/null +++ b/doc/html/gnome-vfs-gnome-vfs-file-trunc-ops.html @@ -0,0 +1,70 @@ +Truncating Files

Truncating Files

Truncating Files —

Synopsis

+
+
+
+GnomeVFSResult gnome_vfs_truncate           (const gchar *text_uri,
+                                             GnomeVFSFileSize length);
+GnomeVFSResult gnome_vfs_truncate_uri       (GnomeVFSURI *uri,
+                                             GnomeVFSFileSize length);
+GnomeVFSResult gnome_vfs_truncate_handle    (GnomeVFSHandle *handle,
+                                             GnomeVFSFileSize length);
+

Description

+ +

Details

gnome_vfs_truncate ()

GnomeVFSResult gnome_vfs_truncate           (const gchar *text_uri,
+                                             GnomeVFSFileSize length);

+Truncate the file at text_uri to length bytes.

+ +

text_uri : URI of the file to be truncated +
length : length of the new file at text_uri +
Returns : An integer representing the result of the operation +

gnome_vfs_truncate_uri ()

GnomeVFSResult gnome_vfs_truncate_uri       (GnomeVFSURI *uri,
+                                             GnomeVFSFileSize length);

+Truncate the file at uri to be only length bytes. Data past length +bytes will be discarded.

+ +

uri : URI of the file to be truncated +
length : length of the new file at uri +
Returns : An integer representing the result of the operation +

gnome_vfs_truncate_handle ()

GnomeVFSResult gnome_vfs_truncate_handle    (GnomeVFSHandle *handle,
+                                             GnomeVFSFileSize length);

+Truncate the file pointed to be handle to be only length bytes. +Data past length bytes will be discarded.

+ +

handle : a handle to the file to be truncated +
length : length of the new file the handle is open to +
Returns : An integer representing the result of the operation +
diff --git a/doc/html/gnome-vfs-gnome-vfs-find-directory.html b/doc/html/gnome-vfs-gnome-vfs-find-directory.html new file mode 100644 index 0000000..2f01387 --- /dev/null +++ b/doc/html/gnome-vfs-gnome-vfs-find-directory.html @@ -0,0 +1,454 @@ +Locating Standard Directories
GnomeVFS - Filesystem Abstraction library

Locating Standard Directories

Name

Locating Standard Directories -- utilities for locating standard directories such as the desktop and trash

Synopsis


+
+enum        GnomeVFSFindDirectoryKind;
+GnomeVFSResult gnome_vfs_find_directory     (GnomeVFSURI *near_uri,
+                                             GnomeVFSFindDirectoryKind kind,
+                                             GnomeVFSURI **result,
+                                             gboolean create_if_needed,
+                                             gboolean find_if_needed,
+                                             guint permissions);

Description

Details

enum GnomeVFSFindDirectoryKind

typedef enum {
+	GNOME_VFS_DIRECTORY_KIND_DESKTOP = 1000,
+	GNOME_VFS_DIRECTORY_KIND_TRASH = 1001
+} GnomeVFSFindDirectoryKind;


gnome_vfs_find_directory ()

GnomeVFSResult gnome_vfs_find_directory     (GnomeVFSURI *near_uri,
+                                             GnomeVFSFindDirectoryKind kind,
+                                             GnomeVFSURI **result,
+                                             gboolean create_if_needed,
+                                             gboolean find_if_needed,
+                                             guint permissions);

Used to return well known directories such as Trash, Desktop, etc. from different +file systems.

There is quite a complicated logic behind finding/creating a Trash directory +and you need to be aware of some implications: +Finding the Trash the first time when using the file method may be pretty +expensive. A cache file is used to store the location of that Trash file +for next time. +If ceate_if_needed is specified without find_if_needed, you may end up +creating a Trash file when there already is one. Your app should start out +by doing a gnome_vfs_find_directory with the find_if_needed to avoid this +and then use the create_if_needed flag to create Trash lazily when it is +needed for throwing away an item on a given disk.

near_uri :

find a well known directory on the same volume as near_uri

kind :

kind of well known directory

result :

newly created URI of the directory we found

create_if_needed :

If directory we are looking for does not exist, try to create it

find_if_needed :

If we don't know where trash is yet, look for it.

permissions :

If creating, use these permissions

Returns :

An integer representing the result of the operation

<<< Directory OperationsAdvanced Operations >>>
\ No newline at end of file diff --git a/doc/html/gnome-vfs-gnome-vfs-inet-connection.html b/doc/html/gnome-vfs-gnome-vfs-inet-connection.html new file mode 100644 index 0000000..d9f62ff --- /dev/null +++ b/doc/html/gnome-vfs-gnome-vfs-inet-connection.html @@ -0,0 +1,107 @@ +gnome-vfs-inet-connection

gnome-vfs-inet-connection

gnome-vfs-inet-connection —

Synopsis

+
+
+
+GnomeVFSResult gnome_vfs_inet_connection_create
+                                            (GnomeVFSInetConnection **connection_return,
+                                             const gchar *host_name,
+                                             guint host_port,
+                                             GnomeVFSCancellation *cancellation);
+void        gnome_vfs_inet_connection_destroy
+                                            (GnomeVFSInetConnection *connection,
+                                             GnomeVFSCancellation *cancellation);
+void        gnome_vfs_inet_connection_free  (GnomeVFSInetConnection *connection,
+                                             GnomeVFSCancellation *cancellation);
+GnomeVFSSocket* gnome_vfs_inet_connection_to_socket
+                                            (GnomeVFSInetConnection *connection);
+GnomeVFSSocketBuffer* gnome_vfs_inet_connection_to_socket_buffer
+                                            (GnomeVFSInetConnection *connection);
+int         gnome_vfs_inet_connection_get_fd
+                                            (GnomeVFSInetConnection *connection);
+

Description

+ +

Details

gnome_vfs_inet_connection_create ()

GnomeVFSResult gnome_vfs_inet_connection_create
+                                            (GnomeVFSInetConnection **connection_return,
+                                             const gchar *host_name,
+                                             guint host_port,
+                                             GnomeVFSCancellation *cancellation);

+Creates a connection at handle_return to host_name using +port port.

+ +

connection_return : pointer to a GnomeVFSInetConnection, which will +contain an allocated GnomeVFSInetConnection object on return. +
host_name : string indicating the host to establish an internet connection with +
host_port : the port number to connect to +
cancellation : handle allowing cancellation of the operation +
Returns : GnomeVFSResult indicating the success of the operation +

gnome_vfs_inet_connection_destroy ()

void        gnome_vfs_inet_connection_destroy
+                                            (GnomeVFSInetConnection *connection,
+                                             GnomeVFSCancellation *cancellation);

+Closes/Destroys connection.

+ +

connection : connection to destroy +
cancellation : handle for cancelling the operation +

gnome_vfs_inet_connection_free ()

void        gnome_vfs_inet_connection_free  (GnomeVFSInetConnection *connection,
+                                             GnomeVFSCancellation *cancellation);

+ +

connection : +
cancellation : + + +

gnome_vfs_inet_connection_to_socket ()

GnomeVFSSocket* gnome_vfs_inet_connection_to_socket
+                                            (GnomeVFSInetConnection *connection);

+Wrapper connection inside a standard GnomeVFSSocket for convenience.

+ +

connection : connection to convert to wrapper in a GnomeVFSSocket +
Returns : a newly created GnomeVFSSocket around connection. +

gnome_vfs_inet_connection_to_socket_buffer ()

GnomeVFSSocketBuffer* gnome_vfs_inet_connection_to_socket_buffer
+                                            (GnomeVFSInetConnection *connection);

+Wrapper connection inside a standard GnomeVFSSocketBuffer for convenience.

+ +

connection : connection to convert to wrapper in a GnomeVFSSocketBuffer +
Returns : a newly created GnomeVFSSocketBuffer around connection. +

gnome_vfs_inet_connection_get_fd ()

int         gnome_vfs_inet_connection_get_fd
+                                            (GnomeVFSInetConnection *connection);

+Retrieve the UNIX file descriptor corresponding to connection.

+ +

connection : connection to get the file descriptor from +
Returns : file descriptor +
diff --git a/doc/html/gnome-vfs-gnome-vfs-init.html b/doc/html/gnome-vfs-gnome-vfs-init.html new file mode 100644 index 0000000..1bf999c --- /dev/null +++ b/doc/html/gnome-vfs-gnome-vfs-init.html @@ -0,0 +1,120 @@ + +Initialization/Shutdown

+Initialization/Shutdown

+Initialization/Shutdown —

Synopsis

+
+
+
+gboolean    gnome_vfs_init                  (void);
+gboolean    gnome_vfs_initialized           (void);
+void        gnome_vfs_shutdown              (void);
+void        gnome_vfs_loadinit              (gpointer app,
+                                             gpointer modinfo);
+void        gnome_vfs_preinit               (gpointer app,
+                                             gpointer modinfo);
+void        gnome_vfs_postinit              (gpointer app,
+                                             gpointer modinfo);
+

Description

+Starting GnomeVFS up and shutting it down. Usually when using the whole +GNOME framework this library is initialized and shutdown automatically +when calling gnome_init. +

Details

gnome_vfs_init ()

gboolean    gnome_vfs_init                  (void);

+If GnomeVFS is not already initialized, initialize it. This must be +called prior to performing any other GnomeVFS operations, and may +be called multiple times without error.

+ +

Returns : TRUE if GnomeVFS is successfully initialized (or was +already initialized) +

gnome_vfs_initialized ()

gboolean    gnome_vfs_initialized           (void);

+Detects if GnomeVFS has already been initialized (GnomeVFS must be +initialized prior to using any methods or operations).

+ +

Returns : TRUE if GnomeVFS has already been initialized +

gnome_vfs_shutdown ()

void        gnome_vfs_shutdown              (void);

+Cease all active GnomeVFS operations and unload the MIME +database from memory.

+ +


gnome_vfs_loadinit ()

void        gnome_vfs_loadinit              (gpointer app,
+                                             gpointer modinfo);

+ +

app : +
modinfo : + + +

gnome_vfs_preinit ()

void        gnome_vfs_preinit               (gpointer app,
+                                             gpointer modinfo);

+ +

app : +
modinfo : + + +

gnome_vfs_postinit ()

void        gnome_vfs_postinit              (gpointer app,
+                                             gpointer modinfo);

+ +

app : +
modinfo : + + +
diff --git a/doc/html/gnome-vfs-gnome-vfs-method.html b/doc/html/gnome-vfs-gnome-vfs-method.html new file mode 100644 index 0000000..61dd63b --- /dev/null +++ b/doc/html/gnome-vfs-gnome-vfs-method.html @@ -0,0 +1,131 @@ +gnome-vfs-method

gnome-vfs-method

gnome-vfs-method —

Synopsis

+
+
+
+GnomeVFSMethod* (*GnomeVFSMethodInitFunc)   (const char *method_name,
+                                             const char *config_args);
+void        (*GnomeVFSMethodShutdownFunc)   (GnomeVFSMethod *method);
+GnomeVFSResult (*GnomeVFSMethodTruncateFunc)
+                                            (GnomeVFSMethod *method,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSFileSize length,
+                                             GnomeVFSContext *context);
+GnomeVFSResult (*GnomeVFSMethodTruncateHandleFunc)
+                                            (GnomeVFSMethod *method,
+                                             GnomeVFSMethodHandle *handle,
+                                             GnomeVFSFileSize length,
+                                             GnomeVFSContext *context);
+#define     VFS_METHOD_HAS_FUNC             (method,func)
+gboolean    gnome_vfs_method_init           (void);
+GnomeVFSMethod* gnome_vfs_method_get        (const gchar *name);
+GnomeVFSTransform* gnome_vfs_transform_get  (const gchar *name);
+

Description

+ +

Details

GnomeVFSMethodInitFunc ()

GnomeVFSMethod* (*GnomeVFSMethodInitFunc)   (const char *method_name,
+                                             const char *config_args);

+ +

method_name : +
config_args : +
Returns : + + +

GnomeVFSMethodShutdownFunc ()

void        (*GnomeVFSMethodShutdownFunc)   (GnomeVFSMethod *method);

+ +

method : + + +

GnomeVFSMethodTruncateFunc ()

GnomeVFSResult (*GnomeVFSMethodTruncateFunc)
+                                            (GnomeVFSMethod *method,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSFileSize length,
+                                             GnomeVFSContext *context);

+ +

method : +
uri : +
length : +
context : +
Returns : + + +

GnomeVFSMethodTruncateHandleFunc ()

GnomeVFSResult (*GnomeVFSMethodTruncateHandleFunc)
+                                            (GnomeVFSMethod *method,
+                                             GnomeVFSMethodHandle *handle,
+                                             GnomeVFSFileSize length,
+                                             GnomeVFSContext *context);

+ +

method : +
handle : +
length : +
context : +
Returns : + + +

VFS_METHOD_HAS_FUNC()

#define VFS_METHOD_HAS_FUNC(method,func) ((((char *)&((method)->func)) - ((char *)(method)) < (method)->method_table_size) && method->func != NULL)
+

+ +

method : +
func : + + +

gnome_vfs_method_init ()

gboolean    gnome_vfs_method_init           (void);

+ +

Returns : + + +

gnome_vfs_method_get ()

GnomeVFSMethod* gnome_vfs_method_get        (const gchar *name);

+ +

name : +
Returns : + + +

gnome_vfs_transform_get ()

GnomeVFSTransform* gnome_vfs_transform_get  (const gchar *name);

+ +

name : +
Returns : + + +
diff --git a/doc/html/gnome-vfs-gnome-vfs-mime-database.html b/doc/html/gnome-vfs-gnome-vfs-mime-database.html new file mode 100644 index 0000000..a406663 --- /dev/null +++ b/doc/html/gnome-vfs-gnome-vfs-mime-database.html @@ -0,0 +1,825 @@ + +File Types

+File Types

+File Types — +functions for getting information about files based on their MIME type

Synopsis

+
+
+
+#define     GNOME_VFS_MIME_TYPE_UNKNOWN
+const char* gnome_vfs_get_mime_type_for_data
+                                            (gconstpointer data,
+                                             int data_size);
+char*       gnome_vfs_get_mime_type         (const char *text_uri);
+enum        GnomeVFSMimeActionType;
+enum        GnomeVFSMimeApplicationArgumentType;
+typedef     GnomeVFSMimeApplication;
+GnomeVFSMimeApplication* gnome_vfs_mime_application_copy
+                                            (GnomeVFSMimeApplication *application);
+GnomeVFSMimeActionType gnome_vfs_mime_get_default_action_type
+                                            (const char *mime_type);
+GnomeVFSMimeAction* gnome_vfs_mime_get_default_action
+                                            (const char *mime_type);
+GnomeVFSMimeApplication* gnome_vfs_mime_get_default_application
+                                            (const char *mime_type);
+Bonobo_ServerInfo* gnome_vfs_mime_get_default_component
+                                            (const char *mime_type);
+GList*      gnome_vfs_mime_get_short_list_applications
+                                            (const char *mime_type);
+GList*      gnome_vfs_mime_get_short_list_components
+                                            (const char *mime_type);
+GList*      gnome_vfs_mime_get_all_applications
+                                            (const char *mime_type);
+GList*      gnome_vfs_mime_get_all_components
+                                            (const char *mime_type);
+GnomeVFSResult gnome_vfs_mime_set_default_action_type
+                                            (const char *mime_type,
+                                             GnomeVFSMimeActionType action_type);
+GnomeVFSResult gnome_vfs_mime_set_default_application
+                                            (const char *mime_type,
+                                             const char *application_id);
+GnomeVFSResult gnome_vfs_mime_set_default_component
+                                            (const char *mime_type,
+                                             const char *component_iid);
+const char* gnome_vfs_mime_get_icon         (const char *mime_type);
+GnomeVFSResult gnome_vfs_mime_set_icon      (const char *mime_type,
+                                             const char *filename);
+const char* gnome_vfs_mime_get_description  (const char *mime_type);
+GnomeVFSResult gnome_vfs_mime_set_description
+                                            (const char *mime_type,
+                                             const char *description);
+gboolean    gnome_vfs_mime_can_be_executable
+                                            (const char *mime_type);
+GnomeVFSResult gnome_vfs_mime_set_can_be_executable
+                                            (const char *mime_type,
+                                             gboolean new_value);
+GnomeVFSResult gnome_vfs_mime_set_short_list_applications
+                                            (const char *mime_type,
+                                             GList *application_ids);
+GnomeVFSResult gnome_vfs_mime_set_short_list_components
+                                            (const char *mime_type,
+                                             GList *component_iids);
+GnomeVFSResult gnome_vfs_mime_add_application_to_short_list
+                                            (const char *mime_type,
+                                             const char *application_id);
+GnomeVFSResult gnome_vfs_mime_remove_application_from_short_list
+                                            (const char *mime_type,
+                                             const char *application_id);
+GnomeVFSResult gnome_vfs_mime_add_component_to_short_list
+                                            (const char *mime_type,
+                                             const char *iid);
+GnomeVFSResult gnome_vfs_mime_remove_component_from_short_list
+                                            (const char *mime_type,
+                                             const char *iid);
+GnomeVFSResult gnome_vfs_mime_add_extension (const char *mime_type,
+                                             const char *extension);
+GnomeVFSResult gnome_vfs_mime_remove_extension
+                                            (const char *mime_type,
+                                             const char *extension);
+GnomeVFSResult gnome_vfs_mime_extend_all_applications
+                                            (const char *mime_type,
+                                             GList *application_ids);
+GnomeVFSResult gnome_vfs_mime_remove_from_all_applications
+                                            (const char *mime_type,
+                                             GList *application_ids);
+GnomeVFSMimeApplication* gnome_vfs_mime_application_new_from_id
+                                            (const char *id);
+void        gnome_vfs_mime_application_free (GnomeVFSMimeApplication *application);
+void        gnome_vfs_mime_action_free      (GnomeVFSMimeAction *action);
+void        gnome_vfs_mime_application_list_free
+                                            (GList *list);
+void        gnome_vfs_mime_component_list_free
+                                            (GList *list);
+gboolean    gnome_vfs_mime_id_in_application_list
+                                            (const char *id,
+                                             GList *applications);
+gboolean    gnome_vfs_mime_id_in_component_list
+                                            (const char *iid,
+                                             GList *components);
+GList*      gnome_vfs_mime_remove_application_from_list
+                                            (GList *applications,
+                                             const char *application_id,
+                                             gboolean *did_remove);
+GList*      gnome_vfs_mime_remove_component_from_list
+                                            (GList *components,
+                                             const char *iid,
+                                             gboolean *did_remove);
+GList*      gnome_vfs_mime_id_list_from_component_list
+                                            (GList *components);
+GList*      gnome_vfs_mime_id_list_from_application_list
+                                            (GList *applications);
+void        gnome_vfs_mime_freeze           (void);
+void        gnome_vfs_mime_thaw             (void);
+void        gnome_vfs_mime_info_reload      (void);
+gboolean    gnome_vfs_mime_type_is_known    (const char *mime_type);
+const char* gnome_vfs_mime_get_value        (const char *mime_type,
+                                             const char *key);
+GnomeVFSResult gnome_vfs_mime_set_value     (const char *mime_type,
+                                             const char *key,
+                                             const char *value);
+GList*      gnome_vfs_mime_get_key_list     (const char *mime_type);
+void        gnome_vfs_mime_keys_list_free   (GList *mime_type_list);
+GList*      gnome_vfs_mime_get_extensions_list
+                                            (const char *mime_type);
+void        gnome_vfs_mime_extensions_list_free
+                                            (GList *list);
+char*       gnome_vfs_mime_get_extensions_string
+                                            (const char *mime_type);
+char*       gnome_vfs_mime_get_extensions_pretty_string
+                                            (const char *mime_type);
+GList*      gnome_vfs_get_registered_mime_types
+                                            (void);
+void        gnome_vfs_mime_registered_mime_type_list_free
+                                            (GList *list);
+GnomeVFSResult gnome_vfs_mime_set_registered_type_key
+                                            (const char *mime_type,
+                                             const char *key,
+                                             const char *data);
+GnomeVFSResult gnome_vfs_mime_set_extensions_list
+                                            (const char *mime_type,
+                                             const char *extensions_list);
+void        gnome_vfs_mime_registered_mime_type_delete
+                                            (const char *mime_type);
+void        gnome_vfs_mime_reset            (void);
+

Description

+ +

Details

GNOME_VFS_MIME_TYPE_UNKNOWN

#define GNOME_VFS_MIME_TYPE_UNKNOWN "application/octet-stream"
+

+The value returned for the MIME type when a file did +not match any entries in the MIME database. May be +treated as a file of an unknown type.

+ +


gnome_vfs_get_mime_type_for_data ()

const char* gnome_vfs_get_mime_type_for_data
+                                            (gconstpointer data,
+                                             int data_size);

+Tries to guess the mime type of the data in data +using the magic patterns.

+ +

data : A pointer to data in memory. +
data_size : Size of the data. +
Returns :the mime-type for this filename. +

gnome_vfs_get_mime_type ()

char*       gnome_vfs_get_mime_type         (const char *text_uri);

+Determine the mime type of text_uri. The mime type is determined +in the same way as by gnome_vfs_get_file_info(). This is meant as +a convenience function for times when you only want the mime type.

+ +

text_uri : URI of the file for which to get the mime type +
Returns : The mime type, or NULL if there is an error reading +the file. +

enum GnomeVFSMimeActionType

typedef enum {
+	GNOME_VFS_MIME_ACTION_TYPE_NONE,
+	GNOME_VFS_MIME_ACTION_TYPE_APPLICATION,
+	GNOME_VFS_MIME_ACTION_TYPE_COMPONENT
+} GnomeVFSMimeActionType;
+

+ +


enum GnomeVFSMimeApplicationArgumentType

typedef enum {
+	GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_URIS,
+	GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_PATHS,
+	GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_URIS_FOR_NON_FILES
+} GnomeVFSMimeApplicationArgumentType;
+

+ +


GnomeVFSMimeApplication

typedef struct {
+	char *id;
+	char *name;
+	char *command;
+	gboolean can_open_multiple_files;
+	GnomeVFSMimeApplicationArgumentType expects_uris;
+	GList *supported_uri_schemes;
+	gboolean requires_terminal;
+
+	/* Padded to avoid future breaks in ABI compatibility */
+	void *reserved1;
+	void *reserved2;
+
+} GnomeVFSMimeApplication;
+

+ +


gnome_vfs_mime_application_copy ()

GnomeVFSMimeApplication* gnome_vfs_mime_application_copy
+                                            (GnomeVFSMimeApplication *application);

+Creates a newly referenced copy of a GnomeVFSMimeApplication object.

+ +

application : The GnomeVFSMimeApplication to be duplicated. +
Returns : A copy of application +

gnome_vfs_mime_get_default_action_type ()

GnomeVFSMimeActionType gnome_vfs_mime_get_default_action_type
+                                            (const char *mime_type);

+Query the MIME database for the type of action to be performed on a particular MIME type by default.

+ +

mime_type : A const char * containing a mime type, e.g. "application/x-php" +
Returns : The type of action to be performed on a file of +MIME type, mime_type by default. +

gnome_vfs_mime_get_default_action ()

GnomeVFSMimeAction* gnome_vfs_mime_get_default_action
+                                            (const char *mime_type);

+Query the MIME database for default action associated with a particular MIME type mime_type.

+ +

mime_type : A const char * containing a mime type, e.g. "application/x-php" +
Returns : A GnomeVFSMimeAction representing the default action to perform upon +file of type mime_type. +

gnome_vfs_mime_get_default_application ()

GnomeVFSMimeApplication* gnome_vfs_mime_get_default_application
+                                            (const char *mime_type);

+Query the MIME database for the application to be executed on files of MIME type +mime_type by default.

+ +

mime_type : A const char * containing a mime type, e.g. "image/png" +
Returns : A GnomeVFSMimeApplication representing the default handler of mime_type +

gnome_vfs_mime_get_default_component ()

Bonobo_ServerInfo* gnome_vfs_mime_get_default_component
+                                            (const char *mime_type);

+Query the MIME database for the default Bonobo component to be activated to +view files of MIME type mime_type.

+ +

mime_type : A const char * containing a mime type, e.g. "image/png" +
Returns : An Bonobo_ServerInfo * representing the OAF server to be activated +to get a reference to the proper component. +

gnome_vfs_mime_get_short_list_applications ()

GList*      gnome_vfs_mime_get_short_list_applications
+                                            (const char *mime_type);

+Return an alphabetically sorted list of GnomeVFSMimeApplication +data structures for the requested mime type. The short list contains +"select" applications recommended for handling this MIME type, appropriate for +display to the user.

+ +

mime_type : A const char * containing a mime type, e.g. "image/png" +
Returns : A GList * where the elements are GnomeVFSMimeApplication * +representing various applications to display in the short list for mime_type. +

gnome_vfs_mime_get_short_list_components ()

GList*      gnome_vfs_mime_get_short_list_components
+                                            (const char *mime_type);

+Return an unsorted sorted list of Bonobo_ServerInfo * +data structures for the requested mime type. The short list contains +"select" components recommended for handling this MIME type, appropriate for +display to the user.

+ +

mime_type : A const char * containing a mime type, e.g. "image/png" +
Returns : A GList * where the elements are Bonobo_ServerInfo * +representing various components to display in the short list for mime_type. +

gnome_vfs_mime_get_all_applications ()

GList*      gnome_vfs_mime_get_all_applications
+                                            (const char *mime_type);

+Return an alphabetically sorted list of GnomeVFSMimeApplication +data structures representing all applications in the MIME database registered +to handle files of MIME type mime_type (and supertypes).

+ +

mime_type : A const char * containing a mime type, e.g. "image/png" +
Returns : A GList * where the elements are GnomeVFSMimeApplication * +representing applications that handle MIME type mime_type. +

gnome_vfs_mime_get_all_components ()

GList*      gnome_vfs_mime_get_all_components
+                                            (const char *mime_type);

+Return an alphabetically sorted list of Bonobo_ServerInfo +data structures representing all Bonobo components registered +to handle files of MIME type mime_type (and supertypes).

+ +

mime_type : A const char * containing a mime type, e.g. "image/png" +
Returns : A GList * where the elements are Bonobo_ServerInfo * +representing components that can handle MIME type mime_type. +

gnome_vfs_mime_set_default_action_type ()

GnomeVFSResult gnome_vfs_mime_set_default_action_type
+                                            (const char *mime_type,
+                                             GnomeVFSMimeActionType action_type);

+Sets the default action type to be performed on files of MIME type mime_type.

+ +

mime_type : A const char * containing a mime type, e.g. "image/png" +
action_type : A GnomeVFSMimeActionType containing the action to perform by default +
Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered. +

gnome_vfs_mime_set_default_application ()

GnomeVFSResult gnome_vfs_mime_set_default_application
+                                            (const char *mime_type,
+                                             const char *application_id);

+Sets the default application to be run on files of MIME type mime_type.

+ +

mime_type : A const char * containing a mime type, e.g. "application/x-php" +
application_id : A key representing an application in the MIME database +(GnomeVFSMimeApplication->id, for example) +
Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered. +

gnome_vfs_mime_set_default_component ()

GnomeVFSResult gnome_vfs_mime_set_default_component
+                                            (const char *mime_type,
+                                             const char *component_iid);

+Sets the default component to be activated for files of MIME type mime_type.

+ +

mime_type : A const char * containing a mime type, e.g. "application/x-php" +
component_iid : The OAFIID of a component +
Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered. +

gnome_vfs_mime_get_icon ()

const char* gnome_vfs_mime_get_icon         (const char *mime_type);

+Query the MIME database for an icon representing the specified MIME type.

+ +

mime_type : A const char * containing a MIME type +
Returns : The filename of the icon as listed in the MIME database. This is +usually a filename without path information, e.g. "i-chardev.png", and sometimes +does not have an extension, e.g. "i-regular" if the icon is supposed to be image +type agnostic between icon themes. Icons are generic, and not theme specific. These +will not necessarily match with the icons a user sees in Nautilus, you have been warned. +

gnome_vfs_mime_set_icon ()

GnomeVFSResult gnome_vfs_mime_set_icon      (const char *mime_type,
+                                             const char *filename);

+Set the icon entry for a particular MIME type in the MIME database. Note that +icon entries need not necessarily contain the full path, and do not necessarily need to +specify an extension. So "i-regular", "my-special-icon.png", and "some-icon" +are all valid icon filenames.

+ +

mime_type : A const char * containing a MIME type +
filename : a const char * containing an image filename +
Returns : A GnomeVFSResult indicating the success of the operation +or any errors that may have occurred. +

gnome_vfs_mime_get_description ()

const char* gnome_vfs_mime_get_description  (const char *mime_type);

+Query the MIME database for a description of the specified MIME type.

+ +

mime_type : the mime type +
Returns : A description of MIME type mime_type +

gnome_vfs_mime_set_description ()

GnomeVFSResult gnome_vfs_mime_set_description
+                                            (const char *mime_type,
+                                             const char *description);

+Set the description of this MIME type in the MIME database. The description +should be something like "Gnumeric spreadsheet".

+ +

mime_type : A const char * containing a mime type +
description : A description of this MIME type +
Returns : GnomeVFSResult indicating the success of the operation or any +errors that may have occurred. +

gnome_vfs_mime_can_be_executable ()

gboolean    gnome_vfs_mime_can_be_executable
+                                            (const char *mime_type);

+Check whether files of this MIME type might conceivably be executable. +Default for known types if FALSE. Default for unknown types is TRUE.

+ +

mime_type : A const char * containing a mime type +
Returns : gboolean containing TRUE if some files of this MIME type +are registered as being executable, and false otherwise. +

gnome_vfs_mime_set_can_be_executable ()

GnomeVFSResult gnome_vfs_mime_set_can_be_executable
+                                            (const char *mime_type,
+                                             gboolean new_value);

+Set whether files of this MIME type might conceivably be executable.

+ +

mime_type : A const char * containing a mime type +
new_value : A boolean value indicating whether mime_type could be executable. +
Returns : GnomeVFSResult indicating the success of the operation or any +errors that may have occurred. +

gnome_vfs_mime_set_short_list_applications ()

GnomeVFSResult gnome_vfs_mime_set_short_list_applications
+                                            (const char *mime_type,
+                                             GList *application_ids);

+Set the short list of applications for the specified MIME type. The short list +contains applications recommended for possible selection by the user.

+ +

mime_type : A const char * containing a mime type, e.g. "application/x-php" +
application_ids : GList of const char * application ids +
Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered. +

gnome_vfs_mime_set_short_list_components ()

GnomeVFSResult gnome_vfs_mime_set_short_list_components
+                                            (const char *mime_type,
+                                             GList *component_iids);

+Set the short list of components for the specified MIME type. The short list +contains companents recommended for possible selection by the user. *

+ +

mime_type : A const char * containing a mime type, e.g. "application/x-php" +
component_iids : GList of const char * OAF IIDs +
Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered. +

gnome_vfs_mime_add_application_to_short_list ()

GnomeVFSResult gnome_vfs_mime_add_application_to_short_list
+                                            (const char *mime_type,
+                                             const char *application_id);

+Add an application to the short list for MIME type mime_type. The short list contains +applications recommended for display as choices to the user for a particular MIME type.

+ +

mime_type : A const char * containing a mime type, e.g. "application/x-php" +
application_id : const char * containing the application's id in the MIME database +
Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered. +

gnome_vfs_mime_remove_application_from_short_list ()

GnomeVFSResult gnome_vfs_mime_remove_application_from_short_list
+                                            (const char *mime_type,
+                                             const char *application_id);

+Remove an application from the short list for MIME type mime_type. The short list contains +applications recommended for display as choices to the user for a particular MIME type.

+ +

mime_type : A const char * containing a mime type, e.g. "application/x-php" +
application_id : const char * containing the application's id in the MIME database +
Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered. +

gnome_vfs_mime_add_component_to_short_list ()

GnomeVFSResult gnome_vfs_mime_add_component_to_short_list
+                                            (const char *mime_type,
+                                             const char *iid);

+Add a component to the short list for MIME type mime_type. The short list contains +components recommended for display as choices to the user for a particular MIME type.

+ +

mime_type : A const char * containing a mime type, e.g. "application/x-php" +
iid : const char * containing the component's OAF IID +
Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered. +

gnome_vfs_mime_remove_component_from_short_list ()

GnomeVFSResult gnome_vfs_mime_remove_component_from_short_list
+                                            (const char *mime_type,
+                                             const char *iid);

+Remove a component from the short list for MIME type mime_type. The short list contains +components recommended for display as choices to the user for a particular MIME type.

+ +

mime_type : A const char * containing a mime type, e.g. "application/x-php" +
iid : const char * containing the component's OAF IID +
Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered. +

gnome_vfs_mime_add_extension ()

GnomeVFSResult gnome_vfs_mime_add_extension (const char *mime_type,
+                                             const char *extension);

+Add a file extension to the specificed MIME type in the MIME database.

+ +

mime_type : The mime type to add the mapping to. +
extension : The extension to add (e.g. "txt") +
Returns : GnomeVFSResult indicating the success of the operation or any +errors that may have occurred. +

gnome_vfs_mime_remove_extension ()

GnomeVFSResult gnome_vfs_mime_remove_extension
+                                            (const char *mime_type,
+                                             const char *extension);

+Removes a file extension from the specificed MIME type in the MIME database.

+ +

mime_type : The mime type to remove the extension from +
extension : The extension to remove +
Returns : GnomeVFSResult indicating the success of the operation or any +errors that may have occurred. +

gnome_vfs_mime_extend_all_applications ()

GnomeVFSResult gnome_vfs_mime_extend_all_applications
+                                            (const char *mime_type,
+                                             GList *application_ids);

+Register mime_type as being handled by all applications list in application_ids.

+ +

mime_type : A const char * containing a mime type, e.g. "application/x-php" +
application_ids : a GList of const char * containing application ids +
Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered. +

gnome_vfs_mime_remove_from_all_applications ()

GnomeVFSResult gnome_vfs_mime_remove_from_all_applications
+                                            (const char *mime_type,
+                                             GList *application_ids);

+Remove mime_type as a handled type from every application in application_ids

+ +

mime_type : A const char * containing a mime type, e.g. "application/x-php" +
application_ids : a GList of const char * containing application ids +
Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered. +

gnome_vfs_mime_application_new_from_id ()

GnomeVFSMimeApplication* gnome_vfs_mime_application_new_from_id
+                                            (const char *id);

+Fetches the GnomeVFSMimeApplication associated with the specified +application ID from the MIME database.

+ +

id : A const char * containing an application id +
Returns : GnomeVFSMimeApplication * corresponding to id +

gnome_vfs_mime_application_free ()

void        gnome_vfs_mime_application_free (GnomeVFSMimeApplication *application);

+Frees a GnomeVFSMimeApplication *.

+ +

application : The GnomeVFSMimeApplication to be freed +

gnome_vfs_mime_action_free ()

void        gnome_vfs_mime_action_free      (GnomeVFSMimeAction *action);

+Frees a GnomeVFSMimeAction *.

+ +

action : The GnomeVFSMimeAction to be freed +

gnome_vfs_mime_application_list_free ()

void        gnome_vfs_mime_application_list_free
+                                            (GList *list);

+Frees lists of GnomeVFSApplications, as returned from functions such +as gnome_vfs_get_all_applications().

+ +

list : a GList of GnomeVFSApplication * to be freed +

gnome_vfs_mime_component_list_free ()

void        gnome_vfs_mime_component_list_free
+                                            (GList *list);

+Frees lists of Bonobo_ServerInfo * (as returned from functions such +as gnome_vfs_get_all_components)

+ +

list : a GList of Bonobo_ServerInfo * to be freed +

gnome_vfs_mime_id_in_application_list ()

gboolean    gnome_vfs_mime_id_in_application_list
+                                            (const char *id,
+                                             GList *applications);

+Check whether an application id is in a list of GnomeVFSMimeApplications.

+ +

id : An application id. +
applications : A GList * whose nodes are GnomeVFSMimeApplications, such as the +result of gnome_vfs_mime_get_short_list_applications(). +
Returns : TRUE if an application whose id matches id is in applications. +

gnome_vfs_mime_id_in_component_list ()

gboolean    gnome_vfs_mime_id_in_component_list
+                                            (const char *iid,
+                                             GList *components);

+Check whether a component iid is in a list of Bonobo_ServerInfos.

+ +

iid : A component iid. +
components : A GList * whose nodes are Bonobo_ServerInfos, such as the +result of gnome_vfs_mime_get_short_list_components(). +
Returns : TRUE if a component whose iid matches iid is in components. +

gnome_vfs_mime_remove_application_from_list ()

GList*      gnome_vfs_mime_remove_application_from_list
+                                            (GList *applications,
+                                             const char *application_id,
+                                             gboolean *did_remove);

+Remove an application specified by id from a list of GnomeVFSMimeApplications.

+ +

applications : A GList * whose nodes are GnomeVFSMimeApplications, such as the +result of gnome_vfs_mime_get_short_list_applications(). +
application_id : The id of an application to remove from applications. +
did_remove : If non-NULL, this is filled in with TRUE if the application +was found in the list, FALSE otherwise. +
Returns : The modified list. If the application is not found, the list will +be unchanged. +

gnome_vfs_mime_remove_component_from_list ()

GList*      gnome_vfs_mime_remove_component_from_list
+                                            (GList *components,
+                                             const char *iid,
+                                             gboolean *did_remove);

+Remove a component specified by iid from a list of Bonobo_ServerInfos.

+ +

components : A GList * whose nodes are Bonobo_ServerInfos, such as the +result of gnome_vfs_mime_get_short_list_components(). +
iid : The iid of a component to remove from components. +
did_remove : If non-NULL, this is filled in with TRUE if the component +was found in the list, FALSE otherwise. +
Returns : The modified list. If the component is not found, the list will +be unchanged. +

gnome_vfs_mime_id_list_from_component_list ()

GList*      gnome_vfs_mime_id_list_from_component_list
+                                            (GList *components);

+Create a list of component iids from a list of Bonobo_ServerInfos.

+ +

components : A GList * whose nodes are Bonobo_ServerInfos, such as the +result of gnome_vfs_mime_get_short_list_components(). +
Returns : A new list where each Bonobo_ServerInfo in the original +list is replaced by a char * with the component's iid. The original list is +not modified. +

gnome_vfs_mime_id_list_from_application_list ()

GList*      gnome_vfs_mime_id_list_from_application_list
+                                            (GList *applications);

+Create a list of application ids from a list of GnomeVFSMimeApplications.

+ +

applications : A GList * whose nodes are GnomeVFSMimeApplications, such as the +result of gnome_vfs_mime_get_short_list_applications(). +
Returns : A new list where each GnomeVFSMimeApplication in the original +list is replaced by a char * with the application's id. The original list is +not modified. +

gnome_vfs_mime_freeze ()

void        gnome_vfs_mime_freeze           (void);

+Freezes the mime data so that you can do multiple +updates to the dat in one batch without needing +to back the files to disk or readind them

+ +


gnome_vfs_mime_thaw ()

void        gnome_vfs_mime_thaw             (void);

+UnFreezes the mime data so that you can do multiple +updates to the dat in one batch without needing +to back the files to disk or readind them

+ +


gnome_vfs_mime_info_reload ()

void        gnome_vfs_mime_info_reload      (void);

+Reload the MIME database from disk and notify any listeners +holding active GnomeVFSMIMEMonitor objects.

+ +


gnome_vfs_mime_type_is_known ()

gboolean    gnome_vfs_mime_type_is_known    (const char *mime_type);

+This function returns TRUE if mime_type is in the MIME database at all.

+ +

mime_type : a mime type. +
Returns : TRUE if anything is known about mime_type, otherwise FALSE +

gnome_vfs_mime_get_value ()

const char* gnome_vfs_mime_get_value        (const char *mime_type,
+                                             const char *key);

+This function retrieves the value associated with key in +the given GnomeMimeContext. The string is private, you +should not free the result.

+ +

mime_type : a mime type. +
key : A key to lookup for the given mime-type +
Returns : GNOME_VFS_OK if the operation succeeded, otherwise an error code +

gnome_vfs_mime_set_value ()

GnomeVFSResult gnome_vfs_mime_set_value     (const char *mime_type,
+                                             const char *key,
+                                             const char *value);

+This function is going to set the value +associated to the key and it will save it +to the user' file if necessary. +You should not free the key/values passed to +this function. They are used internally.

+ +

mime_type : a mime type. +
key : a key to store the value in. +
value : the value to store in the key. +
Returns : GNOME_VFS_OK if the operation succeeded, otherwise an error code + +

gnome_vfs_mime_get_key_list ()

GList*      gnome_vfs_mime_get_key_list     (const char *mime_type);

+Gets a list of all keys associated with mime_type.

+ +

mime_type : the MIME type to lookup +
Returns : a GList of const char * representing keys associated +with mime_type +

gnome_vfs_mime_keys_list_free ()

void        gnome_vfs_mime_keys_list_free   (GList *mime_type_list);

+Frees the mime type list.

+ +

mime_type_list : A mime type list to free. +

gnome_vfs_mime_get_extensions_list ()

GList*      gnome_vfs_mime_get_extensions_list
+                                            (const char *mime_type);

+Get the file extensions associated with mime type mime_type.

+ +

mime_type : type to get the extensions of +
Returns : a GList of char *s +

gnome_vfs_mime_extensions_list_free ()

void        gnome_vfs_mime_extensions_list_free
+                                            (GList *list);

+Call this function on the list returned by gnome_vfs_mime_extensions +to free the list and all of its elements.

+ +

list : the extensions list +

gnome_vfs_mime_get_extensions_string ()

char*       gnome_vfs_mime_get_extensions_string
+                                            (const char *mime_type);

+Retrieves the extensions associated with mime_type as a single +space seperated string.

+ +

mime_type : the mime type +
Returns : a string containing space seperated extensions for mime_type +

gnome_vfs_mime_get_extensions_pretty_string ()

char*       gnome_vfs_mime_get_extensions_pretty_string
+                                            (const char *mime_type);

+Returns the supported extensions for mime_type as a comma-seperated list.

+ +

mime_type : the mime type +
Returns : a string containing comma seperated extensions for this mime-type +

gnome_vfs_get_registered_mime_types ()

GList*      gnome_vfs_get_registered_mime_types
+                                            (void);

+ +

Returns : + + +

gnome_vfs_mime_registered_mime_type_list_free ()

void        gnome_vfs_mime_registered_mime_type_list_free
+                                            (GList *list);

+Call this function on the list returned by gnome_vfs_get_registered_mime_types +to free the list and all of its elements.

+ +

list : the extensions list +

gnome_vfs_mime_set_registered_type_key ()

GnomeVFSResult gnome_vfs_mime_set_registered_type_key
+                                            (const char *mime_type,
+                                             const char *key,
+                                             const char *data);

+This function sets the key data for the registered mime +type's hash table.

+ +

mime_type : Mime type to set key for +
key : The key to set +
data : The data to set for the key +
Returns : GNOME_VFS_OK if the operation succeeded, otherwise an error code +

gnome_vfs_mime_set_extensions_list ()

GnomeVFSResult gnome_vfs_mime_set_extensions_list
+                                            (const char *mime_type,
+                                             const char *extensions_list);

+Sets the extensions for a given mime type. Overrides +the previously set extensions.

+ +

mime_type : the mime type. +
extensions_list : a whitespace-separated list of the + extensions to set for this mime type. +
Returns : GNOME_VFS_OK if the operation succeeded, otherwise an error code. +

gnome_vfs_mime_registered_mime_type_delete ()

void        gnome_vfs_mime_registered_mime_type_delete
+                                            (const char *mime_type);

+Delete a mime type for the user which runs this command. +You can undo this only by calling gnome_vfs_mime_reset

+ +

mime_type : string representing the existing type to delete +

gnome_vfs_mime_reset ()

void        gnome_vfs_mime_reset            (void);

+resets the user's mime database to the system defaults.

+ +

diff --git a/doc/html/gnome-vfs-gnome-vfs-mime-monitor.html b/doc/html/gnome-vfs-gnome-vfs-mime-monitor.html new file mode 100644 index 0000000..f5aa134 --- /dev/null +++ b/doc/html/gnome-vfs-gnome-vfs-mime-monitor.html @@ -0,0 +1,58 @@ + +MIME Database Monitor

+MIME Database Monitor

+MIME Database Monitor — +monitor the MIME database for changes (primarily for file browsers)

Synopsis

+
+
+
+#define     GNOME_VFS_MIME_MONITOR_TYPE
+struct      GnomeVFSMIMEMonitorPrivate;
+GnomeVFSMIMEMonitor* gnome_vfs_mime_monitor_get
+                                            (void);
+
+

Description

+ +

Details

GNOME_VFS_MIME_MONITOR_TYPE

#define GNOME_VFS_MIME_MONITOR_TYPE        (gnome_vfs_mime_monitor_get_type ())
+

+ +


struct GnomeVFSMIMEMonitorPrivate

struct GnomeVFSMIMEMonitorPrivate;

+ +


gnome_vfs_mime_monitor_get ()

GnomeVFSMIMEMonitor* gnome_vfs_mime_monitor_get
+                                            (void);

+Get access to the single global monitor.

+ +

Returns : the global GnomeVFSMIMEMonitor +
diff --git a/doc/html/gnome-vfs-gnome-vfs-mime.html b/doc/html/gnome-vfs-gnome-vfs-mime.html new file mode 100644 index 0000000..b004d9a --- /dev/null +++ b/doc/html/gnome-vfs-gnome-vfs-mime.html @@ -0,0 +1,136 @@ + +MIME typing

+MIME typing

+MIME typing —

Synopsis

+
+
+
+void        gnome_vfs_mime_shutdown         (void);
+const char* gnome_vfs_mime_type_from_name   (const char *filename);
+const char* gnome_vfs_mime_type_from_name_or_default
+                                            (const char *filename,
+                                             const char *defaultv);
+const char* gnome_vfs_get_mime_type_common  (GnomeVFSURI *uri);
+const char* gnome_vfs_get_mime_type_from_uri
+                                            (GnomeVFSURI *uri);
+const char* gnome_vfs_get_mime_type_from_file_data
+                                            (GnomeVFSURI *uri);
+const char* gnome_vfs_get_file_mime_type    (const char *path,
+                                             const struct stat *optional_stat_info,
+                                             gboolean suffix_only);
+gboolean    gnome_vfs_mime_type_is_supertype
+                                            (const char *mime_type);
+char*       gnome_vfs_get_supertype_from_mime_type
+                                            (const char *mime_type);
+

Description

+ +

Details

gnome_vfs_mime_shutdown ()

void        gnome_vfs_mime_shutdown         (void);

+Unload the MIME database from memory.

+ +


gnome_vfs_mime_type_from_name ()

const char* gnome_vfs_mime_type_from_name   (const char *filename);

+Determined the mime type for filename.

+ +

filename : A filename (the file does not necessarily exist). +
Returns :the mime-type for this filename. +

gnome_vfs_mime_type_from_name_or_default ()

const char* gnome_vfs_mime_type_from_name_or_default
+                                            (const char *filename,
+                                             const char *defaultv);

+This routine tries to determine the mime-type of the filename +only by looking at the filename from the GNOME database of mime-types.

+ +

filename : A filename (the file does not necesarily exist). +
defaultv : A default value to be returned if no match is found +
Returns :the mime-type of the filename. If no value could be +determined, it will return defaultv. +

gnome_vfs_get_mime_type_common ()

const char* gnome_vfs_get_mime_type_common  (GnomeVFSURI *uri);

+Tries to guess the mime type of the file represented by uir. +Favors using the file data to the uri extension. +Handles passing uri of a non-existent file by falling back +on returning a type based on the extension. +

+FIXME: This function will not necessarily return the same mime type as doing a +get file info on the text uri.

+ +

uri : a real file or a non-existent uri. +
Returns : the mime-type for this uri. + +

gnome_vfs_get_mime_type_from_uri ()

const char* gnome_vfs_get_mime_type_from_uri
+                                            (GnomeVFSURI *uri);

+Tries to guess the mime type of the file uri by +checking the file name extension. Works on non-existent +files.

+ +

uri : A file uri. +
Returns :the mime-type for this filename. +

gnome_vfs_get_mime_type_from_file_data ()

const char* gnome_vfs_get_mime_type_from_file_data
+                                            (GnomeVFSURI *uri);

+Tries to guess the mime type of the file uri by +checking the file data using the magic patterns. Does not handle text files properly

+ +

uri : A file uri. +
Returns :the mime-type for this filename. +

gnome_vfs_get_file_mime_type ()

const char* gnome_vfs_get_file_mime_type    (const char *path,
+                                             const struct stat *optional_stat_info,
+                                             gboolean suffix_only);

+Tries to guess the mime type of the file represented by path. +If suffix_only is false, uses the mime-magic based lookup first. +Handles passing path of a non-existent file by falling back +on returning a type based on the extension.

+ +

path : a path of a file. +
optional_stat_info : optional stat buffer. +
suffix_only : whether or not to do a magic-based lookup. +
Returns : the mime-type for this path +

gnome_vfs_mime_type_is_supertype ()

gboolean    gnome_vfs_mime_type_is_supertype
+                                            (const char *mime_type);

+ +

mime_type : +
Returns : + + +

gnome_vfs_get_supertype_from_mime_type ()

char*       gnome_vfs_get_supertype_from_mime_type
+                                            (const char *mime_type);

+ +

mime_type : +
Returns : + + +
diff --git a/doc/html/gnome-vfs-gnome-vfs-module-callback-module-api.html b/doc/html/gnome-vfs-gnome-vfs-module-callback-module-api.html new file mode 100644 index 0000000..87cff07 --- /dev/null +++ b/doc/html/gnome-vfs-gnome-vfs-module-callback-module-api.html @@ -0,0 +1,89 @@ +gnome-vfs-module-callback-module-api

gnome-vfs-module-callback-module-api

gnome-vfs-module-callback-module-api —

Synopsis

+
+
+
+gboolean    gnome_vfs_module_callback_invoke
+                                            (const char *callback_name,
+                                             gconstpointer in,
+                                             gsize in_size,
+                                             gpointer out,
+                                             gsize out_size);
+

Description

+ +

Details

gnome_vfs_module_callback_invoke ()

gboolean    gnome_vfs_module_callback_invoke
+                                            (const char *callback_name,
+                                             gconstpointer in,
+                                             gsize in_size,
+                                             gpointer out,
+                                             gsize out_size);

+Invoke a default callback for callback_name, with in arguments +specified by in and in_size, and out arguments specified by out +and out_size. +

+This function should only be called by gnome-vfs modules. +

+If this function is called from an async job thread, it will invoke +the current async handler for callback_name, if any. If no async +handler is set, or the function is not called from an async job +thread, the regular handler, if any, will be invoked instead. If no +handler at all is found for callback_name, the function returns +FALSE.

+ +

callback_name : The name of the module callback to set +
in : In argument - type dependent on the specific callback +
in_size : Size of the in argument +
out : Out argument - type dependent on the specific callback +
out_size : Size of the out argument +
Returns : TRUE if a callback was invoked, FALSE if none was set. + +
diff --git a/doc/html/gnome-vfs-gnome-vfs-module-callback.html b/doc/html/gnome-vfs-gnome-vfs-module-callback.html new file mode 100644 index 0000000..ab62137 --- /dev/null +++ b/doc/html/gnome-vfs-gnome-vfs-module-callback.html @@ -0,0 +1,350 @@ +gnome-vfs-module-callback

gnome-vfs-module-callback

gnome-vfs-module-callback —

Synopsis

+
+
+
+void        (*GnomeVFSModuleCallback)       (gconstpointer in,
+                                             gsize in_size,
+                                             gpointer out,
+                                             gsize out_size,
+                                             gpointer callback_data);
+void        (*GnomeVFSModuleCallbackResponse)
+                                            (gpointer response_data);
+void        (*GnomeVFSAsyncModuleCallback)  (gconstpointer in,
+                                             gsize in_size,
+                                             gpointer out,
+                                             gsize out_size,
+                                             gpointer callback_data,
+                                             GnomeVFSModuleCallbackResponse response,
+                                             gpointer response_data);
+void        gnome_vfs_module_callback_set_default
+                                            (const char *callback_name,
+                                             GnomeVFSModuleCallback callback,
+                                             gpointer callback_data,
+                                             GDestroyNotify destroy_notify);
+void        gnome_vfs_module_callback_push  (const char *callback_name,
+                                             GnomeVFSModuleCallback callback,
+                                             gpointer callback_data,
+                                             GDestroyNotify destroy_notify);
+void        gnome_vfs_module_callback_pop   (const char *callback_name);
+void        gnome_vfs_async_module_callback_set_default
+                                            (const char *callback_name,
+                                             GnomeVFSAsyncModuleCallback callback,
+                                             gpointer callback_data,
+                                             GDestroyNotify destroy_notify);
+void        gnome_vfs_async_module_callback_push
+                                            (const char *callback_name,
+                                             GnomeVFSAsyncModuleCallback callback,
+                                             gpointer callback_data,
+                                             GDestroyNotify destroy_notify);
+void        gnome_vfs_async_module_callback_pop
+                                            (const char *callback_name);
+

Description

+ +

Details

GnomeVFSModuleCallback ()

void        (*GnomeVFSModuleCallback)       (gconstpointer in,
+                                             gsize in_size,
+                                             gpointer out,
+                                             gsize out_size,
+                                             gpointer callback_data);

+This is the type of a callback function that gets set for a module +callback. +

+When the callback is invoked, the user function is called with an +in argument, the exact type of which depends on the specific +callback. It is generally a pointer to a struct with several fields +that provide information to the callback. +

+The out argument is used to return a values from the +callback. Once again the exact type depends on the specific +callback. It is generally a pointer to a pre-allocated struct with +several fields that the callback function should fill in before +returning.

+ +

in : The in argument for this callback; the exact type depends on the specific callback +
in_size : Size of the in argument; useful for sanity-checking +
out : The out argument for this callback; the exact type depends on the specific callback +
out_size : Size of the out argument; useful for sanity-checking +
callback_data : The callback_data specified when this callback was set +

GnomeVFSModuleCallbackResponse ()

void        (*GnomeVFSModuleCallbackResponse)
+                                            (gpointer response_data);

+This is the type of the response function passed to a +GnomeVFSAsyncModuleCallback(). It should be called when the async +callback has completed.

+ +

response_data : Pass the response_data argument originally passed to the async callback +

GnomeVFSAsyncModuleCallback ()

void        (*GnomeVFSAsyncModuleCallback)  (gconstpointer in,
+                                             gsize in_size,
+                                             gpointer out,
+                                             gsize out_size,
+                                             gpointer callback_data,
+                                             GnomeVFSModuleCallbackResponse response,
+                                             gpointer response_data);

+This is the type of a callback function that gets set for an async +module callback. +

+Such callbacks are useful when you are using the API and want +callbacks to be handled from the main thread, for instance if they +need to put up a dialog. +

+Like a GnomeVFSModuleCallback(), an async callback has in and out +arguments for passing data into and out of the callback. However, +an async callback does not need to fill in the out argument before +returning. Instead, it can arrange to have the work done from a +callback on the main loop, from another thread, etc. The response +function should be called by whatever code finishes the work of the +callback with response_data as an argument once the out argument +is filled in and the callback is done. +

+The in and out arguments are guaranteed to remain valid until the +response function is called.

+ +

in : The in argument for this callback; the exact type depends on the specific callback +
in_size : Size of the in argument; useful for sanity-checking +
out : The out argument for this callback; the exact type depends on the specific callback +
out_size : Size of the out argument; useful for sanity-checking +
callback_data : The callback_data specified when this callback was set +
response : Response function to call when the callback is completed +
response_data : Argument to pass to response +

gnome_vfs_module_callback_set_default ()

void        gnome_vfs_module_callback_set_default
+                                            (const char *callback_name,
+                                             GnomeVFSModuleCallback callback,
+                                             gpointer callback_data,
+                                             GDestroyNotify destroy_notify);

+Set the default callback for callback_name to +callback. callback will be called with callback_data on the +same thread as the gnome-vfs operation that invokes it. The default +value is shared for all threads, but setting it is thread-safe. +

+Use this function if you want to set a handler to be used by your +whole application. You can use gnome_vfs_module_callback_push() to +set a callback function that will temporarily override the default +on the current thread instead. Or you can also use +gnome_vfs_async_module_callback_set_default() to set an async +callback function. +

+Note: destroy_notify may be called on any thread - it is not +guaranteed to be called on the main thread.

+ +

callback_name : The name of the module callback to set +
callback : The function to call when the callback is invoked +
callback_data : Pointer to pass as the callback_data argument to callback +
destroy_notify : Function to call when callback_data is to be freed. +

gnome_vfs_module_callback_push ()

void        gnome_vfs_module_callback_push  (const char *callback_name,
+                                             GnomeVFSModuleCallback callback,
+                                             gpointer callback_data,
+                                             GDestroyNotify destroy_notify);

+Set callback as a temprary handler for callback_name. callback +will be called with callback_data on the same thread as the +gnome-vfs operation that invokes it. The temporary handler is set +per-thread. +

+gnome_vfs_module_callback_pop() removes the most recently set +temporary handler. The temporary handlers are treated as a first-in +first-out stack. +

+Use this function to set a temporary callback handler for a single +call or a few calls. You can use +gnome_vfs_module_callback_set_default() to set a callback function +that will establish a permanent global setting for all threads +instead. +

+Note: destroy_notify may be called on any thread - it is not +guaranteed to be called on the main thread.

+ +

callback_name : The name of the module callback to set temporarily +
callback : The function to call when the callback is invoked +
callback_data : Pointer to pass as the callback_data argument to callback +
destroy_notify : Function to call when callback_data is to be freed. +

gnome_vfs_module_callback_pop ()

void        gnome_vfs_module_callback_pop   (const char *callback_name);

+Remove the temporary handler for callback_name most recently set +with gnome_vfs_module_callback_push(). If another temporary +handler was previously set on the same thread, it becomes the +current handler. Otherwise, the default handler, if any, becomes +current. +

+The temporary handlers are treated as a first-in first-out +stack.

+ +

callback_name : The name of the module callback to remove a temporary handler for +

gnome_vfs_async_module_callback_set_default ()

void        gnome_vfs_async_module_callback_set_default
+                                            (const char *callback_name,
+                                             GnomeVFSAsyncModuleCallback callback,
+                                             gpointer callback_data,
+                                             GDestroyNotify destroy_notify);

+Set the default async callback for callback_name to +callback. callback will be called with callback_data +from a callback on the main thread. It will be passed a response +function which should be called to signal completion of the callback. +The callback function itself may return in the meantime. +

+The default value is shared for all threads, but setting it is +thread-safe. +

+Use this function if you want to globally set a callback handler +for use with async operations. +

+You can use gnome_vfs_async_module_callback_push() to set an async +callback function that will temporarily override the default on the +current thread instead. Or you can also use +gnome_vfs_module_callback_set_default() to set a regular callback +function. +

+Note: destroy_notify may be called on any thread - it is not +guaranteed to be called on the main thread.

+ +

callback_name : The name of the async module callback to set +
callback : The function to call when the callback is invoked +
callback_data : Pointer to pass as the callback_data argument to callback +
destroy_notify : Function to call when callback_data is to be freed. +

gnome_vfs_async_module_callback_push ()

void        gnome_vfs_async_module_callback_push
+                                            (const char *callback_name,
+                                             GnomeVFSAsyncModuleCallback callback,
+                                             gpointer callback_data,
+                                             GDestroyNotify destroy_notify);

+Set callback_func as a temprary async handler for +callback_name. callback will be called with callback_data +from a callback on the main thread. It will be passed a response +function which should be called to signal completion of the +callback. The callback function itself may return in the meantime. +

+The temporary async handler is set per-thread. +

+gnome_vfs_async_module_callback_pop() removes the most recently set +temporary temporary handler. The temporary async handlers are +treated as a first-in first-out stack. +

+Use this function to set a temporary async callback handler for a +single call or a few calls. You can use +gnome_vfs_async_module_callback_set_default() to set an async +callback function that will establish a permanent global setting +for all threads instead. +

+Note: destroy_notify may be called on any thread - it is not +guaranteed to be called on the main thread.

+ +

callback_name : The name of the module callback to set temporarily +
callback : The function to call when the callback is invoked +
callback_data : Pointer to pass as the callback_data argument to callback +
destroy_notify : Function to call when callback_data is to be freed. +

gnome_vfs_async_module_callback_pop ()

void        gnome_vfs_async_module_callback_pop
+                                            (const char *callback_name);

+Remove the temporary async handler for callback_name most recently +set with gnome_vfs_async_module_callback_push(). If another +temporary async handler was previously set on the same thread, it +becomes the current handler. Otherwise, the default async handler, +if any, becomes current. +

+The temporary async handlers are treated as a first-in first-out +stack.

+ +

callback_name : The name of the module callback to remove a temporary handler for +
diff --git a/doc/html/gnome-vfs-gnome-vfs-module-shared.html b/doc/html/gnome-vfs-gnome-vfs-module-shared.html new file mode 100644 index 0000000..1ce83d5 --- /dev/null +++ b/doc/html/gnome-vfs-gnome-vfs-module-shared.html @@ -0,0 +1,98 @@ +gnome-vfs-module-shared

gnome-vfs-module-shared

gnome-vfs-module-shared —

Synopsis

+
+
+
+const gchar* gnome_vfs_mime_type_from_mode  (mode_t mode);
+void        gnome_vfs_stat_to_file_info     (GnomeVFSFileInfo *file_info,
+                                             const struct stat *statptr);
+GnomeVFSResult gnome_vfs_set_meta           (GnomeVFSFileInfo *info,
+                                             const char *file_name,
+                                             const char *meta_key);
+GnomeVFSResult gnome_vfs_set_meta_for_list  (GnomeVFSFileInfo *info,
+                                             const char *file_name,
+                                             const GList *meta_keys);
+const char* gnome_vfs_get_special_mime_type (GnomeVFSURI *uri);
+

Description

+ +

Details

gnome_vfs_mime_type_from_mode ()

const gchar* gnome_vfs_mime_type_from_mode  (mode_t mode);

+Returns a MIME type based on the mode passed. It only works when mode +references a special file (directory, device, fifo, socket or symlink) +

+Returns: a string containing the MIME type, if mode is a normal file

+ +

mode : +
Returns :NULL. +

gnome_vfs_stat_to_file_info ()

void        gnome_vfs_stat_to_file_info     (GnomeVFSFileInfo *file_info,
+                                             const struct stat *statptr);

+ +

file_info : +
statptr : + + +

gnome_vfs_set_meta ()

GnomeVFSResult gnome_vfs_set_meta           (GnomeVFSFileInfo *info,
+                                             const char *file_name,
+                                             const char *meta_key);

+ +

info : +
file_name : +
meta_key : +
Returns : + + +

gnome_vfs_set_meta_for_list ()

GnomeVFSResult gnome_vfs_set_meta_for_list  (GnomeVFSFileInfo *info,
+                                             const char *file_name,
+                                             const GList *meta_keys);

+ +

info : +
file_name : +
meta_keys : +
Returns : + + +

gnome_vfs_get_special_mime_type ()

const char* gnome_vfs_get_special_mime_type (GnomeVFSURI *uri);

+Gets the MIME type for uri, this function only returns the type +when the URI points to a file that can't be sniffed (sockets, +directories, devices, and fifos).

+ +

uri : +
Returns : a string containing the mime type, NULL if the uri doesn't +present an special file. +
diff --git a/doc/html/gnome-vfs-gnome-vfs-module.html b/doc/html/gnome-vfs-gnome-vfs-module.html new file mode 100644 index 0000000..1344938 --- /dev/null +++ b/doc/html/gnome-vfs-gnome-vfs-module.html @@ -0,0 +1,69 @@ +gnome-vfs-module

gnome-vfs-module

gnome-vfs-module —

Synopsis

+
+
+
+GnomeVFSMethod* vfs_module_init             (const char *method_name,
+                                             const char *args);
+GnomeVFSTransform* vfs_module_transform     (const char *method_name,
+                                             const char *args);
+void        vfs_module_shutdown             (GnomeVFSMethod *method);
+

Description

+ +

Details

vfs_module_init ()

GnomeVFSMethod* vfs_module_init             (const char *method_name,
+                                             const char *args);

+Standard extern call implemented by each filesystem module. This is called +to initialize the module and setup any basic structures / connections the +method requires. It also allows the module to identify the URI method it is +associated with in this instance.

+ +

method_name : name of the method that invoked this module (e.g. "http", "ftp", "file"). +
args : not used by most modules, but potential arguments for creating the module (could +be a file to point at, for example) +
Returns : the module symbol table, pointing to the appropriate calls for +this module. +

vfs_module_transform ()

GnomeVFSTransform* vfs_module_transform     (const char *method_name,
+                                             const char *args);

+Shift an already instanced module to a new method name. This call is not implemented +by most modules and is optional.

+ +

method_name : name of the method that invoked this module (e.g. "http", "ftp", "file"). +
args : not used by most modules, but potential arguments for creating the module (could +be a file to point at, for example) +
Returns : the module symbol table, pointing to the appropriate calls for +this module. +

vfs_module_shutdown ()

void        vfs_module_shutdown             (GnomeVFSMethod *method);

+Called to tell a module to end any active operations, free all used memory, +and close any connections (as appropriate) or resources.

+ +

method : the symbol table of the module being shut down +
diff --git a/doc/html/gnome-vfs-gnome-vfs-monitor.html b/doc/html/gnome-vfs-gnome-vfs-monitor.html new file mode 100644 index 0000000..028cb24 --- /dev/null +++ b/doc/html/gnome-vfs-gnome-vfs-monitor.html @@ -0,0 +1,133 @@ + +Monitoring

+Monitoring

+Monitoring — +watch files for changes, and get called back if they do

Synopsis

+
+
+
+GnomeVFSResult gnome_vfs_monitor_add        (GnomeVFSMonitorHandle **handle,
+                                             const gchar *text_uri,
+                                             GnomeVFSMonitorType monitor_type,
+                                             GnomeVFSMonitorCallback callback,
+                                             gpointer user_data);
+GnomeVFSResult gnome_vfs_monitor_cancel     (GnomeVFSMonitorHandle *handle);
+enum        GnomeVFSMonitorType;
+enum        GnomeVFSMonitorEventType;
+void        (*GnomeVFSMonitorCallback)      (GnomeVFSMonitorHandle *handle,
+                                             const gchar *monitor_uri,
+                                             const gchar *info_uri,
+                                             GnomeVFSMonitorEventType event_type,
+                                             gpointer user_data);
+

Description

+ +

Details

gnome_vfs_monitor_add ()

GnomeVFSResult gnome_vfs_monitor_add        (GnomeVFSMonitorHandle **handle,
+                                             const gchar *text_uri,
+                                             GnomeVFSMonitorType monitor_type,
+                                             GnomeVFSMonitorCallback callback,
+                                             gpointer user_data);

+Watch the file or directory at text_uri for changes (or the creation/deletion of the file) +and call callback when there is a change. If a directory monitor is added, callback is +notified when any file in the directory changes.

+ +

handle : after the call, handle will be a pointer to an operation handle +
text_uri : URI to monitor +
monitor_type : add a directory or file monitor +
callback : function to call when the monitor is tripped +
user_data : data to pass to callback +
Returns : an integer representing the success of the operation +

gnome_vfs_monitor_cancel ()

GnomeVFSResult gnome_vfs_monitor_cancel     (GnomeVFSMonitorHandle *handle);

+Cancel the monitor pointed to be handle.

+ +

handle : handle of the monitor to cancel +
Returns : an integer representing the success of the operation +

enum GnomeVFSMonitorType

typedef enum {
+  GNOME_VFS_MONITOR_FILE,
+  GNOME_VFS_MONITOR_DIRECTORY
+} GnomeVFSMonitorType;
+

+Type of resources that can be monitored.

+ +


enum GnomeVFSMonitorEventType

typedef enum {
+  GNOME_VFS_MONITOR_EVENT_CHANGED,
+  GNOME_VFS_MONITOR_EVENT_DELETED,
+  GNOME_VFS_MONITOR_EVENT_STARTEXECUTING,
+  GNOME_VFS_MONITOR_EVENT_STOPEXECUTING,
+  GNOME_VFS_MONITOR_EVENT_CREATED,
+  GNOME_VFS_MONITOR_EVENT_METADATA_CHANGED
+} GnomeVFSMonitorEventType;
+

+Types of events that can be monitored.

+ +

GNOME_VFS_MONITOR_EVENT_CHANGED file data changed +
GNOME_VFS_MONITOR_EVENT_DELETED file deleted event +
GNOME_VFS_MONITOR_EVENT_STARTEXECUTING +
GNOME_VFS_MONITOR_EVENT_STOPEXECUTING +
GNOME_VFS_MONITOR_EVENT_CREATED file created event +
GNOME_VFS_MONITOR_EVENT_METADATA_CHANGED file metadata changed +

GnomeVFSMonitorCallback ()

void        (*GnomeVFSMonitorCallback)      (GnomeVFSMonitorHandle *handle,
+                                             const gchar *monitor_uri,
+                                             const gchar *info_uri,
+                                             GnomeVFSMonitorEventType event_type,
+                                             gpointer user_data);

+Function called when a monitor detects a change.

+ +

handle : the handle of the monitor that created the event +
monitor_uri : the URI of the monitor that was triggered +
info_uri : the URI of the actual file this event is concerned with (this can be different +from monitor_uri if it was a directory monitor) +
event_type : what happened to info_uri +
user_data : user data passed to gnome_vfs_monitor_add() when the monitor was created +
diff --git a/doc/html/gnome-vfs-gnome-vfs-ops.html b/doc/html/gnome-vfs-gnome-vfs-ops.html new file mode 100644 index 0000000..717cb91 --- /dev/null +++ b/doc/html/gnome-vfs-gnome-vfs-ops.html @@ -0,0 +1,3817 @@ +File Operations
GnomeVFS - Filesystem Abstraction library

File Operations

Name

File Operations -- basic POSIX-style file operations

Synopsis


+
+GnomeVFSResult gnome_vfs_open               (GnomeVFSHandle **handle,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode);
+GnomeVFSResult gnome_vfs_open_uri           (GnomeVFSHandle **handle,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode);
+GnomeVFSResult gnome_vfs_create             (GnomeVFSHandle **handle,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm);
+GnomeVFSResult gnome_vfs_create_uri         (GnomeVFSHandle **handle,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm);
+GnomeVFSResult gnome_vfs_close              (GnomeVFSHandle *handle);
+GnomeVFSResult gnome_vfs_read               (GnomeVFSHandle *handle,
+                                             gpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_read);
+GnomeVFSResult gnome_vfs_write              (GnomeVFSHandle *handle,
+                                             gconstpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_written);
+GnomeVFSResult gnome_vfs_seek               (GnomeVFSHandle *handle,
+                                             GnomeVFSSeekPosition whence,
+                                             GnomeVFSFileOffset offset);
+GnomeVFSResult gnome_vfs_tell               (GnomeVFSHandle *handle,
+                                             GnomeVFSFileSize *offset_return);
+GnomeVFSResult gnome_vfs_get_file_info      (const gchar *text_uri,
+                                             GnomeVFSFileInfo *info,
+                                             GnomeVFSFileInfoOptions options);
+GnomeVFSResult gnome_vfs_get_file_info_uri  (GnomeVFSURI *uri,
+                                             GnomeVFSFileInfo *info,
+                                             GnomeVFSFileInfoOptions options);
+GnomeVFSResult gnome_vfs_get_file_info_from_handle
+                                            (GnomeVFSHandle *handle,
+                                             GnomeVFSFileInfo *info,
+                                             GnomeVFSFileInfoOptions options);
+GnomeVFSResult gnome_vfs_truncate           (const gchar *text_uri,
+                                             GnomeVFSFileSize length);
+GnomeVFSResult gnome_vfs_truncate_uri       (GnomeVFSURI *uri,
+                                             GnomeVFSFileSize length);
+GnomeVFSResult gnome_vfs_truncate_handle    (GnomeVFSHandle *handle,
+                                             GnomeVFSFileSize length);
+GnomeVFSResult gnome_vfs_unlink_from_uri    (GnomeVFSURI *uri);
+GnomeVFSResult gnome_vfs_create_symbolic_link
+                                            (GnomeVFSURI *uri,
+                                             const gchar *target_reference);
+GnomeVFSResult gnome_vfs_unlink             (const gchar *text_uri);
+GnomeVFSResult gnome_vfs_move_uri           (GnomeVFSURI *old_uri,
+                                             GnomeVFSURI *new_uri,
+                                             gboolean force_replace);
+GnomeVFSResult gnome_vfs_move               (const gchar *old_text_uri,
+                                             const gchar *new_text_uri,
+                                             gboolean force_replace);
+GnomeVFSResult gnome_vfs_check_same_fs_uris (GnomeVFSURI *source_uri,
+                                             GnomeVFSURI *target_uri,
+                                             gboolean *same_fs_return);
+GnomeVFSResult gnome_vfs_check_same_fs      (const gchar *source,
+                                             const gchar *target,
+                                             gboolean *same_fs_return);
+gboolean    gnome_vfs_uri_exists            (GnomeVFSURI *uri);
+GnomeVFSResult gnome_vfs_set_file_info_uri  (GnomeVFSURI *uri,
+                                             GnomeVFSFileInfo *info,
+                                             GnomeVFSSetFileInfoMask mask);
+GnomeVFSResult gnome_vfs_set_file_info      (const gchar *text_uri,
+                                             GnomeVFSFileInfo *info,
+                                             GnomeVFSSetFileInfoMask mask);
+typedef     GnomeVFSMethodHandle;
+enum        GnomeVFSOpenMode;
+enum        GnomeVFSSeekPosition;

Description

Details

gnome_vfs_open ()

GnomeVFSResult gnome_vfs_open               (GnomeVFSHandle **handle,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode);

Open text_uri according to mode open_mode. On return, handle will then +contain a pointer to a handle for the open file.

handle :

A pointer to a pointer to a GnomeVFSHandle object

text_uri :

String representing the URI to open

open_mode :

Open mode

Returns :

An integer representing the result of the operation


gnome_vfs_open_uri ()

GnomeVFSResult gnome_vfs_open_uri           (GnomeVFSHandle **handle,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode);

Open uri according to mode open_mode. On return, handle will then +contain a pointer to a handle for the open file.

handle :

A pointer to a pointer to a GnomeVFSHandle object

uri :

URI to open

open_mode :

Open mode

Returns :

An integer representing the result of the operation


gnome_vfs_create ()

GnomeVFSResult gnome_vfs_create             (GnomeVFSHandle **handle,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm);

Create uri according to mode open_mode. On return, handle will then +contain a pointer to a handle for the open file.

handle :

A pointer to a pointer to a GnomeVFSHandle object

text_uri :

String representing the URI to create

open_mode :

mode to leave the file opened in after creation (or GNOME_VFS_OPEN_MODE_NONE +to leave the file closed after creation)

exclusive :

Whether the file should be created in "exclusive" mode: +i.e. if this flag is nonzero, operation will fail if a file with the +same name already exists.

perm :

Bitmap representing the permissions for the newly created file +(Unix style).

Returns :

An integer representing the result of the operation


gnome_vfs_create_uri ()

GnomeVFSResult gnome_vfs_create_uri         (GnomeVFSHandle **handle,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm);

Create uri according to mode open_mode. On return, handle will then +contain a pointer to a handle for the open file.

handle :

A pointer to a pointer to a GnomeVFSHandle object

uri :

URI for the file to create

open_mode :

Open mode

exclusive :

Whether the file should be created in "exclusive" mode: +i.e. if this flag is nonzero, operation will fail if a file with the +same name already exists.

perm :

Bitmap representing the permissions for the newly created file +(Unix style).

Returns :

An integer representing the result of the operation


gnome_vfs_close ()

GnomeVFSResult gnome_vfs_close              (GnomeVFSHandle *handle);

Close file associated with handle.

handle :

A pointer to a GnomeVFSHandle object

Returns :

An integer representing the result of the operation.


gnome_vfs_read ()

GnomeVFSResult gnome_vfs_read               (GnomeVFSHandle *handle,
+                                             gpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_read);

Read bytes from handle. As with Unix system calls, the number of +bytes read can effectively be less than bytes on return and will be +stored in bytes_read.

handle :

Handle of the file to read data from

buffer :

Pointer to a buffer that must be at least bytes bytes large

bytes :

Number of bytes to read

bytes_read :

Pointer to a variable that will hold the number of bytes +effectively read on return.

Returns :

An integer representing the result of the operation


gnome_vfs_write ()

GnomeVFSResult gnome_vfs_write              (GnomeVFSHandle *handle,
+                                             gconstpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_written);

Write bytes into the file opened through handle. As with Unix system +calls, the number of bytes written can effectively be less than bytes on +return and will be stored in bytes_written.

handle :

Handle of the file to write data to

buffer :

Pointer to the buffer containing the data to be written

bytes :

Number of bytes to write

bytes_written :

Pointer to a variable that will hold the number of bytes +effectively written on return.

Returns :

An integer representing the result of the operation


gnome_vfs_seek ()

GnomeVFSResult gnome_vfs_seek               (GnomeVFSHandle *handle,
+                                             GnomeVFSSeekPosition whence,
+                                             GnomeVFSFileOffset offset);

Set the current position for reading/writing through handle.

handle :

Handle for which the current position must be changed

whence :

Integer value representing the starting position

offset :

Number of bytes to skip from the position specified by whence +(a positive value means to move forward; a negative one to move backwards)

Returns :


gnome_vfs_tell ()

GnomeVFSResult gnome_vfs_tell               (GnomeVFSHandle *handle,
+                                             GnomeVFSFileSize *offset_return);

Return the current position on handle. This is the point in the file +pointed to by handle that reads and writes will occur on.

handle :

Handle for which the current position must be retrieved

offset_return :

Pointer to a variable that will contain the current position +on return

Returns :

An integer representing the result of the operation


gnome_vfs_get_file_info ()

GnomeVFSResult gnome_vfs_get_file_info      (const gchar *text_uri,
+                                             GnomeVFSFileInfo *info,
+                                             GnomeVFSFileInfoOptions options);

Retrieve information about text_uri. The information will be stored in +info.

text_uri :

URI of the file for which information will be retrieved

info :

Pointer to a GnomeVFSFileInfo object that will hold the information +for the file on return

options :

Options for retrieving file information +to retrieve for the file

Returns :

An integer representing the result of the operation


gnome_vfs_get_file_info_uri ()

GnomeVFSResult gnome_vfs_get_file_info_uri  (GnomeVFSURI *uri,
+                                             GnomeVFSFileInfo *info,
+                                             GnomeVFSFileInfoOptions options);

Retrieve information about text_uri. The information will be stored in +info.

uri :

URI of the file for which information will be retrieved

info :

Pointer to a GnomeVFSFileInfo object that will hold the information +for the file on return

options :

Options for retrieving file information +to retrieve for the file

Returns :

An integer representing the result of the operation


gnome_vfs_get_file_info_from_handle ()

GnomeVFSResult gnome_vfs_get_file_info_from_handle
+                                            (GnomeVFSHandle *handle,
+                                             GnomeVFSFileInfo *info,
+                                             GnomeVFSFileInfoOptions options);

Retrieve information about an open file. The information will be stored in +info.

handle :

Handle of the file for which information must be retrieved

info :

Pointer to a GnomeVFSFileInfo object that will hold the information +for the file on return

options :

Options for retrieving file information +to retrieve for the file

Returns :

An integer representing the result of the operation


gnome_vfs_truncate ()

GnomeVFSResult gnome_vfs_truncate           (const gchar *text_uri,
+                                             GnomeVFSFileSize length);

Truncate the file at text_uri to length bytes.

text_uri :

URI of the file to be truncated

length :

length of the new file at text_uri

Returns :

An integer representing the result of the operation


gnome_vfs_truncate_uri ()

GnomeVFSResult gnome_vfs_truncate_uri       (GnomeVFSURI *uri,
+                                             GnomeVFSFileSize length);

Truncate the file at uri to be only length bytes. Data past length +bytes will be discarded.

uri :

URI of the file to be truncated

length :

length of the new file at uri

Returns :

An integer representing the result of the operation


gnome_vfs_truncate_handle ()

GnomeVFSResult gnome_vfs_truncate_handle    (GnomeVFSHandle *handle,
+                                             GnomeVFSFileSize length);

Truncate the file pointed to be handle to be only length bytes. +Data past length bytes will be discarded.

handle :

a handle to the file to be truncated

length :

length of the new file the handle is open to

Returns :

An integer representing the result of the operation


gnome_vfs_unlink_from_uri ()

GnomeVFSResult gnome_vfs_unlink_from_uri    (GnomeVFSURI *uri);

Unlink uri (i.e. delete the file).

uri :

URI of the file to be unlinked

Returns :

An integer representing the result of the operation


gnome_vfs_create_symbolic_link ()

GnomeVFSResult gnome_vfs_create_symbolic_link
+                                            (GnomeVFSURI *uri,
+                                             const gchar *target_reference);

Creates a symbolic link, or eventually, a URI link (as necessary) +at uri pointing to target_reference

uri :

URI to create a link at

target_reference :

URI "reference" to point the link to (URI or relative path)

Returns :

An integer representing the result of the operation


gnome_vfs_unlink ()

GnomeVFSResult gnome_vfs_unlink             (const gchar *text_uri);

Unlink text_uri (i.e. delete the file).

text_uri :

URI of the file to be unlinked

Returns :

An integer representing the result of the operation


gnome_vfs_move_uri ()

GnomeVFSResult gnome_vfs_move_uri           (GnomeVFSURI *old_uri,
+                                             GnomeVFSURI *new_uri,
+                                             gboolean force_replace);

Move a file from URI old_uri to new_uri. This will only work if old_uri +and new_uri are on the same file system. Otherwise, it is necessary +to use the more general %gnome_vfs_xfer_uri() function.

old_uri :

Source URI

new_uri :

Destination URI

force_replace :

If TRUE, move target to new_uri even if there +is already a file at new_uri. If there is a file, it will be discarded.

Returns :

An integer representing the result of the operation.


gnome_vfs_move ()

GnomeVFSResult gnome_vfs_move               (const gchar *old_text_uri,
+                                             const gchar *new_text_uri,
+                                             gboolean force_replace);

Move a file from URI old_text_uri to new_text_uri. This will only work +if old_text_uri and new_text_uri are on the same file system. Otherwise, +it is necessary to use the more general %gnome_vfs_xfer_uri() function.

old_text_uri :

Source URI

new_text_uri :

Destination URI

force_replace :

if TRUE, perform the operation even if it unlinks an existing +file at new_text_uri

Returns :

An integer representing the result of the operation.


gnome_vfs_check_same_fs_uris ()

GnomeVFSResult gnome_vfs_check_same_fs_uris (GnomeVFSURI *source_uri,
+                                             GnomeVFSURI *target_uri,
+                                             gboolean *same_fs_return);

Check if source_uri and target_uri are on the same file system.

source_uri :

A URI

target_uri :

Another URI

same_fs_return :

Pointer to a boolean variable which will be set to TRUE +if source_uri and target_uri are on the same file system on return.

Returns :

An integer representing the result of the operation.


gnome_vfs_check_same_fs ()

GnomeVFSResult gnome_vfs_check_same_fs      (const gchar *source,
+                                             const gchar *target,
+                                             gboolean *same_fs_return);

Return TRUE if source and target are on the same file system.

source :

A URI

target :

Another URI

same_fs_return :

Pointer to a boolean variable which will be set to TRUE

Returns :

An integer representing the result of the operation.


gnome_vfs_uri_exists ()

gboolean    gnome_vfs_uri_exists            (GnomeVFSURI *uri);

Check if the URI points to an existing entity.

uri :

A URI

Returns :

TRUE if URI exists.


gnome_vfs_set_file_info_uri ()

GnomeVFSResult gnome_vfs_set_file_info_uri  (GnomeVFSURI *uri,
+                                             GnomeVFSFileInfo *info,
+                                             GnomeVFSSetFileInfoMask mask);

Set file information for uri; only the information for which the +corresponding bit in mask is set is actually modified.

uri :

A URI

info :

Information that must be set for the file

mask :

Bit mask representing which fields of info need to be set

Returns :

An integer representing the result of the operation.


gnome_vfs_set_file_info ()

GnomeVFSResult gnome_vfs_set_file_info      (const gchar *text_uri,
+                                             GnomeVFSFileInfo *info,
+                                             GnomeVFSSetFileInfoMask mask);

Set file information for uri; only the information for which the +corresponding bit in mask is set is actually modified.

text_uri :

A URI

info :

Information that must be set for the file

mask :

Bit mask representing which fields of info need to be set

Returns :

An integer representing the result of the operation.


GnomeVFSMethodHandle

typedef gpointer GnomeVFSMethodHandle;


enum GnomeVFSOpenMode

typedef enum {
+        GNOME_VFS_OPEN_NONE = 0,
+        GNOME_VFS_OPEN_READ = 1 << 0,
+        GNOME_VFS_OPEN_WRITE = 1 << 1,
+        GNOME_VFS_OPEN_RANDOM = 1 << 2
+} GnomeVFSOpenMode;


enum GnomeVFSSeekPosition

typedef enum {
+        GNOME_VFS_SEEK_START,
+        GNOME_VFS_SEEK_CURRENT,
+        GNOME_VFS_SEEK_END
+} GnomeVFSSeekPosition;

<<< Initialization/ShutdownAsynchronous File Operations >>>
\ No newline at end of file diff --git a/doc/html/gnome-vfs-gnome-vfs-parse-ls.html b/doc/html/gnome-vfs-gnome-vfs-parse-ls.html new file mode 100644 index 0000000..16a86ad --- /dev/null +++ b/doc/html/gnome-vfs-gnome-vfs-parse-ls.html @@ -0,0 +1,53 @@ +gnome-vfs-parse-ls

gnome-vfs-parse-ls

gnome-vfs-parse-ls —

Synopsis

+
+
+
+int         gnome_vfs_parse_ls_lga          (const char *p,
+                                             struct stat *s,
+                                             char **filename,
+                                             char **linkname);
+

Description

+ +

Details

gnome_vfs_parse_ls_lga ()

int         gnome_vfs_parse_ls_lga          (const char *p,
+                                             struct stat *s,
+                                             char **filename,
+                                             char **linkname);

+ +

p : +
s : +
filename : +
linkname : +
Returns : + + +
diff --git a/doc/html/gnome-vfs-gnome-vfs-result.html b/doc/html/gnome-vfs-gnome-vfs-result.html new file mode 100644 index 0000000..dea6e85 --- /dev/null +++ b/doc/html/gnome-vfs-gnome-vfs-result.html @@ -0,0 +1,125 @@ + +GnomeVFSResult

+GnomeVFSResult

+GnomeVFSResult — +Result of I/O operations, the equivalent of errno

Description

+ +

Details

enum GnomeVFSResult

typedef enum {
+	GNOME_VFS_OK,
+	GNOME_VFS_ERROR_NOT_FOUND,
+	GNOME_VFS_ERROR_GENERIC,
+	GNOME_VFS_ERROR_INTERNAL,
+	GNOME_VFS_ERROR_BAD_PARAMETERS,
+	GNOME_VFS_ERROR_NOT_SUPPORTED,
+	GNOME_VFS_ERROR_IO,
+	GNOME_VFS_ERROR_CORRUPTED_DATA,
+	GNOME_VFS_ERROR_WRONG_FORMAT,
+	GNOME_VFS_ERROR_BAD_FILE,
+	GNOME_VFS_ERROR_TOO_BIG,
+	GNOME_VFS_ERROR_NO_SPACE,
+	GNOME_VFS_ERROR_READ_ONLY,
+	GNOME_VFS_ERROR_INVALID_URI,
+	GNOME_VFS_ERROR_NOT_OPEN,
+	GNOME_VFS_ERROR_INVALID_OPEN_MODE,
+	GNOME_VFS_ERROR_ACCESS_DENIED,
+	GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES,
+	GNOME_VFS_ERROR_EOF,
+	GNOME_VFS_ERROR_NOT_A_DIRECTORY,
+	GNOME_VFS_ERROR_IN_PROGRESS,
+	GNOME_VFS_ERROR_INTERRUPTED,
+	GNOME_VFS_ERROR_FILE_EXISTS,
+	GNOME_VFS_ERROR_LOOP,
+	GNOME_VFS_ERROR_NOT_PERMITTED,
+	GNOME_VFS_ERROR_IS_DIRECTORY,
+	GNOME_VFS_ERROR_NO_MEMORY,
+	GNOME_VFS_ERROR_HOST_NOT_FOUND,
+	GNOME_VFS_ERROR_INVALID_HOST_NAME,
+	GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS,
+	GNOME_VFS_ERROR_LOGIN_FAILED,
+	GNOME_VFS_ERROR_CANCELLED,
+	GNOME_VFS_ERROR_DIRECTORY_BUSY,
+	GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY,
+	GNOME_VFS_ERROR_TOO_MANY_LINKS,
+	GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM,
+	GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM,
+	GNOME_VFS_ERROR_NAME_TOO_LONG,
+	GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE,
+	GNOME_VFS_ERROR_SERVICE_OBSOLETE,
+	GNOME_VFS_ERROR_PROTOCOL_ERROR,
+	GNOME_VFS_ERROR_NO_MASTER_BROWSER,
+	GNOME_VFS_ERROR_NO_DEFAULT,
+	GNOME_VFS_ERROR_NO_HANDLER,
+	GNOME_VFS_ERROR_PARSE,
+	GNOME_VFS_ERROR_LAUNCH,
+	GNOME_VFS_NUM_ERRORS
+} GnomeVFSResult;
+

+ +


gnome_vfs_result_to_string ()

const char* gnome_vfs_result_to_string      (GnomeVFSResult result);

+Returns a string representation of result, useful for debugging +purposes, but probably not appropriate for passing to the user.

+ +

result : the result to convert to a string +
Returns : a string representing result +

gnome_vfs_result_from_errno_code ()

GnomeVFSResult gnome_vfs_result_from_errno_code
+                                            (int errno_code);

+Converts a system errno value to a GnomeVFSResult.

+ +

errno_code : integer of the same type as the system "errno" +
Returns : a GnomeVFSResult equivalent to errno_code +

gnome_vfs_result_from_errno ()

GnomeVFSResult gnome_vfs_result_from_errno  (void);

+Converts the system errno to a GnomeVFSResult.

+ +

Returns : a GnomeVFSResult equivalent to the current system errno +

gnome_vfs_result_from_h_errno ()

GnomeVFSResult gnome_vfs_result_from_h_errno
+                                            (void);

+Converts the system "h_errno" to a GnomeVFSResult (h_errno represents errors +accessing and finding internet hosts)

+ +

Returns : a GnomeVFSResult equivalent to the current system "h_errno" +
diff --git a/doc/html/gnome-vfs-gnome-vfs-socket-buffer.html b/doc/html/gnome-vfs-gnome-vfs-socket-buffer.html new file mode 100644 index 0000000..e4738b9 --- /dev/null +++ b/doc/html/gnome-vfs-gnome-vfs-socket-buffer.html @@ -0,0 +1,127 @@ +gnome-vfs-socket-buffer

gnome-vfs-socket-buffer

gnome-vfs-socket-buffer —

Synopsis

+
+
+
+GnomeVFSSocketBuffer* gnome_vfs_socket_buffer_new
+                                            (GnomeVFSSocket *socket);
+GnomeVFSResult gnome_vfs_socket_buffer_destroy
+                                            (GnomeVFSSocketBuffer *socket_buffer,
+                                             gboolean close_socket);
+GnomeVFSResult gnome_vfs_socket_buffer_read (GnomeVFSSocketBuffer *socket_buffer,
+                                             gpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_read);
+GnomeVFSResult gnome_vfs_socket_buffer_peekc
+                                            (GnomeVFSSocketBuffer *socket_buffer,
+                                             char *character);
+GnomeVFSResult gnome_vfs_socket_buffer_write
+                                            (GnomeVFSSocketBuffer *socket_buffer,
+                                             gconstpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_written);
+GnomeVFSResult gnome_vfs_socket_buffer_flush
+                                            (GnomeVFSSocketBuffer *socket_buffer);
+

Description

+ +

Details

gnome_vfs_socket_buffer_new ()

GnomeVFSSocketBuffer* gnome_vfs_socket_buffer_new
+                                            (GnomeVFSSocket *socket);

+Create a socket buffer around socket. A buffered +socket allows data to be poked at without reading it +as it will be buffered. A future read will retrieve +the data again.

+ +

socket : socket to be buffered +
Returns : a newly allocated GnomeVFSSocketBuffer +

gnome_vfs_socket_buffer_destroy ()

GnomeVFSResult gnome_vfs_socket_buffer_destroy
+                                            (GnomeVFSSocketBuffer *socket_buffer,
+                                             gboolean close_socket);

+Free the socket buffer.

+ +

socket_buffer : buffered socket to destray +
close_socket : if TRUE the socket being buffered will be closed too +
Returns : GnomeVFSResult indicating the success of the operation +

gnome_vfs_socket_buffer_read ()

GnomeVFSResult gnome_vfs_socket_buffer_read (GnomeVFSSocketBuffer *socket_buffer,
+                                             gpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_read);

+Read bytes bytes of data from the socket into socket_buffer.

+ +

socket_buffer : buffered socket to read data from +
buffer : allocated buffer of at least bytes bytes to be read into +
bytes : number of bytes to read from socket into socket_buffer +
bytes_read : pointer to a GnomeVFSFileSize, will contain +the number of bytes actually read from the socket on return. +
Returns : GnomeVFSResult indicating the success of the operation +

gnome_vfs_socket_buffer_peekc ()

GnomeVFSResult gnome_vfs_socket_buffer_peekc
+                                            (GnomeVFSSocketBuffer *socket_buffer,
+                                             char *character);

+Peek at the next character in socket_buffer without actually reading +the character in. The next read will retrieve c (as well as any following +data if requested).

+ +

socket_buffer : the socket buffer to read from +
character : pointer to a char, will contain a character on return from +a successful "peek" +
Returns : GnomeVFSResult indicating the success of the operation +

gnome_vfs_socket_buffer_write ()

GnomeVFSResult gnome_vfs_socket_buffer_write
+                                            (GnomeVFSSocketBuffer *socket_buffer,
+                                             gconstpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_written);

+Write bytes bytes of data from buffer to socket_buffer.

+ +

socket_buffer : buffered socket to write data to +
buffer : data to write to the socket +
bytes : number of bytes from buffer to write to socket_buffer +
bytes_written : pointer to a GnomeVFSFileSize, will contain +the number of bytes actually written to the socket on return. +
Returns : GnomeVFSResult indicating the success of the operation +

gnome_vfs_socket_buffer_flush ()

GnomeVFSResult gnome_vfs_socket_buffer_flush
+                                            (GnomeVFSSocketBuffer *socket_buffer);

+Write all outstanding data to socket_buffer.

+ +

socket_buffer : buffer to flush +
Returns : GnomeVFSResult indicating the success of the operation +
diff --git a/doc/html/gnome-vfs-gnome-vfs-socket.html b/doc/html/gnome-vfs-gnome-vfs-socket.html new file mode 100644 index 0000000..df8ec16 --- /dev/null +++ b/doc/html/gnome-vfs-gnome-vfs-socket.html @@ -0,0 +1,163 @@ +gnome-vfs-socket

gnome-vfs-socket

gnome-vfs-socket —

Synopsis

+
+
+
+GnomeVFSResult (*GnomeVFSSocketReadFunc)    (gpointer connection,
+                                             gpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_read);
+GnomeVFSResult (*GnomeVFSSocketWriteFunc)   (gpointer connection,
+                                             gconstpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_written);
+void        (*GnomeVFSSocketCloseFunc)      (gpointer connection);
+typedef     GnomeVFSSocketImpl;
+GnomeVFSSocket* gnome_vfs_socket_new        (GnomeVFSSocketImpl *impl,
+                                             void *connection);
+GnomeVFSResult gnome_vfs_socket_write       (GnomeVFSSocket *socket,
+                                             gconstpointer buffer,
+                                             int bytes,
+                                             GnomeVFSFileSize *bytes_written);
+GnomeVFSResult gnome_vfs_socket_close       (GnomeVFSSocket *socket);
+GnomeVFSResult gnome_vfs_socket_read        (GnomeVFSSocket *socket,
+                                             gpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_read);
+

Description

+ +

Details

GnomeVFSSocketReadFunc ()

GnomeVFSResult (*GnomeVFSSocketReadFunc)    (gpointer connection,
+                                             gpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_read);

+ +

connection : +
buffer : +
bytes : +
bytes_read : +
Returns : + + +

GnomeVFSSocketWriteFunc ()

GnomeVFSResult (*GnomeVFSSocketWriteFunc)   (gpointer connection,
+                                             gconstpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_written);

+ +

connection : +
buffer : +
bytes : +
bytes_written : +
Returns : + + +

GnomeVFSSocketCloseFunc ()

void        (*GnomeVFSSocketCloseFunc)      (gpointer connection);

+ +

connection : + + +

GnomeVFSSocketImpl

typedef struct {
+  GnomeVFSSocketReadFunc read;
+  GnomeVFSSocketWriteFunc write;
+  GnomeVFSSocketCloseFunc close;
+} GnomeVFSSocketImpl;
+

+ +


gnome_vfs_socket_new ()

GnomeVFSSocket* gnome_vfs_socket_new        (GnomeVFSSocketImpl *impl,
+                                             void *connection);

+Creates a new GnomeVFS Socket using the specific implementation +impl.

+ +

impl : an implementation of a socket, e.g. GnomeVFSSSL +
connection : pointer to a connection object used by impl to track +state (the exact nature of connection varies from implementation to +implementation) +
Returns : a newly created socket +

gnome_vfs_socket_write ()

GnomeVFSResult gnome_vfs_socket_write       (GnomeVFSSocket *socket,
+                                             gconstpointer buffer,
+                                             int bytes,
+                                             GnomeVFSFileSize *bytes_written);

+Write bytes bytes of data from buffer to socket.

+ +

socket : socket to write data to +
buffer : data to write to the socket +
bytes : number of bytes from buffer to write to socket +
bytes_written : pointer to a GnomeVFSFileSize, will contain +the number of bytes actually written to the socket on return. +
Returns : GnomeVFSResult indicating the success of the operation +

gnome_vfs_socket_close ()

GnomeVFSResult gnome_vfs_socket_close       (GnomeVFSSocket *socket);

+Close socket, freeing any resources it may be using.

+ +

socket : the socket to be closed +
Returns : GnomeVFSResult indicating the success of the operation +

gnome_vfs_socket_read ()

GnomeVFSResult gnome_vfs_socket_read        (GnomeVFSSocket *socket,
+                                             gpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_read);

+Read bytes bytes of data from the socket into buffer.

+ +

socket : socket to read data from +
buffer : allocated buffer of at least bytes bytes to be read into +
bytes : number of bytes to read from socket into buffer +
bytes_read : pointer to a GnomeVFSFileSize, will contain +the number of bytes actually read from the socket on return. +
Returns : GnomeVFSResult indicating the success of the operation +
diff --git a/doc/html/gnome-vfs-gnome-vfs-ssl.html b/doc/html/gnome-vfs-gnome-vfs-ssl.html new file mode 100644 index 0000000..02c24d9 --- /dev/null +++ b/doc/html/gnome-vfs-gnome-vfs-ssl.html @@ -0,0 +1,128 @@ +gnome-vfs-ssl

gnome-vfs-ssl

gnome-vfs-ssl —

Synopsis

+
+
+
+gboolean    gnome_vfs_ssl_enabled           (void);
+GnomeVFSResult gnome_vfs_ssl_create         (GnomeVFSSSL **handle_return,
+                                             const char *host,
+                                             unsigned int port);
+GnomeVFSResult gnome_vfs_ssl_create_from_fd (GnomeVFSSSL **handle_return,
+                                             gint fd);
+GnomeVFSResult gnome_vfs_ssl_read           (GnomeVFSSSL *ssl,
+                                             gpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_read);
+GnomeVFSResult gnome_vfs_ssl_write          (GnomeVFSSSL *ssl,
+                                             gconstpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_written);
+void        gnome_vfs_ssl_destroy           (GnomeVFSSSL *ssl);
+GnomeVFSSocket* gnome_vfs_ssl_to_socket     (GnomeVFSSSL *ssl);
+

Description

+ +

Details

gnome_vfs_ssl_enabled ()

gboolean    gnome_vfs_ssl_enabled           (void);

+Checks whether GnomeVFS was compiled with SSL support.

+ +

Returns : TRUE if GnomeVFS was compiled with SSL support, +otherwise FALSE. +

gnome_vfs_ssl_create ()

GnomeVFSResult gnome_vfs_ssl_create         (GnomeVFSSSL **handle_return,
+                                             const char *host,
+                                             unsigned int port);

+Creates an SSL socket connection at handle_return to host using +port port.

+ +

handle_return : pointer to a GnmoeVFSSSL struct, which will +contain an allocated GnomeVFSSSL object on return. +
host : string indicating the host to establish an SSL connection with +
port : the port number to connect to +
Returns : GnomeVFSResult indicating the success of the operation +

gnome_vfs_ssl_create_from_fd ()

GnomeVFSResult gnome_vfs_ssl_create_from_fd (GnomeVFSSSL **handle_return,
+                                             gint fd);

+Try to establish an SSL connection over the file descriptor fd.

+ +

handle_return : pointer to a GnmoeVFSSSL struct, which will +contain an allocated GnomeVFSSSL object on return. +
fd : file descriptior to try and establish an SSL connection over +
Returns : a GnomeVFSResult indicating the success of the operation +

gnome_vfs_ssl_read ()

GnomeVFSResult gnome_vfs_ssl_read           (GnomeVFSSSL *ssl,
+                                             gpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_read);

+Read bytes bytes of data from the SSL socket ssl into buffer.

+ +

ssl : SSL socket to read data from +
buffer : allocated buffer of at least bytes bytes to be read into +
bytes : number of bytes to read from ssl into buffer +
bytes_read : pointer to a GnomeVFSFileSize, will contain +the number of bytes actually read from the socket on return. +
Returns : GnomeVFSResult indicating the success of the operation +

gnome_vfs_ssl_write ()

GnomeVFSResult gnome_vfs_ssl_write          (GnomeVFSSSL *ssl,
+                                             gconstpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_written);

+Write bytes bytes of data from buffer to ssl.

+ +

ssl : SSL socket to write data to +
buffer : data to write to the socket +
bytes : number of bytes from buffer to write to ssl +
bytes_written : pointer to a GnomeVFSFileSize, will contain +the number of bytes actually written to the socket on return. +
Returns : GnomeVFSResult indicating the success of the operation +

gnome_vfs_ssl_destroy ()

void        gnome_vfs_ssl_destroy           (GnomeVFSSSL *ssl);

+Free resources used by ssl and close the connection.

+ +

ssl : SSL socket to be closed and destroyed +

gnome_vfs_ssl_to_socket ()

GnomeVFSSocket* gnome_vfs_ssl_to_socket     (GnomeVFSSSL *ssl);

+Wrapper an SSL socket inside a standard GnomeVFSSocket.

+ +

ssl : SSL socket to convert into a standard socket +
Returns : a newly allocated GnomeVFSSocket corresponding to ssl. +
diff --git a/doc/html/gnome-vfs-gnome-vfs-standard-callbacks.html b/doc/html/gnome-vfs-gnome-vfs-standard-callbacks.html new file mode 100644 index 0000000..b5dc32d --- /dev/null +++ b/doc/html/gnome-vfs-gnome-vfs-standard-callbacks.html @@ -0,0 +1,140 @@ +gnome-vfs-standard-callbacks

gnome-vfs-standard-callbacks

gnome-vfs-standard-callbacks —

Description

+ +

Details

GNOME_VFS_MODULE_CALLBACK_AUTHENTICATION

#define GNOME_VFS_MODULE_CALLBACK_AUTHENTICATION "simple-authentication"
+

+ +


GNOME_VFS_MODULE_CALLBACK_HTTP_PROXY_AUTHENTICATION

#define GNOME_VFS_MODULE_CALLBACK_HTTP_PROXY_AUTHENTICATION "http:proxy-authentication"
+

+ +


GnomeVFSModuleCallbackAuthenticationOut

typedef struct {
+	char *username;		/* will be freed by g_free,
+				 * NULL indicates no auth should be provided;
+				 * if the request requires authn, the operation
+				 * will fail with a GNOME_VFS_ERROR_ACCESS_DENIED
+				 * code
+				 */
+	char *password;		/* will be freed by g_free */
+
+	/* Reserved "padding" to avoid future breaks in ABI compatibility */
+	void *reserved1;
+	void *reserved2;
+
+} GnomeVFSModuleCallbackAuthenticationOut;
+

+ +


GNOME_VFS_MODULE_CALLBACK_HTTP_SEND_ADDITIONAL_HEADERS

#define GNOME_VFS_MODULE_CALLBACK_HTTP_SEND_ADDITIONAL_HEADERS "http:send-additional-headers"
+

+ +


GnomeVFSModuleCallbackAdditionalHeadersIn

typedef struct {
+	GnomeVFSURI *uri;		/* URI of operation */
+
+	/* Reserved "padding" to avoid future breaks in ABI compatibility */
+	void *reserved1;
+	void *reserved2;
+} GnomeVFSModuleCallbackAdditionalHeadersIn;
+

+ +


GnomeVFSModuleCallbackAdditionalHeadersOut

typedef struct {
+	GList *headers;			/* list of headers, will be freeed */
+
+	/* Reserved "padding" to avoid future breaks in ABI compatibility */
+	void *reserved1;
+	void *reserved2;
+} GnomeVFSModuleCallbackAdditionalHeadersOut;
+

+ +


GNOME_VFS_MODULE_CALLBACK_HTTP_RECEIVED_HEADERS

#define GNOME_VFS_MODULE_CALLBACK_HTTP_RECEIVED_HEADERS "http:received-headers"
+

+ +


GnomeVFSModuleCallbackReceivedHeadersIn

typedef struct {
+	GnomeVFSURI *uri;		/* URI of operation */
+	GList *headers;			/* list of headers */
+
+	/* Reserved "padding" to avoid future breaks in ABI compatibility */
+	void *reserved1;
+	void *reserved2;
+} GnomeVFSModuleCallbackReceivedHeadersIn;
+

+ +


GnomeVFSModuleCallbackReceivedHeadersOut

typedef struct {
+	int dummy;
+
+	/* Reserved "padding" to avoid future breaks in ABI compatibility */
+	void *reserved1;
+	void *reserved2;
+} GnomeVFSModuleCallbackReceivedHeadersOut;
+

+ +


GNOME_VFS_MODULE_CALLBACK_STATUS_MESSAGE

#define GNOME_VFS_MODULE_CALLBACK_STATUS_MESSAGE "status-message"
+

+ +


GnomeVFSModuleCallbackStatusMessageIn

typedef struct {
+	char *uri;		/* Full URI of operation */
+	char *message;		/* A message indicating the current state or
+				 * NULL if there is no message */
+	int percentage;		/* Percentage indicating completeness 0-100 or
+				 * -1 if there is no progress percentage to
+				 * report */
+
+	/* Reserved "padding" to avoid future breaks in ABI compatibility */
+	void *reserved1;
+	void *reserved2;
+} GnomeVFSModuleCallbackStatusMessageIn;
+

+ +


GnomeVFSModuleCallbackStatusMessageOut

typedef struct {
+	int dummy; /* empty structs not allowed */
+
+	/* Reserved "padding" to avoid future breaks in ABI compatibility */
+	void *reserved1;
+	void *reserved2;
+} GnomeVFSModuleCallbackStatusMessageOut;
+

+ +

diff --git a/doc/html/gnome-vfs-gnome-vfs-transform.html b/doc/html/gnome-vfs-gnome-vfs-transform.html new file mode 100644 index 0000000..1c8f547 --- /dev/null +++ b/doc/html/gnome-vfs-gnome-vfs-transform.html @@ -0,0 +1,65 @@ +gnome-vfs-transform

gnome-vfs-transform

gnome-vfs-transform —

Synopsis

+
+
+
+GnomeVFSTransform* (*GnomeVFSTransformInitFunc)
+                                            (const char *method_name,
+                                             const char *config_args);
+GnomeVFSResult (*GnomeVFSTransformFunc)     (GnomeVFSTransform *transform,
+                                             const char *old_uri,
+                                             char **new_uri,
+                                             GnomeVFSContext *context);
+

Description

+ +

Details

GnomeVFSTransformInitFunc ()

GnomeVFSTransform* (*GnomeVFSTransformInitFunc)
+                                            (const char *method_name,
+                                             const char *config_args);

+ +

method_name : +
config_args : +
Returns : + + +

GnomeVFSTransformFunc ()

GnomeVFSResult (*GnomeVFSTransformFunc)     (GnomeVFSTransform *transform,
+                                             const char *old_uri,
+                                             char **new_uri,
+                                             GnomeVFSContext *context);

+ +

transform : +
old_uri : +
new_uri : +
context : +
Returns : + + +
diff --git a/doc/html/gnome-vfs-gnome-vfs-uri.html b/doc/html/gnome-vfs-gnome-vfs-uri.html new file mode 100644 index 0000000..3ca5226 --- /dev/null +++ b/doc/html/gnome-vfs-gnome-vfs-uri.html @@ -0,0 +1,575 @@ + +GnomeVFSURI

+GnomeVFSURI

+GnomeVFSURI — +Functions for manipulating URIs

Synopsis

+
+
+
+typedef     GnomeVFSToplevelURI;
+enum        GnomeVFSURIHideOptions;
+#define     GNOME_VFS_URI_MAGIC_CHR
+#define     GNOME_VFS_URI_MAGIC_STR
+#define     GNOME_VFS_URI_PATH_CHR
+#define     GNOME_VFS_URI_PATH_STR
+GnomeVFSURI* gnome_vfs_uri_new              (const gchar *text_uri);
+GnomeVFSURI* gnome_vfs_uri_resolve_relative (const GnomeVFSURI *base,
+                                             const gchar *relative_reference);
+GnomeVFSURI* gnome_vfs_uri_ref              (GnomeVFSURI *uri);
+void        gnome_vfs_uri_unref             (GnomeVFSURI *uri);
+GnomeVFSURI* gnome_vfs_uri_append_string    (const GnomeVFSURI *uri,
+                                             const char *uri_fragment);
+GnomeVFSURI* gnome_vfs_uri_append_path      (const GnomeVFSURI *uri,
+                                             const char *path);
+GnomeVFSURI* gnome_vfs_uri_append_file_name (const GnomeVFSURI *uri,
+                                             const gchar *filename);
+gchar*      gnome_vfs_uri_to_string         (const GnomeVFSURI *uri,
+                                             GnomeVFSURIHideOptions hide_options);
+GnomeVFSURI* gnome_vfs_uri_dup              (const GnomeVFSURI *uri);
+gboolean    gnome_vfs_uri_is_local          (const GnomeVFSURI *uri);
+gboolean    gnome_vfs_uri_has_parent        (const GnomeVFSURI *uri);
+GnomeVFSURI* gnome_vfs_uri_get_parent       (const GnomeVFSURI *uri);
+GnomeVFSToplevelURI* gnome_vfs_uri_get_toplevel
+                                            (const GnomeVFSURI *uri);
+const gchar* gnome_vfs_uri_get_host_name    (const GnomeVFSURI *uri);
+const gchar* gnome_vfs_uri_get_scheme       (const GnomeVFSURI *uri);
+guint       gnome_vfs_uri_get_host_port     (const GnomeVFSURI *uri);
+const gchar* gnome_vfs_uri_get_user_name    (const GnomeVFSURI *uri);
+const gchar* gnome_vfs_uri_get_password     (const GnomeVFSURI *uri);
+void        gnome_vfs_uri_set_host_name     (GnomeVFSURI *uri,
+                                             const gchar *host_name);
+void        gnome_vfs_uri_set_host_port     (GnomeVFSURI *uri,
+                                             guint host_port);
+void        gnome_vfs_uri_set_user_name     (GnomeVFSURI *uri,
+                                             const gchar *user_name);
+void        gnome_vfs_uri_set_password      (GnomeVFSURI *uri,
+                                             const gchar *password);
+gboolean    gnome_vfs_uri_equal             (const GnomeVFSURI *a,
+                                             const GnomeVFSURI *b);
+gboolean    gnome_vfs_uri_is_parent         (const GnomeVFSURI *possible_parent,
+                                             const GnomeVFSURI *possible_child,
+                                             gboolean recursive);
+const gchar* gnome_vfs_uri_get_path         (const GnomeVFSURI *uri);
+const gchar* gnome_vfs_uri_get_fragment_identifier
+                                            (const GnomeVFSURI *uri);
+gchar*      gnome_vfs_uri_extract_dirname   (const GnomeVFSURI *uri);
+gchar*      gnome_vfs_uri_extract_short_name
+                                            (const GnomeVFSURI *uri);
+gchar*      gnome_vfs_uri_extract_short_path_name
+                                            (const GnomeVFSURI *uri);
+gint        gnome_vfs_uri_hequal            (gconstpointer a,
+                                             gconstpointer b);
+guint       gnome_vfs_uri_hash              (gconstpointer p);
+GList*      gnome_vfs_uri_list_parse        (const gchar *uri_list);
+GList*      gnome_vfs_uri_list_ref          (GList *list);
+GList*      gnome_vfs_uri_list_unref        (GList *list);
+GList*      gnome_vfs_uri_list_copy         (GList *list);
+void        gnome_vfs_uri_list_free         (GList *list);
+char*       gnome_vfs_uri_make_full_from_relative
+                                            (const char *base_uri,
+                                             const char *relative_uri);
+

Description

+ +

Details

GnomeVFSToplevelURI

typedef struct {
+	/* Base object.  */
+	GnomeVFSURI uri;
+
+	/* Server location information.  */
+	gchar *host_name;
+	guint host_port;
+
+	/* Authorization information.  */
+	gchar *user_name;
+	gchar *password;
+
+	/* The parent URN, if it exists */
+	gchar *urn;
+
+	/* Reserved to avoid future breaks in ABI compatibility */
+	void *reserved1;
+	void *reserved2;
+
+} GnomeVFSToplevelURI;
+

+ +


enum GnomeVFSURIHideOptions

typedef enum {
+	GNOME_VFS_URI_HIDE_NONE = 0,
+	GNOME_VFS_URI_HIDE_USER_NAME = 1 << 0,
+	GNOME_VFS_URI_HIDE_PASSWORD = 1 << 1,
+	GNOME_VFS_URI_HIDE_HOST_NAME = 1 << 2,
+	GNOME_VFS_URI_HIDE_HOST_PORT = 1 << 3,
+	GNOME_VFS_URI_HIDE_TOPLEVEL_METHOD = 1 << 4,
+	GNOME_VFS_URI_HIDE_FRAGMENT_IDENTIFIER = 1 << 8
+} GnomeVFSURIHideOptions;
+

+Packed boolean bitfield controlling hiding of various elements +of a GnomeVFSURI when it is converted to a string.

+ +

GNOME_VFS_URI_HIDE_NONE don't hide anything +
GNOME_VFS_URI_HIDE_USER_NAME hide the user name +
GNOME_VFS_URI_HIDE_PASSWORD hide the password +
GNOME_VFS_URI_HIDE_HOST_NAME hide the host name +
GNOME_VFS_URI_HIDE_HOST_PORT hide the port +
GNOME_VFS_URI_HIDE_TOPLEVEL_METHOD hide the method (e.g. http, file) +
GNOME_VFS_URI_HIDE_FRAGMENT_IDENTIFIER hide the fragment identifier +

GNOME_VFS_URI_MAGIC_CHR

#define GNOME_VFS_URI_MAGIC_CHR	'#'
+

+The character used to divide location from +extra "arguments" passed to the method.

+ +


GNOME_VFS_URI_MAGIC_STR

#define GNOME_VFS_URI_MAGIC_STR "#"
+

+The character used to divide location from +extra "arguments" passed to the method.

+ +


GNOME_VFS_URI_PATH_CHR

#define GNOME_VFS_URI_PATH_CHR '/'
+

+Defines the path seperator character.

+ +


GNOME_VFS_URI_PATH_STR

#define GNOME_VFS_URI_PATH_STR "/"
+

+Defines the path seperator string.

+ +


gnome_vfs_uri_new ()

GnomeVFSURI* gnome_vfs_uri_new              (const gchar *text_uri);

+Create a new URI from text_uri. Unsupported and unsafe methods +are not allowed and will result in null% being returned. URL +transforms are allowed.

+ +

text_uri : A string representing a URI. +
Returns : The new URI. +

gnome_vfs_uri_resolve_relative ()

GnomeVFSURI* gnome_vfs_uri_resolve_relative (const GnomeVFSURI *base,
+                                             const gchar *relative_reference);

+Create a new URI from relative_reference, relative to base.

+ +

base : The base URI. +
relative_reference : A string representing a possibly relative URI reference +
Returns : The new URI. +

gnome_vfs_uri_ref ()

GnomeVFSURI* gnome_vfs_uri_ref              (GnomeVFSURI *uri);

+Increment uri's reference count.

+ +

uri : A GnomeVFSURI. +
Returns : uri. +

gnome_vfs_uri_unref ()

void        gnome_vfs_uri_unref             (GnomeVFSURI *uri);

+Decrement uri's reference count. If the reference count reaches zero, +uri is destroyed.

+ +

uri : A GnomeVFSURI. +

gnome_vfs_uri_append_string ()

GnomeVFSURI* gnome_vfs_uri_append_string    (const GnomeVFSURI *uri,
+                                             const char *uri_fragment);

+Create a new URI obtained by appending path to uri. This will take care +of adding an appropriate directory separator between the end of uri and +the start of path if necessary.

+ +

uri : A GnomeVFSURI. +
uri_fragment : A piece of a URI (ie a fully escaped partial path) +
Returns : The new URI obtained by combining uri and path. +

gnome_vfs_uri_append_path ()

GnomeVFSURI* gnome_vfs_uri_append_path      (const GnomeVFSURI *uri,
+                                             const char *path);

+Create a new URI obtained by appending path to uri. This will take care +of adding an appropriate directory separator between the end of uri and +the start of path if necessary as well as escaping path as necessary.

+ +

uri : A GnomeVFSURI. +
path : A non-escaped file path +
Returns : The new URI obtained by combining uri and path. +

gnome_vfs_uri_append_file_name ()

GnomeVFSURI* gnome_vfs_uri_append_file_name (const GnomeVFSURI *uri,
+                                             const gchar *filename);

+Create a new URI obtained by appending file_name to uri. This will take care +of adding an appropriate directory separator between the end of uri and +the start of file_name if necessary.

+ +

uri : A GnomeVFSURI. +
filename : any "regular" file name (can include #, /, etc) +
Returns : The new URI obtained by combining uri and path. +

gnome_vfs_uri_to_string ()

gchar*      gnome_vfs_uri_to_string         (const GnomeVFSURI *uri,
+                                             GnomeVFSURIHideOptions hide_options);

+Translate uri into a printable string. The string will not contain the +URI elements specified by hide_options.

+ +

uri : A GnomeVFSURI. +
hide_options : Bitmask specifying what URI elements (e.g. password, +user name etc.) should not be represented in the returned string. +
Returns : A malloced printable string representing uri. +

gnome_vfs_uri_dup ()

GnomeVFSURI* gnome_vfs_uri_dup              (const GnomeVFSURI *uri);

+Duplicate uri.

+ +

uri : A GnomeVFSURI. +
Returns : A pointer to a new URI that is exactly the same as uri. +

gnome_vfs_uri_is_local ()

gboolean    gnome_vfs_uri_is_local          (const GnomeVFSURI *uri);

+Check if uri is a local (native) file system.

+ +

uri : A GnomeVFSURI. +
Returns : FALSE if uri is not a local file system, TRUE otherwise. +

gnome_vfs_uri_has_parent ()

gboolean    gnome_vfs_uri_has_parent        (const GnomeVFSURI *uri);

+Check if URI has a parent or not.

+ +

uri : A GnomeVFSURI. +
Returns : TRUE if uri has a parent, FALSE otherwise. +

gnome_vfs_uri_get_parent ()

GnomeVFSURI* gnome_vfs_uri_get_parent       (const GnomeVFSURI *uri);

+Retrieve uri's parent URI.

+ +

uri : A GnomeVFSURI. +
Returns : A pointer to uri's parent URI. +

gnome_vfs_uri_get_toplevel ()

GnomeVFSToplevelURI* gnome_vfs_uri_get_toplevel
+                                            (const GnomeVFSURI *uri);

+Retrieve the toplevel URI in uri.

+ +

uri : A GnomeVFSURI. +
Returns : A pointer to the toplevel URI object. +

gnome_vfs_uri_get_host_name ()

const gchar* gnome_vfs_uri_get_host_name    (const GnomeVFSURI *uri);

+Retrieve the host name for uri.

+ +

uri : A GnomeVFSURI. +
Returns : A string representing the host name. +

gnome_vfs_uri_get_scheme ()

const gchar* gnome_vfs_uri_get_scheme       (const GnomeVFSURI *uri);

+Retrieve the scheme used for uri

+ +

uri : A GnomeVFSURI +
Returns : A string representing the scheme +

gnome_vfs_uri_get_host_port ()

guint       gnome_vfs_uri_get_host_port     (const GnomeVFSURI *uri);

+Retrieve the host port number in uri.

+ +

uri : A GnomeVFSURI. +
Returns : The host port number used by uri. If the value is zero, the +default port value for the specified toplevel access method is used. +

gnome_vfs_uri_get_user_name ()

const gchar* gnome_vfs_uri_get_user_name    (const GnomeVFSURI *uri);

+Retrieve the user name in uri.

+ +

uri : A GnomeVFSURI. +
Returns : A string representing the user name in uri. +

gnome_vfs_uri_get_password ()

const gchar* gnome_vfs_uri_get_password     (const GnomeVFSURI *uri);

+Retrieve the password for uri.

+ +

uri : A GnomeVFSURI. +
Returns : The password for uri. +

gnome_vfs_uri_set_host_name ()

void        gnome_vfs_uri_set_host_name     (GnomeVFSURI *uri,
+                                             const gchar *host_name);

+Set host_name as the host name accessed by uri.

+ +

uri : A GnomeVFSURI. +
host_name : A string representing a host name. +

gnome_vfs_uri_set_host_port ()

void        gnome_vfs_uri_set_host_port     (GnomeVFSURI *uri,
+                                             guint host_port);

+Set the host port number in uri. If host_port is zero, the default port +for uri's toplevel access method is used.

+ +

uri : A GnomeVFSURI. +
host_port : A TCP/IP port number. +

gnome_vfs_uri_set_user_name ()

void        gnome_vfs_uri_set_user_name     (GnomeVFSURI *uri,
+                                             const gchar *user_name);

+Set user_name as the user name for uri.

+ +

uri : A GnomeVFSURI. +
user_name : A string representing a user name on the host accessed by uri. +

gnome_vfs_uri_set_password ()

void        gnome_vfs_uri_set_password      (GnomeVFSURI *uri,
+                                             const gchar *password);

+Set password as the password for uri.

+ +

uri : A GnomeVFSURI. +
password : A password string. +

gnome_vfs_uri_equal ()

gboolean    gnome_vfs_uri_equal             (const GnomeVFSURI *a,
+                                             const GnomeVFSURI *b);

+Compare a and b.

+ +

a : A GnomeVFSURI. +
b : A GnomeVFSURI. +
Returns : TRUE if a and b are equal, FALSE otherwise. + +FIXME: This comparison should take into account the possiblity +that unreserved characters may be escaped. +...or perhaps gnome_vfs_uri_new should unescape unreserved characters? +

gnome_vfs_uri_is_parent ()

gboolean    gnome_vfs_uri_is_parent         (const GnomeVFSURI *possible_parent,
+                                             const GnomeVFSURI *possible_child,
+                                             gboolean recursive);

+Check if possible_child is contained by possible_parent. +If recursive is FALSE, just try the immediate parent directory, else +search up through the hierarchy.

+ +

possible_parent : A GnomeVFSURI. +
possible_child : A GnomeVFSURI. +
recursive : a flag to turn recursive check on. +
Returns : TRUE if possible_child is contained in possible_child. +

gnome_vfs_uri_get_path ()

const gchar* gnome_vfs_uri_get_path         (const GnomeVFSURI *uri);

+Retrieve full path name for uri.

+ +

uri : A GnomeVFSURI +
Returns : A pointer to the full path name in uri. Notice that the +pointer points to the name store in uri, so the name returned must not +be modified nor freed. +

gnome_vfs_uri_get_fragment_identifier ()

const gchar* gnome_vfs_uri_get_fragment_identifier
+                                            (const GnomeVFSURI *uri);

+ +

uri : +
Returns : + + +

gnome_vfs_uri_extract_dirname ()

gchar*      gnome_vfs_uri_extract_dirname   (const GnomeVFSURI *uri);

+Extract the name of the directory in which the file pointed to by uri is +stored as a newly allocated string. The string will end with a +GNOME_VFS_URI_PATH_CHR.

+ +

uri : A GnomeVFSURI +
Returns : A pointer to the newly allocated string representing the +parent directory. +

gnome_vfs_uri_extract_short_name ()

gchar*      gnome_vfs_uri_extract_short_name
+                                            (const GnomeVFSURI *uri);

+Retrieve base file name for uri, ignoring any trailing path separators. +This matches the XPG definition of basename, but not g_basename. This is +often useful when you want the name of something that's pointed to by a +uri, and don't care whether the uri has a directory or file form. +If uri points to the root of a domain, returns the host name. If there's +no host name, returns GNOME_VFS_URI_PATH_STR. +

+See also: gnome_vfs_uri_extract_short_path_name.

+ +

uri : A GnomeVFSURI +
Returns : A pointer to the newly allocated string representing the +unescaped short form of the name. +

gnome_vfs_uri_extract_short_path_name ()

gchar*      gnome_vfs_uri_extract_short_path_name
+                                            (const GnomeVFSURI *uri);

+Retrieve base file name for uri, ignoring any trailing path separators. +This matches the XPG definition of basename, but not g_basename. This is +often useful when you want the name of something that's pointed to by a +uri, and don't care whether the uri has a directory or file form. +If uri points to the root (including the root of any domain), +returns GNOME_VFS_URI_PATH_STR. +

+See also: gnome_vfs_uri_extract_short_name.

+ +

uri : A GnomeVFSURI +
Returns : A pointer to the newly allocated string representing the +escaped short form of the name. +

gnome_vfs_uri_hequal ()

gint        gnome_vfs_uri_hequal            (gconstpointer a,
+                                             gconstpointer b);

+Function intended for use as a hash table "are these two items +the same" comparison. Useful for creating a hash table of URIs.

+ +

a : a pointer to a GnomeVFSURI +
b : a pointer to a GnomeVFSURI +
Returns : TRUE if the URIs are the same +

gnome_vfs_uri_hash ()

guint       gnome_vfs_uri_hash              (gconstpointer p);

+Creates an integer value from a GnomeVFSURI, appropriate +for using as the key to a hash table entry.

+ +

p : a pointer to a GnomeVFSURI +
Returns : a hash key corresponding to p +

gnome_vfs_uri_list_parse ()

GList*      gnome_vfs_uri_list_parse        (const gchar *uri_list);

+Extracts a list of GnomeVFSURI objects from a standard text/uri-list, +such as one you would get on a drop operation. Use +gnome_vfs_uri_list_free when you are done with the list.

+ +

uri_list : +
Returns : A GList of GnomeVFSURIs +

gnome_vfs_uri_list_ref ()

GList*      gnome_vfs_uri_list_ref          (GList *list);

+Increments the reference count of the items in list by one.

+ +

list : list of GnomeVFSURI elements +
Returns : list +

gnome_vfs_uri_list_unref ()

GList*      gnome_vfs_uri_list_unref        (GList *list);

+Decrements the reference count of the items in list by one. +Note that the list is *not freed* even if each member of the list +is freed.

+ +

list : list of GnomeVFSURI elements +
Returns : list +

gnome_vfs_uri_list_copy ()

GList*      gnome_vfs_uri_list_copy         (GList *list);

+Creates a duplicate of list, and references each member of +that list.

+ +

list : list of GnomeVFSURI elements +
Returns : a newly referenced duplicate of list +

gnome_vfs_uri_list_free ()

void        gnome_vfs_uri_list_free         (GList *list);

+Decrements the reference count of each member of list by one, +and frees the list itself.

+ +

list : list of GnomeVFSURI elements +

gnome_vfs_uri_make_full_from_relative ()

char*       gnome_vfs_uri_make_full_from_relative
+                                            (const char *base_uri,
+                                             const char *relative_uri);

+Returns a full URI given a full base URI, and a secondary URI which may +be relative.

+ +

base_uri : a string representing the base URI +
relative_uri : a URI fragment/reference to be appended to base_uri +
Returns : the URI (NULL for some bad errors). +
diff --git a/doc/html/gnome-vfs-gnome-vfs-utils.html b/doc/html/gnome-vfs-gnome-vfs-utils.html new file mode 100644 index 0000000..f90c331 --- /dev/null +++ b/doc/html/gnome-vfs-gnome-vfs-utils.html @@ -0,0 +1,269 @@ +gnome-vfs-utils

gnome-vfs-utils

gnome-vfs-utils —

Synopsis

+
+
+
+char*       gnome_vfs_format_file_size_for_display
+                                            (GnomeVFSFileSize size);
+char*       gnome_vfs_escape_string         (const char *string);
+char*       gnome_vfs_escape_path_string    (const char *path);
+char*       gnome_vfs_escape_host_and_path_string
+                                            (const char *path);
+char*       gnome_vfs_escape_slashes        (const char *string);
+char*       gnome_vfs_escape_set            (const char *string,
+                                             const char *match_set);
+char*       gnome_vfs_unescape_string       (const char *escaped_string,
+                                             const char *illegal_characters);
+char*       gnome_vfs_make_uri_canonical    (const char *uri);
+char*       gnome_vfs_make_path_name_canonical
+                                            (const char *path);
+char*       gnome_vfs_expand_initial_tilde  (const char *path);
+char*       gnome_vfs_unescape_string_for_display
+                                            (const char *escaped);
+char*       gnome_vfs_get_local_path_from_uri
+                                            (const char *uri);
+char*       gnome_vfs_get_uri_from_local_path
+                                            (const char *local_full_path);
+gboolean    gnome_vfs_is_executable_command_string
+                                            (const char *command_string);
+void        gnome_vfs_list_deep_free        (GList *list);
+GnomeVFSResult gnome_vfs_get_volume_free_space
+                                            (const GnomeVFSURI *vfs_uri,
+                                             GnomeVFSFileSize *size);
+char*       gnome_vfs_icon_path_from_filename
+                                            (const char *filename);
+gboolean    gnome_vfs_is_primary_thread     (void);
+char*       gnome_vfs_get_uri_scheme        (const char *uri);
+gboolean    gnome_vfs_uris_match            (const char *uri_1,
+                                             const char *uri_2);
+#define     GNOME_VFS_ASSERT_PRIMARY_THREAD
+#define     GNOME_VFS_ASSERT_SECONDARY_THREAD
+GnomeVFSResult gnome_vfs_read_entire_file   (const char *uri,
+                                             int *file_size,
+                                             char **file_contents);
+

Description

+ +

Details

gnome_vfs_format_file_size_for_display ()

char*       gnome_vfs_format_file_size_for_display
+                                            (GnomeVFSFileSize size);

+Formats the file size passed in bytes in a way that is easy for +the user to read. Gives the size in bytes, kilobytes, megabytes or +gigabytes, choosing whatever is appropriate.

+ +

size : +
Returns : a newly allocated string with the size ready to be shown. +

gnome_vfs_escape_string ()

char*       gnome_vfs_escape_string         (const char *string);

+Escapes string, replacing any and all special characters +with equivalent escape sequences.

+ +

string : string to be escaped +
Returns : a newly allocated string equivalent to string +but with all special characters escaped +

gnome_vfs_escape_path_string ()

char*       gnome_vfs_escape_path_string    (const char *path);

+Escapes path, replacing only special characters that would not +be found in paths (so '/', '&', '=', and '?' will not be escaped by +this function).

+ +

path : string to be escaped +
Returns : a newly allocated string equivalent to path but +with non-path characters escaped +

gnome_vfs_escape_host_and_path_string ()

char*       gnome_vfs_escape_host_and_path_string
+                                            (const char *path);

+Escapes path, replacing only special characters that would not +be found in paths or host name (so '/', '&', '=', ':', '@' +and '?' will not be escaped by this function).

+ +

path : string to be escaped +
Returns : a newly allocated string equivalent to path but +with non-path/host characters escaped +

gnome_vfs_escape_slashes ()

char*       gnome_vfs_escape_slashes        (const char *string);

+Escapes only '/' and '%' characters in string, replacing +them with their escape sequence equivalents.

+ +

string : string to be escaped +
Returns : a newly allocated string equivalent to string, +but with no unescaped '/' or '%' characters +

gnome_vfs_escape_set ()

char*       gnome_vfs_escape_set            (const char *string,
+                                             const char *match_set);

+ +

string : +
match_set : +
Returns : + + +

gnome_vfs_unescape_string ()

char*       gnome_vfs_unescape_string       (const char *escaped_string,
+                                             const char *illegal_characters);

+Decodes escaped characters (i.e. PERCENTxx sequences) in escaped_string. +Characters are encoded in PERCENTxy form, where xy is the ASCII hex code +for character 16x+y.

+ +

escaped_string : an escaped URI, path, or other string +
illegal_characters : a string containing a sequence of characters +considered "illegal", '\0' is automatically in this list. +
Returns : a newly allocated string with the unescaped equivalents, +or NULL if escaped_string contained one of the characters +in illegal_characters. +

gnome_vfs_make_uri_canonical ()

char*       gnome_vfs_make_uri_canonical    (const char *uri);

+Standarizes the format of the uri being passed, so that it can be used +later in other functions that expect a canonical URI.

+ +

uri : and absolute or relative URI, it might have scheme. +
Returns : a newly allocated string that contains the canonical +representation of uri. + +

Since 2.2 +


gnome_vfs_make_path_name_canonical ()

char*       gnome_vfs_make_path_name_canonical
+                                            (const char *path);

+Calls _gnome_vfs_canonicalize_pathname, allocating storage for the +result and providing for a cleaner memory management.

+ +

path : a file path, relative or absolute +
Returns : a canonical version of path +

gnome_vfs_expand_initial_tilde ()

char*       gnome_vfs_expand_initial_tilde  (const char *path);

+If path starts with a ~, representing the user's home +directory, expand it to the actual path location.

+ +

path : a local file path which may start with a '~' +
Returns : a newly allocated string with the initial +tilde (if there was one) converted to an actual path +

gnome_vfs_unescape_string_for_display ()

char*       gnome_vfs_unescape_string_for_display
+                                            (const char *escaped);

+ +

escaped : +
Returns : + + +

gnome_vfs_get_local_path_from_uri ()

char*       gnome_vfs_get_local_path_from_uri
+                                            (const char *uri);

+Create a local path for a file:/// URI. Do not use with URIs +of other methods.

+ +

uri : URI to convert to a local path +
Returns : the local path +NULL is returned on error or if the uri isn't a file: URI +without a fragment identifier (or chained URI). +

gnome_vfs_get_uri_from_local_path ()

char*       gnome_vfs_get_uri_from_local_path
+                                            (const char *local_full_path);

+Returns a file:/// URI for the local path local_full_path.

+ +

local_full_path : a full local filesystem path (i.e. not relative) +
Returns : the URI corresponding to local_full_path +(NULL for some bad errors). +

gnome_vfs_is_executable_command_string ()

gboolean    gnome_vfs_is_executable_command_string
+                                            (const char *command_string);

+Checks if command_string starts with the full path of an executable file +or an executable in $PATH.

+ +

command_string : +
Returns : TRUE if command_string started with and executable file, +FALSE otherwise. +

gnome_vfs_list_deep_free ()

void        gnome_vfs_list_deep_free        (GList *list);

+Free list, and call g_free() on all data members.

+ +

list : list to be freed +

gnome_vfs_get_volume_free_space ()

GnomeVFSResult gnome_vfs_get_volume_free_space
+                                            (const GnomeVFSURI *vfs_uri,
+                                             GnomeVFSFileSize *size);

+Stores in size the amount of free space on a volume. +This only works for local file systems with the file: scheme.

+ +

vfs_uri : +
size : +
Returns : GNOME_VFS_OK on success, otherwise an error code +

gnome_vfs_icon_path_from_filename ()

char*       gnome_vfs_icon_path_from_filename
+                                            (const char *filename);

+ +

filename : +
Returns : + + +

gnome_vfs_is_primary_thread ()

gboolean    gnome_vfs_is_primary_thread     (void);

+Check if the current thread is the thread with the main glib event loop.

+ +

Returns : TRUE if the current thread is the thread with the +main glib event loop +

gnome_vfs_get_uri_scheme ()

char*       gnome_vfs_get_uri_scheme        (const char *uri);

+Retrieve the scheme used in uri

+ +

uri : a stringified URI +
Returns : A string containing the scheme + +

Since 2.2 +


gnome_vfs_uris_match ()

gboolean    gnome_vfs_uris_match            (const char *uri_1,
+                                             const char *uri_2);

+Compare two URIs.

+ +

uri_1 : stringified URI to compare with uri_2. +
uri_2 : stringified URI to compare with uri_1. +
Returns : TRUE if they are the same, FALSE otherwise. + +

Since 2.2 +


GNOME_VFS_ASSERT_PRIMARY_THREAD

#define GNOME_VFS_ASSERT_PRIMARY_THREAD g_assert (gnome_vfs_is_primary_thread())
+

+Asserts that the current thread is the thread with +the main glib event loop

+ +


GNOME_VFS_ASSERT_SECONDARY_THREAD

#define GNOME_VFS_ASSERT_SECONDARY_THREAD g_assert (!gnome_vfs_is_primary_thread())
+

+Asserts that the current thread is NOT the thread with +the main glib event loop

+ +


gnome_vfs_read_entire_file ()

GnomeVFSResult gnome_vfs_read_entire_file   (const char *uri,
+                                             int *file_size,
+                                             char **file_contents);

+Reads an entire file into memory for convenience. Beware accidentally +loading large files into memory with this function.

+ +

uri : URI of the file to read +
file_size : after reading the file, contains the size of the file read +
file_contents : contains the file_size bytes, the contents of the file at uri. +
Returns : An integer representing the result of the operation + +

Since 2.2 +

diff --git a/doc/html/gnome-vfs-gnome-vfs-xfer.html b/doc/html/gnome-vfs-gnome-vfs-xfer.html new file mode 100644 index 0000000..e5e8501 --- /dev/null +++ b/doc/html/gnome-vfs-gnome-vfs-xfer.html @@ -0,0 +1,376 @@ +File Transfers

File Transfers

File Transfers — Conveniently copy/move/delete files en masse

Synopsis

+
+
+
+enum        GnomeVFSXferOptions;
+enum        GnomeVFSXferProgressStatus;
+enum        GnomeVFSXferOverwriteMode;
+enum        GnomeVFSXferOverwriteAction;
+enum        GnomeVFSXferErrorMode;
+enum        GnomeVFSXferErrorAction;
+enum        GnomeVFSXferPhase;
+typedef     GnomeVFSXferProgressInfo;
+gint        (*GnomeVFSXferProgressCallback) (GnomeVFSXferProgressInfo *info,
+                                             gpointer data);
+GnomeVFSResult gnome_vfs_xfer_uri_list      (const GList *source_uri_list,
+                                             const GList *target_uri_list,
+                                             GnomeVFSXferOptions xfer_options,
+                                             GnomeVFSXferErrorMode error_mode,
+                                             GnomeVFSXferOverwriteMode overwrite_mode,
+                                             GnomeVFSXferProgressCallback progress_callback,
+                                             gpointer data);
+GnomeVFSResult gnome_vfs_xfer_uri           (const GnomeVFSURI *source_uri,
+                                             const GnomeVFSURI *target_uri,
+                                             GnomeVFSXferOptions xfer_options,
+                                             GnomeVFSXferErrorMode error_mode,
+                                             GnomeVFSXferOverwriteMode overwrite_mode,
+                                             GnomeVFSXferProgressCallback progress_callback,
+                                             gpointer data);
+GnomeVFSResult gnome_vfs_xfer_delete_list   (const GList *source_uri_list,
+                                             GnomeVFSXferErrorMode error_mode,
+                                             GnomeVFSXferOptions xfer_options,
+                                             GnomeVFSXferProgressCallback progress_callback,
+                                             gpointer data);
+

Description

+ +

Details

enum GnomeVFSXferOptions

typedef enum {
+	GNOME_VFS_XFER_DEFAULT = 0,
+	GNOME_VFS_XFER_UNUSED_1 = 1 << 0,
+	GNOME_VFS_XFER_FOLLOW_LINKS = 1 << 1,
+	GNOME_VFS_XFER_UNUSED_2 = 1 << 2,
+	GNOME_VFS_XFER_RECURSIVE = 1 << 3,
+	GNOME_VFS_XFER_SAMEFS = 1 << 4,
+	GNOME_VFS_XFER_DELETE_ITEMS = 1 << 5,
+	GNOME_VFS_XFER_EMPTY_DIRECTORIES = 1 << 6,
+	GNOME_VFS_XFER_NEW_UNIQUE_DIRECTORY = 1 << 7,
+	GNOME_VFS_XFER_REMOVESOURCE = 1 << 8,
+	GNOME_VFS_XFER_USE_UNIQUE_NAMES = 1 << 9,
+	GNOME_VFS_XFER_LINK_ITEMS = 1 << 10,
+	GNOME_VFS_XFER_FOLLOW_LINKS_RECURSIVE = 1 << 11,
+} GnomeVFSXferOptions;
+

+ +


enum GnomeVFSXferProgressStatus

typedef enum {
+	GNOME_VFS_XFER_PROGRESS_STATUS_OK = 0,
+	GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR = 1,
+	GNOME_VFS_XFER_PROGRESS_STATUS_OVERWRITE = 2,
+	/* during the duplicate status the progress callback is asked to
+	   supply a new unique name */
+	GNOME_VFS_XFER_PROGRESS_STATUS_DUPLICATE = 3
+} GnomeVFSXferProgressStatus;
+

+ +


enum GnomeVFSXferOverwriteMode

typedef enum {
+	/* Interrupt transferring with an error (GNOME_VFS_ERROR_FILEEXISTS).  */
+	GNOME_VFS_XFER_OVERWRITE_MODE_ABORT = 0,
+	/* Invoke the progress callback with a
+	   `GNOME_VFS_XFER_PROGRESS_STATUS_OVERWRITE' status code. */
+	GNOME_VFS_XFER_OVERWRITE_MODE_QUERY = 1,
+	/* Overwrite files silently.  */
+	GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE = 2,
+	/* Ignore files silently.  */
+	GNOME_VFS_XFER_OVERWRITE_MODE_SKIP = 3
+} GnomeVFSXferOverwriteMode;
+

+ +


enum GnomeVFSXferOverwriteAction

typedef enum {
+	GNOME_VFS_XFER_OVERWRITE_ACTION_ABORT = 0,
+	GNOME_VFS_XFER_OVERWRITE_ACTION_REPLACE = 1,
+	GNOME_VFS_XFER_OVERWRITE_ACTION_REPLACE_ALL = 2,
+	GNOME_VFS_XFER_OVERWRITE_ACTION_SKIP = 3,
+	GNOME_VFS_XFER_OVERWRITE_ACTION_SKIP_ALL = 4,
+} GnomeVFSXferOverwriteAction;
+

+This defines the actions to perform before a file is being overwritten +(i.e., these are the answers that can be given to a replace query).

+ +

GNOME_VFS_XFER_OVERWRITE_ACTION_ABORT abort the transfer +
GNOME_VFS_XFER_OVERWRITE_ACTION_REPLACE replace the existing file +
GNOME_VFS_XFER_OVERWRITE_ACTION_REPLACE_ALL replace the existing file, and all future files +without prompting the callback. +
GNOME_VFS_XFER_OVERWRITE_ACTION_SKIP don't copy over the existing file +
GNOME_VFS_XFER_OVERWRITE_ACTION_SKIP_ALL don't copy over the existing file, and all future +files without prompting the callback. +

enum GnomeVFSXferErrorMode

typedef enum {
+	/* Interrupt transferring with an error (code returned is code of the
+           operation that has caused the error).  */
+	GNOME_VFS_XFER_ERROR_MODE_ABORT = 0,
+	/* Invoke the progress callback with a
+	   `GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR' status code. */
+	GNOME_VFS_XFER_ERROR_MODE_QUERY = 1,
+} GnomeVFSXferErrorMode;
+

+ +


enum GnomeVFSXferErrorAction

typedef enum {
+	/* Interrupt operation and return `GNOME_VFS_ERROR_INTERRUPTED'.  */
+	GNOME_VFS_XFER_ERROR_ACTION_ABORT = 0,
+	/* Try the same operation again.  */
+	GNOME_VFS_XFER_ERROR_ACTION_RETRY = 1,
+	/* Skip this file and continue normally.  */
+	GNOME_VFS_XFER_ERROR_ACTION_SKIP = 2
+} GnomeVFSXferErrorAction;
+

+ +


enum GnomeVFSXferPhase

typedef enum {
+	/* Initial phase */
+	GNOME_VFS_XFER_PHASE_INITIAL,
+	/* Checking if destination can handle move/copy */
+	GNOME_VFS_XFER_CHECKING_DESTINATION,
+	/* Collecting file list */
+	GNOME_VFS_XFER_PHASE_COLLECTING,
+	/* File list collected (*) */
+	GNOME_VFS_XFER_PHASE_READYTOGO,
+	/* Opening source file for reading */
+	GNOME_VFS_XFER_PHASE_OPENSOURCE,
+	/* Creating target file for copy */
+	GNOME_VFS_XFER_PHASE_OPENTARGET,
+	/* Copying data from source to target (*) */
+	GNOME_VFS_XFER_PHASE_COPYING,
+	/* Moving file from source to target (*) */
+	GNOME_VFS_XFER_PHASE_MOVING,
+	/* Reading data from source file */
+	GNOME_VFS_XFER_PHASE_READSOURCE,
+	/* Writing data to target file */
+	GNOME_VFS_XFER_PHASE_WRITETARGET,
+	/* Closing source file */
+	GNOME_VFS_XFER_PHASE_CLOSESOURCE,
+	/* Closing target file */
+	GNOME_VFS_XFER_PHASE_CLOSETARGET,
+	/* Deleting source file */
+	GNOME_VFS_XFER_PHASE_DELETESOURCE,
+	/* Setting attributes on target file */
+	GNOME_VFS_XFER_PHASE_SETATTRIBUTES,
+	/* Go to the next file (*) */
+	GNOME_VFS_XFER_PHASE_FILECOMPLETED,
+	/* cleaning up after a move (removing source files, etc.) */
+	GNOME_VFS_XFER_PHASE_CLEANUP,
+	/* Operation finished (*) */
+	GNOME_VFS_XFER_PHASE_COMPLETED,
+	GNOME_VFS_XFER_NUM_PHASES
+} GnomeVFSXferPhase;
+

+ +


GnomeVFSXferProgressInfo

typedef struct {
+	/* Progress status (see above for a description).  */
+	GnomeVFSXferProgressStatus status;
+
+	/* VFS status code.  If `status' is
+           `GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR', you should look at this
+           member to know what has happened.  */
+	GnomeVFSResult vfs_status;
+
+	/* Current phase in the transferring process.  */
+	GnomeVFSXferPhase phase;
+
+	/* Source URI. FIXME bugzilla.eazel.com 1206: change name? */
+	gchar *source_name;
+
+	/* Destination URI. FIXME bugzilla.eazel.com 1206: change name? */
+	gchar *target_name;
+
+	/* Index of file being copied. */
+	gulong file_index;
+
+	/* Total number of files to be copied.  */
+	gulong files_total;
+
+	/* Total number of bytes to be copied.  */
+	GnomeVFSFileSize bytes_total;
+
+	/* Total size of this file (in bytes).  */
+	GnomeVFSFileSize file_size;
+
+	/* Bytes copied for this file so far.  */
+	GnomeVFSFileSize bytes_copied;
+
+	/* Total amount of data copied from the beginning.  */
+	GnomeVFSFileSize total_bytes_copied;
+	
+	/* Target unique name used when duplicating, etc. to avoid collisions */ 
+	gchar *duplicate_name;
+
+	/* Count used in the unique name e.g. (copy 2), etc. */
+	int duplicate_count;
+
+	gboolean top_level_item;
+	/* indicates that the copied/moved/deleted item is an actual item
+	 * passed in the uri list rather than one encountered by recursively
+	 * traversing directories. Used by metadata copying.
+	 */
+
+	/* Reserved for future expansions to GnomeVFSXferProgressInfo
+	 * without having to break ABI compatibility */
+	void *reserved1;
+	void *reserved2;
+
+} GnomeVFSXferProgressInfo;
+

+ +


GnomeVFSXferProgressCallback ()

gint        (*GnomeVFSXferProgressCallback) (GnomeVFSXferProgressInfo *info,
+                                             gpointer data);

+ +

info : +
data : +
Returns : + + +

gnome_vfs_xfer_uri_list ()

GnomeVFSResult gnome_vfs_xfer_uri_list      (const GList *source_uri_list,
+                                             const GList *target_uri_list,
+                                             GnomeVFSXferOptions xfer_options,
+                                             GnomeVFSXferErrorMode error_mode,
+                                             GnomeVFSXferOverwriteMode overwrite_mode,
+                                             GnomeVFSXferProgressCallback progress_callback,
+                                             gpointer data);

+This function will transfer multiple files to a multiple targets. Given a +a source uri(s) and a destination uri(s). There are a list of options that +your application can use to control how the transfer is done.

+ +

source_uri_list : A Glist of uris (ie file;//) +
target_uri_list : A GList of uris +
xfer_options : These are options you wish to set for the transfer. For +instance by setting the xfer behavior you can either make a copy or a +move. +
error_mode : Decide how to behave if the xfer is interrupted. For instance +you could set your application to return an error code in case of an +interuption. +
overwrite_mode : How to react if a file your copying is being overwritten. +
progress_callback : This is used to monitor the progress of a transfer. +Common use would be to check to see if the transfer is asking for permission +to overwrite a file. +
data : Data to be want passed back in callbacks from the xfer engine +
Returns : If all goes well it returns GNOME_VFS_OK. Check GnomeVFSResult for +other values. +

gnome_vfs_xfer_uri ()

GnomeVFSResult gnome_vfs_xfer_uri           (const GnomeVFSURI *source_uri,
+                                             const GnomeVFSURI *target_uri,
+                                             GnomeVFSXferOptions xfer_options,
+                                             GnomeVFSXferErrorMode error_mode,
+                                             GnomeVFSXferOverwriteMode overwrite_mode,
+                                             GnomeVFSXferProgressCallback progress_callback,
+                                             gpointer data);

+This function will allow a person to copy data from one location to another. +The location is specified using a URIs as the means to describe the location +of the data. Like any copy there are several options that can be set. +These can be set using the xfer_options. In addition there are callback +mechanisms and error codes to provide feedback in the copy +process.

+ +

source_uri : This is the location of where your data resides. +
target_uri : This is the location of where you want your data to go. +
xfer_options : Set the kind of transfers you want. These are: +GNOME_VFS_XFER_DEFAULT: Default behavior. Which is to do a straight one to +one copy. +GNOME_VFS_XFER_FOLLOW_LINKS: This means follow the value of the symbolic +link when copying. (ie treat a symbolic link as a directory) +GNOME_VFS_RECURSIVE: Do a recursive copy of the source to the destination. +Equivalent to the cp -r option in GNU cp. +GNOME_VFS_XFER_SAME_FS: This only allows copying onto the same filesystem. +GNOME_VFS_DELETE_ITEM: This is equivalent to a mv. Where you will copy the +contents of the source to the destination and then remove data from the +source URI. +GNOME_VFS_XFER_EMPTY_DIRECTORIES: <TBA> +GNOME_VFS_XFER_NEW_UNIQUE_DIRECTORY: This will create a directory if it +doesn't exist in the destination area. Useful with the +GNOME_VFS_XFER_RECURSIVE xfer option. +GNOME_VFS_XFER_REMOVESOURCE: This option will remove the source data after +whatever xfer option has been taken. +GNOME_VFS_USE_UNIQUE_NAMES: This is a check ot make sure that what you copy +onto the destination is not overwritten. It will only copy the unique items +from the source to the destjnation. +GNOME_VFS_XFER_LINK_ITEMS: <TBA> +
error_mode : When this function returns you need to check the error code +for the results of the copy. The results are generally: +GNOME_VFS_XFER_ERROR_MODE_ABORT: This means that the operation was aborted +by some sort of signal that interrupted the transfer. +GNOME_VFS_ERROR_MODE_QUERY: This means that no error has occured and that +you should query with the GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR. See +
overwrite_mode : This sets the options to deal with data that are duplicate +between the source and the destination. Your choices are: +GNOME_VFS_XFER_OVERWRITE_MODE_ABORT: This means abort the transfer if you +see duplicate data. +GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE: Replace the files silently. Don't +worry be happy. +GNOME_VFS_XFER_OVERWRITE_MODE_SKIP: Skip duplicate files silenty. +target. +
progress_callback : This is an important call back because this is how you +communicate with your copy process. +
data : Data to be want passed back in callbacks from the xfer engine +
Returns : An integer representing the result of the operation. + +

gnome_vfs_xfer_delete_list ()

GnomeVFSResult gnome_vfs_xfer_delete_list   (const GList *source_uri_list,
+                                             GnomeVFSXferErrorMode error_mode,
+                                             GnomeVFSXferOptions xfer_options,
+                                             GnomeVFSXferProgressCallback progress_callback,
+                                             gpointer data);

+Unlink items in the list source_uri_list from their filesystems.

+ +

source_uri_list : This is a list containing uris +
error_mode : Decide how you want to deal with interruptions +
xfer_options : Set whatever transfer options you need. +
progress_callback : Callback to check on progress of transfer. +
data : Data to be want passed back in callbacks from the xfer engine +
Returns : GNOME_VFS_OK if successful, or the appropriate error code otherwise +
diff --git a/doc/html/gnome-vfs-gnomevfsmetadata.html b/doc/html/gnome-vfs-gnomevfsmetadata.html new file mode 100644 index 0000000..f22eeb7 --- /dev/null +++ b/doc/html/gnome-vfs-gnomevfsmetadata.html @@ -0,0 +1,638 @@ +Metadata
GnomeVFS - Filesystem Abstraction library

Metadata

Name

Metadata -- attach extra pieces of information to files, such as icons or positions

Synopsis


+
+#define     GNOME_VFS_METADATA_CONST        (obj)
+struct      GnomeVfsMetadataPrivate;
+void        gnome_vfs_metadata_set_string   (GnomeVfsMetadata *self,
+                                             const char *key,
+                                             const char *value);
+int         gnome_vfs_metadata_get_int      (GnomeVfsMetadata *self,
+                                             const char *key);
+void        gnome_vfs_metadata_set_int      (GnomeVfsMetadata *self,
+                                             const char *key,
+                                             gpointer value);
+GObject*    gnome_vfs_metadata_new          (const char *uri);

Description

Details

GNOME_VFS_METADATA_CONST()

#define GNOME_VFS_METADATA_CONST(obj)	G_TYPE_CHECK_INSTANCE_CAST((obj), gnome_vfs_metadata_get_type(), GnomeVfsMetadata const)

obj :


struct GnomeVfsMetadataPrivate

struct GnomeVfsMetadataPrivate;


gnome_vfs_metadata_set_string ()

void        gnome_vfs_metadata_set_string   (GnomeVfsMetadata *self,
+                                             const char *key,
+                                             const char *value);

self :

key :

value :


gnome_vfs_metadata_get_int ()

int         gnome_vfs_metadata_get_int      (GnomeVfsMetadata *self,
+                                             const char *key);

Gets the piece of integer metadata associated with key.

self :

Metadata object to get the property of

key :

key to retrieve

Returns :

the integer associated with key


gnome_vfs_metadata_set_int ()

void        gnome_vfs_metadata_set_int      (GnomeVfsMetadata *self,
+                                             const char *key,
+                                             gpointer value);

self :

key :

value :


gnome_vfs_metadata_new ()

GObject*    gnome_vfs_metadata_new          (const char *uri);

uri :

Returns :

<<< Advanced OperationsMonitoring >>>
\ No newline at end of file diff --git a/doc/html/gnome-vfs-gnomevfsmimemonitor.html b/doc/html/gnome-vfs-gnomevfsmimemonitor.html new file mode 100644 index 0000000..4889076 --- /dev/null +++ b/doc/html/gnome-vfs-gnomevfsmimemonitor.html @@ -0,0 +1,288 @@ +MIME Database Monitor
GnomeVFS - Filesystem Abstraction library

MIME Database Monitor

Name

MIME Database Monitor -- monitor the MIME database for changes (primarily for file browsers)

Synopsis


+
+#define     GNOME_VFS_MIME_MONITOR_TYPE
+struct      GnomeVFSMIMEMonitorPrivate;
+GnomeVFSMIMEMonitor* gnome_vfs_mime_monitor_get
+                                            (void);

Description

Details

GNOME_VFS_MIME_MONITOR_TYPE

#define GNOME_VFS_MIME_MONITOR_TYPE        (gnome_vfs_mime_monitor_get_type ())


struct GnomeVFSMIMEMonitorPrivate

struct GnomeVFSMIMEMonitorPrivate;


gnome_vfs_mime_monitor_get ()

GnomeVFSMIMEMonitor* gnome_vfs_mime_monitor_get
+                                            (void);

Get access to the single global monitor.

Returns :

the global GnomeVFSMIMEMonitor

<<< File TypesFilesystem Modules >>>
\ No newline at end of file diff --git a/doc/html/gnome-vfs-inet-connection.html b/doc/html/gnome-vfs-inet-connection.html new file mode 100644 index 0000000..e894f6c --- /dev/null +++ b/doc/html/gnome-vfs-inet-connection.html @@ -0,0 +1,603 @@ +inet-connection
GnomeVFS - Filesystem Abstraction library
<<< Previous PageHomeUpNext Page >>>

inet-connection

Name

inet-connection -- 

Synopsis


+
+GnomeVFSResult gnome_vfs_inet_connection_create
+                                            (GnomeVFSInetConnection **connection_return,
+                                             const gchar *host_name,
+                                             guint host_port,
+                                             GnomeVFSCancellation *cancellation);
+void        gnome_vfs_inet_connection_destroy
+                                            (GnomeVFSInetConnection *connection,
+                                             GnomeVFSCancellation *cancellation);
+GnomeVFSIOBuf* gnome_vfs_inet_connection_get_iobuf
+                                            (GnomeVFSInetConnection *connection);

Description

Details

gnome_vfs_inet_connection_create ()

GnomeVFSResult gnome_vfs_inet_connection_create
+                                            (GnomeVFSInetConnection **connection_return,
+                                             const gchar *host_name,
+                                             guint host_port,
+                                             GnomeVFSCancellation *cancellation);

connection_return : 
host_name : 
host_port : 
cancellation : 
Returns : 


gnome_vfs_inet_connection_destroy ()

void        gnome_vfs_inet_connection_destroy
+                                            (GnomeVFSInetConnection *connection,
+                                             GnomeVFSCancellation *cancellation);

connection : 
cancellation : 


gnome_vfs_inet_connection_get_iobuf ()

GnomeVFSIOBuf* gnome_vfs_inet_connection_get_iobuf
+                                            (GnomeVFSInetConnection *connection);

connection : 
Returns : 



<<< Previous PageHomeUpNext Page >>>
Module Callbacks (Module API)iobuf
\ No newline at end of file diff --git a/doc/html/gnome-vfs-initialization.html b/doc/html/gnome-vfs-initialization.html new file mode 100644 index 0000000..e60dca3 --- /dev/null +++ b/doc/html/gnome-vfs-initialization.html @@ -0,0 +1,726 @@ +Initialization
GnomeVFS - Filesystem Abstraction library
<<< Previous PageHomeUpNext Page >>>

Initialization

Name

Initialization -- initializing and shutting down gnome-vfs

Synopsis


+
+gboolean    gnome_vfs_init                  (void);
+gboolean    gnome_vfs_initialized           (void);
+void        gnome_vfs_shutdown              (void);
+void        gnome_vfs_loadinit              (gpointer app,
+                                             gpointer modinfo);
+void        gnome_vfs_preinit               (gpointer app,
+                                             gpointer modinfo);
+void        gnome_vfs_postinit              (gpointer app,
+                                             gpointer modinfo);

Description

Details

gnome_vfs_init ()

gboolean    gnome_vfs_init                  (void);

Returns : 


gnome_vfs_initialized ()

gboolean    gnome_vfs_initialized           (void);

Returns : 


gnome_vfs_shutdown ()

void        gnome_vfs_shutdown              (void);


gnome_vfs_loadinit ()

void        gnome_vfs_loadinit              (gpointer app,
+                                             gpointer modinfo);

app : 
modinfo : 


gnome_vfs_preinit ()

void        gnome_vfs_preinit               (gpointer app,
+                                             gpointer modinfo);

app : 
modinfo : 


gnome_vfs_postinit ()

void        gnome_vfs_postinit              (gpointer app,
+                                             gpointer modinfo);

app : 
modinfo : 

\ No newline at end of file diff --git a/doc/html/gnome-vfs-iobuf.html b/doc/html/gnome-vfs-iobuf.html new file mode 100644 index 0000000..87d81db --- /dev/null +++ b/doc/html/gnome-vfs-iobuf.html @@ -0,0 +1,950 @@ +iobuf
GnomeVFS - Filesystem Abstraction library
<<< Previous PageHomeUpNext Page >>>

iobuf

Name

iobuf -- 

Synopsis


+
+GnomeVFSIOBuf* gnome_vfs_iobuf_new          (gint fd);
+void        gnome_vfs_iobuf_destroy         (GnomeVFSIOBuf *iobuf);
+GnomeVFSResult gnome_vfs_iobuf_read         (GnomeVFSIOBuf *iobuf,
+                                             gpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_read);
+GnomeVFSResult gnome_vfs_iobuf_peekc        (GnomeVFSIOBuf *iobuf,
+                                             gchar *c);
+GnomeVFSResult gnome_vfs_iobuf_write        (GnomeVFSIOBuf *iobuf,
+                                             gconstpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_written);
+GnomeVFSResult gnome_vfs_iobuf_flush        (GnomeVFSIOBuf *iobuf);

Description

Details

gnome_vfs_iobuf_new ()

GnomeVFSIOBuf* gnome_vfs_iobuf_new          (gint fd);

fd : 
Returns : 


gnome_vfs_iobuf_destroy ()

void        gnome_vfs_iobuf_destroy         (GnomeVFSIOBuf *iobuf);

iobuf : 


gnome_vfs_iobuf_read ()

GnomeVFSResult gnome_vfs_iobuf_read         (GnomeVFSIOBuf *iobuf,
+                                             gpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_read);

iobuf : 
buffer : 
bytes : 
bytes_read : 
Returns : 


gnome_vfs_iobuf_peekc ()

GnomeVFSResult gnome_vfs_iobuf_peekc        (GnomeVFSIOBuf *iobuf,
+                                             gchar *c);

iobuf : 
c : 
Returns : 


gnome_vfs_iobuf_write ()

GnomeVFSResult gnome_vfs_iobuf_write        (GnomeVFSIOBuf *iobuf,
+                                             gconstpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_written);

iobuf : 
buffer : 
bytes : 
bytes_written : 
Returns : 


gnome_vfs_iobuf_flush ()

GnomeVFSResult gnome_vfs_iobuf_flush        (GnomeVFSIOBuf *iobuf);

iobuf : 
Returns : 

\ No newline at end of file diff --git a/doc/html/gnome-vfs-method.html b/doc/html/gnome-vfs-method.html new file mode 100644 index 0000000..993d552 --- /dev/null +++ b/doc/html/gnome-vfs-method.html @@ -0,0 +1,1081 @@ +method
GnomeVFS - Filesystem Abstraction library
<<< Previous PageHomeUpNext Page >>>

method

Name

method -- 

Synopsis


+
+GnomeVFSMethod* (*GnomeVFSMethodInitFunc)   (const char *method_name,
+                                             const char *config_args);
+void        (*GnomeVFSMethodShutdownFunc)   (GnomeVFSMethod *method);
+GnomeVFSResult (*GnomeVFSMethodTruncateFunc)
+                                            (GnomeVFSMethod *method,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSFileSize length,
+                                             GnomeVFSContext *context);
+GnomeVFSResult (*GnomeVFSMethodTruncateHandleFunc)
+                                            (GnomeVFSMethod *method,
+                                             GnomeVFSMethodHandle *handle,
+                                             GnomeVFSFileSize length,
+                                             GnomeVFSContext *context);
+#define     VFS_METHOD_HAS_FUNC             (method,func)
+gboolean    gnome_vfs_method_init           (void);
+GnomeVFSMethod* gnome_vfs_method_get        (const gchar *name);
+GnomeVFSTransform* gnome_vfs_transform_get  (const gchar *name);

Description

Details

GnomeVFSMethodInitFunc ()

GnomeVFSMethod* (*GnomeVFSMethodInitFunc)   (const char *method_name,
+                                             const char *config_args);

method_name : 
config_args : 
Returns : 


GnomeVFSMethodShutdownFunc ()

void        (*GnomeVFSMethodShutdownFunc)   (GnomeVFSMethod *method);

method : 


GnomeVFSMethodTruncateFunc ()

GnomeVFSResult (*GnomeVFSMethodTruncateFunc)
+                                            (GnomeVFSMethod *method,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSFileSize length,
+                                             GnomeVFSContext *context);

method : 
uri : 
length : 
context : 
Returns : 


GnomeVFSMethodTruncateHandleFunc ()

GnomeVFSResult (*GnomeVFSMethodTruncateHandleFunc)
+                                            (GnomeVFSMethod *method,
+                                             GnomeVFSMethodHandle *handle,
+                                             GnomeVFSFileSize length,
+                                             GnomeVFSContext *context);

method : 
handle : 
length : 
context : 
Returns : 


VFS_METHOD_HAS_FUNC()

#define VFS_METHOD_HAS_FUNC(method,func) ((((char *)&((method)->func)) - ((char *)(method)) < (method)->method_table_size) && method->func != NULL)

method : 
func : 


gnome_vfs_method_init ()

gboolean    gnome_vfs_method_init           (void);

Returns : 


gnome_vfs_method_get ()

GnomeVFSMethod* gnome_vfs_method_get        (const gchar *name);

name : 
Returns : 


gnome_vfs_transform_get ()

GnomeVFSTransform* gnome_vfs_transform_get  (const gchar *name);

name : 
Returns : 



<<< Previous PageHomeUpNext Page >>>
Writing Modulesmodule-shared
\ No newline at end of file diff --git a/doc/html/gnome-vfs-mime-handlers.html b/doc/html/gnome-vfs-mime-handlers.html new file mode 100644 index 0000000..d448ee1 --- /dev/null +++ b/doc/html/gnome-vfs-mime-handlers.html @@ -0,0 +1,4630 @@ +MIME Handlers
GnomeVFS - Filesystem Abstraction library
<<< Previous PageHomeUpNext Page >>>

MIME Handlers

Name

MIME Handlers -- functions for getting and manipulating the actions to be performed on mime types

Synopsis


+
+enum        GnomeVFSMimeActionType;
+enum        GnomeVFSMimeApplicationArgumentType;
+typedef     GnomeVFSMimeApplication;
+typedef     GnomeVFSMimeAction;
+GnomeVFSMimeApplication* gnome_vfs_mime_application_copy
+                                            (GnomeVFSMimeApplication *application);
+GnomeVFSMimeActionType gnome_vfs_mime_get_default_action_type
+                                            (const char *mime_type);
+GnomeVFSMimeAction* gnome_vfs_mime_get_default_action
+                                            (const char *mime_type);
+GnomeVFSMimeApplication* gnome_vfs_mime_get_default_application
+                                            (const char *mime_type);
+Bonobo_ServerInfo* gnome_vfs_mime_get_default_component
+                                            (const char *mime_type);
+GList*      gnome_vfs_mime_get_short_list_applications
+                                            (const char *mime_type);
+GList*      gnome_vfs_mime_get_short_list_components
+                                            (const char *mime_type);
+GList*      gnome_vfs_mime_get_all_applications
+                                            (const char *mime_type);
+GList*      gnome_vfs_mime_get_all_components
+                                            (const char *mime_type);
+GnomeVFSResult gnome_vfs_mime_set_default_action_type
+                                            (const char *mime_type,
+                                             GnomeVFSMimeActionType action_type);
+GnomeVFSResult gnome_vfs_mime_set_default_application
+                                            (const char *mime_type,
+                                             const char *application_id);
+GnomeVFSResult gnome_vfs_mime_set_default_component
+                                            (const char *mime_type,
+                                             const char *component_iid);
+const char* gnome_vfs_mime_get_icon         (const char *mime_type);
+GnomeVFSResult gnome_vfs_mime_set_icon      (const char *mime_type,
+                                             const char *filename);
+const char* gnome_vfs_mime_get_description  (const char *mime_type);
+GnomeVFSResult gnome_vfs_mime_set_description
+                                            (const char *mime_type,
+                                             const char *description);
+gboolean    gnome_vfs_mime_can_be_executable
+                                            (const char *mime_type);
+GnomeVFSResult gnome_vfs_mime_set_can_be_executable
+                                            (const char *mime_type,
+                                             gboolean new_value);
+GnomeVFSResult gnome_vfs_mime_set_short_list_applications
+                                            (const char *mime_type,
+                                             GList *application_ids);
+GnomeVFSResult gnome_vfs_mime_set_short_list_components
+                                            (const char *mime_type,
+                                             GList *component_iids);
+GnomeVFSResult gnome_vfs_mime_add_application_to_short_list
+                                            (const char *mime_type,
+                                             const char *application_id);
+GnomeVFSResult gnome_vfs_mime_remove_application_from_short_list
+                                            (const char *mime_type,
+                                             const char *application_id);
+GnomeVFSResult gnome_vfs_mime_add_component_to_short_list
+                                            (const char *mime_type,
+                                             const char *iid);
+GnomeVFSResult gnome_vfs_mime_remove_component_from_short_list
+                                            (const char *mime_type,
+                                             const char *iid);
+GnomeVFSResult gnome_vfs_mime_add_extension (const char *mime_type,
+                                             const char *extension);
+GnomeVFSResult gnome_vfs_mime_remove_extension
+                                            (const char *mime_type,
+                                             const char *extension);
+GnomeVFSResult gnome_vfs_mime_extend_all_applications
+                                            (const char *mime_type,
+                                             GList *application_ids);
+GnomeVFSResult gnome_vfs_mime_remove_from_all_applications
+                                            (const char *mime_type,
+                                             GList *application_ids);
+GnomeVFSMimeApplication* gnome_vfs_mime_application_new_from_id
+                                            (const char *id);
+void        gnome_vfs_mime_application_free (GnomeVFSMimeApplication *application);
+void        gnome_vfs_mime_action_free      (GnomeVFSMimeAction *action);
+void        gnome_vfs_mime_application_list_free
+                                            (GList *list);
+void        gnome_vfs_mime_component_list_free
+                                            (GList *list);
+gboolean    gnome_vfs_mime_id_in_application_list
+                                            (const char *id,
+                                             GList *applications);
+gboolean    gnome_vfs_mime_id_in_component_list
+                                            (const char *iid,
+                                             GList *components);
+GList*      gnome_vfs_mime_remove_application_from_list
+                                            (GList *applications,
+                                             const char *application_id,
+                                             gboolean *did_remove);
+GList*      gnome_vfs_mime_remove_component_from_list
+                                            (GList *components,
+                                             const char *iid,
+                                             gboolean *did_remove);
+GList*      gnome_vfs_mime_id_list_from_component_list
+                                            (GList *components);
+GList*      gnome_vfs_mime_id_list_from_application_list
+                                            (GList *applications);

Description

Details

enum GnomeVFSMimeActionType

typedef enum {
+	GNOME_VFS_MIME_ACTION_TYPE_NONE,
+	GNOME_VFS_MIME_ACTION_TYPE_APPLICATION,
+	GNOME_VFS_MIME_ACTION_TYPE_COMPONENT
+} GnomeVFSMimeActionType;


enum GnomeVFSMimeApplicationArgumentType

typedef enum {
+	GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_URIS,
+	GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_PATHS,
+	GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_URIS_FOR_NON_FILES
+} GnomeVFSMimeApplicationArgumentType;


GnomeVFSMimeApplication

typedef struct {
+	char *id;
+	char *name;
+	char *command;
+	gboolean can_open_multiple_files;
+	GnomeVFSMimeApplicationArgumentType expects_uris;
+	GList *supported_uri_schemes;
+	gboolean requires_terminal;
+} GnomeVFSMimeApplication;


GnomeVFSMimeAction

typedef struct {
+	GnomeVFSMimeActionType action_type;
+	union {
+		Bonobo_ServerInfo *component;
+		void *dummy_component;
+		GnomeVFSMimeApplication *application;
+	} action;
+} GnomeVFSMimeAction;


gnome_vfs_mime_application_copy ()

GnomeVFSMimeApplication* gnome_vfs_mime_application_copy
+                                            (GnomeVFSMimeApplication *application);

Creates a newly referenced copy of a GnomeVFSMimeApplication object.

application : The GnomeVFSMimeApplication to be duplicated.
Returns : A copy of application


gnome_vfs_mime_get_default_action_type ()

GnomeVFSMimeActionType gnome_vfs_mime_get_default_action_type
+                                            (const char *mime_type);

Query the MIME database for the type of action to be performed on a particular MIME type by default.

mime_type : A const char * containing a mime type, e.g. "application/x-php"
Returns : The type of action to be performed on a file of +MIME type, mime_type by default.


gnome_vfs_mime_get_default_action ()

GnomeVFSMimeAction* gnome_vfs_mime_get_default_action
+                                            (const char *mime_type);

Query the MIME database for default action associated with a particular MIME type mime_type.

mime_type : A const char * containing a mime type, e.g. "application/x-php"
Returns : A GnomeVFSMimeAction representing the default action to perform upon +file of type mime_type.


gnome_vfs_mime_get_default_application ()

GnomeVFSMimeApplication* gnome_vfs_mime_get_default_application
+                                            (const char *mime_type);

Query the MIME database for the application to be executed on files of MIME type +mime_type by default.

mime_type : A const char * containing a mime type, e.g. "image/png"
Returns : A GnomeVFSMimeApplication representing the default handler of mime_type


gnome_vfs_mime_get_default_component ()

Bonobo_ServerInfo* gnome_vfs_mime_get_default_component
+                                            (const char *mime_type);

Query the MIME database for the default Bonobo component to be activated to +view files of MIME type mime_type.

mime_type : A const char * containing a mime type, e.g. "image/png"
Returns : An Bonobo_ServerInfo * representing the OAF server to be activated +to get a reference to the proper component.


gnome_vfs_mime_get_short_list_applications ()

GList*      gnome_vfs_mime_get_short_list_applications
+                                            (const char *mime_type);

Return an alphabetically sorted list of GnomeVFSMimeApplication +data structures for the requested mime type. The short list contains +"select" applications recommended for handling this MIME type, appropriate for +display to the user.

mime_type : A const char * containing a mime type, e.g. "image/png"
Returns : A GList * where the elements are GnomeVFSMimeApplication * +representing various applications to display in the short list for mime_type.


gnome_vfs_mime_get_short_list_components ()

GList*      gnome_vfs_mime_get_short_list_components
+                                            (const char *mime_type);

Return an unsorted sorted list of Bonobo_ServerInfo * +data structures for the requested mime type. The short list contains +"select" components recommended for handling this MIME type, appropriate for +display to the user.

mime_type : A const char * containing a mime type, e.g. "image/png"
Returns : A GList * where the elements are Bonobo_ServerInfo * +representing various components to display in the short list for mime_type.


gnome_vfs_mime_get_all_applications ()

GList*      gnome_vfs_mime_get_all_applications
+                                            (const char *mime_type);

Return an alphabetically sorted list of GnomeVFSMimeApplication +data structures representing all applications in the MIME database registered +to handle files of MIME type mime_type (and supertypes).

mime_type : A const char * containing a mime type, e.g. "image/png"
Returns : A GList * where the elements are GnomeVFSMimeApplication * +representing applications that handle MIME type mime_type.


gnome_vfs_mime_get_all_components ()

GList*      gnome_vfs_mime_get_all_components
+                                            (const char *mime_type);

Return an alphabetically sorted list of Bonobo_ServerInfo +data structures representing all Bonobo components registered +to handle files of MIME type mime_type (and supertypes).

mime_type : A const char * containing a mime type, e.g. "image/png"
Returns : A GList * where the elements are Bonobo_ServerInfo * +representing components that can handle MIME type mime_type.


gnome_vfs_mime_set_default_action_type ()

GnomeVFSResult gnome_vfs_mime_set_default_action_type
+                                            (const char *mime_type,
+                                             GnomeVFSMimeActionType action_type);

Sets the default action type to be performed on files of MIME type mime_type.

mime_type : A const char * containing a mime type, e.g. "image/png"
action_type : A GnomeVFSMimeActionType containing the action to perform by default
Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered.


gnome_vfs_mime_set_default_application ()

GnomeVFSResult gnome_vfs_mime_set_default_application
+                                            (const char *mime_type,
+                                             const char *application_id);

Sets the default application to be run on files of MIME type mime_type.

mime_type : A const char * containing a mime type, e.g. "application/x-php"
application_id : A key representing an application in the MIME database +(GnomeVFSMimeApplication->id, for example)
Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered.


gnome_vfs_mime_set_default_component ()

GnomeVFSResult gnome_vfs_mime_set_default_component
+                                            (const char *mime_type,
+                                             const char *component_iid);

Sets the default component to be activated for files of MIME type mime_type.

mime_type : A const char * containing a mime type, e.g. "application/x-php"
component_iid : The OAFIID of a component
Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered.


gnome_vfs_mime_get_icon ()

const char* gnome_vfs_mime_get_icon         (const char *mime_type);

Query the MIME database for an icon representing the specified MIME type.

mime_type : A const char * containing a MIME type
Returns : The filename of the icon as listed in the MIME database. This is +usually a filename without path information, e.g. "i-chardev.png", and sometimes +does not have an extension, e.g. "i-regular" if the icon is supposed to be image +type agnostic between icon themes. Icons are generic, and not theme specific. These +will not necessarily match with the icons a user sees in Nautilus, you have been warned.


gnome_vfs_mime_set_icon ()

GnomeVFSResult gnome_vfs_mime_set_icon      (const char *mime_type,
+                                             const char *filename);

Set the icon entry for a particular MIME type in the MIME database. Note that +icon entries need not necessarily contain the full path, and do not necessarily need to +specify an extension. So "i-regular", "my-special-icon.png", and "some-icon" +are all valid icon filenames.

mime_type : A const char * containing a MIME type
filename : a const char * containing an image filename
Returns : A GnomeVFSResult indicating the success of the operation +or any errors that may have occurred.


gnome_vfs_mime_get_description ()

const char* gnome_vfs_mime_get_description  (const char *mime_type);

Query the MIME database for a description of the specified MIME type.

mime_type : the mime type
Returns : A description of MIME type mime_type


gnome_vfs_mime_set_description ()

GnomeVFSResult gnome_vfs_mime_set_description
+                                            (const char *mime_type,
+                                             const char *description);

Set the description of this MIME type in the MIME database. The description +should be something like "Gnumeric spreadsheet".

mime_type : A const char * containing a mime type
description : A description of this MIME type
Returns : GnomeVFSResult indicating the success of the operation or any +errors that may have occurred.


gnome_vfs_mime_can_be_executable ()

gboolean    gnome_vfs_mime_can_be_executable
+                                            (const char *mime_type);

Check whether files of this MIME type might conceivably be executable. +Default for known types if FALSE. Default for unknown types is TRUE.

mime_type : A const char * containing a mime type
Returns : gboolean containing TRUE if some files of this MIME type +are registered as being executable, and false otherwise.


gnome_vfs_mime_set_can_be_executable ()

GnomeVFSResult gnome_vfs_mime_set_can_be_executable
+                                            (const char *mime_type,
+                                             gboolean new_value);

Set whether files of this MIME type might conceivably be executable.

mime_type : A const char * containing a mime type
new_value : A boolean value indicating whether mime_type could be executable.
Returns : GnomeVFSResult indicating the success of the operation or any +errors that may have occurred.


gnome_vfs_mime_set_short_list_applications ()

GnomeVFSResult gnome_vfs_mime_set_short_list_applications
+                                            (const char *mime_type,
+                                             GList *application_ids);

Set the short list of applications for the specified MIME type. The short list +contains applications recommended for possible selection by the user.

mime_type : A const char * containing a mime type, e.g. "application/x-php"
application_ids : GList of const char * application ids
Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered.


gnome_vfs_mime_set_short_list_components ()

GnomeVFSResult gnome_vfs_mime_set_short_list_components
+                                            (const char *mime_type,
+                                             GList *component_iids);

Set the short list of components for the specified MIME type. The short list +contains companents recommended for possible selection by the user. *

mime_type : A const char * containing a mime type, e.g. "application/x-php"
component_iids : GList of const char * OAF IIDs
Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered.


gnome_vfs_mime_add_application_to_short_list ()

GnomeVFSResult gnome_vfs_mime_add_application_to_short_list
+                                            (const char *mime_type,
+                                             const char *application_id);

Add an application to the short list for MIME type mime_type. The short list contains +applications recommended for display as choices to the user for a particular MIME type.

mime_type : A const char * containing a mime type, e.g. "application/x-php"
application_id : const char * containing the application's id in the MIME database
Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered.


gnome_vfs_mime_remove_application_from_short_list ()

GnomeVFSResult gnome_vfs_mime_remove_application_from_short_list
+                                            (const char *mime_type,
+                                             const char *application_id);

Remove an application from the short list for MIME type mime_type. The short list contains +applications recommended for display as choices to the user for a particular MIME type.

mime_type : A const char * containing a mime type, e.g. "application/x-php"
application_id : const char * containing the application's id in the MIME database
Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered.


gnome_vfs_mime_add_component_to_short_list ()

GnomeVFSResult gnome_vfs_mime_add_component_to_short_list
+                                            (const char *mime_type,
+                                             const char *iid);

Add a component to the short list for MIME type mime_type. The short list contains +components recommended for display as choices to the user for a particular MIME type.

mime_type : A const char * containing a mime type, e.g. "application/x-php"
iid : const char * containing the component's OAF IID
Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered.


gnome_vfs_mime_remove_component_from_short_list ()

GnomeVFSResult gnome_vfs_mime_remove_component_from_short_list
+                                            (const char *mime_type,
+                                             const char *iid);

Remove a component from the short list for MIME type mime_type. The short list contains +components recommended for display as choices to the user for a particular MIME type.

mime_type : A const char * containing a mime type, e.g. "application/x-php"
iid : const char * containing the component's OAF IID
Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered.


gnome_vfs_mime_add_extension ()

GnomeVFSResult gnome_vfs_mime_add_extension (const char *mime_type,
+                                             const char *extension);

Add a file extension to the specificed MIME type in the MIME database.

mime_type : The mime type to add the mapping to.
extension : The extension to add (e.g. "txt")
Returns : GnomeVFSResult indicating the success of the operation or any +errors that may have occurred.


gnome_vfs_mime_remove_extension ()

GnomeVFSResult gnome_vfs_mime_remove_extension
+                                            (const char *mime_type,
+                                             const char *extension);

Removes a file extension from the specificed MIME type in the MIME database.

mime_type : The mime type to remove the extension from
extension : The extension to remove
Returns : GnomeVFSResult indicating the success of the operation or any +errors that may have occurred.


gnome_vfs_mime_extend_all_applications ()

GnomeVFSResult gnome_vfs_mime_extend_all_applications
+                                            (const char *mime_type,
+                                             GList *application_ids);

Register mime_type as being handled by all applications list in application_ids.

mime_type : A const char * containing a mime type, e.g. "application/x-php"
application_ids : a GList of const char * containing application ids
Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered.


gnome_vfs_mime_remove_from_all_applications ()

GnomeVFSResult gnome_vfs_mime_remove_from_all_applications
+                                            (const char *mime_type,
+                                             GList *application_ids);

Remove mime_type as a handled type from every application in application_ids

mime_type : A const char * containing a mime type, e.g. "application/x-php"
application_ids : a GList of const char * containing application ids
Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered.


gnome_vfs_mime_application_new_from_id ()

GnomeVFSMimeApplication* gnome_vfs_mime_application_new_from_id
+                                            (const char *id);

Fetches the GnomeVFSMimeApplication associated with the specified +application ID from the MIME database.

id : A const char * containing an application id
Returns : GnomeVFSMimeApplication * corresponding to id


gnome_vfs_mime_application_free ()

void        gnome_vfs_mime_application_free (GnomeVFSMimeApplication *application);

Frees a GnomeVFSMimeApplication *.

application : The GnomeVFSMimeApplication to be freed


gnome_vfs_mime_action_free ()

void        gnome_vfs_mime_action_free      (GnomeVFSMimeAction *action);

Frees a GnomeVFSMimeAction *.

action : The GnomeVFSMimeAction to be freed


gnome_vfs_mime_application_list_free ()

void        gnome_vfs_mime_application_list_free
+                                            (GList *list);

Frees lists of GnomeVFSApplications, as returned from functions such +as gnome_vfs_get_all_applications().

list : a GList of GnomeVFSApplication * to be freed


gnome_vfs_mime_component_list_free ()

void        gnome_vfs_mime_component_list_free
+                                            (GList *list);

Frees lists of Bonobo_ServerInfo * (as returned from functions such +as gnome_vfs_get_all_components)

list : a GList of Bonobo_ServerInfo * to be freed


gnome_vfs_mime_id_in_application_list ()

gboolean    gnome_vfs_mime_id_in_application_list
+                                            (const char *id,
+                                             GList *applications);

Check whether an application id is in a list of GnomeVFSMimeApplications.

id : An application id.
applications : A GList * whose nodes are GnomeVFSMimeApplications, such as the +result of gnome_vfs_mime_get_short_list_applications().
Returns : TRUE if an application whose id matches id is in applications.


gnome_vfs_mime_id_in_component_list ()

gboolean    gnome_vfs_mime_id_in_component_list
+                                            (const char *iid,
+                                             GList *components);

Check whether a component iid is in a list of Bonobo_ServerInfos.

iid : A component iid.
components : A GList * whose nodes are Bonobo_ServerInfos, such as the +result of gnome_vfs_mime_get_short_list_components().
Returns : TRUE if a component whose iid matches iid is in components.


gnome_vfs_mime_remove_application_from_list ()

GList*      gnome_vfs_mime_remove_application_from_list
+                                            (GList *applications,
+                                             const char *application_id,
+                                             gboolean *did_remove);

Remove an application specified by id from a list of GnomeVFSMimeApplications.

applications : A GList * whose nodes are GnomeVFSMimeApplications, such as the +result of gnome_vfs_mime_get_short_list_applications().
application_id : The id of an application to remove from applications.
did_remove : If non-NULL, this is filled in with TRUE if the application +was found in the list, FALSE otherwise.
Returns : The modified list. If the application is not found, the list will +be unchanged.


gnome_vfs_mime_remove_component_from_list ()

GList*      gnome_vfs_mime_remove_component_from_list
+                                            (GList *components,
+                                             const char *iid,
+                                             gboolean *did_remove);

Remove a component specified by iid from a list of Bonobo_ServerInfos.

components : A GList * whose nodes are Bonobo_ServerInfos, such as the +result of gnome_vfs_mime_get_short_list_components().
iid : The iid of a component to remove from components.
did_remove : If non-NULL, this is filled in with TRUE if the component +was found in the list, FALSE otherwise.
Returns : The modified list. If the component is not found, the list will +be unchanged.


gnome_vfs_mime_id_list_from_component_list ()

GList*      gnome_vfs_mime_id_list_from_component_list
+                                            (GList *components);

Create a list of component iids from a list of Bonobo_ServerInfos.

components : A GList * whose nodes are Bonobo_ServerInfos, such as the +result of gnome_vfs_mime_get_short_list_components().
Returns : A new list where each Bonobo_ServerInfo in the original +list is replaced by a char * with the component's iid. The original list is +not modified.


gnome_vfs_mime_id_list_from_application_list ()

GList*      gnome_vfs_mime_id_list_from_application_list
+                                            (GList *applications);

Create a list of application ids from a list of GnomeVFSMimeApplications.

applications : A GList * whose nodes are GnomeVFSMimeApplications, such as the +result of gnome_vfs_mime_get_short_list_applications().
Returns : A new list where each GnomeVFSMimeApplication in the original +list is replaced by a char * with the application's id. The original list is +not modified.



<<< Previous PageHomeUpNext Page >>>
MIME Type Detectionmime-info
\ No newline at end of file diff --git a/doc/html/gnome-vfs-mime-info.html b/doc/html/gnome-vfs-mime-info.html new file mode 100644 index 0000000..6962177 --- /dev/null +++ b/doc/html/gnome-vfs-mime-info.html @@ -0,0 +1,1709 @@ +mime-info
GnomeVFS - Filesystem Abstraction library
<<< Previous PageHomeUpNext Page >>>

mime-info

Name

mime-info -- 

Synopsis


+
+void        gnome_vfs_mime_freeze           (void);
+void        gnome_vfs_mime_thaw             (void);
+void        gnome_vfs_mime_info_reload      (void);
+gboolean    gnome_vfs_mime_type_is_known    (const char *mime_type);
+const char* gnome_vfs_mime_get_value        (const char *mime_type,
+                                             const char *key);
+GnomeVFSResult gnome_vfs_mime_set_value     (const char *mime_type,
+                                             const char *key,
+                                             const char *value);
+GList*      gnome_vfs_mime_get_key_list     (const char *mime_type);
+void        gnome_vfs_mime_keys_list_free   (GList *mime_type_list);
+GList*      gnome_vfs_mime_get_extensions_list
+                                            (const char *mime_type);
+void        gnome_vfs_mime_extensions_list_free
+                                            (GList *list);
+char*       gnome_vfs_mime_get_extensions_string
+                                            (const char *mime_type);
+char*       gnome_vfs_mime_get_extensions_pretty_string
+                                            (const char *mime_type);
+GList*      gnome_vfs_get_registered_mime_types
+                                            (void);
+void        gnome_vfs_mime_registered_mime_type_list_free
+                                            (GList *list);
+GnomeVFSResult gnome_vfs_mime_set_registered_type_key
+                                            (const char *mime_type,
+                                             const char *key,
+                                             const char *data);
+GnomeVFSResult gnome_vfs_mime_set_extensions_list
+                                            (const char *mime_type,
+                                             const char *extensions_list);
+void        gnome_vfs_mime_registered_mime_type_delete
+                                            (const char *mime_type);
+void        gnome_vfs_mime_reset            (void);

Description

Details

gnome_vfs_mime_freeze ()

void        gnome_vfs_mime_freeze           (void);

Freezes the mime data so that you can do multiple +updates to the dat in one batch without needing +to back the files to disk or readind them


gnome_vfs_mime_thaw ()

void        gnome_vfs_mime_thaw             (void);

UnFreezes the mime data so that you can do multiple +updates to the dat in one batch without needing +to back the files to disk or readind them


gnome_vfs_mime_info_reload ()

void        gnome_vfs_mime_info_reload      (void);


gnome_vfs_mime_type_is_known ()

gboolean    gnome_vfs_mime_type_is_known    (const char *mime_type);

This function returns TRUE if mime_type is in the MIME database at all.

mime_type : a mime type.
Returns : TRUE if anything is known about mime_type, otherwise FALSE


gnome_vfs_mime_get_value ()

const char* gnome_vfs_mime_get_value        (const char *mime_type,
+                                             const char *key);

This function retrieves the value associated with key in +the given GnomeMimeContext. The string is private, you +should not free the result.

mime_type : a mime type.
key : A key to lookup for the given mime-type
Returns : GNOME_VFS_OK if the operation succeeded, otherwise an error code


gnome_vfs_mime_set_value ()

GnomeVFSResult gnome_vfs_mime_set_value     (const char *mime_type,
+                                             const char *key,
+                                             const char *value);

This function is going to set the value +associated to the key and it will save it +to the user' file if necessary. +You should not free the key/values passed to +this function. They are used internally.

mime_type : a mime type.
key : a key to store the value in.
value : the value to store in the key.
Returns : GNOME_VFS_OK if the operation succeeded, otherwise an error code


gnome_vfs_mime_get_key_list ()

GList*      gnome_vfs_mime_get_key_list     (const char *mime_type);

mime_type : the mime type to lookup.
Returns :a GList that contains private strings with all of the keys +associated with the mime_type.


gnome_vfs_mime_keys_list_free ()

void        gnome_vfs_mime_keys_list_free   (GList *mime_type_list);

Frees the mime type list.

mime_type_list : A mime type list to free.


gnome_vfs_mime_get_extensions_list ()

GList*      gnome_vfs_mime_get_extensions_list
+                                            (const char *mime_type);

mime_type : the mime type
Returns :a list of extensions for this mime-type


gnome_vfs_mime_extensions_list_free ()

void        gnome_vfs_mime_extensions_list_free
+                                            (GList *list);

list : 


gnome_vfs_mime_get_extensions_string ()

char*       gnome_vfs_mime_get_extensions_string
+                                            (const char *mime_type);

mime_type : 
Returns : 


gnome_vfs_mime_get_extensions_pretty_string ()

char*       gnome_vfs_mime_get_extensions_pretty_string
+                                            (const char *mime_type);

mime_type : the mime type
Returns :a string containing comma seperated extensions for this mime-type


gnome_vfs_get_registered_mime_types ()

GList*      gnome_vfs_get_registered_mime_types
+                                            (void);

Returns : 


gnome_vfs_mime_registered_mime_type_list_free ()

void        gnome_vfs_mime_registered_mime_type_list_free
+                                            (GList *list);

Call this function on the list returned by gnome_vfs_get_registered_mime_types +to free the list and all of its elements.

list : the extensions list


gnome_vfs_mime_set_registered_type_key ()

GnomeVFSResult gnome_vfs_mime_set_registered_type_key
+                                            (const char *mime_type,
+                                             const char *key,
+                                             const char *data);

This function sets the key data for the registered mime +type's hash table.

mime_type : Mime type to set key for
key : The key to set
data : The data to set for the key
Returns : GNOME_VFS_OK if the operation succeeded, otherwise an error code


gnome_vfs_mime_set_extensions_list ()

GnomeVFSResult gnome_vfs_mime_set_extensions_list
+                                            (const char *mime_type,
+                                             const char *extensions_list);

Sets the extensions for a given mime type. Overrides +the previously set extensions.

mime_type : the mime type.
extensions_list : a whitespace-separated list of the +extensions to set for this mime type.
Returns : GNOME_VFS_OK if the operation succeeded, otherwise an error code.


gnome_vfs_mime_registered_mime_type_delete ()

void        gnome_vfs_mime_registered_mime_type_delete
+                                            (const char *mime_type);

Delete a mime type for the user which runs this command. +You can undo this only by calling gnome_vfs_mime_reset

mime_type : 


gnome_vfs_mime_reset ()

void        gnome_vfs_mime_reset            (void);

resets the user's mime database to the system defaults.



<<< Previous PageHomeUpNext Page >>>
MIME Handlersmime-monitor
\ No newline at end of file diff --git a/doc/html/gnome-vfs-mime-magic.html b/doc/html/gnome-vfs-mime-magic.html new file mode 100644 index 0000000..6077f54 --- /dev/null +++ b/doc/html/gnome-vfs-mime-magic.html @@ -0,0 +1,542 @@ +Magic MIME Detection
GnomeVFS - Filesystem Abstraction library
<<< Previous PageHomeUpNext Page >>>

Magic MIME Detection

Name

Magic MIME Detection -- functions for parsing the magic mime database

Synopsis


+
+enum        GnomeMagicType;
+GnomeMagicEntry* gnome_vfs_mime_magic_parse (const gchar *filename,
+                                             gint *nents);
+GnomeMagicEntry* gnome_vfs_mime_test_get_magic_table
+                                            (const char *table_path);
+void        gnome_vfs_mime_dump_magic_table (void);

Description

Details

enum GnomeMagicType

typedef enum {
+	T_END, /* end of array */
+	T_BYTE,
+	T_SHORT,
+	T_LONG,
+	T_STR,
+	T_DATE, 
+	T_BESHORT,
+	T_BELONG,
+	T_BEDATE,
+	T_LESHORT,
+	T_LELONG,
+	T_LEDATE
+} GnomeMagicType;


gnome_vfs_mime_magic_parse ()

GnomeMagicEntry* gnome_vfs_mime_magic_parse (const gchar *filename,
+                                             gint *nents);

filename : 
nents : 
Returns : 


gnome_vfs_mime_test_get_magic_table ()

GnomeMagicEntry* gnome_vfs_mime_test_get_magic_table
+                                            (const char *table_path);

table_path : 
Returns : 


gnome_vfs_mime_dump_magic_table ()

void        gnome_vfs_mime_dump_magic_table (void);



<<< Previous PageHomeUpNext Page >>>
Application RegistryMIME Type Detection
\ No newline at end of file diff --git a/doc/html/gnome-vfs-mime-monitor.html b/doc/html/gnome-vfs-mime-monitor.html new file mode 100644 index 0000000..ce0f9f2 --- /dev/null +++ b/doc/html/gnome-vfs-mime-monitor.html @@ -0,0 +1,383 @@ +mime-monitor
GnomeVFS - Filesystem Abstraction library
<<< Previous PageHomeUpNext Page >>>

mime-monitor

Name

mime-monitor -- 

Description

Details

GnomeVFSMIMEMonitor

typedef struct {
+	GObject object;
+
+	GnomeVFSMIMEMonitorPrivate *priv;
+} GnomeVFSMIMEMonitor;


gnome_vfs_mime_monitor_get ()

GnomeVFSMIMEMonitor* gnome_vfs_mime_monitor_get
+                                            (void);

Returns : 



<<< Previous PageHomeUpNext Page >>>
mime-infoFilesystem Modules
\ No newline at end of file diff --git a/doc/html/gnome-vfs-mime-sniff-buffer.html b/doc/html/gnome-vfs-mime-sniff-buffer.html new file mode 100644 index 0000000..d430443 --- /dev/null +++ b/doc/html/gnome-vfs-mime-sniff-buffer.html @@ -0,0 +1,1625 @@ +Algorithmic Sniff Buffer
GnomeVFS - Filesystem Abstraction library
<<< Previous PageHomeUpNext Page >>>

Algorithmic Sniff Buffer

Name

Algorithmic Sniff Buffer -- algorithmic detection of mime type for select file types

Synopsis


+
+GnomeVFSResult (*GnomeVFSSniffBufferSeekCall)
+                                            (gpointer context,
+                                             GnomeVFSSeekPosition whence,
+                                             GnomeVFSFileOffset offset);
+GnomeVFSResult (*GnomeVFSSniffBufferReadCall)
+                                            (gpointer context,
+                                             gpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_read);
+void        gnome_vfs_mime_clear_magic_table
+                                            (void);
+GnomeVFSMimeSniffBuffer* gnome_vfs_mime_sniff_buffer_new_from_handle
+                                            (GnomeVFSHandle *file);
+GnomeVFSMimeSniffBuffer* gnome_vfs_mime_sniff_buffer_new_from_memory
+                                            (const guchar *buffer,
+                                             gssize buffer_size);
+GnomeVFSMimeSniffBuffer* gnome_vfs_mime_sniff_buffer_new_from_existing_data
+                                            (const guchar *buffer,
+                                             gssize buffer_size);
+GnomeVFSMimeSniffBuffer* gnome_vfs_mime_sniff_buffer_new_generic
+                                            (GnomeVFSSniffBufferSeekCall seek_callback,
+                                             GnomeVFSSniffBufferReadCall read_callback,
+                                             gpointer context);
+void        gnome_vfs_mime_sniff_buffer_free
+                                            (GnomeVFSMimeSniffBuffer *buffer);
+GnomeVFSResult gnome_vfs_mime_sniff_buffer_get
+                                            (GnomeVFSMimeSniffBuffer *buffer,
+                                             gssize size);
+const char* gnome_vfs_get_mime_type_for_buffer
+                                            (GnomeVFSMimeSniffBuffer *buffer);
+gboolean    gnome_vfs_sniff_buffer_looks_like_text
+                                            (GnomeVFSMimeSniffBuffer *buffer);
+gboolean    gnome_vfs_sniff_buffer_looks_like_mp3
+                                            (GnomeVFSMimeSniffBuffer *buffer);
+gboolean    gnome_vfs_sniff_buffer_looks_like_gzip
+                                            (GnomeVFSMimeSniffBuffer *sniff_buffer,
+                                             const char *file_name);

Description

Details

GnomeVFSSniffBufferSeekCall ()

GnomeVFSResult (*GnomeVFSSniffBufferSeekCall)
+                                            (gpointer context,
+                                             GnomeVFSSeekPosition whence,
+                                             GnomeVFSFileOffset offset);

context : 
whence : 
offset : 
Returns : 


GnomeVFSSniffBufferReadCall ()

GnomeVFSResult (*GnomeVFSSniffBufferReadCall)
+                                            (gpointer context,
+                                             gpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_read);

context : 
buffer : 
bytes : 
bytes_read : 
Returns : 


gnome_vfs_mime_clear_magic_table ()

void        gnome_vfs_mime_clear_magic_table
+                                            (void);


gnome_vfs_mime_sniff_buffer_new_from_handle ()

GnomeVFSMimeSniffBuffer* gnome_vfs_mime_sniff_buffer_new_from_handle
+                                            (GnomeVFSHandle *file);

file : 
Returns : 


gnome_vfs_mime_sniff_buffer_new_from_memory ()

GnomeVFSMimeSniffBuffer* gnome_vfs_mime_sniff_buffer_new_from_memory
+                                            (const guchar *buffer,
+                                             gssize buffer_size);

buffer : 
buffer_size : 
Returns : 


gnome_vfs_mime_sniff_buffer_new_from_existing_data ()

GnomeVFSMimeSniffBuffer* gnome_vfs_mime_sniff_buffer_new_from_existing_data
+                                            (const guchar *buffer,
+                                             gssize buffer_size);

buffer : 
buffer_size : 
Returns : 


gnome_vfs_mime_sniff_buffer_new_generic ()

GnomeVFSMimeSniffBuffer* gnome_vfs_mime_sniff_buffer_new_generic
+                                            (GnomeVFSSniffBufferSeekCall seek_callback,
+                                             GnomeVFSSniffBufferReadCall read_callback,
+                                             gpointer context);

seek_callback : 
read_callback : 
context : 
Returns : 


gnome_vfs_mime_sniff_buffer_free ()

void        gnome_vfs_mime_sniff_buffer_free
+                                            (GnomeVFSMimeSniffBuffer *buffer);

buffer : 


gnome_vfs_mime_sniff_buffer_get ()

GnomeVFSResult gnome_vfs_mime_sniff_buffer_get
+                                            (GnomeVFSMimeSniffBuffer *buffer,
+                                             gssize size);

buffer : 
size : 
Returns : 


gnome_vfs_get_mime_type_for_buffer ()

const char* gnome_vfs_get_mime_type_for_buffer
+                                            (GnomeVFSMimeSniffBuffer *buffer);

This routine uses a magic database to guess the mime type of the +data represented by buffer.

buffer : a sniff buffer referencing either a file or data in memory
Returns :a pointer to an internal copy of the mime-type for buffer.


gnome_vfs_sniff_buffer_looks_like_text ()

gboolean    gnome_vfs_sniff_buffer_looks_like_text
+                                            (GnomeVFSMimeSniffBuffer *buffer);

buffer : 
Returns : 


gnome_vfs_sniff_buffer_looks_like_mp3 ()

gboolean    gnome_vfs_sniff_buffer_looks_like_mp3
+                                            (GnomeVFSMimeSniffBuffer *buffer);

buffer : 
Returns : 


gnome_vfs_sniff_buffer_looks_like_gzip ()

gboolean    gnome_vfs_sniff_buffer_looks_like_gzip
+                                            (GnomeVFSMimeSniffBuffer *sniff_buffer,
+                                             const char *file_name);

sniff_buffer : 
file_name : 
Returns : 



<<< Previous PageHomeUpNext Page >>>
MIME types & the Application RegistryApplication Registry
\ No newline at end of file diff --git a/doc/html/gnome-vfs-mime.html b/doc/html/gnome-vfs-mime.html new file mode 100644 index 0000000..6d4c387 --- /dev/null +++ b/doc/html/gnome-vfs-mime.html @@ -0,0 +1,1265 @@ +MIME Type Detection
GnomeVFS - Filesystem Abstraction library
<<< Previous PageHomeUpNext Page >>>

MIME Type Detection

Name

MIME Type Detection -- detecting the mime type of a URI

Synopsis


+
+#define     GNOME_VFS_MIME_TYPE_UNKNOWN
+void        gnome_vfs_mime_shutdown         (void);
+const char* gnome_vfs_mime_type_from_name   (const gchar *filename);
+const char* gnome_vfs_mime_type_from_name_or_default
+                                            (const gchar *filename,
+                                             const gchar *defaultv);
+char*       gnome_vfs_get_mime_type         (const char *text_uri);
+const char* gnome_vfs_get_mime_type_from_uri
+                                            (GnomeVFSURI *uri);
+const char* gnome_vfs_get_mime_type_from_file_data
+                                            (GnomeVFSURI *uri);
+const char* gnome_vfs_get_mime_type_for_data
+                                            (gconstpointer data,
+                                             int data_size);
+const char* gnome_vfs_get_file_mime_type    (const char *path,
+                                             const struct stat *optional_stat_info,
+                                             gboolean suffix_only);
+gboolean    gnome_vfs_mime_type_is_supertype
+                                            (const char *mime_type);
+char*       gnome_vfs_get_supertype_from_mime_type
+                                            (const char *mime_type);

Description

Details

GNOME_VFS_MIME_TYPE_UNKNOWN

#define GNOME_VFS_MIME_TYPE_UNKNOWN "application/octet-stream"


gnome_vfs_mime_shutdown ()

void        gnome_vfs_mime_shutdown         (void);


gnome_vfs_mime_type_from_name ()

const char* gnome_vfs_mime_type_from_name   (const gchar *filename);

Determined the mime type for filename.

filename : A filename (the file does not necessarily exist).
Returns :the mime-type for this filename.


gnome_vfs_mime_type_from_name_or_default ()

const char* gnome_vfs_mime_type_from_name_or_default
+                                            (const gchar *filename,
+                                             const gchar *defaultv);

This routine tries to determine the mime-type of the filename +only by looking at the filename from the GNOME database of mime-types.

filename : A filename (the file does not necesarily exist).
defaultv : A default value to be returned if no match is found
Returns :the mime-type of the filename. If no value could be +determined, it will return defaultv.


gnome_vfs_get_mime_type ()

char*       gnome_vfs_get_mime_type         (const char *text_uri);

Determine the mime type of text_uri. The mime type is determined +in the same way as by gnome_vfs_get_file_info(). This is meant as +a convenience function for times when you only want the mime type.

text_uri : URI of the file for which to get the mime type
Returns : The mime type, or NULL if there is an error reading +the file.


gnome_vfs_get_mime_type_from_uri ()

const char* gnome_vfs_get_mime_type_from_uri
+                                            (GnomeVFSURI *uri);

Tries to guess the mime type of the file uri by +checking the file name extension. Works on non-existent +files.

uri : A file uri.
Returns :the mime-type for this filename.


gnome_vfs_get_mime_type_from_file_data ()

const char* gnome_vfs_get_mime_type_from_file_data
+                                            (GnomeVFSURI *uri);

Tries to guess the mime type of the file uri by +checking the file data using the magic patterns. Does not handle text files properly

uri : A file uri.
Returns :the mime-type for this filename.


gnome_vfs_get_mime_type_for_data ()

const char* gnome_vfs_get_mime_type_for_data
+                                            (gconstpointer data,
+                                             int data_size);

Tries to guess the mime type of the data in data +using the magic patterns.

data : A pointer to data in memory.
data_size : Size of the data.
Returns :the mime-type for this filename.


gnome_vfs_get_file_mime_type ()

const char* gnome_vfs_get_file_mime_type    (const char *path,
+                                             const struct stat *optional_stat_info,
+                                             gboolean suffix_only);

Tries to guess the mime type of the file represented by path. +If suffix_only is false, uses the mime-magic based lookup first. +Handles passing path of a non-existent file by falling back +on returning a type based on the extension.

path : a path of a file.
optional_stat_info : optional stat buffer.
suffix_only : whether or not to do a magic-based lookup.
Returns : the mime-type for this path


gnome_vfs_mime_type_is_supertype ()

gboolean    gnome_vfs_mime_type_is_supertype
+                                            (const char *mime_type);

mime_type : 
Returns : 


gnome_vfs_get_supertype_from_mime_type ()

char*       gnome_vfs_get_supertype_from_mime_type
+                                            (const char *mime_type);

mime_type : 
Returns : 



<<< Previous PageHomeUpNext Page >>>
Magic MIME DetectionMIME Handlers
\ No newline at end of file diff --git a/doc/html/gnome-vfs-module-callback-module-api.html b/doc/html/gnome-vfs-module-callback-module-api.html new file mode 100644 index 0000000..569881d --- /dev/null +++ b/doc/html/gnome-vfs-module-callback-module-api.html @@ -0,0 +1,522 @@ +Module Callbacks (Module API)
GnomeVFS - Filesystem Abstraction library
<<< Previous PageHomeUpNext Page >>>

Module Callbacks (Module API)

Name

Module Callbacks (Module API) -- interface to module callbacks for use by gnome-vfs modules

Synopsis


+
+gboolean    gnome_vfs_module_callback_invoke
+                                            (const char *callback_name,
+                                             gconstpointer in,
+                                             gsize in_size,
+                                             gpointer out,
+                                             gsize out_size);

Description

Modules need to perform special operations on callbacks that are not +needed by applications, for instance, invoking them.

Details

gnome_vfs_module_callback_invoke ()

gboolean    gnome_vfs_module_callback_invoke
+                                            (const char *callback_name,
+                                             gconstpointer in,
+                                             gsize in_size,
+                                             gpointer out,
+                                             gsize out_size);

Invoke a default callback for callback_name, with in arguments +specified by in and in_size, and out arguments specified by out +and out_size.

This function should only be called by gnome-vfs modules.

If this function is called from an async job thread, it will invoke +the current async handler for callback_name, if any. If no async +handler is set, or the function is not called from an async job +thread, the regular handler, if any, will be invoked instead. If no +handler at all is found for callback_name, the function returns +FALSE.

callback_name : The name of the module callback to set
in : In argument - type dependent on the specific callback
in_size : Size of the in argument
out : Out argument - type dependent on the specific callback
out_size : Size of the out argument
Returns : TRUE if a callback was invoked, FALSE if none was set.

\ No newline at end of file diff --git a/doc/html/gnome-vfs-module-callbacks.html b/doc/html/gnome-vfs-module-callbacks.html new file mode 100644 index 0000000..ff9ce06 --- /dev/null +++ b/doc/html/gnome-vfs-module-callbacks.html @@ -0,0 +1,1862 @@ +Module Callbacks
GnomeVFS - Filesystem Abstraction library
<<< Previous PageHomeUpNext Page >>>

Module Callbacks

Name

Module Callbacks -- registering for special callbacks from gnome-vfs module operations

Synopsis


+
+void        (*GnomeVFSModuleCallback)       (gconstpointer in,
+                                             gsize in_size,
+                                             gpointer out,
+                                             gsize out_size,
+                                             gpointer callback_data);
+void        (*GnomeVFSModuleCallbackResponse)
+                                            (gpointer response_data);
+void        (*GnomeVFSAsyncModuleCallback)  (gconstpointer in,
+                                             gsize in_size,
+                                             gpointer out,
+                                             gsize out_size,
+                                             gpointer callback_data,
+                                             GnomeVFSModuleCallbackResponse response,
+                                             gpointer response_data);
+void        gnome_vfs_module_callback_set_default
+                                            (const char *callback_name,
+                                             GnomeVFSModuleCallback callback,
+                                             gpointer callback_data,
+                                             GDestroyNotify destroy_notify);
+void        gnome_vfs_module_callback_push  (const char *callback_name,
+                                             GnomeVFSModuleCallback callback,
+                                             gpointer callback_data,
+                                             GDestroyNotify destroy_notify);
+void        gnome_vfs_module_callback_pop   (const char *callback_name);
+void        gnome_vfs_async_module_callback_set_default
+                                            (const char *callback_name,
+                                             GnomeVFSAsyncModuleCallback callback,
+                                             gpointer callback_data,
+                                             GDestroyNotify destroy_notify);
+void        gnome_vfs_async_module_callback_push
+                                            (const char *callback_name,
+                                             GnomeVFSAsyncModuleCallback callback,
+                                             gpointer callback_data,
+                                             GDestroyNotify destroy_notify);
+void        gnome_vfs_async_module_callback_pop
+                                            (const char *callback_name);

Description

Sometimes, a module operation will want to call back to the +application before completing. For example, it may want to request +that the application prompt the user for a username and password to +access a particular URI. Or it may want to provide a status message +that the application can display.

Such callbacks are handled using the module callback mechanism.

Module callbacks may be set globally for all threads, or they may be +temporarilly overridden using a per-thread stack. Normally the stack +is not inherited by new threads; however, async operations are run +with a set of callbacks that corresponds to when the operation was +tarted.

There are also special async module callbacks. Async callbacks are +only invoked from async module operations, and take precedence over +sync callbacks in this case, if set. They are dispatched on the main +thread. Also, unlike regular callbacks, they do not need to provide +the answer right away. Instead, they can arrange to have a response +function called at any later time. This enables async callbacks to pop +up non-modal dialogs or schedule other async work before providing a +response.

Details

GnomeVFSModuleCallback ()

void        (*GnomeVFSModuleCallback)       (gconstpointer in,
+                                             gsize in_size,
+                                             gpointer out,
+                                             gsize out_size,
+                                             gpointer callback_data);

This is the type of a callback function that gets set for a module +callback.

When the callback is invoked, the user function is called with an +in argument, the exact type of which depends on the specific +callback. It is generally a pointer to a struct with several fields +that provide information to the callback.

The out argument is used to return a values from the +callback. Once again the exact type depends on the specific +callback. It is generally a pointer to a pre-allocated struct with +several fields that the callback function should fill in before +returning.

in : The in argument for this callback; the exact type depends on the specific callback
in_size : Size of the in argument; useful for sanity-checking
out : The out argument for this callback; the exact type depends on the specific callback
out_size : Size of the out argument; useful for sanity-checking
callback_data : The callback_data specified when this callback was set


GnomeVFSModuleCallbackResponse ()

void        (*GnomeVFSModuleCallbackResponse)
+                                            (gpointer response_data);

This is the type of the response function passed to a +GnomeVFSAsyncModuleCallback(). It should be called when the async +callback has completed.

response_data : Pass the response_data argument originally passed to the async callback


GnomeVFSAsyncModuleCallback ()

void        (*GnomeVFSAsyncModuleCallback)  (gconstpointer in,
+                                             gsize in_size,
+                                             gpointer out,
+                                             gsize out_size,
+                                             gpointer callback_data,
+                                             GnomeVFSModuleCallbackResponse response,
+                                             gpointer response_data);

This is the type of a callback function that gets set for an async +module callback.

Such callbacks are useful when you are using the API and want +callbacks to be handled from the main thread, for instance if they +need to put up a dialog.

Like a GnomeVFSModuleCallback(), an async callback has in and out +arguments for passing data into and out of the callback. However, +an async callback does not need to fill in the out argument before +returning. Instead, it can arrange to have the work done from a +callback on the main loop, from another thread, etc. The response +function should be called by whatever code finishes the work of the +callback with response_data as an argument once the out argument +is filled in and the callback is done.

The in and out arguments are guaranteed to remain valid until the +response function is called.

in : The in argument for this callback; the exact type depends on the specific callback
in_size : Size of the in argument; useful for sanity-checking
out : The out argument for this callback; the exact type depends on the specific callback
out_size : Size of the out argument; useful for sanity-checking
callback_data : The callback_data specified when this callback was set
response : Response function to call when the callback is completed
response_data : Argument to pass to response


gnome_vfs_module_callback_set_default ()

void        gnome_vfs_module_callback_set_default
+                                            (const char *callback_name,
+                                             GnomeVFSModuleCallback callback,
+                                             gpointer callback_data,
+                                             GDestroyNotify destroy_notify);

Set the default callback for callback_name to +callback. callback will be called with callback_data on the +same thread as the gnome-vfs operation that invokes it. The default +value is shared for all threads, but setting it is thread-safe.

Use this function if you want to set a handler to be used by your +whole application. You can use gnome_vfs_module_callback_push() to +set a callback function that will temporarily override the default +on the current thread instead. Or you can also use +gnome_vfs_async_module_callback_set_default() to set an async +callback function.

Note: destroy_notify may be called on any thread - it is not +guaranteed to be called on the main thread.

callback_name : The name of the module callback to set
callback : The function to call when the callback is invoked
callback_data : Pointer to pass as the callback_data argument to callback
destroy_notify : Function to call when callback_data is to be freed.


gnome_vfs_module_callback_push ()

void        gnome_vfs_module_callback_push  (const char *callback_name,
+                                             GnomeVFSModuleCallback callback,
+                                             gpointer callback_data,
+                                             GDestroyNotify destroy_notify);

Set callback as a temprary handler for callback_name. callback +will be called with callback_data on the same thread as the +gnome-vfs operation that invokes it. The temporary handler is set +per-thread.

gnome_vfs_module_callback_pop() removes the most recently set +temporary handler. The temporary handlers are treated as a first-in +first-out stack.

Use this function to set a temporary callback handler for a single +call or a few calls. You can use +gnome_vfs_module_callback_set_default() to set a callback function +that will establish a permanent global setting for all threads +instead.

Note: destroy_notify may be called on any thread - it is not +guaranteed to be called on the main thread.

callback_name : The name of the module callback to set temporarily
callback : The function to call when the callback is invoked
callback_data : Pointer to pass as the callback_data argument to callback
destroy_notify : Function to call when callback_data is to be freed.


gnome_vfs_module_callback_pop ()

void        gnome_vfs_module_callback_pop   (const char *callback_name);

Remove the temporary handler for callback_name most recently set +with gnome_vfs_module_callback_push(). If another temporary +handler was previously set on the same thread, it becomes the +current handler. Otherwise, the default handler, if any, becomes +current.

The temporary handlers are treated as a first-in first-out +stack.

callback_name : The name of the module callback to remove a temporary handler for


gnome_vfs_async_module_callback_set_default ()

void        gnome_vfs_async_module_callback_set_default
+                                            (const char *callback_name,
+                                             GnomeVFSAsyncModuleCallback callback,
+                                             gpointer callback_data,
+                                             GDestroyNotify destroy_notify);

Set the default async callback for callback_name to +callback. callback will be called with callback_data +from a callback on the main thread. It will be passed a response +function which should be called to signal completion of the callback. +The callback function itself may return in the meantime.

The default value is shared for all threads, but setting it is +thread-safe.

Use this function if you want to globally set a callback handler +for use with async operations.

You can use gnome_vfs_async_module_callback_push() to set an async +callback function that will temporarily override the default on the +current thread instead. Or you can also use +gnome_vfs_module_callback_set_default() to set a regular callback +function.

Note: destroy_notify may be called on any thread - it is not +guaranteed to be called on the main thread.

callback_name : The name of the async module callback to set
callback : The function to call when the callback is invoked
callback_data : Pointer to pass as the callback_data argument to callback
destroy_notify : Function to call when callback_data is to be freed.


gnome_vfs_async_module_callback_push ()

void        gnome_vfs_async_module_callback_push
+                                            (const char *callback_name,
+                                             GnomeVFSAsyncModuleCallback callback,
+                                             gpointer callback_data,
+                                             GDestroyNotify destroy_notify);

Set callback_func as a temprary async handler for +callback_name. callback will be called with callback_data +from a callback on the main thread. It will be passed a response +function which should be called to signal completion of the +callback. The callback function itself may return in the meantime.

The temporary async handler is set per-thread.

gnome_vfs_async_module_callback_pop() removes the most recently set +temporary temporary handler. The temporary async handlers are +treated as a first-in first-out stack.

Use this function to set a temporary async callback handler for a +single call or a few calls. You can use +gnome_vfs_async_module_callback_set_default() to set an async +callback function that will establish a permanent global setting +for all threads instead.

Note: destroy_notify may be called on any thread - it is not +guaranteed to be called on the main thread.

callback_name : The name of the module callback to set temporarily
callback : The function to call when the callback is invoked
callback_data : Pointer to pass as the callback_data argument to callback
destroy_notify : Function to call when callback_data is to be freed.


gnome_vfs_async_module_callback_pop ()

void        gnome_vfs_async_module_callback_pop
+                                            (const char *callback_name);

Remove the temporary async handler for callback_name most recently +set with gnome_vfs_async_module_callback_push(). If another +temporary async handler was previously set on the same thread, it +becomes the current handler. Otherwise, the default async handler, +if any, becomes current.

The temporary async handlers are treated as a first-in first-out +stack.

callback_name : The name of the module callback to remove a temporary handler for



<<< Previous PageHomeUpNext Page >>>
Copy EngineStandard Callbacks
\ No newline at end of file diff --git a/doc/html/gnome-vfs-module-shared.html b/doc/html/gnome-vfs-module-shared.html new file mode 100644 index 0000000..0a4e751 --- /dev/null +++ b/doc/html/gnome-vfs-module-shared.html @@ -0,0 +1,816 @@ +module-shared
GnomeVFS - Filesystem Abstraction library
<<< Previous PageHomeUpNext Page >>>

module-shared

Name

module-shared -- 

Synopsis


+
+const gchar* gnome_vfs_mime_type_from_mode  (mode_t mode);
+void        gnome_vfs_stat_to_file_info     (GnomeVFSFileInfo *file_info,
+                                             const struct stat *statptr);
+GnomeVFSResult gnome_vfs_set_meta           (GnomeVFSFileInfo *info,
+                                             const gchar *file_name,
+                                             const gchar *meta_key);
+GnomeVFSResult gnome_vfs_set_meta_for_list  (GnomeVFSFileInfo *info,
+                                             const gchar *file_name,
+                                             const GList *meta_keys);
+const char* gnome_vfs_get_special_mime_type (GnomeVFSURI *uri);

Description

Details

gnome_vfs_mime_type_from_mode ()

const gchar* gnome_vfs_mime_type_from_mode  (mode_t mode);

mode : 
Returns : 


gnome_vfs_stat_to_file_info ()

void        gnome_vfs_stat_to_file_info     (GnomeVFSFileInfo *file_info,
+                                             const struct stat *statptr);

file_info : 
statptr : 


gnome_vfs_set_meta ()

GnomeVFSResult gnome_vfs_set_meta           (GnomeVFSFileInfo *info,
+                                             const gchar *file_name,
+                                             const gchar *meta_key);

info : 
file_name : 
meta_key : 
Returns : 


gnome_vfs_set_meta_for_list ()

GnomeVFSResult gnome_vfs_set_meta_for_list  (GnomeVFSFileInfo *info,
+                                             const gchar *file_name,
+                                             const GList *meta_keys);

info : 
file_name : 
meta_keys : 
Returns : 


gnome_vfs_get_special_mime_type ()

const char* gnome_vfs_get_special_mime_type (GnomeVFSURI *uri);

uri : 
Returns : 

\ No newline at end of file diff --git a/doc/html/gnome-vfs-module.html b/doc/html/gnome-vfs-module.html new file mode 100644 index 0000000..22147e0 --- /dev/null +++ b/doc/html/gnome-vfs-module.html @@ -0,0 +1,635 @@ +module
GnomeVFS - Filesystem Abstraction library
<<< Previous PageHomeUpNext Page >>>

module

Name

module -- 

Synopsis


+
+#define     GNOME_VFS_MODULE_INIT
+#define     GNOME_VFS_MODULE_TRANSFORM
+#define     GNOME_VFS_MODULE_SHUTDOWN
+GnomeVFSMethod* vfs_module_init             (const char *method_name,
+                                             const char *args);
+GnomeVFSTransform* vfs_module_transform     (const char *method_name,
+                                             const char *args);
+void        vfs_module_shutdown             (GnomeVFSMethod *method);

Description

Details

GNOME_VFS_MODULE_INIT

#define GNOME_VFS_MODULE_INIT      "vfs_module_init"


GNOME_VFS_MODULE_TRANSFORM

#define GNOME_VFS_MODULE_TRANSFORM "vfs_module_transform"


GNOME_VFS_MODULE_SHUTDOWN

#define GNOME_VFS_MODULE_SHUTDOWN  "vfs_module_shutdown"


vfs_module_init ()

GnomeVFSMethod* vfs_module_init             (const char *method_name,
+                                             const char *args);

method_name : 
args : 
Returns : 


vfs_module_transform ()

GnomeVFSTransform* vfs_module_transform     (const char *method_name,
+                                             const char *args);

method_name : 
args : 
Returns : 


vfs_module_shutdown ()

void        vfs_module_shutdown             (GnomeVFSMethod *method);

method : 



<<< Previous PageHomeUpNext Page >>>
module-sharedModule Callbacks (Module API)
\ No newline at end of file diff --git a/doc/html/gnome-vfs-ops.html b/doc/html/gnome-vfs-ops.html new file mode 100644 index 0000000..241f3d1 --- /dev/null +++ b/doc/html/gnome-vfs-ops.html @@ -0,0 +1,4262 @@ +Basic File I/O
GnomeVFS - Filesystem Abstraction library
<<< Previous PageHomeUpNext Page >>>

Basic File I/O

Name

Basic File I/O -- synchronous file operations similar to posix calls, but using uris

Synopsis


+
+GnomeVFSResult gnome_vfs_open               (GnomeVFSHandle **handle,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode);
+GnomeVFSResult gnome_vfs_open_uri           (GnomeVFSHandle **handle,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode);
+GnomeVFSResult gnome_vfs_create             (GnomeVFSHandle **handle,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm);
+GnomeVFSResult gnome_vfs_create_uri         (GnomeVFSHandle **handle,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm);
+GnomeVFSResult gnome_vfs_close              (GnomeVFSHandle *handle);
+GnomeVFSResult gnome_vfs_read               (GnomeVFSHandle *handle,
+                                             gpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_read);
+GnomeVFSResult gnome_vfs_write              (GnomeVFSHandle *handle,
+                                             gconstpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_written);
+GnomeVFSResult gnome_vfs_seek               (GnomeVFSHandle *handle,
+                                             GnomeVFSSeekPosition whence,
+                                             GnomeVFSFileOffset offset);
+GnomeVFSResult gnome_vfs_tell               (GnomeVFSHandle *handle,
+                                             GnomeVFSFileSize *offset_return);
+GnomeVFSResult gnome_vfs_get_file_info      (const gchar *text_uri,
+                                             GnomeVFSFileInfo *info,
+                                             GnomeVFSFileInfoOptionsoptions);
+GnomeVFSResult gnome_vfs_get_file_info_uri  (GnomeVFSURI *uri,
+                                             GnomeVFSFileInfo *info,
+                                             GnomeVFSFileInfoOptionsoptions);
+GnomeVFSResult gnome_vfs_get_file_info_from_handle
+                                            (GnomeVFSHandle *handle,
+                                             GnomeVFSFileInfo *info,
+                                             GnomeVFSFileInfoOptionsoptions);
+GnomeVFSResult gnome_vfs_truncate           (const gchar *text_uri,
+                                             GnomeVFSFileSize length);
+GnomeVFSResult gnome_vfs_truncate_uri       (GnomeVFSURI *uri,
+                                             GnomeVFSFileSize length);
+GnomeVFSResult gnome_vfs_truncate_handle    (GnomeVFSHandle *handle,
+                                             GnomeVFSFileSize length);
+GnomeVFSResult gnome_vfs_make_directory_for_uri
+                                            (GnomeVFSURI *uri,
+                                             guint perm);
+GnomeVFSResult gnome_vfs_make_directory     (const gchar *text_uri,
+                                             guint perm);
+GnomeVFSResult gnome_vfs_remove_directory_from_uri
+                                            (GnomeVFSURI *uri);
+GnomeVFSResult gnome_vfs_remove_directory   (const gchar *text_uri);
+GnomeVFSResult gnome_vfs_unlink_from_uri    (GnomeVFSURI *uri);
+GnomeVFSResult gnome_vfs_create_symbolic_link
+                                            (GnomeVFSURI *uri,
+                                             const gchar *target_reference);
+GnomeVFSResult gnome_vfs_unlink             (const gchar *text_uri);
+GnomeVFSResult gnome_vfs_move_uri           (GnomeVFSURI *old_uri,
+                                             GnomeVFSURI *new_uri,
+                                             gboolean force_replace);
+GnomeVFSResult gnome_vfs_move               (const gchar *old_text_uri,
+                                             const gchar *new_text_uri,
+                                             gboolean force_replace);
+GnomeVFSResult gnome_vfs_check_same_fs_uris (GnomeVFSURI *source_uri,
+                                             GnomeVFSURI *target_uri,
+                                             gboolean *same_fs_return);
+GnomeVFSResult gnome_vfs_check_same_fs      (const gchar *source,
+                                             const gchar *target,
+                                             gboolean *same_fs_return);
+gboolean    gnome_vfs_uri_exists            (GnomeVFSURI *uri);
+GnomeVFSResult gnome_vfs_set_file_info_uri  (GnomeVFSURI *uri,
+                                             GnomeVFSFileInfo *info,
+                                             GnomeVFSSetFileInfoMask mask);
+GnomeVFSResult gnome_vfs_set_file_info      (const gchar *text_uri,
+                                             GnomeVFSFileInfo *info,
+                                             GnomeVFSSetFileInfoMask mask);

Description

Details

gnome_vfs_open ()

GnomeVFSResult gnome_vfs_open               (GnomeVFSHandle **handle,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode);

Open text_uri according to mode open_mode. On return, @*handle will then +contain a pointer to a handle for the open file.

handle : A pointer to a pointer to a GnomeVFSHandle object
text_uri : String representing the URI to open
open_mode : Open mode
Returns : An integer representing the result of the operation


gnome_vfs_open_uri ()

GnomeVFSResult gnome_vfs_open_uri           (GnomeVFSHandle **handle,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode);

Open uri according to mode open_mode. On return, @*handle will then +contain a pointer to a handle for the open file.

handle : A pointer to a pointer to a GnomeVFSHandle object
uri : URI to open
open_mode : Open mode
Returns : An integer representing the result of the operation


gnome_vfs_create ()

GnomeVFSResult gnome_vfs_create             (GnomeVFSHandle **handle,
+                                             const gchar *text_uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm);

Create uri according to mode open_mode. On return, @*handle will then +contain a pointer to a handle for the open file.

handle : A pointer to a pointer to a GnomeVFSHandle object
text_uri : String representing the URI to create
open_mode : Open mode
exclusive : Whether the file should be created in "exclusive" mode: +i.e. if this flag is nonzero, operation will fail if a file with the +same name already exists.
perm : Bitmap representing the permissions for the newly created file +(Unix style).
Returns : An integer representing the result of the operation


gnome_vfs_create_uri ()

GnomeVFSResult gnome_vfs_create_uri         (GnomeVFSHandle **handle,
+                                             GnomeVFSURI *uri,
+                                             GnomeVFSOpenMode open_mode,
+                                             gboolean exclusive,
+                                             guint perm);

Create uri according to mode open_mode. On return, @*handle will then +contain a pointer to a handle for the open file.

handle : A pointer to a pointer to a GnomeVFSHandle object
uri : URI for the file to create
open_mode : Open mode
exclusive : Whether the file should be created in "exclusive" mode: +i.e. if this flag is nonzero, operation will fail if a file with the +same name already exists.
perm : Bitmap representing the permissions for the newly created file +(Unix style).
Returns : An integer representing the result of the operation


gnome_vfs_close ()

GnomeVFSResult gnome_vfs_close              (GnomeVFSHandle *handle);

Close file associated with handle.

handle : A pointer to a GnomeVFSHandle object
Returns : An integer representing the result of the operation.


gnome_vfs_read ()

GnomeVFSResult gnome_vfs_read               (GnomeVFSHandle *handle,
+                                             gpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_read);

Read bytes from handle. As with Unix system calls, the number of +bytes read can effectively be less than bytes on return and will be +stored in @*bytes_read.

handle : Handle of the file to read data from
buffer : Pointer to a buffer that must be at least bytes bytes large
bytes : Number of bytes to read
bytes_read : Pointer to a variable that will hold the number of bytes +effectively read on return.
Returns : An integer representing the result of the operation


gnome_vfs_write ()

GnomeVFSResult gnome_vfs_write              (GnomeVFSHandle *handle,
+                                             gconstpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_written);

Write bytes into the file opened through handle. As with Unix system +calls, the number of bytes written can effectively be less than bytes on +return and will be stored in @*bytes_written.

handle : Handle of the file to write data to
buffer : Pointer to the buffer containing the data to be written
bytes : Number of bytes to write
bytes_written : 
Returns : An integer representing the result of the operation


gnome_vfs_seek ()

GnomeVFSResult gnome_vfs_seek               (GnomeVFSHandle *handle,
+                                             GnomeVFSSeekPosition whence,
+                                             GnomeVFSFileOffset offset);

Set the current position for reading/writing through handle.

handle : Handle for which the current position must be changed
whence : Integer value representing the starting position
offset : Number of bytes to skip from the position specified by whence +(a positive value means to move forward; a negative one to move backwards)
Returns : 


gnome_vfs_tell ()

GnomeVFSResult gnome_vfs_tell               (GnomeVFSHandle *handle,
+                                             GnomeVFSFileSize *offset_return);

Return the current position on handle.

handle : Handle for which the current position must be retrieved
offset_return : Pointer to a variable that will contain the current position +on return
Returns : An integer representing the result of the operation


gnome_vfs_get_file_info ()

GnomeVFSResult gnome_vfs_get_file_info      (const gchar *text_uri,
+                                             GnomeVFSFileInfo *info,
+                                             GnomeVFSFileInfoOptionsoptions);

Retrieve information about text_uri. The information will be stored in +@*info.

text_uri : URI of the file for which information will be retrieved
info : Pointer to a GnomeVFSFileInfo object that will hold the information +for the file on return
Param3 : 
Returns : An integer representing the result of the operation


gnome_vfs_get_file_info_uri ()

GnomeVFSResult gnome_vfs_get_file_info_uri  (GnomeVFSURI *uri,
+                                             GnomeVFSFileInfo *info,
+                                             GnomeVFSFileInfoOptionsoptions);

Retrieve information about text_uri. The information will be stored in +info.

uri : URI of the file for which information will be retrieved
info : Pointer to a GnomeVFSFileInfo object that will hold the information +for the file on return
Param3 : 
Returns : An integer representing the result of the operation


gnome_vfs_get_file_info_from_handle ()

GnomeVFSResult gnome_vfs_get_file_info_from_handle
+                                            (GnomeVFSHandle *handle,
+                                             GnomeVFSFileInfo *info,
+                                             GnomeVFSFileInfoOptionsoptions);

Retrieve information about an open file. The information will be stored in +@*info.

handle : Handle of the file for which information must be retrieved
info : Pointer to a GnomeVFSFileInfo object that will hold the information +for the file on return
Param3 : 
Returns : An integer representing the result of the operation


gnome_vfs_truncate ()

GnomeVFSResult gnome_vfs_truncate           (const gchar *text_uri,
+                                             GnomeVFSFileSize length);

text_uri : 
length : 
Returns : 


gnome_vfs_truncate_uri ()

GnomeVFSResult gnome_vfs_truncate_uri       (GnomeVFSURI *uri,
+                                             GnomeVFSFileSize length);

uri : 
length : 
Returns : 


gnome_vfs_truncate_handle ()

GnomeVFSResult gnome_vfs_truncate_handle    (GnomeVFSHandle *handle,
+                                             GnomeVFSFileSize length);

handle : 
length : 
Returns : 


gnome_vfs_make_directory_for_uri ()

GnomeVFSResult gnome_vfs_make_directory_for_uri
+                                            (GnomeVFSURI *uri,
+                                             guint perm);

Create uri as a directory.

uri : URI of the directory to be created
perm : Unix-style permissions for the newly created directory
Returns : An integer representing the result of the operation


gnome_vfs_make_directory ()

GnomeVFSResult gnome_vfs_make_directory     (const gchar *text_uri,
+                                             guint perm);

Create text_uri as a directory.

text_uri : URI of the directory to be created
perm : Unix-style permissions for the newly created directory
Returns : An integer representing the result of the operation


gnome_vfs_remove_directory_from_uri ()

GnomeVFSResult gnome_vfs_remove_directory_from_uri
+                                            (GnomeVFSURI *uri);

Remove uri. uri must be an empty directory.

uri : URI of the directory to be removed
Returns : An integer representing the result of the operation


gnome_vfs_remove_directory ()

GnomeVFSResult gnome_vfs_remove_directory   (const gchar *text_uri);

text_uri : 
Returns : 


gnome_vfs_unlink_from_uri ()

GnomeVFSResult gnome_vfs_unlink_from_uri    (GnomeVFSURI *uri);

Unlink text_uri.

uri : 
Returns : An integer representing the result of the operation


gnome_vfs_create_symbolic_link ()

GnomeVFSResult gnome_vfs_create_symbolic_link
+                                            (GnomeVFSURI *uri,
+                                             const gchar *target_reference);

Creates a symbolic link, or eventually, a URI link (as necessary) +at uri pointing to target_reference

uri : URI to create a link at
target_reference : URI "reference" to point the link to (URI or relative path)
Returns : An integer representing the result of the operation


gnome_vfs_unlink ()

GnomeVFSResult gnome_vfs_unlink             (const gchar *text_uri);

text_uri : 
Returns : 


gnome_vfs_move_uri ()

GnomeVFSResult gnome_vfs_move_uri           (GnomeVFSURI *old_uri,
+                                             GnomeVFSURI *new_uri,
+                                             gboolean force_replace);

Move a file from URI old_uri to new_uri. This will only work if old_uri +and new_uri are on the same file system. Otherwise, it is necessary +to use the more general %gnome_vfs_xfer_uri() function.

old_uri : Source URI
new_uri : Destination URI
force_replace : 
Returns : An integer representing the result of the operation.


gnome_vfs_move ()

GnomeVFSResult gnome_vfs_move               (const gchar *old_text_uri,
+                                             const gchar *new_text_uri,
+                                             gboolean force_replace);

Move a file from URI old_text_uri to new_text_uri. This will only work +if old_text_uri and new_text_uri are on the same file system. Otherwise, +it is necessary to use the more general %gnome_vfs_xfer_uri() function.

old_text_uri : Source URI
new_text_uri : Destination URI
force_replace : 
Returns : An integer representing the result of the operation.


gnome_vfs_check_same_fs_uris ()

GnomeVFSResult gnome_vfs_check_same_fs_uris (GnomeVFSURI *source_uri,
+                                             GnomeVFSURI *target_uri,
+                                             gboolean *same_fs_return);

Check if a and b are on the same file system.

source_uri : 
target_uri : 
same_fs_return : Pointer to a boolean variable which will be set to TRUE +if a and b are on the same file system on return.
Returns : An integer representing the result of the operation.


gnome_vfs_check_same_fs ()

GnomeVFSResult gnome_vfs_check_same_fs      (const gchar *source,
+                                             const gchar *target,
+                                             gboolean *same_fs_return);

Check if a and b are on the same file system.

source : 
target : 
same_fs_return : Pointer to a boolean variable which will be set to TRUE +if a and b are on the same file system on return.
Returns : An integer representing the result of the operation.


gnome_vfs_uri_exists ()

gboolean    gnome_vfs_uri_exists            (GnomeVFSURI *uri);

Check if the URI points to an existing entity.

uri : A URI
Returns : TRUE if URI exists.


gnome_vfs_set_file_info_uri ()

GnomeVFSResult gnome_vfs_set_file_info_uri  (GnomeVFSURI *uri,
+                                             GnomeVFSFileInfo *info,
+                                             GnomeVFSSetFileInfoMask mask);

Set file information for uri; only the information for which the +corresponding bit in mask is set is actually modified.

uri : A URI
info : Information that must be set for the file
mask : Bit mask representing which fields of info need to be set
Returns : An integer representing the result of the operation.


gnome_vfs_set_file_info ()

GnomeVFSResult gnome_vfs_set_file_info      (const gchar *text_uri,
+                                             GnomeVFSFileInfo *info,
+                                             GnomeVFSSetFileInfoMask mask);

Set file information for uri; only the information for which the +corresponding bit in mask is set is actually modified.

text_uri : A URI
info : Information that must be set for the file
mask : Bit mask representing which fields of info need to be set
Returns : An integer representing the result of the operation.



<<< Previous PageHomeUpNext Page >>>
Basic File OperationsDirectory Operations
\ No newline at end of file diff --git a/doc/html/gnome-vfs-parse-ls.html b/doc/html/gnome-vfs-parse-ls.html new file mode 100644 index 0000000..ee09ba3 --- /dev/null +++ b/doc/html/gnome-vfs-parse-ls.html @@ -0,0 +1,415 @@ +parse-ls
GnomeVFS - Filesystem Abstraction library
<<< Previous PageHomeUpNext Page >>>

parse-ls

Name

parse-ls -- 

Synopsis


+
+int         gnome_vfs_parse_ls_lga          (const char *p,
+                                             struct stat *s,
+                                             char **filename,
+                                             char **linkname);

Description

Details

gnome_vfs_parse_ls_lga ()

int         gnome_vfs_parse_ls_lga          (const char *p,
+                                             struct stat *s,
+                                             char **filename,
+                                             char **linkname);

p : 
s : 
filename : 
linkname : 
Returns : 

\ No newline at end of file diff --git a/doc/html/gnome-vfs-process.html b/doc/html/gnome-vfs-process.html new file mode 100644 index 0000000..53f30e4 --- /dev/null +++ b/doc/html/gnome-vfs-process.html @@ -0,0 +1,275 @@ +process
GnomeVFS - Filesystem Abstraction library
<<< Previous PageHomeUpNext Page >>>

process

Name

process -- 

Synopsis




Description

Details

\ No newline at end of file diff --git a/doc/html/gnome-vfs-result.html b/doc/html/gnome-vfs-result.html new file mode 100644 index 0000000..27d4e1d --- /dev/null +++ b/doc/html/gnome-vfs-result.html @@ -0,0 +1,598 @@ +Result Codes
GnomeVFS - Filesystem Abstraction library
<<< Previous PageHomeUpNext Page >>>

Result Codes

Name

Result Codes -- utilities for interpreting GnomeVFS Result codes

Description

Details

gnome_vfs_result_to_string ()

const char* gnome_vfs_result_to_string      (GnomeVFSResult result);

result : 
Returns : 


gnome_vfs_result_from_errno_code ()

GnomeVFSResult gnome_vfs_result_from_errno_code
+                                            (int errno_code);

errno_code : 
Returns : 


gnome_vfs_result_from_errno ()

GnomeVFSResult gnome_vfs_result_from_errno  (void);

Returns : 


gnome_vfs_result_from_h_errno ()

GnomeVFSResult gnome_vfs_result_from_h_errno
+                                            (void);

Returns : 

\ No newline at end of file diff --git a/doc/html/gnome-vfs-ssl.html b/doc/html/gnome-vfs-ssl.html new file mode 100644 index 0000000..775ba66 --- /dev/null +++ b/doc/html/gnome-vfs-ssl.html @@ -0,0 +1,734 @@ +ssl
GnomeVFS - Filesystem Abstraction library
<<< Previous PageHomeUpNext Page >>>

ssl

Name

ssl -- 

Synopsis


+
+gboolean    gnome_vfs_ssl_enabled           (void);
+GnomeVFSResult gnome_vfs_ssl_read           (GnomeVFSSSL *ssl,
+                                             gpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_read);
+GnomeVFSResult gnome_vfs_ssl_write          (GnomeVFSSSL *ssl,
+                                             gconstpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_written);
+void        gnome_vfs_ssl_destroy           (GnomeVFSSSL *ssl);

Description

Details

gnome_vfs_ssl_enabled ()

gboolean    gnome_vfs_ssl_enabled           (void);

Returns : 


gnome_vfs_ssl_read ()

GnomeVFSResult gnome_vfs_ssl_read           (GnomeVFSSSL *ssl,
+                                             gpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_read);

ssl : 
buffer : 
bytes : 
bytes_read : 
Returns : 


gnome_vfs_ssl_write ()

GnomeVFSResult gnome_vfs_ssl_write          (GnomeVFSSSL *ssl,
+                                             gconstpointer buffer,
+                                             GnomeVFSFileSize bytes,
+                                             GnomeVFSFileSize *bytes_written);

ssl : 
buffer : 
bytes : 
bytes_written : 
Returns : 


gnome_vfs_ssl_destroy ()

void        gnome_vfs_ssl_destroy           (GnomeVFSSSL *ssl);

ssl : 

\ No newline at end of file diff --git a/doc/html/gnome-vfs-standard-callbacks.html b/doc/html/gnome-vfs-standard-callbacks.html new file mode 100644 index 0000000..c02d44b --- /dev/null +++ b/doc/html/gnome-vfs-standard-callbacks.html @@ -0,0 +1,719 @@ +Standard Callbacks
GnomeVFS - Filesystem Abstraction library
<<< Previous PageHomeUpNext Page >>>

Standard Callbacks

Name

Standard Callbacks -- module callbacks pre-defined by gnome-vfs

Description

Some standard module callbacks are predefined. They include callbacks +for authentication, http proxy authentication, and status +messages. For each standard callback, a macro provides the name, and +structures are defined for the in and out argument.

Details

GNOME_VFS_MODULE_CALLBACK_AUTHENTICATION

#define GNOME_VFS_MODULE_CALLBACK_AUTHENTICATION "simple-authentication"

This callback is called when access to a URI requires a username and +password.


GNOME_VFS_MODULE_CALLBACK_HTTP_PROXY_AUTHENTICATION

#define GNOME_VFS_MODULE_CALLBACK_HTTP_PROXY_AUTHENTICATION "http:proxy-authentication"

This callback is called when access to an HTTP proxy requires a +username and password.


GnomeVFSModuleCallbackAuthenticationIn

typedef struct {
+	char *uri;		/* Full URI of operation */
+	char *realm;		/* for HTTP auth, NULL for others */
+	gboolean previous_attempt_failed;
+				/* TRUE if there were credentials specified
+				 * for this request, but they resulted in
+				 * an authorization error. 
+				 * ("you gave me the wrong pw!")
+				 * 
+				 * FALSE if there were no credentials specified
+				 * but they are required to continue
+				 * 
+				 */
+	enum {
+		AuthTypeBasic,	/* Password will be transmitted unencrypted */
+		AuthTypeDigest	/* Digest is transferred, not plaintext credentials */		
+	} auth_type;
+} GnomeVFSModuleCallbackAuthenticationIn;


GnomeVFSModuleCallbackAuthenticationOut

typedef struct {
+	char *username;		/* will be freed by g_free,
+				 * NULL indicates no auth should be provided;
+				 * if the request requires authn, the operation
+				 * will fail with a GNOME_VFS_ERROR_ACCESS_DENIED
+				 * code
+				 */
+	char *password;		/* will be freed by g_free */
+} GnomeVFSModuleCallbackAuthenticationOut;


GNOME_VFS_MODULE_CALLBACK_STATUS_MESSAGE

#define GNOME_VFS_MODULE_CALLBACK_STATUS_MESSAGE "status-message"

This callback is called when a GnomeVFS module operation has a status +message to return to the application.


GnomeVFSModuleCallbackStatusMessageIn

typedef struct {
+	char *uri;		/* Full URI of operation */
+	char *message;		/* A message indicating the current state or
+				 * NULL if there is no message */
+	int percentage;		/* Percentage indicating completeness 0-100 or
+				 * -1 if there is no progress percentage to
+				 * report */
+} GnomeVFSModuleCallbackStatusMessageIn;


GnomeVFSModuleCallbackStatusMessageOut

typedef struct {
+	int dummy; /* empty structs not allowed */
+} GnomeVFSModuleCallbackStatusMessageOut;



<<< Previous PageHomeUpNext Page >>>
Module CallbacksCommon Data Types
\ No newline at end of file diff --git a/doc/html/gnome-vfs-types.html b/doc/html/gnome-vfs-types.html new file mode 100644 index 0000000..990c2b3 --- /dev/null +++ b/doc/html/gnome-vfs-types.html @@ -0,0 +1,2514 @@ +types
GnomeVFS - Filesystem Abstraction library
<<< Previous PageHomeUpNext Page >>>

types

Name

types -- 

Synopsis


+
+enum        GnomeVFSResult;
+enum        GnomeVFSOpenMode;
+enum        GnomeVFSFileType;
+enum        GnomeVFSFilePermissions;
+enum        GnomeVFSSeekPosition;
+typedef     GnomeVFSToplevelURI;
+enum        GnomeVFSURIHideOptions;
+enum        GnomeVFSFileFlags;
+enum        GnomeVFSFileInfoFields;
+typedef     GnomeVFSFileInfo;
+enum        GnomeVFSFileInfoOptions;
+enum        GnomeVFSSetFileInfoMask;
+enum        GnomeVFSFindDirectoryKind;
+enum        GnomeVFSDirectoryVisitOptions;
+gboolean    (*GnomeVFSDirectoryVisitFunc)   (const gchar *rel_path,
+                                             GnomeVFSFileInfo *info,
+                                             gboolean recursing_will_loop,
+                                             gpointer data,
+                                             gboolean *recurse);
+enum        GnomeVFSXferOptions;
+enum        GnomeVFSXferProgressStatus;
+enum        GnomeVFSXferOverwriteMode;
+enum        GnomeVFSXferOverwriteAction;
+enum        GnomeVFSXferErrorMode;
+enum        GnomeVFSXferErrorAction;
+enum        GnomeVFSXferPhase;
+typedef     GnomeVFSXferProgressInfo;
+gint        (*GnomeVFSXferProgressCallback) (GnomeVFSXferProgressInfo *info,
+                                             gpointer data);
+void        (*GnomeVFSAsyncCallback)        (GnomeVFSAsyncHandle *handle,
+                                             GnomeVFSResult result,
+                                             gpointer callback_data);
+typedef     GnomeVFSAsyncOpenCallback;
+typedef     GnomeVFSAsyncCreateCallback;
+typedef     GnomeVFSAsyncCreateAsChannelCallback;
+#define     GnomeVFSAsyncCloseCallback
+void        (*GnomeVFSAsyncReadCallback)    (GnomeVFSAsyncHandle *handle,
+                                             GnomeVFSResult result,
+                                             gpointer buffer,
+                                             GnomeVFSFileSize bytes_requested,
+                                             GnomeVFSFileSize bytes_read,
+                                             gpointer callback_data);
+void        (*GnomeVFSAsyncWriteCallback)   (GnomeVFSAsyncHandle *handle,
+                                             GnomeVFSResult result,
+                                             gconstpointer buffer,
+                                             GnomeVFSFileSize bytes_requested,
+                                             GnomeVFSFileSize bytes_written,
+                                             gpointer callback_data);
+typedef     GnomeVFSGetFileInfoResult;
+typedef     GnomeVFSFindDirectoryResult;
+GnomeVFSTransform* (*GnomeVFSTransformInitFunc)
+                                            (const char *method_name,
+                                             const char *config_args);
+GnomeVFSResult (*GnomeVFSTransformFunc)     (GnomeVFSTransform *transform,
+                                             const char *old_uri,
+                                             char **new_uri,
+                                             GnomeVFSContext *context);
+typedef     GnomeVFSMethodHandle;

Description

Details

enum GnomeVFSResult

typedef enum {
+	GNOME_VFS_OK,
+	GNOME_VFS_ERROR_NOT_FOUND,
+	GNOME_VFS_ERROR_GENERIC,
+	GNOME_VFS_ERROR_INTERNAL,
+	GNOME_VFS_ERROR_BAD_PARAMETERS,
+	GNOME_VFS_ERROR_NOT_SUPPORTED,
+	GNOME_VFS_ERROR_IO,
+	GNOME_VFS_ERROR_CORRUPTED_DATA,
+	GNOME_VFS_ERROR_WRONG_FORMAT,
+	GNOME_VFS_ERROR_BAD_FILE,
+	GNOME_VFS_ERROR_TOO_BIG,
+	GNOME_VFS_ERROR_NO_SPACE,
+	GNOME_VFS_ERROR_READ_ONLY,
+	GNOME_VFS_ERROR_INVALID_URI,
+	GNOME_VFS_ERROR_NOT_OPEN,
+	GNOME_VFS_ERROR_INVALID_OPEN_MODE,
+	GNOME_VFS_ERROR_ACCESS_DENIED,
+	GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES,
+	GNOME_VFS_ERROR_EOF,
+	GNOME_VFS_ERROR_NOT_A_DIRECTORY,
+	GNOME_VFS_ERROR_IN_PROGRESS,
+	GNOME_VFS_ERROR_INTERRUPTED,
+	GNOME_VFS_ERROR_FILE_EXISTS,
+	GNOME_VFS_ERROR_LOOP,
+	GNOME_VFS_ERROR_NOT_PERMITTED,
+	GNOME_VFS_ERROR_IS_DIRECTORY,
+	GNOME_VFS_ERROR_NO_MEMORY,
+	GNOME_VFS_ERROR_HOST_NOT_FOUND,
+	GNOME_VFS_ERROR_INVALID_HOST_NAME,
+	GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS,
+	GNOME_VFS_ERROR_LOGIN_FAILED,
+	GNOME_VFS_ERROR_CANCELLED,
+	GNOME_VFS_ERROR_DIRECTORY_BUSY,
+	GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY,
+	GNOME_VFS_ERROR_TOO_MANY_LINKS,
+	GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM,
+	GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM,
+	GNOME_VFS_ERROR_NAME_TOO_LONG,
+	GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE,
+	GNOME_VFS_ERROR_SERVICE_OBSOLETE,
+	GNOME_VFS_ERROR_PROTOCOL_ERROR,
+	GNOME_VFS_NUM_ERRORS
+} GnomeVFSResult;


enum GnomeVFSOpenMode

typedef enum {
+        GNOME_VFS_OPEN_NONE = 0,
+        GNOME_VFS_OPEN_READ = 1 << 0,
+        GNOME_VFS_OPEN_WRITE = 1 << 1,
+        GNOME_VFS_OPEN_RANDOM = 1 << 2
+} GnomeVFSOpenMode;


enum GnomeVFSFileType

typedef enum {
+	GNOME_VFS_FILE_TYPE_UNKNOWN,
+	GNOME_VFS_FILE_TYPE_REGULAR,
+	GNOME_VFS_FILE_TYPE_DIRECTORY,
+	GNOME_VFS_FILE_TYPE_FIFO,
+	GNOME_VFS_FILE_TYPE_SOCKET,
+	GNOME_VFS_FILE_TYPE_CHARACTER_DEVICE,
+	GNOME_VFS_FILE_TYPE_BLOCK_DEVICE,
+	GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK
+} GnomeVFSFileType;


enum GnomeVFSFilePermissions

typedef enum {
+	GNOME_VFS_PERM_SUID = S_ISUID,
+	GNOME_VFS_PERM_SGID = S_ISGID,	
+	GNOME_VFS_PERM_STICKY = 01000,	/* S_ISVTX not defined on all systems */
+	GNOME_VFS_PERM_USER_READ = S_IRUSR,
+	GNOME_VFS_PERM_USER_WRITE = S_IWUSR,
+	GNOME_VFS_PERM_USER_EXEC = S_IXUSR,
+	GNOME_VFS_PERM_USER_ALL = S_IRUSR | S_IWUSR | S_IXUSR,
+	GNOME_VFS_PERM_GROUP_READ = S_IRGRP,
+	GNOME_VFS_PERM_GROUP_WRITE = S_IWGRP,
+	GNOME_VFS_PERM_GROUP_EXEC = S_IXGRP,
+	GNOME_VFS_PERM_GROUP_ALL = S_IRGRP | S_IWGRP | S_IXGRP,
+	GNOME_VFS_PERM_OTHER_READ = S_IROTH,
+	GNOME_VFS_PERM_OTHER_WRITE = S_IWOTH,
+	GNOME_VFS_PERM_OTHER_EXEC = S_IXOTH,
+	GNOME_VFS_PERM_OTHER_ALL = S_IROTH | S_IWOTH | S_IXOTH
+} GnomeVFSFilePermissions;


enum GnomeVFSSeekPosition

typedef enum {
+        GNOME_VFS_SEEK_START,
+        GNOME_VFS_SEEK_CURRENT,
+        GNOME_VFS_SEEK_END
+} GnomeVFSSeekPosition;


GnomeVFSToplevelURI

typedef struct {
+	/* Base object.  */
+	GnomeVFSURI uri;
+
+	/* Server location information.  */
+	gchar *host_name;
+	guint host_port;
+
+	/* Authorization information.  */
+	gchar *user_name;
+	gchar *password;
+
+	/* The parent URN, if it exists */
+	gchar *urn;
+} GnomeVFSToplevelURI;


enum GnomeVFSURIHideOptions

typedef enum {
+	GNOME_VFS_URI_HIDE_NONE = 0,
+	GNOME_VFS_URI_HIDE_USER_NAME = 1 << 0,
+	GNOME_VFS_URI_HIDE_PASSWORD = 1 << 1,
+	GNOME_VFS_URI_HIDE_HOST_NAME = 1 << 2,
+	GNOME_VFS_URI_HIDE_HOST_PORT = 1 << 3,
+	GNOME_VFS_URI_HIDE_TOPLEVEL_METHOD = 1 << 4,
+	GNOME_VFS_URI_HIDE_FRAGMENT_IDENTIFIER = 1 << 8
+} GnomeVFSURIHideOptions;


enum GnomeVFSFileFlags

typedef enum {
+	GNOME_VFS_FILE_FLAGS_NONE = 0,
+	/* Whether the file is a symlink.  */
+	GNOME_VFS_FILE_FLAGS_SYMLINK = 1 << 0,
+	/* Whether the file is on a local file system.  */
+	GNOME_VFS_FILE_FLAGS_LOCAL = 1 << 1,
+} GnomeVFSFileFlags;


enum GnomeVFSFileInfoFields

typedef enum {
+	GNOME_VFS_FILE_INFO_FIELDS_NONE = 0,
+	GNOME_VFS_FILE_INFO_FIELDS_TYPE = 1 << 0,
+	GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS = 1 << 1,
+	GNOME_VFS_FILE_INFO_FIELDS_FLAGS = 1 << 2,
+	GNOME_VFS_FILE_INFO_FIELDS_DEVICE = 1 << 3,
+	GNOME_VFS_FILE_INFO_FIELDS_INODE = 1 << 4,
+	GNOME_VFS_FILE_INFO_FIELDS_LINK_COUNT = 1 << 5,
+	GNOME_VFS_FILE_INFO_FIELDS_SIZE = 1 << 6,
+	GNOME_VFS_FILE_INFO_FIELDS_BLOCK_COUNT = 1 << 7,
+	GNOME_VFS_FILE_INFO_FIELDS_IO_BLOCK_SIZE = 1 << 8,
+	GNOME_VFS_FILE_INFO_FIELDS_ATIME = 1 << 9,
+	GNOME_VFS_FILE_INFO_FIELDS_MTIME = 1 << 10,
+	GNOME_VFS_FILE_INFO_FIELDS_CTIME = 1 << 11,
+	GNOME_VFS_FILE_INFO_FIELDS_SYMLINK_NAME = 1 << 12,
+	GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE = 1 << 13
+} GnomeVFSFileInfoFields;


GnomeVFSFileInfo

typedef struct {
+	/* Base name of the file (no path).  */
+	gchar *name;
+
+	/* Fields which are actually valid in this strcture. */
+	GnomeVFSFileInfoFields valid_fields;
+
+	/* File type (i.e. regular, directory, block device...).  */
+	GnomeVFSFileType type;
+
+	/* File permissions.  */
+	GnomeVFSFilePermissions permissions;
+
+	/* Flags for this file.  */
+	GnomeVFSFileFlags flags;
+
+	/* This is only valid if `is_local' is TRUE (see below).  */
+	dev_t device;
+	ino_t inode;
+
+	/* Link count.  */
+	guint link_count;
+
+	/* UID, GID.  */
+	guint uid;
+	guint gid;
+
+	/* Size in bytes.  */
+	GnomeVFSFileSize size;
+
+	/* Size measured in units of 512-byte blocks.  */
+	GnomeVFSFileSize block_count;
+
+	/* Optimal buffer size for reading/writing the file.  */
+	guint io_block_size;
+
+	/* Access, modification and change times.  */
+	time_t atime;
+	time_t mtime;
+	time_t ctime;
+
+	/* If the file is a symlink (see `flags'), this specifies the file the
+           link points to.  */
+	gchar *symlink_name;
+
+	/* MIME type.  */
+	gchar *mime_type;
+
+	guint refcount;
+} GnomeVFSFileInfo;


enum GnomeVFSFileInfoOptions

typedef enum {
+	GNOME_VFS_FILE_INFO_DEFAULT = 0, /* FIXME bugzilla.eazel.com 1203: name sucks */
+	GNOME_VFS_FILE_INFO_GET_MIME_TYPE = 1 << 0,
+	GNOME_VFS_FILE_INFO_FORCE_FAST_MIME_TYPE = 1 << 1,
+	GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE = 1 << 2,
+	GNOME_VFS_FILE_INFO_FOLLOW_LINKS = 1 << 3
+} GnomeVFSFileInfoOptions;


enum GnomeVFSSetFileInfoMask

typedef enum {
+	GNOME_VFS_SET_FILE_INFO_NONE = 0,
+	GNOME_VFS_SET_FILE_INFO_NAME = 1 << 0,
+	GNOME_VFS_SET_FILE_INFO_PERMISSIONS = 1 << 1,
+	GNOME_VFS_SET_FILE_INFO_OWNER = 1 << 2,
+	GNOME_VFS_SET_FILE_INFO_TIME = 1 << 3
+} GnomeVFSSetFileInfoMask;


enum GnomeVFSFindDirectoryKind

typedef enum {
+	GNOME_VFS_DIRECTORY_KIND_DESKTOP = 1000,
+	GNOME_VFS_DIRECTORY_KIND_TRASH = 1001
+} GnomeVFSFindDirectoryKind;


enum GnomeVFSDirectoryVisitOptions

typedef enum {
+	GNOME_VFS_DIRECTORY_VISIT_DEFAULT = 0,
+	GNOME_VFS_DIRECTORY_VISIT_SAMEFS = 1 << 0,
+	GNOME_VFS_DIRECTORY_VISIT_LOOPCHECK = 1 << 1
+} GnomeVFSDirectoryVisitOptions;


GnomeVFSDirectoryVisitFunc ()

gboolean    (*GnomeVFSDirectoryVisitFunc)   (const gchar *rel_path,
+                                             GnomeVFSFileInfo *info,
+                                             gboolean recursing_will_loop,
+                                             gpointer data,
+                                             gboolean *recurse);

rel_path : 
info : 
recursing_will_loop : 
data : 
recurse : 
Returns : 


enum GnomeVFSXferOptions

typedef enum {
+	GNOME_VFS_XFER_DEFAULT = 0,
+	GNOME_VFS_XFER_UNUSED_1 = 1 << 0,
+	GNOME_VFS_XFER_FOLLOW_LINKS = 1 << 1,
+	GNOME_VFS_XFER_UNUSED_2 = 1 << 2,
+	GNOME_VFS_XFER_RECURSIVE = 1 << 3,
+	GNOME_VFS_XFER_SAMEFS = 1 << 4,
+	GNOME_VFS_XFER_DELETE_ITEMS = 1 << 5,
+	GNOME_VFS_XFER_EMPTY_DIRECTORIES = 1 << 6,
+	GNOME_VFS_XFER_NEW_UNIQUE_DIRECTORY = 1 << 7,
+	GNOME_VFS_XFER_REMOVESOURCE = 1 << 8,
+	GNOME_VFS_XFER_USE_UNIQUE_NAMES = 1 << 9,
+	GNOME_VFS_XFER_LINK_ITEMS = 1 << 10
+} GnomeVFSXferOptions;


enum GnomeVFSXferProgressStatus

typedef enum {
+	GNOME_VFS_XFER_PROGRESS_STATUS_OK = 0,
+	GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR = 1,
+	GNOME_VFS_XFER_PROGRESS_STATUS_OVERWRITE = 2,
+	/* during the duplicate status the progress callback is asked to
+	   supply a new unique name */
+	GNOME_VFS_XFER_PROGRESS_STATUS_DUPLICATE = 3
+} GnomeVFSXferProgressStatus;


enum GnomeVFSXferOverwriteMode

typedef enum {
+	/* Interrupt transferring with an error (GNOME_VFS_ERROR_FILEEXISTS).  */
+	GNOME_VFS_XFER_OVERWRITE_MODE_ABORT = 0,
+	/* Invoke the progress callback with a
+	   `GNOME_VFS_XFER_PROGRESS_STATUS_OVERWRITE' status code. */
+	GNOME_VFS_XFER_OVERWRITE_MODE_QUERY = 1,
+	/* Overwrite files silently.  */
+	GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE = 2,
+	/* Ignore files silently.  */
+	GNOME_VFS_XFER_OVERWRITE_MODE_SKIP = 3
+} GnomeVFSXferOverwriteMode;


enum GnomeVFSXferOverwriteAction

typedef enum {
+	GNOME_VFS_XFER_OVERWRITE_ACTION_ABORT = 0,
+	GNOME_VFS_XFER_OVERWRITE_ACTION_REPLACE = 1,
+	GNOME_VFS_XFER_OVERWRITE_ACTION_REPLACE_ALL = 2,
+	GNOME_VFS_XFER_OVERWRITE_ACTION_SKIP = 3,
+	GNOME_VFS_XFER_OVERWRITE_ACTION_SKIP_ALL = 4,
+} GnomeVFSXferOverwriteAction;


enum GnomeVFSXferErrorMode

typedef enum {
+	/* Interrupt transferring with an error (code returned is code of the
+           operation that has caused the error).  */
+	GNOME_VFS_XFER_ERROR_MODE_ABORT = 0,
+	/* Invoke the progress callback with a
+	   `GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR' status code. */
+	GNOME_VFS_XFER_ERROR_MODE_QUERY = 1,
+} GnomeVFSXferErrorMode;


enum GnomeVFSXferErrorAction

typedef enum {
+	/* Interrupt operation and return `GNOME_VFS_ERROR_INTERRUPTED'.  */
+	GNOME_VFS_XFER_ERROR_ACTION_ABORT = 0,
+	/* Try the same operation again.  */
+	GNOME_VFS_XFER_ERROR_ACTION_RETRY = 1,
+	/* Skip this file and continue normally.  */
+	GNOME_VFS_XFER_ERROR_ACTION_SKIP = 2
+} GnomeVFSXferErrorAction;


enum GnomeVFSXferPhase

typedef enum {
+	/* Initial phase */
+	GNOME_VFS_XFER_PHASE_INITIAL,
+	/* Checking if destination can handle move/copy */
+	GNOME_VFS_XFER_CHECKING_DESTINATION,
+	/* Collecting file list */
+	GNOME_VFS_XFER_PHASE_COLLECTING,
+	/* File list collected (*) */
+	GNOME_VFS_XFER_PHASE_READYTOGO,
+	/* Opening source file for reading */
+	GNOME_VFS_XFER_PHASE_OPENSOURCE,
+	/* Creating target file for copy */
+	GNOME_VFS_XFER_PHASE_OPENTARGET,
+	/* Copying data from source to target (*) */
+	GNOME_VFS_XFER_PHASE_COPYING,
+	/* Moving file from source to target (*) */
+	GNOME_VFS_XFER_PHASE_MOVING,
+	/* Reading data from source file */
+	GNOME_VFS_XFER_PHASE_READSOURCE,
+	/* Writing data to target file */
+	GNOME_VFS_XFER_PHASE_WRITETARGET,
+	/* Closing source file */
+	GNOME_VFS_XFER_PHASE_CLOSESOURCE,
+	/* Closing target file */
+	GNOME_VFS_XFER_PHASE_CLOSETARGET,
+	/* Deleting source file */
+	GNOME_VFS_XFER_PHASE_DELETESOURCE,
+	/* Setting attributes on target file */
+	GNOME_VFS_XFER_PHASE_SETATTRIBUTES,
+	/* Go to the next file (*) */
+	GNOME_VFS_XFER_PHASE_FILECOMPLETED,
+	/* cleaning up after a move (removing source files, etc.) */
+	GNOME_VFS_XFER_PHASE_CLEANUP,
+	/* Operation finished (*) */
+	GNOME_VFS_XFER_PHASE_COMPLETED,
+	GNOME_VFS_XFER_NUM_PHASES
+} GnomeVFSXferPhase;


GnomeVFSXferProgressInfo

typedef struct {
+	/* Progress status (see above for a description).  */
+	GnomeVFSXferProgressStatus status;
+
+	/* VFS status code.  If `status' is
+           `GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR', you should look at this
+           member to know what has happened.  */
+	GnomeVFSResult vfs_status;
+
+	/* Current phase in the transferring process.  */
+	GnomeVFSXferPhase phase;
+
+	/* Source URI. FIXME bugzilla.eazel.com 1206: change name? */
+	gchar *source_name;
+
+	/* Destination URI. FIXME bugzilla.eazel.com 1206: change name? */
+	gchar *target_name;
+
+	/* Index of file being copied. */
+	gulong file_index;
+
+	/* Total number of files to be copied.  */
+	gulong files_total;
+
+	/* Total number of bytes to be copied.  */
+	GnomeVFSFileSize bytes_total;
+
+	/* Total size of this file (in bytes).  */
+	GnomeVFSFileSize file_size;
+
+	/* Bytes copied for this file so far.  */
+	GnomeVFSFileSize bytes_copied;
+
+	/* Total amount of data copied from the beginning.  */
+	GnomeVFSFileSize total_bytes_copied;
+	
+	/* Target unique name used when duplicating, etc. to avoid collisions */ 
+	gchar *duplicate_name;
+
+	/* Count used in the unique name e.g. (copy 2), etc. */
+	int duplicate_count;
+
+	gboolean top_level_item;
+	/* indicates that the copied/moved/deleted item is an actual item
+	 * passed in the uri list rather than one encountered by recursively
+	 * traversing directories. Used by metadata copying.
+	 */
+
+} GnomeVFSXferProgressInfo;


GnomeVFSXferProgressCallback ()

gint        (*GnomeVFSXferProgressCallback) (GnomeVFSXferProgressInfo *info,
+                                             gpointer data);

info : 
data : 
Returns : 


GnomeVFSAsyncCallback ()

void        (*GnomeVFSAsyncCallback)        (GnomeVFSAsyncHandle *handle,
+                                             GnomeVFSResult result,
+                                             gpointer callback_data);

handle : 
result : 
callback_data : 


GnomeVFSAsyncOpenCallback

typedef GnomeVFSAsyncCallback GnomeVFSAsyncOpenCallback;


GnomeVFSAsyncCreateCallback

typedef GnomeVFSAsyncCallback GnomeVFSAsyncCreateCallback;


GnomeVFSAsyncCreateAsChannelCallback

typedef GnomeVFSAsyncOpenAsChannelCallback GnomeVFSAsyncCreateAsChannelCallback;


GnomeVFSAsyncCloseCallback

#define GnomeVFSAsyncCloseCallback	GnomeVFSAsyncCallback


GnomeVFSAsyncReadCallback ()

void        (*GnomeVFSAsyncReadCallback)    (GnomeVFSAsyncHandle *handle,
+                                             GnomeVFSResult result,
+                                             gpointer buffer,
+                                             GnomeVFSFileSize bytes_requested,
+                                             GnomeVFSFileSize bytes_read,
+                                             gpointer callback_data);

handle : 
result : 
buffer : 
bytes_requested : 
bytes_read : 
callback_data : 


GnomeVFSAsyncWriteCallback ()

void        (*GnomeVFSAsyncWriteCallback)   (GnomeVFSAsyncHandle *handle,
+                                             GnomeVFSResult result,
+                                             gconstpointer buffer,
+                                             GnomeVFSFileSize bytes_requested,
+                                             GnomeVFSFileSize bytes_written,
+                                             gpointer callback_data);

handle : 
result : 
buffer : 
bytes_requested : 
bytes_written : 
callback_data : 


GnomeVFSGetFileInfoResult

typedef struct {
+	GnomeVFSURI *uri;
+	GnomeVFSResult result;
+	GnomeVFSFileInfo *file_info;
+} GnomeVFSGetFileInfoResult;


GnomeVFSFindDirectoryResult

typedef struct {
+	GnomeVFSURI *uri;
+	GnomeVFSResult result;
+} GnomeVFSFindDirectoryResult;


GnomeVFSTransformInitFunc ()

GnomeVFSTransform* (*GnomeVFSTransformInitFunc)
+                                            (const char *method_name,
+                                             const char *config_args);

method_name : 
config_args : 
Returns : 


GnomeVFSTransformFunc ()

GnomeVFSResult (*GnomeVFSTransformFunc)     (GnomeVFSTransform *transform,
+                                             const char *old_uri,
+                                             char **new_uri,
+                                             GnomeVFSContext *context);

transform : 
old_uri : 
new_uri : 
context : 
Returns : 


GnomeVFSMethodHandle

typedef gpointer GnomeVFSMethodHandle;



<<< Previous PageHomeUpNext Page >>>
Common Data TypesFile Info
\ No newline at end of file diff --git a/doc/html/gnome-vfs-uri.html b/doc/html/gnome-vfs-uri.html new file mode 100644 index 0000000..4653fdb --- /dev/null +++ b/doc/html/gnome-vfs-uri.html @@ -0,0 +1,3941 @@ +uri
GnomeVFS - Filesystem Abstraction library
<<< Previous PageHomeUpNext Page >>>

uri

Name

uri -- 

Synopsis


+
+GnomeVFSURI* gnome_vfs_uri_new              (const gchar *text_uri);
+GnomeVFSURI* gnome_vfs_uri_ref              (GnomeVFSURI *uri);
+void        gnome_vfs_uri_unref             (GnomeVFSURI *uri);
+GnomeVFSURI* gnome_vfs_uri_append_string    (const GnomeVFSURI *uri,
+                                             const char *path);
+GnomeVFSURI* gnome_vfs_uri_append_path      (const GnomeVFSURI *uri,
+                                             const char *path);
+GnomeVFSURI* gnome_vfs_uri_append_file_name (const GnomeVFSURI *uri,
+                                             const gchar *filename);
+gchar*      gnome_vfs_uri_to_string         (const GnomeVFSURI *uri,
+                                             GnomeVFSURIHideOptions hide_options);
+GnomeVFSURI* gnome_vfs_uri_dup              (const GnomeVFSURI *uri);
+gboolean    gnome_vfs_uri_is_local          (const GnomeVFSURI *uri);
+gboolean    gnome_vfs_uri_has_parent        (const GnomeVFSURI *uri);
+GnomeVFSURI* gnome_vfs_uri_get_parent       (const GnomeVFSURI *uri);
+GnomeVFSToplevelURI* gnome_vfs_uri_get_toplevel
+                                            (const GnomeVFSURI *uri);
+const gchar* gnome_vfs_uri_get_host_name    (const GnomeVFSURI *uri);
+const gchar* gnome_vfs_uri_get_scheme       (const GnomeVFSURI *uri);
+guint       gnome_vfs_uri_get_host_port     (const GnomeVFSURI *uri);
+const gchar* gnome_vfs_uri_get_user_name    (const GnomeVFSURI *uri);
+const gchar* gnome_vfs_uri_get_password     (const GnomeVFSURI *uri);
+void        gnome_vfs_uri_set_host_name     (GnomeVFSURI *uri,
+                                             const gchar *host_name);
+void        gnome_vfs_uri_set_host_port     (GnomeVFSURI *uri,
+                                             guint host_port);
+void        gnome_vfs_uri_set_user_name     (GnomeVFSURI *uri,
+                                             const gchar *user_name);
+void        gnome_vfs_uri_set_password      (GnomeVFSURI *uri,
+                                             const gchar *password);
+gboolean    gnome_vfs_uri_equal             (const GnomeVFSURI *a,
+                                             const GnomeVFSURI *b);
+gboolean    gnome_vfs_uri_is_parent         (const GnomeVFSURI *parent,
+                                             const GnomeVFSURI *item,
+                                             gboolean recursive);
+const gchar* gnome_vfs_uri_get_path         (const GnomeVFSURI *uri);
+const gchar* gnome_vfs_uri_get_fragment_identifier
+                                            (const GnomeVFSURI *uri);
+gchar*      gnome_vfs_uri_extract_dirname   (const GnomeVFSURI *uri);
+gchar*      gnome_vfs_uri_extract_short_name
+                                            (const GnomeVFSURI *uri);
+gchar*      gnome_vfs_uri_extract_short_path_name
+                                            (const GnomeVFSURI *uri);
+gint        gnome_vfs_uri_hequal            (gconstpointer a,
+                                             gconstpointer b);
+guint       gnome_vfs_uri_hash              (gconstpointer p);
+GList*      gnome_vfs_uri_list_ref          (GList *list);
+GList*      gnome_vfs_uri_list_unref        (GList *list);
+GList*      gnome_vfs_uri_list_copy         (GList *list);
+void        gnome_vfs_uri_list_free         (GList *list);
+#define     GNOME_VFS_URI_MAGIC_CHR
+#define     GNOME_VFS_URI_MAGIC_STR
+#define     GNOME_VFS_URI_PATH_CHR
+#define     GNOME_VFS_URI_PATH_STR

Description

Details

gnome_vfs_uri_new ()

GnomeVFSURI* gnome_vfs_uri_new              (const gchar *text_uri);

Create a new URI from text_uri.

text_uri : A string representing a URI.
Returns : The new URI.


gnome_vfs_uri_ref ()

GnomeVFSURI* gnome_vfs_uri_ref              (GnomeVFSURI *uri);

Increment uri's reference count.

uri : A GnomeVFSURI.
Returns : uri.


gnome_vfs_uri_unref ()

void        gnome_vfs_uri_unref             (GnomeVFSURI *uri);

Decrement uri's reference count. If the reference count reaches zero, +uri is destroyed.

uri : A GnomeVFSURI.


gnome_vfs_uri_append_string ()

GnomeVFSURI* gnome_vfs_uri_append_string    (const GnomeVFSURI *uri,
+                                             const char *path);

Create a new URI obtained by appending path to uri. This will take care +of adding an appropriate directory separator between the end of uri and +the start of path if necessary.

uri : A GnomeVFSURI.
path : 
Returns : The new URI obtained by combining uri and path.


gnome_vfs_uri_append_path ()

GnomeVFSURI* gnome_vfs_uri_append_path      (const GnomeVFSURI *uri,
+                                             const char *path);

Create a new URI obtained by appending path to uri. This will take care +of adding an appropriate directory separator between the end of uri and +the start of path if necessary as well as escaping path as necessary.

uri : A GnomeVFSURI.
path : A non-escaped file path
Returns : The new URI obtained by combining uri and path.


gnome_vfs_uri_append_file_name ()

GnomeVFSURI* gnome_vfs_uri_append_file_name (const GnomeVFSURI *uri,
+                                             const gchar *filename);

Create a new URI obtained by appending file_name to uri. This will take care +of adding an appropriate directory separator between the end of uri and +the start of file_name if necessary.

uri : A GnomeVFSURI.
filename : 
Returns : The new URI obtained by combining uri and path.


gnome_vfs_uri_to_string ()

gchar*      gnome_vfs_uri_to_string         (const GnomeVFSURI *uri,
+                                             GnomeVFSURIHideOptions hide_options);

Translate uri into a printable string. The string will not contain the +URI elements specified by hide_options.

uri : A GnomeVFSURI.
hide_options : Bitmask specifying what URI elements (e.g. password, +user name etc.) should not be represented in the returned string.
Returns : A malloced printable string representing uri.


gnome_vfs_uri_dup ()

GnomeVFSURI* gnome_vfs_uri_dup              (const GnomeVFSURI *uri);

Duplicate uri.

uri : A GnomeVFSURI.
Returns : A pointer to a new URI that is exactly the same as uri.


gnome_vfs_uri_is_local ()

gboolean    gnome_vfs_uri_is_local          (const GnomeVFSURI *uri);

Check if uri is a local (native) file system.

uri : A GnomeVFSURI.
Returns : FALSE if uri is not a local file system, TRUE otherwise.


gnome_vfs_uri_has_parent ()

gboolean    gnome_vfs_uri_has_parent        (const GnomeVFSURI *uri);

Check if URI has a parent or not.

uri : A GnomeVFSURI.
Returns : TRUE if uri has a parent, FALSE otherwise.


gnome_vfs_uri_get_parent ()

GnomeVFSURI* gnome_vfs_uri_get_parent       (const GnomeVFSURI *uri);

Retrieve uri's parent URI.

uri : A GnomeVFSURI.
Returns : A pointer to uri's parent URI.


gnome_vfs_uri_get_toplevel ()

GnomeVFSToplevelURI* gnome_vfs_uri_get_toplevel
+                                            (const GnomeVFSURI *uri);

Retrieve the toplevel URI in uri.

uri : A GnomeVFSURI.
Returns : A pointer to the toplevel URI object.


gnome_vfs_uri_get_host_name ()

const gchar* gnome_vfs_uri_get_host_name    (const GnomeVFSURI *uri);

Retrieve the host name for uri.

uri : A GnomeVFSURI.
Returns : A string representing the host name.


gnome_vfs_uri_get_scheme ()

const gchar* gnome_vfs_uri_get_scheme       (const GnomeVFSURI *uri);

Retrieve the scheme used for uri

uri : A GnomeVFSURI
Returns : A string representing the scheme


gnome_vfs_uri_get_host_port ()

guint       gnome_vfs_uri_get_host_port     (const GnomeVFSURI *uri);

Retrieve the host port number in uri.

uri : A GnomeVFSURI.
Returns : The host port number used by uri. If the value is zero, the +default port value for the specified toplevel access method is used.


gnome_vfs_uri_get_user_name ()

const gchar* gnome_vfs_uri_get_user_name    (const GnomeVFSURI *uri);

Retrieve the user name in uri.

uri : A GnomeVFSURI.
Returns : A string representing the user name in uri.


gnome_vfs_uri_get_password ()

const gchar* gnome_vfs_uri_get_password     (const GnomeVFSURI *uri);

Retrieve the password for uri.

uri : A GnomeVFSURI.
Returns : The password for uri.


gnome_vfs_uri_set_host_name ()

void        gnome_vfs_uri_set_host_name     (GnomeVFSURI *uri,
+                                             const gchar *host_name);

Set host_name as the host name accessed by uri.

uri : A GnomeVFSURI.
host_name : A string representing a host name.


gnome_vfs_uri_set_host_port ()

void        gnome_vfs_uri_set_host_port     (GnomeVFSURI *uri,
+                                             guint host_port);

Set the host port number in uri. If host_port is zero, the default port +for uri's toplevel access method is used.

uri : A GnomeVFSURI.
host_port : A TCP/IP port number.


gnome_vfs_uri_set_user_name ()

void        gnome_vfs_uri_set_user_name     (GnomeVFSURI *uri,
+                                             const gchar *user_name);

Set user_name as the user name for uri.

uri : A GnomeVFSURI.
user_name : A string representing a user name on the host accessed by uri.


gnome_vfs_uri_set_password ()

void        gnome_vfs_uri_set_password      (GnomeVFSURI *uri,
+                                             const gchar *password);

Set password as the password for uri.

uri : A GnomeVFSURI.
password : A password string.


gnome_vfs_uri_equal ()

gboolean    gnome_vfs_uri_equal             (const GnomeVFSURI *a,
+                                             const GnomeVFSURI *b);

Compare a and b.

a : A GnomeVFSURI.
b : A GnomeVFSURI.
Returns : TRUE if a and b are equal, FALSE otherwise. + +FIXME: This comparison should take into account the possiblity +that unreserved characters may be escaped. +...or perhaps gnome_vfs_uri_new should unescape unreserved characters?


gnome_vfs_uri_is_parent ()

gboolean    gnome_vfs_uri_is_parent         (const GnomeVFSURI *parent,
+                                             const GnomeVFSURI *item,
+                                             gboolean recursive);

Check if possible_child is contained by possible_parent. +If recursive is FALSE, just try the immediate parent directory, else +search up through the hierarchy.

parent : 
item : 
recursive : a flag to turn recursive check on.
Returns : TRUE if possible_child is contained in possible_child.


gnome_vfs_uri_get_path ()

const gchar* gnome_vfs_uri_get_path         (const GnomeVFSURI *uri);

Retrieve full path name for uri.

uri : A GnomeVFSURI
Returns : A pointer to the full path name in uri. Notice that the +pointer points to the name store in uri, so the name returned must not +be modified nor freed.


gnome_vfs_uri_get_fragment_identifier ()

const gchar* gnome_vfs_uri_get_fragment_identifier
+                                            (const GnomeVFSURI *uri);

uri : 
Returns : 


gnome_vfs_uri_extract_dirname ()

gchar*      gnome_vfs_uri_extract_dirname   (const GnomeVFSURI *uri);

Extract the name of the directory in which the file pointed to by uri is +stored as a newly allocated string. The string will end with a +GNOME_VFS_URI_PATH_CHR.

uri : A GnomeVFSURI
Returns : A pointer to the newly allocated string representing the +parent directory.


gnome_vfs_uri_extract_short_name ()

gchar*      gnome_vfs_uri_extract_short_name
+                                            (const GnomeVFSURI *uri);

Retrieve base file name for uri, ignoring any trailing path separators. +This matches the XPG definition of basename, but not g_basename. This is +often useful when you want the name of something that's pointed to by a +uri, and don't care whether the uri has a directory or file form. +If uri points to the root of a domain, returns the host name. If there's +no host name, returns GNOME_VFS_URI_PATH_STR.

See also: gnome_vfs_uri_extract_short_path_name.

uri : A GnomeVFSURI
Returns : A pointer to the newly allocated string representing the +unescaped short form of the name.


gnome_vfs_uri_extract_short_path_name ()

gchar*      gnome_vfs_uri_extract_short_path_name
+                                            (const GnomeVFSURI *uri);

Retrieve base file name for uri, ignoring any trailing path separators. +This matches the XPG definition of basename, but not g_basename. This is +often useful when you want the name of something that's pointed to by a +uri, and don't care whether the uri has a directory or file form. +If uri points to the root (including the root of any domain), +returns GNOME_VFS_URI_PATH_STR.

See also: gnome_vfs_uri_extract_short_name.

uri : A GnomeVFSURI
Returns : A pointer to the newly allocated string representing the +escaped short form of the name.


gnome_vfs_uri_hequal ()

gint        gnome_vfs_uri_hequal            (gconstpointer a,
+                                             gconstpointer b);

a : 
b : 
Returns : 


gnome_vfs_uri_hash ()

guint       gnome_vfs_uri_hash              (gconstpointer p);

p : 
Returns : 


gnome_vfs_uri_list_ref ()

GList*      gnome_vfs_uri_list_ref          (GList *list);

list : 
Returns : 


gnome_vfs_uri_list_unref ()

GList*      gnome_vfs_uri_list_unref        (GList *list);

list : 
Returns : 


gnome_vfs_uri_list_copy ()

GList*      gnome_vfs_uri_list_copy         (GList *list);

list : 
Returns : 


gnome_vfs_uri_list_free ()

void        gnome_vfs_uri_list_free         (GList *list);

list : 


GNOME_VFS_URI_MAGIC_CHR

#define GNOME_VFS_URI_MAGIC_CHR	'#'


GNOME_VFS_URI_MAGIC_STR

#define GNOME_VFS_URI_MAGIC_STR "#"


GNOME_VFS_URI_PATH_CHR

#define GNOME_VFS_URI_PATH_CHR '/'


GNOME_VFS_URI_PATH_STR

#define GNOME_VFS_URI_PATH_STR "/"



<<< Previous PageHomeUpNext Page >>>
Result CodesMIME types & the Application Registry
\ No newline at end of file diff --git a/doc/html/gnome-vfs-utils.html b/doc/html/gnome-vfs-utils.html new file mode 100644 index 0000000..28421c6 --- /dev/null +++ b/doc/html/gnome-vfs-utils.html @@ -0,0 +1,1864 @@ +utils
GnomeVFS - Filesystem Abstraction library
<<< Previous PageHomeUp 

utils

Name

utils -- 

Synopsis


+
+char*       gnome_vfs_format_file_size_for_display
+                                            (GnomeVFSFileSize size);
+char*       gnome_vfs_escape_string         (const char *string);
+char*       gnome_vfs_escape_path_string    (const char *path);
+char*       gnome_vfs_escape_host_and_path_string
+                                            (const char *path);
+char*       gnome_vfs_escape_slashes        (const char *string);
+char*       gnome_vfs_escape_set            (const char *string,
+                                             const char *match_set);
+char*       gnome_vfs_unescape_string       (const char *string,
+                                             const char *illegal_characters);
+char*       gnome_vfs_make_uri_canonical    (const char *uri);
+char*       gnome_vfs_make_path_name_canonical
+                                            (const char *path);
+char*       gnome_vfs_expand_initial_tilde  (const char *path);
+char*       gnome_vfs_unescape_string_for_display
+                                            (const char *escaped);
+char*       gnome_vfs_get_local_path_from_uri
+                                            (const char *uri);
+char*       gnome_vfs_get_uri_from_local_path
+                                            (const char *local_full_path);
+gboolean    gnome_vfs_is_executable_command_string
+                                            (const char *command_string);
+void        gnome_vfs_list_deep_free        (GList *list);
+GnomeVFSResult gnome_vfs_get_volume_free_space
+                                            (const GnomeVFSURI *vfs_uri,
+                                             GnomeVFSFileSize *size);
+char*       gnome_vfs_icon_path_from_filename
+                                            (const char *filename);
+#define     GNOME_VFS_ASSERT_PRIMARY_THREAD
+#define     GNOME_VFS_ASSERT_SECONDARY_THREAD
+gboolean    gnome_vfs_is_primary_thread     (void);

Description

Details

gnome_vfs_format_file_size_for_display ()

char*       gnome_vfs_format_file_size_for_display
+                                            (GnomeVFSFileSize size);

size : 
Returns : 


gnome_vfs_escape_string ()

char*       gnome_vfs_escape_string         (const char *string);

string : 
Returns : 


gnome_vfs_escape_path_string ()

char*       gnome_vfs_escape_path_string    (const char *path);

path : 
Returns : 


gnome_vfs_escape_host_and_path_string ()

char*       gnome_vfs_escape_host_and_path_string
+                                            (const char *path);

path : 
Returns : 


gnome_vfs_escape_slashes ()

char*       gnome_vfs_escape_slashes        (const char *string);

string : 
Returns : 


gnome_vfs_escape_set ()

char*       gnome_vfs_escape_set            (const char *string,
+                                             const char *match_set);

string : 
match_set : 
Returns : 


gnome_vfs_unescape_string ()

char*       gnome_vfs_unescape_string       (const char *string,
+                                             const char *illegal_characters);

string : 
illegal_characters : 
Returns : 


gnome_vfs_make_uri_canonical ()

char*       gnome_vfs_make_uri_canonical    (const char *uri);

uri : 
Returns : 


gnome_vfs_make_path_name_canonical ()

char*       gnome_vfs_make_path_name_canonical
+                                            (const char *path);

path : 
Returns : 


gnome_vfs_expand_initial_tilde ()

char*       gnome_vfs_expand_initial_tilde  (const char *path);

path : 
Returns : 


gnome_vfs_unescape_string_for_display ()

char*       gnome_vfs_unescape_string_for_display
+                                            (const char *escaped);

escaped : 
Returns : 


gnome_vfs_get_local_path_from_uri ()

char*       gnome_vfs_get_local_path_from_uri
+                                            (const char *uri);

Return a local path for a file:/// URI.

uri : 
Returns : the local path +NULL is returned on error or if the uri isn't a file: URI +without a fragment identifier (or chained URI).


gnome_vfs_get_uri_from_local_path ()

char*       gnome_vfs_get_uri_from_local_path
+                                            (const char *local_full_path);

Return a file:/// URI for a local path.

local_full_path : 
Returns : the URI (NULL for some bad errors).


gnome_vfs_is_executable_command_string ()

gboolean    gnome_vfs_is_executable_command_string
+                                            (const char *command_string);

command_string : 
Returns : 


gnome_vfs_list_deep_free ()

void        gnome_vfs_list_deep_free        (GList *list);

list : 


gnome_vfs_get_volume_free_space ()

GnomeVFSResult gnome_vfs_get_volume_free_space
+                                            (const GnomeVFSURI *vfs_uri,
+                                             GnomeVFSFileSize *size);

vfs_uri : 
size : 
Returns : 


gnome_vfs_icon_path_from_filename ()

char*       gnome_vfs_icon_path_from_filename
+                                            (const char *filename);

filename : 
Returns : 


GNOME_VFS_ASSERT_PRIMARY_THREAD

#define GNOME_VFS_ASSERT_PRIMARY_THREAD g_assert (gnome_vfs_is_primary_thread())


GNOME_VFS_ASSERT_SECONDARY_THREAD

#define GNOME_VFS_ASSERT_SECONDARY_THREAD g_assert (!gnome_vfs_is_primary_thread())


gnome_vfs_is_primary_thread ()

gboolean    gnome_vfs_is_primary_thread     (void);

Returns : 



<<< Previous PageHomeUp 
Initialization 
\ No newline at end of file diff --git a/doc/html/gnome-vfs-writing-modules.html b/doc/html/gnome-vfs-writing-modules.html new file mode 100644 index 0000000..ed53d15 --- /dev/null +++ b/doc/html/gnome-vfs-writing-modules.html @@ -0,0 +1,328 @@ +Writing Modules

Writing Modules

Writing Modules — basic gnome-vfs module concepts

Introduction

This section will introduce the basic concepts that are + needed for writing GNOME Virtual File System modules.

GNOME VFS URIs (Uniform Resource Identifiers)

The GNOME Virtual file system uses URIs similiar to the + standard WWW URIs. The basic difference between a VFS URI and + WWW URI is that, while with WWW URIs you can only use a single + protocol for accessing a certain file, with GNOME VFS URIs you + can combine different access methods in sequence.

For example, suppose you want to access file + hello.c in a tar.gz + file which is in turn accessible through FTP from a remote + machine. In order to access this file, you would need to:

  1. Connect to the FTP site.

  2. Fetch the tar.gz + file.

  3. Decompress the tar.gz file using + GZIP.

  4. Extract hello.c from the resulting + uncompressed tar file.

The GNOME Virtual File System lets you express this by + combining the three access methods (i.e. tar, GZIP and FTP) + into a single URI. Access methods are combined in the URI by + using the `#' character, followed by the name for the access + method and the subpath for that specific access method. The + subpath can be omitted for those storage methods that do not + need a path to retrieve the file. (For example, a GZIP file + always contains a single uncompressed file, so no path is + needed to locate the uncompressed file within the GZIP file. + But on the other hand, the TAR method requires a path to + locate a specific file or directory.)

For example, in the case we outlined above, the URI would + look something like:

+
+        ftp://username:password@host.net/path/to/file.tar.gz#gzip#tar/path/to/hello.c

Each method/subpath couple is called a URI + element. When URI elements are combined like this, + each URI element uses the previous one to access a base resource + into which it will look up a file, using the subpath + information. For this reason, we will say that each element is + the parent element for the following one.

The first URI element, the one which has no parent, is + called the toplevel element. It does not + use the `#' character; instead, it uses the standard syntax of + WWW URIs:

+
+        method://user:password@host/path/to/file

This way, normal WWW URIs can be used with the GNOME Virtual + File System.

Toplevel elements are also special because they let users + specify user names, passwords and host names, while + non-toplevel elements don't.


The GnomeVFSURI type

Within the GNOME Virtual File System library, URI elements + are represented by a special type, + GnomeVFSURI, which is meant to represent + user-provided URIs in a machine-optimized way.

Every GnomeVFSURI contains the + following information:

  • A reference counter

  • A pointer to the parent + GnomeVFSURI URI element.

  • The subpath.

  • The name of the access method.

  • A pointer to a + GnomeVFSMethod object, describing the + access method (see below).

GNOME Virtual File System access method implementation

In the GNOME Virtual File System, the implementations for + all the access methods are loaded at runtime, as shared library + modules. The modules are loaded during parsing of the string URI: + if the parser encounters an access method for which no + implementation is currently loaded, it retrieves the corresponding + library file, dynamically links it into the executable, and + initializes it.

After initialization, the module returns a special + GnomeVFSMethod object that contains + pointers to the various implementation functions for that specific + method. By storing a pointer to this object into the + GnomeVFSURI type, the VFS library is then + able to use these functions for file access.

How file access is performed

When the VFS library needs to perform some file operation, + it performs the following steps:

  • If the URI is given in textual form (i.e. as a + string), it parses it and activates the necessary access method + modules.

  • It retrieves a pointer to the lowmost + level URI element.

  • It retrieves a pointer to the + GnomeVFSMethod object that corresponds + to the access method for that URI element.

  • It retrieves a pointer to the implementation + function for that operation from the + GnomeVFSMethodobject.

  • It invokes that implementation function + passing the pointer to the lowmost level URI + element.

Combining the access methods is always done within the + method implementation. If the method implementation needs to do + some file operation on the the parent URI element, it can do so + by simply invoking the corresponding VFS function in, by using + the parent pointer in the GnomeVFSURI + object.

For example, suppose you have to read a simple URI like + the following:

+
+        file:/home/ettore/file.gz#gzip

In this case, the GZIP method will be invoked with a + pointer to the GnomeVFSURI describing the + `gzip' part; then the GZIP method will be able to read + file.gz by just invoking the corresponding + GNOME VFS library function on its parent, and decompress it on + the fly.

Implementing an access method in practice

Implementing a new access method is really not difficult at + all. This section explains how this is done.

Using shared libraries

Every module must be compiled as a shared library (i.e. a + .so file).

The current way for accessing the right module for the + right method is very simple, and is based on file names. In + practice, a module implementing access method named + foo must be named + libfoo.so. For example, the module + implementing the ftp: access method is + called libftp.so, the module implementing + #gzip access is called + libgzip.so and so on.

This might change in the future.


The initialization/shutdown functions

Every shared library module must provide two functions:

+
+GnomeVFSMethod *vfs_module_init (void);
+void vfs_module_shutdown (GnomeVFSMethod *method);

These are the only functions that the VFS library will + access directly. All the other symbols (i.e. functions and + variables) in the module should be made static.

vfs_module_init() is called + as soon as the module is loaded in memory. It will have to + return a pointer to a GnomeVFSMethod + object that will contain the pointers to the method's + implementation functions. We will describe this later.

vfs_module_shutdown, instead, + is called before the module is unloaded or the program that uses + it dies. This functions should:

  • Deallocate all the memory allocated by the + module.

  • Close all the file descriptors associated with + the module.

  • Kill any external process spawned by the + module.

  • In general, make sure that any operation that + was going on before this function was called will be + interrupted correctly, as soon as possible and without any + leaks.


The GnomeVFSMethod object

This object is contains pointers to the module + implementation functions.

+
+GnomeVFSResult (* open)              (GnomeVFSMethodHandle **method_handle_return,
+                                      GnomeVFSURI *uri,
+                                      GnomeVFSOpenMode mode
+                                      GnomeVFSCancellation *cancellation);
+
+GnomeVFSResult (* create)            (GnomeVFSMethodHandle **method_handle_return,
+                                      GnomeVFSURI *uri,
+                                      GnomeVFSOpenMode mode,
+                                      gboolean exclusive,
+                                      guint perm
+                                      GnomeVFSCancellation *cancellation);
+
+GnomeVFSResult (* close)             (GnomeVFSMethodHandle *method_handle
+                                      GnomeVFSCancellation *cancellation);
+
+GnomeVFSResult (* read)              (GnomeVFSMethodHandle *method_handle,
+                                      gpointer buffer,
+                                      GnomeVFSFileSize num_bytes,
+                                      GnomeVFSFileSize *bytes_read_return
+                                      GnomeVFSCancellation *cancellation);
+
+GnomeVFSResult (* write)             (GnomeVFSMethodHandle *method_handle,
+                                      gconstpointer buffer,
+                                      GnomeVFSFileSize num_bytes,
+                                      GnomeVFSFileSize *bytes_written_return
+                                      GnomeVFSCancellation *cancellation);
+
+GnomeVFSResult (* seek)              (GnomeVFSMethodHandle *method_handle,
+                                      GnomeVFSSeekPosition  whence,
+                                      GnomeVFSFileOffset    offset
+                                      GnomeVFSCancellation *cancellation);
+
+GnomeVFSResult (* tell)              (GnomeVFSMethodHandle *method_handle,
+                                      GnomeVFSFileOffset *offset_return);
+
+GnomeVFSResult (* truncate)          (GnomeVFSMethodHandle *method_handle,
+                                      GnomeVFSFileSize where
+                                      GnomeVFSCancellation *cancellation);
+
+GnomeVFSResult (* open_directory)    (GnomeVFSMethodHandle **method_handle,
+                                      GnomeVFSURI *uri,
+                                      GnomeVFSFileInfoOptions options,
+                                      const GList *meta_keys,
+                                      const GnomeVFSDirectoryFilter *filter
+                                      GnomeVFSCancellation *cancellation);
+
+GnomeVFSResult (* close_directory)   (GnomeVFSMethodHandle *method_handle
+                                      GnomeVFSCancellation *cancellation);
+
+GnomeVFSResult (* read_directory)    (GnomeVFSMethodHandle *method_handle,
+                                      GnomeVFSFileInfo *file_info
+                                      GnomeVFSCancellation *cancellation);
+
+GnomeVFSResult (* get_file_info)     (GnomeVFSURI *uri,
+                                      GnomeVFSFileInfo *file_info,
+                                      GnomeVFSFileInfoOptions options,
+                                      const GList *meta_keys
+                                      GnomeVFSCancellation *cancellation);
+
+GnomeVFSResult (* get_file_info_from_handle)
+                                     (GnomeVFSMethodHandle *method_handle,
+                                      GnomeVFSFileInfo *file_info,
+                                      GnomeVFSFileInfoOptions options,
+                                      const GList *meta_keys
+                                      GnomeVFSCancellation *cancellation);
+
+gboolean       (* is_local)          (const GnomeVFSURI *uri
+                                      GnomeVFSCancellation *cancellation);
+
+GnomeVFSResult (* rename)            (GnomeVFSURI *uri, const gchar *new_name
+                                      GnomeVFSCancellation *cancellation);
+
+GnomeVFSResult (* make_directory)    (GnomeVFSURI *uri, guint perm
+                                      GnomeVFSCancellation *cancellation);
+
+GnomeVFSResult (* remove_directory)  (GnomeVFSURI *uri
+                                      GnomeVFSCancellation *cancellation);
+
+GnomeVFSResult (* unlink)            (GnomeVFSURI *uri
+                                      GnomeVFSCancellation *cancellation);
+

Handling cancellation

As VFS operations might be very long, especially in the case + of transient errors (such as a network server that has gone down), + the GNOME Virtual File System Library provides a standard way for + handling cancellation of VFS operations.

The GnomeVFSCancellation object

The object that encapsulates this functionality is + GnomeVFSCancellation. Most + implementation functions get a pointer to such an object, and are + expected to use this object to recognize when an operation should + be interrupted.

The most simple way to check for a cancellation request is + to poll the object with + gnome_vfs_cancellation_check():

+  
+gboolean gnome_vfs_cancellation_check (GnomeVFSCancellation *cancellation);

This function will return a nonzero value if the current + operation should be cancelled.

Notice that cancellation is an asynchronous operation that + might happen outside your function, in parallel with the code that + you are writing. For example, in the case of threads, the request + will be set in the master thread; in the case of slave + CORBA-driven processes, the request will be activated by a Unix + signal. So you can expect a cancellation request to happen (and + consequently be signalled in + GnomeVFSCancellation) at any time.

For this reason, you should be calling this function + periodically, whenever you are going to perform several + iterations of the same task, or execute a single expensive task. + When the function returns a nonzero value, the correct way to + react is:

  1. Clean things up so that the result of the + operations that have been performed are all + cancelled.

  2. Return the + GNOME_VFS_ERROR_CANCELLED error + code.

But there are some other situations in which you want to + be able to interrupt a I/O operation when a cancellation request + is performed. In such cases, polling is not a viable option.

For this reason, + GnomeVFSCancellation provides an + alternative way of sending notifications, using a file + descriptor. To use this feature, you should use the following + function:

+
+gint gnome_vfs_cancellation_get_fd (GnomeVFSCancellation *cancellation); 

When this function is called, it will return an open file + descriptor, which is the read-side of a pipe. The pipe will be + given a character from the write side as soon as a cancellation + request is sent. For this reason, you can check for a + cancellation by using the select() system + call: as soon as select reports that some + data is available on the file descriptor, you know that a + cancellation is being requested.

For example, if you are reading from a file descriptor and + you want to check for a pending cancellation at the same time, + you can set up selectfor checking if data + is available on both the cancellation file descriptor and the + file descriptor you are reading from.


Dealing with EINTR

In order to maximize the chance of cancelling an operation + immediately, the GNOME Virtual File System can sends a signal to + the asynchronous thread or process. This does not happen on all + the systems and setups, though.

The result of this is that, if a process is in the middle + of a Unix system call while receiving this signal, the system + call might be interrupted and return a EINTR + error.

For this reason, when you receive EINTR + you should check if a cancellation request is pending, using + gnome_vfs_cancellation_check() on the + GnomeVFSCancellation object that the + implementation function received:

  • If a cancellation is indeed pending + (gnome_vfs_cancellation_check() returns a + nonzero value), you should cancel the operation, cleaning up + all the effects, and return + GNOME_VFS_ERROR_INTERRUPTED or + GNOME_VFS_ERROR_CANCELLED

  • Otherwise, retry the system call as you would + normally do.

Basic guidelines for writing a module

Writing GNOME VFS modules is easy, but there are a few + things that you must keep in mind when hacking them:

  • All of the code must be completely thread safe. + The reason for this is that the asynchronous GNOME VFS engine + will use threads when available; if you don't make sure that the + code is thread-safe, every kind of weird and unexpected errors + will happen. As debugging these problems can be very hard, it's + important to write the code with threads in mind right from the + start.

  • Use the special + gnome_vfs_*_cancellable() VFS functions + instead of the standard non-cancellable ones, passing them the + same GnomeVFSCancellation object you + are given, so that the operation can always be interrrupted at + any time.

  • The code should respect the basic GNOME + guidelines for source code indentation and + style.

How to make the code thread safe

Although it might sound scary at first, making the code + for the modules thread safe is not complicated at all.

First of all, make sure the amount of global variables is + kept to the bare minimum. If possible, you should avoid them at + all cost.

For those cases where globals are inevitable (such as + caches, connection pools or things like that), you have to make + sure every variable is properly associated with a mutex, and + that the mutex is locked before every access to this variable + and released afterwards. You can also use + G_LOCK_DEFINE_STATIC, + G_LOCK and G_UNLOCK + for this. +

Generally speaking, if you are going to dynamically + allocate structures that are shared by more than one + operation/file, you should provide all of them with their nice + mutex locks.

Finally, make sure mutexes are used only if they are + available. One way to do so is to use macros like the + following:

+
+#ifdef G_THREADS_ENABLED
+#define MUTEX_NEW()     g_mutex_new ()
+#define MUTEX_FREE(a)   g_mutex_free (a)
+#define MUTEX_LOCK(a)   if ((a) != NULL) g_mutex_lock (a)
+#define MUTEX_UNLOCK(a) if ((a) != NULL) g_mutex_unlock (a)
+#else
+#define MUTEX_NEW()     NULL
+#define MUTEX_FREE(a)
+#define MUTEX_LOCK(a)
+#define MUTEX_UNLOCK(a)
+#endif

G_LOCK_DEFINE_STATIC, + G_LOCK and G_UNLOCK in + GLib are always safe to use, as they are already defined to be + nothing when thread support is not available.

(Probably it would be a good idea to have something in the + private GNOME VFS API that does this stuff for all the + modules.)

diff --git a/doc/html/gnome-vfs-xfer.html b/doc/html/gnome-vfs-xfer.html new file mode 100644 index 0000000..81ef96a --- /dev/null +++ b/doc/html/gnome-vfs-xfer.html @@ -0,0 +1,1103 @@ +Copy Engine
GnomeVFS - Filesystem Abstraction library
<<< Previous PageHomeUpNext Page >>>

Copy Engine

Name

Copy Engine -- asynchronous copy/move/delete engine

Synopsis


+
+GnomeVFSResult gnome_vfs_xfer_uri_list      (const GList *source_uri_list,
+                                             const GList *target_uri_list,
+                                             GnomeVFSXferOptions xfer_options,
+                                             GnomeVFSXferErrorMode error_mode,
+                                             GnomeVFSXferOverwriteMode overwrite_mode,
+                                             GnomeVFSXferProgressCallback progress_callback,
+                                             gpointer data);
+GnomeVFSResult gnome_vfs_xfer_uri           (const GnomeVFSURI *source_uri,
+                                             const GnomeVFSURI *target_uri,
+                                             GnomeVFSXferOptions xfer_options,
+                                             GnomeVFSXferErrorMode error_mode,
+                                             GnomeVFSXferOverwriteMode overwrite_mode,
+                                             GnomeVFSXferProgressCallback progress_callback,
+                                             gpointer data);
+GnomeVFSResult gnome_vfs_xfer_delete_list   (const GList *source_uri_list,
+                                             GnomeVFSXferErrorMode error_mode,
+                                             GnomeVFSXferOptions xfer_options,
+                                             GnomeVFSXferProgressCallback progress_callback,
+                                             gpointer data);

Description

Details

gnome_vfs_xfer_uri_list ()

GnomeVFSResult gnome_vfs_xfer_uri_list      (const GList *source_uri_list,
+                                             const GList *target_uri_list,
+                                             GnomeVFSXferOptions xfer_options,
+                                             GnomeVFSXferErrorMode error_mode,
+                                             GnomeVFSXferOverwriteMode overwrite_mode,
+                                             GnomeVFSXferProgressCallback progress_callback,
+                                             gpointer data);

This function will transfer multiple files to a multiple targets. Given a +a source uri(s) and a destination uri(s). There are a list of options that +your application can use to control how the transfer is done.

source_urilist: A Glist of uris (ie file;//) +target_uri_list: A GList of uris +xfer_options: These are options you wish to set for the transfer. For +instance by setting the xfer behavior you can either make a copy or a +move. +error_mode: Decide how to behave if the xfer is interrupted. For instance +you could set your application to return an error code in case of an +interuption. +overwrite_mode: How to react if a file your copying is being overwritten. +progress_callback: This is used to monitor the progress of a transfer. +Common use would be to check to see if the transfer is asking for permission +to overwrite a file. +data: Data to be want passed back in callbacks from the xfer engine

source_uri_list : 
target_uri_list : 
xfer_options : 
error_mode : 
overwrite_mode : 
progress_callback : 
data : 
Returns : If all goes well it returns GNOME_VFS_OK. Check GnomeVFSResult for +other values.


gnome_vfs_xfer_uri ()

GnomeVFSResult gnome_vfs_xfer_uri           (const GnomeVFSURI *source_uri,
+                                             const GnomeVFSURI *target_uri,
+                                             GnomeVFSXferOptions xfer_options,
+                                             GnomeVFSXferErrorMode error_mode,
+                                             GnomeVFSXferOverwriteMode overwrite_mode,
+                                             GnomeVFSXferProgressCallback progress_callback,
+                                             gpointer data);

This function will allow a person to copy data from one location to another. +The location is specified using a URIs as the means to describe the location +of the data. Like any copy there are several options that can be set. +These can be set using the xfer_options. In addition there are callback +mechanisms and error codes to provide feedback in the copy +process.

source_uri: This is the location of where your data resides. +target_uri: This is the location of where you want your data to go. +xfer_options: Set the kind of transfers you want. These are: +GNOME_VFS_XFER_DEFAULT: Default behavior. Which is to do a straight one to +one copy. +GNOME_VFS_XFER_FOLLOW_LINKS: This means follow the value of the symbolic +link when copying. (ie treat a symbolic link as a directory) +GNOME_VFS_RECURSIVE: Do a recursive copy of the source to the destination. +Equivalent to the cp -r option in GNU cp. +GNOME_VFS_XFER_SAME_FS: This only allows copying onto the same filesystem. +GNOME_VFS_DELETE_ITEM: This is equivalent to a mv. Where you will copy the +contents of the source to the destination and then remove data from the +source URI. +GNOME_VFS_XFER_EMPTY_DIRECTORIES: <TBA> +GNOME_VFS_XFER_NEW_UNIQUE_DIRECTORY: This will create a directory if it +doesn't exist in the destination area. Useful with the +GNOME_VFS_XFER_RECURSIVE xfer option. +GNOME_VFS_XFER_REMOVESOURCE: This option will remove the source data after +whatever xfer option has been taken. +GNOME_VFS_USE_UNIQUE_NAMES: This is a check ot make sure that what you copy +onto the destination is not overwritten. It will only copy the unique items +from the source to the destjnation. +GNOME_VFS_XFER_LINK_ITEMS: <TBA> +error_mode: When this function returns you need to check the error code +for the results of the copy. The results are generally: +GNOME_VFS_XFER_ERROR_MODE_ABORT: This means that the operation was aborted +by some sort of signal that interrupted the transfer. +GNOME_VFS_ERROR_MODE_QUERY: This means that no error has occured and that +you should query with the GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR. See

overwrite_mode: This sets the options to deal with data that are duplicate +between the source and the destination. Your choices are: +GNOME_VFS_XFER_OVERWRITE_MODE_ABORT: This means abort the transfer if you +see duplicate data. +GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE: Replace the files silently. Don't +worry be happy. +GNOME_VFS_XFER_OVERWRITE_MODE_SKIP: Skip duplicate files silenty. +target. +progress_callback: This is an important call back because this is how you +communicate with your copy process. +data: Data to be want passed back in callbacks from the xfer engine

source_uri : 
target_uri : 
xfer_options : 
error_mode : 
overwrite_mode : 
progress_callback : 
data : 
Returns : 


gnome_vfs_xfer_delete_list ()

GnomeVFSResult gnome_vfs_xfer_delete_list   (const GList *source_uri_list,
+                                             GnomeVFSXferErrorMode error_mode,
+                                             GnomeVFSXferOptions xfer_options,
+                                             GnomeVFSXferProgressCallback progress_callback,
+                                             gpointer data);

uri_list: This is a list containing uris +error_mode: Decide how you want to deal with interruptions +xfer_options: Set whatever transfer options you need. +progress_callback: Callback to check on progress of transfer. +data: Data to be want passed back in callbacks from the xfer engine

source_uri_list : 
error_mode : 
xfer_options : 
progress_callback : 
data : 
Returns : 



<<< Previous PageHomeUpNext Page >>>
Asynchronous File I/OModule Callbacks
\ No newline at end of file diff --git a/doc/html/index.html b/doc/html/index.html new file mode 100644 index 0000000..09fc13c --- /dev/null +++ b/doc/html/index.html @@ -0,0 +1,39 @@ +GnomeVFS - Filesystem Abstraction library

Seth Nickell


+     
+   

+ Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.1 + or any later version published by the Free Software Foundation; + A copy of the license is included in the section entitled "GNU + Free Documentation License". +


diff --git a/doc/html/index.sgml b/doc/html/index.sgml new file mode 100644 index 0000000..0369340 --- /dev/null +++ b/doc/html/index.sgml @@ -0,0 +1,424 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/html/mime-registry.html b/doc/html/mime-registry.html new file mode 100644 index 0000000..9c23634 --- /dev/null +++ b/doc/html/mime-registry.html @@ -0,0 +1,42 @@ +MIME Registry

MIME Registry

Table of Contents

Application Registry - +stores supported MIME types and URIs of various applications
File Types - +functions for getting information about files based on their MIME type
MIME Database Monitor - +monitor the MIME database for changes (primarily for file browsers)

+ MIME types provide a standardized for denoting the content of files or + file streams. GnomeVFS exposes simple methods for both identifying the + MIME type of a particular file, and deciding how to act on it. The MIME + and application registries provide a mapping between files of a particular + mime type and applications / bonobo components which can view or edit + those files. Applications such as Nautilus use this database to generate + appropriate actions when files are activated. +

diff --git a/doc/html/modules.html b/doc/html/modules.html new file mode 100644 index 0000000..f865130 --- /dev/null +++ b/doc/html/modules.html @@ -0,0 +1,38 @@ +Filesystem Modules

Filesystem Modules

Table of Contents

Writing Modules - basic gnome-vfs module concepts
MIME typing - functions to get a mime-type for a file using its name or its content
gnome-vfs-method -
gnome-vfs-module -
gnome-vfs-module-shared -
gnome-vfs-module-callback-module-api - invoking callbacks from a gnome-vfs module to ask the application for necessary information (authentication, ...)
gnome-vfs-ssl -
GnomeVFSContext - +contexts allows modules to track thread usage and cancellation properly
gnome-vfs-socket -
gnome-vfs-socket-buffer -
gnome-vfs-transform -
gnome-vfs-parse-ls - convenience functions for modules which want to parse a ls-like directory listing

+ Modules are the mechanism by which GnomeVFS accesses different filesystems, + from http, to the local disk, to smb. Module authors must implement a simple + set of filesystem operations and can provide varying degrees of service (read-only, + read-write, seeking, etc). Modules are dynamically loaded based upon the URI + scheme passed into the high-level GnomeVFS APIs. +

diff --git a/doc/html/writing-modules.html b/doc/html/writing-modules.html new file mode 100644 index 0000000..ab5ba95 --- /dev/null +++ b/doc/html/writing-modules.html @@ -0,0 +1,974 @@ +Writing Modules
GnomeVFS - Filesystem Abstraction library

Writing Modules

Name

Writing Modules -- basic gnome-vfs module concepts

Introduction

This section will introduce the basic concepts that are + needed for writing GNOME Virtual File System modules.

GNOME VFS URIs (Uniform Resource Identifiers)

The GNOME Virtual file system uses URIs similiar to the + standard WWW URIs. The basic difference between a VFS URI and + WWW URI is that, while with WWW URIs you can only use a single + protocol for accessing a certain file, with GNOME VFS URIs you + can combine different access methods in sequence.

For example, suppose you want to access file + hello.c in a tar.gz + file which is in turn accessible through FTP from a remote + machine. In order to access this file, you would need to:

  1. Connect to the FTP site.

  2. Fetch the tar.gz + file.

  3. Decompress the tar.gz file using + GZIP.

  4. Extract hello.c from the resulting + uncompressed tar file.

The GNOME Virtual File System lets you express this by + combining the three access methods (i.e. tar, GZIP and FTP) + into a single URI. Access methods are combined in the URI by + using the `#' character, followed by the name for the access + method and the subpath for that specific access method. The + subpath can be omitted for those storage methods that do not + need a path to retrieve the file. (For example, a GZIP file + always contains a single uncompressed file, so no path is + needed to locate the uncompressed file within the GZIP file. + But on the other hand, the TAR method requires a path to + locate a specific file or directory.)

For example, in the case we outlined above, the URI would + look something like:


        ftp://username:password@host.net/path/to/file.tar.gz#gzip#tar/path/to/hello.c

Each method/subpath couple is called a URI + element. When URI elements are combined like this, + each URI element uses the previous one to access a base resource + into which it will look up a file, using the subpath + information. For this reason, we will say that each element is + the parent element for the following one.

The first URI element, the one which has no parent, is + called the toplevel element. It does not + use the `#' character; instead, it uses the standard syntax of + WWW URIs:


        method://user:password@host/path/to/file

This way, normal WWW URIs can be used with the GNOME Virtual + File System.

Toplevel elements are also special because they let users + specify user names, passwords and host names, while + non-toplevel elements don't.


The GnomeVFSURI type

Within the GNOME Virtual File System library, URI elements + are represented by a special type, + GnomeVFSURI, which is meant to represent + user-provided URIs in a machine-optimized way.

Every GnomeVFSURI contains the + following information:

  • A reference counter

  • A pointer to the parent + GnomeVFSURI URI element.

  • The subpath.

  • The name of the access method.

  • A pointer to a + GnomeVFSMethod object, describing the + access method (see below).

GNOME Virtual File System access method implementation

In the GNOME Virtual File System, the implementations for + all the access methods are loaded at runtime, as shared library + modules. The modules are loaded during parsing of the string URI: + if the parser encounters an access method for which no + implementation is currently loaded, it retrieves the corresponding + library file, dynamically links it into the executable, and + initializes it.

After initialization, the module returns a special + GnomeVFSMethod object that contains + pointers to the various implementation functions for that specific + method. By storing a pointer to this object into the + GnomeVFSURI type, the VFS library is then + able to use these functions for file access.

How file access is performed

When the VFS library needs to perform some file operation, + it performs the following steps:

  • If the URI is given in textual form (i.e. as a + string), it parses it and activates the necessary access method + modules.

  • It retrieves a pointer to the lowmost + level URI element.

  • It retrieves a pointer to the + GnomeVFSMethod object that corresponds + to the access method for that URI element.

  • It retrieves a pointer to the implementation + function for that operation from the + GnomeVFSMethodobject.

  • It invokes that implementation function + passing the pointer to the lowmost level URI + element.

Combining the access methods is always done within the + method implementation. If the method implementation needs to do + some file operation on the the parent URI element, it can do so + by simply invoking the corresponding VFS function in, by using + the parent pointer in the GnomeVFSURI + object.

For example, suppose you have to read a simple URI like + the following:


        file:/home/ettore/file.gz#gzip

In this case, the GZIP method will be invoked with a + pointer to the GnomeVFSURI describing the + `gzip' part; then the GZIP method will be able to read + file.gz by just invoking the corresponding + GNOME VFS library function on its parent, and decompress it on + the fly.

Implementing an access method in practice

Implementing a new access method is really not difficult at + all. This section explains how this is done.

Using shared libraries

Every module must be compiled as a shared library (i.e. a + .so file).

The current way for accessing the right module for the + right method is very simple, and is based on file names. In + practice, a module implementing access method named + foo must be named + libfoo.so. For example, the module + implementing the ftp: access method is + called libftp.so, the module implementing + #gzip access is called + libgzip.so and so on.

This might change in the future.


The initialization/shutdown functions

Every shared library module must provide two functions:


GnomeVFSMethod *vfs_module_init (void);
+void vfs_module_shutdown (GnomeVFSMethod *method);

These are the only functions that the VFS library will + access directly. All the other symbols (i.e. functions and + variables) in the module should be made static.

vfs_module_init() is called + as soon as the module is loaded in memory. It will have to + return a pointer to a GnomeVFSMethod + object that will contain the pointers to the method's + implementation functions. We will describe this later.

vfs_module_shutdown, instead, + is called before the module is unloaded or the program that uses + it dies. This functions should:

  • Deallocate all the memory allocated by the + module.

  • Close all the file descriptors associated with + the module.

  • Kill any external process spawned by the + module.

  • In general, make sure that any operation that + was going on before this function was called will be + interrupted correctly, as soon as possible and without any + leaks.


The GnomeVFSMethod object

This object is contains pointers to the module + implementation functions.


GnomeVFSResult (* open)              (GnomeVFSMethodHandle **method_handle_return,
+                                      GnomeVFSURI *uri,
+                                      GnomeVFSOpenMode mode
+                                      GnomeVFSCancellation *cancellation);
+
+GnomeVFSResult (* create)            (GnomeVFSMethodHandle **method_handle_return,
+                                      GnomeVFSURI *uri,
+                                      GnomeVFSOpenMode mode,
+                                      gboolean exclusive,
+                                      guint perm
+                                      GnomeVFSCancellation *cancellation);
+
+GnomeVFSResult (* close)             (GnomeVFSMethodHandle *method_handle
+                                      GnomeVFSCancellation *cancellation);
+
+GnomeVFSResult (* read)              (GnomeVFSMethodHandle *method_handle,
+                                      gpointer buffer,
+                                      GnomeVFSFileSize num_bytes,
+                                      GnomeVFSFileSize *bytes_read_return
+                                      GnomeVFSCancellation *cancellation);
+
+GnomeVFSResult (* write)             (GnomeVFSMethodHandle *method_handle,
+                                      gconstpointer buffer,
+                                      GnomeVFSFileSize num_bytes,
+                                      GnomeVFSFileSize *bytes_written_return
+                                      GnomeVFSCancellation *cancellation);
+
+GnomeVFSResult (* seek)              (GnomeVFSMethodHandle *method_handle,
+                                      GnomeVFSSeekPosition  whence,
+                                      GnomeVFSFileOffset    offset
+                                      GnomeVFSCancellation *cancellation);
+
+GnomeVFSResult (* tell)              (GnomeVFSMethodHandle *method_handle,
+                                      GnomeVFSFileOffset *offset_return);
+
+GnomeVFSResult (* truncate)          (GnomeVFSMethodHandle *method_handle,
+                                      GnomeVFSFileSize where
+                                      GnomeVFSCancellation *cancellation);
+
+GnomeVFSResult (* open_directory)    (GnomeVFSMethodHandle **method_handle,
+                                      GnomeVFSURI *uri,
+                                      GnomeVFSFileInfoOptions options,
+                                      const GList *meta_keys,
+                                      const GnomeVFSDirectoryFilter *filter
+                                      GnomeVFSCancellation *cancellation);
+
+GnomeVFSResult (* close_directory)   (GnomeVFSMethodHandle *method_handle
+                                      GnomeVFSCancellation *cancellation);
+
+GnomeVFSResult (* read_directory)    (GnomeVFSMethodHandle *method_handle,
+                                      GnomeVFSFileInfo *file_info
+                                      GnomeVFSCancellation *cancellation);
+
+GnomeVFSResult (* get_file_info)     (GnomeVFSURI *uri,
+                                      GnomeVFSFileInfo *file_info,
+                                      GnomeVFSFileInfoOptions options,
+                                      const GList *meta_keys
+                                      GnomeVFSCancellation *cancellation);
+
+GnomeVFSResult (* get_file_info_from_handle)
+                                     (GnomeVFSMethodHandle *method_handle,
+                                      GnomeVFSFileInfo *file_info,
+                                      GnomeVFSFileInfoOptions options,
+                                      const GList *meta_keys
+                                      GnomeVFSCancellation *cancellation);
+
+gboolean       (* is_local)          (const GnomeVFSURI *uri
+                                      GnomeVFSCancellation *cancellation);
+
+GnomeVFSResult (* rename)            (GnomeVFSURI *uri, const gchar *new_name
+                                      GnomeVFSCancellation *cancellation);
+
+GnomeVFSResult (* make_directory)    (GnomeVFSURI *uri, guint perm
+                                      GnomeVFSCancellation *cancellation);
+
+GnomeVFSResult (* remove_directory)  (GnomeVFSURI *uri
+                                      GnomeVFSCancellation *cancellation);
+
+GnomeVFSResult (* unlink)            (GnomeVFSURI *uri
+                                      GnomeVFSCancellation *cancellation);

Handling cancellation

As VFS operations might be very long, especially in the case + of transient errors (such as a network server that has gone down), + the GNOME Virtual File System Library provides a standard way for + handling cancellation of VFS operations.

The GnomeVFSCancellation object

The object that encapsulates this functionality is + GnomeVFSCancellation. Most + implementation functions get a pointer to such an object, and are + expected to use this object to recognize when an operation should + be interrupted.

The most simple way to check for a cancellation request is + to poll the object with + gnome_vfs_cancellation_check():

  
+gboolean gnome_vfs_cancellation_check (GnomeVFSCancellation *cancellation);

This function will return a nonzero value if the current + operation should be cancelled.

Notice that cancellation is an asynchronous operation that + might happen outside your function, in parallel with the code that + you are writing. For example, in the case of threads, the request + will be set in the master thread; in the case of slave + CORBA-driven processes, the request will be activated by a Unix + signal. So you can expect a cancellation request to happen (and + consequently be signalled in + GnomeVFSCancellation) at any time.

For this reason, you should be calling this function + periodically, whenever you are going to perform several + iterations of the same task, or execute a single expensive task. + When the function returns a nonzero value, the correct way to + react is:

  1. Clean things up so that the result of the + operations that have been performed are all + cancelled.

  2. >Return the + GNOME_VFS_ERROR_CANCELLED error + code.

But there are some other situations in which you want to + be able to interrupt a I/O operation when a cancellation request + is performed. In such cases, polling is not a viable option.

For this reason, + GnomeVFSCancellation provides an + alternative way of sending notifications, using a file + descriptor. To use this feature, you should use the following + function:


gint gnome_vfs_cancellation_get_fd (GnomeVFSCancellation *cancellation); 

When this function is called, it will return an open file + descriptor, which is the read-side of a pipe. The pipe will be + given a character from the write side as soon as a cancellation + request is sent. For this reason, you can check for a + cancellation by using the select() system + call: as soon as select reports that some + data is available on the file descriptor, you know that a + cancellation is being requested.

For example, if you are reading from a file descriptor and + you want to check for a pending cancellation at the same time, + you can set up selectfor checking if data + is available on both the cancellation file descriptor and the + file descriptor you are reading from.


Dealing with EINTR

In order to maximize the chance of cancelling an operation + immediately, the GNOME Virtual File System can sends a signal to + the asynchronous thread or process. This does not happen on all + the systems and setups, though.

The result of this is that, if a process is in the middle + of a Unix system call while receiving this signal, the system + call might be interrupted and return a EINTR + error.

For this reason, when you receive EINTR + you should check if a cancellation request is pending, using + gnome_vfs_cancellation_check() on the + GnomeVFSCancellation object that the + implementation function received:

  • If a cancellation is indeed pending + (gnome_vfs_cancellation_check() returns a + nonzero value), you should cancel the operation, cleaning up + all the effects, and return + GNOME_VFS_ERROR_INTERRUPTED or + GNOME_VFS_ERROR_CANCELLED

  • Otherwise, retry the system call as you would + normally do.

Basic guidelines for writing a module

Writing GNOME VFS modules is easy, but there are a few + things that you must keep in mind when hacking them:

  • All of the code must be completely thread safe. + The reason for this is that the asynchronous GNOME VFS engine + will use threads when available; if you don't make sure that the + code is thread-safe, every kind of weird and unexpected errors + will happen. As debugging these problems can be very hard, it's + important to write the code with threads in mind right from the + start.

  • Use the special + gnome_vfs_*_cancellable() VFS functions + instead of the standard non-cancellable ones, passing them the + same GnomeVFSCancellation object you + are given, so that the operation can always be interrrupted at + any time.

  • The code should respect the basic GNOME + guidelines for source code indentation and + style.

How to make the code thread safe

Although it might sound scary at first, making the code + for the modules thread safe is not complicated at all.

First of all, make sure the amount of global variables is + kept to the bare minimum. If possible, you should avoid them at + all cost.

For those cases where globals are inevitable (such as + caches, connection pools or things like that), you have to make + sure every variable is properly associated with a mutex, and + that the mutex is locked before every access to this variable + and released afterwards. You can also use + G_LOCK_DEFINE_STATIC, + G_LOCK and G_UNLOCK + for this. +

Generally speaking, if you are going to dynamically + allocate structures that are shared by more than one + operation/file, you should provide all of them with their nice + mutex locks.

Finally, make sure mutexes are used only if they are + available. One way to do so is to use macros like the + following:


#ifdef G_THREADS_ENABLED
+#define MUTEX_NEW()     g_mutex_new ()
+#define MUTEX_FREE(a)   g_mutex_free (a)
+#define MUTEX_LOCK(a)   if ((a) != NULL) g_mutex_lock (a)
+#define MUTEX_UNLOCK(a) if ((a) != NULL) g_mutex_unlock (a)
+#else
+#define MUTEX_NEW()     NULL
+#define MUTEX_FREE(a)
+#define MUTEX_LOCK(a)
+#define MUTEX_UNLOCK(a)
+#endif

G_LOCK_DEFINE_STATIC, + G_LOCK and G_UNLOCK in + GLib are always safe to use, as they are already defined to be + nothing when thread support is not available.

(Probably it would be a good idea to have something in the + private GNOME VFS API that does this stuff for all the + modules.)

<<< Filesystem ModulesMIME typing >>>
\ No newline at end of file diff --git a/doc/html/x27.html b/doc/html/x27.html new file mode 100644 index 0000000..09b29f6 --- /dev/null +++ b/doc/html/x27.html @@ -0,0 +1,474 @@ +A Gentle Programming Primer
GnomeVFS - Filesystem Abstraction library
<<< Previous PageHomeUpNext Page >>>

A Gentle Programming Primer

Using GnomeVFS in an existing application, or writing a new application + with it, is actually very simple since GnomeVFS tries to mimic POSIX + file access syntax and semantics. That means that most "standard unix calls" + have a GnomeVFS equivalent that operates in a fairly similar manner. There are + a few differences to keep in mind. + +

  • The most obvious is probably that all I/O operations return a GnomeVFSResult + indicating the success or failure of the operation. More on this later. +

  • The types may be slightly different (but still parallel), for example rather than using an + int for a file-descriptor, GnomeVFS uses GnomeVFSHandle, a handle + to a particular URI. +

  • Most operations come in Handle (think file descriptor) and URI form. The URI form may be + more convenient if you do not want to track handles, etc, but just be aware that both are + at your disposal and may be used interchangably. For example gnome_vfs_open + and gnome_vfs_open_uri. +

+

By way of example, consider the basic read command: +
	ssize_t read (int fd, void *buf, size_t count);
+      
+

The GnomeVFS equivalent is very similar, but you will notice slightly different data types. The + consistent returning of a GnomeVFSResult also necessitated moving the return value of read into + a pass-back-value pointer bytes_read: +
	GnomeVFSResult gnome_vfs_read (GnomeVFSHandle *handle,
+	                               gpointer buffer,
+                                       GnomeVFSFileSize bytes,
+                                       GnomeVFSFileSize *bytes_read);
+      
+

So gnome_vfs_read takes a GnomeVFSHandle, which functions + like a file descriptor, and attempts to read bytes bytes out of + handle into buffer. The number of bytes succesfully + read into buffer is returned in the pointer bytes_read. + The return value of the function, a GnomeVFSResult indicates the success of the + operation or any errors that might have occurred (for example, permission denied). + GnomeVFSResult is just an enumeration. +


Simple Sample Program

Now lets write a simple program to copy a fixed number of bytes from one file and append + it to another file. +

#include <libgnomevfs/gnome-vfs.h>
+#include <gnome.h>
+
+#define BYTES_TO_PROCESS 256
+
+int print_error (GnomeVFSResult result, const char *uri_string);
+
+int
+main (int argc, char **argv)
+{
+  GnomeVFSHandle *read_handle, *write_handle;
+  const char *input_uri_string = argv[1];
+  const char *output_uri_string = argv[2];
+  GnomeVFSFileSize bytes_read, bytes_written;
+  gpointer buffer;
+  GnomeVFSResult result;
+
+  /* remember to initialize GnomeVFS! */
+  if (!gnome_vfs_init ()) {
+    printf ("Could not initialize GnomeVFS\n");
+    return 1;
+  }
+
+  /* open the input file for read access */
+  result = gnome_vfs_open (&read_handle, input_uri_string, GNOME_VFS_OPEN_READ);
+  /* if the operation was not successful, print the error and abort */
+  if (result != GNOME_VFS_OK) return print_error (result, input_uri_string);
+
+  /* we use create instead of open, because open will not create the file if it does
+     not already exist. The last argument is the permissions to use if the file is created,
+     the second to last tells GnomeVFS that its ok if the file already exists, and just open it */
+  result = gnome_vfs_create (&write_handle, output_uri_string, GNOME_VFS_OPEN_WRITE, FALSE, 0x777);
+  if (result != GNOME_VFS_OK) return print_error (result, output_uri_string);
+
+  /* read data from the input uri */
+  result = gnome_vfs_read (read_handle, buffer, BYTES_TO_PROCESS, &bytes_read);
+  if (result != GNOME_VFS_OK) return print_error (result, input_uri_string);
+
+  /* seek to the end of the output uri so we will append rather than overwrite */
+  /* therefore, we seek 0 bytes relative to the end of the file */
+  result = gnome_vfs_seek (write_handle, GNOME_VFS_SEEK_END, 0);
+
+  /* now write the data we read out to the output uri */
+  result = gnome_vfs_write (write_handle, buffer, bytes_read, &bytes_written);
+  if (result != GNOME_VFS_OK) return print_error (result, output_uri_string);
+
+  return 0;
+}
+
+int
+print_error (GnomeVFSResult result, const char *uri_string)
+{
+  const char *error_string;
+  /* get the string corresponding to this GnomeVFSResult value */
+  error_string = gnome_vfs_result_to_string (result);
+  printf ("Error %s occured opening location %s\n", error_string, uri_string);
+  return 1;
+}
+
+	




<<< Previous PageHomeUpNext Page >>>
Introduction to GnomeVFSBasic File Operations
\ No newline at end of file diff --git a/doc/tmpl/gnome-vfs-2.0-unused.sgml b/doc/tmpl/gnome-vfs-2.0-unused.sgml new file mode 100644 index 0000000..3c15ff4 --- /dev/null +++ b/doc/tmpl/gnome-vfs-2.0-unused.sgml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + +Reading the contents of directories + + + + +Directory Operations + + + + + + + + + + + + + + + + +utilities for locating standard directories such as the desktop and trash + + + + +Locating Standard Directories + + + + + + + + + + + + + + + + +attach extra pieces of information to files, such as icons or positions + + + + +Metadata + + + + + + + +@obj: + + + + + + + + + + + + +@self: +@key: +@Returns: + + + + + + +@uri: +@Returns: + + + + + + +@self: +@key: +@value: + + + + + + +@self: +@key: +@value: + diff --git a/doc/tmpl/gnome-vfs-application-registry.sgml b/doc/tmpl/gnome-vfs-application-registry.sgml new file mode 100644 index 0000000..5bda1db --- /dev/null +++ b/doc/tmpl/gnome-vfs-application-registry.sgml @@ -0,0 +1,233 @@ + +Application Registry + + + +stores supported MIME types and URIs of various applications + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@app_id: +@Returns: + + + + + + + +@app_id: +@Returns: + + + + + + + +@app_id: +@key: +@Returns: + + + + + + + +@app_id: +@key: +@got_key: +@Returns: + + + + + + + +@app_id: + + + + + + + +@app_id: +@key: +@value: + + + + + + + +@app_id: +@key: +@value: + + + + + + + +@app_id: +@key: + + + + + + + +@mime_type: +@Returns: + + + + + + + +@app_id: +@Returns: + + + + + + + +@app_id: +@mime_type: +@Returns: + + + + + + + +@app_id: +@uri_scheme: +@Returns: + + + + + + + +@application: +@Returns: + + + + + + + +@app_id: + + + + + + + +@app_id: +@mime_type: + + + + + + + +@app_id: +@mime_type: + + + + + + + +@Returns: + + + + + + + + + + + + + + + + + + + + + +@app_id: +@Returns: + + + + + + + +@application: + + diff --git a/doc/tmpl/gnome-vfs-async-ops.sgml b/doc/tmpl/gnome-vfs-async-ops.sgml new file mode 100644 index 0000000..bc96794 --- /dev/null +++ b/doc/tmpl/gnome-vfs-async-ops.sgml @@ -0,0 +1,411 @@ + +Asynchronous File Operations + + + +POSIX-style file operations that run outside your main loop + + + + When executing an asynchornous operation on a file the program does not + block waiting for the operation to finish, instead it keeps on running, + which means that the process and the I/O operation can be both running + concurrently. Once the I/O operation has been completed the process is + notified using a callback. + + + + Asynchronous operations are particularly good when long I/O operations + are expected, in this case the program can continue normaly, the I/O + will be performed in the background. On the other hand when operations + are expected to be short (creating a file, writing/reading small amounts + of data, etc.) synchronous operations are prefered. + + + + Within a graphical desktop asynchornous I/O operations can be used to + avoid blocking the UI (User Interface) during a long operation, and + to be able to provide some kind of feedback to the user. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@handle: +@result: +@callback_data: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@handle: +@result: +@buffer: +@bytes_requested: +@bytes_read: +@callback_data: + + + + + + + +@handle: +@result: +@buffer: +@bytes_requested: +@bytes_written: +@callback_data: + + + + + + + + + + + + + +@limit: + + + + + + + +@Returns: + + + + + + + +@handle: + + + + + + + +@handle_return: +@text_uri: +@open_mode: +@priority: +@callback: +@callback_data: + + + + + + + +@handle_return: +@uri: +@open_mode: +@priority: +@callback: +@callback_data: + + + + + + + +@handle_return: +@text_uri: +@open_mode: +@advised_block_size: +@priority: +@callback: +@callback_data: + + + + + + + +@handle_return: +@uri: +@open_mode: +@advised_block_size: +@priority: +@callback: +@callback_data: + + + + + + + +@handle_return: +@text_uri: +@open_mode: +@exclusive: +@perm: +@priority: +@callback: +@callback_data: + + + + + + + +@handle_return: +@uri: +@open_mode: +@exclusive: +@perm: +@priority: +@callback: +@callback_data: + + + + + + + +@handle_return: +@uri: +@uri_reference: +@priority: +@callback: +@callback_data: + + + + + + + +@handle_return: +@text_uri: +@open_mode: +@exclusive: +@perm: +@priority: +@callback: +@callback_data: + + + + + + + +@handle_return: +@uri: +@open_mode: +@exclusive: +@perm: +@priority: +@callback: +@callback_data: + + + + + + + +@handle: +@callback: +@callback_data: + + + + + + + +@handle: +@buffer: +@bytes: +@callback: +@callback_data: + + + + + + + +@handle: +@buffer: +@bytes: +@callback: +@callback_data: + + + + + + + +@handle_return: +@uri_list: +@options: +@priority: +@callback: +@callback_data: + + + + + + + +@handle_return: +@uri: +@info: +@mask: +@options: +@priority: +@callback: +@callback_data: + + + + + + + +@handle_return: +@text_uri: +@options: +@items_per_notification: +@priority: +@callback: +@callback_data: + + + + + + + +@handle_return: +@uri: +@options: +@items_per_notification: +@priority: +@callback: +@callback_data: + + + + + + + +@handle_return: +@source_uri_list: +@target_uri_list: +@xfer_options: +@error_mode: +@overwrite_mode: +@priority: +@progress_update_callback: +@update_callback_data: +@progress_sync_callback: +@sync_callback_data: +@Returns: + + + + + + + +@handle_return: +@near_uri_list: +@kind: +@create_if_needed: +@find_if_needed: +@permissions: +@priority: +@callback: +@user_data: + + + + + + + +@handle: +@operation: +@operation_data: +@operation_data_destroy_func: +@callback: +@callback_data: + + diff --git a/doc/tmpl/gnome-vfs-cancellation.sgml b/doc/tmpl/gnome-vfs-cancellation.sgml new file mode 100644 index 0000000..ade4072 --- /dev/null +++ b/doc/tmpl/gnome-vfs-cancellation.sgml @@ -0,0 +1,67 @@ + +Cancellation + + + +halt in-progress operations + + + + + + + + + + + + + + + + +@Returns: + + + + + + + +@cancellation: + + + + + + + +@cancellation: + + + + + + + +@cancellation: +@Returns: + + + + + + + +@cancellation: + + + + + + + +@cancellation: +@Returns: + + diff --git a/doc/tmpl/gnome-vfs-context.sgml b/doc/tmpl/gnome-vfs-context.sgml new file mode 100644 index 0000000..27688f7 --- /dev/null +++ b/doc/tmpl/gnome-vfs-context.sgml @@ -0,0 +1,66 @@ + +GnomeVFSContext + + + +contexts allows modules to track thread usage and cancellation properly + + + + + + + + + + + + + + + + +@Returns: + + + + + + + +@ctx: + + + + + + + +@ctx: +@Returns: + + + + + + + +@x: + + + + + + + +@Returns: + + + + + + + +@Returns: + + diff --git a/doc/tmpl/gnome-vfs-directory-basic-ops.sgml b/doc/tmpl/gnome-vfs-directory-basic-ops.sgml new file mode 100644 index 0000000..0cf1530 --- /dev/null +++ b/doc/tmpl/gnome-vfs-directory-basic-ops.sgml @@ -0,0 +1,55 @@ + +Basic Directory Operations + + + +Creating and removing directories. + + + + + + + + + + + + + + + + +@text_uri: +@perm: +@Returns: + + + + + + + +@uri: +@perm: +@Returns: + + + + + + + +@text_uri: +@Returns: + + + + + + + +@uri: +@Returns: + + diff --git a/doc/tmpl/gnome-vfs-directory-find-ops.sgml b/doc/tmpl/gnome-vfs-directory-find-ops.sgml new file mode 100644 index 0000000..0de3be3 --- /dev/null +++ b/doc/tmpl/gnome-vfs-directory-find-ops.sgml @@ -0,0 +1,39 @@ + +Locating Standard Directories + + + +Utilities for locating standard directories such as the desktop and trash + + + + + + + + + + + + + + + + +@GNOME_VFS_DIRECTORY_KIND_DESKTOP: +@GNOME_VFS_DIRECTORY_KIND_TRASH: + + + + + + +@near_uri: +@kind: +@result: +@create_if_needed: +@find_if_needed: +@permissions: +@Returns: + + diff --git a/doc/tmpl/gnome-vfs-directory-list-ops.sgml b/doc/tmpl/gnome-vfs-directory-list-ops.sgml new file mode 100644 index 0000000..4a427d3 --- /dev/null +++ b/doc/tmpl/gnome-vfs-directory-list-ops.sgml @@ -0,0 +1,147 @@ + +Listing Directory Contents + + + +Listing the contents of directories. + + + + + + + + + + + + + + + + +@GNOME_VFS_DIRECTORY_VISIT_DEFAULT: +@GNOME_VFS_DIRECTORY_VISIT_SAMEFS: +@GNOME_VFS_DIRECTORY_VISIT_LOOPCHECK: + + + + + + +@rel_path: +@info: +@recursing_will_loop: +@data: +@recurse: +@Returns: + + + + + + + +@handle: +@text_uri: +@options: +@Returns: + + + + + + + +@handle: +@uri: +@options: +@Returns: + + + + + + + +@handle: +@file_info: +@Returns: + + + + + + + +@handle: +@Returns: + + + + + + + +@uri: +@info_options: +@visit_options: +@callback: +@data: +@Returns: + + + + + + + +@uri: +@info_options: +@visit_options: +@callback: +@data: +@Returns: + + + + + + + +@text_uri: +@file_list: +@info_options: +@visit_options: +@callback: +@data: +@Returns: + +@Param4: + + + + + + + +@uri: +@file_list: +@info_options: +@visit_options: +@callback: +@data: +@Returns: + + + + + + + +@list: +@text_uri: +@options: +@Returns: + + diff --git a/doc/tmpl/gnome-vfs-directory.sgml b/doc/tmpl/gnome-vfs-directory.sgml new file mode 100644 index 0000000..7c9092e --- /dev/null +++ b/doc/tmpl/gnome-vfs-directory.sgml @@ -0,0 +1,185 @@ + +Directory Operations + + + +Reading the contents of directories + + + + + + + + + + + + + + + + +@GNOME_VFS_DIRECTORY_VISIT_DEFAULT: +@GNOME_VFS_DIRECTORY_VISIT_SAMEFS: +@GNOME_VFS_DIRECTORY_VISIT_LOOPCHECK: + + + + + + +@rel_path: +@info: +@recursing_will_loop: +@data: +@recurse: +@Returns: + + + + + + + +@handle: +@text_uri: +@options: +@Returns: + + + + + + + +@handle: +@uri: +@options: +@Returns: + + + + + + + +@handle: +@file_info: +@Returns: + + + + + + + +@handle: +@Returns: + + + + + + + +@uri: +@info_options: +@visit_options: +@callback: +@data: +@Returns: + + + + + + + +@uri: +@info_options: +@visit_options: +@callback: +@data: +@Returns: + + + + + + + +@text_uri: +@file_list: +@info_options: +@visit_options: +@callback: +@data: +@Returns: + +@Param4: + + + + + + + +@uri: +@file_list: +@info_options: +@visit_options: +@callback: +@data: +@Returns: + + + + + + + +@list: +@text_uri: +@options: +@Returns: + + + + + + + +@uri: +@perm: +@Returns: + + + + + + + +@text_uri: +@perm: +@Returns: + + + + + + + +@uri: +@Returns: + + + + + + + +@text_uri: +@Returns: + + diff --git a/doc/tmpl/gnome-vfs-file-advanced-ops.sgml b/doc/tmpl/gnome-vfs-file-advanced-ops.sgml new file mode 100644 index 0000000..885350f --- /dev/null +++ b/doc/tmpl/gnome-vfs-file-advanced-ops.sgml @@ -0,0 +1,27 @@ + +Advanced File Operations + + + + + + + + + + + + + + + + + + + +@handle: +@operation: +@operation_data: +@Returns: + + diff --git a/doc/tmpl/gnome-vfs-file-basic-ops.sgml b/doc/tmpl/gnome-vfs-file-basic-ops.sgml new file mode 100644 index 0000000..b988f19 --- /dev/null +++ b/doc/tmpl/gnome-vfs-file-basic-ops.sgml @@ -0,0 +1,164 @@ + +Basic File Operations + + + + + + + + + + + + + + + + + + + +@GNOME_VFS_OPEN_NONE: +@GNOME_VFS_OPEN_READ: +@GNOME_VFS_OPEN_WRITE: +@GNOME_VFS_OPEN_RANDOM: + + + + + + +@handle: +@text_uri: +@open_mode: +@exclusive: +@perm: +@Returns: + + + + + + + +@handle: +@uri: +@open_mode: +@exclusive: +@perm: +@Returns: + + + + + + + +@handle: +@text_uri: +@open_mode: +@Returns: + + + + + + + +@handle: +@uri: +@open_mode: +@Returns: + + + + + + + +@handle: +@Returns: + + + + + + + +@text_uri: +@Returns: + + + + + + + +@uri: +@Returns: + + + + + + + +@old_uri: +@new_uri: +@force_replace: +@Returns: + + + + + + + +@old_text_uri: +@new_text_uri: +@force_replace: +@Returns: + + + + + + + +@source_uri: +@target_uri: +@same_fs_return: +@Returns: + + + + + + + +@source: +@target: +@same_fs_return: +@Returns: + + + + + + + +@uri: +@Returns: + + + + + + + +@uri: +@target_reference: +@Returns: + + diff --git a/doc/tmpl/gnome-vfs-file-info-ops.sgml b/doc/tmpl/gnome-vfs-file-info-ops.sgml new file mode 100644 index 0000000..e2ce02a --- /dev/null +++ b/doc/tmpl/gnome-vfs-file-info-ops.sgml @@ -0,0 +1,86 @@ + +Getting and Setting File Information + + + + + + + Applications can use the #gnome_vfs_get_file_info family of operations to + retrieve file information, as this operation can be quite costly in + terms of time (specilly when sniffing the MIME type) applications can + specify which information need at any time, reducing the performance + impact. + + + All of these operations use a #GnomeVFSFileInfo data structure that holds + the file information, there are several methods that can be used to + manipulate this information. See #GnomeVFSFileInfo for more information. + + + + + + + +#GnomeVFSFileInfo + + + + + + + + + + +@text_uri: +@info: +@options: +@Returns: + + + + + + + +@uri: +@info: +@options: +@Returns: + + + + + + + +@handle: +@info: +@options: +@Returns: + + + + + + + +@uri: +@info: +@mask: +@Returns: + + + + + + + +@text_uri: +@info: +@mask: +@Returns: + + diff --git a/doc/tmpl/gnome-vfs-file-info.sgml b/doc/tmpl/gnome-vfs-file-info.sgml new file mode 100644 index 0000000..c533cf7 --- /dev/null +++ b/doc/tmpl/gnome-vfs-file-info.sgml @@ -0,0 +1,316 @@ + +GnomeVFSFileInfo + + + +stores information about files, GnomeVFS equivalent of stat + + + + + + + + + + + + + + + + +@GNOME_VFS_FILE_FLAGS_NONE: +@GNOME_VFS_FILE_FLAGS_SYMLINK: +@GNOME_VFS_FILE_FLAGS_LOCAL: + + + + + + +@GNOME_VFS_FILE_TYPE_UNKNOWN: +@GNOME_VFS_FILE_TYPE_REGULAR: +@GNOME_VFS_FILE_TYPE_DIRECTORY: +@GNOME_VFS_FILE_TYPE_FIFO: +@GNOME_VFS_FILE_TYPE_SOCKET: +@GNOME_VFS_FILE_TYPE_CHARACTER_DEVICE: +@GNOME_VFS_FILE_TYPE_BLOCK_DEVICE: +@GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK: + + + + + + +@GNOME_VFS_FILE_INFO_FIELDS_NONE: +@GNOME_VFS_FILE_INFO_FIELDS_TYPE: +@GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS: +@GNOME_VFS_FILE_INFO_FIELDS_FLAGS: +@GNOME_VFS_FILE_INFO_FIELDS_DEVICE: +@GNOME_VFS_FILE_INFO_FIELDS_INODE: +@GNOME_VFS_FILE_INFO_FIELDS_LINK_COUNT: +@GNOME_VFS_FILE_INFO_FIELDS_SIZE: +@GNOME_VFS_FILE_INFO_FIELDS_BLOCK_COUNT: +@GNOME_VFS_FILE_INFO_FIELDS_IO_BLOCK_SIZE: +@GNOME_VFS_FILE_INFO_FIELDS_ATIME: +@GNOME_VFS_FILE_INFO_FIELDS_MTIME: +@GNOME_VFS_FILE_INFO_FIELDS_CTIME: +@GNOME_VFS_FILE_INFO_FIELDS_SYMLINK_NAME: +@GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE: +@GNOME_VFS_FILE_INFO_FIELDS_ACCESS: + + + + + + +@GNOME_VFS_PERM_SUID: +@GNOME_VFS_PERM_SGID: +@GNOME_VFS_PERM_STICKY: +@GNOME_VFS_PERM_USER_READ: +@GNOME_VFS_PERM_USER_WRITE: +@GNOME_VFS_PERM_USER_EXEC: +@GNOME_VFS_PERM_USER_ALL: +@GNOME_VFS_PERM_GROUP_READ: +@GNOME_VFS_PERM_GROUP_WRITE: +@GNOME_VFS_PERM_GROUP_EXEC: +@GNOME_VFS_PERM_GROUP_ALL: +@GNOME_VFS_PERM_OTHER_READ: +@GNOME_VFS_PERM_OTHER_WRITE: +@GNOME_VFS_PERM_OTHER_EXEC: +@GNOME_VFS_PERM_OTHER_ALL: +@GNOME_VFS_PERM_ACCESS_READABLE: +@GNOME_VFS_PERM_ACCESS_WRITABLE: +@GNOME_VFS_PERM_ACCESS_EXECUTABLE: + + + + + + +@GNOME_VFS_FILE_INFO_DEFAULT: +@GNOME_VFS_FILE_INFO_GET_MIME_TYPE: +@GNOME_VFS_FILE_INFO_FORCE_FAST_MIME_TYPE: +@GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE: +@GNOME_VFS_FILE_INFO_FOLLOW_LINKS: +@GNOME_VFS_FILE_INFO_GET_ACCESS_RIGHTS: + + + + + + +@GNOME_VFS_SET_FILE_INFO_NONE: +@GNOME_VFS_SET_FILE_INFO_NAME: +@GNOME_VFS_SET_FILE_INFO_PERMISSIONS: +@GNOME_VFS_SET_FILE_INFO_OWNER: +@GNOME_VFS_SET_FILE_INFO_TIME: + + + + + + + + + + + + + + + + + + + + + + + + +@info: + + + + + + + +@info: +@value: + + + + + + + +@info: + + + + + + + +@info: +@value: + + + + + + + +@info: + + + + + + + +@info: + + + + + + + +@info: + + + + + + + +@info: +@value: + + + + + + + +@info: +@value: + + + + + + + +@info: +@value: + + + + + + + +@Returns: + + + + + + + +@info: + + + + + + + +@info: + + + + + + + +@info: + + + + + + + +@info: +@Returns: + + + + + + + +@dest: +@src: + + + + + + + +@orig: +@Returns: + + + + + + + +@a: +@b: +@Returns: + + + + + + + +@list: +@Returns: + + + + + + + +@list: +@Returns: + + + + + + + +@list: +@Returns: + + + + + + + +@list: + + diff --git a/doc/tmpl/gnome-vfs-file-rw-ops.sgml b/doc/tmpl/gnome-vfs-file-rw-ops.sgml new file mode 100644 index 0000000..ea77a3c --- /dev/null +++ b/doc/tmpl/gnome-vfs-file-rw-ops.sgml @@ -0,0 +1,71 @@ + +Reading and Writing + + + + + + + Reading and writing operations are explained, also @gnome_vfs_seek, which + is used to move the file pointer inside the file. + + + + + + + + + + + + +@GNOME_VFS_SEEK_START: +@GNOME_VFS_SEEK_CURRENT: +@GNOME_VFS_SEEK_END: + + + + + + +@handle: +@buffer: +@bytes: +@bytes_read: +@Returns: + + + + + + + +@handle: +@buffer: +@bytes: +@bytes_written: +@Returns: + + + + + + + +@handle: +@whence: +@offset: +@Returns: + + + + + + + +@handle: +@offset_return: +@Returns: + + diff --git a/doc/tmpl/gnome-vfs-file-size.sgml b/doc/tmpl/gnome-vfs-file-size.sgml new file mode 100644 index 0000000..9402439 --- /dev/null +++ b/doc/tmpl/gnome-vfs-file-size.sgml @@ -0,0 +1,49 @@ + +GnomeVFSFileSize + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/tmpl/gnome-vfs-file-trunc-ops.sgml b/doc/tmpl/gnome-vfs-file-trunc-ops.sgml new file mode 100644 index 0000000..ee660c9 --- /dev/null +++ b/doc/tmpl/gnome-vfs-file-trunc-ops.sgml @@ -0,0 +1,46 @@ + +Truncating Files + + + + + + + + + + + + + + + + + + + +@text_uri: +@length: +@Returns: + + + + + + + +@uri: +@length: +@Returns: + + + + + + + +@handle: +@length: +@Returns: + + diff --git a/doc/tmpl/gnome-vfs-find-directory.sgml b/doc/tmpl/gnome-vfs-find-directory.sgml new file mode 100644 index 0000000..b0c6500 --- /dev/null +++ b/doc/tmpl/gnome-vfs-find-directory.sgml @@ -0,0 +1,39 @@ + +Locating Standard Directories + + + +utilities for locating standard directories such as the desktop and trash + + + + + + + + + + + + + + + + +@GNOME_VFS_DIRECTORY_KIND_DESKTOP: +@GNOME_VFS_DIRECTORY_KIND_TRASH: + + + + + + +@near_uri: +@kind: +@result: +@create_if_needed: +@find_if_needed: +@permissions: +@Returns: + + diff --git a/doc/tmpl/gnome-vfs-inet-connection.sgml b/doc/tmpl/gnome-vfs-inet-connection.sgml new file mode 100644 index 0000000..2c24142 --- /dev/null +++ b/doc/tmpl/gnome-vfs-inet-connection.sgml @@ -0,0 +1,73 @@ + +gnome-vfs-inet-connection + + + + + + + + + + + + + + + + + + + +@connection_return: +@host_name: +@host_port: +@cancellation: +@Returns: + + + + + + + +@connection: +@cancellation: + + + + + + + +@connection: +@cancellation: + + + + + + + +@connection: +@Returns: + + + + + + + +@connection: +@Returns: + + + + + + + +@connection: +@Returns: + + diff --git a/doc/tmpl/gnome-vfs-init.sgml b/doc/tmpl/gnome-vfs-init.sgml new file mode 100644 index 0000000..aae35d7 --- /dev/null +++ b/doc/tmpl/gnome-vfs-init.sgml @@ -0,0 +1,68 @@ + +Initialization/Shutdown + + + + + + +Starting GnomeVFS up and shutting it down. Usually when using the whole +GNOME framework this library is initialized and shutdown automatically +when calling gnome_init. + + + + + + + + + + + + +@Returns: + + + + + + + +@Returns: + + + + + + + + + + + + + + +@app: +@modinfo: + + + + + + + +@app: +@modinfo: + + + + + + + +@app: +@modinfo: + + diff --git a/doc/tmpl/gnome-vfs-metadata.sgml b/doc/tmpl/gnome-vfs-metadata.sgml new file mode 100644 index 0000000..5ef48bf --- /dev/null +++ b/doc/tmpl/gnome-vfs-metadata.sgml @@ -0,0 +1,70 @@ + +Metadata + + + +attach extra pieces of information to files, such as icons or positions + + + + + + + + + + + + + + + + +@obj: + + + + + + + + + + + + + +@self: +@key: +@value: + + + + + + + +@self: +@key: +@Returns: + + + + + + + +@self: +@key: +@value: + + + + + + + +@uri: +@Returns: + + diff --git a/doc/tmpl/gnome-vfs-method.sgml b/doc/tmpl/gnome-vfs-method.sgml new file mode 100644 index 0000000..e1c38c8 --- /dev/null +++ b/doc/tmpl/gnome-vfs-method.sgml @@ -0,0 +1,93 @@ + +gnome-vfs-method + + + + + + + + + + + + + + + + + + + +@method_name: +@config_args: +@Returns: + + + + + + + +@method: + + + + + + + +@method: +@uri: +@length: +@context: +@Returns: + + + + + + + +@method: +@handle: +@length: +@context: +@Returns: + + + + + + + +@method: +@func: + + + + + + + +@Returns: + + + + + + + +@name: +@Returns: + + + + + + + +@name: +@Returns: + + diff --git a/doc/tmpl/gnome-vfs-mime-database.sgml b/doc/tmpl/gnome-vfs-mime-database.sgml new file mode 100644 index 0000000..d24d89c --- /dev/null +++ b/doc/tmpl/gnome-vfs-mime-database.sgml @@ -0,0 +1,591 @@ + +File Types + + + +functions for getting information about files based on their MIME type + + + + + + + + + + + + + + + + + + + + + + + +@data: +@data_size: +@Returns: + + + + + + + +@text_uri: +@Returns: + + + + + + + +@GNOME_VFS_MIME_ACTION_TYPE_NONE: +@GNOME_VFS_MIME_ACTION_TYPE_APPLICATION: +@GNOME_VFS_MIME_ACTION_TYPE_COMPONENT: + + + + + + +@GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_URIS: +@GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_PATHS: +@GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_URIS_FOR_NON_FILES: + + + + + + + + + + + + +@application: +@Returns: + + + + + + + +@mime_type: +@Returns: + + + + + + + +@mime_type: +@Returns: + + + + + + + +@mime_type: +@Returns: + + + + + + + +@mime_type: +@Returns: + + + + + + + +@mime_type: +@Returns: + + + + + + + +@mime_type: +@Returns: + + + + + + + +@mime_type: +@Returns: + + + + + + + +@mime_type: +@Returns: + + + + + + + +@mime_type: +@action_type: +@Returns: + + + + + + + +@mime_type: +@application_id: +@Returns: + + + + + + + +@mime_type: +@component_iid: +@Returns: + + + + + + + +@mime_type: +@Returns: + + + + + + + +@mime_type: +@filename: +@Returns: + + + + + + + +@mime_type: +@Returns: + + + + + + + +@mime_type: +@description: +@Returns: + + + + + + + +@mime_type: +@Returns: + + + + + + + +@mime_type: +@new_value: +@Returns: + + + + + + + +@mime_type: +@application_ids: +@Returns: + + + + + + + +@mime_type: +@component_iids: +@Returns: + + + + + + + +@mime_type: +@application_id: +@Returns: + + + + + + + +@mime_type: +@application_id: +@Returns: + + + + + + + +@mime_type: +@iid: +@Returns: + + + + + + + +@mime_type: +@iid: +@Returns: + + + + + + + +@mime_type: +@extension: +@Returns: + + + + + + + +@mime_type: +@extension: +@Returns: + + + + + + + +@mime_type: +@application_ids: +@Returns: + + + + + + + +@mime_type: +@application_ids: +@Returns: + + + + + + + +@id: +@Returns: + + + + + + + +@application: + + + + + + + +@action: + + + + + + + +@list: + + + + + + + +@list: + + + + + + + +@id: +@applications: +@Returns: + + + + + + + +@iid: +@components: +@Returns: + + + + + + + +@applications: +@application_id: +@did_remove: +@Returns: + + + + + + + +@components: +@iid: +@did_remove: +@Returns: + + + + + + + +@components: +@Returns: + + + + + + + +@applications: +@Returns: + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@mime_type: +@Returns: + + + + + + + +@mime_type: +@key: +@Returns: + + + + + + + +@mime_type: +@key: +@value: +@Returns: + + + + + + + +@mime_type: +@Returns: + + + + + + + +@mime_type_list: + + + + + + + +@mime_type: +@Returns: + + + + + + + +@list: + + + + + + + +@mime_type: +@Returns: + + + + + + + +@mime_type: +@Returns: + + + + + + + +@Returns: + + + + + + + +@list: + + + + + + + +@mime_type: +@key: +@data: +@Returns: + + + + + + + +@mime_type: +@extensions_list: +@Returns: + + + + + + + +@mime_type: + + + + + + + + + diff --git a/doc/tmpl/gnome-vfs-mime-monitor.sgml b/doc/tmpl/gnome-vfs-mime-monitor.sgml new file mode 100644 index 0000000..8b6287a --- /dev/null +++ b/doc/tmpl/gnome-vfs-mime-monitor.sgml @@ -0,0 +1,38 @@ + +MIME Database Monitor + + + +monitor the MIME database for changes (primarily for file browsers) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@Returns: + + diff --git a/doc/tmpl/gnome-vfs-mime.sgml b/doc/tmpl/gnome-vfs-mime.sgml new file mode 100644 index 0000000..69a4918 --- /dev/null +++ b/doc/tmpl/gnome-vfs-mime.sgml @@ -0,0 +1,98 @@ + +MIME typing + + +functions to get a mime-type for a file using its name or its content + + + + + + + + + + + + + + + + + + + + + + + +@filename: +@Returns: + + + + + + + +@filename: +@defaultv: +@Returns: + + + + + + + +@uri: +@Returns: + + + + + + + +@uri: +@Returns: + + + + + + + +@uri: +@Returns: + + + + + + + +@path: +@optional_stat_info: +@suffix_only: +@Returns: + + + + + + + +@mime_type: +@Returns: + + + + + + + +@mime_type: +@Returns: + + diff --git a/doc/tmpl/gnome-vfs-module-callback-module-api.sgml b/doc/tmpl/gnome-vfs-module-callback-module-api.sgml new file mode 100644 index 0000000..930102b --- /dev/null +++ b/doc/tmpl/gnome-vfs-module-callback-module-api.sgml @@ -0,0 +1,29 @@ + +gnome-vfs-module-callback-module-api + + +invoking callbacks from a gnome-vfs module to ask the application for necessary information (authentication, ...) + + + + + + + + + + + + + + + + +@callback_name: +@in: +@in_size: +@out: +@out_size: +@Returns: + + diff --git a/doc/tmpl/gnome-vfs-module-callback.sgml b/doc/tmpl/gnome-vfs-module-callback.sgml new file mode 100644 index 0000000..bceee45 --- /dev/null +++ b/doc/tmpl/gnome-vfs-module-callback.sgml @@ -0,0 +1,110 @@ + +gnome-vfs-module-callback + + +functions used by apps if they want to answer to callback invocations by gnome-vfs modules + + + + + + + + + + + + + + + + +@in: +@in_size: +@out: +@out_size: +@callback_data: + + + + + + + +@response_data: + + + + + + + +@in: +@in_size: +@out: +@out_size: +@callback_data: +@response: +@response_data: + + + + + + + +@callback_name: +@callback: +@callback_data: +@destroy_notify: + + + + + + + +@callback_name: +@callback: +@callback_data: +@destroy_notify: + + + + + + + +@callback_name: + + + + + + + +@callback_name: +@callback: +@callback_data: +@destroy_notify: + + + + + + + +@callback_name: +@callback: +@callback_data: +@destroy_notify: + + + + + + + +@callback_name: + + diff --git a/doc/tmpl/gnome-vfs-module-shared.sgml b/doc/tmpl/gnome-vfs-module-shared.sgml new file mode 100644 index 0000000..f5ef7a9 --- /dev/null +++ b/doc/tmpl/gnome-vfs-module-shared.sgml @@ -0,0 +1,65 @@ + +gnome-vfs-module-shared + + + + + + + + + + + + + + + + + + + +@mode: +@Returns: + + + + + + + +@file_info: +@statptr: + + + + + + + +@info: +@file_name: +@meta_key: +@Returns: + + + + + + + +@info: +@file_name: +@meta_keys: +@Returns: + + + + + + + +@uri: +@Returns: + + diff --git a/doc/tmpl/gnome-vfs-module.sgml b/doc/tmpl/gnome-vfs-module.sgml new file mode 100644 index 0000000..1d1ea12 --- /dev/null +++ b/doc/tmpl/gnome-vfs-module.sgml @@ -0,0 +1,44 @@ + +gnome-vfs-module + + + + + + + + + + + + + + + + + + + +@method_name: +@args: +@Returns: + + + + + + + +@method_name: +@args: +@Returns: + + + + + + + +@method: + + diff --git a/doc/tmpl/gnome-vfs-monitor.sgml b/doc/tmpl/gnome-vfs-monitor.sgml new file mode 100644 index 0000000..98e2064 --- /dev/null +++ b/doc/tmpl/gnome-vfs-monitor.sgml @@ -0,0 +1,71 @@ + +Monitoring + + + +watch files for changes, and get called back if they do + + + + + + + + + + + + + + + + +@handle: +@text_uri: +@monitor_type: +@callback: +@user_data: +@Returns: + + + + + + + +@handle: +@Returns: + + + + + + + +@GNOME_VFS_MONITOR_FILE: +@GNOME_VFS_MONITOR_DIRECTORY: + + + + + + +@GNOME_VFS_MONITOR_EVENT_CHANGED: +@GNOME_VFS_MONITOR_EVENT_DELETED: +@GNOME_VFS_MONITOR_EVENT_STARTEXECUTING: +@GNOME_VFS_MONITOR_EVENT_STOPEXECUTING: +@GNOME_VFS_MONITOR_EVENT_CREATED: +@GNOME_VFS_MONITOR_EVENT_METADATA_CHANGED: + + + + + + +@handle: +@monitor_uri: +@info_uri: +@event_type: +@user_data: + + diff --git a/doc/tmpl/gnome-vfs-ops.sgml b/doc/tmpl/gnome-vfs-ops.sgml new file mode 100644 index 0000000..f88ae65 --- /dev/null +++ b/doc/tmpl/gnome-vfs-ops.sgml @@ -0,0 +1,23 @@ + +File Operations + + + +basic POSIX-style file operations + + + + + + + + + + + + + + + + + diff --git a/doc/tmpl/gnome-vfs-parse-ls.sgml b/doc/tmpl/gnome-vfs-parse-ls.sgml new file mode 100644 index 0000000..e1fb50d --- /dev/null +++ b/doc/tmpl/gnome-vfs-parse-ls.sgml @@ -0,0 +1,28 @@ + +gnome-vfs-parse-ls + + +convenience functions for modules which want to parse a ls-like directory listing + + + + + + + + + + + + + + + + +@p: +@s: +@filename: +@linkname: +@Returns: + + diff --git a/doc/tmpl/gnome-vfs-result.sgml b/doc/tmpl/gnome-vfs-result.sgml new file mode 100644 index 0000000..65d993a --- /dev/null +++ b/doc/tmpl/gnome-vfs-result.sgml @@ -0,0 +1,104 @@ + +GnomeVFSResult + + + +Result of I/O operations, the equivalent of errno + + + + + + + + + + + + + + + + +@GNOME_VFS_OK: +@GNOME_VFS_ERROR_NOT_FOUND: +@GNOME_VFS_ERROR_GENERIC: +@GNOME_VFS_ERROR_INTERNAL: +@GNOME_VFS_ERROR_BAD_PARAMETERS: +@GNOME_VFS_ERROR_NOT_SUPPORTED: +@GNOME_VFS_ERROR_IO: +@GNOME_VFS_ERROR_CORRUPTED_DATA: +@GNOME_VFS_ERROR_WRONG_FORMAT: +@GNOME_VFS_ERROR_BAD_FILE: +@GNOME_VFS_ERROR_TOO_BIG: +@GNOME_VFS_ERROR_NO_SPACE: +@GNOME_VFS_ERROR_READ_ONLY: +@GNOME_VFS_ERROR_INVALID_URI: +@GNOME_VFS_ERROR_NOT_OPEN: +@GNOME_VFS_ERROR_INVALID_OPEN_MODE: +@GNOME_VFS_ERROR_ACCESS_DENIED: +@GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES: +@GNOME_VFS_ERROR_EOF: +@GNOME_VFS_ERROR_NOT_A_DIRECTORY: +@GNOME_VFS_ERROR_IN_PROGRESS: +@GNOME_VFS_ERROR_INTERRUPTED: +@GNOME_VFS_ERROR_FILE_EXISTS: +@GNOME_VFS_ERROR_LOOP: +@GNOME_VFS_ERROR_NOT_PERMITTED: +@GNOME_VFS_ERROR_IS_DIRECTORY: +@GNOME_VFS_ERROR_NO_MEMORY: +@GNOME_VFS_ERROR_HOST_NOT_FOUND: +@GNOME_VFS_ERROR_INVALID_HOST_NAME: +@GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS: +@GNOME_VFS_ERROR_LOGIN_FAILED: +@GNOME_VFS_ERROR_CANCELLED: +@GNOME_VFS_ERROR_DIRECTORY_BUSY: +@GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY: +@GNOME_VFS_ERROR_TOO_MANY_LINKS: +@GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM: +@GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM: +@GNOME_VFS_ERROR_NAME_TOO_LONG: +@GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE: +@GNOME_VFS_ERROR_SERVICE_OBSOLETE: +@GNOME_VFS_ERROR_PROTOCOL_ERROR: +@GNOME_VFS_ERROR_NO_MASTER_BROWSER: +@GNOME_VFS_ERROR_NO_DEFAULT: +@GNOME_VFS_ERROR_NO_HANDLER: +@GNOME_VFS_ERROR_PARSE: +@GNOME_VFS_ERROR_LAUNCH: +@GNOME_VFS_NUM_ERRORS: + + + + + + +@result: +@Returns: + + + + + + + +@errno_code: +@Returns: + + + + + + + +@Returns: + + + + + + + +@Returns: + + diff --git a/doc/tmpl/gnome-vfs-socket-buffer.sgml b/doc/tmpl/gnome-vfs-socket-buffer.sgml new file mode 100644 index 0000000..b155467 --- /dev/null +++ b/doc/tmpl/gnome-vfs-socket-buffer.sgml @@ -0,0 +1,80 @@ + +gnome-vfs-socket-buffer + + + + + + + + + + + + + + + + + + + +@socket: +@Returns: + + + + + + + +@socket_buffer: +@close_socket: +@Returns: + + + + + + + +@socket_buffer: +@buffer: +@bytes: +@bytes_read: +@Returns: + + + + + + + +@socket_buffer: +@character: +@Returns: + + + + + + + +@socket_buffer: +@buffer: +@bytes: +@bytes_written: +@Returns: + + + + + + + +@socket_buffer: +@Returns: + +@buffer: + + diff --git a/doc/tmpl/gnome-vfs-socket.sgml b/doc/tmpl/gnome-vfs-socket.sgml new file mode 100644 index 0000000..0065c41 --- /dev/null +++ b/doc/tmpl/gnome-vfs-socket.sgml @@ -0,0 +1,97 @@ + +gnome-vfs-socket + + + + + + + + + + + + + + + + + + + +@connection: +@buffer: +@bytes: +@bytes_read: +@Returns: + + + + + + + +@connection: +@buffer: +@bytes: +@bytes_written: +@Returns: + + + + + + + +@connection: + + + + + + + + + + + + + +@impl: +@connection: +@Returns: + + + + + + + +@socket: +@buffer: +@bytes: +@bytes_written: +@Returns: + + + + + + + +@socket: +@Returns: + + + + + + + +@socket: +@buffer: +@bytes: +@bytes_read: +@Returns: + + diff --git a/doc/tmpl/gnome-vfs-ssl.sgml b/doc/tmpl/gnome-vfs-ssl.sgml new file mode 100644 index 0000000..6dd90f7 --- /dev/null +++ b/doc/tmpl/gnome-vfs-ssl.sgml @@ -0,0 +1,86 @@ + +gnome-vfs-ssl + + + + + + + + + + + + + + + + + + + +@Returns: + + + + + + + +@handle_return: +@host: +@port: +@Returns: + + + + + + + +@handle_return: +@fd: +@Returns: + + + + + + + +@ssl: +@buffer: +@bytes: +@bytes_read: +@Returns: + + + + + + + +@ssl: +@buffer: +@bytes: +@bytes_written: +@Returns: + + + + + + + +@ssl: + + + + + + + +@ssl: +@Returns: + + diff --git a/doc/tmpl/gnome-vfs-standard-callbacks.sgml b/doc/tmpl/gnome-vfs-standard-callbacks.sgml new file mode 100644 index 0000000..d8ca80d --- /dev/null +++ b/doc/tmpl/gnome-vfs-standard-callbacks.sgml @@ -0,0 +1,93 @@ + +gnome-vfs-standard-callbacks + + +standard callbacks for use by gnome-vfs module writers + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/tmpl/gnome-vfs-transform.sgml b/doc/tmpl/gnome-vfs-transform.sgml new file mode 100644 index 0000000..c313c16 --- /dev/null +++ b/doc/tmpl/gnome-vfs-transform.sgml @@ -0,0 +1,38 @@ + +gnome-vfs-transform + + + + + + + + + + + + + + + + + + + +@method_name: +@config_args: +@Returns: + + + + + + + +@transform: +@old_uri: +@new_uri: +@context: +@Returns: + + diff --git a/doc/tmpl/gnome-vfs-unused.sgml b/doc/tmpl/gnome-vfs-unused.sgml new file mode 100644 index 0000000..3c15ff4 --- /dev/null +++ b/doc/tmpl/gnome-vfs-unused.sgml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + +Reading the contents of directories + + + + +Directory Operations + + + + + + + + + + + + + + + + +utilities for locating standard directories such as the desktop and trash + + + + +Locating Standard Directories + + + + + + + + + + + + + + + + +attach extra pieces of information to files, such as icons or positions + + + + +Metadata + + + + + + + +@obj: + + + + + + + + + + + + +@self: +@key: +@Returns: + + + + + + +@uri: +@Returns: + + + + + + +@self: +@key: +@value: + + + + + + +@self: +@key: +@value: + diff --git a/doc/tmpl/gnome-vfs-uri.sgml b/doc/tmpl/gnome-vfs-uri.sgml new file mode 100644 index 0000000..d336697 --- /dev/null +++ b/doc/tmpl/gnome-vfs-uri.sgml @@ -0,0 +1,405 @@ + +GnomeVFSURI + + + +Functions for manipulating URIs + + + + + + + + + + + + + + + + + + + + + + +@GNOME_VFS_URI_HIDE_NONE: +@GNOME_VFS_URI_HIDE_USER_NAME: +@GNOME_VFS_URI_HIDE_PASSWORD: +@GNOME_VFS_URI_HIDE_HOST_NAME: +@GNOME_VFS_URI_HIDE_HOST_PORT: +@GNOME_VFS_URI_HIDE_TOPLEVEL_METHOD: +@GNOME_VFS_URI_HIDE_FRAGMENT_IDENTIFIER: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@text_uri: +@Returns: + + + + + + + +@base: +@relative_reference: +@Returns: + + + + + + + +@uri: +@Returns: + + + + + + + +@uri: + + + + + + + +@uri: +@uri_fragment: +@Returns: + + + + + + + +@uri: +@path: +@Returns: + + + + + + + +@uri: +@filename: +@Returns: + + + + + + + +@uri: +@hide_options: +@Returns: + + + + + + + +@uri: +@Returns: + + + + + + + +@uri: +@Returns: + + + + + + + +@uri: +@Returns: + + + + + + + +@uri: +@Returns: + + + + + + + +@uri: +@Returns: + + + + + + + +@uri: +@Returns: + + + + + + + +@uri: +@Returns: + + + + + + + +@uri: +@Returns: + + + + + + + +@uri: +@Returns: + + + + + + + +@uri: +@Returns: + + + + + + + +@uri: +@host_name: + + + + + + + +@uri: +@host_port: + + + + + + + +@uri: +@user_name: + + + + + + + +@uri: +@password: + + + + + + + +@a: +@b: +@Returns: + + + + + + + +@possible_parent: +@possible_child: +@recursive: +@Returns: + + + + + + + +@uri: +@Returns: + + + + + + + +@uri: +@Returns: + + + + + + + +@uri: +@Returns: + + + + + + + +@uri: +@Returns: + + + + + + + +@uri: +@Returns: + + + + + + + +@a: +@b: +@Returns: + + + + + + + +@p: +@Returns: + + + + + + + +@uri_list: +@Returns: + + + + + + + +@list: +@Returns: + + + + + + + +@list: +@Returns: + + + + + + + +@list: +@Returns: + + + + + + + +@list: + + + + + + + +@base_uri: +@relative_uri: +@Returns: + + diff --git a/doc/tmpl/gnome-vfs-utils.sgml b/doc/tmpl/gnome-vfs-utils.sgml new file mode 100644 index 0000000..f5f4f51 --- /dev/null +++ b/doc/tmpl/gnome-vfs-utils.sgml @@ -0,0 +1,223 @@ + +gnome-vfs-utils + + +various utilities functions to manipulate uris + + + + + + + + + + + + + + + + +@size: +@Returns: + + + + + + + +@string: +@Returns: + + + + + + + +@path: +@Returns: + + + + + + + +@path: +@Returns: + + + + + + + +@string: +@Returns: + + + + + + + +@string: +@match_set: +@Returns: + + + + + + + +@escaped_string: +@illegal_characters: +@Returns: + + + + + + + +@uri: +@Returns: + + + + + + + +@path: +@Returns: + + + + + + + +@path: +@Returns: + + + + + + + +@escaped: +@Returns: + + + + + + + +@uri: +@Returns: + + + + + + + +@local_full_path: +@Returns: + + + + + + + +@command_string: +@Returns: + + + + + + + +@list: + + + + + + + +@vfs_uri: +@size: +@Returns: + + + + + + + +@filename: +@Returns: + + + + + + + +@Returns: + + + + + + + +@uri: +@Returns: + + + + + + + +@uri_1: +@uri_2: +@Returns: + + + + + + + + + + + + + + + + + + + + + +@uri: +@file_size: +@file_contents: +@Returns: + + diff --git a/doc/tmpl/gnome-vfs-xfer.sgml b/doc/tmpl/gnome-vfs-xfer.sgml new file mode 100644 index 0000000..0ef871d --- /dev/null +++ b/doc/tmpl/gnome-vfs-xfer.sgml @@ -0,0 +1,166 @@ + +File Transfers + + +Conveniently copy/move/delete files en masse + + + + + + + + + + + + + + + + +@GNOME_VFS_XFER_DEFAULT: +@GNOME_VFS_XFER_UNUSED_1: +@GNOME_VFS_XFER_FOLLOW_LINKS: +@GNOME_VFS_XFER_UNUSED_2: +@GNOME_VFS_XFER_RECURSIVE: +@GNOME_VFS_XFER_SAMEFS: +@GNOME_VFS_XFER_DELETE_ITEMS: +@GNOME_VFS_XFER_EMPTY_DIRECTORIES: +@GNOME_VFS_XFER_NEW_UNIQUE_DIRECTORY: +@GNOME_VFS_XFER_REMOVESOURCE: +@GNOME_VFS_XFER_USE_UNIQUE_NAMES: +@GNOME_VFS_XFER_LINK_ITEMS: +@GNOME_VFS_XFER_FOLLOW_LINKS_RECURSIVE: + + + + + + +@GNOME_VFS_XFER_PROGRESS_STATUS_OK: +@GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR: +@GNOME_VFS_XFER_PROGRESS_STATUS_OVERWRITE: +@GNOME_VFS_XFER_PROGRESS_STATUS_DUPLICATE: + + + + + + +@GNOME_VFS_XFER_OVERWRITE_MODE_ABORT: +@GNOME_VFS_XFER_OVERWRITE_MODE_QUERY: +@GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE: +@GNOME_VFS_XFER_OVERWRITE_MODE_SKIP: + + + + + + +@GNOME_VFS_XFER_OVERWRITE_ACTION_ABORT: +@GNOME_VFS_XFER_OVERWRITE_ACTION_REPLACE: +@GNOME_VFS_XFER_OVERWRITE_ACTION_REPLACE_ALL: +@GNOME_VFS_XFER_OVERWRITE_ACTION_SKIP: +@GNOME_VFS_XFER_OVERWRITE_ACTION_SKIP_ALL: + + + + + + +@GNOME_VFS_XFER_ERROR_MODE_ABORT: +@GNOME_VFS_XFER_ERROR_MODE_QUERY: + + + + + + +@GNOME_VFS_XFER_ERROR_ACTION_ABORT: +@GNOME_VFS_XFER_ERROR_ACTION_RETRY: +@GNOME_VFS_XFER_ERROR_ACTION_SKIP: + + + + + + +@GNOME_VFS_XFER_PHASE_INITIAL: +@GNOME_VFS_XFER_CHECKING_DESTINATION: +@GNOME_VFS_XFER_PHASE_COLLECTING: +@GNOME_VFS_XFER_PHASE_READYTOGO: +@GNOME_VFS_XFER_PHASE_OPENSOURCE: +@GNOME_VFS_XFER_PHASE_OPENTARGET: +@GNOME_VFS_XFER_PHASE_COPYING: +@GNOME_VFS_XFER_PHASE_MOVING: +@GNOME_VFS_XFER_PHASE_READSOURCE: +@GNOME_VFS_XFER_PHASE_WRITETARGET: +@GNOME_VFS_XFER_PHASE_CLOSESOURCE: +@GNOME_VFS_XFER_PHASE_CLOSETARGET: +@GNOME_VFS_XFER_PHASE_DELETESOURCE: +@GNOME_VFS_XFER_PHASE_SETATTRIBUTES: +@GNOME_VFS_XFER_PHASE_FILECOMPLETED: +@GNOME_VFS_XFER_PHASE_CLEANUP: +@GNOME_VFS_XFER_PHASE_COMPLETED: +@GNOME_VFS_XFER_NUM_PHASES: + + + + + + + + + + + + +@info: +@data: +@Returns: + + + + + + + +@source_uri_list: +@target_uri_list: +@xfer_options: +@error_mode: +@overwrite_mode: +@progress_callback: +@data: +@Returns: + + + + + + + +@source_uri: +@target_uri: +@xfer_options: +@error_mode: +@overwrite_mode: +@progress_callback: +@data: +@Returns: + + + + + + + +@source_uri_list: +@error_mode: +@xfer_options: +@progress_callback: +@data: +@Returns: + + diff --git a/doc/tmpl/gnome-vfs.sgml b/doc/tmpl/gnome-vfs.sgml new file mode 100644 index 0000000..36721f1 --- /dev/null +++ b/doc/tmpl/gnome-vfs.sgml @@ -0,0 +1,16 @@ + +gnome-vfs + + + + + + + + + + + + + + diff --git a/doc/writing-modules.sgml b/doc/writing-modules.sgml new file mode 100644 index 0000000..2344b88 --- /dev/null +++ b/doc/writing-modules.sgml @@ -0,0 +1,554 @@ + + +Writing Modules +3 +GNOME-VFS Library + + + +Writing Modulesbasic gnome-vfs module concepts + + + + Introduction + + This section will introduce the basic concepts that are + needed for writing GNOME Virtual File System modules. + + + GNOME VFS URIs (Uniform Resource Identifiers) + + The GNOME Virtual file system uses URIs similiar to the + standard WWW URIs. The basic difference between a VFS URI and + WWW URI is that, while with WWW URIs you can only use a single + protocol for accessing a certain file, with GNOME VFS URIs you + can combine different access methods in sequence. + + For example, suppose you want to access file + hello.c in a tar.gz + file which is in turn accessible through FTP from a remote + machine. In order to access this file, you would need to: + + + Connect to the FTP site. + + Fetch the tar.gz + file. + + Decompress the tar.gz file using + GZIP. + + Extract hello.c from the resulting + uncompressed tar file. + + + The GNOME Virtual File System lets you express this by + combining the three access methods (i.e. tar, GZIP and FTP) + into a single URI. Access methods are combined in the URI by + using the `#' character, followed by the name for the access + method and the subpath for that specific access method. The + subpath can be omitted for those storage methods that do not + need a path to retrieve the file. (For example, a GZIP file + always contains a single uncompressed file, so no path is + needed to locate the uncompressed file within the GZIP file. + But on the other hand, the TAR method requires a path to + locate a specific file or directory.) + + For example, in the case we outlined above, the URI would + look something like: + + + + + ftp://username:password@host.net/path/to/file.tar.gz#gzip#tar/path/to/hello.c + + Each method/subpath couple is called a URI + element. When URI elements are combined like this, + each URI element uses the previous one to access a base resource + into which it will look up a file, using the subpath + information. For this reason, we will say that each element is + the parent element for the following one. + + The first URI element, the one which has no parent, is + called the toplevel element. It does not + use the `#' character; instead, it uses the standard syntax of + WWW URIs: + + + + method://user:password@host/path/to/file + + This way, normal WWW URIs can be used with the GNOME Virtual + File System. + + Toplevel elements are also special because they let users + specify user names, passwords and host names, while + non-toplevel elements don't. + + + + The <structname>GnomeVFSURI</structname> type + + Within the GNOME Virtual File System library, URI elements + are represented by a special type, + GnomeVFSURI, which is meant to represent + user-provided URIs in a machine-optimized way. + + Every GnomeVFSURI contains the + following information: + + + A reference counter + + A pointer to the parent + GnomeVFSURI URI element. + + The subpath. + + The name of the access method. + + A pointer to a + GnomeVFSMethod object, describing the + access method (see below). + + + + + + + + GNOME Virtual File System access method implementation + + In the GNOME Virtual File System, the implementations for + all the access methods are loaded at runtime, as shared library + modules. The modules are loaded during parsing of the string URI: + if the parser encounters an access method for which no + implementation is currently loaded, it retrieves the corresponding + library file, dynamically links it into the executable, and + initializes it. + + After initialization, the module returns a special + GnomeVFSMethod object that contains + pointers to the various implementation functions for that specific + method. By storing a pointer to this object into the + GnomeVFSURI type, the VFS library is then + able to use these functions for file access. + + + How file access is performed + + When the VFS library needs to perform some file operation, + it performs the following steps: + + + + If the URI is given in textual form (i.e. as a + string), it parses it and activates the necessary access method + modules. + + It retrieves a pointer to the lowmost + level URI element. + + It retrieves a pointer to the + GnomeVFSMethod object that corresponds + to the access method for that URI element. + + It retrieves a pointer to the implementation + function for that operation from the + GnomeVFSMethodobject. + + It invokes that implementation function + passing the pointer to the lowmost level URI + element. + + + + Combining the access methods is always done within the + method implementation. If the method implementation needs to do + some file operation on the the parent URI element, it can do so + by simply invoking the corresponding VFS function in, by using + the parent pointer in the GnomeVFSURI + object. + + For example, suppose you have to read a simple URI like + the following: + + + + + file:/home/ettore/file.gz#gzip + + In this case, the GZIP method will be invoked with a + pointer to the GnomeVFSURI describing the + `gzip' part; then the GZIP method will be able to read + file.gz by just invoking the corresponding + GNOME VFS library function on its parent, and decompress it on + the fly. + + + + + + + Implementing an access method in practice + + Implementing a new access method is really not difficult at + all. This section explains how this is done. + + + Using shared libraries + + Every module must be compiled as a shared library (i.e. a + .so file). + + The current way for accessing the right module for the + right method is very simple, and is based on file names. In + practice, a module implementing access method named + foo must be named + libfoo.so. For example, the module + implementing the ftp: access method is + called libftp.so, the module implementing + #gzip access is called + libgzip.so and so on. + + This might change in the future. + + + + + The initialization/shutdown functions + + Every shared library module must provide two functions: + + + +GnomeVFSMethod *vfs_module_init (void); +void vfs_module_shutdown (GnomeVFSMethod *method); + + These are the only functions that the VFS library will + access directly. All the other symbols (i.e. functions and + variables) in the module should be made static. + + vfs_module_init() is called + as soon as the module is loaded in memory. It will have to + return a pointer to a GnomeVFSMethod + object that will contain the pointers to the method's + implementation functions. We will describe this later. + + vfs_module_shutdown, instead, + is called before the module is unloaded or the program that uses + it dies. This functions should: + + + + Deallocate all the memory allocated by the + module. + + Close all the file descriptors associated with + the module. + + Kill any external process spawned by the + module. + + In general, make sure that any operation that + was going on before this function was called will be + interrupted correctly, as soon as possible and without any + leaks. + + + + + + + The <structname>GnomeVFSMethod</structname> object + + This object is contains pointers to the module + implementation functions. + + + +GnomeVFSResult (* open) (GnomeVFSMethodHandle **method_handle_return, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode + GnomeVFSCancellation *cancellation); + +GnomeVFSResult (* create) (GnomeVFSMethodHandle **method_handle_return, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + gboolean exclusive, + guint perm + GnomeVFSCancellation *cancellation); + +GnomeVFSResult (* close) (GnomeVFSMethodHandle *method_handle + GnomeVFSCancellation *cancellation); + +GnomeVFSResult (* read) (GnomeVFSMethodHandle *method_handle, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read_return + GnomeVFSCancellation *cancellation); + +GnomeVFSResult (* write) (GnomeVFSMethodHandle *method_handle, + gconstpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_written_return + GnomeVFSCancellation *cancellation); + +GnomeVFSResult (* seek) (GnomeVFSMethodHandle *method_handle, + GnomeVFSSeekPosition whence, + GnomeVFSFileOffset offset + GnomeVFSCancellation *cancellation); + +GnomeVFSResult (* tell) (GnomeVFSMethodHandle *method_handle, + GnomeVFSFileOffset *offset_return); + +GnomeVFSResult (* truncate) (GnomeVFSMethodHandle *method_handle, + GnomeVFSFileSize where + GnomeVFSCancellation *cancellation); + +GnomeVFSResult (* open_directory) (GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options, + const GList *meta_keys, + const GnomeVFSDirectoryFilter *filter + GnomeVFSCancellation *cancellation); + +GnomeVFSResult (* close_directory) (GnomeVFSMethodHandle *method_handle + GnomeVFSCancellation *cancellation); + +GnomeVFSResult (* read_directory) (GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info + GnomeVFSCancellation *cancellation); + +GnomeVFSResult (* get_file_info) (GnomeVFSURI *uri, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + const GList *meta_keys + GnomeVFSCancellation *cancellation); + +GnomeVFSResult (* get_file_info_from_handle) + (GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + const GList *meta_keys + GnomeVFSCancellation *cancellation); + +gboolean (* is_local) (const GnomeVFSURI *uri + GnomeVFSCancellation *cancellation); + +GnomeVFSResult (* rename) (GnomeVFSURI *uri, const gchar *new_name + GnomeVFSCancellation *cancellation); + +GnomeVFSResult (* make_directory) (GnomeVFSURI *uri, guint perm + GnomeVFSCancellation *cancellation); + +GnomeVFSResult (* remove_directory) (GnomeVFSURI *uri + GnomeVFSCancellation *cancellation); + +GnomeVFSResult (* unlink) (GnomeVFSURI *uri + GnomeVFSCancellation *cancellation); + + + + + + + + Handling cancellation + + As VFS operations might be very long, especially in the case + of transient errors (such as a network server that has gone down), + the GNOME Virtual File System Library provides a standard way for + handling cancellation of VFS operations. + + + The <structname>GnomeVFSCancellation</structname> object + + The object that encapsulates this functionality is + GnomeVFSCancellation. Most + implementation functions get a pointer to such an object, and are + expected to use this object to recognize when an operation should + be interrupted. + + The most simple way to check for a cancellation request is + to poll the object with + gnome_vfs_cancellation_check(): + + + +gboolean gnome_vfs_cancellation_check (GnomeVFSCancellation *cancellation); + + This function will return a nonzero value if the current + operation should be cancelled. + + Notice that cancellation is an asynchronous operation that + might happen outside your function, in parallel with the code that + you are writing. For example, in the case of threads, the request + will be set in the master thread; in the case of slave + CORBA-driven processes, the request will be activated by a Unix + signal. So you can expect a cancellation request to happen (and + consequently be signalled in + GnomeVFSCancellation) at any time. + + For this reason, you should be calling this function + periodically, whenever you are going to perform several + iterations of the same task, or execute a single expensive task. + When the function returns a nonzero value, the correct way to + react is: + + + Clean things up so that the result of the + operations that have been performed are all + cancelled. + Return the + GNOME_VFS_ERROR_CANCELLED error + code. + + + But there are some other situations in which you want to + be able to interrupt a I/O operation when a cancellation request + is performed. In such cases, polling is not a viable option. + + For this reason, + GnomeVFSCancellation provides an + alternative way of sending notifications, using a file + descriptor. To use this feature, you should use the following + function: + + + +gint gnome_vfs_cancellation_get_fd (GnomeVFSCancellation *cancellation); + + When this function is called, it will return an open file + descriptor, which is the read-side of a pipe. The pipe will be + given a character from the write side as soon as a cancellation + request is sent. For this reason, you can check for a + cancellation by using the select() system + call: as soon as select reports that some + data is available on the file descriptor, you know that a + cancellation is being requested. + + For example, if you are reading from a file descriptor and + you want to check for a pending cancellation at the same time, + you can set up selectfor checking if data + is available on both the cancellation file descriptor and the + file descriptor you are reading from. + + + + Dealing with <symbol>EINTR</symbol> + + In order to maximize the chance of cancelling an operation + immediately, the GNOME Virtual File System can sends a signal to + the asynchronous thread or process. This does not happen on all + the systems and setups, though. + + The result of this is that, if a process is in the middle + of a Unix system call while receiving this signal, the system + call might be interrupted and return a EINTR + error. + + For this reason, when you receive EINTR + you should check if a cancellation request is pending, using + gnome_vfs_cancellation_check() on the + GnomeVFSCancellation object that the + implementation function received: + + + If a cancellation is indeed pending + (gnome_vfs_cancellation_check() returns a + nonzero value), you should cancel the operation, cleaning up + all the effects, and return + GNOME_VFS_ERROR_INTERRUPTED or + GNOME_VFS_ERROR_CANCELLED + + Otherwise, retry the system call as you would + normally do. + + + + + + + Basic guidelines for writing a module + + Writing GNOME VFS modules is easy, but there are a few + things that you must keep in mind when hacking them: + + + All of the code must be completely thread safe. + The reason for this is that the asynchronous GNOME VFS engine + will use threads when available; if you don't make sure that the + code is thread-safe, every kind of weird and unexpected errors + will happen. As debugging these problems can be very hard, it's + important to write the code with threads in mind right from the + start. + + Use the special + gnome_vfs_*_cancellable() VFS functions + instead of the standard non-cancellable ones, passing them the + same GnomeVFSCancellation object you + are given, so that the operation can always be interrrupted at + any time. + + The code should respect the basic GNOME + guidelines for source code indentation and + style. + + + + How to make the code thread safe + + Although it might sound scary at first, making the code + for the modules thread safe is not complicated at all. + + First of all, make sure the amount of global variables is + kept to the bare minimum. If possible, you should avoid them at + all cost. + + For those cases where globals are inevitable (such as + caches, connection pools or things like that), you have to make + sure every variable is properly associated with a mutex, and + that the mutex is locked before every access to this variable + and released afterwards. You can also use + G_LOCK_DEFINE_STATIC, + G_LOCK and G_UNLOCK + for this. + + + Generally speaking, if you are going to dynamically + allocate structures that are shared by more than one + operation/file, you should provide all of them with their nice + mutex locks. + + Finally, make sure mutexes are used only if they are + available. One way to do so is to use macros like the + following: + + + +#ifdef G_THREADS_ENABLED +#define MUTEX_NEW() g_mutex_new () +#define MUTEX_FREE(a) g_mutex_free (a) +#define MUTEX_LOCK(a) if ((a) != NULL) g_mutex_lock (a) +#define MUTEX_UNLOCK(a) if ((a) != NULL) g_mutex_unlock (a) +#else +#define MUTEX_NEW() NULL +#define MUTEX_FREE(a) +#define MUTEX_LOCK(a) +#define MUTEX_UNLOCK(a) +#endif + + G_LOCK_DEFINE_STATIC, + G_LOCK and G_UNLOCK in + GLib are always safe to use, as they are already defined to be + nothing when thread support is not available. + + (Probably it would be a good idea to have something in the + private GNOME VFS API that does this stuff for all the + modules.) + + + + + diff --git a/doc/xml/gnome-vfs-application-registry.xml b/doc/xml/gnome-vfs-application-registry.xml new file mode 100644 index 0000000..4c894cf --- /dev/null +++ b/doc/xml/gnome-vfs-application-registry.xml @@ -0,0 +1,527 @@ + + +Application Registry +3 +GNOME-VFS-2.0 Library + + + +Application Registry +stores supported MIME types and URIs of various applications + + +Synopsis + + + + + +#define GNOME_VFS_APPLICATION_REGISTRY_COMMAND +#define GNOME_VFS_APPLICATION_REGISTRY_NAME +#define GNOME_VFS_APPLICATION_REGISTRY_CAN_OPEN_MULTIPLE_FILES +#define GNOME_VFS_APPLICATION_REGISTRY_REQUIRES_TERMINAL +gboolean gnome_vfs_application_registry_exists + (const char *app_id); +GList* gnome_vfs_application_registry_get_keys + (const char *app_id); +const char* gnome_vfs_application_registry_peek_value + (const char *app_id, + const char *key); +gboolean gnome_vfs_application_registry_get_bool_value + (const char *app_id, + const char *key, + gboolean *got_key); +void gnome_vfs_application_registry_remove_application + (const char *app_id); +void gnome_vfs_application_registry_set_value + (const char *app_id, + const char *key, + const char *value); +void gnome_vfs_application_registry_set_bool_value + (const char *app_id, + const char *key, + gboolean value); +void gnome_vfs_application_registry_unset_key + (const char *app_id, + const char *key); +GList* gnome_vfs_application_registry_get_applications + (const char *mime_type); +GList* gnome_vfs_application_registry_get_mime_types + (const char *app_id); +gboolean gnome_vfs_application_registry_supports_mime_type + (const char *app_id, + const char *mime_type); +gboolean gnome_vfs_application_registry_supports_uri_scheme + (const char *app_id, + const char *uri_scheme); +gboolean gnome_vfs_application_is_user_owned_application + (const GnomeVFSMimeApplication *application); +void gnome_vfs_application_registry_clear_mime_types + (const char *app_id); +void gnome_vfs_application_registry_add_mime_type + (const char *app_id, + const char *mime_type); +void gnome_vfs_application_registry_remove_mime_type + (const char *app_id, + const char *mime_type); +GnomeVFSResult gnome_vfs_application_registry_sync + (void); +void gnome_vfs_application_registry_shutdown + (void); +void gnome_vfs_application_registry_reload + (void); +GnomeVFSMimeApplication* gnome_vfs_application_registry_get_mime_application + (const char *app_id); +void gnome_vfs_application_registry_save_mime_application + (const GnomeVFSMimeApplication *application); + + + + + + + + + + + + +Description + + + + + + +Details + +<anchor id="GNOME-VFS-APPLICATION-REGISTRY-COMMAND-CAPS"/>GNOME_VFS_APPLICATION_REGISTRY_COMMAND +GNOME_VFS_APPLICATION_REGISTRY_COMMAND#define GNOME_VFS_APPLICATION_REGISTRY_COMMAND "command" + + +Application registry key for fetching the command to execute +an application. + + + + +<anchor id="GNOME-VFS-APPLICATION-REGISTRY-NAME-CAPS"/>GNOME_VFS_APPLICATION_REGISTRY_NAME +GNOME_VFS_APPLICATION_REGISTRY_NAME#define GNOME_VFS_APPLICATION_REGISTRY_NAME "name" + + +Application registry key for fetching the name of an application. + + + + +<anchor id="GNOME-VFS-APPLICATION-REGISTRY-CAN-OPEN-MULTIPLE-FILES-CAPS"/>GNOME_VFS_APPLICATION_REGISTRY_CAN_OPEN_MULTIPLE_FILES +GNOME_VFS_APPLICATION_REGISTRY_CAN_OPEN_MULTIPLE_FILES#define GNOME_VFS_APPLICATION_REGISTRY_CAN_OPEN_MULTIPLE_FILES "can_open_multiple_files" + + +Application registry key for determining if an application +can open multiple files in the same invocation. + + + + +<anchor id="GNOME-VFS-APPLICATION-REGISTRY-REQUIRES-TERMINAL-CAPS"/>GNOME_VFS_APPLICATION_REGISTRY_REQUIRES_TERMINAL +GNOME_VFS_APPLICATION_REGISTRY_REQUIRES_TERMINAL#define GNOME_VFS_APPLICATION_REGISTRY_REQUIRES_TERMINAL "requires_terminal" + + +Application registry key for determining if an application +needs to run from within a terminal (for example, mpg123) + + + + +<anchor id="gnome-vfs-application-registry-exists"/>gnome_vfs_application_registry_exists () +gnome_vfs_application_registry_existsgboolean gnome_vfs_application_registry_exists + (const char *app_id); + +This function will return TRUE if there is an entry for app_id in +the registry, otherwise FALSE. + + + +app_id : + an application ID + +Returns : TRUE if the application is in the registry, FALSE if not + + + + +<anchor id="gnome-vfs-application-registry-get-keys"/>gnome_vfs_application_registry_get_keys () +gnome_vfs_application_registry_get_keysGList* gnome_vfs_application_registry_get_keys + (const char *app_id); + +This function wil return a list of strings which is the list of +keys set for app_id in the application registry. + + + +app_id : + the application ID for which to get keys + +Returns : A list of the keys set for app_id + + + + +<anchor id="gnome-vfs-application-registry-peek-value"/>gnome_vfs_application_registry_peek_value () +gnome_vfs_application_registry_peek_valueconst char* gnome_vfs_application_registry_peek_value + (const char *app_id, + const char *key); + +This will return the value associated with key for app_id in the +application registry. There is no need to free the return value. + + + +app_id : + the application ID for which to look up a value + +key : + the key to look up + +Returns : the value associated with the key, or NULL if there is no +associated value + + + + +<anchor id="gnome-vfs-application-registry-get-bool-value"/>gnome_vfs_application_registry_get_bool_value () +gnome_vfs_application_registry_get_bool_valuegboolean gnome_vfs_application_registry_get_bool_value + (const char *app_id, + const char *key, + gboolean *got_key); + +This will look up a key in the structure pointed to by app_id and return the +boolean value of that key. It will return false if there are no +applications associated with the app_id. + + + +app_id : + registry id of the application + +key : + key to look up + +got_key : + TRUE if a setting was dound, otherwise FALSE + +Returns : TRUE if key is set to "true" or "yes" for app_id, otherwise FALSE + + + + +<anchor id="gnome-vfs-application-registry-remove-application"/>gnome_vfs_application_registry_remove_application () +gnome_vfs_application_registry_remove_applicationvoid gnome_vfs_application_registry_remove_application + (const char *app_id); + +Given the registry id this function will remove all applications that has +been set by the user. You will need to call +gnome_vfs_application_registry_sync to save the changes. + + + +app_id : + registry id of the application + + + +<anchor id="gnome-vfs-application-registry-set-value"/>gnome_vfs_application_registry_set_value () +gnome_vfs_application_registry_set_valuevoid gnome_vfs_application_registry_set_value + (const char *app_id, + const char *key, + const char *value); + +This function will set values pertaining to registry entry pointed to by +app_id. You will need to call gnome_vfs_application_registry_sync to +realize the changes. + + + +app_id : + registry id of the application + +key : + target key + +value : + value to set the target key to + + + +<anchor id="gnome-vfs-application-registry-set-bool-value"/>gnome_vfs_application_registry_set_bool_value () +gnome_vfs_application_registry_set_bool_valuevoid gnome_vfs_application_registry_set_bool_value + (const char *app_id, + const char *key, + gboolean value); + +This function will modify those registry values that are of type boolean to +a value specified by the user. You will need to call +gnome_vfs_application_registry_sync to save your changes. + + + +app_id : + registry id of the application + +key : + target key + +value : + value you want to set the target key to + + + +<anchor id="gnome-vfs-application-registry-unset-key"/>gnome_vfs_application_registry_unset_key () +gnome_vfs_application_registry_unset_keyvoid gnome_vfs_application_registry_unset_key + (const char *app_id, + const char *key); + +This function given the application and the target will wipe the current +value that the key contains. + + + +app_id : + registry id of the application + +key : + search key + + + +<anchor id="gnome-vfs-application-registry-get-applications"/>gnome_vfs_application_registry_get_applications () +gnome_vfs_application_registry_get_applicationsGList* gnome_vfs_application_registry_get_applications + (const char *mime_type); + +This will return all applications from the registry that are associated with +the given mime type string, if NULL it returns all applications. + + + +mime_type : + mime type string + +Returns : a list of the application IDs for all applications which +support the given mime type. + + + + +<anchor id="gnome-vfs-application-registry-get-mime-types"/>gnome_vfs_application_registry_get_mime_types () +gnome_vfs_application_registry_get_mime_typesGList* gnome_vfs_application_registry_get_mime_types + (const char *app_id); + +This function returns a list of strings that represent the mime +types that can be handled by an application. + + + +app_id : + registry id of application + +Returns : a list of the mime types supported + + + + +<anchor id="gnome-vfs-application-registry-supports-mime-type"/>gnome_vfs_application_registry_supports_mime_type () +gnome_vfs_application_registry_supports_mime_typegboolean gnome_vfs_application_registry_supports_mime_type + (const char *app_id, + const char *mime_type); + +Use this function to see if there is an application associated with a given +mime type. The function will return true or false. + + + +app_id : + registry id of application + +mime_type : + mime type string + +Returns : TRUE if app_id supports mime_type, otherwise FALSE. + + + + +<anchor id="gnome-vfs-application-registry-supports-uri-scheme"/>gnome_vfs_application_registry_supports_uri_scheme () +gnome_vfs_application_registry_supports_uri_schemegboolean gnome_vfs_application_registry_supports_uri_scheme + (const char *app_id, + const char *uri_scheme); + +Given the id of the application this function will determine if the +uri scheme will given is supported. + + + +app_id : + registry id of application + +uri_scheme : + uri schme string + +Returns : TRUE if app_id supports uri_scheme, otherwise FALSE + + + + +<anchor id="gnome-vfs-application-is-user-owned-application"/>gnome_vfs_application_is_user_owned_application () +gnome_vfs_application_is_user_owned_applicationgboolean gnome_vfs_application_is_user_owned_application + (const GnomeVFSMimeApplication *application); + +This function will determine if a mime application is user owned or not. By +user ownered this means that the application is not a system application +located in the prerequisite /usr area but rather in the user's area. + + + +application : + data structure of the mime application + +Returns : gboolean + + + +<anchor id="gnome-vfs-application-registry-clear-mime-types"/>gnome_vfs_application_registry_clear_mime_types () +gnome_vfs_application_registry_clear_mime_typesvoid gnome_vfs_application_registry_clear_mime_types + (const char *app_id); + +This function will remove the mime types associated with the application. +Changes are not realized until the gnome_vfs_application_registry_sync +function is called to save the changes to the file. + + + +app_id : + Application id + + + +<anchor id="gnome-vfs-application-registry-add-mime-type"/>gnome_vfs_application_registry_add_mime_type () +gnome_vfs_application_registry_add_mime_typevoid gnome_vfs_application_registry_add_mime_type + (const char *app_id, + const char *mime_type); + +This function will associate a mime type with an application given the +application registry id and the mime type. Changes are not realized until +the gnome_vfs_application_registry_sync function is called to save the +changes to the file. + + + +app_id : + registry id of application + +mime_type : + mime type string + + + +<anchor id="gnome-vfs-application-registry-remove-mime-type"/>gnome_vfs_application_registry_remove_mime_type () +gnome_vfs_application_registry_remove_mime_typevoid gnome_vfs_application_registry_remove_mime_type + (const char *app_id, + const char *mime_type); + +This function will de-associate a mime type from an application registry. +Given the application registry id and the mime type. Changes are not +realized until the gnome_vfs_application_registry_sync function is called to +save the changes to the file. + + + +app_id : + registry id of the application + +mime_type : + mime type string + + + +<anchor id="gnome-vfs-application-registry-sync"/>gnome_vfs_application_registry_sync () +gnome_vfs_application_registry_syncGnomeVFSResult gnome_vfs_application_registry_sync + (void); + +This function will sync the registry. Typically you would use this function +after a modification of the registry. When you modify the registry a dirty +flag is set. Calling this function will save your modifications to disk and +reset the flag. + + +If successful, will return GNOME_VFS_OK + + + +Returns : GnomeVFSResult + + + + +<anchor id="gnome-vfs-application-registry-shutdown"/>gnome_vfs_application_registry_shutdown () +gnome_vfs_application_registry_shutdownvoid gnome_vfs_application_registry_shutdown + (void); + +Synchronize gnome-vfs application registry data to disk, and free +resources. + + + + +<anchor id="gnome-vfs-application-registry-reload"/>gnome_vfs_application_registry_reload () +gnome_vfs_application_registry_reloadvoid gnome_vfs_application_registry_reload + (void); + +If this function is called for the first time it will initialize the +registry. Subsequent calls to the function will clear out the current +registry contents and load registry contents from the save file. Make +certain that you've saved your registry before calling this function. It +will destroy unsaved changes. + + + + +<anchor id="gnome-vfs-application-registry-get-mime-application"/>gnome_vfs_application_registry_get_mime_application () +gnome_vfs_application_registry_get_mime_applicationGnomeVFSMimeApplication* gnome_vfs_application_registry_get_mime_application + (const char *app_id); + +Returns a structure that contains the application that handles +the mime type associated by the application referred by app_id. + + + +app_id : + registry id of the application + +Returns : GnomeVFSMimeApplication + + + + +<anchor id="gnome-vfs-application-registry-save-mime-application"/>gnome_vfs_application_registry_save_mime_application () +gnome_vfs_application_registry_save_mime_applicationvoid gnome_vfs_application_registry_save_mime_application + (const GnomeVFSMimeApplication *application); + +This will save to the registry the application that will be associated with +a defined mime type. The defined mime type is located within the +GnomeVFSMimeApplication structure. Changes are not realized until the +gnome_vfs_application_registry_sync function is called. + + + +application : + application associated with the mime type + + + + + + + + + diff --git a/doc/xml/gnome-vfs-async-ops.xml b/doc/xml/gnome-vfs-async-ops.xml new file mode 100644 index 0000000..585c077 --- /dev/null +++ b/doc/xml/gnome-vfs-async-ops.xml @@ -0,0 +1,1227 @@ + + +Asynchronous File Operations +3 +GNOME-VFS-2.0 Library + + + +Asynchronous File Operations +POSIX-style file operations that run outside your main loop + + +Synopsis + + + + + +#define GNOME_VFS_PRIORITY_MIN +#define GNOME_VFS_PRIORITY_MAX +#define GNOME_VFS_PRIORITY_DEFAULT +void (*GnomeVFSAsyncCallback) (GnomeVFSAsyncHandle *handle, + GnomeVFSResult result, + gpointer callback_data); +typedef GnomeVFSAsyncOpenCallback; +typedef GnomeVFSAsyncCreateCallback; +typedef GnomeVFSAsyncCreateAsChannelCallback; +typedef GnomeVFSAsyncCloseCallback; +void (*GnomeVFSAsyncReadCallback) (GnomeVFSAsyncHandle *handle, + GnomeVFSResult result, + gpointer buffer, + GnomeVFSFileSize bytes_requested, + GnomeVFSFileSize bytes_read, + gpointer callback_data); +void (*GnomeVFSAsyncWriteCallback) (GnomeVFSAsyncHandle *handle, + GnomeVFSResult result, + gconstpointer buffer, + GnomeVFSFileSize bytes_requested, + GnomeVFSFileSize bytes_written, + gpointer callback_data); +typedef GnomeVFSFindDirectoryResult; +void gnome_vfs_async_set_job_limit (int limit); +int gnome_vfs_async_get_job_limit (void); +void gnome_vfs_async_cancel (GnomeVFSAsyncHandle *handle); +void gnome_vfs_async_open (GnomeVFSAsyncHandle **handle_return, + const gchar *text_uri, + GnomeVFSOpenMode open_mode, + int priority, + GnomeVFSAsyncOpenCallback callback, + gpointer callback_data); +void gnome_vfs_async_open_uri (GnomeVFSAsyncHandle **handle_return, + GnomeVFSURI *uri, + GnomeVFSOpenMode open_mode, + int priority, + GnomeVFSAsyncOpenCallback callback, + gpointer callback_data); +void gnome_vfs_async_open_as_channel (GnomeVFSAsyncHandle **handle_return, + const gchar *text_uri, + GnomeVFSOpenMode open_mode, + guint advised_block_size, + int priority, + GnomeVFSAsyncOpenAsChannelCallback callback, + gpointer callback_data); +void gnome_vfs_async_open_uri_as_channel + (GnomeVFSAsyncHandle **handle_return, + GnomeVFSURI *uri, + GnomeVFSOpenMode open_mode, + guint advised_block_size, + int priority, + GnomeVFSAsyncOpenAsChannelCallback callback, + gpointer callback_data); +void gnome_vfs_async_create (GnomeVFSAsyncHandle **handle_return, + const gchar *text_uri, + GnomeVFSOpenMode open_mode, + gboolean exclusive, + guint perm, + int priority, + GnomeVFSAsyncOpenCallback callback, + gpointer callback_data); +void gnome_vfs_async_create_uri (GnomeVFSAsyncHandle **handle_return, + GnomeVFSURI *uri, + GnomeVFSOpenMode open_mode, + gboolean exclusive, + guint perm, + int priority, + GnomeVFSAsyncOpenCallback callback, + gpointer callback_data); +void gnome_vfs_async_create_symbolic_link + (GnomeVFSAsyncHandle **handle_return, + GnomeVFSURI *uri, + const gchar *uri_reference, + int priority, + GnomeVFSAsyncOpenCallback callback, + gpointer callback_data); +void gnome_vfs_async_create_as_channel + (GnomeVFSAsyncHandle **handle_return, + const gchar *text_uri, + GnomeVFSOpenMode open_mode, + gboolean exclusive, + guint perm, + int priority, + GnomeVFSAsyncCreateAsChannelCallback callback, + gpointer callback_data); +void gnome_vfs_async_create_uri_as_channel + (GnomeVFSAsyncHandle **handle_return, + GnomeVFSURI *uri, + GnomeVFSOpenMode open_mode, + gboolean exclusive, + guint perm, + int priority, + GnomeVFSAsyncCreateAsChannelCallback callback, + gpointer callback_data); +void gnome_vfs_async_close (GnomeVFSAsyncHandle *handle, + GnomeVFSAsyncCloseCallback callback, + gpointer callback_data); +void gnome_vfs_async_read (GnomeVFSAsyncHandle *handle, + gpointer buffer, + guint bytes, + GnomeVFSAsyncReadCallback callback, + gpointer callback_data); +void gnome_vfs_async_write (GnomeVFSAsyncHandle *handle, + gconstpointer buffer, + guint bytes, + GnomeVFSAsyncWriteCallback callback, + gpointer callback_data); +void gnome_vfs_async_get_file_info (GnomeVFSAsyncHandle **handle_return, + GList *uri_list, + GnomeVFSFileInfoOptions options, + int priority, + GnomeVFSAsyncGetFileInfoCallback callback, + gpointer callback_data); +void gnome_vfs_async_set_file_info (GnomeVFSAsyncHandle **handle_return, + GnomeVFSURI *uri, + GnomeVFSFileInfo *info, + GnomeVFSSetFileInfoMask mask, + GnomeVFSFileInfoOptions options, + int priority, + GnomeVFSAsyncSetFileInfoCallback callback, + gpointer callback_data); +void gnome_vfs_async_load_directory (GnomeVFSAsyncHandle **handle_return, + const gchar *text_uri, + GnomeVFSFileInfoOptions options, + guint items_per_notification, + int priority, + GnomeVFSAsyncDirectoryLoadCallback callback, + gpointer callback_data); +void gnome_vfs_async_load_directory_uri + (GnomeVFSAsyncHandle **handle_return, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options, + guint items_per_notification, + int priority, + GnomeVFSAsyncDirectoryLoadCallback callback, + gpointer callback_data); +GnomeVFSResult gnome_vfs_async_xfer (GnomeVFSAsyncHandle **handle_return, + GList *source_uri_list, + GList *target_uri_list, + GnomeVFSXferOptions xfer_options, + GnomeVFSXferErrorMode error_mode, + GnomeVFSXferOverwriteMode overwrite_mode, + int priority, + GnomeVFSAsyncXferProgressCallback progress_update_callback, + gpointer update_callback_data, + GnomeVFSXferProgressCallback progress_sync_callback, + gpointer sync_callback_data); +void gnome_vfs_async_find_directory (GnomeVFSAsyncHandle **handle_return, + GList *near_uri_list, + GnomeVFSFindDirectoryKind kind, + gboolean create_if_needed, + gboolean find_if_needed, + guint permissions, + int priority, + GnomeVFSAsyncFindDirectoryCallback callback, + gpointer user_data); +void gnome_vfs_async_file_control (GnomeVFSAsyncHandle *handle, + const char *operation, + gpointer operation_data, + GDestroyNotify operation_data_destroy_func, + GnomeVFSAsyncFileControlCallback callback, + gpointer callback_data); + + + + + + + + + + + + +Description + + When executing an asynchornous operation on a file the program does not + block waiting for the operation to finish, instead it keeps on running, + which means that the process and the I/O operation can be both running + concurrently. Once the I/O operation has been completed the process is + notified using a callback. + + + + Asynchronous operations are particularly good when long I/O operations + are expected, in this case the program can continue normaly, the I/O + will be performed in the background. On the other hand when operations + are expected to be short (creating a file, writing/reading small amounts + of data, etc.) synchronous operations are prefered. + + + + Within a graphical desktop asynchornous I/O operations can be used to + avoid blocking the UI (User Interface) during a long operation, and + to be able to provide some kind of feedback to the user. + + + + +Details + +<anchor id="GNOME-VFS-PRIORITY-MIN-CAPS"/>GNOME_VFS_PRIORITY_MIN +GNOME_VFS_PRIORITY_MIN#define GNOME_VFS_PRIORITY_MIN -10 + + +The minimuum priority a job can have. + + + + +<anchor id="GNOME-VFS-PRIORITY-MAX-CAPS"/>GNOME_VFS_PRIORITY_MAX +GNOME_VFS_PRIORITY_MAX#define GNOME_VFS_PRIORITY_MAX 10 + + +The maximuum priority a job can have. + + + + +<anchor id="GNOME-VFS-PRIORITY-DEFAULT-CAPS"/>GNOME_VFS_PRIORITY_DEFAULT +GNOME_VFS_PRIORITY_DEFAULT#define GNOME_VFS_PRIORITY_DEFAULT 0 + + +The default job priority. Its best to use this +unless you have a reason to do otherwise. + + + + +<anchor id="GnomeVFSAsyncCallback"/>GnomeVFSAsyncCallback () +GnomeVFSAsyncCallbackvoid (*GnomeVFSAsyncCallback) (GnomeVFSAsyncHandle *handle, + GnomeVFSResult result, + gpointer callback_data); + +Basic callback from an async operation that passes no data back, +informing the user of the result of the operation. + + + +handle : + handle of the operation generating the callback + +result : + GNOME_VFS_OK if the operation was successful, otherwise +an error code. + +callback_data : + user data defined when the callback was established + + + +<anchor id="GnomeVFSAsyncOpenCallback"/>GnomeVFSAsyncOpenCallback +GnomeVFSAsyncOpenCallbacktypedef GnomeVFSAsyncCallback GnomeVFSAsyncOpenCallback; + + +Basic callback from an async operation that passes no data back, +informing the user of the result of the operation. + + + + +<anchor id="GnomeVFSAsyncCreateCallback"/>GnomeVFSAsyncCreateCallback +GnomeVFSAsyncCreateCallbacktypedef GnomeVFSAsyncCallback GnomeVFSAsyncCreateCallback; + + +Basic callback from an async operation that passes no data back, +informing the user of the result of the operation. + + + + +<anchor id="GnomeVFSAsyncCreateAsChannelCallback"/>GnomeVFSAsyncCreateAsChannelCallback +GnomeVFSAsyncCreateAsChannelCallbacktypedef GnomeVFSAsyncOpenAsChannelCallback GnomeVFSAsyncCreateAsChannelCallback; + + +Callback for the gnome_vfs_async_create_as_channel() function. + + + + +<anchor id="GnomeVFSAsyncCloseCallback"/>GnomeVFSAsyncCloseCallback +GnomeVFSAsyncCloseCallbacktypedef GnomeVFSAsyncCallback GnomeVFSAsyncCloseCallback; + + +Basic callback from an async operation that passes no data back, +informing the user of the result of the operation. + + + + +<anchor id="GnomeVFSAsyncReadCallback"/>GnomeVFSAsyncReadCallback () +GnomeVFSAsyncReadCallbackvoid (*GnomeVFSAsyncReadCallback) (GnomeVFSAsyncHandle *handle, + GnomeVFSResult result, + gpointer buffer, + GnomeVFSFileSize bytes_requested, + GnomeVFSFileSize bytes_read, + gpointer callback_data); + +Callback for the gnome_vfs_async_read() function. + + + +handle : + handle of the operation generating the callback + +result : + GNOME_VFS_OK if the operation was successful, otherwise +an error code. + +buffer : + buffer containing data read from handle. + +bytes_requested : + the number of bytes asked for in the call to +gnome_vfs_async_read(). + +bytes_read : + the number of bytes actually read from handle into buffer. + +callback_data : + user data defined when the callback was established + + + +<anchor id="GnomeVFSAsyncWriteCallback"/>GnomeVFSAsyncWriteCallback () +GnomeVFSAsyncWriteCallbackvoid (*GnomeVFSAsyncWriteCallback) (GnomeVFSAsyncHandle *handle, + GnomeVFSResult result, + gconstpointer buffer, + GnomeVFSFileSize bytes_requested, + GnomeVFSFileSize bytes_written, + gpointer callback_data); + +Callback for the gnome_vfs_async_write() function. + + + +handle : + handle of the operation generating the callback + +result : + GNOME_VFS_OK if the operation was successful, otherwise +an error code. + +buffer : + buffer containing data written to handle. + +bytes_requested : + the number of bytes asked to write in the call to +gnome_vfs_async_write(). + +bytes_written : + the number of bytes actually written to handle from buffer. + +callback_data : + user data defined when the callback was established + + + +<anchor id="GnomeVFSFindDirectoryResult"/>GnomeVFSFindDirectoryResult +GnomeVFSFindDirectoryResulttypedef struct { + GnomeVFSURI *uri; + GnomeVFSResult result; + + /* Reserved to avoid future breaks in ABI compatibility */ + void *reserved1; + void *reserved2; +} GnomeVFSFindDirectoryResult; + + + + + +<anchor id="gnome-vfs-async-set-job-limit"/>gnome_vfs_async_set_job_limit () +gnome_vfs_async_set_job_limitvoid gnome_vfs_async_set_job_limit (int limit); + +Restrict the number of worker threads used by Async operations +to limit. + + + +limit : + maximuum number of allowable threads + + + +<anchor id="gnome-vfs-async-get-job-limit"/>gnome_vfs_async_get_job_limit () +gnome_vfs_async_get_job_limitint gnome_vfs_async_get_job_limit (void); + +Get the current maximuum allowable number of +worker threads for Asynch operations. + + + +Returns : current maximuum number of threads + + + +<anchor id="gnome-vfs-async-cancel"/>gnome_vfs_async_cancel () +gnome_vfs_async_cancelvoid gnome_vfs_async_cancel (GnomeVFSAsyncHandle *handle); + +Cancel an asynchronous operation and close all its callbacks. +Its possible to still receive another call or two on the callback. + + + +handle : + handle of the async operation to be cancelled + + + +<anchor id="gnome-vfs-async-open"/>gnome_vfs_async_open () +gnome_vfs_async_openvoid gnome_vfs_async_open (GnomeVFSAsyncHandle **handle_return, + const gchar *text_uri, + GnomeVFSOpenMode open_mode, + int priority, + GnomeVFSAsyncOpenCallback callback, + gpointer callback_data); + +Open text_uri according to mode open_mode. On return, handle_return will +contain a pointer to the operation. Once the file has been successfully opened, +callback will be called with the GnomeVFSResult. + + + +handle_return : + A pointer to a pointer to a GnomeVFSHandle object + +text_uri : + string of the URI to open + +open_mode : + Open mode + +priority : + a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. + +callback : + function to be called when the operation is complete + +callback_data : + data to pass callback + + + +<anchor id="gnome-vfs-async-open-uri"/>gnome_vfs_async_open_uri () +gnome_vfs_async_open_urivoid gnome_vfs_async_open_uri (GnomeVFSAsyncHandle **handle_return, + GnomeVFSURI *uri, + GnomeVFSOpenMode open_mode, + int priority, + GnomeVFSAsyncOpenCallback callback, + gpointer callback_data); + +Open uri according to mode open_mode. On return, handle_return will +contain a pointer to the operation. Once the file has been successfully opened, +callback will be called with the GnomeVFSResult. + + + +handle_return : + A pointer to a pointer to a GnomeVFSHandle object + +uri : + URI to open + +open_mode : + Open mode + +priority : + a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. + +callback : + function to be called when the operation is complete + +callback_data : + data to pass callback + + + +<anchor id="gnome-vfs-async-open-as-channel"/>gnome_vfs_async_open_as_channel () +gnome_vfs_async_open_as_channelvoid gnome_vfs_async_open_as_channel (GnomeVFSAsyncHandle **handle_return, + const gchar *text_uri, + GnomeVFSOpenMode open_mode, + guint advised_block_size, + int priority, + GnomeVFSAsyncOpenAsChannelCallback callback, + gpointer callback_data); + +Open text_uri as a GIOChannel. Once the channel has been established +callback will be called with callback_data, the result of the operation, +and if the result was GNOME_VFS_OK, a reference to a GIOChannel pointing +at text_uri in open_mode. + + + +handle_return : + A pointer to a pointer to a GnomeVFSHandle object + +text_uri : + string of the URI to open as a GIOChannel + +open_mode : + open for reading, writing, random, etc + +advised_block_size : + the preferred block size for GIOChannel to read + +priority : + a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. + +callback : + function to be called when the operation is complete + +callback_data : + data to pass callback + + + +<anchor id="gnome-vfs-async-open-uri-as-channel"/>gnome_vfs_async_open_uri_as_channel () +gnome_vfs_async_open_uri_as_channelvoid gnome_vfs_async_open_uri_as_channel + (GnomeVFSAsyncHandle **handle_return, + GnomeVFSURI *uri, + GnomeVFSOpenMode open_mode, + guint advised_block_size, + int priority, + GnomeVFSAsyncOpenAsChannelCallback callback, + gpointer callback_data); + +Open uri as a GIOChannel. Once the channel has been established +callback will be called with callback_data, the result of the operation, +and if the result was GNOME_VFS_OK, a reference to a GIOChannel pointing +at uri in open_mode. + + + +handle_return : + A pointer to a pointer to a GnomeVFSHandle object + +uri : + URI to open as a GIOChannel + +open_mode : + open for reading, writing, random, etc + +advised_block_size : + the preferred block size for GIOChannel to read + +priority : + a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. + +callback : + function to be called when the operation is complete + +callback_data : + data to pass callback + + + +<anchor id="gnome-vfs-async-create"/>gnome_vfs_async_create () +gnome_vfs_async_createvoid gnome_vfs_async_create (GnomeVFSAsyncHandle **handle_return, + const gchar *text_uri, + GnomeVFSOpenMode open_mode, + gboolean exclusive, + guint perm, + int priority, + GnomeVFSAsyncOpenCallback callback, + gpointer callback_data); + +Create a file at uri according to mode open_mode, with permissions perm (in +the standard UNIX packed bit permissions format). When the create has been completed +callback will be called with the result code and callback_data. + + + +handle_return : + A pointer to a pointer to a GnomeVFSHandle object + +text_uri : + String representing the URI to create + +open_mode : + mode to leave the file opened in after creation (or GNOME_VFS_OPEN_MODE_NONE +to leave the file closed after creation) + +exclusive : + Whether the file should be created in "exclusive" mode: +i.e. if this flag is nonzero, operation will fail if a file with the +same name already exists. + +perm : + Bitmap representing the permissions for the newly created file +(Unix style). + +priority : + a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. + +callback : + function to be called when the operation is complete + +callback_data : + data to pass callback + + + +<anchor id="gnome-vfs-async-create-uri"/>gnome_vfs_async_create_uri () +gnome_vfs_async_create_urivoid gnome_vfs_async_create_uri (GnomeVFSAsyncHandle **handle_return, + GnomeVFSURI *uri, + GnomeVFSOpenMode open_mode, + gboolean exclusive, + guint perm, + int priority, + GnomeVFSAsyncOpenCallback callback, + gpointer callback_data); + +Create a file at uri according to mode open_mode, with permissions perm (in +the standard UNIX packed bit permissions format). When the create has been completed +callback will be called with the result code and callback_data. + + + +handle_return : + A pointer to a pointer to a GnomeVFSHandle object + +uri : + the URI to create a file at + +open_mode : + mode to leave the file opened in after creation (or GNOME_VFS_OPEN_MODE_NONE +to leave the file closed after creation) + +exclusive : + Whether the file should be created in "exclusive" mode: +i.e. if this flag is nonzero, operation will fail if a file with the +same name already exists. + +perm : + Bitmap representing the permissions for the newly created file +(Unix style). + +priority : + a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. + +callback : + function to be called when the operation is complete + +callback_data : + data to pass callback + + + +<anchor id="gnome-vfs-async-create-symbolic-link"/>gnome_vfs_async_create_symbolic_link () +gnome_vfs_async_create_symbolic_linkvoid gnome_vfs_async_create_symbolic_link + (GnomeVFSAsyncHandle **handle_return, + GnomeVFSURI *uri, + const gchar *uri_reference, + int priority, + GnomeVFSAsyncOpenCallback callback, + gpointer callback_data); + +Create a symbolic link at uri pointing to uri_reference. When the operation +has complete callback will be called with the result of the operation and +callback_data. + + + +handle_return : + when the function returns will point to a handle for +the async operation. + +uri : + location to create the link at + +uri_reference : + location to point uri to (can be a URI fragment, i.e. relative) + +priority : + a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. + +callback : + function to be called when the operation is complete + +callback_data : + data to pass callback + + + +<anchor id="gnome-vfs-async-create-as-channel"/>gnome_vfs_async_create_as_channel () +gnome_vfs_async_create_as_channelvoid gnome_vfs_async_create_as_channel + (GnomeVFSAsyncHandle **handle_return, + const gchar *text_uri, + GnomeVFSOpenMode open_mode, + gboolean exclusive, + guint perm, + int priority, + GnomeVFSAsyncCreateAsChannelCallback callback, + gpointer callback_data); + +Open text_uri as a GIOChannel, creating it as necessary. Once the channel has +been established callback will be called with callback_data, the result of the +operation, and if the result was GNOME_VFS_OK, a reference to a GIOChannel pointing +at text_uri in open_mode. + + + +handle_return : + A pointer to a pointer to a GnomeVFSHandle object + +text_uri : + string of the URI to open as a GIOChannel, creating it as necessary + +open_mode : + open for reading, writing, random, etc + +exclusive : + replace the file if it already exists + +perm : + standard POSIX-style permissions bitmask, permissions of created file + +priority : + a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. + +callback : + function to be called when the operation is complete + +callback_data : + data to pass callback + + + +<anchor id="gnome-vfs-async-create-uri-as-channel"/>gnome_vfs_async_create_uri_as_channel () +gnome_vfs_async_create_uri_as_channelvoid gnome_vfs_async_create_uri_as_channel + (GnomeVFSAsyncHandle **handle_return, + GnomeVFSURI *uri, + GnomeVFSOpenMode open_mode, + gboolean exclusive, + guint perm, + int priority, + GnomeVFSAsyncCreateAsChannelCallback callback, + gpointer callback_data); + + + +handle_return : + + +uri : + + +open_mode : + + +exclusive : + + +perm : + + +priority : + + +callback : + + +callback_data : + + + + + + +<anchor id="gnome-vfs-async-close"/>gnome_vfs_async_close () +gnome_vfs_async_closevoid gnome_vfs_async_close (GnomeVFSAsyncHandle *handle, + GnomeVFSAsyncCloseCallback callback, + gpointer callback_data); + +Close a handle opened with gnome_vfs_async_open(). When the close +has completed, callback will be called with callback_data and +the result of the operation. + + + +handle : + async handle to close + +callback : + function to be called when the operation is complete + +callback_data : + data to pass callback + + + +<anchor id="gnome-vfs-async-read"/>gnome_vfs_async_read () +gnome_vfs_async_readvoid gnome_vfs_async_read (GnomeVFSAsyncHandle *handle, + gpointer buffer, + guint bytes, + GnomeVFSAsyncReadCallback callback, + gpointer callback_data); + +Read bytes bytes from the file pointed to be handle into buffer. +When the operation is complete, callback will be called with the +result of the operation and callback_data. + + + +handle : + handle for the file to be read + +buffer : + allocated block of memory to read into + +bytes : + number of bytes to read + +callback : + function to be called when the operation is complete + +callback_data : + data to pass callback + + + +<anchor id="gnome-vfs-async-write"/>gnome_vfs_async_write () +gnome_vfs_async_writevoid gnome_vfs_async_write (GnomeVFSAsyncHandle *handle, + gconstpointer buffer, + guint bytes, + GnomeVFSAsyncWriteCallback callback, + gpointer callback_data); + +Write bytes bytes from buffer into the file pointed to be handle. +When the operation is complete, callback will be called with the +result of the operation and callback_data. + + + +handle : + handle for the file to be written + +buffer : + block of memory containing data to be written + +bytes : + number of bytes to write + +callback : + function to be called when the operation is complete + +callback_data : + data to pass callback + + + +<anchor id="gnome-vfs-async-get-file-info"/>gnome_vfs_async_get_file_info () +gnome_vfs_async_get_file_infovoid gnome_vfs_async_get_file_info (GnomeVFSAsyncHandle **handle_return, + GList *uri_list, + GnomeVFSFileInfoOptions options, + int priority, + GnomeVFSAsyncGetFileInfoCallback callback, + gpointer callback_data); + +Fetch information about the files indicated in uris and return the +information progressively to callback. + + + +handle_return : + when the function returns will point to a handle for +the async operation. + +uri_list : + a GList of GnomeVFSURIs to fetch information about + +options : + packed boolean type providing control over various details +of the get_file_info operation. + +priority : + a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. + +callback : + function to be called when the operation is complete + +callback_data : + data to pass callback + + + +<anchor id="gnome-vfs-async-set-file-info"/>gnome_vfs_async_set_file_info () +gnome_vfs_async_set_file_infovoid gnome_vfs_async_set_file_info (GnomeVFSAsyncHandle **handle_return, + GnomeVFSURI *uri, + GnomeVFSFileInfo *info, + GnomeVFSSetFileInfoMask mask, + GnomeVFSFileInfoOptions options, + int priority, + GnomeVFSAsyncSetFileInfoCallback callback, + gpointer callback_data); + +Set "file info" details about the file at uri, such as permissions, name, +owner, and modification time. + + + +handle_return : + when the function returns will point to a handle for +the async operation. + +uri : + the URI to set the file info of + +info : + the struct containing new information about the file + +mask : + control which fields of info are changed about the file at uri + +options : + packed boolean type providing control over various details +of the set_file_info operation. + +priority : + a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. + +callback : + function to be called when the operation is complete + +callback_data : + data to pass callback + + + +<anchor id="gnome-vfs-async-load-directory"/>gnome_vfs_async_load_directory () +gnome_vfs_async_load_directoryvoid gnome_vfs_async_load_directory (GnomeVFSAsyncHandle **handle_return, + const gchar *text_uri, + GnomeVFSFileInfoOptions options, + guint items_per_notification, + int priority, + GnomeVFSAsyncDirectoryLoadCallback callback, + gpointer callback_data); + +Read the contents of the directory at text_uri, passing back GnomeVFSFileInfo +structs about each file in the directory to callback. items_per_notification +files will be processed between each call to callback. + + + +handle_return : + when the function returns will point to a handle for +the async operation. + +text_uri : + string representing the URI of the directory to be loaded + +options : + packed boolean type providing control over various details +of the get_file_info operation. + +items_per_notification : + number of files to process in a row before calling callback + +priority : + a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. + +callback : + function to be called when the operation is complete + +callback_data : + data to pass callback + + + +<anchor id="gnome-vfs-async-load-directory-uri"/>gnome_vfs_async_load_directory_uri () +gnome_vfs_async_load_directory_urivoid gnome_vfs_async_load_directory_uri + (GnomeVFSAsyncHandle **handle_return, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options, + guint items_per_notification, + int priority, + GnomeVFSAsyncDirectoryLoadCallback callback, + gpointer callback_data); + +Read the contents of the directory at uri, passing back GnomeVFSFileInfo structs +about each file in the directory to callback. items_per_notification +files will be processed between each call to callback. + + + +handle_return : + when the function returns will point to a handle for +the async operation. + +uri : + string representing the URI of the directory to be loaded + +options : + packed boolean type providing control over various details +of the get_file_info operation. + +items_per_notification : + number of files to process in a row before calling callback + +priority : + a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. + +callback : + function to be called when the operation is complete + +callback_data : + data to pass callback + + + +<anchor id="gnome-vfs-async-xfer"/>gnome_vfs_async_xfer () +gnome_vfs_async_xferGnomeVFSResult gnome_vfs_async_xfer (GnomeVFSAsyncHandle **handle_return, + GList *source_uri_list, + GList *target_uri_list, + GnomeVFSXferOptions xfer_options, + GnomeVFSXferErrorMode error_mode, + GnomeVFSXferOverwriteMode overwrite_mode, + int priority, + GnomeVFSAsyncXferProgressCallback progress_update_callback, + gpointer update_callback_data, + GnomeVFSXferProgressCallback progress_sync_callback, + gpointer sync_callback_data); + +Perform a copy operation in a seperate thread. progress_update_callback will be periodically +polled with status of the operation (percent done, the current phase of operation, the +current file being operated upon). If the xfer engine needs to query the caller to make +a decision or report on important error it will do so on progress_sync_callback. + + + +handle_return : + when the function returns will point to a handle for + +source_uri_list : + GList of GnomeVFSURI representing the files to be transferred + +target_uri_list : + GList of GnomeVFSURI, the target locations for the elements +in source_uri_list + +xfer_options : + various options controlling the details of the transfer. +Use GNOME_VFS_XFER_REMOUVESOURCE to make the operation a move rather than a copy. + +error_mode : + report errors to the progress_sync_callback, or simply abort + +overwrite_mode : + controls whether the xfer engine will overwrite automatically, +skip the file, abort the operation, or query progress_sync_callback + +priority : + a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. + +progress_update_callback : + called periodically to keep the client appraised of progress +in completing the XFer operation, and the current phase of operation. + +update_callback_data : + user data passed to progress_update_callback + +progress_sync_callback : + called when the program requires responses to interactive queries +(e.g. overwriting files, handling errors, etc) + +sync_callback_data : + user data passed to progress_sync_callback + +Returns : GNOME_VFS_OK if the paramaters were in order, +or GNOME_VFS_ERROR_BAD_PARAMETERS if something was wrong in the passed in arguments. + + + +<anchor id="gnome-vfs-async-find-directory"/>gnome_vfs_async_find_directory () +gnome_vfs_async_find_directoryvoid gnome_vfs_async_find_directory (GnomeVFSAsyncHandle **handle_return, + GList *near_uri_list, + GnomeVFSFindDirectoryKind kind, + gboolean create_if_needed, + gboolean find_if_needed, + guint permissions, + int priority, + GnomeVFSAsyncFindDirectoryCallback callback, + gpointer user_data); + +There is quite a complicated logic behind finding/creating a Trash directory +and you need to be aware of some implications: +Finding the Trash the first time when using the file method may be pretty +expensive. A cache file is used to store the location of that Trash file +for next time. +If ceate_if_needed is specified without find_if_needed, you may end up +creating a Trash file when there already is one. Your app should start out +by doing a gnome_vfs_find_directory with the find_if_needed to avoid this +and then use the create_if_needed flag to create Trash lazily when it is +needed for throwing away an item on a given disk. + + +When the operation has completed, callback will be called with the result +of the operation and user_data. + + + +handle_return : + when the function returns will point to a handle for + +near_uri_list : + a GList of GnomeVFSURIs, find a special directory on the same +volume as uris + +kind : + kind of special directory + +create_if_needed : + If directory we are looking for does not exist, try to create it + +find_if_needed : + If we don't know where the directory is yet, look for it. + +permissions : + If creating, use these permissions + +priority : + a value from GNOME_VFS_PRIORITY_MIN to GNOME_VFS_PRIORITY_MAX (normally +should be GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job +in allocating threads from the thread pool. + +callback : + function to be called when the operation is complete + +user_data : + data to pass callback * +Used to return special directories such as Trash and Desktop from different +file systems. + + + +<anchor id="gnome-vfs-async-file-control"/>gnome_vfs_async_file_control () +gnome_vfs_async_file_controlvoid gnome_vfs_async_file_control (GnomeVFSAsyncHandle *handle, + const char *operation, + gpointer operation_data, + GDestroyNotify operation_data_destroy_func, + GnomeVFSAsyncFileControlCallback callback, + gpointer callback_data); + +Execute a backend dependent operation specified by the string operation. +This is typically used for specialized vfs backends that need additional +operations that gnome-vfs doesn't have. Compare it to the unix call ioctl(). +The format of operation_data depends on the operation. Operation that are +backend specific are normally namespaced by their module name. + + +When the operation is complete, callback will be called with the +result of the operation, operation_data and callback_data. + + + +handle : + handle of the file to affect + +operation : + The operation to execute + +operation_data : + The data needed to execute the operation + +operation_data_destroy_func : + Called to destroy operation_data when its no longer needed + +callback : + function to be called when the operation is complete + +callback_data : + data to pass callback + +Since 2.2 + + + + + + + + diff --git a/doc/xml/gnome-vfs-cancellation.xml b/doc/xml/gnome-vfs-cancellation.xml new file mode 100644 index 0000000..55e6cb5 --- /dev/null +++ b/doc/xml/gnome-vfs-cancellation.xml @@ -0,0 +1,142 @@ + + +Cancellation +3 +GNOME-VFS-2.0 Library + + + +Cancellation +halt in-progress operations + + +Synopsis + + + + + +GnomeVFSCancellation* gnome_vfs_cancellation_new + (void); +void gnome_vfs_cancellation_destroy (GnomeVFSCancellation *cancellation); +void gnome_vfs_cancellation_cancel (GnomeVFSCancellation *cancellation); +gboolean gnome_vfs_cancellation_check (GnomeVFSCancellation *cancellation); +void gnome_vfs_cancellation_ack (GnomeVFSCancellation *cancellation); +gint gnome_vfs_cancellation_get_fd (GnomeVFSCancellation *cancellation); + + + + + + + + + + + + +Description + + + + + + +Details + +<anchor id="gnome-vfs-cancellation-new"/>gnome_vfs_cancellation_new () +gnome_vfs_cancellation_newGnomeVFSCancellation* gnome_vfs_cancellation_new + (void); + +Create a new GnomeVFSCancellation object for reporting cancellation to a +GNOME VFS module. + + + +Returns : A pointer to the new GnomeVFSCancellation object. + + + +<anchor id="gnome-vfs-cancellation-destroy"/>gnome_vfs_cancellation_destroy () +gnome_vfs_cancellation_destroyvoid gnome_vfs_cancellation_destroy (GnomeVFSCancellation *cancellation); + +Destroy cancellation. + + + +cancellation : + A GnomeVFSCancellation object + + + +<anchor id="gnome-vfs-cancellation-cancel"/>gnome_vfs_cancellation_cancel () +gnome_vfs_cancellation_cancelvoid gnome_vfs_cancellation_cancel (GnomeVFSCancellation *cancellation); + +Send a cancellation request through cancellation. + + + +cancellation : + A GnomeVFSCancellation object + + + +<anchor id="gnome-vfs-cancellation-check"/>gnome_vfs_cancellation_check () +gnome_vfs_cancellation_checkgboolean gnome_vfs_cancellation_check (GnomeVFSCancellation *cancellation); + +Check for pending cancellation. + + + +cancellation : + A GnomeVFSCancellation object + +Returns : TRUE if the operation should be interrupted. + + + +<anchor id="gnome-vfs-cancellation-ack"/>gnome_vfs_cancellation_ack () +gnome_vfs_cancellation_ackvoid gnome_vfs_cancellation_ack (GnomeVFSCancellation *cancellation); + +Acknowledge a cancellation. This should be called if +`gnome_vfs_cancellation_check()' returns TRUE or if `select()' reports that +input is available on the file descriptor returned by +`gnome_vfs_cancellation_get_fd()'. + + + +cancellation : + A GnomeVFSCancellation object + + + +<anchor id="gnome-vfs-cancellation-get-fd"/>gnome_vfs_cancellation_get_fd () +gnome_vfs_cancellation_get_fdgint gnome_vfs_cancellation_get_fd (GnomeVFSCancellation *cancellation); + +Get a file descriptor -based notificator for cancellation. When +cancellation receives a cancellation request, a character will be made +available on the returned file descriptor for input. + + +This is very useful for detecting cancellation during I/O operations: you +can use the `select()' call to check for available input/output on the file +you are reading/writing, and on the notificator's file descriptor at the +same time. If a data is available on the notificator's file descriptor, you +know you have to cancel the read/write operation. + + + +cancellation : + A GnomeVFSCancellation object + +Returns : the notificator's file descriptor, or -1 if starved of + file descriptors. + + + + + + + + + diff --git a/doc/xml/gnome-vfs-context.xml b/doc/xml/gnome-vfs-context.xml new file mode 100644 index 0000000..5732047 --- /dev/null +++ b/doc/xml/gnome-vfs-context.xml @@ -0,0 +1,131 @@ + + +GnomeVFSContext +3 +GNOME-VFS-2.0 Library + + + +GnomeVFSContext +contexts allows modules to track thread usage and cancellation properly + + +Synopsis + + + + + +GnomeVFSContext* gnome_vfs_context_new (void); +void gnome_vfs_context_free (GnomeVFSContext *ctx); +GnomeVFSCancellation* gnome_vfs_context_get_cancellation + (const GnomeVFSContext *ctx); +#define gnome_vfs_context_check_cancellation(x) +const GnomeVFSContext* gnome_vfs_context_peek_current + (void); +gboolean gnome_vfs_context_check_cancellation_current + (void); + + + + + + + + + + + + +Description + + + + + + +Details + +<anchor id="gnome-vfs-context-new"/>gnome_vfs_context_new () +gnome_vfs_context_newGnomeVFSContext* gnome_vfs_context_new (void); + +Creates a new context and cancellation object. Must be called +from the main glib event loop. + + + +Returns : a newly allocated GnomeVFSContext + + + +<anchor id="gnome-vfs-context-free"/>gnome_vfs_context_free () +gnome_vfs_context_freevoid gnome_vfs_context_free (GnomeVFSContext *ctx); + +Free ctx and destroy the associated GnomeVFSCancellation. + + + +ctx : + context to be freed + + + +<anchor id="gnome-vfs-context-get-cancellation"/>gnome_vfs_context_get_cancellation () +gnome_vfs_context_get_cancellationGnomeVFSCancellation* gnome_vfs_context_get_cancellation + (const GnomeVFSContext *ctx); + +Retrieve the GnomeVFSCancellation associated with ctx. + + + +ctx : + context to get the GnomeVFSCancellation from + +Returns : ctx 's GnomeVFSCancellation + + + +<anchor id="gnome-vfs-context-check-cancellation"/>gnome_vfs_context_check_cancellation() +gnome_vfs_context_check_cancellation#define gnome_vfs_context_check_cancellation(x) + + + +x : + + + + + + +<anchor id="gnome-vfs-context-peek-current"/>gnome_vfs_context_peek_current () +gnome_vfs_context_peek_currentconst GnomeVFSContext* gnome_vfs_context_peek_current + (void); + +Get the currently active context. It shouldn't be +manipulated but can be compared to context's the module +holds to determine whether they are active. + + + +Returns : the currently active GnomeVFSContext + + + +<anchor id="gnome-vfs-context-check-cancellation-current"/>gnome_vfs_context_check_cancellation_current () +gnome_vfs_context_check_cancellation_currentgboolean gnome_vfs_context_check_cancellation_current + (void); + +Check to see if the currently active context has been cancelled. + + + +Returns : TRUE if the currently active context has been cancelled, otherwise FALSE + + + + + + + + + diff --git a/doc/xml/gnome-vfs-directory-basic-ops.xml b/doc/xml/gnome-vfs-directory-basic-ops.xml new file mode 100644 index 0000000..7ed6c9b --- /dev/null +++ b/doc/xml/gnome-vfs-directory-basic-ops.xml @@ -0,0 +1,120 @@ + + +Basic Directory Operations +3 +GNOME-VFS-2.0 Library + + + +Basic Directory Operations +Creating and removing directories. + + +Synopsis + + + + + +GnomeVFSResult gnome_vfs_make_directory (const gchar *text_uri, + guint perm); +GnomeVFSResult gnome_vfs_make_directory_for_uri + (GnomeVFSURI *uri, + guint perm); +GnomeVFSResult gnome_vfs_remove_directory (const gchar *text_uri); +GnomeVFSResult gnome_vfs_remove_directory_from_uri + (GnomeVFSURI *uri); + + + + + + + + + + + + +Description + + + + + + +Details + +<anchor id="gnome-vfs-make-directory"/>gnome_vfs_make_directory () +gnome_vfs_make_directoryGnomeVFSResult gnome_vfs_make_directory (const gchar *text_uri, + guint perm); + +Create text_uri as a directory. + + + +text_uri : + URI of the directory to be created + +perm : + Unix-style permissions for the newly created directory + +Returns : An integer representing the result of the operation + + + +<anchor id="gnome-vfs-make-directory-for-uri"/>gnome_vfs_make_directory_for_uri () +gnome_vfs_make_directory_for_uriGnomeVFSResult gnome_vfs_make_directory_for_uri + (GnomeVFSURI *uri, + guint perm); + +Create a directory at uri. Only succeeds if a file or directory +does not already exist at uri. + + + +uri : + URI of the directory to be created + +perm : + Unix-style permissions for the newly created directory + +Returns : An integer representing the result of the operation + + + +<anchor id="gnome-vfs-remove-directory"/>gnome_vfs_remove_directory () +gnome_vfs_remove_directoryGnomeVFSResult gnome_vfs_remove_directory (const gchar *text_uri); + +Remove text_uri. text_uri must be an empty directory. + + + +text_uri : + URI of the directory to be removed + +Returns : An integer representing the result of the operation + + + +<anchor id="gnome-vfs-remove-directory-from-uri"/>gnome_vfs_remove_directory_from_uri () +gnome_vfs_remove_directory_from_uriGnomeVFSResult gnome_vfs_remove_directory_from_uri + (GnomeVFSURI *uri); + +Remove uri. uri must be an empty directory. + + + +uri : + URI of the directory to be removed + +Returns : An integer representing the result of the operation + + + + + + + + + diff --git a/doc/xml/gnome-vfs-directory-find-ops.xml b/doc/xml/gnome-vfs-directory-find-ops.xml new file mode 100644 index 0000000..b84d91b --- /dev/null +++ b/doc/xml/gnome-vfs-directory-find-ops.xml @@ -0,0 +1,109 @@ + + +Locating Standard Directories +3 +GNOME-VFS-2.0 Library + + + +Locating Standard Directories +Utilities for locating standard directories such as the desktop and trash + + +Synopsis + + + + + +enum GnomeVFSFindDirectoryKind; +GnomeVFSResult gnome_vfs_find_directory (GnomeVFSURI *near_uri, + GnomeVFSFindDirectoryKind kind, + GnomeVFSURI **result, + gboolean create_if_needed, + gboolean find_if_needed, + guint permissions); + + + + + + + + + + + + +Description + + + + + + +Details + +<anchor id="GnomeVFSFindDirectoryKind"/>enum GnomeVFSFindDirectoryKind +GnomeVFSFindDirectoryKindtypedef enum { + GNOME_VFS_DIRECTORY_KIND_DESKTOP = 1000, + GNOME_VFS_DIRECTORY_KIND_TRASH = 1001 +} GnomeVFSFindDirectoryKind; + + + + + +<anchor id="gnome-vfs-find-directory"/>gnome_vfs_find_directory () +gnome_vfs_find_directoryGnomeVFSResult gnome_vfs_find_directory (GnomeVFSURI *near_uri, + GnomeVFSFindDirectoryKind kind, + GnomeVFSURI **result, + gboolean create_if_needed, + gboolean find_if_needed, + guint permissions); + +Used to return well known directories such as Trash, Desktop, etc. from different +file systems. + + +There is quite a complicated logic behind finding/creating a Trash directory +and you need to be aware of some implications: +Finding the Trash the first time when using the file method may be pretty +expensive. A cache file is used to store the location of that Trash file +for next time. +If ceate_if_needed is specified without find_if_needed, you may end up +creating a Trash file when there already is one. Your app should start out +by doing a gnome_vfs_find_directory with the find_if_needed to avoid this +and then use the create_if_needed flag to create Trash lazily when it is +needed for throwing away an item on a given disk. + + + +near_uri : + find a well known directory on the same volume as near_uri + +kind : + kind of well known directory + +result : + newly created URI of the directory we found + +create_if_needed : + If directory we are looking for does not exist, try to create it + +find_if_needed : + If we don't know where trash is yet, look for it. + +permissions : + If creating, use these permissions + +Returns : An integer representing the result of the operation + + + + + + + + + diff --git a/doc/xml/gnome-vfs-directory-list-ops.xml b/doc/xml/gnome-vfs-directory-list-ops.xml new file mode 100644 index 0000000..54601ed --- /dev/null +++ b/doc/xml/gnome-vfs-directory-list-ops.xml @@ -0,0 +1,394 @@ + + +Listing Directory Contents +3 +GNOME-VFS-2.0 Library + + + +Listing Directory Contents +Listing the contents of directories. + + +Synopsis + + + + + +enum GnomeVFSDirectoryVisitOptions; +gboolean (*GnomeVFSDirectoryVisitFunc) (const gchar *rel_path, + GnomeVFSFileInfo *info, + gboolean recursing_will_loop, + gpointer data, + gboolean *recurse); +GnomeVFSResult gnome_vfs_directory_open (GnomeVFSDirectoryHandle **handle, + const gchar *text_uri, + GnomeVFSFileInfoOptions options); +GnomeVFSResult gnome_vfs_directory_open_from_uri + (GnomeVFSDirectoryHandle **handle, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options); +GnomeVFSResult gnome_vfs_directory_read_next + (GnomeVFSDirectoryHandle *handle, + GnomeVFSFileInfo *file_info); +GnomeVFSResult gnome_vfs_directory_close (GnomeVFSDirectoryHandle *handle); +GnomeVFSResult gnome_vfs_directory_visit (const gchar *uri, + GnomeVFSFileInfoOptions info_options, + GnomeVFSDirectoryVisitOptions visit_options, + GnomeVFSDirectoryVisitFunc callback, + gpointer data); +GnomeVFSResult gnome_vfs_directory_visit_uri + (GnomeVFSURI *uri, + GnomeVFSFileInfoOptions info_options, + GnomeVFSDirectoryVisitOptions visit_options, + GnomeVFSDirectoryVisitFunc callback, + gpointer data); +GnomeVFSResult gnome_vfs_directory_visit_files + (const gchar *text_uri, + GList *file_list, + GnomeVFSFileInfoOptions info_options, + GnomeVFSDirectoryVisitOptions visit_options, + GnomeVFSDirectoryVisitFunc callback, + gpointer data); +GnomeVFSResult gnome_vfs_directory_visit_files_at_uri + (GnomeVFSURI *uri, + GList *file_list, + GnomeVFSFileInfoOptions info_options, + GnomeVFSDirectoryVisitOptions visit_options, + GnomeVFSDirectoryVisitFunc callback, + gpointer data); +GnomeVFSResult gnome_vfs_directory_list_load + (GList **list, + const gchar *text_uri, + GnomeVFSFileInfoOptions options); + + + + + + + + + + + + +Description + + + + + + +Details + +<anchor id="GnomeVFSDirectoryVisitOptions"/>enum GnomeVFSDirectoryVisitOptions +GnomeVFSDirectoryVisitOptionstypedef enum { + GNOME_VFS_DIRECTORY_VISIT_DEFAULT = 0, + GNOME_VFS_DIRECTORY_VISIT_SAMEFS = 1 << 0, + GNOME_VFS_DIRECTORY_VISIT_LOOPCHECK = 1 << 1 +} GnomeVFSDirectoryVisitOptions; + + +This options control the way in which directories are visited. + + + + +GNOME_VFS_DIRECTORY_VISIT_DEFAULT + + + + +GNOME_VFS_DIRECTORY_VISIT_SAMEFS + Visit only directories on the same +file system as the parent + + + +GNOME_VFS_DIRECTORY_VISIT_LOOPCHECK + Loop prevention + + + + +<anchor id="GnomeVFSDirectoryVisitFunc"/>GnomeVFSDirectoryVisitFunc () +GnomeVFSDirectoryVisitFuncgboolean (*GnomeVFSDirectoryVisitFunc) (const gchar *rel_path, + GnomeVFSFileInfo *info, + gboolean recursing_will_loop, + gpointer data, + gboolean *recurse); + + + +rel_path : + + +info : + + +recursing_will_loop : + + +data : + + +recurse : + + +Returns : + + + + + +<anchor id="gnome-vfs-directory-open"/>gnome_vfs_directory_open () +gnome_vfs_directory_openGnomeVFSResult gnome_vfs_directory_open (GnomeVFSDirectoryHandle **handle, + const gchar *text_uri, + GnomeVFSFileInfoOptions options); + +Open directory text_uri for reading. On return, @*handle will point to +a GnomeVFSDirectoryHandle object which can be used to read the directory +entries one by one. + + + +handle : + A pointer to a pointer to a GnomeVFSDirectoryHandle object + +text_uri : + String representing the URI to open + +options : + Options for reading file information + +Returns : An integer representing the result of the operation + + + +<anchor id="gnome-vfs-directory-open-from-uri"/>gnome_vfs_directory_open_from_uri () +gnome_vfs_directory_open_from_uriGnomeVFSResult gnome_vfs_directory_open_from_uri + (GnomeVFSDirectoryHandle **handle, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options); + +Open directory text_uri for reading. On return, @*handle will point to +a GnomeVFSDirectoryHandle object which can be used to read the directory +entries one by one. + + + +handle : + A pointer to a pointer to a GnomeVFSDirectoryHandle object + +uri : + URI to open + +options : + Options for reading file information + +Returns : An integer representing the result of the operation. + + + +<anchor id="gnome-vfs-directory-read-next"/>gnome_vfs_directory_read_next () +gnome_vfs_directory_read_nextGnomeVFSResult gnome_vfs_directory_read_next + (GnomeVFSDirectoryHandle *handle, + GnomeVFSFileInfo *file_info); + +Read the next directory entry from handle. + + + +handle : + A directory handle + +file_info : + Pointer to a GnomeVFSFileInfo struct where the data about +the entry will be stored + +Returns : An integer value representing the result of the operation. + + + +<anchor id="gnome-vfs-directory-close"/>gnome_vfs_directory_close () +gnome_vfs_directory_closeGnomeVFSResult gnome_vfs_directory_close (GnomeVFSDirectoryHandle *handle); + +Close handle. + + + +handle : + A directory handle. + +Returns : An integer representing the result of the operation. + + + +<anchor id="gnome-vfs-directory-visit"/>gnome_vfs_directory_visit () +gnome_vfs_directory_visitGnomeVFSResult gnome_vfs_directory_visit (const gchar *uri, + GnomeVFSFileInfoOptions info_options, + GnomeVFSDirectoryVisitOptions visit_options, + GnomeVFSDirectoryVisitFunc callback, + gpointer data); + +Visit uri, retrieving information as specified by info_options. + + + +uri : + URI to start from + +info_options : + Options specifying what kind of file information must be +retrieved + +visit_options : + Options specifying the type of visit + +callback : + Callback to be called for every visited file + +data : + Data to be passed to callback at each iteration + +Returns : + + + +<anchor id="gnome-vfs-directory-visit-uri"/>gnome_vfs_directory_visit_uri () +gnome_vfs_directory_visit_uriGnomeVFSResult gnome_vfs_directory_visit_uri + (GnomeVFSURI *uri, + GnomeVFSFileInfoOptions info_options, + GnomeVFSDirectoryVisitOptions visit_options, + GnomeVFSDirectoryVisitFunc callback, + gpointer data); + +Visit uri, retrieving information as specified by info_options. + + + +uri : + URI to start from + +info_options : + Options specifying what kind of file information must be +retrieved + +visit_options : + Options specifying the type of visit + +callback : + Callback to be called for every visited file + +data : + Data to be passed to callback at each iteration + +Returns : A result code indicating whether the operation succeeded. + + + + +<anchor id="gnome-vfs-directory-visit-files"/>gnome_vfs_directory_visit_files () +gnome_vfs_directory_visit_filesGnomeVFSResult gnome_vfs_directory_visit_files + (const gchar *text_uri, + GList *file_list, + GnomeVFSFileInfoOptions info_options, + GnomeVFSDirectoryVisitOptions visit_options, + GnomeVFSDirectoryVisitFunc callback, + gpointer data); + +Fetches information about a list of files in a base URI uri. + + + +text_uri : + string representing the URI of a directory to "visit" the files in + +file_list : + GList of char *s of file names in uri to visit + +info_options : + bitmask controlling the type of information to fetch + +visit_options : + options controlling e.g. loop prevention, and filesystem checks. +Affects the way visiting is done. + +callback : + function to call with the file info structs + +data : + data to pass to callback. + +Returns : a GnomeVFSResult indication the success of the operation + + + +<anchor id="gnome-vfs-directory-visit-files-at-uri"/>gnome_vfs_directory_visit_files_at_uri () +gnome_vfs_directory_visit_files_at_uriGnomeVFSResult gnome_vfs_directory_visit_files_at_uri + (GnomeVFSURI *uri, + GList *file_list, + GnomeVFSFileInfoOptions info_options, + GnomeVFSDirectoryVisitOptions visit_options, + GnomeVFSDirectoryVisitFunc callback, + gpointer data); + +Fetches information about a list of files in a base URI uri. + + + +uri : + URI of a directory to "visit" the files in + +file_list : + GList of char *s of file names in uri to visit + +info_options : + bitmask controlling the type of information to fetch + +visit_options : + options controlling e.g. loop prevention, and filesystem checks. +Affects the way visiting is done. + +callback : + function to call with the file info structs + +data : + data to pass to callback. + +Returns : a GnomeVFSResult indication the success of the operation + + + +<anchor id="gnome-vfs-directory-list-load"/>gnome_vfs_directory_list_load () +gnome_vfs_directory_list_loadGnomeVFSResult gnome_vfs_directory_list_load + (GList **list, + const gchar *text_uri, + GnomeVFSFileInfoOptions options); + +Load a directory from text_uri with the specified options +into a list. + + + +list : + An address of a pointer to a list of GnomeVFSFileInfo + +text_uri : + A text URI + +options : + Options for loading the directory + +Returns : An integer representing the result of the operation. + + + + + + + + + diff --git a/doc/xml/gnome-vfs-file-advanced-ops.xml b/doc/xml/gnome-vfs-file-advanced-ops.xml new file mode 100644 index 0000000..1a9394a --- /dev/null +++ b/doc/xml/gnome-vfs-file-advanced-ops.xml @@ -0,0 +1,73 @@ + + +Advanced File Operations +3 +GNOME-VFS-2.0 Library + + + +Advanced File Operations + + +Synopsis + + + + + +GnomeVFSResult gnome_vfs_file_control (GnomeVFSHandle *handle, + const char *operation, + gpointer operation_data); + + + + + + + + + + + + +Description + + + + + + +Details + +<anchor id="gnome-vfs-file-control"/>gnome_vfs_file_control () +gnome_vfs_file_controlGnomeVFSResult gnome_vfs_file_control (GnomeVFSHandle *handle, + const char *operation, + gpointer operation_data); + +Execute a backend dependent operation specified by the string operation. +This is typically used for specialized vfs backends that need additional +operations that gnome-vfs doesn't have. Compare it to the unix call ioctl(). +The format of operation_data depends on the operation. Operation that are +backend specific are normally namespaced by their module name. + + + +handle : + handle of the file to affect + +operation : + The operation to execute + +operation_data : + The data needed to execute the operation + +Returns : an integer representing the success of the operation + + + + + + + + + diff --git a/doc/xml/gnome-vfs-file-basic-ops.xml b/doc/xml/gnome-vfs-file-basic-ops.xml new file mode 100644 index 0000000..688dc73 --- /dev/null +++ b/doc/xml/gnome-vfs-file-basic-ops.xml @@ -0,0 +1,381 @@ + + +Basic File Operations +3 +GNOME-VFS-2.0 Library + + + +Basic File Operations + + +Synopsis + + + + + +enum GnomeVFSOpenMode; +GnomeVFSResult gnome_vfs_create (GnomeVFSHandle **handle, + const gchar *text_uri, + GnomeVFSOpenMode open_mode, + gboolean exclusive, + guint perm); +GnomeVFSResult gnome_vfs_create_uri (GnomeVFSHandle **handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode open_mode, + gboolean exclusive, + guint perm); +GnomeVFSResult gnome_vfs_open (GnomeVFSHandle **handle, + const gchar *text_uri, + GnomeVFSOpenMode open_mode); +GnomeVFSResult gnome_vfs_open_uri (GnomeVFSHandle **handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode open_mode); +GnomeVFSResult gnome_vfs_close (GnomeVFSHandle *handle); +GnomeVFSResult gnome_vfs_unlink (const gchar *text_uri); +GnomeVFSResult gnome_vfs_unlink_from_uri (GnomeVFSURI *uri); +GnomeVFSResult gnome_vfs_move_uri (GnomeVFSURI *old_uri, + GnomeVFSURI *new_uri, + gboolean force_replace); +GnomeVFSResult gnome_vfs_move (const gchar *old_text_uri, + const gchar *new_text_uri, + gboolean force_replace); +GnomeVFSResult gnome_vfs_check_same_fs_uris (GnomeVFSURI *source_uri, + GnomeVFSURI *target_uri, + gboolean *same_fs_return); +GnomeVFSResult gnome_vfs_check_same_fs (const gchar *source, + const gchar *target, + gboolean *same_fs_return); +gboolean gnome_vfs_uri_exists (GnomeVFSURI *uri); +GnomeVFSResult gnome_vfs_create_symbolic_link + (GnomeVFSURI *uri, + const gchar *target_reference); + + + + + + + + + + + + +Description + + + + + + +Details + +<anchor id="GnomeVFSOpenMode"/>enum GnomeVFSOpenMode +GnomeVFSOpenModetypedef enum { + GNOME_VFS_OPEN_NONE = 0, + GNOME_VFS_OPEN_READ = 1 << 0, + GNOME_VFS_OPEN_WRITE = 1 << 1, + GNOME_VFS_OPEN_RANDOM = 1 << 2 +} GnomeVFSOpenMode; + + +Mode in which files are opened. If GNOME_VFS_OPEN_RANDOM is not used, the +file will be have to be accessed sequentially. + + + + +<anchor id="gnome-vfs-create"/>gnome_vfs_create () +gnome_vfs_createGnomeVFSResult gnome_vfs_create (GnomeVFSHandle **handle, + const gchar *text_uri, + GnomeVFSOpenMode open_mode, + gboolean exclusive, + guint perm); + +Create uri according to mode open_mode. On return, handle will then +contain a pointer to a handle for the open file. + + + +handle : + A pointer to a pointer to a GnomeVFSHandle object + +text_uri : + String representing the URI to create + +open_mode : + mode to leave the file opened in after creation (or GNOME_VFS_OPEN_MODE_NONE +to leave the file closed after creation) + +exclusive : + Whether the file should be created in "exclusive" mode: +i.e. if this flag is nonzero, operation will fail if a file with the +same name already exists. + +perm : + Bitmap representing the permissions for the newly created file +(Unix style). + +Returns : An integer representing the result of the operation + + + +<anchor id="gnome-vfs-create-uri"/>gnome_vfs_create_uri () +gnome_vfs_create_uriGnomeVFSResult gnome_vfs_create_uri (GnomeVFSHandle **handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode open_mode, + gboolean exclusive, + guint perm); + +Create uri according to mode open_mode. On return, handle will then +contain a pointer to a handle for the open file. + + + +handle : + A pointer to a pointer to a GnomeVFSHandle object + +uri : + URI for the file to create + +open_mode : + Open mode + +exclusive : + Whether the file should be created in "exclusive" mode: +i.e. if this flag is nonzero, operation will fail if a file with the +same name already exists. + +perm : + Bitmap representing the permissions for the newly created file +(Unix style). + +Returns : An integer representing the result of the operation + + + +<anchor id="gnome-vfs-open"/>gnome_vfs_open () +gnome_vfs_openGnomeVFSResult gnome_vfs_open (GnomeVFSHandle **handle, + const gchar *text_uri, + GnomeVFSOpenMode open_mode); + +Open text_uri according to mode open_mode. On return, handle will then +contain a pointer to a handle for the open file. + + + +handle : + A pointer to a pointer to a GnomeVFSHandle object + +text_uri : + String representing the URI to open + +open_mode : + Open mode + +Returns : An integer representing the result of the operation + + + +<anchor id="gnome-vfs-open-uri"/>gnome_vfs_open_uri () +gnome_vfs_open_uriGnomeVFSResult gnome_vfs_open_uri (GnomeVFSHandle **handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode open_mode); + +Open uri according to mode open_mode. On return, handle will then +contain a pointer to a handle for the open file. + + + +handle : + A pointer to a pointer to a GnomeVFSHandle object + +uri : + URI to open + +open_mode : + Open mode + +Returns : An integer representing the result of the operation + + + +<anchor id="gnome-vfs-close"/>gnome_vfs_close () +gnome_vfs_closeGnomeVFSResult gnome_vfs_close (GnomeVFSHandle *handle); + +Close file associated with handle. + + + +handle : + A pointer to a GnomeVFSHandle object + +Returns : An integer representing the result of the operation. + + + +<anchor id="gnome-vfs-unlink"/>gnome_vfs_unlink () +gnome_vfs_unlinkGnomeVFSResult gnome_vfs_unlink (const gchar *text_uri); + +Unlink text_uri (i.e. delete the file). + + + +text_uri : + URI of the file to be unlinked + +Returns : An integer representing the result of the operation + + + +<anchor id="gnome-vfs-unlink-from-uri"/>gnome_vfs_unlink_from_uri () +gnome_vfs_unlink_from_uriGnomeVFSResult gnome_vfs_unlink_from_uri (GnomeVFSURI *uri); + +Unlink uri (i.e. delete the file). + + + +uri : + URI of the file to be unlinked + +Returns : An integer representing the result of the operation + + + +<anchor id="gnome-vfs-move-uri"/>gnome_vfs_move_uri () +gnome_vfs_move_uriGnomeVFSResult gnome_vfs_move_uri (GnomeVFSURI *old_uri, + GnomeVFSURI *new_uri, + gboolean force_replace); + +Move a file from URI old_uri to new_uri. This will only work if old_uri +and new_uri are on the same file system. Otherwise, it is necessary +to use the more general %gnome_vfs_xfer_uri() function. + + + +old_uri : + Source URI + +new_uri : + Destination URI + +force_replace : + If TRUE, move target to new_uri even if there +is already a file at new_uri. If there is a file, it will be discarded. + +Returns : An integer representing the result of the operation. + + + +<anchor id="gnome-vfs-move"/>gnome_vfs_move () +gnome_vfs_moveGnomeVFSResult gnome_vfs_move (const gchar *old_text_uri, + const gchar *new_text_uri, + gboolean force_replace); + +Move a file from URI old_text_uri to new_text_uri. This will only work +if old_text_uri and new_text_uri are on the same file system. Otherwise, +it is necessary to use the more general %gnome_vfs_xfer_uri() function. + + + +old_text_uri : + Source URI + +new_text_uri : + Destination URI + +force_replace : + if TRUE, perform the operation even if it unlinks an existing +file at new_text_uri + +Returns : An integer representing the result of the operation. + + + +<anchor id="gnome-vfs-check-same-fs-uris"/>gnome_vfs_check_same_fs_uris () +gnome_vfs_check_same_fs_urisGnomeVFSResult gnome_vfs_check_same_fs_uris (GnomeVFSURI *source_uri, + GnomeVFSURI *target_uri, + gboolean *same_fs_return); + +Check if source_uri and target_uri are on the same file system. + + + +source_uri : + A URI + +target_uri : + Another URI + +same_fs_return : + Pointer to a boolean variable which will be set to TRUE +if source_uri and target_uri are on the same file system on return. + +Returns : An integer representing the result of the operation. + + + +<anchor id="gnome-vfs-check-same-fs"/>gnome_vfs_check_same_fs () +gnome_vfs_check_same_fsGnomeVFSResult gnome_vfs_check_same_fs (const gchar *source, + const gchar *target, + gboolean *same_fs_return); + +Return TRUE if source and target are on the same file system. + + + +source : + A URI + +target : + Another URI + +same_fs_return : + Pointer to a boolean variable which will be set to TRUE + +Returns : An integer representing the result of the operation. + + + +<anchor id="gnome-vfs-uri-exists"/>gnome_vfs_uri_exists () +gnome_vfs_uri_existsgboolean gnome_vfs_uri_exists (GnomeVFSURI *uri); + +Check if the URI points to an existing entity. + + + +uri : + A URI + +Returns : TRUE if URI exists. + + + +<anchor id="gnome-vfs-create-symbolic-link"/>gnome_vfs_create_symbolic_link () +gnome_vfs_create_symbolic_linkGnomeVFSResult gnome_vfs_create_symbolic_link + (GnomeVFSURI *uri, + const gchar *target_reference); + +Creates a symbolic link, or eventually, a URI link (as necessary) +at uri pointing to target_reference + + + +uri : + URI to create a link at + +target_reference : + URI "reference" to point the link to (URI or relative path) + +Returns : An integer representing the result of the operation + + + + + + + + + diff --git a/doc/xml/gnome-vfs-file-info-ops.xml b/doc/xml/gnome-vfs-file-info-ops.xml new file mode 100644 index 0000000..04521e0 --- /dev/null +++ b/doc/xml/gnome-vfs-file-info-ops.xml @@ -0,0 +1,203 @@ + + +Getting and Setting File Information +3 +GNOME-VFS-2.0 Library + + + +Getting and Setting File Information + + +Synopsis + + + + + +GnomeVFSResult gnome_vfs_get_file_info (const gchar *text_uri, + GnomeVFSFileInfo *info, + GnomeVFSFileInfoOptions options); +GnomeVFSResult gnome_vfs_get_file_info_uri (GnomeVFSURI *uri, + GnomeVFSFileInfo *info, + GnomeVFSFileInfoOptions options); +GnomeVFSResult gnome_vfs_get_file_info_from_handle + (GnomeVFSHandle *handle, + GnomeVFSFileInfo *info, + GnomeVFSFileInfoOptions options); +GnomeVFSResult gnome_vfs_set_file_info_uri (GnomeVFSURI *uri, + GnomeVFSFileInfo *info, + GnomeVFSSetFileInfoMask mask); +GnomeVFSResult gnome_vfs_set_file_info (const gchar *text_uri, + GnomeVFSFileInfo *info, + GnomeVFSSetFileInfoMask mask); + + + + + + + + + + + + +Description + + Applications can use the gnome_vfs_get_file_info family of operations to + retrieve file information, as this operation can be quite costly in + terms of time (specilly when sniffing the MIME type) applications can + specify which information need at any time, reducing the performance + impact. + + + All of these operations use a GnomeVFSFileInfo data structure that holds + the file information, there are several methods that can be used to + manipulate this information. See GnomeVFSFileInfo for more information. + + + + +Details + +<anchor id="gnome-vfs-get-file-info"/>gnome_vfs_get_file_info () +gnome_vfs_get_file_infoGnomeVFSResult gnome_vfs_get_file_info (const gchar *text_uri, + GnomeVFSFileInfo *info, + GnomeVFSFileInfoOptions options); + +Retrieve information about text_uri. The information will be stored in +info. + + + +text_uri : + URI of the file for which information will be retrieved + +info : + Pointer to a GnomeVFSFileInfo object that will hold the information +for the file on return + +options : + Options for retrieving file information +to retrieve for the file + +Returns : An integer representing the result of the operation + + + +<anchor id="gnome-vfs-get-file-info-uri"/>gnome_vfs_get_file_info_uri () +gnome_vfs_get_file_info_uriGnomeVFSResult gnome_vfs_get_file_info_uri (GnomeVFSURI *uri, + GnomeVFSFileInfo *info, + GnomeVFSFileInfoOptions options); + +Retrieve information about text_uri. The information will be stored in +info. + + + +uri : + URI of the file for which information will be retrieved + +info : + Pointer to a GnomeVFSFileInfo object that will hold the information +for the file on return + +options : + Options for retrieving file information +to retrieve for the file + +Returns : An integer representing the result of the operation + + + +<anchor id="gnome-vfs-get-file-info-from-handle"/>gnome_vfs_get_file_info_from_handle () +gnome_vfs_get_file_info_from_handleGnomeVFSResult gnome_vfs_get_file_info_from_handle + (GnomeVFSHandle *handle, + GnomeVFSFileInfo *info, + GnomeVFSFileInfoOptions options); + +Retrieve information about an open file. The information will be stored in +info. + + + +handle : + Handle of the file for which information must be retrieved + +info : + Pointer to a GnomeVFSFileInfo object that will hold the information +for the file on return + +options : + Options for retrieving file information +to retrieve for the file + +Returns : An integer representing the result of the operation + + + +<anchor id="gnome-vfs-set-file-info-uri"/>gnome_vfs_set_file_info_uri () +gnome_vfs_set_file_info_uriGnomeVFSResult gnome_vfs_set_file_info_uri (GnomeVFSURI *uri, + GnomeVFSFileInfo *info, + GnomeVFSSetFileInfoMask mask); + +Set file information for uri; only the information for which the +corresponding bit in mask is set is actually modified. + + + +uri : + A URI + +info : + Information that must be set for the file + +mask : + Bit mask representing which fields of info need to be set + +Returns : An integer representing the result of the operation. + + + +<anchor id="gnome-vfs-set-file-info"/>gnome_vfs_set_file_info () +gnome_vfs_set_file_infoGnomeVFSResult gnome_vfs_set_file_info (const gchar *text_uri, + GnomeVFSFileInfo *info, + GnomeVFSSetFileInfoMask mask); + +Set file information for uri; only the information for which the +corresponding bit in mask is set is actually modified. + + + +text_uri : + A URI + +info : + Information that must be set for the file + +mask : + Bit mask representing which fields of info need to be set + +Returns : An integer representing the result of the operation. + + + + + + + + +See Also + + + + +GnomeVFSFileInfo + + + + + + + diff --git a/doc/xml/gnome-vfs-file-info.xml b/doc/xml/gnome-vfs-file-info.xml new file mode 100644 index 0000000..91ade96 --- /dev/null +++ b/doc/xml/gnome-vfs-file-info.xml @@ -0,0 +1,849 @@ + + +GnomeVFSFileInfo +3 +GNOME-VFS-2.0 Library + + + +GnomeVFSFileInfo +stores information about files, GnomeVFS equivalent of stat + + +Synopsis + + + + + +enum GnomeVFSFileFlags; +enum GnomeVFSFileType; +enum GnomeVFSFileInfoFields; +enum GnomeVFSFilePermissions; +enum GnomeVFSFileInfoOptions; +enum GnomeVFSSetFileInfoMask; +typedef GnomeVFSGetFileInfoResult; +typedef GnomeVFSInodeNumber; +typedef GnomeVFSFileInfo; +#define GNOME_VFS_FILE_INFO_SYMLINK (info) +#define GNOME_VFS_FILE_INFO_SET_SYMLINK (info, value) +#define GNOME_VFS_FILE_INFO_LOCAL (info) +#define GNOME_VFS_FILE_INFO_SET_LOCAL (info, value) +#define GNOME_VFS_FILE_INFO_SUID (info) +#define GNOME_VFS_FILE_INFO_SGID (info) +#define GNOME_VFS_FILE_INFO_STICKY (info) +#define GNOME_VFS_FILE_INFO_SET_SUID (info, value) +#define GNOME_VFS_FILE_INFO_SET_SGID (info, value) +#define GNOME_VFS_FILE_INFO_SET_STICKY (info, value) +GnomeVFSFileInfo* gnome_vfs_file_info_new (void); +void gnome_vfs_file_info_unref (GnomeVFSFileInfo *info); +void gnome_vfs_file_info_ref (GnomeVFSFileInfo *info); +void gnome_vfs_file_info_clear (GnomeVFSFileInfo *info); +const char* gnome_vfs_file_info_get_mime_type + (GnomeVFSFileInfo *info); +void gnome_vfs_file_info_copy (GnomeVFSFileInfo *dest, + const GnomeVFSFileInfo *src); +GnomeVFSFileInfo* gnome_vfs_file_info_dup (const GnomeVFSFileInfo *orig); +gboolean gnome_vfs_file_info_matches (const GnomeVFSFileInfo *a, + const GnomeVFSFileInfo *b); +GList* gnome_vfs_file_info_list_ref (GList *list); +GList* gnome_vfs_file_info_list_unref (GList *list); +GList* gnome_vfs_file_info_list_copy (GList *list); +void gnome_vfs_file_info_list_free (GList *list); + + + + + + + + + + + + +Description + + + + + + +Details + +<anchor id="GnomeVFSFileFlags"/>enum GnomeVFSFileFlags +GnomeVFSFileFlagstypedef enum { + GNOME_VFS_FILE_FLAGS_NONE = 0, + GNOME_VFS_FILE_FLAGS_SYMLINK = 1 << 0, + GNOME_VFS_FILE_FLAGS_LOCAL = 1 << 1 +} GnomeVFSFileFlags; + + +Packed boolean bitfield representing special +flags a GnomeVFSFileInfo struct can have. + + + + +GNOME_VFS_FILE_FLAGS_NONE + no flags + + + +GNOME_VFS_FILE_FLAGS_SYMLINK + whether the file is a symlink. + + + +GNOME_VFS_FILE_FLAGS_LOCAL + whether the file is on a local filesystem + + + + +<anchor id="GnomeVFSFileType"/>enum GnomeVFSFileType +GnomeVFSFileTypetypedef enum { + GNOME_VFS_FILE_TYPE_UNKNOWN, + GNOME_VFS_FILE_TYPE_REGULAR, + GNOME_VFS_FILE_TYPE_DIRECTORY, + GNOME_VFS_FILE_TYPE_FIFO, + GNOME_VFS_FILE_TYPE_SOCKET, + GNOME_VFS_FILE_TYPE_CHARACTER_DEVICE, + GNOME_VFS_FILE_TYPE_BLOCK_DEVICE, + GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK +} GnomeVFSFileType; + + +Identifies the kind of file represented by a GnomeVFSFileInfo struct. (note, +use of MIME types is preferred as this field may eventually disappear) + + + + +<anchor id="GnomeVFSFileInfoFields"/>enum GnomeVFSFileInfoFields +GnomeVFSFileInfoFieldstypedef enum { + GNOME_VFS_FILE_INFO_FIELDS_NONE = 0, + GNOME_VFS_FILE_INFO_FIELDS_TYPE = 1 << 0, + GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS = 1 << 1, + GNOME_VFS_FILE_INFO_FIELDS_FLAGS = 1 << 2, + GNOME_VFS_FILE_INFO_FIELDS_DEVICE = 1 << 3, + GNOME_VFS_FILE_INFO_FIELDS_INODE = 1 << 4, + GNOME_VFS_FILE_INFO_FIELDS_LINK_COUNT = 1 << 5, + GNOME_VFS_FILE_INFO_FIELDS_SIZE = 1 << 6, + GNOME_VFS_FILE_INFO_FIELDS_BLOCK_COUNT = 1 << 7, + GNOME_VFS_FILE_INFO_FIELDS_IO_BLOCK_SIZE = 1 << 8, + GNOME_VFS_FILE_INFO_FIELDS_ATIME = 1 << 9, + GNOME_VFS_FILE_INFO_FIELDS_MTIME = 1 << 10, + GNOME_VFS_FILE_INFO_FIELDS_CTIME = 1 << 11, + GNOME_VFS_FILE_INFO_FIELDS_SYMLINK_NAME = 1 << 12, + GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE = 1 << 13, + GNOME_VFS_FILE_INFO_FIELDS_ACCESS = 1 << 14 +} GnomeVFSFileInfoFields; + + +Flags indicating what fields in a GnomeVFSFileInfo struct are valid. +Name is always assumed valid (how else would you have gotten a +FileInfo struct otherwise?) + + + + +GNOME_VFS_FILE_INFO_FIELDS_NONE + No fields are valid + + + +GNOME_VFS_FILE_INFO_FIELDS_TYPE + Type field is valid + + + +GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS + Permissions field is valid + + + +GNOME_VFS_FILE_INFO_FIELDS_FLAGS + Flags field is valid + + + +GNOME_VFS_FILE_INFO_FIELDS_DEVICE + Device field is valid + + + +GNOME_VFS_FILE_INFO_FIELDS_INODE + Inode field is valid + + + +GNOME_VFS_FILE_INFO_FIELDS_LINK_COUNT + Link count field is valid + + + +GNOME_VFS_FILE_INFO_FIELDS_SIZE + Size field is valid + + + +GNOME_VFS_FILE_INFO_FIELDS_BLOCK_COUNT + Block count field is valid + + + +GNOME_VFS_FILE_INFO_FIELDS_IO_BLOCK_SIZE + I/O Block Size field is valid + + + +GNOME_VFS_FILE_INFO_FIELDS_ATIME + Access time field is valid + + + +GNOME_VFS_FILE_INFO_FIELDS_MTIME + Modification time field is valid + + + +GNOME_VFS_FILE_INFO_FIELDS_CTIME + Creating time field is valid + + + +GNOME_VFS_FILE_INFO_FIELDS_SYMLINK_NAME + Symlink name field is valid + + + +GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE + Mime type field is valid + + + +GNOME_VFS_FILE_INFO_FIELDS_ACCESS + Access bits of the permissions +bitfield are valid + + + + +<anchor id="GnomeVFSFilePermissions"/>enum GnomeVFSFilePermissions +GnomeVFSFilePermissionstypedef enum { + GNOME_VFS_PERM_SUID = S_ISUID, + GNOME_VFS_PERM_SGID = S_ISGID, + GNOME_VFS_PERM_STICKY = 01000, /* S_ISVTX not defined on all systems */ + GNOME_VFS_PERM_USER_READ = S_IRUSR, + GNOME_VFS_PERM_USER_WRITE = S_IWUSR, + GNOME_VFS_PERM_USER_EXEC = S_IXUSR, + GNOME_VFS_PERM_USER_ALL = S_IRUSR | S_IWUSR | S_IXUSR, + GNOME_VFS_PERM_GROUP_READ = S_IRGRP, + GNOME_VFS_PERM_GROUP_WRITE = S_IWGRP, + GNOME_VFS_PERM_GROUP_EXEC = S_IXGRP, + GNOME_VFS_PERM_GROUP_ALL = S_IRGRP | S_IWGRP | S_IXGRP, + GNOME_VFS_PERM_OTHER_READ = S_IROTH, + GNOME_VFS_PERM_OTHER_WRITE = S_IWOTH, + GNOME_VFS_PERM_OTHER_EXEC = S_IXOTH, + GNOME_VFS_PERM_OTHER_ALL = S_IROTH | S_IWOTH | S_IXOTH, + GNOME_VFS_PERM_ACCESS_READABLE = 1 << 16, + GNOME_VFS_PERM_ACCESS_WRITABLE = 1 << 17, + GNOME_VFS_PERM_ACCESS_EXECUTABLE = 1 << 18 +} GnomeVFSFilePermissions; + + +File permissions. These are the same as the Unix ones, but we wrap them +into a nicer VFS-like enum. + + + + +GNOME_VFS_PERM_SUID + UID bit + + + +GNOME_VFS_PERM_SGID + GID bit + + + +GNOME_VFS_PERM_STICKY + Sticky bit. + + + +GNOME_VFS_PERM_USER_READ + Owner has read permission + + + +GNOME_VFS_PERM_USER_WRITE + Owner has write permission + + + +GNOME_VFS_PERM_USER_EXEC + Owner has execution permission + + + +GNOME_VFS_PERM_USER_ALL + Owner has all permissions + + + +GNOME_VFS_PERM_GROUP_READ + Group has read permission + + + +GNOME_VFS_PERM_GROUP_WRITE + Group has write permission + + + +GNOME_VFS_PERM_GROUP_EXEC + Group has execution permission + + + +GNOME_VFS_PERM_GROUP_ALL + Group has all permissions + + + +GNOME_VFS_PERM_OTHER_READ + Others have read permission + + + +GNOME_VFS_PERM_OTHER_WRITE + Others have write permission + + + +GNOME_VFS_PERM_OTHER_EXEC + Others have execution permission + + + +GNOME_VFS_PERM_OTHER_ALL + Others have all permissions + + + +GNOME_VFS_PERM_ACCESS_READABLE + + + + +GNOME_VFS_PERM_ACCESS_WRITABLE + + + + +GNOME_VFS_PERM_ACCESS_EXECUTABLE + + + + + +<anchor id="GnomeVFSFileInfoOptions"/>enum GnomeVFSFileInfoOptions +GnomeVFSFileInfoOptionstypedef enum { + GNOME_VFS_FILE_INFO_DEFAULT = 0, + GNOME_VFS_FILE_INFO_GET_MIME_TYPE = 1 << 0, + GNOME_VFS_FILE_INFO_FORCE_FAST_MIME_TYPE = 1 << 1, + GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE = 1 << 2, + GNOME_VFS_FILE_INFO_FOLLOW_LINKS = 1 << 3, + GNOME_VFS_FILE_INFO_GET_ACCESS_RIGHTS = 1 << 4 +} GnomeVFSFileInfoOptions; + + +Packed boolean bitfield representing options that can +be passed into a gnome_vfs_get_file_info() call (or other +related calls that return file info) and affect the operation +of get_file_info. + + + + +GNOME_VFS_FILE_INFO_DEFAULT + default flags + + + +GNOME_VFS_FILE_INFO_GET_MIME_TYPE + detect the MIME type + + + +GNOME_VFS_FILE_INFO_FORCE_FAST_MIME_TYPE + only use fast MIME type +detection (extensions) + + + +GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE + force slow MIME type +detection where available (sniffing, algorithmic detection, etc) + + + +GNOME_VFS_FILE_INFO_FOLLOW_LINKS + automatically follow symbolic +links and retrieve the properties of their target (recommended) + + + +GNOME_VFS_FILE_INFO_GET_ACCESS_RIGHTS + tries to get data similar +to what would return access(2) on a local file system (ie is the +file readable, writable and/or executable). Can be really slow on +remote file systems + + + + +<anchor id="GnomeVFSSetFileInfoMask"/>enum GnomeVFSSetFileInfoMask +GnomeVFSSetFileInfoMasktypedef enum { + GNOME_VFS_SET_FILE_INFO_NONE = 0, + GNOME_VFS_SET_FILE_INFO_NAME = 1 << 0, + GNOME_VFS_SET_FILE_INFO_PERMISSIONS = 1 << 1, + GNOME_VFS_SET_FILE_INFO_OWNER = 1 << 2, + GNOME_VFS_SET_FILE_INFO_TIME = 1 << 3 +} GnomeVFSSetFileInfoMask; + + +Packed boolean bitfield representing the aspects of the file +to be changed in a gnome_vfs_set_file_info() call. + + + + +GNOME_VFS_SET_FILE_INFO_NONE + don't set any file info fields + + + +GNOME_VFS_SET_FILE_INFO_NAME + change the name + + + +GNOME_VFS_SET_FILE_INFO_PERMISSIONS + change the permissions + + + +GNOME_VFS_SET_FILE_INFO_OWNER + change the file's owner + + + +GNOME_VFS_SET_FILE_INFO_TIME + change the file's time stamp(s) + + + + +<anchor id="GnomeVFSGetFileInfoResult"/>GnomeVFSGetFileInfoResult +GnomeVFSGetFileInfoResulttypedef struct { + GnomeVFSURI *uri; + GnomeVFSResult result; + GnomeVFSFileInfo *file_info; +} GnomeVFSGetFileInfoResult; + + + + + +<anchor id="GnomeVFSInodeNumber"/>GnomeVFSInodeNumber +GnomeVFSInodeNumbertypedef GnomeVFSFileSize GnomeVFSInodeNumber; + + +Represents the i-node of a file, this is a low level data structure +that the operating system uses to hold information about a file. + + + + +<anchor id="GnomeVFSFileInfo"/>GnomeVFSFileInfo +GnomeVFSFileInfotypedef struct { + /* Base name of the file (no path). */ + char *name; + + /* Fields which are actually valid in this structure. */ + GnomeVFSFileInfoFields valid_fields; + + /* File type (i.e. regular, directory, block device...). */ + GnomeVFSFileType type; + + /* File permissions. */ + GnomeVFSFilePermissions permissions; + + /* Flags for this file. */ + GnomeVFSFileFlags flags; + + /* These are only valid if `is_local' is TRUE (see below). */ + dev_t device; + GnomeVFSInodeNumber inode; + + /* Link count. */ + guint link_count; + + /* UID, GID. */ + guint uid; + guint gid; + + /* Size in bytes. */ + GnomeVFSFileSize size; + + /* Size measured in units of 512-byte blocks. */ + GnomeVFSFileSize block_count; + + /* Optimal buffer size for reading/writing the file. */ + guint io_block_size; + + /* Access, modification and change times. */ + time_t atime; + time_t mtime; + time_t ctime; + + /* If the file is a symlink (see `flags'), this specifies the file the + link points to. */ + char *symlink_name; + + /* MIME type. */ + char *mime_type; + + guint refcount; + + /* Reserved for future expansions to GnomeVFSFileInfo without having + to break ABI compatibility */ + void *reserved1; + void *reserved2; + void *reserved3; + void *reserved4; + void *reserved5; +} GnomeVFSFileInfo; + + +The GnomeVFSFileInfo structure contains information about a file. + + + + +<anchor id="GNOME-VFS-FILE-INFO-SYMLINK-CAPS"/>GNOME_VFS_FILE_INFO_SYMLINK() +GNOME_VFS_FILE_INFO_SYMLINK#define GNOME_VFS_FILE_INFO_SYMLINK(info) + +Determines whether a file is a symbolic link given info. + + + +info : + GnomeVFSFileInfo struct + + + +<anchor id="GNOME-VFS-FILE-INFO-SET-SYMLINK-CAPS"/>GNOME_VFS_FILE_INFO_SET_SYMLINK() +GNOME_VFS_FILE_INFO_SET_SYMLINK#define GNOME_VFS_FILE_INFO_SET_SYMLINK(info, value) + +Set the symbolic link field in info to value. + + + +info : + GnomeVFSFileInfo struct + +value : + if TRUE, info is set to indicate the file is a symbolic link + + + +<anchor id="GNOME-VFS-FILE-INFO-LOCAL-CAPS"/>GNOME_VFS_FILE_INFO_LOCAL() +GNOME_VFS_FILE_INFO_LOCAL#define GNOME_VFS_FILE_INFO_LOCAL(info) + +Determines whether a file is local given info. + + + +info : + GnomeVFSFileInfo struct + + + +<anchor id="GNOME-VFS-FILE-INFO-SET-LOCAL-CAPS"/>GNOME_VFS_FILE_INFO_SET_LOCAL() +GNOME_VFS_FILE_INFO_SET_LOCAL#define GNOME_VFS_FILE_INFO_SET_LOCAL(info, value) + +Set the "local file" field in info to value. + + + +info : + GnomeVFSFileInfo struct + +value : + if TRUE, info is set to indicate the file is local + + + +<anchor id="GNOME-VFS-FILE-INFO-SUID-CAPS"/>GNOME_VFS_FILE_INFO_SUID() +GNOME_VFS_FILE_INFO_SUID#define GNOME_VFS_FILE_INFO_SUID(info) + +Determines whether a file belongs to the super user. + + + +info : + GnomeVFSFileInfo struct + + + +<anchor id="GNOME-VFS-FILE-INFO-SGID-CAPS"/>GNOME_VFS_FILE_INFO_SGID() +GNOME_VFS_FILE_INFO_SGID#define GNOME_VFS_FILE_INFO_SGID(info) + +Determines whether a file belongs to the super user's group. + + + +info : + GnomeVFSFileInfo struct + + + +<anchor id="GNOME-VFS-FILE-INFO-STICKY-CAPS"/>GNOME_VFS_FILE_INFO_STICKY() +GNOME_VFS_FILE_INFO_STICKY#define GNOME_VFS_FILE_INFO_STICKY(info) + +Determines whether a file has the sticky bit set, given info + + + +info : + GnomeVFSFileInfo struct + + + +<anchor id="GNOME-VFS-FILE-INFO-SET-SUID-CAPS"/>GNOME_VFS_FILE_INFO_SET_SUID() +GNOME_VFS_FILE_INFO_SET_SUID#define GNOME_VFS_FILE_INFO_SET_SUID(info, value) + +Set the SUID field in info to value. + + + +info : + GnomeVFSFileInfo struct + +value : + if TRUE, info is set to indicate the file belongs to the super user + + + +<anchor id="GNOME-VFS-FILE-INFO-SET-SGID-CAPS"/>GNOME_VFS_FILE_INFO_SET_SGID() +GNOME_VFS_FILE_INFO_SET_SGID#define GNOME_VFS_FILE_INFO_SET_SGID(info, value) + +Set the SGID field in info to value. + + + +info : + GnomeVFSFileInfo struct + +value : + if TRUE, info is set to indicate the file belongs to the super user's group + + + +<anchor id="GNOME-VFS-FILE-INFO-SET-STICKY-CAPS"/>GNOME_VFS_FILE_INFO_SET_STICKY() +GNOME_VFS_FILE_INFO_SET_STICKY#define GNOME_VFS_FILE_INFO_SET_STICKY(info, value) + +Set the sticky bit in info to value. + + + +info : + GnomeVFSFileInfo struct + +value : + if TRUE, info is set to indicate the file has the sticky bit set + + + +<anchor id="gnome-vfs-file-info-new"/>gnome_vfs_file_info_new () +gnome_vfs_file_info_newGnomeVFSFileInfo* gnome_vfs_file_info_new (void); + +Allocate and initialize a new file information struct. + + + +Returns : A pointer to the new file information struct. + + + +<anchor id="gnome-vfs-file-info-unref"/>gnome_vfs_file_info_unref () +gnome_vfs_file_info_unrefvoid gnome_vfs_file_info_unref (GnomeVFSFileInfo *info); + +Destroy info + + + +info : + Pointer to a file information struct + + + +<anchor id="gnome-vfs-file-info-ref"/>gnome_vfs_file_info_ref () +gnome_vfs_file_info_refvoid gnome_vfs_file_info_ref (GnomeVFSFileInfo *info); + +Increment reference count + + + +info : + Pointer to a file information struct + + + +<anchor id="gnome-vfs-file-info-clear"/>gnome_vfs_file_info_clear () +gnome_vfs_file_info_clearvoid gnome_vfs_file_info_clear (GnomeVFSFileInfo *info); + +Clear info so that it's ready to accept new data. This is +supposed to be used when info already contains meaningful information which +we want to replace. + + + +info : + Pointer to a file information struct + + + +<anchor id="gnome-vfs-file-info-get-mime-type"/>gnome_vfs_file_info_get_mime_type () +gnome_vfs_file_info_get_mime_typeconst char* gnome_vfs_file_info_get_mime_type + (GnomeVFSFileInfo *info); + +Retrieve MIME type from info. There is no need to free the return +value. + + + +info : + A pointer to a file information struct + +Returns : A pointer to a string representing the MIME type. + + + +<anchor id="gnome-vfs-file-info-copy"/>gnome_vfs_file_info_copy () +gnome_vfs_file_info_copyvoid gnome_vfs_file_info_copy (GnomeVFSFileInfo *dest, + const GnomeVFSFileInfo *src); + +Copy information from src into dest. + + + +dest : + Pointer to a struct to copy src's information into + +src : + Pointer to the information to be copied into dest + + + +<anchor id="gnome-vfs-file-info-dup"/>gnome_vfs_file_info_dup () +gnome_vfs_file_info_dupGnomeVFSFileInfo* gnome_vfs_file_info_dup (const GnomeVFSFileInfo *orig); + +Duplicates orig and returns it. + + + +orig : + Pointer to a file information structure to duplicate + +Returns : a new file information struct that duplicates the information in orig. + + + +<anchor id="gnome-vfs-file-info-matches"/>gnome_vfs_file_info_matches () +gnome_vfs_file_info_matchesgboolean gnome_vfs_file_info_matches (const GnomeVFSFileInfo *a, + const GnomeVFSFileInfo *b); + +Compare the two file info structs, return TRUE if they match. + + + +a : + first GnomeVFSFileInfo struct to compare + +b : + second GnomeVFSFileInfo struct to compare + +Returns : TRUE if the two GnomeVFSFileInfos match, otherwise return FALSE. + + + +<anchor id="gnome-vfs-file-info-list-ref"/>gnome_vfs_file_info_list_ref () +gnome_vfs_file_info_list_refGList* gnome_vfs_file_info_list_ref (GList *list); + +Increments the reference count of the items in list by one. + + + +list : + list of GnomeVFSFileInfo elements + +Returns : list + + + +<anchor id="gnome-vfs-file-info-list-unref"/>gnome_vfs_file_info_list_unref () +gnome_vfs_file_info_list_unrefGList* gnome_vfs_file_info_list_unref (GList *list); + +Decrements the reference count of the items in list by one. +Note that the list is *not freed* even if each member of the list +is freed. + + + +list : + list of GnomeVFSFileInfo elements + +Returns : list + + + +<anchor id="gnome-vfs-file-info-list-copy"/>gnome_vfs_file_info_list_copy () +gnome_vfs_file_info_list_copyGList* gnome_vfs_file_info_list_copy (GList *list); + +Creates a duplicate of list, and references each member of +that list. + + + +list : + list of GnomeVFSFileInfo elements + +Returns : a newly referenced duplicate of list + + + +<anchor id="gnome-vfs-file-info-list-free"/>gnome_vfs_file_info_list_free () +gnome_vfs_file_info_list_freevoid gnome_vfs_file_info_list_free (GList *list); + +Decrements the reference count of each member of list by one, +and frees the list itself. + + + +list : + list of GnomeVFSFileInfo elements + + + + + + + + + diff --git a/doc/xml/gnome-vfs-file-rw-ops.xml b/doc/xml/gnome-vfs-file-rw-ops.xml new file mode 100644 index 0000000..14795dd --- /dev/null +++ b/doc/xml/gnome-vfs-file-rw-ops.xml @@ -0,0 +1,189 @@ + + +Reading and Writing +3 +GNOME-VFS-2.0 Library + + + +Reading and Writing + + +Synopsis + + + + + +enum GnomeVFSSeekPosition; +GnomeVFSResult gnome_vfs_read (GnomeVFSHandle *handle, + gpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_read); +GnomeVFSResult gnome_vfs_write (GnomeVFSHandle *handle, + gconstpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_written); +GnomeVFSResult gnome_vfs_seek (GnomeVFSHandle *handle, + GnomeVFSSeekPosition whence, + GnomeVFSFileOffset offset); +GnomeVFSResult gnome_vfs_tell (GnomeVFSHandle *handle, + GnomeVFSFileSize *offset_return); + + + + + + + + + + + + +Description + + Reading and writing operations are explained, also gnome_vfs_seek, which + is used to move the file pointer inside the file. + + + + +Details + +<anchor id="GnomeVFSSeekPosition"/>enum GnomeVFSSeekPosition +GnomeVFSSeekPositiontypedef enum { + GNOME_VFS_SEEK_START, + GNOME_VFS_SEEK_CURRENT, + GNOME_VFS_SEEK_END +} GnomeVFSSeekPosition; + + +This is used to specify the start position for seek operations. + + + + +GNOME_VFS_SEEK_START + Start of the file. + + + +GNOME_VFS_SEEK_CURRENT + Current position. + + + +GNOME_VFS_SEEK_END + End of the file. + + + + +<anchor id="gnome-vfs-read"/>gnome_vfs_read () +gnome_vfs_readGnomeVFSResult gnome_vfs_read (GnomeVFSHandle *handle, + gpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_read); + +Read bytes from handle. As with Unix system calls, the number of +bytes read can effectively be less than bytes on return and will be +stored in bytes_read. + + + +handle : + Handle of the file to read data from + +buffer : + Pointer to a buffer that must be at least bytes bytes large + +bytes : + Number of bytes to read + +bytes_read : + Pointer to a variable that will hold the number of bytes +effectively read on return. + +Returns : An integer representing the result of the operation + + + +<anchor id="gnome-vfs-write"/>gnome_vfs_write () +gnome_vfs_writeGnomeVFSResult gnome_vfs_write (GnomeVFSHandle *handle, + gconstpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_written); + +Write bytes into the file opened through handle. As with Unix system +calls, the number of bytes written can effectively be less than bytes on +return and will be stored in bytes_written. + + + +handle : + Handle of the file to write data to + +buffer : + Pointer to the buffer containing the data to be written + +bytes : + Number of bytes to write + +bytes_written : + Pointer to a variable that will hold the number of bytes +effectively written on return. + +Returns : An integer representing the result of the operation + + + +<anchor id="gnome-vfs-seek"/>gnome_vfs_seek () +gnome_vfs_seekGnomeVFSResult gnome_vfs_seek (GnomeVFSHandle *handle, + GnomeVFSSeekPosition whence, + GnomeVFSFileOffset offset); + +Set the current position for reading/writing through handle. + + + +handle : + Handle for which the current position must be changed + +whence : + Integer value representing the starting position + +offset : + Number of bytes to skip from the position specified by whence +(a positive value means to move forward; a negative one to move backwards) + +Returns : + + + +<anchor id="gnome-vfs-tell"/>gnome_vfs_tell () +gnome_vfs_tellGnomeVFSResult gnome_vfs_tell (GnomeVFSHandle *handle, + GnomeVFSFileSize *offset_return); + +Return the current position on handle. This is the point in the file +pointed to by handle that reads and writes will occur on. + + + +handle : + Handle for which the current position must be retrieved + +offset_return : + Pointer to a variable that will contain the current position +on return + +Returns : An integer representing the result of the operation + + + + + + + + + diff --git a/doc/xml/gnome-vfs-file-size.xml b/doc/xml/gnome-vfs-file-size.xml new file mode 100644 index 0000000..28d9bdc --- /dev/null +++ b/doc/xml/gnome-vfs-file-size.xml @@ -0,0 +1,85 @@ + + +GnomeVFSFileSize +3 +GNOME-VFS-2.0 Library + + + +GnomeVFSFileSize + + +Synopsis + + + + + +#define GNOME_VFS_OFFSET_IS_LONG_LONG +#define GNOME_VFS_SIZE_FORMAT_STR +#define GNOME_VFS_OFFSET_FORMAT_STR +typedef GnomeVFSFileSize; +typedef GnomeVFSFileOffset; + + + + + + + + + + + + + +Description + + + + + + +Details + +<anchor id="GNOME-VFS-OFFSET-IS-LONG-LONG-CAPS"/>GNOME_VFS_OFFSET_IS_LONG_LONG +GNOME_VFS_OFFSET_IS_LONG_LONG#define GNOME_VFS_OFFSET_IS_LONG_LONG + + + + + +<anchor id="GNOME-VFS-SIZE-FORMAT-STR-CAPS"/>GNOME_VFS_SIZE_FORMAT_STR +GNOME_VFS_SIZE_FORMAT_STR#define GNOME_VFS_SIZE_FORMAT_STR "Lu" + + + + + +<anchor id="GNOME-VFS-OFFSET-FORMAT-STR-CAPS"/>GNOME_VFS_OFFSET_FORMAT_STR +GNOME_VFS_OFFSET_FORMAT_STR#define GNOME_VFS_OFFSET_FORMAT_STR "Ld" + + + + + +<anchor id="GnomeVFSFileSize"/>GnomeVFSFileSize +GnomeVFSFileSizeG_GNUC_EXTENSION typedef unsigned long long GnomeVFSFileSize; + + + + + +<anchor id="GnomeVFSFileOffset"/>GnomeVFSFileOffset +GnomeVFSFileOffsetG_GNUC_EXTENSION typedef long long GnomeVFSFileOffset; + + + + + + + + + + + diff --git a/doc/xml/gnome-vfs-file-trunc-ops.xml b/doc/xml/gnome-vfs-file-trunc-ops.xml new file mode 100644 index 0000000..12e7c75 --- /dev/null +++ b/doc/xml/gnome-vfs-file-trunc-ops.xml @@ -0,0 +1,106 @@ + + +Truncating Files +3 +GNOME-VFS-2.0 Library + + + +Truncating Files + + +Synopsis + + + + + +GnomeVFSResult gnome_vfs_truncate (const gchar *text_uri, + GnomeVFSFileSize length); +GnomeVFSResult gnome_vfs_truncate_uri (GnomeVFSURI *uri, + GnomeVFSFileSize length); +GnomeVFSResult gnome_vfs_truncate_handle (GnomeVFSHandle *handle, + GnomeVFSFileSize length); + + + + + + + + + + + + +Description + + + + + + +Details + +<anchor id="gnome-vfs-truncate"/>gnome_vfs_truncate () +gnome_vfs_truncateGnomeVFSResult gnome_vfs_truncate (const gchar *text_uri, + GnomeVFSFileSize length); + +Truncate the file at text_uri to length bytes. + + + +text_uri : + URI of the file to be truncated + +length : + length of the new file at text_uri + +Returns : An integer representing the result of the operation + + + +<anchor id="gnome-vfs-truncate-uri"/>gnome_vfs_truncate_uri () +gnome_vfs_truncate_uriGnomeVFSResult gnome_vfs_truncate_uri (GnomeVFSURI *uri, + GnomeVFSFileSize length); + +Truncate the file at uri to be only length bytes. Data past length +bytes will be discarded. + + + +uri : + URI of the file to be truncated + +length : + length of the new file at uri + +Returns : An integer representing the result of the operation + + + +<anchor id="gnome-vfs-truncate-handle"/>gnome_vfs_truncate_handle () +gnome_vfs_truncate_handleGnomeVFSResult gnome_vfs_truncate_handle (GnomeVFSHandle *handle, + GnomeVFSFileSize length); + +Truncate the file pointed to be handle to be only length bytes. +Data past length bytes will be discarded. + + + +handle : + a handle to the file to be truncated + +length : + length of the new file the handle is open to + +Returns : An integer representing the result of the operation + + + + + + + + + diff --git a/doc/xml/gnome-vfs-inet-connection.xml b/doc/xml/gnome-vfs-inet-connection.xml new file mode 100644 index 0000000..5527994 --- /dev/null +++ b/doc/xml/gnome-vfs-inet-connection.xml @@ -0,0 +1,167 @@ + + +gnome-vfs-inet-connection +3 +GNOME-VFS-2.0 Library + + + +gnome-vfs-inet-connection + + +Synopsis + + + + + +GnomeVFSResult gnome_vfs_inet_connection_create + (GnomeVFSInetConnection **connection_return, + const gchar *host_name, + guint host_port, + GnomeVFSCancellation *cancellation); +void gnome_vfs_inet_connection_destroy + (GnomeVFSInetConnection *connection, + GnomeVFSCancellation *cancellation); +void gnome_vfs_inet_connection_free (GnomeVFSInetConnection *connection, + GnomeVFSCancellation *cancellation); +GnomeVFSSocket* gnome_vfs_inet_connection_to_socket + (GnomeVFSInetConnection *connection); +GnomeVFSSocketBuffer* gnome_vfs_inet_connection_to_socket_buffer + (GnomeVFSInetConnection *connection); +int gnome_vfs_inet_connection_get_fd + (GnomeVFSInetConnection *connection); + + + + + + + + + + + + +Description + + + + + + +Details + +<anchor id="gnome-vfs-inet-connection-create"/>gnome_vfs_inet_connection_create () +gnome_vfs_inet_connection_createGnomeVFSResult gnome_vfs_inet_connection_create + (GnomeVFSInetConnection **connection_return, + const gchar *host_name, + guint host_port, + GnomeVFSCancellation *cancellation); + +Creates a connection at handle_return to host_name using +port port. + + + +connection_return : + pointer to a GnomeVFSInetConnection, which will +contain an allocated GnomeVFSInetConnection object on return. + +host_name : + string indicating the host to establish an internet connection with + +host_port : + the port number to connect to + +cancellation : + handle allowing cancellation of the operation + +Returns : GnomeVFSResult indicating the success of the operation + + + +<anchor id="gnome-vfs-inet-connection-destroy"/>gnome_vfs_inet_connection_destroy () +gnome_vfs_inet_connection_destroyvoid gnome_vfs_inet_connection_destroy + (GnomeVFSInetConnection *connection, + GnomeVFSCancellation *cancellation); + +Closes/Destroys connection. + + + +connection : + connection to destroy + +cancellation : + handle for cancelling the operation + + + +<anchor id="gnome-vfs-inet-connection-free"/>gnome_vfs_inet_connection_free () +gnome_vfs_inet_connection_freevoid gnome_vfs_inet_connection_free (GnomeVFSInetConnection *connection, + GnomeVFSCancellation *cancellation); + + + +connection : + + +cancellation : + + + + + + +<anchor id="gnome-vfs-inet-connection-to-socket"/>gnome_vfs_inet_connection_to_socket () +gnome_vfs_inet_connection_to_socketGnomeVFSSocket* gnome_vfs_inet_connection_to_socket + (GnomeVFSInetConnection *connection); + +Wrapper connection inside a standard GnomeVFSSocket for convenience. + + + +connection : + connection to convert to wrapper in a GnomeVFSSocket + +Returns : a newly created GnomeVFSSocket around connection. + + + +<anchor id="gnome-vfs-inet-connection-to-socket-buffer"/>gnome_vfs_inet_connection_to_socket_buffer () +gnome_vfs_inet_connection_to_socket_bufferGnomeVFSSocketBuffer* gnome_vfs_inet_connection_to_socket_buffer + (GnomeVFSInetConnection *connection); + +Wrapper connection inside a standard GnomeVFSSocketBuffer for convenience. + + + +connection : + connection to convert to wrapper in a GnomeVFSSocketBuffer + +Returns : a newly created GnomeVFSSocketBuffer around connection. + + + +<anchor id="gnome-vfs-inet-connection-get-fd"/>gnome_vfs_inet_connection_get_fd () +gnome_vfs_inet_connection_get_fdint gnome_vfs_inet_connection_get_fd + (GnomeVFSInetConnection *connection); + +Retrieve the UNIX file descriptor corresponding to connection. + + + +connection : + connection to get the file descriptor from + +Returns : file descriptor + + + + + + + + + diff --git a/doc/xml/gnome-vfs-init.xml b/doc/xml/gnome-vfs-init.xml new file mode 100644 index 0000000..1eb27d7 --- /dev/null +++ b/doc/xml/gnome-vfs-init.xml @@ -0,0 +1,138 @@ + + +Initialization/Shutdown +3 +GNOME-VFS-2.0 Library + + + +Initialization/Shutdown + + +Synopsis + + + + + +gboolean gnome_vfs_init (void); +gboolean gnome_vfs_initialized (void); +void gnome_vfs_shutdown (void); +void gnome_vfs_loadinit (gpointer app, + gpointer modinfo); +void gnome_vfs_preinit (gpointer app, + gpointer modinfo); +void gnome_vfs_postinit (gpointer app, + gpointer modinfo); + + + + + + + + + + + + +Description + +Starting GnomeVFS up and shutting it down. Usually when using the whole +GNOME framework this library is initialized and shutdown automatically +when calling gnome_init. + + + + +Details + +<anchor id="gnome-vfs-init"/>gnome_vfs_init () +gnome_vfs_initgboolean gnome_vfs_init (void); + +If GnomeVFS is not already initialized, initialize it. This must be +called prior to performing any other GnomeVFS operations, and may +be called multiple times without error. + + + +Returns : TRUE if GnomeVFS is successfully initialized (or was +already initialized) + + + +<anchor id="gnome-vfs-initialized"/>gnome_vfs_initialized () +gnome_vfs_initializedgboolean gnome_vfs_initialized (void); + +Detects if GnomeVFS has already been initialized (GnomeVFS must be +initialized prior to using any methods or operations). + + + +Returns : TRUE if GnomeVFS has already been initialized + + + +<anchor id="gnome-vfs-shutdown"/>gnome_vfs_shutdown () +gnome_vfs_shutdownvoid gnome_vfs_shutdown (void); + +Cease all active GnomeVFS operations and unload the MIME +database from memory. + + + + +<anchor id="gnome-vfs-loadinit"/>gnome_vfs_loadinit () +gnome_vfs_loadinitvoid gnome_vfs_loadinit (gpointer app, + gpointer modinfo); + + + +app : + + +modinfo : + + + + + + +<anchor id="gnome-vfs-preinit"/>gnome_vfs_preinit () +gnome_vfs_preinitvoid gnome_vfs_preinit (gpointer app, + gpointer modinfo); + + + +app : + + +modinfo : + + + + + + +<anchor id="gnome-vfs-postinit"/>gnome_vfs_postinit () +gnome_vfs_postinitvoid gnome_vfs_postinit (gpointer app, + gpointer modinfo); + + + +app : + + +modinfo : + + + + + + + + + + + + diff --git a/doc/xml/gnome-vfs-method.xml b/doc/xml/gnome-vfs-method.xml new file mode 100644 index 0000000..596ea27 --- /dev/null +++ b/doc/xml/gnome-vfs-method.xml @@ -0,0 +1,200 @@ + + +gnome-vfs-method +3 +GNOME-VFS-2.0 Library + + + +gnome-vfs-method + + +Synopsis + + + + + +GnomeVFSMethod* (*GnomeVFSMethodInitFunc) (const char *method_name, + const char *config_args); +void (*GnomeVFSMethodShutdownFunc) (GnomeVFSMethod *method); +GnomeVFSResult (*GnomeVFSMethodTruncateFunc) + (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileSize length, + GnomeVFSContext *context); +GnomeVFSResult (*GnomeVFSMethodTruncateHandleFunc) + (GnomeVFSMethod *method, + GnomeVFSMethodHandle *handle, + GnomeVFSFileSize length, + GnomeVFSContext *context); +#define VFS_METHOD_HAS_FUNC (method,func) +gboolean gnome_vfs_method_init (void); +GnomeVFSMethod* gnome_vfs_method_get (const gchar *name); +GnomeVFSTransform* gnome_vfs_transform_get (const gchar *name); + + + + + + + + + + + + +Description + + + + + + +Details + +<anchor id="GnomeVFSMethodInitFunc"/>GnomeVFSMethodInitFunc () +GnomeVFSMethodInitFuncGnomeVFSMethod* (*GnomeVFSMethodInitFunc) (const char *method_name, + const char *config_args); + + + +method_name : + + +config_args : + + +Returns : + + + + + +<anchor id="GnomeVFSMethodShutdownFunc"/>GnomeVFSMethodShutdownFunc () +GnomeVFSMethodShutdownFuncvoid (*GnomeVFSMethodShutdownFunc) (GnomeVFSMethod *method); + + + +method : + + + + + + +<anchor id="GnomeVFSMethodTruncateFunc"/>GnomeVFSMethodTruncateFunc () +GnomeVFSMethodTruncateFuncGnomeVFSResult (*GnomeVFSMethodTruncateFunc) + (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileSize length, + GnomeVFSContext *context); + + + +method : + + +uri : + + +length : + + +context : + + +Returns : + + + + + +<anchor id="GnomeVFSMethodTruncateHandleFunc"/>GnomeVFSMethodTruncateHandleFunc () +GnomeVFSMethodTruncateHandleFuncGnomeVFSResult (*GnomeVFSMethodTruncateHandleFunc) + (GnomeVFSMethod *method, + GnomeVFSMethodHandle *handle, + GnomeVFSFileSize length, + GnomeVFSContext *context); + + + +method : + + +handle : + + +length : + + +context : + + +Returns : + + + + + +<anchor id="VFS-METHOD-HAS-FUNC-CAPS"/>VFS_METHOD_HAS_FUNC() +VFS_METHOD_HAS_FUNC#define VFS_METHOD_HAS_FUNC(method,func) ((((char *)&((method)->func)) - ((char *)(method)) < (method)->method_table_size) && method->func != NULL) + + + + +method : + + +func : + + + + + + +<anchor id="gnome-vfs-method-init"/>gnome_vfs_method_init () +gnome_vfs_method_initgboolean gnome_vfs_method_init (void); + + + +Returns : + + + + + +<anchor id="gnome-vfs-method-get"/>gnome_vfs_method_get () +gnome_vfs_method_getGnomeVFSMethod* gnome_vfs_method_get (const gchar *name); + + + +name : + + +Returns : + + + + + +<anchor id="gnome-vfs-transform-get"/>gnome_vfs_transform_get () +gnome_vfs_transform_getGnomeVFSTransform* gnome_vfs_transform_get (const gchar *name); + + + +name : + + +Returns : + + + + + + + + + + + diff --git a/doc/xml/gnome-vfs-mime-database.xml b/doc/xml/gnome-vfs-mime-database.xml new file mode 100644 index 0000000..76f733a --- /dev/null +++ b/doc/xml/gnome-vfs-mime-database.xml @@ -0,0 +1,1268 @@ + + +File Types +3 +GNOME-VFS-2.0 Library + + + +File Types +functions for getting information about files based on their MIME type + + +Synopsis + + + + + +#define GNOME_VFS_MIME_TYPE_UNKNOWN +const char* gnome_vfs_get_mime_type_for_data + (gconstpointer data, + int data_size); +char* gnome_vfs_get_mime_type (const char *text_uri); +enum GnomeVFSMimeActionType; +enum GnomeVFSMimeApplicationArgumentType; +typedef GnomeVFSMimeApplication; +GnomeVFSMimeApplication* gnome_vfs_mime_application_copy + (GnomeVFSMimeApplication *application); +GnomeVFSMimeActionType gnome_vfs_mime_get_default_action_type + (const char *mime_type); +GnomeVFSMimeAction* gnome_vfs_mime_get_default_action + (const char *mime_type); +GnomeVFSMimeApplication* gnome_vfs_mime_get_default_application + (const char *mime_type); +Bonobo_ServerInfo* gnome_vfs_mime_get_default_component + (const char *mime_type); +GList* gnome_vfs_mime_get_short_list_applications + (const char *mime_type); +GList* gnome_vfs_mime_get_short_list_components + (const char *mime_type); +GList* gnome_vfs_mime_get_all_applications + (const char *mime_type); +GList* gnome_vfs_mime_get_all_components + (const char *mime_type); +GnomeVFSResult gnome_vfs_mime_set_default_action_type + (const char *mime_type, + GnomeVFSMimeActionType action_type); +GnomeVFSResult gnome_vfs_mime_set_default_application + (const char *mime_type, + const char *application_id); +GnomeVFSResult gnome_vfs_mime_set_default_component + (const char *mime_type, + const char *component_iid); +const char* gnome_vfs_mime_get_icon (const char *mime_type); +GnomeVFSResult gnome_vfs_mime_set_icon (const char *mime_type, + const char *filename); +const char* gnome_vfs_mime_get_description (const char *mime_type); +GnomeVFSResult gnome_vfs_mime_set_description + (const char *mime_type, + const char *description); +gboolean gnome_vfs_mime_can_be_executable + (const char *mime_type); +GnomeVFSResult gnome_vfs_mime_set_can_be_executable + (const char *mime_type, + gboolean new_value); +GnomeVFSResult gnome_vfs_mime_set_short_list_applications + (const char *mime_type, + GList *application_ids); +GnomeVFSResult gnome_vfs_mime_set_short_list_components + (const char *mime_type, + GList *component_iids); +GnomeVFSResult gnome_vfs_mime_add_application_to_short_list + (const char *mime_type, + const char *application_id); +GnomeVFSResult gnome_vfs_mime_remove_application_from_short_list + (const char *mime_type, + const char *application_id); +GnomeVFSResult gnome_vfs_mime_add_component_to_short_list + (const char *mime_type, + const char *iid); +GnomeVFSResult gnome_vfs_mime_remove_component_from_short_list + (const char *mime_type, + const char *iid); +GnomeVFSResult gnome_vfs_mime_add_extension (const char *mime_type, + const char *extension); +GnomeVFSResult gnome_vfs_mime_remove_extension + (const char *mime_type, + const char *extension); +GnomeVFSResult gnome_vfs_mime_extend_all_applications + (const char *mime_type, + GList *application_ids); +GnomeVFSResult gnome_vfs_mime_remove_from_all_applications + (const char *mime_type, + GList *application_ids); +GnomeVFSMimeApplication* gnome_vfs_mime_application_new_from_id + (const char *id); +void gnome_vfs_mime_application_free (GnomeVFSMimeApplication *application); +void gnome_vfs_mime_action_free (GnomeVFSMimeAction *action); +void gnome_vfs_mime_application_list_free + (GList *list); +void gnome_vfs_mime_component_list_free + (GList *list); +gboolean gnome_vfs_mime_id_in_application_list + (const char *id, + GList *applications); +gboolean gnome_vfs_mime_id_in_component_list + (const char *iid, + GList *components); +GList* gnome_vfs_mime_remove_application_from_list + (GList *applications, + const char *application_id, + gboolean *did_remove); +GList* gnome_vfs_mime_remove_component_from_list + (GList *components, + const char *iid, + gboolean *did_remove); +GList* gnome_vfs_mime_id_list_from_component_list + (GList *components); +GList* gnome_vfs_mime_id_list_from_application_list + (GList *applications); +void gnome_vfs_mime_freeze (void); +void gnome_vfs_mime_thaw (void); +void gnome_vfs_mime_info_reload (void); +gboolean gnome_vfs_mime_type_is_known (const char *mime_type); +const char* gnome_vfs_mime_get_value (const char *mime_type, + const char *key); +GnomeVFSResult gnome_vfs_mime_set_value (const char *mime_type, + const char *key, + const char *value); +GList* gnome_vfs_mime_get_key_list (const char *mime_type); +void gnome_vfs_mime_keys_list_free (GList *mime_type_list); +GList* gnome_vfs_mime_get_extensions_list + (const char *mime_type); +void gnome_vfs_mime_extensions_list_free + (GList *list); +char* gnome_vfs_mime_get_extensions_string + (const char *mime_type); +char* gnome_vfs_mime_get_extensions_pretty_string + (const char *mime_type); +GList* gnome_vfs_get_registered_mime_types + (void); +void gnome_vfs_mime_registered_mime_type_list_free + (GList *list); +GnomeVFSResult gnome_vfs_mime_set_registered_type_key + (const char *mime_type, + const char *key, + const char *data); +GnomeVFSResult gnome_vfs_mime_set_extensions_list + (const char *mime_type, + const char *extensions_list); +void gnome_vfs_mime_registered_mime_type_delete + (const char *mime_type); +void gnome_vfs_mime_reset (void); + + + + + + + + + + + + +Description + + + + + + +Details + +<anchor id="GNOME-VFS-MIME-TYPE-UNKNOWN-CAPS"/>GNOME_VFS_MIME_TYPE_UNKNOWN +GNOME_VFS_MIME_TYPE_UNKNOWN#define GNOME_VFS_MIME_TYPE_UNKNOWN "application/octet-stream" + + +The value returned for the MIME type when a file did +not match any entries in the MIME database. May be +treated as a file of an unknown type. + + + + +<anchor id="gnome-vfs-get-mime-type-for-data"/>gnome_vfs_get_mime_type_for_data () +gnome_vfs_get_mime_type_for_dataconst char* gnome_vfs_get_mime_type_for_data + (gconstpointer data, + int data_size); + +Tries to guess the mime type of the data in data +using the magic patterns. + + + +data : + A pointer to data in memory. + +data_size : + Size of the data. + +Returns :the mime-type for this filename. + + + +<anchor id="gnome-vfs-get-mime-type"/>gnome_vfs_get_mime_type () +gnome_vfs_get_mime_typechar* gnome_vfs_get_mime_type (const char *text_uri); + +Determine the mime type of text_uri. The mime type is determined +in the same way as by gnome_vfs_get_file_info(). This is meant as +a convenience function for times when you only want the mime type. + + + +text_uri : + URI of the file for which to get the mime type + +Returns : The mime type, or NULL if there is an error reading +the file. + + + +<anchor id="GnomeVFSMimeActionType"/>enum GnomeVFSMimeActionType +GnomeVFSMimeActionTypetypedef enum { + GNOME_VFS_MIME_ACTION_TYPE_NONE, + GNOME_VFS_MIME_ACTION_TYPE_APPLICATION, + GNOME_VFS_MIME_ACTION_TYPE_COMPONENT +} GnomeVFSMimeActionType; + + + + + +<anchor id="GnomeVFSMimeApplicationArgumentType"/>enum GnomeVFSMimeApplicationArgumentType +GnomeVFSMimeApplicationArgumentTypetypedef enum { + GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_URIS, + GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_PATHS, + GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_URIS_FOR_NON_FILES +} GnomeVFSMimeApplicationArgumentType; + + + + + +<anchor id="GnomeVFSMimeApplication"/>GnomeVFSMimeApplication +GnomeVFSMimeApplicationtypedef struct { + char *id; + char *name; + char *command; + gboolean can_open_multiple_files; + GnomeVFSMimeApplicationArgumentType expects_uris; + GList *supported_uri_schemes; + gboolean requires_terminal; + + /* Padded to avoid future breaks in ABI compatibility */ + void *reserved1; + void *reserved2; + +} GnomeVFSMimeApplication; + + + + + +<anchor id="gnome-vfs-mime-application-copy"/>gnome_vfs_mime_application_copy () +gnome_vfs_mime_application_copyGnomeVFSMimeApplication* gnome_vfs_mime_application_copy + (GnomeVFSMimeApplication *application); + +Creates a newly referenced copy of a GnomeVFSMimeApplication object. + + + +application : + The GnomeVFSMimeApplication to be duplicated. + +Returns : A copy of application + + + +<anchor id="gnome-vfs-mime-get-default-action-type"/>gnome_vfs_mime_get_default_action_type () +gnome_vfs_mime_get_default_action_typeGnomeVFSMimeActionType gnome_vfs_mime_get_default_action_type + (const char *mime_type); + +Query the MIME database for the type of action to be performed on a particular MIME type by default. + + + +mime_type : + A const char * containing a mime type, e.g. "application/x-php" + +Returns : The type of action to be performed on a file of +MIME type, mime_type by default. + + + +<anchor id="gnome-vfs-mime-get-default-action"/>gnome_vfs_mime_get_default_action () +gnome_vfs_mime_get_default_actionGnomeVFSMimeAction* gnome_vfs_mime_get_default_action + (const char *mime_type); + +Query the MIME database for default action associated with a particular MIME type mime_type. + + + +mime_type : + A const char * containing a mime type, e.g. "application/x-php" + +Returns : A GnomeVFSMimeAction representing the default action to perform upon +file of type mime_type. + + + +<anchor id="gnome-vfs-mime-get-default-application"/>gnome_vfs_mime_get_default_application () +gnome_vfs_mime_get_default_applicationGnomeVFSMimeApplication* gnome_vfs_mime_get_default_application + (const char *mime_type); + +Query the MIME database for the application to be executed on files of MIME type +mime_type by default. + + + +mime_type : + A const char * containing a mime type, e.g. "image/png" + +Returns : A GnomeVFSMimeApplication representing the default handler of mime_type + + + +<anchor id="gnome-vfs-mime-get-default-component"/>gnome_vfs_mime_get_default_component () +gnome_vfs_mime_get_default_componentBonobo_ServerInfo* gnome_vfs_mime_get_default_component + (const char *mime_type); + +Query the MIME database for the default Bonobo component to be activated to +view files of MIME type mime_type. + + + +mime_type : + A const char * containing a mime type, e.g. "image/png" + +Returns : An Bonobo_ServerInfo * representing the OAF server to be activated +to get a reference to the proper component. + + + +<anchor id="gnome-vfs-mime-get-short-list-applications"/>gnome_vfs_mime_get_short_list_applications () +gnome_vfs_mime_get_short_list_applicationsGList* gnome_vfs_mime_get_short_list_applications + (const char *mime_type); + +Return an alphabetically sorted list of GnomeVFSMimeApplication +data structures for the requested mime type. The short list contains +"select" applications recommended for handling this MIME type, appropriate for +display to the user. + + + +mime_type : + A const char * containing a mime type, e.g. "image/png" + +Returns : A GList * where the elements are GnomeVFSMimeApplication * +representing various applications to display in the short list for mime_type. + + + +<anchor id="gnome-vfs-mime-get-short-list-components"/>gnome_vfs_mime_get_short_list_components () +gnome_vfs_mime_get_short_list_componentsGList* gnome_vfs_mime_get_short_list_components + (const char *mime_type); + +Return an unsorted sorted list of Bonobo_ServerInfo * +data structures for the requested mime type. The short list contains +"select" components recommended for handling this MIME type, appropriate for +display to the user. + + + +mime_type : + A const char * containing a mime type, e.g. "image/png" + +Returns : A GList * where the elements are Bonobo_ServerInfo * +representing various components to display in the short list for mime_type. + + + +<anchor id="gnome-vfs-mime-get-all-applications"/>gnome_vfs_mime_get_all_applications () +gnome_vfs_mime_get_all_applicationsGList* gnome_vfs_mime_get_all_applications + (const char *mime_type); + +Return an alphabetically sorted list of GnomeVFSMimeApplication +data structures representing all applications in the MIME database registered +to handle files of MIME type mime_type (and supertypes). + + + +mime_type : + A const char * containing a mime type, e.g. "image/png" + +Returns : A GList * where the elements are GnomeVFSMimeApplication * +representing applications that handle MIME type mime_type. + + + +<anchor id="gnome-vfs-mime-get-all-components"/>gnome_vfs_mime_get_all_components () +gnome_vfs_mime_get_all_componentsGList* gnome_vfs_mime_get_all_components + (const char *mime_type); + +Return an alphabetically sorted list of Bonobo_ServerInfo +data structures representing all Bonobo components registered +to handle files of MIME type mime_type (and supertypes). + + + +mime_type : + A const char * containing a mime type, e.g. "image/png" + +Returns : A GList * where the elements are Bonobo_ServerInfo * +representing components that can handle MIME type mime_type. + + + +<anchor id="gnome-vfs-mime-set-default-action-type"/>gnome_vfs_mime_set_default_action_type () +gnome_vfs_mime_set_default_action_typeGnomeVFSResult gnome_vfs_mime_set_default_action_type + (const char *mime_type, + GnomeVFSMimeActionType action_type); + +Sets the default action type to be performed on files of MIME type mime_type. + + + +mime_type : + A const char * containing a mime type, e.g. "image/png" + +action_type : + A GnomeVFSMimeActionType containing the action to perform by default + +Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered. + + + +<anchor id="gnome-vfs-mime-set-default-application"/>gnome_vfs_mime_set_default_application () +gnome_vfs_mime_set_default_applicationGnomeVFSResult gnome_vfs_mime_set_default_application + (const char *mime_type, + const char *application_id); + +Sets the default application to be run on files of MIME type mime_type. + + + +mime_type : + A const char * containing a mime type, e.g. "application/x-php" + +application_id : + A key representing an application in the MIME database +(GnomeVFSMimeApplication->id, for example) + +Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered. + + + +<anchor id="gnome-vfs-mime-set-default-component"/>gnome_vfs_mime_set_default_component () +gnome_vfs_mime_set_default_componentGnomeVFSResult gnome_vfs_mime_set_default_component + (const char *mime_type, + const char *component_iid); + +Sets the default component to be activated for files of MIME type mime_type. + + + +mime_type : + A const char * containing a mime type, e.g. "application/x-php" + +component_iid : + The OAFIID of a component + +Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered. + + + +<anchor id="gnome-vfs-mime-get-icon"/>gnome_vfs_mime_get_icon () +gnome_vfs_mime_get_iconconst char* gnome_vfs_mime_get_icon (const char *mime_type); + +Query the MIME database for an icon representing the specified MIME type. + + + +mime_type : + A const char * containing a MIME type + +Returns : The filename of the icon as listed in the MIME database. This is +usually a filename without path information, e.g. "i-chardev.png", and sometimes +does not have an extension, e.g. "i-regular" if the icon is supposed to be image +type agnostic between icon themes. Icons are generic, and not theme specific. These +will not necessarily match with the icons a user sees in Nautilus, you have been warned. + + + +<anchor id="gnome-vfs-mime-set-icon"/>gnome_vfs_mime_set_icon () +gnome_vfs_mime_set_iconGnomeVFSResult gnome_vfs_mime_set_icon (const char *mime_type, + const char *filename); + +Set the icon entry for a particular MIME type in the MIME database. Note that +icon entries need not necessarily contain the full path, and do not necessarily need to +specify an extension. So "i-regular", "my-special-icon.png", and "some-icon" +are all valid icon filenames. + + + +mime_type : + A const char * containing a MIME type + +filename : + a const char * containing an image filename + +Returns : A GnomeVFSResult indicating the success of the operation +or any errors that may have occurred. + + + +<anchor id="gnome-vfs-mime-get-description"/>gnome_vfs_mime_get_description () +gnome_vfs_mime_get_descriptionconst char* gnome_vfs_mime_get_description (const char *mime_type); + +Query the MIME database for a description of the specified MIME type. + + + +mime_type : + the mime type + +Returns : A description of MIME type mime_type + + + +<anchor id="gnome-vfs-mime-set-description"/>gnome_vfs_mime_set_description () +gnome_vfs_mime_set_descriptionGnomeVFSResult gnome_vfs_mime_set_description + (const char *mime_type, + const char *description); + +Set the description of this MIME type in the MIME database. The description +should be something like "Gnumeric spreadsheet". + + + +mime_type : + A const char * containing a mime type + +description : + A description of this MIME type + +Returns : GnomeVFSResult indicating the success of the operation or any +errors that may have occurred. + + + +<anchor id="gnome-vfs-mime-can-be-executable"/>gnome_vfs_mime_can_be_executable () +gnome_vfs_mime_can_be_executablegboolean gnome_vfs_mime_can_be_executable + (const char *mime_type); + +Check whether files of this MIME type might conceivably be executable. +Default for known types if FALSE. Default for unknown types is TRUE. + + + +mime_type : + A const char * containing a mime type + +Returns : gboolean containing TRUE if some files of this MIME type +are registered as being executable, and false otherwise. + + + +<anchor id="gnome-vfs-mime-set-can-be-executable"/>gnome_vfs_mime_set_can_be_executable () +gnome_vfs_mime_set_can_be_executableGnomeVFSResult gnome_vfs_mime_set_can_be_executable + (const char *mime_type, + gboolean new_value); + +Set whether files of this MIME type might conceivably be executable. + + + +mime_type : + A const char * containing a mime type + +new_value : + A boolean value indicating whether mime_type could be executable. + +Returns : GnomeVFSResult indicating the success of the operation or any +errors that may have occurred. + + + +<anchor id="gnome-vfs-mime-set-short-list-applications"/>gnome_vfs_mime_set_short_list_applications () +gnome_vfs_mime_set_short_list_applicationsGnomeVFSResult gnome_vfs_mime_set_short_list_applications + (const char *mime_type, + GList *application_ids); + +Set the short list of applications for the specified MIME type. The short list +contains applications recommended for possible selection by the user. + + + +mime_type : + A const char * containing a mime type, e.g. "application/x-php" + +application_ids : + GList of const char * application ids + +Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered. + + + +<anchor id="gnome-vfs-mime-set-short-list-components"/>gnome_vfs_mime_set_short_list_components () +gnome_vfs_mime_set_short_list_componentsGnomeVFSResult gnome_vfs_mime_set_short_list_components + (const char *mime_type, + GList *component_iids); + +Set the short list of components for the specified MIME type. The short list +contains companents recommended for possible selection by the user. * + + + +mime_type : + A const char * containing a mime type, e.g. "application/x-php" + +component_iids : + GList of const char * OAF IIDs + +Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered. + + + +<anchor id="gnome-vfs-mime-add-application-to-short-list"/>gnome_vfs_mime_add_application_to_short_list () +gnome_vfs_mime_add_application_to_short_listGnomeVFSResult gnome_vfs_mime_add_application_to_short_list + (const char *mime_type, + const char *application_id); + +Add an application to the short list for MIME type mime_type. The short list contains +applications recommended for display as choices to the user for a particular MIME type. + + + +mime_type : + A const char * containing a mime type, e.g. "application/x-php" + +application_id : + const char * containing the application's id in the MIME database + +Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered. + + + +<anchor id="gnome-vfs-mime-remove-application-from-short-list"/>gnome_vfs_mime_remove_application_from_short_list () +gnome_vfs_mime_remove_application_from_short_listGnomeVFSResult gnome_vfs_mime_remove_application_from_short_list + (const char *mime_type, + const char *application_id); + +Remove an application from the short list for MIME type mime_type. The short list contains +applications recommended for display as choices to the user for a particular MIME type. + + + +mime_type : + A const char * containing a mime type, e.g. "application/x-php" + +application_id : + const char * containing the application's id in the MIME database + +Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered. + + + +<anchor id="gnome-vfs-mime-add-component-to-short-list"/>gnome_vfs_mime_add_component_to_short_list () +gnome_vfs_mime_add_component_to_short_listGnomeVFSResult gnome_vfs_mime_add_component_to_short_list + (const char *mime_type, + const char *iid); + +Add a component to the short list for MIME type mime_type. The short list contains +components recommended for display as choices to the user for a particular MIME type. + + + +mime_type : + A const char * containing a mime type, e.g. "application/x-php" + +iid : + const char * containing the component's OAF IID + +Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered. + + + +<anchor id="gnome-vfs-mime-remove-component-from-short-list"/>gnome_vfs_mime_remove_component_from_short_list () +gnome_vfs_mime_remove_component_from_short_listGnomeVFSResult gnome_vfs_mime_remove_component_from_short_list + (const char *mime_type, + const char *iid); + +Remove a component from the short list for MIME type mime_type. The short list contains +components recommended for display as choices to the user for a particular MIME type. + + + +mime_type : + A const char * containing a mime type, e.g. "application/x-php" + +iid : + const char * containing the component's OAF IID + +Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered. + + + +<anchor id="gnome-vfs-mime-add-extension"/>gnome_vfs_mime_add_extension () +gnome_vfs_mime_add_extensionGnomeVFSResult gnome_vfs_mime_add_extension (const char *mime_type, + const char *extension); + +Add a file extension to the specificed MIME type in the MIME database. + + + +mime_type : + The mime type to add the mapping to. + +extension : + The extension to add (e.g. "txt") + +Returns : GnomeVFSResult indicating the success of the operation or any +errors that may have occurred. + + + +<anchor id="gnome-vfs-mime-remove-extension"/>gnome_vfs_mime_remove_extension () +gnome_vfs_mime_remove_extensionGnomeVFSResult gnome_vfs_mime_remove_extension + (const char *mime_type, + const char *extension); + +Removes a file extension from the specificed MIME type in the MIME database. + + + +mime_type : + The mime type to remove the extension from + +extension : + The extension to remove + +Returns : GnomeVFSResult indicating the success of the operation or any +errors that may have occurred. + + + +<anchor id="gnome-vfs-mime-extend-all-applications"/>gnome_vfs_mime_extend_all_applications () +gnome_vfs_mime_extend_all_applicationsGnomeVFSResult gnome_vfs_mime_extend_all_applications + (const char *mime_type, + GList *application_ids); + +Register mime_type as being handled by all applications list in application_ids. + + + +mime_type : + A const char * containing a mime type, e.g. "application/x-php" + +application_ids : + a GList of const char * containing application ids + +Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered. + + + +<anchor id="gnome-vfs-mime-remove-from-all-applications"/>gnome_vfs_mime_remove_from_all_applications () +gnome_vfs_mime_remove_from_all_applicationsGnomeVFSResult gnome_vfs_mime_remove_from_all_applications + (const char *mime_type, + GList *application_ids); + +Remove mime_type as a handled type from every application in application_ids + + + +mime_type : + A const char * containing a mime type, e.g. "application/x-php" + +application_ids : + a GList of const char * containing application ids + +Returns : A GnomeVFSResult indicating the success of the operation or reporting +any errors encountered. + + + +<anchor id="gnome-vfs-mime-application-new-from-id"/>gnome_vfs_mime_application_new_from_id () +gnome_vfs_mime_application_new_from_idGnomeVFSMimeApplication* gnome_vfs_mime_application_new_from_id + (const char *id); + +Fetches the GnomeVFSMimeApplication associated with the specified +application ID from the MIME database. + + + +id : + A const char * containing an application id + +Returns : GnomeVFSMimeApplication * corresponding to id + + + +<anchor id="gnome-vfs-mime-application-free"/>gnome_vfs_mime_application_free () +gnome_vfs_mime_application_freevoid gnome_vfs_mime_application_free (GnomeVFSMimeApplication *application); + +Frees a GnomeVFSMimeApplication *. + + + +application : + The GnomeVFSMimeApplication to be freed + + + +<anchor id="gnome-vfs-mime-action-free"/>gnome_vfs_mime_action_free () +gnome_vfs_mime_action_freevoid gnome_vfs_mime_action_free (GnomeVFSMimeAction *action); + +Frees a GnomeVFSMimeAction *. + + + +action : + The GnomeVFSMimeAction to be freed + + + +<anchor id="gnome-vfs-mime-application-list-free"/>gnome_vfs_mime_application_list_free () +gnome_vfs_mime_application_list_freevoid gnome_vfs_mime_application_list_free + (GList *list); + +Frees lists of GnomeVFSApplications, as returned from functions such +as gnome_vfs_get_all_applications(). + + + +list : + a GList of GnomeVFSApplication * to be freed + + + +<anchor id="gnome-vfs-mime-component-list-free"/>gnome_vfs_mime_component_list_free () +gnome_vfs_mime_component_list_freevoid gnome_vfs_mime_component_list_free + (GList *list); + +Frees lists of Bonobo_ServerInfo * (as returned from functions such +as gnome_vfs_get_all_components) + + + +list : + a GList of Bonobo_ServerInfo * to be freed + + + +<anchor id="gnome-vfs-mime-id-in-application-list"/>gnome_vfs_mime_id_in_application_list () +gnome_vfs_mime_id_in_application_listgboolean gnome_vfs_mime_id_in_application_list + (const char *id, + GList *applications); + +Check whether an application id is in a list of GnomeVFSMimeApplications. + + + +id : + An application id. + +applications : + A GList * whose nodes are GnomeVFSMimeApplications, such as the +result of gnome_vfs_mime_get_short_list_applications(). + +Returns : TRUE if an application whose id matches id is in applications. + + + +<anchor id="gnome-vfs-mime-id-in-component-list"/>gnome_vfs_mime_id_in_component_list () +gnome_vfs_mime_id_in_component_listgboolean gnome_vfs_mime_id_in_component_list + (const char *iid, + GList *components); + +Check whether a component iid is in a list of Bonobo_ServerInfos. + + + +iid : + A component iid. + +components : + A GList * whose nodes are Bonobo_ServerInfos, such as the +result of gnome_vfs_mime_get_short_list_components(). + +Returns : TRUE if a component whose iid matches iid is in components. + + + +<anchor id="gnome-vfs-mime-remove-application-from-list"/>gnome_vfs_mime_remove_application_from_list () +gnome_vfs_mime_remove_application_from_listGList* gnome_vfs_mime_remove_application_from_list + (GList *applications, + const char *application_id, + gboolean *did_remove); + +Remove an application specified by id from a list of GnomeVFSMimeApplications. + + + +applications : + A GList * whose nodes are GnomeVFSMimeApplications, such as the +result of gnome_vfs_mime_get_short_list_applications(). + +application_id : + The id of an application to remove from applications. + +did_remove : + If non-NULL, this is filled in with TRUE if the application +was found in the list, FALSE otherwise. + +Returns : The modified list. If the application is not found, the list will +be unchanged. + + + +<anchor id="gnome-vfs-mime-remove-component-from-list"/>gnome_vfs_mime_remove_component_from_list () +gnome_vfs_mime_remove_component_from_listGList* gnome_vfs_mime_remove_component_from_list + (GList *components, + const char *iid, + gboolean *did_remove); + +Remove a component specified by iid from a list of Bonobo_ServerInfos. + + + +components : + A GList * whose nodes are Bonobo_ServerInfos, such as the +result of gnome_vfs_mime_get_short_list_components(). + +iid : + The iid of a component to remove from components. + +did_remove : + If non-NULL, this is filled in with TRUE if the component +was found in the list, FALSE otherwise. + +Returns : The modified list. If the component is not found, the list will +be unchanged. + + + +<anchor id="gnome-vfs-mime-id-list-from-component-list"/>gnome_vfs_mime_id_list_from_component_list () +gnome_vfs_mime_id_list_from_component_listGList* gnome_vfs_mime_id_list_from_component_list + (GList *components); + +Create a list of component iids from a list of Bonobo_ServerInfos. + + + +components : + A GList * whose nodes are Bonobo_ServerInfos, such as the +result of gnome_vfs_mime_get_short_list_components(). + +Returns : A new list where each Bonobo_ServerInfo in the original +list is replaced by a char * with the component's iid. The original list is +not modified. + + + +<anchor id="gnome-vfs-mime-id-list-from-application-list"/>gnome_vfs_mime_id_list_from_application_list () +gnome_vfs_mime_id_list_from_application_listGList* gnome_vfs_mime_id_list_from_application_list + (GList *applications); + +Create a list of application ids from a list of GnomeVFSMimeApplications. + + + +applications : + A GList * whose nodes are GnomeVFSMimeApplications, such as the +result of gnome_vfs_mime_get_short_list_applications(). + +Returns : A new list where each GnomeVFSMimeApplication in the original +list is replaced by a char * with the application's id. The original list is +not modified. + + + +<anchor id="gnome-vfs-mime-freeze"/>gnome_vfs_mime_freeze () +gnome_vfs_mime_freezevoid gnome_vfs_mime_freeze (void); + +Freezes the mime data so that you can do multiple +updates to the dat in one batch without needing +to back the files to disk or readind them + + + + +<anchor id="gnome-vfs-mime-thaw"/>gnome_vfs_mime_thaw () +gnome_vfs_mime_thawvoid gnome_vfs_mime_thaw (void); + +UnFreezes the mime data so that you can do multiple +updates to the dat in one batch without needing +to back the files to disk or readind them + + + + +<anchor id="gnome-vfs-mime-info-reload"/>gnome_vfs_mime_info_reload () +gnome_vfs_mime_info_reloadvoid gnome_vfs_mime_info_reload (void); + +Reload the MIME database from disk and notify any listeners +holding active GnomeVFSMIMEMonitor objects. + + + + +<anchor id="gnome-vfs-mime-type-is-known"/>gnome_vfs_mime_type_is_known () +gnome_vfs_mime_type_is_knowngboolean gnome_vfs_mime_type_is_known (const char *mime_type); + +This function returns TRUE if mime_type is in the MIME database at all. + + + +mime_type : + a mime type. + +Returns : TRUE if anything is known about mime_type, otherwise FALSE + + + +<anchor id="gnome-vfs-mime-get-value"/>gnome_vfs_mime_get_value () +gnome_vfs_mime_get_valueconst char* gnome_vfs_mime_get_value (const char *mime_type, + const char *key); + +This function retrieves the value associated with key in +the given GnomeMimeContext. The string is private, you +should not free the result. + + + +mime_type : + a mime type. + +key : + A key to lookup for the given mime-type + +Returns : GNOME_VFS_OK if the operation succeeded, otherwise an error code + + + +<anchor id="gnome-vfs-mime-set-value"/>gnome_vfs_mime_set_value () +gnome_vfs_mime_set_valueGnomeVFSResult gnome_vfs_mime_set_value (const char *mime_type, + const char *key, + const char *value); + +This function is going to set the value +associated to the key and it will save it +to the user' file if necessary. +You should not free the key/values passed to +this function. They are used internally. + + + +mime_type : + a mime type. + +key : + a key to store the value in. + +value : + the value to store in the key. + +Returns : GNOME_VFS_OK if the operation succeeded, otherwise an error code + + + + +<anchor id="gnome-vfs-mime-get-key-list"/>gnome_vfs_mime_get_key_list () +gnome_vfs_mime_get_key_listGList* gnome_vfs_mime_get_key_list (const char *mime_type); + +Gets a list of all keys associated with mime_type. + + + +mime_type : + the MIME type to lookup + +Returns : a GList of const char * representing keys associated +with mime_type + + + +<anchor id="gnome-vfs-mime-keys-list-free"/>gnome_vfs_mime_keys_list_free () +gnome_vfs_mime_keys_list_freevoid gnome_vfs_mime_keys_list_free (GList *mime_type_list); + +Frees the mime type list. + + + +mime_type_list : + A mime type list to free. + + + +<anchor id="gnome-vfs-mime-get-extensions-list"/>gnome_vfs_mime_get_extensions_list () +gnome_vfs_mime_get_extensions_listGList* gnome_vfs_mime_get_extensions_list + (const char *mime_type); + +Get the file extensions associated with mime type mime_type. + + + +mime_type : + type to get the extensions of + +Returns : a GList of char *s + + + +<anchor id="gnome-vfs-mime-extensions-list-free"/>gnome_vfs_mime_extensions_list_free () +gnome_vfs_mime_extensions_list_freevoid gnome_vfs_mime_extensions_list_free + (GList *list); + +Call this function on the list returned by gnome_vfs_mime_extensions +to free the list and all of its elements. + + + +list : + the extensions list + + + +<anchor id="gnome-vfs-mime-get-extensions-string"/>gnome_vfs_mime_get_extensions_string () +gnome_vfs_mime_get_extensions_stringchar* gnome_vfs_mime_get_extensions_string + (const char *mime_type); + +Retrieves the extensions associated with mime_type as a single +space seperated string. + + + +mime_type : + the mime type + +Returns : a string containing space seperated extensions for mime_type + + + +<anchor id="gnome-vfs-mime-get-extensions-pretty-string"/>gnome_vfs_mime_get_extensions_pretty_string () +gnome_vfs_mime_get_extensions_pretty_stringchar* gnome_vfs_mime_get_extensions_pretty_string + (const char *mime_type); + +Returns the supported extensions for mime_type as a comma-seperated list. + + + +mime_type : + the mime type + +Returns : a string containing comma seperated extensions for this mime-type + + + +<anchor id="gnome-vfs-get-registered-mime-types"/>gnome_vfs_get_registered_mime_types () +gnome_vfs_get_registered_mime_typesGList* gnome_vfs_get_registered_mime_types + (void); + + + +Returns : + + + + + +<anchor id="gnome-vfs-mime-registered-mime-type-list-free"/>gnome_vfs_mime_registered_mime_type_list_free () +gnome_vfs_mime_registered_mime_type_list_freevoid gnome_vfs_mime_registered_mime_type_list_free + (GList *list); + +Call this function on the list returned by gnome_vfs_get_registered_mime_types +to free the list and all of its elements. + + + +list : + the extensions list + + + +<anchor id="gnome-vfs-mime-set-registered-type-key"/>gnome_vfs_mime_set_registered_type_key () +gnome_vfs_mime_set_registered_type_keyGnomeVFSResult gnome_vfs_mime_set_registered_type_key + (const char *mime_type, + const char *key, + const char *data); + +This function sets the key data for the registered mime +type's hash table. + + + +mime_type : + Mime type to set key for + +key : + The key to set + +data : + The data to set for the key + +Returns : GNOME_VFS_OK if the operation succeeded, otherwise an error code + + + +<anchor id="gnome-vfs-mime-set-extensions-list"/>gnome_vfs_mime_set_extensions_list () +gnome_vfs_mime_set_extensions_listGnomeVFSResult gnome_vfs_mime_set_extensions_list + (const char *mime_type, + const char *extensions_list); + +Sets the extensions for a given mime type. Overrides +the previously set extensions. + + + +mime_type : + the mime type. + +extensions_list : + a whitespace-separated list of the + extensions to set for this mime type. + +Returns : GNOME_VFS_OK if the operation succeeded, otherwise an error code. + + + +<anchor id="gnome-vfs-mime-registered-mime-type-delete"/>gnome_vfs_mime_registered_mime_type_delete () +gnome_vfs_mime_registered_mime_type_deletevoid gnome_vfs_mime_registered_mime_type_delete + (const char *mime_type); + +Delete a mime type for the user which runs this command. +You can undo this only by calling gnome_vfs_mime_reset + + + +mime_type : + string representing the existing type to delete + + + +<anchor id="gnome-vfs-mime-reset"/>gnome_vfs_mime_reset () +gnome_vfs_mime_resetvoid gnome_vfs_mime_reset (void); + +resets the user's mime database to the system defaults. + + + + + + + + + + diff --git a/doc/xml/gnome-vfs-mime-monitor.xml b/doc/xml/gnome-vfs-mime-monitor.xml new file mode 100644 index 0000000..84a5411 --- /dev/null +++ b/doc/xml/gnome-vfs-mime-monitor.xml @@ -0,0 +1,75 @@ + + +MIME Database Monitor +3 +GNOME-VFS-2.0 Library + + + +MIME Database Monitor +monitor the MIME database for changes (primarily for file browsers) + + +Synopsis + + + + + +#define GNOME_VFS_MIME_MONITOR_TYPE +struct GnomeVFSMIMEMonitorPrivate; +GnomeVFSMIMEMonitor* gnome_vfs_mime_monitor_get + (void); + + + + + + + + + + + + + +Description + + + + + + +Details + +<anchor id="GNOME-VFS-MIME-MONITOR-TYPE-CAPS"/>GNOME_VFS_MIME_MONITOR_TYPE +GNOME_VFS_MIME_MONITOR_TYPE#define GNOME_VFS_MIME_MONITOR_TYPE (gnome_vfs_mime_monitor_get_type ()) + + + + + +<anchor id="GnomeVFSMIMEMonitorPrivate"/>struct GnomeVFSMIMEMonitorPrivate +GnomeVFSMIMEMonitorPrivatestruct GnomeVFSMIMEMonitorPrivate; + + + + +<anchor id="gnome-vfs-mime-monitor-get"/>gnome_vfs_mime_monitor_get () +gnome_vfs_mime_monitor_getGnomeVFSMIMEMonitor* gnome_vfs_mime_monitor_get + (void); + +Get access to the single global monitor. + + + +Returns : the global GnomeVFSMIMEMonitor + + + + + + + + + diff --git a/doc/xml/gnome-vfs-mime.xml b/doc/xml/gnome-vfs-mime.xml new file mode 100644 index 0000000..0c8d2cf --- /dev/null +++ b/doc/xml/gnome-vfs-mime.xml @@ -0,0 +1,214 @@ + + +MIME typing +3 +GNOME-VFS-2.0 Library + + + +MIME typingfunctions to get a mime-type for a file using its name or its content + + +Synopsis + + + + + +void gnome_vfs_mime_shutdown (void); +const char* gnome_vfs_mime_type_from_name (const char *filename); +const char* gnome_vfs_mime_type_from_name_or_default + (const char *filename, + const char *defaultv); +const char* gnome_vfs_get_mime_type_common (GnomeVFSURI *uri); +const char* gnome_vfs_get_mime_type_from_uri + (GnomeVFSURI *uri); +const char* gnome_vfs_get_mime_type_from_file_data + (GnomeVFSURI *uri); +const char* gnome_vfs_get_file_mime_type (const char *path, + const struct stat *optional_stat_info, + gboolean suffix_only); +gboolean gnome_vfs_mime_type_is_supertype + (const char *mime_type); +char* gnome_vfs_get_supertype_from_mime_type + (const char *mime_type); + + + + + + + + + + + + +Description + + + + + + +Details + +<anchor id="gnome-vfs-mime-shutdown"/>gnome_vfs_mime_shutdown () +gnome_vfs_mime_shutdownvoid gnome_vfs_mime_shutdown (void); + +Unload the MIME database from memory. + + + + +<anchor id="gnome-vfs-mime-type-from-name"/>gnome_vfs_mime_type_from_name () +gnome_vfs_mime_type_from_nameconst char* gnome_vfs_mime_type_from_name (const char *filename); + +Determined the mime type for filename. + + + +filename : + A filename (the file does not necessarily exist). + +Returns :the mime-type for this filename. + + + +<anchor id="gnome-vfs-mime-type-from-name-or-default"/>gnome_vfs_mime_type_from_name_or_default () +gnome_vfs_mime_type_from_name_or_defaultconst char* gnome_vfs_mime_type_from_name_or_default + (const char *filename, + const char *defaultv); + +This routine tries to determine the mime-type of the filename +only by looking at the filename from the GNOME database of mime-types. + + + +filename : + A filename (the file does not necesarily exist). + +defaultv : + A default value to be returned if no match is found + +Returns :the mime-type of the filename. If no value could be +determined, it will return defaultv. + + + +<anchor id="gnome-vfs-get-mime-type-common"/>gnome_vfs_get_mime_type_common () +gnome_vfs_get_mime_type_commonconst char* gnome_vfs_get_mime_type_common (GnomeVFSURI *uri); + +Tries to guess the mime type of the file represented by uir. +Favors using the file data to the uri extension. +Handles passing uri of a non-existent file by falling back +on returning a type based on the extension. + + +FIXME: This function will not necessarily return the same mime type as doing a +get file info on the text uri. + + + +uri : + a real file or a non-existent uri. + +Returns : the mime-type for this uri. + + + + +<anchor id="gnome-vfs-get-mime-type-from-uri"/>gnome_vfs_get_mime_type_from_uri () +gnome_vfs_get_mime_type_from_uriconst char* gnome_vfs_get_mime_type_from_uri + (GnomeVFSURI *uri); + +Tries to guess the mime type of the file uri by +checking the file name extension. Works on non-existent +files. + + + +uri : + A file uri. + +Returns :the mime-type for this filename. + + + +<anchor id="gnome-vfs-get-mime-type-from-file-data"/>gnome_vfs_get_mime_type_from_file_data () +gnome_vfs_get_mime_type_from_file_dataconst char* gnome_vfs_get_mime_type_from_file_data + (GnomeVFSURI *uri); + +Tries to guess the mime type of the file uri by +checking the file data using the magic patterns. Does not handle text files properly + + + +uri : + A file uri. + +Returns :the mime-type for this filename. + + + +<anchor id="gnome-vfs-get-file-mime-type"/>gnome_vfs_get_file_mime_type () +gnome_vfs_get_file_mime_typeconst char* gnome_vfs_get_file_mime_type (const char *path, + const struct stat *optional_stat_info, + gboolean suffix_only); + +Tries to guess the mime type of the file represented by path. +If suffix_only is false, uses the mime-magic based lookup first. +Handles passing path of a non-existent file by falling back +on returning a type based on the extension. + + + +path : + a path of a file. + +optional_stat_info : + optional stat buffer. + +suffix_only : + whether or not to do a magic-based lookup. + +Returns : the mime-type for this path + + + +<anchor id="gnome-vfs-mime-type-is-supertype"/>gnome_vfs_mime_type_is_supertype () +gnome_vfs_mime_type_is_supertypegboolean gnome_vfs_mime_type_is_supertype + (const char *mime_type); + + + +mime_type : + + +Returns : + + + + + +<anchor id="gnome-vfs-get-supertype-from-mime-type"/>gnome_vfs_get_supertype_from_mime_type () +gnome_vfs_get_supertype_from_mime_typechar* gnome_vfs_get_supertype_from_mime_type + (const char *mime_type); + + + +mime_type : + + +Returns : + + + + + + + + + + + diff --git a/doc/xml/gnome-vfs-module-callback-module-api.xml b/doc/xml/gnome-vfs-module-callback-module-api.xml new file mode 100644 index 0000000..beaabbb --- /dev/null +++ b/doc/xml/gnome-vfs-module-callback-module-api.xml @@ -0,0 +1,95 @@ + + +gnome-vfs-module-callback-module-api +3 +GNOME-VFS-2.0 Library + + + +gnome-vfs-module-callback-module-apiinvoking callbacks from a gnome-vfs module to ask the application for necessary information (authentication, ...) + + +Synopsis + + + + + +gboolean gnome_vfs_module_callback_invoke + (const char *callback_name, + gconstpointer in, + gsize in_size, + gpointer out, + gsize out_size); + + + + + + + + + + + + +Description + + + + + + +Details + +<anchor id="gnome-vfs-module-callback-invoke"/>gnome_vfs_module_callback_invoke () +gnome_vfs_module_callback_invokegboolean gnome_vfs_module_callback_invoke + (const char *callback_name, + gconstpointer in, + gsize in_size, + gpointer out, + gsize out_size); + +Invoke a default callback for callback_name, with in arguments +specified by in and in_size, and out arguments specified by out +and out_size. + + +This function should only be called by gnome-vfs modules. + + +If this function is called from an async job thread, it will invoke +the current async handler for callback_name, if any. If no async +handler is set, or the function is not called from an async job +thread, the regular handler, if any, will be invoked instead. If no +handler at all is found for callback_name, the function returns +FALSE. + + + +callback_name : + The name of the module callback to set + +in : + In argument - type dependent on the specific callback + +in_size : + Size of the in argument + +out : + Out argument - type dependent on the specific callback + +out_size : + Size of the out argument + +Returns : TRUE if a callback was invoked, FALSE if none was set. + + + + + + + + + + diff --git a/doc/xml/gnome-vfs-module-callback.xml b/doc/xml/gnome-vfs-module-callback.xml new file mode 100644 index 0000000..8aa6bef --- /dev/null +++ b/doc/xml/gnome-vfs-module-callback.xml @@ -0,0 +1,413 @@ + + +gnome-vfs-module-callback +3 +GNOME-VFS-2.0 Library + + + +gnome-vfs-module-callbackfunctions used by apps if they want to answer to callback invocations by gnome-vfs modules + + +Synopsis + + + + + +void (*GnomeVFSModuleCallback) (gconstpointer in, + gsize in_size, + gpointer out, + gsize out_size, + gpointer callback_data); +void (*GnomeVFSModuleCallbackResponse) + (gpointer response_data); +void (*GnomeVFSAsyncModuleCallback) (gconstpointer in, + gsize in_size, + gpointer out, + gsize out_size, + gpointer callback_data, + GnomeVFSModuleCallbackResponse response, + gpointer response_data); +void gnome_vfs_module_callback_set_default + (const char *callback_name, + GnomeVFSModuleCallback callback, + gpointer callback_data, + GDestroyNotify destroy_notify); +void gnome_vfs_module_callback_push (const char *callback_name, + GnomeVFSModuleCallback callback, + gpointer callback_data, + GDestroyNotify destroy_notify); +void gnome_vfs_module_callback_pop (const char *callback_name); +void gnome_vfs_async_module_callback_set_default + (const char *callback_name, + GnomeVFSAsyncModuleCallback callback, + gpointer callback_data, + GDestroyNotify destroy_notify); +void gnome_vfs_async_module_callback_push + (const char *callback_name, + GnomeVFSAsyncModuleCallback callback, + gpointer callback_data, + GDestroyNotify destroy_notify); +void gnome_vfs_async_module_callback_pop + (const char *callback_name); + + + + + + + + + + + + +Description + + + + + + +Details + +<anchor id="GnomeVFSModuleCallback"/>GnomeVFSModuleCallback () +GnomeVFSModuleCallbackvoid (*GnomeVFSModuleCallback) (gconstpointer in, + gsize in_size, + gpointer out, + gsize out_size, + gpointer callback_data); + +This is the type of a callback function that gets set for a module +callback. + + +When the callback is invoked, the user function is called with an +in argument, the exact type of which depends on the specific +callback. It is generally a pointer to a struct with several fields +that provide information to the callback. + + +The out argument is used to return a values from the +callback. Once again the exact type depends on the specific +callback. It is generally a pointer to a pre-allocated struct with +several fields that the callback function should fill in before +returning. + + + +in : + The in argument for this callback; the exact type depends on the specific callback + +in_size : + Size of the in argument; useful for sanity-checking + +out : + The out argument for this callback; the exact type depends on the specific callback + +out_size : + Size of the out argument; useful for sanity-checking + +callback_data : + The callback_data specified when this callback was set + + + +<anchor id="GnomeVFSModuleCallbackResponse"/>GnomeVFSModuleCallbackResponse () +GnomeVFSModuleCallbackResponsevoid (*GnomeVFSModuleCallbackResponse) + (gpointer response_data); + +This is the type of the response function passed to a +GnomeVFSAsyncModuleCallback(). It should be called when the async +callback has completed. + + + +response_data : + Pass the response_data argument originally passed to the async callback + + + +<anchor id="GnomeVFSAsyncModuleCallback"/>GnomeVFSAsyncModuleCallback () +GnomeVFSAsyncModuleCallbackvoid (*GnomeVFSAsyncModuleCallback) (gconstpointer in, + gsize in_size, + gpointer out, + gsize out_size, + gpointer callback_data, + GnomeVFSModuleCallbackResponse response, + gpointer response_data); + +This is the type of a callback function that gets set for an async +module callback. + + +Such callbacks are useful when you are using the API and want +callbacks to be handled from the main thread, for instance if they +need to put up a dialog. + + +Like a GnomeVFSModuleCallback(), an async callback has in and out +arguments for passing data into and out of the callback. However, +an async callback does not need to fill in the out argument before +returning. Instead, it can arrange to have the work done from a +callback on the main loop, from another thread, etc. The response +function should be called by whatever code finishes the work of the +callback with response_data as an argument once the out argument +is filled in and the callback is done. + + +The in and out arguments are guaranteed to remain valid until the +response function is called. + + + +in : + The in argument for this callback; the exact type depends on the specific callback + +in_size : + Size of the in argument; useful for sanity-checking + +out : + The out argument for this callback; the exact type depends on the specific callback + +out_size : + Size of the out argument; useful for sanity-checking + +callback_data : + The callback_data specified when this callback was set + +response : + Response function to call when the callback is completed + +response_data : + Argument to pass to response + + + +<anchor id="gnome-vfs-module-callback-set-default"/>gnome_vfs_module_callback_set_default () +gnome_vfs_module_callback_set_defaultvoid gnome_vfs_module_callback_set_default + (const char *callback_name, + GnomeVFSModuleCallback callback, + gpointer callback_data, + GDestroyNotify destroy_notify); + +Set the default callback for callback_name to +callback. callback will be called with callback_data on the +same thread as the gnome-vfs operation that invokes it. The default +value is shared for all threads, but setting it is thread-safe. + + +Use this function if you want to set a handler to be used by your +whole application. You can use gnome_vfs_module_callback_push() to +set a callback function that will temporarily override the default +on the current thread instead. Or you can also use +gnome_vfs_async_module_callback_set_default() to set an async +callback function. + + +Note: destroy_notify may be called on any thread - it is not +guaranteed to be called on the main thread. + + + +callback_name : + The name of the module callback to set + +callback : + The function to call when the callback is invoked + +callback_data : + Pointer to pass as the callback_data argument to callback + +destroy_notify : + Function to call when callback_data is to be freed. + + + +<anchor id="gnome-vfs-module-callback-push"/>gnome_vfs_module_callback_push () +gnome_vfs_module_callback_pushvoid gnome_vfs_module_callback_push (const char *callback_name, + GnomeVFSModuleCallback callback, + gpointer callback_data, + GDestroyNotify destroy_notify); + +Set callback as a temprary handler for callback_name. callback +will be called with callback_data on the same thread as the +gnome-vfs operation that invokes it. The temporary handler is set +per-thread. + + +gnome_vfs_module_callback_pop() removes the most recently set +temporary handler. The temporary handlers are treated as a first-in +first-out stack. + + +Use this function to set a temporary callback handler for a single +call or a few calls. You can use +gnome_vfs_module_callback_set_default() to set a callback function +that will establish a permanent global setting for all threads +instead. + + +Note: destroy_notify may be called on any thread - it is not +guaranteed to be called on the main thread. + + + +callback_name : + The name of the module callback to set temporarily + +callback : + The function to call when the callback is invoked + +callback_data : + Pointer to pass as the callback_data argument to callback + +destroy_notify : + Function to call when callback_data is to be freed. + + + +<anchor id="gnome-vfs-module-callback-pop"/>gnome_vfs_module_callback_pop () +gnome_vfs_module_callback_popvoid gnome_vfs_module_callback_pop (const char *callback_name); + +Remove the temporary handler for callback_name most recently set +with gnome_vfs_module_callback_push(). If another temporary +handler was previously set on the same thread, it becomes the +current handler. Otherwise, the default handler, if any, becomes +current. + + +The temporary handlers are treated as a first-in first-out +stack. + + + +callback_name : + The name of the module callback to remove a temporary handler for + + + +<anchor id="gnome-vfs-async-module-callback-set-default"/>gnome_vfs_async_module_callback_set_default () +gnome_vfs_async_module_callback_set_defaultvoid gnome_vfs_async_module_callback_set_default + (const char *callback_name, + GnomeVFSAsyncModuleCallback callback, + gpointer callback_data, + GDestroyNotify destroy_notify); + +Set the default async callback for callback_name to +callback. callback will be called with callback_data +from a callback on the main thread. It will be passed a response +function which should be called to signal completion of the callback. +The callback function itself may return in the meantime. + + +The default value is shared for all threads, but setting it is +thread-safe. + + +Use this function if you want to globally set a callback handler +for use with async operations. + + +You can use gnome_vfs_async_module_callback_push() to set an async +callback function that will temporarily override the default on the +current thread instead. Or you can also use +gnome_vfs_module_callback_set_default() to set a regular callback +function. + + +Note: destroy_notify may be called on any thread - it is not +guaranteed to be called on the main thread. + + + +callback_name : + The name of the async module callback to set + +callback : + The function to call when the callback is invoked + +callback_data : + Pointer to pass as the callback_data argument to callback + +destroy_notify : + Function to call when callback_data is to be freed. + + + +<anchor id="gnome-vfs-async-module-callback-push"/>gnome_vfs_async_module_callback_push () +gnome_vfs_async_module_callback_pushvoid gnome_vfs_async_module_callback_push + (const char *callback_name, + GnomeVFSAsyncModuleCallback callback, + gpointer callback_data, + GDestroyNotify destroy_notify); + +Set callback_func as a temprary async handler for +callback_name. callback will be called with callback_data +from a callback on the main thread. It will be passed a response +function which should be called to signal completion of the +callback. The callback function itself may return in the meantime. + + +The temporary async handler is set per-thread. + + +gnome_vfs_async_module_callback_pop() removes the most recently set +temporary temporary handler. The temporary async handlers are +treated as a first-in first-out stack. + + +Use this function to set a temporary async callback handler for a +single call or a few calls. You can use +gnome_vfs_async_module_callback_set_default() to set an async +callback function that will establish a permanent global setting +for all threads instead. + + +Note: destroy_notify may be called on any thread - it is not +guaranteed to be called on the main thread. + + + +callback_name : + The name of the module callback to set temporarily + +callback : + The function to call when the callback is invoked + +callback_data : + Pointer to pass as the callback_data argument to callback + +destroy_notify : + Function to call when callback_data is to be freed. + + + +<anchor id="gnome-vfs-async-module-callback-pop"/>gnome_vfs_async_module_callback_pop () +gnome_vfs_async_module_callback_popvoid gnome_vfs_async_module_callback_pop + (const char *callback_name); + +Remove the temporary async handler for callback_name most recently +set with gnome_vfs_async_module_callback_push(). If another +temporary async handler was previously set on the same thread, it +becomes the current handler. Otherwise, the default async handler, +if any, becomes current. + + +The temporary async handlers are treated as a first-in first-out +stack. + + + +callback_name : + The name of the module callback to remove a temporary handler for + + + + + + + + + diff --git a/doc/xml/gnome-vfs-module-shared.xml b/doc/xml/gnome-vfs-module-shared.xml new file mode 100644 index 0000000..8c17830 --- /dev/null +++ b/doc/xml/gnome-vfs-module-shared.xml @@ -0,0 +1,149 @@ + + +gnome-vfs-module-shared +3 +GNOME-VFS-2.0 Library + + + +gnome-vfs-module-shared + + +Synopsis + + + + + +const gchar* gnome_vfs_mime_type_from_mode (mode_t mode); +void gnome_vfs_stat_to_file_info (GnomeVFSFileInfo *file_info, + const struct stat *statptr); +GnomeVFSResult gnome_vfs_set_meta (GnomeVFSFileInfo *info, + const char *file_name, + const char *meta_key); +GnomeVFSResult gnome_vfs_set_meta_for_list (GnomeVFSFileInfo *info, + const char *file_name, + const GList *meta_keys); +const char* gnome_vfs_get_special_mime_type (GnomeVFSURI *uri); + + + + + + + + + + + + +Description + + + + + + +Details + +<anchor id="gnome-vfs-mime-type-from-mode"/>gnome_vfs_mime_type_from_mode () +gnome_vfs_mime_type_from_modeconst gchar* gnome_vfs_mime_type_from_mode (mode_t mode); + +Returns a MIME type based on the mode passed. It only works when mode +references a special file (directory, device, fifo, socket or symlink) + + +Returns: a string containing the MIME type, if mode is a normal file + + + +mode : + + +Returns :NULL. + + + +<anchor id="gnome-vfs-stat-to-file-info"/>gnome_vfs_stat_to_file_info () +gnome_vfs_stat_to_file_infovoid gnome_vfs_stat_to_file_info (GnomeVFSFileInfo *file_info, + const struct stat *statptr); + + + +file_info : + + +statptr : + + + + + + +<anchor id="gnome-vfs-set-meta"/>gnome_vfs_set_meta () +gnome_vfs_set_metaGnomeVFSResult gnome_vfs_set_meta (GnomeVFSFileInfo *info, + const char *file_name, + const char *meta_key); + + + +info : + + +file_name : + + +meta_key : + + +Returns : + + + + + +<anchor id="gnome-vfs-set-meta-for-list"/>gnome_vfs_set_meta_for_list () +gnome_vfs_set_meta_for_listGnomeVFSResult gnome_vfs_set_meta_for_list (GnomeVFSFileInfo *info, + const char *file_name, + const GList *meta_keys); + + + +info : + + +file_name : + + +meta_keys : + + +Returns : + + + + + +<anchor id="gnome-vfs-get-special-mime-type"/>gnome_vfs_get_special_mime_type () +gnome_vfs_get_special_mime_typeconst char* gnome_vfs_get_special_mime_type (GnomeVFSURI *uri); + +Gets the MIME type for uri, this function only returns the type +when the URI points to a file that can't be sniffed (sockets, +directories, devices, and fifos). + + + +uri : + + +Returns : a string containing the mime type, NULL if the uri doesn't +present an special file. + + + + + + + + + diff --git a/doc/xml/gnome-vfs-module.xml b/doc/xml/gnome-vfs-module.xml new file mode 100644 index 0000000..519bb84 --- /dev/null +++ b/doc/xml/gnome-vfs-module.xml @@ -0,0 +1,106 @@ + + +gnome-vfs-module +3 +GNOME-VFS-2.0 Library + + + +gnome-vfs-module + + +Synopsis + + + + + +GnomeVFSMethod* vfs_module_init (const char *method_name, + const char *args); +GnomeVFSTransform* vfs_module_transform (const char *method_name, + const char *args); +void vfs_module_shutdown (GnomeVFSMethod *method); + + + + + + + + + + + + +Description + + + + + + +Details + +<anchor id="vfs-module-init"/>vfs_module_init () +vfs_module_initGnomeVFSMethod* vfs_module_init (const char *method_name, + const char *args); + +Standard extern call implemented by each filesystem module. This is called +to initialize the module and setup any basic structures / connections the +method requires. It also allows the module to identify the URI method it is +associated with in this instance. + + + +method_name : + name of the method that invoked this module (e.g. "http", "ftp", "file"). + +args : + not used by most modules, but potential arguments for creating the module (could +be a file to point at, for example) + +Returns : the module symbol table, pointing to the appropriate calls for +this module. + + + +<anchor id="vfs-module-transform"/>vfs_module_transform () +vfs_module_transformGnomeVFSTransform* vfs_module_transform (const char *method_name, + const char *args); + +Shift an already instanced module to a new method name. This call is not implemented +by most modules and is optional. + + + +method_name : + name of the method that invoked this module (e.g. "http", "ftp", "file"). + +args : + not used by most modules, but potential arguments for creating the module (could +be a file to point at, for example) + +Returns : the module symbol table, pointing to the appropriate calls for +this module. + + + +<anchor id="vfs-module-shutdown"/>vfs_module_shutdown () +vfs_module_shutdownvoid vfs_module_shutdown (GnomeVFSMethod *method); + +Called to tell a module to end any active operations, free all used memory, +and close any connections (as appropriate) or resources. + + + +method : + the symbol table of the module being shut down + + + + + + + + + diff --git a/doc/xml/gnome-vfs-monitor.xml b/doc/xml/gnome-vfs-monitor.xml new file mode 100644 index 0000000..5d9c6c1 --- /dev/null +++ b/doc/xml/gnome-vfs-monitor.xml @@ -0,0 +1,192 @@ + + +Monitoring +3 +GNOME-VFS-2.0 Library + + + +Monitoring +watch files for changes, and get called back if they do + + +Synopsis + + + + + +GnomeVFSResult gnome_vfs_monitor_add (GnomeVFSMonitorHandle **handle, + const gchar *text_uri, + GnomeVFSMonitorType monitor_type, + GnomeVFSMonitorCallback callback, + gpointer user_data); +GnomeVFSResult gnome_vfs_monitor_cancel (GnomeVFSMonitorHandle *handle); +enum GnomeVFSMonitorType; +enum GnomeVFSMonitorEventType; +void (*GnomeVFSMonitorCallback) (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data); + + + + + + + + + + + + +Description + + + + + + +Details + +<anchor id="gnome-vfs-monitor-add"/>gnome_vfs_monitor_add () +gnome_vfs_monitor_addGnomeVFSResult gnome_vfs_monitor_add (GnomeVFSMonitorHandle **handle, + const gchar *text_uri, + GnomeVFSMonitorType monitor_type, + GnomeVFSMonitorCallback callback, + gpointer user_data); + +Watch the file or directory at text_uri for changes (or the creation/deletion of the file) +and call callback when there is a change. If a directory monitor is added, callback is +notified when any file in the directory changes. + + + +handle : + after the call, handle will be a pointer to an operation handle + +text_uri : + URI to monitor + +monitor_type : + add a directory or file monitor + +callback : + function to call when the monitor is tripped + +user_data : + data to pass to callback + +Returns : an integer representing the success of the operation + + + +<anchor id="gnome-vfs-monitor-cancel"/>gnome_vfs_monitor_cancel () +gnome_vfs_monitor_cancelGnomeVFSResult gnome_vfs_monitor_cancel (GnomeVFSMonitorHandle *handle); + +Cancel the monitor pointed to be handle. + + + +handle : + handle of the monitor to cancel + +Returns : an integer representing the success of the operation + + + +<anchor id="GnomeVFSMonitorType"/>enum GnomeVFSMonitorType +GnomeVFSMonitorTypetypedef enum { + GNOME_VFS_MONITOR_FILE, + GNOME_VFS_MONITOR_DIRECTORY +} GnomeVFSMonitorType; + + +Type of resources that can be monitored. + + + + +<anchor id="GnomeVFSMonitorEventType"/>enum GnomeVFSMonitorEventType +GnomeVFSMonitorEventTypetypedef enum { + GNOME_VFS_MONITOR_EVENT_CHANGED, + GNOME_VFS_MONITOR_EVENT_DELETED, + GNOME_VFS_MONITOR_EVENT_STARTEXECUTING, + GNOME_VFS_MONITOR_EVENT_STOPEXECUTING, + GNOME_VFS_MONITOR_EVENT_CREATED, + GNOME_VFS_MONITOR_EVENT_METADATA_CHANGED +} GnomeVFSMonitorEventType; + + +Types of events that can be monitored. + + + + +GNOME_VFS_MONITOR_EVENT_CHANGED + file data changed + + + +GNOME_VFS_MONITOR_EVENT_DELETED + file deleted event + + + +GNOME_VFS_MONITOR_EVENT_STARTEXECUTING + + + + +GNOME_VFS_MONITOR_EVENT_STOPEXECUTING + + + + +GNOME_VFS_MONITOR_EVENT_CREATED + file created event + + + +GNOME_VFS_MONITOR_EVENT_METADATA_CHANGED + file metadata changed + + + + +<anchor id="GnomeVFSMonitorCallback"/>GnomeVFSMonitorCallback () +GnomeVFSMonitorCallbackvoid (*GnomeVFSMonitorCallback) (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data); + +Function called when a monitor detects a change. + + + +handle : + the handle of the monitor that created the event + +monitor_uri : + the URI of the monitor that was triggered + +info_uri : + the URI of the actual file this event is concerned with (this can be different +from monitor_uri if it was a directory monitor) + +event_type : + what happened to info_uri + +user_data : + user data passed to gnome_vfs_monitor_add() when the monitor was created + + + + + + + + + diff --git a/doc/xml/gnome-vfs-ops.xml b/doc/xml/gnome-vfs-ops.xml new file mode 100644 index 0000000..69afa38 --- /dev/null +++ b/doc/xml/gnome-vfs-ops.xml @@ -0,0 +1,53 @@ + + +File Operations +3 +GNOME-VFS-2.0 Library + + + +File Operations +basic POSIX-style file operations + + +Synopsis + + + + + +typedef GnomeVFSMethodHandle; + + + + + + + + + + + + +Description + + + + + + +Details + +<anchor id="GnomeVFSMethodHandle"/>GnomeVFSMethodHandle +GnomeVFSMethodHandletypedef gpointer GnomeVFSMethodHandle; + + + + + + + + + + + diff --git a/doc/xml/gnome-vfs-parse-ls.xml b/doc/xml/gnome-vfs-parse-ls.xml new file mode 100644 index 0000000..5ab8569 --- /dev/null +++ b/doc/xml/gnome-vfs-parse-ls.xml @@ -0,0 +1,74 @@ + + +gnome-vfs-parse-ls +3 +GNOME-VFS-2.0 Library + + + +gnome-vfs-parse-lsconvenience functions for modules which want to parse a ls-like directory listing + + +Synopsis + + + + + +int gnome_vfs_parse_ls_lga (const char *p, + struct stat *s, + char **filename, + char **linkname); + + + + + + + + + + + + +Description + + + + + + +Details + +<anchor id="gnome-vfs-parse-ls-lga"/>gnome_vfs_parse_ls_lga () +gnome_vfs_parse_ls_lgaint gnome_vfs_parse_ls_lga (const char *p, + struct stat *s, + char **filename, + char **linkname); + + + +p : + + +s : + + +filename : + + +linkname : + + +Returns : + + + + + + + + + + + diff --git a/doc/xml/gnome-vfs-result.xml b/doc/xml/gnome-vfs-result.xml new file mode 100644 index 0000000..2bd2607 --- /dev/null +++ b/doc/xml/gnome-vfs-result.xml @@ -0,0 +1,161 @@ + + +GnomeVFSResult +3 +GNOME-VFS-2.0 Library + + + +GnomeVFSResult +Result of I/O operations, the equivalent of errno + + +Synopsis + + + + + +enum GnomeVFSResult; +const char* gnome_vfs_result_to_string (GnomeVFSResult result); +GnomeVFSResult gnome_vfs_result_from_errno_code + (int errno_code); +GnomeVFSResult gnome_vfs_result_from_errno (void); +GnomeVFSResult gnome_vfs_result_from_h_errno + (void); + + + + + + + + + + + + +Description + + + + + + +Details + +<anchor id="GnomeVFSResult"/>enum GnomeVFSResult +GnomeVFSResulttypedef enum { + GNOME_VFS_OK, + GNOME_VFS_ERROR_NOT_FOUND, + GNOME_VFS_ERROR_GENERIC, + GNOME_VFS_ERROR_INTERNAL, + GNOME_VFS_ERROR_BAD_PARAMETERS, + GNOME_VFS_ERROR_NOT_SUPPORTED, + GNOME_VFS_ERROR_IO, + GNOME_VFS_ERROR_CORRUPTED_DATA, + GNOME_VFS_ERROR_WRONG_FORMAT, + GNOME_VFS_ERROR_BAD_FILE, + GNOME_VFS_ERROR_TOO_BIG, + GNOME_VFS_ERROR_NO_SPACE, + GNOME_VFS_ERROR_READ_ONLY, + GNOME_VFS_ERROR_INVALID_URI, + GNOME_VFS_ERROR_NOT_OPEN, + GNOME_VFS_ERROR_INVALID_OPEN_MODE, + GNOME_VFS_ERROR_ACCESS_DENIED, + GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES, + GNOME_VFS_ERROR_EOF, + GNOME_VFS_ERROR_NOT_A_DIRECTORY, + GNOME_VFS_ERROR_IN_PROGRESS, + GNOME_VFS_ERROR_INTERRUPTED, + GNOME_VFS_ERROR_FILE_EXISTS, + GNOME_VFS_ERROR_LOOP, + GNOME_VFS_ERROR_NOT_PERMITTED, + GNOME_VFS_ERROR_IS_DIRECTORY, + GNOME_VFS_ERROR_NO_MEMORY, + GNOME_VFS_ERROR_HOST_NOT_FOUND, + GNOME_VFS_ERROR_INVALID_HOST_NAME, + GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS, + GNOME_VFS_ERROR_LOGIN_FAILED, + GNOME_VFS_ERROR_CANCELLED, + GNOME_VFS_ERROR_DIRECTORY_BUSY, + GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY, + GNOME_VFS_ERROR_TOO_MANY_LINKS, + GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM, + GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM, + GNOME_VFS_ERROR_NAME_TOO_LONG, + GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE, + GNOME_VFS_ERROR_SERVICE_OBSOLETE, + GNOME_VFS_ERROR_PROTOCOL_ERROR, + GNOME_VFS_ERROR_NO_MASTER_BROWSER, + GNOME_VFS_ERROR_NO_DEFAULT, + GNOME_VFS_ERROR_NO_HANDLER, + GNOME_VFS_ERROR_PARSE, + GNOME_VFS_ERROR_LAUNCH, + GNOME_VFS_NUM_ERRORS +} GnomeVFSResult; + + + + + +<anchor id="gnome-vfs-result-to-string"/>gnome_vfs_result_to_string () +gnome_vfs_result_to_stringconst char* gnome_vfs_result_to_string (GnomeVFSResult result); + +Returns a string representation of result, useful for debugging +purposes, but probably not appropriate for passing to the user. + + + +result : + the result to convert to a string + +Returns : a string representing result + + + +<anchor id="gnome-vfs-result-from-errno-code"/>gnome_vfs_result_from_errno_code () +gnome_vfs_result_from_errno_codeGnomeVFSResult gnome_vfs_result_from_errno_code + (int errno_code); + +Converts a system errno value to a GnomeVFSResult. + + + +errno_code : + integer of the same type as the system "errno" + +Returns : a GnomeVFSResult equivalent to errno_code + + + +<anchor id="gnome-vfs-result-from-errno"/>gnome_vfs_result_from_errno () +gnome_vfs_result_from_errnoGnomeVFSResult gnome_vfs_result_from_errno (void); + +Converts the system errno to a GnomeVFSResult. + + + +Returns : a GnomeVFSResult equivalent to the current system errno + + + +<anchor id="gnome-vfs-result-from-h-errno"/>gnome_vfs_result_from_h_errno () +gnome_vfs_result_from_h_errnoGnomeVFSResult gnome_vfs_result_from_h_errno + (void); + +Converts the system "h_errno" to a GnomeVFSResult (h_errno represents errors +accessing and finding internet hosts) + + + +Returns : a GnomeVFSResult equivalent to the current system "h_errno" + + + + + + + + + diff --git a/doc/xml/gnome-vfs-socket-buffer.xml b/doc/xml/gnome-vfs-socket-buffer.xml new file mode 100644 index 0000000..ccdbe55 --- /dev/null +++ b/doc/xml/gnome-vfs-socket-buffer.xml @@ -0,0 +1,192 @@ + + +gnome-vfs-socket-buffer +3 +GNOME-VFS-2.0 Library + + + +gnome-vfs-socket-buffer + + +Synopsis + + + + + +GnomeVFSSocketBuffer* gnome_vfs_socket_buffer_new + (GnomeVFSSocket *socket); +GnomeVFSResult gnome_vfs_socket_buffer_destroy + (GnomeVFSSocketBuffer *socket_buffer, + gboolean close_socket); +GnomeVFSResult gnome_vfs_socket_buffer_read (GnomeVFSSocketBuffer *socket_buffer, + gpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_read); +GnomeVFSResult gnome_vfs_socket_buffer_peekc + (GnomeVFSSocketBuffer *socket_buffer, + char *character); +GnomeVFSResult gnome_vfs_socket_buffer_write + (GnomeVFSSocketBuffer *socket_buffer, + gconstpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_written); +GnomeVFSResult gnome_vfs_socket_buffer_flush + (GnomeVFSSocketBuffer *socket_buffer); + + + + + + + + + + + + +Description + + + + + + +Details + +<anchor id="gnome-vfs-socket-buffer-new"/>gnome_vfs_socket_buffer_new () +gnome_vfs_socket_buffer_newGnomeVFSSocketBuffer* gnome_vfs_socket_buffer_new + (GnomeVFSSocket *socket); + +Create a socket buffer around socket. A buffered +socket allows data to be poked at without reading it +as it will be buffered. A future read will retrieve +the data again. + + + +socket : + socket to be buffered + +Returns : a newly allocated GnomeVFSSocketBuffer + + + +<anchor id="gnome-vfs-socket-buffer-destroy"/>gnome_vfs_socket_buffer_destroy () +gnome_vfs_socket_buffer_destroyGnomeVFSResult gnome_vfs_socket_buffer_destroy + (GnomeVFSSocketBuffer *socket_buffer, + gboolean close_socket); + +Free the socket buffer. + + + +socket_buffer : + buffered socket to destray + +close_socket : + if TRUE the socket being buffered will be closed too + +Returns : GnomeVFSResult indicating the success of the operation + + + +<anchor id="gnome-vfs-socket-buffer-read"/>gnome_vfs_socket_buffer_read () +gnome_vfs_socket_buffer_readGnomeVFSResult gnome_vfs_socket_buffer_read (GnomeVFSSocketBuffer *socket_buffer, + gpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_read); + +Read bytes bytes of data from the socket into socket_buffer. + + + +socket_buffer : + buffered socket to read data from + +buffer : + allocated buffer of at least bytes bytes to be read into + +bytes : + number of bytes to read from socket into socket_buffer + +bytes_read : + pointer to a GnomeVFSFileSize, will contain +the number of bytes actually read from the socket on return. + +Returns : GnomeVFSResult indicating the success of the operation + + + +<anchor id="gnome-vfs-socket-buffer-peekc"/>gnome_vfs_socket_buffer_peekc () +gnome_vfs_socket_buffer_peekcGnomeVFSResult gnome_vfs_socket_buffer_peekc + (GnomeVFSSocketBuffer *socket_buffer, + char *character); + +Peek at the next character in socket_buffer without actually reading +the character in. The next read will retrieve c (as well as any following +data if requested). + + + +socket_buffer : + the socket buffer to read from + +character : + pointer to a char, will contain a character on return from +a successful "peek" + +Returns : GnomeVFSResult indicating the success of the operation + + + +<anchor id="gnome-vfs-socket-buffer-write"/>gnome_vfs_socket_buffer_write () +gnome_vfs_socket_buffer_writeGnomeVFSResult gnome_vfs_socket_buffer_write + (GnomeVFSSocketBuffer *socket_buffer, + gconstpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_written); + +Write bytes bytes of data from buffer to socket_buffer. + + + +socket_buffer : + buffered socket to write data to + +buffer : + data to write to the socket + +bytes : + number of bytes from buffer to write to socket_buffer + +bytes_written : + pointer to a GnomeVFSFileSize, will contain +the number of bytes actually written to the socket on return. + +Returns : GnomeVFSResult indicating the success of the operation + + + +<anchor id="gnome-vfs-socket-buffer-flush"/>gnome_vfs_socket_buffer_flush () +gnome_vfs_socket_buffer_flushGnomeVFSResult gnome_vfs_socket_buffer_flush + (GnomeVFSSocketBuffer *socket_buffer); + +Write all outstanding data to socket_buffer. + + + +socket_buffer : + buffer to flush + +Returns : GnomeVFSResult indicating the success of the operation + + + + + + + + + diff --git a/doc/xml/gnome-vfs-socket.xml b/doc/xml/gnome-vfs-socket.xml new file mode 100644 index 0000000..6af9f23 --- /dev/null +++ b/doc/xml/gnome-vfs-socket.xml @@ -0,0 +1,229 @@ + + +gnome-vfs-socket +3 +GNOME-VFS-2.0 Library + + + +gnome-vfs-socket + + +Synopsis + + + + + +GnomeVFSResult (*GnomeVFSSocketReadFunc) (gpointer connection, + gpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_read); +GnomeVFSResult (*GnomeVFSSocketWriteFunc) (gpointer connection, + gconstpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_written); +void (*GnomeVFSSocketCloseFunc) (gpointer connection); +typedef GnomeVFSSocketImpl; +GnomeVFSSocket* gnome_vfs_socket_new (GnomeVFSSocketImpl *impl, + void *connection); +GnomeVFSResult gnome_vfs_socket_write (GnomeVFSSocket *socket, + gconstpointer buffer, + int bytes, + GnomeVFSFileSize *bytes_written); +GnomeVFSResult gnome_vfs_socket_close (GnomeVFSSocket *socket); +GnomeVFSResult gnome_vfs_socket_read (GnomeVFSSocket *socket, + gpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_read); + + + + + + + + + + + + +Description + + + + + + +Details + +<anchor id="GnomeVFSSocketReadFunc"/>GnomeVFSSocketReadFunc () +GnomeVFSSocketReadFuncGnomeVFSResult (*GnomeVFSSocketReadFunc) (gpointer connection, + gpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_read); + + + +connection : + + +buffer : + + +bytes : + + +bytes_read : + + +Returns : + + + + + +<anchor id="GnomeVFSSocketWriteFunc"/>GnomeVFSSocketWriteFunc () +GnomeVFSSocketWriteFuncGnomeVFSResult (*GnomeVFSSocketWriteFunc) (gpointer connection, + gconstpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_written); + + + +connection : + + +buffer : + + +bytes : + + +bytes_written : + + +Returns : + + + + + +<anchor id="GnomeVFSSocketCloseFunc"/>GnomeVFSSocketCloseFunc () +GnomeVFSSocketCloseFuncvoid (*GnomeVFSSocketCloseFunc) (gpointer connection); + + + +connection : + + + + + + +<anchor id="GnomeVFSSocketImpl"/>GnomeVFSSocketImpl +GnomeVFSSocketImpltypedef struct { + GnomeVFSSocketReadFunc read; + GnomeVFSSocketWriteFunc write; + GnomeVFSSocketCloseFunc close; +} GnomeVFSSocketImpl; + + + + + +<anchor id="gnome-vfs-socket-new"/>gnome_vfs_socket_new () +gnome_vfs_socket_newGnomeVFSSocket* gnome_vfs_socket_new (GnomeVFSSocketImpl *impl, + void *connection); + +Creates a new GnomeVFS Socket using the specific implementation +impl. + + + +impl : + an implementation of a socket, e.g. GnomeVFSSSL + +connection : + pointer to a connection object used by impl to track +state (the exact nature of connection varies from implementation to +implementation) + +Returns : a newly created socket + + + +<anchor id="gnome-vfs-socket-write"/>gnome_vfs_socket_write () +gnome_vfs_socket_writeGnomeVFSResult gnome_vfs_socket_write (GnomeVFSSocket *socket, + gconstpointer buffer, + int bytes, + GnomeVFSFileSize *bytes_written); + +Write bytes bytes of data from buffer to socket. + + + +socket : + socket to write data to + +buffer : + data to write to the socket + +bytes : + number of bytes from buffer to write to socket + +bytes_written : + pointer to a GnomeVFSFileSize, will contain +the number of bytes actually written to the socket on return. + +Returns : GnomeVFSResult indicating the success of the operation + + + +<anchor id="gnome-vfs-socket-close"/>gnome_vfs_socket_close () +gnome_vfs_socket_closeGnomeVFSResult gnome_vfs_socket_close (GnomeVFSSocket *socket); + +Close socket, freeing any resources it may be using. + + + +socket : + the socket to be closed + +Returns : GnomeVFSResult indicating the success of the operation + + + +<anchor id="gnome-vfs-socket-read"/>gnome_vfs_socket_read () +gnome_vfs_socket_readGnomeVFSResult gnome_vfs_socket_read (GnomeVFSSocket *socket, + gpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_read); + +Read bytes bytes of data from the socket into buffer. + + + +socket : + socket to read data from + +buffer : + allocated buffer of at least bytes bytes to be read into + +bytes : + number of bytes to read from socket into buffer + +bytes_read : + pointer to a GnomeVFSFileSize, will contain +the number of bytes actually read from the socket on return. + +Returns : GnomeVFSResult indicating the success of the operation + + + + + + + + + diff --git a/doc/xml/gnome-vfs-ssl.xml b/doc/xml/gnome-vfs-ssl.xml new file mode 100644 index 0000000..602f82a --- /dev/null +++ b/doc/xml/gnome-vfs-ssl.xml @@ -0,0 +1,195 @@ + + +gnome-vfs-ssl +3 +GNOME-VFS-2.0 Library + + + +gnome-vfs-ssl + + +Synopsis + + + + + +gboolean gnome_vfs_ssl_enabled (void); +GnomeVFSResult gnome_vfs_ssl_create (GnomeVFSSSL **handle_return, + const char *host, + unsigned int port); +GnomeVFSResult gnome_vfs_ssl_create_from_fd (GnomeVFSSSL **handle_return, + gint fd); +GnomeVFSResult gnome_vfs_ssl_read (GnomeVFSSSL *ssl, + gpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_read); +GnomeVFSResult gnome_vfs_ssl_write (GnomeVFSSSL *ssl, + gconstpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_written); +void gnome_vfs_ssl_destroy (GnomeVFSSSL *ssl); +GnomeVFSSocket* gnome_vfs_ssl_to_socket (GnomeVFSSSL *ssl); + + + + + + + + + + + + +Description + + + + + + +Details + +<anchor id="gnome-vfs-ssl-enabled"/>gnome_vfs_ssl_enabled () +gnome_vfs_ssl_enabledgboolean gnome_vfs_ssl_enabled (void); + +Checks whether GnomeVFS was compiled with SSL support. + + + +Returns : TRUE if GnomeVFS was compiled with SSL support, +otherwise FALSE. + + + +<anchor id="gnome-vfs-ssl-create"/>gnome_vfs_ssl_create () +gnome_vfs_ssl_createGnomeVFSResult gnome_vfs_ssl_create (GnomeVFSSSL **handle_return, + const char *host, + unsigned int port); + +Creates an SSL socket connection at handle_return to host using +port port. + + + +handle_return : + pointer to a GnmoeVFSSSL struct, which will +contain an allocated GnomeVFSSSL object on return. + +host : + string indicating the host to establish an SSL connection with + +port : + the port number to connect to + +Returns : GnomeVFSResult indicating the success of the operation + + + +<anchor id="gnome-vfs-ssl-create-from-fd"/>gnome_vfs_ssl_create_from_fd () +gnome_vfs_ssl_create_from_fdGnomeVFSResult gnome_vfs_ssl_create_from_fd (GnomeVFSSSL **handle_return, + gint fd); + +Try to establish an SSL connection over the file descriptor fd. + + + +handle_return : + pointer to a GnmoeVFSSSL struct, which will +contain an allocated GnomeVFSSSL object on return. + +fd : + file descriptior to try and establish an SSL connection over + +Returns : a GnomeVFSResult indicating the success of the operation + + + +<anchor id="gnome-vfs-ssl-read"/>gnome_vfs_ssl_read () +gnome_vfs_ssl_readGnomeVFSResult gnome_vfs_ssl_read (GnomeVFSSSL *ssl, + gpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_read); + +Read bytes bytes of data from the SSL socket ssl into buffer. + + + +ssl : + SSL socket to read data from + +buffer : + allocated buffer of at least bytes bytes to be read into + +bytes : + number of bytes to read from ssl into buffer + +bytes_read : + pointer to a GnomeVFSFileSize, will contain +the number of bytes actually read from the socket on return. + +Returns : GnomeVFSResult indicating the success of the operation + + + +<anchor id="gnome-vfs-ssl-write"/>gnome_vfs_ssl_write () +gnome_vfs_ssl_writeGnomeVFSResult gnome_vfs_ssl_write (GnomeVFSSSL *ssl, + gconstpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_written); + +Write bytes bytes of data from buffer to ssl. + + + +ssl : + SSL socket to write data to + +buffer : + data to write to the socket + +bytes : + number of bytes from buffer to write to ssl + +bytes_written : + pointer to a GnomeVFSFileSize, will contain +the number of bytes actually written to the socket on return. + +Returns : GnomeVFSResult indicating the success of the operation + + + +<anchor id="gnome-vfs-ssl-destroy"/>gnome_vfs_ssl_destroy () +gnome_vfs_ssl_destroyvoid gnome_vfs_ssl_destroy (GnomeVFSSSL *ssl); + +Free resources used by ssl and close the connection. + + + +ssl : + SSL socket to be closed and destroyed + + + +<anchor id="gnome-vfs-ssl-to-socket"/>gnome_vfs_ssl_to_socket () +gnome_vfs_ssl_to_socketGnomeVFSSocket* gnome_vfs_ssl_to_socket (GnomeVFSSSL *ssl); + +Wrapper an SSL socket inside a standard GnomeVFSSocket. + + + +ssl : + SSL socket to convert into a standard socket + +Returns : a newly allocated GnomeVFSSocket corresponding to ssl. + + + + + + + + + diff --git a/doc/xml/gnome-vfs-standard-callbacks.xml b/doc/xml/gnome-vfs-standard-callbacks.xml new file mode 100644 index 0000000..baec70a --- /dev/null +++ b/doc/xml/gnome-vfs-standard-callbacks.xml @@ -0,0 +1,195 @@ + + +gnome-vfs-standard-callbacks +3 +GNOME-VFS-2.0 Library + + + +gnome-vfs-standard-callbacksstandard callbacks for use by gnome-vfs module writers + + +Synopsis + + + + + +#define GNOME_VFS_MODULE_CALLBACK_AUTHENTICATION +#define GNOME_VFS_MODULE_CALLBACK_HTTP_PROXY_AUTHENTICATION +typedef GnomeVFSModuleCallbackAuthenticationOut; +#define GNOME_VFS_MODULE_CALLBACK_HTTP_SEND_ADDITIONAL_HEADERS +typedef GnomeVFSModuleCallbackAdditionalHeadersIn; +typedef GnomeVFSModuleCallbackAdditionalHeadersOut; +#define GNOME_VFS_MODULE_CALLBACK_HTTP_RECEIVED_HEADERS +typedef GnomeVFSModuleCallbackReceivedHeadersIn; +typedef GnomeVFSModuleCallbackReceivedHeadersOut; +#define GNOME_VFS_MODULE_CALLBACK_STATUS_MESSAGE +typedef GnomeVFSModuleCallbackStatusMessageIn; +typedef GnomeVFSModuleCallbackStatusMessageOut; + + + + + + + + + + + + +Description + + + + + + +Details + +<anchor id="GNOME-VFS-MODULE-CALLBACK-AUTHENTICATION-CAPS"/>GNOME_VFS_MODULE_CALLBACK_AUTHENTICATION +GNOME_VFS_MODULE_CALLBACK_AUTHENTICATION#define GNOME_VFS_MODULE_CALLBACK_AUTHENTICATION "simple-authentication" + + + + + +<anchor id="GNOME-VFS-MODULE-CALLBACK-HTTP-PROXY-AUTHENTICATION-CAPS"/>GNOME_VFS_MODULE_CALLBACK_HTTP_PROXY_AUTHENTICATION +GNOME_VFS_MODULE_CALLBACK_HTTP_PROXY_AUTHENTICATION#define GNOME_VFS_MODULE_CALLBACK_HTTP_PROXY_AUTHENTICATION "http:proxy-authentication" + + + + + +<anchor id="GnomeVFSModuleCallbackAuthenticationOut"/>GnomeVFSModuleCallbackAuthenticationOut +GnomeVFSModuleCallbackAuthenticationOuttypedef struct { + char *username; /* will be freed by g_free, + * NULL indicates no auth should be provided; + * if the request requires authn, the operation + * will fail with a GNOME_VFS_ERROR_ACCESS_DENIED + * code + */ + char *password; /* will be freed by g_free */ + + /* Reserved "padding" to avoid future breaks in ABI compatibility */ + void *reserved1; + void *reserved2; + +} GnomeVFSModuleCallbackAuthenticationOut; + + + + + +<anchor id="GNOME-VFS-MODULE-CALLBACK-HTTP-SEND-ADDITIONAL-HEADERS-CAPS"/>GNOME_VFS_MODULE_CALLBACK_HTTP_SEND_ADDITIONAL_HEADERS +GNOME_VFS_MODULE_CALLBACK_HTTP_SEND_ADDITIONAL_HEADERS#define GNOME_VFS_MODULE_CALLBACK_HTTP_SEND_ADDITIONAL_HEADERS "http:send-additional-headers" + + + + + +<anchor id="GnomeVFSModuleCallbackAdditionalHeadersIn"/>GnomeVFSModuleCallbackAdditionalHeadersIn +GnomeVFSModuleCallbackAdditionalHeadersIntypedef struct { + GnomeVFSURI *uri; /* URI of operation */ + + /* Reserved "padding" to avoid future breaks in ABI compatibility */ + void *reserved1; + void *reserved2; +} GnomeVFSModuleCallbackAdditionalHeadersIn; + + + + + +<anchor id="GnomeVFSModuleCallbackAdditionalHeadersOut"/>GnomeVFSModuleCallbackAdditionalHeadersOut +GnomeVFSModuleCallbackAdditionalHeadersOuttypedef struct { + GList *headers; /* list of headers, will be freeed */ + + /* Reserved "padding" to avoid future breaks in ABI compatibility */ + void *reserved1; + void *reserved2; +} GnomeVFSModuleCallbackAdditionalHeadersOut; + + + + + +<anchor id="GNOME-VFS-MODULE-CALLBACK-HTTP-RECEIVED-HEADERS-CAPS"/>GNOME_VFS_MODULE_CALLBACK_HTTP_RECEIVED_HEADERS +GNOME_VFS_MODULE_CALLBACK_HTTP_RECEIVED_HEADERS#define GNOME_VFS_MODULE_CALLBACK_HTTP_RECEIVED_HEADERS "http:received-headers" + + + + + +<anchor id="GnomeVFSModuleCallbackReceivedHeadersIn"/>GnomeVFSModuleCallbackReceivedHeadersIn +GnomeVFSModuleCallbackReceivedHeadersIntypedef struct { + GnomeVFSURI *uri; /* URI of operation */ + GList *headers; /* list of headers */ + + /* Reserved "padding" to avoid future breaks in ABI compatibility */ + void *reserved1; + void *reserved2; +} GnomeVFSModuleCallbackReceivedHeadersIn; + + + + + +<anchor id="GnomeVFSModuleCallbackReceivedHeadersOut"/>GnomeVFSModuleCallbackReceivedHeadersOut +GnomeVFSModuleCallbackReceivedHeadersOuttypedef struct { + int dummy; + + /* Reserved "padding" to avoid future breaks in ABI compatibility */ + void *reserved1; + void *reserved2; +} GnomeVFSModuleCallbackReceivedHeadersOut; + + + + + +<anchor id="GNOME-VFS-MODULE-CALLBACK-STATUS-MESSAGE-CAPS"/>GNOME_VFS_MODULE_CALLBACK_STATUS_MESSAGE +GNOME_VFS_MODULE_CALLBACK_STATUS_MESSAGE#define GNOME_VFS_MODULE_CALLBACK_STATUS_MESSAGE "status-message" + + + + + +<anchor id="GnomeVFSModuleCallbackStatusMessageIn"/>GnomeVFSModuleCallbackStatusMessageIn +GnomeVFSModuleCallbackStatusMessageIntypedef struct { + char *uri; /* Full URI of operation */ + char *message; /* A message indicating the current state or + * NULL if there is no message */ + int percentage; /* Percentage indicating completeness 0-100 or + * -1 if there is no progress percentage to + * report */ + + /* Reserved "padding" to avoid future breaks in ABI compatibility */ + void *reserved1; + void *reserved2; +} GnomeVFSModuleCallbackStatusMessageIn; + + + + + +<anchor id="GnomeVFSModuleCallbackStatusMessageOut"/>GnomeVFSModuleCallbackStatusMessageOut +GnomeVFSModuleCallbackStatusMessageOuttypedef struct { + int dummy; /* empty structs not allowed */ + + /* Reserved "padding" to avoid future breaks in ABI compatibility */ + void *reserved1; + void *reserved2; +} GnomeVFSModuleCallbackStatusMessageOut; + + + + + + + + + + + diff --git a/doc/xml/gnome-vfs-transform.xml b/doc/xml/gnome-vfs-transform.xml new file mode 100644 index 0000000..824c92b --- /dev/null +++ b/doc/xml/gnome-vfs-transform.xml @@ -0,0 +1,96 @@ + + +gnome-vfs-transform +3 +GNOME-VFS-2.0 Library + + + +gnome-vfs-transform + + +Synopsis + + + + + +GnomeVFSTransform* (*GnomeVFSTransformInitFunc) + (const char *method_name, + const char *config_args); +GnomeVFSResult (*GnomeVFSTransformFunc) (GnomeVFSTransform *transform, + const char *old_uri, + char **new_uri, + GnomeVFSContext *context); + + + + + + + + + + + + +Description + + + + + + +Details + +<anchor id="GnomeVFSTransformInitFunc"/>GnomeVFSTransformInitFunc () +GnomeVFSTransformInitFuncGnomeVFSTransform* (*GnomeVFSTransformInitFunc) + (const char *method_name, + const char *config_args); + + + +method_name : + + +config_args : + + +Returns : + + + + + +<anchor id="GnomeVFSTransformFunc"/>GnomeVFSTransformFunc () +GnomeVFSTransformFuncGnomeVFSResult (*GnomeVFSTransformFunc) (GnomeVFSTransform *transform, + const char *old_uri, + char **new_uri, + GnomeVFSContext *context); + + + +transform : + + +old_uri : + + +new_uri : + + +context : + + +Returns : + + + + + + + + + + + diff --git a/doc/xml/gnome-vfs-uri.xml b/doc/xml/gnome-vfs-uri.xml new file mode 100644 index 0000000..659e498 --- /dev/null +++ b/doc/xml/gnome-vfs-uri.xml @@ -0,0 +1,844 @@ + + +GnomeVFSURI +3 +GNOME-VFS-2.0 Library + + + +GnomeVFSURI +Functions for manipulating URIs + + +Synopsis + + + + + +typedef GnomeVFSToplevelURI; +enum GnomeVFSURIHideOptions; +#define GNOME_VFS_URI_MAGIC_CHR +#define GNOME_VFS_URI_MAGIC_STR +#define GNOME_VFS_URI_PATH_CHR +#define GNOME_VFS_URI_PATH_STR +GnomeVFSURI* gnome_vfs_uri_new (const gchar *text_uri); +GnomeVFSURI* gnome_vfs_uri_resolve_relative (const GnomeVFSURI *base, + const gchar *relative_reference); +GnomeVFSURI* gnome_vfs_uri_ref (GnomeVFSURI *uri); +void gnome_vfs_uri_unref (GnomeVFSURI *uri); +GnomeVFSURI* gnome_vfs_uri_append_string (const GnomeVFSURI *uri, + const char *uri_fragment); +GnomeVFSURI* gnome_vfs_uri_append_path (const GnomeVFSURI *uri, + const char *path); +GnomeVFSURI* gnome_vfs_uri_append_file_name (const GnomeVFSURI *uri, + const gchar *filename); +gchar* gnome_vfs_uri_to_string (const GnomeVFSURI *uri, + GnomeVFSURIHideOptions hide_options); +GnomeVFSURI* gnome_vfs_uri_dup (const GnomeVFSURI *uri); +gboolean gnome_vfs_uri_is_local (const GnomeVFSURI *uri); +gboolean gnome_vfs_uri_has_parent (const GnomeVFSURI *uri); +GnomeVFSURI* gnome_vfs_uri_get_parent (const GnomeVFSURI *uri); +GnomeVFSToplevelURI* gnome_vfs_uri_get_toplevel + (const GnomeVFSURI *uri); +const gchar* gnome_vfs_uri_get_host_name (const GnomeVFSURI *uri); +const gchar* gnome_vfs_uri_get_scheme (const GnomeVFSURI *uri); +guint gnome_vfs_uri_get_host_port (const GnomeVFSURI *uri); +const gchar* gnome_vfs_uri_get_user_name (const GnomeVFSURI *uri); +const gchar* gnome_vfs_uri_get_password (const GnomeVFSURI *uri); +void gnome_vfs_uri_set_host_name (GnomeVFSURI *uri, + const gchar *host_name); +void gnome_vfs_uri_set_host_port (GnomeVFSURI *uri, + guint host_port); +void gnome_vfs_uri_set_user_name (GnomeVFSURI *uri, + const gchar *user_name); +void gnome_vfs_uri_set_password (GnomeVFSURI *uri, + const gchar *password); +gboolean gnome_vfs_uri_equal (const GnomeVFSURI *a, + const GnomeVFSURI *b); +gboolean gnome_vfs_uri_is_parent (const GnomeVFSURI *possible_parent, + const GnomeVFSURI *possible_child, + gboolean recursive); +const gchar* gnome_vfs_uri_get_path (const GnomeVFSURI *uri); +const gchar* gnome_vfs_uri_get_fragment_identifier + (const GnomeVFSURI *uri); +gchar* gnome_vfs_uri_extract_dirname (const GnomeVFSURI *uri); +gchar* gnome_vfs_uri_extract_short_name + (const GnomeVFSURI *uri); +gchar* gnome_vfs_uri_extract_short_path_name + (const GnomeVFSURI *uri); +gint gnome_vfs_uri_hequal (gconstpointer a, + gconstpointer b); +guint gnome_vfs_uri_hash (gconstpointer p); +GList* gnome_vfs_uri_list_parse (const gchar *uri_list); +GList* gnome_vfs_uri_list_ref (GList *list); +GList* gnome_vfs_uri_list_unref (GList *list); +GList* gnome_vfs_uri_list_copy (GList *list); +void gnome_vfs_uri_list_free (GList *list); +char* gnome_vfs_uri_make_full_from_relative + (const char *base_uri, + const char *relative_uri); + + + + + + + + + + + + +Description + + + + + + +Details + +<anchor id="GnomeVFSToplevelURI"/>GnomeVFSToplevelURI +GnomeVFSToplevelURItypedef struct { + /* Base object. */ + GnomeVFSURI uri; + + /* Server location information. */ + gchar *host_name; + guint host_port; + + /* Authorization information. */ + gchar *user_name; + gchar *password; + + /* The parent URN, if it exists */ + gchar *urn; + + /* Reserved to avoid future breaks in ABI compatibility */ + void *reserved1; + void *reserved2; + +} GnomeVFSToplevelURI; + + + + + +<anchor id="GnomeVFSURIHideOptions"/>enum GnomeVFSURIHideOptions +GnomeVFSURIHideOptionstypedef enum { + GNOME_VFS_URI_HIDE_NONE = 0, + GNOME_VFS_URI_HIDE_USER_NAME = 1 << 0, + GNOME_VFS_URI_HIDE_PASSWORD = 1 << 1, + GNOME_VFS_URI_HIDE_HOST_NAME = 1 << 2, + GNOME_VFS_URI_HIDE_HOST_PORT = 1 << 3, + GNOME_VFS_URI_HIDE_TOPLEVEL_METHOD = 1 << 4, + GNOME_VFS_URI_HIDE_FRAGMENT_IDENTIFIER = 1 << 8 +} GnomeVFSURIHideOptions; + + +Packed boolean bitfield controlling hiding of various elements +of a GnomeVFSURI when it is converted to a string. + + + + +GNOME_VFS_URI_HIDE_NONE + don't hide anything + + + +GNOME_VFS_URI_HIDE_USER_NAME + hide the user name + + + +GNOME_VFS_URI_HIDE_PASSWORD + hide the password + + + +GNOME_VFS_URI_HIDE_HOST_NAME + hide the host name + + + +GNOME_VFS_URI_HIDE_HOST_PORT + hide the port + + + +GNOME_VFS_URI_HIDE_TOPLEVEL_METHOD + hide the method (e.g. http, file) + + + +GNOME_VFS_URI_HIDE_FRAGMENT_IDENTIFIER + hide the fragment identifier + + + + +<anchor id="GNOME-VFS-URI-MAGIC-CHR-CAPS"/>GNOME_VFS_URI_MAGIC_CHR +GNOME_VFS_URI_MAGIC_CHR#define GNOME_VFS_URI_MAGIC_CHR '#' + + +The character used to divide location from +extra "arguments" passed to the method. + + + + +<anchor id="GNOME-VFS-URI-MAGIC-STR-CAPS"/>GNOME_VFS_URI_MAGIC_STR +GNOME_VFS_URI_MAGIC_STR#define GNOME_VFS_URI_MAGIC_STR "#" + + +The character used to divide location from +extra "arguments" passed to the method. + + + + +<anchor id="GNOME-VFS-URI-PATH-CHR-CAPS"/>GNOME_VFS_URI_PATH_CHR +GNOME_VFS_URI_PATH_CHR#define GNOME_VFS_URI_PATH_CHR '/' + + +Defines the path seperator character. + + + + +<anchor id="GNOME-VFS-URI-PATH-STR-CAPS"/>GNOME_VFS_URI_PATH_STR +GNOME_VFS_URI_PATH_STR#define GNOME_VFS_URI_PATH_STR "/" + + +Defines the path seperator string. + + + + +<anchor id="gnome-vfs-uri-new"/>gnome_vfs_uri_new () +gnome_vfs_uri_newGnomeVFSURI* gnome_vfs_uri_new (const gchar *text_uri); + +Create a new URI from text_uri. Unsupported and unsafe methods +are not allowed and will result in null% being returned. URL +transforms are allowed. + + + +text_uri : + A string representing a URI. + +Returns : The new URI. + + + +<anchor id="gnome-vfs-uri-resolve-relative"/>gnome_vfs_uri_resolve_relative () +gnome_vfs_uri_resolve_relativeGnomeVFSURI* gnome_vfs_uri_resolve_relative (const GnomeVFSURI *base, + const gchar *relative_reference); + +Create a new URI from relative_reference, relative to base. + + + +base : + The base URI. + +relative_reference : + A string representing a possibly relative URI reference + +Returns : The new URI. + + + +<anchor id="gnome-vfs-uri-ref"/>gnome_vfs_uri_ref () +gnome_vfs_uri_refGnomeVFSURI* gnome_vfs_uri_ref (GnomeVFSURI *uri); + +Increment uri's reference count. + + + +uri : + A GnomeVFSURI. + +Returns : uri. + + + +<anchor id="gnome-vfs-uri-unref"/>gnome_vfs_uri_unref () +gnome_vfs_uri_unrefvoid gnome_vfs_uri_unref (GnomeVFSURI *uri); + +Decrement uri's reference count. If the reference count reaches zero, +uri is destroyed. + + + +uri : + A GnomeVFSURI. + + + +<anchor id="gnome-vfs-uri-append-string"/>gnome_vfs_uri_append_string () +gnome_vfs_uri_append_stringGnomeVFSURI* gnome_vfs_uri_append_string (const GnomeVFSURI *uri, + const char *uri_fragment); + +Create a new URI obtained by appending path to uri. This will take care +of adding an appropriate directory separator between the end of uri and +the start of path if necessary. + + + +uri : + A GnomeVFSURI. + +uri_fragment : + A piece of a URI (ie a fully escaped partial path) + +Returns : The new URI obtained by combining uri and path. + + + +<anchor id="gnome-vfs-uri-append-path"/>gnome_vfs_uri_append_path () +gnome_vfs_uri_append_pathGnomeVFSURI* gnome_vfs_uri_append_path (const GnomeVFSURI *uri, + const char *path); + +Create a new URI obtained by appending path to uri. This will take care +of adding an appropriate directory separator between the end of uri and +the start of path if necessary as well as escaping path as necessary. + + + +uri : + A GnomeVFSURI. + +path : + A non-escaped file path + +Returns : The new URI obtained by combining uri and path. + + + +<anchor id="gnome-vfs-uri-append-file-name"/>gnome_vfs_uri_append_file_name () +gnome_vfs_uri_append_file_nameGnomeVFSURI* gnome_vfs_uri_append_file_name (const GnomeVFSURI *uri, + const gchar *filename); + +Create a new URI obtained by appending file_name to uri. This will take care +of adding an appropriate directory separator between the end of uri and +the start of file_name if necessary. + + + +uri : + A GnomeVFSURI. + +filename : + any "regular" file name (can include #, /, etc) + +Returns : The new URI obtained by combining uri and path. + + + +<anchor id="gnome-vfs-uri-to-string"/>gnome_vfs_uri_to_string () +gnome_vfs_uri_to_stringgchar* gnome_vfs_uri_to_string (const GnomeVFSURI *uri, + GnomeVFSURIHideOptions hide_options); + +Translate uri into a printable string. The string will not contain the +URI elements specified by hide_options. + + + +uri : + A GnomeVFSURI. + +hide_options : + Bitmask specifying what URI elements (e.g. password, +user name etc.) should not be represented in the returned string. + +Returns : A malloced printable string representing uri. + + + +<anchor id="gnome-vfs-uri-dup"/>gnome_vfs_uri_dup () +gnome_vfs_uri_dupGnomeVFSURI* gnome_vfs_uri_dup (const GnomeVFSURI *uri); + +Duplicate uri. + + + +uri : + A GnomeVFSURI. + +Returns : A pointer to a new URI that is exactly the same as uri. + + + +<anchor id="gnome-vfs-uri-is-local"/>gnome_vfs_uri_is_local () +gnome_vfs_uri_is_localgboolean gnome_vfs_uri_is_local (const GnomeVFSURI *uri); + +Check if uri is a local (native) file system. + + + +uri : + A GnomeVFSURI. + +Returns : FALSE if uri is not a local file system, TRUE otherwise. + + + +<anchor id="gnome-vfs-uri-has-parent"/>gnome_vfs_uri_has_parent () +gnome_vfs_uri_has_parentgboolean gnome_vfs_uri_has_parent (const GnomeVFSURI *uri); + +Check if URI has a parent or not. + + + +uri : + A GnomeVFSURI. + +Returns : TRUE if uri has a parent, FALSE otherwise. + + + +<anchor id="gnome-vfs-uri-get-parent"/>gnome_vfs_uri_get_parent () +gnome_vfs_uri_get_parentGnomeVFSURI* gnome_vfs_uri_get_parent (const GnomeVFSURI *uri); + +Retrieve uri's parent URI. + + + +uri : + A GnomeVFSURI. + +Returns : A pointer to uri's parent URI. + + + +<anchor id="gnome-vfs-uri-get-toplevel"/>gnome_vfs_uri_get_toplevel () +gnome_vfs_uri_get_toplevelGnomeVFSToplevelURI* gnome_vfs_uri_get_toplevel + (const GnomeVFSURI *uri); + +Retrieve the toplevel URI in uri. + + + +uri : + A GnomeVFSURI. + +Returns : A pointer to the toplevel URI object. + + + +<anchor id="gnome-vfs-uri-get-host-name"/>gnome_vfs_uri_get_host_name () +gnome_vfs_uri_get_host_nameconst gchar* gnome_vfs_uri_get_host_name (const GnomeVFSURI *uri); + +Retrieve the host name for uri. + + + +uri : + A GnomeVFSURI. + +Returns : A string representing the host name. + + + +<anchor id="gnome-vfs-uri-get-scheme"/>gnome_vfs_uri_get_scheme () +gnome_vfs_uri_get_schemeconst gchar* gnome_vfs_uri_get_scheme (const GnomeVFSURI *uri); + +Retrieve the scheme used for uri + + + +uri : + A GnomeVFSURI + +Returns : A string representing the scheme + + + +<anchor id="gnome-vfs-uri-get-host-port"/>gnome_vfs_uri_get_host_port () +gnome_vfs_uri_get_host_portguint gnome_vfs_uri_get_host_port (const GnomeVFSURI *uri); + +Retrieve the host port number in uri. + + + +uri : + A GnomeVFSURI. + +Returns : The host port number used by uri. If the value is zero, the +default port value for the specified toplevel access method is used. + + + +<anchor id="gnome-vfs-uri-get-user-name"/>gnome_vfs_uri_get_user_name () +gnome_vfs_uri_get_user_nameconst gchar* gnome_vfs_uri_get_user_name (const GnomeVFSURI *uri); + +Retrieve the user name in uri. + + + +uri : + A GnomeVFSURI. + +Returns : A string representing the user name in uri. + + + +<anchor id="gnome-vfs-uri-get-password"/>gnome_vfs_uri_get_password () +gnome_vfs_uri_get_passwordconst gchar* gnome_vfs_uri_get_password (const GnomeVFSURI *uri); + +Retrieve the password for uri. + + + +uri : + A GnomeVFSURI. + +Returns : The password for uri. + + + +<anchor id="gnome-vfs-uri-set-host-name"/>gnome_vfs_uri_set_host_name () +gnome_vfs_uri_set_host_namevoid gnome_vfs_uri_set_host_name (GnomeVFSURI *uri, + const gchar *host_name); + +Set host_name as the host name accessed by uri. + + + +uri : + A GnomeVFSURI. + +host_name : + A string representing a host name. + + + +<anchor id="gnome-vfs-uri-set-host-port"/>gnome_vfs_uri_set_host_port () +gnome_vfs_uri_set_host_portvoid gnome_vfs_uri_set_host_port (GnomeVFSURI *uri, + guint host_port); + +Set the host port number in uri. If host_port is zero, the default port +for uri's toplevel access method is used. + + + +uri : + A GnomeVFSURI. + +host_port : + A TCP/IP port number. + + + +<anchor id="gnome-vfs-uri-set-user-name"/>gnome_vfs_uri_set_user_name () +gnome_vfs_uri_set_user_namevoid gnome_vfs_uri_set_user_name (GnomeVFSURI *uri, + const gchar *user_name); + +Set user_name as the user name for uri. + + + +uri : + A GnomeVFSURI. + +user_name : + A string representing a user name on the host accessed by uri. + + + +<anchor id="gnome-vfs-uri-set-password"/>gnome_vfs_uri_set_password () +gnome_vfs_uri_set_passwordvoid gnome_vfs_uri_set_password (GnomeVFSURI *uri, + const gchar *password); + +Set password as the password for uri. + + + +uri : + A GnomeVFSURI. + +password : + A password string. + + + +<anchor id="gnome-vfs-uri-equal"/>gnome_vfs_uri_equal () +gnome_vfs_uri_equalgboolean gnome_vfs_uri_equal (const GnomeVFSURI *a, + const GnomeVFSURI *b); + +Compare a and b. + + + +a : + A GnomeVFSURI. + +b : + A GnomeVFSURI. + +Returns : TRUE if a and b are equal, FALSE otherwise. + +FIXME: This comparison should take into account the possiblity +that unreserved characters may be escaped. +...or perhaps gnome_vfs_uri_new should unescape unreserved characters? + + + +<anchor id="gnome-vfs-uri-is-parent"/>gnome_vfs_uri_is_parent () +gnome_vfs_uri_is_parentgboolean gnome_vfs_uri_is_parent (const GnomeVFSURI *possible_parent, + const GnomeVFSURI *possible_child, + gboolean recursive); + +Check if possible_child is contained by possible_parent. +If recursive is FALSE, just try the immediate parent directory, else +search up through the hierarchy. + + + +possible_parent : + A GnomeVFSURI. + +possible_child : + A GnomeVFSURI. + +recursive : + a flag to turn recursive check on. + +Returns : TRUE if possible_child is contained in possible_child. + + + +<anchor id="gnome-vfs-uri-get-path"/>gnome_vfs_uri_get_path () +gnome_vfs_uri_get_pathconst gchar* gnome_vfs_uri_get_path (const GnomeVFSURI *uri); + +Retrieve full path name for uri. + + + +uri : + A GnomeVFSURI + +Returns : A pointer to the full path name in uri. Notice that the +pointer points to the name store in uri, so the name returned must not +be modified nor freed. + + + +<anchor id="gnome-vfs-uri-get-fragment-identifier"/>gnome_vfs_uri_get_fragment_identifier () +gnome_vfs_uri_get_fragment_identifierconst gchar* gnome_vfs_uri_get_fragment_identifier + (const GnomeVFSURI *uri); + + + +uri : + + +Returns : + + + + + +<anchor id="gnome-vfs-uri-extract-dirname"/>gnome_vfs_uri_extract_dirname () +gnome_vfs_uri_extract_dirnamegchar* gnome_vfs_uri_extract_dirname (const GnomeVFSURI *uri); + +Extract the name of the directory in which the file pointed to by uri is +stored as a newly allocated string. The string will end with a +GNOME_VFS_URI_PATH_CHR. + + + +uri : + A GnomeVFSURI + +Returns : A pointer to the newly allocated string representing the +parent directory. + + + +<anchor id="gnome-vfs-uri-extract-short-name"/>gnome_vfs_uri_extract_short_name () +gnome_vfs_uri_extract_short_namegchar* gnome_vfs_uri_extract_short_name + (const GnomeVFSURI *uri); + +Retrieve base file name for uri, ignoring any trailing path separators. +This matches the XPG definition of basename, but not g_basename. This is +often useful when you want the name of something that's pointed to by a +uri, and don't care whether the uri has a directory or file form. +If uri points to the root of a domain, returns the host name. If there's +no host name, returns GNOME_VFS_URI_PATH_STR. + + +See also: gnome_vfs_uri_extract_short_path_name. + + + +uri : + A GnomeVFSURI + +Returns : A pointer to the newly allocated string representing the +unescaped short form of the name. + + + +<anchor id="gnome-vfs-uri-extract-short-path-name"/>gnome_vfs_uri_extract_short_path_name () +gnome_vfs_uri_extract_short_path_namegchar* gnome_vfs_uri_extract_short_path_name + (const GnomeVFSURI *uri); + +Retrieve base file name for uri, ignoring any trailing path separators. +This matches the XPG definition of basename, but not g_basename. This is +often useful when you want the name of something that's pointed to by a +uri, and don't care whether the uri has a directory or file form. +If uri points to the root (including the root of any domain), +returns GNOME_VFS_URI_PATH_STR. + + +See also: gnome_vfs_uri_extract_short_name. + + + +uri : + A GnomeVFSURI + +Returns : A pointer to the newly allocated string representing the +escaped short form of the name. + + + +<anchor id="gnome-vfs-uri-hequal"/>gnome_vfs_uri_hequal () +gnome_vfs_uri_hequalgint gnome_vfs_uri_hequal (gconstpointer a, + gconstpointer b); + +Function intended for use as a hash table "are these two items +the same" comparison. Useful for creating a hash table of URIs. + + + +a : + a pointer to a GnomeVFSURI + +b : + a pointer to a GnomeVFSURI + +Returns : TRUE if the URIs are the same + + + +<anchor id="gnome-vfs-uri-hash"/>gnome_vfs_uri_hash () +gnome_vfs_uri_hashguint gnome_vfs_uri_hash (gconstpointer p); + +Creates an integer value from a GnomeVFSURI, appropriate +for using as the key to a hash table entry. + + + +p : + a pointer to a GnomeVFSURI + +Returns : a hash key corresponding to p + + + +<anchor id="gnome-vfs-uri-list-parse"/>gnome_vfs_uri_list_parse () +gnome_vfs_uri_list_parseGList* gnome_vfs_uri_list_parse (const gchar *uri_list); + +Extracts a list of GnomeVFSURI objects from a standard text/uri-list, +such as one you would get on a drop operation. Use +gnome_vfs_uri_list_free when you are done with the list. + + + +uri_list : + + +Returns : A GList of GnomeVFSURIs + + + +<anchor id="gnome-vfs-uri-list-ref"/>gnome_vfs_uri_list_ref () +gnome_vfs_uri_list_refGList* gnome_vfs_uri_list_ref (GList *list); + +Increments the reference count of the items in list by one. + + + +list : + list of GnomeVFSURI elements + +Returns : list + + + +<anchor id="gnome-vfs-uri-list-unref"/>gnome_vfs_uri_list_unref () +gnome_vfs_uri_list_unrefGList* gnome_vfs_uri_list_unref (GList *list); + +Decrements the reference count of the items in list by one. +Note that the list is *not freed* even if each member of the list +is freed. + + + +list : + list of GnomeVFSURI elements + +Returns : list + + + +<anchor id="gnome-vfs-uri-list-copy"/>gnome_vfs_uri_list_copy () +gnome_vfs_uri_list_copyGList* gnome_vfs_uri_list_copy (GList *list); + +Creates a duplicate of list, and references each member of +that list. + + + +list : + list of GnomeVFSURI elements + +Returns : a newly referenced duplicate of list + + + +<anchor id="gnome-vfs-uri-list-free"/>gnome_vfs_uri_list_free () +gnome_vfs_uri_list_freevoid gnome_vfs_uri_list_free (GList *list); + +Decrements the reference count of each member of list by one, +and frees the list itself. + + + +list : + list of GnomeVFSURI elements + + + +<anchor id="gnome-vfs-uri-make-full-from-relative"/>gnome_vfs_uri_make_full_from_relative () +gnome_vfs_uri_make_full_from_relativechar* gnome_vfs_uri_make_full_from_relative + (const char *base_uri, + const char *relative_uri); + +Returns a full URI given a full base URI, and a secondary URI which may +be relative. + + + +base_uri : + a string representing the base URI + +relative_uri : + a URI fragment/reference to be appended to base_uri + +Returns : a newly allocated string containing the URI +(NULL for some bad errors). + + + + + + + + + diff --git a/doc/xml/gnome-vfs-utils.xml b/doc/xml/gnome-vfs-utils.xml new file mode 100644 index 0000000..89cdca2 --- /dev/null +++ b/doc/xml/gnome-vfs-utils.xml @@ -0,0 +1,464 @@ + + +gnome-vfs-utils +3 +GNOME-VFS-2.0 Library + + + +gnome-vfs-utilsvarious utilities functions to manipulate uris + + +Synopsis + + + + + +char* gnome_vfs_format_file_size_for_display + (GnomeVFSFileSize size); +char* gnome_vfs_escape_string (const char *string); +char* gnome_vfs_escape_path_string (const char *path); +char* gnome_vfs_escape_host_and_path_string + (const char *path); +char* gnome_vfs_escape_slashes (const char *string); +char* gnome_vfs_escape_set (const char *string, + const char *match_set); +char* gnome_vfs_unescape_string (const char *escaped_string, + const char *illegal_characters); +char* gnome_vfs_make_uri_canonical (const char *uri); +char* gnome_vfs_make_path_name_canonical + (const char *path); +char* gnome_vfs_expand_initial_tilde (const char *path); +char* gnome_vfs_unescape_string_for_display + (const char *escaped); +char* gnome_vfs_get_local_path_from_uri + (const char *uri); +char* gnome_vfs_get_uri_from_local_path + (const char *local_full_path); +gboolean gnome_vfs_is_executable_command_string + (const char *command_string); +void gnome_vfs_list_deep_free (GList *list); +GnomeVFSResult gnome_vfs_get_volume_free_space + (const GnomeVFSURI *vfs_uri, + GnomeVFSFileSize *size); +char* gnome_vfs_icon_path_from_filename + (const char *filename); +gboolean gnome_vfs_is_primary_thread (void); +char* gnome_vfs_get_uri_scheme (const char *uri); +gboolean gnome_vfs_uris_match (const char *uri_1, + const char *uri_2); +#define GNOME_VFS_ASSERT_PRIMARY_THREAD +#define GNOME_VFS_ASSERT_SECONDARY_THREAD +GnomeVFSResult gnome_vfs_read_entire_file (const char *uri, + int *file_size, + char **file_contents); + + + + + + + + + + + + +Description + + + + + + +Details + +<anchor id="gnome-vfs-format-file-size-for-display"/>gnome_vfs_format_file_size_for_display () +gnome_vfs_format_file_size_for_displaychar* gnome_vfs_format_file_size_for_display + (GnomeVFSFileSize size); + +Formats the file size passed in bytes in a way that is easy for +the user to read. Gives the size in bytes, kilobytes, megabytes or +gigabytes, choosing whatever is appropriate. + + + +size : + + +Returns : a newly allocated string with the size ready to be shown. + + + +<anchor id="gnome-vfs-escape-string"/>gnome_vfs_escape_string () +gnome_vfs_escape_stringchar* gnome_vfs_escape_string (const char *string); + +Escapes string, replacing any and all special characters +with equivalent escape sequences. + + + +string : + string to be escaped + +Returns : a newly allocated string equivalent to string +but with all special characters escaped + + + +<anchor id="gnome-vfs-escape-path-string"/>gnome_vfs_escape_path_string () +gnome_vfs_escape_path_stringchar* gnome_vfs_escape_path_string (const char *path); + +Escapes path, replacing only special characters that would not +be found in paths (so '/', '&', '=', and '?' will not be escaped by +this function). + + + +path : + string to be escaped + +Returns : a newly allocated string equivalent to path but +with non-path characters escaped + + + +<anchor id="gnome-vfs-escape-host-and-path-string"/>gnome_vfs_escape_host_and_path_string () +gnome_vfs_escape_host_and_path_stringchar* gnome_vfs_escape_host_and_path_string + (const char *path); + +Escapes path, replacing only special characters that would not +be found in paths or host name (so '/', '&', '=', ':', '@' +and '?' will not be escaped by this function). + + + +path : + string to be escaped + +Returns : a newly allocated string equivalent to path but +with non-path/host characters escaped + + + +<anchor id="gnome-vfs-escape-slashes"/>gnome_vfs_escape_slashes () +gnome_vfs_escape_slasheschar* gnome_vfs_escape_slashes (const char *string); + +Escapes only '/' and '%' characters in string, replacing +them with their escape sequence equivalents. + + + +string : + string to be escaped + +Returns : a newly allocated string equivalent to string, +but with no unescaped '/' or '%' characters + + + +<anchor id="gnome-vfs-escape-set"/>gnome_vfs_escape_set () +gnome_vfs_escape_setchar* gnome_vfs_escape_set (const char *string, + const char *match_set); + + + +string : + + +match_set : + + +Returns : + + + + + +<anchor id="gnome-vfs-unescape-string"/>gnome_vfs_unescape_string () +gnome_vfs_unescape_stringchar* gnome_vfs_unescape_string (const char *escaped_string, + const char *illegal_characters); + +Decodes escaped characters (i.e. PERCENTxx sequences) in escaped_string. +Characters are encoded in PERCENTxy form, where xy is the ASCII hex code +for character 16x+y. + + + +escaped_string : + an escaped URI, path, or other string + +illegal_characters : + a string containing a sequence of characters +considered "illegal", '\0' is automatically in this list. + +Returns : a newly allocated string with the unescaped equivalents, +or NULL if escaped_string contained one of the characters +in illegal_characters. + + + +<anchor id="gnome-vfs-make-uri-canonical"/>gnome_vfs_make_uri_canonical () +gnome_vfs_make_uri_canonicalchar* gnome_vfs_make_uri_canonical (const char *uri); + +Standarizes the format of the uri being passed, so that it can be used +later in other functions that expect a canonical URI. + + + +uri : + and absolute or relative URI, it might have scheme. + +Returns : a newly allocated string that contains the canonical +representation of uri. + + +Since 2.2 + + +<anchor id="gnome-vfs-make-path-name-canonical"/>gnome_vfs_make_path_name_canonical () +gnome_vfs_make_path_name_canonicalchar* gnome_vfs_make_path_name_canonical + (const char *path); + +Calls _gnome_vfs_canonicalize_pathname, allocating storage for the +result and providing for a cleaner memory management. + + + +path : + a file path, relative or absolute + +Returns : a canonical version of path + + + +<anchor id="gnome-vfs-expand-initial-tilde"/>gnome_vfs_expand_initial_tilde () +gnome_vfs_expand_initial_tildechar* gnome_vfs_expand_initial_tilde (const char *path); + +If path starts with a ~, representing the user's home +directory, expand it to the actual path location. + + + +path : + a local file path which may start with a '~' + +Returns : a newly allocated string with the initial +tilde (if there was one) converted to an actual path + + + +<anchor id="gnome-vfs-unescape-string-for-display"/>gnome_vfs_unescape_string_for_display () +gnome_vfs_unescape_string_for_displaychar* gnome_vfs_unescape_string_for_display + (const char *escaped); + + + +escaped : + + +Returns : + + + + + +<anchor id="gnome-vfs-get-local-path-from-uri"/>gnome_vfs_get_local_path_from_uri () +gnome_vfs_get_local_path_from_urichar* gnome_vfs_get_local_path_from_uri + (const char *uri); + +Create a local path for a file:/// URI. Do not use with URIs +of other methods. + + + +uri : + URI to convert to a local path + +Returns : a newly allocated string containing the local path +NULL is returned on error or if the uri isn't a file: URI +without a fragment identifier (or chained URI). + + + +<anchor id="gnome-vfs-get-uri-from-local-path"/>gnome_vfs_get_uri_from_local_path () +gnome_vfs_get_uri_from_local_pathchar* gnome_vfs_get_uri_from_local_path + (const char *local_full_path); + +Returns a file:/// URI for the local path local_full_path. + + + +local_full_path : + a full local filesystem path (i.e. not relative) + +Returns : a newly allocated string containing the URI corresponding +to local_full_path (NULL for some bad errors). + + + +<anchor id="gnome-vfs-is-executable-command-string"/>gnome_vfs_is_executable_command_string () +gnome_vfs_is_executable_command_stringgboolean gnome_vfs_is_executable_command_string + (const char *command_string); + +Checks if command_string starts with the full path of an executable file +or an executable in $PATH. + + + +command_string : + + +Returns : TRUE if command_string started with and executable file, +FALSE otherwise. + + + +<anchor id="gnome-vfs-list-deep-free"/>gnome_vfs_list_deep_free () +gnome_vfs_list_deep_freevoid gnome_vfs_list_deep_free (GList *list); + +Free list, and call g_free() on all data members. + + + +list : + list to be freed + + + +<anchor id="gnome-vfs-get-volume-free-space"/>gnome_vfs_get_volume_free_space () +gnome_vfs_get_volume_free_spaceGnomeVFSResult gnome_vfs_get_volume_free_space + (const GnomeVFSURI *vfs_uri, + GnomeVFSFileSize *size); + +Stores in size the amount of free space on a volume. +This only works for local file systems with the file: scheme. + + + +vfs_uri : + + +size : + + +Returns : GNOME_VFS_OK on success, otherwise an error code + + + +<anchor id="gnome-vfs-icon-path-from-filename"/>gnome_vfs_icon_path_from_filename () +gnome_vfs_icon_path_from_filenamechar* gnome_vfs_icon_path_from_filename + (const char *filename); + + + +filename : + + +Returns : + + + + + +<anchor id="gnome-vfs-is-primary-thread"/>gnome_vfs_is_primary_thread () +gnome_vfs_is_primary_threadgboolean gnome_vfs_is_primary_thread (void); + +Check if the current thread is the thread with the main glib event loop. + + + +Returns : TRUE if the current thread is the thread with the +main glib event loop + + + +<anchor id="gnome-vfs-get-uri-scheme"/>gnome_vfs_get_uri_scheme () +gnome_vfs_get_uri_schemechar* gnome_vfs_get_uri_scheme (const char *uri); + +Retrieve the scheme used in uri + + + +uri : + a stringified URI + +Returns : A newly allocated string containing the scheme, NULL +if uri it doesn't seem to contain a scheme + + +Since 2.2 + + +<anchor id="gnome-vfs-uris-match"/>gnome_vfs_uris_match () +gnome_vfs_uris_matchgboolean gnome_vfs_uris_match (const char *uri_1, + const char *uri_2); + +Compare two URIs. + + + +uri_1 : + stringified URI to compare with uri_2. + +uri_2 : + stringified URI to compare with uri_1. + +Returns : TRUE if they are the same, FALSE otherwise. + + +Since 2.2 + + +<anchor id="GNOME-VFS-ASSERT-PRIMARY-THREAD-CAPS"/>GNOME_VFS_ASSERT_PRIMARY_THREAD +GNOME_VFS_ASSERT_PRIMARY_THREAD#define GNOME_VFS_ASSERT_PRIMARY_THREAD g_assert (gnome_vfs_is_primary_thread()) + + +Asserts that the current thread is the thread with +the main glib event loop + + + + +<anchor id="GNOME-VFS-ASSERT-SECONDARY-THREAD-CAPS"/>GNOME_VFS_ASSERT_SECONDARY_THREAD +GNOME_VFS_ASSERT_SECONDARY_THREAD#define GNOME_VFS_ASSERT_SECONDARY_THREAD g_assert (!gnome_vfs_is_primary_thread()) + + +Asserts that the current thread is NOT the thread with +the main glib event loop + + + + +<anchor id="gnome-vfs-read-entire-file"/>gnome_vfs_read_entire_file () +gnome_vfs_read_entire_fileGnomeVFSResult gnome_vfs_read_entire_file (const char *uri, + int *file_size, + char **file_contents); + +Reads an entire file into memory for convenience. Beware accidentally +loading large files into memory with this function. + + + +uri : + URI of the file to read + +file_size : + after reading the file, contains the size of the file read + +file_contents : + contains the file_size bytes, the contents of the file at uri. + +Returns : An integer representing the result of the operation + + +Since 2.2 + + + + + + + + diff --git a/doc/xml/gnome-vfs-xfer.xml b/doc/xml/gnome-vfs-xfer.xml new file mode 100644 index 0000000..4d50a29 --- /dev/null +++ b/doc/xml/gnome-vfs-xfer.xml @@ -0,0 +1,472 @@ + + +File Transfers +3 +GNOME-VFS-2.0 Library + + + +File TransfersConveniently copy/move/delete files en masse + + +Synopsis + + + + + +enum GnomeVFSXferOptions; +enum GnomeVFSXferProgressStatus; +enum GnomeVFSXferOverwriteMode; +enum GnomeVFSXferOverwriteAction; +enum GnomeVFSXferErrorMode; +enum GnomeVFSXferErrorAction; +enum GnomeVFSXferPhase; +typedef GnomeVFSXferProgressInfo; +gint (*GnomeVFSXferProgressCallback) (GnomeVFSXferProgressInfo *info, + gpointer data); +GnomeVFSResult gnome_vfs_xfer_uri_list (const GList *source_uri_list, + const GList *target_uri_list, + GnomeVFSXferOptions xfer_options, + GnomeVFSXferErrorMode error_mode, + GnomeVFSXferOverwriteMode overwrite_mode, + GnomeVFSXferProgressCallback progress_callback, + gpointer data); +GnomeVFSResult gnome_vfs_xfer_uri (const GnomeVFSURI *source_uri, + const GnomeVFSURI *target_uri, + GnomeVFSXferOptions xfer_options, + GnomeVFSXferErrorMode error_mode, + GnomeVFSXferOverwriteMode overwrite_mode, + GnomeVFSXferProgressCallback progress_callback, + gpointer data); +GnomeVFSResult gnome_vfs_xfer_delete_list (const GList *source_uri_list, + GnomeVFSXferErrorMode error_mode, + GnomeVFSXferOptions xfer_options, + GnomeVFSXferProgressCallback progress_callback, + gpointer data); + + + + + + + + + + + + +Description + + + + + + +Details + +<anchor id="GnomeVFSXferOptions"/>enum GnomeVFSXferOptions +GnomeVFSXferOptionstypedef enum { + GNOME_VFS_XFER_DEFAULT = 0, + GNOME_VFS_XFER_UNUSED_1 = 1 << 0, + GNOME_VFS_XFER_FOLLOW_LINKS = 1 << 1, + GNOME_VFS_XFER_UNUSED_2 = 1 << 2, + GNOME_VFS_XFER_RECURSIVE = 1 << 3, + GNOME_VFS_XFER_SAMEFS = 1 << 4, + GNOME_VFS_XFER_DELETE_ITEMS = 1 << 5, + GNOME_VFS_XFER_EMPTY_DIRECTORIES = 1 << 6, + GNOME_VFS_XFER_NEW_UNIQUE_DIRECTORY = 1 << 7, + GNOME_VFS_XFER_REMOVESOURCE = 1 << 8, + GNOME_VFS_XFER_USE_UNIQUE_NAMES = 1 << 9, + GNOME_VFS_XFER_LINK_ITEMS = 1 << 10, + GNOME_VFS_XFER_FOLLOW_LINKS_RECURSIVE = 1 << 11 +} GnomeVFSXferOptions; + + + + + +<anchor id="GnomeVFSXferProgressStatus"/>enum GnomeVFSXferProgressStatus +GnomeVFSXferProgressStatustypedef enum { + GNOME_VFS_XFER_PROGRESS_STATUS_OK = 0, + GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR = 1, + GNOME_VFS_XFER_PROGRESS_STATUS_OVERWRITE = 2, + /* during the duplicate status the progress callback is asked to + supply a new unique name */ + GNOME_VFS_XFER_PROGRESS_STATUS_DUPLICATE = 3 +} GnomeVFSXferProgressStatus; + + + + + +<anchor id="GnomeVFSXferOverwriteMode"/>enum GnomeVFSXferOverwriteMode +GnomeVFSXferOverwriteModetypedef enum { + /* Interrupt transferring with an error (GNOME_VFS_ERROR_FILEEXISTS). */ + GNOME_VFS_XFER_OVERWRITE_MODE_ABORT = 0, + /* Invoke the progress callback with a + `GNOME_VFS_XFER_PROGRESS_STATUS_OVERWRITE' status code. */ + GNOME_VFS_XFER_OVERWRITE_MODE_QUERY = 1, + /* Overwrite files silently. */ + GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE = 2, + /* Ignore files silently. */ + GNOME_VFS_XFER_OVERWRITE_MODE_SKIP = 3 +} GnomeVFSXferOverwriteMode; + + + + + +<anchor id="GnomeVFSXferOverwriteAction"/>enum GnomeVFSXferOverwriteAction +GnomeVFSXferOverwriteActiontypedef enum { + GNOME_VFS_XFER_OVERWRITE_ACTION_ABORT = 0, + GNOME_VFS_XFER_OVERWRITE_ACTION_REPLACE = 1, + GNOME_VFS_XFER_OVERWRITE_ACTION_REPLACE_ALL = 2, + GNOME_VFS_XFER_OVERWRITE_ACTION_SKIP = 3, + GNOME_VFS_XFER_OVERWRITE_ACTION_SKIP_ALL = 4 +} GnomeVFSXferOverwriteAction; + + +This defines the actions to perform before a file is being overwritten +(i.e., these are the answers that can be given to a replace query). + + + + +GNOME_VFS_XFER_OVERWRITE_ACTION_ABORT + abort the transfer + + + +GNOME_VFS_XFER_OVERWRITE_ACTION_REPLACE + replace the existing file + + + +GNOME_VFS_XFER_OVERWRITE_ACTION_REPLACE_ALL + replace the existing file, and all future files +without prompting the callback. + + + +GNOME_VFS_XFER_OVERWRITE_ACTION_SKIP + don't copy over the existing file + + + +GNOME_VFS_XFER_OVERWRITE_ACTION_SKIP_ALL + don't copy over the existing file, and all future +files without prompting the callback. + + + + +<anchor id="GnomeVFSXferErrorMode"/>enum GnomeVFSXferErrorMode +GnomeVFSXferErrorModetypedef enum { + /* Interrupt transferring with an error (code returned is code of the + operation that has caused the error). */ + GNOME_VFS_XFER_ERROR_MODE_ABORT = 0, + /* Invoke the progress callback with a + `GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR' status code. */ + GNOME_VFS_XFER_ERROR_MODE_QUERY = 1 +} GnomeVFSXferErrorMode; + + + + + +<anchor id="GnomeVFSXferErrorAction"/>enum GnomeVFSXferErrorAction +GnomeVFSXferErrorActiontypedef enum { + /* Interrupt operation and return `GNOME_VFS_ERROR_INTERRUPTED'. */ + GNOME_VFS_XFER_ERROR_ACTION_ABORT = 0, + /* Try the same operation again. */ + GNOME_VFS_XFER_ERROR_ACTION_RETRY = 1, + /* Skip this file and continue normally. */ + GNOME_VFS_XFER_ERROR_ACTION_SKIP = 2 +} GnomeVFSXferErrorAction; + + + + + +<anchor id="GnomeVFSXferPhase"/>enum GnomeVFSXferPhase +GnomeVFSXferPhasetypedef enum { + /* Initial phase */ + GNOME_VFS_XFER_PHASE_INITIAL, + /* Checking if destination can handle move/copy */ + GNOME_VFS_XFER_CHECKING_DESTINATION, + /* Collecting file list */ + GNOME_VFS_XFER_PHASE_COLLECTING, + /* File list collected (*) */ + GNOME_VFS_XFER_PHASE_READYTOGO, + /* Opening source file for reading */ + GNOME_VFS_XFER_PHASE_OPENSOURCE, + /* Creating target file for copy */ + GNOME_VFS_XFER_PHASE_OPENTARGET, + /* Copying data from source to target (*) */ + GNOME_VFS_XFER_PHASE_COPYING, + /* Moving file from source to target (*) */ + GNOME_VFS_XFER_PHASE_MOVING, + /* Reading data from source file */ + GNOME_VFS_XFER_PHASE_READSOURCE, + /* Writing data to target file */ + GNOME_VFS_XFER_PHASE_WRITETARGET, + /* Closing source file */ + GNOME_VFS_XFER_PHASE_CLOSESOURCE, + /* Closing target file */ + GNOME_VFS_XFER_PHASE_CLOSETARGET, + /* Deleting source file */ + GNOME_VFS_XFER_PHASE_DELETESOURCE, + /* Setting attributes on target file */ + GNOME_VFS_XFER_PHASE_SETATTRIBUTES, + /* Go to the next file (*) */ + GNOME_VFS_XFER_PHASE_FILECOMPLETED, + /* cleaning up after a move (removing source files, etc.) */ + GNOME_VFS_XFER_PHASE_CLEANUP, + /* Operation finished (*) */ + GNOME_VFS_XFER_PHASE_COMPLETED, + GNOME_VFS_XFER_NUM_PHASES +} GnomeVFSXferPhase; + + + + + +<anchor id="GnomeVFSXferProgressInfo"/>GnomeVFSXferProgressInfo +GnomeVFSXferProgressInfotypedef struct { + /* Progress status (see above for a description). */ + GnomeVFSXferProgressStatus status; + + /* VFS status code. If `status' is + `GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR', you should look at this + member to know what has happened. */ + GnomeVFSResult vfs_status; + + /* Current phase in the transferring process. */ + GnomeVFSXferPhase phase; + + /* Source URI. FIXME bugzilla.eazel.com 1206: change name? */ + gchar *source_name; + + /* Destination URI. FIXME bugzilla.eazel.com 1206: change name? */ + gchar *target_name; + + /* Index of file being copied. */ + gulong file_index; + + /* Total number of files to be copied. */ + gulong files_total; + + /* Total number of bytes to be copied. */ + GnomeVFSFileSize bytes_total; + + /* Total size of this file (in bytes). */ + GnomeVFSFileSize file_size; + + /* Bytes copied for this file so far. */ + GnomeVFSFileSize bytes_copied; + + /* Total amount of data copied from the beginning. */ + GnomeVFSFileSize total_bytes_copied; + + /* Target unique name used when duplicating, etc. to avoid collisions */ + gchar *duplicate_name; + + /* Count used in the unique name e.g. (copy 2), etc. */ + int duplicate_count; + + gboolean top_level_item; + /* indicates that the copied/moved/deleted item is an actual item + * passed in the uri list rather than one encountered by recursively + * traversing directories. Used by metadata copying. + */ + + /* Reserved for future expansions to GnomeVFSXferProgressInfo + * without having to break ABI compatibility */ + void *reserved1; + void *reserved2; + +} GnomeVFSXferProgressInfo; + + + + + +<anchor id="GnomeVFSXferProgressCallback"/>GnomeVFSXferProgressCallback () +GnomeVFSXferProgressCallbackgint (*GnomeVFSXferProgressCallback) (GnomeVFSXferProgressInfo *info, + gpointer data); + + + +info : + + +data : + + +Returns : + + + + + +<anchor id="gnome-vfs-xfer-uri-list"/>gnome_vfs_xfer_uri_list () +gnome_vfs_xfer_uri_listGnomeVFSResult gnome_vfs_xfer_uri_list (const GList *source_uri_list, + const GList *target_uri_list, + GnomeVFSXferOptions xfer_options, + GnomeVFSXferErrorMode error_mode, + GnomeVFSXferOverwriteMode overwrite_mode, + GnomeVFSXferProgressCallback progress_callback, + gpointer data); + +This function will transfer multiple files to a multiple targets. Given a +a source uri(s) and a destination uri(s). There are a list of options that +your application can use to control how the transfer is done. + + + +source_uri_list : + A Glist of uris (ie file;//) + +target_uri_list : + A GList of uris + +xfer_options : + These are options you wish to set for the transfer. For +instance by setting the xfer behavior you can either make a copy or a +move. + +error_mode : + Decide how to behave if the xfer is interrupted. For instance +you could set your application to return an error code in case of an +interuption. + +overwrite_mode : + How to react if a file your copying is being overwritten. + +progress_callback : + This is used to monitor the progress of a transfer. +Common use would be to check to see if the transfer is asking for permission +to overwrite a file. + +data : + Data to be want passed back in callbacks from the xfer engine + +Returns : If all goes well it returns GNOME_VFS_OK. Check GnomeVFSResult for +other values. + + + +<anchor id="gnome-vfs-xfer-uri"/>gnome_vfs_xfer_uri () +gnome_vfs_xfer_uriGnomeVFSResult gnome_vfs_xfer_uri (const GnomeVFSURI *source_uri, + const GnomeVFSURI *target_uri, + GnomeVFSXferOptions xfer_options, + GnomeVFSXferErrorMode error_mode, + GnomeVFSXferOverwriteMode overwrite_mode, + GnomeVFSXferProgressCallback progress_callback, + gpointer data); + +This function will allow a person to copy data from one location to another. +The location is specified using a URIs as the means to describe the location +of the data. Like any copy there are several options that can be set. +These can be set using the xfer_options. In addition there are callback +mechanisms and error codes to provide feedback in the copy +process. + + + +source_uri : + This is the location of where your data resides. + +target_uri : + This is the location of where you want your data to go. + +xfer_options : + Set the kind of transfers you want. These are: +GNOME_VFS_XFER_DEFAULT: Default behavior. Which is to do a straight one to +one copy. +GNOME_VFS_XFER_FOLLOW_LINKS: This means follow the value of the symbolic +link when copying. (ie treat a symbolic link as a directory) +GNOME_VFS_RECURSIVE: Do a recursive copy of the source to the destination. +Equivalent to the cp -r option in GNU cp. +GNOME_VFS_XFER_SAME_FS: This only allows copying onto the same filesystem. +GNOME_VFS_DELETE_ITEM: This is equivalent to a mv. Where you will copy the +contents of the source to the destination and then remove data from the +source URI. +GNOME_VFS_XFER_EMPTY_DIRECTORIES: <TBA> +GNOME_VFS_XFER_NEW_UNIQUE_DIRECTORY: This will create a directory if it +doesn't exist in the destination area. Useful with the +GNOME_VFS_XFER_RECURSIVE xfer option. +GNOME_VFS_XFER_REMOVESOURCE: This option will remove the source data after +whatever xfer option has been taken. +GNOME_VFS_USE_UNIQUE_NAMES: This is a check ot make sure that what you copy +onto the destination is not overwritten. It will only copy the unique items +from the source to the destjnation. +GNOME_VFS_XFER_LINK_ITEMS: <TBA> + +error_mode : + When this function returns you need to check the error code +for the results of the copy. The results are generally: +GNOME_VFS_XFER_ERROR_MODE_ABORT: This means that the operation was aborted +by some sort of signal that interrupted the transfer. +GNOME_VFS_ERROR_MODE_QUERY: This means that no error has occured and that +you should query with the GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR. See + +overwrite_mode : + This sets the options to deal with data that are duplicate +between the source and the destination. Your choices are: +GNOME_VFS_XFER_OVERWRITE_MODE_ABORT: This means abort the transfer if you +see duplicate data. +GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE: Replace the files silently. Don't +worry be happy. +GNOME_VFS_XFER_OVERWRITE_MODE_SKIP: Skip duplicate files silenty. +target. + +progress_callback : + This is an important call back because this is how you +communicate with your copy process. + +data : + Data to be want passed back in callbacks from the xfer engine + +Returns : An integer representing the result of the operation. + + + + +<anchor id="gnome-vfs-xfer-delete-list"/>gnome_vfs_xfer_delete_list () +gnome_vfs_xfer_delete_listGnomeVFSResult gnome_vfs_xfer_delete_list (const GList *source_uri_list, + GnomeVFSXferErrorMode error_mode, + GnomeVFSXferOptions xfer_options, + GnomeVFSXferProgressCallback progress_callback, + gpointer data); + +Unlink items in the list source_uri_list from their filesystems. + + + +source_uri_list : + This is a list containing uris + +error_mode : + Decide how you want to deal with interruptions + +xfer_options : + Set whatever transfer options you need. + +progress_callback : + Callback to check on progress of transfer. + +data : + Data to be want passed back in callbacks from the xfer engine + +Returns : GNOME_VFS_OK if successful, or the appropriate error code otherwise + + + + + + + + + diff --git a/gnome-vfs-2.0.pc.in b/gnome-vfs-2.0.pc.in new file mode 100644 index 0000000..fc45497 --- /dev/null +++ b/gnome-vfs-2.0.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + + +Name: gnome-vfs +Description: The GNOME virtual file-system libraries +Version: @VERSION@ +Requires: bonobo-activation-2.0,gthread-2.0,gmodule-2.0 +Libs: -L${libdir} -lgnomevfs-2 +Cflags: -I${includedir}/gnome-vfs-2.0 -I${libdir}/gnome-vfs-2.0/include diff --git a/gnome-vfs-module-2.0.pc.in b/gnome-vfs-module-2.0.pc.in new file mode 100644 index 0000000..b52fb7b --- /dev/null +++ b/gnome-vfs-module-2.0.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + + +Name: gnome-vfs-module +Description: The GNOME virtual file-system module include info +Version: @VERSION@ +Requires: bonobo-activation-2.0,gthread-2.0,gmodule-2.0 +Libs: -L${libdir} -lgnomevfs-2 +Cflags: -I${includedir}/gnome-vfs-2.0 -I${includedir}/gnome-vfs-module-2.0 -I${libdir}/gnome-vfs-2.0/include diff --git a/gnome-vfs.spec b/gnome-vfs.spec new file mode 100644 index 0000000..6373123 --- /dev/null +++ b/gnome-vfs.spec @@ -0,0 +1,122 @@ +%define localstatedir /var/lib + +Name: gnome-vfs +Summary: The GNOME virtual file-system libraries +Version: 2.3.8 +Release: 1_cvs +License: LGPL +Group: System Environment/Libraries +Source: ftp://ftp.gnome.org/pub/GNOME/stable/sources/%name/%name-%{version}.tar.gz +URL: http://www.gnome.org/ +BuildRoot: /var/tmp/%{name}-root +Requires: control-center +Requires: glib2 >= 2.0.0 +Requires: GConf2 >= 1.1.1 +BuildRequires: gnome-libs-devel, control-center-devel +BuildRequires: bonobo-activation-devel >= 1.0.0 +BuildRequires: bonobo-devel >= 2.0.0 +BuildRequires: GConf2-devel >= 1.1.1 +BuildRequires: gtk2-devel >= @GTK_REQUIRED@ +BuildRequires: ORBit-devel >= 2.4.0 +BuildRequires: libxml2 >= 2.2.8 + +%description +GNOME VFS is the GNOME virtual file system. It is the foundation of the +Nautilus file manager. It provides a modular architecture and ships with +several modules that implement support for file systems, http, ftp and others. +It provides a URI-based API, a backend supporting asynchronous file operations, +a MIME type manipulation library and other features. + +%package devel +Summary: Libraries and include files for developing GNOME VFS applications. +Group: Development/Libraries +Requires: %name = %{version} +Requires: glib-devel +Requires: bonobo-devel + +%description devel +This package provides the necessary development libraries for writing +GNOME VFS modules and applications that use the GNOME VFS APIs. + +%prep +%setup -q + +%build + +%ifarch alpha + MYARCH_FLAGS="--host=alpha-redhat-linux" +%endif + +# Needed for snapshot releases. +MYCFLAGS="$RPM_OPT_FLAGS" + +if [ ! -f configure ]; then + CFLAGS="$MYCFLAGS" ./autogen.sh $MYARCH_FLAGS \ + --enable-more-warnings --prefix=%{_prefix} \ + --localstatedir=%{localstatedir} --sysconfdir=%{_sysconfdir} \ + --mandir=%{_mandir} --libdir=%{_libdir} \ + --includedir=%{_includedir} --bindir=%{_bindir} +fi + +CFLAGS="$MYCFLAGS" ./configure $MYARCH_FLAGS --enable-more-warnings \ + --prefix=%{_prefix} --localstatedir=%{localstatedir} \ + --sysconfdir=%{_sysconfdir} --mandir=%{_mandir} \ + --libdir=%{_libdir} --includedir=%{_includedir} \ + --bindir=%{_bindir} + +make + +%install +rm -rf $RPM_BUILD_ROOT + +make -k sysconfdir=$RPM_BUILD_ROOT%{_sysconfdir} \ + prefix=$RPM_BUILD_ROOT%{_prefix} mandir=$RPM_BUILD_ROOT%{_mandir} \ + libdir=$RPM_BUILD_ROOT%{_libdir} bindir=$RPM_BUILD_ROOT\%{_bindir} \ + includedir=$RPM_BUILD_ROOT%{_includedir} install + +%find_lang %name + +%clean +rm -rf $RPM_BUILD_ROOT + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + +%files -f %{name}.lang +%defattr(-, root, root) + +%doc AUTHORS COPYING ChangeLog NEWS README +%config %{_sysconfdir}/gnome-vfs-2.0/modules/*.conf +%config %{_sysconfdir}/gnome-vfs-2.0/vfolders/*.vfolder-info +%{_libdir}/*.so.* +%{_libdir}/*.so +%{_libdir}/vfs/extfs/* +%{_libdir}/gnome-vfs-2.0/modules/*.so +%{_libdir}/bonobo/monikers/*.so +%{_libdir}/bonobo/servers/*.server +%{_prefix}/share/gtk-doc/html/gnome-vfs/*.html +%{_prefix}/share/locale/*/LC_MESSAGES/*.mo + +%files devel +%defattr(-, root, root) +%{_includedir}/gnome-vfs-2.0/libgnomevfs/*.h +%{_includedir}/gnome-vfs-module-2.0/libgnomevfs/*.h +%{_libdir}/gnome-vfs-2.0/include/*.h +%{_libdir}/*.a +%{_libdir}/*.la +%{_libdir}/gnome-vfs-2.0/modules/*.a +%{_libdir}/gnome-vfs-2.0/modules/*.la +%{_libdir}/bonobo/monikers/*.a +%{_libdir}/bonobo/monikers/*.la +%{_libdir}/pkgconfig/*.pc + +%changelog + +* Sun Dec 15 2001 Ross Golder +- fixed broken Name: + +* Sun Oct 21 2001 Gregory Leblanc +- some messing around with Requires: and BuildRequires +- cleaned up %files quite a bit (still not quite as good as it could be) +- removed a bunch of unnecessary %defines diff --git a/gnome-vfs.spec.in b/gnome-vfs.spec.in new file mode 100644 index 0000000..ee550a6 --- /dev/null +++ b/gnome-vfs.spec.in @@ -0,0 +1,122 @@ +%define localstatedir /var/lib + +Name: @PACKAGE@ +Summary: The GNOME virtual file-system libraries +Version: @VERSION@ +Release: 1_cvs +License: LGPL +Group: System Environment/Libraries +Source: ftp://ftp.gnome.org/pub/GNOME/stable/sources/%name/%name-%{version}.tar.gz +URL: http://www.gnome.org/ +BuildRoot: /var/tmp/%{name}-root +Requires: control-center +Requires: glib2 >= @GLIB_REQUIRED@ +Requires: GConf2 >= @GCONF_REQUIRED@ +BuildRequires: gnome-libs-devel, control-center-devel +BuildRequires: bonobo-activation-devel >= @BONOBO_ACTIVATION_REQUIRED@ +BuildRequires: bonobo-devel >= @BONOBO_REQUIRED@ +BuildRequires: GConf2-devel >= @GCONF_REQUIRED@ +BuildRequires: gtk2-devel >= @GTK_REQUIRED@ +BuildRequires: ORBit-devel >= @ORBIT_REQUIRED@ +BuildRequires: libxml2 >= @XML_REQUIRED@ + +%description +GNOME VFS is the GNOME virtual file system. It is the foundation of the +Nautilus file manager. It provides a modular architecture and ships with +several modules that implement support for file systems, http, ftp and others. +It provides a URI-based API, a backend supporting asynchronous file operations, +a MIME type manipulation library and other features. + +%package devel +Summary: Libraries and include files for developing GNOME VFS applications. +Group: Development/Libraries +Requires: %name = %{version} +Requires: glib-devel +Requires: bonobo-devel + +%description devel +This package provides the necessary development libraries for writing +GNOME VFS modules and applications that use the GNOME VFS APIs. + +%prep +%setup -q + +%build + +%ifarch alpha + MYARCH_FLAGS="--host=alpha-redhat-linux" +%endif + +# Needed for snapshot releases. +MYCFLAGS="$RPM_OPT_FLAGS" + +if [ ! -f configure ]; then + CFLAGS="$MYCFLAGS" ./autogen.sh $MYARCH_FLAGS \ + --enable-more-warnings --prefix=%{_prefix} \ + --localstatedir=%{localstatedir} --sysconfdir=%{_sysconfdir} \ + --mandir=%{_mandir} --libdir=%{_libdir} \ + --includedir=%{_includedir} --bindir=%{_bindir} +fi + +CFLAGS="$MYCFLAGS" ./configure $MYARCH_FLAGS --enable-more-warnings \ + --prefix=%{_prefix} --localstatedir=%{localstatedir} \ + --sysconfdir=%{_sysconfdir} --mandir=%{_mandir} \ + --libdir=%{_libdir} --includedir=%{_includedir} \ + --bindir=%{_bindir} + +make + +%install +rm -rf $RPM_BUILD_ROOT + +make -k sysconfdir=$RPM_BUILD_ROOT%{_sysconfdir} \ + prefix=$RPM_BUILD_ROOT%{_prefix} mandir=$RPM_BUILD_ROOT%{_mandir} \ + libdir=$RPM_BUILD_ROOT%{_libdir} bindir=$RPM_BUILD_ROOT\%{_bindir} \ + includedir=$RPM_BUILD_ROOT%{_includedir} install + +%find_lang %name + +%clean +rm -rf $RPM_BUILD_ROOT + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + +%files -f %{name}.lang +%defattr(-, root, root) + +%doc AUTHORS COPYING ChangeLog NEWS README +%config %{_sysconfdir}/gnome-vfs-2.0/modules/*.conf +%config %{_sysconfdir}/gnome-vfs-2.0/vfolders/*.vfolder-info +%{_libdir}/*.so.* +%{_libdir}/*.so +%{_libdir}/vfs/extfs/* +%{_libdir}/gnome-vfs-2.0/modules/*.so +%{_libdir}/bonobo/monikers/*.so +%{_libdir}/bonobo/servers/*.server +%{_prefix}/share/gtk-doc/html/gnome-vfs/*.html +%{_prefix}/share/locale/*/LC_MESSAGES/*.mo + +%files devel +%defattr(-, root, root) +%{_includedir}/gnome-vfs-2.0/libgnomevfs/*.h +%{_includedir}/gnome-vfs-module-2.0/libgnomevfs/*.h +%{_libdir}/gnome-vfs-2.0/include/*.h +%{_libdir}/*.a +%{_libdir}/*.la +%{_libdir}/gnome-vfs-2.0/modules/*.a +%{_libdir}/gnome-vfs-2.0/modules/*.la +%{_libdir}/bonobo/monikers/*.a +%{_libdir}/bonobo/monikers/*.la +%{_libdir}/pkgconfig/*.pc + +%changelog + +* Sun Dec 15 2001 Ross Golder +- fixed broken Name: + +* Sun Oct 21 2001 Gregory Leblanc +- some messing around with Requires: and BuildRequires +- cleaned up %files quite a bit (still not quite as good as it could be) +- removed a bunch of unnecessary %defines diff --git a/install-sh b/install-sh new file mode 100755 index 0000000..e9de238 --- /dev/null +++ b/install-sh @@ -0,0 +1,251 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + chmodcmd="" + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/intltool-extract.in b/intltool-extract.in new file mode 100644 index 0000000..cb2657b --- /dev/null +++ b/intltool-extract.in @@ -0,0 +1,406 @@ +#!@INTLTOOL_PERL@ -w +# -*- Mode: perl; indent-tabs-mode: nil; c-basic-offset: 4 -*- + +# +# The Intltool Message Extractor +# +# Copyright (C) 2000-2001, 2003 Free Software Foundation. +# +# Intltool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# Intltool is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. +# +# Authors: Kenneth Christiansen +# Darin Adler +# + +## Release information +my $PROGRAM = "intltool-extract"; +my $PACKAGE = "intltool"; +my $VERSION = "0.26"; + +## Loaded modules +use strict; +use File::Basename; +use Getopt::Long; + +## Scalars used by the option stuff +my $TYPE_ARG = "0"; +my $LOCAL_ARG = "0"; +my $HELP_ARG = "0"; +my $VERSION_ARG = "0"; +my $UPDATE_ARG = "0"; +my $QUIET_ARG = "0"; + +my $FILE; +my $OUTFILE; + +my $gettext_type = ""; +my $input; +my %messages = (); + +## Use this instead of \w for XML files to handle more possible characters. +my $w = "[-A-Za-z0-9._:]"; + +## Always print first +$| = 1; + +## Handle options +GetOptions ( + "type=s" => \$TYPE_ARG, + "local|l" => \$LOCAL_ARG, + "help|h" => \$HELP_ARG, + "version|v" => \$VERSION_ARG, + "update" => \$UPDATE_ARG, + "quiet|q" => \$QUIET_ARG, + ) or &error; + +&split_on_argument; + + +## Check for options. +## This section will check for the different options. + +sub split_on_argument { + + if ($VERSION_ARG) { + &version; + + } elsif ($HELP_ARG) { + &help; + + } elsif ($LOCAL_ARG) { + &place_local; + &extract; + + } elsif ($UPDATE_ARG) { + &place_normal; + &extract; + + } elsif (@ARGV > 0) { + &place_normal; + &message; + &extract; + + } else { + &help; + + } +} + +sub place_normal { + $FILE = $ARGV[0]; + $OUTFILE = "$FILE.h"; +} + +sub place_local { + $OUTFILE = fileparse($FILE, ()); + if (!-e "tmp/") { + system("mkdir tmp/"); + } + $OUTFILE = "./tmp/$OUTFILE.h" +} + +sub determine_type { + if ($TYPE_ARG =~ /^gettext\/(.*)/) { + $gettext_type=$1 + } +} + +## Sub for printing release information +sub version{ + print <<_EOF_; +${PROGRAM} (${PACKAGE}) $VERSION +Copyright (C) 2000, 2003 Free Software Foundation, Inc. +Written by Kenneth Christiansen, 2000. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +_EOF_ + exit; +} + +## Sub for printing usage information +sub help { + print <<_EOF_; +Usage: ${PROGRAM} [OPTION]... [FILENAME] +Generates a header file from an XML source file. + +It grabs all strings between <_translatable_node> and its end tag in +XML files. Read manpage (man ${PROGRAM}) for more info. + + --type=TYPE Specify the file type of FILENAME. Currently supports: + "gettext/glade", "gettext/ini", "gettext/keys" + "gettext/rfc822deb", "gettext/schemas", + "gettext/scheme", "gettext/xml" + -l, --local Writes output into current working directory + (conflicts with --update) + --update Writes output into the same directory the source file + reside (conflicts with --local) + -v, --version Output version information and exit + -h, --help Display this help and exit + -q, --quiet Quiet mode + +Report bugs to http://bugzilla.gnome.org/ (product name "$PACKAGE") +or send email to . +_EOF_ + exit; +} + +## Sub for printing error messages +sub error{ + print STDERR "Try `${PROGRAM} --help' for more information.\n"; + exit; +} + +sub message { + print "Generating C format header file for translation.\n" unless $QUIET_ARG; +} + +sub extract { + &determine_type; + + &convert ($FILE); + + open OUT, ">$OUTFILE"; + &msg_write; + close OUT; + + print "Wrote $OUTFILE\n" unless $QUIET_ARG; +} + +sub convert($) { + + ## Reading the file + { + local (*IN); + local $/; #slurp mode + open (IN, "<$FILE") || die "can't open $FILE: $!"; + $input = ; + } + + &type_ini if $gettext_type eq "ini"; + &type_keys if $gettext_type eq "keys"; + &type_xml if $gettext_type eq "xml"; + &type_glade if $gettext_type eq "glade"; + &type_scheme if $gettext_type eq "scheme"; + &type_schemas if $gettext_type eq "schemas"; + &type_rfc822deb if $gettext_type eq "rfc822deb"; +} + +sub entity_decode_minimal +{ + local ($_) = @_; + + s/'/'/g; # ' + s/"/"/g; # " + s/&/&/g; + + return $_; +} + +sub entity_decode +{ + local ($_) = @_; + + s/'/'/g; # ' + s/"/"/g; # " + s/&/&/g; + s/<//g; + + return $_; +} + +sub escape_char +{ + return '\"' if $_ eq '"'; + return '\n' if $_ eq "\n"; + return '\\' if $_ eq '\\'; + + return $_; +} + +sub escape +{ + my ($string) = @_; + return join "", map &escape_char, split //, $string; +} + +sub type_ini { + ### For generic translatable desktop files ### + while ($input =~ /^_.*=(.*)$/mg) { + $messages{$1} = []; + } +} + +sub type_keys { + ### For generic translatable mime/keys files ### + while ($input =~ /^\s*_\w+=(.*)$/mg) { + $messages{$1} = []; + } +} + +sub type_xml { + ### For generic translatable XML files ### + + while ($input =~ /\s_$w+\s*=\s*\"([^"]+)\"/sg) { # " + $messages{entity_decode_minimal($1)} = []; + } + + while ($input =~ /<_($w+)(?: xml:space="($w+)")?>(.+?)<\/_\1>/sg) { + $_ = $3; + if (!defined($2) || $2 ne "preserve") { + s/\s+/ /g; + s/^ //; + s/ $//; + } + $messages{entity_decode_minimal($_)} = []; + } +} + +sub type_schemas { + ### For schemas XML files ### + + # FIXME: We should handle escaped < (less than) + while ($input =~ / + \s* + (\s*(.*?)\s*<\/default>\s*)? + (\s*(.*?)\s*<\/short>\s*)? + (\s*(.*?)\s*<\/long>\s*)? + <\/locale> + /sgx) { + my @totranslate = ($2,$4,$6); + foreach (@totranslate) { + next if !$_; + s/\s+/ /g; + $messages{entity_decode_minimal($_)} = []; + } + } +} + +sub type_rfc822deb { + ### For rfc822-style Debian configuration files ### + + while ($input =~ /(?:^|\n)_[^:]+:\s*(.*?)(?=\n\S|$)/sg) { + my @str_list = rfc822deb_split($1); + for my $str (@str_list) { + # As rfc822deb is for configuration files, duplicates + # should never happen. Developers must use the + # [] construct to make msgid unique, see also intltool-merge + print STDERR "Warning: msgid multiply defined:\n $str\n" + if defined($messages{$str}); + $messages{$str} = []; + } + } +} + +sub rfc822deb_split { + # Debian defines a special way to deal with rfc822-style files: + # when a value contain newlines, it consists of + # 1. a short form (first line) + # 2. a long description, all lines begin with a space, + # and paragraphs are separated by a single dot on a line + # This routine returns an array of all paragraphs, and reformat + # them. + my $text = shift; + $text =~ s/^ //mg; + return ($text) if $text !~ /\n/; + + $text =~ s/([^\n]*)\n//; + my @list = ($1); + my $str = ''; + for my $line (split (/\n/, $text)) { + chomp $line; + $line =~ /\s+$/; + if ($line =~ /^\.$/) { + # New paragraph + $str =~ s/\s*$//; + push(@list, $str); + $str = ''; + } elsif ($line =~ /^\s/) { + # Line which must not be reformatted + $str .= "\n" if length ($str) && $str !~ /\n$/; + $str .= $line."\n"; + } else { + # Continuation line, remove newline + $str .= " " if length ($str) && $str !~ /[\n ]$/; + $str .= $line; + } + } + $str =~ s/\s*$//; + push(@list, $str) if length ($str); + return @list; +} + +sub type_glade { + ### For translatable Glade XML files ### + + my $tags = "label|title|text|format|copyright|comments|preview_text|tooltip|message"; + + while ($input =~ /<($tags)>([^<]+)<\/($tags)>/sg) { + # Glade sometimes uses tags that normally mark translatable things for + # little bits of non-translatable content. We work around this by not + # translating strings that only includes something like label4 or window1. + $messages{entity_decode($2)} = [] unless $2 =~ /^(window|label)[0-9]+$/; + } + + while ($input =~ /(..[^<]*)<\/items>/sg) { + for my $item (split (/\n/, $1)) { + $messages{entity_decode($item)} = []; + } + } + + ## handle new glade files + while ($input =~ /<(property|atkproperty)\s+[^>]*translatable\s*=\s*"yes"[^>]*>([^<]+)<\/\1>/sg) { + $messages{entity_decode($2)} = [] unless $2 =~ /^(window|label)[0-9]+$/; + } + while ($input =~ /]*)"\s+description="([^>]+)"\/>/sg) { + $messages{entity_decode_minimal($2)} = []; + } +} + +sub type_scheme { + while ($input =~ /_\w*\(?"((?:[^"\\]+|\\.)*)"\)?/sg) { + $messages{$1} = []; + } +} + +sub msg_write { + for my $message (sort keys %messages) { + print OUT "/* xgettext:no-c-format */\n" if $message =~ /%/; + + my @lines = split (/\n/, $message, -1); + for (my $n = 0; $n < @lines; $n++) { + if ($n == 0) { + print OUT "char *s = N_(\""; + } else { + print OUT " \""; + } + + print OUT escape($lines[$n]); + + if ($n < @lines - 1) { + print OUT "\\n\"\n"; + } else { + print OUT "\");\n"; + } + } + } +} + diff --git a/intltool-merge.in b/intltool-merge.in new file mode 100644 index 0000000..1dc40d5 --- /dev/null +++ b/intltool-merge.in @@ -0,0 +1,933 @@ +#!@INTLTOOL_PERL@ -w + +# +# The Intltool Message Merger +# +# Copyright (C) 2000, 2003 Free Software Foundation. +# Copyright (C) 2000, 2001 Eazel, Inc +# +# Intltool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# version 2 published by the Free Software Foundation. +# +# Intltool is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. +# +# Authors: Maciej Stachowiak +# Kenneth Christiansen +# Darin Adler +# +# Proper XML UTF-8'ification written by Cyrille Chepelov +# + +## Release information +my $PROGRAM = "intltool-merge"; +my $PACKAGE = "intltool"; +my $VERSION = "0.26"; + +## Loaded modules +use strict; +use Getopt::Long; +use Text::Wrap; + +## Scalars used by the option stuff +my $HELP_ARG = 0; +my $VERSION_ARG = 0; +my $BA_STYLE_ARG = 0; +my $XML_STYLE_ARG = 0; +my $KEYS_STYLE_ARG = 0; +my $DESKTOP_STYLE_ARG = 0; +my $SCHEMAS_STYLE_ARG = 0; +my $RFC822DEB_STYLE_ARG = 0; +my $QUIET_ARG = 0; +my $PASS_THROUGH_ARG = 0; +my $UTF8_ARG = 0; +my $cache_file; + +## Handle options +GetOptions +( + "help" => \$HELP_ARG, + "version" => \$VERSION_ARG, + "quiet|q" => \$QUIET_ARG, + "oaf-style|o" => \$BA_STYLE_ARG, ## for compatibility + "ba-style|b" => \$BA_STYLE_ARG, + "xml-style|x" => \$XML_STYLE_ARG, + "keys-style|k" => \$KEYS_STYLE_ARG, + "desktop-style|d" => \$DESKTOP_STYLE_ARG, + "schemas-style|s" => \$SCHEMAS_STYLE_ARG, + "rfc822deb-style|r" => \$RFC822DEB_STYLE_ARG, + "pass-through|p" => \$PASS_THROUGH_ARG, + "utf8|u" => \$UTF8_ARG, + "cache|c=s" => \$cache_file + ) or &error; + +my $PO_DIR; +my $FILE; +my $OUTFILE; + +my %po_files_by_lang = (); +my %translations = (); +my $iconv = $ENV{"INTLTOOL_ICONV"} || "iconv"; + +# Use this instead of \w for XML files to handle more possible characters. +my $w = "[-A-Za-z0-9._:]"; + +# XML quoted string contents +my $q = "[^\\\"]*"; + +## Check for options. + +if ($VERSION_ARG) +{ + &print_version; +} +elsif ($HELP_ARG) +{ + &print_help; +} +elsif ($BA_STYLE_ARG && @ARGV > 2) +{ + &preparation; + &print_message; + &ba_merge_translations; + &finalize; +} +elsif ($XML_STYLE_ARG && @ARGV > 2) +{ + &utf8_sanity_check; + &preparation; + &print_message; + &xml_merge_translations; + &finalize; +} +elsif ($KEYS_STYLE_ARG && @ARGV > 2) +{ + &utf8_sanity_check; + &preparation; + &print_message; + &keys_merge_translations; + &finalize; +} +elsif ($DESKTOP_STYLE_ARG && @ARGV > 2) +{ + &preparation; + &print_message; + &desktop_merge_translations; + &finalize; +} +elsif ($SCHEMAS_STYLE_ARG && @ARGV > 2) +{ + &preparation; + &print_message; + &schemas_merge_translations; + &finalize; +} +elsif ($RFC822DEB_STYLE_ARG && @ARGV > 2) +{ + &preparation; + &print_message; + &rfc822deb_merge_translations; + &finalize; +} +else +{ + &print_help; +} + +exit; + +## Sub for printing release information +sub print_version +{ + print <<_EOF_; +${PROGRAM} (${PACKAGE}) ${VERSION} +Written by Maciej Stachowiak, Darin Adler and Kenneth Christiansen. + +Copyright (C) 2000-2003 Free Software Foundation, Inc. +Copyright (C) 2000-2001 Eazel, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +_EOF_ + exit; +} + +## Sub for printing usage information +sub print_help +{ + print <<_EOF_; +Usage: ${PROGRAM} [OPTION]... PO_DIRECTORY FILENAME OUTPUT_FILE +Generates an output file that includes some localized attributes from an +untranslated source file. + +Mandatory options: (exactly one must be specified) + -b, --ba-style includes translations in the bonobo-activation style + -d, --desktop-style includes translations in the desktop style + -k, --keys-style includes translations in the keys style + -s, --schemas-style includes translations in the schemas style + -r, --rfc822deb-style includes translations in the RFC822 style + -x, --xml-style includes translations in the standard xml style + +Other options: + -u, --utf8 convert all strings to UTF-8 before merging + -p, --pass-through use strings as found in .po files, without + conversion (STRONGLY unrecommended with -x) + -c, --cache=FILE specify cache file name + (usually \$top_builddir/po/.intltool-merge-cache) + -q, --quiet suppress most messages + --help display this help and exit + --version output version information and exit + +Report bugs to http://bugzilla.gnome.org/ (product name "$PACKAGE") +or send email to . +_EOF_ + exit; +} + + +## Sub for printing error messages +sub print_error +{ + print STDERR "Try `${PROGRAM} --help' for more information.\n"; + exit; +} + + +sub print_message +{ + print "Merging translations into $OUTFILE.\n" unless $QUIET_ARG; +} + + +sub preparation +{ + $PO_DIR = $ARGV[0]; + $FILE = $ARGV[1]; + $OUTFILE = $ARGV[2]; + + &gather_po_files; + &get_translation_database; +} + +# General-purpose code for looking up translations in .po files + +sub po_file2lang +{ + my ($tmp) = @_; + $tmp =~ s/^.*\/(.*)\.po$/$1/; + return $tmp; +} + +sub gather_po_files +{ + for my $po_file (glob "$PO_DIR/*.po") { + $po_files_by_lang{po_file2lang($po_file)} = $po_file; + } +} + +sub get_local_charset +{ + my ($encoding) = @_; + my $alias_file = $ENV{"G_CHARSET_ALIAS"} || "/gnome/head/INSTALL/lib/charset.alias"; + + # seek character encoding aliases in charset.alias (glib) + + if (open CHARSET_ALIAS, $alias_file) + { + while () + { + next if /^\#/; + return $1 if (/^\s*([-._a-zA-Z0-9]+)\s+$encoding\b/i) + } + + close CHARSET_ALIAS; + } + + # if not found, return input string + + return $encoding; +} + +sub get_po_encoding +{ + my ($in_po_file) = @_; + my $encoding = ""; + + open IN_PO_FILE, $in_po_file or die; + while () + { + ## example: "Content-Type: text/plain; charset=ISO-8859-1\n" + if (/Content-Type\:.*charset=([-a-zA-Z0-9]+)\\n/) + { + $encoding = $1; + last; + } + } + close IN_PO_FILE; + + if (!$encoding) + { + print STDERR "Warning: no encoding found in $in_po_file. Assuming ISO-8859-1\n" unless $QUIET_ARG; + $encoding = "ISO-8859-1"; + } + + system ("$iconv -f $encoding -t UTF-8 /dev/null"); + if ($?) { + $encoding = get_local_charset($encoding); + } + + return $encoding +} + +sub utf8_sanity_check +{ + if (!$UTF8_ARG) + { + if (!$PASS_THROUGH_ARG) + { + $PASS_THROUGH_ARG="1"; + } + } +} + +sub get_translation_database +{ + if ($cache_file) { + &get_cached_translation_database; + } else { + &create_translation_database; + } +} + +sub get_newest_po_age +{ + my $newest_age; + + foreach my $file (values %po_files_by_lang) + { + my $file_age = -M $file; + $newest_age = $file_age if !$newest_age || $file_age < $newest_age; + } + + $newest_age = 0 if !$newest_age; + + return $newest_age; +} + +sub create_cache +{ + print "Generating and caching the translation database\n" unless $QUIET_ARG; + + &create_translation_database; + + open CACHE, ">$cache_file" || die; + print CACHE join "\x01", %translations; + close CACHE; +} + +sub load_cache +{ + print "Found cached translation database\n" unless $QUIET_ARG; + + my $contents; + open CACHE, "<$cache_file" || die; + { + local $/; + $contents = ; + } + close CACHE; + %translations = split "\x01", $contents; +} + +sub get_cached_translation_database +{ + my $cache_file_age = -M $cache_file; + if (defined $cache_file_age) + { + if ($cache_file_age <= &get_newest_po_age) + { + &load_cache; + return; + } + print "Found too-old cached translation database\n" unless $QUIET_ARG; + } + + &create_cache; +} + +sub create_translation_database +{ + for my $lang (keys %po_files_by_lang) + { + my $po_file = $po_files_by_lang{$lang}; + + if ($UTF8_ARG) + { + my $encoding = get_po_encoding ($po_file); + + if (lc $encoding eq "utf-8") + { + open PO_FILE, "<$po_file"; + } + else + { + print STDERR "WARNING: $po_file is not in UTF-8 but $encoding, converting...\n" unless $QUIET_ARG;; + + open PO_FILE, "$iconv -f $encoding -t UTF-8 $po_file|"; + } + } + else + { + open PO_FILE, "<$po_file"; + } + + my $nextfuzzy = 0; + my $inmsgid = 0; + my $inmsgstr = 0; + my $msgid = ""; + my $msgstr = ""; + + while () + { + $nextfuzzy = 1 if /^#, fuzzy/; + + if (/^msgid "((\\.|[^\\])*)"/ ) + { + $translations{$lang, $msgid} = $msgstr if $inmsgstr && $msgid && $msgstr; + $msgid = ""; + $msgstr = ""; + + if ($nextfuzzy) { + $inmsgid = 0; + } else { + $msgid = unescape_po_string($1); + $inmsgid = 1; + } + $inmsgstr = 0; + $nextfuzzy = 0; + } + + if (/^msgstr "((\\.|[^\\])*)"/) + { + $msgstr = unescape_po_string($1); + $inmsgstr = 1; + $inmsgid = 0; + } + + if (/^"((\\.|[^\\])*)"/) + { + $msgid .= unescape_po_string($1) if $inmsgid; + $msgstr .= unescape_po_string($1) if $inmsgstr; + } + } + $translations{$lang, $msgid} = $msgstr if $inmsgstr && $msgid && $msgstr; + } +} + +sub finalize +{ +} + +sub unescape_one_sequence +{ + my ($sequence) = @_; + + return "\\" if $sequence eq "\\\\"; + return "\"" if $sequence eq "\\\""; + return "\n" if $sequence eq "\\n"; + + # gettext also handles \n, \t, \b, \r, \f, \v, \a, \xxx (octal), + # \xXX (hex) and has a comment saying they want to handle \u and \U. + + return $sequence; +} + +sub unescape_po_string +{ + my ($string) = @_; + + $string =~ s/(\\.)/unescape_one_sequence($1)/eg; + + return $string; +} + +## NOTE: deal with < - < but not > - > because it seems its ok to have +## > in the entity. For further info please look at #84738. +sub entity_decode +{ + local ($_) = @_; + + s/'/'/g; # ' + s/"/"/g; # " + s/&/&/g; + s/</ 127 || $_ == 34 || $_ == 38 || $_ == 39 || $_ == 60) + { + # the ($_ > 127) should probably be removed + return "&#" . $_ . ";"; + } + else + { + return chr $_; + } +} + +sub entity_encoded_translation +{ + my ($lang, $string) = @_; + + my $translation = $translations{$lang, $string}; + return $string if !$translation; + return entity_encode ($translation); +} + +## XML (bonobo-activation specific) merge code + +sub ba_merge_translations +{ + my $source; + + { + local $/; # slurp mode + open INPUT, "<$FILE" or die "can't open $FILE: $!"; + $source = ; + close INPUT; + } + + open OUTPUT, ">$OUTFILE" or die "can't open $OUTFILE: $!"; + + while ($source =~ s|^(.*?)([ \t]*<\s*$w+\s+($w+\s*=\s*"$q"\s*)+/?>)([ \t]*\n)?||s) + { + print OUTPUT $1; + + my $node = $2 . "\n"; + + my @strings = (); + $_ = $node; + while (s/(\s)_($w+\s*=\s*"($q)")/$1$2/s) { + push @strings, entity_decode($3); + } + print OUTPUT; + + my %langs; + for my $string (@strings) + { + for my $lang (keys %po_files_by_lang) + { + $langs{$lang} = 1 if $translations{$lang, $string}; + } + } + + for my $lang (sort keys %langs) + { + $_ = $node; + s/(\sname\s*=\s*)"($q)"/$1"$2-$lang"/s; + s/(\s)_($w+\s*=\s*")($q)"/$1 . $2 . entity_encoded_translation($lang, $3) . '"'/seg; + print OUTPUT; + } + } + + print OUTPUT $source; + + close OUTPUT; +} + + +## XML (non-bonobo-activation) merge code + +sub xml_merge_translations +{ + my $source; + + { + local $/; # slurp mode + open INPUT, "<$FILE" or die "can't open $FILE: $!"; + $source = ; + close INPUT; + } + + open OUTPUT, ">$OUTFILE" or die; + + # FIXME: support attribute translations + + # Empty nodes never need translation, so unmark all of them. + # For example, <_foo/> is just replaced by . + $source =~ s|<\s*_($w+)\s*/>|<$1/>|g; + + # Support for <_foo>blah style translations. + while ($source =~ s|^(.*?)([ \t]*)<\s*_($w+)\s*>(.*?)<\s*/_\3\s*>([ \t]*\n)?||s) + { + print OUTPUT $1; + + my $spaces = $2; + my $tag = $3; + my $string = $4; + + print OUTPUT "$spaces<$tag>$string\n"; + + $string =~ s/\s+/ /g; + $string =~ s/^ //; + $string =~ s/ $//; + $string = entity_decode($string); + + for my $lang (sort keys %po_files_by_lang) + { + my $translation = $translations{$lang, $string}; + next if !$translation; + $translation = entity_encode($translation); + print OUTPUT "$spaces<$tag xml:lang=\"$lang\">$translation\n"; + } + } + + print OUTPUT $source; + + close OUTPUT; +} + +sub keys_merge_translations +{ + open INPUT, "<${FILE}" or die; + open OUTPUT, ">${OUTFILE}" or die; + + while () + { + if (s/^(\s*)_(\w+=(.*))/$1$2/) + { + my $string = $3; + + print OUTPUT; + + my $non_translated_line = $_; + + for my $lang (sort keys %po_files_by_lang) + { + my $translation = $translations{$lang, $string}; + next if !$translation; + + $_ = $non_translated_line; + s/(\w+)=.*/[$lang]$1=$translation/; + print OUTPUT; + } + } + else + { + print OUTPUT; + } + } + + close OUTPUT; + close INPUT; +} + +sub desktop_merge_translations +{ + open INPUT, "<${FILE}" or die; + open OUTPUT, ">${OUTFILE}" or die; + + while () + { + if (s/^(\s*)_(\w+=(.*))/$1$2/) + { + my $string = $3; + + print OUTPUT; + + my $non_translated_line = $_; + + for my $lang (sort keys %po_files_by_lang) + { + my $translation = $translations{$lang, $string}; + next if !$translation; + + $_ = $non_translated_line; + s/(\w+)=.*/${1}[$lang]=$translation/; + print OUTPUT; + } + } + else + { + print OUTPUT; + } + } + + close OUTPUT; + close INPUT; +} + +sub schemas_merge_translations +{ + my $source; + + { + local $/; # slurp mode + open INPUT, "<$FILE" or die "can't open $FILE: $!"; + $source = ; + close INPUT; + } + + open OUTPUT, ">$OUTFILE" or die; + + # FIXME: support attribute translations + + # Empty nodes never need translation, so unmark all of them. + # For example, <_foo/> is just replaced by . + $source =~ s|<\s*_($w+)\s*/>|<$1/>|g; + + while ($source =~ s/ + (.*?) + (\s+)((\s*) + (\s*(.*?)\s*<\/default>)?(\s*) + (\s*(.*?)\s*<\/short>)?(\s*) + (\s*(.*?)\s*<\/long>)?(\s*) + <\/locale>) + //sx) + { + print OUTPUT $1; + + my $locale_start_spaces = $2 ? $2 : ''; + my $default_spaces = $4 ? $4 : ''; + my $short_spaces = $7 ? $7 : ''; + my $long_spaces = $10 ? $10 : ''; + my $locale_end_spaces = $13 ? $13 : ''; + my $c_default_block = $3 ? $3 : ''; + my $default_string = $6 ? $6 : ''; + my $short_string = $9 ? $9 : ''; + my $long_string = $12 ? $12 : ''; + + $c_default_block =~ s/default>\[.*?\]/default>/s; + + print OUTPUT "$locale_start_spaces$c_default_block"; + + $default_string =~ s/\s+/ /g; + $default_string = entity_decode($default_string); + $short_string =~ s/\s+/ /g; + $short_string = entity_decode($short_string); + $long_string =~ s/\s+/ /g; + $long_string = entity_decode($long_string); + + for my $lang (sort keys %po_files_by_lang) + { + my $default_translation = $translations{$lang, $default_string}; + my $short_translation = $translations{$lang, $short_string}; + my $long_translation = $translations{$lang, $long_string}; + + next if (!$default_translation && !$short_translation && + !$long_translation); + + print OUTPUT "\n$locale_start_spaces"; + + print OUTPUT "$default_spaces"; + + if ($default_translation) + { + $default_translation = entity_encode($default_translation); + print OUTPUT "$default_translation"; + } + + print OUTPUT "$short_spaces"; + + if ($short_translation) + { + $short_translation = entity_encode($short_translation); + print OUTPUT "$short_translation"; + } + + print OUTPUT "$long_spaces"; + + if ($long_translation) + { + $long_translation = entity_encode($long_translation); + print OUTPUT "$long_translation"; + } + + print OUTPUT "$locale_end_spaces"; + } + } + + print OUTPUT $source; + + close OUTPUT; +} + +sub rfc822deb_merge_translations +{ + my $source; + + $Text::Wrap::huge = 'overflow'; + + { + local $/; # slurp mode + open INPUT, "<$FILE" or die "can't open $FILE: $!"; + $source = ; + close INPUT; + } + + open OUTPUT, ">${OUTFILE}" or die; + + while ($source =~ /(^|\n+)(_)?([^:_\n]+)(:\s*)(.*?)(?=\n[\S\n]|$)/sg) + { + my $sep = $1; + my $non_translated_line = $3.$4; + my $string = $5; + my $is_translatable = defined($2); + # Remove [] dummy strings + $string =~ s/\[\s[^\[\]]*\]$//; + $non_translated_line .= $string; + + print OUTPUT $sep.$non_translated_line; + + if ($is_translatable) + { + my @str_list = rfc822deb_split($string); + + for my $lang (sort keys %po_files_by_lang) + { + my $is_translated = 1; + my $str_translated = ''; + my $first = 1; + + for my $str (@str_list) + { + my $translation = $translations{$lang, $str}; + + if (!$translation) + { + $is_translated = 0; + last; + } + + # $translation may also contain [] dummy + # strings, mostly to indicate an empty string + $translation =~ s/\[\s[^\[\]]*\]$//; + + if ($first) + { + $str_translated .= + Text::Tabs::expand($translation) . + "\n"; + } + else + { + $str_translated .= Text::Tabs::expand( + Text::Wrap::wrap(' ', ' ', $translation)) . + "\n .\n"; + } + $first = 0; + + # To fix some problems with Text::Wrap::wrap + $str_translated =~ s/(\n )+\n/\n .\n/g; + } + next unless $is_translated; + + $str_translated =~ s/\n \.\n$//; + $str_translated =~ s/\s+$//; + + $_ = $non_translated_line; + s/^(\w+):\s*.*/$sep${1}-$lang: $str_translated/s; + print OUTPUT; + } + } + } + print OUTPUT "\n"; + + close OUTPUT; + close INPUT; +} + +sub rfc822deb_split +{ + # Debian defines a special way to deal with rfc822-style files: + # when a value contain newlines, it consists of + # 1. a short form (first line) + # 2. a long description, all lines begin with a space, + # and paragraphs are separated by a single dot on a line + # This routine returns an array of all paragraphs, and reformat + # them. + my $text = shift; + $text =~ s/^ //mg; + return ($text) if $text !~ /\n/; + + $text =~ s/([^\n]*)\n//; + my @list = ($1); + my $str = ''; + + for my $line (split (/\n/, $text)) + { + chomp $line; + $line =~ /\s+$/; + + if ($line =~ /^\.$/) + { + # New paragraph + $str =~ s/\s*$//; + push(@list, $str); + $str = ''; + } + elsif ($line =~ /^\s/) + { + # Line which must not be reformatted + $str .= "\n" if length ($str) && $str !~ /\n$/; + $str .= $line."\n"; + } + else + { + # Continuation line, remove newline + $str .= " " if length ($str) && $str !~ /[\n ]$/; + $str .= $line; + } + } + + $str =~ s/\s*$//; + push(@list, $str) if length ($str); + + return @list; +} + diff --git a/intltool-update.in b/intltool-update.in new file mode 100644 index 0000000..c23984f --- /dev/null +++ b/intltool-update.in @@ -0,0 +1,792 @@ +#!@INTLTOOL_PERL@ -w + +# +# The Intltool Message Updater +# +# Copyright (C) 2000-2002 Free Software Foundation. +# +# Intltool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# version 2 published by the Free Software Foundation. +# +# Intltool is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. +# +# Authors: Kenneth Christiansen +# Maciej Stachowiak +# Darin Adler + +## Release information +my $PROGRAM = "intltool-update"; +my $VERSION = "0.26"; +my $PACKAGE = "intltool"; + +## Loaded modules +use strict; +use Getopt::Long; +use Cwd; +use File::Copy; +use File::Find; + +## Scalars used by the option stuff +my $HELP_ARG = 0; +my $VERSION_ARG = 0; +my $DIST_ARG = 0; +my $POT_ARG = 0; +my $HEADERS_ARG = 0; +my $MAINTAIN_ARG = 0; +my $REPORT_ARG = 0; +my $VERBOSE = 0; +my $GETTEXT_PACKAGE = ""; +my $OUTPUT_FILE = ""; + +my @languages; +my $conf_file; # remove later +my %varhash = (); +my %po_files_by_lang = (); + +# Regular expressions to categorize file types. +# FIXME: Please check if the following is correct + +my $xml_extension = +"xml(\.in)*|". # .in is not required +"ui|". +"lang|". +"glade2?(\.in)*|". # .in is not required +"scm(\.in)*|". # .in is not required +"oaf(\.in)+|". +"etspec|". +"sheet(\.in)+|". +"schemas(\.in)+|". +"pong(\.in)+"; + +my $ini_extension = +"desktop(\.in)+|". +"caves(\.in)+|". +"directory(\.in)+|". +"soundlist(\.in)+|". +"keys(\.in)+|". +"theme(\.in)+|". +"server(\.in)+"; + +## Always print as the first thing +$| = 1; + +## Handle options +GetOptions +( + "help" => \$HELP_ARG, + "version" => \$VERSION_ARG, + "dist|d" => \$DIST_ARG, + "pot|p" => \$POT_ARG, + "headers|s" => \$HEADERS_ARG, + "maintain|m" => \$MAINTAIN_ARG, + "report|r" => \$REPORT_ARG, + "verbose|x" => \$VERBOSE, + "gettext-package|g=s" => \$GETTEXT_PACKAGE, + "output-file|o=s" => \$OUTPUT_FILE, + ) or &print_error_invalid_option; + +&print_help if $HELP_ARG; +&print_version if $VERSION_ARG; + +my $arg_count = ($DIST_ARG > 0) + + ($POT_ARG > 0) + + ($HEADERS_ARG > 0) + + ($MAINTAIN_ARG > 0) + + ($REPORT_ARG > 0); + +&print_help if $arg_count > 1; + +# --version and --help don't require a module name +my $MODULE = $GETTEXT_PACKAGE || &find_package_name; + +if ($DIST_ARG) +{ + if ($ARGV[0] =~ /^[a-z]/) + { + &update_po_file ($ARGV[0], $OUTPUT_FILE); + &print_status ($ARGV[0], $OUTPUT_FILE); + } + else + { + &print_help; + } +} +elsif ($POT_ARG) +{ + &generate_headers; + &generate_po_template; +} +elsif ($HEADERS_ARG) +{ + &generate_headers; +} +elsif ($MAINTAIN_ARG) +{ + &find_leftout_files; +} +elsif ($REPORT_ARG) +{ + &print_report; +} +else +{ + if ($ARGV[0] =~ /^[a-z]/) + { + &main ($ARGV[0], $OUTPUT_FILE); + } + else + { + &print_help; + } +} + +exit; + +######### + +sub print_version +{ + print <<_EOF_; +${PROGRAM} (${PACKAGE}) $VERSION +Written by Kenneth Christiansen, Maciej Stachowiak, and Darin Adler. + +Copyright (C) 2000-2003 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +_EOF_ + exit; +} + +sub print_help +{ + print <<_EOF_; +Usage: ${PROGRAM} [OPTION]... LANGCODE +Updates PO template files and merge them with the translations. + +Mode of operation (only one is allowed): + -p, --pot generate the PO template only + -s, --headers generate the header files in POTFILES.in + -m, --maintain search for left out files from POTFILES.in + -r, --report display a status report for the module + -d, --dist merge LANGCODE.po with existing PO template + +Extra options: + -g, --gettext-package=NAME override PO template name, useful with --pot + -o, --output-file=FILE write merged translation to FILE + -x, --verbose display lots of feedback + --help display this help and exit + --version output version information and exit + +Examples of use: +${PROGRAM} --pot just create a new PO template +${PROGRAM} xy create new PO template and merge xy.po with it + +Report bugs to http://bugzilla.gnome.org/ (product name "$PACKAGE") +or send email to . +_EOF_ + exit; +} + +sub main +{ + my ($lang, $output_file) = @_; + + ## Report error if the language file supplied + ## to the command line is non-existent + &print_error_not_existing("$lang.po") if ! -s "$lang.po"; + + print "Working, please wait..." if $VERBOSE; + &generate_headers; + &generate_po_template; + &update_po_file ($lang, $output_file); + &print_status ($lang, $output_file); +} + +sub determine_type ($) +{ + my $type = $_; + my $gettext_type; + + # FIXME: Use $xml_extentions, and maybe do all this even nicer + my $xml_regex = + "(?:xml(\.in)*|ui|lang|oaf(?:\.in)+|server(?:\.in)+|sheet(?:\.in)+|". + "pong(?:\.in)+|etspec|schemas(?:\.in)+)"; + my $ini_regex = + "(?:desktop(?:\.in)+|theme(?:\.in)+|caves(?:\.in)+|directory(?:\.in)+|". + "soundlist(?:\.in)+)"; + + if ($type =~ /\[type: gettext\/([^\]].*)]/) + { + $gettext_type=$1; + } + elsif ($type =~ /schemas(\.in)+$/) + { + $gettext_type="schemas"; + } + elsif ($type =~ /$xml_regex$/) + { + $gettext_type="xml"; + } + elsif ($type =~ /glade2?(\.in)*$/) + { + $gettext_type="glade"; + } + elsif ($type =~ /$ini_regex$/) + { + $gettext_type="ini"; + } + elsif ($type =~ /scm(\.in)*$/) + { + $gettext_type="scheme"; + } + elsif ($type =~ /keys(\.in)+$/) + { + $gettext_type="keys"; + } + else + { + $gettext_type=""; + } + + return "gettext\/$gettext_type"; +} + +sub find_leftout_files +{ + my (@buf_i18n_plain, + @buf_i18n_xml, + @buf_i18n_xml_unmarked, + @buf_i18n_ini, + @buf_potfiles, + @buf_potfiles_ignore, + @buf_allfiles, + @buf_allfiles_sorted, + @buf_potfiles_sorted + ); + + ## Search and find all translatable files + find sub { + push @buf_i18n_plain, "$File::Find::name" if /\.(c|y|cc|cpp|c\+\+|h|gob)$/ + }, ".."; + find sub { + push @buf_i18n_xml, "$File::Find::name" if /\.($xml_extension)$/ + }, ".."; + find sub { + push @buf_i18n_ini, "$File::Find::name" if /\.($ini_extension)$/ + }, ".."; + find sub { + push @buf_i18n_xml_unmarked, "$File::Find::name" if /\.(schemas(\.in)+)$/ + }, ".."; + + + open POTFILES, "POTFILES.in" or die "$PROGRAM: there's no POTFILES.in!\n"; + + @buf_potfiles = grep /^[^#]/, ; + foreach (@buf_potfiles) { + s/^\[.*]\s*//; + } + + print "Searching for missing translatable files...\n" if $VERBOSE; + + ## Check if we should ignore some found files, when + ## comparing with POTFILES.in + foreach my $ignore ("POTFILES.skip", "POTFILES.ignore") + { + if (-s $ignore) + { + open FILE, $ignore; + + while () + { + if (/^[^#]/) + { + push @buf_potfiles_ignore, $_; + } + } + print "Found $ignore: Ignoring files...\n" if $VERBOSE; + @buf_potfiles = (@buf_potfiles_ignore, @buf_potfiles); + } + } + + foreach my $file (@buf_i18n_plain) + { + my $in_comment = 0; + my $in_macro = 0; + + open FILE, "<$file"; + while () + { + # Handle continued multi-line comment. + if ($in_comment) + { + next unless s-.*\*/--; + $in_comment = 0; + } + + # Handle continued macro. + if ($in_macro) + { + $in_macro = 0 unless /\\$/; + next; + } + + # Handle start of macro (or any preprocessor directive). + if (/^\s*\#/) + { + $in_macro = 1 if /^([^\\]|\\.)*\\$/; + next; + } + + # Handle comments and quoted text. + while (m-(/\*|//|\'|\")-) # \' and \" keep emacs perl mode happy + { + my $match = $1; + if ($match eq "/*") + { + if (!s-/\*.*?\*/--) + { + s-/\*.*--; + $in_comment = 1; + } + } + elsif ($match eq "//") + { + s-//.*--; + } + else # ' or " + { + if (!s-$match([^\\]|\\.)*?$match-QUOTEDTEXT-) + { + warn "mismatched quotes at line $. in $file\n"; + s-$match.*--; + } + } + } + + if (/_\(QUOTEDTEXT/) + { + ## Remove the first 3 chars and add newline + push @buf_allfiles, unpack("x3 A*", $file) . "\n"; + last; + } + } + close FILE; + } + + foreach my $file (@buf_i18n_xml) + { + open FILE, "<$file"; + + while () + { + if (/\s_(.*)=\"/ || /translatable=\"yes\"/) + { + push @buf_allfiles, unpack("x3 A*", $file) . "\n"; + last; + } + } + } + + foreach my $file (@buf_i18n_ini) + { + open FILE, "<$file"; + while () + { + if (/_(.*)=/) + { + push @buf_allfiles, unpack("x3 A*", $file) . "\n"; + last; + } + } + } + + foreach my $file (@buf_i18n_xml_unmarked) + { + push @buf_allfiles, unpack("x3 A*", $file) . "\n"; + } + + + @buf_allfiles_sorted = sort (@buf_allfiles); + @buf_potfiles_sorted = sort (@buf_potfiles); + + my %in2; + foreach (@buf_potfiles_sorted) + { + $in2{$_} = 1; + } + + my @result; + + foreach (@buf_allfiles_sorted) + { + if (!exists($in2{$_})) + { + push @result, $_ + } + } + + ## Save file with information about the files missing + ## if any, and give information about this procedure. + if (@result) + { + print "\n" if $VERBOSE; + open OUT, ">missing"; + print OUT @result; + print STDERR "The following files contain translations and are currently not in use. Please\n"; + print STDERR "consider adding these to the POTFILES.in file, located in the po/ directory.\n\n"; + print STDERR @result, "\n"; + print STDERR "If some of these files are left out on purpose then please add them to\n"; + print STDERR "POTFILES.skip instead of POTFILES.in. A file 'missing' containing this list\n"; + print STDERR "of left out files has been written in the current directory.\n"; + } + + ## If there is nothing to complain about, notify the user + else { + print "\nAll files containing translations are present in POTFILES.in.\n" if $VERBOSE; + } +} + +sub print_error_invalid_option +{ + ## Handle invalid arguments + print STDERR "Try `${PROGRAM} --help' for more information.\n"; + exit 1; +} + +sub generate_headers +{ + my $EXTRACT = `which intltool-extract 2>/dev/null`; + chomp $EXTRACT; + + $EXTRACT = $ENV{"INTLTOOL_EXTRACT"} if $ENV{"INTLTOOL_EXTRACT"}; + + ## Generate the .h header files, so we can allow glade and + ## xml translation support + if (! -s $EXTRACT) + { + print STDERR "\n *** The intltool-extract script wasn't found!" + ."\n *** Without it, intltool-update can not generate files.\n"; + exit; + } + else + { + open (FILE, ") + { + chomp; + + ## Find xml files in POTFILES.in and generate the + ## files with help from the extract script + + my $gettext_type= &determine_type ($1); + + if (/\.($xml_extension|$ini_extension)$/ || /^\[/) + { + s/^\[[^\[].*]\s*//; + + my $filename = "../$_"; + + if ($VERBOSE) + { + system ($EXTRACT, "--update", + "--type=$gettext_type", $filename); + } + else + { + system ($EXTRACT, "--update", "--type=$gettext_type", + "--quiet", $filename); + } + } + } + close FILE; + } +} + +sub generate_po_template +{ + ## Generate the potfiles from the POTFILES.in file + + print "Building the $MODULE.pot...\n" if $VERBOSE; + + move ("POTFILES.in", "POTFILES.in.old"); + + open INFILE, "POTFILES.in"; + + while () + { + chomp; + if (/\.($xml_extension|$ini_extension)$/ || /^\[/) + { + s/^\[.*]\s*//; + print OUTFILE "$_.h\n"; + } + else + { + print OUTFILE "$_\n"; + } + } + + close OUTFILE; + close INFILE; + + system ("xgettext", "--default-domain\=$MODULE", + "--directory\=\.\.", + "--add-comments", + "--keyword\=\_", + "--keyword\=N\_", + "--keyword\=U\_", + "--files-from\=\.\/POTFILES\.in"); + + move ("POTFILES.in.old", "POTFILES.in"); + + print "Removing generated header (.h) files..." if $VERBOSE; + + open FILE, ") + { + chomp; + unlink "../$_.h" if /\.($xml_extension|$ini_extension)$/; + } + + close FILE; + print "done\n" if $VERBOSE; + + if (!-e "$MODULE.po") + { + print STDERR "WARNING: Either none of the files in POTFILES.in contain marked strings,\n". + " or xgettext failed to generate PO template file. Please consult\n". + " error message above if there is any.\n"; + exit (1); + } + + system ("rm", "-f", "$MODULE.pot"); + move ("$MODULE.po", "$MODULE.pot") or + die "$PROGRAM: couldn't move $MODULE.po to $MODULE.pot.\n"; + + print "Wrote $MODULE.pot\n" if $VERBOSE; +} + +sub update_po_file +{ + -f "$MODULE.pot" or die "$PROGRAM: $MODULE.pot does not exist.\n"; + + my ($lang, $output_file) = @_; + my ($infile, $outfile); + + print "Merging $lang.po with $MODULE.pot..." if $VERBOSE; + + if ($output_file ne "") + { + $infile = "$lang.po"; + $outfile = $output_file; + } + else + { + copy ("$lang.po", "$lang.po.old") || die "copy failed: $!"; + $infile = "$lang.po.old"; + $outfile = "$lang.po"; + } + + # Perform merge, remove backup file and the "messages" trash file + # generated by gettext + system ("msgmerge", "-o", $outfile, $infile, "$MODULE.pot"); + + if ($output_file eq "") + { + unlink $infile; + } + unlink "messages"; +} + +sub print_error_not_existing +{ + my ($file) = @_; + + ## Report error if supplied language file is non-existing + print STDERR "$PROGRAM: $file does not exist!\n"; + print STDERR "Try '$PROGRAM --help' for more information.\n"; + exit; +} + +sub gather_po_files +{ + my @po_files = glob ("./*.po"); + + @languages = map (&po_file2lang, @po_files); + + foreach my $lang (@languages) + { + $po_files_by_lang{$lang} = shift (@po_files); + } +} + +sub po_file2lang ($) +{ + my $tmp = $_; + $tmp =~ s/^.*\/(.*)\.po$/$1/; + return $tmp; +} + +sub print_status +{ + my ($lang, $output_file) = @_; + + if ($output_file eq "") + { + $output_file = "$lang.po"; + } + + system ("msgfmt", "-o", "/dev/null", "--statistics", $output_file); + print "\n"; +} + +sub print_report +{ + &generate_headers; + &generate_po_template; + &gather_po_files; + + foreach my $lang (@languages) + { + print "$lang: "; + &update_po_file ($lang, ""); + } + + print "\n\n * Current translation support in $MODULE \n\n"; + + foreach my $lang (@languages) + { + print "$lang: "; + system ("msgfmt", "-o", "/dev/null", "--statistics", "$lang.po"); + } +} + +sub substitute_var +{ + my ($str) = @_; + + # cache each variable. varhash is global to we can add + # variables elsewhere. + while () + { + if (/^(\w+)=(\S+)/) + { + $varhash{$1} = $2; + } + } + + if ($str =~ /^(.*)\${?([A-Z]+)}?(.*)$/) + { + my $rest = $3; + my $untouched = $1; + my $sub = $varhash{$2}; + + return substitute_var ("$untouched$sub$rest"); + } + return $str; +} + +sub open_CONF_handle +{ + my $base_dirname = getcwd(); + $base_dirname =~ s@.*/@@; + + my ($conf_in, $src_dir); + + if ($base_dirname =~ /^po(-.+)?$/) + { + if (-f "../configure.in") + { + $conf_in = "../configure.in"; + } + elsif (-f "../configure.ac") + { + $conf_in = "../configure.ac"; + } + else + { + my $makefile_source; + + local (*IN); + open IN, ") + { + if (/^top_srcdir[ \t]*=/) + { + $src_dir = $_; + $src_dir =~ s/^top_srcdir[ \t]*=[ \t]*([^ \t\n\r]*)/$1/; + + chomp $src_dir; + $conf_in = "$src_dir" . "/configure.in" . "\n"; + + last; + } + } + + $conf_file || die "Cannot find top_srcdir in Makefile."; + } + + $conf_file = $conf_in; + open (CONF, "<$conf_in") || die "can't open $conf_in: $!"; + } + else + { + print STDERR "$PROGRAM: Unable to proceed.\n" . + "Make sure to run this script inside the po directory.\n"; + exit; + } +} + +sub find_package_name +{ + &open_CONF_handle; + + my $conf_source; { + local (*IN); + open (IN, "<$conf_file") || die "can't open $conf_file: $!"; + seek (IN, 0, 0); + local $/; # slurp mode + $conf_source = ; + } + + my $name = "untitled"; + + # /^AM_INIT_AUTOMAKE\([\s\[]*([^,\)\s\]]+)/m + # the \s makes this not work, why? + if ($conf_source =~ /^AM_INIT_AUTOMAKE\([\s\[]*([^,\)\]]+)/m) + { + $name = $1; + } + + if ($conf_source =~ /^AC_INIT\([\s\[]*([^,\)\s\]]+)\]?\s*,/m) + { + $name = $1; + $varhash{"AC_PACKAGE_NAME"} = $1; + } + + # \s makes this not work, why? + $name = $1 if $conf_source =~ /^GETTEXT_PACKAGE=\[?([^\n\]]+)/m; + + $name = "\$AC_PACKAGE_NAME" if "$name" eq "AC_PACKAGE_NAME"; + + $name = substitute_var ($name); + + return $name if $name; +} diff --git a/libgnomevfs/Makefile.am b/libgnomevfs/Makefile.am new file mode 100644 index 0000000..a563938 --- /dev/null +++ b/libgnomevfs/Makefile.am @@ -0,0 +1,180 @@ +NULL = + +INCLUDES = \ + -I$(top_srcdir) \ + -I$(top_builddir) \ + $(LIBGNOMEVFS_CFLAGS) \ + $(VFS_CFLAGS) \ + -D_FILE_OFFSET_BITS=64 \ + -D_BSD_SOURCE \ + -D_GNU_SOURCE \ + -D_LARGEFILE64_SOURCE \ + -D_POSIX_PTHREAD_SEMANTICS \ + -D_REENTRANT \ + -DG_DISABLE_DEPRECATED \ + -DDATADIR=\"$(datadir)\" \ + -DLIBDIR=\"$(libdir)\" \ + -DPREFIX=\"$(prefix)\" \ + -DGNOMEVFS_LOCALEDIR=\"$(prefix)/@DATADIRNAME@/locale\" \ + -DSYSCONFDIR=\"$(sysconfdir)\" \ + -DG_LOG_DOMAIN=\"libgnomevfs\" \ + -I/usr/kerberos/include \ + $(NULL) + +# %.c %.h: %.gob +# $(top_srcdir)/gob/src/gob2 $< +# +# GOB_SRCLIST = \ +# gnome-vfs-metadata.c \ +# gnome-vfs-metadata.h \ +# gnome-vfs-metadata-private.h \ +# $(NULL) +# GOB_FILES = \ +# gnome-vfs-metadata.gob \ +# $(NULL) + +lib_LTLIBRARIES = libgnomevfs-2.la + +libgnomevfs_2_la_LIBADD = \ + $(LIBGNOMEVFS_LIBS) \ + $(NULL) + +libgnomevfs_2_la_LDFLAGS = \ + -version-info $(LIBGNOMEVFS_CURRENT):$(LIBGNOMEVFS_REVISION):$(LIBGNOMEVFS_AGE) \ + -export-symbols-regex "^[^_].*" \ + -no-undefined \ + $(NULL) + +libgnomevfsincludedir = $(includedir)/gnome-vfs-2.0/libgnomevfs + +libgnomevfsmoduleincludedir = $(includedir)/gnome-vfs-module-2.0/libgnomevfs + +# mime-sniff-buffers and cancellabe-ops are used by modules +noinst_HEADERS = \ + gnome-vfs-async-job-map.h \ + gnome-vfs-backend.h \ + gnome-vfs-cancellable-ops.h \ + gnome-vfs-configuration.h \ + gnome-vfs-handle-private.h \ + gnome-vfs-i18n.h \ + gnome-vfs-job-queue.h \ + gnome-vfs-job-slave.h \ + gnome-vfs-job.h \ + gnome-vfs-mime-magic.h \ + gnome-vfs-mime-private.h \ + gnome-vfs-mime-sniff-buffer.h \ + gnome-vfs-mime-sniff-buffer-private.h \ + gnome-vfs-module-callback-private.h \ + gnome-vfs-monitor-private.h \ + gnome-vfs-private-utils.h \ + gnome-vfs-private.h \ + gnome-vfs-process.h \ + gnome-vfs-ssl-private.h \ + gnome-vfs-thread-pool.h \ + $(NULL) + +libgnomevfsmoduleinclude_HEADERS = \ + gnome-vfs-cancellable-ops.h \ + gnome-vfs-inet-connection.h \ + gnome-vfs-method.h \ + gnome-vfs-mime.h \ + gnome-vfs-mime-info.h \ + gnome-vfs-module-callback-module-api.h \ + gnome-vfs-module-shared.h \ + gnome-vfs-module.h \ + gnome-vfs-parse-ls.h \ + gnome-vfs-ssl.h \ + gnome-vfs-transform.h \ + gnome-vfs-socket-buffer.h \ + gnome-vfs-socket.h \ + $(NULL) + + +libgnomevfsinclude_HEADERS = \ + gnome-vfs-application-registry.h \ + gnome-vfs-async-ops.h \ + gnome-vfs-cancellation.h \ + gnome-vfs-context.h \ + gnome-vfs-directory.h \ + gnome-vfs-file-info.h \ + gnome-vfs-file-size.h \ + gnome-vfs-find-directory.h \ + gnome-vfs-handle.h \ + gnome-vfs-init.h \ + gnome-vfs-job-limit.h \ + gnome-vfs-mime-utils.h \ + gnome-vfs-mime-handlers.h \ + gnome-vfs-mime-monitor.h \ + gnome-vfs-module-callback.h \ + gnome-vfs-monitor.h \ + gnome-vfs-ops.h \ + gnome-vfs-result.h \ + gnome-vfs-standard-callbacks.h \ + gnome-vfs-types.h \ + gnome-vfs-uri.h \ + gnome-vfs-utils.h \ + gnome-vfs-xfer.h \ + gnome-vfs.h \ + $(NULL) + +libgnomevfs_2_la_SOURCES = \ + gnome-vfs-application-registry.c \ + gnome-vfs-async-job-map.c \ + gnome-vfs-async-ops.c \ + gnome-vfs-cancellable-ops.c \ + gnome-vfs-cancellation.c \ + gnome-vfs-configuration.c \ + gnome-vfs-context.c \ + gnome-vfs-directory.c \ + gnome-vfs-open-fd.c \ + gnome-vfs-file-info.c \ + gnome-vfs-find-directory.c \ + gnome-vfs-handle.c \ + gnome-vfs-i18n.c \ + gnome-vfs-inet-connection.c \ + gnome-vfs-init.c \ + gnome-vfs-job-queue.c \ + gnome-vfs-job-slave.c \ + gnome-vfs-job.c \ + gnome-vfs-method.c \ + gnome-vfs-mime-handlers.c \ + gnome-vfs-mime-info.c \ + gnome-vfs-mime-magic.c \ + gnome-vfs-mime-monitor.c \ + gnome-vfs-mime-sniff-buffer.c \ + gnome-vfs-mime.c \ + gnome-vfs-module-callback-module-api.c \ + gnome-vfs-module-callback-private.c \ + gnome-vfs-module-callback.c \ + gnome-vfs-module-shared.c \ + gnome-vfs-module.c \ + gnome-vfs-monitor.c \ + gnome-vfs-ops.c \ + gnome-vfs-parse-ls.c \ + gnome-vfs-private-utils.c \ + gnome-vfs-private.c \ + gnome-vfs-process.c \ + gnome-vfs-result.c \ + gnome-vfs-socket-buffer.c \ + gnome-vfs-socket.c \ + gnome-vfs-ssl.c \ + gnome-vfs-thread-pool.c \ + gnome-vfs-transform.c \ + gnome-vfs-uri.c \ + gnome-vfs-utils.c \ + gnome-vfs-xfer.c \ + $(NULL) + +# $(GOB_SRCLIST) \ +# $(GOB_FILES) \ +# BUILT_SOURCES = $(GOB_SRCLIST) +# CLEANFILES = $(BUILT_SOURCES) + +# Platform specific includes +libgnomevfsplatformincludedir = $(libdir)/gnome-vfs-2.0/include +libgnomevfsplatforminclude_HEADERS = \ + gnome-vfs-file-size.h + +# TESTS = check-headers.pl +EXTRA_DIST = check-headers.pl + diff --git a/libgnomevfs/Makefile.am.vfolder-hacks b/libgnomevfs/Makefile.am.vfolder-hacks new file mode 100644 index 0000000..bea4fc0 --- /dev/null +++ b/libgnomevfs/Makefile.am.vfolder-hacks @@ -0,0 +1,179 @@ +NULL = + +INCLUDES = \ + -I$(top_srcdir) \ + -I$(top_builddir) \ + $(LIBGNOMEVFS_CFLAGS) \ + $(VFS_CFLAGS) \ + -D_FILE_OFFSET_BITS=64 \ + -D_BSD_SOURCE \ + -D_GNU_SOURCE \ + -D_LARGEFILE64_SOURCE \ + -D_POSIX_PTHREAD_SEMANTICS \ + -D_REENTRANT \ + -DG_DISABLE_DEPRECATED \ + -DDATADIR=\"$(datadir)\" \ + -DLIBDIR=\"$(libdir)\" \ + -DPREFIX=\"$(prefix)\" \ + -DGNOMEVFS_LOCALEDIR=\"$(prefix)/@DATADIRNAME@/locale\" \ + -DSYSCONFDIR=\"$(sysconfdir)\" \ + -DG_LOG_DOMAIN=\"libgnomevfs\" \ + $(NULL) + +# %.c %.h: %.gob +# $(top_srcdir)/gob/src/gob2 $< +# +# GOB_SRCLIST = \ +# gnome-vfs-metadata.c \ +# gnome-vfs-metadata.h \ +# gnome-vfs-metadata-private.h \ +# $(NULL) +# GOB_FILES = \ +# gnome-vfs-metadata.gob \ +# $(NULL) + +lib_LTLIBRARIES = libgnomevfs-2.la + +libgnomevfs_2_la_LIBADD = \ + $(LIBGNOMEVFS_LIBS) \ + $(NULL) + +libgnomevfs_2_la_LDFLAGS = \ + -version-info $(LIBGNOMEVFS_CURRENT):$(LIBGNOMEVFS_REVISION):$(LIBGNOMEVFS_AGE) \ + -export-symbols-regex "^[^_].*" \ + -no-undefined \ + $(NULL) + +libgnomevfsincludedir = $(includedir)/gnome-vfs-2.0/libgnomevfs + +libgnomevfsmoduleincludedir = $(includedir)/gnome-vfs-module-2.0/libgnomevfs + +# mime-sniff-buffers and cancellabe-ops are used by modules +noinst_HEADERS = \ + gnome-vfs-async-job-map.h \ + gnome-vfs-backend.h \ + gnome-vfs-cancellable-ops.h \ + gnome-vfs-configuration.h \ + gnome-vfs-handle-private.h \ + gnome-vfs-i18n.h \ + gnome-vfs-job-queue.h \ + gnome-vfs-job-slave.h \ + gnome-vfs-job.h \ + gnome-vfs-mime-magic.h \ + gnome-vfs-mime-private.h \ + gnome-vfs-mime-sniff-buffer.h \ + gnome-vfs-mime-sniff-buffer-private.h \ + gnome-vfs-module-callback-private.h \ + gnome-vfs-monitor-private.h \ + gnome-vfs-private-utils.h \ + gnome-vfs-private.h \ + gnome-vfs-process.h \ + gnome-vfs-ssl-private.h \ + gnome-vfs-thread-pool.h \ + $(NULL) + +libgnomevfsmoduleinclude_HEADERS = \ + gnome-vfs-cancellable-ops.h \ + gnome-vfs-inet-connection.h \ + gnome-vfs-method.h \ + gnome-vfs-mime.h \ + gnome-vfs-mime-info.h \ + gnome-vfs-module-callback-module-api.h \ + gnome-vfs-module-shared.h \ + gnome-vfs-module.h \ + gnome-vfs-parse-ls.h \ + gnome-vfs-ssl.h \ + gnome-vfs-transform.h \ + gnome-vfs-socket-buffer.h \ + gnome-vfs-socket.h \ + $(NULL) + + +libgnomevfsinclude_HEADERS = \ + gnome-vfs-application-registry.h \ + gnome-vfs-async-ops.h \ + gnome-vfs-cancellation.h \ + gnome-vfs-context.h \ + gnome-vfs-directory.h \ + gnome-vfs-file-info.h \ + gnome-vfs-file-size.h \ + gnome-vfs-find-directory.h \ + gnome-vfs-handle.h \ + gnome-vfs-init.h \ + gnome-vfs-job-limit.h \ + gnome-vfs-mime-utils.h \ + gnome-vfs-mime-handlers.h \ + gnome-vfs-mime-monitor.h \ + gnome-vfs-module-callback.h \ + gnome-vfs-monitor.h \ + gnome-vfs-ops.h \ + gnome-vfs-result.h \ + gnome-vfs-standard-callbacks.h \ + gnome-vfs-types.h \ + gnome-vfs-uri.h \ + gnome-vfs-utils.h \ + gnome-vfs-xfer.h \ + gnome-vfs.h \ + $(NULL) + +libgnomevfs_2_la_SOURCES = \ + gnome-vfs-application-registry.c \ + gnome-vfs-async-job-map.c \ + gnome-vfs-async-ops.c \ + gnome-vfs-cancellable-ops.c \ + gnome-vfs-cancellation.c \ + gnome-vfs-configuration.c \ + gnome-vfs-context.c \ + gnome-vfs-directory.c \ + gnome-vfs-open-fd.c \ + gnome-vfs-file-info.c \ + gnome-vfs-find-directory.c \ + gnome-vfs-handle.c \ + gnome-vfs-i18n.c \ + gnome-vfs-inet-connection.c \ + gnome-vfs-init.c \ + gnome-vfs-job-queue.c \ + gnome-vfs-job-slave.c \ + gnome-vfs-job.c \ + gnome-vfs-method.c \ + gnome-vfs-mime-handlers.c \ + gnome-vfs-mime-info.c \ + gnome-vfs-mime-magic.c \ + gnome-vfs-mime-monitor.c \ + gnome-vfs-mime-sniff-buffer.c \ + gnome-vfs-mime.c \ + gnome-vfs-module-callback-module-api.c \ + gnome-vfs-module-callback-private.c \ + gnome-vfs-module-callback.c \ + gnome-vfs-module-shared.c \ + gnome-vfs-module.c \ + gnome-vfs-monitor.c \ + gnome-vfs-ops.c \ + gnome-vfs-parse-ls.c \ + gnome-vfs-private-utils.c \ + gnome-vfs-private.c \ + gnome-vfs-process.c \ + gnome-vfs-result.c \ + gnome-vfs-socket-buffer.c \ + gnome-vfs-socket.c \ + gnome-vfs-ssl.c \ + gnome-vfs-thread-pool.c \ + gnome-vfs-transform.c \ + gnome-vfs-uri.c \ + gnome-vfs-utils.c \ + gnome-vfs-xfer.c \ + $(NULL) + +# $(GOB_SRCLIST) \ +# $(GOB_FILES) \ +# BUILT_SOURCES = $(GOB_SRCLIST) +# CLEANFILES = $(BUILT_SOURCES) + +# Platform specific includes +libgnomevfsplatformincludedir = $(libdir)/gnome-vfs-2.0/include +libgnomevfsplatforminclude_HEADERS = \ + gnome-vfs-file-size.h + +# TESTS = check-headers.pl +EXTRA_DIST = check-headers.pl + diff --git a/libgnomevfs/Makefile.in b/libgnomevfs/Makefile.in new file mode 100644 index 0000000..f386086 --- /dev/null +++ b/libgnomevfs/Makefile.in @@ -0,0 +1,978 @@ +# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ +AS = @AS@ +AWK = @AWK@ +BONOBO_ACTIVATION_REQUIRED = @BONOBO_ACTIVATION_REQUIRED@ +BONOBO_IDLDIR = @BONOBO_IDLDIR@ +BONOBO_REQUIRED = @BONOBO_REQUIRED@ +BZ2_LIBS = @BZ2_LIBS@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +DATADIRNAME = @DATADIRNAME@ +DB2HTML = @DB2HTML@ +DLLTOOL = @DLLTOOL@ +ECHO = @ECHO@ +ENABLE_PROFILER = @ENABLE_PROFILER@ +EXEEXT = @EXEEXT@ +FAM_LIBS = @FAM_LIBS@ +GCONFTOOL = @GCONFTOOL@ +GCONF_REQUIRED = @GCONF_REQUIRED@ +GCONF_SCHEMA_CONFIG_SOURCE = @GCONF_SCHEMA_CONFIG_SOURCE@ +GCONF_SCHEMA_FILE_DIR = @GCONF_SCHEMA_FILE_DIR@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GLIB_REQUIRED = @GLIB_REQUIRED@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GNOME_ACLOCAL_DIR = @GNOME_ACLOCAL_DIR@ +GNOME_ACLOCAL_FLAGS = @GNOME_ACLOCAL_FLAGS@ +GNOME_VFS_DIR = @GNOME_VFS_DIR@ +GTKDOC = @GTKDOC@ +HAVE_GTK_DOC = @HAVE_GTK_DOC@ +HTML_DIR = @HTML_DIR@ +INSTOBJEXT = @INSTOBJEXT@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_CAVES_RULE = @INTLTOOL_CAVES_RULE@ +INTLTOOL_DESKTOP_RULE = @INTLTOOL_DESKTOP_RULE@ +INTLTOOL_DIRECTORY_RULE = @INTLTOOL_DIRECTORY_RULE@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_KEYS_RULE = @INTLTOOL_KEYS_RULE@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_OAF_RULE = @INTLTOOL_OAF_RULE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_PONG_RULE = @INTLTOOL_PONG_RULE@ +INTLTOOL_PROP_RULE = @INTLTOOL_PROP_RULE@ +INTLTOOL_SCHEMAS_RULE = @INTLTOOL_SCHEMAS_RULE@ +INTLTOOL_SERVER_RULE = @INTLTOOL_SERVER_RULE@ +INTLTOOL_SHEET_RULE = @INTLTOOL_SHEET_RULE@ +INTLTOOL_SOUNDLIST_RULE = @INTLTOOL_SOUNDLIST_RULE@ +INTLTOOL_THEME_RULE = @INTLTOOL_THEME_RULE@ +INTLTOOL_UI_RULE = @INTLTOOL_UI_RULE@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTLTOOL_XML_RULE = @INTLTOOL_XML_RULE@ +LDFLAGS = @LDFLAGS@ +LIBEFS_CFLAGS = @LIBEFS_CFLAGS@ +LIBEFS_LIBS = @LIBEFS_LIBS@ +LIBGNOMEVFS_AGE = @LIBGNOMEVFS_AGE@ +LIBGNOMEVFS_CFLAGS = @LIBGNOMEVFS_CFLAGS@ +LIBGNOMEVFS_CURRENT = @LIBGNOMEVFS_CURRENT@ +LIBGNOMEVFS_LIBS = @LIBGNOMEVFS_LIBS@ +LIBGNOMEVFS_REVISION = @LIBGNOMEVFS_REVISION@ +LIBGNUTLS_CFLAGS = @LIBGNUTLS_CFLAGS@ +LIBGNUTLS_CONFIG = @LIBGNUTLS_CONFIG@ +LIBGNUTLS_LIBS = @LIBGNUTLS_LIBS@ +LIBIDL_REQUIRED = @LIBIDL_REQUIRED@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MODULES_CFLAGS = @MODULES_CFLAGS@ +MODULES_FILE_CFLAGS = @MODULES_FILE_CFLAGS@ +MODULES_FILE_LIBS = @MODULES_FILE_LIBS@ +MODULES_GCONF_CFLAGS = @MODULES_GCONF_CFLAGS@ +MODULES_GCONF_LIBS = @MODULES_GCONF_LIBS@ +MODULES_LIBS = @MODULES_LIBS@ +MODULES_XML_CFLAGS = @MODULES_XML_CFLAGS@ +MODULES_XML_GCONF_CFLAGS = @MODULES_XML_GCONF_CFLAGS@ +MODULES_XML_GCONF_LIBS = @MODULES_XML_GCONF_LIBS@ +MODULES_XML_LIBS = @MODULES_XML_LIBS@ +MONIKERS_CFLAGS = @MONIKERS_CFLAGS@ +MONIKERS_LIBS = @MONIKERS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ORBIT_IDL = @ORBIT_IDL@ +ORBIT_REQUIRED = @ORBIT_REQUIRED@ +PACKAGE = @PACKAGE@ +PKG_CONFIG = @PKG_CONFIG@ +POFILES = @POFILES@ +POPT_LIBS = @POPT_LIBS@ +POSUB = @POSUB@ +PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ +PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ +RANLIB = @RANLIB@ +STRIP = @STRIP@ +TEST_CFLAGS = @TEST_CFLAGS@ +TEST_LIBS = @TEST_LIBS@ +TOP_BUILDDIR = @TOP_BUILDDIR@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +VFS_CFLAGS = @VFS_CFLAGS@ +VFS_INCLUDEDIR = @VFS_INCLUDEDIR@ +VFS_LIBDIR = @VFS_LIBDIR@ +VFS_LIBS = @VFS_LIBS@ +VFS_OFFSET = @VFS_OFFSET@ +VFS_OFFSET_IS = @VFS_OFFSET_IS@ +VFS_OFFSET_PRINTF = @VFS_OFFSET_PRINTF@ +VFS_SIZE = @VFS_SIZE@ +VFS_SIZE_IS = @VFS_SIZE_IS@ +VFS_SIZE_PRINTF = @VFS_SIZE_PRINTF@ +WARN_CFLAGS = @WARN_CFLAGS@ +XML_REQUIRED = @XML_REQUIRED@ +cxxflags_set = @cxxflags_set@ + +NULL = + +INCLUDES = \ + -I$(top_srcdir) \ + -I$(top_builddir) \ + $(LIBGNOMEVFS_CFLAGS) \ + $(VFS_CFLAGS) \ + -D_FILE_OFFSET_BITS=64 \ + -D_BSD_SOURCE \ + -D_GNU_SOURCE \ + -D_LARGEFILE64_SOURCE \ + -D_POSIX_PTHREAD_SEMANTICS \ + -D_REENTRANT \ + -DG_DISABLE_DEPRECATED \ + -DDATADIR=\"$(datadir)\" \ + -DLIBDIR=\"$(libdir)\" \ + -DPREFIX=\"$(prefix)\" \ + -DGNOMEVFS_LOCALEDIR=\"$(prefix)/@DATADIRNAME@/locale\" \ + -DSYSCONFDIR=\"$(sysconfdir)\" \ + -DG_LOG_DOMAIN=\"libgnomevfs\" \ + $(NULL) + + +# %.c %.h: %.gob +# $(top_srcdir)/gob/src/gob2 $< +# +# GOB_SRCLIST = \ +# gnome-vfs-metadata.c \ +# gnome-vfs-metadata.h \ +# gnome-vfs-metadata-private.h \ +# $(NULL) +# GOB_FILES = \ +# gnome-vfs-metadata.gob \ +# $(NULL) + +lib_LTLIBRARIES = libgnomevfs-2.la + +libgnomevfs_2_la_LIBADD = \ + $(LIBGNOMEVFS_LIBS) \ + $(NULL) + + +libgnomevfs_2_la_LDFLAGS = \ + -version-info $(LIBGNOMEVFS_CURRENT):$(LIBGNOMEVFS_REVISION):$(LIBGNOMEVFS_AGE) \ + -export-symbols-regex "^[^_].*" \ + -no-undefined \ + $(NULL) + + +libgnomevfsincludedir = $(includedir)/gnome-vfs-2.0/libgnomevfs + +libgnomevfsmoduleincludedir = $(includedir)/gnome-vfs-module-2.0/libgnomevfs + +# mime-sniff-buffers and cancellabe-ops are used by modules +noinst_HEADERS = \ + gnome-vfs-async-job-map.h \ + gnome-vfs-backend.h \ + gnome-vfs-cancellable-ops.h \ + gnome-vfs-configuration.h \ + gnome-vfs-handle-private.h \ + gnome-vfs-i18n.h \ + gnome-vfs-job-queue.h \ + gnome-vfs-job-slave.h \ + gnome-vfs-job.h \ + gnome-vfs-mime-magic.h \ + gnome-vfs-mime-private.h \ + gnome-vfs-mime-sniff-buffer.h \ + gnome-vfs-mime-sniff-buffer-private.h \ + gnome-vfs-module-callback-private.h \ + gnome-vfs-monitor-private.h \ + gnome-vfs-private-utils.h \ + gnome-vfs-private.h \ + gnome-vfs-process.h \ + gnome-vfs-ssl-private.h \ + gnome-vfs-thread-pool.h \ + $(NULL) + + +libgnomevfsmoduleinclude_HEADERS = \ + gnome-vfs-cancellable-ops.h \ + gnome-vfs-inet-connection.h \ + gnome-vfs-method.h \ + gnome-vfs-mime.h \ + gnome-vfs-mime-info.h \ + gnome-vfs-module-callback-module-api.h \ + gnome-vfs-module-shared.h \ + gnome-vfs-module.h \ + gnome-vfs-parse-ls.h \ + gnome-vfs-ssl.h \ + gnome-vfs-transform.h \ + gnome-vfs-socket-buffer.h \ + gnome-vfs-socket.h \ + $(NULL) + + +libgnomevfsinclude_HEADERS = \ + gnome-vfs-application-registry.h \ + gnome-vfs-async-ops.h \ + gnome-vfs-cancellation.h \ + gnome-vfs-context.h \ + gnome-vfs-directory.h \ + gnome-vfs-file-info.h \ + gnome-vfs-file-size.h \ + gnome-vfs-find-directory.h \ + gnome-vfs-handle.h \ + gnome-vfs-init.h \ + gnome-vfs-job-limit.h \ + gnome-vfs-mime-utils.h \ + gnome-vfs-mime-handlers.h \ + gnome-vfs-mime-monitor.h \ + gnome-vfs-module-callback.h \ + gnome-vfs-monitor.h \ + gnome-vfs-ops.h \ + gnome-vfs-result.h \ + gnome-vfs-standard-callbacks.h \ + gnome-vfs-types.h \ + gnome-vfs-uri.h \ + gnome-vfs-utils.h \ + gnome-vfs-xfer.h \ + gnome-vfs.h \ + $(NULL) + + +libgnomevfs_2_la_SOURCES = \ + gnome-vfs-application-registry.c \ + gnome-vfs-async-job-map.c \ + gnome-vfs-async-ops.c \ + gnome-vfs-cancellable-ops.c \ + gnome-vfs-cancellation.c \ + gnome-vfs-configuration.c \ + gnome-vfs-context.c \ + gnome-vfs-directory.c \ + gnome-vfs-open-fd.c \ + gnome-vfs-file-info.c \ + gnome-vfs-find-directory.c \ + gnome-vfs-handle.c \ + gnome-vfs-i18n.c \ + gnome-vfs-inet-connection.c \ + gnome-vfs-init.c \ + gnome-vfs-job-queue.c \ + gnome-vfs-job-slave.c \ + gnome-vfs-job.c \ + gnome-vfs-method.c \ + gnome-vfs-mime-handlers.c \ + gnome-vfs-mime-info.c \ + gnome-vfs-mime-magic.c \ + gnome-vfs-mime-monitor.c \ + gnome-vfs-mime-sniff-buffer.c \ + gnome-vfs-mime.c \ + gnome-vfs-module-callback-module-api.c \ + gnome-vfs-module-callback-private.c \ + gnome-vfs-module-callback.c \ + gnome-vfs-module-shared.c \ + gnome-vfs-module.c \ + gnome-vfs-monitor.c \ + gnome-vfs-ops.c \ + gnome-vfs-parse-ls.c \ + gnome-vfs-private-utils.c \ + gnome-vfs-private.c \ + gnome-vfs-process.c \ + gnome-vfs-result.c \ + gnome-vfs-socket-buffer.c \ + gnome-vfs-socket.c \ + gnome-vfs-ssl.c \ + gnome-vfs-thread-pool.c \ + gnome-vfs-transform.c \ + gnome-vfs-uri.c \ + gnome-vfs-utils.c \ + gnome-vfs-xfer.c \ + $(NULL) + + +# $(GOB_SRCLIST) \ +# $(GOB_FILES) \ +# BUILT_SOURCES = $(GOB_SRCLIST) +# CLEANFILES = $(BUILT_SOURCES) + +# Platform specific includes +libgnomevfsplatformincludedir = $(libdir)/gnome-vfs-2.0/include +libgnomevfsplatforminclude_HEADERS = \ + gnome-vfs-file-size.h + + +# TESTS = check-headers.pl +EXTRA_DIST = check-headers.pl +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../config.h +CONFIG_CLEAN_FILES = gnome-vfs-file-size.h +LTLIBRARIES = $(lib_LTLIBRARIES) + + +DEFS = @DEFS@ -I. -I$(srcdir) -I.. +LIBS = @LIBS@ +libgnomevfs_2_la_DEPENDENCIES = +libgnomevfs_2_la_OBJECTS = gnome-vfs-application-registry.lo \ +gnome-vfs-async-job-map.lo gnome-vfs-async-ops.lo \ +gnome-vfs-cancellable-ops.lo gnome-vfs-cancellation.lo \ +gnome-vfs-configuration.lo gnome-vfs-context.lo gnome-vfs-directory.lo \ +gnome-vfs-open-fd.lo gnome-vfs-file-info.lo gnome-vfs-find-directory.lo \ +gnome-vfs-handle.lo gnome-vfs-i18n.lo gnome-vfs-inet-connection.lo \ +gnome-vfs-init.lo gnome-vfs-job-queue.lo gnome-vfs-job-slave.lo \ +gnome-vfs-job.lo gnome-vfs-method.lo gnome-vfs-mime-handlers.lo \ +gnome-vfs-mime-info.lo gnome-vfs-mime-magic.lo \ +gnome-vfs-mime-monitor.lo gnome-vfs-mime-sniff-buffer.lo \ +gnome-vfs-mime.lo gnome-vfs-module-callback-module-api.lo \ +gnome-vfs-module-callback-private.lo gnome-vfs-module-callback.lo \ +gnome-vfs-module-shared.lo gnome-vfs-module.lo gnome-vfs-monitor.lo \ +gnome-vfs-ops.lo gnome-vfs-parse-ls.lo gnome-vfs-private-utils.lo \ +gnome-vfs-private.lo gnome-vfs-process.lo gnome-vfs-result.lo \ +gnome-vfs-socket-buffer.lo gnome-vfs-socket.lo gnome-vfs-ssl.lo \ +gnome-vfs-thread-pool.lo gnome-vfs-transform.lo gnome-vfs-uri.lo \ +gnome-vfs-utils.lo gnome-vfs-xfer.lo +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +HEADERS = $(libgnomevfsinclude_HEADERS) \ +$(libgnomevfsmoduleinclude_HEADERS) \ +$(libgnomevfsplatforminclude_HEADERS) $(noinst_HEADERS) + +DIST_COMMON = Makefile.am Makefile.in gnome-vfs-file-size.h.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +SOURCES = $(libgnomevfs_2_la_SOURCES) +OBJECTS = $(libgnomevfs_2_la_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .lo .o .obj .s +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps libgnomevfs/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + +gnome-vfs-file-size.h: $(top_builddir)/config.status gnome-vfs-file-size.h.in + cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + +mostlyclean-libLTLIBRARIES: + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + +distclean-libLTLIBRARIES: + +maintainer-clean-libLTLIBRARIES: + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(libdir) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \ + $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \ + else :; fi; \ + done + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \ + done + +.c.o: + $(COMPILE) -c $< + +# FIXME: We should only use cygpath when building on Windows, +# and only if it is available. +.c.obj: + $(COMPILE) -c `cygpath -w $<` + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + -rm -f *.$(OBJEXT) + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +.c.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.s.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.S.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + +maintainer-clean-libtool: + +libgnomevfs-2.la: $(libgnomevfs_2_la_OBJECTS) $(libgnomevfs_2_la_DEPENDENCIES) + $(LINK) -rpath $(libdir) $(libgnomevfs_2_la_LDFLAGS) $(libgnomevfs_2_la_OBJECTS) $(libgnomevfs_2_la_LIBADD) $(LIBS) + +install-libgnomevfsincludeHEADERS: $(libgnomevfsinclude_HEADERS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(libgnomevfsincludedir) + @list='$(libgnomevfsinclude_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \ + echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(libgnomevfsincludedir)/$$p"; \ + $(INSTALL_DATA) $$d$$p $(DESTDIR)$(libgnomevfsincludedir)/$$p; \ + done + +uninstall-libgnomevfsincludeHEADERS: + @$(NORMAL_UNINSTALL) + list='$(libgnomevfsinclude_HEADERS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(libgnomevfsincludedir)/$$p; \ + done + +install-libgnomevfsmoduleincludeHEADERS: $(libgnomevfsmoduleinclude_HEADERS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(libgnomevfsmoduleincludedir) + @list='$(libgnomevfsmoduleinclude_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \ + echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(libgnomevfsmoduleincludedir)/$$p"; \ + $(INSTALL_DATA) $$d$$p $(DESTDIR)$(libgnomevfsmoduleincludedir)/$$p; \ + done + +uninstall-libgnomevfsmoduleincludeHEADERS: + @$(NORMAL_UNINSTALL) + list='$(libgnomevfsmoduleinclude_HEADERS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(libgnomevfsmoduleincludedir)/$$p; \ + done + +install-libgnomevfsplatformincludeHEADERS: $(libgnomevfsplatforminclude_HEADERS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(libgnomevfsplatformincludedir) + @list='$(libgnomevfsplatforminclude_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \ + echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(libgnomevfsplatformincludedir)/$$p"; \ + $(INSTALL_DATA) $$d$$p $(DESTDIR)$(libgnomevfsplatformincludedir)/$$p; \ + done + +uninstall-libgnomevfsplatformincludeHEADERS: + @$(NORMAL_UNINSTALL) + list='$(libgnomevfsplatforminclude_HEADERS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(libgnomevfsplatformincludedir)/$$p; \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = libgnomevfs + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +gnome-vfs-application-registry.lo gnome-vfs-application-registry.o : \ + gnome-vfs-application-registry.c ../config.h \ + gnome-vfs-application-registry.h gnome-vfs-mime-handlers.h \ + gnome-vfs-mime-utils.h gnome-vfs-result.h gnome-vfs-uri.h \ + gnome-vfs-configuration.h gnome-vfs-mime-handlers.h \ + gnome-vfs-mime-private.h gnome-vfs-mime-monitor.h \ + gnome-vfs-mime.h gnome-vfs-private-utils.h \ + gnome-vfs-cancellation.h gnome-vfs-handle.h gnome-vfs-context.h \ + gnome-vfs-file-size.h gnome-vfs-file-info.h gnome-vfs-process.h \ + gnome-vfs-result.h +gnome-vfs-async-job-map.lo gnome-vfs-async-job-map.o : \ + gnome-vfs-async-job-map.c ../config.h gnome-vfs-async-job-map.h \ + gnome-vfs-job.h gnome-vfs-async-ops.h gnome-vfs-file-info.h \ + gnome-vfs-file-size.h gnome-vfs-result.h gnome-vfs-uri.h \ + gnome-vfs-find-directory.h gnome-vfs-handle.h \ + gnome-vfs-context.h gnome-vfs-cancellation.h gnome-vfs-xfer.h \ + gnome-vfs-module-callback.h gnome-vfs-module-callback-private.h +gnome-vfs-async-ops.lo gnome-vfs-async-ops.o : gnome-vfs-async-ops.c \ + ../config.h gnome-vfs-async-ops.h gnome-vfs-file-info.h \ + gnome-vfs-file-size.h gnome-vfs-result.h gnome-vfs-uri.h \ + gnome-vfs-find-directory.h gnome-vfs-handle.h \ + gnome-vfs-context.h gnome-vfs-cancellation.h gnome-vfs-xfer.h \ + gnome-vfs-async-job-map.h gnome-vfs-job.h gnome-vfs-async-ops.h \ + gnome-vfs-module-callback.h gnome-vfs-module-callback-private.h \ + gnome-vfs-job-queue.h gnome-vfs-job-limit.h +gnome-vfs-cancellable-ops.lo gnome-vfs-cancellable-ops.o : \ + gnome-vfs-cancellable-ops.c ../config.h \ + gnome-vfs-cancellable-ops.h gnome-vfs-directory.h \ + gnome-vfs-file-info.h gnome-vfs-file-size.h gnome-vfs-result.h \ + gnome-vfs-uri.h gnome-vfs-find-directory.h gnome-vfs-handle.h \ + gnome-vfs-context.h gnome-vfs-cancellation.h gnome-vfs-xfer.h \ + gnome-vfs-method.h gnome-vfs-transform.h gnome-vfs-monitor.h \ + gnome-vfs-handle-private.h +gnome-vfs-cancellation.lo gnome-vfs-cancellation.o : \ + gnome-vfs-cancellation.c ../config.h gnome-vfs-cancellation.h \ + gnome-vfs-utils.h gnome-vfs-file-size.h gnome-vfs-result.h \ + gnome-vfs-uri.h gnome-vfs-handle.h gnome-vfs-context.h \ + gnome-vfs-cancellation.h gnome-vfs-file-info.h +gnome-vfs-configuration.lo gnome-vfs-configuration.o : \ + gnome-vfs-configuration.c ../config.h gnome-vfs-configuration.h \ + gnome-vfs-i18n.h gnome-vfs-private.h +gnome-vfs-context.lo gnome-vfs-context.o : gnome-vfs-context.c \ + ../config.h gnome-vfs-context.h gnome-vfs-cancellation.h \ + gnome-vfs-backend.h gnome-vfs-context.h \ + gnome-vfs-module-callback.h gnome-vfs-cancellation.h \ + gnome-vfs-private-utils.h gnome-vfs-handle.h \ + gnome-vfs-file-size.h gnome-vfs-file-info.h gnome-vfs-result.h \ + gnome-vfs-uri.h gnome-vfs-process.h gnome-vfs-utils.h +gnome-vfs-directory.lo gnome-vfs-directory.o : gnome-vfs-directory.c \ + ../config.h gnome-vfs-directory.h gnome-vfs-file-info.h \ + gnome-vfs-file-size.h gnome-vfs-result.h gnome-vfs-uri.h \ + gnome-vfs-cancellable-ops.h gnome-vfs-directory.h \ + gnome-vfs-find-directory.h gnome-vfs-handle.h \ + gnome-vfs-context.h gnome-vfs-cancellation.h gnome-vfs-xfer.h \ + gnome-vfs-method.h gnome-vfs-transform.h gnome-vfs-monitor.h \ + gnome-vfs-ops.h +gnome-vfs-file-info.lo gnome-vfs-file-info.o : gnome-vfs-file-info.c \ + ../config.h gnome-vfs-file-info.h gnome-vfs-file-size.h \ + gnome-vfs-result.h gnome-vfs-uri.h +gnome-vfs-find-directory.lo gnome-vfs-find-directory.o : \ + gnome-vfs-find-directory.c ../config.h \ + gnome-vfs-find-directory.h gnome-vfs-result.h gnome-vfs-uri.h \ + gnome-vfs-cancellable-ops.h gnome-vfs-directory.h \ + gnome-vfs-file-info.h gnome-vfs-file-size.h \ + gnome-vfs-find-directory.h gnome-vfs-handle.h \ + gnome-vfs-context.h gnome-vfs-cancellation.h gnome-vfs-xfer.h +gnome-vfs-handle.lo gnome-vfs-handle.o : gnome-vfs-handle.c ../config.h \ + gnome-vfs-handle.h gnome-vfs-context.h gnome-vfs-cancellation.h \ + gnome-vfs-file-size.h gnome-vfs-file-info.h gnome-vfs-result.h \ + gnome-vfs-uri.h gnome-vfs-handle-private.h gnome-vfs-method.h \ + gnome-vfs-find-directory.h gnome-vfs-handle.h \ + gnome-vfs-transform.h gnome-vfs-monitor.h +gnome-vfs-i18n.lo gnome-vfs-i18n.o : gnome-vfs-i18n.c ../config.h \ + gnome-vfs-i18n.h gnome-vfs-private-utils.h \ + gnome-vfs-cancellation.h gnome-vfs-handle.h gnome-vfs-context.h \ + gnome-vfs-file-size.h gnome-vfs-file-info.h gnome-vfs-result.h \ + gnome-vfs-uri.h gnome-vfs-process.h +gnome-vfs-inet-connection.lo gnome-vfs-inet-connection.o : \ + gnome-vfs-inet-connection.c ../config.h \ + gnome-vfs-inet-connection.h gnome-vfs-cancellation.h \ + gnome-vfs-socket.h gnome-vfs-file-size.h gnome-vfs-result.h \ + gnome-vfs-socket-buffer.h gnome-vfs-private-utils.h \ + gnome-vfs-handle.h gnome-vfs-context.h gnome-vfs-file-info.h \ + gnome-vfs-uri.h gnome-vfs-process.h +gnome-vfs-init.lo gnome-vfs-init.o : gnome-vfs-init.c ../config.h \ + gnome-vfs-init.h gnome-vfs-ssl-private.h gnome-vfs-mime.h \ + gnome-vfs-uri.h gnome-vfs-configuration.h gnome-vfs-i18n.h \ + gnome-vfs-method.h gnome-vfs-context.h gnome-vfs-cancellation.h \ + gnome-vfs-file-info.h gnome-vfs-file-size.h gnome-vfs-result.h \ + gnome-vfs-find-directory.h gnome-vfs-handle.h \ + gnome-vfs-transform.h gnome-vfs-monitor.h gnome-vfs-process.h \ + gnome-vfs-utils.h gnome-vfs-async-job-map.h gnome-vfs-job.h \ + gnome-vfs-async-ops.h gnome-vfs-xfer.h \ + gnome-vfs-module-callback.h gnome-vfs-module-callback-private.h \ + gnome-vfs-thread-pool.h gnome-vfs-job-queue.h \ + gnome-vfs-job-slave.h gnome-vfs-job.h +gnome-vfs-iobuf.lo gnome-vfs-iobuf.o : gnome-vfs-iobuf.c ../config.h \ + gnome-vfs-iobuf.h gnome-vfs-file-size.h gnome-vfs-result.h +gnome-vfs-job-queue.lo gnome-vfs-job-queue.o : gnome-vfs-job-queue.c \ + ../config.h gnome-vfs-job-queue.h gnome-vfs-job.h \ + gnome-vfs-async-ops.h gnome-vfs-file-info.h \ + gnome-vfs-file-size.h gnome-vfs-result.h gnome-vfs-uri.h \ + gnome-vfs-find-directory.h gnome-vfs-handle.h \ + gnome-vfs-context.h gnome-vfs-cancellation.h gnome-vfs-xfer.h \ + gnome-vfs-module-callback.h gnome-vfs-module-callback-private.h \ + gnome-vfs-job-slave.h gnome-vfs-job-limit.h +gnome-vfs-job-slave.lo gnome-vfs-job-slave.o : gnome-vfs-job-slave.c \ + ../config.h gnome-vfs-job-slave.h gnome-vfs-job.h \ + gnome-vfs-async-ops.h gnome-vfs-file-info.h \ + gnome-vfs-file-size.h gnome-vfs-result.h gnome-vfs-uri.h \ + gnome-vfs-find-directory.h gnome-vfs-handle.h \ + gnome-vfs-context.h gnome-vfs-cancellation.h gnome-vfs-xfer.h \ + gnome-vfs-module-callback.h gnome-vfs-module-callback-private.h \ + gnome-vfs-async-job-map.h gnome-vfs-thread-pool.h \ + gnome-vfs-job-queue.h +gnome-vfs-job.lo gnome-vfs-job.o : gnome-vfs-job.c ../config.h \ + gnome-vfs-job.h gnome-vfs-async-ops.h gnome-vfs-file-info.h \ + gnome-vfs-file-size.h gnome-vfs-result.h gnome-vfs-uri.h \ + gnome-vfs-find-directory.h gnome-vfs-handle.h \ + gnome-vfs-context.h gnome-vfs-cancellation.h gnome-vfs-xfer.h \ + gnome-vfs-module-callback.h gnome-vfs-module-callback-private.h \ + gnome-vfs-async-job-map.h gnome-vfs-job-slave.h \ + gnome-vfs-job-queue.h gnome-vfs-cancellable-ops.h \ + gnome-vfs-directory.h gnome-vfs-i18n.h gnome-vfs-backend.h +gnome-vfs-metadata.lo gnome-vfs-metadata.o : gnome-vfs-metadata.c \ + gnome-vfs-utils.h gnome-vfs-file-size.h gnome-vfs-result.h \ + gnome-vfs-uri.h gnome-vfs-uri.h gnome-vfs-metadata.h \ + gnome-vfs-metadata-private.h +gnome-vfs-method.lo gnome-vfs-method.o : gnome-vfs-method.c ../config.h \ + gnome-vfs-method.h gnome-vfs-context.h gnome-vfs-cancellation.h \ + gnome-vfs-file-info.h gnome-vfs-file-size.h gnome-vfs-result.h \ + gnome-vfs-uri.h gnome-vfs-find-directory.h gnome-vfs-handle.h \ + gnome-vfs-transform.h gnome-vfs-monitor.h \ + gnome-vfs-configuration.h gnome-vfs-private.h \ + gnome-vfs-module.h gnome-vfs-method.h +gnome-vfs-mime-handlers.lo gnome-vfs-mime-handlers.o : \ + gnome-vfs-mime-handlers.c ../config.h gnome-vfs-mime-handlers.h \ + gnome-vfs-mime-utils.h gnome-vfs-result.h gnome-vfs-uri.h \ + gnome-vfs-application-registry.h gnome-vfs-mime-handlers.h \ + gnome-vfs-mime-info.h gnome-vfs-mime.h gnome-vfs-result.h \ + gnome-vfs-private-utils.h gnome-vfs-cancellation.h \ + gnome-vfs-handle.h gnome-vfs-context.h gnome-vfs-file-size.h \ + gnome-vfs-file-info.h gnome-vfs-process.h gnome-vfs-utils.h +gnome-vfs-mime-info.lo gnome-vfs-mime-info.o : gnome-vfs-mime-info.c \ + ../config.h gnome-vfs-mime-info.h gnome-vfs-result.h \ + gnome-vfs-mime-monitor.h gnome-vfs-mime-private.h \ + gnome-vfs-mime-monitor.h gnome-vfs-mime.h gnome-vfs-uri.h \ + gnome-vfs-private-utils.h gnome-vfs-cancellation.h \ + gnome-vfs-handle.h gnome-vfs-context.h gnome-vfs-file-size.h \ + gnome-vfs-file-info.h gnome-vfs-process.h +gnome-vfs-mime-magic.lo gnome-vfs-mime-magic.o : gnome-vfs-mime-magic.c \ + ../config.h gnome-vfs-mime-magic.h \ + gnome-vfs-mime-sniff-buffer-private.h \ + gnome-vfs-mime-sniff-buffer.h gnome-vfs-handle.h \ + gnome-vfs-context.h gnome-vfs-cancellation.h \ + gnome-vfs-file-size.h gnome-vfs-file-info.h gnome-vfs-result.h \ + gnome-vfs-uri.h gnome-vfs-mime.h gnome-vfs-private-utils.h \ + gnome-vfs-process.h +gnome-vfs-mime-monitor.lo gnome-vfs-mime-monitor.o : \ + gnome-vfs-mime-monitor.c ../config.h gnome-vfs-mime-monitor.h \ + gnome-vfs-mime-private.h gnome-vfs-mime-monitor.h \ + gnome-vfs-ops.h gnome-vfs-file-info.h gnome-vfs-file-size.h \ + gnome-vfs-result.h gnome-vfs-uri.h gnome-vfs-handle.h \ + gnome-vfs-context.h gnome-vfs-cancellation.h \ + gnome-vfs-monitor.h +gnome-vfs-mime-sniff-buffer.lo gnome-vfs-mime-sniff-buffer.o : \ + gnome-vfs-mime-sniff-buffer.c ../config.h \ + gnome-vfs-mime-sniff-buffer.h gnome-vfs-handle.h \ + gnome-vfs-context.h gnome-vfs-cancellation.h \ + gnome-vfs-file-size.h gnome-vfs-file-info.h gnome-vfs-result.h \ + gnome-vfs-uri.h gnome-vfs-handle.h \ + gnome-vfs-mime-sniff-buffer-private.h \ + gnome-vfs-mime-sniff-buffer.h gnome-vfs-ops.h \ + gnome-vfs-monitor.h +gnome-vfs-mime.lo gnome-vfs-mime.o : gnome-vfs-mime.c ../config.h \ + gnome-vfs-mime.h gnome-vfs-uri.h gnome-vfs-mime-private.h \ + gnome-vfs-mime-monitor.h gnome-vfs-mime-sniff-buffer-private.h \ + gnome-vfs-mime-sniff-buffer.h gnome-vfs-handle.h \ + gnome-vfs-context.h gnome-vfs-cancellation.h \ + gnome-vfs-file-size.h gnome-vfs-file-info.h gnome-vfs-result.h \ + gnome-vfs-mime-utils.h gnome-vfs-module-shared.h \ + gnome-vfs-ops.h gnome-vfs-monitor.h gnome-vfs-result.h \ + gnome-vfs-uri.h +gnome-vfs-module-callback-module-api.lo gnome-vfs-module-callback-module-api.o : \ + gnome-vfs-module-callback-module-api.c ../config.h \ + gnome-vfs-module-callback-module-api.h +gnome-vfs-module-callback-private.lo gnome-vfs-module-callback-private.o : \ + gnome-vfs-module-callback-private.c ../config.h \ + gnome-vfs-module-callback-private.h +gnome-vfs-module-callback.lo gnome-vfs-module-callback.o : \ + gnome-vfs-module-callback.c ../config.h \ + gnome-vfs-module-callback.h \ + gnome-vfs-module-callback-module-api.h \ + gnome-vfs-module-callback-private.h gnome-vfs-backend.h \ + gnome-vfs-context.h gnome-vfs-cancellation.h \ + gnome-vfs-module-callback.h +gnome-vfs-module-shared.lo gnome-vfs-module-shared.o : \ + gnome-vfs-module-shared.c ../config.h gnome-vfs-module-shared.h \ + gnome-vfs-file-info.h gnome-vfs-file-size.h gnome-vfs-result.h \ + gnome-vfs-uri.h gnome-vfs-module.h gnome-vfs-method.h \ + gnome-vfs-context.h gnome-vfs-cancellation.h \ + gnome-vfs-find-directory.h gnome-vfs-handle.h \ + gnome-vfs-transform.h gnome-vfs-monitor.h gnome-vfs-ops.h +gnome-vfs-module.lo gnome-vfs-module.o : gnome-vfs-module.c ../config.h \ + gnome-vfs-module.h gnome-vfs-method.h gnome-vfs-context.h \ + gnome-vfs-cancellation.h gnome-vfs-file-info.h \ + gnome-vfs-file-size.h gnome-vfs-result.h gnome-vfs-uri.h \ + gnome-vfs-find-directory.h gnome-vfs-handle.h \ + gnome-vfs-transform.h gnome-vfs-monitor.h +gnome-vfs-monitor.lo gnome-vfs-monitor.o : gnome-vfs-monitor.c \ + gnome-vfs-monitor.h gnome-vfs-monitor-private.h \ + gnome-vfs-method.h gnome-vfs-context.h gnome-vfs-cancellation.h \ + gnome-vfs-file-info.h gnome-vfs-file-size.h gnome-vfs-result.h \ + gnome-vfs-uri.h gnome-vfs-find-directory.h gnome-vfs-handle.h \ + gnome-vfs-transform.h +gnome-vfs-open-fd.lo gnome-vfs-open-fd.o : gnome-vfs-open-fd.c \ + ../config.h gnome-vfs-uri.h gnome-vfs-method.h \ + gnome-vfs-context.h gnome-vfs-cancellation.h \ + gnome-vfs-file-info.h gnome-vfs-file-size.h gnome-vfs-result.h \ + gnome-vfs-uri.h gnome-vfs-find-directory.h gnome-vfs-handle.h \ + gnome-vfs-transform.h gnome-vfs-monitor.h gnome-vfs-handle.h \ + gnome-vfs-module-shared.h gnome-vfs-mime.h \ + gnome-vfs-handle-private.h gnome-vfs-utils.h +gnome-vfs-ops.lo gnome-vfs-ops.o : gnome-vfs-ops.c ../config.h \ + gnome-vfs-ops.h gnome-vfs-file-info.h gnome-vfs-file-size.h \ + gnome-vfs-result.h gnome-vfs-uri.h gnome-vfs-handle.h \ + gnome-vfs-context.h gnome-vfs-cancellation.h \ + gnome-vfs-monitor.h gnome-vfs-monitor-private.h \ + gnome-vfs-method.h gnome-vfs-find-directory.h \ + gnome-vfs-transform.h gnome-vfs-cancellable-ops.h \ + gnome-vfs-directory.h gnome-vfs-xfer.h \ + gnome-vfs-handle-private.h +gnome-vfs-parse-ls.lo gnome-vfs-parse-ls.o : gnome-vfs-parse-ls.c \ + ../config.h gnome-vfs-parse-ls.h gnome-vfs-i18n.h +gnome-vfs-private-utils.lo gnome-vfs-private-utils.o : \ + gnome-vfs-private-utils.c ../config.h gnome-vfs-private-utils.h \ + gnome-vfs-cancellation.h gnome-vfs-handle.h gnome-vfs-context.h \ + gnome-vfs-file-size.h gnome-vfs-file-info.h gnome-vfs-result.h \ + gnome-vfs-uri.h gnome-vfs-process.h gnome-vfs-utils.h \ + gnome-vfs-cancellation.h gnome-vfs-ops.h gnome-vfs-monitor.h \ + gnome-vfs-uri.h +gnome-vfs-private.lo gnome-vfs-private.o : gnome-vfs-private.c \ + ../config.h gnome-vfs-private.h +gnome-vfs-process.lo gnome-vfs-process.o : gnome-vfs-process.c \ + ../config.h gnome-vfs-process.h gnome-vfs-private-utils.h \ + gnome-vfs-cancellation.h gnome-vfs-handle.h gnome-vfs-context.h \ + gnome-vfs-file-size.h gnome-vfs-file-info.h gnome-vfs-result.h \ + gnome-vfs-uri.h gnome-vfs-process.h +gnome-vfs-pthread.lo gnome-vfs-pthread.o : gnome-vfs-pthread.c \ + gnome-vfs-pthread.h gnome-vfs-async-job-map.h gnome-vfs-job.h \ + gnome-vfs-async-ops.h gnome-vfs-file-info.h \ + gnome-vfs-file-size.h gnome-vfs-result.h gnome-vfs-uri.h \ + gnome-vfs-find-directory.h gnome-vfs-handle.h \ + gnome-vfs-context.h gnome-vfs-cancellation.h gnome-vfs-xfer.h \ + gnome-vfs-module-callback.h gnome-vfs-module-callback-private.h \ + gnome-vfs-thread-pool.h gnome-vfs-job-queue.h +gnome-vfs-result.lo gnome-vfs-result.o : gnome-vfs-result.c ../config.h \ + gnome-vfs-result.h gnome-vfs-i18n.h +gnome-vfs-socket-buffer.lo gnome-vfs-socket-buffer.o : \ + gnome-vfs-socket-buffer.c ../config.h gnome-vfs-socket-buffer.h \ + gnome-vfs-socket.h gnome-vfs-file-size.h gnome-vfs-result.h +gnome-vfs-socket.lo gnome-vfs-socket.o : gnome-vfs-socket.c ../config.h \ + gnome-vfs-socket.h gnome-vfs-file-size.h gnome-vfs-result.h +gnome-vfs-ssl.lo gnome-vfs-ssl.o : gnome-vfs-ssl.c ../config.h \ + gnome-vfs-ssl.h gnome-vfs-socket.h gnome-vfs-file-size.h \ + gnome-vfs-result.h gnome-vfs-ssl-private.h \ + gnome-vfs-private-utils.h gnome-vfs-cancellation.h \ + gnome-vfs-handle.h gnome-vfs-context.h gnome-vfs-file-info.h \ + gnome-vfs-uri.h gnome-vfs-process.h +gnome-vfs-thread-pool.lo gnome-vfs-thread-pool.o : \ + gnome-vfs-thread-pool.c ../config.h gnome-vfs-thread-pool.h \ + gnome-vfs-job-queue.h gnome-vfs-job.h gnome-vfs-async-ops.h \ + gnome-vfs-file-info.h gnome-vfs-file-size.h gnome-vfs-result.h \ + gnome-vfs-uri.h gnome-vfs-find-directory.h gnome-vfs-handle.h \ + gnome-vfs-context.h gnome-vfs-cancellation.h gnome-vfs-xfer.h \ + gnome-vfs-module-callback.h gnome-vfs-module-callback-private.h \ + gnome-vfs-job-limit.h +gnome-vfs-transform.lo gnome-vfs-transform.o : gnome-vfs-transform.c \ + ../config.h gnome-vfs-transform.h gnome-vfs-result.h \ + gnome-vfs-context.h gnome-vfs-cancellation.h +gnome-vfs-uri.lo gnome-vfs-uri.o : gnome-vfs-uri.c ../config.h \ + gnome-vfs-uri.h gnome-vfs-module.h gnome-vfs-method.h \ + gnome-vfs-context.h gnome-vfs-cancellation.h \ + gnome-vfs-file-info.h gnome-vfs-file-size.h gnome-vfs-result.h \ + gnome-vfs-uri.h gnome-vfs-find-directory.h gnome-vfs-handle.h \ + gnome-vfs-transform.h gnome-vfs-monitor.h \ + gnome-vfs-private-utils.h gnome-vfs-process.h \ + gnome-vfs-transform.h gnome-vfs-utils.h +gnome-vfs-utils.lo gnome-vfs-utils.o : gnome-vfs-utils.c ../config.h \ + gnome-vfs-utils.h gnome-vfs-file-size.h gnome-vfs-result.h \ + gnome-vfs-uri.h gnome-vfs-handle.h gnome-vfs-context.h \ + gnome-vfs-cancellation.h gnome-vfs-file-info.h gnome-vfs-i18n.h \ + gnome-vfs-private-utils.h gnome-vfs-process.h gnome-vfs-ops.h \ + gnome-vfs-monitor.h gnome-vfs-mime-handlers.h \ + gnome-vfs-mime-utils.h +gnome-vfs-xfer.lo gnome-vfs-xfer.o : gnome-vfs-xfer.c ../config.h \ + gnome-vfs-xfer.h gnome-vfs-file-info.h gnome-vfs-file-size.h \ + gnome-vfs-result.h gnome-vfs-uri.h gnome-vfs-cancellable-ops.h \ + gnome-vfs-directory.h gnome-vfs-find-directory.h \ + gnome-vfs-handle.h gnome-vfs-context.h gnome-vfs-cancellation.h \ + gnome-vfs-xfer.h gnome-vfs-directory.h gnome-vfs-ops.h \ + gnome-vfs-monitor.h gnome-vfs-utils.h gnome-vfs-private-utils.h \ + gnome-vfs-process.h + +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: install-libLTLIBRARIES +install-exec: install-exec-am + +install-data-am: install-libgnomevfsincludeHEADERS \ + install-libgnomevfsmoduleincludeHEADERS \ + install-libgnomevfsplatformincludeHEADERS +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-libLTLIBRARIES \ + uninstall-libgnomevfsincludeHEADERS \ + uninstall-libgnomevfsmoduleincludeHEADERS \ + uninstall-libgnomevfsplatformincludeHEADERS +uninstall: uninstall-am +all-am: Makefile $(LTLIBRARIES) $(HEADERS) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(libdir) \ + $(DESTDIR)$(libgnomevfsincludedir) \ + $(DESTDIR)$(libgnomevfsmoduleincludedir) \ + $(DESTDIR)$(libgnomevfsplatformincludedir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-libLTLIBRARIES mostlyclean-compile \ + mostlyclean-libtool mostlyclean-tags \ + mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-libLTLIBRARIES clean-compile clean-libtool clean-tags \ + clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-libLTLIBRARIES distclean-compile \ + distclean-libtool distclean-tags distclean-generic \ + clean-am + -rm -f libtool + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-libLTLIBRARIES \ + maintainer-clean-compile maintainer-clean-libtool \ + maintainer-clean-tags maintainer-clean-generic \ + distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: mostlyclean-libLTLIBRARIES distclean-libLTLIBRARIES \ +clean-libLTLIBRARIES maintainer-clean-libLTLIBRARIES \ +uninstall-libLTLIBRARIES install-libLTLIBRARIES mostlyclean-compile \ +distclean-compile clean-compile maintainer-clean-compile \ +mostlyclean-libtool distclean-libtool clean-libtool \ +maintainer-clean-libtool uninstall-libgnomevfsincludeHEADERS \ +install-libgnomevfsincludeHEADERS \ +uninstall-libgnomevfsmoduleincludeHEADERS \ +install-libgnomevfsmoduleincludeHEADERS \ +uninstall-libgnomevfsplatformincludeHEADERS \ +install-libgnomevfsplatformincludeHEADERS tags mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir info-am info \ +dvi-am dvi check check-am installcheck-am installcheck install-exec-am \ +install-exec install-data-am install-data install-am install \ +uninstall-am uninstall all-redirect all-am all installdirs \ +mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libgnomevfs/check-headers.pl b/libgnomevfs/check-headers.pl new file mode 100755 index 0000000..2116166 --- /dev/null +++ b/libgnomevfs/check-headers.pl @@ -0,0 +1,123 @@ +#!/usr/bin/perl -w +# -*- Mode: perl; indent-tabs-mode: nil -*- + +use diagnostics; +use strict; + +my $DEBUG = 0; + +my %public_headers; +my %module_headers; +my %private_headers; + +my $current_hash; +my $current_hash_name; + +my $current_header; +my $included_header; + +my $exit_code = 0; + +open MAKEFILE_AM, "<./Makefile.am"; + +while () { + if (/libgnomevfsinclude_HEADERS/) { + $current_hash = \%public_headers + } elsif (/libgnomevfsmoduleinclude_HEADERS/) { + $current_hash = \%module_headers + } elsif (/noinst_HEADERS/) { + $current_hash = \%private_headers + } elsif (/\$\(NULL\)/ || ! /\\/) { + $current_hash = 0; + } + + if (/.*\.h[ \t]/) { + chomp; + $current_header = $_; + $current_header =~ s/[ \t]*(.*\.h)[ \t]*.*/$1/; + + if ($current_hash) { + $$current_hash{$current_header} = 1; + } + } +} + +close MAKEFILE_AM; + +for my $public_header (keys %public_headers) { + open HEADER, "<${public_header}"; + while (
) { + if (/\#include[ \t]+.*/) { + chomp; + $included_header = $_; + $included_header =~ s/\#include[ \t]+.*/$1/; + + if ($private_headers{$included_header}) { + print "Public header \"$public_header\" includes private header \"$included_header\"\n"; + $exit_code = 1; + } elsif ($module_headers{$included_header}) { + print "Public header \"$public_header\" includes module API header \"$included_header\"\n"; + $exit_code = 1; + } elsif ($public_headers{$included_header}) { + print "Public header \"$public_header\" includes public header \"$included_header\"\n" if $DEBUG; + } else { + print "Public header \"$public_header\" includes unknown header \"$included_header\"\n"; + $exit_code = 1; + } + } + } + close HEADER; +} + + +for my $module_header (keys %module_headers) { + open HEADER, "<${module_header}"; + + while (
) { + if (/\#include[ \t]+.*/) { + chomp; + $included_header = $_; + $included_header =~ s/\#include[ \t]+.*/$1/; + + if ($private_headers{$included_header}) { + print "Module API header \"$module_header\" includes private header \"$included_header\"\n"; + $exit_code = 1; + } elsif ($module_headers{$included_header}) { + print "Module API header \"$module_header\" includes public header \"$included_header\"\n" if $DEBUG; + } elsif ($public_headers{$included_header}) { + print "Module API header \"$module_header\" includes public header \"$included_header\"\n" if $DEBUG; + } else { + print "Module API header \"$module_header\" includes unknown header \"$included_header\"\n"; + $exit_code = 1; + } + } + } + close HEADER; +} + + +for my $private_header (keys %private_headers) { + open HEADER, "<${private_header}"; + + while (
) { + if (/\#include[ \t]+.*/) { + chomp; + $included_header = $_; + $included_header =~ s/\#include[ \t]+.*/$1/; + + if ($private_headers{$included_header}) { + print "Private header \"$private_header\" includes private header \"$included_header\"\n" if $DEBUG; + } elsif ($module_headers{$included_header}) { + print "Private header \"$private_header\" includes module API header \"$included_header\"\n" if $DEBUG; + } elsif ($public_headers{$included_header}) { + print "Private header \"$private_header\" includes public header \"$included_header\"\n" if $DEBUG; + } else { + print "Private header \"$private_header\" includes unknown header \"$included_header\"\n"; + $exit_code = 1; + } + } + } + close HEADER; +} + +exit $exit_code; diff --git a/libgnomevfs/gnome-vfs-application-registry.c b/libgnomevfs/gnome-vfs-application-registry.c new file mode 100644 index 0000000..29565f3 --- /dev/null +++ b/libgnomevfs/gnome-vfs-application-registry.c @@ -0,0 +1,1999 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* gnome-vfs-mime-info.c - GNOME mime-information implementation. + + Copyright (C) 1998 Miguel de Icaza + Copyright (C) 2000 Eazel, Inc + All rights reserved. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ +/* + * Authors: George Lebl + * Based on original mime-info database code by Miguel de Icaza + */ + +#include "config.h" +#include "gnome-vfs-application-registry.h" +#include "gnome-vfs-configuration.h" +#include "gnome-vfs-mime-handlers.h" +#include "gnome-vfs-mime-private.h" +#include "gnome-vfs-mime.h" +#include "gnome-vfs-private-utils.h" +#include "gnome-vfs-result.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined getc_unlocked && !defined HAVE_GETC_UNLOCKED +# define getc_unlocked(fp) getc (fp) +#endif + +typedef struct _Application Application; +struct _Application { + char *app_id; + int ref_count; + /* The following is true if this was found in the + * home directory or if the user changed any keys + * here. It means that it will be saved into a user + * file */ + gboolean user_owned; + GHashTable *keys; + GnomeVFSMimeApplicationArgumentType expects_uris; + GList *mime_types; + GList *supported_uri_schemes; + /* The user_owned version of this if this is a system + * version */ + Application *user_application; +}; + +/* Describes the directories we scan for information */ +typedef struct { + char *dirname; + unsigned int valid : 1; + unsigned int system_dir : 1; +} ApplicationRegistryDir; + +/* These ones are used to automatically reload mime info on demand */ +static FileDateTracker *registry_date_tracker; +static ApplicationRegistryDir gnome_registry_dir; +static ApplicationRegistryDir user_registry_dir; + +/* To initialize the module automatically */ +static gboolean gnome_vfs_application_registry_initialized = FALSE; + + +static GList *current_lang = NULL; +/* we want to replace the previous key if the current key has a higher + language level */ +static char *previous_key = NULL; +static int previous_key_lang_level = -1; + +/* + * A hash table containing application registry record (Application) + * keyed by application ids. + */ +static GHashTable *global_applications = NULL; +/* + * A hash table containing GList's of application registry records (Application) + * keyed by the mime types + */ +/* specific mime_types (e.g. image/png) */ +static GHashTable *specific_mime_types = NULL; +/* generic mime_types (e.g. image/) */ +static GHashTable *generic_mime_types = NULL; + +/* + * Dirty flag, just to make sure we don't sync needlessly + */ +static gboolean user_file_dirty = FALSE; + +/* + * Some local prototypes + */ +static void gnome_vfs_application_registry_init (void); +static void application_clear_mime_types (Application *application); + +static Application * +application_ref (Application *application) +{ + g_return_val_if_fail(application != NULL, NULL); + + application->ref_count ++; + + return application; +} + +static void +hash_foreach_free_key_value(gpointer key, gpointer value, gpointer user_data) +{ + g_free(key); + g_free(value); +} + +static void +application_unref (Application *application) +{ + g_return_if_fail(application != NULL); + + application->ref_count --; + + if (application->ref_count == 0) { + application_clear_mime_types (application); + + if (application->keys != NULL) { + g_hash_table_foreach(application->keys, hash_foreach_free_key_value, NULL); + g_hash_table_destroy(application->keys); + application->keys = NULL; + } + + g_free(application->app_id); + application->app_id = NULL; + + if (application->user_application != NULL) { + application_unref (application->user_application); + application->user_application = NULL; + } + + g_free(application); + } +} + +static Application * +application_new (const char *app_id, gboolean user_owned) +{ + Application *application; + + application = g_new0 (Application, 1); + application->app_id = g_strdup(app_id); + application->ref_count = 1; + application->expects_uris = GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_PATHS; + application->user_owned = user_owned; + + return application; +} + +static Application * +application_lookup_or_create (const char *app_id, gboolean user_owned) +{ + Application *application; + + g_return_val_if_fail(app_id != NULL, NULL); + + gnome_vfs_application_registry_init (); + + application = g_hash_table_lookup (global_applications, app_id); + if (application != NULL) { + if ( ! user_owned) { + /* if we find only a user app, do magic */ + if (application->user_owned) { + Application *new_application; + new_application = application_new (app_id, FALSE/*user_owned*/); + new_application->user_application = application; + /* override the user application */ + g_hash_table_insert (global_applications, new_application->app_id, + new_application); + return new_application; + } else { + return application; + } + } else { + if (application->user_owned) { + return application; + } if (application->user_application != NULL) { + return application->user_application; + } else { + Application *new_application; + new_application = application_new (app_id, TRUE/*user_owned*/); + application->user_application = new_application; + return new_application; + } + } + } + + application = application_new (app_id, user_owned); + + g_hash_table_insert (global_applications, application->app_id, application); + + return application; +} + +static Application * +application_lookup (const char *app_id) +{ + g_return_val_if_fail(app_id != NULL, NULL); + + if (global_applications == NULL) + return NULL; + + return g_hash_table_lookup (global_applications, app_id); +} + +static const char * +peek_value (const Application *application, const char *key) +{ + g_return_val_if_fail(application != NULL, NULL); + g_return_val_if_fail(key != NULL, NULL); + + if (application->keys == NULL) + return NULL; + + return g_hash_table_lookup (application->keys, key); +} + +static void +set_value (Application *application, const char *key, const char *value) +{ + char *old_value, *old_key; + + g_return_if_fail(application != NULL); + g_return_if_fail(key != NULL); + g_return_if_fail(value != NULL); + + if (application->keys == NULL) + application->keys = g_hash_table_new (g_str_hash, g_str_equal); + + if (g_hash_table_lookup_extended (application->keys, key, + (gpointer *)&old_key, + (gpointer *)&old_value)) { + g_hash_table_insert (application->keys, + old_key, g_strdup (value)); + g_free (old_value); + } else { + g_hash_table_insert (application->keys, + g_strdup (key), g_strdup (value)); + } +} + +static void +unset_key (Application *application, const char *key) +{ + char *old_value, *old_key; + + g_return_if_fail(application != NULL); + g_return_if_fail(key != NULL); + + if (application->keys == NULL) + return; + + if (g_hash_table_lookup_extended (application->keys, key, + (gpointer *)&old_key, + (gpointer *)&old_value)) { + g_hash_table_remove (application->keys, old_key); + g_free (old_key); + g_free (old_value); + } +} + +static gboolean +value_looks_true (const char *value) +{ + if (value && + (value[0] == 'T' || + value[0] == 't' || + value[0] == 'Y' || + value[0] == 'y' || + atoi (value) != 0)) { + return TRUE; + } else { + return FALSE; + } +} + +static gboolean +get_bool_value (const Application *application, const char *key, + gboolean *got_key) +{ + const char *value = peek_value (application, key); + if (got_key) { + if (value != NULL) + *got_key = TRUE; + else + *got_key = FALSE; + } + return value_looks_true (value); + +} + +static void +set_bool_value (Application *application, const char *key, + gboolean value) +{ + set_value (application, key, value ? "true" : "false"); +} + +static int +application_compare (Application *application1, + Application *application2) +{ + return strcmp (application1->app_id, application2->app_id); +} + +static void +add_application_to_mime_type_table (Application *application, + const char *mime_type) +{ + GList *application_list; + GHashTable *table; + char *old_key; + + if (gnome_vfs_mime_type_is_supertype (mime_type)) + table = generic_mime_types; + else + table = specific_mime_types; + + g_assert (table != NULL); + + if (g_hash_table_lookup_extended (table, mime_type, + (gpointer *)&old_key, + (gpointer *)&application_list)) { + /* Sorted order is important as we can then easily + * uniquify the results */ + application_list = g_list_insert_sorted + (application_list, + application_ref (application), + (GCompareFunc) application_compare); + g_hash_table_insert (table, old_key, application_list); + } else { + application_list = g_list_prepend (NULL, + application_ref (application)); + g_hash_table_insert (table, g_strdup (mime_type), application_list); + } +} + +static void +add_mime_type_to_application (Application *application, const char *mime_type) +{ + /* if this exists already, just return */ + if (g_list_find_custom (application->mime_types, + /*glib is const incorrect*/(gpointer)mime_type, + (GCompareFunc) strcmp) != NULL) + return; + + application->mime_types = + g_list_prepend (application->mime_types, + g_strdup (mime_type)); + + add_application_to_mime_type_table (application, mime_type); + +} + +static void +add_supported_uri_scheme_to_application (Application *application, + const char *supported_uri_scheme) +{ + if (g_list_find_custom (application->supported_uri_schemes, + /*glib is const incorrect*/(gpointer) supported_uri_scheme, + (GCompareFunc) strcmp) != NULL) { + return; + } + + application->supported_uri_schemes = + g_list_prepend (application->supported_uri_schemes, + g_strdup (supported_uri_scheme)); + +} + +static GList * +supported_uri_scheme_list_copy (GList *supported_uri_schemes) +{ + GList *copied_list, *node; + + copied_list = NULL; + for (node = supported_uri_schemes; node != NULL; + node = node->next) { + copied_list = g_list_prepend (copied_list, + g_strdup ((char *) node->data)); + } + + return copied_list; +} + +static void +remove_application_from_mime_type_table (Application *application, + const char *mime_type) +{ + GHashTable *table; + char *old_key; + GList *application_list, *entry; + + if (gnome_vfs_mime_type_is_supertype (mime_type)) + table = generic_mime_types; + else + table = specific_mime_types; + + g_assert (table != NULL); + + if (g_hash_table_lookup_extended (table, mime_type, + (gpointer *)&old_key, + (gpointer *)&application_list)) { + entry = g_list_find (application_list, application); + + /* if this fails we're in deep doodoo I guess */ + g_assert (entry != NULL); + + application_list = g_list_remove_link (application_list, entry); + entry->data = NULL; + application_unref (application); + + if (application_list != NULL) { + g_hash_table_insert (table, old_key, application_list); + } else { + g_hash_table_remove (table, old_key); + g_free(old_key); + } + } else + g_assert_not_reached (); +} + +static void +remove_mime_type_for_application (Application *application, const char *mime_type) +{ + GList *entry; + + g_return_if_fail(application != NULL); + g_return_if_fail(mime_type != NULL); + + entry = g_list_find_custom + (application->mime_types, + /*glib is const incorrect*/(gpointer)mime_type, + (GCompareFunc) strcmp); + + /* if this doesn't exist, just return */ + if (entry == NULL) { + return; + } + + remove_application_from_mime_type_table (application, mime_type); + + /* Free data last, in case caller passed in mime_type string + * that was stored in this table. + */ + application->mime_types = + g_list_remove_link (application->mime_types, entry); + g_free (entry->data); + g_list_free_1 (entry); +} + + +static void +application_clear_mime_types (Application *application) +{ + g_return_if_fail (application != NULL); + + while (application->mime_types) + remove_mime_type_for_application (application, application->mime_types->data); +} + +static void +application_remove (Application *application) +{ + Application *main_application; + + g_return_if_fail (application != NULL); + + if (global_applications == NULL) { + return; + } + + main_application = application_lookup (application->app_id); + if (main_application == NULL) { + return; + } + + /* We make sure the mime types are killed even if the application + * entry lives after unreffing it */ + application_clear_mime_types (application); + + if (main_application == application) { + if (application->user_application) + application_clear_mime_types (application->user_application); + + g_hash_table_remove (global_applications, application->app_id); + } else { + /* This must be a user application */ + g_assert (main_application->user_application == application); + + main_application->user_application = NULL; + } + + application_unref (application); + +} + +static void +sync_key (gpointer key, gpointer value, gpointer user_data) +{ + char *key_string = key; + char *value_string = value; + FILE *fp = user_data; + + fprintf (fp, "\t%s=%s\n", key_string, value_string); +} + +/* write an application to a file */ +static void +application_sync (Application *application, FILE *fp) +{ + GList *li; + + g_return_if_fail (application != NULL); + g_return_if_fail (application->app_id != NULL); + g_return_if_fail (fp != NULL); + + fprintf (fp, "%s\n", application->app_id); + + if (application->keys != NULL) + g_hash_table_foreach (application->keys, sync_key, fp); + + if (application->mime_types != NULL) { + char *separator; + fprintf (fp, "\tmime_types="); + separator = ""; + for (li = application->mime_types; li != NULL; li = li->next) { + char *mime_type = li->data; + fprintf (fp, "%s%s", separator, mime_type); + separator = ","; + } + fprintf (fp, "\n"); + } + fprintf (fp, "\n"); +} + + +/* this gives us a number of the language in the current language list, + the higher the number the "better" the translation */ +static int +language_level (const char *lang) +{ + int i; + GList *li; + + if (lang == NULL) + return 0; + + for (i = 1, li = current_lang; li != NULL; i++, li = g_list_next (li)) { + if (strcmp ((const char *) li->data, lang) == 0) + return i; + } + + return -1; +} + + +static void +application_add_key (Application *application, const char *key, + const char *lang, const char *value) +{ + int lang_level; + + g_return_if_fail (application != NULL); + g_return_if_fail (key != NULL); + g_return_if_fail (value != NULL); + + if (strcmp (key, "mime_types") == 0 || + strcmp (key, "supported_uri_schemes") == 0) { + char *value_copy = g_strdup (value); + char *next_value; + /* FIXME: There used to be a check here for + the value of "lang", but spamming + the terminal about it is not really + the right way to deal with that, nor + is "MIME Types can't have languages, bad!" + which is what was here before */ + next_value = strtok (value_copy, ", \t"); + while (next_value != NULL) { + if (strcmp (key, "mime_types") == 0) { + add_mime_type_to_application (application, next_value); + } + else { + add_supported_uri_scheme_to_application (application, next_value); + } + next_value = strtok (NULL, ", \t"); + } + g_free(value_copy); + /* fall through so that we can store the values as keys too */ + } + else if (strcmp (key, "expects_uris") == 0) { + if (strcmp (value, "non-file") == 0) { + application->expects_uris = GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_URIS_FOR_NON_FILES; + } + else if (value_looks_true (value)) { + application->expects_uris = GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_URIS; + } + else { + application->expects_uris = GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_PATHS; + } + } + + lang_level = language_level (lang); + /* wrong language completely */ + if (lang_level < 0) + return; + + /* if we have some language defined and + if there was a previous_key */ + if (lang_level > 0 && + previous_key && + /* our language level really sucks and the previous + translation was of better language quality so just + ignore us */ + previous_key_lang_level > lang_level) { + return; + } + + set_value (application, key, value); + + /* set this as the previous key */ + g_free(previous_key); + previous_key = g_strdup(key); + previous_key_lang_level = lang_level; +} + +typedef enum { + STATE_NONE, + STATE_LANG, + STATE_LOOKING_FOR_KEY, + STATE_ON_APPLICATION, + STATE_ON_KEY, + STATE_ON_VALUE +} ParserState; + +/** + * strip_trailing_whitespace + * + * string + * + * strips the white space from a string. + * + */ + +static void +strip_trailing_whitespace (GString *string) +{ + int i; + + for (i = string->len - 1; i >= 0; i--) { + if (!g_ascii_isspace (string->str[i])) + break; + } + + g_string_truncate (string, i + 1); +} + +/** + * load_application_info_from + * + * filename: Target filename to application info from. + * user_owned: if application is user owned or not. + * + * This function will load application info from a file and parse through the + * application loading the registry with the information contained in the file. + * + * + **/ + +static void +load_application_info_from (const char *filename, gboolean user_owned) +{ + FILE *fp; + gboolean in_comment, app_used; + GString *line; + int column, c; + ParserState state; + Application *application; + char *key; + char *lang; + + fp = fopen (filename, "r"); + if (fp == NULL) + return; + + in_comment = FALSE; + app_used = FALSE; + column = -1; + application = NULL; + key = NULL; + lang = NULL; + line = g_string_sized_new (120); + state = STATE_NONE; + + while ((c = getc_unlocked (fp)) != EOF){ + column++; + if (c == '\r') + continue; + + if (c == '#' && column == 0){ + in_comment = TRUE; + continue; + } + + if (c == '\n'){ + in_comment = FALSE; + column = -1; + if (state == STATE_ON_APPLICATION) { + + /* set previous key to nothing + for this mime type */ + g_free(previous_key); + previous_key = NULL; + previous_key_lang_level = -1; + + strip_trailing_whitespace (line); + application = application_lookup_or_create (line->str, user_owned); + app_used = FALSE; + g_string_assign (line, ""); + state = STATE_LOOKING_FOR_KEY; + continue; + } + if (state == STATE_ON_VALUE){ + app_used = TRUE; + application_add_key (application, key, lang, line->str); + g_string_assign (line, ""); + g_free (key); + key = NULL; + g_free (lang); + lang = NULL; + state = STATE_LOOKING_FOR_KEY; + continue; + } + continue; + } + + if (in_comment) + continue; + + switch (state){ + case STATE_NONE: + if (c != ' ' && c != '\t') + state = STATE_ON_APPLICATION; + else + break; + /* fall down */ + + case STATE_ON_APPLICATION: + if (c == ':'){ + in_comment = TRUE; + break; + } + g_string_append_c (line, c); + break; + + case STATE_LOOKING_FOR_KEY: + if (c == '\t' || c == ' ') + break; + + if (c == '['){ + state = STATE_LANG; + break; + } + + if (column == 0){ + state = STATE_ON_APPLICATION; + g_string_append_c (line, c); + break; + } + state = STATE_ON_KEY; + /* falldown */ + + case STATE_ON_KEY: + if (c == '\\'){ + c = getc (fp); + if (c == EOF) + break; + } + if (c == '='){ + key = g_strdup (line->str); + g_string_assign (line, ""); + state = STATE_ON_VALUE; + break; + } + g_string_append_c (line, c); + break; + + case STATE_ON_VALUE: + g_string_append_c (line, c); + break; + + case STATE_LANG: + if (c == ']'){ + state = STATE_ON_KEY; + if (line->str [0]){ + g_free(lang); + lang = g_strdup(line->str); + } else { + in_comment = TRUE; + state = STATE_LOOKING_FOR_KEY; + } + g_string_assign (line, ""); + break; + } + g_string_append_c (line, c); + break; + } + } + + if (application){ + if (key && line->str [0]) + application_add_key (application, key, lang, line->str); + else + if ( ! app_used) + application_remove (application); + } + + g_string_free (line, TRUE); + g_free (key); + g_free (lang); + + /* free the previous_key stuff */ + g_free(previous_key); + previous_key = NULL; + previous_key_lang_level = -1; + + fclose (fp); + + _gnome_vfs_file_date_tracker_start_tracking_file (registry_date_tracker, filename); +} + +/** + * application_info_load + * + * source: + * + * + */ + +static void +application_info_load (ApplicationRegistryDir *source) +{ + DIR *dir; + struct dirent *dent; + const int extlen = sizeof (".applications") - 1; + char *filename; + struct stat s; + + if (stat (source->dirname, &s) != -1) + source->valid = TRUE; + else + source->valid = FALSE; + + dir = opendir (source->dirname); + if (dir == NULL) { + source->valid = FALSE; + return; + } + if (source->system_dir) { + filename = g_strconcat (source->dirname, "/gnome-vfs.applications", NULL); + load_application_info_from (filename, FALSE /*user_owned*/); + g_free (filename); + } + + while ((dent = readdir (dir)) != NULL){ + + int len = strlen (dent->d_name); + + if (len <= extlen) + continue; + if (strcmp (dent->d_name + len - extlen, ".applications")) + continue; + if (source->system_dir && strcmp (dent->d_name, "gnome-vfs.applications") == 0) + continue; + if ( ! source->system_dir && strcmp (dent->d_name, "user.applications") == 0) + continue; + filename = g_strconcat (source->dirname, "/", dent->d_name, NULL); + load_application_info_from (filename, FALSE /*user_owned*/); + g_free (filename); + } + + if ( ! source->system_dir) { + filename = g_strconcat (source->dirname, "/user.applications", NULL); + /* Currently this is the only file that is "user owned". It actually makes + * sense. Editting of other files from the API would be too complex */ + load_application_info_from (filename, TRUE /*user_owned*/); + g_free (filename); + } + closedir (dir); + + _gnome_vfs_file_date_tracker_start_tracking_file (registry_date_tracker, source->dirname); +} + +/** + * load_application_info + * + * This function will load the registry for an application from disk. + **/ + +static void +load_application_info (void) +{ + application_info_load (&gnome_registry_dir); + application_info_load (&user_registry_dir); +} + +/** + * gnome_vfs_application_registry_init + * + * This function initializes the gnome-vfs application registry. + **/ + +static void +gnome_vfs_application_registry_init (void) +{ + if (gnome_vfs_application_registry_initialized) + return; + + registry_date_tracker = _gnome_vfs_file_date_tracker_new (); + + /* + * The hash tables that store the mime keys. + */ + global_applications = g_hash_table_new (g_str_hash, g_str_equal); + generic_mime_types = g_hash_table_new (g_str_hash, g_str_equal); + specific_mime_types = g_hash_table_new (g_str_hash, g_str_equal); + + current_lang = gnome_vfs_i18n_get_language_list ("LC_MESSAGES"); + + /* + * Setup the descriptors for the information loading + */ + + gnome_registry_dir.dirname = g_strdup (DATADIR "/application-registry"); + gnome_registry_dir.system_dir = TRUE; + + user_registry_dir.dirname = g_strconcat (g_get_home_dir(), "/.gnome/application-info", NULL); + user_registry_dir.system_dir = FALSE; + + /* Make sure user directory exists */ + if (mkdir (user_registry_dir.dirname, 0700) && + errno != EEXIST) { + g_warning("Could not create per-user Gnome application-registry directory: %s", + user_registry_dir.dirname); + } + + /* Things have been initialized flag it as ready so that we can load + * the applications without attempting to reinitialize + */ + gnome_vfs_application_registry_initialized = TRUE; + + load_application_info (); +} + +/* + * maybe_reload + * + * This function will initialize the registry in memory and then reloads the + * + */ + +static void +maybe_reload (void) +{ + gnome_vfs_application_registry_init (); + + if (!_gnome_vfs_file_date_tracker_date_has_changed (registry_date_tracker)) { + return; + } + + gnome_vfs_application_registry_reload (); +} + +/** + * remove_apps + * + * key: + * value: + * user_data: + * + * FIXME: I need a clearer explanation on what this does. + * + */ + +static gboolean +remove_apps (gpointer key, gpointer value, gpointer user_data) +{ + Application *application = value; + + application_clear_mime_types (application); + + application_unref (application); + + return TRUE; +} + +/** + * gnome_vfs_application_registry_clear: + * + * This will wipe the registry clean removing everything from the registry. + * This is different from gnome_vfs_application_registry_shutdown which will + * actually delete the registry and leave it in an uninitialized state. + * + */ + +static void +gnome_vfs_application_registry_clear (void) +{ + if (global_applications != NULL) + g_hash_table_foreach_remove (global_applications, remove_apps, NULL); +} + +/** + * gnome_vfs_application_registry_shutdown + * + * Synchronize gnome-vfs application registry data to disk, and free + * resources. + * + */ + +void +gnome_vfs_application_registry_shutdown (void) +{ + gnome_vfs_application_registry_clear (); + + if (global_applications != NULL) { + g_hash_table_destroy (global_applications); + global_applications = NULL; + } + + if(generic_mime_types != NULL) { + g_hash_table_destroy (generic_mime_types); + generic_mime_types = NULL; + } + + if(specific_mime_types != NULL) { + g_hash_table_destroy (specific_mime_types); + specific_mime_types = NULL; + } + + _gnome_vfs_file_date_tracker_free (registry_date_tracker); + + g_free(gnome_registry_dir.dirname); + gnome_registry_dir.dirname = NULL; + g_free(user_registry_dir.dirname); + user_registry_dir.dirname = NULL; + + g_list_free(current_lang); + current_lang = NULL; + + gnome_vfs_application_registry_initialized = FALSE; +} + + +/** + * gnome_vfs_application_registry_reload + * + * If this function is called for the first time it will initialize the + * registry. Subsequent calls to the function will clear out the current + * registry contents and load registry contents from the save file. Make + * certain that you've saved your registry before calling this function. It + * will destroy unsaved changes. + * + */ + +void +gnome_vfs_application_registry_reload (void) +{ + if ( ! gnome_vfs_application_registry_initialized) { + /* If not initialized, initialization will do a "reload" */ + gnome_vfs_application_registry_init (); + } else { + gnome_vfs_application_registry_clear (); + load_application_info (); + } +} + +/* + * Existance check + */ + +/** + * gnome_vfs_application_registry_exists + * @app_id: an application ID + * + * This function will return TRUE if there is an entry for @app_id in + * the registry, otherwise FALSE. + * + * Returns: TRUE if the application is in the registry, FALSE if not + * + */ + +gboolean +gnome_vfs_application_registry_exists (const char *app_id) +{ + g_return_val_if_fail (app_id != NULL, FALSE); + + maybe_reload (); + + if (application_lookup (app_id) != NULL) + return TRUE; + else + return FALSE; +} + + +/* + * Getting arbitrary keys + */ + + +/** + * get_keys_foreach + * + * key: + * user_data: + * + * FIXME: I have no idea what this function does. + **/ + +static void +get_keys_foreach(gpointer key, gpointer value, gpointer user_data) +{ + GList **listp = user_data; + + /* make sure we only insert unique keys */ + if ( (*listp) && strcmp ((const char *) (*listp)->data, (const char *) key) == 0) + return; + + (*listp) = g_list_insert_sorted ((*listp), key, + (GCompareFunc) strcmp); +} + +/** + * gnome_vfs_application_registry_get_keys: + * @app_id: the application ID for which to get keys + * + * This function wil return a list of strings which is the list of + * keys set for @app_id in the application registry. + * + * Returns: A list of the keys set for @app_id + * + */ + +GList * +gnome_vfs_application_registry_get_keys (const char *app_id) +{ + GList *retval; + Application *application; + + g_return_val_if_fail (app_id != NULL, NULL); + + maybe_reload (); + + application = application_lookup (app_id); + if (application == NULL) + return NULL; + + retval = NULL; + + if (application->keys != NULL) + g_hash_table_foreach (application->keys, get_keys_foreach, + &retval); + + if (application->user_application != NULL && + application->user_application->keys) + g_hash_table_foreach (application->user_application->keys, + get_keys_foreach, &retval); + + return retval; +} + + +/** + * real_peek_value: + * + * @application: registry application + * @key: target key + * + * Returns: the value associated with the key, or NULL if there is no + * associated value. + * + * This function looks and returns the value of the target key in the registry + * application + * + */ + +static const char * +real_peek_value (const Application *application, const char *key) +{ + const char *retval; + + g_return_val_if_fail (application != NULL, NULL); + g_return_val_if_fail (key != NULL, NULL); + + retval = NULL; + + if (application->user_application) + retval = peek_value (application->user_application, key); + + if (retval == NULL) + retval = peek_value (application, key); + + return retval; +} + +/** + * real_get_bool_value + * + * application: Application structure + * key: taget key + * got_key: actual key stored in application if key exists. + * + * This function will try to determine whether a key exists in the application. + * It first checks the user applications and then the system applications and + * then returns whether the key exists and what the value is from the value of + * got_key. + * + * Returns: gboolean + **/ + +static gboolean +real_get_bool_value (const Application *application, const char *key, gboolean *got_key) +{ + gboolean sub_got_key, retval; + + g_return_val_if_fail (application != NULL, FALSE); + g_return_val_if_fail (key != NULL, FALSE); + + sub_got_key = FALSE; + retval = FALSE; + if (application->user_application) + retval = get_bool_value (application->user_application, key, + &sub_got_key); + + if ( ! sub_got_key) + retval = get_bool_value (application, key, &sub_got_key); + + if (got_key != NULL) + *got_key = sub_got_key; + + return retval; +} + + +/** + * gnome_vfs_application_registry_peek_value + * @app_id: the application ID for which to look up a value + * @key: the key to look up + * + * This will return the value associated with @key for @app_id in the + * application registry. There is no need to free the return value. + * + * Returns: the value associated with the key, or NULL if there is no + * associated value + * + */ + +const char * +gnome_vfs_application_registry_peek_value (const char *app_id, const char *key) +{ + Application *application; + + g_return_val_if_fail (app_id != NULL, NULL); + g_return_val_if_fail (key != NULL, NULL); + + maybe_reload (); + + application = application_lookup (app_id); + if (application == NULL) + return NULL; + + return real_peek_value (application, key); +} + +/** + * gnome_vfs_application_registry_get_bool_value + * @app_id: registry id of the application + * @key: key to look up + * @got_key: TRUE if a setting was dound, otherwise FALSE + * + * This will look up a key in the structure pointed to by app_id and return the + * boolean value of that key. It will return false if there are no + * applications associated with the app_id. + * + * Returns: TRUE if @key is set to "true" or "yes" for @app_id, otherwise FALSE + * + */ + +gboolean +gnome_vfs_application_registry_get_bool_value (const char *app_id, const char *key, + gboolean *got_key) +{ + Application *application; + + g_return_val_if_fail (app_id != NULL, FALSE); + g_return_val_if_fail (key != NULL, FALSE); + + maybe_reload (); + + application = application_lookup (app_id); + if (application == NULL) + return FALSE; + + return real_get_bool_value (application, key, got_key); +} + +/* + * Setting stuff + */ + +/** + * gnome_vfs_application_registry_remove_application + * @app_id: registry id of the application + * + * Given the registry id this function will remove all applications that has + * been set by the user. You will need to call + * gnome_vfs_application_registry_sync to save the changes. + * + */ + +void +gnome_vfs_application_registry_remove_application (const char *app_id) +{ + Application *application; + + g_return_if_fail (app_id != NULL); + + maybe_reload (); + + application = application_lookup (app_id); + if (application == NULL) + return; + + /* Only remove the user_owned stuff */ + if (application->user_owned) { + application_remove (application); + user_file_dirty = TRUE; + } else if (application->user_application != NULL) { + application_remove (application->user_application); + user_file_dirty = TRUE; + } +} + +/** + * gnome_vfs_application_registry_set_value + * @app_id: registry id of the application + * @key: target key + * @value: value to set the target key to + * + * This function will set values pertaining to registry entry pointed to by + * app_id. You will need to call gnome_vfs_application_registry_sync to + * realize the changes. + * + */ + +void +gnome_vfs_application_registry_set_value (const char *app_id, + const char *key, + const char *value) +{ + Application *application; + + g_return_if_fail (app_id != NULL); + g_return_if_fail (key != NULL); + g_return_if_fail (value != NULL); + + maybe_reload (); + + application = application_lookup_or_create (app_id, TRUE/*user_owned*/); + + set_value (application, key, value); + + user_file_dirty = TRUE; +} + +/** + * gnome_vfs_application_registry_set_bool_value: + * @app_id: registry id of the application + * @key: target key + * @value: value you want to set the target key to + * + * This function will modify those registry values that are of type boolean to + * a value specified by the user. You will need to call + * gnome_vfs_application_registry_sync to save your changes. + * + */ +void +gnome_vfs_application_registry_set_bool_value (const char *app_id, + const char *key, + gboolean value) +{ + Application *application; + + g_return_if_fail (app_id != NULL); + g_return_if_fail (key != NULL); + + maybe_reload (); + + application = application_lookup_or_create (app_id, TRUE/*user_owned*/); + + set_bool_value (application, key, value); + + user_file_dirty = TRUE; +} + +/** + * gnome_vfs_application_registry_unset_key: + * @app_id: registry id of the application + * @key: search key + * + * This function given the application and the target will wipe the current + * value that the key contains. + * + */ + +void +gnome_vfs_application_registry_unset_key (const char *app_id, + const char *key) +{ + Application *application; + + g_return_if_fail (app_id != NULL); + g_return_if_fail (key != NULL); + + maybe_reload (); + + application = application_lookup_or_create (app_id, TRUE/*user_owned*/); + + unset_key (application, key); + + user_file_dirty = TRUE; +} + +/* + * Query functions + */ + + +static void +cb_application_collect (gpointer key, gpointer value, gpointer user_data) +{ + Application *application = value; + GList **list = user_data; + *list = g_list_prepend (*list, application->app_id); +} + +/** + * gnome_vfs_application_registry_get_applications + * @mime_type: mime type string + * + * This will return all applications from the registry that are associated with + * the given mime type string, if NULL it returns all applications. + * + * Returns: a list of the application IDs for all applications which + * support the given mime type. + * + */ + +GList * +gnome_vfs_application_registry_get_applications (const char *mime_type) +{ + GList *app_list, *app_list2, *retval, *li; + char *supertype; + + retval = NULL; + app_list2 = NULL; + + maybe_reload (); + + if (mime_type == NULL) { + g_hash_table_foreach (global_applications, cb_application_collect, &retval); + return retval; + } + + if (gnome_vfs_mime_type_is_supertype (mime_type)) { + app_list = g_hash_table_lookup (generic_mime_types, mime_type); + } else { + app_list = g_hash_table_lookup (specific_mime_types, mime_type); + + supertype = gnome_vfs_get_supertype_from_mime_type (mime_type); + if (supertype != NULL) { + app_list2 = g_hash_table_lookup (generic_mime_types, supertype); + g_free (supertype); + } + } + + for (li = app_list; li != NULL; li = li->next) { + Application *application = li->data; + /* Note that this list is sorted so to kill duplicates + * in app_list we only need to check the first entry */ + if (retval == NULL || + strcmp ((const char *) retval->data, application->app_id) != 0) + retval = g_list_prepend (retval, application->app_id); + } + + for (li = app_list2; li != NULL; li = li->next) { + Application *application = li->data; + if (g_list_find_custom (retval, application->app_id, + (GCompareFunc) strcmp) == NULL) + retval = g_list_prepend (retval, application->app_id); + } + + return retval; +} + +/** + * gnome_vfs_application_registry_get_mime_types + * @app_id: registry id of application + * + * This function returns a list of strings that represent the mime + * types that can be handled by an application. + * + * Returns: a list of the mime types supported + * + */ + +GList * +gnome_vfs_application_registry_get_mime_types (const char *app_id) +{ + Application *application; + GList *retval; + + g_return_val_if_fail (app_id != NULL, NULL); + + maybe_reload (); + + application = application_lookup (app_id); + if (application == NULL) + return NULL; + + retval = g_list_copy (application->mime_types); + + /* merge in the mime types from the user_application, + * if it exists */ + if (application->user_application) { + GList *li; + for (li = application->user_application->mime_types; + li != NULL; + li = li->next) { + Application *application = li->data; + if (g_list_find_custom (retval, application->app_id, + (GCompareFunc) strcmp) == NULL) + retval = g_list_prepend (retval, + application->app_id); + } + } + + return retval; +} + +/** + * gnome_vfs_application_registry_supports_uri_scheme + * @app_id: registry id of application + * @uri_scheme: uri schme string + * + * Given the id of the application this function will determine if the + * uri scheme will given is supported. + * + * Returns: TRUE if @app_id supports @uri_scheme, otherwise FALSE + * + */ + +gboolean +gnome_vfs_application_registry_supports_uri_scheme (const char *app_id, + const char *uri_scheme) +{ + Application *application; + gboolean uses_gnomevfs; + + g_return_val_if_fail (app_id != NULL, FALSE); + g_return_val_if_fail (uri_scheme != NULL, FALSE); + + maybe_reload (); + + application = application_lookup (app_id); + if (application == NULL) + return FALSE; + + uses_gnomevfs = real_get_bool_value (application, GNOME_VFS_APPLICATION_REGISTRY_USES_GNOMEVFS, NULL); + + if (strcmp (uri_scheme, "file") == 0 && + uses_gnomevfs == FALSE && + application->supported_uri_schemes == NULL && + application->user_application->supported_uri_schemes == NULL) { + return TRUE; + } + + /* check both the application and the user application + * mime_types lists */ + /* FIXME: This method does not allow a user to override and remove + uri schemes that an application can handle. Is this an issue? */ + + if ((g_list_find_custom (application->supported_uri_schemes, + /*glib is const incorrect*/(gpointer)uri_scheme, + (GCompareFunc) strcmp) != NULL) || + (application->user_application && + g_list_find_custom (application->user_application->supported_uri_schemes, + /*glib is const incorrect*/(gpointer) uri_scheme, + (GCompareFunc) strcmp) != NULL)) { + return TRUE; + } + /* check in the list of uris supported by gnome-vfs if necessary */ + else if (uses_gnomevfs) { + GList *supported_uris; + gboolean res; + + supported_uris = _gnome_vfs_configuration_get_methods_list(); + res = (g_list_find_custom(supported_uris, + /*glib is const incorrect*/(gpointer) uri_scheme, + (GCompareFunc) strcmp) != NULL); + + g_list_foreach(supported_uris, (GFunc) g_free, NULL); + g_list_free(supported_uris); + + return res; + } + + return FALSE; +} + +/** + * gnome_vfs_application_registry_supports_mime_type + * @app_id: registry id of application + * @mime_type: mime type string + * + * Use this function to see if there is an application associated with a given + * mime type. The function will return true or false. + * + * Returns: TRUE if @app_id supports @mime_type, otherwise FALSE. + * + */ + +gboolean +gnome_vfs_application_registry_supports_mime_type (const char *app_id, + const char *mime_type) +{ + Application *application; + + g_return_val_if_fail (app_id != NULL, FALSE); + g_return_val_if_fail (mime_type != NULL, FALSE); + + maybe_reload (); + + application = application_lookup (app_id); + if (application == NULL) + return FALSE; + + /* check both the application and the user application + * mime_types lists */ + /* FIXME: This method does not allow a user to override and remove + mime types that an application can handle. Is this an issue? */ + if ((g_list_find_custom (application->mime_types, + /*glib is const incorrect*/(gpointer)mime_type, + (GCompareFunc) strcmp) != NULL) || + (application->user_application && + g_list_find_custom (application->user_application->mime_types, + /*glib is const incorrect*/(gpointer)mime_type, + (GCompareFunc) strcmp) != NULL)) + return TRUE; + else + return FALSE; +} + + +/* + * Mime type functions + * Note that mime_type can be a specific (image/png) or generic (image/) type + */ + + +/** + * gnome_vfs_application_registry_clear_mime_types + * @app_id: Application id + * + * This function will remove the mime types associated with the application. + * Changes are not realized until the gnome_vfs_application_registry_sync + * function is called to save the changes to the file. + * + */ + +void +gnome_vfs_application_registry_clear_mime_types (const char *app_id) +{ + Application *application; + + g_return_if_fail (app_id != NULL); + + maybe_reload (); + + application = application_lookup_or_create (app_id, TRUE/*user_owned*/); + + application_clear_mime_types (application); + + user_file_dirty = TRUE; +} + +/** + * gnome_vfs_application_registry_add_mime_type + * @app_id: registry id of application + * @mime_type: mime type string + * + * This function will associate a mime type with an application given the + * application registry id and the mime type. Changes are not realized until + * the gnome_vfs_application_registry_sync function is called to save the + * changes to the file. + * + */ + +void +gnome_vfs_application_registry_add_mime_type (const char *app_id, + const char *mime_type) +{ + Application *application; + + g_return_if_fail (app_id != NULL); + g_return_if_fail (mime_type != NULL); + + maybe_reload (); + + application = application_lookup_or_create (app_id, TRUE/*user_owned*/); + + add_mime_type_to_application (application, mime_type); + + user_file_dirty = TRUE; +} + +/** + * gnome_vfs_application_registry_remove_mime_type + * @app_id: registry id of the application + * @mime_type: mime type string + * + * This function will de-associate a mime type from an application registry. + * Given the application registry id and the mime type. Changes are not + * realized until the gnome_vfs_application_registry_sync function is called to + * save the changes to the file. + * + */ + +void +gnome_vfs_application_registry_remove_mime_type (const char *app_id, + const char *mime_type) +{ + Application *application; + + g_return_if_fail (app_id != NULL); + + maybe_reload (); + + application = application_lookup_or_create (app_id, TRUE/*user_owned*/); + + remove_mime_type_for_application (application, mime_type); + + user_file_dirty = TRUE; +} + +/* + * Syncing to disk + */ + +static void +application_sync_foreach (gpointer key, gpointer value, gpointer user_data) +{ + Application *application = value; + FILE *fp = user_data; + + /* Only sync things that are user owned */ + if (application->user_owned) + application_sync (application, fp); + else if (application->user_application) + application_sync (application->user_application, fp); +} + +/** + * gnome_vfs_application_registry_sync + * + * This function will sync the registry. Typically you would use this function + * after a modification of the registry. When you modify the registry a dirty + * flag is set. Calling this function will save your modifications to disk and + * reset the flag. + * + * If successful, will return GNOME_VFS_OK + * + * Returns: GnomeVFSResult + * + */ + +GnomeVFSResult +gnome_vfs_application_registry_sync (void) +{ + FILE *fp; + char *file; + time_t curtime; + + if ( ! user_file_dirty) + return GNOME_VFS_OK; + + maybe_reload (); + + file = g_strconcat (user_registry_dir.dirname, "/user.applications", NULL); + fp = fopen (file, "w"); + + if ( ! fp) { + g_warning ("Cannot open '%s' for writing", file); + g_free (file); + return gnome_vfs_result_from_errno (); + } + + g_free (file); + + time(&curtime); + + fprintf (fp, "# This file is automatically generated by gnome-vfs " + "application registry\n" + "# Do NOT edit by hand\n# Generated: %s\n", + ctime (&curtime)); + + if (global_applications != NULL) + g_hash_table_foreach (global_applications, application_sync_foreach, fp); + + fclose (fp); + + user_file_dirty = FALSE; + + return GNOME_VFS_OK; +} + + +/** + * gnome_vfs_application_registry_get_mime_application + * @app_id: registry id of the application + * + * Returns a structure that contains the application that handles + * the mime type associated by the application referred by app_id. + * + * Returns: GnomeVFSMimeApplication + * + */ + +GnomeVFSMimeApplication * +gnome_vfs_application_registry_get_mime_application (const char *app_id) +{ + Application *i_application; + GnomeVFSMimeApplication *application; + gboolean uses_gnomevfs = FALSE; + + g_return_val_if_fail (app_id != NULL, NULL); + + maybe_reload (); + + i_application = application_lookup (app_id); + + if (i_application == NULL) + return NULL; + + application = g_new0 (GnomeVFSMimeApplication, 1); + + application->id = g_strdup (app_id); + + application->name = + g_strdup (real_peek_value + (i_application, + GNOME_VFS_APPLICATION_REGISTRY_NAME)); + application->command = + g_strdup (real_peek_value + (i_application, + GNOME_VFS_APPLICATION_REGISTRY_COMMAND)); + + application->can_open_multiple_files = + real_get_bool_value + (i_application, + GNOME_VFS_APPLICATION_REGISTRY_CAN_OPEN_MULTIPLE_FILES, + NULL); + application->expects_uris = i_application->expects_uris; + application->supported_uri_schemes = + supported_uri_scheme_list_copy (i_application->supported_uri_schemes); + + application->requires_terminal = + real_get_bool_value + (i_application, + GNOME_VFS_APPLICATION_REGISTRY_REQUIRES_TERMINAL, + NULL); + + uses_gnomevfs = real_get_bool_value (i_application, GNOME_VFS_APPLICATION_REGISTRY_USES_GNOMEVFS, NULL); + + if (uses_gnomevfs) { + GList *methods_list = + _gnome_vfs_configuration_get_methods_list(); + GList *l; + if (application->expects_uris == GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_PATHS) { + application->expects_uris = GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_URIS; + } + for (l = methods_list; l != NULL; l = l->next) { + if (g_list_find_custom (application->supported_uri_schemes, + /*glib is const incorrect*/(gpointer) l->data, + (GCompareFunc) strcmp) == NULL) { + application->supported_uri_schemes = + g_list_prepend(application->supported_uri_schemes, + l->data); + } else { + g_free(l->data); + } + } + g_list_free(methods_list); + } + + return application; +} + +/** + * gnome_vfs_application_registry_save_mime_application + * @application: application associated with the mime type + * + * This will save to the registry the application that will be associated with + * a defined mime type. The defined mime type is located within the + * GnomeVFSMimeApplication structure. Changes are not realized until the + * gnome_vfs_application_registry_sync function is called. + * + */ + +void +gnome_vfs_application_registry_save_mime_application (const GnomeVFSMimeApplication *application) +{ + Application *i_application; + + g_return_if_fail (application != NULL); + + /* make us a new user application */ + i_application = application_lookup_or_create (application->id, TRUE); + + application_ref (i_application); + + set_value (i_application, GNOME_VFS_APPLICATION_REGISTRY_NAME, + application->name); + set_value (i_application, GNOME_VFS_APPLICATION_REGISTRY_COMMAND, + application->command); + set_bool_value (i_application, GNOME_VFS_APPLICATION_REGISTRY_CAN_OPEN_MULTIPLE_FILES, + application->can_open_multiple_files); + i_application->expects_uris = application->expects_uris; + set_bool_value (i_application, GNOME_VFS_APPLICATION_REGISTRY_REQUIRES_TERMINAL, + application->requires_terminal); + /* FIXME: Need to save supported_uri_schemes information */ + user_file_dirty = TRUE; +} + +/** + * gnome_vfs_application_is_user_owned_application + * @application: data structure of the mime application + * + * This function will determine if a mime application is user owned or not. By + * user ownered this means that the application is not a system application + * located in the prerequisite /usr area but rather in the user's area. + * + * Returns: gboolean + */ + +gboolean +gnome_vfs_application_is_user_owned_application (const GnomeVFSMimeApplication *application) +{ + Application *i_application; + + g_return_val_if_fail (application != NULL, FALSE); + + /* make us a new user application */ + i_application = g_hash_table_lookup (global_applications, application->id); + if (i_application != NULL) { + return i_application->user_owned; + } + + return FALSE; +} + diff --git a/libgnomevfs/gnome-vfs-application-registry.h b/libgnomevfs/gnome-vfs-application-registry.h new file mode 100644 index 0000000..3306232 --- /dev/null +++ b/libgnomevfs/gnome-vfs-application-registry.h @@ -0,0 +1,153 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* gnome-vfs-application-registry.h + * + * Copyright (C) 1998 Miguel de Icaza + * Copyright (C) 2000 Eazel, Inc + * + * The Gnome Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Gnome Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +/* + * Authors: George Lebl + * Based on original mime-info database code by Miguel de Icaza + */ + +#ifndef GNOME_VFS_APPLICATION_REGISTRY_H +#define GNOME_VFS_APPLICATION_REGISTRY_H + +#include + +G_BEGIN_DECLS + +/** + * GNOME_VFS_APPLICATION_REGISTRY_COMMAND: + * + * Application registry key for fetching the command to execute + * an application. + **/ +#define GNOME_VFS_APPLICATION_REGISTRY_COMMAND "command" + +/** + * GNOME_VFS_APPLICATION_REGISTRY_NAME: + * + * Application registry key for fetching the name of an application. + **/ +#define GNOME_VFS_APPLICATION_REGISTRY_NAME "name" + +/** + * GNOME_VFS_APPLICATION_REGISTRY_CAN_OPEN_MULTIPLE_FILES: + * + * Application registry key for determining if an application + * can open multiple files in the same invocation. + **/ +#define GNOME_VFS_APPLICATION_REGISTRY_CAN_OPEN_MULTIPLE_FILES "can_open_multiple_files" + +/** + * GNOME_VFS_APPLICATION_REGISTRY_REQUIRES_TERMINAL: + * + * Application registry key for determining if an application + * needs to run from within a terminal (for example, mpg123) + **/ +#define GNOME_VFS_APPLICATION_REGISTRY_REQUIRES_TERMINAL "requires_terminal" + +/** + * + * Application registry key for determining if an application + * is using gnome-vfs and thus can open any URI supported by + * gnome-vfs + */ +#define GNOME_VFS_APPLICATION_REGISTRY_USES_GNOMEVFS "uses_gnomevfs" + +/** + * GNOME_VFS_APPLICATION_REGISTRY_STARTUP_NOTIFY: + * + * Application registry key for determining if an application + * supports freedesktop.org-style startup notification. + **/ +#define GNOME_VFS_APPLICATION_REGISTRY_STARTUP_NOTIFY "startup_notify" + +/* + * Existance check + */ +gboolean gnome_vfs_application_registry_exists (const char *app_id); + +/* + * Getting arbitrary keys + */ +GList *gnome_vfs_application_registry_get_keys (const char *app_id); +const char *gnome_vfs_application_registry_peek_value (const char *app_id, + const char *key); +gboolean gnome_vfs_application_registry_get_bool_value (const char *app_id, + const char *key, + gboolean *got_key); + +/* + * Setting stuff + */ +void gnome_vfs_application_registry_remove_application(const char *app_id); +void gnome_vfs_application_registry_set_value (const char *app_id, + const char *key, + const char *value); +void gnome_vfs_application_registry_set_bool_value (const char *app_id, + const char *key, + gboolean value); +void gnome_vfs_application_registry_unset_key (const char *app_id, + const char *key); + +/* + * Query functions + */ +GList *gnome_vfs_application_registry_get_applications(const char *mime_type); +GList *gnome_vfs_application_registry_get_mime_types (const char *app_id); + +gboolean gnome_vfs_application_registry_supports_mime_type (const char *app_id, + const char *mime_type); +gboolean gnome_vfs_application_registry_supports_uri_scheme (const char *app_id, + const char *uri_scheme); +gboolean gnome_vfs_application_is_user_owned_application (const GnomeVFSMimeApplication *application); + +/* + * Mime type functions + * Note that mime_type can be a specific (image/png) or generic (image/) type + */ + +void gnome_vfs_application_registry_clear_mime_types (const char *app_id); +void gnome_vfs_application_registry_add_mime_type (const char *app_id, + const char *mime_type); +void gnome_vfs_application_registry_remove_mime_type (const char *app_id, + const char *mime_type); + + +/* + * Commit function, should be called if ANY stuff changes have been made. + * Stuff is saved into the user directory. + */ +GnomeVFSResult gnome_vfs_application_registry_sync (void); + +void gnome_vfs_application_registry_shutdown (void); +void gnome_vfs_application_registry_reload (void); + +/* + * Integrating with gnome-vfs-mime-handlers + */ +GnomeVFSMimeApplication * + gnome_vfs_application_registry_get_mime_application(const char *app_id); +void gnome_vfs_application_registry_save_mime_application(const GnomeVFSMimeApplication *application); + + +G_END_DECLS + +#endif /* GNOME_VFS_APPLICATION_REGISTRY_H */ diff --git a/libgnomevfs/gnome-vfs-async-job-map.c b/libgnomevfs/gnome-vfs-async-job-map.c new file mode 100644 index 0000000..1b32a73 --- /dev/null +++ b/libgnomevfs/gnome-vfs-async-job-map.c @@ -0,0 +1,293 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-async-job-map.c + + Copyright (C) 2001 Eazel Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Pavel Cisler */ + +#include +#include "gnome-vfs-async-job-map.h" + +#include "gnome-vfs-job.h" +#include +#include + +/* job map bits guarded by this lock */ +static GStaticRecMutex async_job_map_lock = G_STATIC_REC_MUTEX_INIT; +static guint async_job_map_next_id; +static int async_job_map_locked = 0; +static gboolean async_job_map_shutting_down; +static GHashTable *async_job_map; + +/* callback map bits guarded by this lock */ +static GStaticMutex async_job_callback_map_lock = G_STATIC_MUTEX_INIT; +static GHashTable *async_job_callback_map; +static guint async_job_callback_map_next_id; + +void async_job_callback_map_destroy (void); + +void +_gnome_vfs_async_job_map_init (void) +{ +} + +GnomeVFSJob * +_gnome_vfs_async_job_map_get_job (const GnomeVFSAsyncHandle *handle) +{ + _gnome_vfs_async_job_map_assert_locked (); + g_assert (async_job_map != NULL); + + return g_hash_table_lookup (async_job_map, handle); +} + +void +_gnome_vfs_async_job_map_add_job (GnomeVFSJob *job) +{ + _gnome_vfs_async_job_map_lock (); + + g_assert (!async_job_map_shutting_down); + + /* Assign a unique id to each job. The GnomeVFSAsyncHandle pointers each + * async op call deals with this will really be these unique IDs + */ + job->job_handle = GUINT_TO_POINTER (++async_job_map_next_id); + + if (async_job_map == NULL) { + /* First job, allocate a new hash table. */ + async_job_map = g_hash_table_new (NULL, NULL); + } + + g_hash_table_insert (async_job_map, job->job_handle, job); + + _gnome_vfs_async_job_map_unlock (); +} + +void +_gnome_vfs_async_job_map_remove_job (GnomeVFSJob *job) +{ + _gnome_vfs_async_job_map_lock (); + + g_assert (async_job_map); + + g_hash_table_remove (async_job_map, job->job_handle); + + _gnome_vfs_async_job_map_unlock (); +} + + +static void +gnome_vfs_async_job_map_destroy (void) +{ + _gnome_vfs_async_job_map_assert_locked (); + g_assert (async_job_map_shutting_down); + g_assert (async_job_map != NULL); + + g_hash_table_destroy (async_job_map); + async_job_map = NULL; +} + +gboolean +_gnome_vfs_async_job_completed (GnomeVFSAsyncHandle *handle) +{ + GnomeVFSJob *job; + + _gnome_vfs_async_job_map_lock (); + + JOB_DEBUG (("%d", GPOINTER_TO_UINT (handle))); + /* Job done, remove it's id from the map */ + + g_assert (async_job_map != NULL); + + job = _gnome_vfs_async_job_map_get_job (handle); + if (job != NULL) { + g_hash_table_remove (async_job_map, handle); + } + + if (async_job_map_shutting_down && g_hash_table_size (async_job_map) == 0) { + /* We were the last active job, turn the lights off. */ + gnome_vfs_async_job_map_destroy (); + } + + _gnome_vfs_async_job_map_unlock (); + + return job != NULL; +} + +void +_gnome_vfs_async_job_map_shutdown (void) +{ + _gnome_vfs_async_job_map_lock (); + + if (async_job_map) { + + /* tell the async jobs it's quitting time */ + async_job_map_shutting_down = TRUE; + + if (g_hash_table_size (async_job_map) == 0) { + /* No more outstanding jobs to finish, just delete + * the hash table directly. + */ + gnome_vfs_async_job_map_destroy (); + } + } + + /* The last expiring job will delete the hash table. */ + _gnome_vfs_async_job_map_unlock (); + + async_job_callback_map_destroy (); +} + +void +_gnome_vfs_async_job_map_lock (void) +{ + g_static_rec_mutex_lock (&async_job_map_lock); + async_job_map_locked++; +} + +void +_gnome_vfs_async_job_map_unlock (void) +{ + async_job_map_locked--; + g_static_rec_mutex_unlock (&async_job_map_lock); +} + +void +_gnome_vfs_async_job_map_assert_locked (void) +{ + g_assert (async_job_map_locked); +} + +void +_gnome_vfs_async_job_callback_valid (guint callback_id, + gboolean *valid, + gboolean *cancelled) +{ + GnomeVFSNotifyResult *notify_result; + + g_static_mutex_lock (&async_job_callback_map_lock); + + if (async_job_callback_map == NULL) { + g_assert (async_job_map_shutting_down); + *valid = FALSE; + *cancelled = FALSE; + } + + notify_result = (GnomeVFSNotifyResult *) g_hash_table_lookup + (async_job_callback_map, GUINT_TO_POINTER (callback_id)); + + *valid = notify_result != NULL; + *cancelled = notify_result != NULL && notify_result->cancelled; + + g_static_mutex_unlock (&async_job_callback_map_lock); +} + +gboolean +_gnome_vfs_async_job_add_callback (GnomeVFSJob *job, GnomeVFSNotifyResult *notify_result) +{ + gboolean cancelled; + + g_static_mutex_lock (&async_job_callback_map_lock); + + g_assert (!async_job_map_shutting_down); + + /* Assign a unique id to each job callback. Use unique IDs instead of the + * notify_results pointers to avoid aliasing problems. + */ + notify_result->callback_id = ++async_job_callback_map_next_id; + + JOB_DEBUG (("adding callback %d ", notify_result->callback_id)); + + if (async_job_callback_map == NULL) { + /* First job, allocate a new hash table. */ + async_job_callback_map = g_hash_table_new (NULL, NULL); + } + + /* we are using async_job_callback_map_lock to ensure atomicity of + * checking/clearing job->cancelled and adding/cancelling callbacks + */ + cancelled = job->cancelled; + + if (!cancelled) { + g_hash_table_insert (async_job_callback_map, GUINT_TO_POINTER (notify_result->callback_id), + notify_result); + } + g_static_mutex_unlock (&async_job_callback_map_lock); + + return !cancelled; +} + +void +_gnome_vfs_async_job_remove_callback (guint callback_id) +{ + g_assert (async_job_callback_map != NULL); + + JOB_DEBUG (("removing callback %d ", callback_id)); + g_static_mutex_lock (&async_job_callback_map_lock); + + g_hash_table_remove (async_job_callback_map, GUINT_TO_POINTER (callback_id)); + + g_static_mutex_unlock (&async_job_callback_map_lock); +} + +static void +callback_map_cancel_one (gpointer key, gpointer value, gpointer user_data) +{ + GnomeVFSNotifyResult *notify_result; + + notify_result = (GnomeVFSNotifyResult *) value; + + if (notify_result->job_handle == (GnomeVFSAsyncHandle *)user_data) { + JOB_DEBUG (("cancelling callback %u - job %u cancelled", + GPOINTER_TO_UINT (key), + GPOINTER_TO_UINT (user_data))); + notify_result->cancelled = TRUE; + } +} + +void +_gnome_vfs_async_job_cancel_job_and_callbacks (GnomeVFSAsyncHandle *job_handle, GnomeVFSJob *job) +{ + g_static_mutex_lock (&async_job_callback_map_lock); + + if (job != NULL) { + job->cancelled = TRUE; + } + + if (async_job_callback_map == NULL) { + JOB_DEBUG (("job %u, no callbacks scheduled yet", + GPOINTER_TO_UINT (job_handle))); + } else { + g_hash_table_foreach (async_job_callback_map, + callback_map_cancel_one, job_handle); + } + + g_static_mutex_unlock (&async_job_callback_map_lock); +} + +void +async_job_callback_map_destroy (void) +{ + g_static_mutex_lock (&async_job_callback_map_lock); + + if (async_job_callback_map) { + g_hash_table_destroy (async_job_callback_map); + async_job_callback_map = NULL; + } + + g_static_mutex_unlock (&async_job_callback_map_lock); +} diff --git a/libgnomevfs/gnome-vfs-async-job-map.h b/libgnomevfs/gnome-vfs-async-job-map.h new file mode 100644 index 0000000..771db09 --- /dev/null +++ b/libgnomevfs/gnome-vfs-async-job-map.h @@ -0,0 +1,54 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-async-job-map.h: + + The async job map, maps GnomeVFSAsyncHandles to GnomeVFSJobs. Many + async operations, keep the same 'GnomeVFSJob' over the course of several + operations. + + Copyright (C) 2001 Eazel Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Pavel Cisler */ + +#ifndef GNOME_VFS_ASYNC_JOB_MAP_H +#define GNOME_VFS_ASYNC_JOB_MAP_H + +#include "gnome-vfs-job.h" + +/* async job map calls */ +void _gnome_vfs_async_job_map_init (void); +void _gnome_vfs_async_job_map_shutdown (void); +gboolean _gnome_vfs_async_job_completed (GnomeVFSAsyncHandle *handle); +void _gnome_vfs_async_job_map_add_job (GnomeVFSJob *job); +void _gnome_vfs_async_job_map_remove_job (GnomeVFSJob *job); +GnomeVFSJob *_gnome_vfs_async_job_map_get_job (const GnomeVFSAsyncHandle *handle); + +void _gnome_vfs_async_job_map_assert_locked (void); +void _gnome_vfs_async_job_map_lock (void); +void _gnome_vfs_async_job_map_unlock (void); + +/* async job callback map calls */ +void _gnome_vfs_async_job_callback_valid (guint callback_id, + gboolean *valid, + gboolean *cancelled); +gboolean _gnome_vfs_async_job_add_callback (GnomeVFSJob *job, + GnomeVFSNotifyResult *notify_result); +void _gnome_vfs_async_job_remove_callback (guint callback_id); +void _gnome_vfs_async_job_cancel_job_and_callbacks (GnomeVFSAsyncHandle *job_handle, + GnomeVFSJob *job); + +#endif diff --git a/libgnomevfs/gnome-vfs-async-ops.c b/libgnomevfs/gnome-vfs-async-ops.c new file mode 100644 index 0000000..0d585eb --- /dev/null +++ b/libgnomevfs/gnome-vfs-async-ops.c @@ -0,0 +1,1065 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-async-ops.c - Asynchronous operations supported by the + GNOME Virtual File System (version for POSIX threads). + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli */ + +#include + +#include "gnome-vfs-async-ops.h" +#include "gnome-vfs-async-job-map.h" +#include "gnome-vfs-job.h" +#include "gnome-vfs-job-queue.h" +#include "gnome-vfs-job-limit.h" +#include +#include +#include + +/** + * gnome_vfs_async_cancel: + * @handle: handle of the async operation to be cancelled + * + * Cancel an asynchronous operation and close all its callbacks. + * Its possible to still receive another call or two on the callback. + **/ +void +gnome_vfs_async_cancel (GnomeVFSAsyncHandle *handle) +{ + GnomeVFSJob *job; + + _gnome_vfs_async_job_map_lock (); + + job = _gnome_vfs_async_job_map_get_job (handle); + if (job == NULL) { + JOB_DEBUG (("job %u - job no longer exists", GPOINTER_TO_UINT (handle))); + /* have to cancel the callbacks because they still can be pending */ + _gnome_vfs_async_job_cancel_job_and_callbacks (handle, NULL); + } else { + /* Cancel the job in progress. OK to do outside of job->job_lock, + * job lifetime is protected by _gnome_vfs_async_job_map_lock. + */ + _gnome_vfs_job_module_cancel (job); + _gnome_vfs_async_job_cancel_job_and_callbacks (handle, job); + } + + _gnome_vfs_async_job_map_unlock (); +} + +static GnomeVFSAsyncHandle * +async_open (GnomeVFSURI *uri, + GnomeVFSOpenMode open_mode, + int priority, + GnomeVFSAsyncOpenCallback callback, + gpointer callback_data) +{ + GnomeVFSJob *job; + GnomeVFSOpenOp *open_op; + GnomeVFSAsyncHandle *result; + + job = _gnome_vfs_job_new (GNOME_VFS_OP_OPEN, priority, (GFunc) callback, callback_data); + + open_op = &job->op->specifics.open; + + open_op->uri = uri == NULL ? NULL : gnome_vfs_uri_ref (uri); + open_op->open_mode = open_mode; + + result = job->job_handle; + _gnome_vfs_job_go (job); + + return result; +} + +/** + * gnome_vfs_async_open_uri: + * @handle_return: A pointer to a pointer to a GnomeVFSHandle object + * @uri: URI to open + * @open_mode: Open mode + * @priority: a value from %GNOME_VFS_PRIORITY_MIN to %GNOME_VFS_PRIORITY_MAX (normally + * should be %GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job + * in allocating threads from the thread pool. + * @callback: function to be called when the operation is complete + * @callback_data: data to pass @callback + * + * Open @uri according to mode @open_mode. On return, @handle_return will + * contain a pointer to the operation. Once the file has been successfully opened, + * @callback will be called with the GnomeVFSResult. + * + **/ +void +gnome_vfs_async_open_uri (GnomeVFSAsyncHandle **handle_return, + GnomeVFSURI *uri, + GnomeVFSOpenMode open_mode, + int priority, + GnomeVFSAsyncOpenCallback callback, + gpointer callback_data) +{ + g_return_if_fail (handle_return != NULL); + g_return_if_fail (uri != NULL); + g_return_if_fail (callback != NULL); + g_return_if_fail (priority >= GNOME_VFS_PRIORITY_MIN); + g_return_if_fail (priority <= GNOME_VFS_PRIORITY_MAX); + + *handle_return = async_open (uri, open_mode, priority, + callback, callback_data); +} + +/** + * gnome_vfs_async_open: + * @handle_return: A pointer to a pointer to a GnomeVFSHandle object + * @text_uri: string of the URI to open + * @open_mode: Open mode + * @priority: a value from %GNOME_VFS_PRIORITY_MIN to %GNOME_VFS_PRIORITY_MAX (normally + * should be %GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job + * in allocating threads from the thread pool. + * @callback: function to be called when the operation is complete + * @callback_data: data to pass @callback + * + * Open @text_uri according to mode @open_mode. On return, @handle_return will + * contain a pointer to the operation. Once the file has been successfully opened, + * @callback will be called with the GnomeVFSResult. + * + **/ +void +gnome_vfs_async_open (GnomeVFSAsyncHandle **handle_return, + const gchar *text_uri, + GnomeVFSOpenMode open_mode, + int priority, + GnomeVFSAsyncOpenCallback callback, + gpointer callback_data) +{ + GnomeVFSURI *uri; + + g_return_if_fail (handle_return != NULL); + g_return_if_fail (text_uri != NULL); + g_return_if_fail (callback != NULL); + g_return_if_fail (priority >= GNOME_VFS_PRIORITY_MIN); + g_return_if_fail (priority <= GNOME_VFS_PRIORITY_MAX); + + uri = gnome_vfs_uri_new (text_uri); + *handle_return = async_open (uri, open_mode, priority, + callback, callback_data); + if (uri != NULL) { + gnome_vfs_uri_unref (uri); + } +} + +static GnomeVFSAsyncHandle * +async_open_as_channel (GnomeVFSURI *uri, + GnomeVFSOpenMode open_mode, + guint advised_block_size, + int priority, + GnomeVFSAsyncOpenAsChannelCallback callback, + gpointer callback_data) +{ + GnomeVFSJob *job; + GnomeVFSOpenAsChannelOp *open_as_channel_op; + GnomeVFSAsyncHandle *result; + + job = _gnome_vfs_job_new (GNOME_VFS_OP_OPEN_AS_CHANNEL, priority, (GFunc) callback, callback_data); + + open_as_channel_op = &job->op->specifics.open_as_channel; + open_as_channel_op->uri = uri == NULL ? NULL : gnome_vfs_uri_ref (uri); + open_as_channel_op->open_mode = open_mode; + open_as_channel_op->advised_block_size = advised_block_size; + + result = job->job_handle; + _gnome_vfs_job_go (job); + + return result; +} + +/** + * gnome_vfs_async_open_uri_as_channel: + * @handle_return: A pointer to a pointer to a GnomeVFSHandle object + * @uri: URI to open as a #GIOChannel + * @open_mode: open for reading, writing, random, etc + * @advised_block_size: the preferred block size for #GIOChannel to read + * @priority: a value from %GNOME_VFS_PRIORITY_MIN to %GNOME_VFS_PRIORITY_MAX (normally + * should be %GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job + * in allocating threads from the thread pool. + * @callback: function to be called when the operation is complete + * @callback_data: data to pass @callback + * + * Open @uri as a #GIOChannel. Once the channel has been established + * @callback will be called with @callback_data, the result of the operation, + * and if the result was %GNOME_VFS_OK, a reference to a #GIOChannel pointing + * at @uri in @open_mode. + **/ +void +gnome_vfs_async_open_uri_as_channel (GnomeVFSAsyncHandle **handle_return, + GnomeVFSURI *uri, + GnomeVFSOpenMode open_mode, + guint advised_block_size, + int priority, + GnomeVFSAsyncOpenAsChannelCallback callback, + gpointer callback_data) +{ + g_return_if_fail (handle_return != NULL); + g_return_if_fail (uri != NULL); + g_return_if_fail (callback != NULL); + g_return_if_fail (priority >= GNOME_VFS_PRIORITY_MIN); + g_return_if_fail (priority <= GNOME_VFS_PRIORITY_MAX); + + *handle_return = async_open_as_channel (uri, open_mode, advised_block_size, + priority, callback, callback_data); +} + +/** + * gnome_vfs_async_open_as_channel: + * @handle_return: A pointer to a pointer to a GnomeVFSHandle object + * @text_uri: string of the URI to open as a #GIOChannel + * @open_mode: open for reading, writing, random, etc + * @advised_block_size: the preferred block size for #GIOChannel to read + * @priority: a value from %GNOME_VFS_PRIORITY_MIN to %GNOME_VFS_PRIORITY_MAX (normally + * should be %GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job + * in allocating threads from the thread pool. + * @callback: function to be called when the operation is complete + * @callback_data: data to pass @callback + * + * Open @text_uri as a #GIOChannel. Once the channel has been established + * @callback will be called with @callback_data, the result of the operation, + * and if the result was %GNOME_VFS_OK, a reference to a #GIOChannel pointing + * at @text_uri in @open_mode. + **/ +void +gnome_vfs_async_open_as_channel (GnomeVFSAsyncHandle **handle_return, + const gchar *text_uri, + GnomeVFSOpenMode open_mode, + guint advised_block_size, + int priority, + GnomeVFSAsyncOpenAsChannelCallback callback, + gpointer callback_data) +{ + GnomeVFSURI *uri; + + g_return_if_fail (handle_return != NULL); + g_return_if_fail (text_uri != NULL); + g_return_if_fail (callback != NULL); + g_return_if_fail (priority >= GNOME_VFS_PRIORITY_MIN); + g_return_if_fail (priority <= GNOME_VFS_PRIORITY_MAX); + + uri = gnome_vfs_uri_new (text_uri); + *handle_return = async_open_as_channel (uri, open_mode, advised_block_size, + priority, callback, callback_data); + if (uri != NULL) { + gnome_vfs_uri_unref (uri); + } +} + +static GnomeVFSAsyncHandle * +async_create (GnomeVFSURI *uri, + GnomeVFSOpenMode open_mode, + gboolean exclusive, + guint perm, + int priority, + GnomeVFSAsyncOpenCallback callback, + gpointer callback_data) +{ + GnomeVFSJob *job; + GnomeVFSCreateOp *create_op; + GnomeVFSAsyncHandle *result; + + job = _gnome_vfs_job_new (GNOME_VFS_OP_CREATE, priority, (GFunc) callback, callback_data); + + create_op = &job->op->specifics.create; + create_op->uri = uri == NULL ? NULL : gnome_vfs_uri_ref (uri); + create_op->open_mode = open_mode; + create_op->exclusive = exclusive; + create_op->perm = perm; + + result = job->job_handle; + _gnome_vfs_job_go (job); + + return result; +} + +/** + * gnome_vfs_async_create_uri: + * @handle_return: A pointer to a pointer to a GnomeVFSHandle object + * @uri: the URI to create a file at + * @open_mode: mode to leave the file opened in after creation (or %GNOME_VFS_OPEN_MODE_NONE + * to leave the file closed after creation) + * @exclusive: Whether the file should be created in "exclusive" mode: + * i.e. if this flag is nonzero, operation will fail if a file with the + * same name already exists. + * @perm: Bitmap representing the permissions for the newly created file + * (Unix style). + * @priority: a value from %GNOME_VFS_PRIORITY_MIN to %GNOME_VFS_PRIORITY_MAX (normally + * should be %GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job + * in allocating threads from the thread pool. + * @callback: function to be called when the operation is complete + * @callback_data: data to pass @callback + * + * Create a file at @uri according to mode @open_mode, with permissions @perm (in + * the standard UNIX packed bit permissions format). When the create has been completed + * @callback will be called with the result code and @callback_data. + **/ +void +gnome_vfs_async_create_uri (GnomeVFSAsyncHandle **handle_return, + GnomeVFSURI *uri, + GnomeVFSOpenMode open_mode, + gboolean exclusive, + guint perm, + int priority, + GnomeVFSAsyncOpenCallback callback, + gpointer callback_data) +{ + g_return_if_fail (handle_return != NULL); + g_return_if_fail (uri != NULL); + g_return_if_fail (callback != NULL); + g_return_if_fail (priority >= GNOME_VFS_PRIORITY_MIN); + g_return_if_fail (priority <= GNOME_VFS_PRIORITY_MAX); + + *handle_return = async_create (uri, open_mode, exclusive, perm, + priority, callback, callback_data); +} + +/** + * gnome_vfs_async_create: + * @handle_return: A pointer to a pointer to a GnomeVFSHandle object + * @text_uri: String representing the URI to create + * @open_mode: mode to leave the file opened in after creation (or %GNOME_VFS_OPEN_MODE_NONE + * to leave the file closed after creation) + * @exclusive: Whether the file should be created in "exclusive" mode: + * i.e. if this flag is nonzero, operation will fail if a file with the + * same name already exists. + * @perm: Bitmap representing the permissions for the newly created file + * (Unix style). + * @priority: a value from %GNOME_VFS_PRIORITY_MIN to %GNOME_VFS_PRIORITY_MAX (normally + * should be %GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job + * in allocating threads from the thread pool. + * @callback: function to be called when the operation is complete + * @callback_data: data to pass @callback + * + * Create a file at @uri according to mode @open_mode, with permissions @perm (in + * the standard UNIX packed bit permissions format). When the create has been completed + * @callback will be called with the result code and @callback_data. + **/ +void +gnome_vfs_async_create (GnomeVFSAsyncHandle **handle_return, + const gchar *text_uri, + GnomeVFSOpenMode open_mode, + gboolean exclusive, + guint perm, + int priority, + GnomeVFSAsyncOpenCallback callback, + gpointer callback_data) +{ + GnomeVFSURI *uri; + + g_return_if_fail (handle_return != NULL); + g_return_if_fail (text_uri != NULL); + g_return_if_fail (callback != NULL); + g_return_if_fail (priority >= GNOME_VFS_PRIORITY_MIN); + g_return_if_fail (priority <= GNOME_VFS_PRIORITY_MAX); + + uri = gnome_vfs_uri_new (text_uri); + *handle_return = async_create (uri, open_mode, exclusive, perm, + priority, callback, callback_data); + if (uri != NULL) { + gnome_vfs_uri_unref (uri); + } +} + +/** + * gnome_vfs_async_create_as_channel: + * @handle_return: A pointer to a pointer to a GnomeVFSHandle object + * @text_uri: string of the URI to open as a #GIOChannel, creating it as necessary + * @open_mode: open for reading, writing, random, etc + * @exclusive: replace the file if it already exists + * @perm: standard POSIX-style permissions bitmask, permissions of created file + * @priority: a value from %GNOME_VFS_PRIORITY_MIN to %GNOME_VFS_PRIORITY_MAX (normally + * should be %GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job + * in allocating threads from the thread pool. + * @callback: function to be called when the operation is complete + * @callback_data: data to pass @callback + * + * Open @text_uri as a #GIOChannel, creating it as necessary. Once the channel has + * been established @callback will be called with @callback_data, the result of the + * operation, and if the result was %GNOME_VFS_OK, a reference to a #GIOChannel pointing + * at @text_uri in @open_mode. + **/ +void +gnome_vfs_async_create_as_channel (GnomeVFSAsyncHandle **handle_return, + const gchar *text_uri, + GnomeVFSOpenMode open_mode, + gboolean exclusive, + guint perm, + int priority, + GnomeVFSAsyncOpenAsChannelCallback callback, + gpointer callback_data) +{ + GnomeVFSJob *job; + GnomeVFSCreateAsChannelOp *create_as_channel_op; + GnomeVFSAsyncHandle *result; + + g_return_if_fail (handle_return != NULL); + g_return_if_fail (text_uri != NULL); + g_return_if_fail (callback != NULL); + g_return_if_fail (priority >= GNOME_VFS_PRIORITY_MIN); + g_return_if_fail (priority <= GNOME_VFS_PRIORITY_MAX); + + job = _gnome_vfs_job_new (GNOME_VFS_OP_CREATE_AS_CHANNEL, priority, (GFunc) callback, callback_data); + + + create_as_channel_op = &job->op->specifics.create_as_channel; + create_as_channel_op->uri = gnome_vfs_uri_new (text_uri); + create_as_channel_op->open_mode = open_mode; + create_as_channel_op->exclusive = exclusive; + create_as_channel_op->perm = perm; + + result = job->job_handle; + _gnome_vfs_job_go (job); +} + +/** + * gnome_vfs_async_close: + * @handle: async handle to close + * @callback: function to be called when the operation is complete + * @callback_data: data to pass @callback + * + * Close a handle opened with gnome_vfs_async_open(). When the close + * has completed, @callback will be called with @callback_data and + * the result of the operation. + **/ +void +gnome_vfs_async_close (GnomeVFSAsyncHandle *handle, + GnomeVFSAsyncCloseCallback callback, + gpointer callback_data) +{ + GnomeVFSJob *job; + + g_return_if_fail (handle != NULL); + g_return_if_fail (callback != NULL); + + for (;;) { + _gnome_vfs_async_job_map_lock (); + job = _gnome_vfs_async_job_map_get_job (handle); + if (job == NULL) { + g_warning ("trying to read a non-existing handle"); + _gnome_vfs_async_job_map_unlock (); + return; + } + + if (job->op->type != GNOME_VFS_OP_READ && + job->op->type != GNOME_VFS_OP_WRITE) { + _gnome_vfs_job_set (job, GNOME_VFS_OP_CLOSE, + (GFunc) callback, callback_data); + _gnome_vfs_job_go (job); + _gnome_vfs_async_job_map_unlock (); + return; + } + /* Still reading, wait a bit, cancel should be pending. + * This mostly handles a race condition that can happen + * on a dual CPU machine where a cancel stops a read before + * the read thread picks up and a close then gets scheduled + * on a new thread. Without this the job op type would be + * close for both threads and two closes would get executed + */ + _gnome_vfs_async_job_map_unlock (); + usleep (100); + } +} + +/** + * gnome_vfs_async_read: + * @handle: handle for the file to be read + * @buffer: allocated block of memory to read into + * @bytes: number of bytes to read + * @callback: function to be called when the operation is complete + * @callback_data: data to pass @callback + * + * Read @bytes bytes from the file pointed to be @handle into @buffer. + * When the operation is complete, @callback will be called with the + * result of the operation and @callback_data. + **/ +void +gnome_vfs_async_read (GnomeVFSAsyncHandle *handle, + gpointer buffer, + guint bytes, + GnomeVFSAsyncReadCallback callback, + gpointer callback_data) +{ + GnomeVFSJob *job; + GnomeVFSReadOp *read_op; + + g_return_if_fail (handle != NULL); + g_return_if_fail (buffer != NULL); + g_return_if_fail (callback != NULL); + + _gnome_vfs_async_job_map_lock (); + job = _gnome_vfs_async_job_map_get_job (handle); + if (job == NULL) { + g_warning ("trying to read from a non-existing handle"); + _gnome_vfs_async_job_map_unlock (); + return; + } + + _gnome_vfs_job_set (job, GNOME_VFS_OP_READ, + (GFunc) callback, callback_data); + + read_op = &job->op->specifics.read; + read_op->buffer = buffer; + read_op->num_bytes = bytes; + + _gnome_vfs_job_go (job); + _gnome_vfs_async_job_map_unlock (); +} + +/** + * gnome_vfs_async_write: + * @handle: handle for the file to be written + * @buffer: block of memory containing data to be written + * @bytes: number of bytes to write + * @callback: function to be called when the operation is complete + * @callback_data: data to pass @callback + * + * Write @bytes bytes from @buffer into the file pointed to be @handle. + * When the operation is complete, @callback will be called with the + * result of the operation and @callback_data. + **/ +void +gnome_vfs_async_write (GnomeVFSAsyncHandle *handle, + gconstpointer buffer, + guint bytes, + GnomeVFSAsyncWriteCallback callback, + gpointer callback_data) +{ + GnomeVFSJob *job; + GnomeVFSWriteOp *write_op; + + g_return_if_fail (handle != NULL); + g_return_if_fail (buffer != NULL); + g_return_if_fail (callback != NULL); + + _gnome_vfs_async_job_map_lock (); + job = _gnome_vfs_async_job_map_get_job (handle); + if (job == NULL) { + g_warning ("trying to write to a non-existing handle"); + _gnome_vfs_async_job_map_unlock (); + return; + } + + _gnome_vfs_job_set (job, GNOME_VFS_OP_WRITE, + (GFunc) callback, callback_data); + + write_op = &job->op->specifics.write; + write_op->buffer = buffer; + write_op->num_bytes = bytes; + + _gnome_vfs_job_go (job); + _gnome_vfs_async_job_map_unlock (); +} + +/** + * gnome_vfs_async_create_symbolic_link: + * @handle_return: when the function returns will point to a handle for + * the async operation. + * @uri: location to create the link at + * @uri_reference: location to point @uri to (can be a URI fragment, i.e. relative) + * @priority: a value from %GNOME_VFS_PRIORITY_MIN to %GNOME_VFS_PRIORITY_MAX (normally + * should be %GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job + * in allocating threads from the thread pool. + * @callback: function to be called when the operation is complete + * @callback_data: data to pass @callback + * + * Create a symbolic link at @uri pointing to @uri_reference. When the operation + * has complete @callback will be called with the result of the operation and + * @callback_data. + **/ +void +gnome_vfs_async_create_symbolic_link (GnomeVFSAsyncHandle **handle_return, + GnomeVFSURI *uri, + const gchar *uri_reference, + int priority, + GnomeVFSAsyncOpenCallback callback, + gpointer callback_data) +{ + GnomeVFSJob *job; + GnomeVFSCreateLinkOp *create_op; + + g_return_if_fail (handle_return != NULL); + g_return_if_fail (uri != NULL); + g_return_if_fail (callback != NULL); + g_return_if_fail (priority >= GNOME_VFS_PRIORITY_MIN); + g_return_if_fail (priority <= GNOME_VFS_PRIORITY_MAX); + + job = _gnome_vfs_job_new (GNOME_VFS_OP_CREATE_SYMBOLIC_LINK, priority, (GFunc) callback, callback_data); + + create_op = &job->op->specifics.create_symbolic_link; + create_op->uri = gnome_vfs_uri_ref (uri); + create_op->uri_reference = g_strdup (uri_reference); + + *handle_return = job->job_handle; + _gnome_vfs_job_go (job); +} + +/** + * gnome_vfs_async_get_file_info: + * @handle_return: when the function returns will point to a handle for + * the async operation. + * @uri_list: a GList of GnomeVFSURIs to fetch information about + * @options: packed boolean type providing control over various details + * of the get_file_info operation. + * @priority: a value from %GNOME_VFS_PRIORITY_MIN to %GNOME_VFS_PRIORITY_MAX (normally + * should be %GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job + * in allocating threads from the thread pool. + * @callback: function to be called when the operation is complete + * @callback_data: data to pass @callback + * + * Fetch information about the files indicated in @uris and return the + * information progressively to @callback. + **/ +void +gnome_vfs_async_get_file_info (GnomeVFSAsyncHandle **handle_return, + GList *uri_list, + GnomeVFSFileInfoOptions options, + int priority, + GnomeVFSAsyncGetFileInfoCallback callback, + gpointer callback_data) +{ + GnomeVFSJob *job; + GnomeVFSGetFileInfoOp *get_info_op; + + g_return_if_fail (handle_return != NULL); + g_return_if_fail (callback != NULL); + g_return_if_fail (priority >= GNOME_VFS_PRIORITY_MIN); + g_return_if_fail (priority <= GNOME_VFS_PRIORITY_MAX); + + job = _gnome_vfs_job_new (GNOME_VFS_OP_GET_FILE_INFO, priority, (GFunc) callback, callback_data); + + get_info_op = &job->op->specifics.get_file_info; + + get_info_op->uris = gnome_vfs_uri_list_copy (uri_list); + get_info_op->options = options; + + *handle_return = job->job_handle; + _gnome_vfs_job_go (job); +} + +/** + * gnome_vfs_async_set_file_info: + * @handle_return: when the function returns will point to a handle for + * the async operation. + * @uri: the URI to set the file info of + * @info: the struct containing new information about the file + * @mask: control which fields of @info are changed about the file at @uri + * @options: packed boolean type providing control over various details + * of the set_file_info operation. + * @priority: a value from %GNOME_VFS_PRIORITY_MIN to %GNOME_VFS_PRIORITY_MAX (normally + * should be %GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job + * in allocating threads from the thread pool. + * @callback: function to be called when the operation is complete + * @callback_data: data to pass @callback + * + * Set "file info" details about the file at @uri, such as permissions, name, + * owner, and modification time. + **/ +void +gnome_vfs_async_set_file_info (GnomeVFSAsyncHandle **handle_return, + GnomeVFSURI *uri, + GnomeVFSFileInfo *info, + GnomeVFSSetFileInfoMask mask, + GnomeVFSFileInfoOptions options, + int priority, + GnomeVFSAsyncSetFileInfoCallback callback, + gpointer callback_data) +{ + GnomeVFSJob *job; + GnomeVFSSetFileInfoOp *op; + + g_return_if_fail (handle_return != NULL); + g_return_if_fail (uri != NULL); + g_return_if_fail (info != NULL); + g_return_if_fail (callback != NULL); + g_return_if_fail (priority >= GNOME_VFS_PRIORITY_MIN); + g_return_if_fail (priority <= GNOME_VFS_PRIORITY_MAX); + + job = _gnome_vfs_job_new (GNOME_VFS_OP_SET_FILE_INFO, priority, (GFunc) callback, callback_data); + + op = &job->op->specifics.set_file_info; + + op->uri = gnome_vfs_uri_ref (uri); + op->info = gnome_vfs_file_info_new (); + gnome_vfs_file_info_copy (op->info, info); + op->mask = mask; + op->options = options; + + *handle_return = job->job_handle; + _gnome_vfs_job_go (job); +} + +/** + * gnome_vfs_async_find_directory: + * @handle_return: when the function returns will point to a handle for + * @near_uri_list: a GList of GnomeVFSURIs, find a special directory on the same + * volume as @uris + * @kind: kind of special directory + * @create_if_needed: If directory we are looking for does not exist, try to create it + * @find_if_needed: If we don't know where the directory is yet, look for it. + * @permissions: If creating, use these permissions + * @priority: a value from %GNOME_VFS_PRIORITY_MIN to %GNOME_VFS_PRIORITY_MAX (normally + * should be %GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job + * in allocating threads from the thread pool. + * @callback: function to be called when the operation is complete + * @user_data: data to pass @callback * + * Used to return special directories such as Trash and Desktop from different + * file systems. + * + * There is quite a complicated logic behind finding/creating a Trash directory + * and you need to be aware of some implications: + * Finding the Trash the first time when using the file method may be pretty + * expensive. A cache file is used to store the location of that Trash file + * for next time. + * If @ceate_if_needed is specified without @find_if_needed, you may end up + * creating a Trash file when there already is one. Your app should start out + * by doing a gnome_vfs_find_directory with the @find_if_needed to avoid this + * and then use the @create_if_needed flag to create Trash lazily when it is + * needed for throwing away an item on a given disk. + * + * When the operation has completed, @callback will be called with the result + * of the operation and @user_data. + **/ +void +gnome_vfs_async_find_directory (GnomeVFSAsyncHandle **handle_return, + GList *near_uri_list, + GnomeVFSFindDirectoryKind kind, + gboolean create_if_needed, + gboolean find_if_needed, + guint permissions, + int priority, + GnomeVFSAsyncFindDirectoryCallback callback, + gpointer user_data) +{ + GnomeVFSJob *job; + GnomeVFSFindDirectoryOp *get_info_op; + + g_return_if_fail (handle_return != NULL); + g_return_if_fail (callback != NULL); + g_return_if_fail (priority >= GNOME_VFS_PRIORITY_MIN); + g_return_if_fail (priority <= GNOME_VFS_PRIORITY_MAX); + + job = _gnome_vfs_job_new (GNOME_VFS_OP_FIND_DIRECTORY, priority, (GFunc) callback, user_data); + + get_info_op = &job->op->specifics.find_directory; + + get_info_op->uris = gnome_vfs_uri_list_copy (near_uri_list); + get_info_op->kind = kind; + get_info_op->create_if_needed = create_if_needed; + get_info_op->find_if_needed = find_if_needed; + get_info_op->permissions = permissions; + + *handle_return = job->job_handle; + _gnome_vfs_job_go (job); +} + +static GnomeVFSAsyncHandle * +async_load_directory (GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options, + guint items_per_notification, + int priority, + GnomeVFSAsyncDirectoryLoadCallback callback, + gpointer callback_data) +{ + GnomeVFSJob *job; + GnomeVFSLoadDirectoryOp *load_directory_op; + GnomeVFSAsyncHandle *result; + + job = _gnome_vfs_job_new (GNOME_VFS_OP_LOAD_DIRECTORY, priority, (GFunc) callback, callback_data); + + load_directory_op = &job->op->specifics.load_directory; + load_directory_op->uri = uri == NULL ? NULL : gnome_vfs_uri_ref (uri); + load_directory_op->options = options; + load_directory_op->items_per_notification = items_per_notification; + + result = job->job_handle; + _gnome_vfs_job_go (job); + + return result; +} + + + +/** + * gnome_vfs_async_load_directory: + * @handle_return: when the function returns will point to a handle for + * the async operation. + * @text_uri: string representing the URI of the directory to be loaded + * @options: packed boolean type providing control over various details + * of the get_file_info operation. + * @items_per_notification: number of files to process in a row before calling @callback + * @priority: a value from %GNOME_VFS_PRIORITY_MIN to %GNOME_VFS_PRIORITY_MAX (normally + * should be %GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job + * in allocating threads from the thread pool. + * @callback: function to be called when the operation is complete + * @callback_data: data to pass @callback + * + * Read the contents of the directory at @text_uri, passing back GnomeVFSFileInfo + * structs about each file in the directory to @callback. @items_per_notification + * files will be processed between each call to @callback. + **/ +void +gnome_vfs_async_load_directory (GnomeVFSAsyncHandle **handle_return, + const gchar *text_uri, + GnomeVFSFileInfoOptions options, + guint items_per_notification, + int priority, + GnomeVFSAsyncDirectoryLoadCallback callback, + gpointer callback_data) +{ + GnomeVFSURI *uri; + + g_return_if_fail (handle_return != NULL); + g_return_if_fail (text_uri != NULL); + g_return_if_fail (callback != NULL); + g_return_if_fail (priority >= GNOME_VFS_PRIORITY_MIN); + g_return_if_fail (priority <= GNOME_VFS_PRIORITY_MAX); + + uri = gnome_vfs_uri_new (text_uri); + *handle_return = async_load_directory (uri, options, + items_per_notification, + priority, + callback, callback_data); + if (uri != NULL) { + gnome_vfs_uri_unref (uri); + } +} + +/** + * gnome_vfs_async_load_directory_uri: + * @handle_return: when the function returns will point to a handle for + * the async operation. + * @uri: string representing the URI of the directory to be loaded + * @options: packed boolean type providing control over various details + * of the get_file_info operation. + * @items_per_notification: number of files to process in a row before calling @callback + * @priority: a value from %GNOME_VFS_PRIORITY_MIN to %GNOME_VFS_PRIORITY_MAX (normally + * should be %GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job + * in allocating threads from the thread pool. + * @callback: function to be called when the operation is complete + * @callback_data: data to pass @callback + * + * Read the contents of the directory at @uri, passing back GnomeVFSFileInfo structs + * about each file in the directory to @callback. @items_per_notification + * files will be processed between each call to @callback. + **/ +void +gnome_vfs_async_load_directory_uri (GnomeVFSAsyncHandle **handle_return, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options, + guint items_per_notification, + int priority, + GnomeVFSAsyncDirectoryLoadCallback callback, + gpointer callback_data) +{ + g_return_if_fail (handle_return != NULL); + g_return_if_fail (uri != NULL); + g_return_if_fail (callback != NULL); + g_return_if_fail (priority >= GNOME_VFS_PRIORITY_MIN); + g_return_if_fail (priority <= GNOME_VFS_PRIORITY_MAX); + + *handle_return = async_load_directory (uri, options, + items_per_notification, + priority, + callback, callback_data); +} + +/** + * gnome_vfs_async_xfer: + * @handle_return: when the function returns will point to a handle for + * @source_uri_list: #GList of #GnomeVFSURI representing the files to be transferred + * @target_uri_list: #GList of #GnomeVFSURI, the target locations for the elements + * in @source_uri_list + * @xfer_options: various options controlling the details of the transfer. + * Use %GNOME_VFS_XFER_REMOUVESOURCE to make the operation a move rather than a copy. + * @error_mode: report errors to the @progress_sync_callback, or simply abort + * @overwrite_mode: controls whether the xfer engine will overwrite automatically, + * skip the file, abort the operation, or query @progress_sync_callback + * @priority: a value from %GNOME_VFS_PRIORITY_MIN to %GNOME_VFS_PRIORITY_MAX (normally + * should be %GNOME_VFS_PRIORITY_DEFAULT) indicating the priority to assign this job + * in allocating threads from the thread pool. + * @progress_update_callback: called periodically to keep the client appraised of progress + * in completing the XFer operation, and the current phase of operation. + * @update_callback_data: user data passed to @progress_update_callback + * @progress_sync_callback: called when the program requires responses to interactive queries + * (e.g. overwriting files, handling errors, etc) + * @sync_callback_data: user data passed to @progress_sync_callback + * + * Perform a copy operation in a seperate thread. @progress_update_callback will be periodically + * polled with status of the operation (percent done, the current phase of operation, the + * current file being operated upon). If the xfer engine needs to query the caller to make + * a decision or report on important error it will do so on @progress_sync_callback. + * + * Return value: %GNOME_VFS_OK if the paramaters were in order, + * or %GNOME_VFS_ERROR_BAD_PARAMETERS if something was wrong in the passed in arguments. + **/ +GnomeVFSResult +gnome_vfs_async_xfer (GnomeVFSAsyncHandle **handle_return, + GList *source_uri_list, + GList *target_uri_list, + GnomeVFSXferOptions xfer_options, + GnomeVFSXferErrorMode error_mode, + GnomeVFSXferOverwriteMode overwrite_mode, + int priority, + GnomeVFSAsyncXferProgressCallback progress_update_callback, + gpointer update_callback_data, + GnomeVFSXferProgressCallback progress_sync_callback, + gpointer sync_callback_data) +{ + GnomeVFSJob *job; + GnomeVFSXferOp *xfer_op; + + g_return_val_if_fail (handle_return != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail (progress_update_callback != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail (priority >= GNOME_VFS_PRIORITY_MIN, GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail (priority <= GNOME_VFS_PRIORITY_MAX, GNOME_VFS_ERROR_BAD_PARAMETERS); + + job = _gnome_vfs_job_new (GNOME_VFS_OP_XFER, + priority, + (GFunc) progress_update_callback, + update_callback_data); + + + xfer_op = &job->op->specifics.xfer; + xfer_op->source_uri_list = gnome_vfs_uri_list_copy (source_uri_list); + xfer_op->target_uri_list = gnome_vfs_uri_list_copy (target_uri_list); + xfer_op->xfer_options = xfer_options; + xfer_op->error_mode = error_mode; + xfer_op->overwrite_mode = overwrite_mode; + xfer_op->progress_sync_callback = progress_sync_callback; + xfer_op->sync_callback_data = sync_callback_data; + + *handle_return = job->job_handle; + _gnome_vfs_job_go (job); + + return GNOME_VFS_OK; +} + +/** + * gnome_vfs_async_file_control: + * @handle: handle of the file to affect + * @operation: The operation to execute + * @operation_data: The data needed to execute the operation + * @operation_data_destroy_func: Called to destroy operation_data when its no longer needed + * @callback: function to be called when the operation is complete + * @callback_data: data to pass @callback + * + * Execute a backend dependent operation specified by the string @operation. + * This is typically used for specialized vfs backends that need additional + * operations that gnome-vfs doesn't have. Compare it to the unix call ioctl(). + * The format of @operation_data depends on the operation. Operation that are + * backend specific are normally namespaced by their module name. + * + * When the operation is complete, @callback will be called with the + * result of the operation, @operation_data and @callback_data. + * + * Since: 2.2 + **/ +void +gnome_vfs_async_file_control (GnomeVFSAsyncHandle *handle, + const char *operation, + gpointer operation_data, + GDestroyNotify operation_data_destroy_func, + GnomeVFSAsyncFileControlCallback callback, + gpointer callback_data) +{ + GnomeVFSJob *job; + GnomeVFSFileControlOp *file_control_op; + + g_return_if_fail (handle != NULL); + g_return_if_fail (operation != NULL); + g_return_if_fail (callback != NULL); + + _gnome_vfs_async_job_map_lock (); + job = _gnome_vfs_async_job_map_get_job (handle); + if (job == NULL) { + g_warning ("trying to call file_control on a non-existing handle"); + _gnome_vfs_async_job_map_unlock (); + return; + } + + _gnome_vfs_job_set (job, GNOME_VFS_OP_FILE_CONTROL, + (GFunc) callback, callback_data); + + file_control_op = &job->op->specifics.file_control; + file_control_op->operation = g_strdup (operation); + file_control_op->operation_data = operation_data; + file_control_op->operation_data_destroy_func = operation_data_destroy_func; + + _gnome_vfs_job_go (job); + _gnome_vfs_async_job_map_unlock (); +} + +#ifdef OLD_CONTEXT_DEPRECATED + +guint +gnome_vfs_async_add_status_callback (GnomeVFSAsyncHandle *handle, + GnomeVFSStatusCallback callback, + gpointer user_data) +{ + GnomeVFSJob *job; + guint result; + + g_return_val_if_fail (handle != NULL, 0); + g_return_val_if_fail (callback != NULL, 0); + + _gnome_vfs_async_job_map_lock (); + job = _gnome_vfs_async_job_map_get_job (handle); + + if (job->op != NULL || job->op->context != NULL) { + g_warning ("job or context not found"); + _gnome_vfs_async_job_map_unlock (); + return 0; + } + + result = gnome_vfs_message_callbacks_add + (gnome_vfs_context_get_message_callbacks (job->op->context), + callback, user_data); + _gnome_vfs_async_job_map_unlock (); + + return result; +} + +void +gnome_vfs_async_remove_status_callback (GnomeVFSAsyncHandle *handle, + guint callback_id) +{ + GnomeVFSJob *job; + + g_return_if_fail (handle != NULL); + g_return_if_fail (callback_id > 0); + + _gnome_vfs_async_job_map_lock (); + job = _gnome_vfs_async_job_map_get_job (handle); + + if (job->op != NULL || job->op->context != NULL) { + g_warning ("job or context not found"); + _gnome_vfs_async_job_map_unlock (); + return; + } + + gnome_vfs_message_callbacks_remove + (gnome_vfs_context_get_message_callbacks (job->op->context), + callback_id); + + _gnome_vfs_async_job_map_unlock (); +} + +#endif /* OLD_CONTEXT_DEPRECATED */ diff --git a/libgnomevfs/gnome-vfs-async-ops.h b/libgnomevfs/gnome-vfs-async-ops.h new file mode 100644 index 0000000..9813578 --- /dev/null +++ b/libgnomevfs/gnome-vfs-async-ops.h @@ -0,0 +1,425 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* gnome-vfs-async-ops.h - Asynchronous operations in the GNOME Virtual File + System. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli */ + +#ifndef GNOME_VFS_ASYNC_OPS_H +#define GNOME_VFS_ASYNC_OPS_H + +#include +#include +#include +#include +#include + +G_BEGIN_DECLS + +/** + * GNOME_VFS_PRIORITY_MIN: + * + * The minimuum priority a job can have. + **/ +/** + * GNOME_VFS_PRIORITY_MAX: + * + * The maximuum priority a job can have. + **/ +/** + * GNOME_VFS_PRIORITY_DEFAULT: + * + * The default job priority. Its best to use this + * unless you have a reason to do otherwise. + **/ + +#define GNOME_VFS_PRIORITY_MIN -10 +#define GNOME_VFS_PRIORITY_MAX 10 +#define GNOME_VFS_PRIORITY_DEFAULT 0 + +typedef struct GnomeVFSAsyncHandle GnomeVFSAsyncHandle; + +/** + * GnomeVFSAsyncCallback: + * @handle: handle of the operation generating the callback + * @result: %GNOME_VFS_OK if the operation was successful, otherwise + * an error code. + * @callback_data: user data defined when the callback was established + * + * Basic callback from an async operation that passes no data back, + * informing the user of the @result of the operation. + **/ +typedef void (* GnomeVFSAsyncCallback) (GnomeVFSAsyncHandle *handle, + GnomeVFSResult result, + gpointer callback_data); + +/** + * GnomeVFSAsyncOpenCallback: + * @handle: handle of the operation generating the callback + * @result: %GNOME_VFS_OK if the operation was successful, otherwise + * an error code. + * @callback_data: user data defined when the callback was established + * + * Basic callback from an async operation that passes no data back, + * informing the user of the @result of the operation. + **/ +typedef GnomeVFSAsyncCallback GnomeVFSAsyncOpenCallback; + +/** + * GnomeVFSAsyncCreateCallback: + * @handle: handle of the operation generating the callback + * @result: %GNOME_VFS_OK if the operation was successful, otherwise + * an error code. + * @callback_data: user data defined when the callback was established + * + * Basic callback from an async operation that passes no data back, + * informing the user of the @result of the operation. + **/ +typedef GnomeVFSAsyncCallback GnomeVFSAsyncCreateCallback; + +/** + * GnomeVFSAsyncCloseCallback: + * @handle: handle of the operation generating the callback + * @result: %GNOME_VFS_OK if the operation was successful, otherwise + * an error code. + * @callback_data: user data defined when the callback was established + * + * Basic callback from an async operation that passes no data back, + * informing the user of the @result of the operation. + **/ +typedef GnomeVFSAsyncCallback GnomeVFSAsyncCloseCallback; + +/** + * GnomeVFSAsyncOpenAsChannelCallback: + * @handle: handle of the operation generating the callback + * @channel: a #GIOChannel corresponding to the file opened + * @result: %GNOME_VFS_OK if the operation was successful, otherwise + * an error code. + * @callback_data: user data defined when the callback was established + * + * Callback for the gnome_vfs_async_open_as_channel() function. + **/ +typedef void (* GnomeVFSAsyncOpenAsChannelCallback) + (GnomeVFSAsyncHandle *handle, + GIOChannel *channel, + GnomeVFSResult result, + gpointer callback_data); + +/** + * GnomeVFSAsyncCreateAsChannelCallback: + * @handle: handle of the operation generating the callback + * @channel: a #GIOChannel corresponding to the file created + * @result: %GNOME_VFS_OK if the operation was successful, otherwise + * an error code. + * @callback_data: user data defined when the callback was established + * + * Callback for the gnome_vfs_async_create_as_channel() function. + **/ +typedef GnomeVFSAsyncOpenAsChannelCallback GnomeVFSAsyncCreateAsChannelCallback; + +/** + * GnomeVFSAsyncReadCallback: + * @handle: handle of the operation generating the callback + * @result: %GNOME_VFS_OK if the operation was successful, otherwise + * an error code. + * @buffer: buffer containing data read from @handle. + * @bytes_requested: the number of bytes asked for in the call to + * gnome_vfs_async_read(). + * @bytes_read: the number of bytes actually read from @handle into @buffer. + * @callback_data: user data defined when the callback was established + * + * Callback for the gnome_vfs_async_read() function. + **/ +typedef void (* GnomeVFSAsyncReadCallback) (GnomeVFSAsyncHandle *handle, + GnomeVFSResult result, + gpointer buffer, + GnomeVFSFileSize bytes_requested, + GnomeVFSFileSize bytes_read, + gpointer callback_data); + +/** + * GnomeVFSAsyncWriteCallback: + * @handle: handle of the operation generating the callback + * @result: %GNOME_VFS_OK if the operation was successful, otherwise + * an error code. + * @buffer: buffer containing data written to @handle. + * @bytes_requested: the number of bytes asked to write in the call to + * gnome_vfs_async_write(). + * @bytes_written: the number of bytes actually written to @handle from @buffer. + * @callback_data: user data defined when the callback was established + * + * Callback for the gnome_vfs_async_write() function. + **/ +typedef void (* GnomeVFSAsyncWriteCallback) (GnomeVFSAsyncHandle *handle, + GnomeVFSResult result, + gconstpointer buffer, + GnomeVFSFileSize bytes_requested, + GnomeVFSFileSize bytes_written, + gpointer callback_data); + + +/** + * GnomeVFSAsyncGetFileInfoCallback: + * @handle: handle of the operation generating the callback + * @results: #GList of #GnomeVFSFileInfoResult * items representing + * the success of each gnome_vfs_get_file_info() and the data retrieved. + * @callback_data: user data defined when the callback was established + * + * Callback for the gnome_vfs_async_get_file_info() function. + **/ +typedef void (* GnomeVFSAsyncGetFileInfoCallback) + (GnomeVFSAsyncHandle *handle, + GList *results, /* GnomeVFSGetFileInfoResult* items */ + gpointer callback_data); + +/** + * GnomeVFSAsyncSetFileInfoCallback: + * @handle: handle of the operation generating the callback + * @result: %GNOME_VFS_OK if the operation was successful, otherwise a + * #GnomeVFSResult error code + * @file_info: if @result is %GNOME_VFS_OK, a #GnomeVFSFileInfo struct containing + * requested information about the file + * @callback_data: user data defined when the callback was established + * + * Callback for th egnome_vfs_async_set_file_info() function. + **/ +typedef void (* GnomeVFSAsyncSetFileInfoCallback) + (GnomeVFSAsyncHandle *handle, + GnomeVFSResult result, + GnomeVFSFileInfo *file_info, + gpointer callback_data); + + +/** + * GnomeVFSAsyncDirectoryLoadCallback: + * @handle: handle of the operation generating the callback + * @result: %GNOME_VFS_OK if the operation was sucessful, + * %GNOME_VFS_ERROR_EOF if the last file in the directory + * has been read, otherwise a #GnomeVFSResult error code + * @list: a #GList of #GnomeVFSFileInfo structs representing + * information about the files just loaded + * @entries_read: number of entries read from @handle for this instance of + * the callback. + * @callback_data: user data defined when the callback was established + * + * Callback for the gnome_vfs_async_directory_load() function. + **/ +typedef void (* GnomeVFSAsyncDirectoryLoadCallback) + (GnomeVFSAsyncHandle *handle, + GnomeVFSResult result, + GList *list, + guint entries_read, + gpointer callback_data); + +/** + * GnomeVFSAsyncXferProgressCallback: + * @handle: handle of the xfer operation generating the callback + * @info: information on the current progress in the transfer + * @data: user data defined when the transfer was established + * + * Callback for the gnome_vfs_async_xfer() function. Called periodically + * to update the caller about the status of the transfer (percent complete, + * phase of the operation, etc). If @info->status is not %GNOME_VFS_XFER_PROGRESS_STATUS_OK + * then the callback is expected to make a "decision" about some problem / query + * during the operation. The appropriate #GnomeVFSXferErrorAction or #GnomeVFSOverwriteAction + * (depending on the particular state of @info->status) should be returned + * informing the transfer engine how to proceed. + * + * Return value: 0 or an item from #GnomeVFSXferErrorAction or #GnomeVFSOverwriteAction + **/ +typedef gint (* GnomeVFSAsyncXferProgressCallback) + (GnomeVFSAsyncHandle *handle, + GnomeVFSXferProgressInfo *info, + gpointer data); + +typedef struct { + GnomeVFSURI *uri; + GnomeVFSResult result; + + /* Reserved to avoid future breaks in ABI compatibility */ + void *reserved1; + void *reserved2; +} GnomeVFSFindDirectoryResult; + +/** + * GnomeVFSAsyncFindDirectoryCallback: + * @handle: handle of the operation generating the callback + * @results: #GList of #GnomeVFSFindDirectoryResult *s containing + * special directories matching the find criteria. + * @data: user data defined when the operation was established + * + * Callback for the gnome_vfs_async_find_directory() function. + **/ +typedef void (* GnomeVFSAsyncFindDirectoryCallback) + (GnomeVFSAsyncHandle *handle, + GList *results /* GnomeVFSFindDirectoryResult */, + gpointer data); + +typedef void (* GnomeVFSAsyncFileControlCallback) (GnomeVFSAsyncHandle *handle, + GnomeVFSResult result, + gpointer operation_data, + gpointer callback_data); + +void gnome_vfs_async_cancel (GnomeVFSAsyncHandle *handle); + +void gnome_vfs_async_open (GnomeVFSAsyncHandle **handle_return, + const gchar *text_uri, + GnomeVFSOpenMode open_mode, + int priority, + GnomeVFSAsyncOpenCallback callback, + gpointer callback_data); +void gnome_vfs_async_open_uri (GnomeVFSAsyncHandle **handle_return, + GnomeVFSURI *uri, + GnomeVFSOpenMode open_mode, + int priority, + GnomeVFSAsyncOpenCallback callback, + gpointer callback_data); +void gnome_vfs_async_open_as_channel (GnomeVFSAsyncHandle **handle_return, + const gchar *text_uri, + GnomeVFSOpenMode open_mode, + guint advised_block_size, + int priority, + GnomeVFSAsyncOpenAsChannelCallback callback, + gpointer callback_data); +void gnome_vfs_async_open_uri_as_channel (GnomeVFSAsyncHandle **handle_return, + GnomeVFSURI *uri, + GnomeVFSOpenMode open_mode, + guint advised_block_size, + int priority, + GnomeVFSAsyncOpenAsChannelCallback callback, + gpointer callback_data); +void gnome_vfs_async_create (GnomeVFSAsyncHandle **handle_return, + const gchar *text_uri, + GnomeVFSOpenMode open_mode, + gboolean exclusive, + guint perm, + int priority, + GnomeVFSAsyncOpenCallback callback, + gpointer callback_data); +void gnome_vfs_async_create_uri (GnomeVFSAsyncHandle **handle_return, + GnomeVFSURI *uri, + GnomeVFSOpenMode open_mode, + gboolean exclusive, + guint perm, + int priority, + GnomeVFSAsyncOpenCallback callback, + gpointer callback_data); +void gnome_vfs_async_create_symbolic_link (GnomeVFSAsyncHandle **handle_return, + GnomeVFSURI *uri, + const gchar *uri_reference, + int priority, + GnomeVFSAsyncOpenCallback callback, + gpointer callback_data); +void gnome_vfs_async_create_as_channel (GnomeVFSAsyncHandle **handle_return, + const gchar *text_uri, + GnomeVFSOpenMode open_mode, + gboolean exclusive, + guint perm, + int priority, + GnomeVFSAsyncCreateAsChannelCallback callback, + gpointer callback_data); +void gnome_vfs_async_create_uri_as_channel (GnomeVFSAsyncHandle **handle_return, + GnomeVFSURI *uri, + GnomeVFSOpenMode open_mode, + gboolean exclusive, + guint perm, + int priority, + GnomeVFSAsyncCreateAsChannelCallback callback, + gpointer callback_data); +void gnome_vfs_async_close (GnomeVFSAsyncHandle *handle, + GnomeVFSAsyncCloseCallback callback, + gpointer callback_data); +void gnome_vfs_async_read (GnomeVFSAsyncHandle *handle, + gpointer buffer, + guint bytes, + GnomeVFSAsyncReadCallback callback, + gpointer callback_data); +void gnome_vfs_async_write (GnomeVFSAsyncHandle *handle, + gconstpointer buffer, + guint bytes, + GnomeVFSAsyncWriteCallback callback, + gpointer callback_data); +void gnome_vfs_async_get_file_info (GnomeVFSAsyncHandle **handle_return, + GList *uri_list, + GnomeVFSFileInfoOptions options, + int priority, + GnomeVFSAsyncGetFileInfoCallback callback, + gpointer callback_data); + +/* Setting the file info sometimes changes more info than the + * caller specified; for example, if the name changes the MIME type might + * change, and if the owner changes the SUID & SGID bits might change. + * Therefore the callback returns the new file info for the caller's + * convenience. The GnomeVFSFileInfoOptions passed here are those used + * for the returned file info; they are not used when setting. + */ +void gnome_vfs_async_set_file_info (GnomeVFSAsyncHandle **handle_return, + GnomeVFSURI *uri, + GnomeVFSFileInfo *info, + GnomeVFSSetFileInfoMask mask, + GnomeVFSFileInfoOptions options, + int priority, + GnomeVFSAsyncSetFileInfoCallback callback, + gpointer callback_data); +void gnome_vfs_async_load_directory (GnomeVFSAsyncHandle **handle_return, + const gchar *text_uri, + GnomeVFSFileInfoOptions options, + guint items_per_notification, + int priority, + GnomeVFSAsyncDirectoryLoadCallback callback, + gpointer callback_data); +void gnome_vfs_async_load_directory_uri (GnomeVFSAsyncHandle **handle_return, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options, + guint items_per_notification, + int priority, + GnomeVFSAsyncDirectoryLoadCallback callback, + gpointer callback_data); +GnomeVFSResult gnome_vfs_async_xfer (GnomeVFSAsyncHandle **handle_return, + GList *source_uri_list, + GList *target_uri_list, + GnomeVFSXferOptions xfer_options, + GnomeVFSXferErrorMode error_mode, + GnomeVFSXferOverwriteMode overwrite_mode, + int priority, + GnomeVFSAsyncXferProgressCallback progress_update_callback, + gpointer update_callback_data, + GnomeVFSXferProgressCallback progress_sync_callback, + gpointer sync_callback_data); +void gnome_vfs_async_find_directory (GnomeVFSAsyncHandle **handle_return, + GList *near_uri_list, + GnomeVFSFindDirectoryKind kind, + gboolean create_if_needed, + gboolean find_if_needed, + guint permissions, + int priority, + GnomeVFSAsyncFindDirectoryCallback callback, + gpointer user_data); + +void gnome_vfs_async_file_control (GnomeVFSAsyncHandle *handle, + const char *operation, + gpointer operation_data, + GDestroyNotify operation_data_destroy_func, + GnomeVFSAsyncFileControlCallback callback, + gpointer callback_data); + +G_END_DECLS + +#endif /* GNOME_VFS_ASYNC_OPS_H */ diff --git a/libgnomevfs/gnome-vfs-backend.h b/libgnomevfs/gnome-vfs-backend.h new file mode 100644 index 0000000..3596b49 --- /dev/null +++ b/libgnomevfs/gnome-vfs-backend.h @@ -0,0 +1,22 @@ +#ifndef GNOME_VFS_BACKEND_H +#define GNOME_VFS_BACKEND_H + +#include +#include + +G_BEGIN_DECLS + +void _gnome_vfs_get_current_context (/* OUT */ GnomeVFSContext **context); +void _gnome_vfs_dispatch_module_callback (GnomeVFSAsyncModuleCallback callback, + gconstpointer in, + gsize in_size, + gpointer out, + gsize out_size, + gpointer user_data, + GnomeVFSModuleCallbackResponse response, + gpointer response_data); + + +G_END_DECLS + +#endif diff --git a/libgnomevfs/gnome-vfs-cancellable-ops.c b/libgnomevfs/gnome-vfs-cancellable-ops.c new file mode 100644 index 0000000..08bcd62 --- /dev/null +++ b/libgnomevfs/gnome-vfs-cancellable-ops.c @@ -0,0 +1,449 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-private-ops.c - Private synchronous operations for the GNOME + Virtual File System. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli */ + +/* This file provides private versions of the ops for internal use. These are + meant to be used within the GNOME VFS and its modules: they are not for + public consumption through the external API. */ + +#include +#include "gnome-vfs-cancellable-ops.h" +#include "gnome-vfs-method.h" +#include "gnome-vfs-handle-private.h" + +#include +#include +#include + +GnomeVFSResult +gnome_vfs_open_uri_cancellable (GnomeVFSHandle **handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode open_mode, + GnomeVFSContext *context) +{ + GnomeVFSMethodHandle *method_handle; + GnomeVFSResult result; + + g_return_val_if_fail (handle != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail (uri != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail (uri->method != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + if (gnome_vfs_context_check_cancellation (context)) + return GNOME_VFS_ERROR_CANCELLED; + + if (!VFS_METHOD_HAS_FUNC(uri->method, open)) + return GNOME_VFS_ERROR_NOT_SUPPORTED; + + result = uri->method->open (uri->method, &method_handle, uri, open_mode, + context); + + if (result != GNOME_VFS_OK) + return result; + + *handle = _gnome_vfs_handle_new (uri, method_handle, open_mode); + + return GNOME_VFS_OK; +} + +GnomeVFSResult +gnome_vfs_create_uri_cancellable (GnomeVFSHandle **handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode open_mode, + gboolean exclusive, + guint perm, + GnomeVFSContext *context) +{ + GnomeVFSMethodHandle *method_handle; + GnomeVFSResult result; + + g_return_val_if_fail (handle != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail (uri != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + if (gnome_vfs_context_check_cancellation (context)) + return GNOME_VFS_ERROR_CANCELLED; + + if (!VFS_METHOD_HAS_FUNC(uri->method, create)) + return GNOME_VFS_ERROR_NOT_SUPPORTED; + + result = uri->method->create (uri->method, &method_handle, uri, open_mode, + exclusive, perm, context); + if (result != GNOME_VFS_OK) + return result; + + *handle = _gnome_vfs_handle_new (uri, method_handle, open_mode); + + return GNOME_VFS_OK; +} + +GnomeVFSResult +gnome_vfs_close_cancellable (GnomeVFSHandle *handle, + GnomeVFSContext *context) +{ + g_return_val_if_fail (handle != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + if (gnome_vfs_context_check_cancellation (context)) + return GNOME_VFS_ERROR_CANCELLED; + + return _gnome_vfs_handle_do_close (handle, context); +} + +GnomeVFSResult +gnome_vfs_read_cancellable (GnomeVFSHandle *handle, + gpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_read, + GnomeVFSContext *context) +{ + GnomeVFSFileSize dummy_bytes_read; + + g_return_val_if_fail (handle != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + if (gnome_vfs_context_check_cancellation (context)) + return GNOME_VFS_ERROR_CANCELLED; + + if (bytes_read == NULL) { + bytes_read = &dummy_bytes_read; + } + + return _gnome_vfs_handle_do_read (handle, buffer, bytes, bytes_read, + context); +} + +GnomeVFSResult +gnome_vfs_write_cancellable (GnomeVFSHandle *handle, + gconstpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_written, + GnomeVFSContext *context) +{ + GnomeVFSFileSize dummy_bytes_written; + + g_return_val_if_fail (handle != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + if (gnome_vfs_context_check_cancellation (context)) + return GNOME_VFS_ERROR_CANCELLED; + + if (bytes_written == NULL) { + bytes_written = &dummy_bytes_written; + } + + return _gnome_vfs_handle_do_write (handle, buffer, bytes, + bytes_written, context); +} + +GnomeVFSResult +gnome_vfs_seek_cancellable (GnomeVFSHandle *handle, + GnomeVFSSeekPosition whence, + GnomeVFSFileOffset offset, + GnomeVFSContext *context) +{ + g_return_val_if_fail (handle != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + if (gnome_vfs_context_check_cancellation (context)) + return GNOME_VFS_ERROR_CANCELLED; + + return _gnome_vfs_handle_do_seek (handle, whence, offset, context); +} + +GnomeVFSResult +gnome_vfs_get_file_info_uri_cancellable (GnomeVFSURI *uri, + GnomeVFSFileInfo *info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + + g_return_val_if_fail (uri != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + if (gnome_vfs_context_check_cancellation (context)) + return GNOME_VFS_ERROR_CANCELLED; + + if (!VFS_METHOD_HAS_FUNC(uri->method, get_file_info)) + return GNOME_VFS_ERROR_NOT_SUPPORTED; + + result = uri->method->get_file_info (uri->method, uri, info, options, + context); + + return result; +} + +GnomeVFSResult +gnome_vfs_get_file_info_from_handle_cancellable (GnomeVFSHandle *handle, + GnomeVFSFileInfo *info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) + +{ + GnomeVFSResult result; + + g_return_val_if_fail (handle != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + if (gnome_vfs_context_check_cancellation (context)) + return GNOME_VFS_ERROR_CANCELLED; + + + result = _gnome_vfs_handle_do_get_file_info (handle, info, + options, + context); + + return result; +} + +GnomeVFSResult +gnome_vfs_truncate_uri_cancellable (GnomeVFSURI *uri, + GnomeVFSFileSize length, + GnomeVFSContext *context) +{ + g_return_val_if_fail (uri != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + if (gnome_vfs_context_check_cancellation (context)) + return GNOME_VFS_ERROR_CANCELLED; + + if (!VFS_METHOD_HAS_FUNC(uri->method, truncate)) + return GNOME_VFS_ERROR_NOT_SUPPORTED; + + return uri->method->truncate(uri->method, uri, length, context); +} + +GnomeVFSResult +gnome_vfs_truncate_handle_cancellable (GnomeVFSHandle *handle, + GnomeVFSFileSize length, + GnomeVFSContext *context) +{ + g_return_val_if_fail (handle != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + if (gnome_vfs_context_check_cancellation (context)) + return GNOME_VFS_ERROR_CANCELLED; + + return _gnome_vfs_handle_do_truncate (handle, length, context); +} + +GnomeVFSResult +gnome_vfs_make_directory_for_uri_cancellable (GnomeVFSURI *uri, + guint perm, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + + g_return_val_if_fail (uri != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + if (gnome_vfs_context_check_cancellation (context)) + return GNOME_VFS_ERROR_CANCELLED; + + if (!VFS_METHOD_HAS_FUNC(uri->method, make_directory)) + return GNOME_VFS_ERROR_NOT_SUPPORTED; + + result = uri->method->make_directory (uri->method, uri, perm, context); + return result; +} + +GnomeVFSResult +gnome_vfs_find_directory_cancellable (GnomeVFSURI *near_uri, + GnomeVFSFindDirectoryKind kind, + GnomeVFSURI **result_uri, + gboolean create_if_needed, + gboolean find_if_needed, + guint permissions, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + + g_return_val_if_fail (result_uri != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + if (gnome_vfs_context_check_cancellation (context)) + return GNOME_VFS_ERROR_CANCELLED; + + if (near_uri != NULL) { + gnome_vfs_uri_ref (near_uri); + } else { + /* assume file: method and the home directory */ + near_uri = gnome_vfs_uri_new (g_get_home_dir()); + } + + g_assert (near_uri != NULL); + + if (!VFS_METHOD_HAS_FUNC(near_uri->method, find_directory)) { + gnome_vfs_uri_unref (near_uri); + return GNOME_VFS_ERROR_NOT_SUPPORTED; + } + + result = near_uri->method->find_directory (near_uri->method, near_uri, kind, + result_uri, create_if_needed, find_if_needed, permissions, context); + + gnome_vfs_uri_unref (near_uri); + return result; +} + +GnomeVFSResult +gnome_vfs_remove_directory_from_uri_cancellable (GnomeVFSURI *uri, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + + g_return_val_if_fail (uri != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + if (gnome_vfs_context_check_cancellation (context)) { + return GNOME_VFS_ERROR_CANCELLED; + } + + if (!VFS_METHOD_HAS_FUNC(uri->method, remove_directory)) { + return GNOME_VFS_ERROR_NOT_SUPPORTED; + } + + result = uri->method->remove_directory (uri->method, uri, context); + return result; +} + +GnomeVFSResult +gnome_vfs_unlink_from_uri_cancellable (GnomeVFSURI *uri, + GnomeVFSContext *context) +{ + g_return_val_if_fail (uri != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + if (gnome_vfs_context_check_cancellation (context)) { + return GNOME_VFS_ERROR_CANCELLED; + } + + if (!VFS_METHOD_HAS_FUNC(uri->method, unlink)) { + return GNOME_VFS_ERROR_NOT_SUPPORTED; + } + + return uri->method->unlink (uri->method, uri, context); +} + +GnomeVFSResult +gnome_vfs_create_symbolic_link_cancellable (GnomeVFSURI *uri, + const char *target_reference, + GnomeVFSContext *context) +{ + g_return_val_if_fail (uri != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + if (gnome_vfs_context_check_cancellation (context)) { + return GNOME_VFS_ERROR_CANCELLED; + } + + if (!VFS_METHOD_HAS_FUNC(uri->method, create_symbolic_link)) { + return GNOME_VFS_ERROR_NOT_SUPPORTED; + } + + return uri->method->create_symbolic_link (uri->method, uri, target_reference, context); +} + +static gboolean +check_same_fs_in_uri (GnomeVFSURI *a, + GnomeVFSURI *b) +{ + if (a->method != b->method) { + return FALSE; + } + + if (strcmp (a->method_string, b->method_string) != 0) { + return FALSE; + } + + return TRUE; +} + +GnomeVFSResult +gnome_vfs_move_uri_cancellable (GnomeVFSURI *old, + GnomeVFSURI *new, + gboolean force_replace, + GnomeVFSContext *context) +{ + g_return_val_if_fail (old != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail (new != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + if (gnome_vfs_context_check_cancellation (context)) + return GNOME_VFS_ERROR_CANCELLED; + + if (! check_same_fs_in_uri (old, new)) + return GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM; + + if (gnome_vfs_uri_equal (old, new)) { + return GNOME_VFS_OK; + } + + if (!VFS_METHOD_HAS_FUNC(old->method, move)) + return GNOME_VFS_ERROR_NOT_SUPPORTED; + + return old->method->move (old->method, old, new, force_replace, context); +} + +GnomeVFSResult +gnome_vfs_check_same_fs_uris_cancellable (GnomeVFSURI *a, + GnomeVFSURI *b, + gboolean *same_fs_return, + GnomeVFSContext *context) +{ + g_return_val_if_fail (a != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail (b != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail (same_fs_return != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + if (gnome_vfs_context_check_cancellation (context)) + return GNOME_VFS_ERROR_CANCELLED; + + if (! check_same_fs_in_uri (a, b)) { + *same_fs_return = FALSE; + return GNOME_VFS_OK; + } + + if (!VFS_METHOD_HAS_FUNC(a->method, check_same_fs)) { + *same_fs_return = FALSE; + return GNOME_VFS_OK; + } + + return a->method->check_same_fs (a->method, a, b, same_fs_return, context); +} + +GnomeVFSResult +gnome_vfs_set_file_info_cancellable (GnomeVFSURI *a, + const GnomeVFSFileInfo *info, + GnomeVFSSetFileInfoMask mask, + GnomeVFSContext *context) +{ + g_return_val_if_fail (a != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail (info != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + if (gnome_vfs_context_check_cancellation (context)) + return GNOME_VFS_ERROR_CANCELLED; + + if (!VFS_METHOD_HAS_FUNC(a->method, set_file_info)) + return GNOME_VFS_ERROR_NOT_SUPPORTED; + + return a->method->set_file_info (a->method, a, info, mask, context); +} + +GnomeVFSResult +gnome_vfs_file_control_cancellable (GnomeVFSHandle *handle, + const char *operation, + gpointer operation_data, + GnomeVFSContext *context) +{ + g_return_val_if_fail (handle != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail (operation != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + if (gnome_vfs_context_check_cancellation (context)) + return GNOME_VFS_ERROR_CANCELLED; + + return _gnome_vfs_handle_do_file_control (handle, operation, operation_data, context); +} + diff --git a/libgnomevfs/gnome-vfs-cancellable-ops.h b/libgnomevfs/gnome-vfs-cancellable-ops.h new file mode 100644 index 0000000..296276a --- /dev/null +++ b/libgnomevfs/gnome-vfs-cancellable-ops.h @@ -0,0 +1,163 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-private-ops.h - Private synchronous operations for the GNOME + Virtual File System. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli */ + +#ifndef GNOME_VFS_CANCELLABLE_OPS_H +#define GNOME_VFS_CANCELLABLE_OPS_H + +#include +#include +#include +#include + +G_BEGIN_DECLS + +GnomeVFSResult gnome_vfs_open_uri_cancellable + (GnomeVFSHandle **handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode open_mode, + GnomeVFSContext *context); + +GnomeVFSResult gnome_vfs_create_uri_cancellable + (GnomeVFSHandle **handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode open_mode, + gboolean exclusive, + guint perm, + GnomeVFSContext *context); + +GnomeVFSResult gnome_vfs_close_cancellable + (GnomeVFSHandle *handle, + GnomeVFSContext *context); + +GnomeVFSResult gnome_vfs_read_cancellable + (GnomeVFSHandle *handle, + gpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_written, + GnomeVFSContext *context); + +GnomeVFSResult gnome_vfs_write_cancellable + (GnomeVFSHandle *handle, + gconstpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_written, + GnomeVFSContext *context); + +GnomeVFSResult gnome_vfs_seek_cancellable + (GnomeVFSHandle *handle, + GnomeVFSSeekPosition whence, + GnomeVFSFileOffset offset, + GnomeVFSContext *context); + +GnomeVFSResult gnome_vfs_get_file_info_uri_cancellable + (GnomeVFSURI *uri, + GnomeVFSFileInfo *info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context); + +GnomeVFSResult gnome_vfs_get_file_info_from_handle_cancellable + (GnomeVFSHandle *handle, + GnomeVFSFileInfo *info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context); + +GnomeVFSResult gnome_vfs_truncate_uri_cancellable (GnomeVFSURI *uri, + GnomeVFSFileSize length, + GnomeVFSContext *context); + +GnomeVFSResult gnome_vfs_truncate_handle_cancellable (GnomeVFSHandle *handle, + GnomeVFSFileSize length, + GnomeVFSContext *context); + +GnomeVFSResult gnome_vfs_make_directory_for_uri_cancellable + (GnomeVFSURI *uri, + guint perm, + GnomeVFSContext *context); + +GnomeVFSResult gnome_vfs_find_directory_cancellable (GnomeVFSURI *near_uri, + GnomeVFSFindDirectoryKind kind, + GnomeVFSURI **result_uri, + gboolean create_if_needed, + gboolean find_if_needed, + guint permissions, + GnomeVFSContext *context); + +GnomeVFSResult gnome_vfs_remove_directory_from_uri_cancellable + (GnomeVFSURI *uri, + GnomeVFSContext *context); + +GnomeVFSResult gnome_vfs_unlink_from_uri_cancellable + (GnomeVFSURI *uri, + GnomeVFSContext *context); +GnomeVFSResult gnome_vfs_create_symbolic_link_cancellable + (GnomeVFSURI *uri, + const gchar *target_reference, + GnomeVFSContext *context); +GnomeVFSResult gnome_vfs_move_uri_cancellable + (GnomeVFSURI *old, + GnomeVFSURI *new, + gboolean force_replace, + GnomeVFSContext *context); + +GnomeVFSResult gnome_vfs_check_same_fs_uris_cancellable + (GnomeVFSURI *a, + GnomeVFSURI *b, + gboolean *same_fs_return, + GnomeVFSContext *context); + +GnomeVFSResult gnome_vfs_set_file_info_cancellable + (GnomeVFSURI *a, + const GnomeVFSFileInfo *info, + GnomeVFSSetFileInfoMask mask, + GnomeVFSContext *context); + +GnomeVFSResult _gnome_vfs_xfer_private (const GList *source_uri_list, + const GList *target_uri_list, + GnomeVFSXferOptions xfer_options, + GnomeVFSXferErrorMode error_mode, + GnomeVFSXferOverwriteMode overwrite_mode, + GnomeVFSXferProgressCallback progress_callback, + gpointer data, + GnomeVFSXferProgressCallback sync_progress_callback, + gpointer sync_progress_data); + +GnomeVFSResult gnome_vfs_directory_read_next_cancellable + (GnomeVFSDirectoryHandle *handle, + GnomeVFSFileInfo *info, + GnomeVFSContext *context); + +GnomeVFSResult gnome_vfs_directory_open_from_uri_cancellable + (GnomeVFSDirectoryHandle **handle, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context); + +GnomeVFSResult gnome_vfs_file_control_cancellable + (GnomeVFSHandle *handle, + const char *operation, + gpointer operation_data, + GnomeVFSContext *context); + +G_END_DECLS + +#endif /* GNOME_VFS_CANCELLABLE_OPS_H */ diff --git a/libgnomevfs/gnome-vfs-cancellation.c b/libgnomevfs/gnome-vfs-cancellation.c new file mode 100644 index 0000000..db55178 --- /dev/null +++ b/libgnomevfs/gnome-vfs-cancellation.c @@ -0,0 +1,178 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-cancellation.c - Cancellation handling for the GNOME Virtual File + System access methods. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli */ + +#include +#include "gnome-vfs-cancellation.h" + +#include "gnome-vfs-utils.h" +#include + +/* WARNING: this code is not general-purpose. It is supposed to make the two + sides of the VFS (i.e. the main process/thread and its asynchronous slave) + talk in a simple way. For this reason, only the main process/thread should + be allowed to call `gnome_vfs_cancellation_cancel()'. *All* the code is + based on this assumption. */ + + +struct GnomeVFSCancellation { + gboolean cancelled; + gint pipe_in; + gint pipe_out; +}; + + +/** + * gnome_vfs_cancellation_new: + * + * Create a new GnomeVFSCancellation object for reporting cancellation to a + * GNOME VFS module. + * + * Return value: A pointer to the new GnomeVFSCancellation object. + **/ +GnomeVFSCancellation * +gnome_vfs_cancellation_new (void) +{ + GnomeVFSCancellation *new; + + new = g_new (GnomeVFSCancellation, 1); + new->cancelled = FALSE; + new->pipe_in = -1; + new->pipe_out = -1; + + return new; +} + +/** + * gnome_vfs_cancellation_destroy: + * @cancellation: A GnomeVFSCancellation object + * + * Destroy @cancellation. + **/ +void +gnome_vfs_cancellation_destroy (GnomeVFSCancellation *cancellation) +{ + g_return_if_fail (cancellation != NULL); + + if (cancellation->pipe_in >= 0) { + close (cancellation->pipe_in); + close (cancellation->pipe_out); + } + g_free (cancellation); +} + +/** + * gnome_vfs_cancellation_cancel: + * @cancellation: A GnomeVFSCancellation object + * + * Send a cancellation request through @cancellation. + **/ +void +gnome_vfs_cancellation_cancel (GnomeVFSCancellation *cancellation) +{ + g_return_if_fail (cancellation != NULL); + + GNOME_VFS_ASSERT_PRIMARY_THREAD; + + if (cancellation->cancelled) + return; + + if (cancellation->pipe_out >= 0) + write (cancellation->pipe_out, "c", 1); + + cancellation->cancelled = TRUE; +} + +/** + * gnome_vfs_cancellation_check: + * @cancellation: A GnomeVFSCancellation object + * + * Check for pending cancellation. + * + * Return value: %TRUE if the operation should be interrupted. + **/ +gboolean +gnome_vfs_cancellation_check (GnomeVFSCancellation *cancellation) +{ + if (cancellation == NULL) + return FALSE; + + return cancellation->cancelled; +} + +/** + * gnome_vfs_cancellation_ack: + * @cancellation: A GnomeVFSCancellation object + * + * Acknowledge a cancellation. This should be called if + * `gnome_vfs_cancellation_check()' returns %TRUE or if `select()' reports that + * input is available on the file descriptor returned by + * `gnome_vfs_cancellation_get_fd()'. + **/ +void +gnome_vfs_cancellation_ack (GnomeVFSCancellation *cancellation) +{ + gchar c; + + if (cancellation == NULL) + return; + + if (cancellation->pipe_in >= 0) + read (cancellation->pipe_in, &c, 1); + + cancellation->cancelled = FALSE; +} + +/** + * gnome_vfs_cancellation_get_fd: + * @cancellation: A GnomeVFSCancellation object + * + * Get a file descriptor -based notificator for @cancellation. When + * @cancellation receives a cancellation request, a character will be made + * available on the returned file descriptor for input. + * + * This is very useful for detecting cancellation during I/O operations: you + * can use the `select()' call to check for available input/output on the file + * you are reading/writing, and on the notificator's file descriptor at the + * same time. If a data is available on the notificator's file descriptor, you + * know you have to cancel the read/write operation. + * + * Return value: the notificator's file descriptor, or -1 if starved of + * file descriptors. + **/ +gint +gnome_vfs_cancellation_get_fd (GnomeVFSCancellation *cancellation) +{ + g_return_val_if_fail (cancellation != NULL, -1); + + if (cancellation->pipe_in <= 0) { + gint pipefd [2]; + + if (pipe (pipefd) == -1) + return -1; + + cancellation->pipe_in = pipefd [0]; + cancellation->pipe_out = pipefd [1]; + } + + return cancellation->pipe_in; +} diff --git a/libgnomevfs/gnome-vfs-cancellation.h b/libgnomevfs/gnome-vfs-cancellation.h new file mode 100644 index 0000000..ba5dd47 --- /dev/null +++ b/libgnomevfs/gnome-vfs-cancellation.h @@ -0,0 +1,46 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-cancellation.h - Cancellation handling for the GNOME Virtual File + System access methods. + + Copyright (C) 1999, 2001 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli + Seth Nickell +*/ + +#ifndef GNOME_VFS_CANCELLATION_H +#define GNOME_VFS_CANCELLATION_H + +#include + +G_BEGIN_DECLS + +typedef struct GnomeVFSCancellation GnomeVFSCancellation; + + +GnomeVFSCancellation * + gnome_vfs_cancellation_new (void); +void gnome_vfs_cancellation_destroy (GnomeVFSCancellation *cancellation); +void gnome_vfs_cancellation_cancel (GnomeVFSCancellation *cancellation); +gboolean gnome_vfs_cancellation_check (GnomeVFSCancellation *cancellation); +void gnome_vfs_cancellation_ack (GnomeVFSCancellation *cancellation); +gint gnome_vfs_cancellation_get_fd (GnomeVFSCancellation *cancellation); + +G_END_DECLS + +#endif /* GNOME_VFS_CANCELLATION_H */ diff --git a/libgnomevfs/gnome-vfs-configuration.c b/libgnomevfs/gnome-vfs-configuration.c new file mode 100644 index 0000000..18cc9b5 --- /dev/null +++ b/libgnomevfs/gnome-vfs-configuration.c @@ -0,0 +1,581 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-configuration.c - Handling of the GNOME Virtual File System + configuration. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli */ + +#include +#include "gnome-vfs-configuration.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "gnome-vfs-i18n.h" +#include "gnome-vfs-private.h" +#include +#include +#include +#include +#include + +typedef struct _Configuration Configuration; +struct _Configuration { + GHashTable *method_to_module_path; + time_t last_checked; + GList *directories; +}; + +typedef struct _ModulePathElement ModulePathElement; +struct _ModulePathElement { + char *method_name; + char *path; + char *args; +}; + +typedef struct _VfsDirSource VfsDirSource; +struct _VfsDirSource { + char *dirname; + struct stat s; + unsigned int valid : 1; +}; + +/* Global variable */ +static Configuration *configuration = NULL; + +G_LOCK_DEFINE_STATIC (configuration); +#define MAX_CFG_FILES 128 + + + +static ModulePathElement * +module_path_element_new (const char *method_name, + const char *path, + const char *args) +{ + ModulePathElement *new; + + new = g_new (ModulePathElement, 1); + new->method_name = g_strdup (method_name); + new->path = g_strdup (path); + new->args = g_strdup (args); + + return new; +} + +static void +module_path_element_free (ModulePathElement *module_path) +{ + g_free (module_path->method_name); + g_free (module_path->path); + g_free (module_path->args); + g_free (module_path); +} + +static VfsDirSource * +vfs_dir_source_new (const char *dirname) +{ + VfsDirSource *new; + + new = g_new (VfsDirSource, 1); + new->dirname = g_strdup (dirname); + + return new; +} + +static void +vfs_dir_source_free (VfsDirSource *vfs_source) +{ + g_free (vfs_source->dirname); + g_free (vfs_source); +} + + + +static void +hash_free_module_path (gpointer value) +{ + ModulePathElement *module_path; + + module_path = (ModulePathElement *) value; + module_path_element_free (module_path); +} + +/* Destroy configuration information. */ +static void +configuration_destroy (Configuration *configuration) +{ + g_return_if_fail (configuration != NULL); + + g_hash_table_destroy (configuration->method_to_module_path); + g_list_foreach (configuration->directories, (GFunc) vfs_dir_source_free, NULL); + g_list_free (configuration->directories); + g_free (configuration); +} + + + +/* This reads a line and handles backslashes at the end of the line to join + lines. */ +static gint +read_line (FILE *stream, + gchar **line_return, + guint *n, + guint *lines_read) +{ +#define START_BUFFER_SIZE 1024 + gboolean backslash; + gint pos; + + if (feof (stream)) + return -1; + + pos = 0; + backslash = FALSE; + *lines_read = 0; + while (1) { + int c; + + if (pos == *n) { + if (*n == 0) + *n = START_BUFFER_SIZE; + else + *n *= 2; + *line_return = g_realloc (*line_return, *n); + } + + c = fgetc (stream); + if (c == '\n') + (*lines_read)++; + if (c == EOF || (c == '\n' && ! backslash)) { + (*line_return)[pos] = 0; + return pos; + } + + if (c == '\\' && ! backslash) { + backslash = TRUE; + } else if (c != '\n') { + if (backslash) + (*line_return)[pos++] = '\\'; + (*line_return)[pos] = c; + pos++; + backslash = FALSE; + } + } +#undef START_BUFFER_SIZE +} + +static void +remove_comment (gchar *buf) +{ + gchar *p; + + p = strchr (buf, '#'); + if (p != NULL) + *p = '\0'; +} + +static gboolean +parse_line (Configuration *configuration, + gchar *line_buffer, + guint line_len, + const gchar *file_name, + + guint line_number) +{ + guint string_len; + gboolean retval; + gchar *p; + gchar *method_start; + char *module_name; + char *args = NULL; + GList *method_list; + GList *lp; + + string_len = strlen (line_buffer); + if (string_len != line_len) { + g_warning (_("%s:%d contains NUL characters."), + file_name, line_number); + return FALSE; + } + + remove_comment (line_buffer); + line_buffer = g_strstrip (line_buffer); + + method_list = NULL; + p = line_buffer; + method_start = line_buffer; + retval = TRUE; + while (*p != '\0') { + if (*p == ' ' || *p == '\t' || *p == ':') { + gchar *method_name; + + if (p == method_start) { + g_warning (_("%s:%d contains no method name."), + file_name, line_number); + retval = FALSE; + goto cleanup; + } + + method_name = g_strndup (method_start, + p - method_start); + method_list = g_list_prepend (method_list, method_name); + + while (*p == ' ' || *p == '\t') + p++; + + if (*p == ':') { + p++; + break; + } + + method_start = p; + } + + p++; + } + + while (*p && g_ascii_isspace (*p)) + p++; + + if (*p == '\0') { + if (method_list != NULL) { + g_warning (_("%s:%d contains no module name."), + file_name, line_number); + retval = FALSE; + } else { + /* Empty line. */ + retval = TRUE; + } + goto cleanup; + } + + module_name = p; + while(*p && !g_ascii_isspace (*p)) p++; + + if(*p) { + *p = '\0'; + p++; + while(*p && g_ascii_isspace (*p)) p++; + if(*p) + args = p; + } + + for (lp = method_list; lp != NULL; lp = lp->next) { + ModulePathElement *element; + gchar *method_name; + + method_name = lp->data; + element = module_path_element_new (method_name, module_name, args); + g_hash_table_insert (configuration->method_to_module_path, + method_name, element); + } + + retval = TRUE; + + cleanup: + if (method_list != NULL) + g_list_free (method_list); + return retval; +} + +/* FIXME bugzilla.eazel.com 1139: + maybe we should return FALSE if any errors during parsing happen so + that we abort immediately, but this sounds a bit too overkill. */ +static gboolean +parse_file (Configuration *configuration, + const gchar *file_name) +{ + FILE *f; + gchar *line_buffer; + guint line_buffer_size; + guint line_number; + + f = fopen (file_name, "r"); + if (f == NULL) { + g_warning (_("Configuration file `%s' was not found: %s"), + file_name, strerror (errno)); + return FALSE; + } + + line_buffer = NULL; + line_buffer_size = 0; + line_number = 0; + while (1) { + guint lines_read; + gint line_len; + + line_len = read_line (f, &line_buffer, &line_buffer_size, + &lines_read); + if (line_len == -1) + break; /* EOF */ + parse_line (configuration, line_buffer, line_len, file_name, + line_number); + line_number += lines_read; + } + + g_free (line_buffer); + + fclose (f); + + return TRUE; +} + +static void +configuration_load (void) +{ + gchar *file_names[MAX_CFG_FILES + 1]; + GList *list; + int i = 0; + DIR *dirh; + + configuration->method_to_module_path = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, hash_free_module_path); + + /* Go through the list of configuration directories and build up a list of config files */ + for (list = configuration->directories; list && i < MAX_CFG_FILES; list = list->next) { + VfsDirSource *dir_source = (VfsDirSource *)list->data; + struct dirent *dent; + + if (stat (dir_source->dirname, &dir_source->s) == -1) + continue; + + dirh = opendir (dir_source->dirname); + if(!dirh) + continue; + + while ((dent = readdir(dirh)) && i < MAX_CFG_FILES) { + char *ctmp; + ctmp = strstr(dent->d_name, ".conf"); + if(!ctmp || strcmp(ctmp, ".conf")) + continue; + file_names[i] = g_strdup_printf ("%s/%s", dir_source->dirname, dent->d_name); + i++; + } + closedir(dirh); + } + file_names[i] = NULL; + + /* Now read these cfg files */ + for(i = 0; file_names[i]; i++) { + /* FIXME: should we try to catch errors? */ + parse_file (configuration, file_names[i]); + g_free (file_names[i]); + } +} + + +static void +add_directory_internal (const char *dir) +{ + VfsDirSource *dir_source = vfs_dir_source_new (dir); + + configuration->directories = g_list_prepend (configuration->directories, dir_source); +} + +void +_gnome_vfs_configuration_add_directory (const char *dir) +{ + G_LOCK (configuration); + if (configuration == NULL) { + g_warning ("_gnome_vfs_configuration_init must be called prior to adding a directory."); + G_UNLOCK (configuration); + return; + } + + add_directory_internal (dir); + + G_UNLOCK (configuration); +} + + +static void +install_path_list (const gchar *environment_path) +{ + const char *p, *oldp; + + oldp = environment_path; + while (1) { + char *elem; + + p = strchr (oldp, ':'); + + if (p == NULL) { + if (*oldp != '\0') { + add_directory_internal (oldp); + } + break; + } else { + elem = g_strndup (oldp, p - oldp); + add_directory_internal (elem); + g_free (elem); + } + + oldp = p + 1; + } +} + + +gboolean +_gnome_vfs_configuration_init (void) +{ + char *home_config; + char *environment_path; + const char *home_dir; + + G_LOCK (configuration); + if (configuration != NULL) { + G_UNLOCK (configuration); + return FALSE; + } + + configuration = g_new0 (Configuration, 1); + + add_directory_internal (GNOME_VFS_MODULE_CFGDIR); + environment_path = getenv ("GNOME_VFS_MODULE_CONFIG_PATH"); + if (environment_path != NULL) { + install_path_list (environment_path); + } + + home_dir = g_get_home_dir (); + if (home_dir != NULL) { + home_config = g_strdup_printf ("%s%c%s", + home_dir, + G_DIR_SEPARATOR, + ".gnome2/vfs/modules"); + add_directory_internal (home_config); + g_free (home_config); + } + + configuration_load (); + + G_UNLOCK (configuration); + + if (configuration == NULL) { + return FALSE; + } else { + return TRUE; + } +} + +void +_gnome_vfs_configuration_uninit (void) +{ + G_LOCK (configuration); + if (configuration == NULL) { + G_UNLOCK (configuration); + return; + } + + configuration_destroy (configuration); + configuration = NULL; + G_UNLOCK (configuration); +} + +static void +maybe_reload (void) +{ + time_t now = time (NULL); + GList *list; + gboolean need_reload = FALSE; + struct stat s; + + /* only check every 5 seconds minimum */ + if (configuration->last_checked + 5 >= now) + return; + + for (list = configuration->directories; list; list = list->next) { + VfsDirSource *dir_source = (VfsDirSource *) list->data; + if (stat (dir_source->dirname, &s) == -1) + continue; + if (s.st_mtime != dir_source->s.st_mtime) { + need_reload = TRUE; + break; + } + } + + configuration->last_checked = now; + + if (!need_reload) + return; + + configuration->last_checked = time (NULL); + + g_hash_table_destroy (configuration->method_to_module_path); + configuration_load (); +} + +const gchar * +_gnome_vfs_configuration_get_module_path (const gchar *method_name, const char ** args) +{ + ModulePathElement *element; + + g_return_val_if_fail (method_name != NULL, NULL); + + G_LOCK (configuration); + + if (configuration != NULL) { + maybe_reload (); + element = g_hash_table_lookup + (configuration->method_to_module_path, method_name); + } else { + /* This should never happen. */ + g_warning ("Internal error: the configuration system was not initialized. Did you call _gnome_vfs_configuration_init?"); + element = NULL; + } + + G_UNLOCK (configuration); + + if (element == NULL) + return NULL; + + if (args) + *args = element->args; + return element->path; +} + +static void +add_method_to_list(const gchar *key, gpointer value, GList **methods_list) +{ + *methods_list = g_list_append(*methods_list, g_strdup(key)); +} + +GList * +_gnome_vfs_configuration_get_methods_list (void) +{ + GList *methods_list = NULL; + + G_LOCK (configuration); + if (configuration != NULL) { + maybe_reload (); + g_hash_table_foreach(configuration->method_to_module_path, + (GHFunc)add_method_to_list, &methods_list); + } else { + /* This should never happen. */ + methods_list = NULL; + } + + G_UNLOCK (configuration); + return methods_list; +} diff --git a/libgnomevfs/gnome-vfs-configuration.h b/libgnomevfs/gnome-vfs-configuration.h new file mode 100644 index 0000000..1a70522 --- /dev/null +++ b/libgnomevfs/gnome-vfs-configuration.h @@ -0,0 +1,41 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-configuration.h - Handling of the GNOME Virtual File System + configuration. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli */ + +#ifndef GNOME_VFS_CONFIGURATION_H +#define GNOME_VFS_CONFIGURATION_H + +#include +#include + +G_BEGIN_DECLS + +void _gnome_vfs_configuration_add_directory (const char *dir); +gboolean _gnome_vfs_configuration_init (void); +void _gnome_vfs_configuration_uninit (void); +const gchar *_gnome_vfs_configuration_get_module_path (const gchar *method_name, const char ** args); +GList *_gnome_vfs_configuration_get_methods_list(void); + + +G_END_DECLS + +#endif /* GNOME_VFS_CONFIGURATION_H */ diff --git a/libgnomevfs/gnome-vfs-context.c b/libgnomevfs/gnome-vfs-context.c new file mode 100644 index 0000000..74c2f77 --- /dev/null +++ b/libgnomevfs/gnome-vfs-context.c @@ -0,0 +1,146 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-context.c - context VFS modules can use to communicate with gnome-vfs proper + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Havoc Pennington */ + +#include +#include "gnome-vfs-context.h" + +#include "gnome-vfs-backend.h" +#include "gnome-vfs-cancellation.h" +#include "gnome-vfs-private-utils.h" +#include "gnome-vfs-utils.h" +#include + +#if 1 +#define DEBUG_MSG (x) printf x +#else +#define DEBUG_MSG (x) +#endif + + +struct GnomeVFSContext { + GnomeVFSCancellation *cancellation; +}; + +/* This is a token Context to return in situations + * where we don't normally have a context: eg, during sync calls + */ +const GnomeVFSContext sync_context = {NULL}; + +/** + * gnome_vfs_context_new: + * + * Creates a new context and cancellation object. Must be called + * from the main glib event loop. + * + * Return value: a newly allocated #GnomeVFSContext + **/ +GnomeVFSContext* +gnome_vfs_context_new (void) +{ + GnomeVFSContext *ctx; + + GNOME_VFS_ASSERT_PRIMARY_THREAD; + + ctx = g_new0(GnomeVFSContext, 1); + + ctx->cancellation = gnome_vfs_cancellation_new(); + + return ctx; +} + +/** + * gnome_vfs_context_free: + * @ctx: context to be freed + * + * Free @ctx and destroy the associated #GnomeVFSCancellation. + **/ +void +gnome_vfs_context_free (GnomeVFSContext *ctx) +{ + g_return_if_fail(ctx != NULL); + + gnome_vfs_cancellation_destroy(ctx->cancellation); + + g_free(ctx); +} + +/** + * gnome_vfs_context_get_cancellation: + * @ctx: context to get the #GnomeVFSCancellation from + * + * Retrieve the #GnomeVFSCancellation associated with @ctx. + * + * Return value: @ctx 's #GnomeVFSCancellation + **/ +GnomeVFSCancellation* +gnome_vfs_context_get_cancellation (const GnomeVFSContext *ctx) +{ + g_return_val_if_fail(ctx != NULL, NULL); + return ctx->cancellation; +} + +/** + * gnome_vfs_context_peek_current: + * + * Get the currently active context. It shouldn't be + * manipulated but can be compared to context's the module + * holds to determine whether they are active. + * + * Return value: the currently active #GnomeVFSContext + **/ +const GnomeVFSContext * +gnome_vfs_context_peek_current (void) +{ + const GnomeVFSContext *ret; + + _gnome_vfs_get_current_context ((GnomeVFSContext **)&ret); + + /* If the context is NULL, then this must be a synchronous call */ + if (ret == NULL) { + ret = &sync_context; + } + + return ret; +} + +/** + * gnome_vfs_context_check_cancellation_current: + * + * Check to see if the currently active context has been cancelled. + * + * Return value: %TRUE if the currently active context has been cancelled, otherwise %FALSE + **/ +gboolean +gnome_vfs_context_check_cancellation_current (void) +{ + const GnomeVFSContext *current_ctx; + + current_ctx = gnome_vfs_context_peek_current (); + + if (current_ctx == &sync_context) { + return FALSE; + } else if (current_ctx != NULL) { + return gnome_vfs_cancellation_check (gnome_vfs_context_get_cancellation (current_ctx)); + } else { + return FALSE; + } +} diff --git a/libgnomevfs/gnome-vfs-context.h b/libgnomevfs/gnome-vfs-context.h new file mode 100644 index 0000000..b2dacb7 --- /dev/null +++ b/libgnomevfs/gnome-vfs-context.h @@ -0,0 +1,52 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-context.h - context VFS modules can use to communicate with gnome-vfs proper + + Copyright (C) 1999, 2001 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Havoc Pennington + Seth Nickell +*/ + +#ifndef GNOME_VFS_CONTEXT_H +#define GNOME_VFS_CONTEXT_H + +#include + +G_BEGIN_DECLS + +typedef struct GnomeVFSContext GnomeVFSContext; + +GnomeVFSContext* gnome_vfs_context_new (void); +void gnome_vfs_context_free (GnomeVFSContext *ctx); + +/* To be really thread-safe, these need to return objects with an increased + refcount; however they don't, only one thread at a time + can use GnomeVFSContext */ + +GnomeVFSCancellation* + gnome_vfs_context_get_cancellation (const GnomeVFSContext *ctx); + +/* Convenience - both of these accept a NULL context object */ +#define gnome_vfs_context_check_cancellation(x) (gnome_vfs_cancellation_check((x) ? gnome_vfs_context_get_cancellation((x)) : NULL)) + +const GnomeVFSContext *gnome_vfs_context_peek_current (void); +gboolean gnome_vfs_context_check_cancellation_current (void); + +G_END_DECLS + +#endif /* GNOME_VFS_CONTEXT_H */ diff --git a/libgnomevfs/gnome-vfs-directory.c b/libgnomevfs/gnome-vfs-directory.c new file mode 100644 index 0000000..d7fdef2 --- /dev/null +++ b/libgnomevfs/gnome-vfs-directory.c @@ -0,0 +1,684 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-directory.c - Directory handling for the GNOME Virtual + File System. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli */ + +#include +#include "gnome-vfs-directory.h" + +#include "gnome-vfs-cancellable-ops.h" +#include "gnome-vfs-method.h" +#include "gnome-vfs-ops.h" +#include +#include + +#define VFS_MAXIMUM_SYMBOLIC_LINK_DEPTH 256 + +struct GnomeVFSDirectoryHandle { + /* URI of the directory being accessed through the handle. */ + GnomeVFSURI *uri; + + /* Options. */ + GnomeVFSFileInfoOptions options; + + /* Method-specific handle. */ + GnomeVFSMethodHandle *method_handle; +}; + +#define CHECK_IF_SUPPORTED(vfs_method, what) \ +G_STMT_START{ \ + if (!VFS_METHOD_HAS_FUNC(vfs_method, what)) \ + return GNOME_VFS_ERROR_NOT_SUPPORTED; \ +}G_STMT_END + + +static GnomeVFSDirectoryHandle * +gnome_vfs_directory_handle_new (GnomeVFSURI *uri, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfoOptions options) +{ + GnomeVFSDirectoryHandle *new; + + g_return_val_if_fail (uri != NULL, NULL); + g_return_val_if_fail (method_handle != NULL, NULL); + + new = g_new (GnomeVFSDirectoryHandle, 1); + + gnome_vfs_uri_ref (uri); + + new->uri = uri; + new->method_handle = method_handle; + new->options = options; + + return new; +} + +static void +gnome_vfs_directory_handle_destroy (GnomeVFSDirectoryHandle *handle) +{ + g_return_if_fail (handle != NULL); + + gnome_vfs_uri_unref (handle->uri); + + g_free (handle); +} + + +static GnomeVFSResult +open_from_uri (GnomeVFSDirectoryHandle **handle, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSMethodHandle *method_handle; + GnomeVFSResult result; + + CHECK_IF_SUPPORTED (uri->method, open_directory); + + + result = uri->method->open_directory (uri->method, + &method_handle, + uri, + options, + context); + if (result != GNOME_VFS_OK) { + return result; + } + + *handle = gnome_vfs_directory_handle_new (uri, + method_handle, + options); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +open (GnomeVFSDirectoryHandle **handle, + const gchar *text_uri, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSURI *uri; + GnomeVFSResult result; + + g_return_val_if_fail (handle != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail (text_uri != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + uri = gnome_vfs_uri_new (text_uri); + if (uri == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + result = open_from_uri (handle, uri, options, + context); + + gnome_vfs_uri_unref (uri); + + return result; +} + +/** + * gnome_vfs_directory_open + * @handle: A pointer to a pointer to a GnomeVFSDirectoryHandle object + * @text_uri: String representing the URI to open + * @options: Options for reading file information + * + * Open directory @text_uri for reading. On return, @*handle will point to + * a %GnomeVFSDirectoryHandle object which can be used to read the directory + * entries one by one. + * + * Returns: An integer representing the result of the operation + **/ +GnomeVFSResult +gnome_vfs_directory_open (GnomeVFSDirectoryHandle **handle, + const gchar *text_uri, + GnomeVFSFileInfoOptions options) +{ + g_return_val_if_fail (handle != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail (text_uri != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + return open (handle, text_uri, options, NULL); +} + +/** + * gnome_vfs_directory_open_from_uri + * @handle: A pointer to a pointer to a GnomeVFSDirectoryHandle object + * @uri: URI to open + * @options: Options for reading file information + * + * Open directory @text_uri for reading. On return, @*handle will point to + * a %GnomeVFSDirectoryHandle object which can be used to read the directory + * entries one by one. + * + * Returns: An integer representing the result of the operation. + **/ +GnomeVFSResult +gnome_vfs_directory_open_from_uri (GnomeVFSDirectoryHandle **handle, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options) +{ + g_return_val_if_fail (handle != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail (uri != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + return open_from_uri (handle, uri, options, NULL); +} + +GnomeVFSResult +gnome_vfs_directory_open_from_uri_cancellable (GnomeVFSDirectoryHandle **handle, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + g_return_val_if_fail (handle != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail (uri != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + return open_from_uri (handle, uri, options, context); +} + +/** + * gnome_vfs_directory_read_next: + * @handle: A directory handle + * @file_info: Pointer to a %GnomeVFSFileInfo struct where the data about + * the entry will be stored + * + * Read the next directory entry from @handle. + * + * Returns: An integer value representing the result of the operation. + **/ +GnomeVFSResult +gnome_vfs_directory_read_next (GnomeVFSDirectoryHandle *handle, + GnomeVFSFileInfo *file_info) +{ + CHECK_IF_SUPPORTED (handle->uri->method, read_directory); + + gnome_vfs_file_info_clear (file_info); + return handle->uri->method->read_directory (handle->uri->method, + handle->method_handle, + file_info, NULL); +} + +GnomeVFSResult +gnome_vfs_directory_read_next_cancellable (GnomeVFSDirectoryHandle *handle, + GnomeVFSFileInfo *file_info, + GnomeVFSContext *context) +{ + CHECK_IF_SUPPORTED (handle->uri->method, read_directory); + + gnome_vfs_file_info_clear (file_info); + return handle->uri->method->read_directory (handle->uri->method, + handle->method_handle, + file_info, context); +} + + +/** + * gnome_vfs_directory_close: + * @handle: A directory handle. + * + * Close @handle. + * + * Returns: An integer representing the result of the operation. + */ +GnomeVFSResult +gnome_vfs_directory_close (GnomeVFSDirectoryHandle *handle) +{ + GnomeVFSResult result; + + CHECK_IF_SUPPORTED (handle->uri->method, close_directory); + + result = handle->uri->method->close_directory (handle->uri->method, + handle->method_handle, + NULL); + + gnome_vfs_directory_handle_destroy (handle); + + return result; +} + + +struct _DirectoryReference { + ino_t inode; + dev_t device; +}; +typedef struct _DirectoryReference DirectoryReference; + +static GList * +prepend_reference (GList *reference_list, + GnomeVFSFileInfo *info) +{ + DirectoryReference *reference; + + reference = g_new (DirectoryReference, 1); + reference->device = info->device; + reference->inode = info->inode; + + return g_list_prepend (reference_list, reference); +} + +static GList * +remove_first_reference (GList *reference_list) +{ + GList *first; + + if (reference_list == NULL) + return NULL; + + first = reference_list; + g_free (first->data); + + reference_list = g_list_remove_link (reference_list, first); + g_list_free (first); + + return reference_list; +} + +static gboolean +lookup_ancestor (GList *ancestors, + gboolean inode_and_device_are_valid, + ino_t inode, + dev_t device) +{ + GList *p; + + if (!inode_and_device_are_valid) { + return g_list_length (ancestors) >= VFS_MAXIMUM_SYMBOLIC_LINK_DEPTH; + } + + for (p = ancestors; p != NULL; p = p->next) { + DirectoryReference *reference; + + reference = p->data; + if (reference->inode == inode && reference->device == device) + return TRUE; + } + + return FALSE; +} + +static GnomeVFSResult +directory_visit_internal (GnomeVFSURI *uri, + const gchar *prefix, + GList *ancestor_references, /* DirectoryReference */ + GnomeVFSFileInfoOptions info_options, + GnomeVFSDirectoryVisitOptions visit_options, + GnomeVFSDirectoryVisitFunc callback, + gpointer data) +{ + GnomeVFSFileInfo *info; + GnomeVFSDirectoryHandle *handle; + GnomeVFSResult result; + gboolean stop; + + /* The first time, initialize the ancestor list with this + directory. */ + if (prefix == NULL) { + GnomeVFSFileInfo *info; + + info = gnome_vfs_file_info_new (); + result = gnome_vfs_get_file_info_uri (uri, info, + info_options); + if (result != GNOME_VFS_OK) { + gnome_vfs_file_info_unref (info); + return result; + } + + if (info->type != GNOME_VFS_FILE_TYPE_DIRECTORY) { + gnome_vfs_file_info_unref (info); + return GNOME_VFS_ERROR_NOT_A_DIRECTORY; + } + + ancestor_references = prepend_reference (ancestor_references, + info); + gnome_vfs_file_info_unref (info); + } + + result = gnome_vfs_directory_open_from_uri (&handle, uri, info_options); + if (result != GNOME_VFS_OK) + return result; + + info = gnome_vfs_file_info_new (); + + stop = FALSE; + while (! stop) { + gchar *rel_path; + gboolean recurse; + gboolean recursing_will_loop; + + result = gnome_vfs_directory_read_next (handle, info); + if (result != GNOME_VFS_OK) + break; + + /* Skip "." and "..". */ + if (info->name[0] == '.' + && (info->name[1] == 0 + || (info->name[1] == '.' && info->name[2] == 0))) { + gnome_vfs_file_info_clear (info); + continue; + } + + if (prefix == NULL) + rel_path = g_strdup (info->name); + else + rel_path = g_strconcat (prefix, info->name, NULL); + + if (info->type == GNOME_VFS_FILE_TYPE_DIRECTORY + && (visit_options & GNOME_VFS_DIRECTORY_VISIT_LOOPCHECK)) + recursing_will_loop + = lookup_ancestor (ancestor_references, + (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_DEVICE) && + (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_INODE), + info->inode, info->device); + else + recursing_will_loop = FALSE; + + recurse = FALSE; + stop = ! (* callback) (rel_path, info, recursing_will_loop, + data, &recurse); + + if (! stop + && recurse + && info->type == GNOME_VFS_FILE_TYPE_DIRECTORY) { + GnomeVFSURI *new_uri; + gchar *new_prefix; + + if (prefix == NULL) + new_prefix = g_strconcat (info->name, "/", + NULL); + else + new_prefix = g_strconcat (prefix, info->name, + "/", NULL); + + new_uri = gnome_vfs_uri_append_file_name (uri, info->name); + + + if (GNOME_VFS_FILE_INFO_LOCAL (info)) + ancestor_references = prepend_reference + (ancestor_references, info); + + result = directory_visit_internal (new_uri, + new_prefix, + ancestor_references, + info_options, + visit_options, + callback, data); + + if (GNOME_VFS_FILE_INFO_LOCAL (info)) + ancestor_references = remove_first_reference + (ancestor_references); + + if (result != GNOME_VFS_OK) + stop = TRUE; + + gnome_vfs_uri_unref (new_uri); + g_free (new_prefix); + } + + g_free (rel_path); + + gnome_vfs_file_info_clear (info); + + if (stop) + break; + } + + gnome_vfs_directory_close (handle); + gnome_vfs_file_info_unref (info); + + /* The first time, we are responsible for de-allocating the directory + reference we have added by ourselves. */ + if (prefix == NULL) + ancestor_references + = remove_first_reference (ancestor_references); + + if (result == GNOME_VFS_ERROR_EOF) + return GNOME_VFS_OK; + else + return result; +} + +/** + * gnome_vfs_directory_visit_uri + * @uri: URI to start from + * @info_options: Options specifying what kind of file information must be + * retrieved + * @visit_options: Options specifying the type of visit + * @callback: Callback to be called for every visited file + * @data: Data to be passed to @callback at each iteration + * + * Visit @uri, retrieving information as specified by @info_options. + * + * Returns: A result code indicating whether the operation succeeded. + * + */ +GnomeVFSResult +gnome_vfs_directory_visit_uri (GnomeVFSURI *uri, + GnomeVFSFileInfoOptions info_options, + GnomeVFSDirectoryVisitOptions visit_options, + GnomeVFSDirectoryVisitFunc callback, + gpointer data) +{ + g_return_val_if_fail (uri != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + return directory_visit_internal (uri, NULL, NULL, + info_options, + visit_options, callback, data); +} + +/** + * gnome_vfs_directory_visit: + * @uri: URI to start from + * @info_options: Options specifying what kind of file information must be + * retrieved + * @visit_options: Options specifying the type of visit + * @callback: Callback to be called for every visited file + * @data: Data to be passed to @callback at each iteration + * + * Visit @uri, retrieving information as specified by @info_options. + * + * Return value: + **/ +GnomeVFSResult +gnome_vfs_directory_visit (const gchar *text_uri, + GnomeVFSFileInfoOptions info_options, + GnomeVFSDirectoryVisitOptions visit_options, + GnomeVFSDirectoryVisitFunc callback, + gpointer data) +{ + GnomeVFSURI *uri; + GnomeVFSResult result; + + g_return_val_if_fail (text_uri != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + uri = gnome_vfs_uri_new (text_uri); + if (uri == NULL) { + return GNOME_VFS_ERROR_INVALID_URI; + } + + result = directory_visit_internal (uri, NULL, NULL, + info_options, + visit_options, callback, data); + + gnome_vfs_uri_unref (uri); + + return result; +} + +/** + * gnome_vfs_directory_visit_files_at_uri: + * @uri: URI of a directory to "visit" the files in + * @file_list: GList of char *s of file names in @uri to visit + * @info_options: bitmask controlling the type of information to fetch + * @visit_options: options controlling e.g. loop prevention, and filesystem checks. + * Affects the way visiting is done. + * @callback: function to call with the file info structs + * @data: data to pass to @callback. + * + * Fetches information about a list of files in a base URI @uri. + * + * Return value: a GnomeVFSResult indication the success of the operation + **/ +GnomeVFSResult +gnome_vfs_directory_visit_files_at_uri (GnomeVFSURI *uri, + GList *file_list, + GnomeVFSFileInfoOptions info_options, + GnomeVFSDirectoryVisitOptions visit_options, + GnomeVFSDirectoryVisitFunc callback, + gpointer data) +{ + GnomeVFSFileInfo *info; + GnomeVFSResult result; + GList *p; + + g_return_val_if_fail (uri != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail (file_list != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + info = gnome_vfs_file_info_new (); + result = GNOME_VFS_OK; + + for (p = file_list; p != NULL; p = p->next) { + GnomeVFSURI *file_uri; + gboolean recurse; + gboolean stop; + + file_uri = gnome_vfs_uri_append_file_name (uri, p->data); + gnome_vfs_get_file_info_uri (file_uri, + info, + info_options); + + recurse = FALSE; + stop = ! (* callback) (info->name, info, FALSE, data, + &recurse); + + if (! stop + && recurse + && info->type == GNOME_VFS_FILE_TYPE_DIRECTORY) + result = gnome_vfs_directory_visit_uri + (uri, + info_options, + visit_options, + callback, + data); + + gnome_vfs_uri_unref (file_uri); + + if (result != GNOME_VFS_OK || stop) + break; + } + + gnome_vfs_file_info_unref (info); + return GNOME_VFS_OK; +} + +/** + * gnome_vfs_directory_visit_files: + * @text_uri: string representing the URI of a directory to "visit" the files in + * @file_list: GList of char *s of file names in @uri to visit + * @info_options: bitmask controlling the type of information to fetch + * @visit_options: options controlling e.g. loop prevention, and filesystem checks. + * Affects the way visiting is done. + * @callback: function to call with the file info structs + * @data: data to pass to @callback. + * + * Fetches information about a list of files in a base URI @uri. + * + * Return value: a GnomeVFSResult indication the success of the operation + **/ +GnomeVFSResult +gnome_vfs_directory_visit_files (const gchar *text_uri, + GList *file_list, + GnomeVFSFileInfoOptions info_options, + GnomeVFSDirectoryVisitOptions visit_options, + GnomeVFSDirectoryVisitFunc callback, + gpointer data) +{ + GnomeVFSURI *uri; + GnomeVFSResult result; + + uri = gnome_vfs_uri_new (text_uri); + + result = gnome_vfs_directory_visit_files_at_uri (uri, file_list, + info_options, + visit_options, + callback, + data); + gnome_vfs_uri_unref (uri); + + return result; +} + +static GnomeVFSResult +load_from_handle (GList **list, + GnomeVFSDirectoryHandle *handle) +{ + GnomeVFSResult result; + GnomeVFSFileInfo *info; + + *list = NULL; + + for (;;) { + info = gnome_vfs_file_info_new (); + result = gnome_vfs_directory_read_next (handle, info); + if (result != GNOME_VFS_OK) + break; + *list = g_list_prepend (*list, info); + } + + *list = g_list_reverse (*list); + + gnome_vfs_file_info_unref (info); + + if (result != GNOME_VFS_ERROR_EOF) { + gnome_vfs_file_info_list_free (*list); + *list = NULL; + } + + return GNOME_VFS_OK; +} + +/** + * gnome_vfs_directory_list_load: + * @list: An address of a pointer to a list of GnomeVFSFileInfo + * @text_uri: A text URI + * @options: Options for loading the directory + * + * Load a directory from @text_uri with the specified @options + * into a list. + * + * Return value: An integer representing the result of the operation. + **/ +GnomeVFSResult +gnome_vfs_directory_list_load (GList **list, + const gchar *text_uri, + GnomeVFSFileInfoOptions options) +{ + GnomeVFSDirectoryHandle *handle; + GnomeVFSResult result; + + result = gnome_vfs_directory_open (&handle, text_uri, options); + if (result != GNOME_VFS_OK) { + return result; + } + + result = load_from_handle (list, handle); + + gnome_vfs_directory_close (handle); + return result; +} + diff --git a/libgnomevfs/gnome-vfs-directory.h b/libgnomevfs/gnome-vfs-directory.h new file mode 100644 index 0000000..430351f --- /dev/null +++ b/libgnomevfs/gnome-vfs-directory.h @@ -0,0 +1,108 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-directory.h - Directory handling for the GNOME Virtual + File System. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli */ + +#ifndef GNOME_VFS_DIRECTORY_H +#define GNOME_VFS_DIRECTORY_H + +#include +#include + +G_BEGIN_DECLS + +typedef struct GnomeVFSDirectoryHandle GnomeVFSDirectoryHandle; + +/** + * GnomeVFSDirectoryVisitOptions: + * @GNOME_VFS_DIRECTORY_VISIT_DEFAULT: + * @GNOME_VFS_DIRECTORY_VISIT_SAMEFS: Visit only directories on the same + * file system as the parent + * @GNOME_VFS_DIRECTORY_VISIT_LOOPCHECK: Loop prevention + * + * This options control the way in which directories are visited. + **/ + +typedef enum { + GNOME_VFS_DIRECTORY_VISIT_DEFAULT = 0, + GNOME_VFS_DIRECTORY_VISIT_SAMEFS = 1 << 0, + GNOME_VFS_DIRECTORY_VISIT_LOOPCHECK = 1 << 1 +} GnomeVFSDirectoryVisitOptions; + +typedef gboolean (* GnomeVFSDirectoryVisitFunc) (const gchar *rel_path, + GnomeVFSFileInfo *info, + gboolean recursing_will_loop, + gpointer data, + gboolean *recurse); + +GnomeVFSResult gnome_vfs_directory_open + (GnomeVFSDirectoryHandle **handle, + const gchar *text_uri, + GnomeVFSFileInfoOptions options); +GnomeVFSResult gnome_vfs_directory_open_from_uri + (GnomeVFSDirectoryHandle **handle, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options); +GnomeVFSResult gnome_vfs_directory_read_next + (GnomeVFSDirectoryHandle *handle, + GnomeVFSFileInfo *file_info); +GnomeVFSResult gnome_vfs_directory_close + (GnomeVFSDirectoryHandle *handle); + + +GnomeVFSResult gnome_vfs_directory_visit + (const gchar *uri, + GnomeVFSFileInfoOptions info_options, + GnomeVFSDirectoryVisitOptions visit_options, + GnomeVFSDirectoryVisitFunc callback, + gpointer data); + +GnomeVFSResult gnome_vfs_directory_visit_uri + (GnomeVFSURI *uri, + GnomeVFSFileInfoOptions info_options, + GnomeVFSDirectoryVisitOptions visit_options, + GnomeVFSDirectoryVisitFunc callback, + gpointer data); + +GnomeVFSResult gnome_vfs_directory_visit_files + (const gchar *text_uri, + GList *file_list, + GnomeVFSFileInfoOptions info_options, + GnomeVFSDirectoryVisitOptions visit_options, + GnomeVFSDirectoryVisitFunc callback, + gpointer data); + +GnomeVFSResult gnome_vfs_directory_visit_files_at_uri + (GnomeVFSURI *uri, + GList *file_list, + GnomeVFSFileInfoOptions info_options, + GnomeVFSDirectoryVisitOptions visit_options, + GnomeVFSDirectoryVisitFunc callback, + gpointer data); + +GnomeVFSResult gnome_vfs_directory_list_load + (GList **list, + const gchar *text_uri, + GnomeVFSFileInfoOptions options); + +G_END_DECLS + +#endif diff --git a/libgnomevfs/gnome-vfs-file-info.c b/libgnomevfs/gnome-vfs-file-info.c new file mode 100644 index 0000000..12099d8 --- /dev/null +++ b/libgnomevfs/gnome-vfs-file-info.c @@ -0,0 +1,309 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-file-info.c - Handling of file information for the GNOME + Virtual File System. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli +*/ + +#include +#include "gnome-vfs-file-info.h" + +#include +#include +#include +#include + +/* Mutex for making GnomeVFSFileInfo ref's/unref's atomic */ +/* Note that an atomic increment function (such as is present in NSPR) is preferable */ +/* FIXME: This mutex is probably not needed and might be causing performance issues */ +static GStaticMutex file_info_ref_lock = G_STATIC_MUTEX_INIT; + + +/** + * gnome_vfs_file_info_new + * + * Allocate and initialize a new file information struct. + * + * Returns: A pointer to the new file information struct. + **/ +GnomeVFSFileInfo * +gnome_vfs_file_info_new (void) +{ + GnomeVFSFileInfo *new; + + new = g_new0 (GnomeVFSFileInfo, 1); + + /* `g_new0()' is enough to initialize everything (we just want + all the members to be set to zero). */ + + new->refcount = 1; + + return new; +} + + +/** + * gnome_vfs_file_info_ref + * @info: Pointer to a file information struct + * + * Increment reference count + **/ +void +gnome_vfs_file_info_ref (GnomeVFSFileInfo *info) +{ + g_return_if_fail (info != NULL); + g_return_if_fail (info->refcount > 0); + + g_static_mutex_lock (&file_info_ref_lock); + info->refcount += 1; + g_static_mutex_unlock (&file_info_ref_lock); + +} + +/** + * gnome_vfs_file_info_unref + * @info: Pointer to a file information struct + * + * Destroy @info + **/ +void +gnome_vfs_file_info_unref (GnomeVFSFileInfo *info) +{ + g_return_if_fail (info != NULL); + g_return_if_fail (info->refcount > 0); + + g_static_mutex_lock (&file_info_ref_lock); + info->refcount -= 1; + g_static_mutex_unlock (&file_info_ref_lock); + + if (info->refcount == 0) { + gnome_vfs_file_info_clear (info); + g_free (info); + } +} + + +/** + * gnome_vfs_file_info_clear + * @info: Pointer to a file information struct + * + * Clear @info so that it's ready to accept new data. This is + * supposed to be used when @info already contains meaningful information which + * we want to replace. + **/ +void +gnome_vfs_file_info_clear (GnomeVFSFileInfo *info) +{ + guint old_refcount; + + g_return_if_fail (info != NULL); + + g_free (info->name); + g_free (info->symlink_name); + g_free (info->mime_type); + + /* Ensure the ref count is maintained correctly */ + g_static_mutex_lock (&file_info_ref_lock); + + old_refcount = info->refcount; + memset (info, 0, sizeof (*info)); + info->refcount = old_refcount; + + g_static_mutex_unlock (&file_info_ref_lock); +} + + +/** + * gnome_vfs_file_info_get_mime_type + * @info: A pointer to a file information struct + * + * Retrieve MIME type from @info. There is no need to free the return + * value. + * + * Returns: A pointer to a string representing the MIME type. + **/ +const gchar * +gnome_vfs_file_info_get_mime_type (GnomeVFSFileInfo *info) +{ + g_return_val_if_fail (info != NULL, NULL); + + return info->mime_type; +} + +/** + * gnome_vfs_file_info_copy + * @dest: Pointer to a struct to copy @src's information into + * @src: Pointer to the information to be copied into @dest + * + * Copy information from @src into @dest. + **/ +void +gnome_vfs_file_info_copy (GnomeVFSFileInfo *dest, + const GnomeVFSFileInfo *src) +{ + guint old_refcount; + + g_return_if_fail (dest != NULL); + g_return_if_fail (src != NULL); + + /* The primary purpose of this lock is to guarentee that the + * refcount is correctly maintained, not to make the copy + * atomic. If you want to make the copy atomic, you probably + * want serialize access differently (or perhaps you shouldn't + * use copy) + */ + g_static_mutex_lock (&file_info_ref_lock); + + old_refcount = dest->refcount; + + /* Copy basic information all at once; we will fix pointers later. */ + + memcpy (dest, src, sizeof (*src)); + + /* Duplicate dynamically allocated strings. */ + + dest->name = g_strdup (src->name); + dest->symlink_name = g_strdup (src->symlink_name); + dest->mime_type = g_strdup (src->mime_type); + + dest->refcount = old_refcount; + + g_static_mutex_unlock (&file_info_ref_lock); + +} + +/** + * gnome_vfs_file_info_dup: + * @orig: Pointer to a file information structure to duplicate + * + * Duplicates @orig and returns it. + * + * Returns: a new file information struct that duplicates the information in @orig. + **/ +GnomeVFSFileInfo * +gnome_vfs_file_info_dup (const GnomeVFSFileInfo *orig) +{ + GnomeVFSFileInfo * ret; + + g_return_val_if_fail (orig != NULL, NULL); + + ret = gnome_vfs_file_info_new(); + + gnome_vfs_file_info_copy (ret, orig); + + return ret; +} + + +/** + * gnome_vfs_file_info_matches + * @a: first GnomeVFSFileInfo struct to compare + * @b: second GnomeVFSFileInfo struct to compare + * + * Compare the two file info structs, return TRUE if they match. + * + * Returns: TRUE if the two GnomeVFSFileInfos match, otherwise return FALSE. + **/ +gboolean +gnome_vfs_file_info_matches (const GnomeVFSFileInfo *a, + const GnomeVFSFileInfo *b) +{ + g_return_val_if_fail (a != NULL, FALSE); + g_return_val_if_fail (b != NULL, FALSE); + g_return_val_if_fail (a->name != NULL, FALSE); + g_return_val_if_fail (b->name != NULL, FALSE); + + if (a->type != b->type + || a->size != b->size + || a->block_count != b->block_count + || a->atime != b->atime + || a->mtime != b->mtime + || a->ctime != b->ctime + || strcmp (a->name, b->name) != 0) { + return FALSE; + } + + if (a->mime_type == NULL || b->mime_type == NULL) { + return a->mime_type == b->mime_type; + } + + g_assert (a->mime_type != NULL && b->mime_type != NULL); + return g_ascii_strcasecmp (a->mime_type, b->mime_type) == 0; +} + +/** + * gnome_vfs_file_info_list_ref: + * @list: list of GnomeVFSFileInfo elements + * + * Increments the reference count of the items in @list by one. + * + * Return value: @list + **/ +GList * +gnome_vfs_file_info_list_ref (GList *list) +{ + g_list_foreach (list, (GFunc) gnome_vfs_file_info_ref, NULL); + return list; +} + +/** + * gnome_vfs_file_info_list_unref: + * @list: list of GnomeVFSFileInfo elements + * + * Decrements the reference count of the items in @list by one. + * Note that the list is *not freed* even if each member of the list + * is freed. + * + * Return value: @list + **/ +GList * +gnome_vfs_file_info_list_unref (GList *list) +{ + g_list_foreach (list, (GFunc) gnome_vfs_file_info_unref, NULL); + return list; +} + +/** + * gnome_vfs_file_info_list_copy: + * @list: list of GnomeVFSFileInfo elements + * + * Creates a duplicate of @list, and references each member of + * that list. + * + * Return value: a newly referenced duplicate of @list + **/ +GList * +gnome_vfs_file_info_list_copy (GList *list) +{ + return g_list_copy (gnome_vfs_file_info_list_ref (list)); +} + +/** + * gnome_vfs_file_info_list_free: + * @list: list of GnomeVFSFileInfo elements + * + * Decrements the reference count of each member of @list by one, + * and frees the list itself. + **/ +void +gnome_vfs_file_info_list_free (GList *list) +{ + g_list_free (gnome_vfs_file_info_list_unref (list)); +} diff --git a/libgnomevfs/gnome-vfs-file-info.h b/libgnomevfs/gnome-vfs-file-info.h new file mode 100644 index 0000000..5b4f899 --- /dev/null +++ b/libgnomevfs/gnome-vfs-file-info.h @@ -0,0 +1,426 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-file-info.h - Handling of file information for the GNOME + Virtual File System. + + Copyright (C) 1999,2001 Free Software Foundation + Copyright (C) 2002 Seth Nickell + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli + Seth Nickell +*/ + +#ifndef GNOME_VFS_FILE_INFO_H +#define GNOME_VFS_FILE_INFO_H + +#include +#include +#include +#include +#include + +G_BEGIN_DECLS + +/** + * GnomeVFSInodeNumber: + * + * Represents the i-node of a file, this is a low level data structure + * that the operating system uses to hold information about a file. + **/ + +typedef GnomeVFSFileSize GnomeVFSInodeNumber; + +/** + * GnomeVFSFileFlags: + * @GNOME_VFS_FILE_FLAGS_NONE: no flags + * @GNOME_VFS_FILE_FLAGS_SYMLINK: whether the file is a symlink. + * @GNOME_VFS_FILE_FLAGS_LOCAL: whether the file is on a local filesystem + * + * Packed boolean bitfield representing special + * flags a #GnomeVFSFileInfo struct can have. + **/ +typedef enum { + GNOME_VFS_FILE_FLAGS_NONE = 0, + GNOME_VFS_FILE_FLAGS_SYMLINK = 1 << 0, + GNOME_VFS_FILE_FLAGS_LOCAL = 1 << 1 +} GnomeVFSFileFlags; + +/** + * GnomeVFSFileType: + * @GNOME_VFS_FILE_TYPE_UNKNOWN: + * @GNOME_VFS_FILE_TYPE_REGULAR: + * @GNOME_VFS_FILE_TYPE_DIRECTORY: + * @GNOME_VFS_FILE_TYPE_FIFO: + * @GNOME_VFS_FILE_TYPE_SOCKET: + * @GNOME_VFS_FILE_TYPE_CHARACTER_DEVICE: + * @GNOME_VFS_FILE_TYPE_BLOCK_DEVICE: + * @GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK: + * + * Identifies the kind of file represented by a #GnomeVFSFileInfo struct. (note, + * use of MIME types is preferred as this field may eventually disappear) + **/ + +typedef enum { + GNOME_VFS_FILE_TYPE_UNKNOWN, + GNOME_VFS_FILE_TYPE_REGULAR, + GNOME_VFS_FILE_TYPE_DIRECTORY, + GNOME_VFS_FILE_TYPE_FIFO, + GNOME_VFS_FILE_TYPE_SOCKET, + GNOME_VFS_FILE_TYPE_CHARACTER_DEVICE, + GNOME_VFS_FILE_TYPE_BLOCK_DEVICE, + GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK +} GnomeVFSFileType; + +/** + * GnomeVFSFileInfoFields: + * @GNOME_VFS_FILE_INFO_FIELDS_NONE: No fields are valid + * @GNOME_VFS_FILE_INFO_FIELDS_TYPE: Type field is valid + * @GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS: Permissions field is valid + * @GNOME_VFS_FILE_INFO_FIELDS_FLAGS: Flags field is valid + * @GNOME_VFS_FILE_INFO_FIELDS_DEVICE: Device field is valid + * @GNOME_VFS_FILE_INFO_FIELDS_INODE: Inode field is valid + * @GNOME_VFS_FILE_INFO_FIELDS_LINK_COUNT: Link count field is valid + * @GNOME_VFS_FILE_INFO_FIELDS_SIZE: Size field is valid + * @GNOME_VFS_FILE_INFO_FIELDS_BLOCK_COUNT: Block count field is valid + * @GNOME_VFS_FILE_INFO_FIELDS_IO_BLOCK_SIZE: I/O Block Size field is valid + * @GNOME_VFS_FILE_INFO_FIELDS_ATIME: Access time field is valid + * @GNOME_VFS_FILE_INFO_FIELDS_MTIME: Modification time field is valid + * @GNOME_VFS_FILE_INFO_FIELDS_CTIME: Creating time field is valid + * @GNOME_VFS_FILE_INFO_FIELDS_SYMLINK_NAME: Symlink name field is valid + * @GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE: Mime type field is valid + * @GNOME_VFS_FILE_INFO_FIELDS_ACCESS: Access bits of the permissions + * bitfield are valid + * + * Flags indicating what fields in a GnomeVFSFileInfo struct are valid. + * Name is always assumed valid (how else would you have gotten a + * FileInfo struct otherwise?) + **/ + +typedef enum { + GNOME_VFS_FILE_INFO_FIELDS_NONE = 0, + GNOME_VFS_FILE_INFO_FIELDS_TYPE = 1 << 0, + GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS = 1 << 1, + GNOME_VFS_FILE_INFO_FIELDS_FLAGS = 1 << 2, + GNOME_VFS_FILE_INFO_FIELDS_DEVICE = 1 << 3, + GNOME_VFS_FILE_INFO_FIELDS_INODE = 1 << 4, + GNOME_VFS_FILE_INFO_FIELDS_LINK_COUNT = 1 << 5, + GNOME_VFS_FILE_INFO_FIELDS_SIZE = 1 << 6, + GNOME_VFS_FILE_INFO_FIELDS_BLOCK_COUNT = 1 << 7, + GNOME_VFS_FILE_INFO_FIELDS_IO_BLOCK_SIZE = 1 << 8, + GNOME_VFS_FILE_INFO_FIELDS_ATIME = 1 << 9, + GNOME_VFS_FILE_INFO_FIELDS_MTIME = 1 << 10, + GNOME_VFS_FILE_INFO_FIELDS_CTIME = 1 << 11, + GNOME_VFS_FILE_INFO_FIELDS_SYMLINK_NAME = 1 << 12, + GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE = 1 << 13, + GNOME_VFS_FILE_INFO_FIELDS_ACCESS = 1 << 14 +} GnomeVFSFileInfoFields; + +/* FIXME: It's silly to use the symbolic constants for POSIX here. + * This is supposed to be a virtual file system, so it makes no + * sense to use the values of the POSIX-required constants on the + * particular machine this code is compiled on. These should all be changed + * to use numeric constants like GNOME_VFS_PERM_STICKY does now. However, + * be careful in making such a change, since some existing code might + * wrongly assume these equivalencies. + */ + +/** + * GnomeVFSFilePermissions: + * @GNOME_VFS_PERM_SUID: UID bit + * @GNOME_VFS_PERM_SGID: GID bit + * @GNOME_VFS_PERM_STICKY: Sticky bit. + * @GNOME_VFS_PERM_USER_READ: Owner has read permission + * @GNOME_VFS_PERM_USER_WRITE: Owner has write permission + * @GNOME_VFS_PERM_USER_EXEC: Owner has execution permission + * @GNOME_VFS_PERM_USER_ALL: Owner has all permissions + * @GNOME_VFS_PERM_GROUP_READ: Group has read permission + * @GNOME_VFS_PERM_GROUP_WRITE: Group has write permission + * @GNOME_VFS_PERM_GROUP_EXEC: Group has execution permission + * @GNOME_VFS_PERM_GROUP_ALL: Group has all permissions + * @GNOME_VFS_PERM_OTHER_READ: Others have read permission + * @GNOME_VFS_PERM_OTHER_WRITE: Others have write permission + * @GNOME_VFS_PERM_OTHER_EXEC: Others have execution permission + * @GNOME_VFS_PERM_OTHER_ALL: Others have all permissions + * @GNOME_VFS_PERM_ACCESS_READABLE: + * @GNOME_VFS_PERM_ACCESS_WRITABLE: + * @GNOME_VFS_PERM_ACCESS_EXECUTABLE: + * + * File permissions. These are the same as the Unix ones, but we wrap them + * into a nicer VFS-like enum. + **/ +typedef enum { + GNOME_VFS_PERM_SUID = S_ISUID, + GNOME_VFS_PERM_SGID = S_ISGID, + GNOME_VFS_PERM_STICKY = 01000, /* S_ISVTX not defined on all systems */ + GNOME_VFS_PERM_USER_READ = S_IRUSR, + GNOME_VFS_PERM_USER_WRITE = S_IWUSR, + GNOME_VFS_PERM_USER_EXEC = S_IXUSR, + GNOME_VFS_PERM_USER_ALL = S_IRUSR | S_IWUSR | S_IXUSR, + GNOME_VFS_PERM_GROUP_READ = S_IRGRP, + GNOME_VFS_PERM_GROUP_WRITE = S_IWGRP, + GNOME_VFS_PERM_GROUP_EXEC = S_IXGRP, + GNOME_VFS_PERM_GROUP_ALL = S_IRGRP | S_IWGRP | S_IXGRP, + GNOME_VFS_PERM_OTHER_READ = S_IROTH, + GNOME_VFS_PERM_OTHER_WRITE = S_IWOTH, + GNOME_VFS_PERM_OTHER_EXEC = S_IXOTH, + GNOME_VFS_PERM_OTHER_ALL = S_IROTH | S_IWOTH | S_IXOTH, + GNOME_VFS_PERM_ACCESS_READABLE = 1 << 16, + GNOME_VFS_PERM_ACCESS_WRITABLE = 1 << 17, + GNOME_VFS_PERM_ACCESS_EXECUTABLE = 1 << 18 +} GnomeVFSFilePermissions; + + +/** + * GnomeVFSFileInfo: + * + * The GnomeVFSFileInfo structure contains information about a file. + **/ +typedef struct { + /* Base name of the file (no path). */ + char *name; + + /* Fields which are actually valid in this structure. */ + GnomeVFSFileInfoFields valid_fields; + + /* File type (i.e. regular, directory, block device...). */ + GnomeVFSFileType type; + + /* File permissions. */ + GnomeVFSFilePermissions permissions; + + /* Flags for this file. */ + GnomeVFSFileFlags flags; + + /* These are only valid if `is_local' is TRUE (see below). */ + dev_t device; + GnomeVFSInodeNumber inode; + + /* Link count. */ + guint link_count; + + /* UID, GID. */ + guint uid; + guint gid; + + /* Size in bytes. */ + GnomeVFSFileSize size; + + /* Size measured in units of 512-byte blocks. */ + GnomeVFSFileSize block_count; + + /* Optimal buffer size for reading/writing the file. */ + guint io_block_size; + + /* Access, modification and change times. */ + time_t atime; + time_t mtime; + time_t ctime; + + /* If the file is a symlink (see `flags'), this specifies the file the + link points to. */ + char *symlink_name; + + /* MIME type. */ + char *mime_type; + + guint refcount; + + /* Reserved for future expansions to GnomeVFSFileInfo without having + to break ABI compatibility */ + void *reserved1; + void *reserved2; + void *reserved3; + void *reserved4; + void *reserved5; +} GnomeVFSFileInfo; + +/** + * GnomeVFSFileInfoOptions: + * @GNOME_VFS_FILE_INFO_DEFAULT: default flags + * @GNOME_VFS_FILE_INFO_GET_MIME_TYPE: detect the MIME type + * @GNOME_VFS_FILE_INFO_FORCE_FAST_MIME_TYPE: only use fast MIME type + * detection (extensions) + * @GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE: force slow MIME type + * detection where available (sniffing, algorithmic detection, etc) + * @GNOME_VFS_FILE_INFO_FOLLOW_LINKS: automatically follow symbolic + * links and retrieve the properties of their target (recommended) + * @GNOME_VFS_FILE_INFO_GET_ACCESS_RIGHTS: tries to get data similar + * to what would return access(2) on a local file system (ie is the + * file readable, writable and/or executable). Can be really slow on + * remote file systems + * + * Packed boolean bitfield representing options that can + * be passed into a gnome_vfs_get_file_info() call (or other + * related calls that return file info) and affect the operation + * of get_file_info. + **/ + +typedef enum { + GNOME_VFS_FILE_INFO_DEFAULT = 0, + GNOME_VFS_FILE_INFO_GET_MIME_TYPE = 1 << 0, + GNOME_VFS_FILE_INFO_FORCE_FAST_MIME_TYPE = 1 << 1, + GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE = 1 << 2, + GNOME_VFS_FILE_INFO_FOLLOW_LINKS = 1 << 3, + GNOME_VFS_FILE_INFO_GET_ACCESS_RIGHTS = 1 << 4 +} GnomeVFSFileInfoOptions; + +/** + * GnomeVFSSetFileInfoMask: + * @GNOME_VFS_SET_FILE_INFO_NONE: don't set any file info fields + * @GNOME_VFS_SET_FILE_INFO_NAME: change the name + * @GNOME_VFS_SET_FILE_INFO_PERMISSIONS: change the permissions + * @GNOME_VFS_SET_FILE_INFO_OWNER: change the file's owner + * @GNOME_VFS_SET_FILE_INFO_TIME: change the file's time stamp(s) + * + * Packed boolean bitfield representing the aspects of the file + * to be changed in a gnome_vfs_set_file_info() call. + **/ + +typedef enum { + GNOME_VFS_SET_FILE_INFO_NONE = 0, + GNOME_VFS_SET_FILE_INFO_NAME = 1 << 0, + GNOME_VFS_SET_FILE_INFO_PERMISSIONS = 1 << 1, + GNOME_VFS_SET_FILE_INFO_OWNER = 1 << 2, + GNOME_VFS_SET_FILE_INFO_TIME = 1 << 3 +} GnomeVFSSetFileInfoMask; + +typedef struct { + GnomeVFSURI *uri; + GnomeVFSResult result; + GnomeVFSFileInfo *file_info; +} GnomeVFSGetFileInfoResult; + +/** + * GNOME_VFS_FILE_INFO_SYMLINK: + * @info: GnomeVFSFileInfo struct + * + * Determines whether a file is a symbolic link given @info. + */ +#define GNOME_VFS_FILE_INFO_SYMLINK(info) \ + ((info)->flags & GNOME_VFS_FILE_FLAGS_SYMLINK) + +/** + * GNOME_VFS_FILE_INFO_SET_SYMLINK: + * @info: GnomeVFSFileInfo struct + * @value: if %TRUE, @info is set to indicate the file is a symbolic link + * + * Set the symbolic link field in @info to @value. + */ +#define GNOME_VFS_FILE_INFO_SET_SYMLINK(info, value) \ + (value ? ((info)->flags |= GNOME_VFS_FILE_FLAGS_SYMLINK) \ + : ((info)->flags &= ~GNOME_VFS_FILE_FLAGS_SYMLINK)) + +/** + * GNOME_VFS_FILE_INFO_LOCAL: + * @info: GnomeVFSFileInfo struct + * + * Determines whether a file is local given @info. + */ +#define GNOME_VFS_FILE_INFO_LOCAL(info) \ + ((info)->flags & GNOME_VFS_FILE_FLAGS_LOCAL) + +/** + * GNOME_VFS_FILE_INFO_SET_LOCAL: + * @info: GnomeVFSFileInfo struct + * @value: if %TRUE, @info is set to indicate the file is local + * + * Set the "local file" field in @info to @value. + */ +#define GNOME_VFS_FILE_INFO_SET_LOCAL(info, value) \ + (value ? ((info)->flags |= GNOME_VFS_FILE_FLAGS_LOCAL) \ + : ((info)->flags &= ~GNOME_VFS_FILE_FLAGS_LOCAL)) + + +/** + * GNOME_VFS_FILE_INFO_SUID: + * @info: GnomeVFSFileInfo struct + * + * Determines whether a file belongs to the super user. + */ +#define GNOME_VFS_FILE_INFO_SUID(info) \ + ((info)->permissions & GNOME_VFS_PERM_SUID) + +/** + * GNOME_VFS_FILE_INFO_SGID: + * @info: GnomeVFSFileInfo struct + * + * Determines whether a file belongs to the super user's group. + */ +#define GNOME_VFS_FILE_INFO_SGID(info) \ + ((info)->permissions & GNOME_VFS_PERM_SGID) + +/** + * GNOME_VFS_FILE_INFO_STICKY: + * @info: GnomeVFSFileInfo struct + * + * Determines whether a file has the sticky bit set, given @info + */ +#define GNOME_VFS_FILE_INFO_STICKY(info) \ + ((info)->permissions & GNOME_VFS_PERM_STICKY) + +/** + * GNOME_VFS_FILE_INFO_SET_SUID: + * @info: GnomeVFSFileInfo struct + * @value: if %TRUE, @info is set to indicate the file belongs to the super user + * + * Set the SUID field in @info to @value. + */ +#define GNOME_VFS_FILE_INFO_SET_SUID(info, value) \ + (value ? ((info)->permissions |= GNOME_VFS_PERM_SUID) \ + : ((info)->permissions &= ~GNOME_VFS_PERM_SUID)) + +/** + * GNOME_VFS_FILE_INFO_SET_SGID: + * @info: GnomeVFSFileInfo struct + * @value: if %TRUE, @info is set to indicate the file belongs to the super user's group + * + * Set the SGID field in @info to @value. + */ +#define GNOME_VFS_FILE_INFO_SET_SGID(info, value) \ + (value ? ((info)->permissions |= GNOME_VFS_PERM_SGID) \ + : ((info)->permissions &= ~GNOME_VFS_PERM_SGID)) +/** + * GNOME_VFS_FILE_INFO_SET_STICKY: + * @info: GnomeVFSFileInfo struct + * @value: if %TRUE, @info is set to indicate the file has the sticky bit set + * + * Set the sticky bit in @info to @value. + */ +#define GNOME_VFS_FILE_INFO_SET_STICKY(info, value) \ + (value ? ((info)->permissions |= GNOME_VFS_PERM_STICKY) \ + : ((info)->permissions &= ~GNOME_VFS_PERM_STICKY)) + + + +GnomeVFSFileInfo *gnome_vfs_file_info_new (void); +void gnome_vfs_file_info_unref (GnomeVFSFileInfo *info); +void gnome_vfs_file_info_ref (GnomeVFSFileInfo *info); +void gnome_vfs_file_info_clear (GnomeVFSFileInfo *info); +const char * gnome_vfs_file_info_get_mime_type (GnomeVFSFileInfo *info); +void gnome_vfs_file_info_copy (GnomeVFSFileInfo *dest, + const GnomeVFSFileInfo *src); +GnomeVFSFileInfo *gnome_vfs_file_info_dup (const GnomeVFSFileInfo *orig); +gboolean gnome_vfs_file_info_matches (const GnomeVFSFileInfo *a, + const GnomeVFSFileInfo *b); +GList * gnome_vfs_file_info_list_ref (GList *list); +GList * gnome_vfs_file_info_list_unref (GList *list); +GList * gnome_vfs_file_info_list_copy (GList *list); +void gnome_vfs_file_info_list_free (GList *list); + +G_END_DECLS + +#endif /* GNOME_VFS_FILE_INFO_H */ diff --git a/libgnomevfs/gnome-vfs-file-size.h b/libgnomevfs/gnome-vfs-file-size.h new file mode 100644 index 0000000..42fd9b9 --- /dev/null +++ b/libgnomevfs/gnome-vfs-file-size.h @@ -0,0 +1,53 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* gnome-vfs-file-size.h - Typedefs of GnomeVFSFileSize and GnomeVFSFileOffset + Note: This file is generated by configure, please edit gnome-vfs-file-size.h.in + + Copyright (C) 2000 Eazel, Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: George Lebl, +*/ + +#ifndef GNOME_VFS_FILE_SIZE_H +#define GNOME_VFS_FILE_SIZE_H + +#include + +/* + * This defines GnomeVFSFileSize and GnomeVFSFileOffset + * + * It also defines GNOME_VFS_SIZE_IS_ and GNOME_VFS_OFFSET_IS_ + * where type is INT, UNSIGNED_INT, LONG, UNSIGNED_LONG, LONG_LONG + * or UNSIGNED_LONG_LONG. Note that size is always unsigned and offset + * is always signed. + * + * It also defines GNOME_VFS_SIZE_FORMAT_STR and GNOME_VFS_OFFSET_FORMAT_STR + * which is the string representation to be used in printf style expressions. + * This is without the %, so for example for long it would be "ld" + */ + +#define GNOME_VFS_SIZE_IS_UNSIGNED_LONG_LONG +#define GNOME_VFS_OFFSET_IS_LONG_LONG + +#define GNOME_VFS_SIZE_FORMAT_STR "Lu" +#define GNOME_VFS_OFFSET_FORMAT_STR "Ld" + +G_GNUC_EXTENSION typedef unsigned long long GnomeVFSFileSize; +G_GNUC_EXTENSION typedef long long GnomeVFSFileOffset; + +#endif /* GNOME_VFS_FILE_SIZE_H */ diff --git a/libgnomevfs/gnome-vfs-file-size.h.in b/libgnomevfs/gnome-vfs-file-size.h.in new file mode 100644 index 0000000..5ce0dcb --- /dev/null +++ b/libgnomevfs/gnome-vfs-file-size.h.in @@ -0,0 +1,53 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* gnome-vfs-file-size.h - Typedefs of GnomeVFSFileSize and GnomeVFSFileOffset + Note: This file is generated by configure, please edit gnome-vfs-file-size.h.in + + Copyright (C) 2000 Eazel, Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: George Lebl, +*/ + +#ifndef GNOME_VFS_FILE_SIZE_H +#define GNOME_VFS_FILE_SIZE_H + +#include + +/* + * This defines GnomeVFSFileSize and GnomeVFSFileOffset + * + * It also defines GNOME_VFS_SIZE_IS_ and GNOME_VFS_OFFSET_IS_ + * where type is INT, UNSIGNED_INT, LONG, UNSIGNED_LONG, LONG_LONG + * or UNSIGNED_LONG_LONG. Note that size is always unsigned and offset + * is always signed. + * + * It also defines GNOME_VFS_SIZE_FORMAT_STR and GNOME_VFS_OFFSET_FORMAT_STR + * which is the string representation to be used in printf style expressions. + * This is without the %, so for example for long it would be "ld" + */ + +#define GNOME_VFS_SIZE_IS_@VFS_SIZE_IS@ +#define GNOME_VFS_OFFSET_IS_@VFS_OFFSET_IS@ + +#define GNOME_VFS_SIZE_FORMAT_STR "@VFS_SIZE_PRINTF@" +#define GNOME_VFS_OFFSET_FORMAT_STR "@VFS_OFFSET_PRINTF@" + +G_GNUC_EXTENSION typedef @VFS_SIZE@ GnomeVFSFileSize; +G_GNUC_EXTENSION typedef @VFS_OFFSET@ GnomeVFSFileOffset; + +#endif /* GNOME_VFS_FILE_SIZE_H */ diff --git a/libgnomevfs/gnome-vfs-find-directory.c b/libgnomevfs/gnome-vfs-find-directory.c new file mode 100644 index 0000000..051aa87 --- /dev/null +++ b/libgnomevfs/gnome-vfs-find-directory.c @@ -0,0 +1,65 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-find-directory.c - Public utility functions for the GNOME Virtual + File System. + + Copyright (C) 2000 Eazel, Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Pavel Cisler +*/ + +#include +#include "gnome-vfs-find-directory.h" + +#include "gnome-vfs-cancellable-ops.h" + +/** + * gnome_vfs_find_directory: + * @near_uri: find a well known directory on the same volume as @near_uri + * @kind: kind of well known directory + * @result: newly created URI of the directory we found + * @create_if_needed: If directory we are looking for does not exist, try to create it + * @find_if_needed: If we don't know where trash is yet, look for it. + * @permissions: If creating, use these permissions + * + * Used to return well known directories such as Trash, Desktop, etc. from different + * file systems. + * + * There is quite a complicated logic behind finding/creating a Trash directory + * and you need to be aware of some implications: + * Finding the Trash the first time when using the file method may be pretty + * expensive. A cache file is used to store the location of that Trash file + * for next time. + * If @ceate_if_needed is specified without @find_if_needed, you may end up + * creating a Trash file when there already is one. Your app should start out + * by doing a gnome_vfs_find_directory with the @find_if_needed to avoid this + * and then use the @create_if_needed flag to create Trash lazily when it is + * needed for throwing away an item on a given disk. + * + * Returns: An integer representing the result of the operation + **/ +GnomeVFSResult +gnome_vfs_find_directory (GnomeVFSURI *near_uri, + GnomeVFSFindDirectoryKind kind, + GnomeVFSURI **result, + gboolean create_if_needed, + gboolean find_if_needed, + guint permissions) +{ + return gnome_vfs_find_directory_cancellable (near_uri, kind, result, + create_if_needed, find_if_needed, permissions, NULL); +} diff --git a/libgnomevfs/gnome-vfs-find-directory.h b/libgnomevfs/gnome-vfs-find-directory.h new file mode 100644 index 0000000..26fa9d5 --- /dev/null +++ b/libgnomevfs/gnome-vfs-find-directory.h @@ -0,0 +1,50 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* gnome-vfs-find-directory.h - Special directory location functions for + the GNOME Virtual File System. + + Copyright (C) 2000 Eazel, Inc. + Copyright (C) 2001 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Pavel Cisler + Seth Nickell +*/ + +#ifndef GNOME_VFS_FIND_DIRECTORY_H +#define GNOME_VFS_FIND_DIRECTORY_H + +#include +#include + +G_BEGIN_DECLS + +typedef enum { + GNOME_VFS_DIRECTORY_KIND_DESKTOP = 1000, + GNOME_VFS_DIRECTORY_KIND_TRASH = 1001 +} GnomeVFSFindDirectoryKind; + +GnomeVFSResult gnome_vfs_find_directory (GnomeVFSURI *near_uri, + GnomeVFSFindDirectoryKind kind, + GnomeVFSURI **result, + gboolean create_if_needed, + gboolean find_if_needed, + guint permissions); + +G_END_DECLS + +#endif diff --git a/libgnomevfs/gnome-vfs-handle-private.h b/libgnomevfs/gnome-vfs-handle-private.h new file mode 100644 index 0000000..0e57303 --- /dev/null +++ b/libgnomevfs/gnome-vfs-handle-private.h @@ -0,0 +1,71 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-handle-private.h - Handle object functions for GNOME VFS files. + + Copyright (C) 2002 Seth Nickell + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Seth Nickell +*/ + +#ifndef GNOME_VFS_HANDLE_PRIVATE_H +#define GNOME_VFS_HANDLE_PRIVATE_H + +G_BEGIN_DECLS + +GnomeVFSHandle * _gnome_vfs_handle_new (GnomeVFSURI *uri, + GnomeVFSMethodHandle *method_handle, + GnomeVFSOpenMode open_mode); +void _gnome_vfs_handle_destroy (GnomeVFSHandle *handle); +GnomeVFSOpenMode _gnome_vfs_handle_get_open_mode (GnomeVFSHandle *handle); +GnomeVFSResult _gnome_vfs_handle_do_close (GnomeVFSHandle *handle, + GnomeVFSContext *context); +GnomeVFSResult _gnome_vfs_handle_do_read (GnomeVFSHandle *handle, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read, + GnomeVFSContext *context); +GnomeVFSResult _gnome_vfs_handle_do_write (GnomeVFSHandle *handle, + gconstpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_written, + GnomeVFSContext *context); +GnomeVFSResult __gnome_vfs_handle_do_close_directory (GnomeVFSHandle *handle, + GnomeVFSContext *context); +GnomeVFSResult __gnome_vfs_handle_do_read_directory (GnomeVFSHandle *handle, + GnomeVFSFileInfo *file_info, + GnomeVFSContext *context); +GnomeVFSResult _gnome_vfs_handle_do_seek (GnomeVFSHandle *handle, + GnomeVFSSeekPosition whence, + GnomeVFSFileSize offset, + GnomeVFSContext *context); +GnomeVFSResult _gnome_vfs_handle_do_tell (GnomeVFSHandle *handle, + GnomeVFSFileSize *offset_return); +GnomeVFSResult _gnome_vfs_handle_do_get_file_info (GnomeVFSHandle *handle, + GnomeVFSFileInfo *info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context); +GnomeVFSResult _gnome_vfs_handle_do_truncate (GnomeVFSHandle *handle, + GnomeVFSFileSize length, + GnomeVFSContext *context); +GnomeVFSResult _gnome_vfs_handle_do_file_control (GnomeVFSHandle *handle, + const char *operation, + gpointer operation_data, + GnomeVFSContext *context); + +G_END_DECLS + +#endif diff --git a/libgnomevfs/gnome-vfs-handle.c b/libgnomevfs/gnome-vfs-handle.c new file mode 100644 index 0000000..2284100 --- /dev/null +++ b/libgnomevfs/gnome-vfs-handle.c @@ -0,0 +1,194 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-handle.c - Handle object for GNOME VFS files. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli +*/ + +#include +#include "gnome-vfs-handle.h" +#include "gnome-vfs-handle-private.h" +#include "gnome-vfs-method.h" + +#include + +struct GnomeVFSHandle { + /* URI of the file being accessed through the handle. */ + GnomeVFSURI *uri; + + /* Method-specific handle. */ + GnomeVFSMethodHandle *method_handle; + + /* Open mode. */ + GnomeVFSOpenMode open_mode; +}; + +#define CHECK_IF_OPEN(handle) \ +G_STMT_START{ \ + if (handle->uri == NULL) \ + return GNOME_VFS_ERROR_NOT_OPEN; \ +}G_STMT_END + +#define CHECK_IF_SUPPORTED(handle, what) \ +G_STMT_START{ \ + if (!VFS_METHOD_HAS_FUNC(handle->uri->method, what)) \ + return GNOME_VFS_ERROR_NOT_SUPPORTED; \ +}G_STMT_END + +#define INVOKE(result, handle, what, params) \ +G_STMT_START{ \ + CHECK_IF_OPEN (handle); \ + CHECK_IF_SUPPORTED (handle, what); \ + (result) = handle->uri->method->what params; \ +}G_STMT_END + +#define INVOKE_AND_RETURN(handle, what, params) \ +G_STMT_START{ \ + GnomeVFSResult __result; \ + \ + INVOKE (__result, handle, what, params); \ + return __result; \ +}G_STMT_END + + +GnomeVFSHandle * +_gnome_vfs_handle_new (GnomeVFSURI *uri, + GnomeVFSMethodHandle *method_handle, + GnomeVFSOpenMode open_mode) +{ + GnomeVFSHandle *new; + + g_return_val_if_fail (uri != NULL, NULL); + g_return_val_if_fail (method_handle != NULL, NULL); + + new = g_new (GnomeVFSHandle, 1); + + new->uri = gnome_vfs_uri_ref (uri); + new->method_handle = method_handle; + new->open_mode = open_mode; + + return new; +} + +void +_gnome_vfs_handle_destroy (GnomeVFSHandle *handle) +{ + g_return_if_fail (handle != NULL); + + gnome_vfs_uri_unref (handle->uri); + + g_free (handle); +} + + +GnomeVFSOpenMode +_gnome_vfs_handle_get_open_mode (GnomeVFSHandle *handle) +{ + g_return_val_if_fail (handle != NULL, (GnomeVFSOpenMode) 0); + + return handle->open_mode; +} + + +/* Actions. */ + +GnomeVFSResult +_gnome_vfs_handle_do_close (GnomeVFSHandle *handle, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + + INVOKE (result, handle, close, (handle->uri->method, handle->method_handle, context)); + + /* Even if close has failed, we shut down the handle. */ + _gnome_vfs_handle_destroy (handle); + + return result; +} + +GnomeVFSResult +_gnome_vfs_handle_do_read (GnomeVFSHandle *handle, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read, + GnomeVFSContext *context) +{ + INVOKE_AND_RETURN (handle, read, (handle->uri->method, handle->method_handle, + buffer, num_bytes, bytes_read, + context)); +} + +GnomeVFSResult +_gnome_vfs_handle_do_write (GnomeVFSHandle *handle, + gconstpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_written, + GnomeVFSContext *context) +{ + INVOKE_AND_RETURN (handle, write, (handle->uri->method, handle->method_handle, + buffer, num_bytes, bytes_written, + context)); +} + + +GnomeVFSResult +_gnome_vfs_handle_do_seek (GnomeVFSHandle *handle, + GnomeVFSSeekPosition whence, + GnomeVFSFileSize offset, + GnomeVFSContext *context) +{ + INVOKE_AND_RETURN (handle, seek, (handle->uri->method, handle->method_handle, + whence, offset, context)); +} + +GnomeVFSResult +_gnome_vfs_handle_do_tell (GnomeVFSHandle *handle, + GnomeVFSFileSize *offset_return) +{ + INVOKE_AND_RETURN (handle, tell, (handle->uri->method, handle->method_handle, + offset_return)); +} + + +GnomeVFSResult +_gnome_vfs_handle_do_get_file_info (GnomeVFSHandle *handle, + GnomeVFSFileInfo *info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + INVOKE_AND_RETURN (handle, get_file_info_from_handle, + (handle->uri->method, handle->method_handle, info, options, + context)); +} + +GnomeVFSResult _gnome_vfs_handle_do_truncate (GnomeVFSHandle *handle, + GnomeVFSFileSize length, + GnomeVFSContext *context) +{ + INVOKE_AND_RETURN (handle, truncate_handle, (handle->uri->method, handle->method_handle, length, context)); +} + +GnomeVFSResult +_gnome_vfs_handle_do_file_control (GnomeVFSHandle *handle, + const char *operation, + gpointer operation_data, + GnomeVFSContext *context) +{ + INVOKE_AND_RETURN (handle, file_control, (handle->uri->method, handle->method_handle, operation, operation_data, context)); +} diff --git a/libgnomevfs/gnome-vfs-handle.h b/libgnomevfs/gnome-vfs-handle.h new file mode 100644 index 0000000..c0908d7 --- /dev/null +++ b/libgnomevfs/gnome-vfs-handle.h @@ -0,0 +1,78 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-handle.h - Handle object for GNOME VFS files. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli +*/ + +#ifndef GNOME_VFS_HANDLE_H +#define GNOME_VFS_HANDLE_H + +#include +#include +#include + +G_BEGIN_DECLS + +typedef gpointer GnomeVFSMethodHandle; +/** + * GnomeVFSHandle: + * + * Handle to a file, a handle is obtained using gnome_vfs_open and gnome_vfs_create + * family of functions on the file. A handle represents a file stream, gnome_vfs_close, + * gnome_vfs_write, gnome_vfs_read and all the other operations take a GnomeVFSHandle + * that identifies the file where the operation is going to be performed. + **/ +typedef struct GnomeVFSHandle GnomeVFSHandle; + +/** + * GnomeVFSOpenMode: + * @GNOME_VFS_OPEN_NONE: + * @GNOME_VFS_OPEN_READ: + * @GNOME_VFS_OPEN_WRITE: + * @GNOME_VFS_OPEN_RANDOM: + * + * Mode in which files are opened. If GNOME_VFS_OPEN_RANDOM is not used, the + * file will be have to be accessed sequentially. + **/ +typedef enum { + GNOME_VFS_OPEN_NONE = 0, + GNOME_VFS_OPEN_READ = 1 << 0, + GNOME_VFS_OPEN_WRITE = 1 << 1, + GNOME_VFS_OPEN_RANDOM = 1 << 2 +} GnomeVFSOpenMode; + +/** + * GnomeVFSSeekPosition: + * @GNOME_VFS_SEEK_START: Start of the file. + * @GNOME_VFS_SEEK_CURRENT: Current position. + * @GNOME_VFS_SEEK_END: End of the file. + * + * This is used to specify the start position for seek operations. + **/ +typedef enum { + GNOME_VFS_SEEK_START, + GNOME_VFS_SEEK_CURRENT, + GNOME_VFS_SEEK_END +} GnomeVFSSeekPosition; + + +G_END_DECLS + +#endif /* GNOME_VFS_HANDLE_H */ diff --git a/libgnomevfs/gnome-vfs-i18n.c b/libgnomevfs/gnome-vfs-i18n.c new file mode 100644 index 0000000..98ad2f9 --- /dev/null +++ b/libgnomevfs/gnome-vfs-i18n.c @@ -0,0 +1,354 @@ +/* + * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation + * All rights reserved. + * + * This file is part of the Gnome Library. + * + * The Gnome Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Gnome Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include "gnome-vfs-i18n.h" + +#include "gnome-vfs-private-utils.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static GHashTable *alias_table = NULL; +static GHashTable *category_table = NULL; + +/*read an alias file for the locales*/ +static void +read_aliases (char *file) +{ + FILE *fp; + char buf[256]; + + if (!alias_table) + alias_table = g_hash_table_new (g_str_hash, g_str_equal); + fp = fopen (file,"r"); + if (!fp) + return; + while (fgets (buf, 256, fp)) + { + char *p, *q; + + g_strstrip (buf); + + /* Line is a comment */ + if ((buf[0] == '#') || (buf[0] == '\0')) + continue; + + /* Reads first column */ + for (p = buf, q = NULL; *p; p++) { + if ((*p == '\t') || (*p == ' ') || (*p == ':')) { + *p = '\0'; + q = p+1; + while ((*q == '\t') || (*q == ' ')) { + q++; + } + break; + } + } + /* The line only had one column */ + if (!q || *q == '\0') + continue; + + /* Read second column */ + for (p = q; *p; p++) { + if ((*p == '\t') || (*p == ' ')) { + *p = '\0'; + break; + } + } + + /* Add to alias table if necessary */ + if (!g_hash_table_lookup (alias_table, buf)) { + g_hash_table_insert (alias_table, g_strdup (buf), g_strdup (q)); + } + } + fclose (fp); +} + +static char * +unalias_lang (char *lang) +{ + char *p; + int i; + + if (!alias_table) + { + read_aliases ("/usr/share/locale/locale.alias"); + read_aliases ("/usr/local/share/locale/locale.alias"); + read_aliases ("/usr/lib/X11/locale/locale.alias"); + read_aliases ("/usr/openwin/lib/locale/locale.alias"); + } + i = 0; + while ((p = g_hash_table_lookup (alias_table, lang)) && (strcmp (p, lang) != 0)) + { + lang = p; + if (i++ == 30) + { + static gboolean said_before = FALSE; + if (!said_before) + g_warning ("Too many alias levels for a locale, " + "may indicate a loop"); + said_before = TRUE; + return lang; + } + } + return lang; +} + +/* Mask for components of locale spec. The ordering here is from + * least significant to most significant + */ +enum +{ + COMPONENT_CODESET = 1 << 0, + COMPONENT_TERRITORY = 1 << 1, + COMPONENT_MODIFIER = 1 << 2 +}; + +/* Break an X/Open style locale specification into components + */ +static guint +explode_locale (const gchar *locale, + gchar **language, + gchar **territory, + gchar **codeset, + gchar **modifier) +{ + const gchar *uscore_pos; + const gchar *at_pos; + const gchar *dot_pos; + + guint mask = 0; + + uscore_pos = strchr (locale, '_'); + dot_pos = strchr (uscore_pos ? uscore_pos : locale, '.'); + at_pos = strchr (dot_pos ? dot_pos : (uscore_pos ? uscore_pos : locale), '@'); + + if (at_pos) + { + mask |= COMPONENT_MODIFIER; + *modifier = g_strdup (at_pos); + } + else + at_pos = locale + strlen (locale); + + if (dot_pos) + { + mask |= COMPONENT_CODESET; + *codeset = g_strndup (dot_pos, at_pos - dot_pos); + } + else + dot_pos = at_pos; + + if (uscore_pos) + { + mask |= COMPONENT_TERRITORY; + *territory = g_strndup (uscore_pos, dot_pos - uscore_pos); + } + else + uscore_pos = dot_pos; + + *language = g_strndup (locale, uscore_pos - locale); + + return mask; +} + +/* + * Compute all interesting variants for a given locale name - + * by stripping off different components of the value. + * + * For simplicity, we assume that the locale is in + * X/Open format: language[_territory][.codeset][@modifier] + * + * TODO: Extend this to handle the CEN format (see the GNUlibc docs) + * as well. We could just copy the code from glibc wholesale + * but it is big, ugly, and complicated, so I'm reluctant + * to do so when this should handle 99% of the time... + */ +static GList * +compute_locale_variants (const gchar *locale) +{ + GList *retval = NULL; + + gchar *language; + gchar *territory; + gchar *codeset; + gchar *modifier; + + guint mask; + guint i; + + g_return_val_if_fail (locale != NULL, NULL); + + mask = explode_locale (locale, &language, &territory, &codeset, &modifier); + + /* Iterate through all possible combinations, from least attractive + * to most attractive. + */ + for (i = 0; i <= mask; i++) + if ((i & ~mask) == 0) + { + gchar *val = g_strconcat (language, + (i & COMPONENT_TERRITORY) ? territory : "", + (i & COMPONENT_CODESET) ? codeset : "", + (i & COMPONENT_MODIFIER) ? modifier : "", + NULL); + retval = g_list_prepend (retval, val); + } + + g_free (language); + if (mask & COMPONENT_CODESET) + g_free (codeset); + if (mask & COMPONENT_TERRITORY) + g_free (territory); + if (mask & COMPONENT_MODIFIER) + g_free (modifier); + + return retval; +} + +/* The following is (partly) taken from the gettext package. + Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. */ + +static const gchar * +guess_category_value (const gchar *categoryname) +{ + const gchar *retval; + + /* The highest priority value is the `LANGUAGE' environment + variable. This is a GNU extension. */ + retval = g_getenv ("LANGUAGE"); + if ((retval != NULL) && (retval[0] != '\0')) + return retval; + + /* `LANGUAGE' is not set. So we have to proceed with the POSIX + methods of looking to `LC_ALL', `LC_xxx', and `LANG'. On some + systems this can be done by the `setlocale' function itself. */ + + /* Setting of LC_ALL overwrites all other. */ + retval = g_getenv ("LC_ALL"); + if ((retval != NULL) && (retval[0] != '\0')) + return retval; + + /* Next comes the name of the desired category. */ + retval = g_getenv (categoryname); + if ((retval != NULL) && (retval[0] != '\0')) + return retval; + + /* Last possibility is the LANG environment variable. */ + retval = g_getenv ("LANG"); + if ((retval != NULL) && (retval[0] != '\0')) + return retval; + + return NULL; +} + +/** + * gnome_vfs_i18n_get_language_list: + * @category_name: Name of category to look up, e.g. "LC_MESSAGES". + * + * This computes a list of language strings. It searches in the + * standard environment variables to find the list, which is sorted + * in order from most desirable to least desirable. The `C' locale + * is appended to the list if it does not already appear (other + * routines depend on this behaviour). + * If @category_name is %NULL, then LC_ALL is assumed. + * + * Return value: a copy of the list of languages (which you need to free). + **/ +GList * +gnome_vfs_i18n_get_language_list (const gchar *category_name) +{ + GList *list; + + if (!category_name) + category_name = "LC_ALL"; + + if (category_table) + { + list = g_hash_table_lookup (category_table, (const gpointer) category_name); + } + else + { + category_table = g_hash_table_new (g_str_hash, g_str_equal); + list = NULL; + } + + if (!list) + { + gint c_locale_defined = FALSE; + + const gchar *category_value; + gchar *category_memory, *orig_category_memory; + + category_value = guess_category_value (category_name); + if (!category_value) + category_value = "C"; + orig_category_memory = category_memory = + g_malloc (strlen (category_value)+1); + + while (category_value[0] != '\0') + { + while ((category_value[0] != '\0') && (category_value[0] == ':')) + ++category_value; + + if (category_value[0] != '\0') + { + char *cp = category_memory; + + while ((category_value[0] != '\0') && (category_value[0] != ':')) + *category_memory++ = *category_value++; + + category_memory[0] = '\0'; + category_memory++; + + cp = unalias_lang (cp); + + if (strcmp (cp, "C") == 0) + c_locale_defined = TRUE; + + list = g_list_concat (list, compute_locale_variants (cp)); + } + } + + g_free (orig_category_memory); + + if (!c_locale_defined) + list= g_list_append (list, "C"); + + g_hash_table_insert (category_table, (gpointer) category_name, list); + } + + return g_list_copy (list); +} diff --git a/libgnomevfs/gnome-vfs-i18n.h b/libgnomevfs/gnome-vfs-i18n.h new file mode 100644 index 0000000..9986810 --- /dev/null +++ b/libgnomevfs/gnome-vfs-i18n.h @@ -0,0 +1,25 @@ +#ifndef GNOME_VFS_I18N_H +#define GNOME_VFS_I18N_H + +/* The i18n defines */ +#ifdef ENABLE_NLS +# include +# undef _ +# define _(String) dgettext (GETTEXT_PACKAGE, String) +# ifdef gettext_noop +# define N_(String) gettext_noop (String) +# else +# define N_(String) (String) +# endif +#else +/* Stubs that do something close enough. */ +# define textdomain(String) (String) +# define gettext(String) (String) +# define dgettext(Domain,Message) (Message) +# define dcgettext(Domain,Message,Type) (Message) +# define bindtextdomain(Domain,Directory) (Domain) +# define _(String) (String) +# define N_(String) (String) +#endif + +#endif diff --git a/libgnomevfs/gnome-vfs-inet-connection.c b/libgnomevfs/gnome-vfs-inet-connection.c new file mode 100644 index 0000000..8596a69 --- /dev/null +++ b/libgnomevfs/gnome-vfs-inet-connection.c @@ -0,0 +1,337 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-inet-connection.c - Functions for creating and destroying Internet + connections. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli */ + +#include +#include "gnome-vfs-inet-connection.h" +#include "gnome-vfs-private-utils.h" + +#include +#include +#include +#include +/* Keep above the network includes for FreeBSD. */ +#include +#include +#include +#include +#include +#include + +extern int h_errno; + +struct GnomeVFSInetConnection { +#ifdef ENABLE_IPV6 + struct sockaddr_in6 addr6; +#endif + struct sockaddr_in addr; + guint sock; + guint socklen; +}; + +/** + * gnome_vfs_inet_connection_create: + * @connection_return: pointer to a GnomeVFSInetConnection, which will + * contain an allocated GnomeVFSInetConnection object on return. + * @host_name: string indicating the host to establish an internet connection with + * @host_port: the port number to connect to + * @cancellation: handle allowing cancellation of the operation + * + * Creates a connection at @handle_return to @host_name using + * port @port. + * + * Return value: GnomeVFSResult indicating the success of the operation + **/ +GnomeVFSResult +gnome_vfs_inet_connection_create (GnomeVFSInetConnection **connection_return, + const gchar *host_name, + guint host_port, + GnomeVFSCancellation *cancellation) +{ + GnomeVFSInetConnection *new; +#ifdef ENABLE_IPV6 + struct addrinfo hints, *result, *res; + int ret; +#endif + struct hostent *host_info; + struct sockaddr_in addr; + gint sock; + + g_return_val_if_fail (connection_return != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail (host_name != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail (host_port != 0, GNOME_VFS_ERROR_BAD_PARAMETERS); + +#ifdef ENABLE_IPV6 + if (_gnome_vfs_have_ipv6 ()) { + result = NULL; + ret = 0; + sock = 0; + + memset (&hints, 0, sizeof (hints)); + hints.ai_socktype = SOCK_STREAM; + + if (getaddrinfo (host_name, NULL, &hints, &result) != 0) { + return GNOME_VFS_ERROR_HOST_NOT_FOUND; + } + + if (gnome_vfs_cancellation_check (cancellation)) { + return GNOME_VFS_ERROR_CANCELLED; + } + + /*For selecting a valid IP of the List*/ + for (res = result; res; res = res->ai_next) { + + if (res->ai_family != AF_INET && res->ai_family != AF_INET6) { + continue; + } + + sock = socket (res->ai_family, SOCK_STREAM, 0); + if (sock < 0) { + continue; + } + + if (res->ai_family == AF_INET) { + ((struct sockaddr_in *)res->ai_addr)->sin_port = htons (host_port); + } + + if (res->ai_family == AF_INET6) { + ((struct sockaddr_in6 *)res->ai_addr)->sin6_port = htons (host_port); + } + + ret = connect (sock, res->ai_addr, res->ai_addrlen); + if (ret == 0) { + break; + } + + close (sock); + } + + if (!res) { + freeaddrinfo (result); + + if (sock < 0 || ret < 0) { + /*Error in connection or socket creation.*/ + return gnome_vfs_result_from_errno (); + } else { + /*Error: No IPv4 or IPv6 address.*/ + return GNOME_VFS_ERROR_HOST_NOT_FOUND; + } + } + + new = g_new (GnomeVFSInetConnection, 1); + + if (res->ai_family == AF_INET) { + memcpy (&new->addr, res->ai_addr, res->ai_addrlen); + } + + if (res->ai_family == AF_INET6) { + memcpy (&new->addr6, res->ai_addr, res->ai_addrlen); + } + + new->socklen = res->ai_addrlen; + new->sock = sock; + freeaddrinfo (result); + } + else +#endif + { + sock = socket (PF_INET, SOCK_STREAM, 0); + if (sock < 0) { + return gnome_vfs_result_from_errno (); + } + + host_info = gethostbyname (host_name); + if (gnome_vfs_cancellation_check (cancellation)) { + return GNOME_VFS_ERROR_CANCELLED; + } + + if (host_info == NULL) { + return gnome_vfs_result_from_h_errno (); + } + + addr.sin_family = host_info->h_addrtype; + addr.sin_addr = * (struct in_addr *) host_info->h_addr; + addr.sin_port = htons (host_port); + + if (connect (sock, (struct sockaddr *) &addr, sizeof (addr)) < 0) { + return gnome_vfs_result_from_errno (); + } + + new = g_new (GnomeVFSInetConnection, 1); + memcpy (&new->addr, &addr, sizeof (addr)); + new->socklen = sizeof(addr); + new->sock = sock; + + } + *connection_return = new; + return GNOME_VFS_OK; +} + + +/** + * gnome_vfs_inet_connection_destroy: + * @connection: connection to destroy + * @cancellation: handle for cancelling the operation + * + * Closes/Destroys @connection. + **/ +void +gnome_vfs_inet_connection_destroy (GnomeVFSInetConnection *connection, + GnomeVFSCancellation *cancellation) +{ + g_return_if_fail (connection != NULL); + + close (connection->sock); + g_free (connection); +} + +/** + * gnome_vfs_inet_connection_close: + * @connection: connection to close + * + * Closes @connection, freeing all used resources. + **/ +static void +gnome_vfs_inet_connection_close (GnomeVFSInetConnection *connection) +{ + gnome_vfs_inet_connection_destroy (connection, NULL); +} + +/** + * gnome_vfs_inet_connection_get_fd: + * @connection: connection to get the file descriptor from + * + * Retrieve the UNIX file descriptor corresponding to @connection. + * + * Return value: file descriptor + **/ +gint +gnome_vfs_inet_connection_get_fd (GnomeVFSInetConnection *connection) +{ + g_return_val_if_fail (connection != NULL, -1); + return connection->sock; +} + +/* SocketImpl for InetConnections */ + +/** + * gnome_vfs_inet_connection_read: + * @connection: connection to read data from + * @buffer: allocated buffer of at least @bytes bytes to be read into + * @bytes: number of bytes to read from @socket into @buffer + * @bytes_read: pointer to a GnomeVFSFileSize, will contain + * the number of bytes actually read from the socket on return. + * + * Read @bytes bytes of data from @connection into @buffer. + * + * Return value: GnomeVFSResult indicating the success of the operation + **/ +static GnomeVFSResult +gnome_vfs_inet_connection_read (GnomeVFSInetConnection *connection, + gpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_read) +{ + gint read_val; + + do { + read_val = read (connection->sock, buffer, bytes); + } while (read_val == -1 && errno == EINTR); + + if (read_val == -1) { + *bytes_read = 0; + return gnome_vfs_result_from_errno (); + } else { + *bytes_read = read_val; + } + + return bytes_read == 0 ? GNOME_VFS_ERROR_EOF : GNOME_VFS_OK; +} + +/** + * gnome_vfs_inet_connection_write: + * @connection: connection to write data to + * @buffer: data to write to the connection + * @bytes: number of bytes from @buffer to write to @socket + * @bytes_written: pointer to a GnomeVFSFileSize, will contain + * the number of bytes actually written to the connection on return. + * + * Write @bytes bytes of data from @buffer to @connection. + * + * Return value: GnomeVFSResult indicating the success of the operation + **/ +static GnomeVFSResult +gnome_vfs_inet_connection_write (GnomeVFSInetConnection *connection, + gconstpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_written) +{ + gint write_val; + + do { + write_val = write (connection->sock, buffer, bytes); + } while (write_val == -1 && errno == EINTR); + + if (write_val == -1) { + *bytes_written = 0; + return gnome_vfs_result_from_errno (); + } else { + *bytes_written = write_val; + return GNOME_VFS_OK; + } +} + +static GnomeVFSSocketImpl inet_connection_socket_impl = { + (GnomeVFSSocketReadFunc)gnome_vfs_inet_connection_read, + (GnomeVFSSocketWriteFunc)gnome_vfs_inet_connection_write, + (GnomeVFSSocketCloseFunc)gnome_vfs_inet_connection_close +}; + +/** + * gnome_vfs_inet_connection_to_socket: + * @connection: connection to convert to wrapper in a GnomeVFSSocket + * + * Wrapper @connection inside a standard GnomeVFSSocket for convenience. + * + * Return value: a newly created GnomeVFSSocket around @connection. + **/ +GnomeVFSSocket * +gnome_vfs_inet_connection_to_socket (GnomeVFSInetConnection *connection) +{ + return gnome_vfs_socket_new (&inet_connection_socket_impl, connection); +} + +/** + * gnome_vfs_inet_connection_to_socket_buffer: + * @connection: connection to convert to wrapper in a GnomeVFSSocketBuffer + * + * Wrapper @connection inside a standard GnomeVFSSocketBuffer for convenience. + * + * Return value: a newly created GnomeVFSSocketBuffer around @connection. + **/ +GnomeVFSSocketBuffer * +gnome_vfs_inet_connection_to_socket_buffer (GnomeVFSInetConnection *connection) +{ + GnomeVFSSocket *socket; + socket = gnome_vfs_inet_connection_to_socket (connection); + return gnome_vfs_socket_buffer_new (socket); +} diff --git a/libgnomevfs/gnome-vfs-inet-connection.h b/libgnomevfs/gnome-vfs-inet-connection.h new file mode 100644 index 0000000..ec334f8 --- /dev/null +++ b/libgnomevfs/gnome-vfs-inet-connection.h @@ -0,0 +1,61 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-inet-connection.h - Functions for creating and destroying Internet + connections. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli */ + +#ifndef GNOME_VFS_INET_CONNECTION_H +#define GNOME_VFS_INET_CONNECTION_H + +#include +#include +#include + +G_BEGIN_DECLS + +typedef struct GnomeVFSInetConnection GnomeVFSInetConnection; + +GnomeVFSResult gnome_vfs_inet_connection_create + (GnomeVFSInetConnection **connection_return, + const gchar *host_name, + guint host_port, + GnomeVFSCancellation *cancellation); + +/* free the connection structure and close the socket */ +void gnome_vfs_inet_connection_destroy + (GnomeVFSInetConnection *connection, + GnomeVFSCancellation *cancellation); + +/* free the connection structure without closing the socket */ +void gnome_vfs_inet_connection_free + (GnomeVFSInetConnection *connection, + GnomeVFSCancellation *cancellation); + +GnomeVFSSocket * gnome_vfs_inet_connection_to_socket + (GnomeVFSInetConnection *connection); + +GnomeVFSSocketBuffer *gnome_vfs_inet_connection_to_socket_buffer + (GnomeVFSInetConnection *connection); + +int gnome_vfs_inet_connection_get_fd (GnomeVFSInetConnection *connection); + +G_END_DECLS + +#endif /* GNOME_VFS_INET_CONNECTION_H */ diff --git a/libgnomevfs/gnome-vfs-init.c b/libgnomevfs/gnome-vfs-init.c new file mode 100644 index 0000000..b68c458 --- /dev/null +++ b/libgnomevfs/gnome-vfs-init.c @@ -0,0 +1,224 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-init.c - Initialization for the GNOME Virtual File System. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli +*/ + +#include +#include "gnome-vfs-init.h" + +#include "gnome-vfs-ssl-private.h" +#include "gnome-vfs-mime.h" + +#include "gnome-vfs-configuration.h" +#include "gnome-vfs-i18n.h" +#include "gnome-vfs-method.h" +#include "gnome-vfs-process.h" +#include "gnome-vfs-utils.h" + +#include "gnome-vfs-async-job-map.h" +#include "gnome-vfs-thread-pool.h" +#include "gnome-vfs-job-queue.h" + +#include +#include +#include +#include +#include +#include +#include + +static gboolean vfs_already_initialized = FALSE; +G_LOCK_DEFINE_STATIC (vfs_already_initialized); + +static GPrivate * private_is_primary_thread; + +static gboolean +ensure_dot_gnome_exists (void) +{ + gboolean retval = TRUE; + gchar *dirname; + + dirname = g_build_filename (g_get_home_dir (), ".gnome", NULL); + + if (!g_file_test (dirname, G_FILE_TEST_EXISTS)) { + if (mkdir (dirname, S_IRWXU) != 0) { + g_warning ("Unable to create ~/.gnome directory: %s", + g_strerror (errno)); + retval = FALSE; + } + } else if (!g_file_test (dirname, G_FILE_TEST_IS_DIR)) { + g_warning ("Error: ~/.gnome must be a directory."); + retval = FALSE; + } + + g_free (dirname); + return retval; +} + +static void +gnome_vfs_pthread_init (void) +{ + private_is_primary_thread = g_private_new (NULL); + g_private_set (private_is_primary_thread, GUINT_TO_POINTER (1)); + + _gnome_vfs_module_callback_private_init (); + + _gnome_vfs_async_job_map_init (); + _gnome_vfs_thread_pool_init (); + _gnome_vfs_job_queue_init (); +} + +/** + * gnome_vfs_init: + * + * If GnomeVFS is not already initialized, initialize it. This must be + * called prior to performing any other GnomeVFS operations, and may + * be called multiple times without error. + * + * Return value: %TRUE if GnomeVFS is successfully initialized (or was + * already initialized) + **/ +gboolean +gnome_vfs_init (void) +{ + gboolean retval; + char *bogus_argv[2] = { "dummy", NULL }; + + if (!ensure_dot_gnome_exists ()) { + return FALSE; + } + + if (!g_thread_supported ()) + g_thread_init (NULL); + + G_LOCK (vfs_already_initialized); + + if (!vfs_already_initialized) { +#ifdef ENABLE_NLS + bindtextdomain (GETTEXT_PACKAGE, GNOMEVFS_LOCALEDIR); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); +#endif + gnome_vfs_pthread_init (); + + if (bonobo_activation_orb_get() == NULL) { + bonobo_activation_init (0, bogus_argv); + } + + _gnome_vfs_ssl_init (); + + retval = gnome_vfs_method_init (); + + if (retval) { + retval = _gnome_vfs_process_init (); + } + if (retval) { + retval = _gnome_vfs_configuration_init (); + } + if (retval) { + signal (SIGPIPE, SIG_IGN); + } + } else { + retval = TRUE; /* Who cares after all. */ + } + + vfs_already_initialized = TRUE; + G_UNLOCK (vfs_already_initialized); + + return retval; +} + +/** + * gnome_vfs_initialized: + * + * Detects if GnomeVFS has already been initialized (GnomeVFS must be + * initialized prior to using any methods or operations). + * + * Return value: %TRUE if GnomeVFS has already been initialized + **/ +gboolean +gnome_vfs_initialized (void) +{ + gboolean out; + + G_LOCK (vfs_already_initialized); + out = vfs_already_initialized; + G_UNLOCK (vfs_already_initialized); + return out; +} + +/** + * gnome_vfs_shutdown: + * + * Cease all active GnomeVFS operations and unload the MIME + * database from memory. + * + **/ +void +gnome_vfs_shutdown (void) +{ + _gnome_vfs_thread_backend_shutdown (); + gnome_vfs_mime_shutdown (); +} + +void +gnome_vfs_loadinit (gpointer app, gpointer modinfo) +{ +} + +void +gnome_vfs_preinit (gpointer app, gpointer modinfo) +{ +} + +void +gnome_vfs_postinit (gpointer app, gpointer modinfo) +{ + G_LOCK (vfs_already_initialized); + + gnome_vfs_pthread_init (); + + gnome_vfs_method_init (); + _gnome_vfs_process_init (); + _gnome_vfs_configuration_init (); + + signal (SIGPIPE, SIG_IGN); + + vfs_already_initialized = TRUE; + G_UNLOCK (vfs_already_initialized); +} + +/** + * gnome_vfs_is_primary_thread: + * + * Check if the current thread is the thread with the main glib event loop. + * + * Return value: %TRUE if the current thread is the thread with the + * main glib event loop + **/ +gboolean +gnome_vfs_is_primary_thread (void) +{ + if (g_thread_supported()) { + return GPOINTER_TO_UINT(g_private_get (private_is_primary_thread)) == 1; + } else { + return TRUE; + } +} diff --git a/libgnomevfs/gnome-vfs-init.h b/libgnomevfs/gnome-vfs-init.h new file mode 100644 index 0000000..ec505f9 --- /dev/null +++ b/libgnomevfs/gnome-vfs-init.h @@ -0,0 +1,47 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-init.h - Initialization for the GNOME Virtual File System. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli +*/ + +#ifndef GNOME_VFS_INIT_H +#define GNOME_VFS_INIT_H + +#include + +G_BEGIN_DECLS + +gboolean gnome_vfs_init (void); +gboolean gnome_vfs_initialized (void); +void gnome_vfs_shutdown (void); + +#ifndef GNOME_VFS_DISABLE_DEPRECATED +/* Stuff for use in a GnomeModuleInfo */ +void gnome_vfs_loadinit (gpointer app, + gpointer modinfo); +void gnome_vfs_preinit (gpointer app, + gpointer modinfo); +void gnome_vfs_postinit (gpointer app, + gpointer modinfo); +#endif + +G_END_DECLS + +#endif diff --git a/libgnomevfs/gnome-vfs-job-limit.h b/libgnomevfs/gnome-vfs-job-limit.h new file mode 100644 index 0000000..45a4565 --- /dev/null +++ b/libgnomevfs/gnome-vfs-job-limit.h @@ -0,0 +1,32 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* gnome-vfs-job-limit.h - Job queue limit manipulation for asynchronous + operations of the GNOME Virtual File System (version for POSIX threads). + + Copyright (C) 2001 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Laszlo Peter +*/ + +#ifndef GNOME_VFS_JOB_LIMIT_H +#define GNOME_VFS_JOB_LIMIT_H + +void gnome_vfs_async_set_job_limit (int limit); +int gnome_vfs_async_get_job_limit (void); + +#endif /* GNOME_VFS_JOB_LIMIT_H */ diff --git a/libgnomevfs/gnome-vfs-job-queue.c b/libgnomevfs/gnome-vfs-job-queue.c new file mode 100644 index 0000000..d16c6a8 --- /dev/null +++ b/libgnomevfs/gnome-vfs-job-queue.c @@ -0,0 +1,369 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-job-queue.c - Job queue for asynchronous GnomeVFSJobs + (version for POSIX threads). + + Copyright (C) 2001 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: László Péter */ + +#include +#include "gnome-vfs-job-queue.h" +#include "gnome-vfs-job-slave.h" +#include + +#include +#include + +#undef QUEUE_DEBUG + +#ifdef QUEUE_DEBUG +#define Q_DEBUG(x) g_print x +#else +#define Q_DEBUG(x) +#endif + +/* See the comment at job_can_start () for + an explanation of the following macros */ +#ifndef DEFAULT_THREAD_COUNT_LIMIT +#define DEFAULT_THREAD_COUNT_LIMIT 10 +#endif + +#define LIMIT_FUNCTION_LOWER_BOUND 2 /* must NOT be more than DEFAULT_THREAD_COUNT_LIMIT */ +#define LIMIT_FUNCTION_SPEED 7 /* must be more than 0 */ + +#if LIMIT_FUNCTION_LOWER_BOUND > DEFAULT_THREAD_COUNT_LIMIT +#error LIMIT_FUNCTION_LOWER_BOUND must not be more than DEFAULT_THREAD_COUNT_LIMIT +#endif + +#if LIMIT_FUNCTION_SPEED <= 0 +#error LIMIT_FUNCTION_SPEED must be more than 0 +#endif + +/* The maximum number of threads to use for async ops */ +static int thread_count_limit; + +/* This is the maximum number of threads reserved for higher priority jobs */ +static float max_decrease; + +typedef GTree JobQueueType; + +/* This mutex protects these */ +static GStaticMutex job_queue_lock = G_STATIC_MUTEX_INIT; +static JobQueueType *job_queue; +static int running_job_count; +static int job_id; +#ifdef QUEUE_DEBUG + static int job_queue_length; +#endif +/* end mutex guard */ + +typedef struct JobQueueKey { + int job_id; + int priority; +} JobQueueKey; + +static int +key_compare (gconstpointer cast_to_key1, gconstpointer cast_to_key2, gpointer user_data) +{ + JobQueueKey *key1 = (JobQueueKey *)cast_to_key1; + JobQueueKey *key2 = (JobQueueKey *)cast_to_key2; + + /* Lower priority job comes first */ + if (key1->priority > key2->priority) { + return 1; + } + + if (key1->priority < key2->priority) { + return -1; + } + + /* If the 2 priorities are the same then the + job with the lower job_id comes first. + + job_ids are positive so this won't overflow. + */ + return key1->job_id - key2->job_id; +} + +static void +value_destroy (gpointer cast_to_job) +{ + _gnome_vfs_job_destroy ((GnomeVFSJob *)cast_to_job); +} + +static JobQueueType * +job_queue_new (void) +{ + return g_tree_new_full (key_compare, NULL, g_free, value_destroy); +} + +static void +job_queue_destroy (void) +{ + g_tree_destroy (job_queue); + job_queue = NULL; +} + +static void +job_queue_add (GnomeVFSJob *job) +{ + JobQueueKey *key = g_new (JobQueueKey, 1); + key->job_id = ++job_id; + key->priority = job->priority; + + g_tree_insert (job_queue, key, job); +#ifdef QUEUE_DEBUG + job_queue_length++; +#endif +} + +static int +find_first_value (gpointer key, gpointer value, gpointer data) +{ + *((GnomeVFSJob **)data) = value; + return TRUE; +} + +static GnomeVFSJob * +job_queue_get_first (void) +{ + GnomeVFSJob *job = NULL; + + if (job_queue) { + g_tree_foreach (job_queue, find_first_value, &job); + } + + return job; +} + +static int +find_first_key (gpointer key, gpointer value, gpointer data) +{ + *((JobQueueKey **)data) = key; + return TRUE; +} + +static void +job_queue_delete_first (void) +{ + JobQueueKey *key = NULL; + + g_tree_foreach (job_queue, find_first_key, &key); + g_tree_steal (job_queue, key); + + g_free (key); +#ifdef QUEUE_DEBUG + job_queue_length--; +#endif +} + +void +_gnome_vfs_job_queue_init (void) +{ + static gboolean queue_initialized = FALSE; + + if (queue_initialized != TRUE) { + Q_DEBUG (("initializing the job queue (thread limit: %d)\n", DEFAULT_THREAD_COUNT_LIMIT)); + thread_count_limit = DEFAULT_THREAD_COUNT_LIMIT; + max_decrease = (float)thread_count_limit - LIMIT_FUNCTION_LOWER_BOUND; + job_queue = job_queue_new (); + queue_initialized = TRUE; + } +} + +/* This function implements a scheduling policy where a certain number + of threads is reserved for high priority jobs so they can start + immediately if needed. The lower the priority of the running jobs + the more threads are reserved. So the actual limit on running jobs + is a function of the priority of the job to be started. + This function converges to LIMIT_FUNCTION_LOWER_BOUND (i.e. this + will be the limit belonging to the lowest priority jobs.) + The speed of convergence is determined by LIMIT_FUNCTION_SPEED. + For negative priority jobs the limit equals to thread_count_limit. + + Note that thread_count_limit can be queried/set runtime using the + gnome_vfs_async_job_{get,set}_limit functions. + + The formula is as follows: + + max_decrease = thread_count_limit - LIMIT_FUNCTION_LOWER_BOUND + + This is the maximum difference between the limit function and the + thread_count_limit. + + max_decrease * p + max jobs = thread_count_limit - floor (--------------------------) + LIMIT_FUNCTION_SPEED + p + + This table shows some limits belonging to the default parameters: + + priority of the | max number + job to start | of jobs + -----------------+----------- + <1 | 10 + 1 | 9 + 2 | 9 + 3 | 8 + 5 | 7 + 10 | 6 + 20 | 5 + 50 | 3 + 1000 | 3 + + For example a job with a priority of 3 will NOT be started if + there are at least 8 jobs already running. +*/ +static gboolean +job_can_start (int priority) +{ + int transformed_priority; + int actual_limit; + + /* Move the highest priority to the zero point */ + transformed_priority = priority + GNOME_VFS_PRIORITY_MIN; + + if (running_job_count >= thread_count_limit) { + /* Max number of jobs are already running */ + return FALSE; + } else if (transformed_priority >= 0) { + /* Let's not allow low (i.e. positive) priority jobs to use up all the threads. + We reserve some threads for higher priority jobs. + The lower the priority to more threads are reserved. + + The actual limit should the the thread count limit less a proportion + of the maximum decrease. + */ + + actual_limit = thread_count_limit - (int)(max_decrease * transformed_priority / + (LIMIT_FUNCTION_SPEED + transformed_priority)); + + if (actual_limit <= running_job_count) { + return FALSE; + } + } + return TRUE; +} + +void +_gnome_vfs_job_queue_run (void) +{ + GnomeVFSJob *job_to_run; + + g_static_mutex_lock (&job_queue_lock); + + running_job_count--; + Q_DEBUG (("job finished;\t\t\t\t %d jobs running, %d waiting\n", + running_job_count, + job_queue_length)); + + job_to_run = job_queue_get_first (); + if (job_to_run != NULL) { + /* The queue is not empty */ + if (job_can_start (job_to_run->priority)) { + running_job_count++; + job_queue_delete_first (); + Q_DEBUG (("taking a %2d priority job from the queue;" + " %d jobs running, %d waiting\n", + job_to_run->priority, + running_job_count, + job_queue_length)); + g_static_mutex_unlock (&job_queue_lock); + _gnome_vfs_job_create_slave (job_to_run); + } else { + g_static_mutex_unlock (&job_queue_lock); + Q_DEBUG (("waiting job is too low priority (%2d) to start;" + " %d jobs running, %d waiting\n", + job_to_run->priority, + running_job_count, + job_queue_length)); + } + } else { + g_static_mutex_unlock (&job_queue_lock); + Q_DEBUG (("the queue is empty;\t\t\t %d jobs running\n", running_job_count)); + } +} + +gboolean +_gnome_vfs_job_schedule (GnomeVFSJob *job) +{ + g_static_mutex_lock (&job_queue_lock); + if (!job_can_start (job->priority)) { + job_queue_add (job); + Q_DEBUG (("adding a %2d priority job to the queue;" + "\t %d jobs running, %d waiting\n", + job->priority, + running_job_count, + job_queue_length)); + g_static_mutex_unlock (&job_queue_lock); + } else { + running_job_count++; + Q_DEBUG (("starting a %2d priority job;\t\t %d jobs running, %d waiting\n", + job->priority, + running_job_count, + job_queue_length)); + g_static_mutex_unlock (&job_queue_lock); + _gnome_vfs_job_create_slave (job); + } + return TRUE; +} + +/** + * gnome_vfs_async_set_job_limit: + * @limit: maximuum number of allowable threads + * + * Restrict the number of worker threads used by Async operations + * to @limit. + **/ +void +gnome_vfs_async_set_job_limit (int limit) +{ + if (limit < LIMIT_FUNCTION_LOWER_BOUND) { + g_warning ("Attempt to set the thread_count_limit below %d", + LIMIT_FUNCTION_LOWER_BOUND); + return; + } + g_static_mutex_lock (&job_queue_lock); + thread_count_limit = limit; + max_decrease = (float)thread_count_limit - LIMIT_FUNCTION_LOWER_BOUND; + Q_DEBUG (("changing the thread count limit to %d\n", limit)); + g_static_mutex_unlock (&job_queue_lock); +} + +/** + * gnome_vfs_async_get_job_limit: + * + * Get the current maximuum allowable number of + * worker threads for Asynch operations. + * + * Return value: current maximuum number of threads + **/ +int +gnome_vfs_async_get_job_limit (void) +{ + return thread_count_limit; +} + +void +_gnome_vfs_job_queue_shutdown (void) +{ + g_static_mutex_lock (&job_queue_lock); + + job_queue_destroy (); + + g_static_mutex_unlock (&job_queue_lock); +} diff --git a/libgnomevfs/gnome-vfs-job-queue.h b/libgnomevfs/gnome-vfs-job-queue.h new file mode 100644 index 0000000..9b9742a --- /dev/null +++ b/libgnomevfs/gnome-vfs-job-queue.h @@ -0,0 +1,36 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* gnome-vfs-job-queue.h - Job queue for asynchronous operation of the GNOME + Virtual File System (version for POSIX threads). + + Copyright (C) 2001 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: László Péter +*/ + +#ifndef GNOME_VFS_JOB_QUEUE_H +#define GNOME_VFS_JOB_QUEUE_H + +#include "gnome-vfs-job.h" + +void _gnome_vfs_job_queue_init (void); +void _gnome_vfs_job_queue_shutdown (void); +gboolean _gnome_vfs_job_schedule (GnomeVFSJob *job); +void _gnome_vfs_job_queue_run (void); + +#endif /* GNOME_VFS_JOB_QUEUE_H */ diff --git a/libgnomevfs/gnome-vfs-job-slave.c b/libgnomevfs/gnome-vfs-job-slave.c new file mode 100644 index 0000000..d6abc06 --- /dev/null +++ b/libgnomevfs/gnome-vfs-job-slave.c @@ -0,0 +1,149 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-job-slave.c - Thread for asynchronous GnomeVFSJobs + (version for POSIX threads). + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli */ + +#include +#include "gnome-vfs-job-slave.h" + +#include "gnome-vfs-async-job-map.h" +#include "gnome-vfs-thread-pool.h" +#include "gnome-vfs-job-queue.h" +#include +#include + +static volatile gboolean gnome_vfs_quitting = FALSE; +static volatile gboolean gnome_vfs_done_quitting = FALSE; + + +static void * +thread_routine (void *data) +{ + guint id; + GnomeVFSJob *job; + GnomeVFSAsyncHandle *job_handle; + gboolean complete; + + job_handle = (GnomeVFSAsyncHandle *) data; + + id = GPOINTER_TO_UINT (job_handle); + /* job map must always be locked before the job_lock + * if both locks are needed */ + _gnome_vfs_async_job_map_lock (); + + job = _gnome_vfs_async_job_map_get_job (job_handle); + + if (job == NULL) { + JOB_DEBUG (("job already dead, bail %u", id)); + _gnome_vfs_async_job_map_unlock (); + return NULL; + } + + JOB_DEBUG (("locking job_lock %u", id)); + g_mutex_lock (job->job_lock); + _gnome_vfs_async_job_map_unlock (); + + _gnome_vfs_job_execute (job); + complete = _gnome_vfs_job_complete (job); + + JOB_DEBUG (("Unlocking access lock %u", id)); + g_mutex_unlock (job->job_lock); + + if (complete) { + _gnome_vfs_async_job_map_lock (); + JOB_DEBUG (("job %u done, removing from map and destroying", id)); + _gnome_vfs_async_job_completed (job_handle); + _gnome_vfs_job_destroy (job); + _gnome_vfs_async_job_map_unlock (); + } + + return NULL; +} + +gboolean +_gnome_vfs_job_create_slave (GnomeVFSJob *job) +{ + g_return_val_if_fail (job != NULL, FALSE); + + if (gnome_vfs_quitting) { + g_warning ("Someone still starting up GnomeVFS async calls after quit."); + } + + if (gnome_vfs_done_quitting) { + /* The application is quitting, we have already returned from + * gnome_vfs_wait_for_slave_threads, we can't start any more threads + * because they would potentially block indefinitely and prevent the + * app from quitting. + */ + return FALSE; + } + + if (_gnome_vfs_thread_create (thread_routine, job->job_handle) != 0) { + g_warning ("Impossible to allocate a new GnomeVFSJob thread."); + + /* thread did not start up, remove the job from the hash table */ + _gnome_vfs_async_job_completed (job->job_handle); + _gnome_vfs_job_destroy (job); + return FALSE; + } + + return TRUE; +} + +void +_gnome_vfs_thread_backend_shutdown (void) +{ + gboolean done; + int count; + + done = FALSE; + + gnome_vfs_quitting = TRUE; + + JOB_DEBUG (("###### shutting down")); + + _gnome_vfs_job_queue_shutdown(); + + for (count = 0; ; count++) { + /* Check if it is OK to quit. Originally we used a + * count of slave threads, but now we use a count of + * outstanding jobs instead to make sure that the job + * is cleanly destroyed. + */ + if (gnome_vfs_job_get_count () == 0) { + done = TRUE; + gnome_vfs_done_quitting = TRUE; + } + + if (done) { + break; + } + + /* Some threads are still trying to quit, wait a bit until they + * are done. + */ + g_main_context_iteration (NULL, FALSE); + usleep (20000); + } + + _gnome_vfs_thread_pool_shutdown (); + _gnome_vfs_async_job_map_shutdown (); +} diff --git a/libgnomevfs/gnome-vfs-job-slave.h b/libgnomevfs/gnome-vfs-job-slave.h new file mode 100644 index 0000000..530eb23 --- /dev/null +++ b/libgnomevfs/gnome-vfs-job-slave.h @@ -0,0 +1,36 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-job-slave.h - Slave thread for asynchronous GnomeVFSJobs + (version for POSIX threads). + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli */ + +#ifndef GNOME_VFS_JOB_SLAVE_H +#define GNOME_VFS_JOB_SLAVE_H + +#include "gnome-vfs-job.h" + +gboolean _gnome_vfs_job_create_slave (GnomeVFSJob *job); + +/* Call this before taking down the idle task in the master thread to + * give pending slave threads a chance to finish cleanly. + */ +void _gnome_vfs_thread_backend_shutdown (void); + +#endif /* GNOME_VFS_JOB_SLAVE_H */ diff --git a/libgnomevfs/gnome-vfs-job.c b/libgnomevfs/gnome-vfs-job.c new file mode 100644 index 0000000..46efa67 --- /dev/null +++ b/libgnomevfs/gnome-vfs-job.c @@ -0,0 +1,1795 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ /* +gnome-vfs-job.c - Jobs for asynchronous operation of the GNOME Virtual File +System (version for POSIX threads). + + Copyright (C) 1999 Free Software Foundation + Copyright (C) 2000 Eazel + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: + Ettore Perazzoli + Pavel Cisler + Darin Adler + + */ + +#include +#include "gnome-vfs-job.h" + +#include "gnome-vfs-async-job-map.h" +#include "gnome-vfs-job-slave.h" +#include "gnome-vfs-job-queue.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static GStaticPrivate job_private = G_STATIC_PRIVATE_INIT; + +#if GNOME_VFS_JOB_DEBUG + +char *job_debug_types[] = { + "open", "open as channel", + "create", "create symbolic link", + "create as channel", "close", + "read", "write", "read write done", + "load directory", "find directory", + "xfer", "get file info", "set file info", + "module callback", "file control", + "**error**" +}; + +/* FIXME bugzilla.eazel.com 1130 + * - this is should use the correct static mutex initialization macro. + * However glibconfig.h is broken and the supplied macro gives a warning. + * Since this id debug only, just use what the macro should be here. + * even though it is not portable. + */ +GStaticMutex debug_mutex = G_STATIC_MUTEX_INIT; +#endif + +static int job_count = 0; + +static void gnome_vfs_op_destroy (GnomeVFSOp *op); +static void _gnome_vfs_job_destroy_notify_result (GnomeVFSNotifyResult *notify_result); +static gboolean dispatch_job_callback (gpointer data); +static gboolean dispatch_sync_job_callback (gpointer data); + +static void clear_current_job (void); +static void set_current_job (GnomeVFSJob *context); + +static void +set_fl (int fd, int flags) +{ + int val; + + val = fcntl (fd, F_GETFL, 0); + if (val < 0) { + g_warning ("fcntl() F_GETFL failed: %s", strerror (errno)); + return; + } + + val |= flags; + + val = fcntl (fd, F_SETFL, val); + if (val < 0) { + g_warning ("fcntl() F_SETFL failed: %s", strerror (errno)); + return; + } +} + +static void +clr_fl (int fd, int flags) +{ + int val; + + val = fcntl (fd, F_GETFL, 0); + if (val < 0) { + g_warning ("fcntl() F_GETFL failed: %s", strerror (errno)); + return; + } + + val &= ~flags; + + val = fcntl (fd, F_SETFL, val); + if (val < 0) { + g_warning ("fcntl() F_SETFL failed: %s", strerror (errno)); + return; + } +} + +/* + * Find out whether or not a given job should be left in + * the job map, preserving it's open VFS handle, since we + * can do more operations on it later. + */ +gboolean +_gnome_vfs_job_complete (GnomeVFSJob *job) +{ + g_assert (job->op != NULL); + + switch (job->op->type) { + case GNOME_VFS_OP_OPEN: + case GNOME_VFS_OP_OPEN_AS_CHANNEL: + case GNOME_VFS_OP_CREATE: + case GNOME_VFS_OP_CREATE_AS_CHANNEL: + case GNOME_VFS_OP_CREATE_SYMBOLIC_LINK: + /* if job got cancelled, no close expected */ + return job->cancelled || job->failed; + + case GNOME_VFS_OP_READ: + case GNOME_VFS_OP_WRITE: + g_assert_not_reached(); + return FALSE; + case GNOME_VFS_OP_READ_WRITE_DONE: + case GNOME_VFS_OP_FILE_CONTROL: + return FALSE; + + default: + return TRUE; + } +} + +/* This notifies the master thread asynchronously, without waiting for an + * acknowledgment. + */ +static void +job_oneway_notify (GnomeVFSJob *job, GnomeVFSNotifyResult *notify_result) +{ + if (_gnome_vfs_async_job_add_callback (job, notify_result)) { + JOB_DEBUG (("job %u, callback %u type '%s'", + GPOINTER_TO_UINT (notify_result->job_handle), + notify_result->callback_id, + JOB_DEBUG_TYPE (job->op->type))); + + g_idle_add (dispatch_job_callback, notify_result); + } else { + JOB_DEBUG (("Barfing on oneway cancel %u (%d) type '%s'", + GPOINTER_TO_UINT (notify_result->job_handle), + job->op->type, JOB_DEBUG_TYPE (job->op->type))); + _gnome_vfs_job_destroy_notify_result (notify_result); + } +} + +/* This notifies the master threads, waiting until it acknowledges the + notification. */ +static void +job_notify (GnomeVFSJob *job, GnomeVFSNotifyResult *notify_result) +{ + if (!_gnome_vfs_async_job_add_callback (job, notify_result)) { + JOB_DEBUG (("Barfing on sync cancel %u (%d)", + GPOINTER_TO_UINT (notify_result->job_handle), + job->op->type)); + _gnome_vfs_job_destroy_notify_result (notify_result); + return; + } + + /* Send the notification. This will wake up the master thread, which + * will in turn signal the notify condition. + */ + g_idle_add (dispatch_sync_job_callback, notify_result); + + JOB_DEBUG (("Wait notify condition %u", GPOINTER_TO_UINT (notify_result->job_handle))); + /* Wait for the notify condition. */ + g_cond_wait (job->notify_ack_condition, job->job_lock); + + JOB_DEBUG (("Got notify ack condition %u", GPOINTER_TO_UINT (notify_result->job_handle))); +} + +static void +dispatch_open_callback (GnomeVFSNotifyResult *notify_result) +{ + (* notify_result->specifics.open.callback) (notify_result->job_handle, + notify_result->specifics.open.result, + notify_result->specifics.open.callback_data); +} + +static void +dispatch_create_callback (GnomeVFSNotifyResult *notify_result) +{ + (* notify_result->specifics.create.callback) (notify_result->job_handle, + notify_result->specifics.create.result, + notify_result->specifics.create.callback_data); +} + +static void +dispatch_open_as_channel_callback (GnomeVFSNotifyResult *notify_result) +{ + (* notify_result->specifics.open_as_channel.callback) (notify_result->job_handle, + notify_result->specifics.open_as_channel.channel, + notify_result->specifics.open_as_channel.result, + notify_result->specifics.open_as_channel.callback_data); +} + +static void +dispatch_create_as_channel_callback (GnomeVFSNotifyResult *notify_result) +{ + (* notify_result->specifics.create_as_channel.callback) (notify_result->job_handle, + notify_result->specifics.create_as_channel.channel, + notify_result->specifics.create_as_channel.result, + notify_result->specifics.create_as_channel.callback_data); +} + +static void +dispatch_close_callback (GnomeVFSNotifyResult *notify_result) +{ + (* notify_result->specifics.close.callback) (notify_result->job_handle, + notify_result->specifics.close.result, + notify_result->specifics.close.callback_data); +} + +static void +dispatch_read_callback (GnomeVFSNotifyResult *notify_result) +{ + (* notify_result->specifics.read.callback) (notify_result->job_handle, + notify_result->specifics.read.result, + notify_result->specifics.read.buffer, + notify_result->specifics.read.num_bytes, + notify_result->specifics.read.bytes_read, + notify_result->specifics.read.callback_data); +} + +static void +dispatch_write_callback (GnomeVFSNotifyResult *notify_result) +{ + (* notify_result->specifics.write.callback) (notify_result->job_handle, + notify_result->specifics.write.result, + notify_result->specifics.write.buffer, + notify_result->specifics.write.num_bytes, + notify_result->specifics.write.bytes_written, + notify_result->specifics.write.callback_data); +} + +static void +dispatch_load_directory_callback (GnomeVFSNotifyResult *notify_result) +{ + (* notify_result->specifics.load_directory.callback) (notify_result->job_handle, + notify_result->specifics.load_directory.result, + notify_result->specifics.load_directory.list, + notify_result->specifics.load_directory.entries_read, + notify_result->specifics.load_directory.callback_data); +} + +static void +dispatch_get_file_info_callback (GnomeVFSNotifyResult *notify_result) +{ + (* notify_result->specifics.get_file_info.callback) (notify_result->job_handle, + notify_result->specifics.get_file_info.result_list, + notify_result->specifics.get_file_info.callback_data); +} + +static void +dispatch_find_directory_callback (GnomeVFSNotifyResult *notify_result) +{ + (* notify_result->specifics.find_directory.callback) (notify_result->job_handle, + notify_result->specifics.find_directory.result_list, + notify_result->specifics.find_directory.callback_data); +} + +static void +dispatch_set_file_info_callback (GnomeVFSNotifyResult *notify_result) +{ + gboolean new_info_is_valid; + + new_info_is_valid = notify_result->specifics.set_file_info.set_file_info_result == GNOME_VFS_OK + && notify_result->specifics.set_file_info.get_file_info_result == GNOME_VFS_OK; + + (* notify_result->specifics.set_file_info.callback) (notify_result->job_handle, + notify_result->specifics.set_file_info.set_file_info_result, + new_info_is_valid ? notify_result->specifics.set_file_info.info : NULL, + notify_result->specifics.set_file_info.callback_data); +} + +static void +dispatch_xfer_callback (GnomeVFSNotifyResult *notify_result, gboolean cancelled) +{ + if (cancelled) { + /* make the xfer operation stop */ + notify_result->specifics.xfer.reply = 0; + return; + } + + notify_result->specifics.xfer.reply = (* notify_result->specifics.xfer.callback) ( + notify_result->job_handle, + notify_result->specifics.xfer.progress_info, + notify_result->specifics.xfer.callback_data); +} + +static void +dispatch_module_callback (GnomeVFSNotifyResult *notify_result) +{ + notify_result->specifics.callback.callback (notify_result->specifics.callback.in, + notify_result->specifics.callback.in_size, + notify_result->specifics.callback.out, + notify_result->specifics.callback.out_size, + notify_result->specifics.callback.user_data, + notify_result->specifics.callback.response, + notify_result->specifics.callback.response_data); +} + +static void +dispatch_file_control_callback (GnomeVFSNotifyResult *notify_result) +{ + notify_result->specifics.file_control.callback (notify_result->job_handle, + notify_result->specifics.file_control.result, + notify_result->specifics.file_control.operation_data, + notify_result->specifics.file_control.callback_data); +} + +static void +empty_close_callback (GnomeVFSAsyncHandle *handle, + GnomeVFSResult result, + gpointer callback_data) +{ +} + +static void +handle_cancelled_open (GnomeVFSJob *job) +{ + /* schedule a silent close to make sure the handle does not leak */ + _gnome_vfs_job_set (job, GNOME_VFS_OP_CLOSE, + (GFunc) empty_close_callback, NULL); + _gnome_vfs_job_go (job); +} + +static void +free_get_file_info_notify_result (GnomeVFSGetFileInfoOpResult *notify_result) +{ + GList *p; + GnomeVFSGetFileInfoResult *result_item; + + for (p = notify_result->result_list; p != NULL; p = p->next) { + result_item = p->data; + + gnome_vfs_uri_unref (result_item->uri); + gnome_vfs_file_info_unref (result_item->file_info); + g_free (result_item); + } + g_list_free (notify_result->result_list); +} + +static void +free_find_directory_notify_result (GnomeVFSFindDirectoryOpResult *notify_result) +{ + GList *p; + GnomeVFSFindDirectoryResult *result_item; + + for (p = notify_result->result_list; p != NULL; p = p->next) { + result_item = p->data; + + if (result_item->uri != NULL) { + gnome_vfs_uri_unref (result_item->uri); + } + g_free (result_item); + } + g_list_free (notify_result->result_list); +} + +static void +_gnome_vfs_job_destroy_notify_result (GnomeVFSNotifyResult *notify_result) +{ + JOB_DEBUG (("%u", notify_result->callback_id)); + + switch (notify_result->type) { + case GNOME_VFS_OP_CLOSE: + case GNOME_VFS_OP_CREATE: + case GNOME_VFS_OP_CREATE_AS_CHANNEL: + case GNOME_VFS_OP_CREATE_SYMBOLIC_LINK: + case GNOME_VFS_OP_WRITE: + case GNOME_VFS_OP_OPEN: + case GNOME_VFS_OP_OPEN_AS_CHANNEL: + case GNOME_VFS_OP_READ: + g_free (notify_result); + break; + + case GNOME_VFS_OP_FILE_CONTROL: + if (notify_result->specifics.file_control.operation_data_destroy_func) { + notify_result->specifics.file_control.operation_data_destroy_func ( + notify_result->specifics.file_control.operation_data); + } + g_free (notify_result); + break; + + case GNOME_VFS_OP_FIND_DIRECTORY: + free_find_directory_notify_result (¬ify_result->specifics.find_directory); + g_free (notify_result); + break; + + case GNOME_VFS_OP_GET_FILE_INFO: + free_get_file_info_notify_result (¬ify_result->specifics.get_file_info); + g_free (notify_result); + break; + + case GNOME_VFS_OP_SET_FILE_INFO: + gnome_vfs_file_info_unref (notify_result->specifics.set_file_info.info); + g_free (notify_result); + break; + + case GNOME_VFS_OP_LOAD_DIRECTORY: + gnome_vfs_file_info_list_free (notify_result->specifics.load_directory.list); + g_free (notify_result); + break; + + case GNOME_VFS_OP_XFER: + /* the XFER result is allocated on the stack */ + break; + + case GNOME_VFS_OP_MODULE_CALLBACK: + /* the MODULE_CALLBACK result is allocated on the stack */ + break; + + default: + g_assert_not_reached (); + break; + } +} + +/* Entry point for sync notification callback */ +static gboolean +dispatch_sync_job_callback (gpointer data) +{ + GnomeVFSNotifyResult *notify_result; + GnomeVFSJob *job; + gboolean valid; + gboolean cancelled; + + notify_result = (GnomeVFSNotifyResult *) data; + + _gnome_vfs_async_job_callback_valid (notify_result->callback_id, &valid, &cancelled); + + /* Even though the notify result is owned by the async thread and persists + * all through the notification, we still keep it in the job map to + * make cancellation easier. + */ + _gnome_vfs_async_job_remove_callback (notify_result->callback_id); + + g_assert (valid); + + switch (notify_result->type) { + case GNOME_VFS_OP_CREATE_AS_CHANNEL: + dispatch_create_as_channel_callback (notify_result); + break; + case GNOME_VFS_OP_OPEN_AS_CHANNEL: + dispatch_open_as_channel_callback (notify_result); + break; + case GNOME_VFS_OP_XFER: + dispatch_xfer_callback (notify_result, cancelled); + break; + case GNOME_VFS_OP_MODULE_CALLBACK: + dispatch_module_callback (notify_result); + break; + default: + g_assert_not_reached (); + break; + } + + _gnome_vfs_async_job_map_lock (); + job = _gnome_vfs_async_job_map_get_job (notify_result->job_handle); + g_mutex_lock (job->job_lock); + _gnome_vfs_async_job_map_unlock (); + + g_assert (job != NULL); + + JOB_DEBUG (("signalling %u", GPOINTER_TO_UINT (notify_result->job_handle))); + + /* Signal the async thread that we are done with the notification. */ + g_cond_signal (job->notify_ack_condition); + g_mutex_unlock (job->job_lock); + + return FALSE; +} + +/* Entry point for async notification callback */ +static gboolean +dispatch_job_callback (gpointer data) + +{ + GnomeVFSNotifyResult *notify_result; + GnomeVFSJob *job; + gboolean valid; + gboolean cancelled; + + notify_result = (GnomeVFSNotifyResult *) data; + + JOB_DEBUG (("%u type '%s'", GPOINTER_TO_UINT (notify_result->job_handle), + JOB_DEBUG_TYPE (notify_result->type))); + + _gnome_vfs_async_job_callback_valid (notify_result->callback_id, &valid, &cancelled); + _gnome_vfs_async_job_remove_callback (notify_result->callback_id); + + if (!valid) { + /* this can happen when gnome vfs is shutting down */ + JOB_DEBUG (("shutting down: callback %u no longer valid", + notify_result->callback_id)); + _gnome_vfs_job_destroy_notify_result (notify_result); + return FALSE; + } + + if (cancelled) { + /* cancel the job in progress */ + JOB_DEBUG (("cancelling job %u %u", + GPOINTER_TO_UINT (notify_result->job_handle), + notify_result->callback_id)); + + _gnome_vfs_async_job_map_lock (); + + job = _gnome_vfs_async_job_map_get_job (notify_result->job_handle); + + if (job != NULL) { + g_mutex_lock (job->job_lock); + + switch (job->op->type) { + case GNOME_VFS_OP_OPEN: + case GNOME_VFS_OP_OPEN_AS_CHANNEL: + case GNOME_VFS_OP_CREATE: + case GNOME_VFS_OP_CREATE_AS_CHANNEL: + case GNOME_VFS_OP_CREATE_SYMBOLIC_LINK: + if (job->handle) { + g_mutex_unlock (job->job_lock); + handle_cancelled_open (job); + JOB_DEBUG (("handle cancel open job %u", + GPOINTER_TO_UINT (notify_result->job_handle))); + break; + } /* else drop through */ + default: + /* Remove job from the job map. */ + _gnome_vfs_async_job_map_remove_job (job); + g_mutex_unlock (job->job_lock); + break; + } + } + + _gnome_vfs_async_job_map_unlock (); + _gnome_vfs_job_destroy_notify_result (notify_result); + return FALSE; + } + + + JOB_DEBUG (("executing callback %u", GPOINTER_TO_UINT (notify_result->job_handle))); + + switch (notify_result->type) { + case GNOME_VFS_OP_CLOSE: + dispatch_close_callback (notify_result); + break; + case GNOME_VFS_OP_CREATE: + dispatch_create_callback (notify_result); + break; + case GNOME_VFS_OP_CREATE_AS_CHANNEL: + dispatch_create_as_channel_callback (notify_result); + break; + case GNOME_VFS_OP_CREATE_SYMBOLIC_LINK: + dispatch_create_callback (notify_result); + break; + case GNOME_VFS_OP_FIND_DIRECTORY: + dispatch_find_directory_callback (notify_result); + break; + case GNOME_VFS_OP_GET_FILE_INFO: + dispatch_get_file_info_callback (notify_result); + break; + case GNOME_VFS_OP_LOAD_DIRECTORY: + dispatch_load_directory_callback (notify_result); + break; + case GNOME_VFS_OP_OPEN: + dispatch_open_callback (notify_result); + break; + case GNOME_VFS_OP_OPEN_AS_CHANNEL: + dispatch_open_as_channel_callback (notify_result); + break; + case GNOME_VFS_OP_READ: + dispatch_read_callback (notify_result); + break; + case GNOME_VFS_OP_SET_FILE_INFO: + dispatch_set_file_info_callback (notify_result); + break; + case GNOME_VFS_OP_WRITE: + dispatch_write_callback (notify_result); + break; + case GNOME_VFS_OP_FILE_CONTROL: + dispatch_file_control_callback (notify_result); + break; + default: + g_assert_not_reached (); + break; + } + + JOB_DEBUG (("dispatch callback - done %u", GPOINTER_TO_UINT (notify_result->job_handle))); + _gnome_vfs_job_destroy_notify_result (notify_result); + + return FALSE; +} + +void +_gnome_vfs_job_set (GnomeVFSJob *job, + GnomeVFSOpType type, + GFunc callback, + gpointer callback_data) +{ + GnomeVFSOp *op; + + op = g_new (GnomeVFSOp, 1); + op->type = type; + op->callback = callback; + op->callback_data = callback_data; + op->context = gnome_vfs_context_new (); + op->stack_info = _gnome_vfs_module_callback_get_stack_info (); + + g_assert (gnome_vfs_context_get_cancellation (op->context) != NULL); + + JOB_DEBUG (("locking access lock %u, op %d", GPOINTER_TO_UINT (job->job_handle), type)); + + g_mutex_lock (job->job_lock); + + gnome_vfs_op_destroy (job->op); + job->op = op; + job->cancelled = FALSE; + + g_mutex_unlock (job->job_lock); + + JOB_DEBUG (("%u op type %d, op %p", GPOINTER_TO_UINT (job->job_handle), + job->op->type, job->op)); +} + +GnomeVFSJob * +_gnome_vfs_job_new (GnomeVFSOpType type, int priority, GFunc callback, gpointer callback_data) +{ + GnomeVFSJob *new_job; + + new_job = g_new0 (GnomeVFSJob, 1); + + new_job->job_lock = g_mutex_new (); + new_job->notify_ack_condition = g_cond_new (); + new_job->priority = priority; + + /* Add the new job into the job hash table. This also assigns + * the job a unique id + */ + _gnome_vfs_async_job_map_add_job (new_job); + _gnome_vfs_job_set (new_job, type, callback, callback_data); + + job_count++; + + return new_job; +} + +void +_gnome_vfs_job_destroy (GnomeVFSJob *job) +{ + JOB_DEBUG (("destroying job %u", GPOINTER_TO_UINT (job->job_handle))); + + gnome_vfs_op_destroy (job->op); + + g_mutex_free (job->job_lock); + g_cond_free (job->notify_ack_condition); + + memset (job, 0xaa, sizeof (GnomeVFSJob)); + + g_free (job); + job_count--; + + JOB_DEBUG (("job %u terminated cleanly", GPOINTER_TO_UINT (job->job_handle))); +} + +int +gnome_vfs_job_get_count (void) +{ + return job_count; +} + +static void +gnome_vfs_op_destroy (GnomeVFSOp *op) +{ + if (op == NULL) { + return; + } + + switch (op->type) { + case GNOME_VFS_OP_CREATE: + if (op->specifics.create.uri != NULL) { + gnome_vfs_uri_unref (op->specifics.create.uri); + } + break; + case GNOME_VFS_OP_CREATE_AS_CHANNEL: + if (op->specifics.create_as_channel.uri != NULL) { + gnome_vfs_uri_unref (op->specifics.create_as_channel.uri); + } + break; + case GNOME_VFS_OP_CREATE_SYMBOLIC_LINK: + gnome_vfs_uri_unref (op->specifics.create_symbolic_link.uri); + g_free (op->specifics.create_symbolic_link.uri_reference); + break; + case GNOME_VFS_OP_FIND_DIRECTORY: + gnome_vfs_uri_list_free (op->specifics.find_directory.uris); + break; + case GNOME_VFS_OP_GET_FILE_INFO: + gnome_vfs_uri_list_free (op->specifics.get_file_info.uris); + break; + case GNOME_VFS_OP_LOAD_DIRECTORY: + if (op->specifics.load_directory.uri != NULL) { + gnome_vfs_uri_unref (op->specifics.load_directory.uri); + } + break; + case GNOME_VFS_OP_OPEN: + if (op->specifics.open.uri != NULL) { + gnome_vfs_uri_unref (op->specifics.open.uri); + } + break; + case GNOME_VFS_OP_OPEN_AS_CHANNEL: + if (op->specifics.open_as_channel.uri != NULL) { + gnome_vfs_uri_unref (op->specifics.open_as_channel.uri); + } + break; + case GNOME_VFS_OP_SET_FILE_INFO: + gnome_vfs_uri_unref (op->specifics.set_file_info.uri); + gnome_vfs_file_info_unref (op->specifics.set_file_info.info); + break; + case GNOME_VFS_OP_XFER: + gnome_vfs_uri_list_free (op->specifics.xfer.source_uri_list); + gnome_vfs_uri_list_free (op->specifics.xfer.target_uri_list); + break; + case GNOME_VFS_OP_READ: + case GNOME_VFS_OP_WRITE: + case GNOME_VFS_OP_CLOSE: + case GNOME_VFS_OP_READ_WRITE_DONE: + break; + case GNOME_VFS_OP_FILE_CONTROL: + g_free (op->specifics.file_control.operation); + break; + default: + g_warning (_("Unknown op type %u"), op->type); + } + + g_assert (gnome_vfs_context_get_cancellation (op->context) != NULL); + + gnome_vfs_context_free (op->context); + _gnome_vfs_module_callback_free_stack_info (op->stack_info); + + g_free (op); +} + +void +_gnome_vfs_job_go (GnomeVFSJob *job) +{ + JOB_DEBUG (("new job %u, op %d, type '%s' unlocking job lock", + GPOINTER_TO_UINT (job->job_handle), job->op->type, + JOB_DEBUG_TYPE (job->op->type))); + + /* Fire up the async job thread. */ + if (!_gnome_vfs_job_schedule (job)) { + g_warning ("Cannot schedule this job."); + _gnome_vfs_job_destroy (job); + return; + } +} + +#define DEFAULT_BUFFER_SIZE 16384 + +static void +serve_channel_read (GnomeVFSHandle *handle, + GIOChannel *channel_in, + GIOChannel *channel_out, + gulong advised_block_size, + GnomeVFSContext *context) +{ + gpointer buffer; + guint filled_bytes_in_buffer; + guint written_bytes_in_buffer; + guint current_buffer_size; + + if (advised_block_size == 0) { + advised_block_size = DEFAULT_BUFFER_SIZE; + } + + current_buffer_size = advised_block_size; + buffer = g_malloc(current_buffer_size); + filled_bytes_in_buffer = 0; + written_bytes_in_buffer = 0; + + while (1) { + GnomeVFSResult result; + GIOStatus io_result; + GnomeVFSFileSize bytes_read; + + restart_toplevel_loop: + + g_assert(filled_bytes_in_buffer <= current_buffer_size); + g_assert(written_bytes_in_buffer == 0); + + result = gnome_vfs_read_cancellable (handle, + (char *) buffer + filled_bytes_in_buffer, + MIN (advised_block_size, (current_buffer_size + - filled_bytes_in_buffer)), + &bytes_read, context); + + if (result == GNOME_VFS_ERROR_INTERRUPTED) { + continue; + } else if (result != GNOME_VFS_OK && result != GNOME_VFS_ERROR_EOF) { + goto end; + } + + filled_bytes_in_buffer += bytes_read; + + if (filled_bytes_in_buffer == 0) { + goto end; + } + + g_assert(written_bytes_in_buffer <= filled_bytes_in_buffer); + + if (gnome_vfs_context_check_cancellation(context)) { + goto end; + } + + while (written_bytes_in_buffer < filled_bytes_in_buffer) { + gsize bytes_written; + + /* channel_out is nonblocking; if we get + EAGAIN (G_IO_STATUS_AGAIN) then we tried to + write but the pipe was full. In this case, we + want to enlarge our buffer and go back to + reading for one iteration, so we can keep + collecting data while the main thread is + busy. */ + + io_result = g_io_channel_write_chars + (channel_out, + (char *) buffer + written_bytes_in_buffer, + filled_bytes_in_buffer - written_bytes_in_buffer, + &bytes_written, NULL); + + written_bytes_in_buffer += bytes_written; + + if (gnome_vfs_context_check_cancellation(context)) { + goto end; + } + + if (io_result == G_IO_STATUS_AGAIN) { + /* if bytes_read == 0 then we reached + EOF so there's no point reading + again. So turn off nonblocking and + do a blocking write next time through. */ + if (bytes_read == 0) { + int fd; + + fd = g_io_channel_unix_get_fd (channel_out); + + clr_fl (fd, O_NONBLOCK); + } else { + if (written_bytes_in_buffer > 0) { + /* Need to shift the unwritten bytes + to the start of the buffer */ + g_memmove(buffer, + (char *) buffer + written_bytes_in_buffer, + filled_bytes_in_buffer - written_bytes_in_buffer); + filled_bytes_in_buffer = + filled_bytes_in_buffer - written_bytes_in_buffer; + + written_bytes_in_buffer = 0; + } + + /* If the buffer is more than half + full, double its size */ + if (filled_bytes_in_buffer * 2 > current_buffer_size) { + current_buffer_size *= 2; + buffer = g_realloc(buffer, current_buffer_size); + } + + /* Leave this loop, start reading again */ + goto restart_toplevel_loop; + + } /* end of else (bytes_read != 0) */ + + } else if (io_result != G_IO_STATUS_NORMAL || bytes_written == 0) { + goto end; + } + } + + g_assert(written_bytes_in_buffer == filled_bytes_in_buffer); + + /* Reset, we wrote everything */ + written_bytes_in_buffer = 0; + filled_bytes_in_buffer = 0; + } + + end: + g_free (buffer); + g_io_channel_shutdown (channel_out, TRUE, NULL); + g_io_channel_unref (channel_out); + g_io_channel_unref (channel_in); +} + +static void +serve_channel_write (GnomeVFSHandle *handle, + GIOChannel *channel_in, + GIOChannel *channel_out, + GnomeVFSContext *context) +{ + gchar buffer[DEFAULT_BUFFER_SIZE]; + guint buffer_size; + + buffer_size = DEFAULT_BUFFER_SIZE; + + while (1) { + GnomeVFSResult result; + GIOStatus io_result; + gsize bytes_read; + gsize bytes_to_write; + GnomeVFSFileSize bytes_written; + gchar *p; + + io_result = g_io_channel_read_chars (channel_in, buffer, buffer_size, + &bytes_read, NULL); + + if (io_result == G_IO_STATUS_AGAIN) + continue; + if (io_result != G_IO_STATUS_NORMAL || bytes_read == 0) + goto end; + + p = buffer; + bytes_to_write = bytes_read; + while (bytes_to_write > 0) { + result = gnome_vfs_write_cancellable (handle, + p, + bytes_to_write, + &bytes_written, + context); + if (result == GNOME_VFS_ERROR_INTERRUPTED) { + continue; + } + + if (result != GNOME_VFS_OK || bytes_written == 0) { + goto end; + } + + p += bytes_written; + bytes_to_write -= bytes_written; + } + } + + end: + g_io_channel_shutdown (channel_in, TRUE, NULL); + g_io_channel_unref (channel_in); + g_io_channel_unref (channel_out); +} + +/* Job execution. This is performed by the slave thread. */ + +static void +execute_open (GnomeVFSJob *job) +{ + GnomeVFSResult result; + GnomeVFSHandle *handle; + GnomeVFSOpenOp *open_op; + GnomeVFSNotifyResult *notify_result; + + open_op = &job->op->specifics.open; + + if (open_op->uri == NULL) { + result = GNOME_VFS_ERROR_INVALID_URI; + } else { + result = gnome_vfs_open_uri_cancellable (&handle, open_op->uri, + open_op->open_mode, + job->op->context); + job->handle = handle; + } + + notify_result = g_new0 (GnomeVFSNotifyResult, 1); + notify_result->job_handle = job->job_handle; + notify_result->type = job->op->type; + notify_result->specifics.open.result = result; + notify_result->specifics.open.callback = (GnomeVFSAsyncOpenCallback) job->op->callback; + notify_result->specifics.open.callback_data = job->op->callback_data; + + if (result != GNOME_VFS_OK) { + /* if the open failed, just drop the job */ + job->failed = TRUE; + } + + job_oneway_notify (job, notify_result); +} + +static void +execute_open_as_channel (GnomeVFSJob *job) +{ + GnomeVFSResult result; + GnomeVFSHandle *handle; + GnomeVFSOpenAsChannelOp *open_as_channel_op; + GnomeVFSOpenMode open_mode; + GIOChannel *channel_in, *channel_out; + gint pipefd[2]; + GnomeVFSNotifyResult *notify_result; + + open_as_channel_op = &job->op->specifics.open_as_channel; + + if (open_as_channel_op->uri == NULL) { + result = GNOME_VFS_ERROR_INVALID_URI; + } else { + result = gnome_vfs_open_uri_cancellable + (&handle, + open_as_channel_op->uri, + open_as_channel_op->open_mode, + job->op->context); + } + + notify_result = g_new0 (GnomeVFSNotifyResult, 1); + notify_result->job_handle = job->job_handle; + notify_result->type = job->op->type; + notify_result->specifics.open_as_channel.result = result; + notify_result->specifics.open_as_channel.callback = + (GnomeVFSAsyncOpenAsChannelCallback) job->op->callback; + notify_result->specifics.open_as_channel.callback_data = job->op->callback_data; + + if (result != GNOME_VFS_OK) { + /* if the open failed, just drop the job */ + job->failed = TRUE; + job_oneway_notify (job, notify_result); + return; + } + + if (pipe (pipefd) < 0) { + g_warning (_("Cannot create pipe for open GIOChannel: %s"), + g_strerror (errno)); + notify_result->specifics.open_as_channel.result = GNOME_VFS_ERROR_INTERNAL; + /* if the open failed, just drop the job */ + job->failed = TRUE; + job_oneway_notify (job, notify_result); + return; + } + + /* Set up the pipe for nonblocking writes, so if the main + * thread is blocking for some reason the slave can keep + * reading data. + */ + set_fl (pipefd[1], O_NONBLOCK); + + channel_in = g_io_channel_unix_new (pipefd[0]); + channel_out = g_io_channel_unix_new (pipefd[1]); + + open_mode = open_as_channel_op->open_mode; + + if (open_mode & GNOME_VFS_OPEN_READ) { + notify_result->specifics.open_as_channel.channel = channel_in; + } else { + notify_result->specifics.open_as_channel.channel = channel_out; + } + + notify_result->specifics.open_as_channel.result = GNOME_VFS_OK; + + job_notify (job, notify_result); + + if (open_mode & GNOME_VFS_OPEN_READ) { + serve_channel_read (handle, channel_in, channel_out, + open_as_channel_op->advised_block_size, + job->op->context); + } else { + serve_channel_write (handle, channel_in, channel_out, + job->op->context); + } +} + +static void +execute_create (GnomeVFSJob *job) +{ + GnomeVFSResult result; + GnomeVFSHandle *handle; + GnomeVFSCreateOp *create_op; + GnomeVFSNotifyResult *notify_result; + + create_op = &job->op->specifics.create; + + if (create_op->uri == NULL) { + result = GNOME_VFS_ERROR_INVALID_URI; + } else { + result = gnome_vfs_create_uri_cancellable + (&handle, + create_op->uri, + create_op->open_mode, + create_op->exclusive, + create_op->perm, + job->op->context); + + job->handle = handle; + } + + notify_result = g_new0 (GnomeVFSNotifyResult, 1); + notify_result->job_handle = job->job_handle; + notify_result->type = job->op->type; + notify_result->specifics.create.result = result; + notify_result->specifics.create.callback = (GnomeVFSAsyncCreateCallback) job->op->callback; + notify_result->specifics.create.callback_data = job->op->callback_data; + + if (result != GNOME_VFS_OK) { + /* if the open failed, just drop the job */ + job->failed = TRUE; + } + + job_oneway_notify (job, notify_result); +} + +static void +execute_create_symbolic_link (GnomeVFSJob *job) +{ + GnomeVFSResult result; + GnomeVFSCreateLinkOp *create_op; + GnomeVFSNotifyResult *notify_result; + + create_op = &job->op->specifics.create_symbolic_link; + + result = gnome_vfs_create_symbolic_link_cancellable + (create_op->uri, + create_op->uri_reference, + job->op->context); + + notify_result = g_new0 (GnomeVFSNotifyResult, 1); + notify_result->job_handle = job->job_handle; + notify_result->type = job->op->type; + notify_result->specifics.create.result = result; + notify_result->specifics.create.callback = (GnomeVFSAsyncCreateCallback) job->op->callback; + notify_result->specifics.create.callback_data = job->op->callback_data; + + if (result != GNOME_VFS_OK) { + /* if the open failed, just drop the job */ + job->failed = TRUE; + } + + job_oneway_notify (job, notify_result); +} + +static void +execute_create_as_channel (GnomeVFSJob *job) +{ + GnomeVFSResult result; + GnomeVFSHandle *handle; + GnomeVFSCreateAsChannelOp *create_as_channel_op; + GIOChannel *channel_in, *channel_out; + gint pipefd[2]; + GnomeVFSNotifyResult *notify_result; + + create_as_channel_op = &job->op->specifics.create_as_channel; + + if (create_as_channel_op->uri == NULL) { + result = GNOME_VFS_ERROR_INVALID_URI; + } else { + result = gnome_vfs_open_uri_cancellable + (&handle, + create_as_channel_op->uri, + create_as_channel_op->open_mode, + job->op->context); + } + + notify_result = g_new0 (GnomeVFSNotifyResult, 1); + notify_result->job_handle = job->job_handle; + notify_result->type = job->op->type; + notify_result->specifics.create_as_channel.result = result; + notify_result->specifics.create_as_channel.callback = (GnomeVFSAsyncCreateAsChannelCallback) job->op->callback; + notify_result->specifics.create_as_channel.callback_data = job->op->callback_data; + + if (result != GNOME_VFS_OK) { + /* if the open failed, just drop the job */ + job->failed = TRUE; + job_oneway_notify (job, notify_result); + return; + } + + if (pipe (pipefd) < 0) { + g_warning (_("Cannot create pipe for open GIOChannel: %s"), + g_strerror (errno)); + notify_result->specifics.create_as_channel.result = GNOME_VFS_ERROR_INTERNAL; + /* if the open failed, just drop the job */ + job->failed = TRUE; + job_oneway_notify (job, notify_result); + return; + } + + channel_in = g_io_channel_unix_new (pipefd[0]); + channel_out = g_io_channel_unix_new (pipefd[1]); + + notify_result->specifics.create_as_channel.channel = channel_out; + + job_notify (job, notify_result); + + serve_channel_write (handle, channel_in, channel_out, job->op->context); +} + +static void +execute_close (GnomeVFSJob *job) +{ + GnomeVFSCloseOp *close_op; + GnomeVFSNotifyResult *notify_result; + + close_op = &job->op->specifics.close; + + notify_result = g_new0 (GnomeVFSNotifyResult, 1); + notify_result->job_handle = job->job_handle; + notify_result->type = job->op->type; + notify_result->specifics.close.callback = (GnomeVFSAsyncCloseCallback) job->op->callback; + notify_result->specifics.close.callback_data = job->op->callback_data; + notify_result->specifics.close.result + = gnome_vfs_close_cancellable (job->handle, job->op->context); + + job_oneway_notify (job, notify_result); +} + +static void +execute_read (GnomeVFSJob *job) +{ + GnomeVFSReadOp *read_op; + GnomeVFSNotifyResult *notify_result; + + read_op = &job->op->specifics.read; + + notify_result = g_new0 (GnomeVFSNotifyResult, 1); + notify_result->job_handle = job->job_handle; + notify_result->type = job->op->type; + notify_result->specifics.read.callback = (GnomeVFSAsyncReadCallback) job->op->callback; + notify_result->specifics.read.callback_data = job->op->callback_data; + notify_result->specifics.read.buffer = read_op->buffer; + notify_result->specifics.read.num_bytes = read_op->num_bytes; + + notify_result->specifics.read.result = gnome_vfs_read_cancellable (job->handle, + read_op->buffer, + read_op->num_bytes, + ¬ify_result->specifics.read.bytes_read, + job->op->context); + + job->op->type = GNOME_VFS_OP_READ_WRITE_DONE; + + job_oneway_notify (job, notify_result); +} + +static void +execute_write (GnomeVFSJob *job) +{ + GnomeVFSWriteOp *write_op; + GnomeVFSNotifyResult *notify_result; + + write_op = &job->op->specifics.write; + + notify_result = g_new0 (GnomeVFSNotifyResult, 1); + notify_result->job_handle = job->job_handle; + notify_result->type = job->op->type; + notify_result->specifics.write.callback = (GnomeVFSAsyncWriteCallback) job->op->callback; + notify_result->specifics.write.callback_data = job->op->callback_data; + notify_result->specifics.write.buffer = write_op->buffer; + notify_result->specifics.write.num_bytes = write_op->num_bytes; + + notify_result->specifics.write.result = gnome_vfs_write_cancellable (job->handle, + write_op->buffer, + write_op->num_bytes, + ¬ify_result->specifics.write.bytes_written, + job->op->context); + + job->op->type = GNOME_VFS_OP_READ_WRITE_DONE; + + job_oneway_notify (job, notify_result); +} + +static void +execute_get_file_info (GnomeVFSJob *job) +{ + GnomeVFSGetFileInfoOp *get_file_info_op; + GList *p; + GnomeVFSGetFileInfoResult *result_item; + GnomeVFSNotifyResult *notify_result; + + get_file_info_op = &job->op->specifics.get_file_info; + + notify_result = g_new0 (GnomeVFSNotifyResult, 1); + notify_result->job_handle = job->job_handle; + notify_result->type = job->op->type; + notify_result->specifics.get_file_info.callback = + (GnomeVFSAsyncGetFileInfoCallback) job->op->callback; + notify_result->specifics.get_file_info.callback_data = job->op->callback_data; + + for (p = get_file_info_op->uris; p != NULL; p = p->next) { + result_item = g_new (GnomeVFSGetFileInfoResult, 1); + + result_item->uri = gnome_vfs_uri_ref (p->data); + result_item->file_info = gnome_vfs_file_info_new (); + + result_item->result = gnome_vfs_get_file_info_uri_cancellable + (result_item->uri, + result_item->file_info, + get_file_info_op->options, + job->op->context); + + notify_result->specifics.get_file_info.result_list = + g_list_prepend (notify_result->specifics.get_file_info.result_list, result_item); + } + notify_result->specifics.get_file_info.result_list = + g_list_reverse (notify_result->specifics.get_file_info.result_list); + + job_oneway_notify (job, notify_result); +} + +static void +execute_set_file_info (GnomeVFSJob *job) +{ + GnomeVFSSetFileInfoOp *set_file_info_op; + GnomeVFSURI *parent_uri, *uri_after; + GnomeVFSNotifyResult *notify_result; + + set_file_info_op = &job->op->specifics.set_file_info; + + notify_result = g_new0 (GnomeVFSNotifyResult, 1); + notify_result->job_handle = job->job_handle; + notify_result->type = job->op->type; + notify_result->specifics.set_file_info.callback = + (GnomeVFSAsyncSetFileInfoCallback) job->op->callback; + notify_result->specifics.set_file_info.callback_data = + job->op->callback_data; + + notify_result->specifics.set_file_info.set_file_info_result = + gnome_vfs_set_file_info_cancellable (set_file_info_op->uri, + set_file_info_op->info, set_file_info_op->mask, + job->op->context); + + /* Get the new URI after the set_file_info. The name may have + * changed. + */ + uri_after = NULL; + if (notify_result->specifics.set_file_info.set_file_info_result == GNOME_VFS_OK + && (set_file_info_op->mask & GNOME_VFS_SET_FILE_INFO_NAME) != 0) { + parent_uri = gnome_vfs_uri_get_parent (set_file_info_op->uri); + if (parent_uri != NULL) { + uri_after = gnome_vfs_uri_append_file_name + (parent_uri, set_file_info_op->info->name); + gnome_vfs_uri_unref (parent_uri); + } + } + if (uri_after == NULL) { + uri_after = set_file_info_op->uri; + gnome_vfs_uri_ref (uri_after); + } + + notify_result->specifics.set_file_info.info = gnome_vfs_file_info_new (); + if (uri_after == NULL) { + notify_result->specifics.set_file_info.get_file_info_result + = GNOME_VFS_ERROR_INVALID_URI; + } else { + notify_result->specifics.set_file_info.get_file_info_result + = gnome_vfs_get_file_info_uri_cancellable + (uri_after, + notify_result->specifics.set_file_info.info, + set_file_info_op->options, + job->op->context); + gnome_vfs_uri_unref (uri_after); + } + + job_oneway_notify (job, notify_result); +} + +static void +execute_find_directory (GnomeVFSJob *job) +{ + GnomeVFSFindDirectoryOp *find_directory_op; + GList *p; + GnomeVFSFindDirectoryResult *result_item; + GnomeVFSNotifyResult *notify_result; + + notify_result = g_new0 (GnomeVFSNotifyResult, 1); + notify_result->job_handle = job->job_handle; + notify_result->type = job->op->type; + notify_result->specifics.find_directory.callback + = (GnomeVFSAsyncFindDirectoryCallback) job->op->callback; + notify_result->specifics.find_directory.callback_data = job->op->callback_data; + + find_directory_op = &job->op->specifics.find_directory; + for (p = find_directory_op->uris; p != NULL; p = p->next) { + result_item = g_new0 (GnomeVFSFindDirectoryResult, 1); + + result_item->result = gnome_vfs_find_directory_cancellable + ((GnomeVFSURI *) p->data, + find_directory_op->kind, + &result_item->uri, + find_directory_op->create_if_needed, + find_directory_op->find_if_needed, + find_directory_op->permissions, + job->op->context); + notify_result->specifics.find_directory.result_list = + g_list_prepend (notify_result->specifics.find_directory.result_list, result_item); + } + + notify_result->specifics.find_directory.result_list = + g_list_reverse (notify_result->specifics.find_directory.result_list); + + job_oneway_notify (job, notify_result); +} + +static void +load_directory_details (GnomeVFSJob *job) +{ + GnomeVFSLoadDirectoryOp *load_directory_op; + GnomeVFSDirectoryHandle *handle; + GList *directory_list; + GnomeVFSFileInfo *info; + GnomeVFSResult result; + guint count; + GnomeVFSNotifyResult *notify_result; + + JOB_DEBUG (("%u", GPOINTER_TO_UINT (job->job_handle))); + load_directory_op = &job->op->specifics.load_directory; + + if (load_directory_op->uri == NULL) { + result = GNOME_VFS_ERROR_INVALID_URI; + } else { + result = gnome_vfs_directory_open_from_uri_cancellable + (&handle, + load_directory_op->uri, + load_directory_op->options, + job->op->context); + } + + if (result != GNOME_VFS_OK) { + notify_result = g_new0 (GnomeVFSNotifyResult, 1); + notify_result->job_handle = job->job_handle; + notify_result->type = job->op->type; + notify_result->specifics.load_directory.result = result; + notify_result->specifics.load_directory.callback = + (GnomeVFSAsyncDirectoryLoadCallback) job->op->callback; + notify_result->specifics.load_directory.callback_data = job->op->callback_data; + job_oneway_notify (job, notify_result); + return; + } + + directory_list = NULL; + + count = 0; + while (1) { + if (gnome_vfs_context_check_cancellation (job->op->context)) { + JOB_DEBUG (("cancelled, bailing %u", + GPOINTER_TO_UINT (job->job_handle))); + gnome_vfs_file_info_list_free (directory_list); + directory_list = NULL; + result = GNOME_VFS_ERROR_CANCELLED; + break; + } + + info = gnome_vfs_file_info_new (); + + result = gnome_vfs_directory_read_next_cancellable + (handle, info, job->op->context); + + if (result == GNOME_VFS_OK) { + directory_list = g_list_prepend (directory_list, info); + count++; + } else { + gnome_vfs_file_info_unref (info); + } + + if (count == load_directory_op->items_per_notification + || result != GNOME_VFS_OK) { + + notify_result = g_new0 (GnomeVFSNotifyResult, 1); + notify_result->job_handle = job->job_handle; + notify_result->type = job->op->type; + notify_result->specifics.load_directory.result = result; + notify_result->specifics.load_directory.entries_read = count; + notify_result->specifics.load_directory.list = + g_list_reverse (directory_list); + notify_result->specifics.load_directory.callback = + (GnomeVFSAsyncDirectoryLoadCallback) job->op->callback; + notify_result->specifics.load_directory.callback_data = + job->op->callback_data; + + job_oneway_notify (job, notify_result); + + count = 0; + directory_list = NULL; + + if (result != GNOME_VFS_OK) { + break; + } + } + } + + g_assert (directory_list == NULL); + gnome_vfs_directory_close (handle); +} + +static void +execute_load_directory (GnomeVFSJob *job) +{ + GnomeVFSLoadDirectoryOp *load_directory_op; + + load_directory_op = &job->op->specifics.load_directory; + + load_directory_details (job); +} + +static gint +xfer_callback (GnomeVFSXferProgressInfo *info, + gpointer data) +{ + GnomeVFSJob *job; + GnomeVFSNotifyResult notify_result; + + job = (GnomeVFSJob *) data; + + /* xfer is fully synchronous, just allocate the notify result struct on the stack */ + notify_result.job_handle = job->job_handle; + notify_result.callback_id = 0; + notify_result.cancelled = FALSE; + notify_result.type = job->op->type; + notify_result.specifics.xfer.progress_info = info; + notify_result.specifics.xfer.callback = (GnomeVFSAsyncXferProgressCallback) job->op->callback; + notify_result.specifics.xfer.callback_data = job->op->callback_data; + + job_notify (job, ¬ify_result); + + /* Pass the value returned from the callback in the master thread. */ + return notify_result.specifics.xfer.reply; +} + +static void +execute_xfer (GnomeVFSJob *job) +{ + GnomeVFSXferOp *xfer_op; + GnomeVFSResult result; + GnomeVFSXferProgressInfo info; + GnomeVFSNotifyResult notify_result; + + xfer_op = &job->op->specifics.xfer; + + result = _gnome_vfs_xfer_private (xfer_op->source_uri_list, + xfer_op->target_uri_list, + xfer_op->xfer_options, + xfer_op->error_mode, + xfer_op->overwrite_mode, + xfer_callback, + job, + xfer_op->progress_sync_callback, + xfer_op->sync_callback_data); + + /* If the xfer functions returns an error now, something really bad + * must have happened. + */ + if (result != GNOME_VFS_OK && result != GNOME_VFS_ERROR_INTERRUPTED) { + + info.status = GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR; + info.vfs_status = result; + info.phase = GNOME_VFS_XFER_PHASE_INITIAL; + info.source_name = NULL; + info.target_name = NULL; + info.file_index = 0; + info.files_total = 0; + info.bytes_total = 0; + info.file_size = 0; + info.bytes_copied = 0; + info.total_bytes_copied = 0; + + notify_result.job_handle = job->job_handle; + notify_result.callback_id = 0; + notify_result.cancelled = FALSE; + notify_result.type = job->op->type; + notify_result.specifics.xfer.progress_info = &info; + notify_result.specifics.xfer.callback = (GnomeVFSAsyncXferProgressCallback) job->op->callback; + notify_result.specifics.xfer.callback_data = job->op->callback_data; + + job_notify (job, ¬ify_result); + } +} + +static void +execute_file_control (GnomeVFSJob *job) +{ + GnomeVFSFileControlOp *file_control_op; + GnomeVFSNotifyResult *notify_result; + + file_control_op = &job->op->specifics.file_control; + + notify_result = g_new0 (GnomeVFSNotifyResult, 1); + notify_result->job_handle = job->job_handle; + notify_result->type = job->op->type; + notify_result->specifics.file_control.callback = (GnomeVFSAsyncFileControlCallback) job->op->callback; + notify_result->specifics.file_control.callback_data = job->op->callback_data; + notify_result->specifics.file_control.operation_data = file_control_op->operation_data; + notify_result->specifics.file_control.operation_data_destroy_func = file_control_op->operation_data_destroy_func; + + notify_result->specifics.file_control.result = gnome_vfs_file_control_cancellable (job->handle, + file_control_op->operation, + file_control_op->operation_data, + job->op->context); + + job->op->type = GNOME_VFS_OP_FILE_CONTROL; + + job_oneway_notify (job, notify_result); +} + + +/* + * _gnome_vfs_job_execute: + * @job: the job to execute + * + * This function is called by the slave thread to execute + * the job - all work performed by a thread starts here. + */ +void +_gnome_vfs_job_execute (GnomeVFSJob *job) +{ + guint id; + + id = GPOINTER_TO_UINT (job->job_handle); + + JOB_DEBUG (("exec job %u", id)); + + if (!job->cancelled) { + set_current_job (job); + + JOB_DEBUG (("executing %u %d type %s", id, job->op->type, + JOB_DEBUG_TYPE (job->op->type))); + + switch (job->op->type) { + case GNOME_VFS_OP_OPEN: + execute_open (job); + break; + case GNOME_VFS_OP_OPEN_AS_CHANNEL: + execute_open_as_channel (job); + break; + case GNOME_VFS_OP_CREATE: + execute_create (job); + break; + case GNOME_VFS_OP_CREATE_AS_CHANNEL: + execute_create_as_channel (job); + break; + case GNOME_VFS_OP_CREATE_SYMBOLIC_LINK: + execute_create_symbolic_link (job); + break; + case GNOME_VFS_OP_CLOSE: + execute_close (job); + break; + case GNOME_VFS_OP_READ: + execute_read (job); + break; + case GNOME_VFS_OP_WRITE: + execute_write (job); + break; + case GNOME_VFS_OP_LOAD_DIRECTORY: + execute_load_directory (job); + break; + case GNOME_VFS_OP_FIND_DIRECTORY: + execute_find_directory (job); + break; + case GNOME_VFS_OP_XFER: + execute_xfer (job); + break; + case GNOME_VFS_OP_GET_FILE_INFO: + execute_get_file_info (job); + break; + case GNOME_VFS_OP_SET_FILE_INFO: + execute_set_file_info (job); + break; + case GNOME_VFS_OP_FILE_CONTROL: + execute_file_control (job); + break; + default: + g_warning (_("Unknown job kind %u"), job->op->type); + break; + } + /* NB. 'job' is quite probably invalid now */ + clear_current_job (); + } else { + switch (job->op->type) { + case GNOME_VFS_OP_READ: + case GNOME_VFS_OP_WRITE: + job->op->type = GNOME_VFS_OP_READ_WRITE_DONE; + break; + default: + break; + } + } + + JOB_DEBUG (("done job %u", id)); +} + +void +_gnome_vfs_job_module_cancel (GnomeVFSJob *job) +{ + GnomeVFSCancellation *cancellation; + + JOB_DEBUG (("%u", GPOINTER_TO_UINT (job->job_handle))); + + cancellation = gnome_vfs_context_get_cancellation (job->op->context); + if (cancellation != NULL) { + JOB_DEBUG (("cancelling %u", GPOINTER_TO_UINT (job->job_handle))); + gnome_vfs_cancellation_cancel (cancellation); + } + +#ifdef OLD_CONTEXT_DEPRECATED + gnome_vfs_context_emit_message (job->op->context, _("Operation stopped")); +#endif /* OLD_CONTEXT_DEPRECATED */ + + /* Since we are cancelling, we won't have anyone respond to notifications; + * set the expectations right. + */ + JOB_DEBUG (("done %u", GPOINTER_TO_UINT (job->job_handle))); +} + +static void +set_current_job (GnomeVFSJob *job) +{ + /* There shouldn't have been anything here. */ + g_assert (g_static_private_get (&job_private) == NULL); + + g_static_private_set (&job_private, job, NULL); + + _gnome_vfs_module_callback_use_stack_info (job->op->stack_info); + _gnome_vfs_module_callback_set_in_async_thread (TRUE); +} + +static void +clear_current_job (void) +{ + g_static_private_set (&job_private, NULL, NULL); + + _gnome_vfs_module_callback_clear_stacks (); +} + +void +_gnome_vfs_get_current_context (GnomeVFSContext **context) +{ + GnomeVFSJob *job; + + g_return_if_fail (context != NULL); + + job = g_static_private_get (&job_private); + + if (job != NULL) { + *context = job->op->context; + } else { + *context = NULL; + } +} + +void +_gnome_vfs_dispatch_module_callback (GnomeVFSAsyncModuleCallback callback, + gconstpointer in, gsize in_size, + gpointer out, gsize out_size, + gpointer user_data, + GnomeVFSModuleCallbackResponse response, + gpointer response_data) +{ + GnomeVFSJob *job; + GnomeVFSNotifyResult notify_result; + + job = g_static_private_get (&job_private); + + g_return_if_fail (job != NULL); + + memset (¬ify_result, 0, sizeof (notify_result)); + + notify_result.job_handle = job->job_handle; + + notify_result.type = GNOME_VFS_OP_MODULE_CALLBACK; + + notify_result.specifics.callback.callback = callback; + notify_result.specifics.callback.user_data = user_data; + notify_result.specifics.callback.in = in; + notify_result.specifics.callback.in_size = in_size; + notify_result.specifics.callback.out = out; + notify_result.specifics.callback.out_size = out_size; + notify_result.specifics.callback.out = out; + notify_result.specifics.callback.out_size = out_size; + notify_result.specifics.callback.response = response; + notify_result.specifics.callback.response_data = response_data; + + job_notify (job, ¬ify_result); +} diff --git a/libgnomevfs/gnome-vfs-job.h b/libgnomevfs/gnome-vfs-job.h new file mode 100644 index 0000000..d0dd530 --- /dev/null +++ b/libgnomevfs/gnome-vfs-job.h @@ -0,0 +1,416 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* gnome-vfs-job.h - Jobs for asynchronous operation of the GNOME + Virtual File System (version for POSIX threads). + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli +*/ + +#ifndef GNOME_VFS_JOB_PTHREAD_H +#define GNOME_VFS_JOB_PTHREAD_H + +/* + * The following includes help Solaris copy with its own headers. (With 64- + * bit stuff enabled they like to #define open open64, etc.) + * See http://bugzilla.gnome.org/show_bug.cgi?id=71184 for details. + */ +#include +#include + +#include +#include +#include + +typedef struct GnomeVFSJob GnomeVFSJob; + +#define GNOME_VFS_JOB_DEBUG 0 + +#if GNOME_VFS_JOB_DEBUG + +#include + +extern GStaticMutex debug_mutex; + +#define JOB_DEBUG_PRINT(x) \ +G_STMT_START{ \ + struct timeval _tt; \ + gettimeofday(&_tt, NULL); \ + printf ("%ld:%6.ld ", _tt.tv_sec, _tt.tv_usec); \ + g_static_mutex_lock (&debug_mutex); \ + fputs (__FUNCTION__, stdout); \ + printf (": %d ", __LINE__); \ + printf x; \ + fputc ('\n', stdout); \ + fflush (stdout); \ + g_static_mutex_unlock (&debug_mutex); \ +}G_STMT_END + +#endif + +#if GNOME_VFS_JOB_DEBUG +#include + +extern char *job_debug_types[]; + +#define JOB_DEBUG(x) JOB_DEBUG_PRINT(x) +#define JOB_DEBUG_ONLY(x) x +#define JOB_DEBUG_TYPE(x) (job_debug_types[(x)]) + +#else +#define JOB_DEBUG(x) +#define JOB_DEBUG_ONLY(x) +#define JOB_DEBUG_TYPE(x) + +#endif + +/* GNOME_VFS_OP_MODULE_CALLBACK: is not a real OpType; + * its intended to mark GnomeVFSAsyncModuleCallback's in the + * job_callback queue + */ + +enum GnomeVFSOpType { + GNOME_VFS_OP_OPEN, + GNOME_VFS_OP_OPEN_AS_CHANNEL, + GNOME_VFS_OP_CREATE, + GNOME_VFS_OP_CREATE_SYMBOLIC_LINK, + GNOME_VFS_OP_CREATE_AS_CHANNEL, + GNOME_VFS_OP_CLOSE, + GNOME_VFS_OP_READ, + GNOME_VFS_OP_WRITE, + GNOME_VFS_OP_READ_WRITE_DONE, + GNOME_VFS_OP_LOAD_DIRECTORY, + GNOME_VFS_OP_FIND_DIRECTORY, + GNOME_VFS_OP_XFER, + GNOME_VFS_OP_GET_FILE_INFO, + GNOME_VFS_OP_SET_FILE_INFO, + GNOME_VFS_OP_MODULE_CALLBACK, + GNOME_VFS_OP_FILE_CONTROL +}; + +typedef enum GnomeVFSOpType GnomeVFSOpType; + +typedef struct { + GnomeVFSURI *uri; + GnomeVFSOpenMode open_mode; +} GnomeVFSOpenOp; + +typedef struct { + GnomeVFSAsyncOpenCallback callback; + void *callback_data; + GnomeVFSResult result; +} GnomeVFSOpenOpResult; + +typedef struct { + GnomeVFSURI *uri; + GnomeVFSOpenMode open_mode; + guint advised_block_size; +} GnomeVFSOpenAsChannelOp; + +typedef struct { + GnomeVFSAsyncOpenAsChannelCallback callback; + void *callback_data; + GnomeVFSResult result; + GIOChannel *channel; +} GnomeVFSOpenAsChannelOpResult; + +typedef struct { + GnomeVFSURI *uri; + GnomeVFSOpenMode open_mode; + gboolean exclusive; + guint perm; +} GnomeVFSCreateOp; + +typedef struct { + GnomeVFSAsyncCreateCallback callback; + void *callback_data; + GnomeVFSResult result; +} GnomeVFSCreateOpResult; + +typedef struct { + GnomeVFSURI *uri; + char *uri_reference; +} GnomeVFSCreateLinkOp; + +typedef struct { + GnomeVFSURI *uri; + GnomeVFSOpenMode open_mode; + gboolean exclusive; + guint perm; +} GnomeVFSCreateAsChannelOp; + +typedef struct { + GnomeVFSAsyncCreateAsChannelCallback callback; + void *callback_data; + GnomeVFSResult result; + GIOChannel *channel; +} GnomeVFSCreateAsChannelOpResult; + +typedef struct { + char dummy; /* ANSI C does not allow empty structs */ +} GnomeVFSCloseOp; + +typedef struct { + GnomeVFSAsyncCloseCallback callback; + void *callback_data; + GnomeVFSResult result; +} GnomeVFSCloseOpResult; + +typedef struct { + GnomeVFSFileSize num_bytes; + gpointer buffer; +} GnomeVFSReadOp; + +typedef struct { + GnomeVFSAsyncReadCallback callback; + void *callback_data; + GnomeVFSFileSize num_bytes; + gpointer buffer; + GnomeVFSResult result; + GnomeVFSFileSize bytes_read; +} GnomeVFSReadOpResult; + +typedef struct { + GnomeVFSFileSize num_bytes; + gconstpointer buffer; +} GnomeVFSWriteOp; + +typedef struct { + GnomeVFSAsyncWriteCallback callback; + void *callback_data; + GnomeVFSFileSize num_bytes; + gconstpointer buffer; + GnomeVFSResult result; + GnomeVFSFileSize bytes_written; +} GnomeVFSWriteOpResult; + +typedef struct { + GList *uris; /* GnomeVFSURI* */ + GnomeVFSFileInfoOptions options; +} GnomeVFSGetFileInfoOp; + +typedef struct { + GnomeVFSAsyncGetFileInfoCallback callback; + void *callback_data; + GList *result_list; /* GnomeVFSGetFileInfoResult* */ +} GnomeVFSGetFileInfoOpResult; + +typedef struct { + GnomeVFSURI *uri; + GnomeVFSFileInfo *info; + GnomeVFSSetFileInfoMask mask; + GnomeVFSFileInfoOptions options; +} GnomeVFSSetFileInfoOp; + +typedef struct { + GnomeVFSAsyncSetFileInfoCallback callback; + void *callback_data; + GnomeVFSResult set_file_info_result; + GnomeVFSResult get_file_info_result; + GnomeVFSFileInfo *info; +} GnomeVFSSetFileInfoOpResult; + +typedef struct { + GList *uris; /* GnomeVFSURI* */ + GnomeVFSFindDirectoryKind kind; + gboolean create_if_needed; + gboolean find_if_needed; + guint permissions; +} GnomeVFSFindDirectoryOp; + +typedef struct { + GnomeVFSAsyncFindDirectoryCallback callback; + void *callback_data; + GList *result_list; /* GnomeVFSFindDirectoryResult */ +} GnomeVFSFindDirectoryOpResult; + +typedef struct { + GnomeVFSURI *uri; + GnomeVFSFileInfoOptions options; + guint items_per_notification; +} GnomeVFSLoadDirectoryOp; + +typedef struct { + GnomeVFSAsyncDirectoryLoadCallback callback; + void *callback_data; + GnomeVFSResult result; + GList *list; + guint entries_read; +} GnomeVFSLoadDirectoryOpResult; + +typedef struct { + GList *source_uri_list; + GList *target_uri_list; + GnomeVFSXferOptions xfer_options; + GnomeVFSXferErrorMode error_mode; + GnomeVFSXferOverwriteMode overwrite_mode; + GnomeVFSXferProgressCallback progress_sync_callback; + gpointer sync_callback_data; +} GnomeVFSXferOp; + +typedef struct { + GnomeVFSAsyncXferProgressCallback callback; + void *callback_data; + GnomeVFSXferProgressInfo *progress_info; + int reply; +} GnomeVFSXferOpResult; + +typedef struct { + GnomeVFSAsyncModuleCallback callback; + gpointer user_data; + gconstpointer in; + size_t in_size; + gpointer out; + size_t out_size; + GnomeVFSModuleCallbackResponse response; + gpointer response_data; +} GnomeVFSModuleCallbackOpResult; + +typedef struct { + char *operation; + gpointer operation_data; + GDestroyNotify operation_data_destroy_func; +} GnomeVFSFileControlOp; + +typedef struct { + GnomeVFSAsyncFileControlCallback callback; + gpointer callback_data; + GnomeVFSResult result; + gpointer operation_data; + GDestroyNotify operation_data_destroy_func; +} GnomeVFSFileControlOpResult; + +typedef union { + GnomeVFSOpenOp open; + GnomeVFSOpenAsChannelOp open_as_channel; + GnomeVFSCreateOp create; + GnomeVFSCreateLinkOp create_symbolic_link; + GnomeVFSCreateAsChannelOp create_as_channel; + GnomeVFSCloseOp close; + GnomeVFSReadOp read; + GnomeVFSWriteOp write; + GnomeVFSLoadDirectoryOp load_directory; + GnomeVFSXferOp xfer; + GnomeVFSGetFileInfoOp get_file_info; + GnomeVFSSetFileInfoOp set_file_info; + GnomeVFSFindDirectoryOp find_directory; + GnomeVFSFileControlOp file_control; +} GnomeVFSSpecificOp; + +typedef struct { + /* ID of the job (e.g. open, create, close...). */ + GnomeVFSOpType type; + + /* The callback for when the op is completed. */ + GFunc callback; + gpointer callback_data; + + /* Details of the op. */ + GnomeVFSSpecificOp specifics; + + /* The context for cancelling the operation. */ + GnomeVFSContext *context; + GnomeVFSModuleCallbackStackInfo *stack_info; +} GnomeVFSOp; + +typedef union { + GnomeVFSOpenOpResult open; + GnomeVFSOpenAsChannelOpResult open_as_channel; + GnomeVFSCreateOpResult create; + GnomeVFSCreateAsChannelOpResult create_as_channel; + GnomeVFSCloseOpResult close; + GnomeVFSReadOpResult read; + GnomeVFSWriteOpResult write; + GnomeVFSGetFileInfoOpResult get_file_info; + GnomeVFSSetFileInfoOpResult set_file_info; + GnomeVFSFindDirectoryOpResult find_directory; + GnomeVFSLoadDirectoryOpResult load_directory; + GnomeVFSXferOpResult xfer; + GnomeVFSModuleCallbackOpResult callback; + GnomeVFSFileControlOpResult file_control; +} GnomeVFSSpecificNotifyResult; + +typedef struct { + GnomeVFSAsyncHandle *job_handle; + + guint callback_id; + + /* By the time the callback got reached the job might have been cancelled. + * We find out by checking this flag. + */ + gboolean cancelled; + + /* ID of the job (e.g. open, create, close...). */ + GnomeVFSOpType type; + + GnomeVFSSpecificNotifyResult specifics; +} GnomeVFSNotifyResult; + +/* FIXME bugzilla.eazel.com 1135: Move private stuff out of the header. */ +struct GnomeVFSJob { + /* Handle being used for file access. */ + GnomeVFSHandle *handle; + + /* By the time the entry routine for the job got reached + * the job might have been cancelled. We find out by checking + * this flag. + */ + gboolean cancelled; + + /* Read or create returned with an error - helps + * flagging that we do not expect a cancel + */ + gboolean failed; + + /* Global lock for accessing job's 'op' and 'handle' */ + GMutex *job_lock; + + /* This condition is signalled when the master thread gets a + notification and wants to acknowledge it. */ + GCond *notify_ack_condition; + + /* Operations that are being done and those that are completed and + * ready for notification to take place. + */ + GnomeVFSOp *op; + + /* Unique identifier of this job (a uint, really) */ + GnomeVFSAsyncHandle *job_handle; + + /* The priority of this job */ + int priority; +}; + +GnomeVFSJob *_gnome_vfs_job_new (GnomeVFSOpType type, + int priority, + GFunc callback, + gpointer callback_data); +void _gnome_vfs_job_destroy (GnomeVFSJob *job); +void _gnome_vfs_job_set (GnomeVFSJob *job, + GnomeVFSOpType type, + GFunc callback, + gpointer callback_data); +void _gnome_vfs_job_go (GnomeVFSJob *job); +void _gnome_vfs_job_execute (GnomeVFSJob *job); +void _gnome_vfs_job_module_cancel (GnomeVFSJob *job); +int gnome_vfs_job_get_count (void); + +gboolean _gnome_vfs_job_complete (GnomeVFSJob *job); + +#endif /* GNOME_VFS_JOB_PTHREAD_H */ diff --git a/libgnomevfs/gnome-vfs-method.c b/libgnomevfs/gnome-vfs-method.c new file mode 100644 index 0000000..6b8766c --- /dev/null +++ b/libgnomevfs/gnome-vfs-method.c @@ -0,0 +1,353 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-method.c - Handling of access methods in the GNOME + Virtual File System. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli */ + +#include +#include "gnome-vfs-method.h" + +#include "gnome-vfs-configuration.h" +#include "gnome-vfs-private.h" +#include +#include +#include +#include +#include +#include +#include + +#define GNOME_VFS_MODULE_INIT "vfs_module_init" +#define GNOME_VFS_MODULE_TRANSFORM "vfs_module_transform" +#define GNOME_VFS_MODULE_SHUTDOWN "vfs_module_shutdown" + +struct _ModuleElement { + char *name; + const char *args; + GnomeVFSMethod *method; + GnomeVFSTransform *transform; + int nusers; +}; +typedef struct _ModuleElement ModuleElement; + +static gboolean method_already_initialized = FALSE; + +static GHashTable *module_hash = NULL; +G_LOCK_DEFINE_STATIC (gnome_vfs_method_init); +GStaticRecMutex module_hash_lock = G_STATIC_REC_MUTEX_INIT; + +static GList *module_path_list = NULL; + + +static gboolean +init_hash_table (void) +{ + module_hash = g_hash_table_new (g_str_hash, g_str_equal); + + return TRUE; +} + +static gboolean +install_path_list (const gchar *user_path_list) +{ + const gchar *p, *oldp; + + /* Notice that this assumes the list has already been locked. */ + + oldp = user_path_list; + while (1) { + gchar *elem; + + p = strchr (oldp, ':'); + + if (p == NULL) { + if (*oldp != '\0') { + elem = g_strdup (oldp); + module_path_list = g_list_append + (module_path_list, elem); + } + break; + } else if (p != oldp) { + elem = g_strndup (oldp, p - oldp); + module_path_list = g_list_append (module_path_list, + elem); + } else { + elem = NULL; + } + + oldp = p + 1; + } + + return TRUE; +} + +static gboolean +init_path_list (void) +{ + const gchar *user_path_list; + + if (module_path_list != NULL) + return TRUE; + + /* User-supplied path. */ + + user_path_list = getenv ("GNOME_VFS_MODULE_PATH"); + if (user_path_list != NULL) { + if (! install_path_list (user_path_list)) + return FALSE; + } + + /* Default path. It comes last so that users can override it. */ + + module_path_list = g_list_append (module_path_list, + g_strdup (GNOME_VFS_MODULE_DIR)); + + return TRUE; +} + +gboolean +gnome_vfs_method_init (void) +{ + G_LOCK (gnome_vfs_method_init); + + if (method_already_initialized) + goto gnome_vfs_method_init_out; + + if (! init_hash_table ()) + goto gnome_vfs_method_init_out; + if (! init_path_list ()) + goto gnome_vfs_method_init_out; + + method_already_initialized = TRUE; + + gnome_vfs_method_init_out: + G_UNLOCK (gnome_vfs_method_init); + + return method_already_initialized; +} + +static void +load_module (const gchar *module_name, const char *method_name, const char *args, + GnomeVFSMethod **method, GnomeVFSTransform **transform) +{ + GModule *module; + GnomeVFSMethod *temp_method = NULL; + GnomeVFSTransform *temp_transform = NULL; + + GnomeVFSMethodInitFunc init_function = NULL; + GnomeVFSTransformInitFunc transform_function = NULL; + GnomeVFSMethodShutdownFunc shutdown_function = NULL; + + *method = NULL; + *transform = NULL; + + module = g_module_open (module_name, G_MODULE_BIND_LAZY); + if (module == NULL) { + g_warning ("Cannot load module `%s' (%s)", module_name, g_module_error ()); + return; + } + + g_module_symbol (module, GNOME_VFS_MODULE_INIT, + (gpointer *) &init_function); + g_module_symbol (module, GNOME_VFS_MODULE_TRANSFORM, + (gpointer *) &transform_function); + g_module_symbol (module, GNOME_VFS_MODULE_SHUTDOWN, + (gpointer *) &shutdown_function); + + if ((init_function == NULL || shutdown_function == NULL) && + (transform_function == NULL)) { + g_warning ("module '%s' has no init function; may be an out-of-date module", module_name); + return; + } + + if (init_function) + temp_method = (* init_function) (method_name, args); + + if (temp_method == NULL && init_function) { + g_warning ("module '%s' returned a NULL handle", module_name); + return; + } + + if (temp_method != NULL) { + /* Some basic checks */ + if (temp_method->method_table_size == 0) { + g_warning ("module '%s' has 0 table size", module_name); + return; + } else if (temp_method->method_table_size > (0x100 * sizeof (GnomeVFSMethod))) { + g_warning ("module '%s' has unreasonable table size, perhaps it is using the old GnomeVFSMethod struct?", module_name); + return; + } else if (!VFS_METHOD_HAS_FUNC(temp_method, open)) { + g_warning ("module '%s' has no open fn", module_name); + return; +#if 0 + } else if (!VFS_METHOD_HAS_FUNC(temp_method, create)) { + g_warning ("module '%s' has no create fn", module_name); + return; +#endif + } else if (!VFS_METHOD_HAS_FUNC(temp_method, is_local)) { + g_warning ("module '%s' has no is-local fn", module_name); + return; +#if 0 + } else if (!VFS_METHOD_HAS_FUNC(temp_method, get_file_info)) { + g_warning ("module '%s' has no get-file-info fn", module_name); + return; +#endif + } + + /* More advanced assumptions. */ + if (VFS_METHOD_HAS_FUNC(temp_method, tell) && !VFS_METHOD_HAS_FUNC(temp_method, seek)) { + g_warning ("module '%s' has tell and no seek", module_name); + return; + } + + if (VFS_METHOD_HAS_FUNC(temp_method, seek) && !VFS_METHOD_HAS_FUNC(temp_method, tell)) { + g_warning ("module '%s' has seek and no tell", module_name); + return; + } + } + + if (transform_function) + temp_transform = (* transform_function) (method_name, args); + if (temp_transform) { + if (temp_transform->transform == NULL) { + g_warning ("module '%s' has no transform method", module_name); + return; + } + } + + *method = temp_method; + *transform = temp_transform; +} + +static void +load_module_in_path_list (const gchar *base_name, const char *method_name, const char *args, + GnomeVFSMethod **method, GnomeVFSTransform **transform) +{ + GList *p; + + *method = NULL; + *transform = NULL; + + for (p = module_path_list; p != NULL; p = p->next) { + const gchar *path; + gchar *name; + + path = p->data; + name = g_module_build_path (path, base_name); + + load_module (name, method_name, args, method, transform); + g_free (name); + + if (*method != NULL || *transform != NULL) + return; + } +} + +static ModuleElement * +gnome_vfs_add_module_to_hash_table (const gchar *name) +{ + GnomeVFSMethod *method = NULL; + GnomeVFSTransform *transform = NULL; + ModuleElement *module_element; + const char *module_name; + pid_t saved_uid; + gid_t saved_gid; + const char *args; + + g_static_rec_mutex_lock (&module_hash_lock); + + module_element = g_hash_table_lookup (module_hash, name); + + if (module_element != NULL) + goto add_module_out; + + module_name = _gnome_vfs_configuration_get_module_path (name, &args); + if (module_name == NULL) + goto add_module_out; + + /* Set the effective UID/GID to the user UID/GID to prevent attacks to + setuid/setgid executables. */ + + saved_uid = geteuid (); + saved_gid = getegid (); +#if defined(HAVE_SETEUID) + seteuid (getuid ()); +#elif defined(HAVE_SETRESUID) + setresuid (-1, getuid (), -1); +#endif +#if defined(HAVE_SETEGID) + setegid (getgid ()); +#elif defined(HAVE_SETRESGID) + setresgid (-1, getgid (), -1); +#endif + + if (g_path_is_absolute (module_name)) + load_module (module_name, name, args, &method, &transform); + else + load_module_in_path_list (module_name, name, args, &method, &transform); + +#if defined(HAVE_SETEUID) + seteuid (saved_uid); +#elif defined(HAVE_SETRESUID) + setresuid (-1, saved_uid, -1); +#endif +#if defined(HAVE_SETEGID) + setegid (saved_gid); +#elif defined(HAVE_SETRESGID) + setresgid (-1, saved_gid, -1); +#endif + + if (method == NULL && transform == NULL) + goto add_module_out; + + module_element = g_new (ModuleElement, 1); + module_element->name = g_strdup (name); + module_element->method = method; + module_element->transform = transform; + + g_hash_table_insert (module_hash, module_element->name, module_element); + + add_module_out: + g_static_rec_mutex_unlock (&module_hash_lock); + + return module_element; +} + +GnomeVFSMethod * +gnome_vfs_method_get (const gchar *name) +{ + ModuleElement *module_element; + + g_return_val_if_fail (name != NULL, NULL); + + module_element = gnome_vfs_add_module_to_hash_table (name); + return module_element ? module_element->method : NULL; +} + +GnomeVFSTransform * +gnome_vfs_transform_get (const gchar *name) +{ + ModuleElement *module_element; + + g_return_val_if_fail (name != NULL, NULL); + + module_element = gnome_vfs_add_module_to_hash_table (name); + return module_element ? module_element->transform : NULL; +} diff --git a/libgnomevfs/gnome-vfs-method.h b/libgnomevfs/gnome-vfs-method.h new file mode 100644 index 0000000..e9c5487 --- /dev/null +++ b/libgnomevfs/gnome-vfs-method.h @@ -0,0 +1,265 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-method.h - Virtual class for access methods in the GNOME + Virtual File System. + + Copyright (C) 1999, 2001 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli + Seth Nickell +*/ + +#ifndef GNOME_VFS_METHOD_H +#define GNOME_VFS_METHOD_H + +/* + * The following include helps Solaris copy with its own headers. (With 64- + * bit stuff enabled they like to #define open open64, etc.) + * See http://bugzilla.gnome.org/show_bug.cgi?id=71184 for details. + */ +#include + +#include +#include +#include +#include +#include +#include + +G_BEGIN_DECLS + +#define _GNOME_VFS_METHOD_PARAM_CHECK(expression) \ + g_return_val_if_fail ((expression), GNOME_VFS_ERROR_BAD_PARAMETERS); + +typedef struct GnomeVFSMethod GnomeVFSMethod; + +typedef GnomeVFSMethod * (* GnomeVFSMethodInitFunc)(const char *method_name, const char *config_args); +typedef void (*GnomeVFSMethodShutdownFunc)(GnomeVFSMethod *method); + +typedef GnomeVFSResult (* GnomeVFSMethodOpenFunc) + (GnomeVFSMethod *method, + GnomeVFSMethodHandle + **method_handle_return, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + GnomeVFSContext *context); + +typedef GnomeVFSResult (* GnomeVFSMethodCreateFunc) + (GnomeVFSMethod *method, + GnomeVFSMethodHandle + **method_handle_return, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + gboolean exclusive, + guint perm, + GnomeVFSContext *context); + +typedef GnomeVFSResult (* GnomeVFSMethodCloseFunc) + (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context); + +typedef GnomeVFSResult (* GnomeVFSMethodReadFunc) + (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read_return, + GnomeVFSContext *context); + +typedef GnomeVFSResult (* GnomeVFSMethodWriteFunc) + (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gconstpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_written_return, + GnomeVFSContext *context); + +typedef GnomeVFSResult (* GnomeVFSMethodSeekFunc) + (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSSeekPosition whence, + GnomeVFSFileOffset offset, + GnomeVFSContext *context); + +typedef GnomeVFSResult (* GnomeVFSMethodTellFunc) + (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileOffset *offset_return); + +typedef GnomeVFSResult (* GnomeVFSMethodOpenDirectoryFunc) + (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context); + +typedef GnomeVFSResult (* GnomeVFSMethodCloseDirectoryFunc) + (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context); + +typedef GnomeVFSResult (* GnomeVFSMethodReadDirectoryFunc) + (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSContext *context); + +typedef GnomeVFSResult (* GnomeVFSMethodGetFileInfoFunc) + (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context); + +typedef GnomeVFSResult (* GnomeVFSMethodGetFileInfoFromHandleFunc) + (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context); + +typedef GnomeVFSResult (* GnomeVFSMethodTruncateFunc) (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileSize length, + GnomeVFSContext *context); +typedef GnomeVFSResult (* GnomeVFSMethodTruncateHandleFunc) (GnomeVFSMethod *method, + GnomeVFSMethodHandle *handle, + GnomeVFSFileSize length, + GnomeVFSContext *context); + +typedef gboolean (* GnomeVFSMethodIsLocalFunc) + (GnomeVFSMethod *method, + const GnomeVFSURI *uri); + +typedef GnomeVFSResult (* GnomeVFSMethodMakeDirectoryFunc) + (GnomeVFSMethod *method, + GnomeVFSURI *uri, + guint perm, + GnomeVFSContext *context); + +typedef GnomeVFSResult (* GnomeVFSMethodFindDirectoryFunc) + (GnomeVFSMethod *method, + GnomeVFSURI *find_near_uri, + GnomeVFSFindDirectoryKind kind, + GnomeVFSURI **result_uri, + gboolean create_if_needed, + gboolean find_if_needed, + guint perm, + GnomeVFSContext *context); + +typedef GnomeVFSResult (* GnomeVFSMethodRemoveDirectoryFunc) + (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSContext *context); + +typedef GnomeVFSResult (* GnomeVFSMethodMoveFunc) + (GnomeVFSMethod *method, + GnomeVFSURI *old_uri, + GnomeVFSURI *new_uri, + gboolean force_replace, + GnomeVFSContext *context); + +typedef GnomeVFSResult (* GnomeVFSMethodUnlinkFunc) + (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSContext *context); + +typedef GnomeVFSResult (* GnomeVFSMethodCheckSameFSFunc) + (GnomeVFSMethod *method, + GnomeVFSURI *a, + GnomeVFSURI *b, + gboolean *same_fs_return, + GnomeVFSContext *context); + +typedef GnomeVFSResult (* GnomeVFSMethodSetFileInfo) + (GnomeVFSMethod *method, + GnomeVFSURI *a, + const GnomeVFSFileInfo *info, + GnomeVFSSetFileInfoMask mask, + GnomeVFSContext *context); + +typedef GnomeVFSResult (* GnomeVFSMethodCreateSymbolicLinkFunc) + (GnomeVFSMethod *method, + GnomeVFSURI *uri, + const gchar *target_reference, + GnomeVFSContext *context); +typedef GnomeVFSResult (* GnomeVFSMethodMonitorAddFunc) + (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle_return, + GnomeVFSURI *uri, + GnomeVFSMonitorType monitor_type); + +typedef GnomeVFSResult (* GnomeVFSMethodMonitorCancelFunc) + (GnomeVFSMethod *method, + GnomeVFSMethodHandle *handle); + +typedef GnomeVFSResult (* GnomeVFSMethodFileControlFunc) + (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + const char *operation, + gpointer operation_data, + GnomeVFSContext *context); + + + +/* Use this macro to test whether a given function is implemented in + * a given GnomeVFSMethod. Note that it checks the expected size of the structure + * prior to testing NULL. + */ + +#define VFS_METHOD_HAS_FUNC(method,func) ((((char *)&((method)->func)) - ((char *)(method)) < (method)->method_table_size) && method->func != NULL) + +/* Structure defining an access method. This is also defined as an + opaque type in `gnome-vfs-types.h'. */ +struct GnomeVFSMethod { + gsize method_table_size; /* Used for versioning */ + GnomeVFSMethodOpenFunc open; + GnomeVFSMethodCreateFunc create; + GnomeVFSMethodCloseFunc close; + GnomeVFSMethodReadFunc read; + GnomeVFSMethodWriteFunc write; + GnomeVFSMethodSeekFunc seek; + GnomeVFSMethodTellFunc tell; + GnomeVFSMethodTruncateHandleFunc truncate_handle; + GnomeVFSMethodOpenDirectoryFunc open_directory; + GnomeVFSMethodCloseDirectoryFunc close_directory; + GnomeVFSMethodReadDirectoryFunc read_directory; + GnomeVFSMethodGetFileInfoFunc get_file_info; + GnomeVFSMethodGetFileInfoFromHandleFunc get_file_info_from_handle; + GnomeVFSMethodIsLocalFunc is_local; + GnomeVFSMethodMakeDirectoryFunc make_directory; + GnomeVFSMethodRemoveDirectoryFunc remove_directory; + GnomeVFSMethodMoveFunc move; + GnomeVFSMethodUnlinkFunc unlink; + GnomeVFSMethodCheckSameFSFunc check_same_fs; + GnomeVFSMethodSetFileInfo set_file_info; + GnomeVFSMethodTruncateFunc truncate; + GnomeVFSMethodFindDirectoryFunc find_directory; + GnomeVFSMethodCreateSymbolicLinkFunc create_symbolic_link; + GnomeVFSMethodMonitorAddFunc monitor_add; + GnomeVFSMethodMonitorCancelFunc monitor_cancel; + GnomeVFSMethodFileControlFunc file_control; +}; + +gboolean gnome_vfs_method_init (void); +GnomeVFSMethod *gnome_vfs_method_get (const gchar *name); +GnomeVFSTransform *gnome_vfs_transform_get (const gchar *name); + +G_END_DECLS + +#endif /* GNOME_VFS_METHOD_H */ diff --git a/libgnomevfs/gnome-vfs-mime-handlers.c b/libgnomevfs/gnome-vfs-mime-handlers.c new file mode 100644 index 0000000..73252a5 --- /dev/null +++ b/libgnomevfs/gnome-vfs-mime-handlers.c @@ -0,0 +1,2340 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-mime-handlers.c - Mime type handlers for the GNOME Virtual + File System. + + Copyright (C) 2000 Eazel, Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Maciej Stachowiak */ + +#include +#include "gnome-vfs-mime-handlers.h" + +#include "gnome-vfs-application-registry.h" +#include "gnome-vfs-mime-info.h" +#include "gnome-vfs-mime.h" +#include "gnome-vfs-result.h" +#include "gnome-vfs-private-utils.h" +#include "gnome-vfs-utils.h" +#include +#include +#include +#include + +#define GCONF_DEFAULT_VIEWER_EXEC_PATH "/desktop/gnome/applications/component_viewer/exec" + + +static GnomeVFSResult expand_parameters (gpointer action, + GnomeVFSMimeActionType type, + GList *uris, + int *argc, + char ***argv); +static GList * Bonobo_ServerInfoList_to_ServerInfo_g_list (Bonobo_ServerInfoList *info_list); +static GList * copy_str_list (GList *string_list); +static GList * comma_separated_str_to_str_list (const char *str); +static GList * str_list_difference (GList *a, + GList *b); +static char * str_list_to_comma_separated_str (GList *list); +static void g_list_free_deep (GList *list); +static GList * prune_ids_for_nonexistent_applications (GList *list); +static GnomeVFSResult gnome_vfs_mime_edit_user_file (const char *mime_type, + const char *key, + const char *value); +static gboolean application_known_to_be_nonexistent (const char *application_id); +static const char *gnome_vfs_mime_maybe_get_user_level_value (const char *mime_type, + const char *key); + + +/** + * gnome_vfs_mime_get_description: + * @mime_type: the mime type + * + * Query the MIME database for a description of the specified MIME type. + * + * Return value: A description of MIME type @mime_type + */ +const char * +gnome_vfs_mime_get_description (const char *mime_type) +{ + return gnome_vfs_mime_get_value (mime_type, "description"); +} + +/** + * gnome_vfs_mime_set_description: + * @mime_type: A const char * containing a mime type + * @description: A description of this MIME type + * + * Set the description of this MIME type in the MIME database. The description + * should be something like "Gnumeric spreadsheet". + * + * Return value: GnomeVFSResult indicating the success of the operation or any + * errors that may have occurred. + **/ +GnomeVFSResult +gnome_vfs_mime_set_description (const char *mime_type, const char *description) +{ + return gnome_vfs_mime_edit_user_file + (mime_type, "description", description); +} + +/** + * gnome_vfs_mime_get_default_action_type: + * @mime_type: A const char * containing a mime type, e.g. "application/x-php" + * + * Query the MIME database for the type of action to be performed on a particular MIME type by default. + * + * Return value: The type of action to be performed on a file of + * MIME type, @mime_type by default. + **/ +GnomeVFSMimeActionType +gnome_vfs_mime_get_default_action_type (const char *mime_type) +{ + const char *action_type_string; + + action_type_string = gnome_vfs_mime_get_value (mime_type, "default_action_type"); + + if (action_type_string != NULL && g_ascii_strcasecmp (action_type_string, "application") == 0) { + return GNOME_VFS_MIME_ACTION_TYPE_APPLICATION; + } else if (action_type_string != NULL && g_ascii_strcasecmp (action_type_string, "component") == 0) { + return GNOME_VFS_MIME_ACTION_TYPE_COMPONENT; + } else { + return GNOME_VFS_MIME_ACTION_TYPE_NONE; + } + +} + +/** + * gnome_vfs_mime_get_default_action: + * @mime_type: A const char * containing a mime type, e.g. "application/x-php" + * + * Query the MIME database for default action associated with a particular MIME type @mime_type. + * + * Return value: A GnomeVFSMimeAction representing the default action to perform upon + * file of type @mime_type. + **/ +GnomeVFSMimeAction * +gnome_vfs_mime_get_default_action (const char *mime_type) +{ + GnomeVFSMimeAction *action; + + action = g_new0 (GnomeVFSMimeAction, 1); + + action->action_type = gnome_vfs_mime_get_default_action_type (mime_type); + + switch (action->action_type) { + case GNOME_VFS_MIME_ACTION_TYPE_APPLICATION: + action->action.application = + gnome_vfs_mime_get_default_application (mime_type); + if (action->action.application == NULL) { + g_free (action); + action = NULL; + } + break; + case GNOME_VFS_MIME_ACTION_TYPE_COMPONENT: + action->action.component = + gnome_vfs_mime_get_default_component (mime_type); + if (action->action.component == NULL) { + g_free (action); + action = NULL; + } + break; + case GNOME_VFS_MIME_ACTION_TYPE_NONE: + g_free (action); + action = NULL; + break; + default: + g_assert_not_reached (); + } + + return action; +} + +/** + * gnome_vfs_mime_get_default_application: + * @mime_type: A const char * containing a mime type, e.g. "image/png" + * + * Query the MIME database for the application to be executed on files of MIME type + * @mime_type by default. + * + * Return value: A GnomeVFSMimeApplication representing the default handler of @mime_type + **/ +GnomeVFSMimeApplication * +gnome_vfs_mime_get_default_application (const char *mime_type) +{ + const char *default_application_id; + GnomeVFSMimeApplication *default_application; + GList *short_list; + + default_application = NULL; + + /* First, try the default for the mime type */ + default_application_id = gnome_vfs_mime_get_value + (mime_type, "default_application_id"); + + if (default_application_id != NULL + && default_application_id[0] != '\0' + && !application_known_to_be_nonexistent (default_application_id)) { + default_application = + gnome_vfs_application_registry_get_mime_application (default_application_id); + } + + if (default_application == NULL) { + /* Failing that, try something from the short list */ + + short_list = gnome_vfs_mime_get_short_list_applications (mime_type); + + if (short_list != NULL) { + default_application = gnome_vfs_mime_application_copy + ((GnomeVFSMimeApplication *) (short_list->data)); + gnome_vfs_mime_application_list_free (short_list); + } + } + + + return default_application; +} + +/** + * gnome_vfs_mime_get_icon: + * @mime_type: A const char * containing a MIME type + * + * Query the MIME database for an icon representing the specified MIME type. + * + * Return value: The filename of the icon as listed in the MIME database. This is + * usually a filename without path information, e.g. "i-chardev.png", and sometimes + * does not have an extension, e.g. "i-regular" if the icon is supposed to be image + * type agnostic between icon themes. Icons are generic, and not theme specific. These + * will not necessarily match with the icons a user sees in Nautilus, you have been warned. + */ +const char * +gnome_vfs_mime_get_icon (const char *mime_type) +{ + return gnome_vfs_mime_get_value (mime_type, "icon_filename"); +} + +/** + * gnome_vfs_mime_set_icon: + * @mime_type: A const char * containing a MIME type + * @filename: a const char * containing an image filename + * + * Set the icon entry for a particular MIME type in the MIME database. Note that + * icon entries need not necessarily contain the full path, and do not necessarily need to + * specify an extension. So "i-regular", "my-special-icon.png", and "some-icon" + * are all valid icon filenames. + * + * Return value: A GnomeVFSResult indicating the success of the operation + * or any errors that may have occurred. + */ +GnomeVFSResult +gnome_vfs_mime_set_icon (const char *mime_type, const char *filename) +{ + return gnome_vfs_mime_edit_user_file + (mime_type, "icon_filename", filename); +} + + +/** + * gnome_vfs_mime_can_be_executable: + * @mime_type: A const char * containing a mime type + * + * Check whether files of this MIME type might conceivably be executable. + * Default for known types if FALSE. Default for unknown types is TRUE. + * + * Return value: gboolean containing TRUE if some files of this MIME type + * are registered as being executable, and false otherwise. + **/ +gboolean +gnome_vfs_mime_can_be_executable (const char *mime_type) +{ + const char *result_as_string; + gboolean result; + + result_as_string = gnome_vfs_mime_get_value (mime_type, "can_be_executable"); + if (result_as_string != NULL) { + result = strcmp (result_as_string, "TRUE") == 0; + } else { + /* If type is not known, we treat it as potentially executable. + * If type is known, we use default value of not executable. + */ + result = !gnome_vfs_mime_type_is_known (mime_type); + } + + return result; +} + +/** + * gnome_vfs_mime_set_can_be_executable: + * @mime_type: A const char * containing a mime type + * @new_value: A boolean value indicating whether @mime_type could be executable. + * + * Set whether files of this MIME type might conceivably be executable. + * + * Return value: GnomeVFSResult indicating the success of the operation or any + * errors that may have occurred. + **/ +GnomeVFSResult +gnome_vfs_mime_set_can_be_executable (const char *mime_type, gboolean new_value) +{ + return gnome_vfs_mime_edit_user_file + (mime_type, "can_be_executable", new_value ? "TRUE" : "FALSE"); +} + +/** + * gnome_vfs_mime_get_default_component: + * @mime_type: A const char * containing a mime type, e.g. "image/png" + * + * Query the MIME database for the default Bonobo component to be activated to + * view files of MIME type @mime_type. + * + * Return value: An Bonobo_ServerInfo * representing the OAF server to be activated + * to get a reference to the proper component. + **/ +Bonobo_ServerInfo * +gnome_vfs_mime_get_default_component (const char *mime_type) +{ + const char *default_component_iid; + Bonobo_ServerInfoList *info_list; + Bonobo_ServerInfo *default_component; + CORBA_Environment ev; + char *supertype; + char *query; + char *sort[6]; + GList *short_list; + GList *p; + char *prev; + + if (mime_type == NULL) { + return NULL; + } + + CORBA_exception_init (&ev); + + supertype = gnome_vfs_get_supertype_from_mime_type (mime_type); + + /* Find a component that supports either the exact mime type, + the supertype, or all mime types. */ + + /* First try the component specified in the mime database, if available. + gnome_vfs_mime_get_value looks up the value for the mime type and the supertype. */ + default_component_iid = gnome_vfs_mime_get_value + (mime_type, "default_component_iid"); + + query = g_strconcat ("bonobo:supported_mime_types.has_one (['", mime_type, + "', '", supertype, + "', '*'])", NULL); + + + if (default_component_iid != NULL) { + sort[0] = g_strconcat ("iid == '", default_component_iid, "'", NULL); + } else { + sort[0] = g_strdup ("true"); + } + + short_list = gnome_vfs_mime_get_short_list_components (mime_type); + short_list = g_list_concat (short_list, + gnome_vfs_mime_get_short_list_components (supertype)); + if (short_list != NULL) { + sort[1] = g_strdup ("prefer_by_list_order(iid, ['"); + + for (p = short_list; p != NULL; p = p->next) { + prev = sort[1]; + + if (p->next != NULL) { + sort[1] = g_strconcat (prev, ((Bonobo_ServerInfo *) (p->data))->iid, + "','", NULL); + } else { + sort[1] = g_strconcat (prev, ((Bonobo_ServerInfo *) (p->data))->iid, + "'])", NULL); + } + g_free (prev); + } + gnome_vfs_mime_component_list_free (short_list); + } else { + sort[1] = g_strdup ("true"); + } + + + /* Prefer something that matches the exact type to something + that matches the supertype */ + sort[2] = g_strconcat ("bonobo:supported_mime_types.has ('", mime_type, "')", NULL); + + /* Prefer something that matches the supertype to something that matches `*' */ + sort[3] = g_strconcat ("bonobo:supported_mime_types.has ('", supertype, "')", NULL); + + sort[4] = g_strdup ("name"); + sort[5] = NULL; + + info_list = bonobo_activation_query (query, sort, &ev); + + default_component = NULL; + if (ev._major == CORBA_NO_EXCEPTION) { + if (info_list != NULL && info_list->_length > 0) { + default_component = Bonobo_ServerInfo_duplicate (&info_list->_buffer[0]); + } + CORBA_free (info_list); + } + + g_free (supertype); + g_free (query); + g_free (sort[0]); + g_free (sort[1]); + g_free (sort[2]); + g_free (sort[3]); + g_free (sort[4]); + + CORBA_exception_free (&ev); + + return default_component; +} + +static GList * +gnome_vfs_mime_str_list_merge (GList *a, + GList *b) +{ + GList *pruned_b; + GList *extended_a; + GList *a_copy; + + pruned_b = str_list_difference (b, a); + + a_copy = g_list_copy (a); + extended_a = g_list_concat (a_copy, pruned_b); + + /* No need to free a_copy or + * pruned_b since they were concat()ed into + * extended_a + */ + + return extended_a; +} + + +static GList * +gnome_vfs_mime_str_list_apply_delta (GList *list_to_process, + GList *additions, + GList *removals) +{ + GList *extended_original_list; + GList *processed_list; + + extended_original_list = gnome_vfs_mime_str_list_merge (list_to_process, additions); + + processed_list = str_list_difference (extended_original_list, removals); + + g_list_free (extended_original_list); + + return processed_list; +} + +static GList * +gnome_vfs_mime_do_short_list_processing (GList *short_list, + GList *additions, + GList *removals, + GList *supertype_short_list, + GList *supertype_additions, + GList *supertype_removals) +{ + GList *processed_supertype_list; + GList *merged_system_and_supertype; + GList *final_list; + + processed_supertype_list = gnome_vfs_mime_str_list_apply_delta (supertype_short_list, + supertype_additions, + supertype_removals); + + merged_system_and_supertype = gnome_vfs_mime_str_list_merge (short_list, + processed_supertype_list); + + final_list = gnome_vfs_mime_str_list_apply_delta (merged_system_and_supertype, + additions, + removals); + + g_list_free (processed_supertype_list); + g_list_free (merged_system_and_supertype); + + return final_list; +} + + +/* sort_application_list + * + * Sort list alphabetically + */ + +static int +sort_application_list (gconstpointer a, gconstpointer b) +{ + GnomeVFSMimeApplication *application1, *application2; + + application1 = (GnomeVFSMimeApplication *) a; + application2 = (GnomeVFSMimeApplication *) b; + + return g_ascii_strcasecmp (application1->name, application2->name); +} + +/** + * gnome_vfs_mime_get_short_list_applications: + * @mime_type: A const char * containing a mime type, e.g. "image/png" + * + * Return an alphabetically sorted list of GnomeVFSMimeApplication + * data structures for the requested mime type. The short list contains + * "select" applications recommended for handling this MIME type, appropriate for + * display to the user. + * + * Return value: A GList * where the elements are GnomeVFSMimeApplication * + * representing various applications to display in the short list for @mime_type. + **/ +GList * +gnome_vfs_mime_get_short_list_applications (const char *mime_type) +{ + GList *system_short_list; + GList *short_list_additions; + GList *short_list_removals; + char *supertype; + GList *supertype_short_list; + GList *supertype_additions; + GList *supertype_removals; + GList *id_list; + GList *p; + GnomeVFSMimeApplication *application; + GList *preferred_applications; + + if (mime_type == NULL) { + return NULL; + } + + + system_short_list = comma_separated_str_to_str_list (gnome_vfs_mime_maybe_get_user_level_value + (mime_type, + "short_list_application_ids")); + system_short_list = prune_ids_for_nonexistent_applications + (system_short_list); + + /* get user short list delta (add list and remove list) */ + + short_list_additions = comma_separated_str_to_str_list (gnome_vfs_mime_get_value + (mime_type, + "short_list_application_user_additions")); + short_list_additions = prune_ids_for_nonexistent_applications (short_list_additions); + short_list_removals = comma_separated_str_to_str_list (gnome_vfs_mime_get_value + (mime_type, + "short_list_application_user_removals")); + + /* Only include the supertype in the short list if we came up empty with + the specific types */ + supertype = gnome_vfs_get_supertype_from_mime_type (mime_type); + + if (!gnome_vfs_mime_type_is_supertype (mime_type) && system_short_list == NULL) { + supertype_short_list = comma_separated_str_to_str_list + (gnome_vfs_mime_maybe_get_user_level_value + (supertype, + "short_list_application_ids")); + supertype_short_list = prune_ids_for_nonexistent_applications + (supertype_short_list); + + /* get supertype short list delta (add list and remove list) */ + + supertype_additions = comma_separated_str_to_str_list + (gnome_vfs_mime_get_value + (supertype, + "short_list_application_user_additions")); + supertype_removals = comma_separated_str_to_str_list + (gnome_vfs_mime_get_value + (supertype, + "short_list_application_user_removals")); + } else { + supertype_short_list = NULL; + supertype_additions = NULL; + supertype_removals = NULL; + } + g_free (supertype); + + + /* compute list modified by delta */ + + id_list = gnome_vfs_mime_do_short_list_processing (system_short_list, + short_list_additions, + short_list_removals, + supertype_short_list, + supertype_additions, + supertype_removals); + + preferred_applications = NULL; + + for (p = id_list; p != NULL; p = p->next) { + application = gnome_vfs_application_registry_get_mime_application (p->data); + if (application != NULL) { + preferred_applications = g_list_prepend + (preferred_applications, application); + } + } + + + preferred_applications = g_list_reverse (preferred_applications); + + g_list_free_deep (system_short_list); + g_list_free_deep (short_list_additions); + g_list_free_deep (short_list_removals); + g_list_free_deep (supertype_short_list); + g_list_free_deep (supertype_additions); + g_list_free_deep (supertype_removals); + g_list_free (id_list); + + /* Sort list alphabetically by application name */ + preferred_applications = g_list_sort (preferred_applications, sort_application_list); + + return preferred_applications; +} + + + +static char * +join_str_list (const char *separator, GList *list) +{ + char **strv; + GList *p; + int i; + char *retval; + + /* Convert to a strv so we can use g_strjoinv. + * Saves code but could be made faster if we want. + */ + strv = g_new0 (char *, g_list_length (list) + 1); + for (p = list, i = 0; p != NULL; p = p->next, i++) { + strv[i] = (char *) p->data; + } + strv[i] = NULL; + + retval = g_strjoinv (separator, strv); + + g_free (strv); + + return retval; +} + + +/** + * gnome_vfs_mime_get_short_list_components: + * @mime_type: A const char * containing a mime type, e.g. "image/png" + * + * Return an unsorted sorted list of Bonobo_ServerInfo * + * data structures for the requested mime type. The short list contains + * "select" components recommended for handling this MIME type, appropriate for + * display to the user. + * + * Return value: A GList * where the elements are Bonobo_ServerInfo * + * representing various components to display in the short list for @mime_type. + **/ +GList * +gnome_vfs_mime_get_short_list_components (const char *mime_type) +{ + GList *system_short_list; + GList *short_list_additions; + GList *short_list_removals; + char *supertype; + GList *supertype_short_list; + GList *supertype_additions; + GList *supertype_removals; + GList *iid_list; + char *query; + char *sort[2]; + char *iids_delimited; + CORBA_Environment ev; + Bonobo_ServerInfoList *info_list; + GList *preferred_components; + + if (mime_type == NULL) { + return NULL; + } + + + /* get short list IIDs for that user level */ + system_short_list = comma_separated_str_to_str_list (gnome_vfs_mime_get_value + (mime_type, + "short_list_component_iids")); + + /* get user short list delta (add list and remove list) */ + + short_list_additions = comma_separated_str_to_str_list (gnome_vfs_mime_get_value + (mime_type, + "short_list_component_user_additions")); + + short_list_removals = comma_separated_str_to_str_list (gnome_vfs_mime_get_value + (mime_type, + "short_list_component_user_removals")); + + + supertype = gnome_vfs_get_supertype_from_mime_type (mime_type); + + if (strcmp (supertype, mime_type) != 0) { + supertype_short_list = comma_separated_str_to_str_list + (gnome_vfs_mime_get_value + (supertype, + "short_list_component_iids")); + + /* get supertype short list delta (add list and remove list) */ + + supertype_additions = comma_separated_str_to_str_list + (gnome_vfs_mime_get_value + (supertype, + "short_list_component_user_additions")); + supertype_removals = comma_separated_str_to_str_list + (gnome_vfs_mime_get_value + (supertype, + "short_list_component_user_removals")); + } else { + supertype_short_list = NULL; + supertype_additions = NULL; + supertype_removals = NULL; + } + + /* compute list modified by delta */ + + iid_list = gnome_vfs_mime_do_short_list_processing (system_short_list, + short_list_additions, + short_list_removals, + supertype_short_list, + supertype_additions, + supertype_removals); + + + + /* Do usual query but requiring that IIDs be one of the ones + in the short list IID list. */ + + preferred_components = NULL; + if (iid_list != NULL) { + CORBA_exception_init (&ev); + + iids_delimited = join_str_list ("','", iid_list); + + query = g_strconcat ("bonobo:supported_mime_types.has_one (['", mime_type, + "', '", supertype, + "', '*'])", + " AND has(['", iids_delimited, "'], iid)", NULL); + + sort[0] = g_strconcat ("prefer_by_list_order(iid, ['", iids_delimited, "'])", NULL); + sort[1] = NULL; + + info_list = bonobo_activation_query (query, sort, &ev); + + if (ev._major == CORBA_NO_EXCEPTION) { + preferred_components = Bonobo_ServerInfoList_to_ServerInfo_g_list (info_list); + CORBA_free (info_list); + } + + g_free (iids_delimited); + g_free (query); + g_free (sort[0]); + + CORBA_exception_free (&ev); + } + + g_free (supertype); + g_list_free_deep (system_short_list); + g_list_free_deep (short_list_additions); + g_list_free_deep (short_list_removals); + g_list_free_deep (supertype_short_list); + g_list_free_deep (supertype_additions); + g_list_free_deep (supertype_removals); + g_list_free (iid_list); + + return preferred_components; +} + + +/** + * gnome_vfs_mime_get_all_applications: + * @mime_type: A const char * containing a mime type, e.g. "image/png" + * + * Return an alphabetically sorted list of GnomeVFSMimeApplication + * data structures representing all applications in the MIME database registered + * to handle files of MIME type @mime_type (and supertypes). + * + * Return value: A GList * where the elements are GnomeVFSMimeApplication * + * representing applications that handle MIME type @mime_type. + **/ +GList * +gnome_vfs_mime_get_all_applications (const char *mime_type) +{ + GList *applications, *node, *next; + char *application_id; + GnomeVFSMimeApplication *application; + + g_return_val_if_fail (mime_type != NULL, NULL); + + applications = gnome_vfs_application_registry_get_applications (mime_type); + + /* We get back a list of const char *, but the prune function + * wants a list of strings that we own. + */ + for (node = applications; node != NULL; node = node->next) { + node->data = g_strdup (node->data); + } + + /* Remove application ids representing nonexistent (not in path) applications */ + applications = prune_ids_for_nonexistent_applications (applications); + + /* Convert to GnomeVFSMimeApplication's (leaving out NULLs) */ + for (node = applications; node != NULL; node = next) { + next = node->next; + + application_id = node->data; + application = gnome_vfs_application_registry_get_mime_application (application_id); + + /* Replace the application ID with the application */ + if (application == NULL) { + applications = g_list_remove_link (applications, node); + g_list_free_1 (node); + } else { + node->data = application; + } + + g_free (application_id); + } + + return applications; +} + +/** + * gnome_vfs_mime_get_all_components: + * @mime_type: A const char * containing a mime type, e.g. "image/png" + * + * Return an alphabetically sorted list of Bonobo_ServerInfo + * data structures representing all Bonobo components registered + * to handle files of MIME type @mime_type (and supertypes). + * + * Return value: A GList * where the elements are Bonobo_ServerInfo * + * representing components that can handle MIME type @mime_type. + **/ +GList * +gnome_vfs_mime_get_all_components (const char *mime_type) +{ + Bonobo_ServerInfoList *info_list; + GList *components_list; + CORBA_Environment ev; + char *supertype; + char *query; + char *sort[2]; + + if (mime_type == NULL) { + return NULL; + } + + CORBA_exception_init (&ev); + + /* Find a component that supports either the exact mime type, + the supertype, or all mime types. */ + + /* FIXME bugzilla.eazel.com 1142: should probably check for + the right interfaces too. Also slightly semantically + different from nautilus in other tiny ways. + */ + supertype = gnome_vfs_get_supertype_from_mime_type (mime_type); + query = g_strconcat ("bonobo:supported_mime_types.has_one (['", mime_type, + "', '", supertype, + "', '*'])", NULL); + g_free (supertype); + + /* Alphebetize by name, for the sake of consistency */ + sort[0] = g_strdup ("name"); + sort[1] = NULL; + + info_list = bonobo_activation_query (query, sort, &ev); + + if (ev._major == CORBA_NO_EXCEPTION) { + components_list = Bonobo_ServerInfoList_to_ServerInfo_g_list (info_list); + CORBA_free (info_list); + } else { + components_list = NULL; + } + + g_free (query); + g_free (sort[0]); + + CORBA_exception_free (&ev); + + return components_list; +} + +static GnomeVFSResult +gnome_vfs_mime_edit_user_file_full (const char *mime_type, GList *keys, GList *values) +{ + GnomeVFSResult result; + GList *p, *q; + const char *key, *value; + + if (mime_type == NULL) { + return GNOME_VFS_OK; + } + + result = GNOME_VFS_OK; + + gnome_vfs_mime_freeze (); + for (p = keys, q = values; p != NULL && q != NULL; p = p->next, q = q->next) { + key = p->data; + value = q->data; + if (value == NULL) { + value = ""; + } + gnome_vfs_mime_set_value (mime_type, key, value); + } + gnome_vfs_mime_thaw (); + + return result; +} + +static GnomeVFSResult +gnome_vfs_mime_edit_user_file_args (const char *mime_type, va_list args) +{ + GList *keys, *values; + char *key, *value; + GnomeVFSResult result; + + keys = NULL; + values = NULL; + for (;;) { + key = va_arg (args, char *); + if (key == NULL) { + break; + } + value = va_arg (args, char *); + keys = g_list_prepend (keys, key); + values = g_list_prepend (values, value); + } + + result = gnome_vfs_mime_edit_user_file_full (mime_type, keys, values); + + g_list_free (keys); + g_list_free (values); + + return result; +} + +static GnomeVFSResult +gnome_vfs_mime_edit_user_file_multiple (const char *mime_type, ...) +{ + va_list args; + GnomeVFSResult result; + + va_start (args, mime_type); + result = gnome_vfs_mime_edit_user_file_args (mime_type, args); + va_end (args); + + return result; +} + +static GnomeVFSResult +gnome_vfs_mime_edit_user_file (const char *mime_type, const char *key, const char *value) +{ + g_return_val_if_fail (key != NULL, GNOME_VFS_OK); + return gnome_vfs_mime_edit_user_file_multiple (mime_type, key, value, NULL); +} + +/** + * gnome_vfs_mime_set_default_action_type: + * @mime_type: A const char * containing a mime type, e.g. "image/png" + * @action_type: A GnomeVFSMimeActionType containing the action to perform by default + * + * Sets the default action type to be performed on files of MIME type @mime_type. + * + * Return value: A GnomeVFSResult indicating the success of the operation or reporting + * any errors encountered. + **/ +GnomeVFSResult +gnome_vfs_mime_set_default_action_type (const char *mime_type, + GnomeVFSMimeActionType action_type) +{ + const char *action_string; + + switch (action_type) { + case GNOME_VFS_MIME_ACTION_TYPE_APPLICATION: + action_string = "application"; + break; + case GNOME_VFS_MIME_ACTION_TYPE_COMPONENT: + action_string = "component"; + break; + case GNOME_VFS_MIME_ACTION_TYPE_NONE: + default: + action_string = "none"; + } + + return gnome_vfs_mime_edit_user_file + (mime_type, "default_action_type", action_string); +} + +/** + * gnome_vfs_mime_set_default_application: + * @mime_type: A const char * containing a mime type, e.g. "application/x-php" + * @application_id: A key representing an application in the MIME database + * (GnomeVFSMimeApplication->id, for example) + * + * Sets the default application to be run on files of MIME type @mime_type. + * + * Return value: A GnomeVFSResult indicating the success of the operation or reporting + * any errors encountered. + **/ +GnomeVFSResult +gnome_vfs_mime_set_default_application (const char *mime_type, + const char *application_id) +{ + GnomeVFSResult result; + + result = gnome_vfs_mime_edit_user_file + (mime_type, "default_application_id", application_id); + + /* If there's no default action type, set it to match this. */ + if (result == GNOME_VFS_OK + && application_id != NULL + && gnome_vfs_mime_get_default_action_type (mime_type) == GNOME_VFS_MIME_ACTION_TYPE_NONE) { + result = gnome_vfs_mime_set_default_action_type (mime_type, GNOME_VFS_MIME_ACTION_TYPE_APPLICATION); + } + + return result; +} + +/** + * gnome_vfs_mime_set_default_component: + * @mime_type: A const char * containing a mime type, e.g. "application/x-php" + * @component_iid: The OAFIID of a component + * + * Sets the default component to be activated for files of MIME type @mime_type. + * + * Return value: A GnomeVFSResult indicating the success of the operation or reporting + * any errors encountered. + **/ +GnomeVFSResult +gnome_vfs_mime_set_default_component (const char *mime_type, + const char *component_iid) +{ + GnomeVFSResult result; + + result = gnome_vfs_mime_edit_user_file + (mime_type, "default_component_iid", component_iid); + + /* If there's no default action type, set it to match this. */ + if (result == GNOME_VFS_OK + && component_iid != NULL + && gnome_vfs_mime_get_default_action_type (mime_type) == GNOME_VFS_MIME_ACTION_TYPE_NONE) { + gnome_vfs_mime_set_default_action_type (mime_type, GNOME_VFS_MIME_ACTION_TYPE_COMPONENT); + } + + return result; +} + +/** + * gnome_vfs_mime_set_short_list_applications: + * @mime_type: A const char * containing a mime type, e.g. "application/x-php" + * @application_ids: GList of const char * application ids + * + * Set the short list of applications for the specified MIME type. The short list + * contains applications recommended for possible selection by the user. + * + * Return value: A GnomeVFSResult indicating the success of the operation or reporting + * any errors encountered. + **/ +GnomeVFSResult +gnome_vfs_mime_set_short_list_applications (const char *mime_type, + GList *application_ids) +{ + char *addition_string, *removal_string; + GList *short_list_id_list; + GList *short_list_addition_list; + GList *short_list_removal_list; + GnomeVFSResult result; + GList *it; + + /* Get base list. */ + short_list_id_list = comma_separated_str_to_str_list + (gnome_vfs_mime_maybe_get_user_level_value (mime_type, "short_list_application_ids")); + + /* Compute delta. */ + short_list_addition_list = str_list_difference (application_ids, short_list_id_list); + short_list_removal_list = str_list_difference (short_list_id_list, application_ids); + addition_string = str_list_to_comma_separated_str (short_list_addition_list); + removal_string = str_list_to_comma_separated_str (short_list_removal_list); + + /* Make sure the newly added app_ids are already associated to this + * mime type in the application registry + */ + for (it = short_list_addition_list; it != NULL; it = it->next) { + /* add_mime_type won't do anything if mime_type is already + * associated with it->data + */ + gnome_vfs_application_registry_add_mime_type (it->data, mime_type); + } + gnome_vfs_application_registry_sync (); + + g_list_free_deep (short_list_id_list); + g_list_free (short_list_addition_list); + g_list_free (short_list_removal_list); + + /* Write it. */ + result = gnome_vfs_mime_edit_user_file_multiple + (mime_type, + "short_list_application_user_additions", addition_string, + "short_list_application_user_removals", removal_string, + NULL); + + g_free (addition_string); + g_free (removal_string); + + return result; +} + +/** + * gnome_vfs_mime_set_short_list_components: + * @mime_type: A const char * containing a mime type, e.g. "application/x-php" + * @component_iids: GList of const char * OAF IIDs + * + * Set the short list of components for the specified MIME type. The short list + * contains companents recommended for possible selection by the user. * + * + * Return value: A GnomeVFSResult indicating the success of the operation or reporting + * any errors encountered. + **/ +GnomeVFSResult +gnome_vfs_mime_set_short_list_components (const char *mime_type, + GList *component_iids) +{ + char *addition_string, *removal_string; + GList *short_list_id_list; + GList *short_list_addition_list; + GList *short_list_removal_list; + GnomeVFSResult result; + + short_list_id_list = comma_separated_str_to_str_list + (gnome_vfs_mime_get_value (mime_type, "short_list_component_iids")); + + /* Compute delta. */ + short_list_addition_list = str_list_difference (component_iids, short_list_id_list); + short_list_removal_list = str_list_difference (short_list_id_list, component_iids); + addition_string = str_list_to_comma_separated_str (short_list_addition_list); + removal_string = str_list_to_comma_separated_str (short_list_removal_list); + g_list_free (short_list_addition_list); + g_list_free (short_list_removal_list); + + /* Write it. */ + result = gnome_vfs_mime_edit_user_file_multiple + (mime_type, + "short_list_component_user_additions", addition_string, + "short_list_component_user_removals", removal_string, + NULL); + + g_free (addition_string); + g_free (removal_string); + + return result; +} + +/* FIXME bugzilla.eazel.com 1148: + * The next set of helper functions are all replicated in nautilus-mime-actions.c. + * Need to refactor so they can share code. + */ +static gint +gnome_vfs_mime_application_has_id (GnomeVFSMimeApplication *application, const char *id) +{ + return strcmp (application->id, id); +} + +static gint +gnome_vfs_mime_id_matches_application (const char *id, GnomeVFSMimeApplication *application) +{ + return gnome_vfs_mime_application_has_id (application, id); +} + +static gint +gnome_vfs_mime_id_matches_component (const char *iid, Bonobo_ServerInfo *component) +{ + return strcmp (component->iid, iid); +} + +static gint +gnome_vfs_mime_application_matches_id (GnomeVFSMimeApplication *application, const char *id) +{ + return gnome_vfs_mime_id_matches_application (id, application); +} + +static gint +gnome_vfs_mime_component_matches_id (Bonobo_ServerInfo *component, const char *iid) +{ + return gnome_vfs_mime_id_matches_component (iid, component); +} + +/** + * gnome_vfs_mime_id_in_application_list: + * @id: An application id. + * @applications: A GList * whose nodes are GnomeVFSMimeApplications, such as the + * result of gnome_vfs_mime_get_short_list_applications(). + * + * Check whether an application id is in a list of GnomeVFSMimeApplications. + * + * Return value: TRUE if an application whose id matches @id is in @applications. + */ +gboolean +gnome_vfs_mime_id_in_application_list (const char *id, GList *applications) +{ + return g_list_find_custom + (applications, (gpointer) id, + (GCompareFunc) gnome_vfs_mime_application_matches_id) != NULL; +} + +/** + * gnome_vfs_mime_id_in_component_list: + * @iid: A component iid. + * @components: A GList * whose nodes are Bonobo_ServerInfos, such as the + * result of gnome_vfs_mime_get_short_list_components(). + * + * Check whether a component iid is in a list of Bonobo_ServerInfos. + * + * Return value: TRUE if a component whose iid matches @iid is in @components. + */ +gboolean +gnome_vfs_mime_id_in_component_list (const char *iid, GList *components) +{ + return g_list_find_custom + (components, (gpointer) iid, + (GCompareFunc) gnome_vfs_mime_component_matches_id) != NULL; + return FALSE; +} + +/** + * gnome_vfs_mime_id_list_from_application_list: + * @applications: A GList * whose nodes are GnomeVFSMimeApplications, such as the + * result of gnome_vfs_mime_get_short_list_applications(). + * + * Create a list of application ids from a list of GnomeVFSMimeApplications. + * + * Return value: A new list where each GnomeVFSMimeApplication in the original + * list is replaced by a char * with the application's id. The original list is + * not modified. + */ +GList * +gnome_vfs_mime_id_list_from_application_list (GList *applications) +{ + GList *result; + GList *node; + + result = NULL; + + for (node = applications; node != NULL; node = node->next) { + result = g_list_append + (result, g_strdup (((GnomeVFSMimeApplication *)node->data)->id)); + } + + return result; +} + +/** + * gnome_vfs_mime_id_list_from_component_list: + * @components: A GList * whose nodes are Bonobo_ServerInfos, such as the + * result of gnome_vfs_mime_get_short_list_components(). + * + * Create a list of component iids from a list of Bonobo_ServerInfos. + * + * Return value: A new list where each Bonobo_ServerInfo in the original + * list is replaced by a char * with the component's iid. The original list is + * not modified. + */ +GList * +gnome_vfs_mime_id_list_from_component_list (GList *components) +{ + GList *list = NULL; + GList *node; + + for (node = components; node != NULL; node = node->next) { + list = g_list_prepend + (list, g_strdup (((Bonobo_ServerInfo *)node->data)->iid)); + } + return g_list_reverse (list); +} + +static void +g_list_free_deep (GList *list) +{ + g_list_foreach (list, (GFunc) g_free, NULL); + g_list_free (list); +} + +/** + * gnome_vfs_mime_add_application_to_short_list: + * @mime_type: A const char * containing a mime type, e.g. "application/x-php" + * @application_id: const char * containing the application's id in the MIME database + * + * Add an application to the short list for MIME type @mime_type. The short list contains + * applications recommended for display as choices to the user for a particular MIME type. + * + * Return value: A GnomeVFSResult indicating the success of the operation or reporting + * any errors encountered. + **/ +GnomeVFSResult +gnome_vfs_mime_add_application_to_short_list (const char *mime_type, + const char *application_id) +{ + GList *old_list, *new_list; + GnomeVFSResult result; + + old_list = gnome_vfs_mime_get_short_list_applications (mime_type); + + if (gnome_vfs_mime_id_in_application_list (application_id, old_list)) { + result = GNOME_VFS_OK; + } else { + new_list = g_list_append (gnome_vfs_mime_id_list_from_application_list (old_list), + g_strdup (application_id)); + result = gnome_vfs_mime_set_short_list_applications (mime_type, new_list); + g_list_free_deep (new_list); + } + + gnome_vfs_mime_application_list_free (old_list); + + return result; +} + +/** + * gnome_vfs_mime_remove_application_from_list: + * @applications: A GList * whose nodes are GnomeVFSMimeApplications, such as the + * result of gnome_vfs_mime_get_short_list_applications(). + * @application_id: The id of an application to remove from @applications. + * @did_remove: If non-NULL, this is filled in with TRUE if the application + * was found in the list, FALSE otherwise. + * + * Remove an application specified by id from a list of GnomeVFSMimeApplications. + * + * Return value: The modified list. If the application is not found, the list will + * be unchanged. + */ +GList * +gnome_vfs_mime_remove_application_from_list (GList *applications, + const char *application_id, + gboolean *did_remove) +{ + GList *matching_node; + + matching_node = g_list_find_custom + (applications, (gpointer)application_id, + (GCompareFunc) gnome_vfs_mime_application_matches_id); + if (matching_node != NULL) { + applications = g_list_remove_link (applications, matching_node); + gnome_vfs_mime_application_list_free (matching_node); + } + + if (did_remove != NULL) { + *did_remove = matching_node != NULL; + } + + return applications; +} + +/** + * gnome_vfs_mime_remove_application_from_short_list: + * @mime_type: A const char * containing a mime type, e.g. "application/x-php" + * @application_id: const char * containing the application's id in the MIME database + * + * Remove an application from the short list for MIME type @mime_type. The short list contains + * applications recommended for display as choices to the user for a particular MIME type. + * + * Return value: A GnomeVFSResult indicating the success of the operation or reporting + * any errors encountered. + **/ +GnomeVFSResult +gnome_vfs_mime_remove_application_from_short_list (const char *mime_type, + const char *application_id) +{ + GnomeVFSResult result; + GList *old_list, *new_list; + gboolean was_in_list; + + old_list = gnome_vfs_mime_get_short_list_applications (mime_type); + old_list = gnome_vfs_mime_remove_application_from_list + (old_list, application_id, &was_in_list); + + if (!was_in_list) { + result = GNOME_VFS_OK; + } else { + new_list = gnome_vfs_mime_id_list_from_application_list (old_list); + result = gnome_vfs_mime_set_short_list_applications (mime_type, new_list); + g_list_free_deep (new_list); + } + + gnome_vfs_mime_application_list_free (old_list); + + return result; +} + +/** + * gnome_vfs_mime_add_component_to_short_list: + * @mime_type: A const char * containing a mime type, e.g. "application/x-php" + * @iid: const char * containing the component's OAF IID + * + * Add a component to the short list for MIME type @mime_type. The short list contains + * components recommended for display as choices to the user for a particular MIME type. + * + * Return value: A GnomeVFSResult indicating the success of the operation or reporting + * any errors encountered. + **/ +GnomeVFSResult +gnome_vfs_mime_add_component_to_short_list (const char *mime_type, + const char *iid) +{ + GnomeVFSResult result; + GList *old_list, *new_list; + + old_list = gnome_vfs_mime_get_short_list_components (mime_type); + + if (gnome_vfs_mime_id_in_component_list (iid, old_list)) { + result = GNOME_VFS_OK; + } else { + new_list = g_list_append (gnome_vfs_mime_id_list_from_component_list (old_list), + g_strdup (iid)); + result = gnome_vfs_mime_set_short_list_components (mime_type, new_list); + g_list_free_deep (new_list); + } + + gnome_vfs_mime_component_list_free (old_list); + + return result; +} + +/** + * gnome_vfs_mime_remove_component_from_list: + * @components: A GList * whose nodes are Bonobo_ServerInfos, such as the + * result of gnome_vfs_mime_get_short_list_components(). + * @iid: The iid of a component to remove from @components. + * @did_remove: If non-NULL, this is filled in with TRUE if the component + * was found in the list, FALSE otherwise. + * + * Remove a component specified by iid from a list of Bonobo_ServerInfos. + * + * Return value: The modified list. If the component is not found, the list will + * be unchanged. + */ +GList * +gnome_vfs_mime_remove_component_from_list (GList *components, + const char *iid, + gboolean *did_remove) +{ + GList *matching_node; + + matching_node = g_list_find_custom + (components, (gpointer)iid, + (GCompareFunc) gnome_vfs_mime_component_matches_id); + if (matching_node != NULL) { + components = g_list_remove_link (components, matching_node); + gnome_vfs_mime_component_list_free (matching_node); + } + + if (did_remove != NULL) { + *did_remove = matching_node != NULL; + } + return components; +} + +/** + * gnome_vfs_mime_remove_component_from_short_list: + * @mime_type: A const char * containing a mime type, e.g. "application/x-php" + * @iid: const char * containing the component's OAF IID + * + * Remove a component from the short list for MIME type @mime_type. The short list contains + * components recommended for display as choices to the user for a particular MIME type. + * + * Return value: A GnomeVFSResult indicating the success of the operation or reporting + * any errors encountered. + **/ +GnomeVFSResult +gnome_vfs_mime_remove_component_from_short_list (const char *mime_type, + const char *iid) +{ + GnomeVFSResult result; + GList *old_list, *new_list; + gboolean was_in_list; + + old_list = gnome_vfs_mime_get_short_list_components (mime_type); + old_list = gnome_vfs_mime_remove_component_from_list + (old_list, iid, &was_in_list); + + if (!was_in_list) { + result = GNOME_VFS_OK; + } else { + new_list = gnome_vfs_mime_id_list_from_component_list (old_list); + result = gnome_vfs_mime_set_short_list_components (mime_type, new_list); + g_list_free_deep (new_list); + } + + gnome_vfs_mime_component_list_free (old_list); + + return result; +} + +/** + * gnome_vfs_mime_add_extension: + * @extension: The extension to add (e.g. "txt") + * @mime_type: The mime type to add the mapping to. + * + * Add a file extension to the specificed MIME type in the MIME database. + * + * Return value: GnomeVFSResult indicating the success of the operation or any + * errors that may have occurred. + **/ +GnomeVFSResult +gnome_vfs_mime_add_extension (const char *mime_type, const char *extension) +{ + GnomeVFSResult result; + GList *list, *element; + gchar *extensions, *old_extensions; + + extensions = NULL; + old_extensions = NULL; + + result = GNOME_VFS_OK; + + list = gnome_vfs_mime_get_extensions_list (mime_type); + if (list == NULL) { + /* List is NULL. This means there are no current registered extensions. + * Add the new extension and it will cause the list to be created next time. + */ + result = gnome_vfs_mime_set_registered_type_key (mime_type, "ext", extension); + return result; + } + + /* Check for duplicates */ + for (element = list; element != NULL; element = element->next) { + if (strcmp (extension, (char *)element->data) == 0) { + gnome_vfs_mime_extensions_list_free (list); + return result; + } + } + + /* Add new extension to list */ + for (element = list; element != NULL; element = element->next) { + if (extensions != NULL) { + old_extensions = extensions; + extensions = g_strdup_printf ("%s %s", old_extensions, (char *)element->data); + g_free (old_extensions); + } else { + extensions = g_strdup_printf ("%s", (char *)element->data); + } + } + + if (extensions != NULL) { + old_extensions = extensions; + extensions = g_strdup_printf ("%s %s", old_extensions, extension); + g_free (old_extensions); + + /* Add extensions to hash table and flush into the file. */ + gnome_vfs_mime_set_registered_type_key (mime_type, "ext", extensions); + } + + gnome_vfs_mime_extensions_list_free (list); + + return result; +} + +/** + * gnome_vfs_mime_remove_extension: + * @extension: The extension to remove + * @mime_type: The mime type to remove the extension from + * + * Removes a file extension from the specificed MIME type in the MIME database. + * + * Return value: GnomeVFSResult indicating the success of the operation or any + * errors that may have occurred. + **/ +GnomeVFSResult +gnome_vfs_mime_remove_extension (const char *mime_type, const char *extension) +{ + GList *list, *element; + gchar *extensions, *old_extensions; + gboolean in_list; + GnomeVFSResult result; + + result = GNOME_VFS_OK; + extensions = NULL; + old_extensions = NULL; + in_list = FALSE; + + list = gnome_vfs_mime_get_extensions_list (mime_type); + if (list == NULL) { + return result; + } + + /* See if extension is in list */ + for (element = list; element != NULL; element = element->next) { + if (strcmp (extension, (char *)element->data) == 0) { + /* Remove extension from list */ + in_list = TRUE; + list = g_list_remove (list, element->data); + g_free (element->data); + element = NULL; + } + + if (in_list) { + break; + } + } + + /* Exit if we found no match */ + if (!in_list) { + gnome_vfs_mime_extensions_list_free (list); + return result; + } + + /* Create new extension list */ + for (element = list; element != NULL; element = element->next) { + if (extensions != NULL) { + old_extensions = extensions; + extensions = g_strdup_printf ("%s %s", old_extensions, (char *)element->data); + g_free (old_extensions); + } else { + extensions = g_strdup_printf ("%s", (char *)element->data); + } + } + + if (extensions != NULL) { + /* Add extensions to hash table and flush into the file */ + gnome_vfs_mime_set_registered_type_key (mime_type, "ext", extensions); + } else { + gnome_vfs_mime_set_registered_type_key (mime_type, "ext", ""); + } + + gnome_vfs_mime_extensions_list_free (list); + + return result; +} + +/** + * gnome_vfs_mime_extend_all_applications: + * @mime_type: A const char * containing a mime type, e.g. "application/x-php" + * @application_ids: a GList of const char * containing application ids + * + * Register @mime_type as being handled by all applications list in @application_ids. + * + * Return value: A GnomeVFSResult indicating the success of the operation or reporting + * any errors encountered. + **/ +GnomeVFSResult +gnome_vfs_mime_extend_all_applications (const char *mime_type, + GList *application_ids) +{ + GList *li; + + g_return_val_if_fail (mime_type != NULL, GNOME_VFS_ERROR_INTERNAL); + + for (li = application_ids; li != NULL; li = li->next) { + const char *application_id = li->data; + gnome_vfs_application_registry_add_mime_type (application_id, + mime_type); + } + + return gnome_vfs_application_registry_sync (); +} + +/** + * gnome_vfs_mime_remove_from_all_applications: + * @mime_type: A const char * containing a mime type, e.g. "application/x-php" + * @application_ids: a GList of const char * containing application ids + * + * Remove @mime_type as a handled type from every application in @application_ids + * + * Return value: A GnomeVFSResult indicating the success of the operation or reporting + * any errors encountered. + **/ +GnomeVFSResult +gnome_vfs_mime_remove_from_all_applications (const char *mime_type, + GList *application_ids) +{ + GList *li; + + g_return_val_if_fail (mime_type != NULL, GNOME_VFS_ERROR_INTERNAL); + + for (li = application_ids; li != NULL; li = li->next) { + const char *application_id = li->data; + gnome_vfs_application_registry_remove_mime_type (application_id, + mime_type); + } + + return gnome_vfs_application_registry_sync (); +} + + +/** + * gnome_vfs_mime_application_copy: + * @application: The GnomeVFSMimeApplication to be duplicated. + * + * Creates a newly referenced copy of a GnomeVFSMimeApplication object. + * + * Return value: A copy of @application + **/ +GnomeVFSMimeApplication * +gnome_vfs_mime_application_copy (GnomeVFSMimeApplication *application) +{ + GnomeVFSMimeApplication *result; + + if (application == NULL) { + return NULL; + } + + result = g_new0 (GnomeVFSMimeApplication, 1); + result->id = g_strdup (application->id); + result->name = g_strdup (application->name); + result->command = g_strdup (application->command); + result->can_open_multiple_files = application->can_open_multiple_files; + result->expects_uris = application->expects_uris; + result->supported_uri_schemes = copy_str_list (application->supported_uri_schemes); + result->requires_terminal = application->requires_terminal; + + return result; +} + +/** + * gnome_vfs_mime_application_free: + * @application: The GnomeVFSMimeApplication to be freed + * + * Frees a GnomeVFSMimeApplication *. + * + **/ +void +gnome_vfs_mime_application_free (GnomeVFSMimeApplication *application) +{ + if (application != NULL) { + g_free (application->name); + g_free (application->command); + g_list_foreach (application->supported_uri_schemes, + (GFunc) g_free, + NULL); + g_list_free (application->supported_uri_schemes); + g_free (application->id); + g_free (application); + } +} + +/** + * gnome_vfs_mime_action_free: + * @action: The GnomeVFSMimeAction to be freed + * + * Frees a GnomeVFSMimeAction *. + * + **/ +void +gnome_vfs_mime_action_free (GnomeVFSMimeAction *action) +{ + switch (action->action_type) { + case GNOME_VFS_MIME_ACTION_TYPE_APPLICATION: + gnome_vfs_mime_application_free (action->action.application); + break; + case GNOME_VFS_MIME_ACTION_TYPE_COMPONENT: + CORBA_free (action->action.component); + break; + default: + g_assert_not_reached (); + } + + g_free (action); +} + +/** + * gnome_vfs_mime_application_list_free: + * @list: a GList of GnomeVFSApplication * to be freed + * + * Frees lists of GnomeVFSApplications, as returned from functions such + * as gnome_vfs_get_all_applications(). + * + **/ +void +gnome_vfs_mime_application_list_free (GList *list) +{ + g_list_foreach (list, (GFunc) gnome_vfs_mime_application_free, NULL); + g_list_free (list); +} + +/** + * gnome_vfs_mime_component_list_free: + * @list: a GList of Bonobo_ServerInfo * to be freed + * + * Frees lists of Bonobo_ServerInfo * (as returned from functions such + * as @gnome_vfs_get_all_components) + * + **/ +void +gnome_vfs_mime_component_list_free (GList *list) +{ + g_list_foreach (list, (GFunc) CORBA_free, NULL); + g_list_free (list); +} + +/** + * gnome_vfs_mime_application_new_from_id: + * @id: A const char * containing an application id + * + * Fetches the GnomeVFSMimeApplication associated with the specified + * application ID from the MIME database. + * + * Return value: GnomeVFSMimeApplication * corresponding to @id + **/ +GnomeVFSMimeApplication * +gnome_vfs_mime_application_new_from_id (const char *id) +{ + return gnome_vfs_application_registry_get_mime_application (id); +} + +/** + * gnome_vfs_mime_action_launch: + * @action: the GnomeVFSMimeAction to launch + * @uris: parameters for the GnomeVFSMimeAction + * + * Launches the given mime action with the given parameters. If + * the action is an application the command line parameters will + * be expanded as required by the application. The application + * will also be launched in a terminal if that is required. If the + * application only supports one argument per instance then multile + * instances of the application will be launched. + * + * If the default action is a component it will be launched with + * the component viewer application defined using the gconf value: + * /desktop/gnome/application/component_viewer/exec. The parameters + * %s and %c in the command line will be replaced with the list of + * parameters and the default component IID respectively. + * + * Return value: GNOME_VFS_OK if the action was launched, + * GNOME_VFS_ERROR_BAD_PARAMETERS for an invalid action. + * GNOME_VFS_ERROR_NOT_SUPPORTED if the uri protocol is + * not supported by the action. + * GNOME_VFS_ERROR_PARSE if the action command can not be parsed. + * GNOME_VFS_ERROR_LAUNCH if the action command can not be launched. + * GNOME_VFS_ERROR_INTERNAL for other internal and GConf errors. + * + * Since: 2.4 + */ +GnomeVFSResult +gnome_vfs_mime_action_launch (GnomeVFSMimeAction *action, + GList *uris) +{ + return gnome_vfs_mime_action_launch_with_env (action, uris, NULL); +} + +/** + * gnome_vfs_mime_action_launch_with_env: + * + * Same as gnome_vfs_mime_action_launch except that the + * application or component viewer will be launched with + * the given environment. + * + * Return value: same as gnome_vfs_mime_action_launch + * + * Since: 2.4 + */ +GnomeVFSResult +gnome_vfs_mime_action_launch_with_env (GnomeVFSMimeAction *action, + GList *uris, + char **envp) +{ + GnomeVFSResult result; + char **argv; + int argc; + + g_return_val_if_fail (action != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail (uris != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + switch (action->action_type) { + case GNOME_VFS_MIME_ACTION_TYPE_APPLICATION: + + return gnome_vfs_mime_application_launch_with_env + (action->action.application, + uris, envp); + + case GNOME_VFS_MIME_ACTION_TYPE_COMPONENT: + + result = expand_parameters (action->action.component, action->action_type, + uris, &argc, &argv); + + if (result != GNOME_VFS_OK) { + return result; + } + + if (!g_spawn_async (NULL /* working directory */, + argv, + envp, + G_SPAWN_SEARCH_PATH /* flags */, + NULL /* child_setup */, + NULL /* data */, + NULL /* child_pid */, + NULL /* error */)) { + g_strfreev (argv); + return GNOME_VFS_ERROR_LAUNCH; + } + g_strfreev (argv); + + return GNOME_VFS_OK; + + default: + g_assert_not_reached (); + } + + return GNOME_VFS_ERROR_BAD_PARAMETERS; +} + +/** + * gnome_vfs_mime_application_launch: + * @app: the GnomeVFSMimeApplication to launch + * @uris: parameters for the GnomeVFSMimeApplication + * + * Launches the given mime application with the given parameters. + * Command line parameters will be expanded as required by the + * application. The application will also be launched in a terminal + * if that is required. If the application only supports one argument + * per instance then multiple instances of the application will be + * launched. + * + * Return value: + * GNOME_VFS_OK if the application was launched. + * GNOME_VFS_ERROR_NOT_SUPPORTED if the uri protocol is not + * supported by the application. + * GNOME_VFS_ERROR_PARSE if the application command can not + * be parsed. + * GNOME_VFS_ERROR_LAUNCH if the application command can not + * be launched. + * GNOME_VFS_ERROR_INTERNAL for other internal and GConf errors. + * + * Since: 2.4 + */ +GnomeVFSResult +gnome_vfs_mime_application_launch (GnomeVFSMimeApplication *app, + GList *uris) +{ + return gnome_vfs_mime_application_launch_with_env (app, uris, NULL); +} + +/** + * gnome_vfs_mime_application_launch_with_env: + * + * Same as gnome_vfs_mime_application_launch except that + * the application will be launched with the given environment. + * + * Return value: same as gnome_vfs_mime_application_launch + * + * Since: 2.4 + */ +GnomeVFSResult +gnome_vfs_mime_application_launch_with_env (GnomeVFSMimeApplication *app, + GList *uris, + char **envp) +{ + GnomeVFSResult result; + GList *u; + char *scheme; + char **argv; + int argc; + + g_return_val_if_fail (app != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail (uris != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + /* check that all uri schemes are supported */ + if (app->supported_uri_schemes != NULL) { + for (u = uris; u != NULL; u = u->next) { + + scheme = gnome_vfs_get_uri_scheme (u->data); + + if (!g_list_find_custom (app->supported_uri_schemes, + scheme, (GCompareFunc) strcmp)) { + g_free (scheme); + return GNOME_VFS_ERROR_NOT_SUPPORTED; + } + + g_free (scheme); + } + } + + while (uris != NULL) { + + result = expand_parameters (app, GNOME_VFS_MIME_ACTION_TYPE_APPLICATION, + uris, &argc, &argv); + + if (result != GNOME_VFS_OK) { + return result; + } + + if (app->requires_terminal) { + if (!_gnome_vfs_prepend_terminal_to_vector (&argc, &argv)) { + g_strfreev (argv); + return GNOME_VFS_ERROR_INTERNAL; + } + } + + if (!g_spawn_async (NULL /* working directory */, + argv, + envp, + G_SPAWN_SEARCH_PATH /* flags */, + NULL /* child_setup */, + NULL /* data */, + NULL /* child_pid */, + NULL /* error */)) { + g_strfreev (argv); + return GNOME_VFS_ERROR_LAUNCH; + } + + g_strfreev (argv); + uris = uris->next; + + if (app->can_open_multiple_files) { + break; + } + } + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +expand_parameters (gpointer action, + GnomeVFSMimeActionType type, + GList *uris, + int *argc, + char ***argv) +{ + GnomeVFSMimeApplication *app = NULL; + Bonobo_ServerInfo *server = NULL; + GConfClient *client; + char *path; + char *command = NULL; + char **c_argv, **r_argv; + int c_argc, max_r_argc; + int i, c; + gboolean added_arg; + + /* figure out what command to parse */ + switch (type) { + case GNOME_VFS_MIME_ACTION_TYPE_APPLICATION: + app = (GnomeVFSMimeApplication *) action; + command = app->command; + break; + + case GNOME_VFS_MIME_ACTION_TYPE_COMPONENT: + if (!gconf_is_initialized ()) { + if (!gconf_init (0, NULL, NULL)) { + return GNOME_VFS_ERROR_INTERNAL; + } + } + + client = gconf_client_get_default (); + g_return_val_if_fail (client != NULL, GNOME_VFS_ERROR_INTERNAL); + + command = gconf_client_get_string (client, GCONF_DEFAULT_VIEWER_EXEC_PATH, NULL); + g_object_unref (client); + + if (command != NULL) { + g_warning ("No default component viewer set\n"); + return GNOME_VFS_ERROR_INTERNAL; + } + + server = (Bonobo_ServerInfo *) action; + + break; + + default: + g_assert_not_reached (); + } + + if (!g_shell_parse_argv (command, + &c_argc, + &c_argv, + NULL)) { + return GNOME_VFS_ERROR_PARSE; + } + + /* figure out how many parameters we can max have */ + max_r_argc = g_list_length (uris) + c_argc + 1; + r_argv = g_new0 (char *, max_r_argc + 1); + + added_arg = FALSE; + i = 0; + for (c = 0; c < c_argc; c++) { + /* replace %s with the uri parameters */ + if (strcmp (c_argv[c], "%s") == 0) { + while (uris != NULL) { + if (app != NULL) { + switch (app->expects_uris) { + case GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_URIS: + r_argv[i] = g_strdup (uris->data); + break; + + case GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_PATHS: + r_argv[i] = gnome_vfs_get_local_path_from_uri (uris->data); + if (r_argv[i] == NULL) { + g_strfreev (c_argv); + g_strfreev (r_argv); + return GNOME_VFS_ERROR_NOT_SUPPORTED; + } + break; + + case GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_URIS_FOR_NON_FILES: + /* this really means use URIs for non local files */ + path = gnome_vfs_get_local_path_from_uri (uris->data); + + if (path != NULL) { + r_argv[i] = path; + } else { + r_argv[i] = g_strdup (uris->data); + } + + break; + + default: + g_assert_not_reached (); + } + } else { + r_argv[i] = g_strdup (uris->data); + } + i++; + uris = uris->next; + + if (app != NULL && !app->can_open_multiple_files) { + break; + } + } + added_arg = TRUE; + + /* replace %c with the component iid */ + } else if (server != NULL && strcmp (c_argv[c], "%c") == 0) { + r_argv[i++] = g_strdup (server->iid); + added_arg = TRUE; + + /* otherwise take arg from command */ + } else { + r_argv[i++] = g_strdup (c_argv[c]); + } + } + g_strfreev (c_argv); + + /* if there is no %s or %c, append the parameters to the end */ + if (!added_arg) { + while (uris != NULL) { + if (app != NULL) { + switch (app->expects_uris) { + case GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_URIS: + r_argv[i] = g_strdup (uris->data); + break; + + case GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_PATHS: + r_argv[i] = gnome_vfs_get_local_path_from_uri (uris->data); + if (r_argv[i] == NULL) { + g_strfreev (r_argv); + return GNOME_VFS_ERROR_NOT_SUPPORTED; + } + break; + + case GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_URIS_FOR_NON_FILES: + /* this really means use URIs for non local files */ + path = gnome_vfs_get_local_path_from_uri (uris->data); + + if (path != NULL) { + r_argv[i] = path; + } else { + r_argv[i] = g_strdup (uris->data); + } + + break; + + default: + g_assert_not_reached (); + } + } else { + r_argv[i] = g_strdup (uris->data); + } + i++; + uris = uris->next; + + if (app != NULL && !app->can_open_multiple_files) { + break; + } + } + } + + *argv = r_argv; + *argc = i; + + return GNOME_VFS_OK; +} + +static gboolean +application_known_to_be_nonexistent (const char *application_id) +{ + const char *command; + + g_return_val_if_fail (application_id != NULL, FALSE); + + command = gnome_vfs_application_registry_peek_value + (application_id, + GNOME_VFS_APPLICATION_REGISTRY_COMMAND); + + if (command == NULL) { + return TRUE; + } + + return !gnome_vfs_is_executable_command_string (command); +} + +static GList * +prune_ids_for_nonexistent_applications (GList *list) +{ + GList *p, *next; + + for (p = list; p != NULL; p = next) { + next = p->next; + + if (application_known_to_be_nonexistent (p->data)) { + list = g_list_remove_link (list, p); + g_free (p->data); + g_list_free_1 (p); + } + } + + return list; +} + +static GList * +Bonobo_ServerInfoList_to_ServerInfo_g_list (Bonobo_ServerInfoList *info_list) +{ + GList *retval; + int i; + + retval = NULL; + if (info_list != NULL && info_list->_length > 0) { + for (i = 0; i < info_list->_length; i++) { + retval = g_list_prepend (retval, Bonobo_ServerInfo_duplicate (&info_list->_buffer[i])); + } + retval = g_list_reverse (retval); + } + + return retval; +} + +static char ** +strsplit_handle_null (const char *str, const char *delim, int max) +{ + return g_strsplit ((str == NULL ? "" : str), delim, max); +} + +static GList * +strsplit_to_list (const char *str, const char *delim, int max) +{ + char **strv; + GList *retval; + int i; + + strv = strsplit_handle_null (str, delim, max); + + retval = NULL; + + for (i = 0; strv[i] != NULL; i++) { + retval = g_list_prepend (retval, strv[i]); + } + + retval = g_list_reverse (retval); + + /* Don't strfreev, since we didn't copy the individual strings. */ + g_free (strv); + + return retval; +} + +static char * +strjoin_from_list (const char *separator, GList *list) +{ + char **strv; + int i; + GList *p; + char *retval; + + strv = g_new0 (char *, (g_list_length (list) + 1)); + + for (p = list, i = 0; p != NULL; p = p->next, i++) { + strv[i] = p->data; + } + + retval = g_strjoinv (separator, strv); + + g_free (strv); + + return retval; +} + +static GList * +comma_separated_str_to_str_list (const char *str) +{ + return strsplit_to_list (str, ",", 0); +} + +static char * +str_list_to_comma_separated_str (GList *list) +{ + return strjoin_from_list (",", list); +} + +static GList * +str_list_difference (GList *a, GList *b) +{ + GList *node, *result; + + /* Uses an N^2 algorithm rather than a more efficient one + * that sorts or creates a hash table. + */ + + result = NULL; + + for (node = a; node != NULL; node = node->next) { + if (g_list_find_custom (b, node->data, (GCompareFunc) strcmp) == NULL) { + result = g_list_prepend (result, node->data); + } + } + + return g_list_reverse (result); +} + +static GList * +copy_str_list (GList *string_list) +{ + GList *copy, *node; + + copy = NULL; + for (node = string_list; node != NULL; node = node->next) { + copy = g_list_prepend (copy, + g_strdup ((char *) node->data)); + } + return g_list_reverse (copy); +} + +static const char * +gnome_vfs_mime_maybe_get_user_level_value (const char *mime_type, const char *key) +{ + const char *return_value; + char *new_key; + + /* This function checks for a key and falls back + * to the "advanced" user level preference if the key + * doesn't exist. + */ + + return_value = gnome_vfs_mime_get_value (mime_type, key); + + if (return_value != NULL) { + return return_value; + } + + new_key = g_strconcat (key, "_for_advanced_user_level", NULL); + return_value = gnome_vfs_mime_get_value (mime_type, new_key); + g_free (new_key); + + return return_value; +} diff --git a/libgnomevfs/gnome-vfs-mime-handlers.h b/libgnomevfs/gnome-vfs-mime-handlers.h new file mode 100644 index 0000000..5e17f05 --- /dev/null +++ b/libgnomevfs/gnome-vfs-mime-handlers.h @@ -0,0 +1,168 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* gnome-vfs-mime-handlers.h - Mime type handlers for the GNOME Virtual + File System. + + Copyright (C) 2000 Eazel, Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Maciej Stachowiak */ + +#ifndef GNOME_VFS_MIME_HANDLERS_H +#define GNOME_VFS_MIME_HANDLERS_H + +#include +#include +#include +#include + +G_BEGIN_DECLS + +typedef enum { + GNOME_VFS_MIME_ACTION_TYPE_NONE, + GNOME_VFS_MIME_ACTION_TYPE_APPLICATION, + GNOME_VFS_MIME_ACTION_TYPE_COMPONENT +} GnomeVFSMimeActionType; + +typedef enum { + GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_URIS, + GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_PATHS, + GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_URIS_FOR_NON_FILES +} GnomeVFSMimeApplicationArgumentType; + +typedef struct { + char *id; + char *name; + char *command; + gboolean can_open_multiple_files; + GnomeVFSMimeApplicationArgumentType expects_uris; + GList *supported_uri_schemes; + gboolean requires_terminal; + + /* Padded to avoid future breaks in ABI compatibility */ + void *reserved1; + void *reserved2; + +} GnomeVFSMimeApplication; + +/** + * GnomeVFSMimeAction: + * + * This data structure describes an action that can be done + * on a file. + **/ + +typedef struct { + GnomeVFSMimeActionType action_type; + union { + Bonobo_ServerInfo *component; + void *dummy_component; + GnomeVFSMimeApplication *application; + } action; + + /* Padded to avoid future breaks in ABI compatibility */ + void *reserved1; +} GnomeVFSMimeAction; + +GnomeVFSMimeApplication *gnome_vfs_mime_application_copy (GnomeVFSMimeApplication *application); +GnomeVFSMimeActionType gnome_vfs_mime_get_default_action_type (const char *mime_type); +GnomeVFSMimeAction * gnome_vfs_mime_get_default_action (const char *mime_type); +GnomeVFSMimeApplication *gnome_vfs_mime_get_default_application (const char *mime_type); +Bonobo_ServerInfo * gnome_vfs_mime_get_default_component (const char *mime_type); +GList * gnome_vfs_mime_get_short_list_applications (const char *mime_type); +GList * gnome_vfs_mime_get_short_list_components (const char *mime_type); +GList * gnome_vfs_mime_get_all_applications (const char *mime_type); +GList * gnome_vfs_mime_get_all_components (const char *mime_type); +GnomeVFSResult gnome_vfs_mime_set_default_action_type (const char *mime_type, + GnomeVFSMimeActionType action_type); +GnomeVFSResult gnome_vfs_mime_set_default_application (const char *mime_type, + const char *application_id); +GnomeVFSResult gnome_vfs_mime_set_default_component (const char *mime_type, + const char *component_iid); + +const char *gnome_vfs_mime_get_icon (const char *mime_type); +GnomeVFSResult gnome_vfs_mime_set_icon (const char *mime_type, + const char *filename); +const char *gnome_vfs_mime_get_description (const char *mime_type); +GnomeVFSResult gnome_vfs_mime_set_description (const char *mime_type, + const char *description); + +gboolean gnome_vfs_mime_can_be_executable (const char *mime_type); +GnomeVFSResult gnome_vfs_mime_set_can_be_executable (const char *mime_type, + gboolean new_value); + +/* Stored as delta to current user level - API function computes delta and stores in prefs */ +GnomeVFSResult gnome_vfs_mime_set_short_list_applications (const char *mime_type, + GList *application_ids); +GnomeVFSResult gnome_vfs_mime_set_short_list_components (const char *mime_type, + GList *component_iids); +GnomeVFSResult gnome_vfs_mime_add_application_to_short_list (const char *mime_type, + const char *application_id); +GnomeVFSResult gnome_vfs_mime_remove_application_from_short_list (const char *mime_type, + const char *application_id); +GnomeVFSResult gnome_vfs_mime_add_component_to_short_list (const char *mime_type, + const char *iid); +GnomeVFSResult gnome_vfs_mime_remove_component_from_short_list (const char *mime_type, + const char *iid); +GnomeVFSResult gnome_vfs_mime_add_extension (const char *mime_type, + const char *extension); +GnomeVFSResult gnome_vfs_mime_remove_extension (const char *mime_type, + const char *extension); + + +/* No way to override system list; can only add. */ +GnomeVFSResult gnome_vfs_mime_extend_all_applications (const char *mime_type, + GList *application_ids); +/* Only "user" entries may be removed. */ +GnomeVFSResult gnome_vfs_mime_remove_from_all_applications (const char *mime_type, + GList *application_ids); +GnomeVFSMimeApplication *gnome_vfs_mime_application_new_from_id (const char *id); +void gnome_vfs_mime_application_free (GnomeVFSMimeApplication *application); +void gnome_vfs_mime_action_free (GnomeVFSMimeAction *action); + +/* List manipulation helper functions */ +void gnome_vfs_mime_application_list_free (GList *list); +void gnome_vfs_mime_component_list_free (GList *list); +gboolean gnome_vfs_mime_id_in_application_list (const char *id, + GList *applications); +gboolean gnome_vfs_mime_id_in_component_list (const char *iid, + GList *components); +GList * gnome_vfs_mime_remove_application_from_list (GList *applications, + const char *application_id, + gboolean *did_remove); +GList * gnome_vfs_mime_remove_component_from_list (GList *components, + const char *iid, + gboolean *did_remove); +GList * gnome_vfs_mime_id_list_from_component_list (GList *components); +GList * gnome_vfs_mime_id_list_from_application_list (GList *applications); + + +/* For launching mime actions & application */ +GnomeVFSResult gnome_vfs_mime_action_launch (GnomeVFSMimeAction *action, + GList *uris); +GnomeVFSResult gnome_vfs_mime_action_launch_with_env (GnomeVFSMimeAction *action, + GList *uris, + char **envp); +GnomeVFSResult gnome_vfs_mime_application_launch (GnomeVFSMimeApplication *app, + GList *uris); +GnomeVFSResult gnome_vfs_mime_application_launch_with_env (GnomeVFSMimeApplication *app, + GList *uris, + char **envp); + +G_END_DECLS + +#endif /* GNOME_VFS_MIME_HANDLERS_H */ diff --git a/libgnomevfs/gnome-vfs-mime-info.c b/libgnomevfs/gnome-vfs-mime-info.c new file mode 100644 index 0000000..939d6e6 --- /dev/null +++ b/libgnomevfs/gnome-vfs-mime-info.c @@ -0,0 +1,1653 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* gnome-vfs-mime-info.c - GNOME mime-information implementation. + + Copyright (C) 1998 Miguel de Icaza + Copyright (C) 2000, 2001 Eazel, Inc. + All rights reserved. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: + Miguel De Icaza + Mathieu Lacage +*/ + +#include +#include "gnome-vfs-mime-info.h" + +#include "gnome-vfs-mime-monitor.h" +#include "gnome-vfs-mime-private.h" +#include "gnome-vfs-mime.h" +#include "gnome-vfs-private-utils.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef NEED_GNOMESUPPORT_H +#include "gnomesupport.h" +#endif + +#define FAST_FILE_EOF -1 +#define FAST_FILE_BUFFER_SIZE (1024 * 16) + +typedef struct { + guchar *ptr; + guchar *buffer; + int length; + FILE *fh; +} FastFile; + +static void +fast_file_close (FastFile *ffh) +{ + fclose (ffh->fh); + g_free (ffh->buffer); +} + +static gboolean +fast_file_open (FastFile *ffh, const char *filename) +{ + memset (ffh, 0, sizeof (FastFile)); + + ffh->fh = fopen (filename, "r"); + if (ffh->fh == NULL) { + return FALSE; + } + + ffh->buffer = g_malloc (FAST_FILE_BUFFER_SIZE); + ffh->ptr = ffh->buffer; + + ffh->length = fread (ffh->buffer, 1, FAST_FILE_BUFFER_SIZE, ffh->fh); + + if (ffh->length < 0) { + fast_file_close (ffh); + return FALSE; + } + + return TRUE; +} + +static inline int +fast_file_getc (FastFile *ffh) +{ + if (ffh->ptr < ffh->buffer + ffh->length) + return *(ffh->ptr++); + else { + ffh->length = fread (ffh->buffer, 1, FAST_FILE_BUFFER_SIZE, ffh->fh); + + if (!ffh->length) + return FAST_FILE_EOF; + else { + ffh->ptr = ffh->buffer; + return *(ffh->ptr++); + } + } +} + +typedef struct { + char *mime_type; + GHashTable *keys; +} GnomeMimeContext; + +/* Describes the directories we scan for information */ +typedef struct { + char *dirname; + struct stat s; + unsigned int valid : 1; + unsigned int system_dir : 1; + unsigned int force_reload : 1; +} mime_dir_source_t; + + +#define DELETED_KEY "deleted" +#define DELETED_VALUE "moilegrandvizir" + +/* These ones are used to automatically reload mime info on demand */ +static mime_dir_source_t gnome_mime_dir, user_mime_dir; +static time_t last_checked; + +/* To initialize the module automatically */ +static gboolean gnome_vfs_mime_inited = FALSE; + +/* you will write back or reload the file if and only if this var' value is 0 */ +static int gnome_vfs_is_frozen = 0; + +static GList *current_lang = NULL; +/* we want to replace the previous key if the current key has a higher + language level */ +static int previous_key_lang_level = -1; + +/* + * A hash table containing all of the Mime records for specific + * mime types (full description, like image/png) + * It also contains a the generic types like image/ + * extracted from .keys files + */ +static GHashTable *specific_types; +/* user specific data */ +static GHashTable *specific_types_user; + + +/* + * A hash table containing all of the Mime records for all registered + * mime types + * extracted from .mime files + */ +static GHashTable *registered_types; +/* user specific data */ +static GHashTable *registered_types_user; + + + +/* Prototypes */ +static GnomeVFSResult write_back_mime_user_file (void); +static GnomeVFSResult write_back_keys_user_file (void); +static const char * gnome_vfs_mime_get_registered_mime_type_key (const char *mime_type, + const char *key); + +void +_gnome_vfs_mime_info_mark_gnome_mime_dir_dirty (void) +{ + gnome_mime_dir.force_reload = TRUE; +} + +void +_gnome_vfs_mime_info_mark_user_mime_dir_dirty (void) +{ + user_mime_dir.force_reload = TRUE; +} + +static gboolean +does_string_contain_caps (const char *string) +{ + const char *temp_c; + + temp_c = string; + while (*temp_c != '\0') { + if (g_ascii_isupper (*temp_c)) { + return TRUE; + } + temp_c++; + } + + return FALSE; +} + +static GnomeMimeContext * +context_new (GHashTable *hash_table, GString *str) +{ + GnomeMimeContext *context; + char *mime_type; + char last_char; + + mime_type = g_strdup (str->str); + + last_char = mime_type[strlen (mime_type) - 1]; + if (last_char == '*') { + mime_type[strlen (mime_type) - 1] = '\0'; + } + + context = g_hash_table_lookup (hash_table, mime_type); + + if (context != NULL) { + g_free (mime_type); + return context; + } + +/* fprintf (stderr, "New context: '%s'\n", mime_type); */ + + context = g_new (GnomeMimeContext, 1); + context->mime_type = mime_type; + context->keys = g_hash_table_new_full ( + g_str_hash, g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) g_free); + + g_hash_table_insert (hash_table, context->mime_type, context); + return context; +} + +static void +context_destroy (GnomeMimeContext *context) +{ + g_hash_table_destroy (context->keys); + g_free (context->mime_type); + g_free (context); +} + +/* this gives us a number of the language in the current language list, + the higher the number the "better" the translation */ +static int +language_level (const char *langage) +{ + int i; + GList *li; + + if (langage == NULL) + return 0; + + for (i = 1, li = current_lang; li != NULL; i++, li = g_list_next (li)) { + if (strcmp ((const char *) li->data, langage) == 0) + return i; + } + + return -1; +} + + +static void +context_add_key (GnomeMimeContext *context, char *key, char *lang, char *value) +{ + int lang_level; + + lang_level = language_level (lang); + /* wrong language completely */ + if (lang_level < 0) + return; + + /* if a previous key in the hash had a better lang_level don't do anything */ + if (lang_level > 0 && + previous_key_lang_level > lang_level) { + return; + } + + /* fprintf (stderr, "Add key: '%s' '%s' '%s' %d\n", key, lang, value, lang_level);*/ + + g_hash_table_replace (context->keys, g_strdup (key), g_strdup (value)); + + previous_key_lang_level = lang_level; +} + +typedef enum { + STATE_NONE, + STATE_LANG, + STATE_LOOKING_FOR_KEY, + STATE_ON_MIME_TYPE, + STATE_ON_KEY, + STATE_ON_VALUE +} ParserState; + +/* #define APPEND_CHAR(gstr,c) g_string_insert_c ((gstr), -1, (c)) */ + +#define APPEND_CHAR(gstr,c) \ + G_STMT_START { \ + if (gstr->len + 1 < gstr->allocated_len) { \ + gstr->str [gstr->len++] = c; \ + gstr->str [gstr->len] = '\0'; \ + } else { \ + g_string_insert_c (gstr, -1, c); \ + } \ + } G_STMT_END + +typedef enum { + FORMAT_MIME, + FORMAT_KEYS +} Format; + +#define load_mime_type_info_from(a,b) load_type_info_from ((a), (b), FORMAT_MIME) +#define load_mime_list_info_from(a,b) load_type_info_from ((a), (b), FORMAT_KEYS) + +static void +load_type_info_from (const char *filename, + GHashTable *hash_table, + Format format) +{ + GString *line; + int column, c; + ParserState state; + FastFile mime_file; + gboolean skip_line; + GnomeMimeContext *context; + int key, lang, last_str_end; /* offsets */ + + if (!fast_file_open (&mime_file, filename)) { + return; + } + + skip_line = FALSE; + column = -1; + context = NULL; + line = g_string_sized_new (120); + key = lang = last_str_end = 0; + state = STATE_NONE; + + while ((c = fast_file_getc (&mime_file)) != EOF) { + handle_char: + column++; + if (c == '\r') + continue; + + if (c == '#' && column == 0) { + skip_line = TRUE; + continue; + } + + if (skip_line) { + if (c == '\n') { + skip_line = FALSE; + column = -1; + g_string_truncate (line, 0); + key = lang = last_str_end = 0; + } + continue; + } + + if (c == '\n') { + skip_line = FALSE; + column = -1; + if (state == STATE_ON_MIME_TYPE) { + /* setup for a new key */ + previous_key_lang_level = -1; + context = context_new (hash_table, line); + + } else if (state == STATE_ON_VALUE) { + APPEND_CHAR (line, '\0'); + context_add_key (context, + line->str + key, + lang ? line->str + lang : NULL, + line->str + last_str_end); + key = lang = 0; + } + g_string_truncate (line, 0); + last_str_end = 0; + state = STATE_LOOKING_FOR_KEY; + continue; + } + + switch (state) { + case STATE_NONE: + if (c == ' ' || c == '\t') { + break; + } else if (c == ':') { + skip_line = TRUE; + break; + } else { + state = STATE_ON_MIME_TYPE; + } + /* fall down */ + + case STATE_ON_MIME_TYPE: + if (c == ':') { + skip_line = TRUE; + /* setup for a new key */ + previous_key_lang_level = -1; + context = context_new (hash_table, line); + state = STATE_LOOKING_FOR_KEY; + break; + } + APPEND_CHAR (line, c); + break; + + case STATE_LOOKING_FOR_KEY: + if (c == '\t' || c == ' ') { + break; + } + + if (c == '[') { + state = STATE_LANG; + break; + } + + if (column == 0) { + state = STATE_ON_MIME_TYPE; + APPEND_CHAR (line, c); + break; + } + state = STATE_ON_KEY; + /* falldown */ + + case STATE_ON_KEY: + if (c == '\\') { + c = fast_file_getc (&mime_file); + if (c == EOF) { + break; + } + } + if (c == '=') { + key = last_str_end; + APPEND_CHAR (line, '\0'); + last_str_end = line->len; + state = STATE_ON_VALUE; + break; + } + + if (format == FORMAT_KEYS && c == ':') { + key = last_str_end; + + APPEND_CHAR (line, '\0'); + last_str_end = line->len; + + /* Skip space after colon. There should be one + * there. That is how the file is defined. */ + c = fast_file_getc (&mime_file); + if (c != ' ') { + if (c == EOF) { + break; + } else { + goto handle_char; + } + } else { + column++; + } + + state = STATE_ON_VALUE; + break; + } + + APPEND_CHAR (line, c); + break; + + case STATE_ON_VALUE: + APPEND_CHAR (line, c); + break; + + case STATE_LANG: + if (c == ']') { + state = STATE_ON_KEY; + + lang = last_str_end; + APPEND_CHAR (line, '\0'); + last_str_end = line->len; + + if (!line->str [0] || + language_level (line->str + lang) < 0) { + skip_line = TRUE; + key = lang = last_str_end = 0; + g_string_truncate (line, 0); + state = STATE_LOOKING_FOR_KEY; + } + } else { + APPEND_CHAR (line, c); + } + break; + } + } + + /* This happens if the last line of the file doesn't end with '\n' */ + if (context != NULL) { + if (last_str_end && line->str [0]) { + APPEND_CHAR (line, '\0'); + context_add_key (context, + line->str + key, + lang ? line->str + lang : NULL, + line->str + last_str_end); + } else { + if (g_hash_table_size (context->keys) < 1) { + g_hash_table_remove (hash_table, context->mime_type); + context_destroy (context); + } + } + } + + g_string_free (line, TRUE); + + previous_key_lang_level = -1; + + fast_file_close (&mime_file); +} + +static void +mime_info_load (mime_dir_source_t *source) +{ + DIR *dir; + struct dirent *dent; + const int extlen = sizeof (".keys") - 1; + char *filename; + + if (stat (source->dirname, &source->s) != -1) + source->valid = TRUE; + else + source->valid = FALSE; + + dir = opendir (source->dirname); + if (!dir) { + source->valid = FALSE; + return; + } + if (source->system_dir) { + filename = g_strconcat (source->dirname, "/gnome-vfs.keys", NULL); + load_mime_type_info_from (filename, specific_types); + g_free (filename); + } + + while ((dent = readdir (dir)) != NULL) { + + int len = strlen (dent->d_name); + + if (len <= extlen) + continue; + if (strcmp (dent->d_name + len - extlen, ".keys")) + continue; + if (source->system_dir && !strcmp (dent->d_name, "gnome-vfs.keys")) + continue; + + if (source->system_dir && !strcmp (dent->d_name, "gnome.keys")) { + /* Ignore the obsolete "official" one so it doesn't override + * the new official one. + */ + continue; + } + + if (!source->system_dir && !strcmp (dent->d_name, "user.keys")) + continue; + + filename = g_strconcat (source->dirname, "/", dent->d_name, NULL); + load_mime_type_info_from (filename, specific_types); + g_free (filename); + } + if (!source->system_dir) { + filename = g_strconcat (source->dirname, "/user.keys", NULL); + load_mime_type_info_from (filename, specific_types_user); + g_free (filename); + } + closedir (dir); +} + +static void +mime_list_load (mime_dir_source_t *source) +{ + DIR *dir; + struct dirent *dent; + const int extlen = sizeof (".mime") - 1; + char *filename; + + if (stat (source->dirname, &source->s) != -1) + source->valid = TRUE; + else + source->valid = FALSE; + + dir = opendir (source->dirname); + if (!dir) { + source->valid = FALSE; + return; + } + if (source->system_dir) { + filename = g_strconcat (source->dirname, "/gnome-vfs.mime", NULL); + load_mime_list_info_from (filename, registered_types); + g_free (filename); + } + + while ((dent = readdir (dir)) != NULL) { + + int len = strlen (dent->d_name); + + if (len <= extlen) + continue; + if (strcmp (dent->d_name + len - extlen, ".mime")) + continue; + if (source->system_dir && !strcmp (dent->d_name, "gnome-vfs.mime")) + continue; + + if (source->system_dir && !strcmp (dent->d_name, "gnome.mime")) { + /* Ignore the obsolete "official" one so it doesn't override + * the new official one. + */ + continue; + } + + if (!source->system_dir && !strcmp (dent->d_name, "user.mime")) + continue; + + filename = g_strconcat (source->dirname, "/", dent->d_name, NULL); + load_mime_list_info_from (filename, registered_types); + g_free (filename); + } + if (!source->system_dir) { + filename = g_strconcat (source->dirname, "/user.mime", NULL); + load_mime_list_info_from (filename, registered_types_user); + g_free (filename); + } + closedir (dir); +} + +static void +load_mime_type_info (void) +{ + mime_info_load (&gnome_mime_dir); + mime_info_load (&user_mime_dir); + mime_list_load (&gnome_mime_dir); + mime_list_load (&user_mime_dir); +} + +static void +gnome_vfs_mime_init (void) +{ + /* + * The hash tables that store the mime keys. + */ + specific_types = g_hash_table_new (g_str_hash, g_str_equal); + registered_types = g_hash_table_new (g_str_hash, g_str_equal); + + specific_types_user = g_hash_table_new (g_str_hash, g_str_equal); + registered_types_user = g_hash_table_new (g_str_hash, g_str_equal); + + current_lang = gnome_vfs_i18n_get_language_list ("LC_MESSAGES"); + + /* + * Setup the descriptors for the information loading + */ + gnome_mime_dir.dirname = g_strdup (DATADIR "/mime-info"); + gnome_mime_dir.system_dir = TRUE; + + user_mime_dir.dirname = g_strconcat + (g_get_home_dir (), "/.gnome/mime-info", NULL); + user_mime_dir.system_dir = FALSE; + + /* + * Load + */ + load_mime_type_info (); + + last_checked = time (NULL); + gnome_vfs_mime_inited = TRUE; +} + +static gboolean +remove_keys (gpointer key, gpointer value, gpointer user_data) +{ + GnomeMimeContext *context = value; + + context_destroy (context); + + return TRUE; +} + +static void +reload_if_needed (void) +{ + time_t now = time (NULL); + gboolean need_reload = FALSE; + struct stat s; + + if (gnome_vfs_is_frozen > 0) + return; + + if (gnome_mime_dir.force_reload || user_mime_dir.force_reload) + need_reload = TRUE; + else if (now > last_checked + 5) { + if (stat (gnome_mime_dir.dirname, &s) != -1 && + s.st_mtime != gnome_mime_dir.s.st_mtime) + need_reload = TRUE; + else if (stat (user_mime_dir.dirname, &s) != -1 && + s.st_mtime != user_mime_dir.s.st_mtime) + need_reload = TRUE; + } + + last_checked = now; + + if (need_reload) { + gnome_vfs_mime_info_reload (); + } +} + +static void +gnome_vfs_mime_info_clear (void) +{ + if (specific_types != NULL) { + g_hash_table_foreach_remove (specific_types, remove_keys, NULL); + } + if (registered_types != NULL) { + g_hash_table_foreach_remove (registered_types, remove_keys, NULL); + } + if (specific_types_user != NULL) { + g_hash_table_foreach_remove (specific_types_user, remove_keys, NULL); + } + if (registered_types_user != NULL) { + g_hash_table_foreach_remove (registered_types_user, remove_keys, NULL); + } +} + +/** + * _gnome_vfs_mime_info_shutdown: + * + * Remove the MIME database from memory. + **/ +void +_gnome_vfs_mime_info_shutdown (void) +{ + gnome_vfs_mime_info_clear (); + + if (specific_types != NULL) { + g_hash_table_destroy (specific_types); + specific_types = NULL; + } + if (registered_types != NULL) { + g_hash_table_destroy (registered_types); + registered_types = NULL; + } + if (specific_types_user != NULL) { + g_hash_table_destroy (specific_types_user); + specific_types_user = NULL; + } + if (registered_types_user != NULL) { + g_hash_table_destroy (registered_types_user); + registered_types_user = NULL; + } +} + +/** + * gnome_vfs_mime_info_reload: + * + * Reload the MIME database from disk and notify any listeners + * holding active #GnomeVFSMIMEMonitor objects. + **/ +void +gnome_vfs_mime_info_reload (void) +{ + if (!gnome_vfs_mime_inited) { + gnome_vfs_mime_init (); + } + + /* 1. Clean */ + gnome_vfs_mime_info_clear (); + + /* 2. Reload */ + load_mime_type_info (); + + /* 3. clear our force flags */ + gnome_mime_dir.force_reload = FALSE; + user_mime_dir.force_reload = FALSE; + + /* 3. Tell anyone who cares */ + _gnome_vfs_mime_monitor_emit_data_changed (gnome_vfs_mime_monitor_get ()); +} + + +/** + * gnome_vfs_mime_freeze: + * + * Freezes the mime data so that you can do multiple + * updates to the dat in one batch without needing + * to back the files to disk or readind them + */ +void +gnome_vfs_mime_freeze (void) +{ + gnome_vfs_is_frozen++; +} + + + +/** + * gnome_vfs_mime_thaw: + * + * UnFreezes the mime data so that you can do multiple + * updates to the dat in one batch without needing + * to back the files to disk or readind them + */ +void +gnome_vfs_mime_thaw (void) +{ + gnome_vfs_is_frozen--; + + if (gnome_vfs_is_frozen == 0) { + write_back_mime_user_file (); + write_back_keys_user_file (); + } +} + + +static GnomeVFSResult +set_value_real (const char *mime_type, const char *key, const char *value, + GHashTable *user_hash_table) +{ + GnomeMimeContext *context; + + if (mime_type == NULL + || key == NULL + || value == NULL) { + return gnome_vfs_result_from_errno (); + } + + g_return_val_if_fail (!does_string_contain_caps (mime_type), + gnome_vfs_result_from_errno ()); + + if (!gnome_vfs_mime_inited) { + gnome_vfs_mime_init (); + } + + context = g_hash_table_lookup (user_hash_table, mime_type); + if (context == NULL) { + GString *string; + + string = g_string_new (mime_type); + + /* create the mime type context */ + context = context_new (user_hash_table, string); + /* add the info to the mime type context */ + g_hash_table_insert (context->keys, g_strdup (key), g_strdup (value)); + g_string_free (string, TRUE); + } else + g_hash_table_replace (context->keys, g_strdup (key), g_strdup (value)); + + return GNOME_VFS_OK; +} + +/** + * gnome_vfs_mime_set_value + * @mime_type: a mime type. + * @key: a key to store the value in. + * @value: the value to store in the key. + * + * This function is going to set the value + * associated to the key and it will save it + * to the user' file if necessary. + * You should not free the key/values passed to + * this function. They are used internally. + * + * Returns: GNOME_VFS_OK if the operation succeeded, otherwise an error code + * + */ +GnomeVFSResult +gnome_vfs_mime_set_value (const char *mime_type, const char *key, const char *value) +{ + GnomeVFSResult retval; + + retval = set_value_real (mime_type, key, value, specific_types_user); + + if (gnome_vfs_is_frozen == 0) { + return write_back_keys_user_file (); + } + + return retval; +} + + +static gboolean +is_mime_type_deleted (const char *mime_type) +{ + const char *deleted_key; + + deleted_key = gnome_vfs_mime_get_registered_mime_type_key (mime_type, DELETED_KEY); + return deleted_key != NULL && strcmp (deleted_key, DELETED_VALUE) == 0; +} + +static const char * +get_value_from_hash_table (GHashTable *hash_table, const char *mime_type, const char *key) +{ + GnomeMimeContext *context; + char *value; + + value = NULL; + context = g_hash_table_lookup (hash_table, mime_type); + if (context != NULL) { + value = g_hash_table_lookup (context->keys, key); + } + return value; +} + +static const char * +get_value_real (const char *mime_type, + const char *key, + GHashTable *user_hash_table, + GHashTable *system_hash_table) +{ + const char *value; + char *generic_type, *p; + + g_return_val_if_fail (key != NULL, NULL); + g_assert (user_hash_table != NULL); + g_assert (system_hash_table != NULL); + + if (mime_type == NULL) { + return NULL; + } + + g_return_val_if_fail (!does_string_contain_caps (mime_type), + NULL); + + reload_if_needed (); + + if (strcmp (key, DELETED_KEY) != 0 && is_mime_type_deleted (mime_type)) { + return NULL; + } + + value = get_value_from_hash_table (user_hash_table, mime_type, key); + if (value != NULL) { + return value; + } + + value = get_value_from_hash_table (system_hash_table, mime_type, key); + if (value != NULL) { + return value; + } + + generic_type = g_strdup (mime_type); + p = strchr (generic_type, '/'); + if (p != NULL) + *(p+1) = '\0'; + + value = get_value_from_hash_table (user_hash_table, generic_type, key); + if (value != NULL) { + g_free (generic_type); + return value; + } + + value = get_value_from_hash_table (system_hash_table, generic_type, key); + g_free (generic_type); + if (value != NULL) { + return value; + } + + return NULL; +} + + +/** + * gnome_vfs_mime_get_value: + * @mime_type: a mime type. + * @key: A key to lookup for the given mime-type + * + * This function retrieves the value associated with @key in + * the given GnomeMimeContext. The string is private, you + * should not free the result. + * + * Returns: GNOME_VFS_OK if the operation succeeded, otherwise an error code + */ +const char * +gnome_vfs_mime_get_value (const char *mime_type, const char *key) +{ + if (!gnome_vfs_mime_inited) + gnome_vfs_mime_init (); + + return get_value_real (mime_type, key, specific_types_user, specific_types); +} + +/** + * gnome_vfs_mime_type_is_known: + * @mime_type: a mime type. + * + * This function returns TRUE if @mime_type is in the MIME database at all. + * + * Returns: TRUE if anything is known about @mime_type, otherwise FALSE + */ +gboolean +gnome_vfs_mime_type_is_known (const char *mime_type) +{ + if (mime_type == NULL) { + return FALSE; + } + + g_return_val_if_fail (!does_string_contain_caps (mime_type), + FALSE); + + if (!gnome_vfs_mime_inited) + gnome_vfs_mime_init (); + + reload_if_needed (); + + if (is_mime_type_deleted (mime_type)) { + return FALSE; + } + + if (g_hash_table_lookup (specific_types, mime_type)) { + return TRUE; + } + + if (g_hash_table_lookup (specific_types_user, mime_type)) { + return TRUE; + } + + if (g_hash_table_lookup (registered_types, mime_type)) { + return TRUE; + } + + if (g_hash_table_lookup (registered_types_user, mime_type)) { + return TRUE; + } + + return FALSE; +} + + +/** + * gnome_vfs_mime_keys_list_free: + * @mime_type_list: A mime type list to free. + * + * Frees the mime type list. + */ +void +gnome_vfs_mime_keys_list_free (GList *mime_type_list) +{ + /* we do not need to free the data in the list since + the data was stolen from the internal hash table + This function is there so that people do not need + to know this particuliar implementation detail. + */ + + g_list_free (mime_type_list); +} + +static void +assemble_list (gpointer key, gpointer value, gpointer user_data) +{ + GList **listp = user_data; + + (*listp) = g_list_prepend ((*listp), key); +} + +/** + * gnome_vfs_mime_get_key_list: + * @mime_type: the MIME type to lookup + * + * Gets a list of all keys associated with @mime_type. + * + * Return value: a GList of const char * representing keys associated + * with @mime_type + **/ +GList * +gnome_vfs_mime_get_key_list (const char *mime_type) +{ + char *p, *generic_type; + GnomeMimeContext *context; + GList *list = NULL, *l; + + if (mime_type == NULL) { + return NULL; + } + g_return_val_if_fail (!does_string_contain_caps (mime_type), + NULL); + + if (!gnome_vfs_mime_inited) + gnome_vfs_mime_init (); + + reload_if_needed (); + + generic_type = g_strdup (mime_type); + p = strchr (generic_type, '/'); + if (p != NULL) + *(p+1) = 0; + + context = g_hash_table_lookup (specific_types_user, generic_type); + if (context != NULL) { + g_hash_table_foreach ( + context->keys, assemble_list, &list); + } + + context = g_hash_table_lookup (specific_types, generic_type); + if (context != NULL) { + g_hash_table_foreach ( + context->keys, assemble_list, &list); + } + + g_free (generic_type); + for (l = list; l;) { + if (l->next) { + void *this = l->data; + GList *m; + + for (m = l->next; m; m = m->next) { + if (strcmp ((char*) this, (char*) m->data) != 0) + continue; + list = g_list_remove (list, m->data); + break; + } + } + l = l->next; + } + + return list; +} + +gint +str_cmp_callback (gconstpointer a, + gconstpointer b); +gint +str_cmp_callback (gconstpointer a, + gconstpointer b) +{ + return (strcmp ((char *)a, (char *)b)); +} + +/** + * gnome_vfs_mime_set_extensions_list: + * @mime_type: the mime type. + * @extensions_list: a whitespace-separated list of the + * extensions to set for this mime type. + * + * Sets the extensions for a given mime type. Overrides + * the previously set extensions. + * + * Return value: GNOME_VFS_OK if the operation succeeded, otherwise an error code. + */ +GnomeVFSResult +gnome_vfs_mime_set_extensions_list (const char *mime_type, + const char *extensions_list) +{ + if (is_mime_type_deleted (mime_type)) { + gnome_vfs_mime_set_registered_type_key (mime_type, DELETED_KEY, ""); + } + + return gnome_vfs_mime_set_registered_type_key (mime_type, "ext", extensions_list); +} + + +/** + * gnome_vfs_mime_get_extensions_list: + * @mime_type: type to get the extensions of + * + * Get the file extensions associated with mime type @mime_type. + * + * Return value: a GList of char *s + **/ +GList * +gnome_vfs_mime_get_extensions_list (const char *mime_type) +{ + GList *list; + const char *extensions_system, *extensions_user; + char *extensions; + gchar **elements; + int index; + GnomeMimeContext *context; + + if (mime_type == NULL) { + return NULL; + } + g_return_val_if_fail (!does_string_contain_caps (mime_type), + NULL); + + + if (!gnome_vfs_mime_inited) { + gnome_vfs_mime_init (); + } + + reload_if_needed (); + + extensions_system = NULL; + extensions_user = NULL; + + context = g_hash_table_lookup (registered_types_user, mime_type); + if (context != NULL) { + extensions_user = g_hash_table_lookup (context->keys, "ext"); + } + + context = g_hash_table_lookup (registered_types, mime_type); + if (context != NULL) { + extensions_system = g_hash_table_lookup (context->keys, "ext"); + } + + + extensions = NULL; + if (extensions_user != NULL) { + extensions = g_strdup (extensions_user); + } else if (extensions_system != NULL) { + extensions = g_strdup (extensions_system); + } + + /* build a GList from the string */ + list = NULL; + if (extensions != NULL) { + /* Parse the extensions and add to list */ + elements = g_strsplit (extensions, " ", 0); + if (elements != NULL) { + index = 0; + + while (elements[index] != NULL) { + if (strcmp (elements[index], "") != 0) { + list = g_list_append (list, g_strdup (elements[index])); + } + index++; + } + g_strfreev (elements); + } + } + + g_free (extensions); + + return list; +} + + +/** + * gnome_vfs_mime_get_extensions_string: + * @mime_type: the mime type + * + * Retrieves the extensions associated with @mime_type as a single + * space seperated string. + * + * Return value: a string containing space seperated extensions for @mime_type + */ +char * +gnome_vfs_mime_get_extensions_string (const char *mime_type) +{ + GList *extensions_list, *temp_list; + char *extensions; + + if (mime_type == NULL) { + return NULL; + } + g_return_val_if_fail (!does_string_contain_caps (mime_type), + NULL); + + + /* it might seem overkill to use gnome_vfs_mime_get_extensions_list + here but it has the advantage that this function returns + a list of unique extensions */ + + extensions_list = gnome_vfs_mime_get_extensions_list (mime_type); + if (extensions_list == NULL) { + return NULL; + } + extensions = NULL; + + for (temp_list = extensions_list; temp_list != NULL; temp_list = temp_list->next) { + char *temp_string; + temp_string = g_strconcat (temp_list->data, " ", extensions, NULL); + g_free (extensions); + extensions = temp_string; + } + + extensions[strlen (extensions) - 1] = '\0'; + return extensions; +} + +/** + * gnome_vfs_mime_get_extensions_pretty_string: + * @mime_type: the mime type + * + * Returns the supported extensions for @mime_type as a comma-seperated list. + * + * Return value: a string containing comma seperated extensions for this mime-type + **/ +char * +gnome_vfs_mime_get_extensions_pretty_string (const char *mime_type) +{ + GList *extensions, *element; + char *ext_str, *tmp_str; + + if (mime_type == NULL) { + return NULL; + } + + ext_str = NULL; + tmp_str = NULL; + + if (!gnome_vfs_mime_inited) { + gnome_vfs_mime_init (); + } + + reload_if_needed (); + + extensions = gnome_vfs_mime_get_extensions_list (mime_type); + if (extensions == NULL) { + return NULL; + } + + for (element = extensions; element != NULL; element = element->next) { + if (ext_str != NULL) { + tmp_str = ext_str; + + if (element->next == NULL) { + ext_str = g_strconcat (tmp_str, ".", (char *)element->data, NULL); + } else { + ext_str = g_strconcat (tmp_str, ".", (char *)element->data, ", ", NULL); + } + g_free (tmp_str); + } else { + if (g_list_length (extensions) == 1) { + ext_str = g_strconcat (".", (char *)element->data, NULL); + } else { + ext_str = g_strconcat (".", (char *)element->data, ", ", NULL); + } + } + } + gnome_vfs_mime_extensions_list_free (extensions); + + return ext_str; +} + + +/** + * gnome_vfs_mime_extensions_list_free: + * @list: the extensions list + * + * Call this function on the list returned by gnome_vfs_mime_extensions + * to free the list and all of its elements. + **/ +void +gnome_vfs_mime_extensions_list_free (GList *list) +{ + if (list == NULL) { + return; + } + g_list_foreach (list, (GFunc) g_free, NULL); + g_list_free (list); +} + + + +static gint +mime_list_sort (gconstpointer a, gconstpointer b) +{ + return (strcmp ((const char *) a, (const char *) b)); +} + +/** + * get_key_name + * + * Hash table function that adds the name of the mime type + * to the supplied GList. + * + */ +static void +get_key_name (gpointer key, gpointer value, gpointer user_data) +{ + GnomeMimeContext *context; + char *name; + GList **list = user_data; + GList *duplicate; + + if (value == NULL || key == NULL) { + return; + } + + context = (GnomeMimeContext *) value; + + if (context->mime_type[0] == '#') { + return; + } + + if (is_mime_type_deleted (context->mime_type)) { + return; + } + + /* Get name from key and exit if key is NULL or string is empty */ + name = (char *)key; + if (name == NULL || strlen (name) == 0) { + return; + } + + duplicate = NULL; + duplicate = g_list_find_custom ((*list), context->mime_type, (GCompareFunc)strcmp); + if (duplicate == NULL) { + (*list) = g_list_insert_sorted ((*list), g_strdup(context->mime_type), mime_list_sort); + } + +} + +/** + * gnome_vfs_mime_reset + * + * resets the user's mime database to the system defaults. + */ +void +gnome_vfs_mime_reset (void) +{ + char *filename; + + filename = g_strconcat (user_mime_dir.dirname, "/user.keys", NULL); + unlink (filename); + g_free (filename); + + filename = g_strconcat (user_mime_dir.dirname, "/user.mime", NULL); + unlink (filename); + g_free (filename); +} + + +/** + * gnome_vfs_mime_registered_mime_type_delete: + * @mime_type: string representing the existing type to delete + * + * Delete a mime type for the user which runs this command. + * You can undo this only by calling gnome_vfs_mime_reset + */ + +void +gnome_vfs_mime_registered_mime_type_delete (const char *mime_type) +{ + gnome_vfs_mime_set_registered_type_key (mime_type, + DELETED_KEY, + DELETED_VALUE); + +} + +/* + * gnome_vfs_get_registered_mime_types + * + * Return the list containing the name of all + * registrered mime types. + * This function is costly in terms of speed. + */ +GList * +gnome_vfs_get_registered_mime_types (void) +{ + GList *type_list = NULL; + + if (!gnome_vfs_mime_inited) { + gnome_vfs_mime_init (); + } + + reload_if_needed (); + + /* Extract mime type names */ + g_hash_table_foreach (registered_types_user, get_key_name, &type_list); + g_hash_table_foreach (registered_types, get_key_name, &type_list); + + return type_list; +} + +/** + * gnome_vfs_mime_registered_mime_type_list_free: + * @list: the extensions list + * + * Call this function on the list returned by gnome_vfs_get_registered_mime_types + * to free the list and all of its elements. + */ +void +gnome_vfs_mime_registered_mime_type_list_free (GList *list) +{ + if (list == NULL) { + return; + } + + g_list_foreach (list, (GFunc) g_free, NULL); + g_list_free (list); +} + +/** + * gnome_vfs_mime_set_registered_type_key: + * @mime_type: Mime type to set key for + * @key: The key to set + * @data: The data to set for the key + * + * This function sets the key data for the registered mime + * type's hash table. + * + * Returns: GNOME_VFS_OK if the operation succeeded, otherwise an error code + */ +GnomeVFSResult +gnome_vfs_mime_set_registered_type_key (const char *mime_type, const char *key, const char *value) +{ + GnomeVFSResult result; + + result = set_value_real (mime_type, key, value, registered_types_user); + + if (gnome_vfs_is_frozen == 0) { + result = write_back_mime_user_file (); + } + + return result; +} + +/** + * gnome_vfs_mime_get_registered_mime_type_key + * @mime_type: a mime type. + * @key: A key to lookup for the given mime-type + * + * This function retrieves the value associated with @key in + * the given GnomeMimeContext. The string is private, you + * should not free the result. + */ +static const char * +gnome_vfs_mime_get_registered_mime_type_key (const char *mime_type, const char *key) +{ + if (!gnome_vfs_mime_inited) + gnome_vfs_mime_init (); + + return get_value_real (mime_type, key, + registered_types_user, + registered_types); +} + + +static gboolean +ensure_user_directory_exist (void) +{ + DIR *dir; + gboolean retval; + + if (stat (user_mime_dir.dirname, &user_mime_dir.s) != -1) + user_mime_dir.valid = TRUE; + else + user_mime_dir.valid = FALSE; + + dir = NULL; + dir = opendir (user_mime_dir.dirname); + if (dir == NULL) { + int result; + + result = mkdir (user_mime_dir.dirname, S_IRWXU ); + if (result != 0) { + user_mime_dir.valid = FALSE; + return FALSE; + } + dir = opendir (user_mime_dir.dirname); + if (dir == NULL) { + user_mime_dir.valid = FALSE; + } + } + + retval = (dir != NULL); + if (retval) + closedir (dir); + return retval; +} + + +static void +write_back_mime_user_file_context_callback (char *key_data, + char *value_data, + FILE *file) +{ + fprintf (file, "\t%s: %s\n", key_data, value_data); +} +static void +write_back_mime_user_file_callback (char *mime_type, + GnomeMimeContext *context, + FILE *file) +{ + fprintf (file, "%s\n", mime_type); + g_hash_table_foreach (context->keys, + (GHFunc) write_back_mime_user_file_context_callback, + file); + fprintf (file, "\n"); +} + +static GnomeVFSResult +write_back_mime_user_file (void) +{ + FILE *file; + char *filename; + + if (!ensure_user_directory_exist ()) { + return gnome_vfs_result_from_errno (); + } + + if (!user_mime_dir.system_dir) { + filename = g_strconcat (user_mime_dir.dirname, "/user.mime", NULL); + + remove (filename); + file = fopen (filename, "w"); + if (file == NULL) + return gnome_vfs_result_from_errno (); + + fprintf (file, + "# This file was autogenerated by gnome-vfs-mime-info.\n" + "# Do not edit by hand.\n"); + + g_hash_table_foreach (registered_types_user, + (GHFunc) write_back_mime_user_file_callback, + file); + + /* Cleanup file */ + fclose (file); + g_free (filename); + } + + return GNOME_VFS_OK; +} + +static void +write_back_keys_user_file_context_callback (char *key_data, + char *value_data, + FILE *file) +{ + fprintf (file, "\t%s=%s\n", key_data, value_data); +} +static void +write_back_keys_user_file_callback (char *mime_type, + GnomeMimeContext *context, + FILE *file) + +{ + fprintf (file, "%s\n", mime_type); + g_hash_table_foreach (context->keys, + (GHFunc) write_back_keys_user_file_context_callback, + file); + fprintf (file, "\n"); +} + +static GnomeVFSResult +write_back_keys_user_file (void) +{ + FILE *file; + char *filename; + + if (!ensure_user_directory_exist ()) { + return gnome_vfs_result_from_errno (); + } + + if (!user_mime_dir.system_dir) { + filename = g_strconcat (user_mime_dir.dirname, "/user.keys", NULL); + + remove (filename); + file = fopen (filename, "w"); + if (file == NULL) { + return gnome_vfs_result_from_errno (); + } + + + fprintf (file, "# this file was autogenerated by gnome-vfs-mime-info.\n" + "# DO NOT EDIT BY HAND\n"); + + g_hash_table_foreach (specific_types_user, + (GHFunc) write_back_keys_user_file_callback, + file); + + /* Cleanup file */ + fclose (file); + g_free (filename); + } + + return GNOME_VFS_OK; +} diff --git a/libgnomevfs/gnome-vfs-mime-info.h b/libgnomevfs/gnome-vfs-mime-info.h new file mode 100644 index 0000000..1804394 --- /dev/null +++ b/libgnomevfs/gnome-vfs-mime-info.h @@ -0,0 +1,87 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* gnome-vfs-mime-info.h + * + * Copyright (C) 1998 Miguel de Icaza + * Copyright (C) 2000 Eazel, Inc + * + * The Gnome Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Gnome Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef GNOME_VFS_MIME_INFO_H +#define GNOME_VFS_MIME_INFO_H + +#include +#include + +G_BEGIN_DECLS + + /* functions to freeze/thaw the internal hash tables to + avoid writing them back to disk everytime you modify + them through the _set_ functions, or accidentally + reloading them from disk during an edit. + */ +void gnome_vfs_mime_freeze (void); +void gnome_vfs_mime_thaw (void); + + /* forces a reload of the config files */ +void gnome_vfs_mime_info_reload (void); + + +gboolean gnome_vfs_mime_type_is_known (const char *mime_type); + + /* functions which access to the .keys files */ +const char *gnome_vfs_mime_get_value (const char *mime_type, + const char *key); +GnomeVFSResult gnome_vfs_mime_set_value (const char *mime_type, + const char *key, + const char *value); +GList *gnome_vfs_mime_get_key_list (const char *mime_type); +void gnome_vfs_mime_keys_list_free (GList *mime_type_list); + + /* functions to access the .mime files */ +GList *gnome_vfs_mime_get_extensions_list (const char *mime_type); +void gnome_vfs_mime_extensions_list_free (GList *list); +char *gnome_vfs_mime_get_extensions_string (const char *mime_type); +char *gnome_vfs_mime_get_extensions_pretty_string (const char *mime_type); +GList *gnome_vfs_get_registered_mime_types (void); +void gnome_vfs_mime_registered_mime_type_list_free (GList *list); +GnomeVFSResult gnome_vfs_mime_set_registered_type_key (const char *mime_type, + const char *key, + const char *data); +GnomeVFSResult gnome_vfs_mime_set_extensions_list (const char *mime_type, + const char *extensions_list); +void gnome_vfs_mime_registered_mime_type_delete (const char *mime_type); +void gnome_vfs_mime_reset (void); + + +G_END_DECLS + +#endif /* GNOME_VFS_MIME_INFO_H */ + + + + + + + + + + + + + + diff --git a/libgnomevfs/gnome-vfs-mime-magic.c b/libgnomevfs/gnome-vfs-mime-magic.c new file mode 100644 index 0000000..7d6b0e0 --- /dev/null +++ b/libgnomevfs/gnome-vfs-mime-magic.c @@ -0,0 +1,958 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* + * gnome-vfs-mime-magic.c + * + * Written by: + * James Youngman (jay@gnu.org) + * + * Adatped to the GNOME needs by: + * Elliot Lee (sopwith@cuc.edu) + * + * Rewritten by: + * Pavel Cisler + */ + +#include +#include "gnome-vfs-mime-magic.h" + +#include + +#include "gnome-vfs-mime-sniff-buffer-private.h" +#include "gnome-vfs-mime.h" +#include "gnome-vfs-private-utils.h" + +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_WCTYPE_H +#include +#include +#endif + +#include +#include +#include +#include +#include +#include +static gboolean +is_octal_digit (char ch) +{ + return ch >= '0' && ch <= '7'; +} + +static gboolean +is_hex_digit (char ch) +{ + if (ch >= '0' && ch <= '9') { + return TRUE; + } + if (ch >= 'a' && ch <= 'f') { + return TRUE; + } + + return (ch >= 'A' && ch <= 'F'); +} + +/* FIXME bugzilla.eazel.com 2760: + * should return error here + */ +static guchar +read_octal_byte (const char **pos) +{ + guchar retval = 0; + int count; + + for (count = 0; count < 3; count++) { + if (!is_octal_digit (**pos)) { + g_error ("bad octal digit %c", **pos); + return retval; + } + + retval *= 8; + retval += **pos - '0'; + (*pos)++; + } + + return retval; +} + +/* FIXME bugzilla.eazel.com 2760: + * should return error here + */ +static guchar +read_hex_byte (const char **pos) +{ + guchar retval = 0; + int count; + + for (count = 0; ; count++) { + if (!is_hex_digit (**pos)) { + g_error ("bad hex digit %c", **pos); + return retval; + } + if (**pos >= '0' && **pos <= '9') { + retval += **pos - '0'; + } else { + retval += g_ascii_tolower (**pos) - 'a' + 10; + } + + (*pos)++; + if (count >= 1) { + break; + } + retval *= 16; + } + + return retval; +} + +/* FIXME bugzilla.eazel.com 2760: + * should return error here + */ +static const char * +read_string_val (const char *scanner, char *intobuf, int max_len, guint16 *into_len) +{ + char *intobufend; + char ch; + + intobufend = intobuf + max_len - 1; + *into_len = 0; + + while (*scanner && !g_ascii_isspace (*scanner) && *scanner != '#') { + ch = *scanner++; + + switch (ch) { + case '\\': + switch (*scanner) { + case 'x': + /* read hex value */ + scanner++; + ch = read_hex_byte (&scanner); + break; + case '0': + case '1': + case '2': + case '3': + /* read octal value */ + ch = read_octal_byte (&scanner); + break; + case 'n': + ch = '\n'; + scanner++; + break; + default: + /* everything else is a literal */ + ch = *scanner; + scanner++; + break; + } + break; + default: + break; + /* already setup c/moved scanner */ + } + if (intobuf < intobufend) { + *intobuf++=ch; + (*into_len)++; + } + } + + *intobuf = '\0'; + return scanner; +} + +static const char * +read_hex_pattern (const char *scanner, char *result, int length) +{ + if (*scanner == '0') { + scanner++; + } + if (*scanner++ != 'x') { + return NULL; + } + for (;length > 0; length--) { + if (!is_hex_digit (scanner[0]) || !is_hex_digit (scanner[1])) { + return NULL; + } + *result++ = read_hex_byte (&scanner); + } + + return scanner; +} + +static gboolean +read_num_val(const char **offset, int bsize, int *result) +{ + char fmttype, fmtstr[4]; + const char *scanner = *offset; + + if (*scanner == '0') { + if (g_ascii_tolower (scanner[1]) == 'x') { + fmttype = 'x'; + } else { + fmttype = 'o'; + } + } else { + fmttype = 'u'; + } + + switch (bsize) { + case 1: + fmtstr[0] = '%'; + fmtstr[1] = fmttype; + fmtstr[2] = '\0'; + if (sscanf (scanner, fmtstr, result) < 1) { + return FALSE; + } + break; + case 2: + fmtstr[0] = '%'; + fmtstr[1] = 'h'; + fmtstr[2] = fmttype; + fmtstr[3] = '\0'; + if (sscanf (scanner, fmtstr, result) < 1) { + return FALSE; + } + break; + case 4: + fmtstr[0] = '%'; + fmtstr[1] = fmttype; + fmtstr[2] = '\0'; + if (sscanf (scanner, fmtstr, result) < 1) { + return FALSE; + } + break; + } + + while (**offset && !g_ascii_isspace (**offset)) { + (*offset)++; + } + + return TRUE; +} + +static const char * +eat_white_space (const char *scanner) +{ + while (g_ascii_isspace (*scanner)) { + scanner++; + } + return scanner; +} + +static gboolean +match_pattern (const char *scanner, const char **resulting_scanner, const char *pattern) +{ + if (strncmp(scanner, pattern, strlen (pattern)) == 0) { + *resulting_scanner = scanner + strlen (pattern); + return TRUE; + } + *resulting_scanner = scanner; + return FALSE; +} + +GnomeMagicEntry * +_gnome_vfs_mime_magic_parse (const gchar *filename, gint *nents) +{ + GArray *array; + GnomeMagicEntry newent, *retval; + FILE *infile; + const char *infile_name; + int bsize = 0; + char parsed_line [256]; + const char *scanner; + int index; + + infile_name = filename; + + if (!infile_name) { + return NULL; + } + + infile = fopen (infile_name, "r"); + if (!infile) { + return NULL; + } + + array = g_array_new (FALSE, FALSE, sizeof (GnomeMagicEntry)); + + while (fgets (parsed_line, sizeof (parsed_line), infile)) { + scanner = parsed_line; + + /* eat the head */ + scanner = eat_white_space (scanner); + + if (!*scanner || *scanner == '#') { + continue; + } + + if (!g_ascii_isdigit (*scanner)) { + continue; + } + + if (sscanf (scanner, "%hu", &newent.range_start) < 1) { + continue; + } + newent.range_end = newent.range_start; + + while (g_ascii_isdigit (*scanner)) { + scanner++; /* eat the offset */ + } + + if (*scanner == ':') { + /* handle an offset range */ + scanner++; + if (sscanf (scanner, "%hu", &newent.range_end) < 1) { + continue; + } + } + + while (*scanner && !g_ascii_isspace (*scanner)) { + scanner++; /* eat the offset */ + } + + scanner = eat_white_space (scanner); + + if (!*scanner || *scanner == '#') { + continue; + } + + if (match_pattern (scanner, &scanner, "byte")) { + newent.type = T_BYTE; + } else if (match_pattern (scanner, &scanner, "short")) { + newent.type = T_SHORT; + } else if (match_pattern (scanner, &scanner, "long")) { + newent.type = T_LONG; + } else if (match_pattern (scanner, &scanner, "string")) { + newent.type = T_STR; + } else if (match_pattern (scanner, &scanner, "date")) { + newent.type = T_DATE; + } else if (match_pattern (scanner, &scanner, "beshort")) { + newent.type = T_BESHORT; + } else if (match_pattern (scanner, &scanner, "belong")) { + newent.type = T_BELONG; + } else if (match_pattern (scanner, &scanner, "bedate")) { + newent.type = T_BEDATE; + } else if (match_pattern (scanner, &scanner, "leshort")) { + newent.type = T_LESHORT; + } else if (match_pattern (scanner, &scanner, "lelong")) { + newent.type = T_LELONG; + } else if (match_pattern (scanner, &scanner, "ledate")) { + newent.type = T_LEDATE; + } else + continue; /* weird type */ + + scanner = eat_white_space (scanner); + if (!*scanner || *scanner == '#') { + continue; + } + + switch (newent.type) { + case T_BYTE: + bsize = 1; + break; + + case T_SHORT: + case T_BESHORT: + case T_LESHORT: + bsize = 2; + break; + + case T_LONG: + case T_BELONG: + case T_LELONG: + bsize = 4; + break; + + case T_DATE: + case T_BEDATE: + case T_LEDATE: + bsize = 4; + break; + + default: + /* do nothing */ + break; + } + + if (newent.type == T_STR) { + scanner = read_string_val (scanner, newent.pattern, + sizeof (newent.pattern), &newent.pattern_length); + } else { + newent.pattern_length = bsize; + if (!read_num_val (&scanner, bsize, (int *)&newent.pattern)) { + continue; + } + } + + scanner = eat_white_space (scanner); + if (!*scanner || *scanner == '#') { + continue; + } + + if (*scanner == '&') { + scanner++; + scanner = read_hex_pattern (scanner, &newent.mask [0], newent.pattern_length); + if (!scanner) { + g_error ("bad mask"); + continue; + } + newent.use_mask = TRUE; + + for (index = 0; index < newent.pattern_length; index++) { + /* Apply the mask to the pattern itself so we don't have to + * do it each time we compare it with the tested bytes. + */ + newent.pattern[index] &= newent.mask[index]; + } + } else { + newent.use_mask = FALSE; + } + + scanner = eat_white_space (scanner); + if (!*scanner || *scanner == '#') { + continue; + } + + g_snprintf (newent.mimetype, sizeof (newent.mimetype), "%s", scanner); + bsize = strlen (newent.mimetype) - 1; + while (newent.mimetype [bsize] && g_ascii_isspace (newent.mimetype [bsize])) { + newent.mimetype [bsize--] = '\0'; + } + + g_array_append_val (array, newent); + } + fclose(infile); + + newent.type = T_END; + g_array_append_val (array, newent); + + retval = (GnomeMagicEntry *)array->data; + if (nents) { + *nents = array->len; + } + + g_array_free (array, FALSE); + + return retval; +} + +static void +endian_swap (guchar *result, const guchar *data, gsize length) +{ + const guchar *source_ptr = data; + guchar *dest_ptr = result + length - 1; + while (dest_ptr >= result) { + *dest_ptr-- = *source_ptr++; + } +} + +#if G_BYTE_ORDER == G_LITTLE_ENDIAN +#define FIRST_ENDIAN_DEPENDENT_TYPE T_BESHORT +#define LAST_ENDIAN_DEPENDENT_TYPE T_BEDATE +#else +#define FIRST_ENDIAN_DEPENDENT_TYPE T_LESHORT +#define LAST_ENDIAN_DEPENDENT_TYPE T_LEDATE +#endif + +static gboolean +try_one_pattern_on_buffer (const char *sniffed_stream, GnomeMagicEntry *magic_entry) +{ + gboolean using_cloned_pattern; + char pattern_clone [48]; + int index, count; + const char *pattern; + + using_cloned_pattern = FALSE; + if (magic_entry->type >= FIRST_ENDIAN_DEPENDENT_TYPE && magic_entry->type <= LAST_ENDIAN_DEPENDENT_TYPE) { + /* Endian-convert the data we are trying to recognize to + * our host endianness. + */ + char swap_buffer [sizeof(magic_entry->pattern)]; + + g_assert(magic_entry->pattern_length <= 4); + + memcpy (swap_buffer, sniffed_stream, magic_entry->pattern_length); + + endian_swap (pattern_clone, swap_buffer, magic_entry->pattern_length); + sniffed_stream = &pattern_clone[0]; + using_cloned_pattern = TRUE; + } + + if (magic_entry->use_mask) { + /* Apply mask to the examined data. At this point the data in + * sniffed_stream is in the same endianness as the mask. + */ + + if (!using_cloned_pattern) { + memcpy (pattern_clone, sniffed_stream, magic_entry->pattern_length); + using_cloned_pattern = TRUE; + sniffed_stream = &pattern_clone[0]; + } + + for (index = 0; index < magic_entry->pattern_length; index++) { + pattern_clone[index] &= magic_entry->mask[index]; + } + } + + if (*magic_entry->pattern != *sniffed_stream) { + return FALSE; + } + + for (count = magic_entry->pattern_length, pattern = magic_entry->pattern; + count > 0; count--) { + if (*pattern++ != *sniffed_stream++) { + return FALSE; + } + } + return TRUE; +} + +enum { + SNIFF_BUFFER_CHUNK = 32 +}; + + +static gboolean +gnome_vfs_mime_try_one_magic_pattern (GnomeVFSMimeSniffBuffer *sniff_buffer, + GnomeMagicEntry *magic_entry) +{ + int offset; + + if (sniff_buffer->read_whole_file && + sniff_buffer->buffer_length < magic_entry->range_end + magic_entry->pattern_length) { + /* There's no place this pattern could actually match */ + return FALSE; + } + + for (offset = magic_entry->range_start; offset <= magic_entry->range_end; offset++) { + /* this check is done only as an optimization + * _gnome_vfs_mime_sniff_buffer_get already implements the laziness. + * This gets called a million times though and every bit performance + * is valuable. This way we avoid making the call. + */ + + if (sniff_buffer->buffer_length < offset + magic_entry->pattern_length) { + + if (!sniff_buffer->read_whole_file) { + if (_gnome_vfs_mime_sniff_buffer_get (sniff_buffer, + offset + magic_entry->pattern_length) != GNOME_VFS_OK) { + return FALSE; + } + } else { + /* We have the entire file and the pattern won't fit. Return FALSE */ + return FALSE; + } + } + + if (try_one_pattern_on_buffer (sniff_buffer->buffer + offset, magic_entry)) { + return TRUE; + } + } + return FALSE; +} + +/* We lock this mutex whenever we modify global state in this module. */ +G_LOCK_DEFINE_STATIC (mime_magic_table_mutex); + +static GnomeMagicEntry *mime_magic_table = NULL; + +static GnomeMagicEntry * +gnome_vfs_mime_get_magic_table (void) +{ + G_LOCK (mime_magic_table_mutex); + + if (mime_magic_table == NULL) { + mime_magic_table = _gnome_vfs_mime_magic_parse + (SYSCONFDIR "/gnome-vfs-mime-magic" , NULL); + } + + G_UNLOCK (mime_magic_table_mutex); + + return mime_magic_table; +} + +const char * +_gnome_vfs_mime_get_type_from_magic_table (GnomeVFSMimeSniffBuffer *buffer) +{ + GnomeMagicEntry *magic_table; + + magic_table = gnome_vfs_mime_get_magic_table (); + if (magic_table == NULL) { + return NULL; + } + + for (; magic_table->type != T_END; magic_table++) { + if (gnome_vfs_mime_try_one_magic_pattern (buffer, magic_table)) { + return magic_table->mimetype; + } + } + return NULL; +} + + +GnomeMagicEntry * +gnome_vfs_mime_test_get_magic_table (const char *table_path) +{ + G_LOCK (mime_magic_table_mutex); + if (mime_magic_table == NULL) { + mime_magic_table = _gnome_vfs_mime_magic_parse (table_path, NULL); + } + G_UNLOCK (mime_magic_table_mutex); + + return mime_magic_table; +} + +#define HEX_DIGITS "0123456789abcdef" + +static void +print_escaped_string (const guchar *string, int length) +{ + for (; length > 0; length--, string++) { + if (*string == '\\' || *string == '#') { + /* escape \, #, etc. properly */ + printf ("\\%c", *string); + } else if (g_ascii_isgraph (*string)) { + /* everything printable except for white space can go directly */ + printf ("%c", *string); + } else { + /* everything else goes in hex */ + printf ("\\x%c%c", HEX_DIGITS[(*string) / 16], HEX_DIGITS[(*string) % 16]); + } + } +} + +static void +print_hex_pattern (const guchar *string, int length) +{ + printf ("\\x"); + for (; length > 0; length--, string++) { + printf ("%c%c", HEX_DIGITS[(*string) / 16], HEX_DIGITS[(*string) % 16]); + } +} +void +gnome_vfs_mime_dump_magic_table (void) +{ + GnomeMagicEntry *magic_table; + + magic_table = gnome_vfs_mime_get_magic_table (); + if (magic_table == NULL) { + return; + } + + for (; magic_table->type != T_END; magic_table++) { + printf ("%d", magic_table->range_start); + if (magic_table->range_start != magic_table->range_end) { + printf (":%d", magic_table->range_end); + } + printf ("\t"); + switch (magic_table->type) { + case T_BYTE: + printf("byte"); + break; + case T_SHORT: + printf("short"); + break; + case T_LONG: + printf("long"); + break; + case T_STR: + printf("string"); + break; + case T_DATE: + printf("date"); + break; + case T_BESHORT: + printf("beshort"); + break; + case T_BELONG: + printf("belong"); + break; + case T_BEDATE: + printf("bedate"); + break; + case T_LESHORT: + printf("leshort"); + break; + case T_LELONG: + printf("lelong"); + break; + case T_LEDATE: + printf("ledate"); + break; + default: + break; + } + printf ("\t"); + print_escaped_string (magic_table->pattern, magic_table->pattern_length); + if (magic_table->use_mask) { + printf (" &"); + print_hex_pattern (magic_table->mask, magic_table->pattern_length); + } + printf ("\t%s\n", magic_table->mimetype); + } +} + +void +_gnome_vfs_mime_clear_magic_table (void) +{ + G_LOCK (mime_magic_table_mutex); + g_free (mime_magic_table); + mime_magic_table = NULL; + G_UNLOCK (mime_magic_table_mutex); +} + +/** + * gnome_vfs_get_mime_type_for_buffer: + * @buffer: a sniff buffer referencing either a file or data in memory + * + * This routine uses a magic database to guess the mime type of the + * data represented by @buffer. + * + * Returns a pointer to an internal copy of the mime-type for @buffer. + */ +const char * +gnome_vfs_get_mime_type_for_buffer (GnomeVFSMimeSniffBuffer *buffer) +{ + return _gnome_vfs_get_mime_type_internal (buffer, NULL); +} + +enum { + GNOME_VFS_TEXT_SNIFF_LENGTH = 256 +}; + + +/** + * _gnome_vfs_sniff_buffer_looks_like_text: + * @sniff_buffer: buffer to examine + * + * Return value: returns %TRUE if the contents of @sniff_buffer appear to + * be text. + **/ +gboolean +_gnome_vfs_sniff_buffer_looks_like_text (GnomeVFSMimeSniffBuffer *sniff_buffer) +{ + gchar *end; + + _gnome_vfs_mime_sniff_buffer_get (sniff_buffer, GNOME_VFS_TEXT_SNIFF_LENGTH); + + if (sniff_buffer->buffer_length == 0) { + return FALSE; + } + + if (g_utf8_validate (sniff_buffer->buffer, + sniff_buffer->buffer_length, (const gchar**)&end)) + { + return TRUE; + } else { + /* Check whether the string was truncated in the middle of + * a valid UTF8 char, or if we really have an invalid + * UTF8 string + */ + gint remaining_bytes = sniff_buffer->buffer_length; + + remaining_bytes -= (end-((gchar*)sniff_buffer->buffer)); + + if (g_utf8_get_char_validated(end, remaining_bytes) == -2) + return TRUE; +#if defined(HAVE_WCTYPE_H) && defined (HAVE_MBRTOWC) + else { + size_t wlen; + wchar_t wc; + gchar *src, *end; + mbstate_t state; + + src = sniff_buffer->buffer; + end = sniff_buffer->buffer + sniff_buffer->buffer_length; + + memset (&state, 0, sizeof (state)); + while (src < end) { + /* Don't allow embedded zeros in textfiles */ + if (*src == 0) + return FALSE; + + wlen = mbrtowc(&wc, src, end - src, &state); + + if (wlen == (size_t)(-1)) { + /* Illegal mb sequence */ + return FALSE; + } + + if (wlen == (size_t)(-2)) { + /* No complete mb char before end + * Probably a cut off char which is ok */ + return TRUE; + } + + if (wlen == 0) { + /* Don't allow embedded zeros in textfiles */ + return FALSE; + } + + if (!iswspace (wc) && !iswprint(wc)) { + /* Not a printable or whitspace + * Probably not a text file */ + return FALSE; + } + + src += wlen; + } + return TRUE; + } +#endif /* defined(HAVE_WCTYPE_H) && defined (HAVE_MBRTOWC) */ + } + return FALSE; +} + +static int bitrates[2][15] = { + { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320}, + { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 } +}; + +static int frequencies[2][3] = { + { 44100, 48000, 32000 }, + { 22050, 24000, 16000 } +}; + +/* + * Return length of an MP3 frame using potential 32-bit header value. See + * "http://www.dv.co.yu/mpgscript/mpeghdr.htm" for details on the header + * format. + * + * NOTE: As an optimization and because they are rare, this returns 0 for + * version 2.5 or free format MP3s. + */ +static gsize +get_mp3_frame_length (unsigned long mp3_header) +{ + int ver = 4 - ((mp3_header >> 19) & 3u); + int br = (mp3_header >> 12) & 0xfu; + int srf = (mp3_header >> 10) & 3u; + + /* are frame sync and layer 3 bits set? */ + if (((mp3_header & 0xffe20000ul) == 0xffe20000ul) + /* good version? */ + && ((ver == 1) || (ver == 2)) + /* good bitrate index (not free or invalid)? */ + && (br > 0) && (br < 15) + /* good sampling rate frequency index? */ + && (srf != 3) + /* not using reserved emphasis value? */ + && ((mp3_header & 3u) != 2)) { + /* then this is most likely the beginning of a valid frame */ + + gsize length = (gsize) bitrates[ver - 1][br] * 144000; + length /= frequencies[ver - 1][srf]; + return length += ((mp3_header >> 9) & 1u) - 4; + } + return 0; +} + +static unsigned long +get_4_byte_value (const unsigned char *bytes) +{ + unsigned long value = 0; + int count; + + for (count = 0; count < 4; ++count) { + value <<= 8; + value |= *bytes++; + } + return value; +} + +enum { + GNOME_VFS_MP3_SNIFF_LENGTH = 256 +}; + +/** + * _gnome_vfs_sniff_buffer_looks_like_mp3: + * @sniff_buffer: buffer to examine + * + * Return value: returns %TRUE if the contents of @sniff_buffer appear to + * be an MP3. + **/ +gboolean +_gnome_vfs_sniff_buffer_looks_like_mp3 (GnomeVFSMimeSniffBuffer *sniff_buffer) +{ + unsigned long mp3_header; + int offset; + + if (_gnome_vfs_mime_sniff_buffer_get (sniff_buffer, GNOME_VFS_MP3_SNIFF_LENGTH) != GNOME_VFS_OK) { + return FALSE; + } + + /* + * Use algorithm described in "ID3 tag version 2.3.0 Informal Standard" + * at "http://www.id3.org/id3v2.3.0.html" to detect a valid header, "An + * ID3v2 tag can be detected with the following pattern: + * $49 44 33 yy yy xx zz zz zz zz + * Where yy is less than $FF, xx is the 'flags' byte and zz is less than + * $80." + * + * The informal standard also says, "The ID3v2 tag size is encoded with + * four bytes where the most significant bit (bit 7) is set to zero in + * every byte, making a total of 28 bits. The zeroed bits are ignored, + * so a 257 bytes long tag is represented as $00 00 02 01." + */ + if (strncmp ((char *) sniff_buffer->buffer, "ID3", 3) == 0 + && (sniff_buffer->buffer[3] != 0xffu) + && (sniff_buffer->buffer[4] != 0xffu) + && (sniff_buffer->buffer[6] < 0x80u) + && (sniff_buffer->buffer[7] < 0x80u) + && (sniff_buffer->buffer[8] < 0x80u) + && (sniff_buffer->buffer[9] < 0x80u)) { + /* checks for existance of vorbis identification header */ + for (offset=10; offset < GNOME_VFS_MP3_SNIFF_LENGTH-7; offset++) { + if (strncmp ((char *) &sniff_buffer->buffer[offset], + "\x01vorbis", 7) == 0) { + return FALSE; + } + } + return TRUE; + } + + /* + * Scan through the first "GNOME_VFS_MP3_SNIFF_LENGTH" bytes of the + * buffer to find a potential 32-bit MP3 frame header. + */ + mp3_header = 0; + for (offset = 0; offset < GNOME_VFS_MP3_SNIFF_LENGTH; offset++) { + gsize length; + + mp3_header <<= 8; + mp3_header |= sniff_buffer->buffer[offset]; + mp3_header &= 0xfffffffful; + + length = get_mp3_frame_length (mp3_header); + + if (length != 0) { + /* + * Since one frame is available, is there another frame + * just to be sure this is more likely to be a real MP3 + * buffer? + */ + offset += 1 + length; + + if (_gnome_vfs_mime_sniff_buffer_get (sniff_buffer, offset + 4) != GNOME_VFS_OK) { + return FALSE; + } + mp3_header = get_4_byte_value (&sniff_buffer->buffer[offset]); + length = get_mp3_frame_length (mp3_header); + + if (length != 0) { + return TRUE; + } + break; + } + } + + return FALSE; +} diff --git a/libgnomevfs/gnome-vfs-mime-magic.h b/libgnomevfs/gnome-vfs-mime-magic.h new file mode 100644 index 0000000..3192f4a --- /dev/null +++ b/libgnomevfs/gnome-vfs-mime-magic.h @@ -0,0 +1,45 @@ +#ifndef GNOME_VFS_MIME_MAGIC_H +#define GNOME_VFS_MIME_MAGIC_H + +#include + +G_BEGIN_DECLS + +/* Used internally by the magic code, exposes the parsing to users */ +typedef enum { + T_END, /* end of array */ + T_BYTE, + T_SHORT, + T_LONG, + T_STR, + T_DATE, + T_BESHORT, + T_BELONG, + T_BEDATE, + T_LESHORT, + T_LELONG, + T_LEDATE +} GnomeMagicType; + +typedef struct _GnomeMagicEntry { + GnomeMagicType type; + guint16 range_start, range_end; + + guint16 pattern_length; + gboolean use_mask; + char pattern [48]; + char mask [48]; + + char mimetype[48]; +} GnomeMagicEntry; + +GnomeMagicEntry *_gnome_vfs_mime_magic_parse (const gchar *filename, + gint *nents); + +/* testing calls */ +GnomeMagicEntry *gnome_vfs_mime_test_get_magic_table (const char *table_path); +void gnome_vfs_mime_dump_magic_table (void); + +G_END_DECLS + +#endif diff --git a/libgnomevfs/gnome-vfs-mime-monitor.c b/libgnomevfs/gnome-vfs-mime-monitor.c new file mode 100644 index 0000000..293120e --- /dev/null +++ b/libgnomevfs/gnome-vfs-mime-monitor.c @@ -0,0 +1,205 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + + gnome-vfs-mime-monitor.c: Class for noticing changes in MIME data. + + Copyright (C) 2000 Eazel, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: John Sullivan , +*/ + +#include +#include "gnome-vfs-mime-monitor.h" +#include "gnome-vfs-mime-private.h" +#include "gnome-vfs-ops.h" + +enum { + DATA_CHANGED, + LAST_SIGNAL +}; + +enum { + LOCAL_MIME_DIR, + GNOME_MIME_DIR, +}; + +static guint signals[LAST_SIGNAL]; + +static GnomeVFSMIMEMonitor *global_mime_monitor = NULL; + +typedef struct _MonitorCallbackData +{ + GnomeVFSMIMEMonitor *monitor; + gint type; +} MonitorCallbackData; + +struct _GnomeVFSMIMEMonitorPrivate +{ + GnomeVFSMonitorHandle *global_handle; + GnomeVFSMonitorHandle *local_handle; + + /* The hoops I jump through */ + MonitorCallbackData *gnome_callback_data; + MonitorCallbackData *local_callback_data; +}; + + +static void gnome_vfs_mime_monitor_class_init (GnomeVFSMIMEMonitorClass *klass); +static void gnome_vfs_mime_monitor_init (GnomeVFSMIMEMonitor *monitor); +static void mime_dir_changed_callback (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data); +static void gnome_vfs_mime_monitor_finalize (GObject *object); + + + +static void +gnome_vfs_mime_monitor_class_init (GnomeVFSMIMEMonitorClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = gnome_vfs_mime_monitor_finalize; + + signals [DATA_CHANGED] = + g_signal_new ("data_changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GnomeVFSMIMEMonitorClass, data_changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} + +static void +gnome_vfs_mime_monitor_init (GnomeVFSMIMEMonitor *monitor) +{ + gchar *mime_dir; + + monitor->priv = g_new (GnomeVFSMIMEMonitorPrivate, 1); + + monitor->priv->gnome_callback_data = g_new (MonitorCallbackData, 1); + monitor->priv->local_callback_data = g_new (MonitorCallbackData, 1); + + /* FIXME: Bug #80268. These wouldn't be private members if we had a + * _full variant. However, if I want to clean them up, I need to keep + * them around. */ + monitor->priv->gnome_callback_data->type = GNOME_MIME_DIR; + monitor->priv->gnome_callback_data->monitor = monitor; + monitor->priv->local_callback_data->type = LOCAL_MIME_DIR; + monitor->priv->local_callback_data->monitor = monitor; + + mime_dir = g_strdup (DATADIR "/mime-info"); + gnome_vfs_monitor_add (&monitor->priv->global_handle, + mime_dir, + GNOME_VFS_MONITOR_DIRECTORY, + mime_dir_changed_callback, + monitor->priv->gnome_callback_data); + g_free (mime_dir); + + mime_dir = g_strconcat (g_get_home_dir (), "/.gnome/mime-info", NULL); + if (!g_file_test (mime_dir, G_FILE_TEST_EXISTS)) { + mkdir (mime_dir, S_IRWXU); + } + gnome_vfs_monitor_add (&monitor->priv->local_handle, + mime_dir, + GNOME_VFS_MONITOR_DIRECTORY, + mime_dir_changed_callback, + monitor->priv->local_callback_data); + g_free (mime_dir); +} + + +static void +mime_dir_changed_callback (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + MonitorCallbackData *monitor_callback_data = (MonitorCallbackData *)user_data; + + if (monitor_callback_data->type == GNOME_MIME_DIR) + _gnome_vfs_mime_info_mark_gnome_mime_dir_dirty (); + else if (monitor_callback_data->type == LOCAL_MIME_DIR) + _gnome_vfs_mime_info_mark_user_mime_dir_dirty (); + + _gnome_vfs_mime_monitor_emit_data_changed (monitor_callback_data->monitor); +} + +static void +gnome_vfs_mime_monitor_finalize (GObject *object) +{ + gnome_vfs_monitor_cancel (GNOME_VFS_MIME_MONITOR (object)->priv->global_handle); + gnome_vfs_monitor_cancel (GNOME_VFS_MIME_MONITOR (object)->priv->local_handle); + g_free (GNOME_VFS_MIME_MONITOR (object)->priv->gnome_callback_data); + g_free (GNOME_VFS_MIME_MONITOR (object)->priv->local_callback_data); + g_free (GNOME_VFS_MIME_MONITOR (object)->priv); +} + +/** + * gnome_vfs_mime_monitor_get: + * + * Get access to the single global monitor. + * + * Return value: the global #GnomeVFSMIMEMonitor + **/ +GnomeVFSMIMEMonitor * +gnome_vfs_mime_monitor_get (void) +{ + if (global_mime_monitor == NULL) { + global_mime_monitor = GNOME_VFS_MIME_MONITOR + (g_object_new (gnome_vfs_mime_monitor_get_type (), NULL)); + } + return global_mime_monitor; +} + + +void +_gnome_vfs_mime_monitor_emit_data_changed (GnomeVFSMIMEMonitor *monitor) +{ + g_return_if_fail (GNOME_VFS_IS_MIME_MONITOR (monitor)); + + g_signal_emit (G_OBJECT (monitor), + signals [DATA_CHANGED], 0); +} + +GType +gnome_vfs_mime_monitor_get_type (void) +{ + static GType type = 0; + + if (type == 0) { + GTypeInfo info = { + sizeof (GnomeVFSMIMEMonitorClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) gnome_vfs_mime_monitor_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (GnomeVFSMIMEMonitor), + 0, /* n_preallocs */ + (GInstanceInitFunc) gnome_vfs_mime_monitor_init + }; + + type = g_type_register_static ( + G_TYPE_OBJECT, "GnomeVFSMIMEMonitor", &info, 0); + } + + return type; +} diff --git a/libgnomevfs/gnome-vfs-mime-monitor.h b/libgnomevfs/gnome-vfs-mime-monitor.h new file mode 100644 index 0000000..8e2bd01 --- /dev/null +++ b/libgnomevfs/gnome-vfs-mime-monitor.h @@ -0,0 +1,62 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + + gnome-vfs-mime-monitor.h: Class for noticing changes in MIME data. + + Copyright (C) 2000 Eazel, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: John Sullivan +*/ + +#ifndef GNOME_VFS_MIME_MONITOR_H +#define GNOME_VFS_MIME_MONITOR_H + +#include + +G_BEGIN_DECLS + +#define GNOME_VFS_MIME_MONITOR_TYPE (gnome_vfs_mime_monitor_get_type ()) +#define GNOME_VFS_MIME_MONITOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GNOME_VFS_MIME_MONITOR_TYPE, GnomeVFSMIMEMonitor)) +#define GNOME_VFS_MIME_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GNOME_VFS_MIME_MONITOR_TYPE, GnomeVFSMIMEMonitorClass)) +#define GNOME_VFS_IS_MIME_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GNOME_VFS_MIME_MONITOR_TYPE)) +#define GNOME_VFS_IS_MIME_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GNOME_VFS_MIME_MONITOR_TYPE)) + +typedef struct _GnomeVFSMIMEMonitorPrivate GnomeVFSMIMEMonitorPrivate; + +typedef struct { + GObject object; + + GnomeVFSMIMEMonitorPrivate *priv; +} GnomeVFSMIMEMonitor; + +typedef struct { + GObjectClass parent_class; + + /* signals */ + void (*data_changed) (GnomeVFSMIMEMonitor *monitor); +} GnomeVFSMIMEMonitorClass; + +GType gnome_vfs_mime_monitor_get_type (void); + +/* There's a single GnomeVFSMIMEMonitor object. + * The only thing you need it for is to connect to its signals. + */ +GnomeVFSMIMEMonitor *gnome_vfs_mime_monitor_get (void); + +G_END_DECLS + +#endif /* GNOME_VFS_MIME_MONITOR_H */ diff --git a/libgnomevfs/gnome-vfs-mime-private.h b/libgnomevfs/gnome-vfs-mime-private.h new file mode 100644 index 0000000..c8f9066 --- /dev/null +++ b/libgnomevfs/gnome-vfs-mime-private.h @@ -0,0 +1,46 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* gnome-vfs-mime-private.h + * + * Copyright (C) 2000 Eazel, Inc + * + * The Gnome Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Gnome Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef GNOME_VFS_MIME_PRIVATE_H +#define GNOME_VFS_MIME_PRIVATE_H + +#include + +G_BEGIN_DECLS + +void _gnome_vfs_mime_info_shutdown (void); +void _gnome_vfs_mime_monitor_emit_data_changed (GnomeVFSMIMEMonitor *monitor); + +typedef struct FileDateTracker FileDateTracker; + +FileDateTracker *_gnome_vfs_file_date_tracker_new (void); +void _gnome_vfs_file_date_tracker_free (FileDateTracker *tracker); +void _gnome_vfs_file_date_tracker_start_tracking_file (FileDateTracker *tracker, + const char *local_file_path); +gboolean _gnome_vfs_file_date_tracker_date_has_changed (FileDateTracker *tracker); +void _gnome_vfs_mime_info_mark_gnome_mime_dir_dirty (void); +void _gnome_vfs_mime_info_mark_user_mime_dir_dirty (void); + + +G_END_DECLS + +#endif /* GNOME_VFS_MIME_PRIVATE_H */ diff --git a/libgnomevfs/gnome-vfs-mime-sniff-buffer-private.h b/libgnomevfs/gnome-vfs-mime-sniff-buffer-private.h new file mode 100644 index 0000000..9ca02a2 --- /dev/null +++ b/libgnomevfs/gnome-vfs-mime-sniff-buffer-private.h @@ -0,0 +1,47 @@ +/* + * gnome-vfs-mime-sniff-buffer-private.h + * Utility for implementing gnome_vfs_mime_type_from_magic, and other + * mime-type sniffing calls. + * + * Copyright (C) 2000 Eazel, Inc. + * All rights reserved. + * + * This file is part of the Gnome Library. + * + * The Gnome Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Gnome Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef GNOME_VFS_MIME_SNIFF_BUFFER_PRIVATE_H +#define GNOME_VFS_MIME_SNIFF_BUFFER_PRIVATE_H + +#include + +struct GnomeVFSMimeSniffBuffer { + guchar *buffer; + gssize buffer_length; + gboolean read_whole_file; + gboolean owning; + + GnomeVFSSniffBufferSeekCall seek; + GnomeVFSSniffBufferReadCall read; + gpointer context; +}; + +const char *_gnome_vfs_get_mime_type_internal (GnomeVFSMimeSniffBuffer *buffer, + const char *file_name); +const char *_gnome_vfs_mime_get_type_from_magic_table (GnomeVFSMimeSniffBuffer *buffer); + +#endif diff --git a/libgnomevfs/gnome-vfs-mime-sniff-buffer.c b/libgnomevfs/gnome-vfs-mime-sniff-buffer.c new file mode 100644 index 0000000..8377c77 --- /dev/null +++ b/libgnomevfs/gnome-vfs-mime-sniff-buffer.c @@ -0,0 +1,181 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* + * gnome-vfs-mime-sniff-buffer.c + * Utility for implementing gnome_vfs_mime_type_from_magic, and other + * mime-type sniffing calls. + * + * Copyright (C) 2000 Eazel, Inc. + * All rights reserved. + * + * This file is part of the Gnome Library. + * + * The Gnome Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Gnome Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include "gnome-vfs-mime-sniff-buffer.h" + +#include "gnome-vfs-handle.h" +#include "gnome-vfs-mime-sniff-buffer-private.h" +#include "gnome-vfs-ops.h" +#include + +static GnomeVFSResult +handle_seek_glue (gpointer context, GnomeVFSSeekPosition whence, + GnomeVFSFileOffset offset) +{ + GnomeVFSHandle *handle = (GnomeVFSHandle *)context; + return gnome_vfs_seek (handle, whence, offset); +} + +static GnomeVFSResult +handle_read_glue (gpointer context, gpointer buffer, + GnomeVFSFileSize bytes, GnomeVFSFileSize *bytes_read) +{ + GnomeVFSHandle *handle = (GnomeVFSHandle *)context; + return gnome_vfs_read (handle, buffer, bytes, bytes_read); +} + +GnomeVFSMimeSniffBuffer * +_gnome_vfs_mime_sniff_buffer_new_from_handle (GnomeVFSHandle *file) +{ + GnomeVFSMimeSniffBuffer *result; + + result = g_new0 (GnomeVFSMimeSniffBuffer, 1); + result->owning = TRUE; + result->context = file; + result->seek = handle_seek_glue; + result->read = handle_read_glue; + + return result; +} + +GnomeVFSMimeSniffBuffer * +_gnome_vfs_mime_sniff_buffer_new_generic (GnomeVFSSniffBufferSeekCall seek_callback, + GnomeVFSSniffBufferReadCall read_callback, + gpointer context) +{ + GnomeVFSMimeSniffBuffer * result; + + result = g_new0 (GnomeVFSMimeSniffBuffer, 1); + + result->owning = TRUE; + result->seek = seek_callback; + result->read = read_callback; + result->context = context; + + return result; +} + +GnomeVFSMimeSniffBuffer * +_gnome_vfs_mime_sniff_buffer_new_from_memory (const guchar *buffer, + gssize buffer_length) +{ + GnomeVFSMimeSniffBuffer *result; + + result = g_new0 (GnomeVFSMimeSniffBuffer, 1); + result->owning = TRUE; + result->buffer = g_malloc (buffer_length); + result->buffer_length = buffer_length; + memcpy (result->buffer, buffer, buffer_length); + result->read_whole_file = TRUE; + + return result; +} + +GnomeVFSMimeSniffBuffer * +gnome_vfs_mime_sniff_buffer_new_from_existing_data (const guchar *buffer, + gssize buffer_length) +{ + GnomeVFSMimeSniffBuffer *result; + + result = g_new0 (GnomeVFSMimeSniffBuffer, 1); + result->owning = FALSE; + result->buffer = (guchar *)buffer; + result->buffer_length = buffer_length; + result->read_whole_file = TRUE; + + return result; +} + +void +gnome_vfs_mime_sniff_buffer_free (GnomeVFSMimeSniffBuffer *buffer) +{ + if (buffer->owning) + g_free (buffer->buffer); + g_free (buffer); +} + +enum { + GNOME_VFS_SNIFF_BUFFER_INITIAL_CHUNK = 256, + GNOME_VFS_SNIFF_BUFFER_MIN_CHUNK = 128 +}; + +GnomeVFSResult +_gnome_vfs_mime_sniff_buffer_get (GnomeVFSMimeSniffBuffer *buffer, + gssize size) +{ + GnomeVFSResult result; + GnomeVFSFileSize bytes_to_read, bytes_read; + + /* check to see if we already have enough data */ + if (buffer->buffer_length >= size) { + return GNOME_VFS_OK; + } + + /* if we've read the whole file, don't try to read any more */ + if (buffer->read_whole_file) { + return GNOME_VFS_ERROR_EOF; + } + + /* figure out how much to read */ + bytes_to_read = size - buffer->buffer_length; + + /* don't bother to read less than this */ + if (bytes_to_read < GNOME_VFS_SNIFF_BUFFER_MIN_CHUNK) { + bytes_to_read = GNOME_VFS_SNIFF_BUFFER_MIN_CHUNK; + } + + /* make room in buffer for new data */ + buffer->buffer = g_realloc (buffer->buffer, + buffer->buffer_length + bytes_to_read); + + /* read in more data */ + result = (* buffer->read) (buffer->context, + buffer->buffer + buffer->buffer_length, + bytes_to_read, + &bytes_read); + if (result == GNOME_VFS_ERROR_EOF) { + /* only happens with 0-byte files, due to other logic */ + buffer->read_whole_file = TRUE; + } + if (result != GNOME_VFS_OK) { + return result; + } + if (bytes_read < bytes_to_read) { + buffer->read_whole_file = TRUE; + } + buffer->buffer_length += bytes_read; + + /* check to see if we have enough data */ + if (buffer->buffer_length >= size) { + return GNOME_VFS_OK; + } + + /* not enough data */ + return GNOME_VFS_ERROR_EOF; +} diff --git a/libgnomevfs/gnome-vfs-mime-sniff-buffer.h b/libgnomevfs/gnome-vfs-mime-sniff-buffer.h new file mode 100644 index 0000000..103645a --- /dev/null +++ b/libgnomevfs/gnome-vfs-mime-sniff-buffer.h @@ -0,0 +1,73 @@ +/* + * gnome-vfs-mime-sniff-buffer.h + * Utility for implementing gnome_vfs_mime_type_from_magic, and other + * mime-type sniffing calls. + * + * Copyright (C) 2000 Eazel, Inc. + * All rights reserved. + * + * This file is part of the Gnome Library. + * + * The Gnome Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Gnome Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef GNOME_VFS_MIME_SNIFF_BUFFER_H +#define GNOME_VFS_MIME_SNIFF_BUFFER_H + +#include + +G_BEGIN_DECLS + +typedef GnomeVFSResult (* GnomeVFSSniffBufferSeekCall)(gpointer context, + GnomeVFSSeekPosition whence, GnomeVFSFileOffset offset); +typedef GnomeVFSResult (* GnomeVFSSniffBufferReadCall)(gpointer context, + gpointer buffer, GnomeVFSFileSize bytes, GnomeVFSFileSize *bytes_read); + +typedef struct GnomeVFSMimeSniffBuffer GnomeVFSMimeSniffBuffer; + +void _gnome_vfs_mime_clear_magic_table (void); + +GnomeVFSMimeSniffBuffer *_gnome_vfs_mime_sniff_buffer_new_from_handle + (GnomeVFSHandle *file); +GnomeVFSMimeSniffBuffer *_gnome_vfs_mime_sniff_buffer_new_from_memory + (const guchar *buffer, + gssize buffer_size); +GnomeVFSMimeSniffBuffer *gnome_vfs_mime_sniff_buffer_new_from_existing_data + (const guchar *buffer, + gssize buffer_size); +GnomeVFSMimeSniffBuffer *_gnome_vfs_mime_sniff_buffer_new_generic + (GnomeVFSSniffBufferSeekCall seek_callback, + GnomeVFSSniffBufferReadCall read_callback, + gpointer context); + + +void gnome_vfs_mime_sniff_buffer_free + (GnomeVFSMimeSniffBuffer *buffer); + +GnomeVFSResult _gnome_vfs_mime_sniff_buffer_get + (GnomeVFSMimeSniffBuffer *buffer, + gssize size); + +const char *gnome_vfs_get_mime_type_for_buffer + (GnomeVFSMimeSniffBuffer *buffer); + +gboolean _gnome_vfs_sniff_buffer_looks_like_text + (GnomeVFSMimeSniffBuffer *buffer); +gboolean _gnome_vfs_sniff_buffer_looks_like_mp3 + (GnomeVFSMimeSniffBuffer *buffer); +G_END_DECLS + +#endif diff --git a/libgnomevfs/gnome-vfs-mime-utils.h b/libgnomevfs/gnome-vfs-mime-utils.h new file mode 100644 index 0000000..b7a801d --- /dev/null +++ b/libgnomevfs/gnome-vfs-mime-utils.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 1997-2001 Free Software Foundation + * Copyright (C) 2000, 2001 Eazel, Inc. + * All rights reserved. + * + * This file is part of the Gnome Library. + * + * The Gnome Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Gnome Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef GNOME_VFS_MIME_UTILS_H +#define GNOME_VFS_MIME_UTILS_H + +#include + +G_BEGIN_DECLS + +/** + * GNOME_VFS_MIME_TYPE_UNKNOWN: + * + * The value returned for the MIME type when a file did + * not match any entries in the MIME database. May be + * treated as a file of an unknown type. + **/ +#define GNOME_VFS_MIME_TYPE_UNKNOWN "application/octet-stream" + +const char *gnome_vfs_get_mime_type_for_data (gconstpointer data, + int data_size); + +char *gnome_vfs_get_mime_type (const char *text_uri); + +G_END_DECLS + +#endif diff --git a/libgnomevfs/gnome-vfs-mime.c b/libgnomevfs/gnome-vfs-mime.c new file mode 100644 index 0000000..9b34756 --- /dev/null +++ b/libgnomevfs/gnome-vfs-mime.c @@ -0,0 +1,1017 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* + * Copyright (C) 1998 Miguel de Icaza + * Copyright (C) 1997 Paolo Molaro + * Copyright (C) 2000, 2001 Eazel, Inc. + * All rights reserved. + * + * This file is part of the Gnome Library. + * + * The Gnome Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Gnome Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include "gnome-vfs-mime.h" + +#include "gnome-vfs-mime-private.h" +#include "gnome-vfs-mime-sniff-buffer-private.h" +#include "gnome-vfs-mime-utils.h" +#include "gnome-vfs-module-shared.h" +#include "gnome-vfs-ops.h" +#include "gnome-vfs-result.h" +#include "gnome-vfs-uri.h" +#include +#include +#include +#include +#include + +static gboolean module_inited = FALSE; + +static GHashTable *mime_extensions [2] = { NULL, NULL }; +static GList *mime_regexs [2] = { NULL, NULL }; + +#define DEFAULT_DATE_TRACKER_INTERVAL 5 /* in milliseconds */ + +typedef struct { + char *mime_type; + regex_t regex; +} RegexMimePair; + +typedef struct { + char *dirname; + unsigned int valid : 1; + unsigned int system_dir : 1; +} mime_dir_source_t; + +typedef struct { + char *file_path; + time_t mtime; +} FileDateRecord; + +struct FileDateTracker { + time_t last_checked; + guint check_interval; + GHashTable *records; +}; + +/* These ones are used to automatically reload mime-types on demand */ +static mime_dir_source_t gnome_mime_dir, user_mime_dir; +static FileDateTracker *mime_data_date_tracker; + +#ifdef G_THREADS_ENABLED + +/* We lock this mutex whenever we modify global state in this module. */ +G_LOCK_DEFINE_STATIC (mime_mutex); + +#endif /* G_LOCK_DEFINE_STATIC */ + + +static char * +get_priority (char *def, int *priority) +{ + *priority = 0; + + if (*def == ',') { + def++; + if (*def == '1') { + *priority = 0; + def++; + } else if (*def == '2') { + *priority = 1; + def++; + } + } + + while (*def && *def == ':') + def++; + + return def; +} + +static int +list_find_type (gconstpointer value, gconstpointer type) +{ + return g_ascii_strcasecmp((const char *) value, (const char *) type); +} + +static void +add_to_key (char *mime_type, char *def) +{ + int priority = 1; + char *s, *p, *ext; + GList *list = NULL; + + if (strncmp (def, "ext", 3) == 0){ + char *tokp; + + def += 3; + def = get_priority (def, &priority); + s = p = g_strdup (def); + + while ((ext = strtok_r (s, " \t\n\r,", &tokp)) != NULL) { + gboolean found; + gpointer orig_key; + + found = g_hash_table_lookup_extended (mime_extensions [priority], ext, + &orig_key, (gpointer *)&list); + if (!found) { + orig_key = NULL; + list = NULL; + } + + if (!g_list_find_custom (list, mime_type, list_find_type)) { + list = g_list_prepend (list, g_strdup (mime_type)); + g_hash_table_insert (mime_extensions [priority], + found ? orig_key : g_strdup (ext), list); + } + s = NULL; + } + g_free (p); + } + + if (strncmp (def, "regex", 5) == 0) { + RegexMimePair *mp; + def += 5; + def = get_priority (def, &priority); + + while (g_ascii_isspace (*def)) { + def++; + } + + if (*def == '\0') { + return; + } + + /* This was g_new instead of g_new0, but there seems + * to be a bug in the Solaris? version of regcomp that + * requires an initialized regex or it will crash. + */ + mp = g_new0 (RegexMimePair, 1); + if (regcomp (&mp->regex, def, REG_EXTENDED | REG_NOSUB)) { + g_free (mp); + return; + } + mp->mime_type = g_strdup (mime_type); + + mime_regexs [priority] = g_list_prepend (mime_regexs [priority], mp); + } +} + +static void +mime_fill_from_file (const char *filename) +{ + FILE *file; + char buf [1024]; + char *current_key; + + g_assert (filename != NULL); + + _gnome_vfs_file_date_tracker_start_tracking_file (mime_data_date_tracker, filename); + file = fopen (filename, "r"); + + if (file == NULL) { + return; + } + + current_key = NULL; + while (fgets (buf, sizeof (buf), file) != NULL) { + char *p; + + if (buf [0] == '#') { + continue; + } + + /* Trim trailing spaces */ + for (p = buf + strlen (buf) - 1; p >= buf; p--) { + if (!g_ascii_isspace (*p)) { + break; + } + *p = 0; + } + + if (buf [0] == '\0') { + continue; + } + + if (buf [0] == '\t' || buf [0] == ' '){ + if (current_key){ + char *p = buf; + + while (g_ascii_isspace (*p)) + p++; + + if (*p == 0) + continue; + + add_to_key (current_key, p); + } + } else { + g_free (current_key); + + current_key = g_strdup (buf); + if (current_key [strlen (current_key)-1] == ':') + current_key [strlen (current_key)-1] = 0; + } + } + + g_free (current_key); + + fclose (file); +} + +static void +mime_load (mime_dir_source_t *source) +{ + DIR *dir; + struct dirent *dent; + const int extlen = sizeof (".mime") - 1; + char *filename; + struct stat s; + + g_return_if_fail (source != NULL); + g_return_if_fail (source->dirname != NULL); + + source->valid = (stat (source->dirname, &s) != -1); + + if (source->system_dir) { + filename = g_strconcat (source->dirname, "/gnome-vfs.mime", NULL); + mime_fill_from_file (filename); + g_free (filename); + } + + dir = opendir (source->dirname); + + while (dir != NULL) { + int len; + + dent = readdir (dir); + if (dent == NULL) { + break; + } + + len = strlen (dent->d_name); + + if (len <= extlen) { + continue; + } + + if (strcmp (dent->d_name + len - extlen, ".mime") != 0) { + continue; + } + + if (source->system_dir && strcmp (dent->d_name, "gnome-vfs.mime") == 0) { + continue; + } + + if (source->system_dir && strcmp (dent->d_name, "gnome.mime") == 0) { + /* Ignore the obsolete "official" one so it doesn't override + * the new official one. + */ + continue; + } + + if (!source->system_dir && strcmp (dent->d_name, "user.mime") == 0) { + continue; + } + + filename = g_strconcat (source->dirname, "/", dent->d_name, NULL); + + mime_fill_from_file (filename); + g_free (filename); + } + if (dir != NULL) + closedir (dir); + + if (!source->system_dir) { + filename = g_strconcat (source->dirname, "/user.mime", NULL); + mime_fill_from_file (filename); + g_free (filename); + } + + _gnome_vfs_file_date_tracker_start_tracking_file (mime_data_date_tracker, source->dirname); +} + +static gboolean +remove_one_mime_hash_entry (gpointer key, gpointer value, gpointer user_data) +{ + g_free (key); + g_list_foreach (value, (GFunc) g_free, NULL); + g_list_free (value); + + return TRUE; +} + +static void +mime_extensions_empty (void) +{ + GList *p; + int i; + for (i = 0; i < 2; i++) { + if (mime_extensions [i] != NULL) { + g_hash_table_foreach_remove (mime_extensions [i], + remove_one_mime_hash_entry, NULL); + } + + for (p = mime_regexs [i]; p != NULL; p = p->next){ + RegexMimePair *mp = p->data; + + g_free (mp->mime_type); + regfree (&mp->regex); + g_free (mp); + } + g_list_free (mime_regexs [i]); + mime_regexs [i] = NULL; + } +} + +static void +maybe_reload (void) +{ + if (!_gnome_vfs_file_date_tracker_date_has_changed (mime_data_date_tracker)) { + return; + } + + mime_extensions_empty (); + + mime_load (&gnome_mime_dir); + mime_load (&user_mime_dir); +} + +static void +mime_init (void) +{ + mime_extensions [0] = g_hash_table_new (g_str_hash, g_str_equal); + mime_extensions [1] = g_hash_table_new (g_str_hash, g_str_equal); + + mime_data_date_tracker = _gnome_vfs_file_date_tracker_new (); + + gnome_mime_dir.dirname = g_strdup (DATADIR "/mime-info"); + gnome_mime_dir.system_dir = TRUE; + + user_mime_dir.dirname = g_strconcat (g_get_home_dir (), "/.gnome/mime-info", NULL); + user_mime_dir.system_dir = FALSE; + + mime_load (&gnome_mime_dir); + mime_load (&user_mime_dir); + + module_inited = TRUE; +} + +/** + * gnome_vfs_mime_shutdown: + * + * Unload the MIME database from memory. + **/ + +void +gnome_vfs_mime_shutdown (void) +{ + _gnome_vfs_mime_info_shutdown (); + _gnome_vfs_mime_clear_magic_table (); + + if (!module_inited) + return; + + mime_extensions_empty (); + + g_hash_table_destroy (mime_extensions[0]); + g_hash_table_destroy (mime_extensions[1]); + + _gnome_vfs_file_date_tracker_free (mime_data_date_tracker); + + g_free (gnome_mime_dir.dirname); + g_free (user_mime_dir.dirname); +} + +/** + * gnome_vfs_mime_type_from_name_or_default: + * @filename: A filename (the file does not necesarily exist). + * @defaultv: A default value to be returned if no match is found + * + * This routine tries to determine the mime-type of the filename + * only by looking at the filename from the GNOME database of mime-types. + * + * Returns the mime-type of the @filename. If no value could be + * determined, it will return @defaultv. + */ +const char * +gnome_vfs_mime_type_from_name_or_default (const char *filename, const char *defaultv) +{ + const gchar *ext; + char *upext; + int priority; + const char *result = defaultv; + + if (filename == NULL) { + return result; + } + + G_LOCK (mime_mutex); + + ext = strrchr (filename, '.'); + if (ext != NULL) { + ++ext; + } + + if (!module_inited) { + mime_init (); + } + + maybe_reload (); + + for (priority = 1; priority >= 0; priority--){ + GList *l; + GList *list = NULL ; + + if (ext != NULL) { + + list = g_hash_table_lookup (mime_extensions [priority], ext); + if (list != NULL) { + list = g_list_first( list ); + result = (const char *) list->data; + break; + } + + /* Search for UPPER case extension */ + upext = g_ascii_strup (ext, -1); + list = g_hash_table_lookup (mime_extensions [priority], upext); + g_free (upext); + if (list != NULL) { + list = g_list_first (list); + result = (const char *) list->data; + break; + } + + /* Final check for lower case */ + upext = g_ascii_strdown (ext, -1); + list = g_hash_table_lookup (mime_extensions [priority], upext); + g_free (upext); + if (list != NULL) { + list = g_list_first (list); + result = (const char *) list->data; + break; + } + } + + for (l = mime_regexs [priority]; l; l = l->next){ + RegexMimePair *mp = l->data; + + if (regexec (&mp->regex, filename, 0, 0, 0) == 0) { + result = mp->mime_type; + G_UNLOCK (mime_mutex); + return result; + } + } + } + + G_UNLOCK (mime_mutex); + return result; +} + +/** + * gnome_vfs_mime_type_from_name: + * @filename: A filename (the file does not necessarily exist). + * + * Determined the mime type for @filename. + * + * Returns the mime-type for this filename. + */ +const char * +gnome_vfs_mime_type_from_name (const gchar * filename) +{ + return gnome_vfs_mime_type_from_name_or_default (filename, GNOME_VFS_MIME_TYPE_UNKNOWN); +} + +static const char * +gnome_vfs_get_mime_type_from_uri_internal (GnomeVFSURI *uri) +{ + char *base_name; + const char *mime_type; + + /* Return a mime type based on the file extension or NULL if no match. */ + base_name = gnome_vfs_uri_extract_short_path_name (uri); + if (base_name == NULL) { + return NULL; + } + + mime_type = gnome_vfs_mime_type_from_name_or_default (base_name, NULL); + g_free (base_name); + return mime_type; +} + +const char * +_gnome_vfs_get_mime_type_internal (GnomeVFSMimeSniffBuffer *buffer, const char *file_name) +{ + const char *result; + + result = NULL; + + if (buffer != NULL) { + result = _gnome_vfs_mime_get_type_from_magic_table (buffer); + + if (result != NULL) { + if (strcmp (result, "application/x-gzip") == 0) { + + /* So many file types come compressed by gzip + * that extensions are more reliable than magic + * typing. If the file has a suffix, then use + * the type from the suffix. + * + * FIXME bugzilla.gnome.org 46867: + * Allow specific mime types to override + * magic detection + */ + if (file_name != NULL) { + result = gnome_vfs_mime_type_from_name_or_default (file_name, NULL); + } + + if (result != NULL) { + return result; + } + /* Didn't find an extension match, + * assume gzip. */ + return "application/x-gzip"; + } + return result; + } + + if (result == NULL) { + if (_gnome_vfs_sniff_buffer_looks_like_text (buffer)) { + /* Text file -- treat extensions as a more + * accurate source of type information. + */ + if (file_name != NULL) { + result = gnome_vfs_mime_type_from_name_or_default (file_name, NULL); + } + + if (result != NULL) { + return result; + } + + /* Didn't find an extension match, assume plain text. */ + return "text/plain"; + + } else if (_gnome_vfs_sniff_buffer_looks_like_mp3 (buffer)) { + return "audio/mpeg"; + } + } + } + + if (result == NULL && file_name != NULL) { + /* No type recognized -- fall back on extensions. */ + result = gnome_vfs_mime_type_from_name_or_default (file_name, NULL); + } + + if (result == NULL) { + result = GNOME_VFS_MIME_TYPE_UNKNOWN; + } + + return result; +} + +/** + * gnome_vfs_get_mime_type_common: + * @uri: a real file or a non-existent uri. + * + * Tries to guess the mime type of the file represented by @uir. + * Favors using the file data to the @uri extension. + * Handles passing @uri of a non-existent file by falling back + * on returning a type based on the extension. + * + * FIXME: This function will not necessarily return the same mime type as doing a + * get file info on the text uri. + * + * Returns: the mime-type for this uri. + * + */ +const char * +gnome_vfs_get_mime_type_common (GnomeVFSURI *uri) +{ + const char *result; + char *base_name; + GnomeVFSMimeSniffBuffer *buffer; + GnomeVFSHandle *handle; + GnomeVFSResult error; + + /* Check for special stat-defined file types first. */ + result = gnome_vfs_get_special_mime_type (uri); + if (result != NULL) { + return result; + } + + error = gnome_vfs_open_uri (&handle, uri, GNOME_VFS_OPEN_READ); + + if (error != GNOME_VFS_OK) { + /* file may not exist, return type based on name only */ + return gnome_vfs_get_mime_type_from_uri_internal (uri); + } + + buffer = _gnome_vfs_mime_sniff_buffer_new_from_handle (handle); + + base_name = gnome_vfs_uri_extract_short_path_name (uri); + + result = _gnome_vfs_get_mime_type_internal (buffer, base_name); + g_free (base_name); + + gnome_vfs_mime_sniff_buffer_free (buffer); + gnome_vfs_close (handle); + + return result; +} + +static GnomeVFSResult +file_seek_binder (gpointer context, GnomeVFSSeekPosition whence, + GnomeVFSFileOffset offset) +{ + FILE *file = (FILE *)context; + int result; + result = fseek (file, offset, whence); + if (result < 0) { + return gnome_vfs_result_from_errno (); + } + return GNOME_VFS_OK; +} + +static GnomeVFSResult +file_read_binder (gpointer context, gpointer buffer, + GnomeVFSFileSize bytes, GnomeVFSFileSize *bytes_read) +{ + FILE *file = (FILE *)context; + *bytes_read = fread (buffer, 1, bytes, file); + if (*bytes_read < 0) { + *bytes_read = 0; + return gnome_vfs_result_from_errno (); + } + + return GNOME_VFS_OK; +} + +/** + * gnome_vfs_get_file_mime_type: + * @path: a path of a file. + * @optional_stat_info: optional stat buffer. + * @suffix_only: whether or not to do a magic-based lookup. + * + * Tries to guess the mime type of the file represented by @path. + * If @suffix_only is false, uses the mime-magic based lookup first. + * Handles passing @path of a non-existent file by falling back + * on returning a type based on the extension. + * + * Returns: the mime-type for this path + */ +const char * +gnome_vfs_get_file_mime_type (const char *path, const struct stat *optional_stat_info, + gboolean suffix_only) +{ + const char *result; + GnomeVFSMimeSniffBuffer *buffer; + struct stat tmp_stat_buffer; + FILE *file; + + file = NULL; + result = NULL; + + /* get the stat info if needed */ + if (optional_stat_info == NULL && stat (path, &tmp_stat_buffer) == 0) { + optional_stat_info = &tmp_stat_buffer; + } + + /* single out special file types */ + if (optional_stat_info && !S_ISREG(optional_stat_info->st_mode)) { + if (S_ISDIR(optional_stat_info->st_mode)) { + return "x-directory/normal"; + } else if (S_ISCHR(optional_stat_info->st_mode)) { + return "x-special/device-char"; + } else if (S_ISBLK(optional_stat_info->st_mode)) { + return "x-special/device-block"; + } else if (S_ISFIFO(optional_stat_info->st_mode)) { + return "x-special/fifo"; + } else if (S_ISSOCK(optional_stat_info->st_mode)) { + return "x-special/socket"; + } else { + /* unknown entry type, return generic file type */ + return GNOME_VFS_MIME_TYPE_UNKNOWN; + } + } + + if (!suffix_only) { + file = fopen(path, "r"); + } + + if (file != NULL) { + buffer = _gnome_vfs_mime_sniff_buffer_new_generic + (file_seek_binder, file_read_binder, file); + + result = _gnome_vfs_get_mime_type_internal (buffer, path); + gnome_vfs_mime_sniff_buffer_free (buffer); + fclose (file); + } else { + result = _gnome_vfs_get_mime_type_internal (NULL, path); + } + + + g_assert (result != NULL); + return result; +} + +/** + * gnome_vfs_get_mime_type_from_uri: + * @uri: A file uri. + * + * Tries to guess the mime type of the file @uri by + * checking the file name extension. Works on non-existent + * files. + * + * Returns the mime-type for this filename. + */ +const char * +gnome_vfs_get_mime_type_from_uri (GnomeVFSURI *uri) +{ + const char *result; + + result = gnome_vfs_get_mime_type_from_uri_internal (uri); + if (result == NULL) { + /* no type, return generic file type */ + result = GNOME_VFS_MIME_TYPE_UNKNOWN; + } + + return result; +} + +/** + * gnome_vfs_get_mime_type_from_file_data: + * @uri: A file uri. + * + * Tries to guess the mime type of the file @uri by + * checking the file data using the magic patterns. Does not handle text files properly + * + * Returns the mime-type for this filename. + */ +const char * +gnome_vfs_get_mime_type_from_file_data (GnomeVFSURI *uri) +{ + const char *result; + GnomeVFSMimeSniffBuffer *buffer; + GnomeVFSHandle *handle; + GnomeVFSResult error; + + error = gnome_vfs_open_uri (&handle, uri, GNOME_VFS_OPEN_READ); + + if (error != GNOME_VFS_OK) { + return GNOME_VFS_MIME_TYPE_UNKNOWN; + } + + buffer = _gnome_vfs_mime_sniff_buffer_new_from_handle (handle); + result = _gnome_vfs_get_mime_type_internal (buffer, NULL); + gnome_vfs_mime_sniff_buffer_free (buffer); + gnome_vfs_close (handle); + + return result; +} + +/** + * gnome_vfs_get_mime_type_for_data: + * @data: A pointer to data in memory. + * @data_size: Size of the data. + * + * Tries to guess the mime type of the data in @data + * using the magic patterns. + * + * Returns the mime-type for this filename. + */ +const char * +gnome_vfs_get_mime_type_for_data (gconstpointer data, int data_size) +{ + const char *result; + GnomeVFSMimeSniffBuffer *buffer; + + buffer = gnome_vfs_mime_sniff_buffer_new_from_existing_data + (data, data_size); + result = _gnome_vfs_get_mime_type_internal (buffer, NULL); + + gnome_vfs_mime_sniff_buffer_free (buffer); + + return result; +} + +gboolean +gnome_vfs_mime_type_is_supertype (const char *mime_type) +{ + int length; + + if (mime_type == NULL) { + return FALSE; + } + + length = strlen (mime_type); + + return length > 2 + && mime_type[length - 2] == '/' + && mime_type[length - 1] == '*'; +} + +static char * +extract_prefix_add_suffix (const char *string, const char *separator, const char *suffix) +{ + const char *separator_position; + int prefix_length; + char *result; + + separator_position = strstr (string, separator); + prefix_length = separator_position == NULL + ? strlen (string) + : separator_position - string; + + result = g_malloc (prefix_length + strlen (suffix) + 1); + + strncpy (result, string, prefix_length); + result[prefix_length] = '\0'; + + strcat (result, suffix); + + return result; +} + +/* Returns the supertype for a mime type. Note that if called + * on a supertype it will return a copy of the supertype. + */ +char * +gnome_vfs_get_supertype_from_mime_type (const char *mime_type) +{ + if (mime_type == NULL) { + return NULL; + } + return extract_prefix_add_suffix (mime_type, "/", "/*"); +} + +static void +file_date_record_update_mtime (FileDateRecord *record) +{ + struct stat s; + record->mtime = (stat (record->file_path, &s) != -1) ? s.st_mtime : 0; +} + +static FileDateRecord * +file_date_record_new (const char *file_path) { + FileDateRecord *record; + + record = g_new0 (FileDateRecord, 1); + record->file_path = g_strdup (file_path); + + file_date_record_update_mtime (record); + + return record; +} + +static void +file_date_record_free (FileDateRecord *record) +{ + g_free (record->file_path); + g_free (record); +} + +FileDateTracker * +_gnome_vfs_file_date_tracker_new (void) +{ + FileDateTracker *tracker; + + tracker = g_new0 (FileDateTracker, 1); + tracker->check_interval = DEFAULT_DATE_TRACKER_INTERVAL; + tracker->records = g_hash_table_new (g_str_hash, g_str_equal); + + return tracker; +} + +static gboolean +release_key_and_value (gpointer key, gpointer value, gpointer user_data) +{ + g_free (key); + file_date_record_free (value); + + return TRUE; +} + +void +_gnome_vfs_file_date_tracker_free (FileDateTracker *tracker) +{ + g_hash_table_foreach_remove (tracker->records, release_key_and_value, NULL); + g_hash_table_destroy (tracker->records); + g_free (tracker); +} + +/* + * Record the current mod date for a specified file, so that we can check + * later whether it has changed. + */ +void +_gnome_vfs_file_date_tracker_start_tracking_file (FileDateTracker *tracker, + const char *local_file_path) +{ + FileDateRecord *record; + + record = g_hash_table_lookup (tracker->records, local_file_path); + if (record != NULL) { + file_date_record_update_mtime (record); + } else { + g_hash_table_insert (tracker->records, + g_strdup (local_file_path), + file_date_record_new (local_file_path)); + } +} + +static void +check_and_update_one (gpointer key, gpointer value, gpointer user_data) +{ + FileDateRecord *record; + gboolean *return_has_changed; + struct stat s; + + g_assert (key != NULL); + g_assert (value != NULL); + g_assert (user_data != NULL); + + record = (FileDateRecord *)value; + return_has_changed = (gboolean *)user_data; + + if (stat (record->file_path, &s) != -1) { + if (s.st_mtime != record->mtime) { + record->mtime = s.st_mtime; + *return_has_changed = TRUE; + } + } +} + +gboolean +_gnome_vfs_file_date_tracker_date_has_changed (FileDateTracker *tracker) +{ + time_t now; + gboolean any_date_changed; + + now = time (NULL); + + /* Note that this might overflow once in a blue moon, but the + * only side-effect of that would be a slightly-early check + * for changes. + */ + if (tracker->last_checked + tracker->check_interval >= now) { + return FALSE; + } + + any_date_changed = FALSE; + + g_hash_table_foreach (tracker->records, check_and_update_one, &any_date_changed); + + tracker->last_checked = now; + + return any_date_changed; +} + + + + +/** + * gnome_vfs_get_mime_type: + * @text_uri: URI of the file for which to get the mime type + * + * Determine the mime type of @text_uri. The mime type is determined + * in the same way as by gnome_vfs_get_file_info(). This is meant as + * a convenience function for times when you only want the mime type. + * + * Return value: The mime type, or NULL if there is an error reading + * the file. + **/ +char * +gnome_vfs_get_mime_type (const char *text_uri) +{ + GnomeVFSFileInfo *info; + char *mime_type; + GnomeVFSResult result; + + info = gnome_vfs_file_info_new (); + result = gnome_vfs_get_file_info (text_uri, info, + GNOME_VFS_FILE_INFO_GET_MIME_TYPE | + GNOME_VFS_FILE_INFO_FOLLOW_LINKS); + if (info->mime_type == NULL || result != GNOME_VFS_OK) { + mime_type = NULL; + } else { + mime_type = g_strdup (info->mime_type); + } + gnome_vfs_file_info_unref (info); + + return mime_type; +} diff --git a/libgnomevfs/gnome-vfs-mime.h b/libgnomevfs/gnome-vfs-mime.h new file mode 100644 index 0000000..cc3e59b --- /dev/null +++ b/libgnomevfs/gnome-vfs-mime.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 1997-2001 Free Software Foundation + * Copyright (C) 2000, 2001 Eazel, Inc. + * All rights reserved. + * + * This file is part of the Gnome Library. + * + * The Gnome Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Gnome Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef GNOME_VFS_MIME_H +#define GNOME_VFS_MIME_H + +#include + +#include + +G_BEGIN_DECLS + +struct stat; + +#ifndef GNOME_VFS_DISABLE_DEPRECATED +void gnome_vfs_mime_shutdown (void); +#endif + +const char *gnome_vfs_mime_type_from_name (const char *filename); +const char *gnome_vfs_mime_type_from_name_or_default (const char *filename, + const char *defaultv); + +const char *gnome_vfs_get_mime_type_common (GnomeVFSURI *uri); +/* FIXME: This function should be named more clearly, maybe + to show that it gets the mime type only using the uri information. */ +const char *gnome_vfs_get_mime_type_from_uri (GnomeVFSURI *uri); + +#ifndef GNOME_VFS_DISABLE_DEPRECATED +const char *gnome_vfs_get_mime_type_from_file_data (GnomeVFSURI *uri); +#endif + +const char *gnome_vfs_get_file_mime_type (const char *path, + const struct stat *optional_stat_info, + gboolean suffix_only); + +gboolean gnome_vfs_mime_type_is_supertype (const char *mime_type); +char *gnome_vfs_get_supertype_from_mime_type (const char *mime_type); + +G_END_DECLS + +#endif diff --git a/libgnomevfs/gnome-vfs-module-callback-module-api.c b/libgnomevfs/gnome-vfs-module-callback-module-api.c new file mode 100644 index 0000000..0b1077d --- /dev/null +++ b/libgnomevfs/gnome-vfs-module-callback-module-api.c @@ -0,0 +1,2 @@ +#include +#include "gnome-vfs-module-callback-module-api.h" diff --git a/libgnomevfs/gnome-vfs-module-callback-module-api.h b/libgnomevfs/gnome-vfs-module-callback-module-api.h new file mode 100644 index 0000000..1bc75bd --- /dev/null +++ b/libgnomevfs/gnome-vfs-module-callback-module-api.h @@ -0,0 +1,37 @@ + +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-callbacks.h - various callback declarations + + Copyright (C) 2001 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Maciej Stachowiak + Seth Nickell +*/ + +#ifndef GNOME_VFS_MODULE_CALLBACK_MODULE_API_H +#define GNOME_VFS_MODULE_CALLBACK_MODULE_API_H + +#include + +gboolean gnome_vfs_module_callback_invoke (const char *callback_name, + gconstpointer in, + gsize in_size, + gpointer out, + gsize out_size); + +#endif diff --git a/libgnomevfs/gnome-vfs-module-callback-private.c b/libgnomevfs/gnome-vfs-module-callback-private.c new file mode 100644 index 0000000..49fcfd7 --- /dev/null +++ b/libgnomevfs/gnome-vfs-module-callback-private.c @@ -0,0 +1,2 @@ +#include +#include "gnome-vfs-module-callback-private.h" diff --git a/libgnomevfs/gnome-vfs-module-callback-private.h b/libgnomevfs/gnome-vfs-module-callback-private.h new file mode 100644 index 0000000..274e838 --- /dev/null +++ b/libgnomevfs/gnome-vfs-module-callback-private.h @@ -0,0 +1,38 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-module-callbacks-private.h - private entry points for module callback mechanism + + Copyright (C) 2001 Maciej Stachowiak + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Maciej Stachowiak +*/ + +#ifndef GNOME_VFS_MODULE_CALLBACKS_PRIVATE_H +#define GNOME_VFS_MODULE_CALLBACKS_PRIVATE_H + +#include + +typedef struct GnomeVFSModuleCallbackStackInfo GnomeVFSModuleCallbackStackInfo; + +void _gnome_vfs_module_callback_private_init (void); +GnomeVFSModuleCallbackStackInfo *_gnome_vfs_module_callback_get_stack_info (void); +void _gnome_vfs_module_callback_free_stack_info (GnomeVFSModuleCallbackStackInfo *stack_info); +void _gnome_vfs_module_callback_use_stack_info (GnomeVFSModuleCallbackStackInfo *stack_info); +void _gnome_vfs_module_callback_clear_stacks (void); +void _gnome_vfs_module_callback_set_in_async_thread (gboolean in_async_thread); + +#endif diff --git a/libgnomevfs/gnome-vfs-module-callback.c b/libgnomevfs/gnome-vfs-module-callback.c new file mode 100644 index 0000000..57c354d --- /dev/null +++ b/libgnomevfs/gnome-vfs-module-callback.c @@ -0,0 +1,965 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* + + Copyright (C) 2001 Eazel, Inc + Copyright (C) 2001 Maciej Stachowiak + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Michael Fleming + Maciej Stachowiak +*/ + + +#include +#include "gnome-vfs-module-callback.h" + +#include "gnome-vfs-module-callback-module-api.h" +#include "gnome-vfs-module-callback-private.h" +#include "gnome-vfs-backend.h" + +/* -- Private data structure declarations -- */ + +typedef struct CallbackInfo { + GnomeVFSModuleCallback callback; + gpointer callback_data; + GDestroyNotify destroy_notify; + int ref_count; +} CallbackInfo; + +typedef struct AsyncCallbackInfo { + GnomeVFSAsyncModuleCallback callback; + gpointer callback_data; + GDestroyNotify destroy_notify; +} AsyncCallbackInfo; + +typedef struct CallbackResponseData { + gboolean done; +} CallbackResponseData; + +struct GnomeVFSModuleCallbackStackInfo { + GHashTable *current_callbacks; + GHashTable *current_async_callbacks; +}; + + +/* -- Global variables -- */ + +static GStaticMutex callback_table_lock = G_STATIC_MUTEX_INIT; +static GHashTable *default_callbacks = NULL; +static GHashTable *default_async_callbacks = NULL; +static GHashTable *stack_tables_to_free = NULL; + +static GPrivate *callback_stacks_key; +static GPrivate *async_callback_stacks_key; +static GPrivate *in_async_thread_key; + +static GCond *async_callback_cond; +static GStaticMutex async_callback_lock = G_STATIC_MUTEX_INIT; + +/* -- Helper functions -- */ + +/* managing callback structs */ + +static CallbackInfo * +callback_info_new (GnomeVFSModuleCallback callback_func, + gpointer callback_data, + GDestroyNotify notify) +{ + CallbackInfo *callback; + + callback = g_new (CallbackInfo, 1); + + callback->callback = callback_func; + callback->callback_data = callback_data; + callback->destroy_notify = notify; + callback->ref_count = 1; + + return callback; +} + +#include + +static void +callback_info_ref (CallbackInfo *callback) +{ + callback->ref_count++; +} + +static void +callback_info_unref (CallbackInfo *callback) +{ + callback->ref_count--; + + if (callback->ref_count == 0) { + if (callback->destroy_notify != NULL) { + callback->destroy_notify (callback->callback_data); + } + g_free (callback); + } +} + +/* code for handling async callbacks */ + +static void +async_callback_response (gpointer data) +{ + CallbackResponseData *response_data; + + g_static_mutex_lock (&async_callback_lock); + response_data = data; + response_data->done = TRUE; + g_cond_broadcast (async_callback_cond); + + g_static_mutex_unlock (&async_callback_lock); +} + +static void +async_callback_invoke (gconstpointer in, + gsize in_size, + gpointer out, + gsize out_size, + gpointer callback_data) +{ + AsyncCallbackInfo *async_callback; + CallbackResponseData response_data; + + async_callback = callback_data; + + /* Using a single mutex and condition variable could mean bad + * performance if many async callbacks are active at once but + * this is unlikeley, so we avoid the overhead of creating + * new mutexes and condition variables all the time. + */ + + g_static_mutex_lock (&async_callback_lock); + response_data.done = FALSE; + _gnome_vfs_dispatch_module_callback (async_callback->callback, + in, in_size, + out, out_size, + async_callback->callback_data, + async_callback_response, + &response_data); + while (!response_data.done) { + g_cond_wait (async_callback_cond, + g_static_mutex_get_mutex (&async_callback_lock)); + } + + g_static_mutex_unlock (&async_callback_lock); +} + +static void +async_callback_destroy (gpointer callback_data) +{ + AsyncCallbackInfo *async_callback; + + async_callback = callback_data; + + if (async_callback->destroy_notify != NULL) { + async_callback->destroy_notify (async_callback->callback_data); + } + + g_free (async_callback); + +} + +static CallbackInfo * +async_callback_info_new (GnomeVFSAsyncModuleCallback callback_func, + gpointer callback_data, + GDestroyNotify notify) +{ + AsyncCallbackInfo *async_callback; + + async_callback = g_new (AsyncCallbackInfo, 1); + + async_callback->callback = callback_func; + async_callback->callback_data = callback_data; + async_callback->destroy_notify = notify; + + return callback_info_new (async_callback_invoke, async_callback, async_callback_destroy); +} + + + +/* Adding items to hash tables or stack tables */ +static void +insert_callback_into_table (GHashTable *table, + const char *callback_name, + CallbackInfo *callback) +{ + gpointer orig_key; + gpointer old_value; + + callback_info_ref (callback); + + if (g_hash_table_lookup_extended (table, + callback_name, + &orig_key, + &old_value)) { + g_hash_table_remove (table, orig_key); + g_free (orig_key); + callback_info_unref ((CallbackInfo *) old_value); + } + + g_hash_table_insert (table, + g_strdup (callback_name), + callback); +} + +static void +push_callback_into_stack_table (GHashTable *table, + const char *callback_name, + CallbackInfo *callback) +{ + gpointer orig_key; + gpointer old_value; + GSList *stack; + + callback_info_ref (callback); + + if (g_hash_table_lookup_extended (table, + callback_name, + &orig_key, + &old_value)) { + g_hash_table_remove (table, orig_key); + g_free (orig_key); + stack = old_value; + } else { + stack = NULL; + } + + stack = g_slist_prepend (stack, callback); + + g_hash_table_insert (table, + g_strdup (callback_name), + stack); +} + +static void +pop_stack_table (GHashTable *table, + const char *callback_name) +{ + GSList *stack; + GSList *first_link; + gpointer orig_key; + gpointer old_value; + + if (g_hash_table_lookup_extended (table, + callback_name, + &orig_key, + &old_value)) { + g_hash_table_remove (table, orig_key); + g_free (orig_key); + stack = old_value; + } else { + return; + } + + /* Would not be in the hash table if it were NULL */ + g_assert (stack != NULL); + + callback_info_unref ((CallbackInfo *) stack->data); + + first_link = stack; + stack = stack->next; + g_slist_free_1 (first_link); + + if (stack != NULL) { + g_hash_table_insert (table, + g_strdup (callback_name), + stack); + } +} + +/* Functions to copy, duplicate and clear callback tables and callback + * stack tables, and helpers for these functions. + */ + +static void +copy_one_stack_top (gpointer key, + gpointer value, + gpointer callback_data) +{ + GSList *stack; + const char *callback_name; + CallbackInfo *callback; + GHashTable *table; + + callback_name = key; + stack = value; + callback = stack->data; + table = callback_data; + + insert_callback_into_table (table, callback_name, callback); +} + +static void +copy_one_callback_to_stack (gpointer key, + gpointer value, + gpointer callback_data) +{ + const char *callback_name; + CallbackInfo *callback; + GHashTable *table; + + callback_name = key; + callback = value; + table = callback_data; + + push_callback_into_stack_table (table, callback_name, callback); +} + +static void +copy_callback_stack_tops (GHashTable *source, + GHashTable *target) +{ + g_hash_table_foreach (source, + copy_one_stack_top, + target); +} + +static void +copy_callback_table_to_stack_table (GHashTable *source, + GHashTable *target) +{ + g_hash_table_foreach (source, + copy_one_callback_to_stack, + target); +} + +static void +callback_info_unref_func (gpointer data, + gpointer callback_data) +{ + callback_info_unref ((CallbackInfo *) data); +} + +static gboolean +remove_one_stack (gpointer key, + gpointer value, + gpointer callback_data) +{ + char *callback_name; + GSList *stack; + + callback_name = key; + stack = value; + + g_free (callback_name); + g_slist_foreach (stack, callback_info_unref_func, NULL); + g_slist_free (stack); + + return TRUE; +} + +static gboolean +remove_one_callback (gpointer key, + gpointer value, + gpointer callback_data) +{ + char *callback_name; + CallbackInfo *callback; + + callback_name = key; + callback = value; + + g_free (callback_name); + callback_info_unref (callback); + + return TRUE; +} + +static void +clear_stack_table (GHashTable *stack_table) +{ + g_hash_table_foreach_remove (stack_table, + remove_one_stack, + NULL); +} + +static void +clear_callback_table (GHashTable *stack_table) +{ + g_hash_table_foreach_remove (stack_table, + remove_one_callback, + NULL); +} + + +/* Functions to inialize global and per-thread data on demand and + * associated cleanup functions. + */ +static void +stack_table_destroy (gpointer specific) +{ + GHashTable *stack_table; + + stack_table = specific; + + g_static_mutex_lock (&callback_table_lock); + g_hash_table_remove (stack_tables_to_free, stack_table); + g_static_mutex_unlock (&callback_table_lock); + + clear_stack_table (stack_table); + g_hash_table_destroy (stack_table); +} + +static gboolean +stack_table_free_hr_func (gpointer key, + gpointer value, + gpointer callback_data) +{ + GHashTable *table; + + table = key; + + clear_stack_table (table); + g_hash_table_destroy (table); + + return TRUE; +} + + +static void +free_stack_tables_to_free (void) +{ + g_static_mutex_lock (&callback_table_lock); + g_hash_table_foreach_remove (stack_tables_to_free, stack_table_free_hr_func , NULL); + g_hash_table_destroy (stack_tables_to_free); + g_static_mutex_unlock (&callback_table_lock); +} + +void +_gnome_vfs_module_callback_private_init (void) +{ + callback_stacks_key = g_private_new (stack_table_destroy); + async_callback_stacks_key = g_private_new (stack_table_destroy); + in_async_thread_key = g_private_new (NULL); + + stack_tables_to_free = g_hash_table_new (g_direct_hash, g_direct_equal); + + async_callback_cond = g_cond_new (); + + g_atexit (free_stack_tables_to_free); +} + +static void +free_default_callbacks (void) +{ + g_static_mutex_lock (&callback_table_lock); + + clear_callback_table (default_callbacks); + g_hash_table_destroy (default_callbacks); + + clear_callback_table (default_async_callbacks); + g_hash_table_destroy (default_async_callbacks); + + g_static_mutex_unlock (&callback_table_lock); +} + +/* This function should only be called with the mutex held. */ +static void +initialize_global_if_needed (void) +{ + if (default_callbacks == NULL) { + default_callbacks = g_hash_table_new (g_str_hash, g_str_equal); + default_async_callbacks = g_hash_table_new (g_str_hash, g_str_equal); + + g_atexit (free_default_callbacks); + } +} + +/* No need for a mutex, since it's all per-thread data. */ +static void +initialize_per_thread_if_needed (void) +{ + /* Initialize per-thread data, if needed. */ + if (g_private_get (callback_stacks_key) == NULL) { + g_static_mutex_lock (&callback_table_lock); + g_private_set (callback_stacks_key, + g_hash_table_new (g_str_hash, g_str_equal)); + g_hash_table_insert (stack_tables_to_free, + g_private_get (callback_stacks_key), + GINT_TO_POINTER (1)); + g_static_mutex_unlock (&callback_table_lock); + } + + if (g_private_get (async_callback_stacks_key) == NULL) { + g_static_mutex_lock (&callback_table_lock); + g_private_set (async_callback_stacks_key, + g_hash_table_new (g_str_hash, g_str_equal)); + g_hash_table_insert (stack_tables_to_free, + g_private_get (async_callback_stacks_key), + GINT_TO_POINTER (1)); + g_static_mutex_unlock (&callback_table_lock); + } +} + +/* -- Public entry points -- */ + +/** + * GnomeVFSModuleCallback + * @in: The in argument for this callback; the exact type depends on the specific callback + * @in_size: Size of the in argument; useful for sanity-checking + * @out: The out argument for this callback; the exact type depends on the specific callback + * @out_size: Size of the out argument; useful for sanity-checking + * @callback_data: The @callback_data specified when this callback was set + * + * This is the type of a callback function that gets set for a module + * callback. + * + * When the callback is invoked, the user function is called with an + * @in argument, the exact type of which depends on the specific + * callback. It is generally a pointer to a struct with several fields + * that provide information to the callback. + * + * The @out argument is used to return a values from the + * callback. Once again the exact type depends on the specific + * callback. It is generally a pointer to a pre-allocated struct with + * several fields that the callback function should fill in before + * returning. + * + */ + + +/** + * GnomeVFSModuleCallbackResponse + * @response_data: Pass the @response_data argument originally passed to the async callback + * + * This is the type of the response function passed to a + * GnomeVFSAsyncModuleCallback(). It should be called when the async + * callback has completed. + */ + + +/** + * GnomeVFSAsyncModuleCallback + * @in: The in argument for this callback; the exact type depends on the specific callback + * @in_size: Size of the in argument; useful for sanity-checking + * @out: The out argument for this callback; the exact type depends on the specific callback + * @out_size: Size of the out argument; useful for sanity-checking + * @callback_data: The @callback_data specified when this callback was set + * @response: Response function to call when the callback is completed + * @response_data: Argument to pass to @response + * + * This is the type of a callback function that gets set for an async + * module callback. + * + * Such callbacks are useful when you are using the API and want + * callbacks to be handled from the main thread, for instance if they + * need to put up a dialog. + * + * Like a GnomeVFSModuleCallback(), an async callback has @in and @out + * arguments for passing data into and out of the callback. However, + * an async callback does not need to fill in the @out argument before + * returning. Instead, it can arrange to have the work done from a + * callback on the main loop, from another thread, etc. The @response + * function should be called by whatever code finishes the work of the + * callback with @response_data as an argument once the @out argument + * is filled in and the callback is done. + * + * The @in and @out arguments are guaranteed to remain valid until the + * @response function is called. + * + */ + + + + + +/** + * gnome_vfs_module_callback_set_default + * @callback_name: The name of the module callback to set + * @callback: The function to call when the callback is invoked + * @callback_data: Pointer to pass as the @callback_data argument to @callback + * @destroy_notify: Function to call when @callback_data is to be freed. + * + * Set the default callback for @callback_name to + * @callback. @callback will be called with @callback_data on the + * same thread as the gnome-vfs operation that invokes it. The default + * value is shared for all threads, but setting it is thread-safe. + * + * Use this function if you want to set a handler to be used by your + * whole application. You can use gnome_vfs_module_callback_push() to + * set a callback function that will temporarily override the default + * on the current thread instead. Or you can also use + * gnome_vfs_async_module_callback_set_default() to set an async + * callback function. + * + * Note: @destroy_notify may be called on any thread - it is not + * guaranteed to be called on the main thread. + * + **/ +void +gnome_vfs_module_callback_set_default (const char *callback_name, + GnomeVFSModuleCallback callback, + gpointer callback_data, + GDestroyNotify destroy_notify) +{ + CallbackInfo *callback_info; + + callback_info = callback_info_new (callback, callback_data, destroy_notify); + + g_static_mutex_lock (&callback_table_lock); + + initialize_global_if_needed (); + insert_callback_into_table (default_callbacks, callback_name, callback_info); + + g_static_mutex_unlock (&callback_table_lock); + + callback_info_unref (callback_info); +} + +/** + * gnome_vfs_module_callback_push + * @callback_name: The name of the module callback to set temporarily + * @callback: The function to call when the callback is invoked + * @callback_data: Pointer to pass as the @callback_data argument to @callback + * @destroy_notify: Function to call when @callback_data is to be freed. + * + * Set @callback as a temprary handler for @callback_name. @callback + * will be called with @callback_data on the same thread as the + * gnome-vfs operation that invokes it. The temporary handler is set + * per-thread. + * + * gnome_vfs_module_callback_pop() removes the most recently set + * temporary handler. The temporary handlers are treated as a first-in + * first-out stack. + * + * Use this function to set a temporary callback handler for a single + * call or a few calls. You can use + * gnome_vfs_module_callback_set_default() to set a callback function + * that will establish a permanent global setting for all threads + * instead. + * + * Note: @destroy_notify may be called on any thread - it is not + * guaranteed to be called on the main thread. + * + **/ +void +gnome_vfs_module_callback_push (const char *callback_name, + GnomeVFSModuleCallback callback, + gpointer callback_data, + GDestroyNotify notify) +{ + CallbackInfo *callback_info; + + initialize_per_thread_if_needed (); + + callback_info = callback_info_new (callback, callback_data, notify); + push_callback_into_stack_table (g_private_get (callback_stacks_key), + callback_name, + callback_info); + callback_info_unref (callback_info); +} + +/** + * gnome_vfs_module_callback_pop + * @callback_name: The name of the module callback to remove a temporary handler for + * + * Remove the temporary handler for @callback_name most recently set + * with gnome_vfs_module_callback_push(). If another temporary + * handler was previously set on the same thread, it becomes the + * current handler. Otherwise, the default handler, if any, becomes + * current. + * + * The temporary handlers are treated as a first-in first-out + * stack. + * + **/ +void +gnome_vfs_module_callback_pop (const char *callback_name) +{ + initialize_per_thread_if_needed (); + pop_stack_table (g_private_get (callback_stacks_key), + callback_name); +} + + +/** + * gnome_vfs_async_module_callback_set_default + * @callback_name: The name of the async module callback to set + * @callback: The function to call when the callback is invoked + * @callback_data: Pointer to pass as the @callback_data argument to @callback + * @destroy_notify: Function to call when @callback_data is to be freed. + * + * Set the default async callback for @callback_name to + * @callback. @callback will be called with @callback_data + * from a callback on the main thread. It will be passed a response + * function which should be called to signal completion of the callback. + * The callback function itself may return in the meantime. + * + * The default value is shared for all threads, but setting it is + * thread-safe. + * + * Use this function if you want to globally set a callback handler + * for use with async operations. + * + * You can use gnome_vfs_async_module_callback_push() to set an async + * callback function that will temporarily override the default on the + * current thread instead. Or you can also use + * gnome_vfs_module_callback_set_default() to set a regular callback + * function. + * + * Note: @destroy_notify may be called on any thread - it is not + * guaranteed to be called on the main thread. + * + **/ +void +gnome_vfs_async_module_callback_set_default (const char *callback_name, + GnomeVFSAsyncModuleCallback callback, + gpointer callback_data, + GDestroyNotify notify) +{ + CallbackInfo *callback_info; + + callback_info = async_callback_info_new (callback, callback_data, notify); + + g_static_mutex_lock (&callback_table_lock); + + initialize_global_if_needed (); + insert_callback_into_table (default_async_callbacks, callback_name, callback_info); + + g_static_mutex_unlock (&callback_table_lock); + + callback_info_unref (callback_info); +} + +/** + * gnome_vfs_async_module_callback_push + * @callback_name: The name of the module callback to set temporarily + * @callback: The function to call when the callback is invoked + * @callback_data: Pointer to pass as the @callback_data argument to @callback + * @destroy_notify: Function to call when @callback_data is to be freed. + * + * Set @callback_func as a temprary async handler for + * @callback_name. @callback will be called with @callback_data + * from a callback on the main thread. It will be passed a response + * function which should be called to signal completion of the + * callback. The callback function itself may return in the meantime. + * + * The temporary async handler is set per-thread. + * + * gnome_vfs_async_module_callback_pop() removes the most recently set + * temporary temporary handler. The temporary async handlers are + * treated as a first-in first-out stack. + * + * Use this function to set a temporary async callback handler for a + * single call or a few calls. You can use + * gnome_vfs_async_module_callback_set_default() to set an async + * callback function that will establish a permanent global setting + * for all threads instead. + * + * Note: @destroy_notify may be called on any thread - it is not + * guaranteed to be called on the main thread. + * + **/ +void +gnome_vfs_async_module_callback_push (const char *callback_name, + GnomeVFSAsyncModuleCallback callback, + gpointer callback_data, + GDestroyNotify notify) +{ + CallbackInfo *callback_info; + + initialize_per_thread_if_needed (); + + callback_info = async_callback_info_new (callback, callback_data, notify); + + push_callback_into_stack_table (g_private_get (async_callback_stacks_key), + callback_name, + callback_info); + + callback_info_unref (callback_info); +} + +/** + * gnome_vfs_async_module_callback_pop + * @callback_name: The name of the module callback to remove a temporary handler for + * + * Remove the temporary async handler for @callback_name most recently + * set with gnome_vfs_async_module_callback_push(). If another + * temporary async handler was previously set on the same thread, it + * becomes the current handler. Otherwise, the default async handler, + * if any, becomes current. + * + * The temporary async handlers are treated as a first-in first-out + * stack. + * + **/ +void +gnome_vfs_async_module_callback_pop (const char *callback_name) +{ + initialize_per_thread_if_needed (); + pop_stack_table (g_private_get (async_callback_stacks_key), + callback_name); +} + + +/* -- Module-only entry points -- */ + +/** + * gnome_vfs_module_callback_invoke + * @callback_name: The name of the module callback to set + * @in: In argument - type dependent on the specific callback + * @in_size: Size of the in argument + * @out: Out argument - type dependent on the specific callback + * @out_size: Size of the out argument + * + * Invoke a default callback for @callback_name, with in arguments + * specified by @in and @in_size, and out arguments specified by @out + * and @out_size. + * + * This function should only be called by gnome-vfs modules. + * + * If this function is called from an async job thread, it will invoke + * the current async handler for @callback_name, if any. If no async + * handler is set, or the function is not called from an async job + * thread, the regular handler, if any, will be invoked instead. If no + * handler at all is found for @callback_name, the function returns + * FALSE. + * + * Returns: TRUE if a callback was invoked, FALSE if none was set. + * + */ +gboolean +gnome_vfs_module_callback_invoke (const char *callback_name, + gconstpointer in, + gsize in_size, + gpointer out, + gsize out_size) +{ + CallbackInfo *callback; + gboolean invoked; + GSList *stack; + + callback = NULL; + + initialize_per_thread_if_needed (); + + if (g_private_get (in_async_thread_key) != NULL) { + stack = g_hash_table_lookup (g_private_get (async_callback_stacks_key), + callback_name); + + if (stack != NULL) { + callback = stack->data; + g_assert (callback != NULL); + callback_info_ref (callback); + } else { + g_static_mutex_lock (&callback_table_lock); + initialize_global_if_needed (); + callback = g_hash_table_lookup (default_async_callbacks, callback_name); + if (callback != NULL) { + callback_info_ref (callback); + } + g_static_mutex_unlock (&callback_table_lock); + } + } + + if (callback == NULL) { + stack = g_hash_table_lookup (g_private_get (callback_stacks_key), + callback_name); + + if (stack != NULL) { + callback = stack->data; + g_assert (callback != NULL); + callback_info_ref (callback); + } else { + g_static_mutex_lock (&callback_table_lock); + initialize_global_if_needed (); + callback = g_hash_table_lookup (default_callbacks, callback_name); + if (callback != NULL) { + callback_info_ref (callback); + } + g_static_mutex_unlock (&callback_table_lock); + } + } + + if (callback == NULL) { + invoked = FALSE; + } else { + callback->callback (in, in_size, out, out_size, callback->callback_data); + invoked = TRUE; + callback_info_unref (callback); + } + + return invoked; +} + + +/* -- Private entry points -- */ + +/* (used by job mechanism to implement callback + * state copying semantics for async jobs. + */ + +GnomeVFSModuleCallbackStackInfo * +_gnome_vfs_module_callback_get_stack_info (void) +{ + GnomeVFSModuleCallbackStackInfo *stack_info; + + stack_info = g_new (GnomeVFSModuleCallbackStackInfo, 1); + stack_info->current_callbacks = g_hash_table_new (g_str_hash, g_str_equal); + stack_info->current_async_callbacks = g_hash_table_new (g_str_hash, g_str_equal); + + g_static_mutex_lock (&callback_table_lock); + initialize_global_if_needed (); + g_static_mutex_unlock (&callback_table_lock); + + initialize_per_thread_if_needed (); + copy_callback_stack_tops (g_private_get (callback_stacks_key), + stack_info->current_callbacks); + copy_callback_stack_tops (g_private_get (async_callback_stacks_key), + stack_info->current_async_callbacks); + + return stack_info; +} + +void +_gnome_vfs_module_callback_free_stack_info (GnomeVFSModuleCallbackStackInfo *stack_info) +{ + clear_callback_table (stack_info->current_callbacks); + g_hash_table_destroy (stack_info->current_callbacks); + clear_callback_table (stack_info->current_async_callbacks); + g_hash_table_destroy (stack_info->current_async_callbacks); + + g_free (stack_info); +} + +void +_gnome_vfs_module_callback_use_stack_info (GnomeVFSModuleCallbackStackInfo *stack_info) +{ + initialize_per_thread_if_needed (); + copy_callback_table_to_stack_table (stack_info->current_callbacks, + g_private_get (callback_stacks_key)); + copy_callback_table_to_stack_table (stack_info->current_async_callbacks, + g_private_get (async_callback_stacks_key)); +} + +void +_gnome_vfs_module_callback_clear_stacks (void) +{ + initialize_per_thread_if_needed (); + clear_stack_table (g_private_get (callback_stacks_key)); + clear_stack_table (g_private_get (async_callback_stacks_key)); +} + +void +_gnome_vfs_module_callback_set_in_async_thread (gboolean in_async_thread) +{ + initialize_per_thread_if_needed (); + g_private_set (in_async_thread_key, GINT_TO_POINTER (in_async_thread)); +} diff --git a/libgnomevfs/gnome-vfs-module-callback.h b/libgnomevfs/gnome-vfs-module-callback.h new file mode 100644 index 0000000..96fc985 --- /dev/null +++ b/libgnomevfs/gnome-vfs-module-callback.h @@ -0,0 +1,75 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-module-callback.h - registering for callbacks from modules + + Copyright (C) 2001 Eazel, Inc + Copyright (C) 2001 Free Software Foundation + Copyright (C) 2001 Maciej Stachowiak + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Maciej Stachowiak + Seth Nickell + Michael Fleming +*/ + +#ifndef GNOME_VFS_MODULE_CALLBACK_H +#define GNOME_VFS_MODULE_CALLBACK_H + +#include + +G_BEGIN_DECLS + +typedef void (* GnomeVFSModuleCallback) (gconstpointer in, + gsize in_size, + gpointer out, + gsize out_size, + gpointer callback_data); + +typedef void (* GnomeVFSModuleCallbackResponse) (gpointer response_data); + +typedef void (* GnomeVFSAsyncModuleCallback) (gconstpointer in, + gsize in_size, + gpointer out, + gsize out_size, + gpointer callback_data, + GnomeVFSModuleCallbackResponse response, + gpointer response_data); + + +void gnome_vfs_module_callback_set_default (const char *callback_name, + GnomeVFSModuleCallback callback, + gpointer callback_data, + GDestroyNotify destroy_notify); +void gnome_vfs_module_callback_push (const char *callback_name, + GnomeVFSModuleCallback callback, + gpointer callback_data, + GDestroyNotify destroy_notify); +void gnome_vfs_module_callback_pop (const char *callback_name); + +void gnome_vfs_async_module_callback_set_default (const char *callback_name, + GnomeVFSAsyncModuleCallback callback, + gpointer callback_data, + GDestroyNotify destroy_notify); +void gnome_vfs_async_module_callback_push (const char *callback_name, + GnomeVFSAsyncModuleCallback callback, + gpointer callback_data, + GDestroyNotify destroy_notify); +void gnome_vfs_async_module_callback_pop (const char *callback_name); + +G_END_DECLS + +#endif + diff --git a/libgnomevfs/gnome-vfs-module-shared.c b/libgnomevfs/gnome-vfs-module-shared.c new file mode 100644 index 0000000..e712bff --- /dev/null +++ b/libgnomevfs/gnome-vfs-module-shared.c @@ -0,0 +1,149 @@ +#include + +#include "gnome-vfs-module-shared.h" +#include +#include +#include +#include +#include +#include +#include + +#include "gnome-vfs-module.h" +#include "gnome-vfs-ops.h" + +/** + * gnome_vfs_mime_type_from_mode: + * @mode: + * + * Returns a MIME type based on the mode passed. It only works when mode + * references a special file (directory, device, fifo, socket or symlink) + * + * Returns: a string containing the MIME type, if @mode is a normal file + * returns NULL. + **/ + +const gchar * +gnome_vfs_mime_type_from_mode (mode_t mode) +{ + const gchar *mime_type; + + if (S_ISREG (mode)) + mime_type = NULL; + else if (S_ISDIR (mode)) + mime_type = "x-directory/normal"; + else if (S_ISCHR (mode)) + mime_type = "x-special/device-char"; + else if (S_ISBLK (mode)) + mime_type = "x-special/device-block"; + else if (S_ISFIFO (mode)) + mime_type = "x-special/fifo"; + else if (S_ISLNK (mode)) + mime_type = "x-special/symlink"; + else if (S_ISSOCK (mode)) + mime_type = "x-special/socket"; + else + mime_type = NULL; + + return mime_type; +} + +/** + * gnome_vfs_get_special_mime_type: + * @uri: + * + * Gets the MIME type for @uri, this function only returns the type + * when the URI points to a file that can't be sniffed (sockets, + * directories, devices, and fifos). + * + * Returns: a string containing the mime type, NULL if the @uri doesn't + * present an special file. + **/ + +const char * +gnome_vfs_get_special_mime_type (GnomeVFSURI *uri) +{ + GnomeVFSResult error; + GnomeVFSFileInfo info; + + /* Get file info and examine the type field to see if file is + * one of the special kinds. + */ + error = gnome_vfs_get_file_info_uri (uri, &info, GNOME_VFS_FILE_INFO_DEFAULT); + if (error != GNOME_VFS_OK) { + return NULL; + } + + switch (info.type) { + case GNOME_VFS_FILE_TYPE_DIRECTORY: + return "x-directory/normal"; + case GNOME_VFS_FILE_TYPE_CHARACTER_DEVICE: + return "x-special/device-char"; + case GNOME_VFS_FILE_TYPE_BLOCK_DEVICE: + return "x-special/device-block"; + case GNOME_VFS_FILE_TYPE_FIFO: + return "x-special/fifo"; + case GNOME_VFS_FILE_TYPE_SOCKET: + return "x-special/socket"; + default: + break; + } + + return NULL; +} + +void +gnome_vfs_stat_to_file_info (GnomeVFSFileInfo *file_info, + const struct stat *statptr) +{ + if (S_ISDIR (statptr->st_mode)) + file_info->type = GNOME_VFS_FILE_TYPE_DIRECTORY; + else if (S_ISCHR (statptr->st_mode)) + file_info->type = GNOME_VFS_FILE_TYPE_CHARACTER_DEVICE; + else if (S_ISBLK (statptr->st_mode)) + file_info->type = GNOME_VFS_FILE_TYPE_BLOCK_DEVICE; + else if (S_ISFIFO (statptr->st_mode)) + file_info->type = GNOME_VFS_FILE_TYPE_FIFO; + else if (S_ISSOCK (statptr->st_mode)) + file_info->type = GNOME_VFS_FILE_TYPE_SOCKET; + else if (S_ISREG (statptr->st_mode)) + file_info->type = GNOME_VFS_FILE_TYPE_REGULAR; + else if (S_ISLNK (statptr->st_mode)) + file_info->type = GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK; + else + file_info->type = GNOME_VFS_FILE_TYPE_UNKNOWN; + + file_info->permissions + = statptr->st_mode & (GNOME_VFS_PERM_USER_ALL + | GNOME_VFS_PERM_GROUP_ALL + | GNOME_VFS_PERM_OTHER_ALL + | GNOME_VFS_PERM_SUID + | GNOME_VFS_PERM_SGID + | GNOME_VFS_PERM_STICKY); + + file_info->device = statptr->st_dev; + file_info->inode = statptr->st_ino; + + file_info->link_count = statptr->st_nlink; + + file_info->uid = statptr->st_uid; + file_info->gid = statptr->st_gid; + + file_info->size = statptr->st_size; + file_info->block_count = statptr->st_blocks; + file_info->io_block_size = statptr->st_blksize; + + file_info->atime = statptr->st_atime; + file_info->ctime = statptr->st_ctime; + file_info->mtime = statptr->st_mtime; + + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_TYPE | + GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS | GNOME_VFS_FILE_INFO_FIELDS_FLAGS | + GNOME_VFS_FILE_INFO_FIELDS_DEVICE | GNOME_VFS_FILE_INFO_FIELDS_INODE | + GNOME_VFS_FILE_INFO_FIELDS_LINK_COUNT | GNOME_VFS_FILE_INFO_FIELDS_SIZE | + GNOME_VFS_FILE_INFO_FIELDS_BLOCK_COUNT | GNOME_VFS_FILE_INFO_FIELDS_IO_BLOCK_SIZE | + GNOME_VFS_FILE_INFO_FIELDS_ATIME | GNOME_VFS_FILE_INFO_FIELDS_MTIME | + GNOME_VFS_FILE_INFO_FIELDS_CTIME; +} + + diff --git a/libgnomevfs/gnome-vfs-module-shared.h b/libgnomevfs/gnome-vfs-module-shared.h new file mode 100644 index 0000000..c5aa2e0 --- /dev/null +++ b/libgnomevfs/gnome-vfs-module-shared.h @@ -0,0 +1,54 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-module-shared.h - code shared between the different modules + place. + + Copyright (C) 2001 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Seth Nickell + +G_BEGIN_DECLS + +const gchar * gnome_vfs_mime_type_from_mode (mode_t mode); + +void gnome_vfs_stat_to_file_info (GnomeVFSFileInfo *file_info, + const struct stat *statptr); + +GnomeVFSResult gnome_vfs_set_meta (GnomeVFSFileInfo *info, + const char *file_name, + const char *meta_key); + +GnomeVFSResult gnome_vfs_set_meta_for_list (GnomeVFSFileInfo *info, + const char *file_name, + const GList *meta_keys); + +const char *gnome_vfs_get_special_mime_type (GnomeVFSURI *uri); + +G_END_DECLS + +#endif diff --git a/libgnomevfs/gnome-vfs-module.c b/libgnomevfs/gnome-vfs-module.c new file mode 100644 index 0000000..2893bd5 --- /dev/null +++ b/libgnomevfs/gnome-vfs-module.c @@ -0,0 +1,2 @@ +#include +#include "gnome-vfs-module.h" diff --git a/libgnomevfs/gnome-vfs-module.h b/libgnomevfs/gnome-vfs-module.h new file mode 100644 index 0000000..662a28b --- /dev/null +++ b/libgnomevfs/gnome-vfs-module.h @@ -0,0 +1,74 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-method.h - All the VFS bits a module needs to include in one + place. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Michael Meeks */ + +#ifndef GNOME_VFS_MODULE_H +#define GNOME_VFS_MODULE_H + +#include + +G_BEGIN_DECLS + + +/** + * vfs_module_init: + * @method_name: name of the method that invoked this module (e.g. "http", "ftp", "file"). + * @args: not used by most modules, but potential arguments for creating the module (could + * be a file to point at, for example) + * + * Standard extern call implemented by each filesystem module. This is called + * to initialize the module and setup any basic structures / connections the + * method requires. It also allows the module to identify the URI method it is + * associated with in this instance. + * + * Return value: the module symbol table, pointing to the appropriate calls for + * this module. + **/ +extern GnomeVFSMethod *vfs_module_init (const char *method_name, const char *args); + +/** + * vfs_module_transform: + * @method_name: name of the method that invoked this module (e.g. "http", "ftp", "file"). + * @args: not used by most modules, but potential arguments for creating the module (could + * be a file to point at, for example) + * + * Shift an already instanced module to a new method name. This call is not implemented + * by most modules and is optional. + * + * Return value: the module symbol table, pointing to the appropriate calls for + * this module. + **/ +extern GnomeVFSTransform *vfs_module_transform (const char *method_name, const char *args); + +/** + * vfs_module_shutdown: + * @method: the symbol table of the module being shut down + * + * Called to tell a module to end any active operations, free all used memory, + * and close any connections (as appropriate) or resources. + * + **/ +extern void vfs_module_shutdown (GnomeVFSMethod *method); + +G_END_DECLS + +#endif /* GNOME_VFS_MODULE_H */ diff --git a/libgnomevfs/gnome-vfs-monitor-private.h b/libgnomevfs/gnome-vfs-monitor-private.h new file mode 100644 index 0000000..4924a9d --- /dev/null +++ b/libgnomevfs/gnome-vfs-monitor-private.h @@ -0,0 +1,45 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-monitor.h - File Monitoring for the GNOME Virtual File System. + + Copyright (C) 2001 Ian McKellar + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ian McKellar +*/ + +#ifndef GNOME_VFS_MONITOR_PRIVATE_H +#define GNOME_VFS_MONITOR_PRIVATE_H + +#include +#include +#include +#include + +GnomeVFSResult _gnome_vfs_monitor_do_add (GnomeVFSMethod *method, + GnomeVFSMonitorHandle **handle, + GnomeVFSURI *uri, + GnomeVFSMonitorType monitor_type, + GnomeVFSMonitorCallback callback, + gpointer user_data); + +GnomeVFSResult _gnome_vfs_monitor_do_cancel (GnomeVFSMonitorHandle *handle); + +/* this is for modules - should it be in a separate header file? */ +void gnome_vfs_monitor_callback (GnomeVFSMethodHandle *method_handle, + GnomeVFSURI *info_uri, + GnomeVFSMonitorEventType event_type); +#endif /* GNOME_VFS_MONITOR_PRIVATE_H */ diff --git a/libgnomevfs/gnome-vfs-monitor.c b/libgnomevfs/gnome-vfs-monitor.c new file mode 100644 index 0000000..9442378 --- /dev/null +++ b/libgnomevfs/gnome-vfs-monitor.c @@ -0,0 +1,465 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-monitor.c - File Monitoring for the GNOME Virtual File System. + + Copyright (C) 2001 Ian McKellar + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ian McKellar +*/ + +#include +#include +#include +#include +#include +#include + +typedef enum { + CALLBACK_STATE_NOT_SENT, + CALLBACK_STATE_SENDING, + CALLBACK_STATE_SENT +} CallbackState; + + +struct GnomeVFSMonitorHandle { + GnomeVFSURI *uri; /* the URI being monitored */ + GnomeVFSMethodHandle *method_handle; + GnomeVFSMonitorType type; + GnomeVFSMonitorCallback callback; + gpointer user_data; /* FIXME - how does this get freed */ + + gboolean cancelled; + + GList *pending_callbacks; /* protected by handle_hash */ + guint pending_timeout; /* protected by handle_hash */ + guint timeout_count; /* count up each time pending_timeout is changed + to avoid timeout remove race. + protected by handle_hash */ +}; + +struct GnomeVFSMonitorCallbackData { + char *info_uri; + GnomeVFSMonitorEventType event_type; + CallbackState send_state; + guint32 send_at; +}; + +/* Number of seconds between consecutive events of the same type to the same file */ +#define CONSECUTIVE_CALLBACK_DELAY 2 + +typedef struct GnomeVFSMonitorCallbackData GnomeVFSMonitorCallbackData; + +/* This hash maps the module-supplied handle pointer to our own MonitrHandle */ +static GHashTable *handle_hash = NULL; +G_LOCK_DEFINE_STATIC (handle_hash); + +static void +init_hash_table (void) +{ + G_LOCK (handle_hash); + + if (handle_hash == NULL) { + handle_hash = g_hash_table_new (g_direct_hash, g_direct_equal); + } + + G_UNLOCK (handle_hash); +} + +static void +free_callback_data (GnomeVFSMonitorCallbackData *callback_data) +{ + g_free (callback_data->info_uri); + g_free (callback_data); +} + +GnomeVFSResult +_gnome_vfs_monitor_do_add (GnomeVFSMethod *method, + GnomeVFSMonitorHandle **handle, + GnomeVFSURI *uri, + GnomeVFSMonitorType monitor_type, + GnomeVFSMonitorCallback callback, + gpointer user_data) +{ + GnomeVFSResult result; + GnomeVFSMonitorHandle *monitor_handle = + g_new0(GnomeVFSMonitorHandle, 1); + + init_hash_table (); + gnome_vfs_uri_ref (uri); + monitor_handle->uri = uri; + + monitor_handle->type = monitor_type; + monitor_handle->callback = callback; + monitor_handle->user_data = user_data; + + result = uri->method->monitor_add (uri->method, + &monitor_handle->method_handle, uri, monitor_type); + + if (result != GNOME_VFS_OK) { + gnome_vfs_uri_unref (uri); + g_free (monitor_handle); + monitor_handle = NULL; + } else { + G_LOCK (handle_hash); + g_hash_table_insert (handle_hash, + monitor_handle->method_handle, + monitor_handle); + G_UNLOCK (handle_hash); + } + + *handle = monitor_handle; + + return result; +} + +/* Called with handle_hash lock held */ +static gboolean +no_live_callbacks (GnomeVFSMonitorHandle *monitor_handle) +{ + GList *l; + GnomeVFSMonitorCallbackData *callback_data; + + l = monitor_handle->pending_callbacks; + while (l != NULL) { + callback_data = l->data; + + if (callback_data->send_state == CALLBACK_STATE_NOT_SENT || + callback_data->send_state == CALLBACK_STATE_SENDING) { + return FALSE; + } + + l = l->next; + } + return TRUE; +} + +/* Called with handle_hash lock held */ +static void +destroy_monitor_handle (GnomeVFSMonitorHandle *handle) +{ + gboolean res; + + g_assert (no_live_callbacks (handle)); + + g_list_foreach (handle->pending_callbacks, (GFunc) free_callback_data, NULL); + g_list_free (handle->pending_callbacks); + handle->pending_callbacks = NULL; + + res = g_hash_table_remove (handle_hash, handle->method_handle); + if (!res) { + g_warning ("gnome-vfs-monitor.c: A monitor handle was destroyed " + "before it was added to the method hash table. This " + "is a bug in the application and can cause crashed. " + "It is probably a race-condition."); + } + + gnome_vfs_uri_unref (handle->uri); + g_free (handle); +} + +GnomeVFSResult +_gnome_vfs_monitor_do_cancel (GnomeVFSMonitorHandle *handle) +{ + GnomeVFSResult result; + + init_hash_table (); + + if (!VFS_METHOD_HAS_FUNC(handle->uri->method, monitor_cancel)) { + return GNOME_VFS_ERROR_NOT_SUPPORTED; + } + + result = handle->uri->method->monitor_cancel (handle->uri->method, + handle->method_handle); + + if (result == GNOME_VFS_OK) { + /* mark this monitor as cancelled */ + handle->cancelled = TRUE; + + /* destroy the handle if there are no outstanding callbacks */ + G_LOCK (handle_hash); + if (no_live_callbacks (handle)) { + destroy_monitor_handle (handle); + } + G_UNLOCK (handle_hash); + } + + return result; +} + + +typedef struct { + guint timeout_count; + GnomeVFSMonitorHandle *monitor_handle; +} DispatchData; + +static gint +actually_dispatch_callback (gpointer data) +{ + DispatchData *ddata = data; + GnomeVFSMonitorHandle *monitor_handle = ddata->monitor_handle; + GnomeVFSMonitorCallbackData *callback_data; + gchar *uri; + GList *l, *next; + GList *dispatch; + struct timeval tv; + guint32 now; + + /* This function runs on the main loop, so it won't reenter, + * although other threads may add stuff to the pending queue + * while we don't have the lock + */ + + gettimeofday (&tv, NULL); + now = tv.tv_sec; + + G_LOCK (handle_hash); + + /* Don't clear pending_timeout if we started another timeout + * (and removed this) + */ + if (monitor_handle->timeout_count == ddata->timeout_count) { + monitor_handle->pending_timeout = 0; + } + + if (!monitor_handle->cancelled) { + /* Find all callbacks that needs to be dispatched */ + dispatch = NULL; + l = monitor_handle->pending_callbacks; + while (l != NULL) { + callback_data = l->data; + + g_assert (callback_data->send_state != CALLBACK_STATE_SENDING); + + if (callback_data->send_state == CALLBACK_STATE_NOT_SENT && + callback_data->send_at <= now) { + callback_data->send_state = CALLBACK_STATE_SENDING; + dispatch = g_list_prepend (dispatch, callback_data); + } + + l = l->next; + } + + dispatch = g_list_reverse (dispatch); + + G_UNLOCK (handle_hash); + + l = dispatch; + while (l != NULL) { + callback_data = l->data; + + uri = gnome_vfs_uri_to_string + (monitor_handle->uri, + GNOME_VFS_URI_HIDE_NONE); + + + /* actually run app code */ + monitor_handle->callback (monitor_handle, uri, + callback_data->info_uri, + callback_data->event_type, + monitor_handle->user_data); + + g_free (uri); + callback_data->send_state = CALLBACK_STATE_SENT; + + l = l->next; + } + + g_list_free (dispatch); + + G_LOCK (handle_hash); + + l = monitor_handle->pending_callbacks; + while (l != NULL) { + callback_data = l->data; + next = l->next; + + g_assert (callback_data->send_state != CALLBACK_STATE_SENDING); + + /* If we've sent the event, and its not affecting coming events, free it */ + if (callback_data->send_state == CALLBACK_STATE_SENT && + callback_data->send_at + CONSECUTIVE_CALLBACK_DELAY <= now) { + /* free the callback_data */ + free_callback_data (callback_data); + + monitor_handle->pending_callbacks = + g_list_delete_link (monitor_handle->pending_callbacks, + l); + } + + l = next; + } + + } + + /* if we were waiting for this callback to be dispatched to free + * this monitor, then do it now. + */ + if (monitor_handle->cancelled && + no_live_callbacks (monitor_handle)) { + destroy_monitor_handle (monitor_handle); + } + + G_UNLOCK (handle_hash); + + return FALSE; +} + +/* Called with handle_hash lock held */ +static void +send_uri_changes_now (GnomeVFSMonitorHandle *monitor_handle, + const char *uri, + gint32 now) +{ + GList *l; + GnomeVFSMonitorCallbackData *callback_data; + + l = monitor_handle->pending_callbacks; + while (l != NULL) { + callback_data = l->data; + if (strcmp (callback_data->info_uri, uri) == 0) { + callback_data->send_at = now; + } + l = l->next; + } +} + +/* Called with handle_hash lock held */ +static guint32 +get_min_delay (GList *list, gint32 now) +{ + guint32 min_send_at; + GnomeVFSMonitorCallbackData *callback_data; + + min_send_at = G_MAXINT; + + while (list != NULL) { + callback_data = list->data; + + if (callback_data->send_state == CALLBACK_STATE_NOT_SENT) { + min_send_at = MIN (min_send_at, callback_data->send_at); + } + + list = list->next; + } + + if (min_send_at < now) { + return 0; + } else { + return min_send_at - now; + } +} + + +/* for modules to send callbacks to the app */ +void +gnome_vfs_monitor_callback (GnomeVFSMethodHandle *method_handle, + GnomeVFSURI *info_uri, /* GList of uris */ + GnomeVFSMonitorEventType event_type) +{ + GnomeVFSMonitorCallbackData *callback_data, *other_data, *last_data; + GnomeVFSMonitorHandle *monitor_handle; + char *uri; + struct timeval tv; + guint32 now; + guint32 delay; + GList *l; + DispatchData *ddata; + + g_return_if_fail (info_uri != NULL); + + init_hash_table (); + + /* We need to loop here, because there is a race after we add the + * handle and when we add it to the hash table. + */ + do { + G_LOCK (handle_hash); + monitor_handle = g_hash_table_lookup (handle_hash, method_handle); + if (monitor_handle == NULL) { + G_UNLOCK (handle_hash); + } + } while (monitor_handle == NULL); + + if (monitor_handle->cancelled) { + G_UNLOCK (handle_hash); + return; + } + + gettimeofday (&tv, NULL); + now = tv.tv_sec; + + uri = gnome_vfs_uri_to_string (info_uri, GNOME_VFS_URI_HIDE_NONE); + + last_data = NULL; + l = monitor_handle->pending_callbacks; + while (l != NULL) { + other_data = l->data; + if (strcmp (other_data->info_uri, uri) == 0) { + last_data = l->data; + } + l = l->next; + } + + if (last_data == NULL || + (last_data->event_type != event_type || + last_data->send_state == CALLBACK_STATE_SENT)) { + callback_data = g_new0 (GnomeVFSMonitorCallbackData, 1); + callback_data->info_uri = g_strdup (uri); + callback_data->event_type = event_type; + callback_data->send_state = CALLBACK_STATE_NOT_SENT; + if (last_data == NULL) { + callback_data->send_at = now; + } else { + if (last_data->event_type != event_type) { + /* New type, flush old events */ + send_uri_changes_now (monitor_handle, uri, now); + callback_data->send_at = now; + } else { + callback_data->send_at = last_data->send_at + CONSECUTIVE_CALLBACK_DELAY; + } + } + + monitor_handle->pending_callbacks = + g_list_append(monitor_handle->pending_callbacks, callback_data); + + delay = get_min_delay (monitor_handle->pending_callbacks, now); + + if (monitor_handle->pending_timeout) { + g_source_remove (monitor_handle->pending_timeout); + } + + ddata = g_new (DispatchData, 1); + ddata->monitor_handle = monitor_handle; + ddata->timeout_count = ++monitor_handle->timeout_count; + + if (delay == 0) { + monitor_handle->pending_timeout = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, + actually_dispatch_callback, + ddata, (GDestroyNotify)g_free); + } else { + monitor_handle->pending_timeout = g_timeout_add_full (G_PRIORITY_DEFAULT, + delay * 1000, + actually_dispatch_callback, + ddata, (GDestroyNotify)g_free); + } + } + + g_free (uri); + + G_UNLOCK (handle_hash); + +} diff --git a/libgnomevfs/gnome-vfs-monitor.h b/libgnomevfs/gnome-vfs-monitor.h new file mode 100644 index 0000000..1062702 --- /dev/null +++ b/libgnomevfs/gnome-vfs-monitor.h @@ -0,0 +1,82 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-monitor.h - File Monitoring for the GNOME Virtual File System. + + Copyright (C) 2001 Ian McKellar + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ian McKellar +*/ + +#ifndef GNOME_VFS_MONITOR_H +#define GNOME_VFS_MONITOR_H + +#include + +/** + * GnomeVFSMonitorType: + * @GNOME_VFS_MONITOR_FILE: + * @GNOME_VFS_MONITOR_DIRECTORY: + * + * Type of resources that can be monitored. + **/ + +typedef enum { + GNOME_VFS_MONITOR_FILE, + GNOME_VFS_MONITOR_DIRECTORY +} GnomeVFSMonitorType; + +/** + * GnomeVFSMonitorEventType: + * @GNOME_VFS_MONITOR_EVENT_CHANGED: file data changed + * @GNOME_VFS_MONITOR_EVENT_DELETED: file deleted event + * @GNOME_VFS_MONITOR_EVENT_STARTEXECUTING: + * @GNOME_VFS_MONITOR_EVENT_STOPEXECUTING: + * @GNOME_VFS_MONITOR_EVENT_CREATED: file created event + * @GNOME_VFS_MONITOR_EVENT_METADATA_CHANGED: file metadata changed + * + * Types of events that can be monitored. + **/ + +typedef enum { + GNOME_VFS_MONITOR_EVENT_CHANGED, + GNOME_VFS_MONITOR_EVENT_DELETED, + GNOME_VFS_MONITOR_EVENT_STARTEXECUTING, + GNOME_VFS_MONITOR_EVENT_STOPEXECUTING, + GNOME_VFS_MONITOR_EVENT_CREATED, + GNOME_VFS_MONITOR_EVENT_METADATA_CHANGED +} GnomeVFSMonitorEventType; + +typedef struct GnomeVFSMonitorHandle GnomeVFSMonitorHandle; + +/** + * GnomeVFSMonitorCallback: + * @handle: the handle of the monitor that created the event + * @monitor_uri: the URI of the monitor that was triggered + * @info_uri: the URI of the actual file this event is concerned with (this can be different + * from @monitor_uri if it was a directory monitor) + * @event_type: what happened to @info_uri + * @user_data: user data passed to gnome_vfs_monitor_add() when the monitor was created + * + * Function called when a monitor detects a change. + * + **/ +typedef void (* GnomeVFSMonitorCallback) (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data); +#endif /* GNOME_VFS_MONITOR_H */ diff --git a/libgnomevfs/gnome-vfs-open-fd.c b/libgnomevfs/gnome-vfs-open-fd.c new file mode 100644 index 0000000..ebe3e7b --- /dev/null +++ b/libgnomevfs/gnome-vfs-open-fd.c @@ -0,0 +1,428 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-open-fd.c - convert a file descriptor to a handle + + Copyright (C) 2002 Giovanni Corriga + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Giovanni Corriga +*/ + +#include +#include + +#include +#include +#include + +#include "gnome-vfs-uri.h" +#include "gnome-vfs-method.h" +#include "gnome-vfs-handle.h" +#include "gnome-vfs-module-shared.h" +#include "gnome-vfs-mime.h" +#include "gnome-vfs-handle-private.h" +#include "gnome-vfs-utils.h" + +static GnomeVFSURI* +create_anonymous_uri (GnomeVFSMethod* method) +{ + GnomeVFSToplevelURI* tl_uri; + GnomeVFSURI* uri; + + tl_uri = g_new0 (GnomeVFSToplevelURI, 1); + + uri = (GnomeVFSURI *) tl_uri; + + uri->ref_count = 1; + uri->method = method; + + return uri; +} + +typedef struct { + GnomeVFSURI *uri; + gint fd; +} FileHandle; + +static FileHandle * +file_handle_new (GnomeVFSURI *uri, + gint fd) +{ + FileHandle *result; + result = g_new (FileHandle, 1); + + result->uri = gnome_vfs_uri_ref (uri); + result->fd = fd; + + return result; +} + +static void +file_handle_destroy (FileHandle *handle) +{ + gnome_vfs_uri_unref (handle->uri); + g_free (handle); +} + +static GnomeVFSResult +do_close (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + FileHandle *file_handle; + gint close_retval; + + g_return_val_if_fail (method_handle != NULL, GNOME_VFS_ERROR_INTERNAL); + + file_handle = (FileHandle *) method_handle; + + do { + close_retval = close (file_handle->fd); + } while (close_retval != 0 + && errno == EINTR + && ! gnome_vfs_context_check_cancellation (context)); + + /* FIXME bugzilla.eazel.com 1163: Should do this even after a failure? */ + file_handle_destroy (file_handle); + + if (close_retval != 0) { + return gnome_vfs_result_from_errno (); + } + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_read (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read, + GnomeVFSContext *context) +{ + FileHandle *file_handle; + gint read_val; + + g_return_val_if_fail (method_handle != NULL, GNOME_VFS_ERROR_INTERNAL); + + file_handle = (FileHandle *) method_handle; + + do { + read_val = read (file_handle->fd, buffer, num_bytes); + } while (read_val == -1 + && errno == EINTR + && ! gnome_vfs_context_check_cancellation (context)); + + if (read_val == -1) { + *bytes_read = 0; + return gnome_vfs_result_from_errno (); + } else { + *bytes_read = read_val; + + /* Getting 0 from read() means EOF! */ + if (read_val == 0) { + return GNOME_VFS_ERROR_EOF; + } + } + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_write (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gconstpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_written, + GnomeVFSContext *context) +{ + FileHandle *file_handle; + gint write_val; + + g_return_val_if_fail (method_handle != NULL, GNOME_VFS_ERROR_INTERNAL); + + file_handle = (FileHandle *) method_handle; + + do { + write_val = write (file_handle->fd, buffer, num_bytes); + } while (write_val == -1 + && errno == EINTR + && ! gnome_vfs_context_check_cancellation (context)); + + if (write_val == -1) { + *bytes_written = 0; + return gnome_vfs_result_from_errno (); + } else { + *bytes_written = write_val; + return GNOME_VFS_OK; + } +} + + +static gint +seek_position_to_unix (GnomeVFSSeekPosition position) +{ + switch (position) { + case GNOME_VFS_SEEK_START: + return SEEK_SET; + case GNOME_VFS_SEEK_CURRENT: + return SEEK_CUR; + case GNOME_VFS_SEEK_END: + return SEEK_END; + default: + return SEEK_SET; /* bogus */ + } +} + +static GnomeVFSResult +do_seek (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSSeekPosition whence, + GnomeVFSFileOffset offset, + GnomeVFSContext *context) +{ + FileHandle *file_handle; + gint lseek_whence; + + file_handle = (FileHandle *) method_handle; + lseek_whence = seek_position_to_unix (whence); + + if (lseek (file_handle->fd, offset, lseek_whence) == -1) { + if (errno == ESPIPE) { + return GNOME_VFS_ERROR_NOT_SUPPORTED; + } else { + return gnome_vfs_result_from_errno (); + } + } + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_tell (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileOffset *offset_return) +{ + FileHandle *file_handle; + off_t offset; + + file_handle = (FileHandle *) method_handle; + + offset = lseek (file_handle->fd, 0, SEEK_CUR); + if (offset == -1) { + if (errno == ESPIPE) { + return GNOME_VFS_ERROR_NOT_SUPPORTED; + } else { + return gnome_vfs_result_from_errno (); + } + } + + *offset_return = offset; + return GNOME_VFS_OK; +} + + +static GnomeVFSResult +do_truncate_handle (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileSize where, + GnomeVFSContext *context) +{ + FileHandle *file_handle; + + g_return_val_if_fail (method_handle != NULL, GNOME_VFS_ERROR_INTERNAL); + + file_handle = (FileHandle *) method_handle; + + if (ftruncate (file_handle->fd, where) == 0) { + return GNOME_VFS_OK; + } else { + switch (errno) { + case EBADF: + case EROFS: + return GNOME_VFS_ERROR_READ_ONLY; + case EINVAL: + return GNOME_VFS_ERROR_NOT_SUPPORTED; + default: + return GNOME_VFS_ERROR_GENERIC; + } + } +} + +static GnomeVFSResult +get_stat_info_from_handle (GnomeVFSFileInfo *file_info, + FileHandle *handle, + GnomeVFSFileInfoOptions options, + struct stat *statptr) +{ + struct stat statbuf; + + if (statptr == NULL) { + statptr = &statbuf; + } + + if (fstat (handle->fd, statptr) != 0) { + return gnome_vfs_result_from_errno (); + } + + gnome_vfs_stat_to_file_info (file_info, statptr); + GNOME_VFS_FILE_INFO_SET_LOCAL (file_info, TRUE); + + return GNOME_VFS_OK; +} + +/* MIME detection code. */ +static void +get_mime_type (GnomeVFSFileInfo *info, + GnomeVFSFileInfoOptions options, + struct stat *stat_buffer) +{ + const char *mime_type; + + mime_type = NULL; + if ((options & GNOME_VFS_FILE_INFO_FOLLOW_LINKS) == 0 + && (info->type == GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK)) { + /* we are a symlink and aren't asked to follow - + * return the type for a symlink + */ + mime_type = "x-special/symlink"; + } else { + mime_type = gnome_vfs_get_file_mime_type (NULL, stat_buffer, + (options & GNOME_VFS_FILE_INFO_FORCE_FAST_MIME_TYPE) != 0); + } + + g_assert (mime_type); + info->mime_type = g_strdup (mime_type); + info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; +} + +static GnomeVFSResult +do_get_file_info_from_handle (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + FileHandle *file_handle; + struct stat statbuf; + GnomeVFSResult result; + + file_handle = (FileHandle *) method_handle; + + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_NONE; + + result = get_stat_info_from_handle (file_info, file_handle, + options, &statbuf); + if (result != GNOME_VFS_OK) { + return result; + } + + if (options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE) { + get_mime_type (file_info, options, &statbuf); + } + + return GNOME_VFS_OK; +} + +static gboolean +do_is_local (GnomeVFSMethod *method, + const GnomeVFSURI *uri) +{ + return TRUE; +} + +static GnomeVFSMethod method = { + sizeof (GnomeVFSMethod), + NULL, /* do_open */ + NULL, /* do_create */ + do_close, + do_read, + do_write, + do_seek, + do_tell, + do_truncate_handle, + NULL, /* do_open_directory */ + NULL, /* do_close_directory */ + NULL, /* do_read_directory */ + NULL, /* do_get_file_info */ + do_get_file_info_from_handle, + do_is_local, + NULL, /* do_make_directory */ + NULL, /* do_remove_directory */ + NULL, /* do_move */ + NULL, /* do_unlink */ + NULL, /* do_check_same_fs */ + NULL, /* do_set_file_info */ + NULL, /* do_truncate */ + NULL, /* do_find_directory */ + NULL, /* do_create_symbolic_link */ + NULL, /* do_monitor_add */ + NULL, /* do_monitor_cancel */ +}; + +static GnomeVFSOpenMode +get_open_mode (gint filedes) +{ + int flags; + + flags = fcntl(filedes, F_GETFL); + if (flags & O_RDONLY) { + return GNOME_VFS_OPEN_READ; + } else if (flags & O_WRONLY) { + return GNOME_VFS_OPEN_WRITE; + } else if (flags & O_RDWR) { + return (GNOME_VFS_OPEN_READ | GNOME_VFS_OPEN_WRITE); + } + + return GNOME_VFS_OPEN_READ; /* bogus */ +} + +/** + * gnome_vfs_open_fs: + * @handle: A pointer to a pointer to a GnomeVFSHandle object + * @filedes: a UNIX file descriptor + * + * Converts an open unix file descript into a GnomeVFSHandle that + * can be used with the normal GnomeVFS file operations. When the + * handle is closed the file descriptor will also be closed. + * + * Return Value: %GNOME_VFS_OK if the open was ok, a suitable error otherwise. + * + * Since 2.2 + **/ + +GnomeVFSResult +gnome_vfs_open_fd (GnomeVFSHandle **handle, int filedes) +{ + GnomeVFSURI* uri; + FileHandle* file_handle; + GnomeVFSOpenMode open_mode; + + g_return_val_if_fail(handle != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + uri = create_anonymous_uri (&method); + + open_mode = get_open_mode (filedes); + + file_handle = file_handle_new (uri, filedes); + + *handle = _gnome_vfs_handle_new (uri, (GnomeVFSMethodHandle*)file_handle, open_mode); + if (!handle) { + return GNOME_VFS_ERROR_INTERNAL; + } + + return GNOME_VFS_OK; +} + diff --git a/libgnomevfs/gnome-vfs-ops.c b/libgnomevfs/gnome-vfs-ops.c new file mode 100644 index 0000000..b14d4df --- /dev/null +++ b/libgnomevfs/gnome-vfs-ops.c @@ -0,0 +1,811 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-ops.c - Synchronous operations for the GNOME Virtual File + System. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli */ + +#include +#include "gnome-vfs-ops.h" +#include "gnome-vfs-monitor-private.h" +#include "gnome-vfs-cancellable-ops.h" +#include "gnome-vfs-handle-private.h" +#include + +/** + * gnome_vfs_open: + * @handle: A pointer to a pointer to a GnomeVFSHandle object + * @text_uri: String representing the URI to open + * @open_mode: Open mode + * + * Open @text_uri according to mode @open_mode. On return, @handle will then + * contain a pointer to a handle for the open file. + * + * Return value: An integer representing the result of the operation + **/ +GnomeVFSResult +gnome_vfs_open (GnomeVFSHandle **handle, + const gchar *text_uri, + GnomeVFSOpenMode open_mode) +{ + GnomeVFSURI *uri; + GnomeVFSResult result; + + g_return_val_if_fail (handle != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail (text_uri != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + uri = gnome_vfs_uri_new (text_uri); + if (uri == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + result = gnome_vfs_open_uri (handle, uri, open_mode); + + gnome_vfs_uri_unref (uri); + + return result; +} + +/** + * gnome_vfs_open_uri: + * @handle: A pointer to a pointer to a GnomeVFSHandle object + * @uri: URI to open + * @open_mode: Open mode + * + * Open @uri according to mode @open_mode. On return, @handle will then + * contain a pointer to a handle for the open file. + * + * Return value: An integer representing the result of the operation + **/ +GnomeVFSResult +gnome_vfs_open_uri (GnomeVFSHandle **handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode open_mode) +{ + return gnome_vfs_open_uri_cancellable (handle, uri, open_mode, NULL); +} + +/** + * gnome_vfs_create: + * @handle: A pointer to a pointer to a GnomeVFSHandle object + * @text_uri: String representing the URI to create + * @open_mode: mode to leave the file opened in after creation (or %GNOME_VFS_OPEN_MODE_NONE + * to leave the file closed after creation) + * @exclusive: Whether the file should be created in "exclusive" mode: + * i.e. if this flag is nonzero, operation will fail if a file with the + * same name already exists. + * @perm: Bitmap representing the permissions for the newly created file + * (Unix style). + * + * Create @uri according to mode @open_mode. On return, @handle will then + * contain a pointer to a handle for the open file. + * + * Return value: An integer representing the result of the operation + **/ +GnomeVFSResult +gnome_vfs_create (GnomeVFSHandle **handle, + const gchar *text_uri, + GnomeVFSOpenMode open_mode, + gboolean exclusive, + guint perm) +{ + GnomeVFSURI *uri; + GnomeVFSResult result; + + g_return_val_if_fail (handle != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail (text_uri != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + uri = gnome_vfs_uri_new (text_uri); + if (uri == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + result = gnome_vfs_create_uri (handle, uri, open_mode, exclusive, perm); + + gnome_vfs_uri_unref (uri); + + return result; +} + +/** + * gnome_vfs_create_uri: + * @handle: A pointer to a pointer to a GnomeVFSHandle object + * @uri: URI for the file to create + * @open_mode: Open mode + * @exclusive: Whether the file should be created in "exclusive" mode: + * i.e. if this flag is nonzero, operation will fail if a file with the + * same name already exists. + * @perm: Bitmap representing the permissions for the newly created file + * (Unix style). + * + * Create @uri according to mode @open_mode. On return, @handle will then + * contain a pointer to a handle for the open file. + * + * Return value: An integer representing the result of the operation + **/ +GnomeVFSResult +gnome_vfs_create_uri (GnomeVFSHandle **handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode open_mode, + gboolean exclusive, + guint perm) +{ + return gnome_vfs_create_uri_cancellable (handle, uri, open_mode, + exclusive, perm, NULL); +} + +/** + * gnome_vfs_close: + * @handle: A pointer to a GnomeVFSHandle object + * + * Close file associated with @handle. + * + * Return value: An integer representing the result of the operation. + **/ +GnomeVFSResult +gnome_vfs_close (GnomeVFSHandle *handle) +{ + return gnome_vfs_close_cancellable (handle, NULL); +} + +/** + * gnome_vfs_read: + * @handle: Handle of the file to read data from + * @buffer: Pointer to a buffer that must be at least @bytes bytes large + * @bytes: Number of bytes to read + * @bytes_read: Pointer to a variable that will hold the number of bytes + * effectively read on return. + * + * Read @bytes from @handle. As with Unix system calls, the number of + * bytes read can effectively be less than @bytes on return and will be + * stored in @bytes_read. + * + * Return value: An integer representing the result of the operation + **/ +GnomeVFSResult +gnome_vfs_read (GnomeVFSHandle *handle, + gpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_read) +{ + return gnome_vfs_read_cancellable (handle, buffer, bytes, bytes_read, + NULL); +} + +/** + * gnome_vfs_write: + * @handle: Handle of the file to write data to + * @buffer: Pointer to the buffer containing the data to be written + * @bytes: Number of bytes to write + * @bytes_written: Pointer to a variable that will hold the number of bytes + * effectively written on return. + * + * Write @bytes into the file opened through @handle. As with Unix system + * calls, the number of bytes written can effectively be less than @bytes on + * return and will be stored in @bytes_written. + * + * Return value: An integer representing the result of the operation + **/ +GnomeVFSResult +gnome_vfs_write (GnomeVFSHandle *handle, + gconstpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_written) +{ + return gnome_vfs_write_cancellable (handle, buffer, bytes, + bytes_written, NULL); +} + +/** + * gnome_vfs_seek: + * @handle: Handle for which the current position must be changed + * @whence: Integer value representing the starting position + * @offset: Number of bytes to skip from the position specified by @whence + * (a positive value means to move forward; a negative one to move backwards) + * + * Set the current position for reading/writing through @handle. + * + * Return value: + **/ +GnomeVFSResult +gnome_vfs_seek (GnomeVFSHandle *handle, + GnomeVFSSeekPosition whence, + GnomeVFSFileOffset offset) +{ + return gnome_vfs_seek_cancellable (handle, whence, offset, NULL); +} + +/** + * gnome_vfs_tell: + * @handle: Handle for which the current position must be retrieved + * @offset_return: Pointer to a variable that will contain the current position + * on return + * + * Return the current position on @handle. This is the point in the file + * pointed to by handle that reads and writes will occur on. + * + * Return value: An integer representing the result of the operation + **/ +GnomeVFSResult +gnome_vfs_tell (GnomeVFSHandle *handle, + GnomeVFSFileSize *offset_return) +{ + g_return_val_if_fail (handle != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + return _gnome_vfs_handle_do_tell (handle, offset_return); +} + +/** + * gnome_vfs_get_file_info: + * @text_uri: URI of the file for which information will be retrieved + * @info: Pointer to a GnomeVFSFileInfo object that will hold the information + * for the file on return + * @options: Options for retrieving file information + * to retrieve for the file + * + * Retrieve information about @text_uri. The information will be stored in + * @info. + * + * Return value: An integer representing the result of the operation + **/ +GnomeVFSResult +gnome_vfs_get_file_info (const gchar *text_uri, + GnomeVFSFileInfo *info, + GnomeVFSFileInfoOptions options) +{ + GnomeVFSURI *uri; + GnomeVFSResult result; + + uri = gnome_vfs_uri_new (text_uri); + + if (uri == NULL) + return GNOME_VFS_ERROR_NOT_SUPPORTED; + + result = gnome_vfs_get_file_info_uri(uri, info, options); + gnome_vfs_uri_unref (uri); + + return result; +} + +/** + * gnome_vfs_get_file_info_uri: + * @uri: URI of the file for which information will be retrieved + * @info: Pointer to a GnomeVFSFileInfo object that will hold the information + * for the file on return + * @options: Options for retrieving file information + * to retrieve for the file + * + * Retrieve information about @text_uri. The information will be stored in + * @info. + * + * Return value: An integer representing the result of the operation + **/ +GnomeVFSResult +gnome_vfs_get_file_info_uri (GnomeVFSURI *uri, + GnomeVFSFileInfo *info, + GnomeVFSFileInfoOptions options) +{ + return gnome_vfs_get_file_info_uri_cancellable (uri, + info, + options, + NULL); +} + +/** + * gnome_vfs_get_file_info_from_handle: + * @handle: Handle of the file for which information must be retrieved + * @info: Pointer to a GnomeVFSFileInfo object that will hold the information + * for the file on return + * @options: Options for retrieving file information + * to retrieve for the file + * + * Retrieve information about an open file. The information will be stored in + * @info. + * + * Return value: An integer representing the result of the operation + **/ +GnomeVFSResult +gnome_vfs_get_file_info_from_handle (GnomeVFSHandle *handle, + GnomeVFSFileInfo *info, + GnomeVFSFileInfoOptions options) +{ + return gnome_vfs_get_file_info_from_handle_cancellable (handle, info, + options, + NULL); +} + +/** + * gnome_vfs_truncate: + * @text_uri: URI of the file to be truncated + * @length: length of the new file at @text_uri + * + * Truncate the file at @text_uri to @length bytes. + * + * Return value: An integer representing the result of the operation + **/ +GnomeVFSResult +gnome_vfs_truncate (const char *text_uri, GnomeVFSFileSize length) +{ + GnomeVFSURI *uri; + GnomeVFSResult result; + + uri = gnome_vfs_uri_new (text_uri); + + if (uri == NULL) + return GNOME_VFS_ERROR_NOT_SUPPORTED; + + result = gnome_vfs_truncate_uri(uri, length); + gnome_vfs_uri_unref (uri); + + return result; +} + + +/** + * gnome_vfs_truncate_uri: + * @uri: URI of the file to be truncated + * @length: length of the new file at @uri + * + * Truncate the file at @uri to be only @length bytes. Data past @length + * bytes will be discarded. + * + * Return value: An integer representing the result of the operation + **/ +GnomeVFSResult +gnome_vfs_truncate_uri (GnomeVFSURI *uri, GnomeVFSFileSize length) +{ + return gnome_vfs_truncate_uri_cancellable(uri, length, NULL); +} + +/** + * gnome_vfs_truncate_handle: + * @handle: a handle to the file to be truncated + * @length: length of the new file the handle is open to + * + * Truncate the file pointed to be @handle to be only @length bytes. + * Data past @length bytes will be discarded. + * + * Return value: An integer representing the result of the operation + **/ +GnomeVFSResult +gnome_vfs_truncate_handle (GnomeVFSHandle *handle, GnomeVFSFileSize length) +{ + return gnome_vfs_truncate_handle_cancellable(handle, length, NULL); +} + +/** + * gnome_vfs_make_directory_for_uri: + * @uri: URI of the directory to be created + * @perm: Unix-style permissions for the newly created directory + * + * Create a directory at @uri. Only succeeds if a file or directory + * does not already exist at @uri. + * + * Return value: An integer representing the result of the operation + **/ +GnomeVFSResult +gnome_vfs_make_directory_for_uri (GnomeVFSURI *uri, + guint perm) +{ + return gnome_vfs_make_directory_for_uri_cancellable (uri, perm, NULL); +} + +/** + * gnome_vfs_make_directory: + * @text_uri: URI of the directory to be created + * @perm: Unix-style permissions for the newly created directory + * + * Create @text_uri as a directory. + * + * Return value: An integer representing the result of the operation + **/ +GnomeVFSResult +gnome_vfs_make_directory (const gchar *text_uri, + guint perm) +{ + GnomeVFSResult result; + GnomeVFSURI *uri; + + g_return_val_if_fail (text_uri != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + uri = gnome_vfs_uri_new (text_uri); + if (uri == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + result = gnome_vfs_make_directory_for_uri (uri, perm); + + gnome_vfs_uri_unref (uri); + + return result; +} + +/** + * gnome_vfs_remove_directory_from_uri: + * @uri: URI of the directory to be removed + * + * Remove @uri. @uri must be an empty directory. + * + * Return value: An integer representing the result of the operation + **/ +GnomeVFSResult +gnome_vfs_remove_directory_from_uri (GnomeVFSURI *uri) +{ + return gnome_vfs_remove_directory_from_uri_cancellable (uri, NULL); +} + +/** + * gnome_vfs_remove_directory: + * @text_uri: URI of the directory to be removed + * + * Remove @text_uri. @text_uri must be an empty directory. + * + * Return value: An integer representing the result of the operation + **/ +GnomeVFSResult +gnome_vfs_remove_directory (const gchar *text_uri) +{ + GnomeVFSResult result; + GnomeVFSURI *uri; + + g_return_val_if_fail (text_uri != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + uri = gnome_vfs_uri_new (text_uri); + if (uri == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + result = gnome_vfs_remove_directory_from_uri (uri); + + gnome_vfs_uri_unref (uri); + + return result; +} + +/** + * gnome_vfs_unlink_from_uri: + * @uri: URI of the file to be unlinked + * + * Unlink @uri (i.e. delete the file). + * + * Return value: An integer representing the result of the operation + **/ +GnomeVFSResult +gnome_vfs_unlink_from_uri (GnomeVFSURI *uri) +{ + return gnome_vfs_unlink_from_uri_cancellable (uri, NULL); +} + +/** + * gnome_vfs_create_symbolic_link: + * @uri: URI to create a link at + * @target_reference: URI "reference" to point the link to (URI or relative path) + * + * Creates a symbolic link, or eventually, a URI link (as necessary) + * at @uri pointing to @target_reference + * + * Return value: An integer representing the result of the operation + **/ +GnomeVFSResult +gnome_vfs_create_symbolic_link (GnomeVFSURI *uri, const gchar *target_reference) +{ + return gnome_vfs_create_symbolic_link_cancellable (uri, target_reference, NULL); +} + +/** + * gnome_vfs_unlink: + * @text_uri: URI of the file to be unlinked + * + * Unlink @text_uri (i.e. delete the file). + * + * Return value: An integer representing the result of the operation + **/ +GnomeVFSResult +gnome_vfs_unlink (const gchar *text_uri) +{ + GnomeVFSResult result; + GnomeVFSURI *uri; + + g_return_val_if_fail (text_uri != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + uri = gnome_vfs_uri_new (text_uri); + if (uri == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + result = gnome_vfs_unlink_from_uri (uri); + + gnome_vfs_uri_unref (uri); + + return result; +} + +/** + * gnome_vfs_move_uri: + * @old_uri: Source URI + * @new_uri: Destination URI + * @force_replace: If %TRUE, move target to @new_uri even if there + * is already a file at @new_uri. If there is a file, it will be discarded. + * + * Move a file from URI @old_uri to @new_uri. This will only work if @old_uri + * and @new_uri are on the same file system. Otherwise, it is necessary + * to use the more general %gnome_vfs_xfer_uri() function. + * + * Return value: An integer representing the result of the operation. + **/ +GnomeVFSResult +gnome_vfs_move_uri (GnomeVFSURI *old_uri, + GnomeVFSURI *new_uri, + gboolean force_replace) +{ + return gnome_vfs_move_uri_cancellable (old_uri, new_uri, + force_replace, NULL); +} + +/** + * gnome_vfs_move: + * @old_text_uri: Source URI + * @new_text_uri: Destination URI + * @force_replace: if %TRUE, perform the operation even if it unlinks an existing + * file at @new_text_uri + * + * Move a file from URI @old_text_uri to @new_text_uri. This will only work + * if @old_text_uri and @new_text_uri are on the same file system. Otherwise, + * it is necessary to use the more general %gnome_vfs_xfer_uri() function. + * + * Return value: An integer representing the result of the operation. + **/ +GnomeVFSResult +gnome_vfs_move (const gchar *old_text_uri, + const gchar *new_text_uri, + gboolean force_replace) +{ + GnomeVFSURI *old_uri, *new_uri; + GnomeVFSResult retval; + + g_return_val_if_fail (old_text_uri != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail (new_text_uri != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + old_uri = gnome_vfs_uri_new (old_text_uri); + if (old_uri == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + new_uri = gnome_vfs_uri_new (new_text_uri); + if (new_uri == NULL) { + gnome_vfs_uri_unref (old_uri); + return GNOME_VFS_ERROR_INVALID_URI; + } + + retval = gnome_vfs_move_uri (old_uri, new_uri, force_replace); + + gnome_vfs_uri_unref (old_uri); + gnome_vfs_uri_unref (new_uri); + + return retval; +} + +/** + * gnome_vfs_check_same_fs_uris: + * @source_uri: A URI + * @target_uri: Another URI + * @same_fs_return: Pointer to a boolean variable which will be set to %TRUE + * if @source_uri and @target_uri are on the same file system on return. + * + * Check if @source_uri and @target_uri are on the same file system. + * + * Return value: An integer representing the result of the operation. + **/ +GnomeVFSResult +gnome_vfs_check_same_fs_uris (GnomeVFSURI *source_uri, + GnomeVFSURI *target_uri, + gboolean *same_fs_return) +{ + return gnome_vfs_check_same_fs_uris_cancellable (source_uri, + target_uri, + same_fs_return, + NULL); +} + +/** + * gnome_vfs_check_same_fs: + * @source: A URI + * @target: Another URI + * @same_fs_return: Pointer to a boolean variable which will be set to %TRUE + * + * Return %TRUE if @source and @target are on the same file system. + * + * Return value: An integer representing the result of the operation. + **/ +GnomeVFSResult +gnome_vfs_check_same_fs (const gchar *source, + const gchar *target, + gboolean *same_fs_return) +{ + GnomeVFSURI *a_uri, *b_uri; + GnomeVFSResult retval; + + g_return_val_if_fail (source != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail (target != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail (same_fs_return != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + *same_fs_return = FALSE; + + a_uri = gnome_vfs_uri_new (source); + if (a_uri == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + b_uri = gnome_vfs_uri_new (target); + if (b_uri == NULL) { + gnome_vfs_uri_unref (a_uri); + return GNOME_VFS_ERROR_INVALID_URI; + } + + retval = gnome_vfs_check_same_fs_uris (a_uri, b_uri, same_fs_return); + + gnome_vfs_uri_unref (a_uri); + gnome_vfs_uri_unref (b_uri); + + return retval; +} + +/** + * gnome_vfs_set_file_info_uri: + * @uri: A URI + * @info: Information that must be set for the file + * @mask: Bit mask representing which fields of @info need to be set + * + * Set file information for @uri; only the information for which the + * corresponding bit in @mask is set is actually modified. + * + * Return value: An integer representing the result of the operation. + **/ +GnomeVFSResult +gnome_vfs_set_file_info_uri (GnomeVFSURI *uri, + GnomeVFSFileInfo *info, + GnomeVFSSetFileInfoMask mask) +{ + return gnome_vfs_set_file_info_cancellable (uri, info, mask, NULL); +} + +/** + * gnome_vfs_set_file_info: + * @text_uri: A URI + * @info: Information that must be set for the file + * @mask: Bit mask representing which fields of @info need to be set + * + * Set file information for @uri; only the information for which the + * corresponding bit in @mask is set is actually modified. + * + * Return value: An integer representing the result of the operation. + **/ +GnomeVFSResult +gnome_vfs_set_file_info (const gchar *text_uri, + GnomeVFSFileInfo *info, + GnomeVFSSetFileInfoMask mask) +{ + GnomeVFSURI *uri; + GnomeVFSResult result; + + uri = gnome_vfs_uri_new (text_uri); + if (uri == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + result = gnome_vfs_set_file_info_uri (uri, info, mask); + + gnome_vfs_uri_unref (uri); + + return result; +} + +/** + * gnome_vfs_uri_exists: + * @uri: A URI + * + * Check if the URI points to an existing entity. + * + * Return value: TRUE if URI exists. + **/ +gboolean +gnome_vfs_uri_exists (GnomeVFSURI *uri) +{ + GnomeVFSFileInfo *info; + GnomeVFSResult result; + + info = gnome_vfs_file_info_new (); + result = gnome_vfs_get_file_info_uri (uri, info, GNOME_VFS_FILE_INFO_DEFAULT); + gnome_vfs_file_info_unref (info); + + return result == GNOME_VFS_OK; +} + +/** + * gnome_vfs_monitor_add: + * @handle: after the call, @handle will be a pointer to an operation handle + * @text_uri: URI to monitor + * @monitor_type: add a directory or file monitor + * @callback: function to call when the monitor is tripped + * @user_data: data to pass to @callback + * + * Watch the file or directory at @text_uri for changes (or the creation/deletion of the file) + * and call @callback when there is a change. If a directory monitor is added, @callback is + * notified when any file in the directory changes. + * + * Return value: an integer representing the success of the operation + **/ +GnomeVFSResult +gnome_vfs_monitor_add (GnomeVFSMonitorHandle **handle, + const gchar *text_uri, + GnomeVFSMonitorType monitor_type, + GnomeVFSMonitorCallback callback, + gpointer user_data) +{ + GnomeVFSURI *uri = gnome_vfs_uri_new (text_uri); + GnomeVFSResult result; + + if (uri == NULL) { + return GNOME_VFS_ERROR_INVALID_URI; + } + + if (!VFS_METHOD_HAS_FUNC(uri->method, monitor_add)) { + gnome_vfs_uri_unref (uri); + return GNOME_VFS_ERROR_NOT_SUPPORTED; + } + + result = _gnome_vfs_monitor_do_add (uri->method, handle, uri, + monitor_type, callback, + user_data); + + gnome_vfs_uri_unref (uri); + + return result; +} + +/** + * gnome_vfs_monitor_cancel: + * @handle: handle of the monitor to cancel + * + * Cancel the monitor pointed to be @handle. + * + * Return value: an integer representing the success of the operation + **/ +GnomeVFSResult +gnome_vfs_monitor_cancel (GnomeVFSMonitorHandle *handle) +{ + g_return_val_if_fail (handle != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + return _gnome_vfs_monitor_do_cancel (handle); +} + +/** + * gnome_vfs_file_control: + * @handle: handle of the file to affect + * @operation: The operation to execute + * @operation_data: The data needed to execute the operation + * + * Execute a backend dependent operation specified by the string @operation. + * This is typically used for specialized vfs backends that need additional + * operations that gnome-vfs doesn't have. Compare it to the unix call ioctl(). + * The format of @operation_data depends on the operation. Operation that are + * backend specific are normally namespaced by their module name. + * + * Return value: an integer representing the success of the operation + **/ +GnomeVFSResult +gnome_vfs_file_control (GnomeVFSHandle *handle, + const char *operation, + gpointer operation_data) +{ + return gnome_vfs_file_control_cancellable (handle, operation, operation_data, NULL); +} + diff --git a/libgnomevfs/gnome-vfs-ops.h b/libgnomevfs/gnome-vfs-ops.h new file mode 100644 index 0000000..7bdb1cf --- /dev/null +++ b/libgnomevfs/gnome-vfs-ops.h @@ -0,0 +1,146 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-ops.h - Synchronous operations for the GNOME Virtual File + System. + + Copyright (C) 1999, 2001 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli + Seth Nickell +*/ + +#ifndef GNOME_VFS_OPS_H +#define GNOME_VFS_OPS_H + +#include +#include +#include +#include + +G_BEGIN_DECLS + +GnomeVFSResult gnome_vfs_open (GnomeVFSHandle **handle, + const gchar *text_uri, + GnomeVFSOpenMode open_mode); + +GnomeVFSResult gnome_vfs_open_uri (GnomeVFSHandle **handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode open_mode); + +GnomeVFSResult gnome_vfs_create (GnomeVFSHandle **handle, + const gchar *text_uri, + GnomeVFSOpenMode open_mode, + gboolean exclusive, + guint perm); + +GnomeVFSResult gnome_vfs_create_uri (GnomeVFSHandle **handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode open_mode, + gboolean exclusive, + guint perm); + +GnomeVFSResult gnome_vfs_close (GnomeVFSHandle *handle); + +GnomeVFSResult gnome_vfs_read (GnomeVFSHandle *handle, + gpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_read); + +GnomeVFSResult gnome_vfs_write (GnomeVFSHandle *handle, + gconstpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_written); + +GnomeVFSResult gnome_vfs_seek (GnomeVFSHandle *handle, + GnomeVFSSeekPosition whence, + GnomeVFSFileOffset offset); + +GnomeVFSResult gnome_vfs_tell (GnomeVFSHandle *handle, + GnomeVFSFileSize *offset_return); + +GnomeVFSResult gnome_vfs_get_file_info (const gchar *text_uri, + GnomeVFSFileInfo *info, + GnomeVFSFileInfoOptions options); + +GnomeVFSResult gnome_vfs_get_file_info_uri (GnomeVFSURI *uri, + GnomeVFSFileInfo *info, + GnomeVFSFileInfoOptions options); + +GnomeVFSResult gnome_vfs_get_file_info_from_handle + (GnomeVFSHandle *handle, + GnomeVFSFileInfo *info, + GnomeVFSFileInfoOptions options); + +GnomeVFSResult gnome_vfs_truncate (const gchar *text_uri, + GnomeVFSFileSize length); +GnomeVFSResult gnome_vfs_truncate_uri (GnomeVFSURI *uri, + GnomeVFSFileSize length); +GnomeVFSResult gnome_vfs_truncate_handle (GnomeVFSHandle *handle, + GnomeVFSFileSize length); + +GnomeVFSResult gnome_vfs_make_directory_for_uri + (GnomeVFSURI *uri, guint perm); +GnomeVFSResult gnome_vfs_make_directory (const gchar *text_uri, + guint perm); + +GnomeVFSResult gnome_vfs_remove_directory_from_uri + (GnomeVFSURI *uri); +GnomeVFSResult gnome_vfs_remove_directory (const gchar *text_uri); + +GnomeVFSResult gnome_vfs_unlink_from_uri (GnomeVFSURI *uri); +GnomeVFSResult gnome_vfs_create_symbolic_link (GnomeVFSURI *uri, + const gchar *target_reference); +GnomeVFSResult gnome_vfs_unlink (const gchar *text_uri); + +GnomeVFSResult gnome_vfs_move_uri (GnomeVFSURI *old_uri, + GnomeVFSURI *new_uri, + gboolean force_replace); +GnomeVFSResult gnome_vfs_move (const gchar *old_text_uri, + const gchar *new_text_uri, + gboolean force_replace); + +GnomeVFSResult gnome_vfs_check_same_fs_uris (GnomeVFSURI *source_uri, + GnomeVFSURI *target_uri, + gboolean *same_fs_return); +GnomeVFSResult gnome_vfs_check_same_fs (const gchar *source, + const gchar *target, + gboolean *same_fs_return); + +gboolean gnome_vfs_uri_exists (GnomeVFSURI *uri); + +GnomeVFSResult gnome_vfs_set_file_info_uri (GnomeVFSURI *uri, + GnomeVFSFileInfo *info, + GnomeVFSSetFileInfoMask mask); +GnomeVFSResult gnome_vfs_set_file_info (const gchar *text_uri, + GnomeVFSFileInfo *info, + GnomeVFSSetFileInfoMask mask); + +GnomeVFSResult gnome_vfs_monitor_add (GnomeVFSMonitorHandle **handle, + const gchar *text_uri, + GnomeVFSMonitorType monitor_type, + GnomeVFSMonitorCallback callback, + gpointer user_data); + +GnomeVFSResult gnome_vfs_monitor_cancel (GnomeVFSMonitorHandle *handle); + +GnomeVFSResult gnome_vfs_file_control (GnomeVFSHandle *handle, + const char *operation, + gpointer operation_data); + +G_END_DECLS + +#endif /* GNOME_VFS_OPS_H */ diff --git a/libgnomevfs/gnome-vfs-parse-ls.c b/libgnomevfs/gnome-vfs-parse-ls.c new file mode 100644 index 0000000..85a6175 --- /dev/null +++ b/libgnomevfs/gnome-vfs-parse-ls.c @@ -0,0 +1,660 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-parse-ls.c - Routines for parsing output from the `ls' command. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: 1995 Miguel de Icaza + 1995 Jakub Jelinek + 1998 Pavel Machek + 1999 Cleanup by Ettore Perazzoli + + finduid, findgid are from GNU tar. */ + +#include +#include "gnome-vfs-parse-ls.h" + +#include "gnome-vfs-i18n.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef TUNMLEN +#define TUNMLEN 256 +#endif +#ifndef TGNMLEN +#define TGNMLEN 256 +#endif + + +/* FIXME bugzilla.eazel.com 1179: + * remove these globals. */ +static int saveuid = -993; +static char saveuname[TUNMLEN]; +static int my_uid = -993; + +static int savegid = -993; +static char savegname[TGNMLEN]; +static int my_gid = -993; + +#define myuid ( my_uid < 0? (my_uid = getuid ()): my_uid ) +#define mygid ( my_gid < 0? (my_gid = getgid ()): my_gid ) + +static int finduid (char *uname) +{ + struct passwd *pw; + + if (uname[0] != saveuname[0]/* Quick test w/o proc call */ + || 0 != strncmp (uname, saveuname, TUNMLEN)) { + strncpy (saveuname, uname, TUNMLEN); + pw = getpwnam (uname); + if (pw) { + saveuid = pw->pw_uid; + } else { + saveuid = myuid; + } + } + return saveuid; +} + +static int findgid (char *gname) +{ + struct group *gr; + + if (gname[0] != savegname[0]/* Quick test w/o proc call */ + || 0 != strncmp (gname, savegname, TUNMLEN)) { + strncpy (savegname, gname, TUNMLEN); + gr = getgrnam (gname); + if (gr) { + savegid = gr->gr_gid; + } else { + savegid = mygid; + } + } + return savegid; +} + + +/* FIXME bugzilla.eazel.com 1188: This is ugly. */ +#define MAXCOLS 30 + +static int +vfs_split_text (char *p, + char *columns[], + int column_ptr[]) +{ + char *original = p; + int numcols; + + for (numcols = 0; *p && numcols < MAXCOLS; numcols++) { + while (*p == ' ' || *p == '\r' || *p == '\n') { + *p = 0; + p++; + } + columns [numcols] = p; + column_ptr [numcols] = p - original; + while (*p && *p != ' ' && *p != '\r' && *p != '\n') + p++; + } + return numcols; +} + +static int +is_num (const char *s) +{ + if (!s || s[0] < '0' || s[0] > '9') + return 0; + return 1; +} + +static int +is_dos_date (char *str) +{ + if (strlen (str) == 8 && str[2] == str[5] && strchr ("\\-/", (int)str[2]) != NULL) + return 1; + + return 0; +} + +static int +is_week (char *str, struct tm *tim) +{ + static char *week = "SunMonTueWedThuFriSat"; + char *pos; + + if ((pos = strstr (week, str)) != NULL) { + if (tim != NULL) + tim->tm_wday = (pos - week)/3; + return 1; + } + return 0; +} + +static int +is_month (const char *str, struct tm *tim) +{ + static char *month = "JanFebMarAprMayJunJulAugSepOctNovDec"; + char *pos; + + if ((pos = strstr (month, str)) != NULL) { + if (tim != NULL) + tim->tm_mon = (pos - month)/3; + return 1; + } + return 0; +} + +static int +is_time (const char *str, struct tm *tim) +{ + char *p, *p2; + + if ((p = strchr (str, ':')) && (p2 = strrchr (str, ':'))) { + if (p != p2) { + if (sscanf (str, "%2d:%2d:%2d", + &tim->tm_hour, &tim->tm_min, &tim->tm_sec) + != 3) + return 0; + } + else { + if (sscanf (str, "%2d:%2d", + &tim->tm_hour, &tim->tm_min) + != 2) + return 0; + } + } + else + return 0; + + return 1; +} + +static int is_year (const char *str, struct tm *tim) +{ + long year; + + if (strchr (str,':')) + return 0; + + if (strlen (str) != 4) + return 0; + + if (sscanf (str, "%ld", &year) != 1) + return 0; + + if (year < 1900 || year > 3000) + return 0; + + tim->tm_year = (int) (year - 1900); + + return 1; +} + +/* + * FIXME bugzilla.eazel.com 1182: + * this is broken. Consider following entry: + * -rwx------ 1 root root 1 Aug 31 10:04 2904 1234 + * where "2904 1234" is filename. Well, this code decodes it as year :-(. + */ + +static int +vfs_parse_filetype (char c) +{ + switch (c) { + case 'd': + return S_IFDIR; + case 'b': + return S_IFBLK; + case 'c': + return S_IFCHR; + case 'l': + return S_IFLNK; + case 's': +#ifdef IS_IFSOCK /* And if not, we fall through to IFIFO, which is pretty + close. */ + return S_IFSOCK; +#endif + case 'p': + return S_IFIFO; + case 'm': + case 'n': /* Don't know what these are :-) */ + case '-': + case '?': + return S_IFREG; + default: + return -1; + } +} + +static int +vfs_parse_filemode (const char *p) +{ + /* converts rw-rw-rw- into 0666 */ + int res = 0; + + switch (*(p++)) { + case 'r': + res |= 0400; break; + case '-': + break; + default: + return -1; + } + + switch (*(p++)) { + case 'w': + res |= 0200; break; + case '-': + break; + default: + return -1; + } + + switch (*(p++)) { + case 'x': + res |= 0100; break; + case 's': + res |= 0100 | S_ISUID; break; + case 'S': + res |= S_ISUID; break; + case '-': + break; + default: + return -1; + } + + switch (*(p++)) { + case 'r': + res |= 0040; break; + case '-': + break; + default: + return -1; + } + + switch (*(p++)) { + case 'w': + res |= 0020; break; + case '-': + break; + default: + return -1; + } + + switch (*(p++)) { + case 'x': + res |= 0010; break; + case 's': + res |= 0010 | S_ISGID; break; + case 'l': + /* Solaris produces these */ + case 'S': + res |= S_ISGID; break; + case '-': + break; + default: + return -1; + } + + switch (*(p++)) { + case 'r': + res |= 0004; break; + case '-': + break; + default: + return -1; + } + + switch (*(p++)) { + case 'w': + res |= 0002; break; + case '-': + break; + default: + return -1; + } + + switch (*(p++)) { + case 'x': + res |= 0001; break; + case 't': + res |= 0001 | S_ISVTX; break; + case 'T': + res |= S_ISVTX; break; + case '-': + break; + default: + return -1; + } + + return res; +} + +static int +vfs_parse_filedate (int idx, + char *columns[], + time_t *t) +{ /* This thing parses from idx in columns[] array */ + + char *p; + struct tm tim; + int d[3]; + int got_year = 0; + int current_mon; + time_t now; + + /* Let's setup default time values */ + now = time (NULL); + tim = *localtime (&now); + current_mon = tim.tm_mon; + tim.tm_hour = 0; + tim.tm_min = 0; + tim.tm_sec = 0; + tim.tm_isdst = -1; /* Let mktime () try to guess correct dst offset */ + + p = columns [idx++]; + + /* We eat weekday name in case of extfs */ + if (is_week (p, &tim)) + p = columns [idx++]; + + /* Month name */ + if (is_month (p, &tim)) { + /* And we expect, it followed by day number */ + if (is_num (columns[idx])) + tim.tm_mday = (int)atol (columns [idx++]); + else + return 0; /* No day */ + + } else { + /* We usually expect: + Mon DD hh:mm + Mon DD YYYY + But in case of extfs we allow these date formats: + Mon DD YYYY hh:mm + Mon DD hh:mm YYYY + Wek Mon DD hh:mm:ss YYYY + MM-DD-YY hh:mm + where Mon is Jan-Dec, DD, MM, YY two digit day, month, year, + YYYY four digit year, hh, mm, ss two digit hour, minute + or second. */ + + /* Here just this special case with MM-DD-YY */ + if (is_dos_date (p)) { + p[2] = p[5] = '-'; + + if (sscanf (p, "%2d-%2d-%2d", &d[0], &d[1], &d[2]) == 3) { + /* We expect to get: + 1. MM-DD-YY + 2. DD-MM-YY + 3. YY-MM-DD + 4. YY-DD-MM */ + + /* Hmm... maybe, next time :)*/ + + /* At last, MM-DD-YY */ + d[0]--; /* Months are zerobased */ + /* Y2K madness */ + if (d[2] < 70) + d[2] += 100; + + tim.tm_mon = d[0]; + tim.tm_mday = d[1]; + tim.tm_year = d[2]; + got_year = 1; + } else + return 0; /* sscanf failed */ + } else + return 0; /* unsupported format */ + } + + /* Here we expect to find time and/or year */ + + if (is_num (columns[idx])) { + if (is_time (columns[idx], &tim) || (got_year = is_year (columns[idx], &tim))) { + idx++; + + /* This is a special case for ctime () or Mon DD YYYY hh:mm */ + if (is_num (columns[idx]) && + ((got_year = is_year (columns[idx], &tim)) || is_time (columns[idx], &tim))) + idx++; /* time & year or reverse */ + } /* only time or date */ + } + else + return 0; /* Nor time or date */ + + /* + * If the date is less than 6 months in the past, it is shown without year + * other dates in the past or future are shown with year but without time + * This does not check for years before 1900 ... I don't know, how + * to represent them at all + */ + if (!got_year && + current_mon < 6 && current_mon < tim.tm_mon && + tim.tm_mon - current_mon >= 6) + + tim.tm_year--; + + if ((*t = mktime (&tim)) < 0) + *t = 0; + return idx; +} + +int +gnome_vfs_parse_ls_lga (const char *p, + struct stat *s, + char **filename, + char **linkname) +{ + char *columns [MAXCOLS]; /* Points to the string in column n */ + int column_ptr [MAXCOLS]; /* Index from 0 to the starting positions of the columns */ + int idx, idx2, num_cols; + int i; + int nlink; + char *p_copy, *p_pristine; + + if (strncmp (p, "total", 5) == 0) + return 0; + + p_copy = g_strdup (p); + if ((i = vfs_parse_filetype (*(p++))) == -1) + goto error; + + s->st_mode = i; + if (*p == ' ') /* Notwell 4 */ + p++; + if (*p == '[') { + if (strlen (p) <= 8 || p [8] != ']') + goto error; + /* Should parse here the Notwell permissions :) */ + if (S_ISDIR (s->st_mode)) + s->st_mode |= (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR + | S_IXUSR | S_IXGRP | S_IXOTH); + else + s->st_mode |= (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR); + p += 9; + } else { + if ((i = vfs_parse_filemode (p)) == -1) + goto error; + s->st_mode |= i; + p += 9; + + /* This is for an extra ACL attribute (HP-UX) */ + if (*p == '+') + p++; + } + + g_free (p_copy); + p_copy = g_strdup (p); + p_pristine = g_strdup (p); + num_cols = vfs_split_text (p_copy, columns, column_ptr); + + nlink = atol (columns [0]); + if (nlink < 0) + goto error; + + s->st_nlink = nlink; + + if (!is_num (columns[1])) + s->st_uid = finduid (columns [1]); + else + s->st_uid = (uid_t) atol (columns [1]); + + /* Mhm, the ls -lg did not produce a group field */ + for (idx = 3; idx <= 5; idx++) + if (is_month (columns [idx], NULL) + || is_week (columns [idx], NULL) + || is_dos_date (columns[idx])) + break; + + if (idx == 6 || (idx == 5 + && !S_ISCHR (s->st_mode) + && !S_ISBLK (s->st_mode))) + goto error; + + /* We don't have gid */ + if (idx == 3 || (idx == 4 && (S_ISCHR (s->st_mode) + || S_ISBLK (s->st_mode)))) + idx2 = 2; + else { + /* We have gid field */ + if (is_num (columns[2])) + s->st_gid = (gid_t) atol (columns [2]); + else + s->st_gid = findgid (columns [2]); + idx2 = 3; + } + + /* This is device */ + if (S_ISCHR (s->st_mode) || S_ISBLK (s->st_mode)) { + int maj, min; + + if (!is_num (columns[idx2]) + || sscanf (columns [idx2], " %d,", &maj) != 1) + goto error; + + if (!is_num (columns[++idx2]) + || sscanf (columns [idx2], " %d", &min) != 1) + goto error; + +#ifdef HAVE_ST_RDEV + s->st_rdev = ((maj & 0xff) << 8) | (min & 0xffff00ff); +#endif + s->st_size = 0; + + } else { + /* Common file size */ + if (!is_num (columns[idx2])) + goto error; + + s->st_size = (gsize) atol (columns [idx2]); +#ifdef HAVE_ST_RDEV + s->st_rdev = 0; +#endif + } + + idx = vfs_parse_filedate (idx, columns, &s->st_mtime); + if (!idx) + goto error; + /* Use resulting time value */ + s->st_atime = s->st_ctime = s->st_mtime; + s->st_dev = 0; + s->st_ino = 0; +#ifdef HAVE_ST_BLKSIZE + s->st_blksize = 512; +#endif +#ifdef HAVE_ST_BLOCKS + s->st_blocks = (s->st_size + 511) / 512; +#endif + + for (i = idx + 1, idx2 = 0; i < num_cols; i++ ) + if (strcmp (columns [i], "->") == 0) { + idx2 = i; + break; + } + + if (((S_ISLNK (s->st_mode) + || (num_cols == idx + 3 && s->st_nlink > 1))) /* Maybe a hardlink? + (in extfs) */ + && idx2) { + int p; + char *s; + + if (filename) { + s = g_strndup (p_copy + column_ptr [idx], + column_ptr [idx2] - column_ptr [idx] - 1); + *filename = s; + } + if (linkname) { + s = g_strdup (p_copy + column_ptr [idx2+1]); + p = strlen (s); + if (s [p-1] == '\r' || s [p-1] == '\n') + s [p-1] = 0; + if (s [p-2] == '\r' || s [p-2] == '\n') + s [p-2] = 0; + + *linkname = s; + } + } else { + /* Extract the filename from the string copy, not from the columns + * this way we have a chance of entering hidden directories like ". ." + */ + if (filename) { + /* + *filename = g_strdup (columns [idx++]); + */ + int p; + char *s; + + s = g_strdup (p_pristine + column_ptr [idx]); + p = strcspn (s, "\r\n"); + s[p] = '\0'; + + *filename = s; + } + if (linkname) + *linkname = NULL; + } + g_free (p_copy); + g_free (p_pristine); + return 1; + + error: + { + static int errorcount = 0; + + if (++errorcount < 5) + g_warning (_("Could not parse: %s"), p_copy); + else if (errorcount == 5) + g_warning (_("More parsing errors will be ignored.")); + } + + if (p_copy != p) /* Carefull! */ + g_free (p_copy); + return 0; +} diff --git a/libgnomevfs/gnome-vfs-parse-ls.h b/libgnomevfs/gnome-vfs-parse-ls.h new file mode 100644 index 0000000..663c8eb --- /dev/null +++ b/libgnomevfs/gnome-vfs-parse-ls.h @@ -0,0 +1,44 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-parse-ls.h - Routines for parsing output from the `ls' command. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: 1995 Miguel de Icaza + 1995 Jakub Jelinek + 1998 Pavel Machek + 1999 Cleanup by Ettore Perazzoli + + finduid, findgid are from GNU tar. */ + +#ifndef GNOME_VFS_PARSE_LS_H +#define GNOME_VFS_PARSE_LS_H + +#include + +#include + +G_BEGIN_DECLS + +struct stat; + +int gnome_vfs_parse_ls_lga (const char *p, struct stat *s, + char **filename, char **linkname); + +G_END_DECLS + +#endif /* GNOME_VFS_PARSE_LS_H */ diff --git a/libgnomevfs/gnome-vfs-private-utils.c b/libgnomevfs/gnome-vfs-private-utils.c new file mode 100644 index 0000000..b652ab3 --- /dev/null +++ b/libgnomevfs/gnome-vfs-private-utils.c @@ -0,0 +1,846 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-utils.c - Private utility functions for the GNOME Virtual + File System. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli + + `_gnome_vfs_canonicalize_pathname()' derived from code by Brian Fox and Chet + Ramey in GNU Bash, the Bourne Again SHell. Copyright (C) 1987, 1988, 1989, + 1990, 1991, 1992 Free Software Foundation, Inc. */ + +#include +#include "gnome-vfs-private-utils.h" + +#include "gnome-vfs-utils.h" +#include "gnome-vfs-cancellation.h" +#include "gnome-vfs-ops.h" +#include "gnome-vfs-uri.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define GCONF_URL_HANDLER_PATH "/desktop/gnome/url-handlers/" +#define GCONF_DEFAULT_TERMINAL_EXEC_PATH "/desktop/gnome/applications/terminal/exec" +#define GCONF_DEFAULT_TERMINAL_ARG_PATH "/desktop/gnome/applications/terminal/exec_arg" + +/* Check whether the node is IPv6 enabled.*/ +gboolean +_gnome_vfs_have_ipv6 () +{ +#ifdef ENABLE_IPV6 + int s; + + s = socket (AF_INET6, SOCK_STREAM, 0); + if (s != -1) { + close (s); + return TRUE; + } + +#endif + return FALSE; +} + +static int +find_next_slash (const char *path, int current_offset) +{ + const char *match; + + g_assert (current_offset <= strlen (path)); + + match = strchr (path + current_offset, GNOME_VFS_URI_PATH_CHR); + return match == NULL ? -1 : match - path; +} + +static int +find_slash_before_offset (const char *path, int to) +{ + int result; + int next_offset; + + result = -1; + next_offset = 0; + for (;;) { + next_offset = find_next_slash (path, next_offset); + if (next_offset < 0 || next_offset >= to) { + break; + } + result = next_offset; + next_offset++; + } + return result; +} + +static void +collapse_slash_runs (char *path, int from_offset) +{ + int i; + /* Collapse multiple `/'s in a row. */ + for (i = from_offset;; i++) { + if (path[i] != GNOME_VFS_URI_PATH_CHR) { + break; + } + } + + if (from_offset < i) { + strcpy (path + from_offset, path + i); + i = from_offset + 1; + } +} + +/* Canonicalize path, and return a new path. Do everything in situ. The new + path differs from path in: + + Multiple `/'s are collapsed to a single `/'. + Leading `./'s and trailing `/.'s are removed. + Non-leading `../'s and trailing `..'s are handled by removing + portions of the path. */ +gchar * +_gnome_vfs_canonicalize_pathname (gchar *path) +{ + int i, marker; + + if (path == NULL || strlen (path) == 0) { + return ""; + } + + /* Walk along path looking for things to compact. */ + for (i = 0, marker = 0;;) { + if (!path[i]) + break; + + /* Check for `../', `./' or trailing `.' by itself. */ + if (path[i] == '.') { + /* Handle trailing `.' by itself. */ + if (path[i + 1] == '\0') { + if (i > 1 && path[i - 1] == GNOME_VFS_URI_PATH_CHR) { + /* strip the trailing /. */ + path[i - 1] = '\0'; + } else { + /* convert path "/." to "/" */ + path[i] = '\0'; + } + break; + } + + /* Handle `./'. */ + if (path[i + 1] == GNOME_VFS_URI_PATH_CHR) { + strcpy (path + i, path + i + 2); + if (i == 0) { + /* don't leave leading '/' for paths that started + * as relative (.//foo) + */ + collapse_slash_runs (path, i); + marker = 0; + } + continue; + } + + /* Handle `../' or trailing `..' by itself. + * Remove the previous xxx/ part + */ + if (path[i + 1] == '.' + && (path[i + 2] == GNOME_VFS_URI_PATH_CHR + || path[i + 2] == '\0')) { + + /* ignore ../ at the beginning of a path */ + if (i != 0) { + marker = find_slash_before_offset (path, i - 1); + + /* Either advance past '/' or point to the first character */ + marker ++; + if (path [i + 2] == '\0' && marker > 1) { + /* If we are looking at a /.. at the end of the uri and we + * need to eat the last '/' too. + */ + marker--; + } + g_assert(marker < i); + + if (path[i + 2] == GNOME_VFS_URI_PATH_CHR) { + /* strip the entire ../ string */ + i++; + } + + strcpy (path + marker, path + i + 2); + i = marker; + } else { + i = 2; + if (path[i] == GNOME_VFS_URI_PATH_CHR) { + i++; + } + } + collapse_slash_runs (path, i); + continue; + } + } + + /* advance to the next '/' */ + i = find_next_slash (path, i); + + /* If we didn't find any slashes, then there is nothing left to do. */ + if (i < 0) { + break; + } + + marker = i++; + collapse_slash_runs (path, i); + } + return path; +} + +static glong +get_max_fds (void) +{ +#if defined _SC_OPEN_MAX + return sysconf (_SC_OPEN_MAX); +#elif defined RLIMIT_NOFILE + { + struct rlimit rlimit; + + if (getrlimit (RLIMIT_NOFILE, &rlimit) == 0) + return rlimit.rlim_max; + else + return -1; + } +#elif defined HAVE_GETDTABLESIZE + return getdtablesize(); +#else +#warning Cannot determine the number of available file descriptors + return 1024; /* bogus */ +#endif +} + +/* Close all the currrently opened file descriptors. */ +static void +shut_down_file_descriptors (void) +{ + glong i, max_fds; + + max_fds = get_max_fds (); + + for (i = 3; i < max_fds; i++) + close (i); +} + +pid_t +gnome_vfs_forkexec (const gchar *file_name, + const gchar * const argv[], + GnomeVFSProcessOptions options, + GnomeVFSProcessInitFunc init_func, + gpointer init_data) +{ + pid_t child_pid; + + child_pid = fork (); + if (child_pid == 0) { + if (init_func != NULL) + (* init_func) (init_data); + if (options & GNOME_VFS_PROCESS_SETSID) + setsid (); + if (options & GNOME_VFS_PROCESS_CLOSEFDS) + shut_down_file_descriptors (); + if (options & GNOME_VFS_PROCESS_USEPATH) + execvp (file_name, (char **) argv); + else + execv (file_name, (char **) argv); + _exit (1); + } + + return child_pid; +} + +/** + * gnome_vfs_process_run_cancellable: + * @file_name: Name of the executable to run + * @argv: NULL-terminated argument list + * @options: Options + * @cancellation: Cancellation object + * @return_value: Pointer to an integer that will contain the exit value + * on return. + * + * Run @file_name with argument list @argv, according to the specified + * @options. + * + * Return value: + **/ +GnomeVFSProcessResult +gnome_vfs_process_run_cancellable (const gchar *file_name, + const gchar * const argv[], + GnomeVFSProcessOptions options, + GnomeVFSCancellation *cancellation, + guint *exit_value) +{ + pid_t child_pid; + + child_pid = gnome_vfs_forkexec (file_name, argv, options, NULL, NULL); + if (child_pid == -1) + return GNOME_VFS_PROCESS_RUN_ERROR; + + while (1) { + pid_t pid; + int status; + + pid = waitpid (child_pid, &status, WUNTRACED); + if (pid == -1) { + if (errno != EINTR) + return GNOME_VFS_PROCESS_RUN_ERROR; + if (gnome_vfs_cancellation_check (cancellation)) { + *exit_value = 0; + return GNOME_VFS_PROCESS_RUN_CANCELLED; + } + } else if (pid == child_pid) { + if (WIFEXITED (status)) { + *exit_value = WEXITSTATUS (status); + return GNOME_VFS_PROCESS_RUN_OK; + } + if (WIFSIGNALED (status)) { + *exit_value = WTERMSIG (status); + return GNOME_VFS_PROCESS_RUN_SIGNALED; + } + if (WIFSTOPPED (status)) { + *exit_value = WSTOPSIG (status); + return GNOME_VFS_PROCESS_RUN_SIGNALED; + } + } + } + +} + +/** + * gnome_vfs_create_temp: + * @prefix: Prefix for the name of the temporary file + * @name_return: Pointer to a pointer that, on return, will point to + * the dynamically allocated name for the new temporary file created. + * @handle_return: Pointer to a variable that will hold a file handle for + * the new temporary file on return. + * + * Create a temporary file whose name is prefixed with @prefix, and return an + * open file handle for it in @*handle_return. + * + * Return value: An integer value representing the result of the operation + **/ +GnomeVFSResult +gnome_vfs_create_temp (const gchar *prefix, + gchar **name_return, + GnomeVFSHandle **handle_return) +{ + GnomeVFSHandle *handle; + GnomeVFSResult result; + gchar *name; + gint fd; + + while (1) { + name = g_strdup_printf("%sXXXXXX", prefix); + fd = mkstemp(name); + + if (fd < 0) + return GNOME_VFS_ERROR_INTERNAL; + + fchmod(fd, 0600); + close(fd); + + result = gnome_vfs_open + (&handle, name, + GNOME_VFS_OPEN_WRITE | GNOME_VFS_OPEN_READ); + + if (result == GNOME_VFS_OK) { + *name_return = name; + *handle_return = handle; + return GNOME_VFS_OK; + } + + if (result != GNOME_VFS_ERROR_FILE_EXISTS) { + *name_return = NULL; + *handle_return = NULL; + return result; + } + } +} + +/* The following comes from GNU Wget with minor changes by myself. + Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. */ + +/* Converts struct tm to time_t, assuming the data in tm is UTC rather + than local timezone (mktime assumes the latter). + + Contributed by Roger Beeman , with the help of + Mark Baushke and the rest of the Gurus at CISCO. */ +static time_t +mktime_from_utc (struct tm *t) +{ + time_t tl, tb; + + tl = mktime (t); + if (tl == -1) + return -1; + tb = mktime (gmtime (&tl)); + return (tl <= tb ? (tl + (tl - tb)) : (tl - (tb - tl))); +} + +/* Check whether the result of strptime() indicates success. + strptime() returns the pointer to how far it got to in the string. + The processing has been successful if the string is at `GMT' or + `+X', or at the end of the string. + + In extended regexp parlance, the function returns 1 if P matches + "^ *(GMT|[+-][0-9]|$)", 0 otherwise. P being NULL (a valid result of + strptime()) is considered a failure and 0 is returned. */ +static int +check_end (const gchar *p) +{ + if (!p) + return 0; + while (g_ascii_isspace (*p)) + ++p; + if (!*p + || (p[0] == 'G' && p[1] == 'M' && p[2] == 'T') + || ((p[0] == '+' || p[1] == '-') && g_ascii_isdigit (p[1]))) + return 1; + else + return 0; +} + +/* Convert TIME_STRING time to time_t. TIME_STRING can be in any of + the three formats RFC2068 allows the HTTP servers to emit -- + RFC1123-date, RFC850-date or asctime-date. Timezones are ignored, + and should be GMT. + + We use strptime() to recognize various dates, which makes it a + little bit slacker than the RFC1123/RFC850/asctime (e.g. it always + allows shortened dates and months, one-digit days, etc.). It also + allows more than one space anywhere where the specs require one SP. + The routine should probably be even more forgiving (as recommended + by RFC2068), but I do not have the time to write one. + + Return the computed time_t representation, or -1 if all the + schemes fail. + + Needless to say, what we *really* need here is something like + Marcus Hennecke's atotm(), which is forgiving, fast, to-the-point, + and does not use strptime(). atotm() is to be found in the sources + of `phttpd', a little-known HTTP server written by Peter Erikson. */ +gboolean +gnome_vfs_atotm (const gchar *time_string, + time_t *value_return) +{ + struct tm t; + + /* Roger Beeman says: "This function dynamically allocates struct tm + t, but does no initialization. The only field that actually + needs initialization is tm_isdst, since the others will be set by + strptime. Since strptime does not set tm_isdst, it will return + the data structure with whatever data was in tm_isdst to begin + with. For those of us in timezones where DST can occur, there + can be a one hour shift depending on the previous contents of the + data area where the data structure is allocated." */ + t.tm_isdst = -1; + + /* Note that under foreign locales Solaris strptime() fails to + recognize English dates, which renders this function useless. I + assume that other non-GNU strptime's are plagued by the same + disease. We solve this by setting only LC_MESSAGES in + i18n_initialize(), instead of LC_ALL. + + Another solution could be to temporarily set locale to C, invoke + strptime(), and restore it back. This is slow and dirty, + however, and locale support other than LC_MESSAGES can mess other + things, so I rather chose to stick with just setting LC_MESSAGES. + + Also note that none of this is necessary under GNU strptime(), + because it recognizes both international and local dates. */ + + /* NOTE: We don't use `%n' for white space, as OSF's strptime uses + it to eat all white space up to (and including) a newline, and + the function fails if there is no newline (!). + + Let's hope all strptime() implementations use ` ' to skip *all* + whitespace instead of just one (it works that way on all the + systems I've tested it on). */ + + /* RFC1123: Thu, 29 Jan 1998 22:12:57 */ + if (check_end (strptime (time_string, "%a, %d %b %Y %T", &t))) { + *value_return = mktime_from_utc (&t); + return TRUE; + } + + /* RFC850: Thu, 29-Jan-98 22:12:57 */ + if (check_end (strptime (time_string, "%a, %d-%b-%y %T", &t))) { + *value_return = mktime_from_utc (&t); + return TRUE; + } + + /* asctime: Thu Jan 29 22:12:57 1998 */ + if (check_end (strptime (time_string, "%a %b %d %T %Y", &t))) { + *value_return = mktime_from_utc (&t); + return TRUE; + } + + /* Failure. */ + return FALSE; +} + +/* _gnome_vfs_istr_has_prefix + * copy-pasted from Nautilus + */ +gboolean +_gnome_vfs_istr_has_prefix (const char *haystack, const char *needle) +{ + const char *h, *n; + char hc, nc; + + /* Eat one character at a time. */ + h = haystack == NULL ? "" : haystack; + n = needle == NULL ? "" : needle; + do { + if (*n == '\0') { + return TRUE; + } + if (*h == '\0') { + return FALSE; + } + hc = *h++; + nc = *n++; + hc = g_ascii_tolower (hc); + nc = g_ascii_tolower (nc); + } while (hc == nc); + return FALSE; +} + +/* _gnome_vfs_istr_has_suffix + * copy-pasted from Nautilus + */ +gboolean +_gnome_vfs_istr_has_suffix (const char *haystack, const char *needle) +{ + const char *h, *n; + char hc, nc; + + if (needle == NULL) { + return TRUE; + } + if (haystack == NULL) { + return needle[0] == '\0'; + } + + /* Eat one character at a time. */ + h = haystack + strlen (haystack); + n = needle + strlen (needle); + do { + if (n == needle) { + return TRUE; + } + if (h == haystack) { + return FALSE; + } + hc = *--h; + nc = *--n; + hc = g_ascii_tolower (hc); + nc = g_ascii_tolower (nc); + } while (hc == nc); + return FALSE; +} + +/** + * _gnome_vfs_use_handler_for_scheme: + * @scheme: the URI scheme + * + * Checks GConf to see if there is a URL handler + * defined for this scheme and if it is enabled. + * + * Return value: TRUE if handler is defined and enabled, + * FALSE otherwise. + * + * Since: 2.4 + */ +gboolean +_gnome_vfs_use_handler_for_scheme (const char *scheme) +{ + GConfClient *client; + gboolean ret; + char *path; + + g_return_val_if_fail (scheme != NULL, FALSE); + + if (!gconf_is_initialized ()) { + if (!gconf_init (0, NULL, NULL)) { + return FALSE; + } + } + + client = gconf_client_get_default (); + path = g_strconcat (GCONF_URL_HANDLER_PATH, scheme, "/enabled", NULL); + ret = gconf_client_get_bool (client, path, NULL); + + g_free (path); + g_object_unref (G_OBJECT (client)); + + return ret; +} + +/** + * _gnome_vfs_url_show_using_handler_with_env: + * @url: the url to show + * @envp: environment for the handler + * + * Same as gnome_url_show_using_handler except that the handler + * will be launched with the given environment. + * + * Return value: GNOME_VFS_OK on success. + * GNOME_VFS_ERROR_BAD_PAREMETER if the URL is invalid. + * GNOME_VFS_ERROR_NOT_SUPPORTED if no handler is defined. + * GNOME_VFS_ERROR_PARSE if the handler command can not be parsed. + * GNOME_VFS_ERROR_LAUNCH if the handler command can not be launched. + * GNOME_VFS_ERROR_INTERNAL for internal/GConf errors. + * + * Since: 2.4 + */ +GnomeVFSResult +_gnome_vfs_url_show_using_handler_with_env (const char *url, + char **envp) +{ + GConfClient *client; + char *path; + char *scheme; + char *template; + char **argv; + int argc; + int i; + gboolean ret; + + g_return_val_if_fail (url != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + scheme = gnome_vfs_get_uri_scheme (url); + + g_return_val_if_fail (scheme != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + if (!gconf_is_initialized ()) { + if (!gconf_init (0, NULL, NULL)) { + g_free (scheme); + return GNOME_VFS_ERROR_INTERNAL; + } + } + + client = gconf_client_get_default (); + path = g_strconcat (GCONF_URL_HANDLER_PATH, scheme, "/command", NULL); + template = gconf_client_get_string (client, path, NULL); + g_free (path); + + if (template == NULL) { + g_free (template); + g_free (scheme); + return GNOME_VFS_ERROR_NO_HANDLER; + } + + if (!g_shell_parse_argv (template, + &argc, + &argv, + NULL)) { + g_free (template); + g_free (scheme); + return GNOME_VFS_ERROR_PARSE; + } + + g_free (template); + + path = g_strconcat (GCONF_URL_HANDLER_PATH, scheme, "/needs_terminal", NULL); + if (gconf_client_get_bool (client, path, NULL)) { + if (!_gnome_vfs_prepend_terminal_to_vector (&argc, &argv)) { + g_free (path); + g_free (scheme); + g_strfreev (argv); + return GNOME_VFS_ERROR_INTERNAL; + } + } + g_free (path); + g_free (scheme); + + g_object_unref (G_OBJECT (client)); + + for (i = 0; i < argc; i++) { + char *arg; + + if (strcmp (argv[i], "%s") != 0) + continue; + + arg = argv[i]; + argv[i] = g_strdup (url); + g_free (arg); + } + + ret = g_spawn_async (NULL /* working directory */, + argv, + envp, + G_SPAWN_SEARCH_PATH /* flags */, + NULL /* child_setup */, + NULL /* data */, + NULL /* child_pid */, + NULL); + g_strfreev (argv); + + if (!ret) { + return GNOME_VFS_ERROR_LAUNCH; + } + + return GNOME_VFS_OK; +} + +/* This is a copy from libgnome, internalized here to avoid + strange dependency loops */ + +/** + * _gnome_vfs_prepend_terminal_to_vector: + * @argc: a pointer to the vector size + * @argv: a pointer to the vector + * + * Prepends a terminal (either the one configured as default in GnomeVFS + * or one of the common xterm emulators) to the passed in vector, modifying + * it in the process. The vector should be allocated with #g_malloc, as + * this will #g_free the original vector. Also all elements must + * have been allocated separately. That is the standard glib/GNOME way of + * doing vectors. If the integer that @argc points to is negative, the + * size will first be computed. Also note that passing in pointers to a vector + * that is empty, will just create a new vector for you. + * + * Return value: TRUE if successful, FALSE otherwise. + * + * Since: 2.4 + */ +gboolean +_gnome_vfs_prepend_terminal_to_vector (int *argc, + char ***argv) +{ + char **real_argv; + int real_argc; + int i, j; + char **term_argv = NULL; + int term_argc = 0; + GConfClient *client; + + char *terminal = NULL; + char **the_argv; + + g_return_val_if_fail (argc != NULL, FALSE); + g_return_val_if_fail (argv != NULL, FALSE); + + /* sanity */ + if(*argv == NULL) { + *argc = 0; + } + + the_argv = *argv; + + /* compute size if not given */ + if (*argc < 0) { + for (i = 0; the_argv[i] != NULL; i++) + ; + *argc = i; + } + + if (!gconf_is_initialized ()) { + if (!gconf_init (0, NULL, NULL)) { + return FALSE; + } + } + + client = gconf_client_get_default (); + terminal = gconf_client_get_string (client, GCONF_DEFAULT_TERMINAL_EXEC_PATH, NULL); + + if (terminal) { + gchar *exec_flag; + exec_flag = gconf_client_get_string (client, GCONF_DEFAULT_TERMINAL_ARG_PATH, NULL); + + if (exec_flag == NULL) { + term_argc = 1; + term_argv = g_new0 (char *, 2); + term_argv[0] = terminal; + term_argv[1] = NULL; + } else { + term_argc = 2; + term_argv = g_new0 (char *, 3); + term_argv[0] = terminal; + term_argv[1] = exec_flag; + term_argv[2] = NULL; + } + } + + g_object_unref (G_OBJECT (client)); + + if (term_argv == NULL) { + char *check; + + term_argc = 2; + term_argv = g_new0 (char *, 3); + + check = g_find_program_in_path ("gnome-terminal"); + if (check != NULL) { + term_argv[0] = check; + /* Note that gnome-terminal takes -x and + * as -e in gnome-terminal is broken we use that. */ + term_argv[1] = g_strdup ("-x"); + } else { + if (check == NULL) + check = g_find_program_in_path ("nxterm"); + if (check == NULL) + check = g_find_program_in_path ("color-xterm"); + if (check == NULL) + check = g_find_program_in_path ("rxvt"); + if (check == NULL) + check = g_find_program_in_path ("xterm"); + if (check == NULL) + check = g_find_program_in_path ("dtterm"); + if (check == NULL) { + check = g_strdup ("xterm"); + g_warning ("couldn't find a terminal, falling back to xterm"); + } + term_argv[0] = check; + term_argv[1] = g_strdup ("-e"); + } + } + + real_argc = term_argc + *argc; + real_argv = g_new (char *, real_argc + 1); + + for (i = 0; i < term_argc; i++) + real_argv[i] = term_argv[i]; + + for (j = 0; j < *argc; j++, i++) + real_argv[i] = (char *)the_argv[j]; + + real_argv[i] = NULL; + + g_free (*argv); + *argv = real_argv; + *argc = real_argc; + + /* we use g_free here as we sucked all the inner strings + * out from it into real_argv */ + g_free (term_argv); + + return TRUE; +} + diff --git a/libgnomevfs/gnome-vfs-private-utils.h b/libgnomevfs/gnome-vfs-private-utils.h new file mode 100644 index 0000000..2ee73ef --- /dev/null +++ b/libgnomevfs/gnome-vfs-private-utils.h @@ -0,0 +1,93 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-private-utils.h - Private utility functions for the GNOME Virtual + File System. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli */ + +#ifndef GNOME_VFS_PRIVATE_UTILS_H +#define GNOME_VFS_PRIVATE_UTILS_H + +/* You should not use calls in here outside GnomeVFS. The APIs in here may + * break even when the GnomeVFS APIs are otherwise frozen. + */ + +#include +#include +#include +#include + +G_BEGIN_DECLS + +gboolean _gnome_vfs_have_ipv6 (void); + +gchar *_gnome_vfs_canonicalize_pathname (char *path); +GnomeVFSResult gnome_vfs_remove_optional_escapes (char *escaped_uri); + +pid_t gnome_vfs_forkexec (const gchar *file_name, + const gchar * const argv[], + GnomeVFSProcessOptions options, + GnomeVFSProcessInitFunc init_func, + gpointer data); +GnomeVFSProcessRunResult + gnome_vfs_process_run_cancellable + (const gchar *file_name, + const gchar * const argv[], + GnomeVFSProcessOptions options, + GnomeVFSCancellation *cancellation, + guint *exit_value); + +GnomeVFSResult gnome_vfs_create_temp (const gchar *prefix, + gchar **name_return, + GnomeVFSHandle **handle_return); +gboolean gnome_vfs_atotm (const gchar *time_string, + time_t *value_return); + +GList *gnome_vfs_i18n_get_language_list + (const gchar *category_name); + +GnomeVFSURI *gnome_vfs_uri_new_private (const gchar *text_uri, + gboolean allow_unknown_method, + gboolean allow_unsafe_method, + gboolean allow_translate); + + +gboolean _gnome_vfs_istr_has_prefix (const char *haystack, + const char *needle); +gboolean _gnome_vfs_istr_has_suffix (const char *haystack, + const char *needle); + +GnomeVFSResult _gnome_vfs_uri_resolve_all_symlinks_uri (GnomeVFSURI *uri, + GnomeVFSURI **result_uri); +GnomeVFSResult _gnome_vfs_uri_resolve_all_symlinks (const char *text_uri, + char **resolved_text_uri); + +gboolean _gnome_vfs_uri_is_in_subdir (GnomeVFSURI *uri, GnomeVFSURI *dir); + + +GnomeVFSResult _gnome_vfs_url_show_using_handler_with_env (const char *url, + char **envp); +gboolean _gnome_vfs_use_handler_for_scheme (const char *scheme); + +gboolean _gnome_vfs_prepend_terminal_to_vector (int *argc, + char ***argv); + +G_END_DECLS + +#endif /* _GNOME_VFS_PRIVATE_UTILS_H */ diff --git a/libgnomevfs/gnome-vfs-private.c b/libgnomevfs/gnome-vfs-private.c new file mode 100644 index 0000000..120f474 --- /dev/null +++ b/libgnomevfs/gnome-vfs-private.c @@ -0,0 +1,2 @@ +#include +#include "gnome-vfs-private.h" diff --git a/libgnomevfs/gnome-vfs-private.h b/libgnomevfs/gnome-vfs-private.h new file mode 100644 index 0000000..0b6d28a --- /dev/null +++ b/libgnomevfs/gnome-vfs-private.h @@ -0,0 +1,31 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* gnome-vfs-private.h - Private header file for the GNOME Virtual + File System. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli */ + +#ifndef GNOME_VFS_PRIVATE_H +#define GNOME_VFS_PRIVATE_H + +#define GNOME_VFS_MODULE_DIR LIBDIR "/gnome-vfs-2.0/modules" +#define GNOME_VFS_MODULE_CFGDIR SYSCONFDIR "/gnome-vfs-2.0/modules" + +#endif /* GNOME_VFS_PRIVATE_H */ diff --git a/libgnomevfs/gnome-vfs-process.c b/libgnomevfs/gnome-vfs-process.c new file mode 100644 index 0000000..b059c14 --- /dev/null +++ b/libgnomevfs/gnome-vfs-process.c @@ -0,0 +1,281 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-process.c - Unified method for executing external processes. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli +*/ + +/* WARNING: This is *NOT* MT-safe at all. It is designed to call all processes + from the main thread exclusively. But for now this is fine, because we are + only using this module internally. */ + +#include +#include "gnome-vfs-process.h" + +#include "gnome-vfs-private-utils.h" +#include +#include /* workaround for giochannel.h bug */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* A launched process. */ +struct _GnomeVFSProcess { + pid_t pid; + GnomeVFSProcessCallback callback; + gpointer callback_data; +}; + +/* Have we been initialized yet? */ +static gboolean initialized = FALSE; + +/* Table to get a pointer to a GnomeVFSProcess struct from a PID value. */ +static GHashTable *pid_to_process = NULL; + +/* Input channel for waking up the main loop whenever a SIGCHLD is received, + and call our SIGCHLD handling callback. */ +static GIOChannel *wake_up_channel_in = NULL; + +/* The output side of the previous channel. We use low-level I/O in the signal + handler instead of `g_io_*' stuff. */ +static volatile gint wake_up_channel_out_fd = -1; + +/* The sigaction we had before installing the SIGCHLD handler. */ +static struct sigaction old_sigchld_action; + +static void +foreach_pid_func (gpointer key, + gpointer value, + gpointer data) +{ + GnomeVFSProcess *process; + pid_t pid; + gint status; + gboolean *found; + + pid = GPOINTER_TO_INT (key); + process = (GnomeVFSProcess *) value; + found = (gboolean *) data; + + if (waitpid (pid, &status, WNOHANG) == pid) { + write (wake_up_channel_out_fd, &process, sizeof (process)); + write (wake_up_channel_out_fd, &status, sizeof (status)); + *found = TRUE; + } +} + +static void +sigchld_handler (int signum) +{ + gboolean found = FALSE; + + found = FALSE; + g_hash_table_foreach (pid_to_process, foreach_pid_func, &found); + + if (! found && old_sigchld_action.sa_handler != NULL) + (* old_sigchld_action.sa_handler) (signum); +} + +static gboolean +wake_up (GIOChannel *source, + GIOCondition condition, + gpointer data) +{ + GnomeVFSProcess *process; + GIOError result; + gsize bytes_read; + gint status; + + do { + result = g_io_channel_read_chars (source, (gchar *) &process, + sizeof (process), &bytes_read, NULL); + } while (result == G_IO_ERROR_AGAIN); + if (result != G_IO_ERROR_NONE) { + g_warning (__FILE__ ": Cannot read from the notification channel (error %d)", + result); + return TRUE; + } + + do { + result = g_io_channel_read_chars (source, (gchar *) &status, + sizeof (status), &bytes_read, NULL); + } while (result == G_IO_ERROR_AGAIN); + if (result != G_IO_ERROR_NONE) { + g_warning (__FILE__ ": Cannot read from the notification channel (error %d)", + result); + return TRUE; + } + + if (process->callback != NULL) + (* process->callback) (process, status, + process->callback_data); + + if (WIFSIGNALED (status)) { + g_hash_table_remove (pid_to_process, + GINT_TO_POINTER (process->pid)); + _gnome_vfs_process_free (process); + } + + return TRUE; +} + +gboolean +_gnome_vfs_process_init (void) +{ + gint pipe_fd[2]; + struct sigaction sigchld_action; + sigset_t sigchld_mask; + + if (initialized) + return TRUE; + + if (pipe (pipe_fd) == -1) { + g_warning ("Cannot create pipe for GnomeVFSProcess initialization: %s", + g_strerror (errno)); + return FALSE; + } + + pid_to_process = g_hash_table_new (NULL, NULL); + + sigchld_action.sa_handler = sigchld_handler; + sigemptyset (&sigchld_action.sa_mask); + sigchld_action.sa_flags = 0; + + sigaction (SIGCHLD, &sigchld_action, &old_sigchld_action); + + wake_up_channel_in = g_io_channel_unix_new (pipe_fd[0]); + wake_up_channel_out_fd = pipe_fd[1]; + + g_io_add_watch (wake_up_channel_in, G_IO_IN, wake_up, NULL); + + sigemptyset (&sigchld_mask); + sigaddset (&sigchld_mask, SIGCHLD); + sigprocmask (SIG_UNBLOCK, &sigchld_mask, NULL); + + return TRUE; +} + +/** + * _gnome_vfs_process_new: + * @file_name: Name of the executable. + * @argv: NULL-terminated parameter list. + * @use_search_path: If TRUE, use the `PATH' environment variable to locate + * the executable. + * @close_file_descriptors: If TRUE, close all the open file descriptors. + * except stdio, stdin and stderr before launching the process. + * @init_func: Function to be called before launching the process. + * @init_data: Value to pass to @init_func. + * @callback: Function to invoke when the process die. + * @callback_data: Data to pass to @callback when the process dies. + * + * Launch a new process. @init_func is called immediately after calling + * fork(), and before closing the file descriptors and executing the program in + * the new process. + * + * Return value: An opaque structure describing the launched process. + **/ +GnomeVFSProcess * +_gnome_vfs_process_new (const gchar *file_name, + const gchar * const argv[], + GnomeVFSProcessOptions options, + GnomeVFSProcessInitFunc init_func, + gpointer init_data, + GnomeVFSProcessCallback callback, + gpointer callback_data) +{ + GnomeVFSProcess *new; + sigset_t sigchld_mask, old_mask; + pid_t child_pid; + + /* Make sure no SIGCHLD happens while we set things up. */ + + sigemptyset (&sigchld_mask); + sigaddset (&sigchld_mask, SIGCHLD); + sigprocmask (SIG_BLOCK, &sigchld_mask, &old_mask); + + child_pid = gnome_vfs_forkexec (file_name, argv, options, + init_func, init_data); + + if (child_pid == -1) + return NULL; + + new = g_new (GnomeVFSProcess, 1); + new->pid = child_pid; + new->callback = callback; + new->callback_data = callback_data; + + g_hash_table_insert (pid_to_process, GINT_TO_POINTER (child_pid), new); + + sigprocmask (SIG_SETMASK, &old_mask, NULL); + + return new; +} + +/** + * _gnome_vfs_process_free: + * @process: An existing process. + * + * Free @process. This will not kill the process, but will prevent the + * associated callbacks to be called. + **/ +void +_gnome_vfs_process_free (GnomeVFSProcess *process) +{ + g_hash_table_remove (pid_to_process, GINT_TO_POINTER (process->pid)); + g_free (process); +} + +/** + * _gnome_vfs_process_signal: + * @process: A launched process + * @signal_number: A signal number + * + * Send signal @signal_number to the specified @process. + * + * Return value: A numeric value reporting the result of the operation. + **/ +GnomeVFSProcessRunResult +_gnome_vfs_process_signal (GnomeVFSProcess *process, + guint signal_number) +{ + gint kill_result; + + kill_result = kill (process->pid, signal_number); + + switch (kill_result) { + case 0: + return GNOME_VFS_PROCESS_OK; + case EINVAL: + return GNOME_VFS_PROCESS_ERROR_INVALIDSIGNAL; + case EPERM: + return GNOME_VFS_PROCESS_ERROR_NOPERM; + case ESRCH: + return GNOME_VFS_PROCESS_ERROR_NOPROCESS; + default: + return GNOME_VFS_PROCESS_ERROR_UNKNOWN; + } +} + diff --git a/libgnomevfs/gnome-vfs-process.h b/libgnomevfs/gnome-vfs-process.h new file mode 100644 index 0000000..05d1894 --- /dev/null +++ b/libgnomevfs/gnome-vfs-process.h @@ -0,0 +1,73 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-process.h - Unified method for executing external processes. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli +*/ + +#ifndef GNOME_VFS_PROCESS_H +#define GNOME_VFS_PROCESS_H + +#include +#include /* For the signal values. */ + +typedef enum { + GNOME_VFS_PROCESS_OK, + GNOME_VFS_PROCESS_ERROR_UNKNOWN, + GNOME_VFS_PROCESS_ERROR_INVALIDSIGNAL, + GNOME_VFS_PROCESS_ERROR_NOPERM, + GNOME_VFS_PROCESS_ERROR_NOPROCESS +} GnomeVFSProcessResult; + +typedef enum { + GNOME_VFS_PROCESS_RUN_OK, + GNOME_VFS_PROCESS_RUN_ERROR, + GNOME_VFS_PROCESS_RUN_CANCELLED, + GNOME_VFS_PROCESS_RUN_SIGNALED, + GNOME_VFS_PROCESS_RUN_STOPPED +} GnomeVFSProcessRunResult; + +typedef enum { + GNOME_VFS_PROCESS_DEFAULT = 0, + GNOME_VFS_PROCESS_USEPATH = 1 << 0, + GNOME_VFS_PROCESS_CLOSEFDS = 1 << 1, + GNOME_VFS_PROCESS_SETSID = 1 << 2 +} GnomeVFSProcessOptions; + +typedef struct _GnomeVFSProcess GnomeVFSProcess; + +typedef void (* GnomeVFSProcessInitFunc) (gpointer data); + +typedef void (* GnomeVFSProcessCallback) (GnomeVFSProcess *process, + gint status, + gpointer data); + +gboolean _gnome_vfs_process_init (void); +GnomeVFSProcess * _gnome_vfs_process_new (const gchar *file_name, + const gchar * const argv[], + GnomeVFSProcessOptions options, + GnomeVFSProcessInitFunc init_func, + gpointer init_data, + GnomeVFSProcessCallback callback, + gpointer callback_data); +GnomeVFSProcessResult _gnome_vfs_process_signal (GnomeVFSProcess *process, + guint signal_number); +void _gnome_vfs_process_free (GnomeVFSProcess *process); + +#endif /* GNOME_VFS_PROCESS_H */ diff --git a/libgnomevfs/gnome-vfs-result.c b/libgnomevfs/gnome-vfs-result.c new file mode 100644 index 0000000..393dae3 --- /dev/null +++ b/libgnomevfs/gnome-vfs-result.c @@ -0,0 +1,177 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-error.c - Error handling for the GNOME Virtual File System. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli +*/ + +#include +#include "gnome-vfs-result.h" + +#include "gnome-vfs-i18n.h" +#include +#include +#include + +extern int h_errno; + +static char *status_strings[] = { + /* GNOME_VFS_OK */ N_("No error"), + /* GNOME_VFS_ERROR_NOT_FOUND */ N_("File not found"), + /* GNOME_VFS_ERROR_GENERIC */ N_("Generic error"), + /* GNOME_VFS_ERROR_INTERNAL */ N_("Internal error"), + /* GNOME_VFS_ERROR_BAD_PARAMETERS */ N_("Invalid parameters"), + /* GNOME_VFS_ERROR_NOT_SUPPORTED */ N_("Unsupported operation"), + /* GNOME_VFS_ERROR_IO */ N_("I/O error"), + /* GNOME_VFS_ERROR_CORRUPTED_DATA */ N_("Data corrupted"), + /* GNOME_VFS_ERROR_WRONG_FORMAT */ N_("Format not valid"), + /* GNOME_VFS_ERROR_BAD_FILE */ N_("Bad file handle"), + /* GNOME_VFS_ERROR_TOO_BIG */ N_("File too big"), + /* GNOME_VFS_ERROR_NO_SPACE */ N_("No space left on device"), + /* GNOME_VFS_ERROR_READ_ONLY */ N_("Read-only file system"), + /* GNOME_VFS_ERROR_INVALID_URI */ N_("Invalid URI"), + /* GNOME_VFS_ERROR_NOT_OPEN */ N_("File not open"), + /* GNOME_VFS_ERROR_INVALID_OPEN_MODE */ N_("Open mode not valid"), + /* GNOME_VFS_ERROR_ACCESS_DENIED */ N_("Access denied"), + /* GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES */ N_("Too many open files"), + /* GNOME_VFS_ERROR_EOF */ N_("End of file"), + /* GNOME_VFS_ERROR_NOT_A_DIRECTORY */ N_("Not a directory"), + /* GNOME_VFS_ERROR_IN_PROGRESS */ N_("Operation in progress"), + /* GNOME_VFS_ERROR_INTERRUPTED */ N_("Operation interrupted"), + /* GNOME_VFS_ERROR_FILE_EXISTS */ N_("File exists"), + /* GNOME_VFS_ERROR_LOOP */ N_("Looping links encountered"), + /* GNOME_VFS_ERROR_NOT_PERMITTED */ N_("Operation not permitted"), + /* GNOME_VFS_ERROR_IS_DIRECTORY */ N_("Is a directory"), + /* GNOME_VFS_ERROR_NO_MEMMORY */ N_("Not enough memory"), + /* GNOME_VFS_ERROR_HOST_NOT_FOUND */ N_("Host not found"), + /* GNOME_VFS_ERROR_INVALID_HOST_NAME */ N_("Host name not valid"), + /* GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS */ N_("Host has no address"), + /* GNOME_VFS_ERROR_LOGIN_FAILED */ N_("Login failed"), + /* GNOME_VFS_ERROR_CANCELLED */ N_("Operation cancelled"), + /* GNOME_VFS_ERROR_DIRECTORY_BUSY */ N_("Directory busy"), + /* GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY */ N_("Directory not empty"), + /* GNOME_VFS_ERROR_TOO_MANY_LINKS */ N_("Too many links"), + /* GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM */ N_("Read only file system"), + /* GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM */ N_("Not on the same file system"), + /* GNOME_VFS_ERROR_NAME_TOO_LONG */ N_("Name too long"), + /* GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE */ N_("Service not available"), + /* GNOME_VFS_ERROR_SERVICE_OBSOLETE */ N_("Request obsoletes service's data"), + /* GNOME_VFS_ERROR_PROTOCOL_ERROR */ N_("Protocol error"), + /* GNOME_VFS_ERROR_NO_MASTER_BROWSER */ N_("Could not find master browser"), + /* GNOME_VFS_ERROR_NO_DEFAULT */ N_("No default action associated"), + /* GNOME_VFS_ERROR_NO_HANDLER */ N_("No handler for URL scheme"), + /* GNOME_VFS_ERROR_PARSE */ N_("Error parsing command line"), + /* GNOME_VFS_ERROR_LAUNCH */ N_("Error launching command") +}; + + +/** + * gnome_vfs_result_from_errno_code + * @errno_code: integer of the same type as the system "errno" + * + * Converts a system errno value to a GnomeVFSResult. + * + * Return value: a GnomeVFSResult equivalent to @errno_code + **/ +GnomeVFSResult +gnome_vfs_result_from_errno_code (int errno_code) +{ + /* Please keep these in alphabetical order. */ + switch (errno_code) { + case E2BIG: return GNOME_VFS_ERROR_TOO_BIG; + case EACCES: return GNOME_VFS_ERROR_ACCESS_DENIED; + case EBUSY: return GNOME_VFS_ERROR_DIRECTORY_BUSY; + case EBADF: return GNOME_VFS_ERROR_BAD_FILE; + case EEXIST: return GNOME_VFS_ERROR_FILE_EXISTS; + case EFAULT: return GNOME_VFS_ERROR_INTERNAL; + case EFBIG: return GNOME_VFS_ERROR_TOO_BIG; + case EINTR: return GNOME_VFS_ERROR_INTERRUPTED; + case EINVAL: return GNOME_VFS_ERROR_BAD_PARAMETERS; + case EIO: return GNOME_VFS_ERROR_IO; + case EISDIR: return GNOME_VFS_ERROR_IS_DIRECTORY; + case ELOOP: return GNOME_VFS_ERROR_LOOP; + case EMFILE: return GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES; + case EMLINK: return GNOME_VFS_ERROR_TOO_MANY_LINKS; + case ENFILE: return GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES; + case ENOTEMPTY: return GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY; + case ENOENT: return GNOME_VFS_ERROR_NOT_FOUND; + case ENOMEM: return GNOME_VFS_ERROR_NO_MEMORY; + case ENOSPC: return GNOME_VFS_ERROR_NO_SPACE; + case ENOTDIR: return GNOME_VFS_ERROR_NOT_A_DIRECTORY; + case EPERM: return GNOME_VFS_ERROR_NOT_PERMITTED; + case EROFS: return GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM; + case EXDEV: return GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM; + /* FIXME bugzilla.eazel.com 1191: To be completed. */ + default: return GNOME_VFS_ERROR_GENERIC; + } +} + +/** + * gnome_vfs_result_from_errno: + * + * Converts the system errno to a GnomeVFSResult. + * + * Return value: a GnomeVFSResult equivalent to the current system errno + **/ +GnomeVFSResult +gnome_vfs_result_from_errno (void) +{ + return gnome_vfs_result_from_errno_code(errno); +} + + +/** + * gnome_vfs_result_from_h_errno: + * + * Converts the system "h_errno" to a GnomeVFSResult (h_errno represents errors + * accessing and finding internet hosts) + * + * Return value: a GnomeVFSResult equivalent to the current system "h_errno" + **/ +GnomeVFSResult +gnome_vfs_result_from_h_errno (void) +{ + switch (h_errno) { + case HOST_NOT_FOUND: return GNOME_VFS_ERROR_HOST_NOT_FOUND; + case NO_ADDRESS: return GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS; + case TRY_AGAIN: /* FIXME bugzilla.eazel.com 1190 */ + case NO_RECOVERY: /* FIXME bugzilla.eazel.com 1190 */ + default: + return GNOME_VFS_ERROR_GENERIC; + } +} + +/** + * gnome_vfs_result_to_string: + * @result: the result to convert to a string + * + * Returns a string representation of @result, useful for debugging + * purposes, but probably not appropriate for passing to the user. + * + * Return value: a string representing @result + **/ +const char * +gnome_vfs_result_to_string (GnomeVFSResult result) +{ + if ((guint) result >= (guint) (sizeof (status_strings) + / sizeof (*status_strings))) + return _("Unknown error"); + + return _(status_strings[(guint) result]); +} diff --git a/libgnomevfs/gnome-vfs-result.h b/libgnomevfs/gnome-vfs-result.h new file mode 100644 index 0000000..7aac63b --- /dev/null +++ b/libgnomevfs/gnome-vfs-result.h @@ -0,0 +1,93 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* gnome-vfs-result.h - Result handling for the GNOME Virtual File System. + + Copyright (C) 1999, 2001 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli + Seth Nickell +*/ + +#ifndef GNOME_VFS_RESULT_H +#define GNOME_VFS_RESULT_H + +#include + +G_BEGIN_DECLS + +/* IMPORTANT NOTICE: If you add error types here, please also add the + corresponding descriptions in `gnome-vfs-result.c'. Moreover, *always* add + new values at the end of the list, and *never* remove values. */ +typedef enum { + GNOME_VFS_OK, + GNOME_VFS_ERROR_NOT_FOUND, + GNOME_VFS_ERROR_GENERIC, + GNOME_VFS_ERROR_INTERNAL, + GNOME_VFS_ERROR_BAD_PARAMETERS, + GNOME_VFS_ERROR_NOT_SUPPORTED, + GNOME_VFS_ERROR_IO, + GNOME_VFS_ERROR_CORRUPTED_DATA, + GNOME_VFS_ERROR_WRONG_FORMAT, + GNOME_VFS_ERROR_BAD_FILE, + GNOME_VFS_ERROR_TOO_BIG, + GNOME_VFS_ERROR_NO_SPACE, + GNOME_VFS_ERROR_READ_ONLY, + GNOME_VFS_ERROR_INVALID_URI, + GNOME_VFS_ERROR_NOT_OPEN, + GNOME_VFS_ERROR_INVALID_OPEN_MODE, + GNOME_VFS_ERROR_ACCESS_DENIED, + GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES, + GNOME_VFS_ERROR_EOF, + GNOME_VFS_ERROR_NOT_A_DIRECTORY, + GNOME_VFS_ERROR_IN_PROGRESS, + GNOME_VFS_ERROR_INTERRUPTED, + GNOME_VFS_ERROR_FILE_EXISTS, + GNOME_VFS_ERROR_LOOP, + GNOME_VFS_ERROR_NOT_PERMITTED, + GNOME_VFS_ERROR_IS_DIRECTORY, + GNOME_VFS_ERROR_NO_MEMORY, + GNOME_VFS_ERROR_HOST_NOT_FOUND, + GNOME_VFS_ERROR_INVALID_HOST_NAME, + GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS, + GNOME_VFS_ERROR_LOGIN_FAILED, + GNOME_VFS_ERROR_CANCELLED, + GNOME_VFS_ERROR_DIRECTORY_BUSY, + GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY, + GNOME_VFS_ERROR_TOO_MANY_LINKS, + GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM, + GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM, + GNOME_VFS_ERROR_NAME_TOO_LONG, + GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE, + GNOME_VFS_ERROR_SERVICE_OBSOLETE, + GNOME_VFS_ERROR_PROTOCOL_ERROR, + GNOME_VFS_ERROR_NO_MASTER_BROWSER, + GNOME_VFS_ERROR_NO_DEFAULT, + GNOME_VFS_ERROR_NO_HANDLER, + GNOME_VFS_ERROR_PARSE, + GNOME_VFS_ERROR_LAUNCH, + GNOME_VFS_NUM_ERRORS +} GnomeVFSResult; + +const char *gnome_vfs_result_to_string (GnomeVFSResult result); +GnomeVFSResult gnome_vfs_result_from_errno_code (int errno_code); +GnomeVFSResult gnome_vfs_result_from_errno (void); +GnomeVFSResult gnome_vfs_result_from_h_errno (void); + +G_END_DECLS + +#endif /* GNOME_VFS_RESULT_H */ diff --git a/libgnomevfs/gnome-vfs-socket-buffer.c b/libgnomevfs/gnome-vfs-socket-buffer.c new file mode 100644 index 0000000..1c35ba6 --- /dev/null +++ b/libgnomevfs/gnome-vfs-socket-buffer.c @@ -0,0 +1,353 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-socket-buffer.c + * + * Copyright (C) 2001 Seth Nickell + * Copyright (C) 2001 Maciej Stachowiak + * + * The Gnome Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Gnome Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ +/* + * Authors: Seth Nickell + * Maciej Stachowiak + * (reverse-engineered from code by Ian McKellar ) + */ + +#include +#include "gnome-vfs-socket-buffer.h" + +#include +#include +#include + + +#define BUFFER_SIZE 4096 + +struct Buffer { + gchar data[BUFFER_SIZE]; + guint offset; + guint byte_count; + GnomeVFSResult last_error; +}; +typedef struct Buffer Buffer; + + +struct GnomeVFSSocketBuffer { + GnomeVFSSocket *socket; + Buffer input_buffer; + Buffer output_buffer; +}; + + +static void +buffer_init (Buffer *buffer) +{ + buffer->byte_count = 0; + buffer->offset = 0; + buffer->last_error = GNOME_VFS_OK; +} + +/** + * gnome_vfs_socket_buffer_new: + * @socket: socket to be buffered + * + * Create a socket buffer around @socket. A buffered + * socket allows data to be poked at without reading it + * as it will be buffered. A future read will retrieve + * the data again. + * + * Return value: a newly allocated GnomeVFSSocketBuffer + **/ +GnomeVFSSocketBuffer* +gnome_vfs_socket_buffer_new (GnomeVFSSocket *socket) +{ + GnomeVFSSocketBuffer *socket_buffer; + + g_return_val_if_fail (socket != NULL, NULL); + + socket_buffer = g_new (GnomeVFSSocketBuffer, 1); + socket_buffer->socket = socket; + + buffer_init (&socket_buffer->input_buffer); + buffer_init (&socket_buffer->output_buffer); + + return socket_buffer; +} + +/** + * gnome_vfs_socket_buffer_destroy: + * @socket_buffer: buffered socket to destray + * @close_socket: if %TRUE the socket being buffered will be closed too + * + * Free the socket buffer. + * + * Return value: GnomeVFSResult indicating the success of the operation + **/ +GnomeVFSResult +gnome_vfs_socket_buffer_destroy (GnomeVFSSocketBuffer *socket_buffer, + gboolean close_socket) +{ + gnome_vfs_socket_buffer_flush (socket_buffer); + + if (close_socket) { + gnome_vfs_socket_close (socket_buffer->socket); + } + g_free (socket_buffer); + return GNOME_VFS_OK; +} + + + + +static gboolean +refill_input_buffer (GnomeVFSSocketBuffer *socket_buffer) +{ + Buffer *input_buffer; + GnomeVFSResult result; + GnomeVFSFileSize bytes_read; + + input_buffer = &socket_buffer->input_buffer; + + if (input_buffer->last_error != GNOME_VFS_OK + || input_buffer->byte_count > 0) { + return FALSE; + } + + input_buffer->offset = 0; + + result = gnome_vfs_socket_read (socket_buffer->socket, + &input_buffer->data, + BUFFER_SIZE, + &bytes_read); + + if (bytes_read == 0) { + input_buffer->last_error = GNOME_VFS_ERROR_EOF; + return FALSE; + } + + input_buffer->byte_count = bytes_read; + + return TRUE; +} + +/** + * gnome_vfs_socket_buffer_read: + * @socket_buffer: buffered socket to read data from + * @buffer: allocated buffer of at least @bytes bytes to be read into + * @bytes: number of bytes to read from @socket into @socket_buffer + * @bytes_read: pointer to a GnomeVFSFileSize, will contain + * the number of bytes actually read from the socket on return. + * + * Read @bytes bytes of data from the @socket into @socket_buffer. + * + * Return value: GnomeVFSResult indicating the success of the operation + **/ +GnomeVFSResult +gnome_vfs_socket_buffer_read (GnomeVFSSocketBuffer *socket_buffer, + gpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_read) +{ + Buffer *input_buffer; + GnomeVFSResult result; + GnomeVFSFileSize n; + + g_return_val_if_fail (socket_buffer != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail (buffer != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + /* Quote from UNIX 98: + "If nbyte is 0, read() will return 0 and have no other results." + */ + if (bytes == 0) { + *bytes_read = 0; + return GNOME_VFS_OK; + } + + input_buffer = &socket_buffer->input_buffer; + + result = GNOME_VFS_OK; + + if (input_buffer->byte_count == 0) { + if (! refill_input_buffer (socket_buffer)) { + /* The buffer is empty but we had an error last time we + filled it, so we report the error. */ + result = input_buffer->last_error; + input_buffer->last_error = GNOME_VFS_OK; + } + } + + if (input_buffer->byte_count != 0) { + n = MIN (bytes, input_buffer->byte_count); + memcpy (buffer, input_buffer->data + input_buffer->offset, n); + input_buffer->byte_count -= n; + input_buffer->offset += n; + if (bytes_read != NULL) { + *bytes_read = n; + } + } else { + if (bytes_read != NULL) { + *bytes_read = 0; + } + } + + if (result == GNOME_VFS_ERROR_EOF) { + result = GNOME_VFS_OK; + } + + return result; +} + +/** + * gnome_vfs_socket_buffer_peekc: + * @socket_buffer: the socket buffer to read from + * @character: pointer to a char, will contain a character on return from + * a successful "peek" + * + * Peek at the next character in @socket_buffer without actually reading + * the character in. The next read will retrieve @c (as well as any following + * data if requested). + * + * Return value: GnomeVFSResult indicating the success of the operation + **/ +GnomeVFSResult +gnome_vfs_socket_buffer_peekc (GnomeVFSSocketBuffer *socket_buffer, + gchar *character) +{ + GnomeVFSResult result; + Buffer *input_buffer; + + g_return_val_if_fail (socket_buffer != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail (character != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + input_buffer = &socket_buffer->input_buffer; + result = GNOME_VFS_OK; + + if (input_buffer->byte_count == 0) { + if (!refill_input_buffer (socket_buffer)) { + /* The buffer is empty but we had an error last time we + filled it, so we report the error. */ + result = input_buffer->last_error; + input_buffer->last_error = GNOME_VFS_OK; + } + } + + if (result == GNOME_VFS_OK) { + *character = *(input_buffer->data + input_buffer->offset); + } + + return result; +} + + + +static GnomeVFSResult +flush (GnomeVFSSocketBuffer *socket_buffer) +{ + Buffer *output_buffer; + GnomeVFSResult result; + GnomeVFSFileSize bytes_written; + + output_buffer = &socket_buffer->output_buffer; + + while (output_buffer->byte_count > 0) { + result = gnome_vfs_socket_write (socket_buffer->socket, + output_buffer->data, + output_buffer->byte_count, + &bytes_written); + output_buffer->last_error = result; + output_buffer->byte_count -= bytes_written; + } + + return GNOME_VFS_OK; +} + +/** + * gnome_vfs_socket_buffer_write: + * @socket_buffer: buffered socket to write data to + * @buffer: data to write to the socket + * @bytes: number of bytes from @buffer to write to @socket_buffer + * @bytes_written: pointer to a GnomeVFSFileSize, will contain + * the number of bytes actually written to the socket on return. + * + * Write @bytes bytes of data from @buffer to @socket_buffer. + * + * Return value: GnomeVFSResult indicating the success of the operation + **/ +GnomeVFSResult +gnome_vfs_socket_buffer_write (GnomeVFSSocketBuffer *socket_buffer, + gconstpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_written) +{ + Buffer *output_buffer; + GnomeVFSFileSize write_count; + GnomeVFSResult result; + const gchar *p; + + g_return_val_if_fail (socket_buffer != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail (buffer != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail (bytes_written != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + output_buffer = &socket_buffer->output_buffer; + + result = GNOME_VFS_OK; + + p = buffer; + write_count = 0; + while (write_count < bytes) { + if (output_buffer->byte_count < BUFFER_SIZE) { + GnomeVFSFileSize n; + + n = MIN (BUFFER_SIZE - output_buffer->byte_count, + bytes); + memcpy (output_buffer->data + output_buffer->byte_count, + p, n); + p += n; + write_count += n; + output_buffer->byte_count += n; + } else { + result = flush (socket_buffer); + if (result != GNOME_VFS_OK) { + break; + } + } + } + + if (bytes_written != NULL) { + *bytes_written = write_count; + } + + return result; +} + +/** + * gnome_vfs_socket_buffer_flush: + * @socket_buffer: buffer to flush + * + * Write all outstanding data to @socket_buffer. + * + * Return value: GnomeVFSResult indicating the success of the operation + **/ +GnomeVFSResult +gnome_vfs_socket_buffer_flush (GnomeVFSSocketBuffer *socket_buffer) +{ + g_return_val_if_fail (socket_buffer != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + return flush (socket_buffer); +} + + + diff --git a/libgnomevfs/gnome-vfs-socket-buffer.h b/libgnomevfs/gnome-vfs-socket-buffer.h new file mode 100644 index 0000000..0b5f633 --- /dev/null +++ b/libgnomevfs/gnome-vfs-socket-buffer.h @@ -0,0 +1,56 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-socket-buffer.h + * + * Copyright (C) 2001 Seth Nickell + * Copyright (C) 2001 Maciej Stachowiak + * + * The Gnome Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Gnome Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ +/* + * Authors: Seth Nickell + * Maciej Stachowiak + * (reverse-engineered from code by Ian McKellar ) + */ + +#ifndef GNOME_VFS_SOCKET_BUFFER_H +#define GNOME_VFS_SOCKET_BUFFER_H + +#include "gnome-vfs-socket.h" + +G_BEGIN_DECLS + +typedef struct GnomeVFSSocketBuffer GnomeVFSSocketBuffer; + + +GnomeVFSSocketBuffer* gnome_vfs_socket_buffer_new (GnomeVFSSocket *socket); +GnomeVFSResult gnome_vfs_socket_buffer_destroy (GnomeVFSSocketBuffer *socket_buffer, + gboolean close_socket); +GnomeVFSResult gnome_vfs_socket_buffer_read (GnomeVFSSocketBuffer *socket_buffer, + gpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_read); +GnomeVFSResult gnome_vfs_socket_buffer_peekc (GnomeVFSSocketBuffer *socket_buffer, + char *character); +GnomeVFSResult gnome_vfs_socket_buffer_write (GnomeVFSSocketBuffer *socket_buffer, + gconstpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_written); +GnomeVFSResult gnome_vfs_socket_buffer_flush (GnomeVFSSocketBuffer *socket_buffer); + +G_END_DECLS + +#endif diff --git a/libgnomevfs/gnome-vfs-socket.c b/libgnomevfs/gnome-vfs-socket.c new file mode 100644 index 0000000..78e8e9a --- /dev/null +++ b/libgnomevfs/gnome-vfs-socket.c @@ -0,0 +1,121 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-socket.c + * + * Copyright (C) 2001 Seth Nickell + * Copyright (C) 2001 Maciej Stachowiak + * + * The Gnome Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Gnome Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ +/* + * Authors: Seth Nickell + * Maciej Stachowiak + * (reverse-engineered from code by Ian McKellar ) + */ + +#include +#include "gnome-vfs-socket.h" + +#include + +struct GnomeVFSSocket { + GnomeVFSSocketImpl *impl; + gpointer connection; +}; + + +/** + * gnome_vfs_socket_new: + * @impl: an implementation of a socket, e.g. GnomeVFSSSL + * @connection: pointer to a connection object used by @impl to track + * state (the exact nature of @connection varies from implementation to + * implementation) + * + * Creates a new GnomeVFS Socket using the specific implementation + * @impl. + * + * Return value: a newly created socket + **/ +GnomeVFSSocket* gnome_vfs_socket_new (GnomeVFSSocketImpl *impl, + void *connection) +{ + GnomeVFSSocket *socket; + + socket = g_new0 (GnomeVFSSocket, 1); + socket->impl = impl; + socket->connection = connection; + + return socket; +} + +/** + * gnome_vfs_socket_write: + * @socket: socket to write data to + * @buffer: data to write to the socket + * @bytes: number of bytes from @buffer to write to @socket + * @bytes_written: pointer to a GnomeVFSFileSize, will contain + * the number of bytes actually written to the socket on return. + * + * Write @bytes bytes of data from @buffer to @socket. + * + * Return value: GnomeVFSResult indicating the success of the operation + **/ +GnomeVFSResult +gnome_vfs_socket_write (GnomeVFSSocket *socket, + gconstpointer buffer, + int bytes, + GnomeVFSFileSize *bytes_written) +{ + return socket->impl->write (socket->connection, + buffer, bytes, bytes_written); +} + +/** + * gnome_vfs_socket_close: + * @socket: the socket to be closed + * + * Close @socket, freeing any resources it may be using. + * + * Return value: GnomeVFSResult indicating the success of the operation + **/ +GnomeVFSResult +gnome_vfs_socket_close (GnomeVFSSocket *socket) +{ + socket->impl->close (socket->connection); + return GNOME_VFS_OK; +} + +/** + * gnome_vfs_socket_read: + * @socket: socket to read data from + * @buffer: allocated buffer of at least @bytes bytes to be read into + * @bytes: number of bytes to read from @socket into @buffer + * @bytes_read: pointer to a GnomeVFSFileSize, will contain + * the number of bytes actually read from the socket on return. + * + * Read @bytes bytes of data from the @socket into @buffer. + * + * Return value: GnomeVFSResult indicating the success of the operation + **/ +GnomeVFSResult +gnome_vfs_socket_read (GnomeVFSSocket *socket, + gpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_read) +{ + return socket->impl->read (socket->connection, + buffer, bytes, bytes_read); +} diff --git a/libgnomevfs/gnome-vfs-socket.h b/libgnomevfs/gnome-vfs-socket.h new file mode 100644 index 0000000..b5c0aca --- /dev/null +++ b/libgnomevfs/gnome-vfs-socket.h @@ -0,0 +1,73 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-socket.h + * + * Copyright (C) 2001 Seth Nickell + * Copyright (C) 2001 Maciej Stachowiak + * + * The Gnome Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Gnome Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ +/* + * Authors: Seth Nickell + * Maciej Stachowiak + * (reverse-engineered from code by Ian McKellar ) + */ + +#ifndef GNOME_VFS_SOCKET_H +#define GNOME_VFS_SOCKET_H + +#include +#include +#include + +G_BEGIN_DECLS + +typedef struct GnomeVFSSocket GnomeVFSSocket; + + +typedef GnomeVFSResult (*GnomeVFSSocketReadFunc) (gpointer connection, + gpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_read); +typedef GnomeVFSResult (*GnomeVFSSocketWriteFunc) (gpointer connection, + gconstpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_written); + +typedef void (*GnomeVFSSocketCloseFunc) (gpointer connection); + +typedef struct { + GnomeVFSSocketReadFunc read; + GnomeVFSSocketWriteFunc write; + GnomeVFSSocketCloseFunc close; +} GnomeVFSSocketImpl; + + +GnomeVFSSocket* gnome_vfs_socket_new (GnomeVFSSocketImpl *impl, + void *connection); +GnomeVFSResult gnome_vfs_socket_write (GnomeVFSSocket *socket, + gconstpointer buffer, + int bytes, + GnomeVFSFileSize *bytes_written); +GnomeVFSResult gnome_vfs_socket_close (GnomeVFSSocket *socket); +GnomeVFSResult gnome_vfs_socket_read (GnomeVFSSocket *socket, + gpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_read); + +G_END_DECLS + +#endif /* GNOME_VFS_SOCKET_H */ diff --git a/libgnomevfs/gnome-vfs-ssl-private.h b/libgnomevfs/gnome-vfs-ssl-private.h new file mode 100644 index 0000000..31d126c --- /dev/null +++ b/libgnomevfs/gnome-vfs-ssl-private.h @@ -0,0 +1,37 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* gnome-vfs-ssl-private.h + * + * Copyright (C) 2001 Ian McKellar + * + * The Gnome Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Gnome Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +/* + * Authors: Ian McKellar + */ + +#ifndef GNOME_VFS_SSL_PRIVATE_H +#define GNOME_VFS_SSL_PRIVATE_H + +#include + +G_BEGIN_DECLS + +void _gnome_vfs_ssl_init (void); + +G_END_DECLS + +#endif /* GNOME_VFS_SSL_PRIVATE_H */ diff --git a/libgnomevfs/gnome-vfs-ssl.c b/libgnomevfs/gnome-vfs-ssl.c new file mode 100644 index 0000000..66d1eba --- /dev/null +++ b/libgnomevfs/gnome-vfs-ssl.c @@ -0,0 +1,479 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* gnome-vfs-ssl.h + * + * Copyright (C) 2001 Ian McKellar + * Copyright (C) 2002 Andrew McDonald + * + * The Gnome Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Gnome Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +/* + * Authors: Ian McKellar + * My knowledge of SSL programming is due to reading Jeffrey Stedfast's + * excellent SSL implementation in Evolution. + * + * Andrew McDonald + * Basic SSL/TLS support using the LGPL'ed GNUTLS Library + */ + +#include +#include "gnome-vfs-ssl.h" + +#include "gnome-vfs-ssl-private.h" +#include "gnome-vfs-private-utils.h" +#include +#include + +#ifdef HAVE_OPENSSL +#include +#include +#include +#elif defined HAVE_GNUTLS +#include +#endif +#if defined(HAVE_OPENSSL) || defined(HAVE_GNUTLS) +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +typedef struct { +#ifdef HAVE_OPENSSL + int sockfd; + SSL *ssl; +#elif defined HAVE_GNUTLS + int sockfd; + GNUTLS_STATE tlsstate; + GNUTLS_CERTIFICATE_CLIENT_CREDENTIALS xcred; +#elif defined HAVE_NSS + PRFileDesc *sockfd; +#else + char dummy; +#endif +} GnomeVFSSSLPrivate; + +struct GnomeVFSSSL { + GnomeVFSSSLPrivate *private; +}; + +void +_gnome_vfs_ssl_init () { +#ifdef HAVE_OPENSSL + SSL_library_init (); +#elif defined HAVE_GNUTLS + gnutls_global_init(); +#endif +} + +/** + * gnome_vfs_ssl_enabled: + * + * Checks whether GnomeVFS was compiled with SSL support. + * + * Return value: %TRUE if GnomeVFS was compiled with SSL support, + * otherwise %FALSE. + **/ +gboolean +gnome_vfs_ssl_enabled () +{ +#if defined HAVE_OPENSSL || defined HAVE_GNUTLS + return TRUE; +#else + return FALSE; +#endif +} + +/** + * gnome_vfs_ssl_create: + * @handle_return: pointer to a GnmoeVFSSSL struct, which will + * contain an allocated GnomeVFSSSL object on return. + * @host: string indicating the host to establish an SSL connection with + * @port: the port number to connect to + * + * Creates an SSL socket connection at @handle_return to @host using + * port @port. + * + * Return value: GnomeVFSResult indicating the success of the operation + **/ +GnomeVFSResult +gnome_vfs_ssl_create (GnomeVFSSSL **handle_return, + const char *host, + unsigned int port) +{ +/* FIXME: add *some* kind of cert verification! */ +#if defined(HAVE_OPENSSL) || defined(HAVE_GNUTLS) + int fd; + int ret; +#ifdef ENABLE_IPV6 + struct addrinfo hints, *result, *res; +#endif + struct hostent *h; + struct sockaddr_in sin; + +#ifdef ENABLE_IPV6 + if (_gnome_vfs_have_ipv6 ()) { + fd = 0; + ret = 0; + result = NULL; + + memset (&hints, 0, sizeof (hints)); + hints.ai_socktype = SOCK_STREAM; + + if (getaddrinfo (host, NULL, &hints, &result) != 0) { + /* host lookup failed */ + return GNOME_VFS_ERROR_HOST_NOT_FOUND; + } + + for (res = result; res; res = res->ai_next) { + + if (res->ai_family != AF_INET && res->ai_family != AF_INET6) { + continue; + } + + fd = socket (res->ai_family, SOCK_STREAM, 0); + if (fd < 0) { + continue; + } + + if (res->ai_family == AF_INET) { + ((struct sockaddr_in *)res->ai_addr)->sin_port = htons (port); + } + + if (res->ai_family == AF_INET6) { + ((struct sockaddr_in6 *)res->ai_addr)->sin6_port = htons (port); + } + + ret = connect (fd, res->ai_addr, res->ai_addrlen); + if (ret != -1) { + break; + } + + close (fd); + } + + freeaddrinfo (result); + if (!res) { + if (fd < 0 || ret < 0) { + /*Error in socket creation.*/ + return gnome_vfs_result_from_errno (); + } else { + /*Error: No IPv4 or IPv6 address.*/ + return GNOME_VFS_ERROR_HOST_NOT_FOUND; + } + } + } + else +#endif + { + sin.sin_port = htons (port); + h = gethostbyname (host); + + if (h == NULL) { + /* host lookup failed */ + return gnome_vfs_result_from_h_errno (); + } + + sin.sin_family = h->h_addrtype; + memcpy (&sin.sin_addr, h->h_addr, sizeof (sin.sin_addr)); + + fd = socket (h->h_addrtype, SOCK_STREAM, 0); + if (fd < 0) { + return gnome_vfs_result_from_errno (); + } + + ret = connect (fd, (struct sockaddr *)&sin, sizeof (sin)); + } + + if (ret == -1) { + /* connect failed */ + return gnome_vfs_result_from_errno (); + } + + return gnome_vfs_ssl_create_from_fd (handle_return, fd); +#else + return GNOME_VFS_ERROR_NOT_SUPPORTED; +#endif +} + +#ifdef HAVE_GNUTLS +static const int protocol_priority[] = {GNUTLS_TLS1, GNUTLS_SSL3, 0}; +static const int cipher_priority[] = + {GNUTLS_CIPHER_RIJNDAEL_128_CBC, GNUTLS_CIPHER_3DES_CBC, + GNUTLS_CIPHER_RIJNDAEL_256_CBC, GNUTLS_CIPHER_TWOFISH_128_CBC, + GNUTLS_CIPHER_ARCFOUR, 0}; +static const int comp_priority[] = + {GNUTLS_COMP_ZLIB, GNUTLS_COMP_NULL, 0}; +static const int kx_priority[] = + {GNUTLS_KX_DHE_RSA, GNUTLS_KX_RSA, GNUTLS_KX_DHE_DSS, 0}; +static const int mac_priority[] = + {GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0}; +#endif + +/** + * gnome_vfs_ssl_create_from_fd: + * @handle_return: pointer to a GnmoeVFSSSL struct, which will + * contain an allocated GnomeVFSSSL object on return. + * @fd: file descriptior to try and establish an SSL connection over + * + * Try to establish an SSL connection over the file descriptor @fd. + * + * Return value: a GnomeVFSResult indicating the success of the operation + **/ +GnomeVFSResult +gnome_vfs_ssl_create_from_fd (GnomeVFSSSL **handle_return, + gint fd) +{ +#ifdef HAVE_OPENSSL + GnomeVFSSSL *ssl; + SSL_CTX *ssl_ctx = NULL; + int ret; + + ssl = g_new0 (GnomeVFSSSL, 1); + ssl->private = g_new0 (GnomeVFSSSLPrivate, 1); + ssl->private->sockfd = fd; + + /* SSLv23_client_method will negotiate with SSL v2, v3, or TLS v1 */ + ssl_ctx = SSL_CTX_new (SSLv23_client_method ()); + + if (ssl_ctx == NULL) { + return GNOME_VFS_ERROR_INTERNAL; + } + + /* FIXME: SSL_CTX_set_verify (ssl_ctx, SSL_VERIFY_PEER, &ssl_verify);*/ + ssl->private->ssl = SSL_new (ssl_ctx); + + if (ssl->private->ssl == NULL) { + return GNOME_VFS_ERROR_IO; + } + + SSL_set_fd (ssl->private->ssl, fd); + + ret = SSL_connect (ssl->private->ssl); + if (ret != 1) { + SSL_shutdown (ssl->private->ssl); + + if (ssl->private->ssl->ctx) + SSL_CTX_free (ssl->private->ssl->ctx); + + SSL_free (ssl->private->ssl); + g_free (ssl->private); + g_free (ssl); + return GNOME_VFS_ERROR_IO; + } + + *handle_return = ssl; + + return GNOME_VFS_OK; + +#elif defined HAVE_GNUTLS + GnomeVFSSSL *ssl; + int err; + + ssl = g_new0 (GnomeVFSSSL, 1); + ssl->private = g_new0 (GnomeVFSSSLPrivate, 1); + ssl->private->sockfd = fd; + + err = gnutls_certificate_allocate_sc (&ssl->private->xcred); + if (err < 0) { + g_free (ssl->private); + g_free (ssl); + return GNOME_VFS_ERROR_INTERNAL; + } + + gnutls_init (&ssl->private->tlsstate, GNUTLS_CLIENT); + + /* set socket */ + gnutls_transport_set_ptr (ssl->private->tlsstate, fd); + + gnutls_protocol_set_priority (ssl->private->tlsstate, protocol_priority); + gnutls_cipher_set_priority (ssl->private->tlsstate, cipher_priority); + gnutls_compression_set_priority (ssl->private->tlsstate, comp_priority); + gnutls_kx_set_priority (ssl->private->tlsstate, kx_priority); + gnutls_mac_set_priority (ssl->private->tlsstate, mac_priority); + + gnutls_cred_set (ssl->private->tlsstate, GNUTLS_CRD_CERTIFICATE, + ssl->private->xcred); + + err = gnutls_handshake (ssl->private->tlsstate); + + while (err == GNUTLS_E_AGAIN || err == GNUTLS_E_INTERRUPTED) { + err = gnutls_handshake (ssl->private->tlsstate); + } + + if (err < 0) { + gnutls_certificate_free_sc (ssl->private->xcred); + gnutls_deinit (ssl->private->tlsstate); + g_free (ssl->private); + g_free (ssl); + return GNOME_VFS_ERROR_IO; + } + + *handle_return = ssl; + + return GNOME_VFS_OK; +#else + return GNOME_VFS_ERROR_NOT_SUPPORTED; +#endif +} + +/** + * gnome_vfs_ssl_read: + * @ssl: SSL socket to read data from + * @buffer: allocated buffer of at least @bytes bytes to be read into + * @bytes: number of bytes to read from @ssl into @buffer + * @bytes_read: pointer to a GnomeVFSFileSize, will contain + * the number of bytes actually read from the socket on return. + * + * Read @bytes bytes of data from the SSL socket @ssl into @buffer. + * + * Return value: GnomeVFSResult indicating the success of the operation + **/ +GnomeVFSResult +gnome_vfs_ssl_read (GnomeVFSSSL *ssl, + gpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_read) +{ +#if HAVE_OPENSSL + if (bytes == 0) { + *bytes_read = 0; + return GNOME_VFS_OK; + } + + *bytes_read = SSL_read (ssl->private->ssl, buffer, bytes); + + if (*bytes_read <= 0) { + *bytes_read = 0; + return GNOME_VFS_ERROR_GENERIC; + } + return GNOME_VFS_OK; +#elif defined HAVE_GNUTLS + if (bytes == 0) { + *bytes_read = 0; + return GNOME_VFS_OK; + } + + *bytes_read = gnutls_record_recv (ssl->private->tlsstate, buffer, bytes); + + if (*bytes_read <= 0) { + *bytes_read = 0; + return GNOME_VFS_ERROR_GENERIC; + } + return GNOME_VFS_OK; +#else + return GNOME_VFS_ERROR_NOT_SUPPORTED; +#endif +} + +/** + * gnome_vfs_ssl_write: + * @ssl: SSL socket to write data to + * @buffer: data to write to the socket + * @bytes: number of bytes from @buffer to write to @ssl + * @bytes_written: pointer to a GnomeVFSFileSize, will contain + * the number of bytes actually written to the socket on return. + * + * Write @bytes bytes of data from @buffer to @ssl. + * + * Return value: GnomeVFSResult indicating the success of the operation + **/ +GnomeVFSResult +gnome_vfs_ssl_write (GnomeVFSSSL *ssl, + gconstpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_written) +{ +#if HAVE_OPENSSL + if (bytes == 0) { + *bytes_written = 0; + return GNOME_VFS_OK; + } + + *bytes_written = SSL_write (ssl->private->ssl, buffer, bytes); + + if (*bytes_written <= 0) { + *bytes_written = 0; + return GNOME_VFS_ERROR_GENERIC; + } + return GNOME_VFS_OK; +#elif defined HAVE_GNUTLS + if (bytes == 0) { + *bytes_written = 0; + return GNOME_VFS_OK; + } + + *bytes_written = gnutls_record_send (ssl->private->tlsstate, buffer, bytes); + + if (*bytes_written <= 0) { + *bytes_written = 0; + return GNOME_VFS_ERROR_GENERIC; + } + return GNOME_VFS_OK; +#else + return GNOME_VFS_ERROR_NOT_SUPPORTED; +#endif +} + +/** + * gnome_vfs_ssl_destroy: + * @ssl: SSL socket to be closed and destroyed + * + * Free resources used by @ssl and close the connection. + */ +void +gnome_vfs_ssl_destroy (GnomeVFSSSL *ssl) +{ +#if HAVE_OPENSSL + SSL_shutdown (ssl->private->ssl); + SSL_CTX_free (ssl->private->ssl->ctx); + SSL_free (ssl->private->ssl); + close (ssl->private->sockfd); +#elif defined HAVE_GNUTLS + gnutls_bye (ssl->private->tlsstate, GNUTLS_SHUT_RDWR); + gnutls_certificate_free_sc (ssl->private->xcred); + gnutls_deinit (ssl->private->tlsstate); + close (ssl->private->sockfd); +#else +#endif + g_free (ssl->private); + g_free (ssl); +} + +static GnomeVFSSocketImpl ssl_socket_impl = { + (GnomeVFSSocketReadFunc)gnome_vfs_ssl_read, + (GnomeVFSSocketWriteFunc)gnome_vfs_ssl_write, + (GnomeVFSSocketCloseFunc)gnome_vfs_ssl_destroy +}; + +/** + * gnome_vfs_ssl_to_socket: + * @ssl: SSL socket to convert into a standard socket + * + * Wrapper an SSL socket inside a standard GnomeVFSSocket. + * + * Return value: a newly allocated GnomeVFSSocket corresponding to @ssl. + **/ +GnomeVFSSocket * +gnome_vfs_ssl_to_socket (GnomeVFSSSL *ssl) +{ + return gnome_vfs_socket_new (&ssl_socket_impl, ssl); +} diff --git a/libgnomevfs/gnome-vfs-ssl.h b/libgnomevfs/gnome-vfs-ssl.h new file mode 100644 index 0000000..ca5a83c --- /dev/null +++ b/libgnomevfs/gnome-vfs-ssl.h @@ -0,0 +1,55 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* gnome-vfs-ssl.h + * + * Copyright (C) 2001 Ian McKellar + * + * The Gnome Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Gnome Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +/* + * Authors: Ian McKellar + */ + +#ifndef GNOME_VFS_SSL_H +#define GNOME_VFS_SSL_H + +#include + +G_BEGIN_DECLS + +typedef struct GnomeVFSSSL GnomeVFSSSL; + +gboolean gnome_vfs_ssl_enabled (void); +/* FIXME: add *some* kind of cert verification! */ +GnomeVFSResult gnome_vfs_ssl_create (GnomeVFSSSL **handle_return, + const char *host, + unsigned int port); +GnomeVFSResult gnome_vfs_ssl_create_from_fd (GnomeVFSSSL **handle_return, + gint fd); +GnomeVFSResult gnome_vfs_ssl_read (GnomeVFSSSL *ssl, + gpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_read); +GnomeVFSResult gnome_vfs_ssl_write (GnomeVFSSSL *ssl, + gconstpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_written); +void gnome_vfs_ssl_destroy (GnomeVFSSSL *ssl); +GnomeVFSSocket *gnome_vfs_ssl_to_socket (GnomeVFSSSL *ssl); + +G_END_DECLS + +#endif /* GNOME_VFS_SSL_H */ diff --git a/libgnomevfs/gnome-vfs-standard-callbacks.h b/libgnomevfs/gnome-vfs-standard-callbacks.h new file mode 100644 index 0000000..a35f3a0 --- /dev/null +++ b/libgnomevfs/gnome-vfs-standard-callbacks.h @@ -0,0 +1,182 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* + + Copyright (C) 2001 Eazel, Inc + Copyright (C) 2002 Seth Nickell + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Michael Fleming + Seth Nickell +*/ + +#ifndef GNOME_VFS_STANDARD_CALLBACKS_H +#define GNOME_VFS_STANDARD_CALLBACKS_H + +#include +#include + +G_BEGIN_DECLS + +/* + * defined callback structures + */ + +/* + * hook name: "simple-authentication" + * In arg: GnomeVFSModuleCallbackAuthenticationIn * + * Out arg: GnomeVFSModuleCallbacAuthenticationOut * + * + * Called when access to a URI requires a username/password + */ +#define GNOME_VFS_MODULE_CALLBACK_AUTHENTICATION "simple-authentication" + +/* + * hook name: "http:proxy-authentication" + * In arg: GnomeVFSModuleCallbackAuthenticationIn * + * Out arg: GnomeVFSModuleCallbackAuthenticationOut * + * + * Called when access to an HTTP proxy requires a username/password + */ +#define GNOME_VFS_MODULE_CALLBACK_HTTP_PROXY_AUTHENTICATION "http:proxy-authentication" + +typedef struct { + char *uri; /* Full URI of operation */ + char *realm; /* for HTTP auth, NULL for others */ + gboolean previous_attempt_failed; + /* TRUE if there were credentials specified + * for this request, but they resulted in + * an authorization error. + * ("you gave me the wrong pw!") + * + * FALSE if there were no credentials specified + * but they are required to continue + * + */ + enum { + AuthTypeBasic, /* Password will be transmitted unencrypted */ + AuthTypeDigest /* Digest is transferred, not plaintext credentials */ + } auth_type; + + /* Reserved "padding" to avoid future breaks in ABI compatibility */ + void *reserved1; + void *reserved2; + +} GnomeVFSModuleCallbackAuthenticationIn; + +typedef struct { + char *username; /* will be freed by g_free, + * NULL indicates no auth should be provided; + * if the request requires authn, the operation + * will fail with a GNOME_VFS_ERROR_ACCESS_DENIED + * code + */ + char *password; /* will be freed by g_free */ + + /* Reserved "padding" to avoid future breaks in ABI compatibility */ + void *reserved1; + void *reserved2; + +} GnomeVFSModuleCallbackAuthenticationOut; + +/* + * hook name: "http:send-additional-headers" + * In arg: GnomeVFSModuleCallbackAdditionalHeadersIn * + * Out arg: GnomeVFSModuleCallbackAdditionalHeadersOut * + * + * Called before sending headers to an HTTP server. + */ + +#define GNOME_VFS_MODULE_CALLBACK_HTTP_SEND_ADDITIONAL_HEADERS "http:send-additional-headers" + +typedef struct { + GnomeVFSURI *uri; /* URI of operation */ + + /* Reserved "padding" to avoid future breaks in ABI compatibility */ + void *reserved1; + void *reserved2; +} GnomeVFSModuleCallbackAdditionalHeadersIn; + +typedef struct { + GList *headers; /* list of headers, will be freeed */ + + /* Reserved "padding" to avoid future breaks in ABI compatibility */ + void *reserved1; + void *reserved2; +} GnomeVFSModuleCallbackAdditionalHeadersOut; + +/* + * hook name: "http:received-headers" + * In arg: GnomeVFSModuleCallbackReceivedHeadersIn * + * Out arg: GnomeVFSModuleCallbackReceivedHeadersOut * + * + * Called after receiving the HTTP headers from the server. + */ + +#define GNOME_VFS_MODULE_CALLBACK_HTTP_RECEIVED_HEADERS "http:received-headers" + +typedef struct { + GnomeVFSURI *uri; /* URI of operation */ + GList *headers; /* list of headers */ + + /* Reserved "padding" to avoid future breaks in ABI compatibility */ + void *reserved1; + void *reserved2; +} GnomeVFSModuleCallbackReceivedHeadersIn; + +typedef struct { + int dummy; + + /* Reserved "padding" to avoid future breaks in ABI compatibility */ + void *reserved1; + void *reserved2; +} GnomeVFSModuleCallbackReceivedHeadersOut; + +/* + * hook name: "status-message" + * In arg: GnomeVFSModuleCallbackStatusMessageIn * + * Out arg: GnomeVFSModuleCallbackStatusMessageOut * + * + * Called when a GnomeVFS API or module has a status message to return to + * the user. + */ + +#define GNOME_VFS_MODULE_CALLBACK_STATUS_MESSAGE "status-message" + +typedef struct { + char *uri; /* Full URI of operation */ + char *message; /* A message indicating the current state or + * NULL if there is no message */ + int percentage; /* Percentage indicating completeness 0-100 or + * -1 if there is no progress percentage to + * report */ + + /* Reserved "padding" to avoid future breaks in ABI compatibility */ + void *reserved1; + void *reserved2; +} GnomeVFSModuleCallbackStatusMessageIn; + +typedef struct { + int dummy; /* empty structs not allowed */ + + /* Reserved "padding" to avoid future breaks in ABI compatibility */ + void *reserved1; + void *reserved2; +} GnomeVFSModuleCallbackStatusMessageOut; + +G_END_DECLS + +#endif /* GNOME_VFS_STANDARD_CALLBACKS_H */ diff --git a/libgnomevfs/gnome-vfs-thread-pool.c b/libgnomevfs/gnome-vfs-thread-pool.c new file mode 100644 index 0000000..d9b801a --- /dev/null +++ b/libgnomevfs/gnome-vfs-thread-pool.c @@ -0,0 +1,266 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-thread-pool.c - Simple thread pool implementation + + Copyright (C) 2000 Eazel, Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Pavel Cisler +*/ + +#include +#include "gnome-vfs-thread-pool.h" +#include "gnome-vfs-job-queue.h" +#include +#include +#include + +#undef DEBUG_PRINT + +#define GNOME_VFS_THREAD_STACK_SIZE 256*1024 + +#if 0 +#define DEBUG_PRINT(x) g_print x +#else +#define DEBUG_PRINT(x) +#endif + +typedef struct { + GThread *thread; + GMutex *waiting_for_work_lock; + GCond *waiting_for_work_lock_condition; + + void *(* entry_point) (void *); + void *entry_data; + + volatile gboolean exit_requested; +} GnomeVFSThreadState; + +static GStaticMutex thread_list_lock = G_STATIC_MUTEX_INIT; + +static const int MAX_AVAILABLE_THREADS = 20; +static GList *available_threads; +static int thread_count; + +static void *thread_entry (void *cast_to_state); +static void destroy_thread_state (GnomeVFSThreadState *state); + +void +_gnome_vfs_thread_pool_init (void) +{ +} + +static GnomeVFSThreadState * +new_thread_state (void) +{ + GnomeVFSThreadState *state; + GError *error; + + state = g_new0 (GnomeVFSThreadState, 1); + + state->waiting_for_work_lock = g_mutex_new (); + state->waiting_for_work_lock_condition = g_cond_new (); + + error = NULL; + + /* spawn a new thread, call the entry point immediately -- it will block + * until it receives a new entry_point for the first job to execute + */ + state->thread = g_thread_create_full (thread_entry, state, + GNOME_VFS_THREAD_STACK_SIZE, + FALSE, FALSE, + G_THREAD_PRIORITY_NORMAL, &error); + + DEBUG_PRINT (("new thread %p\n", state->thread)); + + if (error != NULL || !state->thread) { + g_error_free (error); + return NULL; + } + + return state; +} + +static void +destroy_thread_state (GnomeVFSThreadState *state) +{ + g_mutex_free (state->waiting_for_work_lock); + g_cond_free (state->waiting_for_work_lock_condition); + g_free (state); +} + +static gboolean +make_thread_available (GnomeVFSThreadState *state) +{ + /* thread is done with it's work, add it to the available pool */ + gboolean delete_thread = TRUE; + int job_limit; + + g_mutex_lock (state->waiting_for_work_lock); + /* we are done with the last task, clear it out */ + state->entry_point = NULL; + g_mutex_unlock (state->waiting_for_work_lock); + + g_static_mutex_lock (&thread_list_lock); + + job_limit = gnome_vfs_async_get_job_limit(); + if (thread_count < MIN(MAX_AVAILABLE_THREADS, job_limit)) { + /* haven't hit the max thread limit yet, add the now available + * thread to the pool + */ + available_threads = g_list_prepend (available_threads, state); + thread_count++; + delete_thread = FALSE; + DEBUG_PRINT (("adding thread %p the pool, %d threads\n", + state->thread, thread_count)); + } + + g_static_mutex_unlock (&thread_list_lock); + + return !delete_thread; +} + +static void +gnome_vfs_thread_pool_wait_for_work (GnomeVFSThreadState *state) +{ + /* FIXME: The Eazel profiler should be taught about this call + * and ignore any timings it collects from the program hanging out + * in here. + */ + + /* Wait to get scheduled to do some work. */ + DEBUG_PRINT (("thread %p getting ready to wait for work \n", + state->thread)); + + g_mutex_lock (state->waiting_for_work_lock); + if (state->entry_point != NULL) { + DEBUG_PRINT (("thread %p ready to work right away \n", + state->thread)); + } else { + while (state->entry_point == NULL) { + /* Don't have any work yet, wait till we get some. */ + DEBUG_PRINT (("thread %p waiting for work \n", state->thread)); + g_cond_wait (state->waiting_for_work_lock_condition, + state->waiting_for_work_lock); + } + } + + g_mutex_unlock (state->waiting_for_work_lock); + DEBUG_PRINT (("thread %p woken up\n", state->thread)); +} + +static void * +thread_entry (void *cast_to_state) +{ + GnomeVFSThreadState *state = (GnomeVFSThreadState *)cast_to_state; + + for (;;) { + + if (state->exit_requested) { + /* We have been explicitly asked to expire */ + break; + } + + gnome_vfs_thread_pool_wait_for_work (state); + g_assert (state->entry_point); + + /* Enter the actual thread entry point. */ + (*state->entry_point) (state->entry_data); + + if (!make_thread_available (state)) { + /* Available thread pool is full of threads, just let this one + * expire. + */ + break; + } + + /* We're finished with this job so run the job queue scheduler + * to start a new job if the queue is not empty + */ + _gnome_vfs_job_queue_run (); + } + + destroy_thread_state (state); + return NULL; +} + +int +_gnome_vfs_thread_create (void *(* thread_routine) (void *), + void *thread_arguments) +{ + GnomeVFSThreadState *available_thread; + + g_static_mutex_lock (&thread_list_lock); + if (available_threads == NULL) { + /* Thread pool empty, create a new thread. */ + available_thread = new_thread_state (); + } else { + /* Pick the next available thread from the list. */ + available_thread = (GnomeVFSThreadState *)available_threads->data; + available_threads = g_list_remove (available_threads, available_thread); + thread_count--; + DEBUG_PRINT (("got thread %p from the pool, %d threads left\n", + available_thread->thread, thread_count)); + } + g_static_mutex_unlock (&thread_list_lock); + + if (available_thread == NULL) { + /* Failed to allocate a new thread. */ + return -1; + } + + /* Lock it so we can condition-signal it next. */ + g_mutex_lock (available_thread->waiting_for_work_lock); + + /* Prepare work for the thread. */ + available_thread->entry_point = thread_routine; + available_thread->entry_data = thread_arguments; + + /* Unleash the thread. */ + DEBUG_PRINT (("waking up thread %p\n", available_thread->thread)); + g_cond_signal (available_thread->waiting_for_work_lock_condition); + g_mutex_unlock (available_thread->waiting_for_work_lock); + + return 0; +} + +void +_gnome_vfs_thread_pool_shutdown (void) +{ + GnomeVFSThreadState *thread_state; + for (;;) { + thread_state = NULL; + + g_static_mutex_lock (&thread_list_lock); + if (available_threads != NULL) { + /* Pick the next thread from the list. */ + thread_state = (GnomeVFSThreadState *)available_threads->data; + available_threads = g_list_remove (available_threads, thread_state); + } + g_static_mutex_unlock (&thread_list_lock); + + if (thread_state == NULL) { + break; + } + + g_mutex_lock (thread_state->waiting_for_work_lock); + /* Tell the thread to expire. */ + thread_state->exit_requested = TRUE; + g_cond_signal (thread_state->waiting_for_work_lock_condition); + g_mutex_unlock (thread_state->waiting_for_work_lock); + } +} + diff --git a/libgnomevfs/gnome-vfs-thread-pool.h b/libgnomevfs/gnome-vfs-thread-pool.h new file mode 100644 index 0000000..45f58ea --- /dev/null +++ b/libgnomevfs/gnome-vfs-thread-pool.h @@ -0,0 +1,36 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-thread-pool.h - Simple thread pool implementation + + Copyright (C) 2000 Eazel, Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Pavel Cisler +*/ + +#ifndef GNOME_VFS_THREAD_POOL +#define GNOME_VFS_THREAD_POOL + +#include + +int _gnome_vfs_thread_create (void *(* thread_routine) (void *), + void *thread_arguments); + +void _gnome_vfs_thread_pool_init (void); +void _gnome_vfs_thread_pool_shutdown (void); +/* called during app shutdown, quit all the threads from the pool */ + +#endif diff --git a/libgnomevfs/gnome-vfs-transform.c b/libgnomevfs/gnome-vfs-transform.c new file mode 100644 index 0000000..f31ef9c --- /dev/null +++ b/libgnomevfs/gnome-vfs-transform.c @@ -0,0 +1,2 @@ +#include +#include "gnome-vfs-transform.h" diff --git a/libgnomevfs/gnome-vfs-transform.h b/libgnomevfs/gnome-vfs-transform.h new file mode 100644 index 0000000..3f8f399 --- /dev/null +++ b/libgnomevfs/gnome-vfs-transform.h @@ -0,0 +1,49 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-transform.h - transform function declarations + + Copyright (C) 1999, 2001 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli + Seth Nickell +*/ + +#ifndef GNOME_VFS_TRANSFORM_H +#define GNOME_VFS_TRANSFORM_H + +#include +#include + +G_BEGIN_DECLS + +typedef struct GnomeVFSTransform GnomeVFSTransform; + +typedef GnomeVFSTransform * (* GnomeVFSTransformInitFunc) (const char *method_name, + const char *config_args); + +typedef GnomeVFSResult (* GnomeVFSTransformFunc) (GnomeVFSTransform *transform, + const char *old_uri, + char **new_uri, + GnomeVFSContext *context); + +struct GnomeVFSTransform { + GnomeVFSTransformFunc transform; +}; + +G_END_DECLS + +#endif diff --git a/libgnomevfs/gnome-vfs-types.h b/libgnomevfs/gnome-vfs-types.h new file mode 100644 index 0000000..8059edc --- /dev/null +++ b/libgnomevfs/gnome-vfs-types.h @@ -0,0 +1,90 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-types.h - Types used by the GNOME Virtual File System. + + Copyright (C) 1999, 2001 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli + Seth Nickell +*/ + +#ifndef GNOME_VFS_TYPES_H +#define GNOME_VFS_TYPES_H + +#ifndef GNOME_VFS_DISABLE_DEPRECATED + +/* see gnome-vfs-file-size.h for GNOME_VFS_SIZE_IS_ */ +/* see gnome-vfs-file-size.h for GNOME_VFS_OFFSET_IS_ */ +/* see gnome-vfs-file-size.h for GNOME_VFS_SIZE_FORMAT_STR */ +/* see gnome-vfs-file-size.h for GNOME_VFS_OSFFSET_FORMAT_STR */ +/* see gnome-vfs-file-size.h for GnomeVFSFileSize */ +/* see gnome-vfs-file-size.h for GnomeVFSFileOffset */ +/* see gnome-vfs-result.h for GnomeVFSResult */ +/* see gnome-vfs-method.h for GnomeVFSOpenMode */ +/* see gnome-vfs-method.h for GnomeVFSSeekPosition */ +/* see gnome-vfs-file-info.h for GnomeVFSFileType */ +/* see gnome-vfs-file-info.h for GnomeVFSFilePermissions */ +/* see gnome-vfs-handle.h for GnomeVFSHandle */ +/* see gnome-vfs-uri.h for GnomeVFSURI */ +/* see gnome-vfs-uri.h for GnomeVFSToplevelURI */ +/* see gnome-vfs-uri.h for GnomeVFSURIHideOptions */ +/* see gnome-vfs-file-info.h for GnomeVFSFileFlags */ +/* see gnome-vfs-file-info.h for GnomeVFSFileInfoFields */ +/* see gnome-vfs-file-info.h for GnomeVFSFileInfo */ +/* see gnome-vfs-file-info.h for GnomeVFSFileInfoOptions */ +/* see gnome-vfs-file-info.h for GnomeVFSFileInfoMask */ +/* see gnome-vfs-find-directory.h for GnomeVFSFindDirectoryKind */ +/* see gnome-vfs-xfer.h for GnomeVFSXferOptions */ +/* see gnome-vfs-xfer.h for GnomeVFSXferProgressStatus */ +/* see gnome-vfs-xfer.h for GnomeVFSXferOverwriteMode */ +/* see gnome-vfs-xfer.h for GnomeVFSXferOverwriteAction */ +/* see gnome-vfs-xfer.h for GnomeVFSXferErrorMode */ +/* see gnome-vfs-xfer.h for GnomeVFSXferErrorAction */ +/* see gnome-vfs-xfer.h for GnomeVFSXferPhase */ +/* see gnome-vfs-xfer.h for GnomeVFSXferProgressInfo */ +/* see gnome-vfs-xfer.h for GnomeVFSXferProgressCallback */ +/* see gnome-vfs-async-ops.h for GnomeVFSAsyncHandle */ +/* see gnome-vfs-async-ops.h for GnomeVFSAsyncCallback */ +/* see gnome-vfs-async-ops.h for GnomeVFSAsyncOpenCallback */ +/* see gnome-vfs-async-ops.h for GnomeVFSAsyncCreateCallback */ +/* see gnome-vfs-async-ops.h for GnomeVFSAsyncOpenAsChannelCallback */ +/* see gnome-vfs-async-ops.h for GnomeVFSAsyncCloseCallback */ +/* see gnome-vfs-async-ops.h for GnomeVFSAsyncReadCallback */ +/* see gnome-vfs-async-ops.h for GnomeVFSAsyncWriteCallback */ +/* see gnome-vfs-file-info.h for GnomeVFSFileInfoResult */ +/* see gnome-vfs-async-ops.h for GnomeVFSAsyncGetFileInfoCallback */ +/* see gnome-vfs-async-ops.h for GnomeVFSAsyncSetFileInfoCallback */ +/* see gnome-vfs-async-ops.h for GnomeVFSAsyncDirectoryLoadCallback */ +/* see gnome-vfs-async-ops.h for GnomeVFSAsyncXferProgressCallback */ +/* see gnome-vfs-async-ops.h for GnomeVFSFindDirectoryResult */ +/* see gnome-vfs-async-ops.h for GnomeVFSAsyncFindDirectoryCallback */ +/* see gnome-vfs-module-callback.h for GnomeVFSModuleCallback */ + +/* Includes to provide compatibility with programs that + still include gnome-vfs-types.h directly */ +#include +#include +#include +#include +#include +#include +#include +#include + +#endif /* GNOME_VFS_DISABLE_DEPRECATED */ + +#endif /* GNOME_VFS_TYPES_H */ diff --git a/libgnomevfs/gnome-vfs-uri.c b/libgnomevfs/gnome-vfs-uri.c new file mode 100644 index 0000000..41b860c --- /dev/null +++ b/libgnomevfs/gnome-vfs-uri.c @@ -0,0 +1,2042 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-uri.c - URI handling for the GNOME Virtual File System. + + Copyright (C) 1999 Free Software Foundation + Copyright (C) 2000, 2001 Eazel, Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli + +*/ + +#include +#include "gnome-vfs-uri.h" + +#include "gnome-vfs-module.h" +#include "gnome-vfs-private-utils.h" +#include "gnome-vfs-transform.h" +#include "gnome-vfs-utils.h" +#include +#include +#include +#include +#include +#include + +/* + split_toplevel_uri + + Extract hostname and username from "path" with length "path_len" + + examples: + sunsite.unc.edu/pub/linux + miguel@sphinx.nuclecu.unam.mx/c/nc + tsx-11.mit.edu:8192/ + joe@foo.edu:11321/private + joe:password@foo.se + + This function implements the following regexp: (whitespace for clarity) + + ( ( ([^:@/]*) (:[^@/]*)? @ )? ([^/:]*) (:([0-9]*)?) )? (/.*)? + ( ( ( user ) ( pw )? )? (host) (port)? )? (path )? + + It returns NULL if neither nor could be matched. + + port is checked to ensure that it does not exceed 0xffff. + + return value is or is "/" if the path portion is not present + All other arguments are set to 0 or NULL if their portions are not present + + pedantic: this function ends up doing an unbounded lookahead, making it + potentially O(n^2) instead of O(n). This could be avoided. Realistically, though, + its just the password field. + + Differences between the old and the new implemention: + + Old New + localhost:8080 host="localhost:8080" host="localhost" port=8080 + /Users/mikef host="" host=NULL + +*/ + + +#define URI_MOVE_PAST_DELIMITER \ + do { \ + cur_tok_start = (++cur); \ + if (path_end == cur) { \ + success = FALSE; \ + goto done; \ + } \ + } while (0); + + +#define uri_strlen_to(from, to) ( (to) - (from) ) +#define uri_strdup_to(from, to) g_strndup ((from), uri_strlen_to((from), (to))) + +typedef struct { + const char *chrs; + gboolean primed; + char bv[32]; +} UriStrspnSet; + +UriStrspnSet uri_strspn_sets[] = { + {":@]" GNOME_VFS_URI_PATH_STR, FALSE, ""}, + {"@" GNOME_VFS_URI_PATH_STR, FALSE, ""}, + {":" GNOME_VFS_URI_PATH_STR, FALSE, ""}, + {"]" GNOME_VFS_URI_PATH_STR, FALSE, ""} +}; + +#define URI_DELIMITER_ALL_SET (uri_strspn_sets + 0) +#define URI_DELIMITER_USER_SET (uri_strspn_sets + 1) +#define URI_DELIMITER_HOST_SET (uri_strspn_sets + 2) +#define URI_DELIMITER_IPV6_SET (uri_strspn_sets + 3) + +#define BV_SET(bv, idx) (bv)[((guchar)(idx))>>3] |= (1 << ( (idx) & 7) ) +#define BV_IS_SET(bv, idx) ((bv)[((guchar)(idx))>>3] & (1 << ( (idx) & 7))) + +static const char * +uri_strspn_to(const char *str, UriStrspnSet *set, const char *path_end) +{ + const char *cur; + const char *cur_chr; + + if (!set->primed) { + memset (set->bv, 0, sizeof(set->bv)); + + for (cur_chr = set->chrs; '\0' != *cur_chr; cur_chr++) { + BV_SET (set->bv, *cur_chr); + } + + BV_SET (set->bv, '\0'); + set->primed = TRUE; + } + + for (cur = str; cur < path_end && ! BV_IS_SET (set->bv, *cur); cur++) + ; + + if (cur >= path_end || '\0' == *cur) { + return NULL; + } + + return cur; +} + + +static gchar * +split_toplevel_uri (const gchar *path, guint path_len, + gchar **host_return, gchar **user_return, + guint *port_return, gchar **password_return) +{ + const char *path_end; + const char *cur_tok_start; + const char *cur; + const char *next_delimiter; + char *ret; + char *host; + gboolean success; + + g_assert (host_return != NULL); + g_assert (user_return != NULL); + g_assert (port_return != NULL); + g_assert (password_return != NULL); + + *host_return = NULL; + *user_return = NULL; + *port_return = 0; + *password_return = NULL; + ret = NULL; + + success = FALSE; + + if (path == NULL || path_len == 0) { + return NULL; + } + + + path_end = path + path_len; + + cur_tok_start = path; + cur = uri_strspn_to (cur_tok_start, URI_DELIMITER_ALL_SET, path_end); + + if (cur != NULL) { + const char *tmp; + + if (*cur == ':') { + /* This ':' belongs to username or IPv6 address.*/ + tmp = uri_strspn_to (cur_tok_start, URI_DELIMITER_USER_SET, path_end); + + if (tmp == NULL || *tmp != '@') { + tmp = uri_strspn_to (cur_tok_start, URI_DELIMITER_IPV6_SET, path_end); + + if (tmp != NULL && *tmp == ']') { + cur = tmp; + } + } + } + } + + if (cur != NULL) { + + /* Check for IPv6 address. */ + if (*cur == ']') { + + /* No username:password in the URI */ + /* cur points to ']' */ + + cur = uri_strspn_to (cur, URI_DELIMITER_HOST_SET, path_end); + } + } + + if (cur != NULL) { + next_delimiter = uri_strspn_to (cur, URI_DELIMITER_USER_SET, path_end); + } else { + next_delimiter = NULL; + } + + if (cur != NULL + && (*cur == '@' + || (next_delimiter != NULL && *next_delimiter != '/' ))) { + + /* *cur == ':' or '@' and string contains a @ before a / */ + + if (uri_strlen_to (cur_tok_start, cur) > 0) { + *user_return = uri_strdup_to (cur_tok_start,cur); + } + + if (*cur == ':') { + URI_MOVE_PAST_DELIMITER; + + cur = uri_strspn_to(cur_tok_start, URI_DELIMITER_USER_SET, path_end); + + if (cur == NULL || *cur != '@') { + success = FALSE; + goto done; + } else if (uri_strlen_to (cur_tok_start, cur) > 0) { + *password_return = uri_strdup_to (cur_tok_start,cur); + } + } + + if (*cur != '/') { + URI_MOVE_PAST_DELIMITER; + + /* Move cur to point to ':' after ']' */ + cur = uri_strspn_to (cur_tok_start, URI_DELIMITER_IPV6_SET, path_end); + + if (cur != NULL && *cur == ']') { /* For IPv6 address */ + cur = uri_strspn_to (cur, URI_DELIMITER_HOST_SET, path_end); + } else { + cur = uri_strspn_to (cur_tok_start, URI_DELIMITER_HOST_SET, path_end); + } + } else { + cur_tok_start = cur; + } + } + + if (cur == NULL) { + /* [^:/]+$ */ + if (uri_strlen_to (cur_tok_start, path_end) > 0) { + *host_return = uri_strdup_to (cur_tok_start, path_end); + if (*(path_end - 1) == GNOME_VFS_URI_PATH_CHR) { + ret = g_strdup (GNOME_VFS_URI_PATH_STR); + } else { + ret = g_strdup (""); + } + success = TRUE; + } else { /* No host, no path */ + success = FALSE; + } + + goto done; + + } else if (*cur == ':') { + guint port; + /* [^:/]*:.* */ + + if (uri_strlen_to (cur_tok_start, cur) > 0) { + *host_return = uri_strdup_to (cur_tok_start, cur); + } else { + success = FALSE; + goto done; /*No host but a port?*/ + } + + URI_MOVE_PAST_DELIMITER; + + port = 0; + + for ( ; cur < path_end && g_ascii_isdigit (*cur); cur++) { + port *= 10; + port += *cur - '0'; + } + + /* We let :(/.*)$ be treated gracefully */ + if (*cur != '\0' && *cur != GNOME_VFS_URI_PATH_CHR) { + success = FALSE; + goto done; /* ...but this would be an error */ + } + + if (port > 0xffff) { + success = FALSE; + goto done; + } + + *port_return = port; + + cur_tok_start = cur; + + } else /* GNOME_VFS_URI_PATH_CHR == *cur */ { + /* ^[^:@/]+/.*$ */ + + if (uri_strlen_to (cur_tok_start, cur) > 0) { + *host_return = uri_strdup_to (cur_tok_start, cur); + } + + cur_tok_start = cur; + } + + if (*cur_tok_start != '\0' && uri_strlen_to (cur_tok_start, path_end) > 0) { + ret = uri_strdup_to(cur, path_end); + } else if (*host_return != NULL) { + ret = g_strdup (GNOME_VFS_URI_PATH_STR); + } + + success = TRUE; + +done: + if (*host_return != NULL) { + + /* Check for an IPv6 address in square brackets.*/ + if (strchr (*host_return, '[') && strchr (*host_return, ']') && strchr (*host_return, ':')) { + + /* Extract the IPv6 address from square braced string. */ + host = g_ascii_strdown ((*host_return) + 1, strlen (*host_return) - 2); + } else { + host = g_ascii_strdown (*host_return, -1); + } + + g_free (*host_return); + *host_return = host; + + } + + /* If we didn't complete our mission, discard all the partials */ + if (!success) { + g_free (*host_return); + g_free (*user_return); + g_free (*password_return); + g_free (ret); + + *host_return = NULL; + *user_return = NULL; + *port_return = 0; + *password_return = NULL; + ret = NULL; + } + + return ret; +} + + +static void +set_uri_element (GnomeVFSURI *uri, + const gchar *text, + guint len) +{ + char *escaped_text; + + if (text == NULL || len == 0) { + uri->text = g_strdup("/");; + return; + } + + if (uri->parent == NULL && text[0] == '/' && text[1] == '/') { + GnomeVFSToplevelURI *toplevel; + + toplevel = (GnomeVFSToplevelURI *) uri; + uri->text = split_toplevel_uri (text + 2, len - 2, + &toplevel->host_name, + &toplevel->user_name, + &toplevel->host_port, + &toplevel->password); + } else { + uri->text = g_strndup (text, len); + } + + /* FIXME: this should be handled/supported by the specific method. + * This is a quick and dirty hack to minimize the amount of changes + * right before a milestone release. + * + * Do some method specific escaping. This for instance converts + * '?' to %3F in every method except "http" where it has a special + * meaning. + */ + if ( ! (strcmp (uri->method_string, "http") == 0 + || strcmp (uri->method_string, "eazel-services") == 0 + || strcmp (uri->method_string, "ghelp") == 0 + || strcmp (uri->method_string, "gnome-help") == 0 + || strcmp (uri->method_string, "help") == 0 + )) { + + escaped_text = gnome_vfs_escape_set (uri->text, ";?&=+$,"); + g_free (uri->text); + uri->text = escaped_text; + } + + gnome_vfs_remove_optional_escapes (uri->text); + _gnome_vfs_canonicalize_pathname (uri->text); +} + +static const gchar * +get_method_string (const gchar *substring, gchar **method_string) +{ + const gchar *p; + char *method; + + for (p = substring; + g_ascii_isalnum (*p) || *p == '+' || *p == '-' || *p == '.'; + p++) + ; + + if (*p == ':') { + /* Found toplevel method specification. */ + method = g_strndup (substring, p - substring); + *method_string = g_ascii_strdown (method, -1); + g_free (method); + p++; + } else { + *method_string = g_strdup ("file"); + p = substring; + } + return p; +} + +static GnomeVFSURI * +parse_uri_substring (const gchar *substring, GnomeVFSURI *parent) +{ + GnomeVFSMethod *method; + GnomeVFSURI *uri, *child_uri; + gchar *method_string; + const gchar *method_scanner; + const gchar *extension_scanner; + + if (substring == NULL || *substring == '\0') { + return NULL; + } + + method_scanner = get_method_string (substring, &method_string); + + method = gnome_vfs_method_get (method_string); + if (!method) { + g_free (method_string); + return NULL; + } + + uri = g_new0 (GnomeVFSURI, 1); + uri->method = method; + uri->method_string = method_string; + uri->ref_count = 1; + uri->parent = parent; + + extension_scanner = strchr (method_scanner, GNOME_VFS_URI_MAGIC_CHR); + + if (extension_scanner == NULL) { + set_uri_element (uri, method_scanner, strlen (method_scanner)); + return uri; + } + + /* handle '#' */ + set_uri_element (uri, method_scanner, extension_scanner - method_scanner); + + if (strchr (extension_scanner, ':') == NULL) { + /* extension is a fragment identifier */ + uri->fragment_id = g_strdup (extension_scanner + 1); + return uri; + } + + /* extension is a uri chain */ + child_uri = parse_uri_substring (extension_scanner + 1, uri); + + if (child_uri != NULL) { + return child_uri; + } + + return uri; +} + +/** + * gnome_vfs_uri_new: + * @text_uri: A string representing a URI. + * + * Create a new URI from @text_uri. Unsupported and unsafe methods + * are not allowed and will result in %null% being returned. URL + * transforms are allowed. + * + * Return value: The new URI. + **/ +GnomeVFSURI * +gnome_vfs_uri_new (const gchar *text_uri) +{ + return gnome_vfs_uri_new_private (text_uri, FALSE, FALSE, TRUE); +} + +GnomeVFSURI * +gnome_vfs_uri_new_private (const gchar *text_uri, + gboolean allow_unknown_methods, + gboolean allow_unsafe_methods, + gboolean allow_transforms) +{ + GnomeVFSMethod *method; + GnomeVFSTransform *trans; + GnomeVFSToplevelURI *toplevel; + GnomeVFSURI *uri, *child_uri; + const gchar *method_scanner, *extension_scanner; + gchar *method_string; + gchar *new_uri_string = NULL; + + g_return_val_if_fail (text_uri != NULL, NULL); + + if (text_uri[0] == '\0') { + return NULL; + } + + method_scanner = get_method_string (text_uri, &method_string); + if (strcmp (method_string, "pipe") == 0 && !allow_unsafe_methods) { + g_free (method_string); + return NULL; + } + + toplevel = g_new (GnomeVFSToplevelURI, 1); + toplevel->host_name = NULL; + toplevel->host_port = 0; + toplevel->user_name = NULL; + toplevel->password = NULL; + + uri = (GnomeVFSURI *) toplevel; + uri->parent = NULL; + + if (allow_transforms) { + trans = gnome_vfs_transform_get (method_string); + if (trans != NULL && trans->transform) { + const GnomeVFSContext *context; + + context = gnome_vfs_context_peek_current (); + (* trans->transform) (trans, + method_scanner, + &new_uri_string, + (GnomeVFSContext *) context); + if (new_uri_string != NULL) { + toplevel->urn = g_strdup (text_uri); + g_free (method_string); + method_scanner = get_method_string (new_uri_string, &method_string); + } + } + } + + method = gnome_vfs_method_get (method_string); + /* The toplevel URI element is special, as it also contains host/user + information. */ + uri->method = method; + uri->ref_count = 1; + uri->method_string = method_string; + uri->text = NULL; + uri->fragment_id = NULL; + if (method == NULL && !allow_unknown_methods) { + g_free (new_uri_string); + gnome_vfs_uri_unref (uri); + return NULL; + } + + extension_scanner = strchr (method_scanner, GNOME_VFS_URI_MAGIC_CHR); + if (extension_scanner == NULL) { + set_uri_element (uri, method_scanner, strlen (method_scanner)); + g_free (new_uri_string); + return uri; + } + + /* handle '#' */ + set_uri_element (uri, method_scanner, extension_scanner - method_scanner); + + if (strchr (extension_scanner, ':') == NULL) { + /* extension is a fragment identifier */ + uri->fragment_id = g_strdup (extension_scanner + 1); + g_free (new_uri_string); + return uri; + } + + /* extension is a uri chain */ + child_uri = parse_uri_substring (extension_scanner + 1, uri); + + g_free (new_uri_string); + + if (child_uri != NULL) { + return child_uri; + } + + return uri; +} + +/* Destroy an URI element, but not its parent. */ +static void +destroy_element (GnomeVFSURI *uri) +{ + g_free (uri->text); + g_free (uri->fragment_id); + g_free (uri->method_string); + + if (uri->parent == NULL) { + GnomeVFSToplevelURI *toplevel; + + toplevel = (GnomeVFSToplevelURI *) uri; + g_free (toplevel->host_name); + g_free (toplevel->user_name); + g_free (toplevel->password); + } + + g_free (uri); +} + +static gboolean +is_uri_relative (const char *uri) +{ + const char *current; + + /* RFC 2396 section 3.1 */ + for (current = uri ; + *current + && ((*current >= 'a' && *current <= 'z') + || (*current >= 'A' && *current <= 'Z') + || (*current >= '0' && *current <= '9') + || ('-' == *current) + || ('+' == *current) + || ('.' == *current)) ; + current++); + + return !(':' == *current); +} + + +/* + * Remove "./" segments + * Compact "../" segments inside the URI + * Remove "." at the end of the URL + * Leave any ".."'s at the beginning of the URI + +*/ +/* + * FIXME this is not the simplest or most time-efficent way + * to do this. Probably a far more clear way of doing this processing + * is to split the path into segments, rather than doing the processing + * in place. + */ +static void +remove_internal_relative_components (char *uri_current) +{ + char *segment_prev, *segment_cur; + gsize len_prev, len_cur; + + len_prev = len_cur = 0; + segment_prev = NULL; + + segment_cur = uri_current; + + while (*segment_cur) { + len_cur = strcspn (segment_cur, "/"); + + if (len_cur == 1 && segment_cur[0] == '.') { + /* Remove "." 's */ + if (segment_cur[1] == '\0') { + segment_cur[0] = '\0'; + break; + } else { + memmove (segment_cur, segment_cur + 2, strlen (segment_cur + 2) + 1); + continue; + } + } else if (len_cur == 2 && segment_cur[0] == '.' && segment_cur[1] == '.' ) { + /* Remove ".."'s (and the component to the left of it) that aren't at the + * beginning or to the right of other ..'s + */ + if (segment_prev) { + if (! (len_prev == 2 + && segment_prev[0] == '.' + && segment_prev[1] == '.')) { + if (segment_cur[2] == '\0') { + segment_prev[0] = '\0'; + break; + } else { + memmove (segment_prev, segment_cur + 3, strlen (segment_cur + 3) + 1); + + segment_cur = segment_prev; + len_cur = len_prev; + + /* now we find the previous segment_prev */ + if (segment_prev == uri_current) { + segment_prev = NULL; + } else if (segment_prev - uri_current >= 2) { + segment_prev -= 2; + for ( ; segment_prev > uri_current && segment_prev[0] != '/' + ; segment_prev-- ); + if (segment_prev[0] == '/') { + segment_prev++; + } + } + continue; + } + } + } + } + + /*Forward to next segment */ + + if (segment_cur [len_cur] == '\0') { + break; + } + + segment_prev = segment_cur; + len_prev = len_cur; + segment_cur += len_cur + 1; + } + +} + +/* If I had known this relative uri code would have ended up this long, I would + * have done it a different way + */ +static char * +make_full_uri_from_relative (const char *base_uri, const char *uri) +{ + char *result = NULL; + + char *mutable_base_uri; + char *mutable_uri; + + char *uri_current; + gsize base_uri_length; + char *separator; + + /* We may need one extra character + * to append a "/" to uri's that have no "/" + * (such as help:) + */ + + mutable_base_uri = g_malloc(strlen(base_uri)+2); + strcpy (mutable_base_uri, base_uri); + + uri_current = mutable_uri = g_strdup (uri); + + /* Chew off Fragment and Query from the base_url */ + + separator = strrchr (mutable_base_uri, '#'); + + if (separator) { + *separator = '\0'; + } + + separator = strrchr (mutable_base_uri, '?'); + + if (separator) { + *separator = '\0'; + } + + if ('/' == uri_current[0] && '/' == uri_current [1]) { + /* Relative URI's beginning with the authority + * component inherit only the scheme from their parents + */ + + separator = strchr (mutable_base_uri, ':'); + + if (separator) { + separator[1] = '\0'; + } + } else if ('/' == uri_current[0]) { + /* Relative URI's beginning with '/' absolute-path based + * at the root of the base uri + */ + + separator = strchr (mutable_base_uri, ':'); + + /* g_assert (separator), really */ + if (separator) { + /* If we start with //, skip past the authority section */ + if ('/' == separator[1] && '/' == separator[2]) { + separator = strchr (separator + 3, '/'); + if (separator) { + separator[0] = '\0'; + } + } else { + /* If there's no //, just assume the scheme is the root */ + separator[1] = '\0'; + } + } + } else if ('#' != uri_current[0]) { + /* Handle the ".." convention for relative uri's */ + + /* If there's a trailing '/' on base_url, treat base_url + * as a directory path. + * Otherwise, treat it as a file path, and chop off the filename + */ + + base_uri_length = strlen (mutable_base_uri); + if ('/' == mutable_base_uri[base_uri_length-1]) { + /* Trim off '/' for the operation below */ + mutable_base_uri[base_uri_length-1] = 0; + } else { + separator = strrchr (mutable_base_uri, '/'); + if (separator) { + /* Make sure we don't eat a domain part */ + gchar *tmp = (gchar*)((int)separator - 1); + if ((separator != mutable_base_uri) && (*tmp != '/')) { + *separator = '\0'; + } + } + } + + remove_internal_relative_components (uri_current); + + /* handle the "../"'s at the beginning of the relative URI */ + while (0 == strncmp ("../", uri_current, 3)) { + uri_current += 3; + separator = strrchr (mutable_base_uri, '/'); + if (separator) { + *separator = '\0'; + } else { + /* */ + break; + } + } + + /* handle a ".." at the end */ + if (uri_current[0] == '.' && uri_current[1] == '.' + && uri_current[2] == '\0') { + + uri_current += 2; + separator = strrchr (mutable_base_uri, '/'); + if (separator) { + *separator = '\0'; + } + } + + /* Re-append the '/' */ + mutable_base_uri [strlen(mutable_base_uri)+1] = '\0'; + mutable_base_uri [strlen(mutable_base_uri)] = '/'; + } + + result = g_strconcat (mutable_base_uri, uri_current, NULL); + g_free (mutable_base_uri); + g_free (mutable_uri); + + return result; +} + +/** + * gnome_vfs_uri_resolve_relative + * @base: The base URI. + * @relative_reference: A string representing a possibly relative URI reference + * + * Create a new URI from @relative_reference, relative to @base. + * + * Return value: The new URI. + **/ +GnomeVFSURI * +gnome_vfs_uri_resolve_relative (const GnomeVFSURI *base, + const gchar *relative_reference) +{ + char *text_base; + char *text_new; + GnomeVFSURI *uri; + + g_assert (relative_reference != NULL); + + if (base == NULL) { + text_base = g_strdup (""); + } else { + text_base = gnome_vfs_uri_to_string (base, 0); + } + + if (is_uri_relative (relative_reference)) { + text_new = make_full_uri_from_relative (text_base, + relative_reference); + } else { + text_new = g_strdup (relative_reference); + } + + uri = gnome_vfs_uri_new (text_new); + + g_free (text_base); + g_free (text_new); + + return uri; +} + +/** + * gnome_vfs_uri_ref: + * @uri: A GnomeVFSURI. + * + * Increment @uri's reference count. + * + * Return value: @uri. + **/ +GnomeVFSURI * +gnome_vfs_uri_ref (GnomeVFSURI *uri) +{ + GnomeVFSURI *p; + + g_return_val_if_fail (uri != NULL, NULL); + + for (p = uri; p != NULL; p = p->parent) + p->ref_count++; + + return uri; +} + +/** + * gnome_vfs_uri_unref: + * @uri: A GnomeVFSURI. + * + * Decrement @uri's reference count. If the reference count reaches zero, + * @uri is destroyed. + **/ +void +gnome_vfs_uri_unref (GnomeVFSURI *uri) +{ + GnomeVFSURI *p, *parent; + + g_return_if_fail (uri != NULL); + g_return_if_fail (uri->ref_count > 0); + + for (p = uri; p != NULL; p = parent) { + parent = p->parent; + g_assert (p->ref_count > 0); + p->ref_count--; + if (p->ref_count == 0) + destroy_element (p); + } +} + +/** + * gnome_vfs_uri_dup: + * @uri: A GnomeVFSURI. + * + * Duplicate @uri. + * + * Return value: A pointer to a new URI that is exactly the same as @uri. + **/ +GnomeVFSURI * +gnome_vfs_uri_dup (const GnomeVFSURI *uri) +{ + const GnomeVFSURI *p; + GnomeVFSURI *new_uri, *child; + + if (uri == NULL) { + return NULL; + } + + new_uri = NULL; + child = NULL; + for (p = uri; p != NULL; p = p->parent) { + GnomeVFSURI *new_element; + + if (p->parent == NULL) { + GnomeVFSToplevelURI *toplevel; + GnomeVFSToplevelURI *new_toplevel; + + toplevel = (GnomeVFSToplevelURI *) p; + new_toplevel = g_new (GnomeVFSToplevelURI, 1); + + new_toplevel->host_name = g_strdup (toplevel->host_name); + new_toplevel->host_port = toplevel->host_port; + new_toplevel->user_name = g_strdup (toplevel->user_name); + new_toplevel->password = g_strdup (toplevel->password); + + new_element = (GnomeVFSURI *) new_toplevel; + } else { + new_element = g_new (GnomeVFSURI, 1); + } + + new_element->ref_count = 1; + new_element->text = g_strdup (p->text); + new_element->fragment_id = g_strdup (p->fragment_id); + new_element->method_string = g_strdup (p->method_string); + new_element->method = p->method; + new_element->parent = NULL; + + if (child != NULL) { + child->parent = new_element; + } else { + new_uri = new_element; + } + + child = new_element; + } + + return new_uri; +} + +/** + * gnome_vfs_uri_append_string: + * @uri: A GnomeVFSURI. + * @uri_fragment: A piece of a URI (ie a fully escaped partial path) + * + * Create a new URI obtained by appending @path to @uri. This will take care + * of adding an appropriate directory separator between the end of @uri and + * the start of @path if necessary. + * + * Return value: The new URI obtained by combining @uri and @path. + **/ +GnomeVFSURI * +gnome_vfs_uri_append_string (const GnomeVFSURI *uri, + const gchar *uri_fragment) +{ + gchar *uri_string; + GnomeVFSURI *new_uri; + gchar *new_string; + guint len; + + g_return_val_if_fail (uri != NULL, NULL); + g_return_val_if_fail (uri_fragment != NULL, NULL); + + uri_string = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE); + len = strlen (uri_string); + if (len == 0) { + g_free (uri_string); + return gnome_vfs_uri_new (uri_fragment); + } + + len--; + while (uri_string[len] == GNOME_VFS_URI_PATH_CHR && len > 0) { + len--; + } + + uri_string[len + 1] = '\0'; + + while (*uri_fragment == GNOME_VFS_URI_PATH_CHR) { + uri_fragment++; + } + + if (uri_fragment[0] != GNOME_VFS_URI_MAGIC_CHR) { + new_string = g_strconcat (uri_string, GNOME_VFS_URI_PATH_STR, uri_fragment, NULL); + } else { + new_string = g_strconcat (uri_string, uri_fragment, NULL); + } + new_uri = gnome_vfs_uri_new (new_string); + + g_free (new_string); + g_free (uri_string); + + return new_uri; +} + +/** + * gnome_vfs_uri_append_path: + * @uri: A GnomeVFSURI. + * @path: A non-escaped file path + * + * Create a new URI obtained by appending @path to @uri. This will take care + * of adding an appropriate directory separator between the end of @uri and + * the start of @path if necessary as well as escaping @path as necessary. + * + * Return value: The new URI obtained by combining @uri and @path. + **/ +GnomeVFSURI * +gnome_vfs_uri_append_path (const GnomeVFSURI *uri, + const gchar *path) +{ + gchar *escaped_string; + GnomeVFSURI *new_uri; + + escaped_string = gnome_vfs_escape_path_string (path); + new_uri = gnome_vfs_uri_append_string (uri, escaped_string); + g_free (escaped_string); + return new_uri; +} + +/** + * gnome_vfs_uri_append_file_name: + * @uri: A GnomeVFSURI. + * @filename: any "regular" file name (can include #, /, etc) + * + * Create a new URI obtained by appending @file_name to @uri. This will take care + * of adding an appropriate directory separator between the end of @uri and + * the start of @file_name if necessary. + * + * Return value: The new URI obtained by combining @uri and @path. + **/ +GnomeVFSURI * +gnome_vfs_uri_append_file_name (const GnomeVFSURI *uri, + const gchar *filename) +{ + gchar *escaped_string; + GnomeVFSURI *new_uri; + + escaped_string = gnome_vfs_escape_string (filename); + new_uri = gnome_vfs_uri_append_string (uri, escaped_string); + g_free (escaped_string); + return new_uri; +} + + +/** + * gnome_vfs_uri_to_string: + * @uri: A GnomeVFSURI. + * @hide_options: Bitmask specifying what URI elements (e.g. password, + * user name etc.) should not be represented in the returned string. + * + * Translate @uri into a printable string. The string will not contain the + * URI elements specified by @hide_options. + * + * Return value: A malloced printable string representing @uri. + **/ +gchar * +gnome_vfs_uri_to_string (const GnomeVFSURI *uri, + GnomeVFSURIHideOptions hide_options) +{ + GString *string; + gchar *result; + + string = g_string_new (uri->method_string); + g_string_append_c (string, ':'); + + if (uri->parent == NULL) { + GnomeVFSToplevelURI *top_level_uri = (GnomeVFSToplevelURI *)uri; + gboolean shown_user_pass = FALSE; + + if (top_level_uri->user_name != NULL + || top_level_uri->host_name != NULL + || (uri->text != NULL && uri->text[0] == GNOME_VFS_URI_PATH_CHR)) { + /* don't append '//' for uris such as pipe:foo */ + g_string_append (string, "//"); + } + + if ((hide_options & GNOME_VFS_URI_HIDE_TOPLEVEL_METHOD) != 0) { + g_string_free (string, TRUE); /* throw away method */ + string = g_string_new (""); + } + + if (top_level_uri->user_name != NULL + && (hide_options & GNOME_VFS_URI_HIDE_USER_NAME) == 0) { + g_string_append (string, top_level_uri->user_name); + shown_user_pass = TRUE; + } + + if (top_level_uri->password != NULL + && (hide_options & GNOME_VFS_URI_HIDE_PASSWORD) == 0) { + g_string_append_c (string, ':'); + g_string_append (string, top_level_uri->password); + shown_user_pass = TRUE; + } + + if (shown_user_pass) { + g_string_append_c (string, '@'); + } + + if (top_level_uri->host_name != NULL + && (hide_options & GNOME_VFS_URI_HIDE_HOST_NAME) == 0) { + + /* Check for an IPv6 address. */ + + if (strchr (top_level_uri->host_name, ':')) { + g_string_append_c (string, '['); + g_string_append (string, top_level_uri->host_name); + g_string_append_c (string, ']'); + } else { + g_string_append (string, top_level_uri->host_name); + } + } + + if (top_level_uri->host_port > 0 + && (hide_options & GNOME_VFS_URI_HIDE_HOST_PORT) == 0) { + gchar tmp[128]; + sprintf (tmp, ":%d", top_level_uri->host_port); + g_string_append (string, tmp); + } + + } + + if (uri->text != NULL) { + g_string_append (string, uri->text); + } + + if (uri->fragment_id != NULL + && (hide_options & GNOME_VFS_URI_HIDE_FRAGMENT_IDENTIFIER) == 0) { + g_string_append_c (string, '#'); + g_string_append (string, uri->fragment_id); + } + + if (uri->parent != NULL) { + gchar *uri_str; + uri_str = gnome_vfs_uri_to_string (uri->parent, hide_options); + g_string_prepend_c (string, '#'); + g_string_prepend (string, uri_str); + g_free (uri_str); + } + + result = string->str; + g_string_free (string, FALSE); + + return result; +} + +/** + * gnome_vfs_uri_is_local: + * @uri: A GnomeVFSURI. + * + * Check if @uri is a local (native) file system. + * + * Return value: %FALSE if @uri is not a local file system, %TRUE otherwise. + **/ +gboolean +gnome_vfs_uri_is_local (const GnomeVFSURI *uri) +{ + g_return_val_if_fail (uri != NULL, FALSE); + + /* It's illegal to have is_local be NULL in a method. + * That's why we fail here. If we decide that it's legal, + * then we can change this into an if statement. + */ + g_return_val_if_fail (VFS_METHOD_HAS_FUNC (uri->method, is_local), FALSE); + + return uri->method->is_local (uri->method, uri); +} + +/** + * gnome_vfs_uri_has_parent: + * @uri: A GnomeVFSURI. + * + * Check if URI has a parent or not. + * + * Return value: %TRUE if @uri has a parent, %FALSE otherwise. + **/ +gboolean +gnome_vfs_uri_has_parent (const GnomeVFSURI *uri) +{ + GnomeVFSURI *parent; + + parent = gnome_vfs_uri_get_parent (uri); + if (parent == NULL) { + return FALSE; + } + + gnome_vfs_uri_unref (parent); + return TRUE; +} + +/** + * gnome_vfs_uri_get_parent: + * @uri: A GnomeVFSURI. + * + * Retrieve @uri's parent URI. + * + * Return value: A pointer to @uri's parent URI. + **/ +GnomeVFSURI * +gnome_vfs_uri_get_parent (const GnomeVFSURI *uri) +{ + g_return_val_if_fail (uri != NULL, NULL); + + if (uri->text != NULL && strchr (uri->text, GNOME_VFS_URI_PATH_CHR) != NULL) { + gchar *p; + guint len; + + len = strlen (uri->text); + p = uri->text + len - 1; + + /* Skip trailing slashes */ + while (p != uri->text && *p == GNOME_VFS_URI_PATH_CHR) + p--; + + /* Search backwards to the next slash. */ + while (p != uri->text && *p != GNOME_VFS_URI_PATH_CHR) + p--; + + /* Get the parent without slashes */ + while (p > uri->text + 1 && p[-1] == GNOME_VFS_URI_PATH_CHR) + p--; + + if (p[1] != '\0') { + GnomeVFSURI *new_uri; + char *new_uri_text; + int length; + + /* build a new parent text */ + length = p - uri->text; + if (length == 0) { + new_uri_text = g_strdup (GNOME_VFS_URI_PATH_STR); + } else { + new_uri_text = g_malloc (length + 1); + memcpy (new_uri_text, uri->text, length); + new_uri_text[length] = '\0'; + } + + /* copy the uri and replace the uri text with the new parent text */ + new_uri = gnome_vfs_uri_dup (uri); + g_free (new_uri->text); + new_uri->text = new_uri_text; + + /* The parent doesn't have the child's fragment */ + g_free (new_uri->fragment_id); + new_uri->fragment_id = NULL; + + return new_uri; + } + } + + return gnome_vfs_uri_dup (uri->parent); +} + +/** + * gnome_vfs_uri_get_toplevel: + * @uri: A GnomeVFSURI. + * + * Retrieve the toplevel URI in @uri. + * + * Return value: A pointer to the toplevel URI object. + **/ +GnomeVFSToplevelURI * +gnome_vfs_uri_get_toplevel (const GnomeVFSURI *uri) +{ + const GnomeVFSURI *p; + + g_return_val_if_fail (uri != NULL, NULL); + + for (p = uri; p->parent != NULL; p = p->parent) + ; + + return (GnomeVFSToplevelURI *) p; +} + +/** + * gnome_vfs_uri_get_host_name: + * @uri: A GnomeVFSURI. + * + * Retrieve the host name for @uri. + * + * Return value: A string representing the host name. + **/ +const gchar * +gnome_vfs_uri_get_host_name (const GnomeVFSURI *uri) +{ + GnomeVFSToplevelURI *toplevel; + + g_return_val_if_fail (uri != NULL, NULL); + + toplevel = gnome_vfs_uri_get_toplevel (uri); + return toplevel->host_name; +} + +/** + * gnome_vfs_uri_get_scheme: + * @uri: A GnomeVFSURI + * + * Retrieve the scheme used for @uri + * + * Return value: A string representing the scheme + **/ +const gchar * +gnome_vfs_uri_get_scheme (const GnomeVFSURI *uri) +{ + return uri->method_string; +} + +/** + * gnome_vfs_uri_get_host_port: + * @uri: A GnomeVFSURI. + * + * Retrieve the host port number in @uri. + * + * Return value: The host port number used by @uri. If the value is zero, the + * default port value for the specified toplevel access method is used. + **/ +guint +gnome_vfs_uri_get_host_port (const GnomeVFSURI *uri) +{ + GnomeVFSToplevelURI *toplevel; + + g_return_val_if_fail (uri != NULL, 0); + + toplevel = gnome_vfs_uri_get_toplevel (uri); + return toplevel->host_port; +} + +/** + * gnome_vfs_uri_get_user_name: + * @uri: A GnomeVFSURI. + * + * Retrieve the user name in @uri. + * + * Return value: A string representing the user name in @uri. + **/ +const gchar * +gnome_vfs_uri_get_user_name (const GnomeVFSURI *uri) +{ + GnomeVFSToplevelURI *toplevel; + + g_return_val_if_fail (uri != NULL, NULL); + + toplevel = gnome_vfs_uri_get_toplevel (uri); + return toplevel->user_name; +} + +/** + * gnome_vfs_uri_get_password: + * @uri: A GnomeVFSURI. + * + * Retrieve the password for @uri. + * + * Return value: The password for @uri. + **/ +const gchar * +gnome_vfs_uri_get_password (const GnomeVFSURI *uri) +{ + GnomeVFSToplevelURI *toplevel; + + g_return_val_if_fail (uri != NULL, NULL); + + toplevel = gnome_vfs_uri_get_toplevel (uri); + return toplevel->password; +} + +/** + * gnome_vfs_uri_set_host_name: + * @uri: A GnomeVFSURI. + * @host_name: A string representing a host name. + * + * Set @host_name as the host name accessed by @uri. + **/ +void +gnome_vfs_uri_set_host_name (GnomeVFSURI *uri, + const gchar *host_name) +{ + GnomeVFSToplevelURI *toplevel; + + g_return_if_fail (uri != NULL); + + toplevel = gnome_vfs_uri_get_toplevel (uri); + + g_free (toplevel->host_name); + toplevel->host_name = g_strdup (host_name); +} + +/** + * gnome_vfs_uri_set_host_port: + * @uri: A GnomeVFSURI. + * @host_port: A TCP/IP port number. + * + * Set the host port number in @uri. If @host_port is zero, the default port + * for @uri's toplevel access method is used. + **/ +void +gnome_vfs_uri_set_host_port (GnomeVFSURI *uri, + guint host_port) +{ + GnomeVFSToplevelURI *toplevel; + + g_return_if_fail (uri != NULL); + + toplevel = gnome_vfs_uri_get_toplevel (uri); + + toplevel->host_port = host_port; +} + +/** + * gnome_vfs_uri_set_user_name: + * @uri: A GnomeVFSURI. + * @user_name: A string representing a user name on the host accessed by @uri. + * + * Set @user_name as the user name for @uri. + **/ +void +gnome_vfs_uri_set_user_name (GnomeVFSURI *uri, + const gchar *user_name) +{ + GnomeVFSToplevelURI *toplevel; + + g_return_if_fail (uri != NULL); + + toplevel = gnome_vfs_uri_get_toplevel (uri); + + g_free (toplevel->user_name); + toplevel->user_name = g_strdup (user_name); +} + +/** + * gnome_vfs_uri_set_password: + * @uri: A GnomeVFSURI. + * @password: A password string. + * + * Set @password as the password for @uri. + **/ +void +gnome_vfs_uri_set_password (GnomeVFSURI *uri, + const gchar *password) +{ + GnomeVFSToplevelURI *toplevel; + + g_return_if_fail (uri != NULL); + + toplevel = gnome_vfs_uri_get_toplevel (uri); + + g_free (toplevel->password); + toplevel->password = g_strdup (password); +} + +static gboolean +string_match (const gchar *a, const gchar *b) +{ + if (a == NULL || *a == '\0') { + return b == NULL || *b == '\0'; + } + + if (a == NULL || b == NULL) + return FALSE; + + return strcmp (a, b) == 0; +} + +static gboolean +compare_elements (const GnomeVFSURI *a, + const GnomeVFSURI *b) +{ + if (!string_match (a->text, b->text) + || !string_match (a->method_string, b->method_string)) + return FALSE; + + /* The following should never fail, but we make sure anyway. */ + return a->method == b->method; +} + +/** + * gnome_vfs_uri_equal: + * @a: A GnomeVFSURI. + * @b: A GnomeVFSURI. + * + * Compare @a and @b. + * + * Return value: %TRUE if @a and @b are equal, %FALSE otherwise. + * + * FIXME: This comparison should take into account the possiblity + * that unreserved characters may be escaped. + * ...or perhaps gnome_vfs_uri_new should unescape unreserved characters? + **/ +gboolean +gnome_vfs_uri_equal (const GnomeVFSURI *a, + const GnomeVFSURI *b) +{ + const GnomeVFSToplevelURI *toplevel_a; + const GnomeVFSToplevelURI *toplevel_b; + + g_return_val_if_fail (a != NULL, FALSE); + g_return_val_if_fail (b != NULL, FALSE); + + /* First check non-toplevel elements. */ + while (a->parent != NULL && b->parent != NULL) { + if (!compare_elements (a, b)) { + return FALSE; + } + } + + /* Now we should be at toplevel for both. */ + if (a->parent != NULL || b->parent != NULL) { + return FALSE; + } + + if (!compare_elements (a, b)) { + return FALSE; + } + + toplevel_a = (GnomeVFSToplevelURI *) a; + toplevel_b = (GnomeVFSToplevelURI *) b; + + /* Finally, compare the extra toplevel members. */ + return toplevel_a->host_port == toplevel_b->host_port + && string_match (toplevel_a->host_name, toplevel_b->host_name) + && string_match (toplevel_a->user_name, toplevel_b->user_name) + && string_match (toplevel_a->password, toplevel_b->password); +} + +/* Convenience function that deals with the problem where we distinguish + * uris "foo://bar.com" and "foo://bar.com/" but we do not define + * what a child item of "foo://bar.com" would be -- to work around this, + * we will consider both "foo://bar.com" and "foo://bar.com/" the parent + * of "foo://bar.com/child" + */ +static gboolean +uri_matches_as_parent (const GnomeVFSURI *possible_parent, const GnomeVFSURI *parent) +{ + GnomeVFSURI *alternate_possible_parent; + gboolean result; + + if (possible_parent->text == NULL || + strlen (possible_parent->text) == 0) { + alternate_possible_parent = gnome_vfs_uri_append_string (possible_parent, + GNOME_VFS_URI_PATH_STR); + + result = gnome_vfs_uri_equal (alternate_possible_parent, parent); + + gnome_vfs_uri_unref (alternate_possible_parent); + return result; + } + + return gnome_vfs_uri_equal (possible_parent, parent); +} + +/** + * gnome_vfs_uri_is_parent: + * @possible_parent: A GnomeVFSURI. + * @possible_child: A GnomeVFSURI. + * @recursive: a flag to turn recursive check on. + * + * Check if @possible_child is contained by @possible_parent. + * If @recursive is FALSE, just try the immediate parent directory, else + * search up through the hierarchy. + * + * Return value: %TRUE if @possible_child is contained in @possible_child. + **/ +gboolean +gnome_vfs_uri_is_parent (const GnomeVFSURI *possible_parent, + const GnomeVFSURI *possible_child, + gboolean recursive) +{ + gboolean result; + GnomeVFSURI *item_parent_uri; + GnomeVFSURI *item; + + if (!recursive) { + item_parent_uri = gnome_vfs_uri_get_parent (possible_child); + + if (item_parent_uri == NULL) { + return FALSE; + } + + result = uri_matches_as_parent (possible_parent, item_parent_uri); + gnome_vfs_uri_unref (item_parent_uri); + + return result; + } + + item = gnome_vfs_uri_dup (possible_child); + for (;;) { + item_parent_uri = gnome_vfs_uri_get_parent (item); + gnome_vfs_uri_unref (item); + + if (item_parent_uri == NULL) { + return FALSE; + } + + result = uri_matches_as_parent (possible_parent, item_parent_uri); + + if (result) { + gnome_vfs_uri_unref (item_parent_uri); + break; + } + + item = item_parent_uri; + } + + return result; +} + +/** + * gnome_vfs_uri_get_path: + * @uri: A GnomeVFSURI + * + * Retrieve full path name for @uri. + * + * Return value: A pointer to the full path name in @uri. Notice that the + * pointer points to the name store in @uri, so the name returned must not + * be modified nor freed. + **/ +const gchar * +gnome_vfs_uri_get_path (const GnomeVFSURI *uri) +{ + /* FIXME bugzilla.eazel.com 1472 */ + /* this is based on the assumtion that uri->text won't contain the + * query string. + */ + g_return_val_if_fail (uri != NULL, NULL); + + return uri->text; +} + +/** + * gnome_vfs_uri_get_fragment_id: + * @uri: A GnomeVFSURI + * + * Retrieve the optional fragment identifier for @uri. + * + * Return value: A pointer to the fragment identifier for the uri or NULL. + **/ +const gchar * +gnome_vfs_uri_get_fragment_identifier (const GnomeVFSURI *uri) +{ + g_return_val_if_fail (uri != NULL, NULL); + + return uri->fragment_id; +} + +/** + * gnome_vfs_uri_extract_dirname: + * @uri: A GnomeVFSURI + * + * Extract the name of the directory in which the file pointed to by @uri is + * stored as a newly allocated string. The string will end with a + * GNOME_VFS_URI_PATH_CHR. + * + * Return value: A pointer to the newly allocated string representing the + * parent directory. + **/ +gchar * +gnome_vfs_uri_extract_dirname (const GnomeVFSURI *uri) +{ + const gchar *base; + + g_return_val_if_fail (uri != NULL, NULL); + + if (uri->text == NULL) { + return NULL; + } + + base = strrchr (uri->text, GNOME_VFS_URI_PATH_CHR); + + if (base == NULL || base == uri->text) { + return g_strdup (GNOME_VFS_URI_PATH_STR); + } + + return g_strndup (uri->text, base - uri->text); +} + +/** + * gnome_vfs_uri_extract_short_name: + * @uri: A GnomeVFSURI + * + * Retrieve base file name for @uri, ignoring any trailing path separators. + * This matches the XPG definition of basename, but not g_basename. This is + * often useful when you want the name of something that's pointed to by a + * uri, and don't care whether the uri has a directory or file form. + * If @uri points to the root of a domain, returns the host name. If there's + * no host name, returns GNOME_VFS_URI_PATH_STR. + * + * See also: gnome_vfs_uri_extract_short_path_name. + * + * Return value: A pointer to the newly allocated string representing the + * unescaped short form of the name. + **/ +gchar * +gnome_vfs_uri_extract_short_name (const GnomeVFSURI *uri) +{ + gchar *escaped_short_path_name, *short_path_name; + const gchar *host_name; + + escaped_short_path_name = gnome_vfs_uri_extract_short_path_name (uri); + short_path_name = gnome_vfs_unescape_string (escaped_short_path_name, "/"); + g_free (escaped_short_path_name); + + host_name = NULL; + if (short_path_name != NULL + && strcmp (short_path_name, GNOME_VFS_URI_PATH_STR) == 0) { + host_name = gnome_vfs_uri_get_host_name (uri); + } + + if (host_name == NULL || strlen (host_name) == 0) { + return short_path_name; + } + + g_free (short_path_name); + return g_strdup (host_name); +} + +/** + * gnome_vfs_uri_extract_short_path_name: + * @uri: A GnomeVFSURI + * + * Retrieve base file name for @uri, ignoring any trailing path separators. + * This matches the XPG definition of basename, but not g_basename. This is + * often useful when you want the name of something that's pointed to by a + * uri, and don't care whether the uri has a directory or file form. + * If @uri points to the root (including the root of any domain), + * returns GNOME_VFS_URI_PATH_STR. + * + * See also: gnome_vfs_uri_extract_short_name. + * + * Return value: A pointer to the newly allocated string representing the + * escaped short form of the name. + **/ +gchar * +gnome_vfs_uri_extract_short_path_name (const GnomeVFSURI *uri) +{ + const gchar *p, *short_name_start, *short_name_end; + + g_return_val_if_fail (uri != NULL, NULL); + + if (uri->text == NULL) { + return NULL; + } + + /* Search for the last run of non-'/' characters. */ + p = uri->text; + short_name_start = NULL; + short_name_end = p; + do { + if (*p == '\0' || *p == GNOME_VFS_URI_PATH_CHR) { + /* While we are in a run of non-separators, short_name_end is NULL. */ + if (short_name_end == NULL) + short_name_end = p; + } else { + /* While we are in a run of separators, short_name_end is not NULL. */ + if (short_name_end != NULL) { + short_name_start = p; + short_name_end = NULL; + } + } + } while (*p++ != '\0'); + g_assert (short_name_end != NULL); + + /* If we never found a short name, that means that the string is all + directory separators. Since it can't be an empty string, that means + it points to the root, so "/" is a good result. + */ + if (short_name_start == NULL) { + return g_strdup (GNOME_VFS_URI_PATH_STR); + } + + /* Return a copy of the short name. */ + return g_strndup (short_name_start, short_name_end - short_name_start); +} + +/* The following functions are useful for creating URI hash tables. */ + +/** + * gnome_vfs_uri_hequal: + * @a: a pointer to a GnomeVFSURI + * @b: a pointer to a GnomeVFSURI + * + * Function intended for use as a hash table "are these two items + * the same" comparison. Useful for creating a hash table of URIs. + * + * Return value: %TRUE if the URIs are the same + **/ +gint +gnome_vfs_uri_hequal (gconstpointer a, + gconstpointer b) +{ + return gnome_vfs_uri_equal (a, b); +} + +/** + * gnome_vfs_uri_hash: + * @p: a pointer to a GnomeVFSURI + * + * Creates an integer value from a GnomeVFSURI, appropriate + * for using as the key to a hash table entry. + * + * Return value: a hash key corresponding to @p + **/ +guint +gnome_vfs_uri_hash (gconstpointer p) +{ + const GnomeVFSURI *uri; + const GnomeVFSURI *uri_p; + guint hash_value; + +#define HASH_STRING(value, string) \ + if ((string) != NULL) \ + (value) ^= g_str_hash (string); + +#define HASH_NUMBER(value, number) \ + (value) ^= number; + + uri = (const GnomeVFSURI *) p; + hash_value = 0; + + for (uri_p = uri; uri_p != NULL; uri_p = uri_p->parent) { + HASH_STRING (hash_value, uri_p->text); + HASH_STRING (hash_value, uri_p->method_string); + + if (uri_p->parent != NULL) { + const GnomeVFSToplevelURI *toplevel; + + toplevel = (const GnomeVFSToplevelURI *) uri_p; + + HASH_STRING (hash_value, toplevel->host_name); + HASH_NUMBER (hash_value, toplevel->host_port); + HASH_STRING (hash_value, toplevel->user_name); + HASH_STRING (hash_value, toplevel->password); + } + } + + return hash_value; + +#undef HASH_STRING +#undef HASH_NUMBER +} + +/** + * gnome_vfs_uri_list_ref: + * @list: list of GnomeVFSURI elements + * + * Increments the reference count of the items in @list by one. + * + * Return value: @list + **/ +GList * +gnome_vfs_uri_list_ref (GList *list) +{ + g_list_foreach (list, (GFunc) gnome_vfs_uri_ref, NULL); + return list; +} + +/** + * gnome_vfs_uri_list_unref: + * @list: list of GnomeVFSURI elements + * + * Decrements the reference count of the items in @list by one. + * Note that the list is *not freed* even if each member of the list + * is freed. + * + * Return value: @list + **/ +GList * +gnome_vfs_uri_list_unref (GList *list) +{ + g_list_foreach (list, (GFunc) gnome_vfs_uri_unref, NULL); + return list; +} + +/** + * gnome_vfs_uri_list_copy: + * @list: list of GnomeVFSURI elements + * + * Creates a duplicate of @list, and references each member of + * that list. + * + * Return value: a newly referenced duplicate of @list + **/ +GList * +gnome_vfs_uri_list_copy (GList *list) +{ + return g_list_copy (gnome_vfs_uri_list_ref (list)); +} + +/** + * gnome_vfs_uri_list_free: + * @list: list of GnomeVFSURI elements + * + * Decrements the reference count of each member of @list by one, + * and frees the list itself. + **/ +void +gnome_vfs_uri_list_free (GList *list) +{ + g_list_free (gnome_vfs_uri_list_unref (list)); +} + +/** + * gnome_vfs_uri_make_full_from_relative: + * @base_uri: a string representing the base URI + * @relative_uri: a URI fragment/reference to be appended to @base_uri + * + * Returns a full URI given a full base URI, and a secondary URI which may + * be relative. + * + * Return value: a newly allocated string containing the URI + * (NULL for some bad errors). + **/ +char * +gnome_vfs_uri_make_full_from_relative (const char *base_uri, + const char *relative_uri) +{ + char *result = NULL; + + /* See section 5.2 in RFC 2396 */ + + if (base_uri == NULL && relative_uri == NULL) { + result = NULL; + } else if (base_uri == NULL) { + result = g_strdup (relative_uri); + } else if (relative_uri == NULL) { + result = g_strdup (base_uri); + } else if (is_uri_relative (relative_uri)) { + result = make_full_uri_from_relative (base_uri, relative_uri); + } else { + result = g_strdup (relative_uri); + } + + return result; +} + +/** + * gnome_vfs_uri_list_parse: + * @uri_list: + * + * Extracts a list of #GnomeVFSURI objects from a standard text/uri-list, + * such as one you would get on a drop operation. Use + * #gnome_vfs_uri_list_free when you are done with the list. + * + * Return value: A GList of GnomeVFSURIs + **/ +GList* +gnome_vfs_uri_list_parse (const gchar* uri_list) +{ + /* Note that this is mostly very stolen from old libgnome/gnome-mime.c */ + + const gchar *p, *q; + gchar *retval; + GnomeVFSURI *uri; + GList *result = NULL; + + g_return_val_if_fail (uri_list != NULL, NULL); + + p = uri_list; + + /* We don't actually try to validate the URI according to RFC + * 2396, or even check for allowed characters - we just ignore + * comments and trim whitespace off the ends. We also + * allow LF delimination as well as the specified CRLF. + */ + while (p != NULL) { + if (*p != '#') { + while (g_ascii_isspace (*p)) + p++; + + q = p; + while ((*q != '\0') + && (*q != '\n') + && (*q != '\r')) + q++; + + if (q > p) { + q--; + while (q > p + && g_ascii_isspace (*q)) + q--; + + retval = g_malloc (q - p + 2); + strncpy (retval, p, q - p + 1); + retval[q - p + 1] = '\0'; + + uri = gnome_vfs_uri_new (retval); + + g_free (retval); + + if (uri != NULL) + result = g_list_prepend (result, uri); + } + } + p = strchr (p, '\n'); + if (p != NULL) + p++; + } + + return g_list_reverse (result); +} diff --git a/libgnomevfs/gnome-vfs-uri.h b/libgnomevfs/gnome-vfs-uri.h new file mode 100644 index 0000000..23f251b --- /dev/null +++ b/libgnomevfs/gnome-vfs-uri.h @@ -0,0 +1,200 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-uri.h - URI handling for the GNOME Virtual File System. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli +*/ + +#ifndef GNOME_VFS_URI_H +#define GNOME_VFS_URI_H + +#include + +G_BEGIN_DECLS + +/* This describes a URI element. */ +typedef struct GnomeVFSURI { + /* Reference count. */ + guint ref_count; + + /* Text for the element: eg. some/path/name. */ + gchar *text; + + /* Text for uri fragment: eg, #anchor */ + gchar *fragment_id; + + /* Method string: eg. `gzip', `tar', `http'. This is necessary as + one GnomeVFSMethod can be used for different method strings + (e.g. extfs handles zip, rar, zoo and several other ones). */ + gchar *method_string; + + /* VFS method to access the element. */ + struct GnomeVFSMethod *method; + + /* Pointer to the parent element, or NULL for toplevel elements. */ + struct GnomeVFSURI *parent; + + /* Reserved to avoid future breaks in ABI compatibility */ + void *reserved1; + void *reserved2; +} GnomeVFSURI; + +/* This is the toplevel URI element. A toplevel method implementations should + cast the `GnomeVFSURI' argument to this type to get the additional host/auth + information. If any of the elements is 0, it is unspecified. */ +typedef struct { + /* Base object. */ + GnomeVFSURI uri; + + /* Server location information. */ + gchar *host_name; + guint host_port; + + /* Authorization information. */ + gchar *user_name; + gchar *password; + + /* The parent URN, if it exists */ + gchar *urn; + + /* Reserved to avoid future breaks in ABI compatibility */ + void *reserved1; + void *reserved2; + +} GnomeVFSToplevelURI; + + +/** + * GnomeVFSURIHideOptions: + * @GNOME_VFS_URI_HIDE_NONE: don't hide anything + * @GNOME_VFS_URI_HIDE_USER_NAME: hide the user name + * @GNOME_VFS_URI_HIDE_PASSWORD: hide the password + * @GNOME_VFS_URI_HIDE_HOST_NAME: hide the host name + * @GNOME_VFS_URI_HIDE_HOST_PORT: hide the port + * @GNOME_VFS_URI_HIDE_TOPLEVEL_METHOD: hide the method (e.g. http, file) + * @GNOME_VFS_URI_HIDE_FRAGMENT_IDENTIFIER: hide the fragment identifier + * + * Packed boolean bitfield controlling hiding of various elements + * of a GnomeVFSURI when it is converted to a string. + **/ +typedef enum { + GNOME_VFS_URI_HIDE_NONE = 0, + GNOME_VFS_URI_HIDE_USER_NAME = 1 << 0, + GNOME_VFS_URI_HIDE_PASSWORD = 1 << 1, + GNOME_VFS_URI_HIDE_HOST_NAME = 1 << 2, + GNOME_VFS_URI_HIDE_HOST_PORT = 1 << 3, + GNOME_VFS_URI_HIDE_TOPLEVEL_METHOD = 1 << 4, + GNOME_VFS_URI_HIDE_FRAGMENT_IDENTIFIER = 1 << 8 +} GnomeVFSURIHideOptions; + + +/** + * GNOME_VFS_URI_MAGIC_CHR: + * + * The character used to divide location from + * extra "arguments" passed to the method. + **/ +/** + * GNOME_VFS_URI_MAGIC_STR: + * + * The character used to divide location from + * extra "arguments" passed to the method. + **/ +#define GNOME_VFS_URI_MAGIC_CHR '#' +#define GNOME_VFS_URI_MAGIC_STR "#" + +/** + * GNOME_VFS_URI_PATH_CHR: + * + * Defines the path seperator character. + **/ +/** + * GNOME_VFS_URI_PATH_STR: + * + * Defines the path seperator string. + **/ +#define GNOME_VFS_URI_PATH_CHR '/' +#define GNOME_VFS_URI_PATH_STR "/" + +/* FUNCTIONS */ +GnomeVFSURI *gnome_vfs_uri_new (const gchar *text_uri); +GnomeVFSURI *gnome_vfs_uri_resolve_relative (const GnomeVFSURI *base, + const gchar *relative_reference); +GnomeVFSURI *gnome_vfs_uri_ref (GnomeVFSURI *uri); +void gnome_vfs_uri_unref (GnomeVFSURI *uri); + +GnomeVFSURI *gnome_vfs_uri_append_string (const GnomeVFSURI *uri, + const char *uri_fragment); +GnomeVFSURI *gnome_vfs_uri_append_path (const GnomeVFSURI *uri, + const char *path); +GnomeVFSURI *gnome_vfs_uri_append_file_name (const GnomeVFSURI *uri, + const gchar *filename); +gchar *gnome_vfs_uri_to_string (const GnomeVFSURI *uri, + GnomeVFSURIHideOptions hide_options); +GnomeVFSURI *gnome_vfs_uri_dup (const GnomeVFSURI *uri); +gboolean gnome_vfs_uri_is_local (const GnomeVFSURI *uri); +gboolean gnome_vfs_uri_has_parent (const GnomeVFSURI *uri); +GnomeVFSURI *gnome_vfs_uri_get_parent (const GnomeVFSURI *uri); + +GnomeVFSToplevelURI *gnome_vfs_uri_get_toplevel (const GnomeVFSURI *uri); + +const gchar *gnome_vfs_uri_get_host_name (const GnomeVFSURI *uri); +const gchar *gnome_vfs_uri_get_scheme (const GnomeVFSURI *uri); +guint gnome_vfs_uri_get_host_port (const GnomeVFSURI *uri); +const gchar *gnome_vfs_uri_get_user_name (const GnomeVFSURI *uri); +const gchar *gnome_vfs_uri_get_password (const GnomeVFSURI *uri); + +void gnome_vfs_uri_set_host_name (GnomeVFSURI *uri, + const gchar *host_name); +void gnome_vfs_uri_set_host_port (GnomeVFSURI *uri, + guint host_port); +void gnome_vfs_uri_set_user_name (GnomeVFSURI *uri, + const gchar *user_name); +void gnome_vfs_uri_set_password (GnomeVFSURI *uri, + const gchar *password); + +gboolean gnome_vfs_uri_equal (const GnomeVFSURI *a, + const GnomeVFSURI *b); + +gboolean gnome_vfs_uri_is_parent (const GnomeVFSURI *possible_parent, + const GnomeVFSURI *possible_child, + gboolean recursive); + +const gchar *gnome_vfs_uri_get_path (const GnomeVFSURI *uri); +const gchar *gnome_vfs_uri_get_fragment_identifier (const GnomeVFSURI *uri); +gchar *gnome_vfs_uri_extract_dirname (const GnomeVFSURI *uri); +gchar *gnome_vfs_uri_extract_short_name (const GnomeVFSURI *uri); +gchar *gnome_vfs_uri_extract_short_path_name (const GnomeVFSURI *uri); + +gint gnome_vfs_uri_hequal (gconstpointer a, + gconstpointer b); +guint gnome_vfs_uri_hash (gconstpointer p); + +GList *gnome_vfs_uri_list_parse (const gchar* uri_list); +GList *gnome_vfs_uri_list_ref (GList *list); +GList *gnome_vfs_uri_list_unref (GList *list); +GList *gnome_vfs_uri_list_copy (GList *list); +void gnome_vfs_uri_list_free (GList *list); + +char *gnome_vfs_uri_make_full_from_relative (const char *base_uri, + const char *relative_uri); + +G_END_DECLS + +#endif /* GNOME_VFS_URI_H */ diff --git a/libgnomevfs/gnome-vfs-utils.c b/libgnomevfs/gnome-vfs-utils.c new file mode 100644 index 0000000..8732fbd --- /dev/null +++ b/libgnomevfs/gnome-vfs-utils.c @@ -0,0 +1,2065 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* gnome-vfs-utils.c - Private utility functions for the GNOME Virtual + File System. + + Copyright (C) 1999 Free Software Foundation + Copyright (C) 2000, 2001 Eazel, Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Ettore Perazzoli + John Sullivan + Darin Adler +*/ + +#include +#ifdef HAVE_SYS_PARAM_H +#include +#endif +#include "gnome-vfs-utils.h" + +#include "gnome-vfs-i18n.h" +#include "gnome-vfs-private-utils.h" +#include "gnome-vfs-ops.h" +#include "gnome-vfs-mime-handlers.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if HAVE_SYS_STATVFS_H +#include +#endif + +#if HAVE_SYS_VFS_H +#include +#elif HAVE_SYS_MOUNT_H +#include +#endif + +#define KILOBYTE_FACTOR 1024.0 +#define MEGABYTE_FACTOR (1024.0 * 1024.0) +#define GIGABYTE_FACTOR (1024.0 * 1024.0 * 1024.0) + +#define READ_CHUNK_SIZE 8192 + +#define MAX_SYMLINKS_FOLLOWED 32 + + +/** + * gnome_vfs_format_file_size_for_display: + * @size: + * + * Formats the file size passed in @bytes in a way that is easy for + * the user to read. Gives the size in bytes, kilobytes, megabytes or + * gigabytes, choosing whatever is appropriate. + * + * Returns: a newly allocated string with the size ready to be shown. + **/ + +gchar* +gnome_vfs_format_file_size_for_display (GnomeVFSFileSize size) +{ + if (size < (GnomeVFSFileSize) KILOBYTE_FACTOR) { + if (size == 1) + return g_strdup (_("1 byte")); + else + return g_strdup_printf (_("%u bytes"), + (guint) size); + } else { + gdouble displayed_size; + + if (size < (GnomeVFSFileSize) MEGABYTE_FACTOR) { + displayed_size = (gdouble) size / KILOBYTE_FACTOR; + return g_strdup_printf (_("%.1f K"), + displayed_size); + } else if (size < (GnomeVFSFileSize) GIGABYTE_FACTOR) { + displayed_size = (gdouble) size / MEGABYTE_FACTOR; + return g_strdup_printf (_("%.1f MB"), + displayed_size); + } else { + displayed_size = (gdouble) size / GIGABYTE_FACTOR; + return g_strdup_printf (_("%.1f GB"), + displayed_size); + } + } +} + +typedef enum { + UNSAFE_ALL = 0x1, /* Escape all unsafe characters */ + UNSAFE_ALLOW_PLUS = 0x2, /* Allows '+' */ + UNSAFE_PATH = 0x4, /* Allows '/' and '?' and '&' and '=' */ + UNSAFE_DOS_PATH = 0x8, /* Allows '/' and '?' and '&' and '=' and ':' */ + UNSAFE_HOST = 0x10, /* Allows '/' and ':' and '@' */ + UNSAFE_SLASHES = 0x20 /* Allows all characters except for '/' and '%' */ +} UnsafeCharacterSet; + +static const guchar acceptable[96] = +{ /* X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 XA XB XC XD XE XF */ + 0x00,0x3F,0x20,0x20,0x20,0x00,0x2C,0x3F,0x3F,0x3F,0x3F,0x22,0x20,0x3F,0x3F,0x1C, /* 2X !"#$%&'()*+,-./ */ + 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x38,0x20,0x20,0x2C,0x20,0x2C, /* 3X 0123456789:;<=>? */ + 0x30,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F, /* 4X @ABCDEFGHIJKLMNO */ + 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x20,0x20,0x20,0x20,0x3F, /* 5X PQRSTUVWXYZ[\]^_ */ + 0x20,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F, /* 6X `abcdefghijklmno */ + 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x20,0x20,0x20,0x3F,0x20 /* 7X pqrstuvwxyz{|}~DEL */ +}; + +enum { + RESERVED = 1, + UNRESERVED, + DELIMITERS, + UNWISE, + CONTROL, + SPACE +}; + +static const guchar uri_character_kind[128] = +{ + CONTROL ,CONTROL ,CONTROL ,CONTROL ,CONTROL ,CONTROL ,CONTROL ,CONTROL , + CONTROL ,CONTROL ,CONTROL ,CONTROL ,CONTROL ,CONTROL ,CONTROL ,CONTROL , + CONTROL ,CONTROL ,CONTROL ,CONTROL ,CONTROL ,CONTROL ,CONTROL ,CONTROL , + CONTROL ,CONTROL ,CONTROL ,CONTROL ,CONTROL ,CONTROL ,CONTROL ,CONTROL , + /* ' ' ! " # $ % & ' */ + SPACE ,UNRESERVED,DELIMITERS,DELIMITERS,RESERVED ,DELIMITERS,RESERVED ,UNRESERVED, + /* ( ) * + , - . / */ + UNRESERVED,UNRESERVED,UNRESERVED,RESERVED ,RESERVED ,UNRESERVED,UNRESERVED,RESERVED , + /* 0 1 2 3 4 5 6 7 */ + UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED, + /* 8 9 : ; < = > ? */ + UNRESERVED,UNRESERVED,RESERVED ,RESERVED ,DELIMITERS,RESERVED ,DELIMITERS,RESERVED , + /* @ A B C D E F G */ + RESERVED ,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED, + /* H I J K L M N O */ + UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED, + /* P Q R S T U V W */ + UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED, + /* X Y Z [ \ ] ^ _ */ + UNRESERVED,UNRESERVED,UNRESERVED,UNWISE ,UNWISE ,UNWISE ,UNWISE ,UNRESERVED, + /* ` a b c d e f g */ + UNWISE ,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED, + /* h i j k l m n o */ + UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED, + /* p q r s t u v w */ + UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED, + /* x y z { | } ~ DEL */ + UNRESERVED,UNRESERVED,UNRESERVED,UNWISE ,UNWISE ,UNWISE ,UNRESERVED,CONTROL +}; + + +/* Below modified from libwww HTEscape.c */ + +#define HEX_ESCAPE '%' + +/* Escape undesirable characters using % + * ------------------------------------- + * + * This function takes a pointer to a string in which + * some characters may be unacceptable unescaped. + * It returns a string which has these characters + * represented by a '%' character followed by two hex digits. + * + * This routine returns a g_malloced string. + */ + +static const gchar hex[16] = "0123456789ABCDEF"; + +static gchar * +gnome_vfs_escape_string_internal (const gchar *string, + UnsafeCharacterSet mask) +{ +#define ACCEPTABLE_CHAR(a) ((a)>=32 && (a)<128 && (acceptable[(a)-32] & use_mask)) + + const gchar *p; + gchar *q; + gchar *result; + guchar c; + gint unacceptable; + UnsafeCharacterSet use_mask; + + g_return_val_if_fail (mask == UNSAFE_ALL + || mask == UNSAFE_ALLOW_PLUS + || mask == UNSAFE_PATH + || mask == UNSAFE_DOS_PATH + || mask == UNSAFE_HOST + || mask == UNSAFE_SLASHES, NULL); + + if (string == NULL) { + return NULL; + } + + unacceptable = 0; + use_mask = mask; + for (p = string; *p != '\0'; p++) { + c = *p; + if (!ACCEPTABLE_CHAR (c)) { + unacceptable++; + } + if ((use_mask == UNSAFE_HOST) && + (unacceptable || (c == '/'))) { + /* when escaping a host, if we hit something that needs to be escaped, or we finally + * hit a path separator, revert to path mode (the host segment of the url is over). + */ + use_mask = UNSAFE_PATH; + } + } + + result = g_malloc (p - string + unacceptable * 2 + 1); + + use_mask = mask; + for (q = result, p = string; *p != '\0'; p++){ + c = *p; + + if (!ACCEPTABLE_CHAR (c)) { + *q++ = HEX_ESCAPE; /* means hex coming */ + *q++ = hex[c >> 4]; + *q++ = hex[c & 15]; + } else { + *q++ = c; + } + if ((use_mask == UNSAFE_HOST) && + (!ACCEPTABLE_CHAR (c) || (c == '/'))) { + use_mask = UNSAFE_PATH; + } + } + + *q = '\0'; + + return result; +} + +/** + * gnome_vfs_escape_string: + * @string: string to be escaped + * + * Escapes @string, replacing any and all special characters + * with equivalent escape sequences. + * + * Return value: a newly allocated string equivalent to @string + * but with all special characters escaped + **/ +gchar * +gnome_vfs_escape_string (const gchar *string) +{ + return gnome_vfs_escape_string_internal (string, UNSAFE_ALL); +} + +/** + * gnome_vfs_escape_path_string: + * @path: string to be escaped + * + * Escapes @path, replacing only special characters that would not + * be found in paths (so '/', '&', '=', and '?' will not be escaped by + * this function). + * + * Return value: a newly allocated string equivalent to @path but + * with non-path characters escaped + **/ +gchar * +gnome_vfs_escape_path_string (const gchar *path) +{ + return gnome_vfs_escape_string_internal (path, UNSAFE_PATH); +} + +/** + * gnome_vfs_escape_host_and_path_string: + * @path: string to be escaped + * + * Escapes @path, replacing only special characters that would not + * be found in paths or host name (so '/', '&', '=', ':', '@' + * and '?' will not be escaped by this function). + * + * Return value: a newly allocated string equivalent to @path but + * with non-path/host characters escaped + **/ +gchar * +gnome_vfs_escape_host_and_path_string (const gchar *path) +{ + return gnome_vfs_escape_string_internal (path, UNSAFE_HOST); +} + +/** + * gnome_vfs_escape_slashes: + * @string: string to be escaped + * + * Escapes only '/' and '%' characters in @string, replacing + * them with their escape sequence equivalents. + * + * Return value: a newly allocated string equivalent to @string, + * but with no unescaped '/' or '%' characters + **/ +gchar * +gnome_vfs_escape_slashes (const gchar *string) +{ + return gnome_vfs_escape_string_internal (string, UNSAFE_SLASHES); +} + +char * +gnome_vfs_escape_set (const char *string, + const char *match_set) +{ + char *result; + const char *scanner; + char *result_scanner; + int escape_count; + + escape_count = 0; + + if (string == NULL) { + return NULL; + } + + if (match_set == NULL) { + return g_strdup (string); + } + + for (scanner = string; *scanner != '\0'; scanner++) { + if (strchr(match_set, *scanner) != NULL) { + /* this character is in the set of characters + * we want escaped. + */ + escape_count++; + } + } + + if (escape_count == 0) { + return g_strdup (string); + } + + /* allocate two extra characters for every character that + * needs escaping and space for a trailing zero + */ + result = g_malloc (scanner - string + escape_count * 2 + 1); + for (scanner = string, result_scanner = result; *scanner != '\0'; scanner++) { + if (strchr(match_set, *scanner) != NULL) { + /* this character is in the set of characters + * we want escaped. + */ + *result_scanner++ = HEX_ESCAPE; + *result_scanner++ = hex[*scanner >> 4]; + *result_scanner++ = hex[*scanner & 15]; + + } else { + *result_scanner++ = *scanner; + } + } + + *result_scanner = '\0'; + + return result; +} + +/** + * gnome_vfs_expand_initial_tilde: + * @path: a local file path which may start with a '~' + * + * If @path starts with a ~, representing the user's home + * directory, expand it to the actual path location. + * + * Return value: a newly allocated string with the initial + * tilde (if there was one) converted to an actual path + **/ +char * +gnome_vfs_expand_initial_tilde (const char *path) +{ + char *slash_after_user_name, *user_name; + struct passwd *passwd_file_entry; + + g_return_val_if_fail (path != NULL, NULL); + + if (path[0] != '~') { + return g_strdup (path); + } + + if (path[1] == '/' || path[1] == '\0') { + return g_strconcat (g_get_home_dir (), &path[1], NULL); + } + + slash_after_user_name = strchr (&path[1], '/'); + if (slash_after_user_name == NULL) { + user_name = g_strdup (&path[1]); + } else { + user_name = g_strndup (&path[1], + slash_after_user_name - &path[1]); + } + passwd_file_entry = getpwnam (user_name); + g_free (user_name); + + if (passwd_file_entry == NULL || passwd_file_entry->pw_dir == NULL) { + return g_strdup (path); + } + + return g_strconcat (passwd_file_entry->pw_dir, + slash_after_user_name, + NULL); +} + +static int +hex_to_int (gchar c) +{ + return c >= '0' && c <= '9' ? c - '0' + : c >= 'A' && c <= 'F' ? c - 'A' + 10 + : c >= 'a' && c <= 'f' ? c - 'a' + 10 + : -1; +} + +static int +unescape_character (const char *scanner) +{ + int first_digit; + int second_digit; + + first_digit = hex_to_int (*scanner++); + if (first_digit < 0) { + return -1; + } + + second_digit = hex_to_int (*scanner++); + if (second_digit < 0) { + return -1; + } + + return (first_digit << 4) | second_digit; +} + +/** + * gnome_vfs_unescape_string: + * @escaped_string: an escaped URI, path, or other string + * @illegal_characters: a string containing a sequence of characters + * considered "illegal", '\0' is automatically in this list. + * + * Decodes escaped characters (i.e. PERCENTxx sequences) in @escaped_string. + * Characters are encoded in PERCENTxy form, where xy is the ASCII hex code + * for character 16x+y. + * + * Return value: a newly allocated string with the unescaped equivalents, + * or %NULL if @escaped_string contained one of the characters + * in @illegal_characters. + **/ +char * +gnome_vfs_unescape_string (const gchar *escaped_string, + const gchar *illegal_characters) +{ + const gchar *in; + gchar *out, *result; + gint character; + + if (escaped_string == NULL) { + return NULL; + } + + result = g_malloc (strlen (escaped_string) + 1); + + out = result; + for (in = escaped_string; *in != '\0'; in++) { + character = *in; + if (*in == HEX_ESCAPE) { + character = unescape_character (in + 1); + + /* Check for an illegal character. We consider '\0' illegal here. */ + if (character <= 0 + || (illegal_characters != NULL + && strchr (illegal_characters, (char)character) != NULL)) { + g_free (result); + return NULL; + } + in += 2; + } + *out++ = (char)character; + } + + *out = '\0'; + g_assert (out - result <= strlen (escaped_string)); + return result; + +} + +/** + * gnome_vfs_unescape_for_display: + * @escaped: The string encoded with escaped sequences + * + * Similar to gnome_vfs_unescape_string, but it returns something + * semi-intelligable to a user even upon receiving traumatic input + * such as %00 or URIs in bad form. + * + * See also: gnome_vfs_unescape_string. + * + * Return value: A pointer to a g_malloc'd string with all characters + * replacing their escaped hex values + * + * WARNING: You should never use this function on a whole URI! It + * unescapes reserved characters, and can result in a mangled URI + * that can not be re-entered. For example, it unescapes "#" "&" and "?", + * which have special meanings in URI strings. + **/ +gchar * +gnome_vfs_unescape_string_for_display (const gchar *escaped) +{ + const gchar *in, *start_escape; + gchar *out, *result; + gint i,j; + gchar c; + gint invalid_escape; + + if (escaped == NULL) { + return NULL; + } + + result = g_malloc (strlen (escaped) + 1); + + out = result; + for (in = escaped; *in != '\0'; ) { + start_escape = in; + c = *in++; + invalid_escape = 0; + + if (c == HEX_ESCAPE) { + /* Get the first hex digit. */ + i = hex_to_int (*in++); + if (i < 0) { + invalid_escape = 1; + in--; + } + c = i << 4; + + if (invalid_escape == 0) { + /* Get the second hex digit. */ + i = hex_to_int (*in++); + if (i < 0) { + invalid_escape = 2; + in--; + } + c |= i; + } + if (invalid_escape == 0) { + /* Check for an illegal character. */ + if (c == '\0') { + invalid_escape = 3; + } + } + } + if (invalid_escape != 0) { + for (j = 0; j < invalid_escape; j++) { + *out++ = *start_escape++; + } + } else { + *out++ = c; + } + } + + *out = '\0'; + g_assert (out - result <= strlen (escaped)); + return result; +} + +/** + * gnome_vfs_remove_optional_escapes: + * @uri: an escaped uri + * + * Scans the uri and converts characters that do not have to be + * escaped into an un-escaped form. The characters that get treated this + * way are defined as unreserved by the RFC. + * + * Return value: an error value if the uri is found to be malformed. + **/ +GnomeVFSResult +gnome_vfs_remove_optional_escapes (char *uri) +{ + guchar *scanner; + int character; + int length; + + if (uri == NULL) { + return GNOME_VFS_OK; + } + + length = strlen (uri); + + for (scanner = uri; *scanner != '\0'; scanner++, length--) { + if (*scanner == HEX_ESCAPE) { + character = unescape_character (scanner + 1); + if (character < 0) { + /* invalid hexadecimal character */ + return GNOME_VFS_ERROR_INVALID_URI; + } + + if (uri_character_kind [character] == UNRESERVED) { + /* This character does not need to be escaped, convert it + * to a non-escaped form. + */ + *scanner = (guchar)character; + g_assert (length >= 3); + + /* Shrink the string covering up the two extra digits of the + * escaped character. Include the trailing '\0' in the copy + * to keep the string terminated. + */ + memmove (scanner + 1, scanner + 3, length - 2); + } else { + /* This character must stay escaped, skip the entire + * escaped sequence + */ + scanner += 2; + } + length -= 2; + + } else if (*scanner > 127 + || uri_character_kind [*scanner] == DELIMITERS + || uri_character_kind [*scanner] == UNWISE + || uri_character_kind [*scanner] == CONTROL) { + /* It is illegal for this character to be in an un-escaped form + * in the uri. + */ + return GNOME_VFS_ERROR_INVALID_URI; + } + } + return GNOME_VFS_OK; +} + +static char * +gnome_vfs_make_uri_canonical_old (const char *original_uri_text) +{ + GnomeVFSURI *uri; + char *result; + + uri = gnome_vfs_uri_new_private (original_uri_text, TRUE, TRUE, FALSE); + if (uri == NULL) { + return NULL;; + } + + result = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE); + gnome_vfs_uri_unref (uri); + + return result; +} + +/** + * gnome_vfs_make_path_name_canonical: + * @path: a file path, relative or absolute + * + * Calls _gnome_vfs_canonicalize_pathname, allocating storage for the + * result and providing for a cleaner memory management. + * + * Return value: a canonical version of @path + **/ +gchar * +gnome_vfs_make_path_name_canonical (const gchar *path) +{ + char *path_clone; + char *result; + + path_clone = g_strdup (path); + result = _gnome_vfs_canonicalize_pathname (path_clone); + if (result != path_clone) { + g_free (path_clone); + return g_strdup (result); + } + + return path_clone; +} + +/** + * gnome_vfs_list_deep_free: + * @list: list to be freed + * + * Free @list, and call g_free() on all data members. + **/ +void +gnome_vfs_list_deep_free (GList *list) +{ + GList *p; + + if (list == NULL) + return; + + for (p = list; p != NULL; p = p->next) { + g_free (p->data); + } + g_list_free (list); +} + +/** + * gnome_vfs_get_local_path_from_uri: + * @uri: URI to convert to a local path + * + * Create a local path for a file:/// URI. Do not use with URIs + * of other methods. + * + * Return value: a newly allocated string containing the local path + * NULL is returned on error or if the uri isn't a file: URI + * without a fragment identifier (or chained URI). + **/ +char * +gnome_vfs_get_local_path_from_uri (const char *uri) +{ + const char *path_part; + + if (!_gnome_vfs_istr_has_prefix (uri, "file:/")) { + return NULL; + } + + path_part = uri + strlen ("file:"); + if (strchr (path_part, '#') != NULL) { + return NULL; + } + + if (_gnome_vfs_istr_has_prefix (path_part, "///")) { + path_part += 2; + } else if (_gnome_vfs_istr_has_prefix (path_part, "//")) { + return NULL; + } + + return gnome_vfs_unescape_string (path_part, "/"); +} + +/** + * gnome_vfs_get_uri_from_local_path: + * @local_full_path: a full local filesystem path (i.e. not relative) + * + * Returns a file:/// URI for the local path @local_full_path. + * + * Return value: a newly allocated string containing the URI corresponding + * to @local_full_path (NULL for some bad errors). + **/ +char * +gnome_vfs_get_uri_from_local_path (const char *local_full_path) +{ + char *escaped_path, *result; + + if (local_full_path == NULL) { + return NULL; + } + + g_return_val_if_fail (local_full_path[0] == '/', NULL); + + escaped_path = gnome_vfs_escape_path_string (local_full_path); + result = g_strconcat ("file://", escaped_path, NULL); + g_free (escaped_path); + return result; +} + +/** + * gnome_vfs_get_volume_free_space: + * @vfs_uri: + * @size: + * + * Stores in @size the amount of free space on a volume. + * This only works for local file systems with the file: scheme. + * + * Returns: GNOME_VFS_OK on success, otherwise an error code + */ +GnomeVFSResult +gnome_vfs_get_volume_free_space (const GnomeVFSURI *vfs_uri, + GnomeVFSFileSize *size) +{ + GnomeVFSFileSize free_blocks, block_size; + int statfs_result; + const char *path, *scheme; + char *unescaped_path; + +#if HAVE_STATVFS + struct statvfs statfs_buffer; +#else + struct statfs statfs_buffer; +#endif + + *size = 0; + + path = gnome_vfs_uri_get_path (vfs_uri); + if (path == NULL) { + return GNOME_VFS_ERROR_NOT_SUPPORTED; + } + + scheme = gnome_vfs_uri_get_scheme (vfs_uri); + + /* We only handle the file scheme for now */ + if (g_ascii_strcasecmp (scheme, "file") != 0 || !_gnome_vfs_istr_has_prefix (path, "/")) { + return GNOME_VFS_ERROR_NOT_SUPPORTED; + } + + unescaped_path = gnome_vfs_unescape_string (path, G_DIR_SEPARATOR_S); + +#if HAVE_STATVFS + statfs_result = statvfs (unescaped_path, &statfs_buffer); +#else + statfs_result = statfs (unescaped_path, &statfs_buffer); +#endif + + g_free (unescaped_path); + + if (statfs_result != 0) { + return gnome_vfs_result_from_errno (); + } + + block_size = statfs_buffer.f_bsize; + free_blocks = statfs_buffer.f_bavail; + + *size = block_size * free_blocks; + + return GNOME_VFS_OK; +} + +char * +gnome_vfs_icon_path_from_filename (const char *relative_filename) +{ + const char *gnome_var; + char *full_filename; + char **paths, **temp_paths; + + if (g_path_is_absolute (relative_filename) && + g_file_test (relative_filename, G_FILE_TEST_EXISTS)) + return g_strdup (relative_filename); + + gnome_var = g_getenv ("GNOME_PATH"); + + if (gnome_var == NULL) { + gnome_var = PREFIX; + } + + paths = g_strsplit (gnome_var, ":", 0); + + for (temp_paths = paths; *temp_paths != NULL; temp_paths++) { + full_filename = g_strconcat (*temp_paths, "/share/pixmaps/", relative_filename, NULL); + if (g_file_test (full_filename, G_FILE_TEST_EXISTS)) { + g_strfreev (paths); + return full_filename; + } + g_free (full_filename); + full_filename = NULL; + } + + g_strfreev (paths); + return NULL; +} + +static char * +strdup_to (const char *string, const char *end) +{ + if (end == NULL) { + return g_strdup (string); + } + return g_strndup (string, end - string); +} + +static gboolean +is_executable_file (const char *path) +{ + struct stat stat_buffer; + + /* Check that it exists. */ + if (stat (path, &stat_buffer) != 0) { + return FALSE; + } + + /* Check that it is a file. */ + if (!S_ISREG (stat_buffer.st_mode)) { + return FALSE; + } + + /* Check that it's executable. */ + if (access (path, X_OK) != 0) { + return FALSE; + } + + return TRUE; +} + +static gboolean +executable_in_path (const char *executable_name) +{ + const char *path_list, *piece_start, *piece_end; + char *piece, *raw_path, *expanded_path; + gboolean is_good; + + path_list = g_getenv ("PATH"); + + for (piece_start = path_list; ; piece_start = piece_end + 1) { + /* Find the next piece of PATH. */ + piece_end = strchr (piece_start, ':'); + piece = strdup_to (piece_start, piece_end); + g_strstrip (piece); + + if (piece[0] == '\0') { + is_good = FALSE; + } else { + /* Try out this path with the executable. */ + raw_path = g_strconcat (piece, "/", executable_name, NULL); + expanded_path = gnome_vfs_expand_initial_tilde (raw_path); + g_free (raw_path); + + is_good = is_executable_file (expanded_path); + g_free (expanded_path); + } + + g_free (piece); + + if (is_good) { + return TRUE; + } + + if (piece_end == NULL) { + return FALSE; + } + } +} + +static char * +get_executable_name_from_command_string (const char *command_string) +{ + /* FIXME bugzilla.eazel.com 2757: + * We need to handle quoting here for the full-path case */ + return g_strstrip (strdup_to (command_string, strchr (command_string, ' '))); +} + +/** + * gnome_vfs_is_executable_command_string: + * @command_string: + * + * Checks if @command_string starts with the full path of an executable file + * or an executable in $PATH. + * + * Returns: TRUE if command_string started with and executable file, + * FALSE otherwise. + */ +gboolean +gnome_vfs_is_executable_command_string (const char *command_string) +{ + char *executable_name; + char *executable_path; + gboolean found; + + /* Check whether command_string is a full path for an executable. */ + if (command_string[0] == '/') { + + /* FIXME bugzilla.eazel.com 2757: + * Because we don't handle quoting, we can check for full + * path including spaces, but no parameters, and full path + * with no spaces with or without parameters. But this will + * fail for quoted full path with spaces, and parameters. + */ + + /* This works if command_string contains a space, but not + * if command_string has parameters. + */ + if (is_executable_file (command_string)) { + return TRUE; + } + + /* This works if full path has no spaces, with or without parameters */ + executable_path = get_executable_name_from_command_string (command_string); + found = is_executable_file (executable_path); + g_free (executable_path); + + return found; + } + + executable_name = get_executable_name_from_command_string (command_string); + found = executable_in_path (executable_name); + g_free (executable_name); + + return found; +} + +/** + * gnome_vfs_read_entire_file: + * @uri: URI of the file to read + * @file_size: after reading the file, contains the size of the file read + * @file_contents: contains the file_size bytes, the contents of the file at @uri. + * + * Reads an entire file into memory for convenience. Beware accidentally + * loading large files into memory with this function. + * + * Return value: An integer representing the result of the operation + * + * Since: 2.2 + */ + +GnomeVFSResult +gnome_vfs_read_entire_file (const char *uri, + int *file_size, + char **file_contents) +{ + GnomeVFSResult result; + GnomeVFSHandle *handle; + char *buffer; + GnomeVFSFileSize total_bytes_read; + GnomeVFSFileSize bytes_read; + + *file_size = 0; + *file_contents = NULL; + + /* Open the file. */ + result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ); + if (result != GNOME_VFS_OK) { + return result; + } + + /* Read the whole thing. */ + buffer = NULL; + total_bytes_read = 0; + do { + buffer = g_realloc (buffer, total_bytes_read + READ_CHUNK_SIZE); + result = gnome_vfs_read (handle, + buffer + total_bytes_read, + READ_CHUNK_SIZE, + &bytes_read); + if (result != GNOME_VFS_OK && result != GNOME_VFS_ERROR_EOF) { + g_free (buffer); + gnome_vfs_close (handle); + return result; + } + + /* Check for overflow. */ + if (total_bytes_read + bytes_read < total_bytes_read) { + g_free (buffer); + gnome_vfs_close (handle); + return GNOME_VFS_ERROR_TOO_BIG; + } + + total_bytes_read += bytes_read; + } while (result == GNOME_VFS_OK); + + /* Close the file. */ + result = gnome_vfs_close (handle); + if (result != GNOME_VFS_OK) { + g_free (buffer); + return result; + } + + /* Return the file. */ + *file_size = total_bytes_read; + *file_contents = g_realloc (buffer, total_bytes_read); + return GNOME_VFS_OK; +} + +static char * +gnome_vfs_make_valid_utf8 (const char *name) +{ + GString *string; + const char *remainder, *invalid; + int remaining_bytes, valid_bytes; + + string = NULL; + remainder = name; + remaining_bytes = strlen (name); + + while (remaining_bytes != 0) { + if (g_utf8_validate (remainder, remaining_bytes, &invalid)) { + break; + } + valid_bytes = invalid - remainder; + + if (string == NULL) { + string = g_string_sized_new (remaining_bytes); + } + g_string_append_len (string, remainder, valid_bytes); + g_string_append_c (string, '?'); + + remaining_bytes -= valid_bytes + 1; + remainder = invalid + 1; + } + + if (string == NULL) { + return g_strdup (name); + } + + g_string_append (string, remainder); + g_string_append (string, _(" (invalid Unicode)")); + g_assert (g_utf8_validate (string->str, -1, NULL)); + + return g_string_free (string, FALSE); +} + +static char * +gnome_vfs_format_uri_for_display_internal (const char *uri, gboolean filenames_are_locale_encoded) +{ + char *canonical_uri, *path, *utf8_path; + + g_return_val_if_fail (uri != NULL, g_strdup ("")); + + canonical_uri = gnome_vfs_make_uri_canonical_old (uri); + + /* If there's no fragment and it's a local path. */ + path = gnome_vfs_get_local_path_from_uri (canonical_uri); + + if (path != NULL) { + if (filenames_are_locale_encoded) { + utf8_path = g_locale_to_utf8 (path, -1, NULL, NULL, NULL); + if (utf8_path) { + g_free (canonical_uri); + g_free (path); + return utf8_path; + } + } else if (g_utf8_validate (path, -1, NULL)) { + g_free (canonical_uri); + return path; + } + } + + if (canonical_uri && !g_utf8_validate (canonical_uri, -1, NULL)) { + utf8_path = gnome_vfs_make_valid_utf8 (canonical_uri); + g_free (canonical_uri); + canonical_uri = utf8_path; + } + + g_free (path); + return canonical_uri; +} + + +/** + * gnome_vfs_format_uri_for_display: + * + * Filter, modify, unescape and change URIs to make them appropriate + * to display to users. The conversion is done such that the roundtrip + * to UTF-8 is reversible. + * + * Rules: + * file: URI's without fragments should appear as local paths + * file: URI's with fragments should appear as file: URI's + * All other URI's appear as expected + * + * @uri: a URI + * + * Returns: a newly allocated UTF-8 string + * + * Since: 2.2 + **/ + +char * +gnome_vfs_format_uri_for_display (const char *uri) +{ + static gboolean broken_filenames; + + broken_filenames = g_getenv ("G_BROKEN_FILENAMES") != NULL; + + return gnome_vfs_format_uri_for_display_internal (uri, broken_filenames); +} + +static gboolean +is_valid_scheme_character (char c) +{ + return g_ascii_isalnum (c) || c == '+' || c == '-' || c == '.'; +} + +static gboolean +has_valid_scheme (const char *uri) +{ + const char *p; + + p = uri; + + if (!is_valid_scheme_character (*p)) { + return FALSE; + } + + do { + p++; + } while (is_valid_scheme_character (*p)); + + return *p == ':'; +} + +static char * +gnome_vfs_escape_high_chars (const guchar *string) +{ + char *result; + const guchar *scanner; + guchar *result_scanner; + int escape_count; + static const gchar hex[16] = "0123456789ABCDEF"; + +#define ACCEPTABLE(a) ((a)>=32 && (a)<128) + + escape_count = 0; + + if (string == NULL) { + return NULL; + } + + for (scanner = string; *scanner != '\0'; scanner++) { + if (!ACCEPTABLE(*scanner)) { + escape_count++; + } + } + + if (escape_count == 0) { + return g_strdup (string); + } + + /* allocate two extra characters for every character that + * needs escaping and space for a trailing zero + */ + result = g_malloc (scanner - string + escape_count * 2 + 1); + for (scanner = string, result_scanner = result; *scanner != '\0'; scanner++) { + if (!ACCEPTABLE(*scanner)) { + *result_scanner++ = '%'; + *result_scanner++ = hex[*scanner >> 4]; + *result_scanner++ = hex[*scanner & 15]; + + } else { + *result_scanner++ = *scanner; + } + } + + *result_scanner = '\0'; + + return result; +} + +/* http uris look like .<2-4 letters>, possibly followed by a slash and some text. */ +static gboolean +looks_like_http_uri (const char *str) +{ + int len; + int i; + char c; + const char *first_slash; + + first_slash = strchr(str, '/'); + if (first_slash == NULL) { + len = strlen (str); + } else { + len = first_slash - str; + } + for (i = 0; i < 5 && i < len; i++) { + c = str[len - 1 - i]; + if (i >= 2 && c == '.') { + return TRUE; + } + if (!g_ascii_isalpha (c)) { + return FALSE; + } + } + return FALSE; +} + +/* The strip_trailing_whitespace option is intended to make copy/paste of + * URIs less error-prone when it is known that trailing whitespace isn't + * part of the uri. + */ +static char * +gnome_vfs_make_uri_from_input_internal (const char *text, + gboolean filenames_are_locale_encoded, + gboolean strip_trailing_whitespace) +{ + char *stripped, *path, *uri, *locale_path, *filesystem_path, *escaped; + + g_return_val_if_fail (text != NULL, g_strdup ("")); + + /* Strip off leading whitespaces (since they can't be part of a valid + uri). Only strip off trailing whitespaces when requested since + they might be part of a valid uri. + */ + if (strip_trailing_whitespace) { + stripped = g_strstrip (g_strdup (text)); + } else { + stripped = g_strchug (g_strdup (text)); + } + + switch (stripped[0]) { + case '\0': + uri = g_strdup (""); + break; + case '/': + if (filenames_are_locale_encoded) { + GError *error = NULL; + locale_path = g_locale_from_utf8 (stripped, -1, NULL, NULL, &error); + if (locale_path != NULL) { + uri = gnome_vfs_get_uri_from_local_path (locale_path); + g_free (locale_path); + } else { + /* We couldn't convert to the locale. */ + /* FIXME: We should probably give a user-visible error here. */ + uri = g_strdup(""); + } + } else { + uri = gnome_vfs_get_uri_from_local_path (stripped); + } + break; + case '~': + if (filenames_are_locale_encoded) { + filesystem_path = g_locale_from_utf8 (stripped, -1, NULL, NULL, NULL); + } else { + filesystem_path = g_strdup (stripped); + } + /* deliberately falling into default case on fail */ + if (filesystem_path != NULL) { + path = gnome_vfs_expand_initial_tilde (filesystem_path); + g_free (filesystem_path); + if (*path == '/') { + uri = gnome_vfs_get_uri_from_local_path (path); + g_free (path); + break; + } + g_free (path); + } + /* don't insert break here, read above comment */ + default: + if (has_valid_scheme (stripped)) { + uri = gnome_vfs_escape_high_chars (stripped); + } else if (looks_like_http_uri (stripped)) { + escaped = gnome_vfs_escape_high_chars (stripped); + uri = g_strconcat ("http://", escaped, NULL); + g_free (escaped); + } else { + escaped = gnome_vfs_escape_high_chars (stripped); + uri = g_strconcat ("file://", escaped, NULL); + g_free (escaped); + } + } + + g_free (stripped); + + return uri; + +} + +/** + * gnome_vfs_make_uri_from_input: + * @location: a possibly mangled "uri", in UTF8 + * + * Takes a user input path/URI and makes a valid URI out of it. + * + * This function is the reverse of gnome_vfs_format_uri_for_display + * but it also handles the fact that the user could have typed + * arbitrary UTF8 in the entry showing the string. + * + * Returns: a newly allocated uri. + * + * Since: 2.2 + **/ +char * +gnome_vfs_make_uri_from_input (const char *location) +{ + static gboolean broken_filenames; + + broken_filenames = g_getenv ("G_BROKEN_FILENAMES") != NULL; + + return gnome_vfs_make_uri_from_input_internal (location, broken_filenames, TRUE); +} + +/** + * gnome_vfs_make_uri_from_input_with_dirs: + * @in: a relative or absolute path + * + * Determines a fully qualified URL from a relative or absolute input path. + * Basically calls gnome_vfs_make_uri_from_input except it specifically + * tries to support paths relative to the specified directories (can be homedir + * and/or current directory). + * + * Return value: a newly allocated string containing the fully qualified URL + * + * Since: 2.4 + */ +char * +gnome_vfs_make_uri_from_input_with_dirs (const char *in, + GnomeVFSMakeURIDirs dirs) +{ + char *uri, *path, *dir; + + switch (in[0]) { + case '\0': + uri = g_strdup (""); + break; + + case '~': + case '/': + uri = gnome_vfs_make_uri_from_input (in); + break; + + default: + /* this might be a relative path, check if it exists relative + * to current dir and home dir. + */ + uri = NULL; + if (dirs & GNOME_VFS_MAKE_URI_DIR_CURRENT) { + dir = g_get_current_dir (); + path = g_build_filename (dir, in, NULL); + g_free (dir); + + if (g_file_test (path, G_FILE_TEST_EXISTS)) { + uri = gnome_vfs_make_uri_from_input (path); + } + g_free (path); + } + + if (uri == NULL && + dirs & GNOME_VFS_MAKE_URI_DIR_HOMEDIR) { + path = g_build_filename (g_get_home_dir (), in, NULL); + + if (g_file_test (path, G_FILE_TEST_EXISTS)) { + uri = gnome_vfs_make_uri_from_input (path); + } + g_free (path); + } + + if (uri == NULL) { + uri = gnome_vfs_make_uri_from_input (in); + } + } + + return uri; +} + + +/** + * gnome_vfs_make_uri_canonical_strip_fragment: + * @uri: + * + * If the @uri passed contains a fragment (anything after a '#') strips if, + * then makes the URI canonical. + * + * Returns: a newly allocated string containing a canonical URI. + * + * Since: 2.2 + **/ + +char * +gnome_vfs_make_uri_canonical_strip_fragment (const char *uri) +{ + const char *fragment; + char *without_fragment, *canonical; + + fragment = strchr (uri, '#'); + if (fragment == NULL) { + return gnome_vfs_make_uri_canonical (uri); + } + + without_fragment = g_strndup (uri, fragment - uri); + canonical = gnome_vfs_make_uri_canonical (without_fragment); + g_free (without_fragment); + return canonical; +} + +static gboolean +uris_match (const char *uri_1, const char *uri_2, gboolean ignore_fragments) +{ + char *canonical_1, *canonical_2; + gboolean result; + + if (ignore_fragments) { + canonical_1 = gnome_vfs_make_uri_canonical_strip_fragment (uri_1); + canonical_2 = gnome_vfs_make_uri_canonical_strip_fragment (uri_2); + } else { + canonical_1 = gnome_vfs_make_uri_canonical (uri_1); + canonical_2 = gnome_vfs_make_uri_canonical (uri_2); + } + + result = strcmp (canonical_1, canonical_2) ? FALSE : TRUE; + + g_free (canonical_1); + g_free (canonical_2); + + return result; +} + +/** + * gnome_vfs_uris_match: + * @uri_1: stringified URI to compare with @uri_2. + * @uri_2: stringified URI to compare with @uri_1. + * + * Compare two URIs. + * + * Return value: TRUE if they are the same, FALSE otherwise. + * + * Since: 2.2 + **/ + +gboolean +gnome_vfs_uris_match (const char *uri_1, const char *uri_2) +{ + return uris_match (uri_1, uri_2, FALSE); +} + +static gboolean +gnome_vfs_str_has_prefix (const char *haystack, const char *needle) +{ + const char *h, *n; + + /* Eat one character at a time. */ + h = haystack == NULL ? "" : haystack; + n = needle == NULL ? "" : needle; + do { + if (*n == '\0') { + return TRUE; + } + if (*h == '\0') { + return FALSE; + } + } while (*h++ == *n++); + return FALSE; +} + + +static gboolean +gnome_vfs_uri_is_local_scheme (const char *uri) +{ + gboolean is_local_scheme; + char *temp_scheme; + int i; + char *local_schemes[] = {"file:", "help:", "ghelp:", "gnome-help:", + "trash:", "man:", "info:", + "hardware:", "search:", "pipe:", + "gnome-trash:", NULL}; + + is_local_scheme = FALSE; + for (temp_scheme = *local_schemes, i = 0; temp_scheme != NULL; i++, temp_scheme = local_schemes[i]) { + is_local_scheme = _gnome_vfs_istr_has_prefix (uri, temp_scheme); + if (is_local_scheme) { + break; + } + } + + + return is_local_scheme; +} + +static char * +gnome_vfs_handle_trailing_slashes (const char *uri) +{ + char *temp, *uri_copy; + gboolean previous_char_is_column, previous_chars_are_slashes_without_column; + gboolean previous_chars_are_slashes_with_column; + gboolean is_local_scheme; + + g_assert (uri != NULL); + + uri_copy = g_strdup (uri); + if (strlen (uri_copy) <= 2) { + return uri_copy; + } + + is_local_scheme = gnome_vfs_uri_is_local_scheme (uri); + + previous_char_is_column = FALSE; + previous_chars_are_slashes_without_column = FALSE; + previous_chars_are_slashes_with_column = FALSE; + + /* remove multiple trailing slashes */ + for (temp = uri_copy; *temp != '\0'; temp++) { + if (*temp == '/' && !previous_char_is_column) { + previous_chars_are_slashes_without_column = TRUE; + } else if (*temp == '/' && previous_char_is_column) { + previous_chars_are_slashes_without_column = FALSE; + previous_char_is_column = TRUE; + previous_chars_are_slashes_with_column = TRUE; + } else { + previous_chars_are_slashes_without_column = FALSE; + previous_char_is_column = FALSE; + previous_chars_are_slashes_with_column = FALSE; + } + + if (*temp == ':') { + previous_char_is_column = TRUE; + } + } + + if (*temp == '\0' && previous_chars_are_slashes_without_column) { + if (is_local_scheme) { + /* go back till you remove them all. */ + for (temp--; *(temp) == '/'; temp--) { + *temp = '\0'; + } + } else { + /* go back till you remove them all but one. */ + for (temp--; *(temp - 1) == '/'; temp--) { + *temp = '\0'; + } + } + } + + if (*temp == '\0' && previous_chars_are_slashes_with_column) { + /* go back till you remove them all but three. */ + for (temp--; *(temp - 3) != ':' && *(temp - 2) != ':' && *(temp - 1) != ':'; temp--) { + *temp = '\0'; + } + } + + + return uri_copy; +} + +/** + * gnome_vfs_make_uri_canonical: + * @uri: and absolute or relative URI, it might have scheme. + * + * Standarizes the format of the uri being passed, so that it can be used + * later in other functions that expect a canonical URI. + * + * Returns: a newly allocated string that contains the canonical + * representation of @uri. + * + * Since: 2.2 + **/ + +char * +gnome_vfs_make_uri_canonical (const char *uri) +{ + char *canonical_uri, *old_uri, *p; + gboolean relative_uri; + + relative_uri = FALSE; + + if (uri == NULL) { + return NULL; + } + + /* FIXME bugzilla.eazel.com 648: + * This currently ignores the issue of two uris that are not identical but point + * to the same data except for the specific cases of trailing '/' characters, + * file:/ and file:///, and "lack of file:". + */ + + canonical_uri = gnome_vfs_handle_trailing_slashes (uri); + + /* Note: In some cases, a trailing slash means nothing, and can + * be considered equivalent to no trailing slash. But this is + * not true in every case; specifically not for web addresses passed + * to a web-browser. So we don't have the trailing-slash-equivalence + * logic here, but we do use that logic in EelDirectory where + * the rules are more strict. + */ + + /* Add file: if there is no scheme. */ + if (strchr (canonical_uri, ':') == NULL) { + old_uri = canonical_uri; + + if (old_uri[0] != '/') { + /* FIXME bugzilla.eazel.com 5069: + * bandaid alert. Is this really the right thing to do? + * + * We got what really is a relative path. We do a little bit of + * a stretch here and assume it was meant to be a cryptic absolute path, + * and convert it to one. Since we can't call gnome_vfs_uri_new and + * gnome_vfs_uri_to_string to do the right make-canonical conversion, + * we have to do it ourselves. + */ + relative_uri = TRUE; + canonical_uri = gnome_vfs_make_path_name_canonical (old_uri); + g_free (old_uri); + old_uri = canonical_uri; + canonical_uri = g_strconcat ("file:///", old_uri, NULL); + } else { + canonical_uri = g_strconcat ("file:", old_uri, NULL); + } + g_free (old_uri); + } + + /* Lower-case the scheme. */ + for (p = canonical_uri; *p != ':'; p++) { + g_assert (*p != '\0'); + *p = g_ascii_tolower (*p); + } + + if (!relative_uri) { + old_uri = canonical_uri; + canonical_uri = gnome_vfs_make_uri_canonical_old (canonical_uri); + if (canonical_uri != NULL) { + g_free (old_uri); + } else { + canonical_uri = old_uri; + } + } + + /* FIXME bugzilla.eazel.com 2802: + * Work around gnome-vfs's desire to convert file:foo into file://foo + * by converting to file:///foo here. When you remove this, check that + * typing "foo" into location bar does not crash and returns an error + * rather than displaying the contents of / + */ + if (gnome_vfs_str_has_prefix (canonical_uri, "file://") + && !gnome_vfs_str_has_prefix (canonical_uri, "file:///")) { + old_uri = canonical_uri; + canonical_uri = g_strconcat ("file:/", old_uri + 5, NULL); + g_free (old_uri); + } + + return canonical_uri; +} + +/** + * gnome_vfs_get_uri_scheme: + * @uri: a stringified URI + * + * Retrieve the scheme used in @uri + * + * Return value: A newly allocated string containing the scheme, NULL + * if @uri it doesn't seem to contain a scheme + * + * Since: 2.2 + **/ + +char * +gnome_vfs_get_uri_scheme (const char *uri) +{ + char *colon; + + g_return_val_if_fail (uri != NULL, NULL); + + colon = strchr (uri, ':'); + + if (colon == NULL) { + return NULL; + } + + return g_strndup (uri, colon - uri); +} + +/* Note that NULL's and full paths are also handled by this function. + * A NULL location will return the current working directory + */ +static char * +file_uri_from_local_relative_path (const char *location) +{ + char *current_dir; + char *base_uri, *base_uri_slash; + char *location_escaped; + char *uri; + + current_dir = g_get_current_dir (); + base_uri = gnome_vfs_get_uri_from_local_path (current_dir); + /* g_get_current_dir returns w/o trailing / */ + base_uri_slash = g_strconcat (base_uri, "/", NULL); + + location_escaped = gnome_vfs_escape_path_string (location); + + uri = gnome_vfs_uri_make_full_from_relative (base_uri_slash, location_escaped); + + g_free (location_escaped); + g_free (base_uri_slash); + g_free (base_uri); + g_free (current_dir); + + return uri; +} + +/** + * gnome_vfs_make_uri_from_shell_arg: + * @location: a possibly mangled "uri" + * + * Similar to gnome_vfs_make_uri_from_input, except that: + * + * 1) guesses relative paths instead of http domains + * 2) doesn't bother stripping leading/trailing white space + * 3) doesn't bother with ~ expansion--that's done by the shell + * + * Returns: a newly allocated uri + * + * Since: 2.2 + **/ + +char * +gnome_vfs_make_uri_from_shell_arg (const char *location) +{ + char *uri; + + g_return_val_if_fail (location != NULL, g_strdup ("")); + + switch (location[0]) { + case '\0': + uri = g_strdup (""); + break; + case '/': + uri = gnome_vfs_get_uri_from_local_path (location); + break; + default: + if (has_valid_scheme (location)) { + uri = g_strdup (location); + } else { + uri = file_uri_from_local_relative_path (location); + } + } + + return uri; +} + +/** + * gnome_vfs_make_uri_full_from_relative: + * + * Returns a full URI given a full base URI, and a secondary URI which may + * be relative. + * + * This function is deprecated, please use + * gnome_vfs_uri_make_full_from_relative from gnome-vfs-uri.h + * + * Return value: the URI (NULL for some bad errors). + * + * Since: 2.2 + **/ + +char * +gnome_vfs_make_uri_full_from_relative (const char *base_uri, const char *relative_uri) +{ + return gnome_vfs_uri_make_full_from_relative (base_uri, relative_uri); +} + +GnomeVFSResult +_gnome_vfs_uri_resolve_all_symlinks_uri (GnomeVFSURI *uri, + GnomeVFSURI **result_uri) +{ + GnomeVFSURI *new_uri, *resolved_uri; + GnomeVFSFileInfo *info; + GnomeVFSResult res; + char *p; + int n_followed_symlinks; + + /* Ref the original uri so we don't lose it */ + uri = gnome_vfs_uri_ref (uri); + + *result_uri = NULL; + + info = gnome_vfs_file_info_new (); + + p = uri->text; + n_followed_symlinks = 0; + while (*p != 0) { + while (*p == GNOME_VFS_URI_PATH_CHR) + p++; + while (*p != 0 && *p != GNOME_VFS_URI_PATH_CHR) + p++; + + new_uri = gnome_vfs_uri_dup (uri); + g_free (new_uri->text); + new_uri->text = g_strndup (uri->text, p - uri->text); + + gnome_vfs_file_info_clear (info); + res = gnome_vfs_get_file_info_uri (new_uri, info, GNOME_VFS_FILE_INFO_DEFAULT); + if (res != GNOME_VFS_OK) { + gnome_vfs_uri_unref (new_uri); + goto out; + } + if (info->type == GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK && + info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SYMLINK_NAME) { + n_followed_symlinks++; + if (n_followed_symlinks > MAX_SYMLINKS_FOLLOWED) { + res = GNOME_VFS_ERROR_TOO_MANY_LINKS; + gnome_vfs_uri_unref (new_uri); + goto out; + } + resolved_uri = gnome_vfs_uri_resolve_relative (new_uri, + info->symlink_name); + if (*p != 0) { + gnome_vfs_uri_unref (uri); + uri = gnome_vfs_uri_append_path (resolved_uri, p); + gnome_vfs_uri_unref (resolved_uri); + } else { + gnome_vfs_uri_unref (uri); + uri = resolved_uri; + } + + p = uri->text; + } + gnome_vfs_uri_unref (new_uri); + } + + res = GNOME_VFS_OK; + *result_uri = gnome_vfs_uri_dup (uri); + out: + gnome_vfs_file_info_unref (info); + gnome_vfs_uri_unref (uri); + return res; +} + +GnomeVFSResult +_gnome_vfs_uri_resolve_all_symlinks (const char *text_uri, + char **resolved_text_uri) +{ + GnomeVFSURI *uri, *resolved_uri; + GnomeVFSResult res; + + *resolved_text_uri = NULL; + + uri = gnome_vfs_uri_new (text_uri); + if (uri == NULL || uri->text == NULL) { + return GNOME_VFS_ERROR_NOT_SUPPORTED; + } + + res = _gnome_vfs_uri_resolve_all_symlinks_uri (uri, &resolved_uri); + + if (res == GNOME_VFS_OK) { + *resolved_text_uri = gnome_vfs_uri_to_string (resolved_uri, GNOME_VFS_URI_HIDE_NONE); + gnome_vfs_uri_unref (resolved_uri); + } + return res; +} + +gboolean +_gnome_vfs_uri_is_in_subdir (GnomeVFSURI *uri, GnomeVFSURI *dir) +{ + GnomeVFSFileInfo *dirinfo, *info; + GnomeVFSURI *resolved_dir, *parent, *tmp; + GnomeVFSResult res; + gboolean is_in_dir; + + resolved_dir = NULL; + parent = NULL; + + is_in_dir = FALSE; + + dirinfo = gnome_vfs_file_info_new (); + info = gnome_vfs_file_info_new (); + + res = gnome_vfs_get_file_info_uri (dir, dirinfo, GNOME_VFS_FILE_INFO_DEFAULT); + if (res != GNOME_VFS_OK || dirinfo->type != GNOME_VFS_FILE_TYPE_DIRECTORY) { + goto out; + } + + res = _gnome_vfs_uri_resolve_all_symlinks_uri (dir, &resolved_dir); + if (res != GNOME_VFS_OK) { + goto out; + } + + res = _gnome_vfs_uri_resolve_all_symlinks_uri (uri, &tmp); + if (res != GNOME_VFS_OK) { + goto out; + } + + parent = gnome_vfs_uri_get_parent (tmp); + gnome_vfs_uri_unref (tmp); + + while (parent != NULL) { + res = gnome_vfs_get_file_info_uri (parent, info, GNOME_VFS_FILE_INFO_DEFAULT); + if (res != GNOME_VFS_OK) { + break; + } + + if (dirinfo->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_DEVICE && + dirinfo->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_INODE && + info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_DEVICE && + info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_INODE) { + if (dirinfo->device == info->device && + dirinfo->inode == info->inode) { + is_in_dir = TRUE; + break; + } + } else { + if (gnome_vfs_uri_equal (dir, parent)) { + is_in_dir = TRUE; + break; + } + } + + tmp = gnome_vfs_uri_get_parent (parent); + gnome_vfs_uri_unref (parent); + parent = tmp; + } + + out: + if (resolved_dir != NULL) { + gnome_vfs_uri_unref (resolved_dir); + } + if (parent != NULL) { + gnome_vfs_uri_unref (parent); + } + gnome_vfs_file_info_unref (info); + gnome_vfs_file_info_unref (dirinfo); + return is_in_dir; +} + +/** + * gnome_vfs_url_show: + * + * Launches the default application or component associated with the given url. + * + * Return value: GNOME_VFS_OK if the default action was launched, + * GNOME_VFS_ERROR_BAD_PARAMETERS for an invalid or non-existant url, + * GNOME_VFS_ERROR_NOT_SUPPORTED if no default action is associated with the URL. + * Also error codes from gnome_vfs_mime_action_launch and + * gnome_vfs_url_show_using_handler for other errors. + * + * Since: 2.4 + */ +GnomeVFSResult +gnome_vfs_url_show (const char *url) +{ + return gnome_vfs_url_show_with_env (url, NULL); +} + +/** + * gnome_vfs_url_show_with_env: + * + * Like gnome_vfs_url_show except that the default action will be launched + * with the given environment. + * + * Return value: GNOME_VFS_OK if the default action was launched. + * + * Since: 2.4 + */ +GnomeVFSResult +gnome_vfs_url_show_with_env (const char *url, + char **envp) +{ + GnomeVFSMimeApplication *app; + GnomeVFSMimeAction *action; + GnomeVFSResult result; + GList params; + char *type; + char *scheme; + + g_return_val_if_fail (url != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + scheme = gnome_vfs_get_uri_scheme (url); + if (scheme == NULL) { + return GNOME_VFS_ERROR_BAD_PARAMETERS; + } + + /* check if this scheme requires special handling */ + if (_gnome_vfs_use_handler_for_scheme (scheme)) { + result = _gnome_vfs_url_show_using_handler_with_env (url, envp); + g_free (scheme); + return result; + } + + g_free (scheme); + + type = gnome_vfs_get_mime_type (url); + + if (type == NULL) { + return GNOME_VFS_ERROR_BAD_PARAMETERS; + } + + params.data = (char *) url; + params.prev = NULL; + params.next = NULL; + + app = gnome_vfs_mime_get_default_application (type); + + if (app != NULL) { + result = gnome_vfs_mime_application_launch_with_env (app, ¶ms, envp); + gnome_vfs_mime_application_free (app); + g_free (type); + return result; + } + + action = gnome_vfs_mime_get_default_action (type); + + if (action != NULL) { + result = gnome_vfs_mime_action_launch_with_env (action, ¶ms, envp); + gnome_vfs_mime_action_free (action); + g_free (type); + return result; + } + + g_free (type); + return GNOME_VFS_ERROR_NO_DEFAULT; +} + diff --git a/libgnomevfs/gnome-vfs-utils.h b/libgnomevfs/gnome-vfs-utils.h new file mode 100644 index 0000000..c82e2ef --- /dev/null +++ b/libgnomevfs/gnome-vfs-utils.h @@ -0,0 +1,174 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gnome-vfs-utils.h - Public utility functions for the GNOME Virtual + File System. + + Copyright (C) 1999 Free Software Foundation + Copyright (C) 2000 Eazel, Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Ettore Perazzoli + John Sullivan +*/ + +#ifndef GNOME_VFS_UTILS_H +#define GNOME_VFS_UTILS_H + +#include +#include +#include +#include +#include + +G_BEGIN_DECLS + +typedef enum { + GNOME_VFS_MAKE_URI_DIR_NONE = 0, + GNOME_VFS_MAKE_URI_DIR_HOMEDIR = 1 << 0, + GNOME_VFS_MAKE_URI_DIR_CURRENT = 1 << 1 +} GnomeVFSMakeURIDirs; + +/* Makes a human-readable string. */ +char *gnome_vfs_format_file_size_for_display (GnomeVFSFileSize size); + +/* Converts unsafe characters to % sequences so the string can be + * used as a piece of a URI. Escapes all reserved URI characters. + */ +char *gnome_vfs_escape_string (const char *string); + +/* Converts unsafe characters to % sequences so the path can be + * used as a piece of a URI. Escapes all reserved URI characters + * except for "/". + */ +char *gnome_vfs_escape_path_string (const char *path); + +/* Converts unsafe characters to % sequences so the host/path segment + * can be used as a piece of a URI. Allows ":" and "@" in the host + * section (everything up to the first "/"), and after that, it behaves + * like gnome_vfs_escape_path_string. + */ +char *gnome_vfs_escape_host_and_path_string (const char *path); + +/* Converts only slashes and % characters to % sequences. This is useful + * for code that wants to use an arbitrary string as a file name. To use + * it in a URI, you have to escape again, of course. + */ +char *gnome_vfs_escape_slashes (const char *string); + + +/* Escapes all the characters that match any of the @match_set */ +char *gnome_vfs_escape_set (const char *string, + const char *match_set); + +/* Returns NULL if any of the illegal character appear in escaped + * form. If the illegal characters are in there unescaped, that's OK. + * Typically you pass "/" for illegal characters when converting to a + * Unix path, since pieces of Unix paths can't contain "/". ASCII 0 + * is always illegal due to the limitations of NULL-terminated strings. + */ +char *gnome_vfs_unescape_string (const char *escaped_string, + const char *illegal_characters); + +/* returns a copy of uri, converted to a canonical form */ +char *gnome_vfs_make_uri_canonical (const char *uri); + +/* returns a copy of path, converted to a canonical form */ +char *gnome_vfs_make_path_name_canonical (const char *path); + +/* returns a copy of path, with initial ~ expanded, or just copy of path + * if there's no initial ~ + */ +char *gnome_vfs_expand_initial_tilde (const char *path); + +/* Prepare an escaped string for display. Unlike gnome_vfs_unescape_string, + * this doesn't return NULL if an illegal sequences appears in the string, + * instead doing its best to provide a useful result. + */ +char *gnome_vfs_unescape_string_for_display (const char *escaped); + +/* Turn a "file://" URI in string form into a local path. Returns NULL + * if it's not a URI that can be converted. + */ +char *gnome_vfs_get_local_path_from_uri (const char *uri); + +/* Turn a path into a "file://" URI. */ +char *gnome_vfs_get_uri_from_local_path (const char *local_full_path); + +/* Check whether a string starts with an executable command */ +gboolean gnome_vfs_is_executable_command_string (const char *command_string); + +/* Free the list, freeing each item data with a g_free */ +void gnome_vfs_list_deep_free (GList *list); + + +/* Return amount of free space on target */ +GnomeVFSResult gnome_vfs_get_volume_free_space (const GnomeVFSURI *vfs_uri, + GnomeVFSFileSize *size); + +char *gnome_vfs_icon_path_from_filename (const char *filename); + +/* Convert a file descriptor to a handle */ +GnomeVFSResult gnome_vfs_open_fd (GnomeVFSHandle **handle, + int filedes); + +/* TRUE if the current thread is the thread with the main glib event loop */ +gboolean gnome_vfs_is_primary_thread (void); + +/** + * GNOME_VFS_ASSERT_PRIMARY_THREAD: + * + * Asserts that the current thread is the thread with + * the main glib event loop + **/ +#define GNOME_VFS_ASSERT_PRIMARY_THREAD g_assert (gnome_vfs_is_primary_thread()) + +/** + * GNOME_VFS_ASSERT_SECONDARY_THREAD: + * + * Asserts that the current thread is NOT the thread with + * the main glib event loop + **/ +#define GNOME_VFS_ASSERT_SECONDARY_THREAD g_assert (!gnome_vfs_is_primary_thread()) + +/* Reads the contents of an entire file into memory */ +GnomeVFSResult gnome_vfs_read_entire_file (const char *uri, + int *file_size, + char **file_contents); + +char * gnome_vfs_format_uri_for_display (const char *uri); +char * gnome_vfs_make_uri_from_input (const char *uri); +char * gnome_vfs_make_uri_from_input_with_dirs (const char *uri, + GnomeVFSMakeURIDirs dirs); +char * gnome_vfs_make_uri_canonical_strip_fragment (const char *uri); +gboolean gnome_vfs_uris_match (const char *uri_1, + const char *uri_2); +char * gnome_vfs_get_uri_scheme (const char *uri); +char * gnome_vfs_make_uri_from_shell_arg (const char *uri); + + +#ifndef GNOME_VFS_DISABLE_DEPRECATED +char * gnome_vfs_make_uri_full_from_relative (const char *base_uri, + const char *relative_uri); +#endif /* GNOME_VFS_DISABLE_DEPRECATED */ + +GnomeVFSResult gnome_vfs_url_show (const char *url); +GnomeVFSResult gnome_vfs_url_show_with_env (const char *url, + char **envp); + + +G_END_DECLS + +#endif /* GNOME_VFS_UTILS_H */ diff --git a/libgnomevfs/gnome-vfs-xfer.c b/libgnomevfs/gnome-vfs-xfer.c new file mode 100644 index 0000000..5f32891 --- /dev/null +++ b/libgnomevfs/gnome-vfs-xfer.c @@ -0,0 +1,2496 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* gnome-vfs-xfer.c - File transfers in the GNOME Virtual File System. + + Copyright (C) 1999 Free Software Foundation + Copyright (C) 2000, 2001 Eazel, Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: + Ettore Perazzoli + Pavel Cisler +*/ + +/* FIXME bugzilla.eazel.com 1197: + Check that all the flags passed by address are set at least once by + functions that are expected to set them. */ +/* FIXME bugzilla.eazel.com 1198: + There should be a concept of a `context' in the file methods that would + allow us to set a prefix URI for all the operations. This way we can + greatly optimize access to "strange" file systems. */ + +#include +#include "gnome-vfs-xfer.h" + +#include "gnome-vfs-cancellable-ops.h" +#include "gnome-vfs-directory.h" +#include "gnome-vfs-ops.h" +#include "gnome-vfs-utils.h" +#include "gnome-vfs-private-utils.h" +#include +#include +#include +#include + +/* Implementation of file transfers (`gnome_vfs_xfer*()' functions). */ + +static GnomeVFSResult remove_directory (GnomeVFSURI *uri, + gboolean recursive, + GnomeVFSProgressCallbackState *progress, + GnomeVFSXferOptions xfer_options, + GnomeVFSXferErrorMode *error_mode, + gboolean *skip); + + +enum { + /* size used for accounting for the expense of copying directories, + * doing a move operation, etc. in a progress callback + * (during a move the file size is used for a regular file). + */ + DEFAULT_SIZE_OVERHEAD = 1024 +}; + +/* in asynch mode the progress callback does a context switch every time + * it gets called. We'll only call it every now and then to not loose a + * lot of performance + */ +#define UPDATE_PERIOD ((gint64) (100 * 1000)) + +static gint64 +system_time (void) +{ + struct timeval time_of_day; + + gettimeofday (&time_of_day, NULL); + return (gint64) time_of_day.tv_usec + ((gint64) time_of_day.tv_sec) * 1000000; +} + +static void +init_progress (GnomeVFSProgressCallbackState *progress_state, + GnomeVFSXferProgressInfo *progress_info) +{ + progress_info->source_name = NULL; + progress_info->target_name = NULL; + progress_info->status = GNOME_VFS_XFER_PROGRESS_STATUS_OK; + progress_info->vfs_status = GNOME_VFS_OK; + progress_info->phase = GNOME_VFS_XFER_PHASE_INITIAL; + progress_info->file_index = 0; + progress_info->files_total = 0; + progress_info->bytes_total = 0; + progress_info->file_size = 0; + progress_info->bytes_copied = 0; + progress_info->total_bytes_copied = 0; + progress_info->duplicate_name = NULL; + progress_info->top_level_item = FALSE; + + progress_state->progress_info = progress_info; + progress_state->sync_callback = NULL; + progress_state->update_callback = NULL; + progress_state->async_job_data = NULL; + progress_state->next_update_callback_time = 0; + progress_state->next_text_update_callback_time = 0; + progress_state->update_callback_period = UPDATE_PERIOD; +} + +static void +free_progress (GnomeVFSXferProgressInfo *progress_info) +{ + g_free (progress_info->source_name); + progress_info->source_name = NULL; + g_free (progress_info->target_name); + progress_info->target_name = NULL; +} + +static void +progress_set_source_target_uris (GnomeVFSProgressCallbackState *progress, + const GnomeVFSURI *source_uri, const GnomeVFSURI *dest_uri) +{ + g_free (progress->progress_info->source_name); + progress->progress_info->source_name = source_uri ? gnome_vfs_uri_to_string (source_uri, + GNOME_VFS_URI_HIDE_NONE) : NULL; + g_free (progress->progress_info->target_name); + progress->progress_info->target_name = dest_uri ? gnome_vfs_uri_to_string (dest_uri, + GNOME_VFS_URI_HIDE_NONE) : NULL; + +} + +static void +progress_set_source_target (GnomeVFSProgressCallbackState *progress, + const char *source, const char *dest) +{ + g_free (progress->progress_info->source_name); + progress->progress_info->source_name = source ? g_strdup (source) : NULL; + g_free (progress->progress_info->target_name); + progress->progress_info->target_name = dest ? g_strdup (dest) : NULL; + +} + +static int +call_progress (GnomeVFSProgressCallbackState *progress, GnomeVFSXferPhase phase) +{ + int result; + + /* FIXME bugzilla.eazel.com 1199: should use proper progress result values from an enum here */ + + result = 0; + progress_set_source_target_uris (progress, NULL, NULL); + + progress->next_update_callback_time = system_time () + progress->update_callback_period; + + progress->progress_info->phase = phase; + + if (progress->sync_callback != NULL) + result = (* progress->sync_callback) (progress->progress_info, progress->user_data); + + if (progress->update_callback != NULL) { + result = (* progress->update_callback) (progress->progress_info, + progress->async_job_data); + } + + return result; +} + +static GnomeVFSXferErrorAction +call_progress_with_current_names (GnomeVFSProgressCallbackState *progress, GnomeVFSXferPhase phase) +{ + int result; + + result = GNOME_VFS_XFER_ERROR_ACTION_ABORT; + + progress->next_update_callback_time = system_time () + progress->update_callback_period; + progress->next_update_callback_time = progress->next_text_update_callback_time; + + progress->progress_info->phase = phase; + + if (progress->sync_callback != NULL) { + result = (* progress->sync_callback) (progress->progress_info, progress->user_data); + } + + if (progress->update_callback != NULL) { + result = (* progress->update_callback) (progress->progress_info, + progress->async_job_data); + } + + return result; +} + +static int +call_progress_uri (GnomeVFSProgressCallbackState *progress, + const GnomeVFSURI *source_uri, const GnomeVFSURI *dest_uri, + GnomeVFSXferPhase phase) +{ + int result; + + result = 0; + progress_set_source_target_uris (progress, source_uri, dest_uri); + + progress->next_text_update_callback_time = system_time () + progress->update_callback_period; + progress->next_update_callback_time = progress->next_text_update_callback_time; + + progress->progress_info->phase = phase; + + if (progress->sync_callback != NULL) { + result = (* progress->sync_callback) (progress->progress_info, progress->user_data); + } + + if (progress->update_callback != NULL) { + result = (* progress->update_callback) (progress->progress_info, + progress->async_job_data); + } + + return result; +} + +static gboolean +at_end (GnomeVFSProgressCallbackState *progress) +{ + return progress->progress_info->total_bytes_copied + >= progress->progress_info->bytes_total; +} + +static int +call_progress_often_internal (GnomeVFSProgressCallbackState *progress, + GnomeVFSXferPhase phase, + gint64 *next_time) +{ + int result; + gint64 now; + + result = 1; + now = system_time (); + + progress->progress_info->phase = phase; + + if (progress->sync_callback != NULL) { + result = (* progress->sync_callback) (progress->progress_info, progress->user_data); + } + + if (now < *next_time && !at_end (progress)) { + return result; + } + + *next_time = now + progress->update_callback_period; + if (progress->update_callback != NULL) { + result = (* progress->update_callback) (progress->progress_info, progress->async_job_data); + } + + return result; +} + +static int +call_progress_often (GnomeVFSProgressCallbackState *progress, + GnomeVFSXferPhase phase) +{ + return call_progress_often_internal + (progress, phase, &progress->next_update_callback_time); +} + +static int +call_progress_with_uris_often (GnomeVFSProgressCallbackState *progress, + const GnomeVFSURI *source_uri, const GnomeVFSURI *dest_uri, + GnomeVFSXferPhase phase) +{ + progress_set_source_target_uris (progress, source_uri, dest_uri); + return call_progress_often_internal + (progress, phase, &progress->next_text_update_callback_time); +} + +/* Handle an error condition according to `error_mode'. Returns `TRUE' if the + * operation should be retried, `FALSE' otherwise. `*result' will be set to + * the result value we want to be returned to the caller of the xfer + * function. + */ +static gboolean +handle_error (GnomeVFSResult *result, + GnomeVFSProgressCallbackState *progress, + GnomeVFSXferErrorMode *error_mode, + gboolean *skip) +{ + GnomeVFSXferErrorAction action; + + *skip = FALSE; + + switch (*error_mode) { + case GNOME_VFS_XFER_ERROR_MODE_ABORT: + return FALSE; + + case GNOME_VFS_XFER_ERROR_MODE_QUERY: + progress->progress_info->status = GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR; + progress->progress_info->vfs_status = *result; + action = call_progress_with_current_names (progress, progress->progress_info->phase); + progress->progress_info->status = GNOME_VFS_XFER_PROGRESS_STATUS_OK; + + switch (action) { + case GNOME_VFS_XFER_ERROR_ACTION_RETRY: + return TRUE; + case GNOME_VFS_XFER_ERROR_ACTION_ABORT: + *result = GNOME_VFS_ERROR_INTERRUPTED; + return FALSE; + case GNOME_VFS_XFER_ERROR_ACTION_SKIP: + *result = GNOME_VFS_OK; + *skip = TRUE; + return FALSE; + } + break; + } + + *skip = FALSE; + return FALSE; +} + +/* This is conceptually similiar to the previous `handle_error()' function, but + * handles the overwrite case. + */ +static gboolean +handle_overwrite (GnomeVFSResult *result, + GnomeVFSProgressCallbackState *progress, + GnomeVFSXferErrorMode *error_mode, + GnomeVFSXferOverwriteMode *overwrite_mode, + gboolean *replace, + gboolean *skip) +{ + GnomeVFSXferOverwriteAction action; + + switch (*overwrite_mode) { + case GNOME_VFS_XFER_OVERWRITE_MODE_ABORT: + *replace = FALSE; + *result = GNOME_VFS_ERROR_FILE_EXISTS; + *skip = FALSE; + return FALSE; + case GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE: + *replace = TRUE; + *skip = FALSE; + return TRUE; + case GNOME_VFS_XFER_OVERWRITE_MODE_SKIP: + *replace = FALSE; + *skip = TRUE; + return FALSE; + case GNOME_VFS_XFER_OVERWRITE_MODE_QUERY: + progress->progress_info->vfs_status = *result; + progress->progress_info->status = GNOME_VFS_XFER_PROGRESS_STATUS_OVERWRITE; + action = call_progress_with_current_names (progress, progress->progress_info->phase); + progress->progress_info->status = GNOME_VFS_XFER_PROGRESS_STATUS_OK; + + switch (action) { + case GNOME_VFS_XFER_OVERWRITE_ACTION_ABORT: + *replace = FALSE; + *result = GNOME_VFS_ERROR_FILE_EXISTS; + *skip = FALSE; + return FALSE; + case GNOME_VFS_XFER_OVERWRITE_ACTION_REPLACE: + *replace = TRUE; + *skip = FALSE; + return TRUE; + case GNOME_VFS_XFER_OVERWRITE_ACTION_REPLACE_ALL: + *replace = TRUE; + *overwrite_mode = GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE; + *skip = FALSE; + return TRUE; + case GNOME_VFS_XFER_OVERWRITE_ACTION_SKIP: + *replace = FALSE; + *skip = TRUE; + return FALSE; + case GNOME_VFS_XFER_OVERWRITE_ACTION_SKIP_ALL: + *replace = FALSE; + *skip = TRUE; + *overwrite_mode = GNOME_VFS_XFER_OVERWRITE_MODE_SKIP; + return FALSE; + } + } + + *replace = FALSE; + *skip = FALSE; + return FALSE; +} + +static GnomeVFSResult +remove_file (GnomeVFSURI *uri, + GnomeVFSProgressCallbackState *progress, + GnomeVFSXferOptions xfer_options, + GnomeVFSXferErrorMode *error_mode, + gboolean *skip) +{ + GnomeVFSResult result; + gboolean retry; + + progress->progress_info->file_index++; + do { + retry = FALSE; + result = gnome_vfs_unlink_from_uri (uri); + if (result != GNOME_VFS_OK) { + retry = handle_error (&result, progress, + error_mode, skip); + } else { + /* add some small size for each deleted item because delete overhead + * does not depend on file/directory size + */ + progress->progress_info->total_bytes_copied += DEFAULT_SIZE_OVERHEAD; + + if (call_progress_with_uris_often (progress, uri, NULL, + GNOME_VFS_XFER_PHASE_DELETESOURCE) + == GNOME_VFS_XFER_OVERWRITE_ACTION_ABORT) { + result = GNOME_VFS_ERROR_INTERRUPTED; + break; + } + } + + + } while (retry); + + return result; +} + +static GnomeVFSResult +empty_directory (GnomeVFSURI *uri, + GnomeVFSProgressCallbackState *progress, + GnomeVFSXferOptions xfer_options, + GnomeVFSXferErrorMode *error_mode, + gboolean *skip) +{ + GnomeVFSResult result; + GnomeVFSDirectoryHandle *directory_handle; + gboolean retry; + + + *skip = FALSE; + do { + result = gnome_vfs_directory_open_from_uri (&directory_handle, uri, + GNOME_VFS_FILE_INFO_DEFAULT); + retry = FALSE; + if (result != GNOME_VFS_OK) { + retry = handle_error (&result, progress, + error_mode, skip); + } + } while (retry); + + if (result != GNOME_VFS_OK || *skip) { + return result; + } + + for (;;) { + GnomeVFSFileInfo *info; + GnomeVFSURI *item_uri; + + item_uri = NULL; + info = gnome_vfs_file_info_new (); + result = gnome_vfs_directory_read_next (directory_handle, info); + if (result != GNOME_VFS_OK) { + gnome_vfs_file_info_unref (info); + break; + } + + /* Skip "." and "..". */ + if (strcmp (info->name, ".") != 0 && strcmp (info->name, "..") != 0) { + + item_uri = gnome_vfs_uri_append_file_name (uri, info->name); + + progress_set_source_target_uris (progress, item_uri, NULL); + + if (info->type == GNOME_VFS_FILE_TYPE_DIRECTORY) { + result = remove_directory (item_uri, TRUE, + progress, xfer_options, error_mode, + skip); + } else { + result = remove_file (item_uri, progress, + xfer_options, + error_mode, + skip); + } + + } + + gnome_vfs_file_info_unref (info); + + if (item_uri != NULL) { + gnome_vfs_uri_unref (item_uri); + } + + if (result != GNOME_VFS_OK) { + break; + } + } + gnome_vfs_directory_close (directory_handle); + + if (result == GNOME_VFS_ERROR_EOF) { + result = GNOME_VFS_OK; + } + + return result; +} + +typedef struct { + const GnomeVFSURI *base_uri; + GList *uri_list; +} PrependOneURIParams; + +static gboolean +PrependOneURIToList (const gchar *rel_path, GnomeVFSFileInfo *info, + gboolean recursing_will_loop, gpointer cast_to_params, gboolean *recurse) +{ + PrependOneURIParams *params; + + params = (PrependOneURIParams *)cast_to_params; + params->uri_list = g_list_prepend (params->uri_list, gnome_vfs_uri_append_string ( + params->base_uri, rel_path)); + + if (recursing_will_loop) { + return FALSE; + } + *recurse = TRUE; + return TRUE; +} + +static GnomeVFSResult +non_recursive_empty_directory (GnomeVFSURI *directory_uri, + GnomeVFSProgressCallbackState *progress, + GnomeVFSXferOptions xfer_options, + GnomeVFSXferErrorMode *error_mode, + gboolean *skip) +{ + /* Used as a fallback when we run out of file descriptors during + * a deep recursive deletion. + * We instead compile a flat list of URIs, doing a recursion that does not + * keep directories open. + */ + + GList *uri_list; + GList *p; + GnomeVFSURI *uri; + GnomeVFSResult result; + GnomeVFSFileInfo *info; + PrependOneURIParams visit_params; + + /* Build up the list so that deep items appear before their parents + * so that we can delete directories, children first. + */ + visit_params.base_uri = directory_uri; + visit_params.uri_list = NULL; + result = gnome_vfs_directory_visit_uri (directory_uri, GNOME_VFS_FILE_INFO_DEFAULT, + GNOME_VFS_DIRECTORY_VISIT_SAMEFS | GNOME_VFS_DIRECTORY_VISIT_LOOPCHECK, + PrependOneURIToList, &visit_params); + + uri_list = visit_params.uri_list; + + if (result == GNOME_VFS_OK) { + for (p = uri_list; p != NULL; p = p->next) { + + uri = (GnomeVFSURI *)p->data; + info = gnome_vfs_file_info_new (); + result = gnome_vfs_get_file_info_uri (uri, info, GNOME_VFS_FILE_INFO_DEFAULT); + progress_set_source_target_uris (progress, uri, NULL); + if (result == GNOME_VFS_OK) { + if (info->type == GNOME_VFS_FILE_TYPE_DIRECTORY) { + result = remove_directory (uri, FALSE, + progress, xfer_options, error_mode, skip); + } else { + result = remove_file (uri, progress, + xfer_options, error_mode, skip); + } + } + gnome_vfs_file_info_unref (info); + } + } + + gnome_vfs_uri_list_free (uri_list); + + return result; +} + +static GnomeVFSResult +remove_directory (GnomeVFSURI *uri, + gboolean recursive, + GnomeVFSProgressCallbackState *progress, + GnomeVFSXferOptions xfer_options, + GnomeVFSXferErrorMode *error_mode, + gboolean *skip) +{ + GnomeVFSResult result; + gboolean retry; + + result = GNOME_VFS_OK; + + if (recursive) { + result = empty_directory (uri, progress, xfer_options, error_mode, skip); + if (result == GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES) { + result = non_recursive_empty_directory (uri, progress, xfer_options, + error_mode, skip); + } + } + + if (result == GNOME_VFS_ERROR_EOF) { + result = GNOME_VFS_OK; + } + + if (result == GNOME_VFS_OK) { + progress->progress_info->file_index++; + + do { + retry = FALSE; + + result = gnome_vfs_remove_directory_from_uri (uri); + if (result != GNOME_VFS_OK) { + retry = handle_error (&result, progress, + error_mode, skip); + } else { + /* add some small size for each deleted item */ + progress->progress_info->total_bytes_copied += DEFAULT_SIZE_OVERHEAD; + + if (call_progress_with_uris_often (progress, uri, NULL, + GNOME_VFS_XFER_PHASE_DELETESOURCE) + == GNOME_VFS_XFER_OVERWRITE_ACTION_ABORT) { + result = GNOME_VFS_ERROR_INTERRUPTED; + break; + } + } + + } while (retry); + } + + return result; +} + +/* iterates the list of names in a given directory, applies @callback on each, + * optionally recurses into directories + */ +static GnomeVFSResult +gnome_vfs_visit_list (const GList *name_uri_list, + GnomeVFSFileInfoOptions info_options, + GnomeVFSDirectoryVisitOptions visit_options, + gboolean recursive, + GnomeVFSDirectoryVisitFunc callback, + gpointer data) +{ + GnomeVFSResult result; + const GList *p; + GnomeVFSURI *uri; + GnomeVFSFileInfo *info; + gboolean tmp_recurse; + + result = GNOME_VFS_OK; + + /* go through our list of items */ + for (p = name_uri_list; p != NULL; p = p->next) { + + /* get the URI and VFSFileInfo for each */ + uri = (GnomeVFSURI *)p->data; + info = gnome_vfs_file_info_new (); + result = gnome_vfs_get_file_info_uri (uri, info, info_options); + + if (result == GNOME_VFS_OK) { + tmp_recurse = TRUE; + + /* call our callback on each item*/ + if (!callback (gnome_vfs_uri_get_path (uri), info, FALSE, data, &tmp_recurse)) { + result = GNOME_VFS_ERROR_INTERRUPTED; + } + + if (result == GNOME_VFS_OK + && recursive + && info->type == GNOME_VFS_FILE_TYPE_DIRECTORY) { + /* let gnome_vfs_directory_visit_uri call our callback + * recursively + */ + result = gnome_vfs_directory_visit_uri (uri, info_options, + visit_options, callback, data); + } + } + gnome_vfs_file_info_unref (info); + + if (result != GNOME_VFS_OK) { + break; + } + } + return result; +} + +typedef struct { + GnomeVFSProgressCallbackState *progress; + GnomeVFSResult result; +} CountEachFileSizeParams; + +/* iteratee for count_items_and_size */ +static gboolean +count_each_file_size_one (const gchar *rel_path, + GnomeVFSFileInfo *info, + gboolean recursing_will_loop, + gpointer data, + gboolean *recurse) +{ + CountEachFileSizeParams *params; + + params = (CountEachFileSizeParams *)data; + + if (call_progress_often (params->progress, params->progress->progress_info->phase) == 0) { + /* progress callback requested to stop */ + params->result = GNOME_VFS_ERROR_INTERRUPTED; + *recurse = FALSE; + return FALSE; + } + + /* keep track of the item we are counting so we can correctly report errors */ + progress_set_source_target (params->progress, rel_path, NULL); + + /* count each file, folder, symlink */ + params->progress->progress_info->files_total++; + if (info->type == GNOME_VFS_FILE_TYPE_REGULAR) { + /* add each file size */ + params->progress->progress_info->bytes_total += info->size + DEFAULT_SIZE_OVERHEAD; + } else if (info->type == GNOME_VFS_FILE_TYPE_DIRECTORY) { + /* add some small size for each directory */ + params->progress->progress_info->bytes_total += DEFAULT_SIZE_OVERHEAD; + } + + /* watch out for infinite recursion*/ + if (recursing_will_loop) { + params->result = GNOME_VFS_ERROR_LOOP; + return FALSE; + } + + *recurse = TRUE; + + return TRUE; +} + +/* calculate the number of items and their total size; used as a preflight + * before the transfer operation starts + */ +static GnomeVFSResult +count_items_and_size (const GList *name_uri_list, + GnomeVFSXferOptions xfer_options, + GnomeVFSProgressCallbackState *progress, + gboolean move, + gboolean link) +{ + /* + * FIXME bugzilla.eazel.com 1200: + * Deal with errors here, respond to skip by pulling items from the name list + */ + GnomeVFSFileInfoOptions info_options; + GnomeVFSDirectoryVisitOptions visit_options; + CountEachFileSizeParams each_params; + + /* initialize the results */ + progress->progress_info->files_total = 0; + progress->progress_info->bytes_total = 0; + + /* set up the params for recursion */ + visit_options = GNOME_VFS_DIRECTORY_VISIT_LOOPCHECK; + if (xfer_options & GNOME_VFS_XFER_SAMEFS) + visit_options |= GNOME_VFS_DIRECTORY_VISIT_SAMEFS; + each_params.progress = progress; + each_params.result = GNOME_VFS_OK; + + if (xfer_options & GNOME_VFS_XFER_FOLLOW_LINKS) { + info_options = GNOME_VFS_FILE_INFO_FOLLOW_LINKS; + } else { + info_options = GNOME_VFS_FILE_INFO_DEFAULT; + } + + return gnome_vfs_visit_list (name_uri_list, info_options, + visit_options, !link && !move && (xfer_options & GNOME_VFS_XFER_RECURSIVE) != 0, + count_each_file_size_one, &each_params); +} + +/* calculate the number of items and their total size; used as a preflight + * before the transfer operation starts + */ +static GnomeVFSResult +directory_add_items_and_size (GnomeVFSURI *dir_uri, + GnomeVFSXferOptions xfer_options, + GnomeVFSProgressCallbackState *progress) +{ + GnomeVFSFileInfoOptions info_options; + GnomeVFSDirectoryVisitOptions visit_options; + CountEachFileSizeParams each_params; + + /* set up the params for recursion */ + visit_options = GNOME_VFS_DIRECTORY_VISIT_LOOPCHECK; + if (xfer_options & GNOME_VFS_XFER_SAMEFS) + visit_options |= GNOME_VFS_DIRECTORY_VISIT_SAMEFS; + each_params.progress = progress; + each_params.result = GNOME_VFS_OK; + + if (xfer_options & GNOME_VFS_XFER_FOLLOW_LINKS) { + info_options = GNOME_VFS_FILE_INFO_FOLLOW_LINKS; + } else { + info_options = GNOME_VFS_FILE_INFO_DEFAULT; + } + + return gnome_vfs_directory_visit_uri (dir_uri, info_options, + visit_options, count_each_file_size_one, &each_params); + +} + +/* Checks to see if any part of the source pathname of a move + * is inside the target. If it is we can't remove the target + * and then move the source to it since we would then remove + * the source before we moved it. + */ +static gboolean +move_source_is_in_target (GnomeVFSURI *source, GnomeVFSURI *target) +{ + GnomeVFSURI *parent, *tmp; + gboolean res; + + parent = gnome_vfs_uri_ref (source); + + res = FALSE; + while (parent != NULL) { + if (_gnome_vfs_uri_is_in_subdir (parent, target)) { + res = TRUE; + break; + } + tmp = gnome_vfs_uri_get_parent (parent); + gnome_vfs_uri_unref (parent); + parent = tmp; + } + gnome_vfs_uri_unref (parent); + + return res; +} + +/* Compares the list of files about to be created by a transfer with + * any possible existing files with conflicting names in the target directory. + * Handles conflicts, optionaly removing the conflicting file/directory + */ +static GnomeVFSResult +handle_name_conflicts (GList **source_uri_list, + GList **target_uri_list, + GnomeVFSXferOptions xfer_options, + GnomeVFSXferErrorMode *error_mode, + GnomeVFSXferOverwriteMode *overwrite_mode, + GnomeVFSProgressCallbackState *progress) +{ + GnomeVFSResult result; + GList *source_item; + GList *target_item; + + int conflict_count; /* values are 0, 1, many */ + + result = GNOME_VFS_OK; + conflict_count = 0; + + /* Go through the list of names, find out if there is 0, 1 or more conflicts. */ + for (target_item = *target_uri_list; target_item != NULL; + target_item = target_item->next) { + if (gnome_vfs_uri_exists ((GnomeVFSURI *)target_item->data)) { + conflict_count++; + if (conflict_count > 1) { + break; + } + } + } + + if (conflict_count == 0) { + /* No conflicts, we are done. */ + return GNOME_VFS_OK; + } + + /* Pass in the conflict count so that we can decide to present the Replace All + * for multiple conflicts. + */ + progress->progress_info->duplicate_count = conflict_count; + + + /* Go through the list of names again, present overwrite alerts for each. */ + for (target_item = *target_uri_list, source_item = *source_uri_list; + target_item != NULL;) { + gboolean replace; + gboolean skip; + gboolean is_move_to_self; + GnomeVFSURI *uri, *source_uri; + GnomeVFSFileInfo *info; + + skip = FALSE; + source_uri = (GnomeVFSURI *)source_item->data; + uri = (GnomeVFSURI *)target_item->data; + is_move_to_self = (xfer_options & GNOME_VFS_XFER_REMOVESOURCE) != 0 + && gnome_vfs_uri_equal (source_uri, uri); + if (!is_move_to_self && gnome_vfs_uri_exists (uri)) { + progress_set_source_target_uris (progress, source_uri, uri); + + /* no error getting info -- file exists, ask what to do */ + replace = handle_overwrite (&result, progress, error_mode, + overwrite_mode, &replace, &skip); + + /* FIXME bugzilla.eazel.com 1207: + * move items to Trash here + */ + + /* get rid of the conflicting file */ + if (replace) { + info = gnome_vfs_file_info_new (); + gnome_vfs_get_file_info_uri (uri, info, GNOME_VFS_FILE_INFO_DEFAULT); + progress_set_source_target_uris (progress, uri, NULL); + if (info->type == GNOME_VFS_FILE_TYPE_DIRECTORY) { + if (move_source_is_in_target (source_uri, uri)) { + /* Would like a better error here */ + result = GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY; + } else { + remove_directory (uri, TRUE, progress, + xfer_options, error_mode, &skip); + } + } else { + remove_file (uri, progress, + xfer_options, error_mode, &skip); + } + gnome_vfs_file_info_unref (info); + } + } + + + if (result != GNOME_VFS_OK) { + break; + } + + if (skip) { + /* skipping a file, remove it's name from the source and target name + * lists. + */ + GList *source_item_to_remove; + GList *target_item_to_remove; + + source_item_to_remove = source_item; + target_item_to_remove = target_item; + + source_item = source_item->next; + target_item = target_item->next; + + gnome_vfs_uri_unref ((GnomeVFSURI *)source_item_to_remove->data); + gnome_vfs_uri_unref ((GnomeVFSURI *)target_item_to_remove->data); + *source_uri_list = g_list_remove_link (*source_uri_list, source_item_to_remove); + *target_uri_list = g_list_remove_link (*target_uri_list, target_item_to_remove); + + continue; + } + + + target_item = target_item->next; + source_item = source_item->next; + } + + return result; +} + +/* Create new directory. If GNOME_VFS_XFER_USE_UNIQUE_NAMES is set, + * return with an error if a name conflict occurs, else + * handle the overwrite. + * On success, opens the new directory + */ +static GnomeVFSResult +create_directory (GnomeVFSURI *dir_uri, + GnomeVFSDirectoryHandle **return_handle, + GnomeVFSXferOptions xfer_options, + GnomeVFSXferErrorMode *error_mode, + GnomeVFSXferOverwriteMode *overwrite_mode, + GnomeVFSProgressCallbackState *progress, + gboolean *skip) +{ + GnomeVFSResult result; + gboolean retry; + + *skip = FALSE; + do { + retry = FALSE; + + result = gnome_vfs_make_directory_for_uri (dir_uri, 0777); + + if (result == GNOME_VFS_ERROR_FILE_EXISTS) { + gboolean force_replace; + + if ((xfer_options & GNOME_VFS_XFER_USE_UNIQUE_NAMES) != 0) { + /* just let the caller pass a unique name*/ + return result; + } + + retry = handle_overwrite (&result, + progress, + error_mode, + overwrite_mode, + &force_replace, + skip); + + if (*skip) { + return GNOME_VFS_OK; + } + if (force_replace) { + result = remove_directory (dir_uri, TRUE, progress, + xfer_options, error_mode, + skip); + } else { + result = GNOME_VFS_OK; + } + } + + if (result == GNOME_VFS_OK) { + return gnome_vfs_directory_open_from_uri (return_handle, + dir_uri, + GNOME_VFS_FILE_INFO_DEFAULT); + } + /* handle the error case */ + retry = handle_error (&result, progress, + error_mode, skip); + + if (*skip) { + return GNOME_VFS_OK; + } + + } while (retry); + + return result; +} + +/* Copy the data of a single file. */ +static GnomeVFSResult +copy_file_data (GnomeVFSHandle *target_handle, + GnomeVFSHandle *source_handle, + GnomeVFSProgressCallbackState *progress, + GnomeVFSXferOptions xfer_options, + GnomeVFSXferErrorMode *error_mode, + guint block_size, + gboolean *skip) +{ + GnomeVFSResult result; + gpointer buffer; + const char *write_buffer; + GnomeVFSFileSize total_bytes_read; + + *skip = FALSE; + + if (call_progress_often (progress, GNOME_VFS_XFER_PHASE_COPYING) == 0) { + return GNOME_VFS_ERROR_INTERRUPTED; + } + + buffer = g_malloc (block_size); + total_bytes_read = 0; + + do { + GnomeVFSFileSize bytes_read; + GnomeVFSFileSize bytes_to_write; + GnomeVFSFileSize bytes_written; + gboolean retry; + + progress->progress_info->status = GNOME_VFS_XFER_PROGRESS_STATUS_OK; + progress->progress_info->vfs_status = GNOME_VFS_OK; + + progress->progress_info->phase = GNOME_VFS_XFER_PHASE_READSOURCE; + + do { + retry = FALSE; + + result = gnome_vfs_read (source_handle, buffer, + block_size, &bytes_read); + if (result != GNOME_VFS_OK && result != GNOME_VFS_ERROR_EOF) + retry = handle_error (&result, progress, + error_mode, skip); + } while (retry); + + if (result != GNOME_VFS_OK || bytes_read == 0 || *skip) { + break; + } + + total_bytes_read += total_bytes_read; + bytes_to_write = bytes_read; + + progress->progress_info->phase = GNOME_VFS_XFER_PHASE_WRITETARGET; + + write_buffer = buffer; + do { + retry = FALSE; + + result = gnome_vfs_write (target_handle, write_buffer, + bytes_to_write, + &bytes_written); + + if (result != GNOME_VFS_OK) { + retry = handle_error (&result, progress, error_mode, skip); + } + + bytes_to_write -= bytes_written; + write_buffer += bytes_written; + } while ((result == GNOME_VFS_OK && bytes_to_write > 0) || retry); + + progress->progress_info->phase = GNOME_VFS_XFER_PHASE_COPYING; + + progress->progress_info->bytes_copied += bytes_read; + progress->progress_info->total_bytes_copied += bytes_read; + + if (call_progress_often (progress, GNOME_VFS_XFER_PHASE_COPYING) == 0) { + g_free (buffer); + return GNOME_VFS_ERROR_INTERRUPTED; + } + + if (*skip) { + break; + } + + } while (result == GNOME_VFS_OK); + + if (result == GNOME_VFS_ERROR_EOF) { + result = GNOME_VFS_OK; + } + + if (result == GNOME_VFS_OK) { + /* tiny (0 - sized) files still present non-zero overhead during a copy, make sure + * we count at least a default amount for each file + */ + progress->progress_info->total_bytes_copied += DEFAULT_SIZE_OVERHEAD; + + call_progress_often (progress, GNOME_VFS_XFER_PHASE_COPYING); + } + + g_free (buffer); + + return result; +} + +static GnomeVFSResult +xfer_open_source (GnomeVFSHandle **source_handle, + GnomeVFSURI *source_uri, + GnomeVFSProgressCallbackState *progress, + GnomeVFSXferOptions xfer_options, + GnomeVFSXferErrorMode *error_mode, + gboolean *skip) +{ + GnomeVFSResult result; + gboolean retry; + + *skip = FALSE; + do { + retry = FALSE; + + result = gnome_vfs_open_uri (source_handle, source_uri, + GNOME_VFS_OPEN_READ); + + if (result != GNOME_VFS_OK) { + retry = handle_error (&result, progress, error_mode, skip); + } + } while (retry); + + return result; +} + +static GnomeVFSResult +xfer_create_target (GnomeVFSHandle **target_handle, + GnomeVFSURI *target_uri, + GnomeVFSProgressCallbackState *progress, + GnomeVFSXferOptions xfer_options, + GnomeVFSXferErrorMode *error_mode, + GnomeVFSXferOverwriteMode *overwrite_mode, + gboolean *skip) +{ + GnomeVFSResult result; + gboolean retry; + gboolean exclusive; + + exclusive = (*overwrite_mode != GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE); + + *skip = FALSE; + do { + retry = FALSE; + + result = gnome_vfs_create_uri (target_handle, target_uri, + GNOME_VFS_OPEN_WRITE, + exclusive, 0666); + + if (result == GNOME_VFS_ERROR_FILE_EXISTS) { + gboolean replace; + + retry = handle_overwrite (&result, + progress, + error_mode, + overwrite_mode, + &replace, + skip); + + if (replace) { + exclusive = FALSE; + } + + } else if (result != GNOME_VFS_OK) { + retry = handle_error (&result, progress, error_mode, skip); + } + } while (retry); + + return result; +} + +static GnomeVFSResult +copy_symlink (GnomeVFSURI *source_uri, + GnomeVFSURI *target_uri, + const char *link_name, + GnomeVFSXferErrorMode *error_mode, + GnomeVFSProgressCallbackState *progress, + gboolean *skip) +{ + GnomeVFSResult result; + gboolean retry; + + *skip = FALSE; + do { + retry = FALSE; + + result = gnome_vfs_create_symbolic_link (target_uri, link_name); + + if (result != GNOME_VFS_OK) { + retry = handle_error (&result, progress, error_mode, skip); + } else if (result == GNOME_VFS_OK && + call_progress_with_uris_often (progress, source_uri, + target_uri, GNOME_VFS_XFER_PHASE_OPENTARGET) == 0) { + result = GNOME_VFS_ERROR_INTERRUPTED; + } + } while (retry); + + if (*skip) { + return GNOME_VFS_OK; + } + + return result; +} + +static GnomeVFSResult +copy_file (GnomeVFSFileInfo *info, + GnomeVFSURI *source_uri, + GnomeVFSURI *target_uri, + GnomeVFSXferOptions xfer_options, + GnomeVFSXferErrorMode *error_mode, + GnomeVFSXferOverwriteMode *overwrite_mode, + GnomeVFSProgressCallbackState *progress, + gboolean *skip) +{ + GnomeVFSResult close_result, result; + GnomeVFSHandle *source_handle, *target_handle; + GnomeVFSSetFileInfoMask set_mask; + + progress->progress_info->phase = GNOME_VFS_XFER_PHASE_OPENSOURCE; + progress->progress_info->bytes_copied = 0; + result = xfer_open_source (&source_handle, source_uri, + progress, xfer_options, + error_mode, skip); + if (*skip) { + return GNOME_VFS_OK; + } + + if (result != GNOME_VFS_OK) { + return result; + } + + progress->progress_info->phase = GNOME_VFS_XFER_PHASE_OPENTARGET; + result = xfer_create_target (&target_handle, target_uri, + progress, xfer_options, + error_mode, overwrite_mode, + skip); + + + if (*skip) { + gnome_vfs_close (source_handle); + return GNOME_VFS_OK; + } + if (result != GNOME_VFS_OK) { + gnome_vfs_close (source_handle); + return result; + } + + if (call_progress_with_uris_often (progress, source_uri, target_uri, + GNOME_VFS_XFER_PHASE_OPENTARGET) != GNOME_VFS_XFER_OVERWRITE_ACTION_ABORT) { + + result = copy_file_data (target_handle, source_handle, + progress, xfer_options, error_mode, + /* use an arbitrary default block size of 4096 + * if one isn't available for this file system + */ + (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_IO_BLOCK_SIZE && info->io_block_size > 0) + ? info->io_block_size : 4096, + skip); + } + + if (result == GNOME_VFS_OK + && call_progress_often (progress, GNOME_VFS_XFER_PHASE_CLOSETARGET) == 0) { + result = GNOME_VFS_ERROR_INTERRUPTED; + } + + close_result = gnome_vfs_close (source_handle); + if (result == GNOME_VFS_OK && close_result != GNOME_VFS_OK) { + handle_error (&close_result, progress, error_mode, skip); + return close_result; + } + + close_result = gnome_vfs_close (target_handle); + if (result == GNOME_VFS_OK && close_result != GNOME_VFS_OK) { + handle_error (&close_result, progress, error_mode, skip); + return close_result; + } + + if (result == GNOME_VFS_OK) { + /* FIXME the modules should ignore setting of permissions if + * "valid_fields & GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS" is clear + * for now, make sure permissions aren't set to 000 + */ + + if ((info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS) == 0) { + set_mask = GNOME_VFS_SET_FILE_INFO_TIME; + } else { + set_mask = GNOME_VFS_SET_FILE_INFO_PERMISSIONS + | GNOME_VFS_SET_FILE_INFO_OWNER + | GNOME_VFS_SET_FILE_INFO_TIME; + } + + /* ignore errors while setting file info attributes at this point */ + gnome_vfs_set_file_info_uri (target_uri, info, set_mask); + } + + if (*skip) { + return GNOME_VFS_OK; + } + + return result; +} + +static GnomeVFSResult +copy_directory (GnomeVFSFileInfo *source_file_info, + GnomeVFSURI *source_dir_uri, + GnomeVFSURI *target_dir_uri, + GnomeVFSXferOptions xfer_options, + GnomeVFSXferErrorMode *error_mode, + GnomeVFSXferOverwriteMode *overwrite_mode, + GnomeVFSProgressCallbackState *progress, + gboolean *skip) +{ + GnomeVFSResult result; + GnomeVFSDirectoryHandle *source_directory_handle; + GnomeVFSDirectoryHandle *dest_directory_handle; + GnomeVFSSetFileInfoMask set_mask; + + source_directory_handle = NULL; + dest_directory_handle = NULL; + + result = gnome_vfs_directory_open_from_uri (&source_directory_handle, source_dir_uri, + GNOME_VFS_FILE_INFO_DEFAULT); + + if (result != GNOME_VFS_OK) { + return result; + } + + progress->progress_info->bytes_copied = 0; + if (call_progress_with_uris_often (progress, source_dir_uri, target_dir_uri, + GNOME_VFS_XFER_PHASE_COPYING) + == GNOME_VFS_XFER_OVERWRITE_ACTION_ABORT) { + return GNOME_VFS_ERROR_INTERRUPTED; + } + + result = create_directory (target_dir_uri, + &dest_directory_handle, + xfer_options, + error_mode, + overwrite_mode, + progress, + skip); + + if (*skip) { + gnome_vfs_directory_close (source_directory_handle); + return GNOME_VFS_OK; + } + + if (result != GNOME_VFS_OK) { + gnome_vfs_directory_close (source_directory_handle); + return result; + } + + if (call_progress_with_uris_often (progress, source_dir_uri, target_dir_uri, + GNOME_VFS_XFER_PHASE_OPENTARGET) != 0) { + + progress->progress_info->total_bytes_copied += DEFAULT_SIZE_OVERHEAD; + progress->progress_info->top_level_item = FALSE; + + /* We do not deal with symlink loops here. That's OK + * because we don't follow symlinks, unless the user + * explicitly requests this with + * GNOME_VFS_XFER_FOLLOW_LINKS_RECURSIVE. + */ + do { + GnomeVFSURI *source_uri; + GnomeVFSURI *dest_uri; + GnomeVFSFileInfo *info; + + source_uri = NULL; + dest_uri = NULL; + info = gnome_vfs_file_info_new (); + + result = gnome_vfs_directory_read_next (source_directory_handle, info); + if (result != GNOME_VFS_OK) { + gnome_vfs_file_info_unref (info); + break; + } + + /* Skip "." and "..". */ + if (strcmp (info->name, ".") != 0 && strcmp (info->name, "..") != 0) { + + progress->progress_info->file_index++; + + source_uri = gnome_vfs_uri_append_file_name (source_dir_uri, info->name); + dest_uri = gnome_vfs_uri_append_file_name (target_dir_uri, info->name); + + if (info->type == GNOME_VFS_FILE_TYPE_REGULAR) { + result = copy_file (info, source_uri, dest_uri, + xfer_options, error_mode, overwrite_mode, + progress, skip); + } else if (info->type == GNOME_VFS_FILE_TYPE_DIRECTORY) { + result = copy_directory (info, source_uri, dest_uri, + xfer_options, error_mode, overwrite_mode, + progress, skip); + } else if (info->type == GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK) { + if (xfer_options & GNOME_VFS_XFER_FOLLOW_LINKS_RECURSIVE) { + GnomeVFSFileInfo *symlink_target_info = gnome_vfs_file_info_new (); + result = gnome_vfs_get_file_info_uri (source_uri, symlink_target_info, + GNOME_VFS_FILE_INFO_FOLLOW_LINKS); + if (result == GNOME_VFS_OK) + result = copy_file (symlink_target_info, source_uri, dest_uri, + xfer_options, error_mode, overwrite_mode, + progress, skip); + gnome_vfs_file_info_unref (symlink_target_info); + } else { + result = copy_symlink (source_uri, dest_uri, info->symlink_name, + error_mode, progress, skip); + } + } + /* just ignore all the other special file system objects here */ + } + + gnome_vfs_file_info_unref (info); + + if (dest_uri != NULL) { + gnome_vfs_uri_unref (dest_uri); + } + if (source_uri != NULL) { + gnome_vfs_uri_unref (source_uri); + } + + } while (result == GNOME_VFS_OK); + } + + if (result == GNOME_VFS_ERROR_EOF) { + /* all is well, we just finished iterating the directory */ + result = GNOME_VFS_OK; + } + + gnome_vfs_directory_close (dest_directory_handle); + gnome_vfs_directory_close (source_directory_handle); + + if (result == GNOME_VFS_OK) { + /* FIXME the modules should ignore setting of permissions if + * "valid_fields & GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS" is clear + * for now, make sure permissions aren't set to 000 + */ + + if ((source_file_info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS) == 0) { + set_mask = GNOME_VFS_SET_FILE_INFO_TIME; + } else { + set_mask = GNOME_VFS_SET_FILE_INFO_PERMISSIONS + | GNOME_VFS_SET_FILE_INFO_OWNER + | GNOME_VFS_SET_FILE_INFO_TIME; + } + + /* ignore errors while setting file info attributes at this point */ + gnome_vfs_set_file_info_uri (target_dir_uri, source_file_info, set_mask); + } + + return result; +} + +static GnomeVFSResult +copy_items (const GList *source_uri_list, + const GList *target_uri_list, + GnomeVFSXferOptions xfer_options, + GnomeVFSXferErrorMode *error_mode, + GnomeVFSXferOverwriteMode overwrite_mode, + GnomeVFSProgressCallbackState *progress, + GList **p_source_uris_copied_list) +{ + GnomeVFSResult result; + const GList *source_item, *target_item; + + result = GNOME_VFS_OK; + + /* go through the list of names */ + for (source_item = source_uri_list, target_item = target_uri_list; source_item != NULL;) { + + GnomeVFSURI *source_uri; + GnomeVFSURI *target_uri; + GnomeVFSURI *target_dir_uri; + + GnomeVFSFileInfo *info; + gboolean skip; + int count; + int progress_result; + + progress->progress_info->file_index++; + + skip = FALSE; + target_uri = NULL; + + source_uri = (GnomeVFSURI *)source_item->data; + target_dir_uri = gnome_vfs_uri_get_parent ((GnomeVFSURI *)target_item->data); + + /* get source URI and file info */ + info = gnome_vfs_file_info_new (); + result = gnome_vfs_get_file_info_uri (source_uri, info, + GNOME_VFS_FILE_INFO_DEFAULT); + + progress->progress_info->duplicate_name = + gnome_vfs_uri_extract_short_path_name + ((GnomeVFSURI *)target_item->data); + + if (result == GNOME_VFS_OK) { + /* optionally keep trying until we hit a unique target name */ + for (count = 1; ; count++) { + GnomeVFSXferOverwriteMode overwrite_mode_abort; + + target_uri = gnome_vfs_uri_append_string + (target_dir_uri, + progress->progress_info->duplicate_name); + + progress->progress_info->status = GNOME_VFS_XFER_PROGRESS_STATUS_OK; + progress->progress_info->file_size = info->size; + progress->progress_info->bytes_copied = 0; + progress->progress_info->top_level_item = TRUE; + + if (call_progress_with_uris_often (progress, source_uri, target_uri, + GNOME_VFS_XFER_PHASE_COPYING) == 0) { + result = GNOME_VFS_ERROR_INTERRUPTED; + } + + overwrite_mode_abort = GNOME_VFS_XFER_OVERWRITE_MODE_ABORT; + + + if (info->type == GNOME_VFS_FILE_TYPE_REGULAR) { + result = copy_file (info, source_uri, target_uri, + xfer_options, error_mode, + &overwrite_mode_abort, + progress, &skip); + } else if (info->type == GNOME_VFS_FILE_TYPE_DIRECTORY) { + result = copy_directory (info, source_uri, target_uri, + xfer_options, error_mode, + &overwrite_mode_abort, + progress, &skip); + } else if (info->type == GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK) { + result = copy_symlink (source_uri, target_uri, info->symlink_name, + error_mode, progress, &skip); + } + /* just ignore all the other special file system objects here */ + + if (result == GNOME_VFS_OK && !skip) { + /* Add to list of successfully copied files... */ + *p_source_uris_copied_list = g_list_prepend (*p_source_uris_copied_list, source_uri); + gnome_vfs_uri_ref (source_uri); + } + + if (result != GNOME_VFS_ERROR_FILE_EXISTS) { + /* whatever happened, it wasn't a name conflict */ + break; + } + + if (overwrite_mode != GNOME_VFS_XFER_OVERWRITE_MODE_QUERY + || (xfer_options & GNOME_VFS_XFER_USE_UNIQUE_NAMES) == 0) + break; + + /* pass in the current target name, progress will update it to + * a new unique name such as 'foo (copy)' or 'bar (copy 2)' + */ + g_free (progress->progress_info->duplicate_name); + progress->progress_info->duplicate_name = + gnome_vfs_uri_extract_short_path_name + ((GnomeVFSURI *)target_item->data); + progress->progress_info->duplicate_count = count; + progress->progress_info->status = GNOME_VFS_XFER_PROGRESS_STATUS_DUPLICATE; + progress->progress_info->vfs_status = result; + progress_result = call_progress_uri (progress, source_uri, target_uri, + GNOME_VFS_XFER_PHASE_COPYING); + progress->progress_info->status = GNOME_VFS_XFER_PROGRESS_STATUS_OK; + + if (progress_result == GNOME_VFS_XFER_OVERWRITE_ACTION_ABORT) { + break; + } + + if (skip) { + break; + } + + /* try again with new uri */ + gnome_vfs_uri_unref (target_uri); + + } + } + + gnome_vfs_file_info_unref (info); + g_free (progress->progress_info->duplicate_name); + + if (result != GNOME_VFS_OK) { + break; + } + + gnome_vfs_uri_unref (target_dir_uri); + + source_item = source_item->next; + target_item = target_item->next; + + g_assert ((source_item != NULL) == (target_item != NULL)); + } + + return result; +} + +static GnomeVFSResult +move_items (const GList *source_uri_list, + const GList *target_uri_list, + GnomeVFSXferOptions xfer_options, + GnomeVFSXferErrorMode *error_mode, + GnomeVFSXferOverwriteMode *overwrite_mode, + GnomeVFSProgressCallbackState *progress) +{ + GnomeVFSResult result; + const GList *source_item, *target_item; + + result = GNOME_VFS_OK; + + /* go through the list of names */ + for (source_item = source_uri_list, target_item = target_uri_list; source_item != NULL;) { + + GnomeVFSURI *source_uri; + GnomeVFSURI *target_uri; + GnomeVFSURI *target_dir_uri; + gboolean retry; + gboolean skip; + int conflict_count; + int progress_result; + + progress->progress_info->file_index++; + + source_uri = (GnomeVFSURI *)source_item->data; + target_dir_uri = gnome_vfs_uri_get_parent ((GnomeVFSURI *)target_item->data); + + progress->progress_info->duplicate_name = + gnome_vfs_uri_extract_short_path_name + ((GnomeVFSURI *)target_item->data); + + skip = FALSE; + conflict_count = 1; + + do { + retry = FALSE; + target_uri = gnome_vfs_uri_append_string (target_dir_uri, + progress->progress_info->duplicate_name); + + progress->progress_info->file_size = 0; + progress->progress_info->bytes_copied = 0; + progress_set_source_target_uris (progress, source_uri, target_uri); + progress->progress_info->top_level_item = TRUE; + + /* no matter what the replace mode, just overwrite the destination + * handle_name_conflicts took care of conflicting files + */ + result = gnome_vfs_move_uri (source_uri, target_uri, + (xfer_options & GNOME_VFS_XFER_USE_UNIQUE_NAMES) != 0 + ? GNOME_VFS_XFER_OVERWRITE_MODE_ABORT + : GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE); + + + if (result == GNOME_VFS_ERROR_FILE_EXISTS) { + /* deal with a name conflict -- ask the progress_callback for a better name */ + g_free (progress->progress_info->duplicate_name); + progress->progress_info->duplicate_name = + gnome_vfs_uri_extract_short_path_name + ((GnomeVFSURI *)target_item->data); + progress->progress_info->duplicate_count = conflict_count; + progress->progress_info->status = GNOME_VFS_XFER_PROGRESS_STATUS_DUPLICATE; + progress->progress_info->vfs_status = result; + progress_result = call_progress_uri (progress, source_uri, target_uri, + GNOME_VFS_XFER_PHASE_COPYING); + progress->progress_info->status = GNOME_VFS_XFER_PROGRESS_STATUS_OK; + + if (progress_result == GNOME_VFS_XFER_OVERWRITE_ACTION_ABORT) { + gnome_vfs_uri_unref (target_uri); + break; + } + conflict_count++; + result = GNOME_VFS_OK; + retry = TRUE; + continue; + } + + if (result != GNOME_VFS_OK) { + retry = handle_error (&result, progress, error_mode, &skip); + } + + if (result == GNOME_VFS_OK + && !skip + && call_progress_with_uris_often (progress, source_uri, + target_uri, GNOME_VFS_XFER_PHASE_MOVING) == 0) { + result = GNOME_VFS_ERROR_INTERRUPTED; + gnome_vfs_uri_unref (target_uri); + break; + } + gnome_vfs_uri_unref (target_uri); + } while (retry); + + gnome_vfs_uri_unref (target_dir_uri); + + if (result != GNOME_VFS_OK && !skip) + break; + + source_item = source_item->next; + target_item = target_item->next; + g_assert ((source_item != NULL) == (target_item != NULL)); + } + + return result; +} + +static GnomeVFSResult +link_items (const GList *source_uri_list, + const GList *target_uri_list, + GnomeVFSXferOptions xfer_options, + GnomeVFSXferErrorMode *error_mode, + GnomeVFSXferOverwriteMode *overwrite_mode, + GnomeVFSProgressCallbackState *progress) +{ + GnomeVFSResult result; + const GList *source_item, *target_item; + GnomeVFSURI *source_uri; + GnomeVFSURI *target_dir_uri; + GnomeVFSURI *target_uri; + gboolean retry; + gboolean skip; + int conflict_count; + int progress_result; + char *source_reference; + + result = GNOME_VFS_OK; + + /* go through the list of names, create a link to each item */ + for (source_item = source_uri_list, target_item = target_uri_list; source_item != NULL;) { + + progress->progress_info->file_index++; + + source_uri = (GnomeVFSURI *)source_item->data; + source_reference = gnome_vfs_uri_to_string (source_uri, GNOME_VFS_URI_HIDE_NONE); + + target_dir_uri = gnome_vfs_uri_get_parent ((GnomeVFSURI *)target_item->data); + progress->progress_info->duplicate_name = + gnome_vfs_uri_extract_short_path_name + ((GnomeVFSURI *)target_item->data); + + skip = FALSE; + conflict_count = 1; + + do { + retry = FALSE; + target_uri = gnome_vfs_uri_append_string + (target_dir_uri, + progress->progress_info->duplicate_name); + + progress->progress_info->file_size = 0; + progress->progress_info->bytes_copied = 0; + progress->progress_info->top_level_item = TRUE; + progress_set_source_target_uris (progress, source_uri, target_uri); + + /* no matter what the replace mode, just overwrite the destination + * handle_name_conflicts took care of conflicting files + */ + result = gnome_vfs_create_symbolic_link (target_uri, source_reference); + if (result == GNOME_VFS_ERROR_FILE_EXISTS) { + /* deal with a name conflict -- ask the progress_callback for a better name */ + g_free (progress->progress_info->duplicate_name); + progress->progress_info->duplicate_name = + gnome_vfs_uri_extract_short_path_name + ((GnomeVFSURI *)target_item->data); + progress->progress_info->duplicate_count = conflict_count; + progress->progress_info->status = GNOME_VFS_XFER_PROGRESS_STATUS_DUPLICATE; + progress->progress_info->vfs_status = result; + progress_result = call_progress_uri (progress, source_uri, target_uri, + GNOME_VFS_XFER_PHASE_COPYING); + progress->progress_info->status = GNOME_VFS_XFER_PROGRESS_STATUS_OK; + + if (progress_result == GNOME_VFS_XFER_OVERWRITE_ACTION_ABORT) { + gnome_vfs_uri_unref (target_uri); + break; + } + conflict_count++; + result = GNOME_VFS_OK; + retry = TRUE; + continue; + } + + if (result != GNOME_VFS_OK) { + retry = handle_error (&result, progress, error_mode, &skip); + } + + if (result == GNOME_VFS_OK + && call_progress_with_uris_often (progress, source_uri, + target_uri, GNOME_VFS_XFER_PHASE_OPENTARGET) == 0) { + result = GNOME_VFS_ERROR_INTERRUPTED; + gnome_vfs_uri_unref (target_uri); + break; + } + gnome_vfs_uri_unref (target_uri); + } while (retry); + + gnome_vfs_uri_unref (target_dir_uri); + g_free (source_reference); + + if (result != GNOME_VFS_OK && !skip) + break; + + source_item = source_item->next; + target_item = target_item->next; + g_assert ((source_item != NULL) == (target_item != NULL)); + } + + return result; +} + + +static GnomeVFSResult +gnome_vfs_xfer_empty_directories (const GList *trash_dir_uris, + GnomeVFSXferErrorMode error_mode, + GnomeVFSProgressCallbackState *progress) +{ + GnomeVFSResult result; + const GList *p; + gboolean skip; + + result = GNOME_VFS_OK; + + /* initialize the results */ + progress->progress_info->files_total = 0; + progress->progress_info->bytes_total = 0; + progress->progress_info->phase = GNOME_VFS_XFER_PHASE_COLLECTING; + + + for (p = trash_dir_uris; p != NULL; p = p->next) { + result = directory_add_items_and_size (p->data, + GNOME_VFS_XFER_REMOVESOURCE | GNOME_VFS_XFER_RECURSIVE, + progress); + if (result == GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES) { + /* out of file descriptors -- we will deal with that */ + result = GNOME_VFS_OK; + break; + } + /* set up a fake total size to represent the bulk of the operation + * -- we'll subtract a proportional value for every deletion + */ + progress->progress_info->bytes_total + = progress->progress_info->files_total * DEFAULT_SIZE_OVERHEAD; + } + call_progress (progress, GNOME_VFS_XFER_PHASE_READYTOGO); + for (p = trash_dir_uris; p != NULL; p = p->next) { + result = empty_directory ((GnomeVFSURI *)p->data, progress, + GNOME_VFS_XFER_REMOVESOURCE | GNOME_VFS_XFER_RECURSIVE, + &error_mode, &skip); + if (result == GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES) { + result = non_recursive_empty_directory ((GnomeVFSURI *)p->data, + progress, GNOME_VFS_XFER_REMOVESOURCE | GNOME_VFS_XFER_RECURSIVE, + &error_mode, &skip); + } + } + + return result; +} + + +static GnomeVFSResult +gnome_vfs_xfer_delete_items_common (const GList *source_uri_list, + GnomeVFSXferErrorMode error_mode, + GnomeVFSXferOptions xfer_options, + GnomeVFSProgressCallbackState *progress) +{ + GnomeVFSFileInfo *info; + GnomeVFSResult result; + GnomeVFSURI *uri; + const GList *p; + gboolean skip; + + result = GNOME_VFS_OK; + + for (p = source_uri_list; p != NULL; p = p->next) { + + skip = FALSE; + /* get the URI and VFSFileInfo for each */ + uri = p->data; + + info = gnome_vfs_file_info_new (); + result = gnome_vfs_get_file_info_uri (uri, info, + GNOME_VFS_FILE_INFO_DEFAULT); + + if (result != GNOME_VFS_OK) { + break; + } + + progress_set_source_target_uris (progress, uri, NULL); + if (info->type == GNOME_VFS_FILE_TYPE_DIRECTORY) { + remove_directory (uri, TRUE, progress, xfer_options, + &error_mode, &skip); + } else { + remove_file (uri, progress, xfer_options, &error_mode, + &skip); + } + } + + return result; +} + + +static GnomeVFSResult +gnome_vfs_xfer_delete_items (const GList *source_uri_list, + GnomeVFSXferErrorMode error_mode, + GnomeVFSXferOptions xfer_options, + GnomeVFSProgressCallbackState *progress) +{ + + GnomeVFSResult result; + + /* initialize the results */ + progress->progress_info->files_total = 0; + progress->progress_info->bytes_total = 0; + call_progress (progress, GNOME_VFS_XFER_PHASE_COLLECTING); + + result = count_items_and_size (source_uri_list, + GNOME_VFS_XFER_REMOVESOURCE | GNOME_VFS_XFER_RECURSIVE, progress, FALSE, FALSE); + + /* When deleting, ignore the real file sizes, just count the same DEFAULT_SIZE_OVERHEAD + * for each file. + */ + progress->progress_info->bytes_total + = progress->progress_info->files_total * DEFAULT_SIZE_OVERHEAD; + if (result != GNOME_VFS_ERROR_INTERRUPTED) { + call_progress (progress, GNOME_VFS_XFER_PHASE_READYTOGO); + result = gnome_vfs_xfer_delete_items_common (source_uri_list, + error_mode, xfer_options, progress); + } + + return result; +} + + +static GnomeVFSResult +gnome_vfs_new_directory_with_unique_name (const GnomeVFSURI *target_dir_uri, + const char *name, + GnomeVFSXferErrorMode error_mode, + GnomeVFSXferOverwriteMode overwrite_mode, + GnomeVFSProgressCallbackState *progress) +{ + GnomeVFSResult result; + GnomeVFSURI *target_uri; + GnomeVFSDirectoryHandle *dest_directory_handle; + gboolean dummy; + int progress_result; + int conflict_count; + + dest_directory_handle = NULL; + progress->progress_info->top_level_item = TRUE; + progress->progress_info->duplicate_name = g_strdup (name); + + for (conflict_count = 1; ; conflict_count++) { + + target_uri = gnome_vfs_uri_append_string + (target_dir_uri, + progress->progress_info->duplicate_name); + result = create_directory (target_uri, + &dest_directory_handle, + GNOME_VFS_XFER_USE_UNIQUE_NAMES, + &error_mode, + &overwrite_mode, + progress, + &dummy); + + if (result != GNOME_VFS_ERROR_FILE_EXISTS + && result != GNOME_VFS_ERROR_NAME_TOO_LONG) { + break; + } + + /* deal with a name conflict -- ask the progress_callback for a better name */ + g_free (progress->progress_info->duplicate_name); + progress->progress_info->duplicate_name = g_strdup (name); + progress->progress_info->duplicate_count = conflict_count; + progress->progress_info->status = GNOME_VFS_XFER_PROGRESS_STATUS_DUPLICATE; + progress->progress_info->vfs_status = result; + progress_result = call_progress_uri (progress, NULL, target_uri, + GNOME_VFS_XFER_PHASE_COPYING); + progress->progress_info->status = GNOME_VFS_XFER_PROGRESS_STATUS_OK; + + if (progress_result == GNOME_VFS_XFER_OVERWRITE_ACTION_ABORT) { + break; + } + + gnome_vfs_uri_unref (target_uri); + } + + call_progress_uri (progress, NULL, target_uri, + GNOME_VFS_XFER_PHASE_OPENTARGET); + + if (dest_directory_handle != NULL) { + gnome_vfs_directory_close (dest_directory_handle); + } + + gnome_vfs_uri_unref (target_uri); + g_free (progress->progress_info->duplicate_name); + + return result; +} + +static GnomeVFSResult +gnome_vfs_destination_is_writable (const GnomeVFSURI *uri) +{ + GnomeVFSURI *test_uri; + GnomeVFSResult result; + GnomeVFSHandle *handle; + + if (!gnome_vfs_uri_is_local (uri)) { + /* if destination is not local, do not test it for writability, just + * assume it's writable + */ + return GNOME_VFS_OK; + } + + /* test writability by creating and erasing a temporary file */ + test_uri = gnome_vfs_uri_append_file_name (uri, ".vfs-write.tmp"); + result = gnome_vfs_create_uri (&handle, test_uri, GNOME_VFS_OPEN_WRITE, TRUE, 0600); + + if (result == GNOME_VFS_OK) { + gnome_vfs_close (handle); + } + + if (result == GNOME_VFS_OK || result == GNOME_VFS_ERROR_FILE_EXISTS) { + gnome_vfs_unlink_from_uri (test_uri); + result = GNOME_VFS_OK; + } + + /* some methods only allow certain filenames (e.g. .desktop files) */ + if (result == GNOME_VFS_ERROR_INVALID_URI) { + result = GNOME_VFS_OK; + } + + gnome_vfs_uri_unref (test_uri); + return result; +} + +static GnomeVFSResult +gnome_vfs_xfer_uri_internal (const GList *source_uris, + const GList *target_uris, + GnomeVFSXferOptions xfer_options, + GnomeVFSXferErrorMode error_mode, + GnomeVFSXferOverwriteMode overwrite_mode, + GnomeVFSProgressCallbackState *progress) +{ + GnomeVFSResult result; + GList *source_uri_list, *target_uri_list; + GList *source_uri, *target_uri; + GList *source_uri_list_copied; + GnomeVFSURI *target_dir_uri; + gboolean move, link; + GnomeVFSFileSize free_bytes; + GnomeVFSFileSize bytes_total; + gulong files_total; + gboolean skip; + + result = GNOME_VFS_OK; + move = FALSE; + link = FALSE; + target_dir_uri = NULL; + source_uri_list_copied = NULL; + + /* Check and see if target is writable. Return error if it is not. */ + call_progress (progress, GNOME_VFS_XFER_CHECKING_DESTINATION); + target_dir_uri = gnome_vfs_uri_get_parent ((GnomeVFSURI *)((GList *)target_uris)->data); + result = gnome_vfs_destination_is_writable (target_dir_uri); + progress_set_source_target_uris (progress, NULL, target_dir_uri); + if (result != GNOME_VFS_OK) { + handle_error (&result, progress, &error_mode, &skip); + gnome_vfs_uri_unref (target_dir_uri); + return result; + } + + move = (xfer_options & GNOME_VFS_XFER_REMOVESOURCE) != 0; + link = (xfer_options & GNOME_VFS_XFER_LINK_ITEMS) != 0; + + if (move && link) { + return GNOME_VFS_ERROR_BAD_PARAMETERS; + } + + /* Create an owning list of source and destination uris. + * We want to be able to remove items that we decide to skip during + * name conflict check. + */ + source_uri_list = gnome_vfs_uri_list_copy ((GList *)source_uris); + target_uri_list = gnome_vfs_uri_list_copy ((GList *)target_uris); + + if ((xfer_options & GNOME_VFS_XFER_USE_UNIQUE_NAMES) == 0) { + /* see if moved files are on the same file system so that we decide to do + * a simple move or have to do a copy/remove + */ + for (source_uri = source_uri_list, target_uri = target_uri_list; + source_uri != NULL; + source_uri = source_uri->next, target_uri = target_uri->next) { + gboolean same_fs; + + g_assert (target_dir_uri != NULL); + + result = gnome_vfs_check_same_fs_uris ((GnomeVFSURI *)source_uri->data, + target_dir_uri, &same_fs); + + if (result != GNOME_VFS_OK) { + break; + } + + move &= same_fs; + } + } + + if (target_dir_uri != NULL) { + gnome_vfs_uri_unref (target_dir_uri); + target_dir_uri = NULL; + } + + if (result == GNOME_VFS_OK) { + call_progress (progress, GNOME_VFS_XFER_PHASE_COLLECTING); + result = count_items_and_size (source_uri_list, xfer_options, progress, move, link); + if (result != GNOME_VFS_ERROR_INTERRUPTED) { + /* Ignore anything but interruptions here -- we will deal with the errors + * during the actual copy + */ + result = GNOME_VFS_OK; + } + } + + if (result == GNOME_VFS_OK) { + /* Calculate free space on destination. If an error is returned, we have a non-local + * file system, so we just forge ahead and hope for the best + */ + target_dir_uri = gnome_vfs_uri_get_parent ((GnomeVFSURI *)target_uri_list->data); + result = gnome_vfs_get_volume_free_space (target_dir_uri, &free_bytes); + + + if (result == GNOME_VFS_OK) { + if (!move && progress->progress_info->bytes_total > free_bytes) { + result = GNOME_VFS_ERROR_NO_SPACE; + progress_set_source_target_uris (progress, NULL, target_dir_uri); + handle_error (&result, progress, &error_mode, &skip); + } + } else { + /* Errors from gnome_vfs_get_volume_free_space should be ignored */ + result = GNOME_VFS_OK; + } + + if (target_dir_uri != NULL) { + gnome_vfs_uri_unref (target_dir_uri); + target_dir_uri = NULL; + } + + if (result != GNOME_VFS_OK) { + return result; + } + + if ((xfer_options & GNOME_VFS_XFER_USE_UNIQUE_NAMES) == 0) { + + /* Save the preflight numbers, handle_name_conflicts would overwrite them */ + bytes_total = progress->progress_info->bytes_total; + files_total = progress->progress_info->files_total; + + /* Set the preflight numbers to 0, we don't want to run progress on the + * removal of conflicting items. + */ + progress->progress_info->bytes_total = 0; + progress->progress_info->files_total = 0; + + result = handle_name_conflicts (&source_uri_list, &target_uri_list, + xfer_options, &error_mode, &overwrite_mode, + progress); + + progress->progress_info->bytes_total = bytes_total; + progress->progress_info->files_total = files_total; + + } + + /* reset the preflight numbers */ + progress->progress_info->file_index = 0; + progress->progress_info->total_bytes_copied = 0; + + if (result != GNOME_VFS_OK) { + /* don't care about any results from handle_error */ + handle_error (&result, progress, &error_mode, &skip); + + /* whatever error it was, we handled it */ + result = GNOME_VFS_OK; + } else { + call_progress (progress, GNOME_VFS_XFER_PHASE_READYTOGO); + + if (move) { + g_assert (!link); + result = move_items (source_uri_list, target_uri_list, + xfer_options, &error_mode, &overwrite_mode, + progress); + } else if (link) { + result = link_items (source_uri_list, target_uri_list, + xfer_options, &error_mode, &overwrite_mode, + progress); + } else { + result = copy_items (source_uri_list, target_uri_list, + xfer_options, &error_mode, overwrite_mode, + progress, &source_uri_list_copied); + } + + if (result == GNOME_VFS_OK) { + if (xfer_options & GNOME_VFS_XFER_REMOVESOURCE + && ! (move || link)) { + call_progress (progress, GNOME_VFS_XFER_PHASE_CLEANUP); + result = gnome_vfs_xfer_delete_items_common ( + source_uri_list_copied, + error_mode, xfer_options, progress); + } + } + } + } + + gnome_vfs_uri_list_free (source_uri_list); + gnome_vfs_uri_list_free (target_uri_list); + gnome_vfs_uri_list_free (source_uri_list_copied); + + return result; +} + +GnomeVFSResult +_gnome_vfs_xfer_private (const GList *source_uri_list, + const GList *target_uri_list, + GnomeVFSXferOptions xfer_options, + GnomeVFSXferErrorMode error_mode, + GnomeVFSXferOverwriteMode overwrite_mode, + GnomeVFSXferProgressCallback progress_callback, + gpointer data, + GnomeVFSXferProgressCallback sync_progress_callback, + gpointer sync_progress_data) +{ + GnomeVFSProgressCallbackState progress_state; + GnomeVFSXferProgressInfo progress_info; + GnomeVFSURI *target_dir_uri; + GnomeVFSResult result; + char *short_name; + + init_progress (&progress_state, &progress_info); + progress_state.sync_callback = sync_progress_callback; + progress_state.user_data = sync_progress_data; + progress_state.update_callback = progress_callback; + progress_state.async_job_data = data; + + + if ((xfer_options & GNOME_VFS_XFER_EMPTY_DIRECTORIES) != 0) { + /* Directory empty operation (Empty Trash, etc.). */ + g_assert (source_uri_list != NULL); + g_assert (target_uri_list == NULL); + + call_progress (&progress_state, GNOME_VFS_XFER_PHASE_INITIAL); + result = gnome_vfs_xfer_empty_directories (source_uri_list, error_mode, &progress_state); + } else if ((xfer_options & GNOME_VFS_XFER_DELETE_ITEMS) != 0) { + /* Delete items operation */ + g_assert (source_uri_list != NULL); + g_assert (target_uri_list == NULL); + + call_progress (&progress_state, GNOME_VFS_XFER_PHASE_INITIAL); + result = gnome_vfs_xfer_delete_items (source_uri_list, + error_mode, xfer_options, &progress_state); + } else if ((xfer_options & GNOME_VFS_XFER_NEW_UNIQUE_DIRECTORY) != 0) { + /* New directory create operation */ + g_assert (source_uri_list == NULL); + g_assert (g_list_length ((GList *) target_uri_list) == 1); + + target_dir_uri = gnome_vfs_uri_get_parent ((GnomeVFSURI *) target_uri_list->data); + result = GNOME_VFS_ERROR_INVALID_URI; + if (target_dir_uri != NULL) { + short_name = gnome_vfs_uri_extract_short_path_name ((GnomeVFSURI *) target_uri_list->data); + result = gnome_vfs_new_directory_with_unique_name (target_dir_uri, short_name, + error_mode, overwrite_mode, &progress_state); + g_free (short_name); + gnome_vfs_uri_unref (target_dir_uri); + } + } else { + /* Copy items operation */ + g_assert (source_uri_list != NULL); + g_assert (target_uri_list != NULL); + g_assert (g_list_length ((GList *)source_uri_list) == g_list_length ((GList *)target_uri_list)); + + call_progress (&progress_state, GNOME_VFS_XFER_PHASE_INITIAL); + result = gnome_vfs_xfer_uri_internal (source_uri_list, target_uri_list, + xfer_options, error_mode, overwrite_mode, &progress_state); + } + + call_progress (&progress_state, GNOME_VFS_XFER_PHASE_COMPLETED); + free_progress (&progress_info); + + /* FIXME bugzilla.eazel.com 1218: + * + * The async job setup will try to call the callback function with the callback data + * even though they are usually dead at this point because the callback detected + * that we are giving up and cleaned up after itself. + * + * Should fix this in the async job call setup. + * + * For now just pretend everything worked well. + * + */ + result = GNOME_VFS_OK; + + return result; +} + +/** + * gnome_vfs_xfer_uri_list: + * @source_uri_list: A Glist of uris (ie file;//) + * @target_uri_list: A GList of uris + * @xfer_options: These are options you wish to set for the transfer. For + * instance by setting the xfer behavior you can either make a copy or a + * move. + * @error_mode: Decide how to behave if the xfer is interrupted. For instance + * you could set your application to return an error code in case of an + * interuption. + * @overwrite_mode: How to react if a file your copying is being overwritten. + * @progress_callback: This is used to monitor the progress of a transfer. + * Common use would be to check to see if the transfer is asking for permission + * to overwrite a file. + * @data: Data to be want passed back in callbacks from the xfer engine + * + * This function will transfer multiple files to a multiple targets. Given a + * a source uri(s) and a destination uri(s). There are a list of options that + * your application can use to control how the transfer is done. + * + * Returns: If all goes well it returns GNOME_VFS_OK. Check GnomeVFSResult for + * other values. + **/ +GnomeVFSResult +gnome_vfs_xfer_uri_list (const GList *source_uri_list, + const GList *target_uri_list, + GnomeVFSXferOptions xfer_options, + GnomeVFSXferErrorMode error_mode, + GnomeVFSXferOverwriteMode overwrite_mode, + GnomeVFSXferProgressCallback progress_callback, + gpointer data) +{ + GnomeVFSProgressCallbackState progress_state; + GnomeVFSXferProgressInfo progress_info; + GnomeVFSResult result; + + g_return_val_if_fail (source_uri_list != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail (target_uri_list != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail (progress_callback != NULL || error_mode != GNOME_VFS_XFER_ERROR_MODE_QUERY, + GNOME_VFS_ERROR_BAD_PARAMETERS); + + init_progress (&progress_state, &progress_info); + progress_state.sync_callback = progress_callback; + progress_state.user_data = data; + + call_progress (&progress_state, GNOME_VFS_XFER_PHASE_INITIAL); + + result = gnome_vfs_xfer_uri_internal (source_uri_list, target_uri_list, + xfer_options, error_mode, overwrite_mode, &progress_state); + + call_progress (&progress_state, GNOME_VFS_XFER_PHASE_COMPLETED); + free_progress (&progress_info); + + return result; +} + +/** + * gnome_vfs_xfer_uri: + * @source_uri: This is the location of where your data resides. + * @target_uri: This is the location of where you want your data to go. + * @xfer_options: Set the kind of transfers you want. These are: + * GNOME_VFS_XFER_DEFAULT: Default behavior. Which is to do a straight one to + * one copy. + * GNOME_VFS_XFER_FOLLOW_LINKS: This means follow the value of the symbolic + * link when copying. (ie treat a symbolic link as a directory) + * GNOME_VFS_RECURSIVE: Do a recursive copy of the source to the destination. + * Equivalent to the cp -r option in GNU cp. + * GNOME_VFS_XFER_SAME_FS: This only allows copying onto the same filesystem. + * GNOME_VFS_DELETE_ITEM: This is equivalent to a mv. Where you will copy the + * contents of the source to the destination and then remove data from the + * source URI. + * GNOME_VFS_XFER_EMPTY_DIRECTORIES: + * GNOME_VFS_XFER_NEW_UNIQUE_DIRECTORY: This will create a directory if it + * doesn't exist in the destination area. Useful with the + * GNOME_VFS_XFER_RECURSIVE xfer option. + * GNOME_VFS_XFER_REMOVESOURCE: This option will remove the source data after + * whatever xfer option has been taken. + * GNOME_VFS_USE_UNIQUE_NAMES: This is a check ot make sure that what you copy + * onto the destination is not overwritten. It will only copy the unique items + * from the source to the destjnation. + * GNOME_VFS_XFER_LINK_ITEMS: + * @error_mode: When this function returns you need to check the error code + * for the results of the copy. The results are generally: + * GNOME_VFS_XFER_ERROR_MODE_ABORT: This means that the operation was aborted + * by some sort of signal that interrupted the transfer. + * GNOME_VFS_ERROR_MODE_QUERY: This means that no error has occured and that + * you should query with the GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR. See + * @overwrite_mode: This sets the options to deal with data that are duplicate + * between the source and the destination. Your choices are: + * GNOME_VFS_XFER_OVERWRITE_MODE_ABORT: This means abort the transfer if you + * see duplicate data. + * GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE: Replace the files silently. Don't + * worry be happy. + * GNOME_VFS_XFER_OVERWRITE_MODE_SKIP: Skip duplicate files silenty. + * target. + * @progress_callback: This is an important call back because this is how you + * communicate with your copy process. + * @data: Data to be want passed back in callbacks from the xfer engine + * + * This function will allow a person to copy data from one location to another. + * The location is specified using a URIs as the means to describe the location + * of the data. Like any copy there are several options that can be set. + * These can be set using the xfer_options. In addition there are callback + * mechanisms and error codes to provide feedback in the copy + * process. + * + * Return value: An integer representing the result of the operation. + * + **/ +GnomeVFSResult +gnome_vfs_xfer_uri (const GnomeVFSURI *source_uri, + const GnomeVFSURI *target_uri, + GnomeVFSXferOptions xfer_options, + GnomeVFSXferErrorMode error_mode, + GnomeVFSXferOverwriteMode overwrite_mode, + GnomeVFSXferProgressCallback progress_callback, + gpointer data) +{ + GList *source_uri_list, *target_uri_list; + GnomeVFSResult result; + + g_return_val_if_fail (source_uri != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail (target_uri != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail (progress_callback != NULL || error_mode != GNOME_VFS_XFER_ERROR_MODE_QUERY, + GNOME_VFS_ERROR_BAD_PARAMETERS); + + source_uri_list = g_list_append (NULL, (void *)source_uri); + target_uri_list = g_list_append (NULL, (void *)target_uri); + + result = gnome_vfs_xfer_uri_list (source_uri_list, target_uri_list, + xfer_options, error_mode, overwrite_mode, progress_callback, data); + + g_list_free (source_uri_list); + g_list_free (target_uri_list); + + return result; +} + +/** + * gnome_vfs_xfer_delete_list: + * @source_uri_list: This is a list containing uris + * @error_mode: Decide how you want to deal with interruptions + * @xfer_options: Set whatever transfer options you need. + * @progress_callback: Callback to check on progress of transfer. + * @data: Data to be want passed back in callbacks from the xfer engine + * + * Unlink items in the list @source_uri_list from their filesystems. + * + * Return value: %GNOME_VFS_OK if successful, or the appropriate error code otherwise + **/ +GnomeVFSResult +gnome_vfs_xfer_delete_list (const GList *source_uri_list, + GnomeVFSXferErrorMode error_mode, + GnomeVFSXferOptions xfer_options, + GnomeVFSXferProgressCallback + progress_callback, + gpointer data) +{ + GnomeVFSProgressCallbackState progress_state; + GnomeVFSXferProgressInfo progress_info; + GnomeVFSResult result; + + g_return_val_if_fail (source_uri_list != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail (progress_callback != NULL || error_mode != GNOME_VFS_XFER_ERROR_MODE_QUERY, + GNOME_VFS_ERROR_BAD_PARAMETERS); + + init_progress (&progress_state, &progress_info); + progress_state.sync_callback = progress_callback; + progress_state.user_data = data; + call_progress (&progress_state, GNOME_VFS_XFER_PHASE_INITIAL); + + result = gnome_vfs_xfer_delete_items (source_uri_list, error_mode, xfer_options, + &progress_state); + + call_progress (&progress_state, GNOME_VFS_XFER_PHASE_COMPLETED); + free_progress (&progress_info); + + return result; +} + diff --git a/libgnomevfs/gnome-vfs-xfer.h b/libgnomevfs/gnome-vfs-xfer.h new file mode 100644 index 0000000..4e64064 --- /dev/null +++ b/libgnomevfs/gnome-vfs-xfer.h @@ -0,0 +1,293 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* gnome-vfs-xfer.h - File transfers in the GNOME Virtual File System. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli */ + +#ifndef GNOME_VFS_XFER_H +#define GNOME_VFS_XFER_H + +#include + +G_BEGIN_DECLS + +/* Xfer options. + * FIXME bugzilla.eazel.com 1205: + * Split these up into xfer options and xfer actions + */ +typedef enum { + GNOME_VFS_XFER_DEFAULT = 0, + GNOME_VFS_XFER_UNUSED_1 = 1 << 0, + GNOME_VFS_XFER_FOLLOW_LINKS = 1 << 1, + GNOME_VFS_XFER_UNUSED_2 = 1 << 2, + GNOME_VFS_XFER_RECURSIVE = 1 << 3, + GNOME_VFS_XFER_SAMEFS = 1 << 4, + GNOME_VFS_XFER_DELETE_ITEMS = 1 << 5, + GNOME_VFS_XFER_EMPTY_DIRECTORIES = 1 << 6, + GNOME_VFS_XFER_NEW_UNIQUE_DIRECTORY = 1 << 7, + GNOME_VFS_XFER_REMOVESOURCE = 1 << 8, + GNOME_VFS_XFER_USE_UNIQUE_NAMES = 1 << 9, + GNOME_VFS_XFER_LINK_ITEMS = 1 << 10, + GNOME_VFS_XFER_FOLLOW_LINKS_RECURSIVE = 1 << 11 +} GnomeVFSXferOptions; + +/* Progress status, to be reported to the caller of the transfer operation. */ +typedef enum { + GNOME_VFS_XFER_PROGRESS_STATUS_OK = 0, + GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR = 1, + GNOME_VFS_XFER_PROGRESS_STATUS_OVERWRITE = 2, + /* during the duplicate status the progress callback is asked to + supply a new unique name */ + GNOME_VFS_XFER_PROGRESS_STATUS_DUPLICATE = 3 +} GnomeVFSXferProgressStatus; + +/* The different ways to deal with overwriting during a transfer operation. */ +typedef enum { + /* Interrupt transferring with an error (GNOME_VFS_ERROR_FILEEXISTS). */ + GNOME_VFS_XFER_OVERWRITE_MODE_ABORT = 0, + /* Invoke the progress callback with a + `GNOME_VFS_XFER_PROGRESS_STATUS_OVERWRITE' status code. */ + GNOME_VFS_XFER_OVERWRITE_MODE_QUERY = 1, + /* Overwrite files silently. */ + GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE = 2, + /* Ignore files silently. */ + GNOME_VFS_XFER_OVERWRITE_MODE_SKIP = 3 +} GnomeVFSXferOverwriteMode; + +/** + * GnomeVFSXferOverwriteAction: + * @GNOME_VFS_XFER_OVERWRITE_ACTION_ABORT: abort the transfer + * @GNOME_VFS_XFER_OVERWRITE_ACTION_REPLACE: replace the existing file + * @GNOME_VFS_XFER_OVERWRITE_ACTION_REPLACE_ALL: replace the existing file, and all future files + * without prompting the callback. + * @GNOME_VFS_XFER_OVERWRITE_ACTION_SKIP: don't copy over the existing file + * @GNOME_VFS_XFER_OVERWRITE_ACTION_SKIP_ALL: don't copy over the existing file, and all future + * files without prompting the callback. + * + * This defines the actions to perform before a file is being overwritten + * (i.e., these are the answers that can be given to a replace query). + **/ +typedef enum { + GNOME_VFS_XFER_OVERWRITE_ACTION_ABORT = 0, + GNOME_VFS_XFER_OVERWRITE_ACTION_REPLACE = 1, + GNOME_VFS_XFER_OVERWRITE_ACTION_REPLACE_ALL = 2, + GNOME_VFS_XFER_OVERWRITE_ACTION_SKIP = 3, + GNOME_VFS_XFER_OVERWRITE_ACTION_SKIP_ALL = 4 +} GnomeVFSXferOverwriteAction; + +typedef enum { + /* Interrupt transferring with an error (code returned is code of the + operation that has caused the error). */ + GNOME_VFS_XFER_ERROR_MODE_ABORT = 0, + /* Invoke the progress callback with a + `GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR' status code. */ + GNOME_VFS_XFER_ERROR_MODE_QUERY = 1 +} GnomeVFSXferErrorMode; + +/* This defines the possible actions to be performed after an error has + occurred. */ +typedef enum { + /* Interrupt operation and return `GNOME_VFS_ERROR_INTERRUPTED'. */ + GNOME_VFS_XFER_ERROR_ACTION_ABORT = 0, + /* Try the same operation again. */ + GNOME_VFS_XFER_ERROR_ACTION_RETRY = 1, + /* Skip this file and continue normally. */ + GNOME_VFS_XFER_ERROR_ACTION_SKIP = 2 +} GnomeVFSXferErrorAction; + +/* This specifies the current phase in the transfer operation. Phases whose + comments are marked with `(*)' are always reported in "normal" (i.e. no + error) condition; the other ones are only reported if an error happens in + that specific phase. */ +typedef enum { + /* Initial phase */ + GNOME_VFS_XFER_PHASE_INITIAL, + /* Checking if destination can handle move/copy */ + GNOME_VFS_XFER_CHECKING_DESTINATION, + /* Collecting file list */ + GNOME_VFS_XFER_PHASE_COLLECTING, + /* File list collected (*) */ + GNOME_VFS_XFER_PHASE_READYTOGO, + /* Opening source file for reading */ + GNOME_VFS_XFER_PHASE_OPENSOURCE, + /* Creating target file for copy */ + GNOME_VFS_XFER_PHASE_OPENTARGET, + /* Copying data from source to target (*) */ + GNOME_VFS_XFER_PHASE_COPYING, + /* Moving file from source to target (*) */ + GNOME_VFS_XFER_PHASE_MOVING, + /* Reading data from source file */ + GNOME_VFS_XFER_PHASE_READSOURCE, + /* Writing data to target file */ + GNOME_VFS_XFER_PHASE_WRITETARGET, + /* Closing source file */ + GNOME_VFS_XFER_PHASE_CLOSESOURCE, + /* Closing target file */ + GNOME_VFS_XFER_PHASE_CLOSETARGET, + /* Deleting source file */ + GNOME_VFS_XFER_PHASE_DELETESOURCE, + /* Setting attributes on target file */ + GNOME_VFS_XFER_PHASE_SETATTRIBUTES, + /* Go to the next file (*) */ + GNOME_VFS_XFER_PHASE_FILECOMPLETED, + /* cleaning up after a move (removing source files, etc.) */ + GNOME_VFS_XFER_PHASE_CLEANUP, + /* Operation finished (*) */ + GNOME_VFS_XFER_PHASE_COMPLETED, + GNOME_VFS_XFER_NUM_PHASES +} GnomeVFSXferPhase; + +/* Progress information for the transfer operation. This is especially useful + for interactive programs. */ +typedef struct { + /* Progress status (see above for a description). */ + GnomeVFSXferProgressStatus status; + + /* VFS status code. If `status' is + `GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR', you should look at this + member to know what has happened. */ + GnomeVFSResult vfs_status; + + /* Current phase in the transferring process. */ + GnomeVFSXferPhase phase; + + /* Source URI. FIXME bugzilla.eazel.com 1206: change name? */ + gchar *source_name; + + /* Destination URI. FIXME bugzilla.eazel.com 1206: change name? */ + gchar *target_name; + + /* Index of file being copied. */ + gulong file_index; + + /* Total number of files to be copied. */ + gulong files_total; + + /* Total number of bytes to be copied. */ + GnomeVFSFileSize bytes_total; + + /* Total size of this file (in bytes). */ + GnomeVFSFileSize file_size; + + /* Bytes copied for this file so far. */ + GnomeVFSFileSize bytes_copied; + + /* Total amount of data copied from the beginning. */ + GnomeVFSFileSize total_bytes_copied; + + /* Target unique name used when duplicating, etc. to avoid collisions */ + gchar *duplicate_name; + + /* Count used in the unique name e.g. (copy 2), etc. */ + int duplicate_count; + + gboolean top_level_item; + /* indicates that the copied/moved/deleted item is an actual item + * passed in the uri list rather than one encountered by recursively + * traversing directories. Used by metadata copying. + */ + + /* Reserved for future expansions to GnomeVFSXferProgressInfo + * without having to break ABI compatibility */ + void *reserved1; + void *reserved2; + +} GnomeVFSXferProgressInfo; + +/* This is the prototype for functions called during a transfer operation to + report progress. If the return value is `FALSE' (0), the operation is + interrupted immediately: the transfer function returns with the value of + `vfs_status' if it is different from `GNOME_VFS_OK', or with + `GNOME_VFS_ERROR_INTERRUPTED' otherwise. The effect of other values depend + on the value of `info->status': + + - If the status is `GNOME_VFS_XFER_PROGRESS_STATUS_OK', the transfer + operation is resumed normally. + + - If the status is `GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR', the return + value is interpreted as a `GnomeVFSXferErrorAction' and operation is + interrupted, continued or retried accordingly. + + - If the status is `GNOME_VFS_XFER_PROGRESS_STATUS_OVERWRITE', the return + value is interpreted as a `GnomeVFSXferOverwriteAction'. */ + +typedef gint (* GnomeVFSXferProgressCallback) (GnomeVFSXferProgressInfo *info, + gpointer data); + +typedef struct GnomeVFSProgressCallbackState { + + /* xfer state */ + GnomeVFSXferProgressInfo *progress_info; + + /* Callback called for every xfer operation. For async calls called + in async xfer context. */ + GnomeVFSXferProgressCallback sync_callback; + + /* Callback called periodically every few hundred miliseconds + and whenever user interaction is needed. For async calls + called in the context of the async call caller. */ + GnomeVFSXferProgressCallback update_callback; + + /* User data passed to sync_callback. */ + gpointer user_data; + + /* Async job state passed to the update callback. */ + gpointer async_job_data; + + /* When will update_callback be called next. */ + gint64 next_update_callback_time; + + /* When will update_callback be called next. */ + gint64 next_text_update_callback_time; + + /* Period at which the update_callback will be called. */ + gint64 update_callback_period; + + + /* Reserved for future expansions to GnomeVFSProgressCallbackState + * without having to break ABI compatibility */ + void *reserved1; + void *reserved2; + +} GnomeVFSProgressCallbackState; + +GnomeVFSResult gnome_vfs_xfer_uri_list (const GList *source_uri_list, + const GList *target_uri_list, + GnomeVFSXferOptions xfer_options, + GnomeVFSXferErrorMode error_mode, + GnomeVFSXferOverwriteMode overwrite_mode, + GnomeVFSXferProgressCallback progress_callback, + gpointer data); +GnomeVFSResult gnome_vfs_xfer_uri (const GnomeVFSURI *source_uri, + const GnomeVFSURI *target_uri, + GnomeVFSXferOptions xfer_options, + GnomeVFSXferErrorMode error_mode, + GnomeVFSXferOverwriteMode overwrite_mode, + GnomeVFSXferProgressCallback progress_callback, + gpointer data); +GnomeVFSResult gnome_vfs_xfer_delete_list (const GList *source_uri_list, + GnomeVFSXferErrorMode error_mode, + GnomeVFSXferOptions xfer_options, + GnomeVFSXferProgressCallback progress_callback, + gpointer data); + +G_END_DECLS + +#endif /* GNOME_VFS_XFER_H */ diff --git a/libgnomevfs/gnome-vfs.h b/libgnomevfs/gnome-vfs.h new file mode 100644 index 0000000..184d3a4 --- /dev/null +++ b/libgnomevfs/gnome-vfs.h @@ -0,0 +1,41 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* gnome-vfs.h - The GNOME Virtual File System. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli +*/ + +#ifndef GNOME_VFS_H +#define GNOME_VFS_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif /* GNOME_VFS_H */ diff --git a/ltmain.sh b/ltmain.sh new file mode 100644 index 0000000..dd490ba --- /dev/null +++ b/ltmain.sh @@ -0,0 +1,5118 @@ +# ltmain.sh - Provide generalized library-building support services. +# NOTE: Changing this file will not affect anything until you rerun configure. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit , 1996 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Check that we have a working $echo. +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : +else + # Restart under the correct shell, and then maybe $echo will work. + exec $SHELL "$0" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat <&2 + echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit 1 +fi + +# Global variables. +mode=$default_mode +nonopt= +prev= +prevopt= +run= +show="$echo" +show_help= +execute_dlfiles= +lo2o="s/\\.lo\$/.${objext}/" +o2lo="s/\\.${objext}\$/.lo/" + +# Parse our command line options once, thoroughly. +while test $# -gt 0 +do + arg="$1" + shift + + case $arg in + -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + execute_dlfiles) + execute_dlfiles="$execute_dlfiles $arg" + ;; + *) + eval "$prev=\$arg" + ;; + esac + + prev= + prevopt= + continue + fi + + # Have we seen a non-optional argument yet? + case $arg in + --help) + show_help=yes + ;; + + --version) + echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP" + exit 0 + ;; + + --config) + ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $0 + exit 0 + ;; + + --debug) + echo "$progname: enabling shell trace mode" + set -x + ;; + + --dry-run | -n) + run=: + ;; + + --features) + echo "host: $host" + if test "$build_libtool_libs" = yes; then + echo "enable shared libraries" + else + echo "disable shared libraries" + fi + if test "$build_old_libs" = yes; then + echo "enable static libraries" + else + echo "disable static libraries" + fi + exit 0 + ;; + + --finish) mode="finish" ;; + + --mode) prevopt="--mode" prev=mode ;; + --mode=*) mode="$optarg" ;; + + --preserve-dup-deps) duplicate_deps="yes" ;; + + --quiet | --silent) + show=: + ;; + + -dlopen) + prevopt="-dlopen" + prev=execute_dlfiles + ;; + + -*) + $echo "$modename: unrecognized option \`$arg'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + + *) + nonopt="$arg" + break + ;; + esac +done + +if test -n "$prevopt"; then + $echo "$modename: option \`$prevopt' requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 +fi + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + +if test -z "$show_help"; then + + # Infer the operation mode. + if test -z "$mode"; then + case $nonopt in + *cc | *++ | gcc* | *-gcc* | xlc*) + mode=link + for arg + do + case $arg in + -c) + mode=compile + break + ;; + esac + done + ;; + *db | *dbx | *strace | *truss) + mode=execute + ;; + *install*|cp|mv) + mode=install + ;; + *rm) + mode=uninstall + ;; + *) + # If we have no mode, but dlfiles were specified, then do execute mode. + test -n "$execute_dlfiles" && mode=execute + + # Just use the default operation mode. + if test -z "$mode"; then + if test -n "$nonopt"; then + $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 + else + $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 + fi + fi + ;; + esac + fi + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$execute_dlfiles" && test "$mode" != execute; then + $echo "$modename: unrecognized option \`-dlopen'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$modename --help --mode=$mode' for more information." + + # These modes are in order of execution frequency so that they run quickly. + case $mode in + # libtool compile mode + compile) + modename="$modename: compile" + # Get the compilation command and the source file. + base_compile= + prev= + lastarg= + srcfile="$nonopt" + suppress_output= + + user_target=no + for arg + do + case $prev in + "") ;; + xcompiler) + # Aesthetically quote the previous argument. + prev= + lastarg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + + case $arg in + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + + # Add the previous argument to base_compile. + if test -z "$base_compile"; then + base_compile="$lastarg" + else + base_compile="$base_compile $lastarg" + fi + continue + ;; + esac + + # Accept any command-line options. + case $arg in + -o) + if test "$user_target" != "no"; then + $echo "$modename: you cannot specify \`-o' more than once" 1>&2 + exit 1 + fi + user_target=next + ;; + + -static) + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` + lastarg= + save_ifs="$IFS"; IFS=',' + for arg in $args; do + IFS="$save_ifs" + + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + lastarg="$lastarg $arg" + done + IFS="$save_ifs" + lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"` + + # Add the arguments to base_compile. + if test -z "$base_compile"; then + base_compile="$lastarg" + else + base_compile="$base_compile $lastarg" + fi + continue + ;; + esac + + case $user_target in + next) + # The next one is the -o target name + user_target=yes + continue + ;; + yes) + # We got the output file + user_target=set + libobj="$arg" + continue + ;; + esac + + # Accept the current argument as the source file. + lastarg="$srcfile" + srcfile="$arg" + + # Aesthetically quote the previous argument. + + # Backslashify any backslashes, double quotes, and dollar signs. + # These are the only characters that are still specially + # interpreted inside of double-quoted scrings. + lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` + + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + case $lastarg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + lastarg="\"$lastarg\"" + ;; + esac + + # Add the previous argument to base_compile. + if test -z "$base_compile"; then + base_compile="$lastarg" + else + base_compile="$base_compile $lastarg" + fi + done + + case $user_target in + set) + ;; + no) + # Get the name of the library object. + libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` + ;; + *) + $echo "$modename: you must specify a target with \`-o'" 1>&2 + exit 1 + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + xform='[cCFSfmso]' + case $libobj in + *.ada) xform=ada ;; + *.adb) xform=adb ;; + *.ads) xform=ads ;; + *.asm) xform=asm ;; + *.c++) xform=c++ ;; + *.cc) xform=cc ;; + *.cpp) xform=cpp ;; + *.cxx) xform=cxx ;; + *.f90) xform=f90 ;; + *.for) xform=for ;; + esac + + libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` + + case $libobj in + *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; + *) + $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 + exit 1 + ;; + esac + + if test -z "$base_compile"; then + $echo "$modename: you must specify a compilation command" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $libobj" + else + removelist="$libobj" + fi + + $run $rm $removelist + trap "$run $rm $removelist; exit 1" 1 2 15 + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2*) + pic_mode=default + ;; + esac + if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} + lockfile="$output_obj.lock" + removelist="$removelist $output_obj $lockfile" + trap "$run $rm $removelist; exit 1" 1 2 15 + else + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until $run ln "$0" "$lockfile" 2>/dev/null; do + $show "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + echo "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit 1 + fi + echo $srcfile > "$lockfile" + fi + + if test -n "$fix_srcfile_path"; then + eval srcfile=\"$fix_srcfile_path\" + fi + + # Only build a PIC object if we are building libtool libraries. + if test "$build_libtool_libs" = yes; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + if test "$pic_mode" != no; then + # All platforms use -DPIC, to notify preprocessed assembler code. + command="$base_compile $srcfile $pic_flag -DPIC" + else + # Don't build PIC code + command="$base_compile $srcfile" + fi + if test "$build_old_libs" = yes; then + lo_libobj="$libobj" + dir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$dir" = "X$libobj"; then + dir="$objdir" + else + dir="$dir/$objdir" + fi + libobj="$dir/"`$echo "X$libobj" | $Xsed -e 's%^.*/%%'` + + if test -d "$dir"; then + $show "$rm $libobj" + $run $rm $libobj + else + $show "$mkdir $dir" + $run $mkdir $dir + status=$? + if test $status -ne 0 && test ! -d $dir; then + exit $status + fi + fi + fi + if test "$compiler_o_lo" = yes; then + output_obj="$libobj" + command="$command -o $output_obj" + elif test "$compiler_c_o" = yes; then + output_obj="$obj" + command="$command -o $output_obj" + fi + + $run $rm "$output_obj" + $show "$command" + if $run eval "$command"; then : + else + test -n "$output_obj" && $run $rm $removelist + exit 1 + fi + + if test "$need_locks" = warn && + test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then + echo "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit 1 + fi + + # Just move the object if needed, then go on to compile the next one + if test x"$output_obj" != x"$libobj"; then + $show "$mv $output_obj $libobj" + if $run $mv $output_obj $libobj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # If we have no pic_flag, then copy the object into place and finish. + if (test -z "$pic_flag" || test "$pic_mode" != default) && + test "$build_old_libs" = yes; then + # Rename the .lo from within objdir to obj + if test -f $obj; then + $show $rm $obj + $run $rm $obj + fi + + $show "$mv $libobj $obj" + if $run $mv $libobj $obj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + + xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$obj"; then + xdir="." + else + xdir="$xdir" + fi + baseobj=`$echo "X$obj" | $Xsed -e "s%.*/%%"` + libobj=`$echo "X$baseobj" | $Xsed -e "$o2lo"` + # Now arrange that obj and lo_libobj become the same file + $show "(cd $xdir && $LN_S $baseobj $libobj)" + if $run eval '(cd $xdir && $LN_S $baseobj $libobj)'; then + # Unlock the critical section if it was locked + if test "$need_locks" != no; then + $run $rm "$lockfile" + fi + exit 0 + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Allow error messages only from the first compilation. + suppress_output=' >/dev/null 2>&1' + fi + + # Only build a position-dependent object if we build old libraries. + if test "$build_old_libs" = yes; then + if test "$pic_mode" != yes; then + # Don't build PIC code + command="$base_compile $srcfile" + else + # All platforms use -DPIC, to notify preprocessed assembler code. + command="$base_compile $srcfile $pic_flag -DPIC" + fi + if test "$compiler_c_o" = yes; then + command="$command -o $obj" + output_obj="$obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + command="$command$suppress_output" + $run $rm "$output_obj" + $show "$command" + if $run eval "$command"; then : + else + $run $rm $removelist + exit 1 + fi + + if test "$need_locks" = warn && + test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then + echo "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit 1 + fi + + # Just move the object if needed + if test x"$output_obj" != x"$obj"; then + $show "$mv $output_obj $obj" + if $run $mv $output_obj $obj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Create an invalid libtool object if no PIC, so that we do not + # accidentally link it into a program. + if test "$build_libtool_libs" != yes; then + $show "echo timestamp > $libobj" + $run eval "echo timestamp > \$libobj" || exit $? + else + # Move the .lo from within objdir + $show "$mv $libobj $lo_libobj" + if $run $mv $libobj $lo_libobj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + fi + + # Unlock the critical section if it was locked + if test "$need_locks" != no; then + $run $rm "$lockfile" + fi + + exit 0 + ;; + + # libtool link mode + link | relink) + modename="$modename: link" + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # which system we are compiling for in order to pass an extra + # flag for every libtool invokation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll which has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args="$nonopt" + compile_command="$nonopt" + finalize_command="$nonopt" + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + inst_prefix_dir= + + avoid_version=no + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + prefer_static_libs=no + preload=no + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -all-static | -static) + if test "X$arg" = "X-all-static"; then + if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then + $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2 + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + else + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + fi + build_libtool_libs=no + build_old_libs=yes + prefer_static_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test $# -gt 0; do + arg="$1" + shift + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test + ;; + *) qarg=$arg ;; + esac + libtool_args="$libtool_args $qarg" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + compile_command="$compile_command @OUTPUT@" + finalize_command="$finalize_command @OUTPUT@" + ;; + esac + + case $prev in + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + compile_command="$compile_command @SYMFILE@" + finalize_command="$finalize_command @SYMFILE@" + preload=yes + fi + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + else + dlprefiles="$dlprefiles $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols="$arg" + if test ! -f "$arg"; then + $echo "$modename: symbol file \`$arg' does not exist" + exit 1 + fi + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + inst_prefix) + inst_prefix_dir="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit 1 + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) rpath="$rpath $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) xrpath="$xrpath $arg" ;; + esac + fi + prev= + continue + ;; + xcompiler) + compiler_flags="$compiler_flags $qarg" + prev= + compile_command="$compile_command $qarg" + finalize_command="$finalize_command $qarg" + continue + ;; + xlinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $wl$qarg" + prev= + compile_command="$compile_command $wl$qarg" + finalize_command="$finalize_command $wl$qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n $prev + + prevarg="$arg" + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + compile_command="$compile_command $link_static_flag" + finalize_command="$finalize_command $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 + continue + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: more than one -exported-symbols argument is not allowed" + exit 1 + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | no/*-*-nonstopux*) + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + ;; + esac + continue + ;; + + -L*) + dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2 + exit 1 + fi + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "*) ;; + *) + deplibs="$deplibs -L$dir" + lib_search_path="$lib_search_path $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + case :$dllsearchpath: in + *":$dir:"*) ;; + *) dllsearchpath="$dllsearchpath:$dir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-pw32* | *-*-beos*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-mingw* | *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + esac + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-openbsd* | *-*-freebsd*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + deplibs="$deplibs $arg" + continue + ;; + + -module) + module=yes + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + # The PATH hackery in wrapper scripts is required on Windows + # in order for the loader to find any dlls it needs. + $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2 + $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2 + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -o) prev=output ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit 1 + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + continue + ;; + + -static) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Wl,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $wl$flag" + linker_flags="$linker_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + # Some other compiler flag. + -* | +*) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + ;; + + *.lo | *.$objext) + # A library or standard object. + if test "$prev" = dlfiles; then + # This file was specified with -dlopen. + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $arg" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles "`$echo "X$arg" | $Xsed -e "$lo2o"` + prev= + else + case $arg in + *.lo) libobjs="$libobjs $arg" ;; + *) objs="$objs $arg" ;; + esac + fi + ;; + + *.$libext) + # An archive. + deplibs="$deplibs $arg" + old_deplibs="$old_deplibs $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + dlfiles="$dlfiles $arg" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + dlprefiles="$dlprefiles $arg" + prev= + else + deplibs="$deplibs $arg" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + done # argument parsing loop + + if test -n "$prev"; then + $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + + # calculate the name of the file, without its directory + outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` + libobjs_save="$libobjs" + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` + if test "X$output_objdir" = "X$output"; then + output_objdir="$objdir" + else + output_objdir="$output_objdir/$objdir" + fi + # Create the object directory. + if test ! -d $output_objdir; then + $show "$mkdir $output_objdir" + $run $mkdir $output_objdir + status=$? + if test $status -ne 0 && test ! -d $output_objdir; then + exit $status + fi + fi + + # Determine the type of output + case $output in + "") + $echo "$modename: you must specify an output file" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + specialdeplibs= + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if test "X$duplicate_deps" = "Xyes" ; then + case "$libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + libs="$libs $deplib" + done + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + case $linkmode in + lib) + passes="conv link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2 + exit 1 + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + for pass in $passes; do + if test $linkmode = prog; then + # Determine which files to process + case $pass in + dlopen) + libs="$dlfiles" + save_deplibs="$deplibs" # Collect dlpreopened libraries + deplibs= + ;; + dlpreopen) libs="$dlprefiles" ;; + link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + esac + fi + for deplib in $libs; do + lib= + found=no + case $deplib in + -l*) + if test $linkmode = oldlib && test $linkmode = obj; then + $echo "$modename: warning: \`-l' is ignored for archives/objects: $deplib" 1>&2 + continue + fi + if test $pass = conv; then + deplibs="$deplib $deplibs" + continue + fi + name=`$echo "X$deplib" | $Xsed -e 's/^-l//'` + for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do + # Search the libtool library + lib="$searchdir/lib${name}.la" + if test -f "$lib"; then + found=yes + break + fi + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test $linkmode = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + ;; # -l + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test $pass = conv && continue + newdependency_libs="$deplib $newdependency_libs" + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + ;; + prog) + if test $pass = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test $pass = scan; then + deplibs="$deplib $deplibs" + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + ;; + *) + $echo "$modename: warning: \`-L' is ignored for archives/objects: $deplib" 1>&2 + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test $pass = link; then + dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'` + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) lib="$deplib" ;; + *.$libext) + if test $pass = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + if test "$deplibs_check_method" != pass_all; then + echo + echo "*** Warning: Trying to link with static lib archive $deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because the file extensions .$libext of this argument makes me believe" + echo "*** that it is just a static archive that I should not used here." + else + echo + echo "*** Warning: Linking the shared library $output against the" + echo "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + continue + ;; + prog) + if test $pass != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test $pass = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + newdlprefiles="$newdlprefiles $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + newdlfiles="$newdlfiles $deplib" + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + if test $found = yes || test -f "$lib"; then : + else + $echo "$modename: cannot find the library \`$lib'" 1>&2 + exit 1 + fi + + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $lib | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit 1 + fi + + ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` + test "X$ladir" = "X$lib" && ladir="." + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + # If the library was installed with an old release of libtool, + # it will not redefine variable installed. + installed=yes + + # Read the .la file + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test $linkmode = oldlib && test $linkmode = obj; }; then + # Add dl[pre]opened files of deplib + test -n "$dlopen" && dlfiles="$dlfiles $dlopen" + test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" + fi + + if test $pass = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit 1 + fi + # It is a libtool convenience library, so add in its objects. + convenience="$convenience $ladir/$objdir/$old_library" + old_convenience="$old_convenience $ladir/$objdir/$old_library" + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + elif test $linkmode != prog && test $linkmode != lib; then + $echo "$modename: \`$lib' is not a convenience library" 1>&2 + exit 1 + fi + continue + fi # $pass = conv + + # Get the name of the library we link against. + linklib= + for l in $old_library $library_names; do + linklib="$l" + done + if test -z "$linklib"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit 1 + fi + + # This library was specified with -dlopen. + if test $pass = dlopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2 + exit 1 + fi + if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. + dlprefiles="$dlprefiles $lib" + else + newdlfiles="$newdlfiles $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2 + $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 + abs_ladir="$ladir" + fi + ;; + esac + laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + $echo "$modename: warning: library \`$lib' was moved." 1>&2 + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$libdir" + absdir="$libdir" + fi + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + fi # $installed = yes + name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + + # This library was specified with -dlpreopen. + if test $pass = dlpreopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2 + exit 1 + fi + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + newdlprefiles="$newdlprefiles $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + newdlprefiles="$newdlprefiles $dir/$dlname" + else + newdlprefiles="$newdlprefiles $dir/$linklib" + fi + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test $linkmode = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" + fi + continue + fi + + if test $linkmode = prog && test $pass != link; then + newlib_search_path="$newlib_search_path $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test + esac + # Need to link against all dependency_libs? + if test $linkalldeplibs = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + link_static=no # Whether the deplib will be linked statically + if test -n "$library_names" && + { test "$prefer_static_libs" = no || test -z "$old_library"; }; then + # Link against this shared library + + if test "$linkmode,$pass" = "prog,link" || + { test $linkmode = lib && test $hardcode_into_libs = yes; }; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + if test $linkmode = prog; then + # We need to hardcode the library path + if test -n "$shlibpath_var"; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath " in + *" $dir "*) ;; + *" $absdir "*) ;; + *) temp_rpath="$temp_rpath $dir" ;; + esac + fi + fi + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + + if test "$installed" = no; then + notinst_deplibs="$notinst_deplibs $lib" + need_relink=yes + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + realname="$2" + shift; shift + libname=`eval \\$echo \"$libname_spec\"` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname="$dlname" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin*) + major=`expr $current - $age` + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + soname=`echo $soroot | ${SED} -e 's/^.*\///'` + newlib="libimp-`echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a" + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + $show "extracting exported symbol list from \`$soname'" + save_ifs="$IFS"; IFS='~' + eval cmds=\"$extract_expsyms_cmds\" + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + $show "generating import library for \`$soname'" + save_ifs="$IFS"; IFS='~' + eval cmds=\"$old_archive_from_expsyms_cmds\" + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n $old_archive_from_expsyms_cmds + + if test $linkmode = prog || test "$mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + $echo "$modename: configuration error: unsupported hardcode properties" + exit 1 + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; + esac + fi + if test $linkmode = prog; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test "$hardcode_direct" != yes && \ + test "$hardcode_minus_L" != yes && \ + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + fi + fi + fi + + if test $linkmode = prog || test "$mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + # Try looking first in the location we're being installed to. + add_dir= + if test -n "$inst_prefix_dir"; then + case "$libdir" in + [\\/]*) + add_dir="-L$inst_prefix_dir$libdir" + ;; + esac + fi + add_dir="$add_dir -L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + add="-l$name" + else + # We cannot seem to hardcode it, guess we'll fake it. + # Try looking first in the location we're being installed to. + add_dir= + if test -n "$inst_prefix_dir"; then + case "$libdir" in + [\\/]*) + add_dir="-L$inst_prefix_dir$libdir" + ;; + esac + fi + add_dir="$add_dir -L$libdir" + add="-l$name" + fi + + if test $linkmode = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test $linkmode = prog; then + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + + # Try to link the static library + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + echo + echo "*** Warning: This system can not link to static lib archive $lib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + if test "$module" = yes; then + echo "*** But as you try to build a module library, libtool will still create " + echo "*** a static module, that should work as long as the dlopening application" + echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + convenience="$convenience $dir/$old_library" + old_convenience="$old_convenience $dir/$old_library" + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test $linkmode = lib; then + if test -n "$dependency_libs" && + { test $hardcode_into_libs != yes || test $build_old_libs = yes || + test $link_static = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'` + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) xrpath="$xrpath $temp_xrpath";; + esac;; + *) temp_deplibs="$temp_deplibs $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + newlib_search_path="$newlib_search_path $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + + if test $link_all_deplibs != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + case $deplib in + -L*) path="$deplib" ;; + *.la) + dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$deplib" && dir="." + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 + absdir="$dir" + fi + ;; + esac + if grep "^installed=no" $deplib > /dev/null; then + path="-L$absdir/$objdir" + else + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit 1 + fi + if test "$absdir" != "$libdir"; then + $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2 + fi + path="-L$absdir" + fi + ;; + *) continue ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$deplibs $path" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + if test $pass = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test $pass != dlopen; then + test $pass != scan && dependency_libs="$newdependency_libs" + if test $pass != conv; then + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) lib_search_path="$lib_search_path $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + *) + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + if test "$pass" = "conv" && + { test "$linkmode" = "lib" || test "$linkmode" = "prog"; }; then + libs="$deplibs" # reset libs + deplibs= + fi + done # for pass + if test $linkmode = prog; then + dlfiles="$newdlfiles" + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for archives" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for archives" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for archives" 1>&2 + fi + + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2 + fi + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + objs="$objs$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form `libNAME.la'. + case $outputname in + lib*) + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + eval libname=\"$libname_spec\" + ;; + *) + if test "$module" = no; then + $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + eval libname=\"$libname_spec\" + else + libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + fi + ;; + esac + + if test -n "$objs"; then + if test "$deplibs_check_method" != pass_all; then + $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1 + exit 1 + else + echo + echo "*** Warning: Linking the shared library $output against the non-libtool" + echo "*** objects $objs is not portable!" + libobjs="$libobjs $objs" + fi + fi + + if test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2 + fi + + set dummy $rpath + if test $# -gt 2; then + $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 + fi + install_libdir="$2" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + libext=al + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for convenience libraries" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2 + fi + else + + # Parse the version information argument. + save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + IFS="$save_ifs" + + if test -n "$8"; then + $echo "$modename: too many parameters to \`-version-info'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + current="$2" + revision="$3" + age="$4" + + # Check that each of the things are valid numbers. + case $current in + [0-9]*) ;; + *) + $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + case $revision in + [0-9]*) ;; + *) + $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + case $age in + [0-9]*) ;; + *) + $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + if test $age -gt $current; then + $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + minor_current=`expr $current + 1` + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current"; + ;; + + irix | nonstopux) + major=`expr $current - $age + 1` + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring="$verstring_prefix$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test $loop != 0; do + iface=`expr $revision - $loop` + loop=`expr $loop - 1` + verstring="$verstring_prefix$major.$iface:$verstring" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + linux) + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + ;; + + osf) + major=.`expr $current - $age` + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test $loop != 0; do + iface=`expr $current - $loop` + loop=`expr $loop - 1` + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + verstring="$verstring:${current}.0" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + major=`expr $current - $age` + versuffix="-$major" + ;; + + *) + $echo "$modename: unknown library version type \`$version_type'" 1>&2 + echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit 1 + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + verstring="0.0" + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring="" + ;; + *) + verstring="0.0" + ;; + esac + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + fi + + if test "$mode" != relink; then + # Remove our outputs. + $show "${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*" + $run ${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.* + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + oldlibs="$oldlibs $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + for path in $notinst_path; do + lib_search_path=`echo "$lib_search_path " | ${SED} -e 's% $path % %g'` + deplibs=`echo "$deplibs " | ${SED} -e 's% -L$path % %g'` + dependency_libs=`echo "$dependency_libs " | ${SED} -e 's% -L$path % %g'` + done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + temp_xrpath="$temp_xrpath -R$libdir" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + if test $hardcode_into_libs != yes || test $build_old_libs = yes; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles="$dlfiles" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) dlfiles="$dlfiles $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) dlprefiles="$dlprefiles $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + deplibs="$deplibs -framework System" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd*) + # Do not include libc due to us having libc/libc_r. + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test $build_libtool_need_lc = "yes"; then + deplibs="$deplibs -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behaviour. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $rm conftest.c + cat > conftest.c </dev/null` + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null \ + | grep " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ + | ${SED} 10q \ + | egrep "$file_magic_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + echo "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + echo "*** with $libname but no candidates were found. (...for file magic test)" + else + echo "*** with $libname and none of the candidates passed a file format test" + echo "*** using a file magic. Last file checked: $potlib" + fi + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method + match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` + for a_deplib in $deplibs; do + name="`expr $a_deplib : '-l\(.*\)'`" + # If $name is empty we are operating on a -L argument. + if test -n "$name" && test "$name" != "0"; then + libname=`eval \\$echo \"$libname_spec\"` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib="$potent_lib" # see symlink-check below in file_magic test + if eval echo \"$potent_lib\" 2>/dev/null \ + | ${SED} 10q \ + | egrep "$match_pattern_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + echo "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + echo "*** with $libname but no candidates were found. (...for regex pattern test)" + else + echo "*** with $libname and none of the candidates passed a file format test" + echo "*** using a regex pattern. Last file checked: $potlib" + fi + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + if $echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ + -e 's/ -[LR][^ ]*//g' -e 's/[ ]//g' | + grep . >/dev/null; then + echo + if test "X$deplibs_check_method" = "Xnone"; then + echo "*** Warning: inter-library dependencies are not supported in this platform." + else + echo "*** Warning: inter-library dependencies are not known to be supported." + fi + echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + fi + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'` + ;; + esac + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + echo + echo "*** Warning: libtool could not satisfy all declared inter-library" + echo "*** dependencies of module $libname. Therefore, libtool will create" + echo "*** a static module, that should work as long as the dlopening" + echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + echo "*** The inter-library dependencies that have been dropped here will be" + echo "*** automatically added whenever a program is linked with this library" + echo "*** or is declared to -dlopen it." + + if test $allow_undefined = no; then + echo + echo "*** Since this library must not contain undefined symbols," + echo "*** because either the platform does not support them or" + echo "*** it was explicitly requested with -no-undefined," + echo "*** libtool will only create a static version of it." + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + if test $hardcode_into_libs = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$mode" != relink && rpath="$compile_rpath$rpath" + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + dep_rpath="$dep_rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval dep_rpath=\"$hardcode_libdir_flag_spec\" + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval library_names=\"$library_names_spec\" + set dummy $library_names + realname="$2" + shift; shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + test -z "$dlname" && dlname=$soname + + lib="$output_objdir/$realname" + for link + do + linknames="$linknames $link" + done + + # Ensure that we have .o objects for linkers which dislike .lo + # (e.g. aix) in case we are running --disable-static + for obj in $libobjs; do + xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$obj"; then + xdir="." + else + xdir="$xdir" + fi + baseobj=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` + oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"` + if test ! -f $xdir/$oldobj; then + $show "(cd $xdir && ${LN_S} $baseobj $oldobj)" + $run eval '(cd $xdir && ${LN_S} $baseobj $oldobj)' || exit $? + fi + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + $show "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $run $rm $export_symbols + eval cmds=\"$export_symbols_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + if test -n "$export_symbols_regex"; then + $show "egrep -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"" + $run eval 'egrep -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + $show "$mv \"${export_symbols}T\" \"$export_symbols\"" + $run eval '$mv "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' + fi + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${outputname}x" + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "mkdir $gentop" + $run mkdir "$gentop" + status=$? + if test $status -ne 0 && test ! -d "$gentop"; then + exit $status + fi + generated="$generated $gentop" + + for xlib in $convenience; do + # Extract the objects. + case $xlib in + [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; + *) xabs=`pwd`"/$xlib" ;; + esac + xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` + xdir="$gentop/$xlib" + + $show "${rm}r $xdir" + $run ${rm}r "$xdir" + $show "mkdir $xdir" + $run mkdir "$xdir" + status=$? + if test $status -ne 0 && test ! -d "$xdir"; then + exit $status + fi + $show "(cd $xdir && $AR x $xabs)" + $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? + + libobjs="$libobjs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP` + done + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + linker_flags="$linker_flags $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval cmds=\"$archive_expsym_cmds\" + else + save_deplibs="$deplibs" + for conv in $convenience; do + tmp_deplibs= + for test_deplib in $deplibs; do + if test "$test_deplib" != "$conv"; then + tmp_deplibs="$tmp_deplibs $test_deplib" + fi + done + deplibs="$tmp_deplibs" + done + eval cmds=\"$archive_cmds\" + deplibs="$save_deplibs" + fi + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $? + exit 0 + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" + $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $? + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + obj) + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for objects" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 + fi + + case $output in + *.lo) + if test -n "$objs$old_deplibs"; then + $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 + exit 1 + fi + libobj="$output" + obj=`$echo "X$output" | $Xsed -e "$lo2o"` + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $run $rm $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${obj}x" + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "mkdir $gentop" + $run mkdir "$gentop" + status=$? + if test $status -ne 0 && test ! -d "$gentop"; then + exit $status + fi + generated="$generated $gentop" + + for xlib in $convenience; do + # Extract the objects. + case $xlib in + [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; + *) xabs=`pwd`"/$xlib" ;; + esac + xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` + xdir="$gentop/$xlib" + + $show "${rm}r $xdir" + $run ${rm}r "$xdir" + $show "mkdir $xdir" + $run mkdir "$xdir" + status=$? + if test $status -ne 0 && test ! -d "$xdir"; then + exit $status + fi + $show "(cd $xdir && $AR x $xabs)" + $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? + + reload_conv_objs="$reload_objs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP` + done + fi + fi + + # Create the old-style object. + reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + + output="$obj" + eval cmds=\"$reload_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit 0 + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + $show "echo timestamp > $libobj" + $run eval "echo timestamp > $libobj" || exit $? + exit 0 + fi + + if test -n "$pic_flag" || test "$pic_mode" != default; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + eval cmds=\"$reload_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + else + # Just create a symlink. + $show $rm $libobj + $run $rm $libobj + xdir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$libobj"; then + xdir="." + else + xdir="$xdir" + fi + baseobj=`$echo "X$libobj" | $Xsed -e 's%^.*/%%'` + oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"` + $show "(cd $xdir && $LN_S $oldobj $baseobj)" + $run eval '(cd $xdir && $LN_S $oldobj $baseobj)' || exit $? + fi + + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit 0 + ;; + + prog) + case $host in + *cygwin*) output=`echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;; + esac + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for programs" 1>&2 + fi + + if test "$preload" = yes; then + if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown && + test "$dlopen_self_static" = unknown; then + $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." + fi + fi + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + case $host in + *darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + compile_command="$compile_command ${wl}-bind_at_load" + finalize_command="$finalize_command ${wl}-bind_at_load" + ;; + esac + ;; + esac + + compile_command="$compile_command $compile_deplibs" + finalize_command="$finalize_command $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + case :$dllsearchpath: in + *":$libdir:"*) ;; + *) dllsearchpath="$dllsearchpath:$libdir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + fi + + dlsyms= + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + dlsyms="${outputname}S.c" + else + $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 + fi + fi + + if test -n "$dlsyms"; then + case $dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${outputname}.nm" + + $show "$rm $nlist ${nlist}S ${nlist}T" + $run $rm "$nlist" "${nlist}S" "${nlist}T" + + # Parse the name list into a source file. + $show "creating $output_objdir/$dlsyms" + + test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ +/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */ +/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +/* Prevent the only kind of declaration conflicts we can make. */ +#define lt_preloaded_symbols some_other_symbol + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + $show "generating symbol list for \`$output'" + + test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + for arg in $progfiles; do + $show "extracting global C symbols from \`$arg'" + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $run eval 'egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + if test -n "$export_symbols_regex"; then + $run eval 'egrep -e "$export_symbols_regex" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$output.exp" + $run $rm $export_symbols + $run eval "${SED} -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + else + $run eval "${SED} -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"' + $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T' + $run eval 'mv "$nlist"T "$nlist"' + fi + fi + + for arg in $dlprefiles; do + $show "extracting global C symbols from \`$arg'" + name=`echo "$arg" | ${SED} -e 's%^.*/%%'` + $run eval 'echo ": $name " >> "$nlist"' + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -z "$run"; then + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $mv "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if grep -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + grep -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"' + else + echo '/* NONE */' >> "$output_objdir/$dlsyms" + fi + + $echo >> "$output_objdir/$dlsyms" "\ + +#undef lt_preloaded_symbols + +#if defined (__STDC__) && __STDC__ +# define lt_ptr void * +#else +# define lt_ptr char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr address; +} +lt_preloaded_symbols[] = +{\ +" + + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms" + + $echo >> "$output_objdir/$dlsyms" "\ + {0, (lt_ptr) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + fi + + pic_flag_for_symtable= + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag -DPIC -DFREEBSD_WORKAROUND";; + esac;; + *-*-hpux*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag -DPIC";; + esac + esac + + # Now compile the dynamic symbol file. + $show "(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" + $run eval '(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? + + # Clean up the generated files. + $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" + $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" + + # Transform the symbol file into the correct name. + compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` + ;; + *) + $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 + exit 1 + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` + fi + + if test $need_relink = no || test "$build_libtool_libs" != yes; then + # Replace the output file specification. + compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + $show "$link_command" + $run eval "$link_command" + status=$? + + # Delete the generated files. + if test -n "$dlsyms"; then + $show "$rm $output_objdir/${outputname}S.${objext}" + $run $rm "$output_objdir/${outputname}S.${objext}" + fi + + exit $status + fi + + if test -n "$shlibpath_var"; then + # We should set the shlibpath_var + rpath= + for dir in $temp_rpath; do + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) + # Absolute path. + rpath="$rpath$dir:" + ;; + *) + # Relative path: add a thisdir entry. + rpath="$rpath\$thisdir/$dir:" + ;; + esac + done + temp_rpath="$rpath" + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + rpath="$rpath$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$no_install" = yes; then + # We don't need to create a wrapper script. + link_command="$compile_var$compile_command$compile_rpath" + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $run $rm $output + # Link the executable and exit + $show "$link_command" + $run eval "$link_command" || exit $? + exit 0 + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 + $echo "$modename: \`$output' will be relinked during installation" 1>&2 + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname + + $show "$link_command" + $run eval "$link_command" || exit $? + + # Now create the wrapper script. + $show "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` + fi + + # Quote $echo for shipping. + if test "X$echo" = "X$SHELL $0 --fallback-echo"; then + case $0 in + [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $0 --fallback-echo";; + *) qecho="$SHELL `pwd`/$0 --fallback-echo";; + esac + qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` + else + qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` + fi + + # Only actually do things if our run command is non-null. + if test -z "$run"; then + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) output=`echo $output|${SED} 's,.exe$,,'` ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) exeext=.exe ;; + *) exeext= ;; + esac + $rm $output + trap "$rm $output; exit 1" 1 2 15 + + $echo > $output "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed="${SED}"' -e 1s/^X//' +sed_quote_subst='$sed_quote_subst' + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +if test \"\${CDPATH+set}\" = set; then CDPATH=:; export CDPATH; fi + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variable: + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$echo are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + echo=\"$qecho\" + file=\"\$0\" + # Make sure echo works. + if test \"X\$1\" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift + elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then + # Yippee, \$echo works! + : + else + # Restart under the correct shell, and then maybe \$echo will work. + exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} + fi + fi\ +" + $echo >> $output "\ + + # Find the directory that this script lives in. + thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` + done + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + echo >> $output "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || \\ + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $mkdir \"\$progdir\" + else + $rm \"\$progdir/\$file\" + fi" + + echo >> $output "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + $echo \"\$relink_command_output\" >&2 + $rm \"\$progdir/\$file\" + exit 1 + fi + fi + + $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $rm \"\$progdir/\$program\"; + $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $rm \"\$progdir/\$file\" + fi" + else + echo >> $output "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + echo >> $output "\ + + if test -f \"\$progdir/\$program\"; then" + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $echo >> $output "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 ${SED} + $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` + + export $shlibpath_var +" + fi + + # fixup the dll searchpath if we need to. + if test -n "$dllsearchpath"; then + $echo >> $output "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + $echo >> $output "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. +" + case $host in + # win32 systems need to use the prog path for dll + # lookup to work + *-*-cygwin* | *-*-pw32*) + $echo >> $output "\ + exec \$progdir/\$program \${1+\"\$@\"} +" + ;; + + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2*) + $echo >> $output "\ + exec \$progdir\\\\\$program \${1+\"\$@\"} +" + ;; + + *) + $echo >> $output "\ + # Export the path to the program. + PATH=\"\$progdir:\$PATH\" + export PATH + + exec \$program \${1+\"\$@\"} +" + ;; + esac + $echo >> $output "\ + \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\" + exit 1 + fi + else + # The program doesn't exist. + \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2 + \$echo \"This script is just a wrapper for \$program.\" 1>&2 + echo \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" + chmod +x $output + fi + exit 0 + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$objs$old_deplibs "`$echo "X$libobjs_save" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP` + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "mkdir $gentop" + $run mkdir "$gentop" + status=$? + if test $status -ne 0 && test ! -d "$gentop"; then + exit $status + fi + generated="$generated $gentop" + + # Add in members from convenience archives. + for xlib in $addlibs; do + # Extract the objects. + case $xlib in + [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; + *) xabs=`pwd`"/$xlib" ;; + esac + xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` + xdir="$gentop/$xlib" + + $show "${rm}r $xdir" + $run ${rm}r "$xdir" + $show "mkdir $xdir" + $run mkdir "$xdir" + status=$? + if test $status -ne 0 && test ! -d "$xdir"; then + exit $status + fi + $show "(cd $xdir && $AR x $xabs)" + $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? + + oldobjs="$oldobjs "`find $xdir -name \*.${objext} -print -o -name \*.lo -print | $NL2SP` + done + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + eval cmds=\"$old_archive_from_new_cmds\" + else + # Ensure that we have .o objects in place in case we decided + # not to build a shared library, and have fallen back to building + # static libs even though --disable-static was passed! + for oldobj in $oldobjs; do + if test ! -f $oldobj; then + xdir=`$echo "X$oldobj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$oldobj"; then + xdir="." + else + xdir="$xdir" + fi + baseobj=`$echo "X$oldobj" | $Xsed -e 's%^.*/%%'` + obj=`$echo "X$baseobj" | $Xsed -e "$o2lo"` + $show "(cd $xdir && ${LN_S} $obj $baseobj)" + $run eval '(cd $xdir && ${LN_S} $obj $baseobj)' || exit $? + fi + done + + eval cmds=\"$old_archive_cmds\" + fi + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$generated"; then + $show "${rm}r$generated" + $run ${rm}r$generated + fi + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + $show "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL $0 --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` + + # Only create the output if not a dry run. + if test -z "$run"; then + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit 1 + fi + newdependency_libs="$newdependency_libs $libdir/$name" + ;; + *) newdependency_libs="$newdependency_libs $deplib" ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + for lib in $dlfiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit 1 + fi + newdlfiles="$newdlfiles $libdir/$name" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit 1 + fi + newdlprefiles="$newdlprefiles $libdir/$name" + done + dlprefiles="$newdlprefiles" + fi + $rm $output + # place dlname in correct position for cygwin + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; + esac + $echo > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test "$installed" = no && test $need_relink = yes; then + $echo >> $output "\ +relink_command=\"$relink_command\"" + fi + done + fi + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" + $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $? + ;; + esac + exit 0 + ;; + + # libtool install mode + install) + modename="$modename: install" + + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + $echo "X$nonopt" | $Xsed | grep shtool > /dev/null; then + # Aesthetically quote it. + arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$arg " + arg="$1" + shift + else + install_prog= + arg="$nonopt" + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog$arg" + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + for arg + do + if test -n "$dest"; then + files="$files $dest" + dest="$arg" + continue + fi + + case $arg in + -d) isdir=yes ;; + -f) prev="-f" ;; + -g) prev="-g" ;; + -m) prev="-m" ;; + -o) prev="-o" ;; + -s) + stripme=" -s" + continue + ;; + -*) ;; + + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + prev= + else + dest="$arg" + continue + fi + ;; + esac + + # Aesthetically quote the argument. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog $arg" + done + + if test -z "$install_prog"; then + $echo "$modename: you must specify an install program" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test -n "$prev"; then + $echo "$modename: the \`$prev' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test -z "$files"; then + if test -z "$dest"; then + $echo "$modename: no file or destination specified" 1>&2 + else + $echo "$modename: you must specify a destination" 1>&2 + fi + $echo "$help" 1>&2 + exit 1 + fi + + # Strip any trailing slash from the destination. + dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` + test "X$destdir" = "X$dest" && destdir=. + destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` + + # Not a directory, so check to see that there is only one file specified. + set dummy $files + if test $# -gt 2; then + $echo "$modename: \`$dest' is not a directory" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + staticlibs="$staticlibs $file" + ;; + + *.la) + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + library_names= + old_library= + relink_command= + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) current_libdirs="$current_libdirs $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) future_libdirs="$future_libdirs $libdir" ;; + esac + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/ + test "X$dir" = "X$file/" && dir= + dir="$dir$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$echo "$destdir" | sed "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + if test "$inst_prefix_dir" = "$destdir"; then + $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2 + exit 1 + fi + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$echo "$relink_command" | sed "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$echo "$relink_command" | sed "s%@inst_prefix_dir@%%"` + fi + + $echo "$modename: warning: relinking \`$file'" 1>&2 + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + exit 1 + fi + fi + + # See the names of the shared library. + set dummy $library_names + if test -n "$2"; then + realname="$2" + shift + shift + + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + + # Install the shared library and build the symlinks. + $show "$install_prog $dir/$srcname $destdir/$realname" + $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $? + if test -n "$stripme" && test -n "$striplib"; then + $show "$striplib $destdir/$realname" + $run eval "$striplib $destdir/$realname" || exit $? + fi + + if test $# -gt 0; then + # Delete the old symlinks, and create new ones. + for linkname + do + if test "$linkname" != "$realname"; then + $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" + $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" + fi + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + eval cmds=\"$postinstall_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Install the pseudo-library for information purposes. + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + instname="$dir/$name"i + $show "$install_prog $instname $destdir/$name" + $run eval "$install_prog $instname $destdir/$name" || exit $? + + # Maybe install the static library, too. + test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` + ;; + *.$objext) + staticdest="$destfile" + destfile= + ;; + *) + $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + esac + + # Install the libtool object if requested. + if test -n "$destfile"; then + $show "$install_prog $file $destfile" + $run eval "$install_prog $file $destfile" || exit $? + fi + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` + + $show "$install_prog $staticobj $staticdest" + $run eval "$install_prog \$staticobj \$staticdest" || exit $? + fi + exit 0 + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin*|*mingw*) + wrapper=`echo $file | ${SED} -e 's,.exe$,,'` + ;; + *) + wrapper=$file + ;; + esac + if (${SED} -e '4q' $wrapper | egrep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then + notinst_deplibs= + relink_command= + + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $wrapper ;; + *) . ./$wrapper ;; + esac + + # Check the variables that should have been set. + if test -z "$notinst_deplibs"; then + $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2 + exit 1 + fi + + finalize=yes + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + # If there is no directory component, then add one. + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + fi + libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 + finalize=no + fi + done + + relink_command= + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $wrapper ;; + *) . ./$wrapper ;; + esac + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + if test "$finalize" = yes && test -z "$run"; then + tmpdir="/tmp" + test -n "$TMPDIR" && tmpdir="$TMPDIR" + tmpdir_mktemp=`mktemp -d $tmpdir/libtool-XXXXXX 2> /dev/null` + if test $? = 0 ; then + tmpdir="$tmpdir_mktemp" + unset tmpdir_mktemp + else + tmpdir="$tmpdir/libtool-$$" + fi + if $mkdir -p "$tmpdir" && chmod 700 "$tmpdir"; then : + else + $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2 + continue + fi + file=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` + + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + ${rm}r "$tmpdir" + continue + fi + file="$outputname" + else + $echo "$modename: warning: cannot relink \`$file'" 1>&2 + fi + else + # Install the binary that we compiled earlier. + file=`$echo "X$file" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyways + case $install_prog,$host in + /usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + destfile=`echo $destfile | ${SED} -e 's,.exe$,,'` + ;; + esac + ;; + esac + $show "$install_prog$stripme $file $destfile" + $run eval "$install_prog\$stripme \$file \$destfile" || exit $? + test -n "$outputname" && ${rm}r "$tmpdir" + ;; + esac + done + + for file in $staticlibs; do + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + + $show "$install_prog $file $oldlib" + $run eval "$install_prog \$file \$oldlib" || exit $? + + if test -n "$stripme" && test -n "$striplib"; then + $show "$old_striplib $oldlib" + $run eval "$old_striplib $oldlib" || exit $? + fi + + # Do each command in the postinstall commands. + eval cmds=\"$old_postinstall_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$future_libdirs"; then + $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 + fi + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + test -n "$run" && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL $0 --finish$current_libdirs' + else + exit 0 + fi + ;; + + # libtool finish mode + finish) + modename="$modename: finish" + libdirs="$nonopt" + admincmds= + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for dir + do + libdirs="$libdirs $dir" + done + + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + eval cmds=\"$finish_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || admincmds="$admincmds + $cmd" + done + IFS="$save_ifs" + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $run eval "$cmds" || admincmds="$admincmds + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + test "$show" = ":" && exit 0 + + echo "----------------------------------------------------------------------" + echo "Libraries have been installed in:" + for libdir in $libdirs; do + echo " $libdir" + done + echo + echo "If you ever happen to want to link against installed libraries" + echo "in a given directory, LIBDIR, you must either use libtool, and" + echo "specify the full pathname of the library, or use the \`-LLIBDIR'" + echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + echo " - add LIBDIR to the \`$shlibpath_var' environment variable" + echo " during execution" + fi + if test -n "$runpath_var"; then + echo " - add LIBDIR to the \`$runpath_var' environment variable" + echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + echo " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + echo " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + echo + echo "See any operating system documentation about shared libraries for" + echo "more information, such as the ld(1) and ld.so(8) manual pages." + echo "----------------------------------------------------------------------" + exit 0 + ;; + + # libtool execute mode + execute) + modename="$modename: execute" + + # The first argument is the command name. + cmd="$nonopt" + if test -z "$cmd"; then + $echo "$modename: you must specify a COMMAND" 1>&2 + $echo "$help" + exit 1 + fi + + # Handle -dlopen flags immediately. + for file in $execute_dlfiles; do + if test ! -f "$file"; then + $echo "$modename: \`$file' is not a file" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + dir= + case $file in + *.la) + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Read the libtool library. + dlname= + library_names= + + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" + continue + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + + if test -f "$dir/$objdir/$dlname"; then + dir="$dir/$objdir" + else + $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 + exit 1 + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + ;; + + *) + $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -*) ;; + *) + # Do a test to see if this is really a libtool program. + if (${SED} -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` + args="$args \"$file\"" + done + + if test -z "$run"; then + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved enviroment variables + if test "${save_LC_ALL+set}" = set; then + LC_ALL="$save_LC_ALL"; export LC_ALL + fi + if test "${save_LANG+set}" = set; then + LANG="$save_LANG"; export LANG + fi + + # Now prepare to actually exec the command. + exec_cmd="\$cmd$args" + else + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" + $echo "export $shlibpath_var" + fi + $echo "$cmd$args" + exit 0 + fi + ;; + + # libtool clean and uninstall mode + clean | uninstall) + modename="$modename: $mode" + rm="$nonopt" + files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + for arg + do + case $arg in + -f) rm="$rm $arg"; rmforce=yes ;; + -*) rm="$rm $arg" ;; + *) files="$files $arg" ;; + esac + done + + if test -z "$rm"; then + $echo "$modename: you must specify an RM program" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + rmdirs= + + for file in $files; do + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + if test "X$dir" = "X$file"; then + dir=. + objdir="$objdir" + else + objdir="$dir/$objdir" + fi + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + test $mode = uninstall && objdir="$dir" + + # Remember objdir for removal later, being careful to avoid duplicates + if test $mode = clean; then + case " $rmdirs " in + *" $objdir "*) ;; + *) rmdirs="$rmdirs $objdir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if (test -L "$file") >/dev/null 2>&1 \ + || (test -h "$file") >/dev/null 2>&1 \ + || test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi + + rmfiles="$file" + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if (${SED} -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + . $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + rmfiles="$rmfiles $objdir/$n" + done + test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" + test $mode = clean && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" + + if test $mode = uninstall; then + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + eval cmds=\"$postuninstall_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" + if test $? != 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + eval cmds=\"$old_postuninstall_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" + if test $? != 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + # FIXME: should reinstall the best remaining shared library. + fi + fi + ;; + + *.lo) + if test "$build_old_libs" = yes; then + oldobj=`$echo "X$name" | $Xsed -e "$lo2o"` + rmfiles="$rmfiles $dir/$oldobj" + fi + ;; + + *) + # Do a test to see if this is a libtool program. + if test $mode = clean && + (${SED} -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + relink_command= + . $dir/$file + + rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + rmfiles="$rmfiles $objdir/lt-$name" + fi + fi + ;; + esac + $show "$rm $rmfiles" + $run $rm $rmfiles || exit_status=1 + done + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + $show "rmdir $dir" + $run rmdir $dir >/dev/null 2>&1 + fi + done + + exit $exit_status + ;; + + "") + $echo "$modename: you must specify a MODE" 1>&2 + $echo "$generic_help" 1>&2 + exit 1 + ;; + esac + + if test -z "$exec_cmd"; then + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$generic_help" 1>&2 + exit 1 + fi +fi # test -z "$show_help" + +if test -n "$exec_cmd"; then + eval exec $exec_cmd + exit 1 +fi + +# We need to display help for each of the modes. +case $mode in +"") $echo \ +"Usage: $modename [OPTION]... [MODE-ARG]... + +Provide generalized library-building support services. + + --config show all configuration variables + --debug enable verbose shell tracing +-n, --dry-run display commands without modifying any files + --features display basic configuration information and exit + --finish same as \`--mode=finish' + --help display this help message and exit + --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] + --quiet same as \`--silent' + --silent don't print informational messages + --version print version information + +MODE must be one of the following: + + clean remove files from the build directory + compile compile a source file into a libtool object + execute automatically set library path, then run a program + finish complete the installation of libtool libraries + install install libraries or executables + link create a library or an executable + uninstall remove libraries from an installed directory + +MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for +a more detailed description of MODE." + exit 0 + ;; + +clean) + $echo \ +"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + +compile) + $echo \ +"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -prefer-pic try to building PIC objects only + -prefer-non-pic try to building non-PIC objects only + -static always build a \`.o' file suitable for static linking + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + +execute) + $echo \ +"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + +finish) + $echo \ +"Usage: $modename [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + +install) + $echo \ +"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + +link) + $echo \ +"Usage: $modename [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -static do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, +only library objects (\`.lo' files) may be specified, and \`-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created +using \`ar' and \`ranlib', or on Windows using \`lib'. + +If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + +uninstall) + $echo \ +"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + +*) + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; +esac + +echo +$echo "Try \`$modename --help' for more information about other modes." + +exit 0 + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: diff --git a/missing b/missing new file mode 100755 index 0000000..22e101a --- /dev/null +++ b/missing @@ -0,0 +1,198 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. +# Copyright (C) 1996, 1997, 2001, 2002 Free Software Foundation, Inc. +# Franc,ois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.in; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +case "$1" in + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + yacc create \`y.tab.[ch]', if possible, from existing .[ch]" + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing - GNU libit 0.0" + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + + aclocal*) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acinclude.m4' or \`$configure_ac'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`$configure_ac'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acconfig.h' or \`$configure_ac'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' $configure_ac` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case "$f" in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`$configure_ac'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if [ ! -f y.tab.h ]; then + echo >y.tab.h + fi + if [ ! -f y.tab.c ]; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if [ ! -f lex.yy.c ]; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + makeinfo) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` + fi + touch $file + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and you do not seem to have it handy on your + system. You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequirements for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 diff --git a/mkinstalldirs b/mkinstalldirs new file mode 100755 index 0000000..6b3b5fc --- /dev/null +++ b/mkinstalldirs @@ -0,0 +1,40 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +# $Id$ + +errstatus=0 + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case "$pathcomp" in + -* ) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# mkinstalldirs ends here diff --git a/modules/Makefile.am b/modules/Makefile.am new file mode 100644 index 0000000..3f55830 --- /dev/null +++ b/modules/Makefile.am @@ -0,0 +1,205 @@ +NULL = +SUBDIRS = extfs vfolder + +INCLUDES = \ + -I$(top_srcdir) \ + -I$(top_builddir) \ + $(MODULES_XML_GCONF_CFLAGS) \ + $(MODULES_FILE_CFLAGS) \ + $(LIBEFS_CFLAGS) \ + $(VFS_CFLAGS) \ + -D_FILE_OFFSET_BITS=64 \ + -D_BSD_SOURCE \ + -D_GNU_SOURCE \ + -D_LARGEFILE64_SOURCE \ + -D_POSIX_PTHREAD_SEMANTICS \ + -D_REENTRANT \ + -DG_DISABLE_DEPRECATED \ + -DDATADIR=\"$(datadir)\" \ + -DPREFIX=\"$(prefix)\" \ + -DLIBDIR=\"$(libdir)\" \ + -DSYSCONFDIR=\"$(sysconfdir)\" \ + -DG_LOG_DOMAIN=\"gnome-vfs-modules\" \ + $(NULL) + +EXTRA_DIST = \ + default-modules.conf \ + cdda-module.conf \ + cdemenu-module.conf \ + ssl-modules.conf + +### Module setup + +if HAVE_CDDA +CDDA_LTLIBS = libcdda.la +else +CDDA_LTLIBS = +endif + +if BUILD_CDEMENU_MODULE +CDEMENU_LTLIBS = libcdemenu-desktop.la +else +CDEMENU_LTLIBS = +endif + +module_flags = -export_dynamic -avoid-version -module -no-undefined +modulesdir = $(libdir)/gnome-vfs-2.0/modules + +modules_LTLIBRARIES = \ + $(CDDA_LTLIBS) \ + libextfs.la \ + libfile.la \ + libnntp.la \ + libvfs-test.la \ + $(HTTP_LTLIBS) \ + libbzip2.la \ + libgzip.la \ + libftp.la \ + libvfs-pipe.la \ + libvfs-translate.la \ + $(CDEMENU_LTLIBS) \ + libssh.la \ + libtar.la \ + libdesktop.la \ + libvfolder-desktop-old.la \ + $(NULL) + +# Not currently supported +# libnfs.la + +modulesconfdir=$(sysconfdir)/gnome-vfs-2.0/modules +if HAVE_CDDA +CDDA_CONF = cdda-module.conf +endif +if HAVE_SSL +SSL_CONF = ssl-modules.conf +endif +if BUILD_CDEMENU_MODULE +CDE_CONF = cdemenu-module.conf +endif +modulesconf_DATA = default-modules.conf $(CDDA_CONF) $(SSL_CONF) $(CDE_CONF) + +### `cdda' method + +libcdda_la_SOURCES = \ + cdda-method.c \ + cdda-cddb.c \ + cdda-cddb.h \ + cdda-cdrom-extensions.h + +libcdda_la_LDFLAGS = $(module_flags) +libcdda_la_LIBADD = -lcdda_paranoia -lcdda_interface ../libgnomevfs/libgnomevfs-2.la + +### `extfs' method + +libextfs_la_SOURCES = extfs-method.c +libextfs_la_LDFLAGS = $(module_flags) +libextfs_la_LIBADD = $(MODULES_FILE_LIBS) ../libgnomevfs/libgnomevfs-2.la + +### `file' method + +libfile_la_SOURCES = file-method.c fstype.c +libfile_la_LDFLAGS = $(module_flags) +libfile_la_LIBADD = $(FAM_LIBS) $(MODULES_FILE_LIBS) ../libgnomevfs/libgnomevfs-2.la + +### `nntp' method + +libnntp_la_SOURCES = nntp-method.c nntp-method.h +libnntp_la_LDFLAGS = $(module_flags) +libnntp_la_LIBADD = $(MODULES_LIBS) ../libgnomevfs/libgnomevfs-2.la + +### `cdemenu-desktop' method + +libcdemenu_desktop_la_SOURCES = cdemenu-desktop-method.c +libcdemenu_desktop_la_LDFLAGS = $(module_flags) +libcdemenu_desktop_la_LIBADD = $(MODULES_LIBS) ../libgnomevfs/libgnomevfs-2.la + +### `ssh' method + +libssh_la_SOURCES = ssh-method.c +libssh_la_LDFLAGS = $(module_flags) +libssh_la_LIBADD = $(MODULES_LIBS) ../libgnomevfs/libgnomevfs-2.la + +### `test' method + +libvfs_test_la_SOURCES = test-method.c +libvfs_test_la_LDFLAGS = $(module_flags) +libvfs_test_la_LIBADD = $(MODULES_XML_LIBS) ../libgnomevfs/libgnomevfs-2.la + +### `gzip' method + +libgzip_la_SOURCES = gzip-method.c +libgzip_la_LDFLAGS = $(module_flags) +libgzip_la_LIBADD = $(MODULES_LIBS) -lz ../libgnomevfs/libgnomevfs-2.la + +### `bzip2' method + +libbzip2_la_SOURCES = bzip2-method.c +libbzip2_la_LDFLAGS = $(module_flags) +libbzip2_la_LIBADD = $(MODULES_LIBS) $(BZ2_LIBS) ../libgnomevfs/libgnomevfs-2.la + +### `ftp' method + +libftp_la_SOURCES = ftp-method.c +libftp_la_LDFLAGS = $(module_flags) +libftp_la_LIBADD = $(MODULES_LIBS) ../libgnomevfs/libgnomevfs-2.la + +### `desktop' method + +libdesktop_la_SOURCES = desktop-method.c +libdesktop_la_LDFLAGS = $(module_flags) +libdesktop_la_LIBADD = ../libgnomevfs/libgnomevfs-2.la + +### `vfolder-desktop' method + +libvfolder_desktop_old_la_SOURCES = vfolder-desktop-method.c +libvfolder_desktop_old_la_LDFLAGS = $(module_flags) +libvfolder_desktop_old_la_LIBADD = ../libgnomevfs/libgnomevfs-2.la + +### `nfs' method + +#libnfs_la_SOURCES = \ +# nfs-method.c \ +# nfs-method.h \ +# nfs-method_mount_xdr.c \ +# nfs-method_nfs_prot_xdr.c \ +# nfs-method_mount.h \ +# nfs-method_nfs_prot.h +#libnfs_la_LDFLAGS = $(module_flags) + +### `http' method + +HTTP_LTLIBS = libhttp.la + +libhttp_la_SOURCES = \ + http-method.c \ + http-method.h \ + http-authn.c \ + http-authn.h \ + http-cache.c \ + http-cache.h \ + $(NULL) +libhttp_la_LDFLAGS = $(module_flags) +libhttp_la_LIBADD = $(MODULES_GCONF_LIBS) $(MODULES_XML_LIBS) ../libgnomevfs/libgnomevfs-2.la + +libvfs_pipe_la_SOURCES = pipe-method.c +libvfs_pipe_la_LDFLAGS = $(module_flags) +libvfs_pipe_la_LIBADD = $(MODULES_LIBS) ../libgnomevfs/libgnomevfs-2.la + +libvfs_translate_la_SOURCES = translate-method.c +libvfs_translate_la_LDFLAGS = $(module_flags) +libvfs_translate_la_LIBADD = $(MODULES_LIBS) ../libgnomevfs/libgnomevfs-2.la + +libtar_la_SOURCES = tar-method.c tarpet.h +libtar_la_LDFLAGS = $(module_flags) +libtar_la_LIBADD = $(MODULES_LIBS) ../libgnomevfs/libgnomevfs-2.la + +#if HAVE_LIBEFS +#vefsmoduledir = $(modulesdir) +#vefsmodule_LTLIBRARIES = libvefs.la +# +#libvefs_la_SOURCES = \ +# efs-method.c +#libvefs_la_LIBADD = $(LIBEFS_LIBS) $(MODULES_LIBS) +#endif + diff --git a/modules/Makefile.am.old-modules b/modules/Makefile.am.old-modules new file mode 100644 index 0000000..08cf0fa --- /dev/null +++ b/modules/Makefile.am.old-modules @@ -0,0 +1,191 @@ +NULL = +SUBDIRS = extfs vfolder + +INCLUDES = \ + -I$(top_srcdir) \ + -I$(top_builddir) \ + $(MODULES_XML_GCONF_CFLAGS) \ + $(MODULES_FILE_CFLAGS) \ + $(LIBEFS_CFLAGS) \ + $(VFS_CFLAGS) \ + -D_FILE_OFFSET_BITS=64 \ + -D_BSD_SOURCE \ + -D_GNU_SOURCE \ + -D_LARGEFILE64_SOURCE \ + -D_POSIX_PTHREAD_SEMANTICS \ + -D_REENTRANT \ + -DG_DISABLE_DEPRECATED \ + -DDATADIR=\"$(datadir)\" \ + -DPREFIX=\"$(prefix)\" \ + -DLIBDIR=\"$(libdir)\" \ + -DSYSCONFDIR=\"$(sysconfdir)\" \ + -DG_LOG_DOMAIN=\"gnome-vfs-modules\" \ + $(NULL) + +EXTRA_DIST = \ + default-modules.conf \ + cdda-module.conf \ + cdemenu-module.conf \ + ssl-modules.conf + +### Module setup + +if HAVE_CDDA +CDDA_LTLIBS = libcdda.la +else +CDDA_LTLIBS = +endif + +if BUILD_CDEMENU_MODULE +CDEMENU_LTLIBS = libcdemenu-desktop.la +else +CDEMENU_LTLIBS = +endif + +module_flags = -export_dynamic -avoid-version -module -no-undefined +modulesdir = $(libdir)/gnome-vfs-2.0/modules + +modules_LTLIBRARIES = \ + $(CDDA_LTLIBS) \ + libextfs.la \ + libfile.la \ + libnntp.la \ + libvfs-test.la \ + $(HTTP_LTLIBS) \ + libbzip2.la \ + libgzip.la \ + libftp.la \ + libvfs-pipe.la \ + libvfs-translate.la \ + $(CDEMENU_LTLIBS) \ + libssh.la \ + libtar.la \ + $(NULL) + +# Not currently supported +# libnfs.la + +modulesconfdir=$(sysconfdir)/gnome-vfs-2.0/modules +if HAVE_CDDA +CDDA_CONF = cdda-module.conf +endif +if HAVE_SSL +SSL_CONF = ssl-modules.conf +endif +if BUILD_CDEMENU_MODULE +CDE_CONF = cdemenu-module.conf +endif +modulesconf_DATA = default-modules.conf $(CDDA_CONF) $(SSL_CONF) $(CDE_CONF) + +### `cdda' method + +libcdda_la_SOURCES = \ + cdda-method.c \ + cdda-cddb.c \ + cdda-cddb.h \ + cdda-cdrom-extensions.h + +libcdda_la_LDFLAGS = $(module_flags) +libcdda_la_LIBADD = -lcdda_paranoia -lcdda_interface ../libgnomevfs/libgnomevfs-2.la + +### `extfs' method + +libextfs_la_SOURCES = extfs-method.c +libextfs_la_LDFLAGS = $(module_flags) +libextfs_la_LIBADD = $(MODULES_FILE_LIBS) ../libgnomevfs/libgnomevfs-2.la + +### `file' method + +libfile_la_SOURCES = file-method.c fstype.c +libfile_la_LDFLAGS = $(module_flags) +libfile_la_LIBADD = $(FAM_LIBS) $(MODULES_FILE_LIBS) ../libgnomevfs/libgnomevfs-2.la + +### `nntp' method + +libnntp_la_SOURCES = nntp-method.c nntp-method.h +libnntp_la_LDFLAGS = $(module_flags) +libnntp_la_LIBADD = $(MODULES_LIBS) ../libgnomevfs/libgnomevfs-2.la + +### `cdemenu-desktop' method + +libcdemenu_desktop_la_SOURCES = cdemenu-desktop-method.c +libcdemenu_desktop_la_LDFLAGS = $(module_flags) +libcdemenu_desktop_la_LIBADD = $(MODULES_LIBS) ../libgnomevfs/libgnomevfs-2.la + +### `ssh' method + +libssh_la_SOURCES = ssh-method.c +libssh_la_LDFLAGS = $(module_flags) +libssh_la_LIBADD = $(MODULES_LIBS) ../libgnomevfs/libgnomevfs-2.la + +### `test' method + +libvfs_test_la_SOURCES = test-method.c +libvfs_test_la_LDFLAGS = $(module_flags) +libvfs_test_la_LIBADD = $(MODULES_XML_LIBS) ../libgnomevfs/libgnomevfs-2.la + +### `gzip' method + +libgzip_la_SOURCES = gzip-method.c +libgzip_la_LDFLAGS = $(module_flags) +libgzip_la_LIBADD = $(MODULES_LIBS) -lz ../libgnomevfs/libgnomevfs-2.la + +### `bzip2' method + +libbzip2_la_SOURCES = bzip2-method.c +libbzip2_la_LDFLAGS = $(module_flags) +libbzip2_la_LIBADD = $(MODULES_LIBS) $(BZ2_LIBS) ../libgnomevfs/libgnomevfs-2.la + +### `ftp' method + +libftp_la_SOURCES = ftp-method.c +libftp_la_LDFLAGS = $(module_flags) +libftp_la_LIBADD = $(MODULES_LIBS) ../libgnomevfs/libgnomevfs-2.la + +### `nfs' method + +#libnfs_la_SOURCES = \ +# nfs-method.c \ +# nfs-method.h \ +# nfs-method_mount_xdr.c \ +# nfs-method_nfs_prot_xdr.c \ +# nfs-method_mount.h \ +# nfs-method_nfs_prot.h +#libnfs_la_LDFLAGS = $(module_flags) + +### `http' method + +HTTP_LTLIBS = libhttp.la + +libhttp_la_SOURCES = \ + http-method.c \ + http-method.h \ + http-authn.c \ + http-authn.h \ + http-cache.c \ + http-cache.h \ + $(NULL) +libhttp_la_LDFLAGS = $(module_flags) +libhttp_la_LIBADD = $(MODULES_GCONF_LIBS) $(MODULES_XML_LIBS) ../libgnomevfs/libgnomevfs-2.la + +libvfs_pipe_la_SOURCES = pipe-method.c +libvfs_pipe_la_LDFLAGS = $(module_flags) +libvfs_pipe_la_LIBADD = $(MODULES_LIBS) ../libgnomevfs/libgnomevfs-2.la + +libvfs_translate_la_SOURCES = translate-method.c +libvfs_translate_la_LDFLAGS = $(module_flags) +libvfs_translate_la_LIBADD = $(MODULES_LIBS) ../libgnomevfs/libgnomevfs-2.la + +libtar_la_SOURCES = tar-method.c tarpet.h +libtar_la_LDFLAGS = $(module_flags) +libtar_la_LIBADD = $(MODULES_LIBS) ../libgnomevfs/libgnomevfs-2.la + +#if HAVE_LIBEFS +#vefsmoduledir = $(modulesdir) +#vefsmodule_LTLIBRARIES = libvefs.la +# +#libvefs_la_SOURCES = \ +# efs-method.c +#libvefs_la_LIBADD = $(LIBEFS_LIBS) $(MODULES_LIBS) +#endif + diff --git a/modules/Makefile.in b/modules/Makefile.in new file mode 100644 index 0000000..29c29ba --- /dev/null +++ b/modules/Makefile.in @@ -0,0 +1,1049 @@ +# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ +AS = @AS@ +AWK = @AWK@ +BONOBO_ACTIVATION_REQUIRED = @BONOBO_ACTIVATION_REQUIRED@ +BONOBO_IDLDIR = @BONOBO_IDLDIR@ +BONOBO_REQUIRED = @BONOBO_REQUIRED@ +BZ2_LIBS = @BZ2_LIBS@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +DATADIRNAME = @DATADIRNAME@ +DB2HTML = @DB2HTML@ +DLLTOOL = @DLLTOOL@ +ECHO = @ECHO@ +ENABLE_PROFILER = @ENABLE_PROFILER@ +EXEEXT = @EXEEXT@ +FAM_LIBS = @FAM_LIBS@ +GCONFTOOL = @GCONFTOOL@ +GCONF_REQUIRED = @GCONF_REQUIRED@ +GCONF_SCHEMA_CONFIG_SOURCE = @GCONF_SCHEMA_CONFIG_SOURCE@ +GCONF_SCHEMA_FILE_DIR = @GCONF_SCHEMA_FILE_DIR@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GLIB_REQUIRED = @GLIB_REQUIRED@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GNOME_ACLOCAL_DIR = @GNOME_ACLOCAL_DIR@ +GNOME_ACLOCAL_FLAGS = @GNOME_ACLOCAL_FLAGS@ +GNOME_VFS_DIR = @GNOME_VFS_DIR@ +GTKDOC = @GTKDOC@ +HAVE_GTK_DOC = @HAVE_GTK_DOC@ +HTML_DIR = @HTML_DIR@ +INSTOBJEXT = @INSTOBJEXT@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_CAVES_RULE = @INTLTOOL_CAVES_RULE@ +INTLTOOL_DESKTOP_RULE = @INTLTOOL_DESKTOP_RULE@ +INTLTOOL_DIRECTORY_RULE = @INTLTOOL_DIRECTORY_RULE@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_KEYS_RULE = @INTLTOOL_KEYS_RULE@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_OAF_RULE = @INTLTOOL_OAF_RULE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_PONG_RULE = @INTLTOOL_PONG_RULE@ +INTLTOOL_PROP_RULE = @INTLTOOL_PROP_RULE@ +INTLTOOL_SCHEMAS_RULE = @INTLTOOL_SCHEMAS_RULE@ +INTLTOOL_SERVER_RULE = @INTLTOOL_SERVER_RULE@ +INTLTOOL_SHEET_RULE = @INTLTOOL_SHEET_RULE@ +INTLTOOL_SOUNDLIST_RULE = @INTLTOOL_SOUNDLIST_RULE@ +INTLTOOL_THEME_RULE = @INTLTOOL_THEME_RULE@ +INTLTOOL_UI_RULE = @INTLTOOL_UI_RULE@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTLTOOL_XML_RULE = @INTLTOOL_XML_RULE@ +LDFLAGS = @LDFLAGS@ +LIBEFS_CFLAGS = @LIBEFS_CFLAGS@ +LIBEFS_LIBS = @LIBEFS_LIBS@ +LIBGNOMEVFS_AGE = @LIBGNOMEVFS_AGE@ +LIBGNOMEVFS_CFLAGS = @LIBGNOMEVFS_CFLAGS@ +LIBGNOMEVFS_CURRENT = @LIBGNOMEVFS_CURRENT@ +LIBGNOMEVFS_LIBS = @LIBGNOMEVFS_LIBS@ +LIBGNOMEVFS_REVISION = @LIBGNOMEVFS_REVISION@ +LIBGNUTLS_CFLAGS = @LIBGNUTLS_CFLAGS@ +LIBGNUTLS_CONFIG = @LIBGNUTLS_CONFIG@ +LIBGNUTLS_LIBS = @LIBGNUTLS_LIBS@ +LIBIDL_REQUIRED = @LIBIDL_REQUIRED@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MODULES_CFLAGS = @MODULES_CFLAGS@ +MODULES_FILE_CFLAGS = @MODULES_FILE_CFLAGS@ +MODULES_FILE_LIBS = @MODULES_FILE_LIBS@ +MODULES_GCONF_CFLAGS = @MODULES_GCONF_CFLAGS@ +MODULES_GCONF_LIBS = @MODULES_GCONF_LIBS@ +MODULES_LIBS = @MODULES_LIBS@ +MODULES_XML_CFLAGS = @MODULES_XML_CFLAGS@ +MODULES_XML_GCONF_CFLAGS = @MODULES_XML_GCONF_CFLAGS@ +MODULES_XML_GCONF_LIBS = @MODULES_XML_GCONF_LIBS@ +MODULES_XML_LIBS = @MODULES_XML_LIBS@ +MONIKERS_CFLAGS = @MONIKERS_CFLAGS@ +MONIKERS_LIBS = @MONIKERS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ORBIT_IDL = @ORBIT_IDL@ +ORBIT_REQUIRED = @ORBIT_REQUIRED@ +PACKAGE = @PACKAGE@ +PKG_CONFIG = @PKG_CONFIG@ +POFILES = @POFILES@ +POPT_LIBS = @POPT_LIBS@ +POSUB = @POSUB@ +PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ +PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ +RANLIB = @RANLIB@ +STRIP = @STRIP@ +TEST_CFLAGS = @TEST_CFLAGS@ +TEST_LIBS = @TEST_LIBS@ +TOP_BUILDDIR = @TOP_BUILDDIR@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +VFS_CFLAGS = @VFS_CFLAGS@ +VFS_INCLUDEDIR = @VFS_INCLUDEDIR@ +VFS_LIBDIR = @VFS_LIBDIR@ +VFS_LIBS = @VFS_LIBS@ +VFS_OFFSET = @VFS_OFFSET@ +VFS_OFFSET_IS = @VFS_OFFSET_IS@ +VFS_OFFSET_PRINTF = @VFS_OFFSET_PRINTF@ +VFS_SIZE = @VFS_SIZE@ +VFS_SIZE_IS = @VFS_SIZE_IS@ +VFS_SIZE_PRINTF = @VFS_SIZE_PRINTF@ +WARN_CFLAGS = @WARN_CFLAGS@ +XML_REQUIRED = @XML_REQUIRED@ +cxxflags_set = @cxxflags_set@ + +NULL = +SUBDIRS = extfs vfolder + +INCLUDES = \ + -I$(top_srcdir) \ + -I$(top_builddir) \ + $(MODULES_XML_GCONF_CFLAGS) \ + $(MODULES_FILE_CFLAGS) \ + $(LIBEFS_CFLAGS) \ + $(VFS_CFLAGS) \ + -D_FILE_OFFSET_BITS=64 \ + -D_BSD_SOURCE \ + -D_GNU_SOURCE \ + -D_LARGEFILE64_SOURCE \ + -D_POSIX_PTHREAD_SEMANTICS \ + -D_REENTRANT \ + -DG_DISABLE_DEPRECATED \ + -DDATADIR=\"$(datadir)\" \ + -DPREFIX=\"$(prefix)\" \ + -DLIBDIR=\"$(libdir)\" \ + -DSYSCONFDIR=\"$(sysconfdir)\" \ + -DG_LOG_DOMAIN=\"gnome-vfs-modules\" \ + $(NULL) + + +EXTRA_DIST = \ + default-modules.conf \ + cdda-module.conf \ + cdemenu-module.conf \ + ssl-modules.conf + +@HAVE_CDDA_TRUE@CDDA_LTLIBS = @HAVE_CDDA_TRUE@libcdda.la +@HAVE_CDDA_FALSE@CDDA_LTLIBS = +@BUILD_CDEMENU_MODULE_TRUE@CDEMENU_LTLIBS = @BUILD_CDEMENU_MODULE_TRUE@libcdemenu-desktop.la +@BUILD_CDEMENU_MODULE_FALSE@CDEMENU_LTLIBS = + +module_flags = -export_dynamic -avoid-version -module -no-undefined +modulesdir = $(libdir)/gnome-vfs-2.0/modules + +modules_LTLIBRARIES = \ + $(CDDA_LTLIBS) \ + libextfs.la \ + libfile.la \ + libnntp.la \ + libvfs-test.la \ + $(HTTP_LTLIBS) \ + libbzip2.la \ + libgzip.la \ + libftp.la \ + libvfs-pipe.la \ + libvfs-translate.la \ + $(CDEMENU_LTLIBS) \ + libssh.la \ + libtar.la \ + $(NULL) + + +# Not currently supported +# libnfs.la + +modulesconfdir = $(sysconfdir)/gnome-vfs-2.0/modules +@HAVE_CDDA_TRUE@CDDA_CONF = @HAVE_CDDA_TRUE@cdda-module.conf +@HAVE_SSL_TRUE@SSL_CONF = @HAVE_SSL_TRUE@ssl-modules.conf +@BUILD_CDEMENU_MODULE_TRUE@CDE_CONF = @BUILD_CDEMENU_MODULE_TRUE@cdemenu-module.conf +modulesconf_DATA = default-modules.conf $(CDDA_CONF) $(SSL_CONF) $(CDE_CONF) + +### `cdda' method + +libcdda_la_SOURCES = \ + cdda-method.c \ + cdda-cddb.c \ + cdda-cddb.h \ + cdda-cdrom-extensions.h + + +libcdda_la_LDFLAGS = $(module_flags) +libcdda_la_LIBADD = -lcdda_paranoia -lcdda_interface ../libgnomevfs/libgnomevfs-2.la + +### `extfs' method + +libextfs_la_SOURCES = extfs-method.c +libextfs_la_LDFLAGS = $(module_flags) +libextfs_la_LIBADD = $(MODULES_FILE_LIBS) ../libgnomevfs/libgnomevfs-2.la + +### `file' method + +libfile_la_SOURCES = file-method.c fstype.c +libfile_la_LDFLAGS = $(module_flags) +libfile_la_LIBADD = $(FAM_LIBS) $(MODULES_FILE_LIBS) ../libgnomevfs/libgnomevfs-2.la + +### `nntp' method + +libnntp_la_SOURCES = nntp-method.c nntp-method.h +libnntp_la_LDFLAGS = $(module_flags) +libnntp_la_LIBADD = $(MODULES_LIBS) ../libgnomevfs/libgnomevfs-2.la + +### `cdemenu-desktop' method + +libcdemenu_desktop_la_SOURCES = cdemenu-desktop-method.c +libcdemenu_desktop_la_LDFLAGS = $(module_flags) +libcdemenu_desktop_la_LIBADD = $(MODULES_LIBS) ../libgnomevfs/libgnomevfs-2.la + +### `ssh' method + +libssh_la_SOURCES = ssh-method.c +libssh_la_LDFLAGS = $(module_flags) +libssh_la_LIBADD = $(MODULES_LIBS) ../libgnomevfs/libgnomevfs-2.la + +### `test' method + +libvfs_test_la_SOURCES = test-method.c +libvfs_test_la_LDFLAGS = $(module_flags) +libvfs_test_la_LIBADD = $(MODULES_XML_LIBS) ../libgnomevfs/libgnomevfs-2.la + +### `gzip' method + +libgzip_la_SOURCES = gzip-method.c +libgzip_la_LDFLAGS = $(module_flags) +libgzip_la_LIBADD = $(MODULES_LIBS) -lz ../libgnomevfs/libgnomevfs-2.la + +### `bzip2' method + +libbzip2_la_SOURCES = bzip2-method.c +libbzip2_la_LDFLAGS = $(module_flags) +libbzip2_la_LIBADD = $(MODULES_LIBS) $(BZ2_LIBS) ../libgnomevfs/libgnomevfs-2.la + +### `ftp' method + +libftp_la_SOURCES = ftp-method.c +libftp_la_LDFLAGS = $(module_flags) +libftp_la_LIBADD = $(MODULES_LIBS) ../libgnomevfs/libgnomevfs-2.la + +### `nfs' method + +#libnfs_la_SOURCES = \ +# nfs-method.c \ +# nfs-method.h \ +# nfs-method_mount_xdr.c \ +# nfs-method_nfs_prot_xdr.c \ +# nfs-method_mount.h \ +# nfs-method_nfs_prot.h +#libnfs_la_LDFLAGS = $(module_flags) + +### `http' method + +HTTP_LTLIBS = libhttp.la + +libhttp_la_SOURCES = \ + http-method.c \ + http-method.h \ + http-authn.c \ + http-authn.h \ + http-cache.c \ + http-cache.h \ + $(NULL) + +libhttp_la_LDFLAGS = $(module_flags) +libhttp_la_LIBADD = $(MODULES_GCONF_LIBS) $(MODULES_XML_LIBS) ../libgnomevfs/libgnomevfs-2.la + +libvfs_pipe_la_SOURCES = pipe-method.c +libvfs_pipe_la_LDFLAGS = $(module_flags) +libvfs_pipe_la_LIBADD = $(MODULES_LIBS) ../libgnomevfs/libgnomevfs-2.la + +libvfs_translate_la_SOURCES = translate-method.c +libvfs_translate_la_LDFLAGS = $(module_flags) +libvfs_translate_la_LIBADD = $(MODULES_LIBS) ../libgnomevfs/libgnomevfs-2.la + +libtar_la_SOURCES = tar-method.c tarpet.h +libtar_la_LDFLAGS = $(module_flags) +libtar_la_LIBADD = $(MODULES_LIBS) ../libgnomevfs/libgnomevfs-2.la +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../config.h +CONFIG_CLEAN_FILES = +LTLIBRARIES = $(modules_LTLIBRARIES) + + +DEFS = @DEFS@ -I. -I$(srcdir) -I.. +LIBS = @LIBS@ +libcdda_la_DEPENDENCIES = ../libgnomevfs/libgnomevfs-2.la +libcdda_la_OBJECTS = cdda-method.lo cdda-cddb.lo +libextfs_la_DEPENDENCIES = ../libgnomevfs/libgnomevfs-2.la +libextfs_la_OBJECTS = extfs-method.lo +libfile_la_DEPENDENCIES = ../libgnomevfs/libgnomevfs-2.la +libfile_la_OBJECTS = file-method.lo fstype.lo +libnntp_la_DEPENDENCIES = ../libgnomevfs/libgnomevfs-2.la +libnntp_la_OBJECTS = nntp-method.lo +libvfs_test_la_DEPENDENCIES = ../libgnomevfs/libgnomevfs-2.la +libvfs_test_la_OBJECTS = test-method.lo +libhttp_la_DEPENDENCIES = ../libgnomevfs/libgnomevfs-2.la +libhttp_la_OBJECTS = http-method.lo http-authn.lo http-cache.lo +libbzip2_la_DEPENDENCIES = ../libgnomevfs/libgnomevfs-2.la +libbzip2_la_OBJECTS = bzip2-method.lo +libgzip_la_DEPENDENCIES = ../libgnomevfs/libgnomevfs-2.la +libgzip_la_OBJECTS = gzip-method.lo +libftp_la_DEPENDENCIES = ../libgnomevfs/libgnomevfs-2.la +libftp_la_OBJECTS = ftp-method.lo +libvfs_pipe_la_DEPENDENCIES = ../libgnomevfs/libgnomevfs-2.la +libvfs_pipe_la_OBJECTS = pipe-method.lo +libvfs_translate_la_DEPENDENCIES = ../libgnomevfs/libgnomevfs-2.la +libvfs_translate_la_OBJECTS = translate-method.lo +libcdemenu_desktop_la_DEPENDENCIES = ../libgnomevfs/libgnomevfs-2.la +libcdemenu_desktop_la_OBJECTS = cdemenu-desktop-method.lo +libssh_la_DEPENDENCIES = ../libgnomevfs/libgnomevfs-2.la +libssh_la_OBJECTS = ssh-method.lo +libtar_la_DEPENDENCIES = ../libgnomevfs/libgnomevfs-2.la +libtar_la_OBJECTS = tar-method.lo +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +DATA = $(modulesconf_DATA) + +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +SOURCES = $(libcdda_la_SOURCES) $(libextfs_la_SOURCES) $(libfile_la_SOURCES) $(libnntp_la_SOURCES) $(libvfs_test_la_SOURCES) $(libhttp_la_SOURCES) $(libbzip2_la_SOURCES) $(libgzip_la_SOURCES) $(libftp_la_SOURCES) $(libvfs_pipe_la_SOURCES) $(libvfs_translate_la_SOURCES) $(libcdemenu_desktop_la_SOURCES) $(libssh_la_SOURCES) $(libtar_la_SOURCES) +OBJECTS = $(libcdda_la_OBJECTS) $(libextfs_la_OBJECTS) $(libfile_la_OBJECTS) $(libnntp_la_OBJECTS) $(libvfs_test_la_OBJECTS) $(libhttp_la_OBJECTS) $(libbzip2_la_OBJECTS) $(libgzip_la_OBJECTS) $(libftp_la_OBJECTS) $(libvfs_pipe_la_OBJECTS) $(libvfs_translate_la_OBJECTS) $(libcdemenu_desktop_la_OBJECTS) $(libssh_la_OBJECTS) $(libtar_la_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .lo .o .obj .s +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps modules/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-modulesLTLIBRARIES: + +clean-modulesLTLIBRARIES: + -test -z "$(modules_LTLIBRARIES)" || rm -f $(modules_LTLIBRARIES) + +distclean-modulesLTLIBRARIES: + +maintainer-clean-modulesLTLIBRARIES: + +install-modulesLTLIBRARIES: $(modules_LTLIBRARIES) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(modulesdir) + @list='$(modules_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(modulesdir)/$$p"; \ + $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(modulesdir)/$$p; \ + else :; fi; \ + done + +uninstall-modulesLTLIBRARIES: + @$(NORMAL_UNINSTALL) + list='$(modules_LTLIBRARIES)'; for p in $$list; do \ + $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(modulesdir)/$$p; \ + done + +.c.o: + $(COMPILE) -c $< + +# FIXME: We should only use cygpath when building on Windows, +# and only if it is available. +.c.obj: + $(COMPILE) -c `cygpath -w $<` + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + -rm -f *.$(OBJEXT) + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +.c.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.s.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.S.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + +maintainer-clean-libtool: + +libcdda.la: $(libcdda_la_OBJECTS) $(libcdda_la_DEPENDENCIES) + $(LINK) -rpath $(modulesdir) $(libcdda_la_LDFLAGS) $(libcdda_la_OBJECTS) $(libcdda_la_LIBADD) $(LIBS) + +libextfs.la: $(libextfs_la_OBJECTS) $(libextfs_la_DEPENDENCIES) + $(LINK) -rpath $(modulesdir) $(libextfs_la_LDFLAGS) $(libextfs_la_OBJECTS) $(libextfs_la_LIBADD) $(LIBS) + +libfile.la: $(libfile_la_OBJECTS) $(libfile_la_DEPENDENCIES) + $(LINK) -rpath $(modulesdir) $(libfile_la_LDFLAGS) $(libfile_la_OBJECTS) $(libfile_la_LIBADD) $(LIBS) + +libnntp.la: $(libnntp_la_OBJECTS) $(libnntp_la_DEPENDENCIES) + $(LINK) -rpath $(modulesdir) $(libnntp_la_LDFLAGS) $(libnntp_la_OBJECTS) $(libnntp_la_LIBADD) $(LIBS) + +libvfs-test.la: $(libvfs_test_la_OBJECTS) $(libvfs_test_la_DEPENDENCIES) + $(LINK) -rpath $(modulesdir) $(libvfs_test_la_LDFLAGS) $(libvfs_test_la_OBJECTS) $(libvfs_test_la_LIBADD) $(LIBS) + +libhttp.la: $(libhttp_la_OBJECTS) $(libhttp_la_DEPENDENCIES) + $(LINK) -rpath $(modulesdir) $(libhttp_la_LDFLAGS) $(libhttp_la_OBJECTS) $(libhttp_la_LIBADD) $(LIBS) + +libbzip2.la: $(libbzip2_la_OBJECTS) $(libbzip2_la_DEPENDENCIES) + $(LINK) -rpath $(modulesdir) $(libbzip2_la_LDFLAGS) $(libbzip2_la_OBJECTS) $(libbzip2_la_LIBADD) $(LIBS) + +libgzip.la: $(libgzip_la_OBJECTS) $(libgzip_la_DEPENDENCIES) + $(LINK) -rpath $(modulesdir) $(libgzip_la_LDFLAGS) $(libgzip_la_OBJECTS) $(libgzip_la_LIBADD) $(LIBS) + +libftp.la: $(libftp_la_OBJECTS) $(libftp_la_DEPENDENCIES) + $(LINK) -rpath $(modulesdir) $(libftp_la_LDFLAGS) $(libftp_la_OBJECTS) $(libftp_la_LIBADD) $(LIBS) + +libvfs-pipe.la: $(libvfs_pipe_la_OBJECTS) $(libvfs_pipe_la_DEPENDENCIES) + $(LINK) -rpath $(modulesdir) $(libvfs_pipe_la_LDFLAGS) $(libvfs_pipe_la_OBJECTS) $(libvfs_pipe_la_LIBADD) $(LIBS) + +libvfs-translate.la: $(libvfs_translate_la_OBJECTS) $(libvfs_translate_la_DEPENDENCIES) + $(LINK) -rpath $(modulesdir) $(libvfs_translate_la_LDFLAGS) $(libvfs_translate_la_OBJECTS) $(libvfs_translate_la_LIBADD) $(LIBS) + +libcdemenu-desktop.la: $(libcdemenu_desktop_la_OBJECTS) $(libcdemenu_desktop_la_DEPENDENCIES) + $(LINK) -rpath $(modulesdir) $(libcdemenu_desktop_la_LDFLAGS) $(libcdemenu_desktop_la_OBJECTS) $(libcdemenu_desktop_la_LIBADD) $(LIBS) + +libssh.la: $(libssh_la_OBJECTS) $(libssh_la_DEPENDENCIES) + $(LINK) -rpath $(modulesdir) $(libssh_la_LDFLAGS) $(libssh_la_OBJECTS) $(libssh_la_LIBADD) $(LIBS) + +libtar.la: $(libtar_la_OBJECTS) $(libtar_la_DEPENDENCIES) + $(LINK) -rpath $(modulesdir) $(libtar_la_LDFLAGS) $(libtar_la_OBJECTS) $(libtar_la_LIBADD) $(LIBS) + +install-modulesconfDATA: $(modulesconf_DATA) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(modulesconfdir) + @list='$(modulesconf_DATA)'; for p in $$list; do \ + if test -f $(srcdir)/$$p; then \ + echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(modulesconfdir)/$$p"; \ + $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(modulesconfdir)/$$p; \ + else if test -f $$p; then \ + echo " $(INSTALL_DATA) $$p $(DESTDIR)$(modulesconfdir)/$$p"; \ + $(INSTALL_DATA) $$p $(DESTDIR)$(modulesconfdir)/$$p; \ + fi; fi; \ + done + +uninstall-modulesconfDATA: + @$(NORMAL_UNINSTALL) + list='$(modulesconf_DATA)'; for p in $$list; do \ + rm -f $(DESTDIR)$(modulesconfdir)/$$p; \ + done + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. + +@SET_MAKE@ + +all-recursive install-data-recursive install-exec-recursive \ +installdirs-recursive install-recursive uninstall-recursive \ +check-recursive installcheck-recursive info-recursive dvi-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ + rev="$$subdir $$rev"; \ + test "$$subdir" != "." || dot_seen=yes; \ + done; \ + test "$$dot_seen" = "no" && rev=". $$rev"; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = modules + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + for subdir in $(SUBDIRS); do \ + if test "$$subdir" = .; then :; else \ + test -d $(distdir)/$$subdir \ + || mkdir $(distdir)/$$subdir \ + || exit 1; \ + chmod 777 $(distdir)/$$subdir; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(top_distdir) distdir=../$(distdir)/$$subdir distdir) \ + || exit 1; \ + fi; \ + done +bzip2-method.lo bzip2-method.o : bzip2-method.c ../config.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h ../libgnomevfs/gnome-vfs-mime.h \ + ../libgnomevfs/gnome-vfs-module.h \ + ../libgnomevfs/gnome-vfs-method.h \ + ../libgnomevfs/gnome-vfs-find-directory.h \ + ../libgnomevfs/gnome-vfs-transform.h \ + ../libgnomevfs/gnome-vfs-monitor.h \ + ../libgnomevfs/gnome-vfs-ops.h +console-method.lo console-method.o : console-method.c ../config.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-i18n.h \ + ../libgnomevfs/gnome-vfs-method.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-find-directory.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-transform.h \ + ../libgnomevfs/gnome-vfs-monitor.h \ + ../libgnomevfs/gnome-vfs-module-shared.h \ + ../libgnomevfs/gnome-vfs-module.h \ + ../libgnomevfs/gnome-vfs-utils.h +desktop-method.lo desktop-method.o : desktop-method.c ../config.h \ + ../libgnomevfs/gnome-vfs-mime.h ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-module.h \ + ../libgnomevfs/gnome-vfs-method.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-find-directory.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-transform.h \ + ../libgnomevfs/gnome-vfs-monitor.h \ + ../libgnomevfs/gnome-vfs-utils.h ../libgnomevfs/gnome-vfs-ops.h \ + ../libgnomevfs/gnome-vfs-module-shared.h \ + ../libgnomevfs/gnome-vfs-monitor-private.h +extfs-method.lo extfs-method.o : extfs-method.c ../config.h \ + ../libgnomevfs/gnome-vfs-cancellable-ops.h \ + ../libgnomevfs/gnome-vfs-directory.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-find-directory.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-xfer.h ../libgnomevfs/gnome-vfs-mime.h \ + ../libgnomevfs/gnome-vfs-module-shared.h \ + ../libgnomevfs/gnome-vfs-module.h \ + ../libgnomevfs/gnome-vfs-method.h \ + ../libgnomevfs/gnome-vfs-transform.h \ + ../libgnomevfs/gnome-vfs-monitor.h \ + ../libgnomevfs/gnome-vfs-ops.h \ + ../libgnomevfs/gnome-vfs-parse-ls.h \ + ../libgnomevfs/gnome-vfs-private-utils.h \ + ../libgnomevfs/gnome-vfs-process.h +file-method.lo file-method.o : file-method.c ../config.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-i18n.h \ + ../libgnomevfs/gnome-vfs-method.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-find-directory.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-transform.h \ + ../libgnomevfs/gnome-vfs-monitor.h \ + ../libgnomevfs/gnome-vfs-mime.h \ + ../libgnomevfs/gnome-vfs-module-shared.h \ + ../libgnomevfs/gnome-vfs-module.h \ + ../libgnomevfs/gnome-vfs-utils.h \ + ../libgnomevfs/gnome-vfs-monitor-private.h +fstype.lo fstype.o : fstype.c ../config.h +ftp-method.lo ftp-method.o : ftp-method.c ../config.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-inet-connection.h \ + ../libgnomevfs/gnome-vfs-socket.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-socket-buffer.h \ + ../libgnomevfs/gnome-vfs-method.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-find-directory.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-transform.h \ + ../libgnomevfs/gnome-vfs-monitor.h \ + ../libgnomevfs/gnome-vfs-mime.h \ + ../libgnomevfs/gnome-vfs-mime-utils.h \ + ../libgnomevfs/gnome-vfs-module.h \ + ../libgnomevfs/gnome-vfs-module-shared.h \ + ../libgnomevfs/gnome-vfs-parse-ls.h \ + ../libgnomevfs/gnome-vfs-utils.h +gzip-method.lo gzip-method.o : gzip-method.c ../config.h \ + ../libgnomevfs/gnome-vfs-mime.h ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-module.h \ + ../libgnomevfs/gnome-vfs-method.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-find-directory.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-transform.h \ + ../libgnomevfs/gnome-vfs-monitor.h \ + ../libgnomevfs/gnome-vfs-ops.h +http-authn.lo http-authn.o : http-authn.c ../config.h http-authn.h \ + ../libgnomevfs/gnome-vfs-uri.h http-method.h \ + ../libgnomevfs/gnome-vfs-method.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-find-directory.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-transform.h \ + ../libgnomevfs/gnome-vfs-monitor.h \ + ../libgnomevfs/gnome-vfs-utils.h +http-cache.lo http-cache.o : http-cache.c ../config.h http-cache.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h http-method.h \ + ../libgnomevfs/gnome-vfs-method.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-find-directory.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-transform.h \ + ../libgnomevfs/gnome-vfs-monitor.h \ + ../libgnomevfs/gnome-vfs-utils.h +http-method.lo http-method.o : http-method.c ../config.h http-method.h \ + http-authn.h ../libgnomevfs/gnome-vfs-uri.h http-cache.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-inet-connection.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-socket.h \ + ../libgnomevfs/gnome-vfs-socket-buffer.h \ + ../libgnomevfs/gnome-vfs-mime-sniff-buffer.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-mime.h \ + ../libgnomevfs/gnome-vfs-module-callback-module-api.h \ + ../libgnomevfs/gnome-vfs-module.h \ + ../libgnomevfs/gnome-vfs-method.h \ + ../libgnomevfs/gnome-vfs-find-directory.h \ + ../libgnomevfs/gnome-vfs-transform.h \ + ../libgnomevfs/gnome-vfs-monitor.h \ + ../libgnomevfs/gnome-vfs-private-utils.h \ + ../libgnomevfs/gnome-vfs-process.h \ + ../libgnomevfs/gnome-vfs-ssl.h \ + ../libgnomevfs/gnome-vfs-standard-callbacks.h +nntp-method.lo nntp-method.o : nntp-method.c ../config.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-socket-buffer.h \ + ../libgnomevfs/gnome-vfs-socket.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-inet-connection.h \ + ../libgnomevfs/gnome-vfs-method.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-find-directory.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-transform.h \ + ../libgnomevfs/gnome-vfs-monitor.h \ + ../libgnomevfs/gnome-vfs-module.h \ + ../libgnomevfs/gnome-vfs-module-shared.h \ + ../libgnomevfs/gnome-vfs-module-callback-module-api.h \ + ../libgnomevfs/gnome-vfs-standard-callbacks.h \ + ../libgnomevfs/gnome-vfs-mime.h \ + ../libgnomevfs/gnome-vfs-parse-ls.h \ + ../libgnomevfs/gnome-vfs-utils.h nntp-method.h +pipe-method.lo pipe-method.o : pipe-method.c ../config.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-method.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-find-directory.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-transform.h \ + ../libgnomevfs/gnome-vfs-monitor.h \ + ../libgnomevfs/gnome-vfs-mime.h \ + ../libgnomevfs/gnome-vfs-mime-utils.h \ + ../libgnomevfs/gnome-vfs-module-shared.h \ + ../libgnomevfs/gnome-vfs-module.h \ + ../libgnomevfs/gnome-vfs-utils.h +ssh-method.lo ssh-method.o : ssh-method.c ../config.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-mime.h ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-module-shared.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-module.h \ + ../libgnomevfs/gnome-vfs-method.h \ + ../libgnomevfs/gnome-vfs-find-directory.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-transform.h \ + ../libgnomevfs/gnome-vfs-monitor.h \ + ../libgnomevfs/gnome-vfs-parse-ls.h \ + ../libgnomevfs/gnome-vfs-utils.h +tar-method.lo tar-method.o : tar-method.c \ + ../libgnomevfs/gnome-vfs-method.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-find-directory.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-transform.h \ + ../libgnomevfs/gnome-vfs-monitor.h \ + ../libgnomevfs/gnome-vfs-mime.h \ + ../libgnomevfs/gnome-vfs-mime-utils.h \ + ../libgnomevfs/gnome-vfs-module.h ../libgnomevfs/gnome-vfs.h \ + ../libgnomevfs/gnome-vfs-async-ops.h \ + ../libgnomevfs/gnome-vfs-xfer.h \ + ../libgnomevfs/gnome-vfs-directory.h \ + ../libgnomevfs/gnome-vfs-init.h \ + ../libgnomevfs/gnome-vfs-module-callback.h \ + ../libgnomevfs/gnome-vfs-ops.h ../libgnomevfs/gnome-vfs-utils.h \ + tarpet.h +test-method.lo test-method.o : test-method.c ../config.h \ + ../libgnomevfs/gnome-vfs-cancellable-ops.h \ + ../libgnomevfs/gnome-vfs-directory.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-find-directory.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-xfer.h ../libgnomevfs/gnome-vfs-ops.h \ + ../libgnomevfs/gnome-vfs-monitor.h \ + ../libgnomevfs/gnome-vfs-i18n.h \ + ../libgnomevfs/gnome-vfs-module.h \ + ../libgnomevfs/gnome-vfs-method.h \ + ../libgnomevfs/gnome-vfs-transform.h +translate-method.lo translate-method.o : translate-method.c ../config.h \ + ../libgnomevfs/gnome-vfs-method.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-find-directory.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-transform.h \ + ../libgnomevfs/gnome-vfs-monitor.h \ + ../libgnomevfs/gnome-vfs-mime.h \ + ../libgnomevfs/gnome-vfs-mime-utils.h \ + ../libgnomevfs/gnome-vfs-module.h \ + ../libgnomevfs/gnome-vfs-private-utils.h \ + ../libgnomevfs/gnome-vfs-process.h +vfolder-desktop-method.lo vfolder-desktop-method.o : \ + vfolder-desktop-method.c ../config.h \ + ../libgnomevfs/gnome-vfs-mime.h ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-module.h \ + ../libgnomevfs/gnome-vfs-method.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-find-directory.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-transform.h \ + ../libgnomevfs/gnome-vfs-monitor.h \ + ../libgnomevfs/gnome-vfs-utils.h ../libgnomevfs/gnome-vfs-ops.h \ + ../libgnomevfs/gnome-vfs-module-shared.h \ + ../libgnomevfs/gnome-vfs-monitor-private.h + +info-am: +info: info-recursive +dvi-am: +dvi: dvi-recursive +check-am: all-am +check: check-recursive +installcheck-am: +installcheck: installcheck-recursive +install-exec-am: +install-exec: install-exec-recursive + +install-data-am: install-modulesLTLIBRARIES install-modulesconfDATA +install-data: install-data-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-recursive +uninstall-am: uninstall-modulesLTLIBRARIES uninstall-modulesconfDATA +uninstall: uninstall-recursive +all-am: Makefile $(LTLIBRARIES) $(DATA) +all-redirect: all-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: installdirs-recursive +installdirs-am: + $(mkinstalldirs) $(DESTDIR)$(modulesdir) $(DESTDIR)$(modulesconfdir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-modulesLTLIBRARIES mostlyclean-compile \ + mostlyclean-libtool mostlyclean-tags \ + mostlyclean-generic + +mostlyclean: mostlyclean-recursive + +clean-am: clean-modulesLTLIBRARIES clean-compile clean-libtool \ + clean-tags clean-generic mostlyclean-am + +clean: clean-recursive + +distclean-am: distclean-modulesLTLIBRARIES distclean-compile \ + distclean-libtool distclean-tags distclean-generic \ + clean-am + -rm -f libtool + +distclean: distclean-recursive + +maintainer-clean-am: maintainer-clean-modulesLTLIBRARIES \ + maintainer-clean-compile maintainer-clean-libtool \ + maintainer-clean-tags maintainer-clean-generic \ + distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-recursive + +.PHONY: mostlyclean-modulesLTLIBRARIES distclean-modulesLTLIBRARIES \ +clean-modulesLTLIBRARIES maintainer-clean-modulesLTLIBRARIES \ +uninstall-modulesLTLIBRARIES install-modulesLTLIBRARIES \ +mostlyclean-compile distclean-compile clean-compile \ +maintainer-clean-compile mostlyclean-libtool distclean-libtool \ +clean-libtool maintainer-clean-libtool uninstall-modulesconfDATA \ +install-modulesconfDATA install-data-recursive uninstall-data-recursive \ +install-exec-recursive uninstall-exec-recursive installdirs-recursive \ +uninstalldirs-recursive all-recursive check-recursive \ +installcheck-recursive info-recursive dvi-recursive \ +mostlyclean-recursive distclean-recursive clean-recursive \ +maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir info-am info \ +dvi-am dvi check check-am installcheck-am installcheck install-exec-am \ +install-exec install-data-am install-data install-am install \ +uninstall-am uninstall all-redirect all-am all installdirs-am \ +installdirs mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +#if HAVE_LIBEFS +#vefsmoduledir = $(modulesdir) +#vefsmodule_LTLIBRARIES = libvefs.la +# +#libvefs_la_SOURCES = \ +# efs-method.c +#libvefs_la_LIBADD = $(LIBEFS_LIBS) $(MODULES_LIBS) +#endif + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/modules/bzip2-method.c b/modules/bzip2-method.c new file mode 100644 index 0000000..3b56d9b --- /dev/null +++ b/modules/bzip2-method.c @@ -0,0 +1,573 @@ +/* + * bzip2-method.c - Bzip2 access method for the GNOME Virtual File + * System. + * + * Copyright (C) 1999 Free Software Foundation + * + * The Gnome Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Gnome Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite + * 330, Boston, MA 02111-1307, USA. + * + * Author: Cody Russell + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#ifdef HAVE_OLDER_BZIP2 +#define BZ2_bzDecompressInit bzDecompressInit +#define BZ2_bzCompressInit bzCompressInit +#define BZ2_bzDecompress bzDecompress +#define BZ2_bzCompress bzCompress +#endif + +#define BZ_BUFSIZE 5000 + +struct _Bzip2MethodHandle { + GnomeVFSURI *uri; + GnomeVFSHandle *parent_handle; + GnomeVFSOpenMode open_mode; + + BZFILE *file; + GnomeVFSResult last_vfs_result; + gint last_bz_result; + bz_stream bzstream; + guchar *buffer; +}; + +typedef struct _Bzip2MethodHandle Bzip2MethodHandle; + +static GnomeVFSResult do_open (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + GnomeVFSContext *context); + +static GnomeVFSResult do_create (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + gboolean exclusive, + guint perm, + GnomeVFSContext *context); + +static GnomeVFSResult do_close (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context); + +static GnomeVFSResult do_read (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read, + GnomeVFSContext *context); + +static GnomeVFSResult do_write (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gconstpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_written, + GnomeVFSContext *context); + +static GnomeVFSResult do_get_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context); + +static gboolean do_is_local (GnomeVFSMethod *method, const GnomeVFSURI *uri); + +static GnomeVFSMethod method = { + sizeof (GnomeVFSMethod), + do_open, + do_create, + do_close, + do_read, + do_write, + NULL, /* seek */ + NULL, /* tell */ + NULL, /* truncate_handle */ + NULL, /* open_directory */ + NULL, /* close_directory */ + NULL, /* read_directory */ + do_get_file_info, + NULL, /* get_file_info_from_handle */ + do_is_local, + NULL, /* make_directory */ + NULL, /* remove_directory */ + NULL, /* move */ + NULL, /* unlink */ + NULL, /* set_file_info */ + NULL, /* truncate */ + NULL, /* find_directory */ + NULL /* create_symbolic_link */ +}; + +#define RETURN_IF_FAIL(action) \ +G_STMT_START { \ + GnomeVFSResult __tmp_result; \ + \ + __tmp_result = (action); \ + if (__tmp_result != GNOME_VFS_OK) \ + return __tmp_result; \ +} G_STMT_END + +#define VALID_URI(u) ((u)->parent!=NULL&&(((u)->text==NULL)||((u)->text[0]=='\0')||(((u)->text[0]=='/')&&((u)->text[1]=='\0')))) + +static Bzip2MethodHandle * +bzip2_method_handle_new (GnomeVFSHandle *parent_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode open_mode) +{ + Bzip2MethodHandle *new; + + new = g_new (Bzip2MethodHandle, 1); + + new->parent_handle = parent_handle; + new->uri = gnome_vfs_uri_ref (uri); + new->open_mode = open_mode; + + new->buffer = NULL; + + return new; +} + +static void +bzip2_method_handle_destroy (Bzip2MethodHandle *handle) +{ + gnome_vfs_uri_unref (handle->uri); + g_free (handle->buffer); + g_free (handle); +} + +static gboolean +bzip2_method_handle_init_for_decompress (Bzip2MethodHandle *handle) +{ + handle->bzstream.bzalloc = NULL; + handle->bzstream.bzfree = NULL; + handle->bzstream.opaque = NULL; + + g_free (handle->buffer); + + handle->buffer = g_malloc (BZ_BUFSIZE); + handle->bzstream.next_in = handle->buffer; + handle->bzstream.avail_in = 0; + + /* FIXME bugzilla.eazel.com 1177: Make small, and possibly verbosity, configurable! */ + if (BZ2_bzDecompressInit (&handle->bzstream, 0, 0) != BZ_OK) { + g_free (handle->buffer); + return FALSE; + } + + handle->last_bz_result = BZ_OK; + handle->last_vfs_result = GNOME_VFS_OK; + + return TRUE; +} + +static gboolean +bzip2_method_handle_init_for_compress (Bzip2MethodHandle *handle) G_GNUC_UNUSED; + +static gboolean +bzip2_method_handle_init_for_compress (Bzip2MethodHandle *handle) +{ + handle->bzstream.bzalloc = NULL; + handle->bzstream.bzfree = NULL; + handle->bzstream.opaque = NULL; + + g_free (handle->buffer); + + handle->buffer = g_malloc (BZ_BUFSIZE); + handle->bzstream.next_out = handle->buffer; + handle->bzstream.avail_out = BZ_BUFSIZE; + + /* FIXME bugzilla.eazel.com 1174: We want this to be user configurable. */ + if (BZ2_bzCompressInit (&handle->bzstream, 3, 0, 30) != BZ_OK) { + g_free (handle->buffer); + return FALSE; + } + + handle->last_bz_result = BZ_OK; + handle->last_vfs_result = GNOME_VFS_OK; + + return TRUE; +} + +static GnomeVFSResult +result_from_bz_result (gint bz_result) +{ + switch (bz_result) { + case BZ_OK: + case BZ_STREAM_END: + return GNOME_VFS_OK; + + case BZ_MEM_ERROR: + return GNOME_VFS_ERROR_NO_MEMORY; + + case BZ_PARAM_ERROR: + return GNOME_VFS_ERROR_BAD_PARAMETERS; + + case BZ_DATA_ERROR: + return GNOME_VFS_ERROR_CORRUPTED_DATA; + + case BZ_UNEXPECTED_EOF: + return GNOME_VFS_ERROR_EOF; + + case BZ_SEQUENCE_ERROR: + return GNOME_VFS_ERROR_NOT_PERMITTED; + + default: + return GNOME_VFS_ERROR_INTERNAL; + } +} + +static GnomeVFSResult +flush_write (Bzip2MethodHandle *bzip2_handle) +{ + GnomeVFSHandle *parent_handle; + GnomeVFSResult result; + gboolean done; + bz_stream *bzstream; + gint bz_result; + + bzstream = &bzip2_handle->bzstream; + bzstream->avail_in = 0; + parent_handle = bzip2_handle->parent_handle; + + done = FALSE; + bz_result = BZ_OK; + while (bz_result == BZ_OK || bz_result == BZ_STREAM_END) { + GnomeVFSFileSize bytes_written; + GnomeVFSFileSize len; + + len = BZ_BUFSIZE - bzstream->avail_out; + + result = gnome_vfs_write (parent_handle, bzip2_handle->buffer, + len, &bytes_written); + RETURN_IF_FAIL (result); + + bzstream->next_out = bzip2_handle->buffer; + bzstream->avail_out = BZ_BUFSIZE; + + if (done) + break; + + bz_result = BZ2_bzCompress (bzstream, BZ_FINISH); + + done = (bzstream->avail_out != 0 || bz_result == BZ_STREAM_END); + } + + if (bz_result == BZ_OK || bz_result == BZ_STREAM_END) + return GNOME_VFS_OK; + else + return result_from_bz_result (bz_result); +} + +/* Open */ +/* TODO: Check that there is no subpath. */ + +static GnomeVFSResult +do_open (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode open_mode, + GnomeVFSContext *context) +{ + GnomeVFSHandle *parent_handle; + GnomeVFSURI *parent_uri; + GnomeVFSResult result; + Bzip2MethodHandle *bzip2_handle; + + _GNOME_VFS_METHOD_PARAM_CHECK (method_handle != NULL); + _GNOME_VFS_METHOD_PARAM_CHECK (uri != NULL); + + /* Check that the URI is valid. */ + if (!VALID_URI(uri)) return GNOME_VFS_ERROR_INVALID_URI; + + if (open_mode & GNOME_VFS_OPEN_WRITE) + return GNOME_VFS_ERROR_INVALID_OPEN_MODE; + + parent_uri = uri->parent; + + if (open_mode & GNOME_VFS_OPEN_RANDOM) + return GNOME_VFS_ERROR_NOT_SUPPORTED; + + result = gnome_vfs_open_uri (&parent_handle, parent_uri, open_mode); + RETURN_IF_FAIL (result); + + bzip2_handle = bzip2_method_handle_new (parent_handle, uri, open_mode); + + if (result != GNOME_VFS_OK) { + gnome_vfs_close (parent_handle); + bzip2_method_handle_destroy (bzip2_handle); + return result; + } + + if (!bzip2_method_handle_init_for_decompress (bzip2_handle)) { + gnome_vfs_close (parent_handle); + bzip2_method_handle_destroy (bzip2_handle); + return GNOME_VFS_ERROR_INTERNAL; + } + + *method_handle = (GnomeVFSMethodHandle *) bzip2_handle; + + return GNOME_VFS_OK; +} + +/* Create */ + +static GnomeVFSResult +do_create (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + gboolean exclusive, + guint perm, + GnomeVFSContext *context) +{ + _GNOME_VFS_METHOD_PARAM_CHECK (method_handle != NULL); + _GNOME_VFS_METHOD_PARAM_CHECK (uri != NULL); + + return GNOME_VFS_ERROR_NOT_SUPPORTED; +} + +/* Close */ + +static GnomeVFSResult +do_close (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + Bzip2MethodHandle *bzip2_handle; + GnomeVFSResult result; + + _GNOME_VFS_METHOD_PARAM_CHECK (method_handle != NULL); + + bzip2_handle = (Bzip2MethodHandle *) method_handle; + + if (bzip2_handle->open_mode & GNOME_VFS_OPEN_WRITE) + result = flush_write (bzip2_handle); + else + result = GNOME_VFS_OK; + + if (result == GNOME_VFS_OK) + result = gnome_vfs_close (bzip2_handle->parent_handle); + + bzip2_method_handle_destroy (bzip2_handle); + + return result; +} + +/* Read */ + +static GnomeVFSResult +fill_buffer (Bzip2MethodHandle *bzip2_handle, + GnomeVFSFileSize num_bytes) +{ + GnomeVFSResult result; + GnomeVFSFileSize count; + bz_stream *bzstream; + + bzstream = &bzip2_handle->bzstream; + + if (bzstream->avail_in > 0) + return GNOME_VFS_OK; + + result = gnome_vfs_read (bzip2_handle->parent_handle, + bzip2_handle->buffer, + BZ_BUFSIZE, + &count); + + if (result != GNOME_VFS_OK) { + if (bzstream->avail_out == num_bytes) + return result; + bzip2_handle->last_vfs_result = result; + } else { + bzstream->next_in = bzip2_handle->buffer; + bzstream->avail_in = count; + } + + return GNOME_VFS_OK; +} + +/* TODO: Concatenated Bzip2 file handling. */ + +static GnomeVFSResult +do_read (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read, + GnomeVFSContext *context) +{ + Bzip2MethodHandle *bzip2_handle; + GnomeVFSResult result; + bz_stream *bzstream; + int bz_result; + + *bytes_read = 0; + + bzip2_handle = (Bzip2MethodHandle *) method_handle; + bzstream = &bzip2_handle->bzstream; + + if (bzip2_handle->last_bz_result != BZ_OK) { + if (bzip2_handle->last_bz_result == BZ_STREAM_END) + return GNOME_VFS_OK; + else + return result_from_bz_result (bzip2_handle->last_bz_result); + } else if (bzip2_handle->last_vfs_result != GNOME_VFS_OK) { + return bzip2_handle->last_vfs_result; + } + + bzstream->next_out = buffer; + bzstream->avail_out = num_bytes; + + while (bzstream->avail_out != 0) { + result = fill_buffer (bzip2_handle, num_bytes); + RETURN_IF_FAIL (result); + + bz_result = BZ2_bzDecompress (&bzip2_handle->bzstream); + + if (bzip2_handle->last_bz_result != BZ_OK + && bzstream->avail_out == num_bytes) { + bzip2_handle->last_bz_result = bz_result; + return result_from_bz_result (bzip2_handle->last_bz_result); + } + + *bytes_read = num_bytes - bzstream->avail_out; + + if (bz_result == BZ_STREAM_END) { + bzip2_handle->last_bz_result = bz_result; + break; + } + + } + + return GNOME_VFS_OK; +} + +/* Write. */ + +static GnomeVFSResult +do_write (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gconstpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_written, + GnomeVFSContext *context) +{ + Bzip2MethodHandle *bzip2_handle; + GnomeVFSResult result; + bz_stream *bzstream; + gint bz_result; + + bzip2_handle = (Bzip2MethodHandle *) method_handle; + bzstream = &bzip2_handle->bzstream; + + bzstream->next_in = (gpointer) buffer; + bzstream->avail_in = num_bytes; + + result = GNOME_VFS_OK; + + while (bzstream->avail_in != 0 && result == GNOME_VFS_OK) { + if (bzstream->avail_out == 0) { + GnomeVFSFileSize written; + + bzstream->next_out = bzip2_handle->buffer; + result = gnome_vfs_write (bzip2_handle->parent_handle, + bzip2_handle->buffer, + BZ_BUFSIZE, &written); + if (result != GNOME_VFS_OK) + break; + + bzstream->avail_out += written; + } + + bz_result = BZ2_bzCompress (bzstream, BZ_RUN); + result = result_from_bz_result (bz_result); + } + + *bytes_written = num_bytes - bzstream->avail_in; + + return result; +} + +static gboolean +do_is_local (GnomeVFSMethod *method, const GnomeVFSURI *uri) +{ + g_return_val_if_fail (uri != NULL, FALSE); + return gnome_vfs_uri_is_local (uri->parent); +} + +static GnomeVFSResult +do_get_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + + /* Check that the URI is valid. */ + if (!VALID_URI(uri)) return GNOME_VFS_ERROR_INVALID_URI; + + result = gnome_vfs_get_file_info_uri(uri->parent, file_info, options); + + if(result == GNOME_VFS_OK) { + gint namelen = strlen(file_info->name); + + /* work out the name */ + /* FIXME bugzilla.eazel.com 2790: handle uppercase */ + if(namelen > 4 && + file_info->name[namelen-1] == '2' && + file_info->name[namelen-2] == 'z' && + file_info->name[namelen-3] == 'b' && + file_info->name[namelen-4] == '.') + file_info->name[namelen-4] = '\0'; + + /* we can't tell the size without uncompressing it */ + //file_info->valid_fields &= ~GNOME_VFS_FILE_INFO_FIELDS_SIZE; + + /* guess the mime type of the file inside */ + /* FIXME bugzilla.eazel.com 2791: guess mime based on contents */ + g_free(file_info->mime_type); + file_info->mime_type = g_strdup(gnome_vfs_mime_type_from_name(file_info->name)); + } + + return result; +} + +GnomeVFSMethod * +vfs_module_init (const char *method_name, const char *args) +{ + return &method; +} + +void +vfs_module_shutdown (GnomeVFSMethod *method) +{ + return; +} diff --git a/modules/cdda-cddb.c b/modules/cdda-cddb.c new file mode 100644 index 0000000..6fd66e7 --- /dev/null +++ b/modules/cdda-cddb.c @@ -0,0 +1,1012 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: 8; c-basic-offset: 8 -*- */ + +/* + + cdda-cddb.c + + Based on code from libcdaudio 0.5.0 (Copyright (C)1998 Tony Arcieri) + + All changes copyright (c) 1998 by Mike Oliphant - oliphant@ling.ed.ac.uk + + http://www.ling.ed.ac.uk/~oliphant/grip + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + +*/ + +#include "cdda-cddb.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define size16 short +#define size32 int +#include + +#include "cdda-cdrom-extensions.h" + +/* This is here to work around a broken header file. + * cdda_interface.h has a statically defined array of + * chars that is unused. This will break our build + * due to our strict error checking. + */ +char **broken_header_fix2 = strerror_tr; + +static int CDDBSum(int val); +static int CDDBConnect(CDDBServer *server); +static void CDDBDisconnect(int sock); +static void CDDBSkipHTTP(int sock); +static int CDDBReadLine(int sock,char *inbuffer,int len); +static void CDDBMakeHello(CDDBHello *hello,char *hellobuf); +static void CDDBMakeRequest(CDDBServer *server, CDDBHello *hello, char *cmd,char *outbuf,int outlen); +static void CDDBProcessLine(char *inbuffer,DiscData *data, int numtracks); +#if 0 +static void CDDBWriteLine(char *header,int num,char *data,FILE *outfile); +#endif + +static char *cddb_genres[] = {"unknown","blues","classical","country", + "data","folk","jazz","misc","newage", + "reggae","rock","soundtrack"}; + +#ifdef ENABLE_IPV6 +/*Check whether the node is IPv6 enabled.*/ +static gboolean +have_ipv6 (void) +{ + int s; + + s = socket (AF_INET6, SOCK_STREAM, 0); + if (s != -1) { + close (s); + return TRUE; + } + + return FALSE; +} +#endif + +/* CDDB sum function */ +static int +CDDBSum(int val) +{ + char *bufptr, buf[16]; + int ret = 0; + + g_snprintf(buf,16,"%lu",(unsigned long int)val); + + for(bufptr = buf; *bufptr != '\0'; bufptr++) { + ret += (*bufptr - '0'); + } + return ret; +} + +/* Produce CDDB ID for CD currently in CD-ROM */ +unsigned int +CDDBDiscid (cdrom_drive *drive) +{ + int index, tracksum = 0, discid, retval; + disc_info disc; + + retval = CDStat (drive->ioctl_fd, &disc, TRUE); + + for(index = 0; index < disc.disc_totaltracks; index++) { + tracksum += CDDBSum(disc.track[index].track_pos.minutes * 60 + + disc.track[index].track_pos.seconds); + } + + discid = (disc.disc_length.minutes * 60 + disc.disc_length.seconds) - + (disc.track[0].track_pos.minutes * 60 + disc.track[0].track_pos.seconds); + + return (tracksum % 0xFF) << 24 | discid << 8 | disc.disc_totaltracks; +} + +/* Convert numerical genre to text */ +char *CDDBGenre(int genre) +{ + if(genre>11) { + return("unknown"); + } + + return cddb_genres[genre]; +} + +/* Convert genre from text form into an integer value */ +int CDDBGenreValue(char *genre) +{ + int pos; + + for (pos = 0; pos < 12; pos++) { + if (!strcmp (genre,cddb_genres[pos])) { + return pos; + } + } + return 0; +} + +/* Connect to a CDDB server */ +static int +CDDBConnect (CDDBServer *server) +{ + int sock = -1; +#ifdef ENABLE_IPV6 + struct sockaddr_in6 sin6; + struct addrinfo hints, *result, *res; /*info abt the IP of node*/ +#endif + struct sockaddr_in sin; + struct hostent *host; + char *sname; + +#ifdef ENABLE_IPV6 + if (have_ipv6 ()) { + result = NULL; + + memset (&sin6, 0 , sizeof (sin6)); + sin6.sin6_family = AF_INET6; + + if (server->use_proxy) { + sin6.sin6_port = htons (server->proxy->port); + } else { + sin6.sin6_port = htons (server->port); + } + } +#endif + + memset (&sin, 0, sizeof (sin)); + sin.sin_family = AF_INET; + + if (server->use_proxy) + sin.sin_port=htons(server->proxy->port); + else + sin.sin_port = htons(server->port); + + if (server->use_proxy) + sname=server->proxy->name; + else + sname=server->name; + +#ifdef ENABLE_IPV6 + if (have_ipv6 ()) { + memset (&hints, 0, sizeof (hints)); + hints.ai_socktype = SOCK_STREAM; + + if ((getaddrinfo (sname, NULL, &hints, &result)) != 0) { + return -1; + } + + for (res = result; res; res = res->ai_next) { + + if (res->ai_family != AF_INET && res->ai_family != AF_INET6) { + continue; + } + + sock = socket (res->ai_family, SOCK_STREAM, 0); + if (sock < 0) { + continue; + } + + if (res->ai_family == AF_INET) { + memcpy (&sin.sin_addr, &((struct sockaddr_in *)res->ai_addr)->sin_addr, sizeof (struct in_addr)); + + if (connect (sock, (struct sockaddr *)&sin, sizeof (sin)) != -1) { + break; + } + } + + if (res->ai_family == AF_INET6) { + memcpy (&sin6.sin6_addr, &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, sizeof (struct in6_addr)); + + if (connect (sock, (struct sockaddr *)&sin6, sizeof (sin6)) != -1) { + break; + } + } + + close (sock); + } + + freeaddrinfo (result); + + if (!res) { + /* No valid address found. */ + return -1; + } + } else +#endif /*IPv4*/ + { + sin.sin_addr.s_addr = inet_addr (sname); +#ifdef SOLARIS + if (sin.sin_addr.s_addr == (unsigned long)-1) +#else + if (sin.sin_addr.s_addr == INADDR_NONE) +#endif + { + host = gethostbyname (sname); + if (host == NULL) { + return -1; + } + + bcopy (host->h_addr, &sin.sin_addr, host->h_length); + } + + sock = socket (AF_INET, SOCK_STREAM, 0); + if (sock < 0) { + return -1; + } + + if (connect (sock, (struct sockaddr *)&sin, sizeof (sin)) < 0) { + return -1; + } + + } + + return sock; +} + + +/* Disconnect from CDDB server */ + +static void CDDBDisconnect(int sock) +{ + shutdown(sock,2); + close(sock); +} + +/* Skip http header */ + +static void CDDBSkipHTTP(int sock) +{ + char inchar; + int len; + + do { + len=0; + do { + read(sock,&inchar,1); + len++; + //g_message ("%c",inchar); + } + while(inchar!='\n'); + } + while(len>2); +} + +/* Read a single line from the CDDB server*/ + +static int CDDBReadLine(int sock,char *inbuffer,int len) +{ + int index; + char inchar; + char *pos; + + pos=inbuffer; + + for(index = 0; index < len; index++) { + read(sock, &inchar, 1); + + if(inchar == '\n') { + inbuffer[index] = '\0'; + //g_message ("[%s]\n",pos); + pos=inbuffer+index; + + if(inbuffer[0] == '.') + return 1; + + return 0; + } + + inbuffer[index] = inchar; + } + + return index; +} + +/* Make a 'hello' string from a cddb_hello structure */ + +static void CDDBMakeHello(CDDBHello *hello,char *hellobuf) +{ + g_snprintf(hellobuf,256,"&hello=private+free.the.cddb+%s+%s", + hello->hello_program,hello->hello_version); +} + +/* Make a CDDB http request string */ + +static void CDDBMakeRequest(CDDBServer *server, + CDDBHello *hello, + char *cmd,char *outbuf,int outlen) +{ + char hellobuf[256]; + + CDDBMakeHello(hello,hellobuf); + + if(server->use_proxy) + g_snprintf(outbuf,outlen, + "GET http://%s/%s?cmd=%s%s&proto=%s HTTP/1.1\r\nHost: %s\r\nUser-Agent: %s/%s\r\nAccept: text/plain\n\n", + server->name,server->cgi_prog,cmd,hellobuf, + //CDDA_CDDB_LEVEL, server->name, Program, Version); + CDDA_CDDB_LEVEL, server->name, "Loser", "1.0"); + else + g_snprintf(outbuf,outlen,"GET /%s?cmd=%s%s&proto=%s HTTP/1.1\r\nHost: %s\r\nUser-Agent: %s/%s\r\nAccept: text/plain\n\n", + server->cgi_prog,cmd,hellobuf,CDDA_CDDB_LEVEL,server->name, + //Program,Version); + "Loser", "1.0"); +} + +/* Query the CDDB for the CD currently in the CD-ROM */ +gboolean +CDDBDoQuery (cdrom_drive *cd_desc, CDDBServer *server, CDDBHello *hello, CDDBQuery *query) +{ + int socket, index; + disc_info disc; + char *offset_buffer, *query_buffer, *http_buffer, inbuffer[256]; + int tot_len,len; + + socket = CDDBConnect (server); + if (socket==-1) { + //g_message ("CDDBConnect failure"); + return FALSE; + } + + query->query_matches = 0; + + CDStat (cd_desc->ioctl_fd, &disc, TRUE); + + // Figure out a good buffer size -- 7 chars per track, plus 256 for the rest of the query + tot_len = (disc.disc_totaltracks * 7) + 256; + + offset_buffer = malloc(tot_len); + len = 0; + + len += g_snprintf (offset_buffer + len, tot_len - len, "%d", disc.disc_totaltracks); + + for (index = 0; index < disc.disc_totaltracks; index++) { + len += g_snprintf (offset_buffer + len, tot_len - len, "+%d", disc.track[index].track_start); + } + + query_buffer = malloc(tot_len); + + g_snprintf (query_buffer, tot_len, "cddb+query+%08x+%s+%d", + CDDBDiscid(cd_desc), + offset_buffer, + disc.disc_length.minutes * 60 + + disc.disc_length.seconds); + + http_buffer = malloc(tot_len); + + CDDBMakeRequest (server, hello, query_buffer, http_buffer, tot_len); + + //g_message ("Query is [%s]\n",http_buffer); + + write (socket, http_buffer, strlen (http_buffer)); + + free (offset_buffer); + free (query_buffer); + free (http_buffer); + + CDDBSkipHTTP (socket); + + *inbuffer='\0'; + + CDDBReadLine(socket,inbuffer,256); + + /* Skip the keep-alive */ + if((strlen(inbuffer)<5)||!strncmp(inbuffer,"Keep",4)) { + //g_message("Skipping keepalive\n"); + CDDBReadLine (socket,inbuffer,256); + } + + //g_message ("Reply is [%s]\n",inbuffer); + + switch(strtol(strtok(inbuffer," "),NULL,10)) { + /* 200 - exact match */ + case 200: + query->query_match=MATCH_EXACT; + query->query_matches=1; + + query->query_list[0].list_genre= + CDDBGenreValue(ChopWhite(strtok(NULL," "))); + + sscanf(ChopWhite(strtok(NULL," ")),"%xd", + &query->query_list[0].list_id); + + CDDBParseTitle(ChopWhite(strtok(NULL,"")),query->query_list[0].list_title, + query->query_list[0].list_artist,"/"); + + break; + /* 211 - inexact match */ + case 211: + query->query_match=MATCH_INEXACT; + query->query_matches=0; + + while(!CDDBReadLine(socket,inbuffer,256)) { + query->query_list[query->query_matches].list_genre= + CDDBGenreValue(ChopWhite(strtok(inbuffer," "))); + + sscanf(ChopWhite(strtok(NULL," ")),"%xd", + &query->query_list[query->query_matches].list_id); + + CDDBParseTitle(ChopWhite(strtok(NULL,"")), + query->query_list[query->query_matches].list_title, + query->query_list[query->query_matches].list_artist,"/"); + + query->query_matches++; + } + + break; + + /* No match */ + default: + query->query_match=MATCH_NOMATCH; + + CDDBDisconnect(socket); + + return FALSE; + } + + CDDBDisconnect(socket); + + return TRUE; +} + +/* Get rid of whitespace at the beginning or end of a string */ + +char *ChopWhite(char *buf) +{ + int pos; + + for(pos=strlen(buf)-1;(pos>=0)&&g_ascii_isspace(buf[pos]);pos--); + + buf[pos+1]='\0'; + + for(;g_ascii_isspace(*buf);buf++); + + return buf; +} + +/* Split string into title/artist */ + +void CDDBParseTitle(char *buf,char *title,char *artist,char *sep) +{ + char *tmp; + + tmp=strtok(buf,sep); + + if(!tmp) return; + + strncpy(artist,ChopWhite(tmp),64); + + tmp=strtok(NULL,""); + + if(tmp) + strncpy(title,ChopWhite(tmp),64); + else strcpy(title,artist); +} + +/* Process a line of input data */ + +static void CDDBProcessLine(char *inbuffer,DiscData *data, + int numtracks) +{ + int track; + int len = 0; + char *st; + + if(!g_ascii_strncasecmp(inbuffer,"DTITLE",6)) { + len = strlen(data->data_title); + + strncpy(data->data_title+len,ChopWhite(inbuffer+7),256-len); + } + else if(!g_ascii_strncasecmp(inbuffer,"DYEAR",5)) { + strtok(inbuffer,"="); + + st = strtok(NULL, ""); + if(st == NULL) + return; + + data->data_year=atoi(ChopWhite(st)); + } + else if(!g_ascii_strncasecmp(inbuffer,"DGENRE",6)) { + strtok(inbuffer,"="); + + st = strtok(NULL, ""); + if(st == NULL) + return; + + data->data_genre=CDDBGenreValue(ChopWhite(st)); + } + else if(!g_ascii_strncasecmp(inbuffer,"TTITLE",6)) { + track=atoi(strtok(inbuffer+6,"=")); + + if(trackdata_track[track].track_name); + + strncpy(data->data_track[track].track_name+len, + ChopWhite(strtok(NULL,"")),256-len); + } + else if(!g_ascii_strncasecmp(inbuffer,"TARTIST",7)) { + data->data_multi_artist=TRUE; + + track=atoi(strtok(inbuffer+7,"=")); + + if(trackdata_track[track].track_artist); + + st = strtok(NULL, ""); + if(st == NULL) + return; + + strncpy(data->data_track[track].track_artist+len, + ChopWhite(st),256-len); + } + else if(!g_ascii_strncasecmp(inbuffer,"EXTD",4)) { + len=strlen(data->data_extended); + + strncpy(data->data_extended+len,ChopWhite(inbuffer+5),4096-len); + } + else if(!g_ascii_strncasecmp(inbuffer,"EXTT",4)) { + track=atoi(strtok(inbuffer+4,"=")); + + if(trackdata_track[track].track_extended); + + st = strtok(NULL, ""); + if(st == NULL) + return; + + strncpy(data->data_track[track].track_extended+len, + ChopWhite(st),4096-len); + } + else if(!g_ascii_strncasecmp(inbuffer,"PLAYORDER",5)) { + len=strlen(data->data_playlist); + + strncpy(data->data_playlist+len,ChopWhite(inbuffer+10),256-len); + } +} + + +/* Read the actual CDDB entry */ +gboolean CDDBRead(cdrom_drive *cd_desc, CDDBServer *server, + CDDBHello *hello,CDDBEntry *entry, + DiscData *data) +{ + int socket; + int index; + char outbuffer[256], inbuffer[512],cmdbuffer[256]; + disc_info disc; + + socket=CDDBConnect(server); + if(socket==-1) return FALSE; + + //CDStat(cd_desc,&disc,TRUE); + + data->data_genre=entry->entry_genre; + data->data_id=CDDBDiscid(cd_desc); + *(data->data_extended)='\0'; + *(data->data_title)='\0'; + *(data->data_artist)='\0'; + *(data->data_playlist)='\0'; + data->data_multi_artist=FALSE; + data->data_year=0; + + for(index=0;indexdata_track[index].track_name)='\0'; + *(data->data_track[index].track_artist)='\0'; + *(data->data_track[index].track_extended)='\0'; + } + + g_snprintf(cmdbuffer,256,"cddb+read+%s+%08x",CDDBGenre(entry->entry_genre), + entry->entry_id); + + CDDBMakeRequest(server,hello,cmdbuffer,outbuffer,256); + + write(socket,outbuffer,strlen(outbuffer)); + + CDDBSkipHTTP(socket); + + CDDBReadLine(socket,inbuffer,256); + + /* Skip the keep-alive */ + if((strlen(inbuffer)<5)||!strncmp(inbuffer,"Keep",4)) { + //g_message ("Skipping keepalive\n"); + CDDBReadLine(socket,inbuffer,256); + } + + while(!CDDBReadLine(socket,inbuffer,512)) + CDDBProcessLine(inbuffer,data,disc.disc_totaltracks); + + /* Both disc title and artist have been stuffed in the title field, so the + need to be separated */ + + CDDBParseTitle(data->data_title,data->data_title,data->data_artist,"/"); + + CDDBDisconnect(socket); + + return 0; +} + +/* See if a disc is in the local database */ + +gboolean CDDBStatDiscData(cdrom_drive *cd_desc) +{ + int index,id; + //disc_info disc; + struct stat st; + char root_dir[256], file[256]; + + //CDStat(cd_desc,&disc,TRUE); + + id=CDDBDiscid(cd_desc); + + g_snprintf(root_dir,256,"%s/.cddb",getenv("HOME")); + + if(stat(root_dir, &st) < 0) + return FALSE; + else { + if(!S_ISDIR(st.st_mode)) + return FALSE; + } + + g_snprintf(file,256,"%s/%08x",root_dir,id); + if(stat(file,&st)==0) return TRUE; + + for(index=0;index<12;index++) { + g_snprintf(file,256,"%s/%s/%08x",root_dir,CDDBGenre(index),id); + + if(stat(file,&st) == 0) + return TRUE; + } + + return FALSE; +} + +/* Read from the local database */ +int +CDDBReadDiscData(cdrom_drive *cd_desc,DiscData *ddata) +{ + FILE *cddb_data = NULL; + int index,genre; + char root_dir[256], file[256], inbuf[512]; + disc_info disc; + struct stat st; + + g_snprintf(root_dir,256,"%s/.cddb",getenv("HOME")); + + if(stat(root_dir, &st) < 0) { + return -1; + } else { + if(!S_ISDIR(st.st_mode)) { + errno = ENOTDIR; + return -1; + } + } + + CDStat (cd_desc->ioctl_fd, &disc, TRUE); + + ddata->data_id=CDDBDiscid(cd_desc); + *(ddata->data_extended)='\0'; + *(ddata->data_title)='\0'; + *(ddata->data_artist)='\0'; + *(ddata->data_playlist)='\0'; + ddata->data_multi_artist=FALSE; + ddata->data_year=0; + + for(index=0;indexdata_track[index].track_name)='\0'; + *(ddata->data_track[index].track_artist)='\0'; + *(ddata->data_track[index].track_extended)='\0'; + } + + g_snprintf(file,256,"%s/%08x",root_dir,ddata->data_id); + if(stat(file,&st)==0) { + cddb_data=fopen(file, "r"); + } + else { + for(genre=0;genre<12;genre++) { + g_snprintf(file,256,"%s/%s/%08x",root_dir,CDDBGenre(genre), + ddata->data_id); + + if(stat(file,&st)==0) { + cddb_data=fopen(file, "r"); + + ddata->data_genre=genre; + break; + } + } + + if(genre==12) return -1; + } + + while(fgets(inbuf,512,cddb_data)) + CDDBProcessLine(inbuf,ddata,disc.disc_totaltracks); + + /* Both disc title and artist have been stuffed in the title field, so the + need to be separated */ + + CDDBParseTitle(ddata->data_title,ddata->data_title,ddata->data_artist,"/"); + + fclose(cddb_data); + + return 0; +} + +#if 0 +static void CDDBWriteLine(char *header,int num,char *data,FILE *outfile) +{ + int len; + char *offset; + + len=strlen(data); + offset=data; + + for(;;) { + if(len>80) { + if(num==-1) + fprintf(outfile,"%s=%.70s\n",header,offset); + else fprintf(outfile,"%s%d=%.70s\n",header,num,offset); + + offset+=70; + len-=70; + } + else { + if(num==-1) fprintf(outfile,"%s=%s\n",header,offset); + else fprintf(outfile,"%s%d=%s\n",header,num,offset); + break; + } + } +} +#endif + +/* Write to the local cache */ +int CDDBWriteDiscData(cdrom_drive *drive, DiscData *ddata,FILE *outfile, + gboolean gripext) +{ +#if 0 + FILE *cddb_data; + int track; + char root_dir[256],file[256]; + struct stat st; + disc_info disc; + + //CDStat(cd_desc,&disc,TRUE); + + if(!outfile) { + g_snprintf(root_dir,256,"%s/.cddb",getenv("HOME")); + g_snprintf(file,256,"%s/%08x",root_dir,ddata->data_id); + + if(stat(root_dir,&st)<0) { + if(errno != ENOENT) { + //g_message("Stat error %d on %s\n",errno,root_dir); + return -1; + } + else { + //g_message("Creating directory %s\n",root_dir); + mkdir(root_dir, 0755); + } + } else { + if(!S_ISDIR(st.st_mode)) { + //g_message("Error: %s exists, but is a file\n",root_dir); + errno=ENOTDIR; + return -1; + } + } + + if((cddb_data=fopen(file,"w"))==NULL) { + //g_message("Error: Unable to open %s for writing\n",file); + return -1; + } + } + else cddb_data=outfile; + + //fprintf(cddb_data,"# xmcd CD database file generated by %s %s\n", Program,Version); + fprintf(cddb_data,"# xmcd CD database file generated by Loser 1.0\n"); + fputs("# \n",cddb_data); + fputs("# Track frame offsets:\n",cddb_data); + + for (track = 0; track < disc.disc_totaltracks; track++) + fprintf(cddb_data, "# %d\n",disc.track[track].track_start); + + fputs("# \n",cddb_data); + fprintf(cddb_data,"# Disc length: %d seconds\n",disc.disc_length.minutes * + 60 + disc.disc_length.seconds); + fputs("# \n",cddb_data); + fprintf(cddb_data,"# Revision: %s\n",CDDA_CDDB_LEVEL); + //fprintf(cddb_data,"# Submitted via: %s %s\n",Program,Version); + fprintf(cddb_data,"# Submitted via: Loser 1.0\n"); + fputs("# \n",cddb_data); + fprintf(cddb_data,"DISCID=%08x\n",ddata->data_id); + + fprintf(cddb_data,"DTITLE=%s / %s\n", + ddata->data_artist,ddata->data_title); + + if(gripext&&ddata->data_year) + fprintf(cddb_data,"DYEAR=%d\n",ddata->data_year); + + if(gripext) + fprintf(cddb_data,"DGENRE=%s\n",CDDBGenre(ddata->data_genre)); + + for(track=0;trackdata_track[track].track_artist)) { + fprintf(cddb_data,"TTITLE%d=%s\n",track, + ddata->data_track[track].track_name); + } + else { + fprintf(cddb_data,"TTITLE%d=%s / %s\n",track, + ddata->data_track[track].track_name, + ddata->data_track[track].track_artist); + } + + if(gripext&&*(ddata->data_track[track].track_artist)) + fprintf(cddb_data,"TARTIST%d=%s\n",track, + ddata->data_track[track].track_artist); + + } + + CDDBWriteLine("EXTD",-1,ddata->data_extended,cddb_data); + + for(track=0;trackdata_track[track].track_extended,cddb_data); + + if(outfile) + fprintf(cddb_data,"PLAYORDER=\n"); + else { + fprintf(cddb_data,"PLAYORDER=%s\n",ddata->data_playlist); + fclose(cddb_data); + } +#endif + return 0; +} + + +gboolean +CDDBLookupDisc (CDDBServer *server, cdrom_drive *drive, DiscData *disc_data) +{ + CDDBHello hello; + CDDBQuery query; + CDDBEntry entry; + gboolean success = FALSE; + + if(server->use_proxy) { + //g_message ("Querying %s (through %s:%d) for disc %02x.\n", server->name, + //server->proxy->name, server->proxy->port, CDDBDiscid (drive)); + } else { + //g_message ("Querying %s for disc %02x.\n",server->name, CDDBDiscid (drive)); + } + + strncpy (hello.hello_program, "Loser", 256); + strncpy (hello.hello_version, "1.0", 256); + + if (!CDDBDoQuery (drive, server, &hello, &query)) { + g_message ("Query failed"); + } else { + switch(query.query_match) { + case MATCH_INEXACT: + case MATCH_EXACT: + //g_message ("Match for \"%s / %s\"\nDownloading data...\n", + // query.query_list[0].list_artist, + // query.query_list[0].list_title); + entry.entry_genre = query.query_list[0].list_genre; + entry.entry_id = query.query_list[0].list_id; + CDDBRead (drive, server, &hello, &entry, disc_data); + + //g_message ("Done\n"); + success = TRUE; + + //if (CDDBWriteDiscData (drive, disc_data, NULL, TRUE) < 0) { + // printf ("Error saving disc data\n"); + //} + break; + + case MATCH_NOMATCH: + g_message ("No match\n"); + break; + } + } + return success; +} + +/* Update a CD status structure... because operating system interfaces vary + so does this function. */ + +int +CDStat (int cd_desc, disc_info *disc, gboolean read_toc) +{ + struct cdrom_tochdr cdth; + struct cdrom_tocentry cdte; + int readtracks,frame[MAX_TRACKS],pos; + int retcode; + + retcode = ioctl(cd_desc, CDROM_DRIVE_STATUS, CDSL_CURRENT); + //g_message("Drive status is %d\n", retcode); + if (retcode < 0) { + //g_message("Drive doesn't support drive status check (assume CDS_NO_INFO)\n"); + } else if (retcode != CDS_DISC_OK && retcode != CDS_NO_INFO) { + return -1; + } + + disc->disc_present = 1; + + if (read_toc) { + //g_message ("Reading TOC"); + /* Read the Table Of Contents header */ + if(ioctl(cd_desc, CDROMREADTOCHDR, &cdth) < 0) { + printf("Error: Failed to read disc contents\n"); + return -1; + } + disc->disc_totaltracks = cdth.cdth_trk1; + + /* Read the table of contents */ + for(readtracks = 0; readtracks <= disc->disc_totaltracks; readtracks++) { + if(readtracks == disc->disc_totaltracks) + cdte.cdte_track = CDROM_LEADOUT; + else + cdte.cdte_track = readtracks + 1; + + cdte.cdte_format = CDROM_MSF; + if(ioctl(cd_desc, CDROMREADTOCENTRY, &cdte) < 0) { + printf("Error: Failed to read disc contents\n"); + return -1; + } + + disc->track[readtracks].track_pos.minutes = cdte.cdte_addr.msf.minute; + disc->track[readtracks].track_pos.seconds = cdte.cdte_addr.msf.second; + frame[readtracks] = cdte.cdte_addr.msf.frame; + } + + for(readtracks = 0; readtracks <= disc->disc_totaltracks; readtracks++) { + disc->track[readtracks].track_start= + (disc->track[readtracks].track_pos.minutes * 60 + + disc->track[readtracks].track_pos.seconds) * 75 + frame[readtracks]; + + if(readtracks > 0) { + pos = (disc->track[readtracks].track_pos.minutes * 60 + + disc->track[readtracks].track_pos.seconds) - + (disc->track[readtracks - 1].track_pos.minutes * 60 + + disc->track[readtracks -1].track_pos.seconds); + disc->track[readtracks - 1].track_length.minutes = pos / 60; + disc->track[readtracks - 1].track_length.seconds = pos % 60; + } + } + + disc->disc_length.minutes= + disc->track[disc->disc_totaltracks].track_pos.minutes; + + disc->disc_length.seconds= + disc->track[disc->disc_totaltracks].track_pos.seconds; + } + + disc->disc_track = 0; + + while(disc->disc_track < disc->disc_totaltracks && + disc->disc_frame >= disc->track[disc->disc_track].track_start) + disc->disc_track++; + + pos=(disc->disc_frame - disc->track[disc->disc_track - 1].track_start) / 75; + + disc->track_time.minutes = pos / 60; + disc->track_time.seconds = pos % 60; + + return 0; +} diff --git a/modules/cdda-cddb.h b/modules/cdda-cddb.h new file mode 100644 index 0000000..e856071 --- /dev/null +++ b/modules/cdda-cddb.h @@ -0,0 +1,179 @@ +/***************************************************************** + + cdda-cddb.h + + Based on code from libcdaudio 0.5.0 (Copyright (C)1998 Tony Arcieri) + + All changes copyright (c) 1998 by Mike Oliphant - oliphant@ling.ed.ac.uk + + http://www.ling.ed.ac.uk/~oliphant/grip + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + +*****************************************************************/ + +#ifndef CDDA_CDDB_H +#define CDDA_CDDB_H + +#include +#include + +#define size16 short +#define size32 int + +#include + +#define CURRENT_CDDBREVISION 2 +#define MAX_TRACKS 100 + +/* CDDB hello structure */ +struct CDDBHello { + /* Program */ + char hello_program[256]; + /* Program version */ + char hello_version[256]; +}; + +/* Used for keeping track of times */ +struct disc_timeval { + int minutes; + int seconds; +}; + +/* Track specific information */ +struct track_info { + struct disc_timeval track_length; + struct disc_timeval track_pos; + int track_frames; + int track_start; +}; + +/* Disc information such as current track, amount played, etc */ +typedef struct { + int disc_present; /* Is disc present? */ + int disc_mode; /* Current disc mode */ + struct disc_timeval track_time; /* Current track time */ + struct disc_timeval disc_time; /* Current disc time */ + struct disc_timeval disc_length; /* Total disc length */ + int disc_frame; /* Current frame */ + int disc_track; /* Current track */ + int disc_totaltracks; /* Number of tracks on disc */ + struct track_info track[MAX_TRACKS]; /* Track specific information */ +} disc_info; + +/* HTTP proxy server structure */ +typedef struct _proxy_server { + char name[256]; + int port; +} ProxyServer; + +/* CDDB server structure */ + +typedef struct _cddb_server { + char name[256]; + char cgi_prog[256]; + int port; + int use_proxy; + ProxyServer *proxy; +} CDDBServer; + +#define CDDA_CDDB_LEVEL "3" /* Current CDDB protocol level supported */ + +/* CDDB entry */ +typedef struct _cddb_entry { + unsigned int entry_id; + int entry_genre; +} CDDBEntry; + +/* CDDB hello structure */ +typedef struct _cddb_hello { + /* Program */ + char hello_program[256]; + /* Program version */ + char hello_version[256]; +} CDDBHello; + +#define MAX_INEXACT_MATCHES 16 + +/* An entry in the query list */ +struct query_list_entry { + int list_genre; + int list_id; + char list_title[64]; + char list_artist[64]; +}; + +/* CDDB query structure */ +typedef struct _cddb_query { + int query_match; + int query_matches; + struct query_list_entry query_list[MAX_INEXACT_MATCHES]; +} CDDBQuery; + +/* Match values returned by a query */ + +#define MATCH_NOMATCH 0 +#define MATCH_EXACT 1 +#define MATCH_INEXACT 2 + +/* Track database structure */ + +typedef struct _track_data { + char track_name[256]; /* Track name */ + char track_artist[256]; /* Track artist */ + char track_extended[4096]; /* Extended information */ +} TrackData; + +/* Disc database structure */ +typedef struct _disc_data { + unsigned int data_id; /* CD id */ + char data_title[256]; /* Disc title */ + char data_artist[256]; /* We may be able to extract this */ + char data_extended[4096]; /* Extended information */ + int data_genre; /* Disc genre */ + int data_year; /* Disc year */ + char data_playlist[256]; /* Playlist info */ + gboolean data_multi_artist; /* Is CD multi-artist? */ + TrackData data_track[MAX_TRACKS]; /* Track names */ +} DiscData; + + +/* Encode list structure */ +typedef struct _encode_track { + int track_num; + int start_frame; + int end_frame; + char song_name[80]; + char song_artist[80]; + char disc_name[80]; + char disc_artist[80]; + int song_year; + int id3_genre; + int mins; + int secs; + int discid; +} EncodeTrack; + + +unsigned int CDDBDiscid(cdrom_drive *drive); +char *CDDBGenre(int genre); +int CDDBGenreValue(char *genre); +gboolean CDDBDoQuery(cdrom_drive *cd_desc, CDDBServer *server, CDDBHello *hello,CDDBQuery *query); +gboolean CDDBRead(cdrom_drive *cd_desc,CDDBServer *server, CDDBHello *hello,CDDBEntry *entry, DiscData *data); +gboolean CDDBRead(cdrom_drive *cd_desc,CDDBServer *server, CDDBHello *hello,CDDBEntry *entry, DiscData *data); +gboolean CDDBStatDiscData(cdrom_drive *cd_desc); +int CDDBReadDiscData(cdrom_drive *cd_desc, DiscData *outdata); +int CDDBWriteDiscData(cdrom_drive *drive, DiscData *ddata,FILE *outfile, gboolean gripext); +void CDDBParseTitle(char *buf,char *title,char *artist,char *sep); +char *ChopWhite(char *buf); +gboolean CDDBLookupDisc (CDDBServer *server, cdrom_drive *drive, DiscData *disc_data); +int CDStat(int cd_desc, disc_info *disc, gboolean read_toc); + +#endif diff --git a/modules/cdda-cdrom-extensions.h b/modules/cdda-cdrom-extensions.h new file mode 100644 index 0000000..634ff54 --- /dev/null +++ b/modules/cdda-cdrom-extensions.h @@ -0,0 +1,277 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* fm-cdrom-extension.c - CDROM handliong constants copied from . + + Copyright (C) 2000 Eazel, Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Gene Z. Ragan +*/ + +#ifndef CDDA_CDROM_EXTENSIONS_H +#define CDDA_CDROM_EXTENSIONS_H + +/******************************************************* + * The CD-ROM IOCTL commands -- these should be supported by + * all the various cdrom drivers. For the CD-ROM ioctls, we + * will commandeer byte 0x53, or 'S'. + *******************************************************/ +#define CDROMPAUSE 0x5301 /* Pause Audio Operation */ +#define CDROMRESUME 0x5302 /* Resume paused Audio Operation */ +#define CDROMPLAYMSF 0x5303 /* Play Audio MSF (struct cdrom_msf) */ +#define CDROMPLAYTRKIND 0x5304 /* Play Audio Track/index + (struct cdrom_ti) */ +#define CDROMREADTOCHDR 0x5305 /* Read TOC header + (struct cdrom_tochdr) */ +#define CDROMREADTOCENTRY 0x5306 /* Read TOC entry + (struct cdrom_tocentry) */ +#define CDROMSTOP 0x5307 /* Stop the cdrom drive */ +#define CDROMSTART 0x5308 /* Start the cdrom drive */ +#define CDROMEJECT 0x5309 /* Ejects the cdrom media */ +#define CDROMVOLCTRL 0x530a /* Control output volume + (struct cdrom_volctrl) */ +#define CDROMSUBCHNL 0x530b /* Read subchannel data + (struct cdrom_subchnl) */ +#define CDROMREADMODE2 0x530c /* Read CDROM mode 2 data (2336 Bytes) + (struct cdrom_read) */ +#define CDROMREADMODE1 0x530d /* Read CDROM mode 1 data (2048 Bytes) + (struct cdrom_read) */ +#define CDROMREADAUDIO 0x530e /* (struct cdrom_read_audio) */ +#define CDROMEJECT_SW 0x530f /* enable(1)/disable(0) auto-ejecting */ +#define CDROMMULTISESSION 0x5310 /* Obtain the start-of-last-session + address of multi session disks + (struct cdrom_multisession) */ +#define CDROM_GET_MCN 0x5311 /* Obtain the "Universal Product Code" + if available (struct cdrom_mcn) */ +#define CDROM_GET_UPC CDROM_GET_MCN /* This one is depricated, + but here anyway for compatability */ +#define CDROMRESET 0x5312 /* hard-reset the drive */ +#define CDROMVOLREAD 0x5313 /* Get the drive's volume setting + (struct cdrom_volctrl) */ +#define CDROMREADRAW 0x5314 /* read data in raw mode (2352 Bytes) + (struct cdrom_read) */ +/* + * These ioctls are used only used in aztcd.c and optcd.c + */ +#define CDROMREADCOOKED 0x5315 /* read data in cooked mode */ +#define CDROMSEEK 0x5316 /* seek msf address */ + +/* + * This ioctl is only used by the scsi-cd driver. + It is for playing audio in logical block addressing mode. + */ +#define CDROMPLAYBLK 0x5317 /* (struct cdrom_blk) */ + +/* + * These ioctls are only used in optcd.c + */ +#define CDROMREADALL 0x5318 /* read all 2646 bytes */ + +/* + * These ioctls are (now) only in ide-cd.c for controlling + * drive spindown time. They should be implemented in the + * Uniform driver, via generic packet commands, GPCMD_MODE_SELECT_10, + * GPCMD_MODE_SENSE_10 and the GPMODE_POWER_PAGE... + * -Erik + */ +#define CDROMGETSPINDOWN 0x531d +#define CDROMSETSPINDOWN 0x531e + +/* + * These ioctls are implemented through the uniform CD-ROM driver + * They _will_ be adopted by all CD-ROM drivers, when all the CD-ROM + * drivers are eventually ported to the uniform CD-ROM driver interface. + */ +#define CDROMCLOSETRAY 0x5319 /* pendant of CDROMEJECT */ +#define CDROM_SET_OPTIONS 0x5320 /* Set behavior options */ +#define CDROM_CLEAR_OPTIONS 0x5321 /* Clear behavior options */ +#define CDROM_SELECT_SPEED 0x5322 /* Set the CD-ROM speed */ +#define CDROM_SELECT_DISC 0x5323 /* Select disc (for juke-boxes) */ +#define CDROM_MEDIA_CHANGED 0x5325 /* Check is media changed */ +#define CDROM_DRIVE_STATUS 0x5326 /* Get tray position, etc. */ +#define CDROM_DISC_STATUS 0x5327 /* Get disc type, etc. */ +#define CDROM_CHANGER_NSLOTS 0x5328 /* Get number of slots */ +#define CDROM_LOCKDOOR 0x5329 /* lock or unlock door */ +#define CDROM_DEBUG 0x5330 /* Turn debug messages on/off */ +#define CDROM_GET_CAPABILITY 0x5331 /* get capabilities */ + +/* This ioctl is only used by sbpcd at the moment */ +#define CDROMAUDIOBUFSIZ 0x5382 /* set the audio buffer size */ + +/* DVD-ROM Specific ioctls */ +#define DVD_READ_STRUCT 0x5390 /* Read structure */ +#define DVD_WRITE_STRUCT 0x5391 /* Write structure */ +#define DVD_AUTH 0x5392 /* Authentication */ + +#define CDROM_SEND_PACKET 0x5393 /* send a packet to the drive */ +#define CDROM_NEXT_WRITABLE 0x5394 /* get next writable block */ +#define CDROM_LAST_WRITTEN 0x5395 /* get last block written on disc */ + +/* Some generally useful CD-ROM information -- mostly based on the above */ +#define CD_MINS 74 /* max. minutes per CD, not really a limit */ +#define CD_SECS 60 /* seconds per minute */ +#define CD_FRAMES 75 /* frames per second */ +#define CD_SYNC_SIZE 12 /* 12 sync bytes per raw data frame */ +#define CD_MSF_OFFSET 150 /* MSF numbering offset of first frame */ +#define CD_CHUNK_SIZE 24 /* lowest-level "data bytes piece" */ +#define CD_NUM_OF_CHUNKS 98 /* chunks per frame */ +#define CD_FRAMESIZE_SUB 96 /* subchannel data "frame" size */ +#define CD_HEAD_SIZE 4 /* header (address) bytes per raw data frame */ +#define CD_SUBHEAD_SIZE 8 /* subheader bytes per raw XA data frame */ +#define CD_EDC_SIZE 4 /* bytes EDC per most raw data frame types */ +#define CD_ZERO_SIZE 8 /* bytes zero per yellow book mode 1 frame */ +#define CD_ECC_SIZE 276 /* bytes ECC per most raw data frame types */ +#define CD_FRAMESIZE 2048 /* bytes per frame, "cooked" mode */ +#define CD_FRAMESIZE_RAW 2352 /* bytes per frame, "raw" mode */ +#define CD_FRAMESIZE_RAWER 2646 /* The maximum possible returned bytes */ +/* most drives don't deliver everything: */ +#define CD_FRAMESIZE_RAW1 (CD_FRAMESIZE_RAW-CD_SYNC_SIZE) /*2340*/ +#define CD_FRAMESIZE_RAW0 (CD_FRAMESIZE_RAW-CD_SYNC_SIZE-CD_HEAD_SIZE) /*2336*/ + +#define CD_XA_HEAD (CD_HEAD_SIZE+CD_SUBHEAD_SIZE) /* "before data" part of raw XA frame */ +#define CD_XA_TAIL (CD_EDC_SIZE+CD_ECC_SIZE) /* "after data" part of raw XA frame */ +#define CD_XA_SYNC_HEAD (CD_SYNC_SIZE+CD_XA_HEAD) /* sync bytes + header of XA frame */ + +/* CD-ROM address types (cdrom_tocentry.cdte_format) */ +#define CDROM_LBA 0x01 /* "logical block": first frame is #0 */ +#define CDROM_MSF 0x02 /* "minute-second-frame": binary, not bcd here! */ + +/* bit to tell whether track is data or audio (cdrom_tocentry.cdte_ctrl) */ +#define CDROM_DATA_TRACK 0x04 + +/* The leadout track is always 0xAA, regardless of # of tracks on disc */ +#define CDROM_LEADOUT 0xAA + +/* audio states (from SCSI-2, but seen with other drives, too) */ +#define CDROM_AUDIO_INVALID 0x00 /* audio status not supported */ +#define CDROM_AUDIO_PLAY 0x11 /* audio play operation in progress */ +#define CDROM_AUDIO_PAUSED 0x12 /* audio play operation paused */ +#define CDROM_AUDIO_COMPLETED 0x13 /* audio play successfully completed */ +#define CDROM_AUDIO_ERROR 0x14 /* audio play stopped due to error */ +#define CDROM_AUDIO_NO_STATUS 0x15 /* no current audio status to return */ + +/* capability flags used with the uniform CD-ROM driver */ +#define CDC_CLOSE_TRAY 0x1 /* caddy systems _can't_ close */ +#define CDC_OPEN_TRAY 0x2 /* but _can_ eject. */ +#define CDC_LOCK 0x4 /* disable manual eject */ +#define CDC_SELECT_SPEED 0x8 /* programmable speed */ +#define CDC_SELECT_DISC 0x10 /* select disc from juke-box */ +#define CDC_MULTI_SESSION 0x20 /* read sessions>1 */ +#define CDC_MCN 0x40 /* Medium Catalog Number */ +#define CDC_MEDIA_CHANGED 0x80 /* media changed */ +#define CDC_PLAY_AUDIO 0x100 /* audio functions */ +#define CDC_RESET 0x200 /* hard reset device */ +#define CDC_IOCTLS 0x400 /* driver has non-standard ioctls */ +#define CDC_DRIVE_STATUS 0x800 /* driver implements drive status */ +#define CDC_GENERIC_PACKET 0x1000 /* driver implements generic packets */ +#define CDC_CD_R 0x2000 /* drive is a CD-R */ +#define CDC_CD_RW 0x4000 /* drive is a CD-RW */ +#define CDC_DVD 0x8000 /* drive is a DVD */ +#define CDC_DVD_R 0x10000 /* drive can write DVD-R */ +#define CDC_DVD_RAM 0x20000 /* drive can write DVD-RAM */ + +/* drive status possibilities returned by CDROM_DRIVE_STATUS ioctl */ +#define CDS_NO_INFO 0 /* if not implemented */ +#define CDS_NO_DISC 1 +#define CDS_TRAY_OPEN 2 +#define CDS_DRIVE_NOT_READY 3 +#define CDS_DISC_OK 4 + +/* return values for the CDROM_DISC_STATUS ioctl */ +/* can also return CDS_NO_[INFO|DISC], from above */ +#define CDS_AUDIO 100 +#define CDS_DATA_1 101 +#define CDS_DATA_2 102 +#define CDS_XA_2_1 103 +#define CDS_XA_2_2 104 +#define CDS_MIXED 105 + +/* User-configurable behavior options for the uniform CD-ROM driver */ +#define CDO_AUTO_CLOSE 0x1 /* close tray on first open() */ +#define CDO_AUTO_EJECT 0x2 /* open tray on last release() */ +#define CDO_USE_FFLAGS 0x4 /* use O_NONBLOCK information on open */ +#define CDO_LOCK 0x8 /* lock tray on open files */ +#define CDO_CHECK_TYPE 0x10 /* check type on open for data */ + +/* Special codes used when specifying changer slots. */ +#define CDSL_NONE ((int) (~0U>>1)-1) +#define CDSL_CURRENT ((int) (~0U>>1)) + +/* For partition based multisession access. IDE can handle 64 partitions + * per drive - SCSI CD-ROM's use minors to differentiate between the + * various drives, so we can't do multisessions the same way there. + * Use the -o session=x option to mount on them. + */ +#define CD_PART_MAX 64 +#define CD_PART_MASK (CD_PART_MAX - 1) + +/******************************************************* + * CDROM IOCTL structures + *******************************************************/ + +/* Address in MSF format */ +struct cdrom_msf0 +{ + u_char minute; + u_char second; + u_char frame; +}; + +/* Address in either MSF or logical format */ +union cdrom_addr +{ + struct cdrom_msf0 msf; + int lba; +}; + +/* This struct is used by the CDROMSUBCHNL ioctl */ +struct cdrom_subchnl +{ + u_char cdsc_format; + u_char cdsc_audiostatus; + u_char cdsc_adr: 4; + u_char cdsc_ctrl: 4; + u_char cdsc_trk; + u_char cdsc_ind; + union cdrom_addr cdsc_absaddr; + union cdrom_addr cdsc_reladdr; +}; + + +/* This struct is used by the CDROMREADTOCENTRY ioctl */ +struct cdrom_tocentry +{ + u_char cdte_track; + u_char cdte_adr :4; + u_char cdte_ctrl :4; + u_char cdte_format; + union cdrom_addr cdte_addr; + u_char cdte_datamode; +}; + + +/* This struct is used by the CDROMREADTOCHDR ioctl */ +struct cdrom_tochdr +{ + u_char cdth_trk0; /* start track */ + u_char cdth_trk1; /* end track */ +}; + + + + +#endif /* CDDA_CDROM_EXTENSIONS_H */ diff --git a/modules/cdda-method.c b/modules/cdda-method.c new file mode 100644 index 0000000..fe3387c --- /dev/null +++ b/modules/cdda-method.c @@ -0,0 +1,1035 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: 8; c-basic-offset: 8 -*- */ + +/* cdda-method.c + + Copyright (C) 2000, Eazel Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Gene Z. Ragan +*/ + +#include + +#include "cdda-cddb.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +typedef struct { + GnomeVFSURI *uri; + GnomeVFSFileInfo *file_info; + cdrom_drive *drive; + int access_count; + unsigned int cddb_discid; + gboolean use_cddb; + DiscData disc_data; +} CDDAContext; + +typedef struct { + GnomeVFSURI *uri; + gboolean inited; + gboolean wrote_header; + cdrom_paranoia *paranoia; + long cursor; + long first_sector, last_sector; +} ReadHandle; + +CDDAContext *global_context = NULL; + +/* This is here to work around a broken header file. + * cdda_interface.h has a statically defined array of + * chars that is unused. This will break our build + * due to our strict error checking. + */ +char **broken_header_fix = strerror_tr; + +static GnomeVFSResult do_open (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + GnomeVFSContext *context); +static gboolean do_is_local (GnomeVFSMethod *method, + const GnomeVFSURI *uri); +static GnomeVFSResult do_open_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context); +static GnomeVFSResult do_close_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context); +static GnomeVFSResult do_read_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSContext *context); +static int get_data_size (cdrom_drive *drive, + int track); +static gboolean is_file_is_on_disc (CDDAContext *context, + const GnomeVFSURI *uri); +static int write_wav_header (gpointer buffer, + long bytes); + + +static const char PROXY_HOST_KEY[] = "/system/http_proxy/host"; +static const char PROXY_PORT_KEY[] = "/system/http_proxy/port"; +static const char USE_PROXY_KEY[] = "/system/http_proxy/use_http_proxy"; + +static CDDAContext * +cdda_context_new (cdrom_drive *drive, GnomeVFSURI *uri) +{ + CDDAContext *context; + GConfClient *gconf_client; + char *proxy_host; + gboolean use_proxy; + ProxyServer proxy_server; + CDDBServer cddb_server; + + context = g_new0 (CDDAContext, 1); + context->drive = drive; + context->file_info = gnome_vfs_file_info_new (); + context->uri = gnome_vfs_uri_ref (uri); + context->access_count = 0; + context->cddb_discid = CDDBDiscid (drive); + + // Look up CDDB info + gconf_client = gconf_client_get_default (); + + use_proxy = gconf_client_get_bool (gconf_client, USE_PROXY_KEY, NULL); + if (use_proxy) { + proxy_host = gconf_client_get_string (gconf_client, PROXY_HOST_KEY, NULL); + + proxy_server.port = gconf_client_get_int (gconf_client, PROXY_PORT_KEY, NULL); + + if (proxy_host != NULL) { + strcpy (proxy_server.name, proxy_host); + g_free (proxy_host); + } else { + use_proxy = FALSE; + } + + if (proxy_server.port == 0) { + proxy_server.port = 8080; + } + } + + strcpy (cddb_server.name, "freedb.freedb.org"); + strcpy (cddb_server.cgi_prog, "~cddb/cddb.cgi"); + cddb_server.port = 80; + cddb_server.use_proxy = use_proxy; + cddb_server.proxy = &proxy_server; + + context->use_cddb = CDDBLookupDisc (&cddb_server, drive, &context->disc_data); + + return context; +} + +static void +cdda_context_free (CDDAContext *context) +{ + if (context == NULL) { + return; + } + + cdda_close (context->drive); + gnome_vfs_file_info_unref (context->file_info); + gnome_vfs_uri_unref (context->uri); + + g_free (context); + context = NULL; +} + +static void +cdda_set_file_info_for_root (CDDAContext *context, GnomeVFSURI *uri) +{ + g_assert (context); + + // We don't know the io_block size + context->file_info->io_block_size = 0; + context->file_info->valid_fields -= GNOME_VFS_FILE_INFO_FIELDS_IO_BLOCK_SIZE; + context->file_info->name = gnome_vfs_uri_extract_short_path_name (uri); + //context->file_info->name = g_strdup (context->disc_data.data_title); + context->file_info->type = GNOME_VFS_FILE_TYPE_DIRECTORY; + context->file_info->mime_type = g_strdup ("x-directory/normal"); + context->file_info->atime = time (NULL); + context->file_info->ctime = time (NULL); + context->file_info->mtime = time (NULL); + context->file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_TYPE | + GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE | + GNOME_VFS_FILE_INFO_FIELDS_ATIME | + GNOME_VFS_FILE_INFO_FIELDS_MTIME | + GNOME_VFS_FILE_INFO_FIELDS_CTIME; +}; + +static ReadHandle * +read_handle_new (GnomeVFSURI *uri) +{ + ReadHandle *result; + result = g_new (ReadHandle, 1); + + result->uri = gnome_vfs_uri_ref (uri); + result->inited = FALSE; + result->wrote_header = FALSE; + result->paranoia = NULL; + result->cursor = 0; + result->first_sector = 0; + result->last_sector = 0; + + return result; +} + +static void +read_handle_destroy (ReadHandle *handle) +{ + gnome_vfs_uri_unref (handle->uri); + + if (handle->paranoia == NULL) { + paranoia_free (handle->paranoia); + } + + g_free (handle); +} + +static int +get_track_index_from_uri (CDDAContext *context, GnomeVFSURI *uri) { + char *base_name; + int index; + char *escaped_name; + + base_name = gnome_vfs_uri_extract_short_path_name (uri); + escaped_name = gnome_vfs_unescape_string_for_display (base_name); + g_free (base_name); + + // Check and see if filename is in cddb data list + for (index = 0; index < context->drive->tracks; index++) { + if (strcmp (escaped_name, context->disc_data.data_track[index].track_name) == 0) { + g_free (escaped_name); + return index + 1; + } + } + + g_free (escaped_name); + return -1; +} + +static GnomeVFSResult +do_open (GnomeVFSMethod *method, GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, GnomeVFSOpenMode mode, GnomeVFSContext *context) +{ + GnomeVFSResult result; + ReadHandle *read_handle; + GnomeVFSFileInfoOptions options; + char *base_name; + char *dirname, *schemedir, *sep; + GnomeVFSURI *dir_uri; + + result = GNOME_VFS_ERROR_GENERIC; + *method_handle = NULL; + + //g_message ("cdda do_open: %s", gnome_vfs_uri_get_path (uri)); + + // Load in context for disc if we not yet done so. + if (global_context == NULL) { + base_name = gnome_vfs_uri_extract_short_path_name (uri); + if (base_name[0] == GNOME_VFS_URI_PATH_CHR) { + g_free (base_name); + return result; + } else { + g_free (base_name); + } + + dirname = gnome_vfs_uri_extract_dirname (uri); + schemedir = g_strdup_printf ("cdda://%s", dirname); + + // Remove trailing '/' if there is one + sep = strrchr (schemedir, '/'); + if (sep != NULL) { + schemedir [strlen (schemedir) - 1] = '\0'; + } + + dir_uri = gnome_vfs_uri_new (schemedir); + options = 0; + result = do_open_directory (method, method_handle, dir_uri, options, NULL); + gnome_vfs_uri_unref (dir_uri); + + if (result != GNOME_VFS_OK) { + //g_message ("cdda do_open: Unable to load context"); + return result; + } + } + + if (mode == GNOME_VFS_OPEN_READ) { + // Make sure file is present + if (is_file_is_on_disc (global_context, uri)) { + result = GNOME_VFS_OK; + read_handle = read_handle_new (uri); + + // Set up cdparanoia + if (!read_handle->inited) { + int track; + int paranoia_mode; + long offset, sec, off; + + track = get_track_index_from_uri (global_context, uri); + if (track == -1) { + return GNOME_VFS_ERROR_GENERIC; + } + + if (!cdda_track_audiop (global_context->drive, track)) { + //g_message ("Error. Selected track is not an audio track."); + return GNOME_VFS_ERROR_GENERIC; + } + + /* Calculate sector span and offset */ + sec = cdda_track_firstsector (global_context->drive, track); + off = cdda_track_lastsector (global_context->drive, track) - sec + 1; + + read_handle->first_sector = 0; + read_handle->last_sector = off - 1; + + offset = cdda_track_firstsector (global_context->drive, track); + read_handle->first_sector += offset; + read_handle->last_sector += offset; + + read_handle->paranoia = paranoia_init (global_context->drive); + //paranoia_mode = PARANOIA_MODE_FULL^PARANOIA_MODE_NEVERSKIP; + paranoia_mode = PARANOIA_MODE_DISABLE; + paranoia_modeset (read_handle->paranoia, paranoia_mode); + cdda_verbose_set (global_context->drive, CDDA_MESSAGE_PRINTIT,CDDA_MESSAGE_FORGETIT); + + paranoia_seek (read_handle->paranoia, read_handle->cursor = read_handle->first_sector, SEEK_SET); + + read_handle->inited = TRUE; + } + + *method_handle = (GnomeVFSMethodHandle *) read_handle; + } + } else if (mode == GNOME_VFS_OPEN_WRITE) { + result = GNOME_VFS_ERROR_READ_ONLY; + } else { + result = GNOME_VFS_ERROR_INVALID_OPEN_MODE; + } + + return result; +} + +static GnomeVFSResult +do_close (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + ReadHandle *read_handle; + + //g_message ("cdda do_close"); + + g_return_val_if_fail (method_handle != NULL, GNOME_VFS_ERROR_INTERNAL); + + read_handle = (ReadHandle *) method_handle; + read_handle_destroy (read_handle); + + return GNOME_VFS_OK; +} + + +/* We have to pass in a callback to paranoia_read, even though we don't use it */ +static void +paranoia_callback (long inpos, int function) { +} + +static GnomeVFSResult +do_read (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read, + GnomeVFSContext *context) +{ + ReadHandle *read_handle; + gint16 *readbuf; + g_return_val_if_fail (method_handle != NULL, GNOME_VFS_ERROR_INTERNAL); + + if (gnome_vfs_context_check_cancellation (context)) { + return GNOME_VFS_ERROR_CANCELLED; + } + + read_handle = (ReadHandle *) method_handle; + if (read_handle == NULL) { + return GNOME_VFS_ERROR_INTERNAL; + } + + readbuf = NULL; + + if (!read_handle->wrote_header) { + *bytes_read = write_wav_header (buffer, (read_handle->last_sector - read_handle->first_sector + 1) + * CD_FRAMESIZE_RAW); + read_handle->wrote_header = TRUE; + return GNOME_VFS_OK; + } + + + if (read_handle->cursor <= read_handle->last_sector) { + readbuf = paranoia_read (read_handle->paranoia, paranoia_callback); + } else { + return GNOME_VFS_ERROR_EOF; + + } + + if (readbuf == NULL) { + *bytes_read = 0; + return GNOME_VFS_ERROR_GENERIC; + } + + read_handle->cursor++; + + memcpy (buffer, readbuf, CD_FRAMESIZE_RAW); + *bytes_read = CD_FRAMESIZE_RAW; + + return GNOME_VFS_OK; +} + +#if 0 +static void +display_toc (cdrom_drive *d) +{ + long audiolen = 0; + int i; + + printf ("\nTable of contents (audio tracks only):\n" + "track length begin copy pre ch\n" + "===========================================================\n"); + + for (i = 1; i <= d->tracks; i++) { + if (cdda_track_audiop (d, i)) { + char buffer[256]; + + long sec = cdda_track_firstsector (d, i); + long off = cdda_track_lastsector (d, i) - sec + 1; + + sprintf(buffer, + "%3d. %7ld [%02d:%02d.%02d] %7ld [%02d:%02d.%02d] %s %s %s", + i, + off,(int)(off/(60*75)),(int)((off/75)%60),(int)(off%75), + sec,(int)(sec/(60*75)),(int)((sec/75)%60),(int)(sec%75), + cdda_track_copyp (d,i)?" OK":" no", + cdda_track_preemp (d,i)?" yes":" no", + cdda_track_channels (d,i)==2?" 2":" 4"); + printf ("%s\n", buffer); + audiolen+=off; + } + } + + { + char buffer[256]; + sprintf (buffer, "TOTAL %7ld [%02d:%02d.%02d] (audio only)", + audiolen, (int)(audiolen / (60 * 75)),(int)((audiolen / 75) % 60), + (int)(audiolen % 75)); + printf ("%s\n", buffer); + } + + printf ("\n"); +} +#endif + +static cdrom_drive * +open_cdda_device (GnomeVFSURI *uri) +{ + const char *device_name; + cdrom_drive *drive; + + device_name = gnome_vfs_uri_get_path (uri); + + drive = cdda_identify (device_name, FALSE, NULL); + if (drive == NULL) { + return NULL; + } + + /* Turn off verbosity */ + cdda_verbose_set (drive, CDDA_MESSAGE_PRINTIT, CDDA_MESSAGE_FORGETIT); + + /* Open drive */ + switch (cdda_open (drive)) { + case -2: + case -3: + case -4: + case -5: + g_message ("Unable to open disc. Is there an audio CD in the drive?"); + return NULL; + + case -6: + g_message ("CDDA method could not find a way to read audio from this drive."); + return NULL; + + case 0: + break; + + default: + g_message ("Unable to open disc."); + return NULL; + } + + return drive; +} + +static gboolean +is_file_is_on_disc (CDDAContext *context, const GnomeVFSURI *uri) +{ + int index; + char *base_name; + char *escaped_name; + + if (context == NULL) { + return FALSE; + } + + base_name = gnome_vfs_uri_extract_short_path_name (uri); + escaped_name = gnome_vfs_unescape_string_for_display (base_name); + g_free (base_name); + + for (index = 0; index < context->drive->tracks; index++) { + if (strcmp (escaped_name, context->disc_data.data_track[index].track_name) == 0) { + g_free (escaped_name); + return TRUE; + } + } + + g_free (escaped_name); + return FALSE; +} + +static GnomeVFSResult +get_file_info_for_basename (CDDAContext *context, const char *base_name) +{ + int index; + + g_assert (context); + + if (!context->use_cddb) { + return GNOME_VFS_ERROR_GENERIC; + } + + // Check and see if filename is in cddb data list + for (index = 0; index < context->drive->tracks; index++) { + if (strcmp (base_name, context->disc_data.data_track[index].track_name) == 0) { + // Populate file info struture + context->file_info->io_block_size = CD_FRAMESIZE_RAW; + context->file_info->name = g_strdup (base_name); + context->file_info->type = GNOME_VFS_FILE_TYPE_REGULAR; + context->file_info->mime_type = g_strdup ("audio/x-wav"); + context->file_info->atime = time (NULL); + context->file_info->ctime = time (NULL); + context->file_info->mtime = time (NULL); + context->file_info->size = get_data_size (context->drive, index + 1); + context->file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_TYPE | + GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE | + GNOME_VFS_FILE_INFO_FIELDS_SIZE | + GNOME_VFS_FILE_INFO_FIELDS_IO_BLOCK_SIZE | + GNOME_VFS_FILE_INFO_FIELDS_ATIME | + GNOME_VFS_FILE_INFO_FIELDS_MTIME | + GNOME_VFS_FILE_INFO_FIELDS_CTIME; + + return GNOME_VFS_OK; + } + } + return GNOME_VFS_ERROR_GENERIC; +} + +static GnomeVFSResult +do_get_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + cdrom_drive *drive; + char *base_name; + gboolean use_base, use_cache; + GnomeVFSResult result; + char *escaped_name; + + //g_message ("do_get_file_info: %s", gnome_vfs_uri_get_path (uri)); + + use_base = FALSE; + use_cache = FALSE; + + result = GNOME_VFS_OK; + + // Get basename + base_name = gnome_vfs_uri_extract_short_path_name (uri); + escaped_name = gnome_vfs_unescape_string_for_display (base_name); + g_free (base_name); + + // Extract path and attempt to open + drive = open_cdda_device (uri); + if (drive == NULL) { + // OK. We failed to open. Let's try the parent... + gchar *dirname, *schemedir, *sep; + GnomeVFSURI *dir_uri; + + dirname = gnome_vfs_uri_extract_dirname (uri); + schemedir = g_strdup_printf ("cdda://%s", dirname); + + // Remove trailing '/' if there is one + sep = strrchr (schemedir, '/'); + if (sep != NULL) { + schemedir [strlen (schemedir) - 1] = '\0'; + } + + dir_uri = gnome_vfs_uri_new (schemedir); + drive = open_cdda_device (dir_uri); + + g_free (dirname); + g_free (schemedir); + gnome_vfs_uri_unref (dir_uri); + + if (drive == NULL) { + g_free (escaped_name); + return GNOME_VFS_ERROR_GENERIC; + } + + use_base = TRUE; + } + + // Check and see if we already have opened and stashed this drive + if (!use_base) { + if (global_context != NULL) { + if (strcmp (drive->cdda_device_name, global_context->drive->cdda_device_name) == 0) { + use_cache = TRUE; + cdda_close (drive); + gnome_vfs_file_info_copy (file_info, global_context->file_info); + } else { + // We have a new drive. + cdda_context_free (global_context); + global_context = cdda_context_new (drive, uri); + cdda_set_file_info_for_root (global_context, uri); + gnome_vfs_file_info_copy (file_info, global_context->file_info); + } + } else { + // Create a new context + global_context = cdda_context_new (drive, uri); + cdda_set_file_info_for_root (global_context, uri); + gnome_vfs_file_info_copy (file_info, global_context->file_info); + } + } else { + cdda_context_free (global_context); + global_context = cdda_context_new (drive, uri); + result = get_file_info_for_basename (global_context, escaped_name); + if (result == GNOME_VFS_OK) { + gnome_vfs_file_info_copy (file_info, global_context->file_info); + } else { + cdda_context_free (global_context); + global_context = NULL; + } + } + + g_free (escaped_name); + return result; +} + +static GnomeVFSResult +do_open_directory (GnomeVFSMethod *method, GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + cdrom_drive *drive; + gboolean use_base, use_cache; + char *base_name; + char *escaped_name; + + g_print ("do_open_directory () in uri: %s\n", gnome_vfs_uri_get_path (uri)); + + use_base = FALSE; + use_cache = FALSE; + + // Get basename + base_name = gnome_vfs_uri_extract_short_path_name (uri); + escaped_name = gnome_vfs_unescape_string_for_display (base_name); + g_free (base_name); + + // Make sure we can open URI + drive = open_cdda_device (uri); + if (drive == NULL) { + // OK. We failed to open. Let's try the parent... + gchar *dirname, *schemedir, *sep; + GnomeVFSURI *dir_uri; + + dirname = gnome_vfs_uri_extract_dirname (uri); + schemedir = g_strdup_printf ("cdda://%s", dirname); + + // Remove trailing '/' if there is one + sep = strrchr (schemedir, '/'); + if (sep != NULL) { + schemedir [strlen (schemedir) - 1] = '\0'; + } + + dir_uri = gnome_vfs_uri_new (schemedir); + drive = open_cdda_device (dir_uri); + + g_free (dirname); + g_free (schemedir); + gnome_vfs_uri_unref (dir_uri); + + if (drive == NULL) { + g_free (escaped_name); + return GNOME_VFS_ERROR_GENERIC; + } + use_base = TRUE; + } + + if (!use_base) { + // Check for cache + if (global_context != NULL) { + if (strcmp (drive->cdda_device_name, global_context->drive->cdda_device_name) != 0) { + // Clear old cache + cdda_context_free (global_context); + global_context = cdda_context_new (drive, uri); + cdda_set_file_info_for_root (global_context, uri); + } else { + //g_message ("Using cache"); + cdda_close (drive); + } + } else { + // Allocate new context + global_context = cdda_context_new (drive, uri); + cdda_set_file_info_for_root (global_context, uri); + } + } else { + // This is a file. Blast cache. + //g_message ("Use base: %s", escaped_name); + cdda_context_free (global_context); + global_context = NULL; + *method_handle = NULL; + cdda_close (drive); + g_free (escaped_name); + return GNOME_VFS_ERROR_GENERIC; + } + + *method_handle = (GnomeVFSMethodHandle *) global_context; + g_free (escaped_name); + + return GNOME_VFS_OK; +} + + +static GnomeVFSResult +do_close_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + CDDAContext *cdda_context = (CDDAContext *)method_handle; + + //g_message ("cdda do_close_directory"); + + if (cdda_context == NULL) { + //g_message ("cdda do_close_directory: NULL cdda context"); + return GNOME_VFS_ERROR_GENERIC; + } + + cdda_context->access_count = 0; + + return GNOME_VFS_OK; +} + +static int +get_data_size (cdrom_drive *drive, int track) +{ + int minutes, seconds, total_seconds, size; + + size = 0; + + if (cdda_track_audiop (drive, track)) { + long sec = cdda_track_firstsector (drive, track); + long off = cdda_track_lastsector (drive, track) - sec + 1; + + minutes = off / (60 * 75); + seconds = (off / 75) % 60; + + total_seconds = (minutes * 60) + seconds; + size = ((total_seconds * 44) * 2 * 2) * 1024; + } + + //g_message ("get_data_size: %d", size); + + return size; +} + +#if 0 +static int +get_data_size_from_uri (GnomeVFSURI *uri, CDDAContext *context) +{ + int minutes, seconds, total_seconds, size, index; + const char *base_name; + + size = -1; + + if (context == NULL) { + return size; + } + + base_name = gnome_vfs_uri_extract_short_path_name (uri); + + // Check and see if filename is in cddb data list + for (index = 0; index < context->drive->tracks; index++) { + if (strcmp (base_name, context->disc_data.data_track[index].track_name) == 0) { + if (cdda_track_audiop (context->drive, index+1)) { + long sec = cdda_track_firstsector (context->drive, index+1); + long off = cdda_track_lastsector (context->drive, index+1) - sec + 1; + + minutes = off / (60 * 75); + seconds = (off / 75) % 60; + + total_seconds = (minutes * 60) + seconds; + size = ((total_seconds * 44) * 2 * 2) * 1024; + } + g_free (base_name); + return size; + } + } + g_free (base_name); + return size; +} +#endif + +static GnomeVFSResult +do_read_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSContext *context) +{ + + CDDAContext *cdda_context = (CDDAContext *) method_handle; + + //g_message ("cdda do_read_directory"); + + if (cdda_context == NULL) { + g_warning ("do_read_directory: NULL context"); + return GNOME_VFS_ERROR_GENERIC; + } + + if (cdda_context->access_count >= cdda_context->drive->tracks) { + //g_message ("do_read_directory: over access count"); + return GNOME_VFS_ERROR_EOF; + } + + cdda_context->access_count++; + + /* Populate file info */ + file_info->io_block_size = CD_FRAMESIZE_RAW; + file_info->size = get_data_size (cdda_context->drive, cdda_context->access_count); + file_info->atime = time (NULL); + file_info->ctime = time (NULL); + file_info->mtime = time (NULL); + if (cdda_context->use_cddb) { + file_info->name = g_strdup (cdda_context->disc_data.data_track[cdda_context->access_count-1].track_name); + } else { + file_info->name = g_strdup_printf ("Untitled %d", cdda_context->access_count); + } + file_info->type = GNOME_VFS_FILE_TYPE_REGULAR; + file_info->mime_type = g_strdup ("audio/x-wav"); + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_TYPE | + GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE | + GNOME_VFS_FILE_INFO_FIELDS_SIZE | + GNOME_VFS_FILE_INFO_FIELDS_IO_BLOCK_SIZE | + GNOME_VFS_FILE_INFO_FIELDS_ATIME | + GNOME_VFS_FILE_INFO_FIELDS_MTIME | + GNOME_VFS_FILE_INFO_FIELDS_CTIME; + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_check_same_fs (GnomeVFSMethod *method, + GnomeVFSURI *a, + GnomeVFSURI *b, + gboolean *same_fs_return, + GnomeVFSContext *context) +{ + *same_fs_return = TRUE; + + return GNOME_VFS_OK; +} + +static gboolean +do_is_local (GnomeVFSMethod *method, const GnomeVFSURI *uri) +{ + return TRUE; +} + + +static GnomeVFSMethod method = { + sizeof (GnomeVFSMethod), + do_open, + NULL, /* do_create */ + do_close, + do_read, /* do_read */ + NULL, /* do_write */ + NULL, /* seek */ + NULL, /* tell */ + NULL, /* truncate */ + do_open_directory, + do_close_directory, + do_read_directory, + do_get_file_info, + NULL, + do_is_local, + NULL, /* make directory */ + NULL, /* remove directory */ + NULL, /* rename */ + NULL, /* unlink */ + do_check_same_fs, + NULL, /* do_set_file_info */ + NULL, /* do_truncate */ + NULL, /* do_find_directory */ + NULL /* do_create_symbolic_link */ +}; + +#if 0 +static void +put_num (long num, int f, int endianness, int bytes) +{ + int i; + unsigned char c; + + if (!endianness) { + i = 0; + } else { + i = bytes - 1; + } + + while (bytes--){ + c = (num >> (i << 3)) & 0xff; + if (write (f, &c, 1) == -1) { + perror ("Could not write to output."); + exit (1); + } + + if (endianness) { + i--; + } else { + i++; + } + } +} +#endif + + +/* Write WAV header information into memory buffer */ +#if 0 +static int +write_wav_header (gpointer buffer, long bytes) +{ + char *ptr; + + memset (buffer, 0, CD_FRAMESIZE_RAW); + + ptr = buffer; + + *ptr = "RIFF"; ptr += 4; + *ptr = bytes + 44 - 8; ptr += 4; + *ptr = "WAVEfmt "; ptr += 8; + *ptr = 16; ptr += 4; + *ptr = 1; ptr += 2; + *ptr = 2; ptr += 2; + *ptr = 44100; ptr += 4; + *ptr = 44100 * 2 * 2; ptr += 4; + *ptr = 4; ptr += 2; + *ptr = 16; ptr += 2; + *ptr = "data"; ptr += 4; + *ptr = bytes; ptr += 4; + + return 44; +} +#endif + +static int +write_wav_header (gpointer buffer, long bytes) +{ + char *ptr; + int var; + + memset (buffer, 0, CD_FRAMESIZE_RAW); + + ptr = buffer; + + memcpy (ptr, "RIFF", 4); ptr += 4; + + var = bytes + 44 - 8; + memcpy (ptr, &var, 4); ptr += 4; + + memcpy (ptr, "WAVEfmt ", 8); ptr += 8; + + var = 16; + memcpy (ptr, &var, 4); ptr += 4; + + var = 1; + memcpy (ptr, &var, 2); ptr += 2; + + var = 2; + memcpy (ptr, &var, 2); ptr += 2; + + var = 44100; + memcpy (ptr, &var, 4); ptr += 4; + + var = 44100 * 2 * 2; + memcpy (ptr, &var, 4); ptr += 4; + + var = 4; + memcpy (ptr, &var, 2); ptr += 2; + + var = 16; + memcpy (ptr, &var, 2); ptr += 2; + + memcpy (ptr, "data", 4); ptr += 4; + + memcpy (ptr, &bytes, 4); ptr += 4; + + return 44; +} + +GnomeVFSMethod * +vfs_module_init (const char *method_name, + const char *args) +{ + char *argv[] = { "gnome-vfs-cdda-module", NULL }; + + if (!gconf_is_initialized ()) { + gconf_init (1, argv, NULL); + } + + return &method; +} + +void +vfs_module_shutdown (GnomeVFSMethod *method) +{ +} diff --git a/modules/cdda-module.conf b/modules/cdda-module.conf new file mode 100644 index 0000000..07ea518 --- /dev/null +++ b/modules/cdda-module.conf @@ -0,0 +1 @@ +cdda: cdda diff --git a/modules/cdemenu-desktop-method.c b/modules/cdemenu-desktop-method.c new file mode 100644 index 0000000..83a4773 --- /dev/null +++ b/modules/cdemenu-desktop-method.c @@ -0,0 +1,736 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: 4; c-basic-offset: 4 -*- */ + +/* cdemenu-desktop--method.c + + Author: Stephen Browne + + Copyright (C) 2002 Sun Microsystems, Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#define LINESIZE 1024 +#define CDE_ICON_NAME_CACHE "/.gnome/g-cdeiconnames" + +static GSList *cdemenufiles; + +typedef struct _DtFile DtFile; + +struct _DtFile { + gchar *contents; + gchar *current; +}; + +static GnomeVFSMethod *parent_method = NULL; + +static gchar * +find_title_for_menu (gchar *name) +{ + GSList *filename; + char line[LINESIZE]; + gboolean found=FALSE; + char *title="\0"; + FILE *file = NULL; + gchar *tmp=NULL; + + for (filename = cdemenufiles; filename !=NULL; filename=filename->next){ + file = fopen((gchar*)filename->data,"r"); + while (fgets(line,LINESIZE,file) != NULL){ + if (strstr(line,"f.menu") && strstr(line, name)) { + tmp = strstr (line, "f.menu"); + *tmp = '\0'; + title = strdup (line); + found = TRUE; + break; + } + } + fclose (file); + file = NULL; + if (found) break; + } + return title; +} + +static FILE * +open_and_find_pointer_to_menu(gchar *name) +{ + GSList *filename; + gchar line[LINESIZE]; + FILE *filesave = NULL, *file = NULL; + glong position = 0; + gboolean found = FALSE; + + for (filename = cdemenufiles; filename !=NULL; filename=filename->next){ + found = FALSE; + file = fopen((gchar*)filename->data,"r"); + while (fgets(line,LINESIZE,file) != NULL){ + if (strstr(line,"Menu") == line) { + char *temp = NULL; + + temp = (strtok(line," ")); + + if (!temp) + temp = (strtok(line,"\t")); + + while (temp) { + temp = g_strstrip(temp); + if (temp && !(strcmp(temp,name))) { + found = TRUE; + position = ftell (file); + break; + } + temp = (strtok (NULL," ")); + if (!temp) + temp = (strtok (NULL,"\t")); + } + } + } + if (found) { + fseek (file, position, SEEK_SET); + if (filesave !=NULL) fclose(filesave); + filesave = file; + if (!strcmp(name, "DtRootMenu")) break; + } else { + fclose(file); + file=NULL; + } + } + return filesave; +} + +static char * +expand_env_vars(char *s) +{ + char **tokens, **token; + char *tmp, *tmp2; + const char *tmp3; + char *expanded; + tokens = g_strsplit(s,"/",30); + for (token = tokens; *token !=NULL; token++) { + if (**token=='$'){ + tmp = *token+1; + if (*tmp == '{'){ + tmp++; + tmp2 = tmp+(strlen(tmp))-1; *tmp2='\0'; + } + tmp3 = g_getenv(tmp); + if (!tmp3 && strstr(tmp, "LC_CTYPE")) + /* It's not always the case $LC_CTYPE or $LANG is set */ + tmp3 = (char*)setlocale(LC_CTYPE, NULL); + g_free(*token); + /* don't do g_strdup (s?s1:s2) as that doesn't work with + certain gcc 2.96 versions */ + *token = tmp3 ? g_strdup(tmp3) : g_strdup(""); + } + } + expanded = g_strjoinv("/", tokens); + g_strfreev(tokens); + return expanded; +} + +/* This function is only used to make the default CDE menu look nice */ +static char* +get_icon_for_menu (char *name) +{ + /* Translate exactly the same in CDE's sys.dtwmrc file of the locale */ + if (!strcmp(name, _("Applications"))) + return ("/usr/dt/appconfig/icons/C/Dtapps.m.pm"); + /* Translate exactly the same in CDE's sys.dtwmrc file of the locale */ + if (!strcmp(name, _("Cards"))) + return ("/usr/dt/appconfig/icons/C/SDtCard.m.pm"); + /* Translate exactly the same in CDE's sys.dtwmrc file of the locale */ + if (!strcmp(name, _("Files"))) + return ("/usr/dt/appconfig/icons/C/Dtdata.m.pm"); + /* Translate exactly the same in CDE's sys.dtwmrc file of the locale */ + if (!strcmp(name, _("Folders"))) + return ("/usr/dt/appconfig/icons/C/DtdirB.m.pm"); + /* Translate exactly the same in CDE's sys.dtwmrc file of the locale */ + if (!strcmp(name, _("Help"))) + return ("/usr/dt/appconfig/icons/C/Dthelp.m.pm"); + /* Translate exactly the same in CDE's sys.dtwmrc file of the locale */ + if (!strcmp(name, _("Hosts"))) + return ("/usr/dt/appconfig/icons/C/Dtterm.m.pm"); + /* Translate exactly the same in CDE's sys.dtwmrc file of the locale */ + if (!strcmp(name, _("Links"))) + return ("/usr/dt/appconfig/icons/C/SDturlweb.m.pm"); + /* Translate exactly the same in CDE's sys.dtwmrc file of the locale */ + if (!strcmp(name, _("Mail"))) + return ("/usr/dt/appconfig/icons/C/Dtmail.m.pm"); + /* Translate exactly the same in CDE's sys.dtwmrc file of the locale */ + if (!strcmp(name, _("Tools"))) + return ("/usr/dt/appconfig/icons/C/SDtGears.m.pm"); + /* Translate exactly the same in CDE's sys.dtwmrc file of the locale */ + if (!strcmp(name, _("Windows"))) + return ("/usr/dt/appconfig/icons/C/DtDtwm.m.pm"); + return (""); +} + +static char* +get_icon_for_action(char *action) +{ + gchar line[LINESIZE]; + FILE *file; + char **dir, *expandeddir, *fullpath=NULL; + char *tmp=NULL; + char *icon_name_cache_path; + + char *iconsearchpath[] = {"/usr/dt/appconfig/icons/$LC_CTYPE", + "/etc/dt/appconfig/icons/$LC_CTYPE", + "$HOME/.dt/icons", + "/usr/dt/appconfig/icons/C", NULL}; + + /*if action has arg strip the arg*/ + if ((tmp=strchr(action,'\"'))) {*tmp='\0'; tmp=NULL;} + + /*Return NULL icon if icon DB does not exist*/ + icon_name_cache_path = g_strconcat (g_get_home_dir (), CDE_ICON_NAME_CACHE, NULL); + file = fopen(icon_name_cache_path,"r"); + g_free(icon_name_cache_path); + if (!file) return NULL; + + while (fgets(line,LINESIZE,file) != NULL){ + if (strstr(line,action)){ + if (fgets(line,LINESIZE,file) != NULL) { + if (strstr(line,"ICON")){ + tmp = strchr(line,':'); + if (tmp == NULL) return NULL; + tmp++; + tmp = g_strstrip(tmp); + for (dir = iconsearchpath; *dir != NULL; dir++) { + expandeddir = expand_env_vars(*dir); + fullpath = g_strdup_printf("%s/%s.m.pm", + expandeddir, tmp); + if (g_file_test(fullpath,G_FILE_TEST_EXISTS)){ + g_free(expandeddir); + break; + } else { + g_free(fullpath); + fullpath = g_strdup_printf("%s/%s.s.pm", + expandeddir, tmp); + if (g_file_test(fullpath,G_FILE_TEST_EXISTS)){ + g_free(expandeddir); + break; + } else g_free (fullpath); + } + } + } + } + break; + } + } + fclose(file); + return fullpath; +} + +static gchar * +get_title (gchar *line) +{ + gchar *tmp; + tmp = strchr (line, '\"'); + if (!tmp) + tmp = g_strstrip (line); + else { + gchar *tmp2; + tmp ++; + tmp2 = strchr (tmp, '\"'); + if(tmp2) *tmp2 = '\0'; + } + return (g_strdup (tmp)); +} + +static GnomeVFSResult +do_open (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + GnomeVFSContext *context) +{ + FILE *file; + gchar *tmp, *tmp2, *end; + gchar *unescaped; + gchar line[LINESIZE]; + gchar *name, *title, *exec=NULL, *icon=NULL; + gchar *menuname = g_path_get_basename(g_path_get_dirname(uri->text)); + DtFile *dtfile = g_new0(DtFile, 1); + + *method_handle = (GnomeVFSMethodHandle *)dtfile; + + if (strcmp(menuname,"/") == 0) menuname = "DtRootMenu"; + unescaped = gnome_vfs_unescape_string (menuname, NULL); + + name = gnome_vfs_unescape_string (g_path_get_basename(uri->text), NULL); + /* Strip off the .desktop if this is a .desktop file */ + tmp = strstr(name,".desktop"); if (tmp) *tmp='\0'; tmp=NULL; + + file = open_and_find_pointer_to_menu (unescaped); + + if (!file) { + g_free (name); + g_free (unescaped); + return GNOME_VFS_ERROR_NOT_FOUND; + } + + if (strcmp(name,".directory") == 0) { + char *utf8_name = NULL; + + if (!strcmp (unescaped, "DtRootMenu")) + title = g_strdup_printf ("\"%s\"",unescaped); + else title = find_title_for_menu (unescaped); + + tmp = get_title (title); + + utf8_name = g_locale_to_utf8 (tmp, -1, + NULL, NULL, + NULL); + /* fallback to avoid crash */ + if (utf8_name == NULL) + utf8_name = g_strdup (tmp); + + dtfile->contents = g_strdup_printf + ("[Desktop Entry]\n" + "Encoding=UTF-8\n" + /* Note that we include the utf-8 + * translated name without a language + * specifier, but that's OK, it will + * work */ + "Name=%s\n" + "Comment=\n" + "Icon=%s\n" + "Type=Directory\n", + utf8_name, + get_icon_for_menu(utf8_name)); + + g_free (utf8_name); + g_free (title); + g_free (tmp); + } else { + while (fgets(line,LINESIZE,file) != NULL){ + if (line[0] == '#') continue; + else if (line[0] == '}') break; + else if (strstr(line,name)){ + if((tmp = strstr(line,"f.action")) != NULL){ + char *utf8_name = NULL; + + tmp+=8; + end = strchr(tmp,'\n'); + if (end) *end='\0'; + exec=g_strdup_printf("dtaction %s",tmp); + icon=get_icon_for_action(tmp); + if (!icon) icon=g_strdup("NONE"); + + utf8_name = g_locale_to_utf8 (name, -1, + NULL, + NULL, + NULL); + /* fallback to avoid crash */ + if (utf8_name == NULL) + utf8_name = g_strdup (name); + + dtfile->contents= g_strdup_printf + ("[Desktop Entry]\n" + "Encoding=UTF-8\n" + /* Note that we include the + * utf-8 translated name + * without a language + * specifier, but that's + * OK, it will work */ + "Name=%s\n" + "Comment=\n" + "Exec=%s\n" + "Icon=%s\n" + "Terminal=0\n" + "Type=Application\n", + utf8_name, + exec, icon); + g_free (utf8_name); + g_free(icon); + } else if ((tmp = strstr(line,"f.exec"))!=NULL){ + char *utf8_name = NULL; + + tmp+=6; + tmp = g_strstrip(tmp); + /* strip off quotes */ + if (*tmp == '\"') tmp++; + end = tmp+(strlen(tmp))-1; + if (*end == '\"') *end = '\0'; + + utf8_name = g_locale_to_utf8 (name, -1, + NULL, + NULL, + NULL); + /* fallback to avoid crash */ + if (utf8_name == NULL) + utf8_name = g_strdup (name); + + dtfile->contents= g_strdup_printf + ("[Desktop Entry]\n" + "Encoding=UTF-8\n" + /* Note that we include the + * utf-8 translated name + * without a language + * specifier, but that's + * OK, it will work */ + "Name=%s\n" + "Comment=\n" + "Exec=%s\n" + "Icon=\n" + "Terminal=0\n" + "Type=Application\n", + utf8_name, tmp); + g_free (utf8_name); + } + } + } + } + + fclose(file); + + dtfile->current=dtfile->contents; + + g_free (unescaped); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_close (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + + DtFile *dtfile = (DtFile*)method_handle; + + g_free(dtfile->contents); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_read (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read, + GnomeVFSContext *context) +{ + int bytes; + DtFile *dtfile = (DtFile *)method_handle; + if (dtfile->current == NULL) return GNOME_VFS_ERROR_EOF; + + bytes = snprintf(buffer, num_bytes, "%s",dtfile->current); + if (bytes == -1 ) dtfile->current+=num_bytes; + else dtfile->current=NULL; + + *bytes_read=(GnomeVFSFileSize)bytes; + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_open_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + FILE *file; + gchar* unescaped; + gchar *menuname = g_path_get_basename(uri->text); + if (strcmp(menuname,"/") == 0) menuname = "DtRootMenu"; + + unescaped = gnome_vfs_unescape_string (menuname, NULL); + + file = open_and_find_pointer_to_menu(unescaped); + + *method_handle = (GnomeVFSMethodHandle *)file; + + g_free (unescaped); + + return file ? GNOME_VFS_OK : GNOME_VFS_ERROR_NOT_FOUND; +} + +static GnomeVFSResult +do_close_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + fclose((FILE *)method_handle); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_read_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSContext *context) +{ + gchar line[LINESIZE]; + gchar *tmp, *tmp2,*escaped_str; + FILE *file = (FILE *)method_handle; + /*static int sep=0;*/ + + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_TYPE; + + while (fgets(line,LINESIZE,file) != NULL){ + if (line[0] == '#') continue; + else if (line[0] == '}') return GNOME_VFS_ERROR_EOF; + else if (strstr(line,"f.action") && (strstr(line,"ExitSession") + || strstr(line,"LockDisplay") + || strstr(line,"AddItemToMenu") + || strstr(line,"CustomizeWorkspaceMenu") + || strstr(line,"UpdateWorkspaceMenu"))) { + file_info->name = g_strdup("bogus.desktop"); + file_info->type = GNOME_VFS_FILE_TYPE_REGULAR; + continue; + } + else if (strstr(line,"f.action") || strstr(line,"f.exec")) { + tmp2 = strstr (line, "f."); + *tmp2 = '\0'; + + tmp = get_title (line); + escaped_str = gnome_vfs_escape_string (tmp); + file_info->name = g_strdup_printf("%s.desktop",escaped_str); + file_info->type = GNOME_VFS_FILE_TYPE_REGULAR; + g_free (escaped_str); + g_free (tmp); + break; + } + /* + else if (strstr(line,"f.separator")) { + file_info->name = g_strdup_printf("separator%d.desktop", + sep); + file_info->type = GNOME_VFS_FILE_TYPE_REGULAR; + sep++; if (sep>10) sep = 0; + break; + } + */ + else if (strstr(line,"f.menu")) { + tmp = strstr(line,"f.menu"); + tmp+=6; + tmp = g_strstrip(tmp); + file_info->name = gnome_vfs_escape_string (tmp); + file_info->type = GNOME_VFS_FILE_TYPE_DIRECTORY; + break; + } + } + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_get_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result; + + char *s; + + /* FIXME: This isnt right at all but it satisfies gnome-vfs for now */ + s = gnome_vfs_get_uri_from_local_path(cdemenufiles->data); + file_uri = gnome_vfs_uri_new(s); + g_free(s); + + result = (* parent_method->get_file_info) (parent_method, + file_uri, + file_info, + options, + context); + gnome_vfs_uri_unref (file_uri); + + return result; +} + +static gboolean +do_is_local (GnomeVFSMethod *method, + const GnomeVFSURI *uri) +{ + /* FIXME: This isn't always true, some cde menu files are remote */ + return TRUE; +} + +/* gnome-vfs bureaucracy */ +static GnomeVFSMethod method = { + sizeof (GnomeVFSMethod), + do_open, + NULL, /* create */ + do_close, + do_read, + NULL, /* write */ + NULL, /* seek */ + NULL, /* tell */ + NULL, /* truncate handle */ + do_open_directory, + do_close_directory, + do_read_directory, + do_get_file_info, + NULL, /* file info from handle */ + do_is_local, + NULL, /* make directory */ + NULL, /* remove directory */ + NULL, /* move */ + NULL, /* unlink */ + NULL, /* same fs */ + NULL, /* set file info */ + NULL, /* truncate */ + NULL, /* find directory */ + NULL /* symbolic link */ +}; + +static void +find_all_included_files(gchar *filename) +{ + FILE *file; + gchar line[LINESIZE]; + gchar *tmp, *expanded; + file = fopen(filename,"r"); + while (fgets(line,LINESIZE,file) != NULL){ + if (g_ascii_strncasecmp(line, "Include",7) == 0) { + while (fgets(line,LINESIZE,file) !=NULL){ + if (line[0] == '#') continue; + if (line[0] == '{') continue; + else if (line[0] == '}') break; + tmp = g_strstrip(line); + if (tmp[0] == '\0') continue; + expanded = expand_env_vars(tmp); + if (g_file_test(expanded,G_FILE_TEST_EXISTS)){ + cdemenufiles = g_slist_append(cdemenufiles, + g_strdup(expanded)); + find_all_included_files(expanded); + } + free(expanded); + } + } + } + fclose(file); +} + +static void +create_cde_icon_name_cache (void) +{ + /* fork the dttypes command to create the icon name cache */ + int fd, t; + mode_t old_mask; + char *icon_name_cache_path; + + if ((t = fork ()) < 0) { + g_error ("Unable to fork."); + } else if (t) { + /* On a Solaris box, waitpid() fails with an interrupted system call. + Hence, loop till it succeeds. Avoids zombies + */ + while ((waitpid (t,NULL,0) == -1) && errno == EINTR); + } else { + icon_name_cache_path = g_strconcat (g_get_home_dir (), CDE_ICON_NAME_CACHE, NULL); + old_mask = umask(033); + fd = open (icon_name_cache_path, O_WRONLY | O_CREAT | O_TRUNC, 0644); + dup2 (fd, 1); + fchmod (fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + g_free(icon_name_cache_path); + umask(old_mask); + execl("/usr/dt/bin/dttypes", "dttypes", "-w", "fld_name", "ICON", + "-l", "fld_name", "ICON", NULL); + } +} + +GnomeVFSMethod * +vfs_module_init (const char *method_name, + const char *args) +{ + gchar *files[7]; + int i; + char *icon_name_cache_path; + + parent_method = gnome_vfs_method_get ("file"); + + if (parent_method == NULL) { + g_error ("Could not find 'file' method for gnome-vfs"); + return NULL; + } + + /* find the right cde menu file to start with */ + cdemenufiles = NULL; + files[0] = expand_env_vars("$HOME/.dt/$LC_CTYPE/dtwmrc"); + files[1] = expand_env_vars("$HOME/.dt/dtwmrc"); + files[2] = expand_env_vars("/etc/dt/config/$LC_CTYPE/sys.dtwmrc"); + files[3] = g_strdup("/etc/dt/config/sys.dtwmrc"); + files[4] = expand_env_vars("/usr/dt/config/$LC_CTYPE/sys.dtwmrc"); + files[5] = g_strdup("/usr/dt/config/sys.dtwmrc"); + files[6] = g_strdup("/usr/dt/config/C/sys.dtwmrc"); + + for (i=0;i<7;i++){ + if (g_file_test(files[i],G_FILE_TEST_EXISTS)){ + cdemenufiles = g_slist_append(cdemenufiles, + g_strdup(files[i])); + break; + } + } + for (i=0;i<7;i++) g_free(files[i]); + + /* if didnt find any menu start file then we are fecked */ + if (cdemenufiles == NULL) return NULL; + + /* from that file find a list of all included files */ + find_all_included_files(cdemenufiles->data); + + /*create the icon name cache if it does not exist*/ + icon_name_cache_path = g_strconcat (g_get_home_dir (), CDE_ICON_NAME_CACHE, NULL); + if (!g_file_test(icon_name_cache_path, G_FILE_TEST_EXISTS)) + create_cde_icon_name_cache(); + + g_free(icon_name_cache_path); + return &method; +} + +void +vfs_module_shutdown (GnomeVFSMethod *method) +{ + /* free up any stuff in here */ + + g_slist_foreach(cdemenufiles, (GFunc)g_free, NULL); + g_slist_free(cdemenufiles); +} + diff --git a/modules/cdemenu-module.conf b/modules/cdemenu-module.conf new file mode 100644 index 0000000..3376ba0 --- /dev/null +++ b/modules/cdemenu-module.conf @@ -0,0 +1 @@ +cdemenu: cdemenu-desktop diff --git a/modules/default-modules.conf b/modules/default-modules.conf new file mode 100644 index 0000000..6db996c --- /dev/null +++ b/modules/default-modules.conf @@ -0,0 +1,51 @@ +# +# Module configuration file for the GNOME Virtual File System. +# +# Syntax: +# +# ... : +# + +bzip2: bzip2 + +cdda: cdda + +file: file + +test: vfs-test + +ftp: ftp + +nntp: nntp + +gzip ugzip: gzip + +http: http + +dav: http + +pipe: vfs-pipe + +#efs: vefs + +#nfs: nfs + +ssh: ssh + +# The various access methods implemented by the extfs system. +a ar arj cpio deb hp48 lha mailfs patchfs rar rpm rpms trpm zip zoo: extfs + +# vfolder desktop method +applications: vfolder-desktop-old +applications-all-users: vfolder-desktop-old +all-applications: vfolder-desktop-old +all-preferences: vfolder-desktop-old +favorites: desktop +network: desktop +preferences: vfolder-desktop-old +preferences-all-users: vfolder-desktop-old +server-settings: vfolder-desktop-old +start-here: desktop +system-settings: vfolder-desktop-old + +tar: tar diff --git a/modules/default-modules.conf.modules-conf b/modules/default-modules.conf.modules-conf new file mode 100644 index 0000000..439bbfd --- /dev/null +++ b/modules/default-modules.conf.modules-conf @@ -0,0 +1,51 @@ +# +# Module configuration file for the GNOME Virtual File System. +# +# Syntax: +# +# ... : +# + +bzip2: bzip2 + +cdda: cdda + +file: file + +test: vfs-test + +ftp: ftp + +nntp: nntp + +gzip ugzip: gzip + +http: http + +dav: http + +pipe: vfs-pipe + +#efs: vefs + +#nfs: nfs + +ssh: ssh + +# The various access methods implemented by the extfs system. +a ar arj cpio deb hp48 lha mailfs patchfs rar rpm rpms trpm zip zoo: extfs + +# vfolder desktop method +applications: vfolder-desktop +applications-all-users: vfolder-desktop +all-applications: vfolder-desktop +preferences: vfolder-desktop +preferences-all-users: vfolder-desktop +all-preferences: vfolder-desktop +favorites: vfolder-desktop +network: vfolder-desktop +start-here: vfolder-desktop +system-settings: vfolder-desktop +server-settings: vfolder-desktop + +tar: tar diff --git a/modules/default-modules.conf.with-menu-editing b/modules/default-modules.conf.with-menu-editing new file mode 100644 index 0000000..439bbfd --- /dev/null +++ b/modules/default-modules.conf.with-menu-editing @@ -0,0 +1,51 @@ +# +# Module configuration file for the GNOME Virtual File System. +# +# Syntax: +# +# ... : +# + +bzip2: bzip2 + +cdda: cdda + +file: file + +test: vfs-test + +ftp: ftp + +nntp: nntp + +gzip ugzip: gzip + +http: http + +dav: http + +pipe: vfs-pipe + +#efs: vefs + +#nfs: nfs + +ssh: ssh + +# The various access methods implemented by the extfs system. +a ar arj cpio deb hp48 lha mailfs patchfs rar rpm rpms trpm zip zoo: extfs + +# vfolder desktop method +applications: vfolder-desktop +applications-all-users: vfolder-desktop +all-applications: vfolder-desktop +preferences: vfolder-desktop +preferences-all-users: vfolder-desktop +all-preferences: vfolder-desktop +favorites: vfolder-desktop +network: vfolder-desktop +start-here: vfolder-desktop +system-settings: vfolder-desktop +server-settings: vfolder-desktop + +tar: tar diff --git a/modules/desktop-method.c b/modules/desktop-method.c new file mode 100644 index 0000000..87f327d --- /dev/null +++ b/modules/desktop-method.c @@ -0,0 +1,985 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: 8; c-basic-offset: 8 -*- */ + +/* desktop-method.c + + Copyright (C) 2001 Red Hat, Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/* URI scheme for remapping directories under magic URIs, used + * for the magic desktop file directories such as start-here. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +/* FIXME Maybe when chaining to file:, we should call the gnome-vfs wrapper + * functions, instead of the file: methods directly. + */ + +#define N_ELEMENTS(arr) (sizeof (arr) / sizeof ((arr)[0])) + +static GnomeVFSURI* desktop_uri_to_file_uri (GnomeVFSURI *desktop_uri); + +static GnomeVFSResult open_merged_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context); + +static char* create_file_uri_in_dir (const char *dir, + const char *filename); + +static GnomeVFSMethod *parent_method = NULL; + +static GnomeVFSResult +do_open (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result; + + file_uri = desktop_uri_to_file_uri (uri); + result = (* parent_method->open) (parent_method, + method_handle, + file_uri, + mode, + context); + gnome_vfs_uri_unref (file_uri); + + return result; +} + +static GnomeVFSResult +do_create (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + gboolean exclusive, + guint perm, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result; + + file_uri = desktop_uri_to_file_uri (uri); + result = (* parent_method->create) (parent_method, + method_handle, + file_uri, + mode, + exclusive, + perm, + context); + gnome_vfs_uri_unref (file_uri); + + return result; +} + +static GnomeVFSResult +do_close (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + + result = (* parent_method->close) (parent_method, + method_handle, + context); + + return result; +} + +static GnomeVFSResult +do_read (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + + result = (* parent_method->read) (parent_method, + method_handle, + buffer, num_bytes, + bytes_read, + context); + + return result; +} + +static GnomeVFSResult +do_write (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gconstpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_written, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + + result = (* parent_method->write) (parent_method, + method_handle, + buffer, num_bytes, + bytes_written, + context); + + return result; +} + + +static GnomeVFSResult +do_seek (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSSeekPosition whence, + GnomeVFSFileOffset offset, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + + result = (* parent_method->seek) (parent_method, + method_handle, + whence, offset, + context); + + return result; +} + +static GnomeVFSResult +do_tell (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileOffset *offset_return) +{ + GnomeVFSResult result; + + result = (* parent_method->tell) (parent_method, + method_handle, + offset_return); + + return result; +} + + +static GnomeVFSResult +do_truncate_handle (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileSize where, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + + result = (* parent_method->truncate_handle) (parent_method, + method_handle, + where, + context); + + return result; +} + +static GnomeVFSResult +do_truncate (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileSize where, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result; + + file_uri = desktop_uri_to_file_uri (uri); + result = (* parent_method->truncate) (parent_method, + file_uri, + where, + context); + + gnome_vfs_uri_unref (file_uri); + + return result; +} + +typedef struct _DirHandle DirHandle; + +struct _DirHandle +{ + GSList *next; + GSList *handles; +}; + +static GnomeVFSResult +do_open_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + return open_merged_directory (method, method_handle, + uri, options, context); +} + +static GnomeVFSResult +do_close_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + GSList *tmp; + DirHandle *dh; + + dh = (DirHandle*) method_handle; + + result = GNOME_VFS_OK; + tmp = dh->handles; + while (tmp != NULL) { + GnomeVFSResult this_result; + + this_result = (* parent_method->close_directory) (parent_method, + tmp->data, + context); + + if (this_result != GNOME_VFS_OK) + result = this_result; + + tmp = tmp->next; + } + + g_slist_free (dh->handles); + g_free (dh); + + return result; +} + +static GnomeVFSResult +do_read_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + GnomeVFSMethodHandle *parent_handle; + DirHandle *dh; + + dh = (DirHandle*) method_handle; + + if (dh->next == NULL) { + return GNOME_VFS_ERROR_EOF; + } + + next: + parent_handle = dh->next->data; + + result = (* parent_method->read_directory) (parent_method, + parent_handle, + file_info, + context); + + if (result != GNOME_VFS_OK) { + dh->next = dh->next->next; + if (dh->next) + goto next; + else + return result; + } else { + return GNOME_VFS_OK; + } +} + + +static void +set_directory_mime_type (GnomeVFSFileInfo *file_info) +{ + g_free (file_info->mime_type); + + file_info->mime_type = g_strdup ("x-directory/vfolder-desktop"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; +} + +static GnomeVFSResult +do_get_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result; + + file_uri = desktop_uri_to_file_uri (uri); + result = (* parent_method->get_file_info) (parent_method, + file_uri, + file_info, + options, + context); + + if (file_info->type == GNOME_VFS_FILE_TYPE_DIRECTORY) + set_directory_mime_type (file_info); + + gnome_vfs_uri_unref (file_uri); + + return result; +} + +static GnomeVFSResult +do_get_file_info_from_handle (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + + result = (* parent_method->get_file_info_from_handle) (parent_method, + method_handle, + file_info, + options, + context); + + if (file_info->type == GNOME_VFS_FILE_TYPE_DIRECTORY) + set_directory_mime_type (file_info); + + return result; +} + + +static gboolean +do_is_local (GnomeVFSMethod *method, + const GnomeVFSURI *uri) +{ + return TRUE; +} + + +static GnomeVFSResult +do_make_directory (GnomeVFSMethod *method, + GnomeVFSURI *uri, + guint perm, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result; + + file_uri = desktop_uri_to_file_uri (uri); + result = (* parent_method->make_directory) (parent_method, + file_uri, + perm, + context); + + gnome_vfs_uri_unref (file_uri); + + return result; +} + +static GnomeVFSResult +do_remove_directory (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result; + + file_uri = desktop_uri_to_file_uri (uri); + result = (* parent_method->remove_directory) (parent_method, + file_uri, + context); + + gnome_vfs_uri_unref (file_uri); + + return result; +} + +static GnomeVFSResult +do_find_directory (GnomeVFSMethod *method, + GnomeVFSURI *near_uri, + GnomeVFSFindDirectoryKind kind, + GnomeVFSURI **result_uri, + gboolean create_if_needed, + gboolean find_if_needed, + guint permissions, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSURI *file_result_uri; + GnomeVFSResult result; + + file_result_uri = NULL; + file_uri = desktop_uri_to_file_uri (near_uri); + result = (* parent_method->find_directory) (parent_method, + file_uri, + kind, + &file_result_uri, + create_if_needed, + find_if_needed, + permissions, + context); + + gnome_vfs_uri_unref (file_uri); + + if (result_uri) + *result_uri = file_result_uri; + + if (file_result_uri == NULL) + result = GNOME_VFS_ERROR_NOT_FOUND; + + return result; +} + +static GnomeVFSResult +do_move (GnomeVFSMethod *method, + GnomeVFSURI *old_uri, + GnomeVFSURI *new_uri, + gboolean force_replace, + GnomeVFSContext *context) +{ + GnomeVFSURI *old_file_uri; + GnomeVFSURI *new_file_uri; + GnomeVFSResult result; + + old_file_uri = desktop_uri_to_file_uri (old_uri); + new_file_uri = desktop_uri_to_file_uri (new_uri); + + result = (* parent_method->move) (parent_method, + old_file_uri, + new_file_uri, + force_replace, + context); + gnome_vfs_uri_unref (old_file_uri); + gnome_vfs_uri_unref (new_file_uri); + + return result; +} + +static GnomeVFSResult +do_unlink (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result; + + file_uri = desktop_uri_to_file_uri (uri); + result = (* parent_method->unlink) (parent_method, + file_uri, + context); + + gnome_vfs_uri_unref (file_uri); + + return result; +} + +static GnomeVFSResult +do_create_symbolic_link (GnomeVFSMethod *method, + GnomeVFSURI *uri, + const char *target_reference, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result; + + file_uri = desktop_uri_to_file_uri (uri); + result = (* parent_method->create_symbolic_link) (parent_method, + file_uri, + target_reference, + context); + + gnome_vfs_uri_unref (file_uri); + + return result; +} + +static GnomeVFSResult +do_check_same_fs (GnomeVFSMethod *method, + GnomeVFSURI *source_uri, + GnomeVFSURI *target_uri, + gboolean *same_fs_return, + GnomeVFSContext *context) +{ + GnomeVFSURI *source_file_uri; + GnomeVFSURI *target_file_uri; + GnomeVFSResult result; + + source_file_uri = desktop_uri_to_file_uri (source_uri); + target_file_uri = desktop_uri_to_file_uri (target_uri); + + result = (* parent_method->check_same_fs) (parent_method, + source_file_uri, + target_file_uri, + same_fs_return, + context); + gnome_vfs_uri_unref (source_file_uri); + gnome_vfs_uri_unref (target_file_uri); + + return result; +} + +static GnomeVFSResult +do_set_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + const GnomeVFSFileInfo *info, + GnomeVFSSetFileInfoMask mask, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result; + + file_uri = desktop_uri_to_file_uri (uri); + result = (* parent_method->set_file_info) (parent_method, + file_uri, + info, + mask, + context); + + gnome_vfs_uri_unref (file_uri); + + return result; +} + +typedef struct { + GnomeVFSMonitorHandle *handle; + GnomeVFSURI *desktop_uri; +} DesktopMonitorHandle; + +static void +monitor_notify_cb (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + DesktopMonitorHandle *monitor_handle; + GnomeVFSURI *desktop_info_uri; + const gchar *uri_diff; + gint monitor_uri_len; + + monitor_handle = (DesktopMonitorHandle *) user_data; + desktop_info_uri = NULL; + monitor_uri_len = strlen (monitor_uri); + + if (info_uri != NULL && + strncmp (info_uri, monitor_uri, monitor_uri_len) == 0) { + uri_diff = &info_uri [monitor_uri_len]; + + if (*uri_diff != '\0') { + desktop_info_uri = + gnome_vfs_uri_append_string ( + monitor_handle->desktop_uri, + uri_diff); + } else { + desktop_info_uri = monitor_handle->desktop_uri; + gnome_vfs_uri_ref (desktop_info_uri); + } + } + + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *) monitor_handle, + desktop_info_uri, + event_type); + + gnome_vfs_uri_unref (desktop_info_uri); +} + +static GnomeVFSResult +do_monitor_add (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle_return, + GnomeVFSURI *uri, + GnomeVFSMonitorType monitor_type) +{ + DesktopMonitorHandle *monitor_handle; + GnomeVFSURI *file_uri; + GnomeVFSResult result; + + monitor_handle = g_new0 (DesktopMonitorHandle, 1); + monitor_handle->desktop_uri = uri; + gnome_vfs_uri_ref (uri); + + file_uri = desktop_uri_to_file_uri (uri); + result = _gnome_vfs_monitor_do_add (parent_method, + &monitor_handle->handle, + file_uri, + monitor_type, + monitor_notify_cb, + monitor_handle); + gnome_vfs_uri_unref (file_uri); + + if (result != GNOME_VFS_OK) { + gnome_vfs_uri_unref (monitor_handle->desktop_uri); + g_free (monitor_handle); + } + + *method_handle_return = (GnomeVFSMethodHandle *) monitor_handle; + + return result; +} + +static GnomeVFSResult +do_monitor_cancel (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle) +{ + DesktopMonitorHandle *monitor_handle; + GnomeVFSResult result; + + monitor_handle = (DesktopMonitorHandle *) method_handle; + + result = _gnome_vfs_monitor_do_cancel (monitor_handle->handle); + + gnome_vfs_uri_unref (monitor_handle->desktop_uri); + g_free (monitor_handle); + + return result; +} + + + +/* gnome-vfs bureaucracy */ + +static GnomeVFSMethod method = { + sizeof (GnomeVFSMethod), + do_open, + do_create, + do_close, + do_read, + do_write, + do_seek, + do_tell, + do_truncate_handle, + do_open_directory, + do_close_directory, + do_read_directory, + do_get_file_info, + do_get_file_info_from_handle, + do_is_local, + do_make_directory, + do_remove_directory, + do_move, + do_unlink, + do_check_same_fs, + do_set_file_info, + do_truncate, + do_find_directory, + do_create_symbolic_link, + do_monitor_add, + do_monitor_cancel +}; + + +typedef enum +{ + SCHEME_FAVORITES, + SCHEME_PREFERENCES, + SCHEME_START_HERE, + SCHEME_SYSTEM_SETTINGS, + SCHEME_SERVER_SETTINGS, + SCHEME_PROGRAMS, + SCHEME_NETWORK +} SchemeID; + +#define MAX_DIRECTORIES 3 +#define DIRECTORIES_INITIALIZER { NULL, NULL, NULL } + +typedef struct _SchemeDescription SchemeDescription; + +struct _SchemeDescription +{ + SchemeID id; + + const char *scheme; + + char *directories[MAX_DIRECTORIES]; +}; + +static SchemeDescription schemes[] = +{ + { SCHEME_FAVORITES, "favorites", + DIRECTORIES_INITIALIZER }, + { SCHEME_PREFERENCES, "preferences", + DIRECTORIES_INITIALIZER }, + { SCHEME_START_HERE, "start-here", + DIRECTORIES_INITIALIZER }, + { SCHEME_SYSTEM_SETTINGS, "system-settings", + DIRECTORIES_INITIALIZER }, + { SCHEME_SERVER_SETTINGS, "server-settings", + DIRECTORIES_INITIALIZER }, + { SCHEME_PROGRAMS, "programs", + DIRECTORIES_INITIALIZER }, + { SCHEME_NETWORK, "network", + DIRECTORIES_INITIALIZER } +}; + +GnomeVFSMethod * +vfs_module_init (const char *method_name, + const char *args) +{ + int i; + + parent_method = gnome_vfs_method_get ("file"); + + if (parent_method == NULL) { + g_error ("Could not find 'file' method for gnome-vfs"); + return NULL; + } + + i = 0; + while (i < N_ELEMENTS (schemes)) { + switch (schemes[i].id) { + case SCHEME_FAVORITES: + schemes[i].directories[0] = + g_strconcat (g_get_home_dir (), + "/.gnome/apps", + NULL); + break; + case SCHEME_PREFERENCES: + /* FIXME I think the GNOME 2 control center will move + * this, but we don't know where to yet + */ + schemes[i].directories[0] = + g_strconcat (DATADIR, "/control-center/capplets", NULL); + break; + case SCHEME_START_HERE: + schemes[i].directories[0] = g_strconcat (SYSCONFDIR, + "/X11/starthere", + NULL); + break; + case SCHEME_SYSTEM_SETTINGS: + schemes[i].directories[0] = + g_strconcat (SYSCONFDIR, "/X11/sysconfig", NULL); + break; + case SCHEME_SERVER_SETTINGS: + schemes[i].directories[0] = + g_strconcat (SYSCONFDIR, "/X11/serverconfig", NULL); + break; + case SCHEME_PROGRAMS: + schemes[i].directories[0] = g_strconcat (SYSCONFDIR, + "/X11/applnk", + NULL); + schemes[i].directories[1] = + g_strconcat (DATADIR, "gnome/apps", NULL); + break; + case SCHEME_NETWORK: + schemes[i].directories[0] = + g_build_filename (DATADIR, "gnome/network", NULL); + break; + default: + g_assert_not_reached (); + break; + } + + ++i; + } + + return &method; +} + +void +vfs_module_shutdown (GnomeVFSMethod *method) +{ + int i; + + i = 0; + while (i < N_ELEMENTS (schemes)) { + int j; + + j = 0; + while (j < MAX_DIRECTORIES) { + g_free (schemes[i].directories[j]); + schemes[i].directories[j] = NULL; + ++j; + } + + ++i; + } +} + + + +static const SchemeDescription* +get_desc_for_uri (GnomeVFSURI *desktop_uri) +{ + const SchemeDescription *desc; + int i; + const char *scheme; + + scheme = gnome_vfs_uri_get_scheme (desktop_uri); + + desc = NULL; + i = 0; + while (i < N_ELEMENTS (schemes)) { + if (strcmp (schemes[i].scheme, scheme) == 0) { + desc = &schemes[i]; + break; + } + + ++i; + } + + return desc; +} + +static GnomeVFSURI* +desktop_uri_to_file_uri (GnomeVFSURI *desktop_uri) +{ + const SchemeDescription *desc; + GnomeVFSURI *new_uri; + const char *path; + int i; + + desc = get_desc_for_uri (desktop_uri); + + if (desc == NULL) { + gnome_vfs_uri_ref (desktop_uri); + return desktop_uri; + } + + /* Prepend the base for the desktop URI. + * If the SchemeDescription contains > 1 directory, we use the directory + * after the first if the given file actually exists there. + */ + new_uri = NULL; + path = gnome_vfs_uri_get_path (desktop_uri); + i = 0; + while (desc->directories[i]) + ++i; + do { + char *s; + + --i; + + s = create_file_uri_in_dir (desc->directories[i], path); + + new_uri = gnome_vfs_uri_new (s); + + g_free (s); + + if (i == 0 || + gnome_vfs_uri_exists (new_uri)) { + return new_uri; + } else { + gnome_vfs_uri_unref (new_uri); + new_uri = NULL; + } + } while (i > 0); + + + g_assert_not_reached (); + + return NULL; +} + + +static GnomeVFSResult +open_merged_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *desktop_uri, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + DirHandle *dh; + const SchemeDescription *desc; + int i; + gboolean found; + const char *path; + + desc = get_desc_for_uri (desktop_uri); + + if (desc == NULL) { + return GNOME_VFS_ERROR_NOT_FOUND; + } + + dh = g_new0 (DirHandle, 1); + + /* Prepend the base for the desktop URI. + * If the SchemeDescription contains > 1 directory, we use the directory + * after the first if the given file actually exists there. + */ + found = FALSE; + path = gnome_vfs_uri_get_path (desktop_uri); + i = 0; + while (desc->directories[i]) { + char *s; + GnomeVFSURI *file_uri; + GnomeVFSMethodHandle *parent_handle = NULL; + + s = create_file_uri_in_dir (desc->directories[i], path); + + file_uri = gnome_vfs_uri_new (s); + + g_free (s); + + result = (* parent_method->open_directory) (parent_method, + &parent_handle, + file_uri, + options, + context); + + if (result == GNOME_VFS_OK) { + found = TRUE; + dh->handles = g_slist_prepend (dh->handles, parent_handle); + } + + gnome_vfs_uri_unref (file_uri); + + ++i; + } + + dh->next = dh->handles; + + *method_handle = (GnomeVFSMethodHandle*) dh; + + return found ? GNOME_VFS_OK : GNOME_VFS_ERROR_NOT_FOUND; +} + + +static char* +create_file_uri_in_dir (const char *dir, + const char *filename) +{ + char *dir_uri; + char *retval; + + dir_uri = gnome_vfs_get_uri_from_local_path (dir); + + retval = g_strconcat (dir_uri, "/", filename, NULL); + + g_free (dir_uri); + + return retval; +} + + + + + diff --git a/modules/desktop-method.c.network-uri b/modules/desktop-method.c.network-uri new file mode 100644 index 0000000..609a4cf --- /dev/null +++ b/modules/desktop-method.c.network-uri @@ -0,0 +1,978 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: 8; c-basic-offset: 8 -*- */ + +/* desktop-method.c + + Copyright (C) 2001 Red Hat, Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/* URI scheme for remapping directories under magic URIs, used + * for the magic desktop file directories such as start-here. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +/* FIXME Maybe when chaining to file:, we should call the gnome-vfs wrapper + * functions, instead of the file: methods directly. + */ + +#define N_ELEMENTS(arr) (sizeof (arr) / sizeof ((arr)[0])) + +static GnomeVFSURI* desktop_uri_to_file_uri (GnomeVFSURI *desktop_uri); + +static GnomeVFSResult open_merged_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context); + +static char* create_file_uri_in_dir (const char *dir, + const char *filename); + +static GnomeVFSMethod *parent_method = NULL; + +static GnomeVFSResult +do_open (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result; + + file_uri = desktop_uri_to_file_uri (uri); + result = (* parent_method->open) (parent_method, + method_handle, + file_uri, + mode, + context); + gnome_vfs_uri_unref (file_uri); + + return result; +} + +static GnomeVFSResult +do_create (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + gboolean exclusive, + guint perm, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result; + + file_uri = desktop_uri_to_file_uri (uri); + result = (* parent_method->create) (parent_method, + method_handle, + file_uri, + mode, + exclusive, + perm, + context); + gnome_vfs_uri_unref (file_uri); + + return result; +} + +static GnomeVFSResult +do_close (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + + result = (* parent_method->close) (parent_method, + method_handle, + context); + + return result; +} + +static GnomeVFSResult +do_read (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + + result = (* parent_method->read) (parent_method, + method_handle, + buffer, num_bytes, + bytes_read, + context); + + return result; +} + +static GnomeVFSResult +do_write (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gconstpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_written, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + + result = (* parent_method->write) (parent_method, + method_handle, + buffer, num_bytes, + bytes_written, + context); + + return result; +} + + +static GnomeVFSResult +do_seek (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSSeekPosition whence, + GnomeVFSFileOffset offset, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + + result = (* parent_method->seek) (parent_method, + method_handle, + whence, offset, + context); + + return result; +} + +static GnomeVFSResult +do_tell (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileOffset *offset_return) +{ + GnomeVFSResult result; + + result = (* parent_method->tell) (parent_method, + method_handle, + offset_return); + + return result; +} + + +static GnomeVFSResult +do_truncate_handle (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileSize where, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + + result = (* parent_method->truncate_handle) (parent_method, + method_handle, + where, + context); + + return result; +} + +static GnomeVFSResult +do_truncate (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileSize where, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result; + + file_uri = desktop_uri_to_file_uri (uri); + result = (* parent_method->truncate) (parent_method, + file_uri, + where, + context); + + gnome_vfs_uri_unref (file_uri); + + return result; +} + +typedef struct _DirHandle DirHandle; + +struct _DirHandle +{ + GSList *next; + GSList *handles; +}; + +static GnomeVFSResult +do_open_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + return open_merged_directory (method, method_handle, + uri, options, context); +} + +static GnomeVFSResult +do_close_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + GSList *tmp; + DirHandle *dh; + + dh = (DirHandle*) method_handle; + + result = GNOME_VFS_OK; + tmp = dh->handles; + while (tmp != NULL) { + GnomeVFSResult this_result; + + this_result = (* parent_method->close_directory) (parent_method, + tmp->data, + context); + + if (this_result != GNOME_VFS_OK) + result = this_result; + + tmp = tmp->next; + } + + g_slist_free (dh->handles); + g_free (dh); + + return result; +} + +static GnomeVFSResult +do_read_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + GnomeVFSMethodHandle *parent_handle; + DirHandle *dh; + + dh = (DirHandle*) method_handle; + + if (dh->next == NULL) { + return GNOME_VFS_ERROR_EOF; + } + + next: + parent_handle = dh->next->data; + + result = (* parent_method->read_directory) (parent_method, + parent_handle, + file_info, + context); + + if (result != GNOME_VFS_OK) { + dh->next = dh->next->next; + if (dh->next) + goto next; + else + return result; + } else { + return GNOME_VFS_OK; + } +} + + +static void +set_directory_mime_type (GnomeVFSFileInfo *file_info) +{ + g_free (file_info->mime_type); + + file_info->mime_type = g_strdup ("x-directory/vfolder-desktop"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; +} + +static GnomeVFSResult +do_get_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result; + + file_uri = desktop_uri_to_file_uri (uri); + result = (* parent_method->get_file_info) (parent_method, + file_uri, + file_info, + options, + context); + + if (file_info->type == GNOME_VFS_FILE_TYPE_DIRECTORY) + set_directory_mime_type (file_info); + + gnome_vfs_uri_unref (file_uri); + + return result; +} + +static GnomeVFSResult +do_get_file_info_from_handle (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + + result = (* parent_method->get_file_info_from_handle) (parent_method, + method_handle, + file_info, + options, + context); + + if (file_info->type == GNOME_VFS_FILE_TYPE_DIRECTORY) + set_directory_mime_type (file_info); + + return result; +} + + +static gboolean +do_is_local (GnomeVFSMethod *method, + const GnomeVFSURI *uri) +{ + return TRUE; +} + + +static GnomeVFSResult +do_make_directory (GnomeVFSMethod *method, + GnomeVFSURI *uri, + guint perm, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result; + + file_uri = desktop_uri_to_file_uri (uri); + result = (* parent_method->make_directory) (parent_method, + file_uri, + perm, + context); + + gnome_vfs_uri_unref (file_uri); + + return result; +} + +static GnomeVFSResult +do_remove_directory (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result; + + file_uri = desktop_uri_to_file_uri (uri); + result = (* parent_method->remove_directory) (parent_method, + file_uri, + context); + + gnome_vfs_uri_unref (file_uri); + + return result; +} + +static GnomeVFSResult +do_find_directory (GnomeVFSMethod *method, + GnomeVFSURI *near_uri, + GnomeVFSFindDirectoryKind kind, + GnomeVFSURI **result_uri, + gboolean create_if_needed, + gboolean find_if_needed, + guint permissions, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSURI *file_result_uri; + GnomeVFSResult result; + + file_result_uri = NULL; + file_uri = desktop_uri_to_file_uri (near_uri); + result = (* parent_method->find_directory) (parent_method, + file_uri, + kind, + &file_result_uri, + create_if_needed, + find_if_needed, + permissions, + context); + + gnome_vfs_uri_unref (file_uri); + + if (result_uri) + *result_uri = file_result_uri; + + if (file_result_uri == NULL) + result = GNOME_VFS_ERROR_NOT_FOUND; + + return result; +} + +static GnomeVFSResult +do_move (GnomeVFSMethod *method, + GnomeVFSURI *old_uri, + GnomeVFSURI *new_uri, + gboolean force_replace, + GnomeVFSContext *context) +{ + GnomeVFSURI *old_file_uri; + GnomeVFSURI *new_file_uri; + GnomeVFSResult result; + + old_file_uri = desktop_uri_to_file_uri (old_uri); + new_file_uri = desktop_uri_to_file_uri (new_uri); + + result = (* parent_method->move) (parent_method, + old_file_uri, + new_file_uri, + force_replace, + context); + gnome_vfs_uri_unref (old_file_uri); + gnome_vfs_uri_unref (new_file_uri); + + return result; +} + +static GnomeVFSResult +do_unlink (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result; + + file_uri = desktop_uri_to_file_uri (uri); + result = (* parent_method->unlink) (parent_method, + file_uri, + context); + + gnome_vfs_uri_unref (file_uri); + + return result; +} + +static GnomeVFSResult +do_create_symbolic_link (GnomeVFSMethod *method, + GnomeVFSURI *uri, + const char *target_reference, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result; + + file_uri = desktop_uri_to_file_uri (uri); + result = (* parent_method->create_symbolic_link) (parent_method, + file_uri, + target_reference, + context); + + gnome_vfs_uri_unref (file_uri); + + return result; +} + +static GnomeVFSResult +do_check_same_fs (GnomeVFSMethod *method, + GnomeVFSURI *source_uri, + GnomeVFSURI *target_uri, + gboolean *same_fs_return, + GnomeVFSContext *context) +{ + GnomeVFSURI *source_file_uri; + GnomeVFSURI *target_file_uri; + GnomeVFSResult result; + + source_file_uri = desktop_uri_to_file_uri (source_uri); + target_file_uri = desktop_uri_to_file_uri (target_uri); + + result = (* parent_method->check_same_fs) (parent_method, + source_file_uri, + target_file_uri, + same_fs_return, + context); + gnome_vfs_uri_unref (source_file_uri); + gnome_vfs_uri_unref (target_file_uri); + + return result; +} + +static GnomeVFSResult +do_set_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + const GnomeVFSFileInfo *info, + GnomeVFSSetFileInfoMask mask, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result; + + file_uri = desktop_uri_to_file_uri (uri); + result = (* parent_method->set_file_info) (parent_method, + file_uri, + info, + mask, + context); + + gnome_vfs_uri_unref (file_uri); + + return result; +} + +typedef struct { + GnomeVFSMonitorHandle *handle; + GnomeVFSURI *desktop_uri; +} DesktopMonitorHandle; + +static void +monitor_notify_cb (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + DesktopMonitorHandle *monitor_handle; + GnomeVFSURI *desktop_info_uri; + const gchar *uri_diff; + gint monitor_uri_len; + + monitor_handle = (DesktopMonitorHandle *) user_data; + desktop_info_uri = NULL; + monitor_uri_len = strlen (monitor_uri); + + if (info_uri != NULL && + strncmp (info_uri, monitor_uri, monitor_uri_len) == 0) { + uri_diff = &info_uri [monitor_uri_len]; + + if (*uri_diff != '\0') { + desktop_info_uri = + gnome_vfs_uri_append_string ( + monitor_handle->desktop_uri, + uri_diff); + } else { + desktop_info_uri = monitor_handle->desktop_uri; + gnome_vfs_uri_ref (desktop_info_uri); + } + } + + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *) monitor_handle, + desktop_info_uri, + event_type); + + gnome_vfs_uri_unref (desktop_info_uri); +} + +static GnomeVFSResult +do_monitor_add (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle_return, + GnomeVFSURI *uri, + GnomeVFSMonitorType monitor_type) +{ + DesktopMonitorHandle *monitor_handle; + GnomeVFSURI *file_uri; + GnomeVFSResult result; + + monitor_handle = g_new0 (DesktopMonitorHandle, 1); + monitor_handle->desktop_uri = uri; + gnome_vfs_uri_ref (uri); + + file_uri = desktop_uri_to_file_uri (uri); + result = gnome_vfs_monitor_do_add (parent_method, + &monitor_handle->handle, + file_uri, + monitor_type, + monitor_notify_cb, + monitor_handle); + gnome_vfs_uri_unref (file_uri); + + if (result != GNOME_VFS_OK) { + gnome_vfs_uri_unref (monitor_handle->desktop_uri); + g_free (monitor_handle); + } + + *method_handle_return = (GnomeVFSMethodHandle *) monitor_handle; + + return result; +} + +static GnomeVFSResult +do_monitor_cancel (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle) +{ + DesktopMonitorHandle *monitor_handle; + GnomeVFSResult result; + + monitor_handle = (DesktopMonitorHandle *) method_handle; + + result = gnome_vfs_monitor_do_cancel (monitor_handle->handle); + + gnome_vfs_uri_unref (monitor_handle->desktop_uri); + g_free (monitor_handle); + + return result; +} + + + +/* gnome-vfs bureaucracy */ + +static GnomeVFSMethod method = { + sizeof (GnomeVFSMethod), + do_open, + do_create, + do_close, + do_read, + do_write, + do_seek, + do_tell, + do_truncate_handle, + do_open_directory, + do_close_directory, + do_read_directory, + do_get_file_info, + do_get_file_info_from_handle, + do_is_local, + do_make_directory, + do_remove_directory, + do_move, + do_unlink, + do_check_same_fs, + do_set_file_info, + do_truncate, + do_find_directory, + do_create_symbolic_link, + do_monitor_add, + do_monitor_cancel +}; + + +typedef enum +{ + SCHEME_FAVORITES, + SCHEME_PREFERENCES, + SCHEME_START_HERE, + SCHEME_SYSTEM_SETTINGS, + SCHEME_SERVER_SETTINGS, + SCHEME_PROGRAMS +} SchemeID; + +#define MAX_DIRECTORIES 3 +#define DIRECTORIES_INITIALIZER { NULL, NULL, NULL } + +typedef struct _SchemeDescription SchemeDescription; + +struct _SchemeDescription +{ + SchemeID id; + + const char *scheme; + + char *directories[MAX_DIRECTORIES]; +}; + +static SchemeDescription schemes[] = +{ + { SCHEME_FAVORITES, "favorites", + DIRECTORIES_INITIALIZER }, + { SCHEME_PREFERENCES, "preferences", + DIRECTORIES_INITIALIZER }, + { SCHEME_START_HERE, "start-here", + DIRECTORIES_INITIALIZER }, + { SCHEME_SYSTEM_SETTINGS, "system-settings", + DIRECTORIES_INITIALIZER }, + { SCHEME_SERVER_SETTINGS, "server-settings", + DIRECTORIES_INITIALIZER }, + { SCHEME_PROGRAMS, "programs", + DIRECTORIES_INITIALIZER } +}; + +GnomeVFSMethod * +vfs_module_init (const char *method_name, + const char *args) +{ + int i; + + parent_method = gnome_vfs_method_get ("file"); + + if (parent_method == NULL) { + g_error ("Could not find 'file' method for gnome-vfs"); + return NULL; + } + + i = 0; + while (i < N_ELEMENTS (schemes)) { + switch (schemes[i].id) { + case SCHEME_FAVORITES: + schemes[i].directories[0] = + g_strconcat (g_get_home_dir (), + "/.gnome/apps", + NULL); + break; + case SCHEME_PREFERENCES: + /* FIXME I think the GNOME 2 control center will move + * this, but we don't know where to yet + */ + schemes[i].directories[0] = + g_strconcat (DATADIR, "/control-center/capplets", NULL); + break; + case SCHEME_START_HERE: + schemes[i].directories[0] = g_strconcat (SYSCONFDIR, + "/X11/starthere", + NULL); + break; + case SCHEME_SYSTEM_SETTINGS: + schemes[i].directories[0] = + g_strconcat (SYSCONFDIR, "/X11/sysconfig", NULL); + break; + case SCHEME_SERVER_SETTINGS: + schemes[i].directories[0] = + g_strconcat (SYSCONFDIR, "/X11/serverconfig", NULL); + break; + case SCHEME_PROGRAMS: + schemes[i].directories[0] = g_strconcat (SYSCONFDIR, + "/X11/applnk", + NULL); + schemes[i].directories[1] = + g_strconcat (DATADIR, "gnome/apps", NULL); + break; + default: + g_assert_not_reached (); + break; + } + + ++i; + } + + return &method; +} + +void +vfs_module_shutdown (GnomeVFSMethod *method) +{ + int i; + + i = 0; + while (i < N_ELEMENTS (schemes)) { + int j; + + j = 0; + while (j < MAX_DIRECTORIES) { + g_free (schemes[i].directories[j]); + schemes[i].directories[j] = NULL; + ++j; + } + + ++i; + } +} + + + +static const SchemeDescription* +get_desc_for_uri (GnomeVFSURI *desktop_uri) +{ + const SchemeDescription *desc; + int i; + const char *scheme; + + scheme = gnome_vfs_uri_get_scheme (desktop_uri); + + desc = NULL; + i = 0; + while (i < N_ELEMENTS (schemes)) { + if (strcmp (schemes[i].scheme, scheme) == 0) { + desc = &schemes[i]; + break; + } + + ++i; + } + + return desc; +} + +static GnomeVFSURI* +desktop_uri_to_file_uri (GnomeVFSURI *desktop_uri) +{ + const SchemeDescription *desc; + GnomeVFSURI *new_uri; + const char *path; + int i; + + desc = get_desc_for_uri (desktop_uri); + + if (desc == NULL) { + gnome_vfs_uri_ref (desktop_uri); + return desktop_uri; + } + + /* Prepend the base for the desktop URI. + * If the SchemeDescription contains > 1 directory, we use the directory + * after the first if the given file actually exists there. + */ + new_uri = NULL; + path = gnome_vfs_uri_get_path (desktop_uri); + i = 0; + while (desc->directories[i]) + ++i; + do { + char *s; + + --i; + + s = create_file_uri_in_dir (desc->directories[i], path); + + new_uri = gnome_vfs_uri_new (s); + + g_free (s); + + if (i == 0 || + gnome_vfs_uri_exists (new_uri)) { + return new_uri; + } else { + gnome_vfs_uri_unref (new_uri); + new_uri = NULL; + } + } while (i > 0); + + + g_assert_not_reached (); + + return NULL; +} + + +static GnomeVFSResult +open_merged_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *desktop_uri, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + DirHandle *dh; + const SchemeDescription *desc; + int i; + gboolean found; + const char *path; + + desc = get_desc_for_uri (desktop_uri); + + if (desc == NULL) { + return GNOME_VFS_ERROR_NOT_FOUND; + } + + dh = g_new0 (DirHandle, 1); + + /* Prepend the base for the desktop URI. + * If the SchemeDescription contains > 1 directory, we use the directory + * after the first if the given file actually exists there. + */ + found = FALSE; + path = gnome_vfs_uri_get_path (desktop_uri); + i = 0; + while (desc->directories[i]) { + char *s; + GnomeVFSURI *file_uri; + GnomeVFSMethodHandle *parent_handle = NULL; + + s = create_file_uri_in_dir (desc->directories[i], path); + + file_uri = gnome_vfs_uri_new (s); + + g_free (s); + + result = (* parent_method->open_directory) (parent_method, + &parent_handle, + file_uri, + options, + context); + + if (result == GNOME_VFS_OK) { + found = TRUE; + dh->handles = g_slist_prepend (dh->handles, parent_handle); + } + + gnome_vfs_uri_unref (file_uri); + + ++i; + } + + dh->next = dh->handles; + + *method_handle = (GnomeVFSMethodHandle*) dh; + + return found ? GNOME_VFS_OK : GNOME_VFS_ERROR_NOT_FOUND; +} + + +static char* +create_file_uri_in_dir (const char *dir, + const char *filename) +{ + char *dir_uri; + char *retval; + + dir_uri = gnome_vfs_get_uri_from_local_path (dir); + + retval = g_strconcat (dir_uri, "/", filename, NULL); + + g_free (dir_uri); + + return retval; +} + + + + + diff --git a/modules/desktop-method.c.no-private-methods b/modules/desktop-method.c.no-private-methods new file mode 100644 index 0000000..670ba49 --- /dev/null +++ b/modules/desktop-method.c.no-private-methods @@ -0,0 +1,985 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: 8; c-basic-offset: 8 -*- */ + +/* desktop-method.c + + Copyright (C) 2001 Red Hat, Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/* URI scheme for remapping directories under magic URIs, used + * for the magic desktop file directories such as start-here. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +/* FIXME Maybe when chaining to file:, we should call the gnome-vfs wrapper + * functions, instead of the file: methods directly. + */ + +#define N_ELEMENTS(arr) (sizeof (arr) / sizeof ((arr)[0])) + +static GnomeVFSURI* desktop_uri_to_file_uri (GnomeVFSURI *desktop_uri); + +static GnomeVFSResult open_merged_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context); + +static char* create_file_uri_in_dir (const char *dir, + const char *filename); + +static GnomeVFSMethod *parent_method = NULL; + +static GnomeVFSResult +do_open (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result; + + file_uri = desktop_uri_to_file_uri (uri); + result = (* parent_method->open) (parent_method, + method_handle, + file_uri, + mode, + context); + gnome_vfs_uri_unref (file_uri); + + return result; +} + +static GnomeVFSResult +do_create (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + gboolean exclusive, + guint perm, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result; + + file_uri = desktop_uri_to_file_uri (uri); + result = (* parent_method->create) (parent_method, + method_handle, + file_uri, + mode, + exclusive, + perm, + context); + gnome_vfs_uri_unref (file_uri); + + return result; +} + +static GnomeVFSResult +do_close (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + + result = (* parent_method->close) (parent_method, + method_handle, + context); + + return result; +} + +static GnomeVFSResult +do_read (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + + result = (* parent_method->read) (parent_method, + method_handle, + buffer, num_bytes, + bytes_read, + context); + + return result; +} + +static GnomeVFSResult +do_write (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gconstpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_written, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + + result = (* parent_method->write) (parent_method, + method_handle, + buffer, num_bytes, + bytes_written, + context); + + return result; +} + + +static GnomeVFSResult +do_seek (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSSeekPosition whence, + GnomeVFSFileOffset offset, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + + result = (* parent_method->seek) (parent_method, + method_handle, + whence, offset, + context); + + return result; +} + +static GnomeVFSResult +do_tell (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileOffset *offset_return) +{ + GnomeVFSResult result; + + result = (* parent_method->tell) (parent_method, + method_handle, + offset_return); + + return result; +} + + +static GnomeVFSResult +do_truncate_handle (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileSize where, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + + result = (* parent_method->truncate_handle) (parent_method, + method_handle, + where, + context); + + return result; +} + +static GnomeVFSResult +do_truncate (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileSize where, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result; + + file_uri = desktop_uri_to_file_uri (uri); + result = (* parent_method->truncate) (parent_method, + file_uri, + where, + context); + + gnome_vfs_uri_unref (file_uri); + + return result; +} + +typedef struct _DirHandle DirHandle; + +struct _DirHandle +{ + GSList *next; + GSList *handles; +}; + +static GnomeVFSResult +do_open_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + return open_merged_directory (method, method_handle, + uri, options, context); +} + +static GnomeVFSResult +do_close_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + GSList *tmp; + DirHandle *dh; + + dh = (DirHandle*) method_handle; + + result = GNOME_VFS_OK; + tmp = dh->handles; + while (tmp != NULL) { + GnomeVFSResult this_result; + + this_result = (* parent_method->close_directory) (parent_method, + tmp->data, + context); + + if (this_result != GNOME_VFS_OK) + result = this_result; + + tmp = tmp->next; + } + + g_slist_free (dh->handles); + g_free (dh); + + return result; +} + +static GnomeVFSResult +do_read_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + GnomeVFSMethodHandle *parent_handle; + DirHandle *dh; + + dh = (DirHandle*) method_handle; + + if (dh->next == NULL) { + return GNOME_VFS_ERROR_EOF; + } + + next: + parent_handle = dh->next->data; + + result = (* parent_method->read_directory) (parent_method, + parent_handle, + file_info, + context); + + if (result != GNOME_VFS_OK) { + dh->next = dh->next->next; + if (dh->next) + goto next; + else + return result; + } else { + return GNOME_VFS_OK; + } +} + + +static void +set_directory_mime_type (GnomeVFSFileInfo *file_info) +{ + g_free (file_info->mime_type); + + file_info->mime_type = g_strdup ("x-directory/vfolder-desktop"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; +} + +static GnomeVFSResult +do_get_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result; + + file_uri = desktop_uri_to_file_uri (uri); + result = (* parent_method->get_file_info) (parent_method, + file_uri, + file_info, + options, + context); + + if (file_info->type == GNOME_VFS_FILE_TYPE_DIRECTORY) + set_directory_mime_type (file_info); + + gnome_vfs_uri_unref (file_uri); + + return result; +} + +static GnomeVFSResult +do_get_file_info_from_handle (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + + result = (* parent_method->get_file_info_from_handle) (parent_method, + method_handle, + file_info, + options, + context); + + if (file_info->type == GNOME_VFS_FILE_TYPE_DIRECTORY) + set_directory_mime_type (file_info); + + return result; +} + + +static gboolean +do_is_local (GnomeVFSMethod *method, + const GnomeVFSURI *uri) +{ + return TRUE; +} + + +static GnomeVFSResult +do_make_directory (GnomeVFSMethod *method, + GnomeVFSURI *uri, + guint perm, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result; + + file_uri = desktop_uri_to_file_uri (uri); + result = (* parent_method->make_directory) (parent_method, + file_uri, + perm, + context); + + gnome_vfs_uri_unref (file_uri); + + return result; +} + +static GnomeVFSResult +do_remove_directory (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result; + + file_uri = desktop_uri_to_file_uri (uri); + result = (* parent_method->remove_directory) (parent_method, + file_uri, + context); + + gnome_vfs_uri_unref (file_uri); + + return result; +} + +static GnomeVFSResult +do_find_directory (GnomeVFSMethod *method, + GnomeVFSURI *near_uri, + GnomeVFSFindDirectoryKind kind, + GnomeVFSURI **result_uri, + gboolean create_if_needed, + gboolean find_if_needed, + guint permissions, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSURI *file_result_uri; + GnomeVFSResult result; + + file_result_uri = NULL; + file_uri = desktop_uri_to_file_uri (near_uri); + result = (* parent_method->find_directory) (parent_method, + file_uri, + kind, + &file_result_uri, + create_if_needed, + find_if_needed, + permissions, + context); + + gnome_vfs_uri_unref (file_uri); + + if (result_uri) + *result_uri = file_result_uri; + + if (file_result_uri == NULL) + result = GNOME_VFS_ERROR_NOT_FOUND; + + return result; +} + +static GnomeVFSResult +do_move (GnomeVFSMethod *method, + GnomeVFSURI *old_uri, + GnomeVFSURI *new_uri, + gboolean force_replace, + GnomeVFSContext *context) +{ + GnomeVFSURI *old_file_uri; + GnomeVFSURI *new_file_uri; + GnomeVFSResult result; + + old_file_uri = desktop_uri_to_file_uri (old_uri); + new_file_uri = desktop_uri_to_file_uri (new_uri); + + result = (* parent_method->move) (parent_method, + old_file_uri, + new_file_uri, + force_replace, + context); + gnome_vfs_uri_unref (old_file_uri); + gnome_vfs_uri_unref (new_file_uri); + + return result; +} + +static GnomeVFSResult +do_unlink (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result; + + file_uri = desktop_uri_to_file_uri (uri); + result = (* parent_method->unlink) (parent_method, + file_uri, + context); + + gnome_vfs_uri_unref (file_uri); + + return result; +} + +static GnomeVFSResult +do_create_symbolic_link (GnomeVFSMethod *method, + GnomeVFSURI *uri, + const char *target_reference, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result; + + file_uri = desktop_uri_to_file_uri (uri); + result = (* parent_method->create_symbolic_link) (parent_method, + file_uri, + target_reference, + context); + + gnome_vfs_uri_unref (file_uri); + + return result; +} + +static GnomeVFSResult +do_check_same_fs (GnomeVFSMethod *method, + GnomeVFSURI *source_uri, + GnomeVFSURI *target_uri, + gboolean *same_fs_return, + GnomeVFSContext *context) +{ + GnomeVFSURI *source_file_uri; + GnomeVFSURI *target_file_uri; + GnomeVFSResult result; + + source_file_uri = desktop_uri_to_file_uri (source_uri); + target_file_uri = desktop_uri_to_file_uri (target_uri); + + result = (* parent_method->check_same_fs) (parent_method, + source_file_uri, + target_file_uri, + same_fs_return, + context); + gnome_vfs_uri_unref (source_file_uri); + gnome_vfs_uri_unref (target_file_uri); + + return result; +} + +static GnomeVFSResult +do_set_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + const GnomeVFSFileInfo *info, + GnomeVFSSetFileInfoMask mask, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result; + + file_uri = desktop_uri_to_file_uri (uri); + result = (* parent_method->set_file_info) (parent_method, + file_uri, + info, + mask, + context); + + gnome_vfs_uri_unref (file_uri); + + return result; +} + +typedef struct { + GnomeVFSMonitorHandle *handle; + GnomeVFSURI *desktop_uri; +} DesktopMonitorHandle; + +static void +monitor_notify_cb (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + DesktopMonitorHandle *monitor_handle; + GnomeVFSURI *desktop_info_uri; + const gchar *uri_diff; + gint monitor_uri_len; + + monitor_handle = (DesktopMonitorHandle *) user_data; + desktop_info_uri = NULL; + monitor_uri_len = strlen (monitor_uri); + + if (info_uri != NULL && + strncmp (info_uri, monitor_uri, monitor_uri_len) == 0) { + uri_diff = &info_uri [monitor_uri_len]; + + if (*uri_diff != '\0') { + desktop_info_uri = + gnome_vfs_uri_append_string ( + monitor_handle->desktop_uri, + uri_diff); + } else { + desktop_info_uri = monitor_handle->desktop_uri; + gnome_vfs_uri_ref (desktop_info_uri); + } + } + + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *) monitor_handle, + desktop_info_uri, + event_type); + + gnome_vfs_uri_unref (desktop_info_uri); +} + +static GnomeVFSResult +do_monitor_add (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle_return, + GnomeVFSURI *uri, + GnomeVFSMonitorType monitor_type) +{ + DesktopMonitorHandle *monitor_handle; + GnomeVFSURI *file_uri; + GnomeVFSResult result; + + monitor_handle = g_new0 (DesktopMonitorHandle, 1); + monitor_handle->desktop_uri = uri; + gnome_vfs_uri_ref (uri); + + file_uri = desktop_uri_to_file_uri (uri); + result = gnome_vfs_monitor_do_add (parent_method, + &monitor_handle->handle, + file_uri, + monitor_type, + monitor_notify_cb, + monitor_handle); + gnome_vfs_uri_unref (file_uri); + + if (result != GNOME_VFS_OK) { + gnome_vfs_uri_unref (monitor_handle->desktop_uri); + g_free (monitor_handle); + } + + *method_handle_return = (GnomeVFSMethodHandle *) monitor_handle; + + return result; +} + +static GnomeVFSResult +do_monitor_cancel (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle) +{ + DesktopMonitorHandle *monitor_handle; + GnomeVFSResult result; + + monitor_handle = (DesktopMonitorHandle *) method_handle; + + result = gnome_vfs_monitor_do_cancel (monitor_handle->handle); + + gnome_vfs_uri_unref (monitor_handle->desktop_uri); + g_free (monitor_handle); + + return result; +} + + + +/* gnome-vfs bureaucracy */ + +static GnomeVFSMethod method = { + sizeof (GnomeVFSMethod), + do_open, + do_create, + do_close, + do_read, + do_write, + do_seek, + do_tell, + do_truncate_handle, + do_open_directory, + do_close_directory, + do_read_directory, + do_get_file_info, + do_get_file_info_from_handle, + do_is_local, + do_make_directory, + do_remove_directory, + do_move, + do_unlink, + do_check_same_fs, + do_set_file_info, + do_truncate, + do_find_directory, + do_create_symbolic_link, + do_monitor_add, + do_monitor_cancel +}; + + +typedef enum +{ + SCHEME_FAVORITES, + SCHEME_PREFERENCES, + SCHEME_START_HERE, + SCHEME_SYSTEM_SETTINGS, + SCHEME_SERVER_SETTINGS, + SCHEME_PROGRAMS, + SCHEME_NETWORK +} SchemeID; + +#define MAX_DIRECTORIES 3 +#define DIRECTORIES_INITIALIZER { NULL, NULL, NULL } + +typedef struct _SchemeDescription SchemeDescription; + +struct _SchemeDescription +{ + SchemeID id; + + const char *scheme; + + char *directories[MAX_DIRECTORIES]; +}; + +static SchemeDescription schemes[] = +{ + { SCHEME_FAVORITES, "favorites", + DIRECTORIES_INITIALIZER }, + { SCHEME_PREFERENCES, "preferences", + DIRECTORIES_INITIALIZER }, + { SCHEME_START_HERE, "start-here", + DIRECTORIES_INITIALIZER }, + { SCHEME_SYSTEM_SETTINGS, "system-settings", + DIRECTORIES_INITIALIZER }, + { SCHEME_SERVER_SETTINGS, "server-settings", + DIRECTORIES_INITIALIZER }, + { SCHEME_PROGRAMS, "programs", + DIRECTORIES_INITIALIZER }, + { SCHEME_NETWORK, "network", + DIRECTORIES_INITIALIZER } +}; + +GnomeVFSMethod * +vfs_module_init (const char *method_name, + const char *args) +{ + int i; + + parent_method = gnome_vfs_method_get ("file"); + + if (parent_method == NULL) { + g_error ("Could not find 'file' method for gnome-vfs"); + return NULL; + } + + i = 0; + while (i < N_ELEMENTS (schemes)) { + switch (schemes[i].id) { + case SCHEME_FAVORITES: + schemes[i].directories[0] = + g_strconcat (g_get_home_dir (), + "/.gnome/apps", + NULL); + break; + case SCHEME_PREFERENCES: + /* FIXME I think the GNOME 2 control center will move + * this, but we don't know where to yet + */ + schemes[i].directories[0] = + g_strconcat (DATADIR, "/control-center/capplets", NULL); + break; + case SCHEME_START_HERE: + schemes[i].directories[0] = g_strconcat (SYSCONFDIR, + "/X11/starthere", + NULL); + break; + case SCHEME_SYSTEM_SETTINGS: + schemes[i].directories[0] = + g_strconcat (SYSCONFDIR, "/X11/sysconfig", NULL); + break; + case SCHEME_SERVER_SETTINGS: + schemes[i].directories[0] = + g_strconcat (SYSCONFDIR, "/X11/serverconfig", NULL); + break; + case SCHEME_PROGRAMS: + schemes[i].directories[0] = g_strconcat (SYSCONFDIR, + "/X11/applnk", + NULL); + schemes[i].directories[1] = + g_strconcat (DATADIR, "gnome/apps", NULL); + break; + case SCHEME_NETWORK: + schemes[i].directories[0] = + g_build_filename (DATADIR, "gnome/network", NULL); + break; + default: + g_assert_not_reached (); + break; + } + + ++i; + } + + return &method; +} + +void +vfs_module_shutdown (GnomeVFSMethod *method) +{ + int i; + + i = 0; + while (i < N_ELEMENTS (schemes)) { + int j; + + j = 0; + while (j < MAX_DIRECTORIES) { + g_free (schemes[i].directories[j]); + schemes[i].directories[j] = NULL; + ++j; + } + + ++i; + } +} + + + +static const SchemeDescription* +get_desc_for_uri (GnomeVFSURI *desktop_uri) +{ + const SchemeDescription *desc; + int i; + const char *scheme; + + scheme = gnome_vfs_uri_get_scheme (desktop_uri); + + desc = NULL; + i = 0; + while (i < N_ELEMENTS (schemes)) { + if (strcmp (schemes[i].scheme, scheme) == 0) { + desc = &schemes[i]; + break; + } + + ++i; + } + + return desc; +} + +static GnomeVFSURI* +desktop_uri_to_file_uri (GnomeVFSURI *desktop_uri) +{ + const SchemeDescription *desc; + GnomeVFSURI *new_uri; + const char *path; + int i; + + desc = get_desc_for_uri (desktop_uri); + + if (desc == NULL) { + gnome_vfs_uri_ref (desktop_uri); + return desktop_uri; + } + + /* Prepend the base for the desktop URI. + * If the SchemeDescription contains > 1 directory, we use the directory + * after the first if the given file actually exists there. + */ + new_uri = NULL; + path = gnome_vfs_uri_get_path (desktop_uri); + i = 0; + while (desc->directories[i]) + ++i; + do { + char *s; + + --i; + + s = create_file_uri_in_dir (desc->directories[i], path); + + new_uri = gnome_vfs_uri_new (s); + + g_free (s); + + if (i == 0 || + gnome_vfs_uri_exists (new_uri)) { + return new_uri; + } else { + gnome_vfs_uri_unref (new_uri); + new_uri = NULL; + } + } while (i > 0); + + + g_assert_not_reached (); + + return NULL; +} + + +static GnomeVFSResult +open_merged_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *desktop_uri, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + DirHandle *dh; + const SchemeDescription *desc; + int i; + gboolean found; + const char *path; + + desc = get_desc_for_uri (desktop_uri); + + if (desc == NULL) { + return GNOME_VFS_ERROR_NOT_FOUND; + } + + dh = g_new0 (DirHandle, 1); + + /* Prepend the base for the desktop URI. + * If the SchemeDescription contains > 1 directory, we use the directory + * after the first if the given file actually exists there. + */ + found = FALSE; + path = gnome_vfs_uri_get_path (desktop_uri); + i = 0; + while (desc->directories[i]) { + char *s; + GnomeVFSURI *file_uri; + GnomeVFSMethodHandle *parent_handle = NULL; + + s = create_file_uri_in_dir (desc->directories[i], path); + + file_uri = gnome_vfs_uri_new (s); + + g_free (s); + + result = (* parent_method->open_directory) (parent_method, + &parent_handle, + file_uri, + options, + context); + + if (result == GNOME_VFS_OK) { + found = TRUE; + dh->handles = g_slist_prepend (dh->handles, parent_handle); + } + + gnome_vfs_uri_unref (file_uri); + + ++i; + } + + dh->next = dh->handles; + + *method_handle = (GnomeVFSMethodHandle*) dh; + + return found ? GNOME_VFS_OK : GNOME_VFS_ERROR_NOT_FOUND; +} + + +static char* +create_file_uri_in_dir (const char *dir, + const char *filename) +{ + char *dir_uri; + char *retval; + + dir_uri = gnome_vfs_get_uri_from_local_path (dir); + + retval = g_strconcat (dir_uri, "/", filename, NULL); + + g_free (dir_uri); + + return retval; +} + + + + + diff --git a/modules/extfs-method.c b/modules/extfs-method.c new file mode 100644 index 0000000..d0df0b2 --- /dev/null +++ b/modules/extfs-method.c @@ -0,0 +1,971 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* extfs-method.c - Integrated support for various archiving methods via + helper scripts. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli + Based on the ideas from the extfs system implemented in the GNU Midnight + Commander. */ + +/* TODO: Support archives on non-local file systems. Although I am not + that sure it's such a terrific idea anymore. */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef HAVE_GETDELIM + + +/* Read up to (and including) a TERMINATOR from STREAM into *LINEPTR + (and null-terminate it). *LINEPTR is a pointer returned from malloc (or + NULL), pointing to *N characters of space. It is realloc'd as + necessary. Returns the number of characters read (not including the + null terminator), or -1 on error or EOF. */ + + + +static ssize_t +getdelim (lineptr, n, terminator, stream) + char **lineptr; + size_t *n; + int terminator; + FILE *stream; +{ + char *line, *p; + size_t size, copy; + + if (lineptr == NULL || n == NULL) + { + return -1; + } + + if (ferror (stream)) + return -1; + + /* Make sure we have a line buffer to start with. */ + if (*lineptr == NULL || *n < 2) /* !seen and no buf yet need 2 chars. */ + { +#ifndef MAX_CANON +#define MAX_CANON 256 +#endif + line = realloc (*lineptr, MAX_CANON); + if (line == NULL) + return -1; + *lineptr = line; + *n = MAX_CANON; + } + + line = *lineptr; + size = *n; + + copy = size; + p = line; + + while (1) + { + size_t len; + while (--copy > 0) + { + register int c = getc (stream); + if (c == EOF) + goto lose; + else if ((*p++ = c) == terminator) + goto win; + } + + /* Need to enlarge the line buffer. */ + len = p - line; + size *= 2; + line = realloc (line, size); + if (line == NULL) + goto lose; + *lineptr = line; + *n = size; + p = line + len; + copy = size - len; + } + + lose: + if (p == *lineptr) + return -1; + /* Return a partial line since we got an error in the middle. */ + win: + *p = '\0'; + return p - *lineptr; + } + + +#endif + +#define EXTFS_COMMAND_DIR LIBDIR "/vfs/2.0/extfs" + +/* Our private handle struct. */ +struct _ExtfsHandle { + GnomeVFSOpenMode open_mode; + GnomeVFSHandle *vfs_handle; + gchar *local_path; +}; +typedef struct _ExtfsHandle ExtfsHandle; + +#define VFS_HANDLE(method_handle) \ + ((ExtfsHandle *) method_handle)->vfs_handle + +/* List of current handles, for cleaning up in `vfs_module_shutdown_2()'. */ +static GList *handle_list; +G_LOCK_DEFINE_STATIC (handle_list); + + +struct _ExtfsDirectoryEntry { + gchar *directory; + GnomeVFSFileInfo *info; +}; +typedef struct _ExtfsDirectoryEntry ExtfsDirectoryEntry; + +struct _ExtfsDirectory { + guint ref_count; + GnomeVFSURI *uri; + GList *entries; +}; +typedef struct _ExtfsDirectory ExtfsDirectory; + +/* Hash of directory lists. */ +/* Notice that, for the way the code currently works, this is useless. But I + plan to add some caching (i.e. keep directory lists for a while to make + visiting easier) in the future, so this will help. The main reason for not + doing so now right is that we need some support for expiration in the GNOME + VFS library core. */ +static GHashTable *uri_to_directory_hash; +G_LOCK_DEFINE_STATIC (uri_to_directory_hash); + + +#define ERROR_IF_NOT_LOCAL(uri) \ + if ((!uri) || (!uri->parent) || (!(uri)->parent->method_string) || strcmp ((uri)->parent->method_string, "file") != 0) \ + return GNOME_VFS_ERROR_NOT_SUPPORTED; + +static GnomeVFSResult +extfs_handle_close (ExtfsHandle *handle) +{ + GnomeVFSResult close_result; + + close_result = gnome_vfs_close (handle->vfs_handle); + + /* Maybe we could use the VFS functions here. */ + if (unlink (handle->local_path) != 0) + g_warning ("Cannot unlink temporary file `%s': %s", + handle->local_path, g_strerror (errno)); + + g_free (handle->local_path); + g_free (handle); + + return close_result; +} + +static gchar * +quote_file_name (const gchar *file_name) +{ + guint len; + const gchar *p; + gchar *q; + gchar *new; + + len = 2; + for (p = file_name; *p != 0; p++) { + if (*p == '\'') + len += 3; + else + len++; + } + + new = g_malloc (len + 1); + new[0] = '\''; + + for (p = file_name, q = new + 1; *p != 0; p++) { + if (*p == '\'') { + q[0] = '"'; + q[1] = '\''; + q[2] = '"'; + q += 3; + } else { + *q = *p; + q++; + } + } + + *q++ = '\''; + *q = 0; + + return new; +} + +static gchar * +get_script_path (const GnomeVFSURI *uri) +{ + return g_strconcat (EXTFS_COMMAND_DIR, "/", uri->method_string, NULL); +} + +static gchar * +strip_separators (const gchar *pth) +{ + gchar *path_buf = g_strdup(pth); + gchar *path = path_buf, *p, *s; + + while (*path == G_DIR_SEPARATOR) path++; + + p = path+strlen(path)-1; + while (p > path && *p == G_DIR_SEPARATOR) *(p--) = '\0'; + s = g_strdup(path); + + g_free(path_buf); + + return s; +} + +static gchar * +get_basename (const gchar *pth) +{ + gchar *path = strip_separators(pth); + gchar *s; + + s = g_path_get_basename (path); + + g_free(path); + + return s; +} + +static gchar * +get_dirname (const gchar *pth) +{ + gchar *p; + //gchar *s; + //guint len; + gchar *path = strip_separators(pth); + + p = strrchr (path, G_DIR_SEPARATOR); + if (p == NULL) + return g_strdup(""); + + *p = '\0'; + + return path; +} + + +/* URI -> directory hash table handling. */ + +static void +free_directory_entries (GList *entries) +{ + GList *p; + + for (p = entries; p != NULL; p = p->next) { + ExtfsDirectoryEntry *entry; + + entry = p->data; + gnome_vfs_file_info_unref (entry->info); + g_free (entry->directory); + g_free (entry); + } + + g_list_free (entries); +} + +static ExtfsDirectory * +extfs_directory_new (const GnomeVFSURI *uri, + GList *entries) +{ + ExtfsDirectory *new; + ExtfsDirectory *existing; + + G_LOCK (uri_to_directory_hash); + + /* First check that a new directory has not been registered for this + URI yet. */ + existing = g_hash_table_lookup (uri_to_directory_hash, uri); + if (existing != NULL) { + free_directory_entries (entries); + G_UNLOCK (uri_to_directory_hash); + return existing; + } + + new = g_new (ExtfsDirectory, 1); + + new->uri = gnome_vfs_uri_dup (uri); + new->entries = entries; + new->ref_count = 1; + + g_hash_table_insert (uri_to_directory_hash, new->uri, new); + + G_UNLOCK (uri_to_directory_hash); + + return new; +} + +#if 0 +static void +extfs_directory_unref (ExtfsDirectory *dir) +{ + g_return_if_fail (dir->ref_count > 0); + + G_LOCK (uri_to_directory_hash); + + dir->ref_count--; + if (dir->ref_count == 0) { + g_hash_table_remove (uri_to_directory_hash, dir->uri); + + free_directory_entries (dir->entries); + gnome_vfs_uri_unref (dir->uri); + g_free (dir); + } + + G_UNLOCK (uri_to_directory_hash); +} +#endif + +static ExtfsDirectory * +extfs_directory_lookup (GnomeVFSURI *uri) +{ + ExtfsDirectory *directory; + + G_LOCK (uri_to_directory_hash); + directory = g_hash_table_lookup (uri_to_directory_hash, uri); + if (directory != NULL) + directory->ref_count++; + G_UNLOCK (uri_to_directory_hash); + + return directory; +} + + +static GnomeVFSResult +do_open (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + GnomeVFSProcessResult process_result; + GnomeVFSHandle *temp_handle; + ExtfsHandle *handle; + gchar *script_path; + const gchar *stored_name; + const gchar *args[6]; + gchar *temp_name; + gboolean cleanup; + gint process_exit_value; + + ERROR_IF_NOT_LOCAL (uri); + + /* TODO: Support write mode. */ + if (mode & GNOME_VFS_OPEN_WRITE) + return GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM; + + if (uri->text == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + if (uri->method_string == NULL) + return GNOME_VFS_ERROR_INTERNAL; + + stored_name = uri->text; + while (*stored_name == G_DIR_SEPARATOR) + stored_name++; + + if (*stored_name == '\0') + return GNOME_VFS_ERROR_INVALID_URI; + + result = gnome_vfs_create_temp ("/tmp/extfs", &temp_name, &temp_handle); + if (result != GNOME_VFS_OK) + return result; + + handle = g_new (ExtfsHandle, 1); + handle->vfs_handle = temp_handle; + handle->open_mode = mode; + handle->local_path = temp_name; + + script_path = get_script_path (uri); + + args[0] = uri->method_string; + args[1] = "copyout"; + args[2] = uri->parent->text; + args[3] = (gchar *) stored_name; + args[4] = temp_name; + args[5] = NULL; + + /* FIXME bugzilla.eazel.com 1223: + * args + * Ettore needs to elaborate here some more, it is not clear what this + * FixMe is about + */ + process_result = gnome_vfs_process_run_cancellable + (script_path, args, GNOME_VFS_PROCESS_CLOSEFDS, + context ? gnome_vfs_context_get_cancellation(context) : NULL, + &process_exit_value); + + switch (process_result) { + case GNOME_VFS_PROCESS_RUN_OK: + if (process_exit_value == 0) { + result = GNOME_VFS_OK; + cleanup = FALSE; + } else { + /* This is not very accurate, but it should be + enough. */ + result = GNOME_VFS_ERROR_NOT_FOUND; + cleanup = TRUE; + } + break; + case GNOME_VFS_PROCESS_RUN_CANCELLED: + result = GNOME_VFS_ERROR_CANCELLED; + cleanup = TRUE; + break; + case GNOME_VFS_PROCESS_RUN_SIGNALED: + result = GNOME_VFS_ERROR_INTERRUPTED; + cleanup = TRUE; + break; + case GNOME_VFS_PROCESS_RUN_STOPPED: + result = GNOME_VFS_ERROR_INTERRUPTED; + cleanup = TRUE; + break; + case GNOME_VFS_PROCESS_RUN_ERROR: + default: + /* If we get `GNOME_VFS_PROCESS_RUN_ERROR', it means that we + could not run the executable for some weird reason.*/ + result = GNOME_VFS_ERROR_INTERNAL; + cleanup = TRUE; + break; + } + + if (cleanup) { + extfs_handle_close (handle); + } else { + *method_handle = (GnomeVFSMethodHandle *) handle; + G_LOCK (handle_list); + handle_list = g_list_prepend (handle_list, handle); + G_UNLOCK (handle_list); + } + + g_free (script_path); + return result; +} + +static GnomeVFSResult +do_create (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + gboolean exclusive, + guint perm, + GnomeVFSContext *context) +{ + return GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM; +} + +static GnomeVFSResult +do_close (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + ExtfsHandle *extfs_handle; + GnomeVFSResult result; + + extfs_handle = (ExtfsHandle *) method_handle; + result = extfs_handle_close (extfs_handle); + + if (result == GNOME_VFS_OK) { + G_LOCK (handle_list); + handle_list = g_list_remove (handle_list, extfs_handle); + G_UNLOCK (handle_list); + } + + return result; +} + +static GnomeVFSResult +do_read (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read, + GnomeVFSContext *context) +{ + return gnome_vfs_read_cancellable (VFS_HANDLE (method_handle), + buffer, num_bytes, bytes_read, + context); +} + +static GnomeVFSResult +do_write (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gconstpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_written, + GnomeVFSContext *context) +{ + return GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM; +} + +static GnomeVFSResult +do_seek (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSSeekPosition whence, + GnomeVFSFileOffset offset, + GnomeVFSContext *context) +{ + return gnome_vfs_seek_cancellable (VFS_HANDLE (method_handle), + whence, offset, + context); +} + +static GnomeVFSResult +do_tell (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileOffset *offset_return) +{ + return gnome_vfs_tell (VFS_HANDLE (method_handle), offset_return); +} + +static GnomeVFSResult +do_truncate_handle (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileSize where, + GnomeVFSContext *context) +{ + return GNOME_VFS_ERROR_NOT_SUPPORTED; +} + +static GnomeVFSResult +do_truncate (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileSize where, + GnomeVFSContext *context) +{ + return GNOME_VFS_ERROR_NOT_SUPPORTED; +} + + +/* Directory reading. */ +static GnomeVFSResult +read_directory_list (FILE *p, + GList **list_return, + GnomeVFSFileInfoOptions info_options, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + GList *list; + gchar *line_buffer; + size_t line_buffer_size = 0; + + list = NULL; + line_buffer = NULL; + line_buffer_size = 0; + result = GNOME_VFS_OK; + + while (1) { + GnomeVFSFileInfo *info; + ExtfsDirectoryEntry *entry; + ssize_t chars_read; + struct stat statbuf; + gchar *name; + gchar *symlink_name; + + if (gnome_vfs_context_check_cancellation(context)) { + result = GNOME_VFS_ERROR_CANCELLED; + break; + } + + chars_read = getdelim (&line_buffer, &line_buffer_size, '\n', p); + if (chars_read == -1) + break; + + /* FIXME bugzilla.eazel.com 1223: */ + fputs (line_buffer, stdout); + + line_buffer[chars_read] = '\0'; + + if (! gnome_vfs_parse_ls_lga (line_buffer, &statbuf, + &name, &symlink_name)) { + continue; + } + + info = gnome_vfs_file_info_new (); + + info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_NONE; + gnome_vfs_stat_to_file_info (info, &statbuf); + + GNOME_VFS_FILE_INFO_SET_LOCAL (info, FALSE); + info->name = g_strdup (get_basename (name)); + info->symlink_name = symlink_name; + + /* Notice that we always do stupid, fast MIME type checking. + Real checking based on contents would be too expensive. */ + if (info_options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE) { + info->mime_type = g_strdup (gnome_vfs_get_file_mime_type( + info->name, &statbuf, FALSE)); + info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + } + + entry = g_new (ExtfsDirectoryEntry, 1); + entry->info = info; + entry->directory = get_dirname (name); + + g_free (name); + + /* Order does not really matter here. */ + list = g_list_prepend (list, entry); + } + + *list_return = list; + return result; +} + +static GnomeVFSResult +do_open_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions info_options, + GnomeVFSContext *context) +{ + GList **handle; + ExtfsDirectoryEntry *entry; + ExtfsDirectory *directory; + struct stat statbuf; + gchar *script_path; + gchar *quoted_file_name; + gchar *cmd; + gchar *sub_uri; + //const gchar *p; + //const GList *item; + GList *entries=NULL; + GList *l; + FILE *pipe; + + ERROR_IF_NOT_LOCAL (uri); + + directory = extfs_directory_lookup (uri->parent); + if (directory == NULL) { + GList *list; + GnomeVFSResult result; + + /* Check that the file exists first. */ + if (stat (uri->parent->text, &statbuf) != 0) + return GNOME_VFS_ERROR_NOT_FOUND; + + quoted_file_name = quote_file_name (uri->parent->text); + script_path = get_script_path (uri); + cmd = g_strconcat (script_path, " list ", quoted_file_name, + NULL); + + pipe = popen (cmd, "r"); + + g_free (cmd); + g_free (script_path); + g_free (quoted_file_name); + + if (pipe == NULL) + return GNOME_VFS_ERROR_NOT_SUPPORTED; + + result = read_directory_list (pipe, &list, info_options, + context); + + if (pclose (pipe) == 0 && result == GNOME_VFS_OK) { + directory = extfs_directory_new (uri->parent, list); + } else { + free_directory_entries (list); + if (result == GNOME_VFS_OK) + return GNOME_VFS_ERROR_IO; /* FIXME bugzilla.eazel.com 1223:? */ + else + return result; + } + } + + /* Remove all leading slashes, as they don't matter for us. */ + if (uri->text != NULL) { + sub_uri = strip_separators(uri->text); + } else { + sub_uri = NULL; + } + + l = directory->entries; + while (l != NULL) { + entry = l->data; + + /* check if one of entry->directory or sub_uri is NULL */ + if ((entry->directory != NULL && sub_uri == NULL) + || (entry->directory == NULL && + sub_uri != NULL)) { + l = l->next; + continue; + } + + /* check if the paths match */ + if(strcmp(entry->directory, sub_uri)) { + l = l->next; + continue; + } + + entries = g_list_append(entries, entry->info); + l = l->next; + } + + g_free (sub_uri); + + if(entries) { + handle = g_malloc( sizeof(GList *) ); + + *handle = entries; + + *method_handle = (GnomeVFSMethodHandle *) handle; + + return GNOME_VFS_OK; + } else { + return GNOME_VFS_ERROR_NOT_A_DIRECTORY; + } +} + +static GnomeVFSResult +do_close_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + GList *item; + + item = *((GList **)method_handle); + + g_list_free (g_list_first (item)); + + g_free(method_handle); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_read_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSContext *context) +{ + GList *item; + + item = *((GList **)method_handle); + + if (item == NULL) + return GNOME_VFS_ERROR_EOF; + + gnome_vfs_file_info_copy (file_info, (GnomeVFSFileInfo *)item->data); + + //gnome_vfs_file_info_unref((GnomeVFSFileInfo *)item->data); + + *((GList **)method_handle) = item->next; + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_get_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSMethodHandle *method_handle; + GnomeVFSResult result; + GnomeVFSURI *parent; + gchar *filename; + + parent = gnome_vfs_uri_get_parent(uri); + + if (parent == NULL) { + return GNOME_VFS_ERROR_INVALID_URI; + } + + filename = gnome_vfs_uri_extract_short_name(uri); + + if(strcmp(parent->method_string, uri->method_string)) { + + result = gnome_vfs_get_file_info_uri(parent, file_info, options); + /* now we get evil and tell the app that this is in fact a dir */ + file_info->type = GNOME_VFS_FILE_TYPE_DIRECTORY; + g_free(file_info->mime_type); + file_info->mime_type = g_strdup("x-directory/normal"); + g_free(filename); + return result; + } + + result = do_open_directory (method, &method_handle, parent, options, context); + if (result != GNOME_VFS_OK) + return result; + + while (TRUE) { + result = do_read_directory (method, method_handle, file_info, context); + if (result != GNOME_VFS_OK || + !strcmp (file_info->name, filename)) + break; + } + do_close_directory (method, method_handle, context); + + if (result == GNOME_VFS_ERROR_EOF) + result = GNOME_VFS_ERROR_NOT_FOUND; + + g_free (filename); + return result; +} + +static GnomeVFSResult +do_get_file_info_from_handle (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + return GNOME_VFS_ERROR_NOT_SUPPORTED; +} + +static gboolean +do_is_local (GnomeVFSMethod *method, + const GnomeVFSURI *uri) +{ + return FALSE; +} + +static GnomeVFSResult +do_make_directory (GnomeVFSMethod *method, + GnomeVFSURI *uri, + guint perm, + GnomeVFSContext *context) +{ + return GNOME_VFS_ERROR_NOT_SUPPORTED; +} + +static GnomeVFSResult +do_find_directory (GnomeVFSMethod *method, + GnomeVFSURI *near_uri, + GnomeVFSFindDirectoryKind kind, + GnomeVFSURI **result_uri, + gboolean create_if_needed, + gboolean find_if_needed, + guint permissions, + GnomeVFSContext *context) +{ + return GNOME_VFS_ERROR_NOT_SUPPORTED; +} + + +static GnomeVFSResult +do_remove_directory (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSContext *context) +{ + return GNOME_VFS_ERROR_NOT_SUPPORTED; +} + +static GnomeVFSResult +do_move (GnomeVFSMethod *method, + GnomeVFSURI *old_uri, + GnomeVFSURI *new_uri, + gboolean force_replace, + GnomeVFSContext *context) +{ + return GNOME_VFS_ERROR_NOT_SUPPORTED; +} + + +static GnomeVFSResult +do_unlink (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSContext *context) +{ + return GNOME_VFS_ERROR_NOT_SUPPORTED; +} + +static GnomeVFSResult +do_check_same_fs (GnomeVFSMethod *method, + GnomeVFSURI *a, + GnomeVFSURI *b, + gboolean *same_fs_return, + GnomeVFSContext *context) +{ + return GNOME_VFS_ERROR_NOT_SUPPORTED; +} + + +static GnomeVFSMethod method = { + sizeof (GnomeVFSMethod), + do_open, + do_create, + do_close, + do_read, + do_write, + do_seek, + do_tell, + do_truncate_handle, + do_open_directory, + do_close_directory, + do_read_directory, + do_get_file_info, + do_get_file_info_from_handle, + do_is_local, + do_make_directory, + do_remove_directory, + do_move, + do_unlink, + do_check_same_fs, + NULL, + do_truncate, + do_find_directory, + NULL /* FIXME bugzilla.eazel.com 2804: do_create_symbolic_link */ +}; + +GnomeVFSMethod * +vfs_module_init (const char *method_name, const char *args) +{ + handle_list = NULL; + uri_to_directory_hash = g_hash_table_new (gnome_vfs_uri_hash, + gnome_vfs_uri_hequal); + + return &method; +} + +void +vfs_module_shutdown (GnomeVFSMethod *method) +{ + GList *p; + + for (p = handle_list; p != NULL; p = p->next) + extfs_handle_close ((ExtfsHandle *) p->data); +} diff --git a/modules/extfs/Makefile.am b/modules/extfs/Makefile.am new file mode 100644 index 0000000..794967b --- /dev/null +++ b/modules/extfs/Makefile.am @@ -0,0 +1,41 @@ +extfsdir = $(libdir)/vfs/2.0/extfs + +extfs_DATA = \ + README + +extfs_SCRIPTS = \ + a \ + deb \ + hp48 \ + mailfs \ + patchfs \ + rpm \ + rpms \ + trpm \ + ar \ + arj \ + cpio \ + lha \ + rar \ + zip \ + tar \ + zoo + +EXTRA_DIST = \ + a \ + ar.in \ + arj \ + cpio.in \ + deb.in \ + hp48 \ + lha.in \ + mailfs \ + patchfs \ + rar.in \ + rpm \ + tar \ + rpms \ + trpm \ + uha.in \ + zip.in \ + zoo.in diff --git a/modules/extfs/Makefile.in b/modules/extfs/Makefile.in new file mode 100644 index 0000000..c7eab02 --- /dev/null +++ b/modules/extfs/Makefile.in @@ -0,0 +1,383 @@ +# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = ../.. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ +AS = @AS@ +AWK = @AWK@ +BONOBO_ACTIVATION_REQUIRED = @BONOBO_ACTIVATION_REQUIRED@ +BONOBO_IDLDIR = @BONOBO_IDLDIR@ +BONOBO_REQUIRED = @BONOBO_REQUIRED@ +BZ2_LIBS = @BZ2_LIBS@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +DATADIRNAME = @DATADIRNAME@ +DB2HTML = @DB2HTML@ +DLLTOOL = @DLLTOOL@ +ECHO = @ECHO@ +ENABLE_PROFILER = @ENABLE_PROFILER@ +EXEEXT = @EXEEXT@ +FAM_LIBS = @FAM_LIBS@ +GCONFTOOL = @GCONFTOOL@ +GCONF_REQUIRED = @GCONF_REQUIRED@ +GCONF_SCHEMA_CONFIG_SOURCE = @GCONF_SCHEMA_CONFIG_SOURCE@ +GCONF_SCHEMA_FILE_DIR = @GCONF_SCHEMA_FILE_DIR@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GLIB_REQUIRED = @GLIB_REQUIRED@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GNOME_ACLOCAL_DIR = @GNOME_ACLOCAL_DIR@ +GNOME_ACLOCAL_FLAGS = @GNOME_ACLOCAL_FLAGS@ +GNOME_VFS_DIR = @GNOME_VFS_DIR@ +GTKDOC = @GTKDOC@ +HAVE_GTK_DOC = @HAVE_GTK_DOC@ +HTML_DIR = @HTML_DIR@ +INSTOBJEXT = @INSTOBJEXT@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_CAVES_RULE = @INTLTOOL_CAVES_RULE@ +INTLTOOL_DESKTOP_RULE = @INTLTOOL_DESKTOP_RULE@ +INTLTOOL_DIRECTORY_RULE = @INTLTOOL_DIRECTORY_RULE@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_KEYS_RULE = @INTLTOOL_KEYS_RULE@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_OAF_RULE = @INTLTOOL_OAF_RULE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_PONG_RULE = @INTLTOOL_PONG_RULE@ +INTLTOOL_PROP_RULE = @INTLTOOL_PROP_RULE@ +INTLTOOL_SCHEMAS_RULE = @INTLTOOL_SCHEMAS_RULE@ +INTLTOOL_SERVER_RULE = @INTLTOOL_SERVER_RULE@ +INTLTOOL_SHEET_RULE = @INTLTOOL_SHEET_RULE@ +INTLTOOL_SOUNDLIST_RULE = @INTLTOOL_SOUNDLIST_RULE@ +INTLTOOL_THEME_RULE = @INTLTOOL_THEME_RULE@ +INTLTOOL_UI_RULE = @INTLTOOL_UI_RULE@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTLTOOL_XML_RULE = @INTLTOOL_XML_RULE@ +LDFLAGS = @LDFLAGS@ +LIBEFS_CFLAGS = @LIBEFS_CFLAGS@ +LIBEFS_LIBS = @LIBEFS_LIBS@ +LIBGNOMEVFS_AGE = @LIBGNOMEVFS_AGE@ +LIBGNOMEVFS_CFLAGS = @LIBGNOMEVFS_CFLAGS@ +LIBGNOMEVFS_CURRENT = @LIBGNOMEVFS_CURRENT@ +LIBGNOMEVFS_LIBS = @LIBGNOMEVFS_LIBS@ +LIBGNOMEVFS_REVISION = @LIBGNOMEVFS_REVISION@ +LIBGNUTLS_CFLAGS = @LIBGNUTLS_CFLAGS@ +LIBGNUTLS_CONFIG = @LIBGNUTLS_CONFIG@ +LIBGNUTLS_LIBS = @LIBGNUTLS_LIBS@ +LIBIDL_REQUIRED = @LIBIDL_REQUIRED@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MODULES_CFLAGS = @MODULES_CFLAGS@ +MODULES_FILE_CFLAGS = @MODULES_FILE_CFLAGS@ +MODULES_FILE_LIBS = @MODULES_FILE_LIBS@ +MODULES_GCONF_CFLAGS = @MODULES_GCONF_CFLAGS@ +MODULES_GCONF_LIBS = @MODULES_GCONF_LIBS@ +MODULES_LIBS = @MODULES_LIBS@ +MODULES_XML_CFLAGS = @MODULES_XML_CFLAGS@ +MODULES_XML_GCONF_CFLAGS = @MODULES_XML_GCONF_CFLAGS@ +MODULES_XML_GCONF_LIBS = @MODULES_XML_GCONF_LIBS@ +MODULES_XML_LIBS = @MODULES_XML_LIBS@ +MONIKERS_CFLAGS = @MONIKERS_CFLAGS@ +MONIKERS_LIBS = @MONIKERS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ORBIT_IDL = @ORBIT_IDL@ +ORBIT_REQUIRED = @ORBIT_REQUIRED@ +PACKAGE = @PACKAGE@ +PKG_CONFIG = @PKG_CONFIG@ +POFILES = @POFILES@ +POPT_LIBS = @POPT_LIBS@ +POSUB = @POSUB@ +PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ +PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ +RANLIB = @RANLIB@ +STRIP = @STRIP@ +TEST_CFLAGS = @TEST_CFLAGS@ +TEST_LIBS = @TEST_LIBS@ +TOP_BUILDDIR = @TOP_BUILDDIR@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +VFS_CFLAGS = @VFS_CFLAGS@ +VFS_INCLUDEDIR = @VFS_INCLUDEDIR@ +VFS_LIBDIR = @VFS_LIBDIR@ +VFS_LIBS = @VFS_LIBS@ +VFS_OFFSET = @VFS_OFFSET@ +VFS_OFFSET_IS = @VFS_OFFSET_IS@ +VFS_OFFSET_PRINTF = @VFS_OFFSET_PRINTF@ +VFS_SIZE = @VFS_SIZE@ +VFS_SIZE_IS = @VFS_SIZE_IS@ +VFS_SIZE_PRINTF = @VFS_SIZE_PRINTF@ +WARN_CFLAGS = @WARN_CFLAGS@ +XML_REQUIRED = @XML_REQUIRED@ +cxxflags_set = @cxxflags_set@ + +extfsdir = $(libdir)/vfs/2.0/extfs + +extfs_DATA = \ + README + + +extfs_SCRIPTS = \ + a \ + deb \ + hp48 \ + mailfs \ + patchfs \ + rpm \ + rpms \ + trpm \ + ar \ + arj \ + cpio \ + lha \ + rar \ + zip \ + tar \ + zoo + + +EXTRA_DIST = \ + a \ + ar.in \ + arj \ + cpio.in \ + deb.in \ + hp48 \ + lha.in \ + mailfs \ + patchfs \ + rar.in \ + rpm \ + tar \ + rpms \ + trpm \ + uha.in \ + zip.in \ + zoo.in + +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../../config.h +CONFIG_CLEAN_FILES = ar cpio deb lha rar zip zoo +SCRIPTS = $(extfs_SCRIPTS) + +DATA = $(extfs_DATA) + +DIST_COMMON = README Makefile.am Makefile.in ar.in cpio.in deb.in \ +lha.in rar.in zip.in zoo.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +all: all-redirect +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps modules/extfs/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + +ar: $(top_builddir)/config.status ar.in + cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status +cpio: $(top_builddir)/config.status cpio.in + cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status +deb: $(top_builddir)/config.status deb.in + cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status +lha: $(top_builddir)/config.status lha.in + cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status +rar: $(top_builddir)/config.status rar.in + cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status +zip: $(top_builddir)/config.status zip.in + cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status +zoo: $(top_builddir)/config.status zoo.in + cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + +install-extfsSCRIPTS: $(extfs_SCRIPTS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(extfsdir) + @list='$(extfs_SCRIPTS)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(INSTALL_SCRIPT) $$p $(DESTDIR)$(extfsdir)/`echo $$p|sed '$(transform)'`"; \ + $(INSTALL_SCRIPT) $$p $(DESTDIR)$(extfsdir)/`echo $$p|sed '$(transform)'`; \ + else if test -f $(srcdir)/$$p; then \ + echo " $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(extfsdir)/`echo $$p|sed '$(transform)'`"; \ + $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(extfsdir)/`echo $$p|sed '$(transform)'`; \ + else :; fi; fi; \ + done + +uninstall-extfsSCRIPTS: + @$(NORMAL_UNINSTALL) + list='$(extfs_SCRIPTS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(extfsdir)/`echo $$p|sed '$(transform)'`; \ + done + +install-extfsDATA: $(extfs_DATA) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(extfsdir) + @list='$(extfs_DATA)'; for p in $$list; do \ + if test -f $(srcdir)/$$p; then \ + echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(extfsdir)/$$p"; \ + $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(extfsdir)/$$p; \ + else if test -f $$p; then \ + echo " $(INSTALL_DATA) $$p $(DESTDIR)$(extfsdir)/$$p"; \ + $(INSTALL_DATA) $$p $(DESTDIR)$(extfsdir)/$$p; \ + fi; fi; \ + done + +uninstall-extfsDATA: + @$(NORMAL_UNINSTALL) + list='$(extfs_DATA)'; for p in $$list; do \ + rm -f $(DESTDIR)$(extfsdir)/$$p; \ + done +tags: TAGS +TAGS: + + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = modules/extfs + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: +install-exec: install-exec-am + +install-data-am: install-extfsSCRIPTS install-extfsDATA +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-extfsSCRIPTS uninstall-extfsDATA +uninstall: uninstall-am +all-am: Makefile $(SCRIPTS) $(DATA) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(extfsdir) $(DESTDIR)$(extfsdir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-generic clean-am + -rm -f libtool + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: uninstall-extfsSCRIPTS install-extfsSCRIPTS uninstall-extfsDATA \ +install-extfsDATA tags distdir info-am info dvi-am dvi check check-am \ +installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/modules/extfs/README b/modules/extfs/README new file mode 100644 index 0000000..1b74171 --- /dev/null +++ b/modules/extfs/README @@ -0,0 +1,192 @@ + Writing scripts for Midnight Commander's external vfs + +IMPORTANT NOTE: There may be some bugs left in extfs. Enjoy. + +Starting with version 3.1, the Midnight Commander comes with so called +extfs, which is one of the virtual filesystems. This system makes it +possible to create new virtual filesystems for the GNU MC very easily. + +Such work has two basic steps: + +Editing $(libdir)/extfs/extfs.ini. +Creating a shell script/program to handle requests. +(Note: $(libdir) should be substituted for actual libdir path stored when +configured or compiled, like /usr/local/lib/mc or /usr/lib/mc). + +The first one is very easy: +You assign a vfs suffix. For example, if you have .zip file, and would +like to see what's inside it, path will be + +/anypath/my.zip#uzip/some_path/... + +Then you add a line extfs.ini file containing just that extension. If +your vfs does not require file to work on, add ':' to the of name. + +In this example, .zip is suffix, but I call vfs 'uzip'. Why? Well, +what this vfs essentially does is UNzip. UN is too long, so I choosed +U. Note that sometime in future filesystem like zip may exist: It will +take whole tree and create .zip file from it. So /usr:zip will be +zipfile containing whole /usr tree. + +The second one may require some your knowledge of shell/c programming: +You have to create a program (with executable permissions) prefix in +$(libdir)/extfs (in our example $(libdir)/extfs/uzip). + +* Commands that should be implemented by your shell script +---------------------------------------------------------- + +Return zero from your script upon completion of the command, otherwise +nonzero for failure or in case of an unsupported command. + +$libdir/extfs/prefix command [arguments] + +* Command: list archivename + +This command should list the complete archive content in the following format +(a little modified ls -l listing): + +AAAAAAA NNN OOOOOOOO GGGGGGGG SSSSSSSS DATETIME [PATH/]FILENAME [-> [PATH/]FILENAME[/]]] + +where (things in [] are optional): + +AAAAAAA is the permission string like in ls -l +NNN is the number of links +OOOOOOOO is the owner (either UID or name) +GGGGGGGG is the group (either GID or name) +SSSSSSSS is the file size +FILENAME is the filename +PATH is the path from the archive's root without the leading slash (/) +DATETIME has one of the following formats: + Mon DD hh:mm, Mon DD YYYY, Mon DD YYYY hh:mm, MM-DD-YY hh:mm + + where Mon is a three digit english month name, DD day + 1-31, MM month 01-12, YY two digit year, YYYY four digit + year, hh hour and mm minute. + +If the -> [PATH/]FILENAME part is present, it means: + +If permissions start with an l (ell), then it is the name that symlink +points to. (If this PATH starts with a MC vfs prefix, then it is a symlink +somewhere to the other virtual filesystem (if you want to specify path from +the local root, use local:/path_name instead of /path_name, since /path_name +means from root of the archive listed). + +If permissions do not start with l, but number of links is greater than one, +then it says that this file should be a hardlinked with the other file. + +* Command: copyout archivename storedfilename extractto + +This should extract from archive archivename the file called +storedfilename (possibly with path if not located in archive's root +[this is wrong. current extfs strips paths! -- pavel@ucw.cz]) +to file extractto. + +* Command: copyin archivename storedfilename sourcefile + +This should add to the archivename the sourcefile with the name +storedfilename inside the archive. + +Important note: archivename in the above examples may not have the +extension you are expecting to have, like it may happen that +archivename will be something like /tmp/f43513254 or just +anything. Some archivers do not like it, so you'll have to find some +workaround. + +* Command: rm archivename storedfilename + +This should remove storedfilename from archivename. + +* Command: mkdir archivename dirname + +This should create a new directory called dirname inside archivename. + +* Command: rmdir archivename dirname + +This should remove an existing directory dirname. If the directory is +not empty, mc will recursively delete it (possibly prompting). + +* Command: run + +Undocumented :-) + +--------------------------------------------------------- + +Don't forget to mark this file executable (chmod 755 ThisFile, for example) + +For skeleton structure of executable, look at some of filesystems +similar to yours. + +--------------------------------------------------------- + +In constructing these routines, errors will be made, and mc will not display +a malformed printing line. That can lead the programmer down many false +trails in search of the bug. Since this routine is an executable shell script +it can be run from the command line independently of mc, and its output will +show on the console or can be redirected to a file. + +* Putting it to use +---------------------------------------------------------- +The file .mc.ext in a home directory, and in mc's user directory (commonly +/usr/local/lib/mc), contains instructions for operations on files depending +on filename extensions. It is well documented in other files in this +distribution, so here are just a few notes specifically on use of the +Virtual File System you just built. + +There are entries in .mc.ext defining a few operations that can be done on a +file from an mc panel. Typically they are annotated with a hash mark and a +file extension like this: + +# zip + +There must be a way to find the file by extension, so the next line does +that. In essence it says "identify the string ".zip" or (|) ".ZIP" at the +end ($) of a filename": + +regex/\.(zip|ZIP)$ + +The operations themselves follow that. They must be indented by at least a +space, and a tab works as well. In particular, the Open operation will +now use your new virtual file system by cd'ing to it like this: + + Open=%cd zip:%d/%p + +This is the line used when a file is highlighted in a panel and the user +presses or . The contents of the archive should show just +as if they were in a real directory, and can be manipulated as such. +The rest of the entry pertains to use of the F3 View key: + + View=%view{ascii} unzip -v %f + +And perhaps an optional icon for X: + + Icon=zip.xpm + +And perhaps an operation to extract the contents of the file, called from +a menu selection: + + Extract=unzip %f '*' + +This is just an example. The current entry for .zip files has a menu selection +of 'Unzip' which could be used in place of 'Extract'. What goes here depends +on what items you have in, or add to, the menu system, and that's another +subject. The sum of this is the .mc.ext entry: + +# zip +regex/\.(zip|ZIP)$ + Open=%cd zip:%d/%p + View=%view{ascii} unzip -v %f + Icon=zip.xpm + Extract=unzip %f '*' + +Add an entry like this to the .mc.ext file in a user's home directory, If you +want others to have it, add it to the mc.ext file in the mc system directory, +often /usr/local/lib/mc/mc.ext. Notice this file is not prepended with a dot. + +Once all this is done, and things are in their proper places, exit mc if you +were using it, and restart it so it picks up the new information. + +That's all there is to it. The hardest part is making a listing function +that sorts the output of a system listing command and turns it into a form +that mc can use. Currently awk (or gawk) is used because nearly all systems +have it. If another scripting language is available, like perl, that could +also be used. diff --git a/modules/extfs/a b/modules/extfs/a new file mode 100755 index 0000000..a9c400e --- /dev/null +++ b/modules/extfs/a @@ -0,0 +1,89 @@ +#! /usr/bin/perl +# +# External filesystem for mc, using mtools +# Written Ludek Brukner (lubr@barco.cz), 1997 +# +# WARNING - This software is ALPHA - Absolutely NO WARRANTY +# + +### Change this when the commands are outside PATH +$mdir = "mdir"; +$mcopy = "mcopy -noQ"; +### + +$disk = $0; +$disk =~ s/^.*\/([^\/]*)$/\1/; + +sub get_dirs { + my ($path, $name, $size, $date, $time, $longname, @lst, @rv); + + $path = shift(@_); + @rv = (); + + open(FILE,"$mdir $disk:/$path |"); + while ( ) { + chomp(); + /^ / && next; # ignore `non-file' lines + /^$/ && next; # ignore empty lines + /^\.\.?/ && next; # ignore `.' and `..' + + $name = substr($_,0,12); + $name =~ s/^([^ ]*) +([^ ]+)[ \t]*$/$1.$2/; + $name =~ s/[ .]+$//; + + $_ = substr($_,12); + s/^[ ]+//; + + ($size,$date,$time,$longname) = split(/[ \t]+/); + + @lst = split(/([:ap])/, $time); + $lst[0] += 12 if ($lst[3] eq "p"); + $time = sprintf("%02d:%02d", $lst[0], $lst[2]); + @lst = split(/-/, $date); + $lst[2] %= 100 if ($lst[2] > 100); + $date = sprintf ("%02d-%02d-%02d", @lst); + + $name = $path . lc(($longname) ? $longname : $name); + + if ($size =~ /DIR/) { + printf("drwxr-xr-x 1 %-8d %-8d %8d %s %s %s\n", 0, 0, 0, $date, $time, $name); + push @rv, $name; + } + else { + printf("-rw-r--r-- 1 %-8d %-8d %8d %s %s %s\n", 0, 0, $size, $date, $time, $name); + } + } + close(FILE); + return @rv; +} + +sub a_list +{ + my (@files, $file); + + @files = get_dirs(""); + while ($file = shift(@files)) { + push @files, get_dirs("$file/"); + } +} + +sub a_copyout +{ + my($archname,$filename,$dest) = @_; + system "$mcopy $disk:/$filename $dest >& /dev/null"; +} + +# system "touch /tmp/deb"; + +sub a_copyin +{ + my($archname,$filename,$dest) = @_; + system "$mcopy $dest $disk:/$filename >& /dev/null"; +} + +if($ARGV[0] eq "list") { shift; &a_list(@ARGV); exit 0; } +elsif($ARGV[0] eq "copyout") { shift; &a_copyout(@ARGV); exit 0; } +elsif($ARGV[0] eq "copyin") { shift; &a_copyin(@ARGV); exit 0; } + +exit 1; + diff --git a/modules/extfs/ar.in b/modules/extfs/ar.in new file mode 100644 index 0000000..ab31800 --- /dev/null +++ b/modules/extfs/ar.in @@ -0,0 +1,48 @@ +#!/bin/sh +# +# Written by Alex Kuchma +# Alex Tkachenko +# Updated by Vitezslav Samel +# +# (C) 1997, 1998 The Free Software Foundation. +# +# +XAR=ar +XUNAR=ar +XARINFO="ar tv" +AWK=awk + +mcarfs_list () +{ + YEAR=`date '+%Y'` + $XARINFO $1 | @AWK@ -v year=$YEAR ' + { + date = $(NF-1) + if(date == year) { + date = $(NF-2); + } + perms = substr($1, 1, 9); + split($2, id, "/"); + if(NF > 8) { + id[2] = $3; + } + printf("-%9s 1 %8d %8d %8d %s %s %s %s\n", perms, id[1], id[2], $(NF-5), $(NF-4), $(NF-3), date, $(NF)); + }' 2>/dev/null +} + +mcarfs_copyout () +{ + $XUNAR p $1 $2 > $3 +} + +# override any locale for dates +LC_ALL=C +export LC_ALL + +umask 077 +case "$1" in + list) mcarfs_list $2; exit 0;; + copyout) shift; mcarfs_copyout $*; exit 0;; + copyin) shift; mcarfs_copyin $*; exit 0;; +esac +exit 1 diff --git a/modules/extfs/arj b/modules/extfs/arj new file mode 100644 index 0000000..96966f2 --- /dev/null +++ b/modules/extfs/arj @@ -0,0 +1,34 @@ +#! /bin/sh +# +# Copyright 1998 Pavel Machek, +# partly based on zip by Jakub Jelinek 1995 +# +# Distribute in terms of GPL. +# +# +ARJ=mcunarj + +mcarjfs_list () +{ +$ARJ v $1 | awk -v uid=${UID-0} ' +BEGIN { hyphens=0 } +/^----------/ { if (hyphens > 0) exit 0; hyphens=1; next } +{ +if (hyphens < 1) next; +path=$1; +getline; +printf "-rw-r--r-- 1 %-8d %-8d %8d %s-%s %s %s\n", uid, 0, $1, substr($4,4), substr($4,1,2), substr($5,1,5), path +}' 2>/dev/null +} + +mcarjfs_copyout () +{ +$ARJ p $1 $2 2> $3 > /dev/null +} + +umask 077 +case "$1" in + list) mcarjfs_list $2; exit 0;; + copyout) mcarjfs_copyout $2 $3 $4; exit 0;; +esac +exit 1 diff --git a/modules/extfs/cpio.in b/modules/extfs/cpio.in new file mode 100644 index 0000000..e11b354 --- /dev/null +++ b/modules/extfs/cpio.in @@ -0,0 +1,75 @@ +#!/bin/sh +# +# Written by Stas Maximov 1998 SVR4 (UnixWare) +# stmax@u213.srcc.msu.su +# (C) 1996 The Free Software Foundation. +# +# + +uni_cat () +# $1 is the archive name +{ + case "$1" in + *.cpio.Z) compress -dc "$1" + ;; + *.cpio.gz) gzip -dc "$1" + ;; + *.cpio) cat "$1" + ;; + *) echo "unknown extension" + esac +} + +mccpiofs_list () +# $1 is the archive name +{ + uni_cat "$1" | cpio -itv | @AWK@ ' + { + if (substr($9,length($9),1) == ",") + { + tmp = substr($9, 1, length($9)-1); + $9 = $8; + $8 = tmp + } + else if (substr($10,length($10),1) == ",") + { + tmp = substr($10, 1, length($10)-1); + $10 = $9 + $9 = tmp + } + + print $0 + }' +} + +mccpiofs_copyout () +# $1 is the archive name +# $2 is a name of a file within the archive +# $3 is a name of a file within the system (to add from or extract to) +{ + TMPDIR=/tmp/mctmpdir.$$ +# FIXME bugzilla.eazel.com 1225: Try harder to generate a unique directory if this fails + mkdir -m 0700 $TMPDIR || exit 1 + cd $TMPDIR + uni_cat "$1" | cpio -icumd "$2" 2>/dev/null + mv "$2" "$3" + cd / + rm -rf $TMPDIR +} + +# +# main +# + umask 077 + + case "$1" in + list) mccpiofs_list $2 + exit 0 + ;; + copyout) mccpiofs_copyout $2 $3 $4 + exit 0 + ;; + esac + + exit 1 + diff --git a/modules/extfs/deb.in b/modules/extfs/deb.in new file mode 100644 index 0000000..1af3dbd --- /dev/null +++ b/modules/extfs/deb.in @@ -0,0 +1,188 @@ +#!/usr/bin/perl +# +# Written by Fernando Alegre 1996 +# +# Applied patch by Dimitri Maziuk 1997 +# (to handle new tar format) +# +# Modified by Fernando Alegre 1997 +# (to handle both new and old tar formats) +# +# Modified by Patrik Rak 1998 +# (add by Michael Bramer Debian-mc-maintainer ) +# (to allow access to package control files) +# +# +# +# Copyright (C) 1997 Free Software Foundation +# + +sub mcdebfs_list +{ +# +# CAVEAT: Hard links are listed as if they were symlinks +# Empty directories do not appear at all +# + local($archivename)=@_; + chop($date=`LC_ALL=C date "+%b %d %Y %H:%M"`); + chop($info_size=`dpkg -I $archivename | wc -c`); + $install_size=length($pressinstall); + + print "dr-xr-xr-x 1 root root 0 $date CONTENTS\n"; + # from Patrik Rak + print "dr-xr-xr-x 1 root root 0 $date DEBIAN\n"; + print "-r--r--r-- 1 root root $info_size $date INFO\n"; + print "-r-xr--r-- 1 root root $install_size $date INSTALL\n"; + + if ( open(PIPEIN, "dpkg-deb -c $archivename |") ) + { + while() + { + split; + + $perm=$_[0]; $owgr=$_[1]; $size=$_[2]; + if($_[3] =~ /^\d\d\d\d\-/) { # New tar format + + ($year,$mon,$day) = split(/-/,$_[3]); + $month = ("Gee","Jan","Feb","Mar","Apr","May","Jun", + "Jul","Aug","Sep","Oct","Nov","Dec")[$mon] || "Gee"; + $time=$_[4]; + $pathindex=5; + } + else { + $month=$_[3]; + $day=$_[4]; + $time=$_[5]; + $year=$_[6]; + $pathindex=7; + } + + $path=$_[$pathindex++]; + $arrow=$_[$pathindex++]; + $link=$_[$pathindex++]; + $link2=$_[$pathindex++]; + + $owgr=~s!/! !; + next if $path=~m!/$!; + if($arrow eq 'link') + { +# report hard links as soft links + $arrow='->'; $link="/$link2"; + substr($perm, 0, 1) = "l"; + } + if($arrow ne '') + { + $arrow=' ' . $arrow; + $link= ' ' . $link; + } + print "$perm 1 $owgr $size $month $day $year $time CONTENTS/$path$arrow$link\n"; + } + } + # begin from Patrik Rak + if ( open(PIPEIN, "dpkg-deb -I $archivename |") ) + { + while() + { + split; + $size=$_[0]; + last if $size =~ /:/; + next if $size !~ /\d+/; + if($_[4] eq '*') + { + $perm='-r-xr-xr-x'; + $name=$_[5]; + } + else + { + $perm='-r--r--r--'; + $name=$_[4]; + } + print "$perm 1 root root $size $date DEBIAN/$name\n"; + } + } + # end from Patrik Rak + +} + +sub mcdebfs_copyout +{ + local($archive,$filename,$destfile)=@_; + + if($filename eq "INFO") + { + system("dpkg-deb -I $archive > $destfile"); + # begin from Patrik Rak + } + elsif($filename =~ /^DEBIAN/) + { + $filename=~s!^DEBIAN/!!; + system("dpkg-deb -I $archive $filename > $destfile"); + # end from Patrik Rak + + } + elsif($filename eq "INSTALL") + { + if ( open(FILEOUT,">$destfile") ) + { + print FILEOUT $pressinstall; + close FILEOUT; + system("chmod a+x $destfile"); + } + } + else + { + $filename=~s!^CONTENTS/!!; + system("dpkg-deb --fsys-tarfile $archive | tar xOf - $filename > $destfile"); + } +} + +sub mcdebfs_run +{ + local($archive,$filename)=@_; + if($filename eq "INSTALL") + { + print "Installing $archive\n"; + system("dpkg -i $archive"); + } + else + { + $suffix = "aaa"; + while (1) { + $tmpdir = "/tmp/mcdebfs.run".$$.$suffix; + last if mkdir $tmpdir, 0700; + $suffix++; + # Somebody is being really nasty, give up + exit 1 if $suffix eq "zzz"; + } + + $tmpcmd="$tmpdir/run"; + &mcdebfs_copyout($archive, $filename, $tmpcmd); + system("chmod u+x $tmpcmd"); + system($tmpcmd); + unlink($tmpcmd); + rmdir($tmpdir); + } +} + +$pressinstall=<, Feb 1998 +# +# This script makes it possible to view and copy files to/from a hp48 +# (tested with a HP48G and the emulator x48) +# +# To use the hp48 external filesystem: +# - read the relevant parts of your HP48 manual +# - install kermit +# - connect the HP48 to your computer or start x48 +# - below change the line which reflects the serial device you use +# - configure your HP48 ( - i/o - iopar): +# port: wire +# baud: 9600 +# transfer format: binary (fast transfers) or +# ascii (editable on the pc) +# - start the server on the HP48: - i/o - srvr - serve +# or the shortcut - +# - on MC's commandline enter "cd hp48:" +# +# Make sure you have kermit installed and that it's using the right serial +# device by changing /dev/ttyXX on the next line +AWK=awk +KERMIT="kermit -l /dev/ttyS1 -b 9600" + +hp48_cmd() +{ +$KERMIT -C "SET EXIT WARNING OFF,REMOTE $*,QUIT" +} + +hp48_cd() +{ +(echo SET EXIT WARNING OFF;echo REMOTE HOST HOME +for HP48_DIR in `echo $*|tr '/' ' '`;do + if [ "$HP48_DIR" != "." ];then echo REMOTE HOST $HP48_DIR;fi +done +echo QUIT)| $KERMIT -B >/dev/null +} + +hp48_retdir() +{ +echo $1 +} + +hp48_retsize() +{ +printf "%d" $2 2>/dev/null +} + +hp48_parser() +{ +HP48_DIRS= +read INPUT +while [ "$INPUT" != "EOF" ] +do + case `echo $INPUT | @AWK@ '{if (int($2)) if ($3=="Directory") print "dir";else print "file"}'` in + dir) HP48_DIRS="$HP48_DIRS `hp48_retdir $INPUT`" + printf "drwxr-xr-x 1 %-8d %-8d %8d %s %s\n" 0 0 `hp48_retsize $INPUT` "`date +\"%b %d %Y %k:%M"`" "$HP48_CDIR/`hp48_retdir $INPUT`";; + file) printf "-rw-r--r-- 1 %-8d %-8d %8d %s %s\n" 0 0 `hp48_retsize $INPUT` "`date +"%b %d %Y %k:%M"`" "$HP48_CDIR/`hp48_retdir $INPUT`";; + esac + read INPUT +done +for HP48_DIR in $HP48_DIRS;do + HP48_PDIR=$HP48_CDIR + HP48_CDIR=$HP48_CDIR/$HP48_DIR; hp48_cmd HOST $HP48_DIR >/dev/null + hp48_list + HP48_CDIR=$HP48_PDIR; hp48_cmd HOST UPDIR >/dev/null +done +} + +hp48_list() +{ +(hp48_cmd DIRECTORY;echo;echo EOF)|hp48_parser +} + +# override any locale for dates +LC_ALL=C +export LC_ALL + +case $1 in +list) HP48_CDIR= + hp48_cmd HOST HOME >/dev/null + hp48_list + exit 0;; +copyout) + cd `dirname $4` + hp48_cd `dirname $3` + $KERMIT -B -g `basename $3` -a $4 >/dev/null + exit 0;; +copyin) + cd `dirname $4` + hp48_cd `dirname $3` + $KERMIT -B -s $4 -a `basename $3` >/dev/null + exit 0;; +esac +exit 1 diff --git a/modules/extfs/lha.in b/modules/extfs/lha.in new file mode 100644 index 0000000..58293e3 --- /dev/null +++ b/modules/extfs/lha.in @@ -0,0 +1,164 @@ +#! /bin/sh + +# +# LHa Virtual filesystem executive v0.1 +# Copyright (C) 1996, 1997 Joseph M. Hinkle +# May be distributed under the terms of the GNU Public License +# +# + +# Code for mc_lha_fs_run() suggested by: +# Jan 97 Zdenek Kabelac + +# Tested with mc 3.5.18 and gawk 3.0.0 on Linux 2.0.0 +# Tested with lha v1.01 and lharc v1.02 +# Information and sources for other forms of lha/lzh appreciated + +# Nota bene: +# There are several compression utilities which produce *.lha files. +# LHArc and LHa in exist several versions, and their listing output varies. +# Another variable is the architecture on which the compressed file was made. +# This program attempts to sort out the variables known to me, but it is likely +# to display an empty panel if it encounters a mystery. +# In that case it will be useful to execute this file from the command line: +# ./lha list Mystery.lha +# to examine the output directly on the console. The output string must be +# precisely in the format described in the README in this directory. +# Another helpful thing is to temporarily remove the redirection of error +# output of awk (The '2> /dev/null' instruction near the end of mcfs_list()) +# The screen will get ugly if there's an error, but some useful text shows +# at the bottom of the screen. +# Caveat emptor. +# Learn Latin. + +# Define your awk +AWK=@AWK@ + +if ls -de . >& /dev/null; +then + LS_COMMAND="ls -le" +else + LS_COMMAND="ls -l --full-time" +fi + +# Define which archiver you are using with appropriate options +LHA_LIST="lha l" +LHA_GET="lha pq" +LHA_PUT="lha aq" + +# Define a directory to create a temporary file for when +# running a command to be run from the archive +TMPDIR=/tmp/mc-cmd.$$ +# Temporary file within the directory +TMPCMD=$TMPDIR/run + +# The 'list' command executive + +mc_lha_fs_list() +{ + # Get the year of the file timestamp in case we need to replace 'hh:mm' + YEAR=$($LS_COMMAND $1 | $AWK '{ print $10 }') + # List the contents of the archive and sort it out + $LHA_LIST $1 | $AWK -v uid=$(id -nu) -v gid=$(id -ng) -v year=$YEAR ' + # Ignore the annotations, quit on the last one + /^\ PERMSSN/ { next } + /^-----/ { next } + /^\ Total/ { exit 0 } + # Strip a leading '/' if present in a filepath + $(NF) ~ /^\// { $(NF) = substr($NF,2) } + # Replace the year stamp if it is expressed as 'hh:mm' + $(NF-1) ~ /\:/ { $(NF-1) = year } + # Print the line this way if there is no permission string + $1 ~ /^\[generic\]/ { + # Invent a generic permission + $1 = ($10 ~ /\/$/) ? "drwxr-xr-x":"-rwxr--r--"; + # Print it + printf "%s 1 %-8s %-8s %-8d %3s %2d %4d %s\n", + $1, uid, gid, $2, $4, $5, $6, $7; + # Get the next line of the list + next; + } + # Do it this way for a defined permission + $1 !~ /^\[generic\]/ { + # If the permissions and UID run together + if ($1 ~ /\//) { + $8 = $7; + $7 = $6; + $6 = $5; + $5 = $4; + $3 = $2; + $2 = substr($1,10); + $1 = substr($1,1,9); + } + # If the permission string is missing a type + if (length($1) == 9) { + if ($NF ~ /\/$/) + $1 = ("d" $1); + else + $1 = ("-" $1); + } + # UID:GID might not be the same as on your system so print numbers + # Well, that is the intent. At the moment mc is translating them. + split($2, id, "/"); + printf "%s 1 %-8d %-8d %-8d %3s %2d %4d %s\n", + $1, id[1], id[2], $3, $5, $6, $7, $8; + # Get the next line of the list + next; + } + + ' 2> /dev/null +} + +# The 'copyout' command executive to copy displayed files to a destination + +mc_lha_fs_copyout() +{ + $LHA_GET $1 $2 > $3 2> /dev/null +} + +# The 'copyin' command executive to add something to the archive + +mc_lha_fs_copyin () +{ + NAME2=`basename $2`; DIR2=${2%$NAME2} + NAME3=`basename $3`; DIR3=${3%$NAME3} + + cd ${DIR3} + + ONE2=${2%%/*} + [ -n ${ONE2} ] || exit + [ -e ${ONE2} ] && exit + + [ -e ${DIR2} ] || mkdir -p ${DIR2} + ln $3 $2 || exit + + $LHA_PUT $1 $2 2> /dev/null + rm -r ${ONE2} +} + +# The 'run' command executive to run a command from within an archive + +mc_lha_fs_run() +{ + trap "rm $TMPCMD; rmdir $TMPDIR; exit 0" 1 2 3 4 15 +# FIXME bugzilla.eazel.com 1225: Try harder to generate a unique directory if this fails + mkdir -m 0700 $TMPDIR || exit 1 + $LHA_GET $1 $2 > $TMPCMD 2> /dev/null + chmod a+x $TMPCMD 2> /dev/null + $TMPCMD 2> /dev/null + rm $TMPCMD + rmdir $TMPDIR +} + + +# The main routine +umask 077 + +case "$1" in + list) mc_lha_fs_list $2; exit $?;; + copyout) mc_lha_fs_copyout $2 $3 $4; exit $?;; + copyin) mc_lha_fs_copyin $2 $3 $4; exit $?;; + run) mc_lha_fs_run $2 $3 $4; exit $?;; +esac +exit 1 + diff --git a/modules/extfs/mailfs b/modules/extfs/mailfs new file mode 100644 index 0000000..91757d9 --- /dev/null +++ b/modules/extfs/mailfs @@ -0,0 +1,115 @@ +#!/usr/bin/perl + +# MC extfs for (possibly compressed) Berkeley style mailbox files +# Peter Daum (Jan 1998, mc-4.1.24) + +$zcat="zcat"; # gunzip to stdout +$bzcat="bzip2 -dc"; # bunzip2 to stdout +$file="file"; # "file" command +$TZ='GMT'; # default timezone (for Date module) + +if (eval "require Date::Parse") { # fancy date parsing available? + import Date::Parse; + $parse_date= + sub { + local $_ =localtime(str2time($_[0],$TZ)); + s/^... (.+) (\d\d:\d\d):\d\d (\d\d\d\d)$/$1 $3 $2/; + return $_; + } +} else { # use "light" version + $parse_date= sub { + # assumes something like: Mon, 5 Jan 1998 16:08:19 +0200 (GMT+0200) + # if you have mails with another date format, add it here + if (/(\d\d?) ([A-Z][a-z][a-z]) (\d\d\d\d) (\d\d:\d\d):\d\d/) { + return "$2 $1 $3 $4"; + } + } +} + +sub process_header { + while () { + last if /^$/; + die "unexpeced EOF\n" if eof; + if (/^Date: (.*)$/) { + $date=&$parse_date($1); + } elsif (/^Subject: (.*)$/) { + $subj=$1; + $subj=~ s/^(re: ?)+//gi; # no leading Re: + $subj=~ tr/a-zA-Z0-9//cd; # strip all "special" characters + } elsif (/^From: .*?(\w+)\@/) { + $from=$1; + } elsif (/^To: .*?(\w+)\@/) { + $to=$1; + } + } +} + +sub print_dir_line { + $from=$to if ($from eq $user); # otherwise, it would look pretty boring + printf "-r-------- 1 $< $< %d %s %3.3d_%.16s\n", + $line, $date, $msg_nr, "${from}_${subj}"; +} + +sub mailfs_list { + my $blank = 1; + $user=$ENV{USER}||getlogin||getpwuid($<) || "nobody"; + + while(1) { + $_=; + if (!defined($_)) { # EOF + print_dir_line; + exit 0; + } + if($blank && /^From /) { # Start of header + print_dir_line unless (!$msg_nr); + $msg_nr++; + ($from,$to,$subj,$date)=("none","none","none", "01-01-80"); + process_header; + $line=$blank= 0; + } else { + $line++; + $blank= /^$/; + } + } +} + +sub mailfs_copyout { + my($source,$dest)=@_; + exit 1 unless (open STDOUT, ">$dest"); + ($nr)= ($source =~ /^(\d+)/); # extract message number from "filename" + + my $blank = 1; + while() { + if($blank && /^From /) { + $msg_nr++; + exit(0) if ($msg_nr > $nr); + $blank= 0; + } else { + $blank= /^$/; + } + print if ($msg_nr == $nr); + } +} + +# main { +$msg_nr=0; +$cmd=shift; +$mbox_name=shift; +$_=`$file $mbox_name`; + +if (/gzip/) { + exit 1 unless (open IN, "$zcat $mbox_name|"); +} elsif (/bzip/) { + exit 1 unless (open IN, "$bzcat $mbox_name|"); +} else { + exit 1 unless (open IN, "<$mbox_name"); +} + +umask 077; + +if($cmd eq "list") { &mailfs_list; exit 0; } +elsif($cmd eq "copyout") { &mailfs_copyout(@ARGV); exit 0; } + +exit 1; + + diff --git a/modules/extfs/patchfs b/modules/extfs/patchfs new file mode 100644 index 0000000..12a7490 --- /dev/null +++ b/modules/extfs/patchfs @@ -0,0 +1,73 @@ +#!/bin/sh + +# Peter Daum (Jan 1998, mc-4.1.22) + +# paths to used programs: +ncat=cat # regular cat +zcat=zcat # gunzip to stdout +bzcat="bzip2 -dc" # bunzip2 to stdout +file=file # "file" command +sed=sed + +filelist=FILELIST # names for "special" files + +patchfs_list () +{ + date=`date +"%b %d %H:%M"` + perm="-r--r--r--" + uid=00000000 + gid=00000000 + size=00000000 + nlink=" 1" + + echo "$perm $nlink $uid $gid $size $date $filelist" + $cat $1 | + $sed -n "/^diff /{ + s|^.* \([^ ]*\)$|$perm $nlink $uid $gid $size $date \1|gp + }" +} + +patchfs_copyout () +{ + if [ "$2" = "$filelist" ]; then # list of all affected files + $cat $1 | + $sed -n "/^diff /{ + s|^.* \([^ ]*\)$|\1|gp + }" > $3 + exit 0 + fi + + fn=`echo $2|$sed 's|/|\\\/|g'` # escape '/' in filename + $cat $1 | + $sed -n "/^diff .*$fn/,/^diff /{ + /^diff ./{ + /$fn/p + d + } + p + }" > $3 +} + +patchfs_run () +{ + exit 0 +} + +type=`$file $2` +case $type in + *bzip*) cat=$bzcat ;; + *gzip*) cat=$zcat ;; + *text*) cat=$ncat ;; + *) exit 1 +esac + +umask 077 +case "$1" in + list) patchfs_list $2; exit 0;; + copyout) patchfs_copyout $2 $3 $4; exit 0;; + run) patchfs_run; exit 0;; +esac + +exit 1 + + diff --git a/modules/extfs/rar.in b/modules/extfs/rar.in new file mode 100644 index 0000000..29beebd --- /dev/null +++ b/modules/extfs/rar.in @@ -0,0 +1,101 @@ +#! /bin/sh +# +# Written by andrey joukov +# (C) 1996 2:5020/337.13@fidonet.org +# Updated by christian.gennerat@alcatel.fr 1999 +# beta version 2.0 +# +DRAR=/usr/bin +RAR=$DRAR/rar +UNRAR=$DRAR/unrar # Prefer unrar (freeware) +# +# NOTE: rar ver 2.0 by Eugene Roshal +# ftp.elf.stuba.sk/pub/pc/pack +# + +mcrarfs_list () +{ + $UNRAR v -c- "$1" | @AWK@ -v uid=${UID-0} ' +BEGIN { flag=0; date="JanFebMarAprMayJunJulAugSepOctNovDec" } +/^-------/ { flag++; if (flag > 1) exit 0; next } +{ +if (flag == 0) next +if ( !/ [0-9][0-9]:[0-9][0-9] /) str = $0 # there is no time spec in this line +else { + if (str ~ /^\^/) + str=substr(str, 2) + split($4, a, "-") + if (a[3] < 50) + a[3] = 2000 + a[3] + else + a[3] = 1900 + a[3] + if (index($6, "D") != 0) + $6="drwxr-xr-x" + else + if (index($6, ".") != 0) + $6="-rw-r--r--" + printf "%s 1 %-8d %-8d %8d %3s %2d %4d %s %s\n", $6, uid, 0, $1, substr(date, (a[2]-1)*3+1, 3), a[1], a[3], $5, str +} +}' 2>/dev/null +} + +mcrarfs_copyin () +{ +# copyin by christian.gennerat@alcatel.fr +# preserve pwd. It is clean, but is it necessary? + pwd=`pwd` +# Create a directory and copy in it the tmp file with the good name + mkdir $3.dir + cd $3.dir + di="${2%/*}" +# if file is to be written upper in the archive tree, make fake dir + if test "$di" != "${2##*/}" ; then + mkdir -p "$di" + fi +# (cp -p) to preserve date, but $2 is dated now! + cp -p $3 "$3.dir/$2" + $RAR a "$1" "$2" >/dev/null + cd $pwd + rm -rf $3.dir +} + +mcrarfs_copyout () +{ + $UNRAR p -c- -inul "$1" "$2" > $3 2>/dev/null +} + +mcrarfs_mkdir () +{ +# preserve pwd. It is clean, but is it necessary? + pwd=`pwd` +# Create a directory and create in it a tmp directory with the good name + dir=tmpdir.${RANDOM} + mkdir $dir + cd $dir + mkdir -p "$2" +# rar cannot create an empty directory + touch "$2"/.rarfs + $RAR a -r "$1" "$2" &>/dev/null + $RAR d "$1" "$2"/.rarfs &>/dev/null + cd $pwd + rm -rf $dir +} + +mcrarfs_rm () +{ + $RAR d "$1" "$2" &>/dev/null +} + +umask 077 + +# uncomment this line for debugging +#echo "`date +%T` ${0##*/} $1 $2 to=$3 tmp=$4" >>/tmp/${0##*/}.log +case "$1" in + list) mcrarfs_list "$2"; exit 0;; + rm) mcrarfs_rm "$2" "$3" ; exit 0;; + rmdir) mcrarfs_rm "$2" "$3" ; exit 0;; + mkdir) mcrarfs_mkdir "$2" "$3" ; exit 0;; + copyin) mcrarfs_copyin "$2" "$3" $4; exit 0;; + copyout) mcrarfs_copyout "$2" "$3" $4; exit 0;; +esac +exit 1 diff --git a/modules/extfs/rpm b/modules/extfs/rpm new file mode 100644 index 0000000..a67a958 --- /dev/null +++ b/modules/extfs/rpm @@ -0,0 +1,171 @@ +#! /bin/sh +# +# Written by Erik Troan (ewt@redhat.com) 1996 +# Jakub Jelinek (jj@sunsite.mff.cuni.cz) 1996 +# Tomasz K³oczko (kloczek@rudy.mif.pg.gda.pl) 1997 +# minor changes by Wojtek Pilorz (wpilorz@bdk.lublin.pl) 1997 +# minor changes by Michele Marziani (marziani@fe.infn.it) 1997 +# bug files by Marc Merlin (marcsoft@merlins.org) 1998 +# (C) 1996 The Free Software Foundation. +# +# + +mcrpmfs_list () +{ + # set MCFASTRPM_DFLT to 1 for faster rpm files handling by default, to 0 for + # slower handling + MCFASTRPM_DFLT=0 + if test -z "$MCFASTRPM"; then + MCFASTRPM=$MCFASTRPM_DFLT + fi + FILEPREF="-r--r--r-- 1 root root " + DESC=`rpm -qip "$1"` + DATE=`rpm -qp --qf "%{BUILDTIME:date}\n" "$1" | cut -c 5-11,21-24` + HEADERSIZE=`echo "$DESC" | wc -c` + echo "-r--r--r-- 1 root root $HEADERSIZE $DATE HEADER" + echo "-r-xr-xr-x 1 root root 39 $DATE INSTALL" + echo "-r-xr-xr-x 1 root root 39 $DATE UPGRADE" + echo "dr-xr-xr-x 3 root root 0 $DATE INFO" + echo "$FILEPREF 0 $DATE INFO/NAME-VERSION-RELEASE" + echo "$FILEPREF 0 $DATE INFO/GROUP" + echo "$FILEPREF 0 $DATE INFO/BUILDHOST" + echo "$FILEPREF 0 $DATE INFO/SOURCERPM" + if test "$MCFASTRPM" = 0 ; then + test "`rpm -qp --qf \"%{DISTRIBUTION}\" \"$1\"`" = "(none)" || + echo "$FILEPREF 0 $DATE INFO/DISTRIBUTION" + test "`rpm -qp --qf \"%{VENDOR}\" \"$1\"`" = "(none)" || + echo "$FILEPREF 0 $DATE INFO/VENDOR" + test "`rpm -qp --qf \"%{DESCRIPTION}\" \"$1\"`" = "(none)" || + echo "$FILEPREF 0 $DATE INFO/DESCRIPTION" + test "`rpm -qp --qf \"%{SUMMARY}\" \"$1\"`" = "(none)" || + echo "$FILEPREF 0 $DATE INFO/SUMMARY" + if test "`rpm -qp --qf \"%{RPMTAG_PREIN}%{RPMTAG_POSTIN}%{RPMTAG_PREUN}%{RPMTAG_POSTUN}%{VERIFYSCRIPT}\" \"$1\"`" != "(none)(none)(none)(none)(none)"; then + echo "dr-xr-xr-x 1 root root 0 $DATE INFO/SCRIPTS" + test "`rpm -qp --qf \"%{RPMTAG_PREIN}\" \"$1\"`" = '(none)' || + echo "$FILEPREF 0 $DATE INFO/SCRIPTS/PREIN" + test "`rpm -qp --qf \"%{RPMTAG_POSTIN}\" \"$1\"`" = '(none)' || + echo "$FILEPREF 0 $DATE INFO/SCRIPTS/POSTIN" + test "`rpm -qp --qf \"%{RPMTAG_PREUN}\" \"$1\"`" = '(none)' || + echo "$FILEPREF 0 $DATE INFO/SCRIPTS/PREUN" + test "`rpm -qp --qf \"%{RPMTAG_POSTUN}\" \"$1\"`" = '(none)' || + echo "$FILEPREF 0 $DATE INFO/SCRIPTS/POSTUN" + test "`rpm -qp --qf \"%{VERIFYSCRIPT}\" \"$1\"`" = '(none)' || + echo "$FILEPREF 0 $DATE INFO/SCRIPTS/VERIFYSCRIPT" + echo "$FILEPREF 0 $DATE INFO/SCRIPTS/ALL" + fi + else + echo "$FILEPREF 0 $DATE INFO/DISTRIBUTION" + echo "$FILEPREF 0 $DATE INFO/VENDOR" + echo "$FILEPREF 0 $DATE INFO/DESCRIPTION" + echo "$FILEPREF 0 $DATE INFO/SUMMARY" + echo "dr-xr-xr-x 1 root root 0 $DATE INFO/SCRIPTS" + echo "$FILEPREF 0 $DATE INFO/SCRIPTS/PREIN" + echo "$FILEPREF 0 $DATE INFO/SCRIPTS/POSTIN" + echo "$FILEPREF 0 $DATE INFO/SCRIPTS/PREUN" + echo "$FILEPREF 0 $DATE INFO/SCRIPTS/POSTUN" + echo "$FILEPREF 0 $DATE INFO/SCRIPTS/VERIFYSCRIPT" + echo "$FILEPREF 0 $DATE INFO/SCRIPTS/ALL" + fi + if test "$MCFASTRPM" = 0 ; then + test "`rpm -qp --qf \"%{PACKAGER}\" \"$1\"`" = "(none)" || + echo "$FILEPREF 0 $DATE INFO/PACKAGER" + test "`rpm -qp --qf \"%{URL}\" \"$1\"`" = "(none)" || + echo "$FILEPREF 0 $DATE INFO/URL" + test "`rpm -qp --qf \"%{SERIAL}\" \"$1\"`" = "(none)" || + echo "$FILEPREF 0 $DATE INFO/SERIAL" + test "`rpm -qp --qf \"%{COPYRIGHT}\" \"$1\"`" = "(none)" || + echo "$FILEPREF 0 $DATE INFO/COPYRIGHT" + test "`rpm -qp --qf \"%{LICENSE}\" \"$1\"`" = "(none)" || + echo "$FILEPREF 0 $DATE INFO/LICENSE" + else + echo "$FILEPREF 0 $DATE INFO/PACKAGER" + echo "$FILEPREF 0 $DATE INFO/URL" + echo "$FILEPREF 0 $DATE INFO/SERIAL" + echo "$FILEPREF 0 $DATE INFO/COPYRIGHT" + echo "$FILEPREF 0 $DATE INFO/LICENSE" + fi + echo "$FILEPREF 0 $DATE INFO/BUILDTIME" + echo "$FILEPREF 0 $DATE INFO/RPMVERSION" + echo "$FILEPREF 0 $DATE INFO/OS" + echo "$FILEPREF 0 $DATE INFO/SIZE" + if test "$MCFASTRPM" != 0 ; then + rpm -qp --qf "[%{REQUIRENAME}\n]" "$1" | grep "(none)" > /dev/null || + echo "$FILEPREF 0 $DATE INFO/REQUIRENAME" + rpm -qp --qf "[%{OBSOLETES}\n]" "$1" | grep "(none)" > /dev/null || + echo "$FILEPREF 0 $DATE INFO/OBSOLETES" + rpm -qp --qf "[%{PROVIDES}\n]" "$1" | grep "(none)" > /dev/null || + echo "$FILEPREF 0 $DATE INFO/PROVIDES" + test "`rpm -qp --qf \"%{CHANGELOGTEXT}\" \"$1\"`" = "(none)" || + echo "$FILEPREF 0 $DATE INFO/CHANGELOG" + else + echo "$FILEPREF 0 $DATE INFO/REQUIRENAME" + echo "$FILEPREF 0 $DATE INFO/OBSOLETES" + echo "$FILEPREF 0 $DATE INFO/PROVIDES" + echo "$FILEPREF 0 $DATE INFO/CHANGELOG" + fi + + rpm -qlvp "$1" | sed -e 's/^\(..........\)[-t]* /\1 1 /' +} + +mcrpmfs_copyout () +{ + case "$2" in + HEADER) rpm -qip "$1" > "$3"; exit 0;; + INSTALL) echo "# Run this to install this RPM package" > "$3"; exit 0;; + UPGRADE) echo "# Run this to upgrade this RPM package" > "$3"; exit 0;; + INFO/NAME-VERSION-RELEASE) rpm -qp --qf "%{NAME}-%{VERSION}-%{RELEASE}\n" "$1" > "$3"; exit 0;; + INFO/RELEASE) rpm -qp --qf "%{RELEASE}\n" "$1" > "$3"; exit 0;; + INFO/GROUP) rpm -qp --qf "%{GROUP}\n" "$1" > "$3"; exit 0;; + INFO/DISTRIBUTION) rpm -qp --qf "%{DISTRIBUTION}\n" "$1" > "$3"; exit 0;; + INFO/VENDOR) rpm -qp --qf "%{VENDOR}\n" "$1" > "$3"; exit 0;; + INFO/BUILDHOST) rpm -qp --qf "%{BUILDHOST}\n" "$1" > "$3"; exit 0;; + INFO/SOURCERPM) rpm -qp --qf "%{SOURCERPM}\n" "$1" > "$3"; exit 0;; + INFO/DESCRIPTION) rpm -qp --qf "%{DESCRIPTION}\n" "$1" > "$3"; exit 0;; + INFO/PACKAGER) rpm -qp --qf "%{PACKAGER}\n" "$1" > "$3"; exit 0;; + INFO/URL) rpm -qp --qf "%{URL}\n" "$1" >"$3"; exit 0;; + INFO/BUILDTIME) rpm -qp --qf "%{BUILDTIME:date}\n" "$1" >"$3"; exit 0;; + INFO/SERIAL) rpm -qp --qf "%{SERIAL}\n" "$1" >"$3"; exit 0;; + INFO/COPYRIGHT) rpm -qp --qf "%{COPYRIGHT}\n" "$1" >"$3"; exit 0;; + INFO/RPMVERSION) rpm -qp --qf "%{RPMVERSION}\n" "$1" >"$3"; exit 0;; + INFO/REQUIRENAME) rpm -qp --qf "[%{REQUIRENAME} %{REQUIREFLAGS:depflags} %{REQUIREVERSION}\n]" "$1" >"$3"; exit 0;; + INFO/PROVIDES) rpm -qp --qf "[%{PROVIDES}\n]" "$1" >"$3"; exit 0;; + INFO/SCRIPTS/PREIN) rpm -qp --qf "%{RPMTAG_PREIN}\n" "$1" >"$3"; exit 0;; + INFO/SCRIPTS/POSTIN) rpm -qp --qf "%{RPMTAG_POSTIN}\n" "$1" >"$3"; exit 0;; + INFO/SCRIPTS/PREUN) rpm -qp --qf "%{RPMTAG_PREUN}\n" "$1" >"$3"; exit 0;; + INFO/SCRIPTS/POSTUN) rpm -qp --qf "%{RPMTAG_POSTUN}\n" "$1" >"$3"; exit 0;; + INFO/SCRIPTS/VERIFYSCRIPT) rpm -qp --qf "%{VERIFYSCRIPT}\n" "$1" >"$3"; exit 0;; + INFO/SCRIPTS/ALL) rpm -qp --scripts "$1" > "$3"; exit 0;; + INFO/SUMMARY) rpm -qp --qf "%{SUMMARY}\n" "$1" > "$3"; exit 0;; + INFO/OS) rpm -qp --qf "%{OS}\n" "$1" > "$3"; exit 0;; + INFO/CHANGELOG) rpm -qp --qf "[* %{CHANGELOGTIME:date} %{CHANGELOGNAME}\n%{CHANGELOGTEXT}\n\n]\n" "$1" > "$3"; exit 0;; + INFO/SIZE) rpm -qp --qf "%{SIZE} bytes\n" "$1" > "$3"; exit 0;; + *) + TMPDIR=/tmp/mctmpdir.$$ + mkdir $TMPDIR || exit 1 + cd $TMPDIR + rpm2cpio "$1" | cpio -iumd --quiet "$2" >/dev/null + mv "$2" "$3" + cd / + rm -rf $TMPDIR;; + esac +} + +mcrpmfs_run () +{ + case "$2" in + INSTALL) echo "Installing \"$1\""; rpm -ivh "$1"; exit 0;; + UPGRADE) echo "Upgrading \"$1\""; rpm -iUvh "$1"; exit 0;; + esac +} + +# override any locale for dates +LC_ALL=C +export LC_ALL + +umask 077 +case "$1" in + list) mcrpmfs_list "$2"; exit 0;; + copyout) mcrpmfs_copyout "$2" "$3" "$4"; exit 0;; + run) mcrpmfs_run "$2" "$3"; exit 1;; +esac +exit 1 diff --git a/modules/extfs/rpms b/modules/extfs/rpms new file mode 100755 index 0000000..67b3f64 --- /dev/null +++ b/modules/extfs/rpms @@ -0,0 +1,61 @@ +#! /usr/bin/perl +# +# Written by Balazs Nagy (julian7@kva.hu) 1998 +# (C) 1998 The Free Software Foundation. +# +# + +sub gd +{ + my ($dt) = @_; + $dt =~ tr/ //s; + $dt =~ s/^\w+ (\w+) (\d+) (\d+:\d+):\d+ .+\n?$/$1 $2 $3/; + return $dt; +} + +$DATE=gd(`date`); + +sub list +{ + my (@rpms, %files, $i, $fn, $dn, $sz, $bt); +# @rpms = `rpm -qa --qf "\%{NAME}-\%{VERSION}-\%{RELEASE}:\%{GROUP}:\%{SIZE}:\%{BUILDTIME:date}\n"`; + @rpms = `rpm -qa --qf "\%{NAME}-\%{VERSION}:\%{GROUP}:\%{SIZE}:\%{BUILDTIME:date}\n"`; + print @trpms; + %files = (); + %sizes = (); + %dates = (); + for $i (@rpms) { + if ($i =~ /^([^:]+):([^:]+):([^:]+):(.+)$/) { + ($fn, $dn, $sz, $bt) = ($1, $2, $3, $4); + $dn =~ s/ /_/g; + if (defined $files{$dn}) { + push(@{$files{$dn}}, $fn); + } else { + @{$files{$dn}} = ($fn); + } + $sizes{$fn} = $sz; + $dates{$fn} = gd($bt); + } + } + for $i (sort keys %files) { + print "dr-xr-xr-x 1 root root 0 $DATE $i/\n"; + for $fn (sort @{$files{$i}}) { + print "-r--r--r-- 1 root root $sizes{$fn} $dates{$fn} $i/$fn.trpm\n"; + } + } +} + +# override any locale for dates +$ENV{"LC_ALL"}="C"; + +#open O, ">>/tmp/tt"; +#print O "RPMS: "; +#for $i (@ARGV) { +# print O "$i "; +#} +#print O "\n"; +#close O; + +if ($ARGV[0] eq "list") { list(); exit(0); } +elsif ($ARGV[0] eq "copyout") { open O, ">$ARGV[3]"; print O $ARGV[2], "\n"; close O; exit(0); } +exit(1); diff --git a/modules/extfs/tar b/modules/extfs/tar new file mode 100644 index 0000000..b9563e5 --- /dev/null +++ b/modules/extfs/tar @@ -0,0 +1,34 @@ +#!/usr/bin/perl + +sub list { + ($filename) = @_; + $uid = `id -u`; + $gid = `id -g`; + chomp($uid); + chomp($gid); + open(TARLIST, "tar tvf $filename|"); + while() { + s/\s+/ /g; + ($perms, $usergroup, $size, $date, $time, $name) = split; + + # convert tar fmt dates/times to our date/time format + ($year, $month, $day) = split(/-/, $date); + ($hours, $mins, $secs) = split(/-/, $time); + #printf "-rw------- 1 %-8s %-8s %8s %02d-%02d-%02d %02d:%02d %s\n", $uid, $gid, $size, $day, $month, ($year%100), $hours, $mins, $name; + printf "%s 1 %-8s %-8s %8s %02d-%02d-%02d %02d:%02d %s\n", $perms, $uid, $gid, $size, $day, $month, ($year%100), $hours, $mins, $name; + } +} + +sub copyout { + ($archive, $stored, $local) = @_; + $result = system("tar xOf $archive $stored > $local"); + exit $result +} + +$command = $ARGV[0]; + +if($command eq "list") { + list($ARGV[1]); +} elsif($command eq "copyout") { + copyout($ARGV[1], $ARGV[2], $ARGV[3]); +} diff --git a/modules/extfs/trpm b/modules/extfs/trpm new file mode 100644 index 0000000..c9006c2 --- /dev/null +++ b/modules/extfs/trpm @@ -0,0 +1,161 @@ +#! /bin/sh +# +# Written by Erik Troan (ewt@redhat.com) 1996 +# Jakub Jelinek (jj@sunsite.mff.cuni.cz) 1996 +# Tomasz K³oczko (kloczek@rudy.mif.pg.gda.pl) 1997 +# minor changes by Wojtek Pilorz (wpilorz@bdk.lublin.pl) 1997 +# minor changes by Michele Marziani (marziani@fe.infn.it) 1997 +# slight changes to put rpm to Trpm by Balazs Nagy (julian7@kva.hu) 1998 +# (C) 1996 The Free Software Foundation. +# +# + +mcrpmfs_list () +{ + # set MCFASTRPM_DFLT to 1 for faster rpm files handling by default, to 0 for + # slower handling + MCFASTRPM_DFLT=0 + if test -z "$MCFASTRPM"; then + MCFASTRPM=$MCFASTRPM_DFLT + fi + FILEPREF="-r--r--r-- 1 root root " + DESC=`rpm -qi $1` + DATE=`rpm -q --qf "%{BUILDTIME:date}" $1 | cut -c 5-11,21-24` + HEADERSIZE=`echo "$DESC" | wc -c` + echo "-r--r--r-- 1 root root $HEADERSIZE $DATE HEADER" + echo "-r-xr-xr-x 1 root root 39 $DATE UNINSTALL" + echo "dr-xr-xr-x 3 root root 0 $DATE INFO" + echo "$FILEPREF 0 $DATE INFO/NAME-VERSION-RELEASE" + echo "$FILEPREF 0 $DATE INFO/GROUP" + echo "$FILEPREF 0 $DATE INFO/BUILDHOST" + echo "$FILEPREF 0 $DATE INFO/SOURCERPM" + if test "$MCFASTRPM" = 0 ; then + test "`rpm -q --qf \"%{DISTRIBUTION}\" $1`" = "(none)" || + echo "$FILEPREF 0 $DATE INFO/DISTRIBUTION" + test "`rpm -q --qf \"%{VENDOR}\" $1`" = "(none)" || + echo "$FILEPREF 0 $DATE INFO/VENDOR" + test "`rpm -q --qf \"%{DESCRIPTION}\" $1`" = "(none)" || + echo "$FILEPREF 0 $DATE INFO/DESCRIPTION" + test "`rpm -q --qf \"%{SUMMARY}\" $1`" = "(none)" || + echo "$FILEPREF 0 $DATE INFO/SUMMARY" + if test "`rpm -q --qf \"%{RPMTAG_PREIN}%{RPMTAG_POSTIN}%{RPMTAG_PREUN}%{RPMTAG_POSTUN}%{VERIFYSCRIPT}\" $1`" != "(none)(none)(none)(none)(none)"; then + echo "dr-xr-xr-x 1 root root 0 $DATE INFO/SCRIPTS" + test "`rpm -q --qf \"%{RPMTAG_PREIN}\" $1`" = '(none)' || + echo "$FILEPREF 0 $DATE INFO/SCRIPTS/PREIN" + test "`rpm -q --qf \"%{RPMTAG_POSTIN}\" $1`" = '(none)' || + echo "$FILEPREF 0 $DATE INFO/SCRIPTS/POSTIN" + test "`rpm -q --qf \"%{RPMTAG_PREUN}\" $1`" = '(none)' || + echo "$FILEPREF 0 $DATE INFO/SCRIPTS/PREUN" + test "`rpm -q --qf \"%{RPMTAG_POSTUN}\" $1`" = '(none)' || + echo "$FILEPREF 0 $DATE INFO/SCRIPTS/POSTUN" + test "`rpm -q --qf \"%{VERIFYSCRIPT}\" $1`" = '(none)' || + echo "$FILEPREF 0 $DATE INFO/SCRIPTS/VERIFYSCRIPT" + echo "$FILEPREF 0 $DATE INFO/SCRIPTS/ALL" + fi + else + echo "$FILEPREF 0 $DATE INFO/DISTRIBUTION" + echo "$FILEPREF 0 $DATE INFO/VENDOR" + echo "$FILEPREF 0 $DATE INFO/DESCRIPTION" + echo "$FILEPREF 0 $DATE INFO/SUMMARY" + echo "dr-xr-xr-x 1 root root 0 $DATE INFO/SCRIPTS" + echo "$FILEPREF 0 $DATE INFO/SCRIPTS/PREIN" + echo "$FILEPREF 0 $DATE INFO/SCRIPTS/POSTIN" + echo "$FILEPREF 0 $DATE INFO/SCRIPTS/PREUN" + echo "$FILEPREF 0 $DATE INFO/SCRIPTS/POSTUN" + echo "$FILEPREF 0 $DATE INFO/SCRIPTS/VERIFYSCRIPT" + echo "$FILEPREF 0 $DATE INFO/SCRIPTS/ALL" + fi + if test "$MCFASTRPM" = 0 ; then + test "`rpm -q --qf \"%{PACKAGER}\" $1`" = "(none)" || + echo "$FILEPREF 0 $DATE INFO/PACKAGER" + test "`rpm -q --qf \"%{URL}\" $1`" = "(none)" || + echo "$FILEPREF 0 $DATE INFO/URL" + test "`rpm -q --qf \"%{SERIAL}\" $1`" = "(none)" || + echo "$FILEPREF 0 $DATE INFO/SERIAL" + test "`rpm -q --qf \"%{COPYRIGHT}\" $1`" = "(none)" || + echo "$FILEPREF 0 $DATE INFO/COPYRIGHT" + else + echo "$FILEPREF 0 $DATE INFO/PACKAGER" + echo "$FILEPREF 0 $DATE INFO/URL" + echo "$FILEPREF 0 $DATE INFO/SERIAL" + echo "$FILEPREF 0 $DATE INFO/COPYRIGHT" + fi + echo "$FILEPREF 0 $DATE INFO/BUILDTIME" + echo "$FILEPREF 0 $DATE INFO/RPMVERSION" + echo "$FILEPREF 0 $DATE INFO/OS" + echo "$FILEPREF 0 $DATE INFO/SIZE" + if test "$MCFASTRPM" != 0 ; then + rpm -q --qf "[%{REQUIRENAME}\n]" $1 | grep "(none)" > /dev/null || + echo "$FILEPREF 0 $DATE INFO/REQUIRENAME" + rpm -q --qf "[%{PROVIDES}\n]" $1 | grep "(none)" > /dev/null || + echo "$FILEPREF 0 $DATE INFO/PROVIDES" + test "`rpm -q --qf \"%{CHANGELOGTEXT}\" $1`" = "(none)" || + echo "$FILEPREF 0 $DATE INFO/CHANGELOG" + else + echo "$FILEPREF 0 $DATE INFO/REQUIRENAME" + echo "$FILEPREF 0 $DATE INFO/PROVIDES" + echo "$FILEPREF 0 $DATE INFO/CHANGELOG" + fi + + rpm -qlv $1 | sed -e 's/^\(..........\) /\1 1 /' +} + +mcrpmfs_copyout () +{ + case "$2" in + HEADER) rpm -qi $1 > $3; exit 0;; + UNINSTALL) echo "# Run this to uninstall this RPM package" > $3; exit 0;; + INFO/NAME-VERSION-RELEASE) rpm -q --qf "%{NAME}-%{VERSION}-%{RELEASE}\n" $1 > $3; exit 0;; + INFO/RELEASE) rpm -q --qf "%{RELEASE}\n" $1 > $3; exit 0;; + INFO/GROUP) rpm -q --qf "%{GROUP}\n" $1 > $3; exit 0;; + INFO/DISTRIBUTION) rpm -q --qf "%{DISTRIBUTION}\n" $1 > $3; exit 0;; + INFO/VENDOR) rpm -q --qf "%{VENDOR}\n" $1 > $3; exit 0;; + INFO/BUILDHOST) rpm -q --qf "%{BUILDHOST}\n" $1 > $3; exit 0;; + INFO/SOURCERPM) rpm -q --qf "%{SOURCERPM}\n" $1 > $3; exit 0;; + INFO/DESCRIPTION) rpm -q --qf "%{DESCRIPTION}\n" $1 > $3; exit 0;; + INFO/PACKAGER) rpm -q --qf "%{PACKAGER}\n" $1 > $3; exit 0;; + INFO/URL) rpm -q --qf "%{URL}\n" $1 >$3; exit 0;; + INFO/BUILDTIME) rpm -q --qf "%{BUILDTIME:date}\n" $1 >$3; exit 0;; + INFO/SERIAL) rpm -q --qf "%{SERIAL}\n" $1 >$3; exit 0;; + INFO/COPYRIGHT) rpm -q --qf "%{COPYRIGHT}\n" $1 >$3; exit 0;; + INFO/RPMVERSION) rpm -q --qf "%{RPMVERSION}\n" $1 >$3; exit 0;; + INFO/REQUIRENAME) rpm -q --qf "[%{REQUIRENAME} %{REQUIREFLAGS:depflags} %{REQUIREVERSION}\n]" $1 >$3; exit 0;; + INFO/PROVIDES) rpm -q --qf "[%{PROVIDES}\n]" $1 >$3; exit 0;; + INFO/SCRIPTS/PREIN) rpm -q --qf "%{RPMTAG_PREIN}\n" $1 >$3; exit 0;; + INFO/SCRIPTS/POSTIN) rpm -q --qf "%{RPMTAG_POSTIN}\n" $1 >$3; exit 0;; + INFO/SCRIPTS/PREUN) rpm -q --qf "%{RPMTAG_PREUN}\n" $1 >$3; exit 0;; + INFO/SCRIPTS/POSTUN) rpm -q --qf "%{RPMTAG_POSTUN}\n" $1 >$3; exit 0;; + INFO/SCRIPTS/VERIFYSCRIPT) rpm -q --qf "%{VERIFYSCRIPT}\n" $1 >$3; exit 0;; + INFO/SCRIPTS/ALL) rpm -q --scripts $1 > $3; exit 0;; + INFO/SUMMARY) rpm -q --qf "%{SUMMARY}\n" $1 > $3; exit 0;; + INFO/OS) rpm -q --qf "%{OS}\n" $1 > $3; exit 0;; + INFO/CHANGELOG) rpm -q --qf "[* %{CHANGELOGTIME:date} %{CHANGELOGNAME}\n%{CHANGELOGTEXT}\n\n]\n" $1 > $3; exit 0;; + INFO/SIZE) rpm -q --qf "%{SIZE} bytes\n" $1 > $3; exit 0;; + *) + cp /$2 $3 + esac +} + +mcrpmfs_run () +{ + case "$2" in + UNINSTALL) echo "Uninstalling $1"; rpm -e $1; exit 0;; + esac +} + +# override any locale for dates +LC_ALL=C +export LC_ALL +name=$2 +if [ ${name%%.trpm} = $name ]; then + name=`head -1 $name` +fi +#echo "TRPM: $@ ($name)" >> /tmp/tt +#name=`echo $(basename $2 .trpm) | sed "s/^\(.*\)\.[^\.]*/\1/"` +name=`basename $name .trpm` +case "$1" in + list) mcrpmfs_list $name; exit 0;; + copyout) mcrpmfs_copyout $name $3 $4; exit 0;; + run) mcrpmfs_run $name $3; exit 1;; +esac +exit 1 diff --git a/modules/extfs/uha.in b/modules/extfs/uha.in new file mode 100644 index 0000000..d227206 --- /dev/null +++ b/modules/extfs/uha.in @@ -0,0 +1,43 @@ +#!/bin/sh +# +# It is the uhafs Valery Kornienkov vlk@st.simbirsk.su 2:5051/30@fidonet +# ver ? :) + +HA=ha # for HA 0.999 Copyright (c) 1995 Harri Hirvola + # Source: ftp://sunsite.unc.edu/pub/Linux/compress/ha0999p-linux.tar.gz + +mchafs_list () +{ + eval $HA lf $1 2>/dev/null |@AWK@ -v uid=${UID-0} ' +{ date="JanFebMarAprMayJunJulAugSepOctNovDec" } +/^===========/ {next} +{ + if ($5="%" && $8~/DIR|ASC|CPY/) { + split($6, a, "-") + split($7, t, ":") + filename=$1 + filesize=$2 + getline + if ($2=="(none)") $2="" + path=$2 + getline + if ($1~/^d.*/) next + printf "%s %s %-8d %-8d %8d %3s %2d %4d %s:%s %s%s \n",\ + $1,1,0,0,filesize, substr(date,(a[2]-1)*3+1,3),a[3],a[1],t[1],t[2],\ + path,filename + } +}' 2>/dev/null +} + +mchafs_copyout () +{ + cd /tmp + eval $HA xy $1 $2 >/dev/null 2>&1 + mv -f $2 $3 +} + +case "$1" in + list) shift; mchafs_list $1; exit 0;; + copyout) shift; mchafs_copyout $1 $2 $3; exit 0;; +esac +exit 1 diff --git a/modules/extfs/zip.in b/modules/extfs/zip.in new file mode 100644 index 0000000..28aaf5f --- /dev/null +++ b/modules/extfs/zip.in @@ -0,0 +1,134 @@ +#! /bin/sh +# +# Written by Jakub Jelinek 1995 +# Updated by Christian Gennerat 1999 +# +# (C) 1995,1999 The Free Software Foundation. +# +# + +DZIP=/usr/bin +XZIP="$DZIP/zip -g" +XDZIP="$DZIP/zip -d" +XUNZIP="$DZIP/unzip" +XZIPINFO="$DZIP/unzip -Z" +# +#If you don't have zipinfo, set ZIPINFO= +# + +mczipfs_list () +{ +DOZIPINFO=no +if test -n "$XZIPINFO"; then + DOZIPINFO= + $XZIPINFO -l "$1" | @AWK@ -v uid=${UID-0} -v zipfile="$1" -v xunzip=${XUNZIP-unzip} ' +/^Archive/ { next } +/^[0-9]*\ file/ { next } +/unx/ { +split($0,a,":") +nam = substr(a[2],4) +if ($1 ~ /^l/ ) { + arrow=" -> " + linkname="" + cmd=xunzip " -p " zipfile " " nam + cmd | getline linkname +} else { + arrow="" + linkname="" +} + +if (nam ~ /^\^/) + nam=substr(nam, 2) +split($8, a, "-") +if (a[3] < 50) + a[3] = 2000 + a[3] +else + a[3] = 1900 + a[3] +printf "%s 1 %-8d %-8d %8d %3s %2d %4d %s %s%s%s\n", $1, uid, 0, $4, a[2], a[1], a[3], $9, nam, arrow, linkname +next +} +{ +exit 214 +}' 2>/dev/null + if test $? = 214; then + DOZIPINFO=no + fi +fi +if test -n "$DOZIPINFO"; then + $XUNZIP -v "$1" | @AWK@ -v uid=${UID-0} ' +BEGIN { hyphens=0 } +/^Archive/ { next } +/^\ Length/ { next } +/^\ ?------/ { if (hyphens > 0) exit 0; hyphens=1; next } +{ +if (hyphens < 1) next; +if ($8 ~ /^\^/) + $8=substr($8, 2) +if ($8 ~ /\/$/) + printf "drwxr-xr-x 1 %-8d %-8d %8d %s %s %s\n", uid, 0, $1, $5, $6, $8 +else + printf "-rw-r--r-- 1 %-8d %-8d %8d %s %s %s\n", uid, 0, $1, $5, $6, $8 +}' 2>/dev/null +fi +} + +mczipfs_mkdir () +{ +# preserve pwd. It is clean, but is it necessary? + pwd=`pwd` +# Create a directory and create in it a tmp directory with the good name + dir=tmpdir.${RANDOM} + mkdir $dir + cd $dir + mkdir -p "$2" + $XZIP "$1" "$2" &>/dev/null + cd $pwd + rm -rf $dir +} + +mczipfs_copyin () +{ +# preserve pwd. It is clean, but is it necessary? + pwd=`pwd` +# Create a directory and copy in it the tmp file with the good name + mkdir $3.dir + cd $3.dir + di="${2%/*}" +# if file is to be written upper in the archive tree, make fake dir + if test "$di" != "${2##*/}" ; then + mkdir -p "$di" + fi +# (cp -p) to preserve date, but $2 is dated now! + cp -p $3 "$3.dir/$2" + $XZIP "$1" "$2" >/dev/null + cd $pwd + rm -rf $3.dir +} + +mczipfs_copyout () +{ + $XUNZIP -p "$1" "$2" > "$3" 2>/dev/null +} + +mczipfs_rm () +{ + $XDZIP "$1" "$2" &>/dev/null +} + +mczipfs_rmdir () +{ + $XDZIP "$1" "$2"/ &>/dev/null +} + +umask 077 + +#echo "`date +%T` ${0##*/} $1 $2 to=$3 tmp=$4" >>/tmp/${0##*/}.log +case "$1" in + list) mczipfs_list "$2"; exit 0;; + rm) mczipfs_rm "$2" "$3" ; exit 0;; + rmdir) mczipfs_rmdir "$2" "$3" ; exit 0;; + mkdir) mczipfs_mkdir "$2" "$3" ; exit 0;; + copyin) mczipfs_copyin "$2" "$3" "$4" ; exit 0;; + copyout) mczipfs_copyout "$2" "$3" "$4" ; exit 0;; +esac +exit 1 diff --git a/modules/extfs/zoo.in b/modules/extfs/zoo.in new file mode 100644 index 0000000..6a6ec52 --- /dev/null +++ b/modules/extfs/zoo.in @@ -0,0 +1,69 @@ +#! /bin/sh +# +# Zoo file system +# +# Copyright ? U. N. Known +# +# This filesystem is _dangerous_. It used to create symlinks in filesystem +# with zoo file, it used to happily delete file from your filesystem. +# Now it is 'only' very ugly (it creates temporary files in ~/.mc/ +# + +ZOO=zoo + +mczoofs_list () +{ + $ZOO l $1 | @AWK@ -v uid=${UID-0} ' +BEGIN { hyphens=0 } +/^---/ { if (hyphens > 0) exit 0; hyphens=1; next } +/^[^\ ]/ { next } +{ +if (NF < 8) + next +if ($8 ~ /^\^/) + $8=substr($8, 2) +if ($6 > 50) + $6=$6 + 1900 +else + $6=$6 + 2000 +split($7, a, ":") +if ($8 ~ /\/$/) + printf "drwxr-xr-x 1 %-8d %-8d %8d %s %2d %4d %02d:%02d %s\n", uid, 0, $1, $5, $4, $6, a[1], a[2], $8 +else + printf "-rw-r--r-- 1 %-8d %-8d %8d %s %2d %4d %02d:%02d %s\n", uid, 0, $1, $5, $4, $6, a[1], a[2], $8 +}' 2>/dev/null + exit 0 +} + +mczoofs_copyout () +{ + $ZOO xp $1 $2 | tail +6l > $3 2>/dev/null + exit 0 +} + +# zoo is stupid and won't be happy when the name has no extension. +# We have to do a small trick :) [pretty dirty, broken hack -- pavel] +if echo $2 | grep '\.zoo$'; then + : +else + SYMLINK=~/.mc/temporary.$2.zoo + if test -f $SYMLINK; then + SYMLINK=~/.mc/temporary.$2. + fi + if test -f $SYMLINK; then + echo "Ugh. I did not expect this to happen. Cleanup your ~/.mc." + sleep 5 + exit 1 + fi + ln -s $2 $SYMLINK + trap 'rm -f $SYMLINK' 0 1 2 3 5 13 15 + $2=$SYMLINK +fi + +umask 077 + +case "$1" in + list) mczoofs_list $2; exit $?;; + copyout) mczoofs_copyout $2 $3 $4; exit $?;; +esac +exit 1 diff --git a/modules/file-method.c b/modules/file-method.c new file mode 100644 index 0000000..d1ac2e4 --- /dev/null +++ b/modules/file-method.c @@ -0,0 +1,2380 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* file-method.c - Local file access method for the GNOME Virtual File + System. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: + Ettore Perazzoli + Pavel Cisler + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_FAM +#include +#include +#endif + +#ifdef HAVE_FAM +FAMConnection *fam_connection = NULL; +G_LOCK_DEFINE_STATIC (fam_connection); + +typedef struct { + FAMRequest request; + GnomeVFSURI *uri; + gboolean cancelled; +} FileMonitorHandle; + +#endif + +#ifdef PATH_MAX +#define GET_PATH_MAX() PATH_MAX +#else +static int +GET_PATH_MAX (void) +{ + static unsigned int value; + + /* This code is copied from GNU make. It returns the maximum + path length by using `pathconf'. */ + + if (value == 0) { + long int x = pathconf(G_DIR_SEPARATOR_S, _PC_PATH_MAX); + + if (x > 0) + value = x; + else + return MAXPATHLEN; + } + + return value; +} +#endif + +#ifdef HAVE_OPEN64 +#define OPEN open64 +#else +#define OPEN open +#endif + +#if defined(HAVE_LSEEK64) && defined(HAVE_OFF64_T) +#define LSEEK lseek64 +#define OFF_T off64_t +#else +#define LSEEK lseek +#define OFF_T off_t +#endif + +static gchar * +get_path_from_uri (GnomeVFSURI const *uri) +{ + gchar *path; + + path = gnome_vfs_unescape_string (uri->text, + G_DIR_SEPARATOR_S); + + if (path == NULL) { + return NULL; + } + + if (path[0] != G_DIR_SEPARATOR) { + g_free (path); + return NULL; + } + + return path; +} + +static gchar * +get_base_from_uri (GnomeVFSURI const *uri) +{ + gchar *escaped_base, *base; + + escaped_base = gnome_vfs_uri_extract_short_path_name (uri); + base = gnome_vfs_unescape_string (escaped_base, G_DIR_SEPARATOR_S); + g_free (escaped_base); + return base; +} + +typedef struct { + GnomeVFSURI *uri; + gint fd; +} FileHandle; + +static FileHandle * +file_handle_new (GnomeVFSURI *uri, + gint fd) +{ + FileHandle *result; + result = g_new (FileHandle, 1); + + result->uri = gnome_vfs_uri_ref (uri); + result->fd = fd; + + return result; +} + +static void +file_handle_destroy (FileHandle *handle) +{ + gnome_vfs_uri_unref (handle->uri); + g_free (handle); +} + +static GnomeVFSResult +do_open (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + GnomeVFSContext *context) +{ + FileHandle *file_handle; + gint fd; + mode_t unix_mode; + gchar *file_name; + struct stat statbuf; + + _GNOME_VFS_METHOD_PARAM_CHECK (method_handle != NULL); + _GNOME_VFS_METHOD_PARAM_CHECK (uri != NULL); + + if (mode & GNOME_VFS_OPEN_READ) { + if (mode & GNOME_VFS_OPEN_WRITE) + unix_mode = O_RDWR; + else + unix_mode = O_RDONLY; + } else { + if (mode & GNOME_VFS_OPEN_WRITE) + unix_mode = O_WRONLY; + else + return GNOME_VFS_ERROR_INVALID_OPEN_MODE; + } + + if (! (mode & GNOME_VFS_OPEN_RANDOM) && (mode & GNOME_VFS_OPEN_WRITE)) + unix_mode |= O_TRUNC; + + file_name = get_path_from_uri (uri); + if (file_name == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + do + fd = OPEN (file_name, unix_mode); + while (fd == -1 + && errno == EINTR + && ! gnome_vfs_context_check_cancellation (context)); + + g_free (file_name); + + if (fd == -1) + return gnome_vfs_result_from_errno (); + + if (fstat (fd, &statbuf) != 0) + return gnome_vfs_result_from_errno (); + + if (S_ISDIR (statbuf.st_mode)) { + close (fd); + return GNOME_VFS_ERROR_IS_DIRECTORY; + } + + file_handle = file_handle_new (uri, fd); + + *method_handle = (GnomeVFSMethodHandle *) file_handle; + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_create (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + gboolean exclusive, + guint perm, + GnomeVFSContext *context) +{ + FileHandle *file_handle; + gint fd; + mode_t unix_mode; + gchar *file_name; + + _GNOME_VFS_METHOD_PARAM_CHECK (method_handle != NULL); + _GNOME_VFS_METHOD_PARAM_CHECK (uri != NULL); + + unix_mode = O_CREAT | O_TRUNC; + + if (!(mode & GNOME_VFS_OPEN_WRITE)) + return GNOME_VFS_ERROR_INVALID_OPEN_MODE; + + if (mode & GNOME_VFS_OPEN_READ) + unix_mode |= O_RDWR; + else + unix_mode |= O_WRONLY; + + if (exclusive) + unix_mode |= O_EXCL; + + file_name = get_path_from_uri (uri); + if (file_name == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + do + fd = OPEN (file_name, unix_mode, perm); + while (fd == -1 + && errno == EINTR + && ! gnome_vfs_context_check_cancellation (context)); + + g_free (file_name); + + if (fd == -1) + return gnome_vfs_result_from_errno (); + + file_handle = file_handle_new (uri, fd); + + *method_handle = (GnomeVFSMethodHandle *) file_handle; + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_close (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + FileHandle *file_handle; + gint close_retval; + + g_return_val_if_fail (method_handle != NULL, GNOME_VFS_ERROR_INTERNAL); + + file_handle = (FileHandle *) method_handle; + + do + close_retval = close (file_handle->fd); + while (close_retval != 0 + && errno == EINTR + && ! gnome_vfs_context_check_cancellation (context)); + + /* FIXME bugzilla.eazel.com 1163: Should do this even after a failure? */ + file_handle_destroy (file_handle); + + if (close_retval != 0) { + return gnome_vfs_result_from_errno (); + } + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_read (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read, + GnomeVFSContext *context) +{ + FileHandle *file_handle; + gint read_val; + + g_return_val_if_fail (method_handle != NULL, GNOME_VFS_ERROR_INTERNAL); + + file_handle = (FileHandle *) method_handle; + + do { + read_val = read (file_handle->fd, buffer, num_bytes); + } while (read_val == -1 + && errno == EINTR + && ! gnome_vfs_context_check_cancellation (context)); + + if (read_val == -1) { + *bytes_read = 0; + return gnome_vfs_result_from_errno (); + } else { + *bytes_read = read_val; + + /* Getting 0 from read() means EOF! */ + if (read_val == 0) { + return GNOME_VFS_ERROR_EOF; + } + } + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_write (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gconstpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_written, + GnomeVFSContext *context) +{ + FileHandle *file_handle; + gint write_val; + + g_return_val_if_fail (method_handle != NULL, GNOME_VFS_ERROR_INTERNAL); + + file_handle = (FileHandle *) method_handle; + + do + write_val = write (file_handle->fd, buffer, num_bytes); + while (write_val == -1 + && errno == EINTR + && ! gnome_vfs_context_check_cancellation (context)); + + if (write_val == -1) { + *bytes_written = 0; + return gnome_vfs_result_from_errno (); + } else { + *bytes_written = write_val; + return GNOME_VFS_OK; + } +} + + +static gint +seek_position_to_unix (GnomeVFSSeekPosition position) +{ + switch (position) { + case GNOME_VFS_SEEK_START: + return SEEK_SET; + case GNOME_VFS_SEEK_CURRENT: + return SEEK_CUR; + case GNOME_VFS_SEEK_END: + return SEEK_END; + default: + g_warning (_("Unknown GnomeVFSSeekPosition %d"), position); + return SEEK_SET; /* bogus */ + } +} + +static GnomeVFSResult +do_seek (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSSeekPosition whence, + GnomeVFSFileOffset offset, + GnomeVFSContext *context) +{ + FileHandle *file_handle; + gint lseek_whence; + + file_handle = (FileHandle *) method_handle; + lseek_whence = seek_position_to_unix (whence); + + if (LSEEK (file_handle->fd, offset, lseek_whence) == -1) { + if (errno == ESPIPE) + return GNOME_VFS_ERROR_NOT_SUPPORTED; + else + return gnome_vfs_result_from_errno (); + } + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_tell (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileOffset *offset_return) +{ + FileHandle *file_handle; + OFF_T offset; + + file_handle = (FileHandle *) method_handle; + + offset = LSEEK (file_handle->fd, 0, SEEK_CUR); + if (offset == -1) { + if (errno == ESPIPE) + return GNOME_VFS_ERROR_NOT_SUPPORTED; + else + return gnome_vfs_result_from_errno (); + } + + *offset_return = offset; + return GNOME_VFS_OK; +} + + +static GnomeVFSResult +do_truncate_handle (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileSize where, + GnomeVFSContext *context) +{ + FileHandle *file_handle; + + g_return_val_if_fail (method_handle != NULL, GNOME_VFS_ERROR_INTERNAL); + + file_handle = (FileHandle *) method_handle; + + if (ftruncate (file_handle->fd, where) == 0) { + return GNOME_VFS_OK; + } else { + switch (errno) { + case EBADF: + case EROFS: + return GNOME_VFS_ERROR_READ_ONLY; + case EINVAL: + return GNOME_VFS_ERROR_NOT_SUPPORTED; + default: + return GNOME_VFS_ERROR_GENERIC; + } + } +} + +static GnomeVFSResult +do_truncate (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileSize where, + GnomeVFSContext *context) +{ + gchar *path; + + path = get_path_from_uri (uri); + if (path == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + if (truncate (path, where) == 0) { + g_free (path); + return GNOME_VFS_OK; + } else { + g_free (path); + switch (errno) { + case EBADF: + case EROFS: + return GNOME_VFS_ERROR_READ_ONLY; + case EINVAL: + return GNOME_VFS_ERROR_NOT_SUPPORTED; + default: + return GNOME_VFS_ERROR_GENERIC; + } + } +} + +typedef struct { + GnomeVFSURI *uri; + DIR *dir; + GnomeVFSFileInfoOptions options; + + struct dirent *current_entry; + + gchar *name_buffer; + gchar *name_ptr; +} DirectoryHandle; + +static DirectoryHandle * +directory_handle_new (GnomeVFSURI *uri, + DIR *dir, + GnomeVFSFileInfoOptions options) +{ + DirectoryHandle *result; + gchar *full_name; + guint full_name_len; + + result = g_new (DirectoryHandle, 1); + + result->uri = gnome_vfs_uri_ref (uri); + result->dir = dir; + + /* Reserve extra space for readdir_r, see man page */ + result->current_entry = g_malloc (sizeof (struct dirent) + GET_PATH_MAX() + 1); + + full_name = get_path_from_uri (uri); + g_assert (full_name != NULL); /* already done by caller */ + full_name_len = strlen (full_name); + + result->name_buffer = g_malloc (full_name_len + GET_PATH_MAX () + 2); + memcpy (result->name_buffer, full_name, full_name_len); + + if (full_name_len > 0 && full_name[full_name_len - 1] != '/') + result->name_buffer[full_name_len++] = '/'; + + result->name_ptr = result->name_buffer + full_name_len; + + g_free (full_name); + + result->options = options; + + return result; +} + +static void +directory_handle_destroy (DirectoryHandle *directory_handle) +{ + gnome_vfs_uri_unref (directory_handle->uri); + g_free (directory_handle->name_buffer); + g_free (directory_handle->current_entry); + g_free (directory_handle); +} + +/* MIME detection code. */ +static void +get_mime_type (GnomeVFSFileInfo *info, + const char *full_name, + GnomeVFSFileInfoOptions options, + struct stat *stat_buffer) +{ + const char *mime_type; + + mime_type = NULL; + if ((options & GNOME_VFS_FILE_INFO_FOLLOW_LINKS) == 0 + && (info->type == GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK)) { + /* we are a symlink and aren't asked to follow - + * return the type for a symlink + */ + mime_type = "x-special/symlink"; + } else { + mime_type = gnome_vfs_get_file_mime_type (full_name, + stat_buffer, (options & GNOME_VFS_FILE_INFO_FORCE_FAST_MIME_TYPE) != 0); + } + + g_assert (mime_type); + info->mime_type = g_strdup (mime_type); + info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; +} + +static gchar * +read_link (const gchar *full_name) +{ + gchar *buffer; + guint size; + + size = 256; + buffer = g_malloc (size); + + while (1) { + int read_size; + + read_size = readlink (full_name, buffer, size); + if (read_size < 0) { + g_free (buffer); + return NULL; + } + if (read_size < size) { + buffer[read_size] = 0; + return buffer; + } + size *= 2; + buffer = g_realloc (buffer, size); + } +} + +static void +get_access_info (GnomeVFSFileInfo *file_info, + const gchar *full_name) +{ + /* FIXME: should check errno after calling access because we don't + * want to set valid_fields if something bad happened during one + * of the access calls + */ + if (access (full_name, R_OK) == 0) { + file_info->permissions |= GNOME_VFS_PERM_ACCESS_READABLE; + } + + if (access (full_name, W_OK) == 0) { + file_info->permissions |= GNOME_VFS_PERM_ACCESS_WRITABLE; + } + + if (access (full_name, X_OK) == 0) { + file_info->permissions |= GNOME_VFS_PERM_ACCESS_EXECUTABLE; + } + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_ACCESS; +} + +static GnomeVFSResult +get_stat_info (GnomeVFSFileInfo *file_info, + const gchar *full_name, + GnomeVFSFileInfoOptions options, + struct stat *statptr) +{ + struct stat statbuf; + gboolean followed_symlink; + gboolean is_symlink; + gboolean recursive; + char *link_file_path; + char *symlink_name; + char *symlink_dir; + char *newpath; + + followed_symlink = FALSE; + + recursive = FALSE; + + GNOME_VFS_FILE_INFO_SET_LOCAL (file_info, TRUE); + + if (statptr == NULL) { + statptr = &statbuf; + } + + if (lstat (full_name, statptr) != 0) { + return gnome_vfs_result_from_errno (); + } + + is_symlink = S_ISLNK (statptr->st_mode); + + if ((options & GNOME_VFS_FILE_INFO_FOLLOW_LINKS) && is_symlink) { + if (stat (full_name, statptr) != 0) { + if (errno == ELOOP) { + recursive = TRUE; + } + + /* It's a broken symlink, revert to the lstat. This is sub-optimal but + * acceptable because it's not a common case. + */ + if (lstat (full_name, statptr) != 0) { + return gnome_vfs_result_from_errno (); + } + } + GNOME_VFS_FILE_INFO_SET_SYMLINK (file_info, TRUE); + followed_symlink = TRUE; + } + + gnome_vfs_stat_to_file_info (file_info, statptr); + + if (is_symlink) { + symlink_name = NULL; + link_file_path = g_strdup (full_name); + + /* We will either successfully read the link name or return + * NULL if read_link fails -- flag it as a valid field either + * way. + */ + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_SYMLINK_NAME; + + while (TRUE) { + /* Deal with multiple-level symlinks by following them as + * far as we can. + */ + + g_free (symlink_name); + symlink_name = read_link (link_file_path); + if (symlink_name == NULL) { + g_free (link_file_path); + return gnome_vfs_result_from_errno (); + } + if (symlink_name[0] != '/') { + symlink_dir = g_path_get_dirname (link_file_path); + newpath = g_build_filename (symlink_dir, + symlink_name, NULL); + g_free (symlink_dir); + g_free (symlink_name); + symlink_name = newpath; + } + + if ((options & GNOME_VFS_FILE_INFO_FOLLOW_LINKS) == 0 + /* if we had an earlier ELOOP, don't get in an infinite loop here */ + || recursive + /* we don't care to follow links */ + || lstat (symlink_name, statptr) != 0 + /* we can't make out where this points to */ + || !S_ISLNK (statptr->st_mode)) { + /* the next level is not a link */ + break; + } + g_free (link_file_path); + link_file_path = g_strdup (symlink_name); + } + g_free (link_file_path); + + file_info->symlink_name = symlink_name; + } + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +get_stat_info_from_handle (GnomeVFSFileInfo *file_info, + FileHandle *handle, + GnomeVFSFileInfoOptions options, + struct stat *statptr) +{ + struct stat statbuf; + + if (statptr == NULL) { + statptr = &statbuf; + } + + if (fstat (handle->fd, statptr) != 0) { + return gnome_vfs_result_from_errno (); + } + + gnome_vfs_stat_to_file_info (file_info, statptr); + GNOME_VFS_FILE_INFO_SET_LOCAL (file_info, TRUE); + + return GNOME_VFS_OK; +} + + +static GnomeVFSResult +do_open_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + gchar *directory_name; + DIR *dir; + + directory_name = get_path_from_uri (uri); + if (directory_name == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + dir = opendir (directory_name); + g_free (directory_name); + if (dir == NULL) + return gnome_vfs_result_from_errno (); + + *method_handle + = (GnomeVFSMethodHandle *) directory_handle_new (uri, dir, + options); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_close_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + DirectoryHandle *directory_handle; + + directory_handle = (DirectoryHandle *) method_handle; + + closedir (directory_handle->dir); + + directory_handle_destroy (directory_handle); + + return GNOME_VFS_OK; +} + +#ifndef HAVE_READDIR_R +G_LOCK_DEFINE_STATIC (readdir); +#endif + +static GnomeVFSResult +do_read_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSContext *context) +{ + struct dirent *result; + struct stat statbuf; + gchar *full_name; + DirectoryHandle *handle; + + handle = (DirectoryHandle *) method_handle; + + errno = 0; +#ifdef HAVE_READDIR_R + if (readdir_r (handle->dir, handle->current_entry, &result) != 0) { + /* Work around a Solaris bug. + * readdir64_r returns -1 instead of 0 at EOF. + */ + if (errno == 0) { + return GNOME_VFS_ERROR_EOF; + } + return gnome_vfs_result_from_errno (); + } +#else + G_LOCK (readdir); + errno = 0; + result = readdir (handle->dir); + + if (result == NULL && errno != 0) { + GnomeVFSResult ret = gnome_vfs_result_from_errno (); + G_UNLOCK (readdir); + return ret; + } + if (result != NULL) { + memcpy (handle->current_entry, result, sizeof (struct dirent)); + } + G_UNLOCK (readdir); +#endif + + if (result == NULL) { + return GNOME_VFS_ERROR_EOF; + } + + file_info->name = g_strdup (result->d_name); + + strcpy (handle->name_ptr, result->d_name); + full_name = handle->name_buffer; + + if (get_stat_info (file_info, full_name, handle->options, &statbuf) != GNOME_VFS_OK) { + /* Return OK - this should not terminate the directory iteration + * and we will know from the valid_fields that we don't have the + * stat info. + */ + return GNOME_VFS_OK; + } + + if (handle->options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE) { + get_mime_type (file_info, full_name, handle->options, &statbuf); + } + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_get_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + gchar *full_name; + struct stat statbuf; + + full_name = get_path_from_uri (uri); + if (full_name == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_NONE; + + file_info->name = get_base_from_uri (uri); + g_assert (file_info->name != NULL); + + result = get_stat_info (file_info, full_name, options, &statbuf); + if (result != GNOME_VFS_OK) { + g_free (full_name); + return result; + } + + if (options & GNOME_VFS_FILE_INFO_GET_ACCESS_RIGHTS) { + get_access_info (file_info, full_name); + } + + if (options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE) { + get_mime_type (file_info, full_name, options, &statbuf); + } + + g_free (full_name); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_get_file_info_from_handle (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + FileHandle *file_handle; + gchar *full_name; + struct stat statbuf; + GnomeVFSResult result; + + file_handle = (FileHandle *) method_handle; + + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_NONE; + + full_name = get_path_from_uri (file_handle->uri); + if (full_name == NULL) { + return GNOME_VFS_ERROR_INVALID_URI; + } + + file_info->name = get_base_from_uri (file_handle->uri); + g_assert (file_info->name != NULL); + + result = get_stat_info_from_handle (file_info, file_handle, + options, &statbuf); + if (result != GNOME_VFS_OK) { + g_free (full_name); + return result; + } + + if (options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE) { + get_mime_type (file_info, full_name, options, &statbuf); + } + + g_free (full_name); + + return GNOME_VFS_OK; +} + +GHashTable *fstype_hash = NULL; +G_LOCK_DEFINE_STATIC (fstype_hash); +extern char *filesystem_type (char *path, char *relpath, struct stat *statp); + +static gboolean +do_is_local (GnomeVFSMethod *method, + const GnomeVFSURI *uri) +{ + gchar *path; + gpointer local = NULL; + + g_return_val_if_fail (uri != NULL, FALSE); + + path = get_path_from_uri (uri); + if (path == NULL) + return TRUE; /* GNOME_VFS_ERROR_INVALID_URI */ + + G_LOCK (fstype_hash); + if (fstype_hash == NULL) + fstype_hash = g_hash_table_new_full ( + g_str_hash, g_str_equal, g_free, NULL); + else + local = g_hash_table_lookup (fstype_hash, path); + + if (local == NULL) { + struct stat statbuf; + if (stat (path, &statbuf) == 0) { + char *type = filesystem_type (path, path, &statbuf); + gboolean is_local = ((strcmp (type, "nfs") != 0) && + (strcmp (type, "afs") != 0) && + (strcmp (type, "ncpfs") != 0)); + local = GINT_TO_POINTER (is_local ? 1 : -1); + g_hash_table_insert (fstype_hash, path, local); + } + } else + g_free (path); + + G_UNLOCK (fstype_hash); + return GPOINTER_TO_INT (local) > 0; +} + + +static GnomeVFSResult +do_make_directory (GnomeVFSMethod *method, + GnomeVFSURI *uri, + guint perm, + GnomeVFSContext *context) +{ + gint retval; + gchar *full_name; + + full_name = get_path_from_uri (uri); + if (full_name == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + retval = mkdir (full_name, perm); + + g_free (full_name); + + if (retval != 0) { + return gnome_vfs_result_from_errno (); + } + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_remove_directory (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSContext *context) +{ + gchar *full_name; + gint retval; + + full_name = get_path_from_uri (uri); + if (full_name == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + retval = rmdir (full_name); + + g_free (full_name); + + if (retval != 0) { + return gnome_vfs_result_from_errno (); + } + + return GNOME_VFS_OK; +} + +#undef DEBUG_FIND_DIRECTORY +/* Get rid of debugging code once we know the logic works. */ + +#define TRASH_DIRECTORY_NAME_BASE ".Trash" +#define MAX_TRASH_SEARCH_DEPTH 5 + +/* mkdir_recursive + * Works like mkdir, except it creates all the levels of directories in @path. + */ +static int +mkdir_recursive (const char *path, int permission_bits) +{ + struct stat stat_buffer; + const char *dir_separator_scanner; + char *current_path; + + /* try creating a director for each level */ + for (dir_separator_scanner = path;; dir_separator_scanner++) { + /* advance to the next directory level */ + for (;;dir_separator_scanner++) { + if (!*dir_separator_scanner) { + break; + } + if (*dir_separator_scanner == G_DIR_SEPARATOR) { + break; + } + } + if (dir_separator_scanner - path > 0) { + current_path = g_strndup (path, dir_separator_scanner - path); + mkdir (current_path, permission_bits); + if (stat (current_path, &stat_buffer) != 0) { + /* we failed to create a directory and it wasn't there already; + * bail + */ + g_free (current_path); + return -1; + } + g_free (current_path); + } + if (!*dir_separator_scanner) { + break; + } + } + return 0; +} + + +static char * +append_to_path (const char *path, const char *name) +{ + return g_strconcat (path, G_DIR_SEPARATOR_S, name, NULL); +} + +static char * +append_trash_path (const char *path) +{ + /* When creating trash outside of /home/pavel, create it in the form: + * .Trash-pavel to allow sharing the name space for several users. + * Treat "/" specially to avoid creating non-canonical "//foo" path. + */ + if (strcmp (path, "/") == 0) { + return g_strconcat (path, TRASH_DIRECTORY_NAME_BASE, + "-", g_get_user_name (), NULL); + } else { + return g_strconcat (path, G_DIR_SEPARATOR_S, TRASH_DIRECTORY_NAME_BASE, + "-", g_get_user_name (), NULL); + } +} + +/* Try to find the Trash in @current_directory. If not found, collect all the + * directories in @current_directory to visit later. + */ +static char * +find_trash_in_one_hierarchy_level (const char *current_directory, dev_t near_device_id, + GList **directory_list, GnomeVFSContext *context) +{ + char *trash_path; + char *item_path; + struct stat stat_buffer; + DIR *directory; + struct dirent *item_buffer; + struct dirent *item; + + if (gnome_vfs_context_check_cancellation (context)) + return NULL; + + /* check if there is a trash in this directory */ + trash_path = append_trash_path (current_directory); + if (lstat (trash_path, &stat_buffer) == 0 && S_ISDIR (stat_buffer.st_mode)) { + /* found it, we are done */ + g_assert (near_device_id == stat_buffer.st_dev); + return trash_path; + } + g_free (trash_path); + + + if (gnome_vfs_context_check_cancellation (context)) + return NULL; + + /* Trash not in this directory. + * Collect the list of all the directories in this directory to visit later. + */ + directory = opendir (current_directory); + if (directory == NULL) { + return NULL; + } + + item_buffer = g_malloc (sizeof (struct dirent) + GET_PATH_MAX() + 1); + for (;;) { +#ifdef HAVE_READDIR_R + if (readdir_r (directory, item_buffer, &item) != 0 || item == NULL) { + break; + } +#else + G_LOCK (readdir); + item = readdir (directory); + if (item == NULL) { + G_UNLOCK (readdir); + break; + } +#endif + + if (gnome_vfs_context_check_cancellation (context)) { +#ifndef HAVE_READDIR_R + G_UNLOCK (readdir); +#endif + break; + } + + if (strcmp (item->d_name, ".") == 0 + || strcmp (item->d_name, "..") == 0) { +#ifndef HAVE_READDIR_R + G_UNLOCK (readdir); +#endif + continue; + } + + item_path = append_to_path (current_directory, item->d_name); +#ifndef HAVE_READDIR_R + G_UNLOCK (readdir); +#endif + if (lstat (item_path, &stat_buffer) == 0 + && S_ISDIR (stat_buffer.st_mode) + && near_device_id == stat_buffer.st_dev) { + + /* Directory -- put it on the list to search, + * just as long as it is on the same device. + */ + *directory_list = g_list_prepend (*directory_list, item_path); + } else { + g_free (item_path); + } + if (gnome_vfs_context_check_cancellation (context)) + break; + } + + + closedir (directory); + g_free (item_buffer); + return NULL; +} + +/* Do a width-first search of the directory hierarchy starting at start_dir, + * looking for the trash directory. + * Not doing a traditional depth-first search here to prevent descending too deep in + * the hierarchy -- we expect the Trash to be in a reasonably "shallow" location. + * + * We only look MAX_TRASH_SEARCH_DEPTH deep, if the Trash is deeper in the hierarchy, + * we will fail to find it. + */ +static char * +find_trash_in_hierarchy (const char *start_dir, dev_t near_device_id, GnomeVFSContext *context) +{ + GList *next_directory_list; + char *result; + +#ifdef DEBUG_FIND_DIRECTORY + g_print ("searching for trash in %s\n", start_dir); +#endif + + next_directory_list = NULL; + + /* Search the top level. */ + result = find_trash_in_one_hierarchy_level (start_dir, near_device_id, + &next_directory_list, context); + + gnome_vfs_list_deep_free (next_directory_list); + + return result; +} + +static GList *cached_trash_directories; +G_LOCK_DEFINE_STATIC (cached_trash_directories); + +/* Element used to store chached Trash entries in the local, in-memory Trash item cache. */ +typedef struct { + char *path; + char *device_mount_point; + dev_t device_id; +} TrashDirectoryCachedItem; + +typedef struct { + dev_t device_id; +} FindByDeviceIDParameters; + +static int +match_trash_item_by_device_id (gconstpointer item, gconstpointer data) +{ + const TrashDirectoryCachedItem *cached_item; + FindByDeviceIDParameters *parameters; + + cached_item = (const TrashDirectoryCachedItem *)item; + parameters = (FindByDeviceIDParameters *)data; + + return cached_item->device_id == parameters->device_id ? 0 : -1; +} + +static char * +try_creating_trash_in (const char *path, guint permissions) +{ + char *trash_path; + + + trash_path = append_trash_path (path); + if (mkdir_recursive (trash_path, permissions) == 0) { +#ifdef DEBUG_FIND_DIRECTORY + g_print ("created trash in %s\n", trash_path); +#endif + return trash_path; + } + +#ifdef DEBUG_FIND_DIRECTORY + g_print ("failed to create trash in %s\n", trash_path); +#endif + g_free (trash_path); + return NULL; +} + +static char * +find_disk_top_directory (const char *item_on_disk, + dev_t near_device_id, + GnomeVFSContext *context) +{ + char *disk_top_directory; + struct stat stat_buffer; + + disk_top_directory = g_strdup (item_on_disk); + + /* Walk up in the hierarchy, finding the top-most point that still + * matches our device ID -- the root directory of the volume. + */ + for (;;) { + char *previous_search_directory; + char *last_slash; + + previous_search_directory = g_strdup (disk_top_directory); + last_slash = strrchr (disk_top_directory, '/'); + if (last_slash == NULL) { + g_free (previous_search_directory); + break; + } + + *last_slash = '\0'; + if (lstat (disk_top_directory, &stat_buffer) < 0 + || stat_buffer.st_dev != near_device_id) { + /* we ran past the root of the disk we are exploring */ + g_free (disk_top_directory); + disk_top_directory = previous_search_directory; + break; + } + /* FIXME bugzilla.eazel.com 2733: This must result in + * a cancelled error, but there's no way for the + * caller to know that. We probably have to add a + * GnomeVFSResult to this function. + */ + if (gnome_vfs_context_check_cancellation (context)) { + g_free (previous_search_directory); + g_free (disk_top_directory); + return NULL; + } + } + return disk_top_directory; +} + +#define TRASH_ENTRY_CACHE_PARENT ".gnome/gnome-vfs" +#define TRASH_ENTRY_CACHE_NAME ".trash_entry_cache" +#define NON_EXISTENT_TRASH_ENTRY "-" + +/* Save the localy cached Trashed paths on disk in the user's home + * directory. + */ +static void +save_trash_entry_cache (void) +{ + int cache_file; + char *cache_file_parent, *cache_file_path; + GList *p; + char *buffer, *escaped_path, *escaped_mount_point; + + cache_file_parent = append_to_path (g_get_home_dir (), TRASH_ENTRY_CACHE_PARENT); + cache_file_path = append_to_path (cache_file_parent, TRASH_ENTRY_CACHE_NAME); + + if (mkdir_recursive (cache_file_parent, 0777) != 0) { + g_warning ("failed to create trash item cache file"); + return; + } + + cache_file = open (cache_file_path, O_CREAT | O_TRUNC | O_RDWR, 0666); + if (cache_file < 0) { + g_warning ("failed to create trash item cache file"); + return; + } + + for (p = cached_trash_directories; p != NULL; p = p->next) { + /* Use proper escaping to not confuse paths with spaces in them */ + escaped_path = gnome_vfs_escape_path_string ( + ((TrashDirectoryCachedItem *)p->data)->path); + escaped_mount_point = gnome_vfs_escape_path_string( + ((TrashDirectoryCachedItem *)p->data)->device_mount_point); + + buffer = g_strdup_printf ("%s %s\n", escaped_mount_point, escaped_path); + write (cache_file, buffer, strlen (buffer)); + +#ifdef DEBUG_FIND_DIRECTORY + g_print ("saving trash item cache %s\n", buffer); +#endif + + g_free (buffer); + g_free (escaped_mount_point); + g_free (escaped_path); + } + close (cache_file); + + g_free (cache_file_path); + g_free (cache_file_parent); +} + +typedef struct { + const char *mount_point; + const char *trash_path; + dev_t device_id; + gboolean done; +} UpdateOneCachedEntryContext; + +/* Updates one entry in the local Trash item cache to reflect the + * location we just found or in which we created a new Trash. + */ +static void +update_one_cached_trash_entry (gpointer element, gpointer cast_to_context) +{ + UpdateOneCachedEntryContext *context; + TrashDirectoryCachedItem *item; + + context = (UpdateOneCachedEntryContext *)cast_to_context; + item = (TrashDirectoryCachedItem *)element; + + if (context->done) { + /* We already took care of business in a previous iteration. */ + return; + } + + if (strcmp (context->mount_point, item->device_mount_point) == 0) { + /* This is the item we are looking for, update it. */ + g_free (item->path); + item->path = g_strdup (context->trash_path); + item->device_id = context->device_id; + + /* no more work */ + context->done = TRUE; + } +} + +static void +add_local_cached_trash_entry (dev_t near_device_id, const char *trash_path, const char *mount_point) +{ + TrashDirectoryCachedItem *new_cached_item; + UpdateOneCachedEntryContext update_context; + + /* First check if we already have an entry for this mountpoint, + * if so, update it. + */ + + update_context.mount_point = mount_point; + update_context.trash_path = trash_path; + update_context.device_id = near_device_id; + update_context.done = FALSE; + + g_list_foreach (cached_trash_directories, update_one_cached_trash_entry, &update_context); + if (update_context.done) { + /* Sucessfully updated, no more work left. */ + return; + } + + /* Save the new trash item to the local cache. */ + new_cached_item = g_new (TrashDirectoryCachedItem, 1); + new_cached_item->path = g_strdup (trash_path); + new_cached_item->device_mount_point = g_strdup (mount_point); + new_cached_item->device_id = near_device_id; + + + cached_trash_directories = g_list_prepend (cached_trash_directories, new_cached_item); +} + +static void +add_cached_trash_entry (dev_t near_device_id, const char *trash_path, const char *mount_point) +{ + add_local_cached_trash_entry (near_device_id, trash_path, mount_point); + /* write out the local cache */ + save_trash_entry_cache (); +} + +static void +destroy_cached_trash_entry (TrashDirectoryCachedItem *entry) +{ + g_free (entry->path); + g_free (entry->device_mount_point); + g_free (entry); +} + +/* Read the cached entries for the file cache into the local Trash item cache. */ +static void +read_saved_cached_trash_entries (void) +{ + char *cache_file_path; + FILE *cache_file; + char buffer[2048]; + char escaped_mount_point[PATH_MAX], escaped_trash_path[PATH_MAX]; + char *mount_point, *trash_path; + struct stat stat_buffer; + + /* empty the old locally cached entries */ + g_list_foreach (cached_trash_directories, + (GFunc)destroy_cached_trash_entry, NULL); + g_list_free (cached_trash_directories); + cached_trash_directories = NULL; + + /* read in the entries from disk */ + cache_file_path = g_strconcat (g_get_home_dir (), G_DIR_SEPARATOR_S, + TRASH_ENTRY_CACHE_PARENT, G_DIR_SEPARATOR_S, TRASH_ENTRY_CACHE_NAME, NULL); + cache_file = fopen (cache_file_path, "r"); + + if (cache_file != NULL) { + for (;;) { + if (fgets (buffer, sizeof (buffer), cache_file) == NULL) { + break; + } + + mount_point = NULL; + trash_path = NULL; + if (sscanf (buffer, "%s %s", escaped_mount_point, escaped_trash_path) == 2) { + /* the paths are saved in escaped form */ + trash_path = gnome_vfs_unescape_string (escaped_trash_path, "/"); + mount_point = gnome_vfs_unescape_string (escaped_mount_point, "/"); + + if (trash_path != NULL + && mount_point != NULL + && (strcmp (trash_path, NON_EXISTENT_TRASH_ENTRY) == 0 || lstat (trash_path, &stat_buffer) == 0) + && lstat (mount_point, &stat_buffer) == 0) { + /* We either know the trash doesn't exist or we checked that it's really + * there - this is a good entry, copy it into the local cache. + */ + add_local_cached_trash_entry (stat_buffer.st_dev, trash_path, mount_point); +#ifdef DEBUG_FIND_DIRECTORY + g_print ("read trash item cache entry %s %s\n", trash_path, mount_point); +#endif + } + } + + g_free (trash_path); + g_free (mount_point); + } + fclose (cache_file); + } + + g_free (cache_file_path); +} + +/* Create a Trash directory on the same disk as @full_name_near. */ +static char * +create_trash_near (const char *full_name_near, dev_t near_device_id, const char *disk_top_directory, + guint permissions, GnomeVFSContext *context) +{ + return try_creating_trash_in (disk_top_directory, permissions); +} + + +static gboolean +cached_trash_entry_exists (const TrashDirectoryCachedItem *entry) +{ + struct stat stat_buffer; + return lstat (entry->path, &stat_buffer) == 0; +} + +/* Search through the local cache looking for an entry that matches a given + * device ID. If @check_disk specified, check if the entry we found actually exists. + */ +static char * +find_locally_cached_trash_entry_for_device_id (dev_t device_id, gboolean check_disk) +{ + GList *matching_item; + FindByDeviceIDParameters tmp; + const char *trash_path; + + tmp.device_id = device_id; + + matching_item = g_list_find_custom (cached_trash_directories, + &tmp, match_trash_item_by_device_id); + + if (matching_item == NULL) { + return NULL; + } + + trash_path = ((TrashDirectoryCachedItem *)matching_item->data)->path; + + if (trash_path == NULL) { + /* we already know that this disk does not contain a trash directory */ +#ifdef DEBUG_FIND_DIRECTORY + g_print ("cache indicates no trash for %s \n", trash_path); +#endif + return g_strdup (NON_EXISTENT_TRASH_ENTRY); + } + + if (check_disk) { + /* We found something, make sure it still exists. */ + if (strcmp (((TrashDirectoryCachedItem *)matching_item->data)->path, NON_EXISTENT_TRASH_ENTRY) != 0 + && !cached_trash_entry_exists ((TrashDirectoryCachedItem *)matching_item->data)) { + /* The cached item doesn't really exist, make a new one + * and delete the cached entry + */ +#ifdef DEBUG_FIND_DIRECTORY + g_print ("entry %s doesn't exist, removing \n", + ((TrashDirectoryCachedItem *)matching_item->data)->path); +#endif + destroy_cached_trash_entry ((TrashDirectoryCachedItem *)matching_item->data); + cached_trash_directories = g_list_remove (cached_trash_directories, + matching_item->data); + return NULL; + } + } + +#ifdef DEBUG_FIND_DIRECTORY + g_print ("local cache found %s \n", trash_path); +#endif + g_assert (matching_item != NULL); + return g_strdup (trash_path); +} + +/* Look for an entry in the file and local caches. */ +static char * +find_cached_trash_entry_for_device (dev_t device_id, gboolean check_disk) +{ + if (cached_trash_directories == NULL) { + if (!check_disk) { + return NULL; + } + read_saved_cached_trash_entries (); + } + return find_locally_cached_trash_entry_for_device_id (device_id, check_disk); +} + +/* Search for a Trash entry or create one. Called when there is no cached entry. */ +static char * +find_or_create_trash_near (const char *full_name_near, dev_t near_device_id, + gboolean create_if_needed, gboolean find_if_needed, guint permissions, + GnomeVFSContext *context) +{ + char *result; + char *disk_top_directory; + + result = NULL; + /* figure out the topmost disk directory */ + disk_top_directory = find_disk_top_directory (full_name_near, + near_device_id, context); + + if (disk_top_directory == NULL) { + /* Failed to find it, don't look at this disk until we + * are ready to try to create a Trash on it again. + */ +#ifdef DEBUG_FIND_DIRECTORY + g_print ("failed to find top disk directory for %s\n", full_name_near); +#endif + add_cached_trash_entry (near_device_id, NON_EXISTENT_TRASH_ENTRY, disk_top_directory); + return NULL; + } + + if (find_if_needed) { + /* figure out the topmost disk directory */ + result = find_trash_in_hierarchy (disk_top_directory, near_device_id, context); + if (result == NULL) { + /* We just found out there is no Trash on the disk, + * remember this for next time. + */ + result = g_strdup(NON_EXISTENT_TRASH_ENTRY); + } + } + + if (result == NULL && create_if_needed) { + /* didn't find a Trash, create one */ + result = create_trash_near (full_name_near, near_device_id, disk_top_directory, + permissions, context); + } + + if (result != NULL) { + /* remember whatever we found for next time */ + add_cached_trash_entry (near_device_id, result, disk_top_directory); + } + + g_free (disk_top_directory); + + return result; +} + +/* Find or create a trash directory on the same disk as @full_name_near. Check + * the local and file cache for matching Trash entries first. + * + * This is the only entry point for the trash cache code, + * we holds the lock while operating on it only here. + */ +static char * +find_trash_directory (const char *full_name_near, dev_t near_device_id, + gboolean create_if_needed, gboolean find_if_needed, + guint permissions, GnomeVFSContext *context) +{ + char *result; + + G_LOCK (cached_trash_directories); + + /* look in the saved trash locations first */ + result = find_cached_trash_entry_for_device (near_device_id, find_if_needed); + + if (find_if_needed) { + if (result != NULL && strcmp (result, NON_EXISTENT_TRASH_ENTRY) == 0 && create_if_needed) { + /* We know there is no Trash yet because we remember + * from the last time we looked. + * If we were asked to create one, ignore the fact that + * we already looked for it, look again and create a + * new trash if we find nothing. + */ +#ifdef DEBUG_FIND_DIRECTORY + g_print ("cache indicates no trash for %s, force a creation \n", full_name_near); +#endif + g_free (result); + result = NULL; + } + + if (result == NULL) { + /* No luck sofar. Look for the Trash on the disk, optionally create it + * if we find nothing. + */ + result = find_or_create_trash_near (full_name_near, near_device_id, + create_if_needed, find_if_needed, permissions, context); + } + } else if (create_if_needed) { + if (result == NULL || strcmp (result, NON_EXISTENT_TRASH_ENTRY) == 0) { + result = find_or_create_trash_near (full_name_near, near_device_id, + create_if_needed, find_if_needed, permissions, context); + } + } + + if (result != NULL && strcmp(result, NON_EXISTENT_TRASH_ENTRY) == 0) { + /* This means that we know there is no Trash */ + g_free (result); + result = NULL; + } + + G_UNLOCK (cached_trash_directories); + + return result; +} + +static GnomeVFSResult +do_find_directory (GnomeVFSMethod *method, + GnomeVFSURI *near_uri, + GnomeVFSFindDirectoryKind kind, + GnomeVFSURI **result_uri, + gboolean create_if_needed, + gboolean find_if_needed, + guint permissions, + GnomeVFSContext *context) +{ + gint retval; + char *full_name_near; + struct stat near_item_stat; + struct stat home_volume_stat; + const char *home_directory; + char *target_directory_path; + char *target_directory_uri; + + + target_directory_path = NULL; + *result_uri = NULL; + + full_name_near = get_path_from_uri (near_uri); + if (full_name_near == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + /* We will need the URI and the stat structure for the home directory. */ + home_directory = g_get_home_dir (); + + if (gnome_vfs_context_check_cancellation (context)) { + g_free (full_name_near); + return GNOME_VFS_ERROR_CANCELLED; + } + + retval = lstat (full_name_near, &near_item_stat); + if (retval != 0) { + g_free (full_name_near); + return gnome_vfs_result_from_errno (); + } + + if (gnome_vfs_context_check_cancellation (context)) { + g_free (full_name_near); + return GNOME_VFS_ERROR_CANCELLED; + } + + retval = stat (home_directory, &home_volume_stat); + if (retval != 0) { + g_free (full_name_near); + return gnome_vfs_result_from_errno (); + } + + if (gnome_vfs_context_check_cancellation (context)) { + g_free (full_name_near); + return GNOME_VFS_ERROR_CANCELLED; + } + + switch (kind) { + case GNOME_VFS_DIRECTORY_KIND_TRASH: + /* Use 0700 (S_IRWXU) for the permissions, + * regardless of the requested permissions, so other + * users can't view the trash files. + */ + permissions = S_IRWXU; + if (near_item_stat.st_dev != home_volume_stat.st_dev) { + /* This volume does not contain our home, we have to find/create the Trash + * elsewhere on the volume. Use a heuristic to find a good place. + */ + FindByDeviceIDParameters tmp; + tmp.device_id = near_item_stat.st_dev; + + if (gnome_vfs_context_check_cancellation (context)) + return GNOME_VFS_ERROR_CANCELLED; + + target_directory_path = find_trash_directory (full_name_near, + near_item_stat.st_dev, create_if_needed, find_if_needed, + permissions, context); + + if (gnome_vfs_context_check_cancellation (context)) { + return GNOME_VFS_ERROR_CANCELLED; + } + } else { + /* volume with a home directory, just create a trash in home */ + target_directory_path = append_to_path (home_directory, TRASH_DIRECTORY_NAME_BASE); + } + break; + + case GNOME_VFS_DIRECTORY_KIND_DESKTOP: + if (near_item_stat.st_dev != home_volume_stat.st_dev) { + /* unsupported */ + break; + } + target_directory_path = append_to_path (home_directory, "Desktop"); + break; + + default: + break; + } + + g_free (full_name_near); + + if (target_directory_path == NULL) { + return GNOME_VFS_ERROR_NOT_SUPPORTED; + } + + if (create_if_needed && access (target_directory_path, F_OK) != 0) { + mkdir_recursive (target_directory_path, permissions); + } + + if (access (target_directory_path, F_OK) != 0) { + g_free (target_directory_path); + return GNOME_VFS_ERROR_NOT_FOUND; + } + + target_directory_uri = gnome_vfs_get_uri_from_local_path (target_directory_path); + g_free (target_directory_path); + *result_uri = gnome_vfs_uri_new (target_directory_uri); + g_free (target_directory_uri); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +rename_helper (const gchar *old_full_name, + const gchar *new_full_name, + gboolean force_replace, + GnomeVFSContext *context) +{ + gboolean old_exists; + struct stat statbuf; + gint retval; + + retval = stat (new_full_name, &statbuf); + if (retval == 0) { + /* If we are not allowed to replace an existing file, return an + error. */ + if (! force_replace) + return GNOME_VFS_ERROR_FILE_EXISTS; + old_exists = TRUE; + } else { + old_exists = FALSE; + } + + if (gnome_vfs_context_check_cancellation (context)) + return GNOME_VFS_ERROR_CANCELLED; + + retval = rename (old_full_name, new_full_name); + + /* FIXME bugzilla.eazel.com 1186: The following assumes that, + * if `new_uri' and `old_uri' are on different file systems, + * `rename()' will always return `EXDEV' instead of `EISDIR', + * even if the old file is not a directory while the new one + * is. If this is not the case, we have to stat() both the + * old and new file. + */ + if (retval != 0 && errno == EISDIR && force_replace && old_exists) { + /* The Unix version of `rename()' fails if the original file is + not a directory, while the new one is. But we have been + explicitly asked to replace the destination name, so if the + new name points to a directory, we remove it manually. */ + if (S_ISDIR (statbuf.st_mode)) { + if (gnome_vfs_context_check_cancellation (context)) + return GNOME_VFS_ERROR_CANCELLED; + retval = rmdir (new_full_name); + if (retval != 0) { + return gnome_vfs_result_from_errno (); + } + + if (gnome_vfs_context_check_cancellation (context)) + return GNOME_VFS_ERROR_CANCELLED; + + retval = rename (old_full_name, new_full_name); + } + } + + if (retval != 0) { + return gnome_vfs_result_from_errno (); + } + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_move (GnomeVFSMethod *method, + GnomeVFSURI *old_uri, + GnomeVFSURI *new_uri, + gboolean force_replace, + GnomeVFSContext *context) +{ + gchar *old_full_name; + gchar *new_full_name; + GnomeVFSResult result; + + old_full_name = get_path_from_uri (old_uri); + if (old_full_name == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + new_full_name = get_path_from_uri (new_uri); + if (new_full_name == NULL) { + g_free (old_full_name); + return GNOME_VFS_ERROR_INVALID_URI; + } + + result = rename_helper (old_full_name, new_full_name, + force_replace, context); + + g_free (old_full_name); + g_free (new_full_name); + + return result; +} + +static GnomeVFSResult +do_unlink (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSContext *context) +{ + gchar *full_name; + gint retval; + + full_name = get_path_from_uri (uri); + if (full_name == NULL) { + return GNOME_VFS_ERROR_INVALID_URI; + } + + retval = unlink (full_name); + + g_free (full_name); + + if (retval != 0) { + return gnome_vfs_result_from_errno (); + } + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_create_symbolic_link (GnomeVFSMethod *method, + GnomeVFSURI *uri, + const char *target_reference, + GnomeVFSContext *context) +{ + const char *link_scheme, *target_scheme; + char *link_full_name, *target_full_name; + GnomeVFSResult result; + GnomeVFSURI *target_uri; + + g_assert (target_reference != NULL); + g_assert (uri != NULL); + + /* what we actually want is a function that takes a const char * and + * tells whether it is a valid URI + */ + target_uri = gnome_vfs_uri_new (target_reference); + if (target_uri == NULL) { + return GNOME_VFS_ERROR_INVALID_URI; + } + + link_scheme = gnome_vfs_uri_get_scheme (uri); + g_assert (link_scheme != NULL); + + target_scheme = gnome_vfs_uri_get_scheme (target_uri); + if (target_scheme == NULL) { + target_scheme = "file"; + } + + if ((strcmp (link_scheme, "file") == 0) && (strcmp (target_scheme, "file") == 0)) { + /* symlink between two places on the local filesystem */ + if (strncmp (target_reference, "file", 4) != 0) { + /* target_reference wasn't a full URI */ + target_full_name = strdup (target_reference); + } else { + target_full_name = get_path_from_uri (target_uri); + } + + link_full_name = get_path_from_uri (uri); + + if (symlink (target_full_name, link_full_name) != 0) { + result = gnome_vfs_result_from_errno (); + } else { + result = GNOME_VFS_OK; + } + + g_free (target_full_name); + g_free (link_full_name); + } else { + /* FIXME bugzilla.eazel.com 2792: do a URI link */ + result = GNOME_VFS_ERROR_NOT_SUPPORTED; + } + + gnome_vfs_uri_unref (target_uri); + + return result; +} + +/* When checking whether two locations are on the same file system, we are + doing this to determine whether we can recursively move or do other + sorts of transfers. When a symbolic link is the "source", its + location is the location of the link file, because we want to + know about transferring the link, whereas for symbolic links that + are "targets", we use the location of the object being pointed to, + because that is where we will be moving/copying to. */ +static GnomeVFSResult +do_check_same_fs (GnomeVFSMethod *method, + GnomeVFSURI *source_uri, + GnomeVFSURI *target_uri, + gboolean *same_fs_return, + GnomeVFSContext *context) +{ + gchar *full_name_source, *full_name_target; + struct stat s_source, s_target; + gint retval; + + full_name_source = get_path_from_uri (source_uri); + retval = lstat (full_name_source, &s_source); + g_free (full_name_source); + + if (retval != 0) + return gnome_vfs_result_from_errno (); + + if (gnome_vfs_context_check_cancellation (context)) + return GNOME_VFS_ERROR_CANCELLED; + + full_name_target = get_path_from_uri (target_uri); + retval = stat (full_name_target, &s_target); + g_free (full_name_target); + + if (retval != 0) + return gnome_vfs_result_from_errno (); + + *same_fs_return = (s_source.st_dev == s_target.st_dev); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_set_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + const GnomeVFSFileInfo *info, + GnomeVFSSetFileInfoMask mask, + GnomeVFSContext *context) +{ + gchar *full_name; + + full_name = get_path_from_uri (uri); + if (full_name == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + if (mask & GNOME_VFS_SET_FILE_INFO_NAME) { + GnomeVFSResult result; + gchar *dir, *encoded_dir; + gchar *new_name; + + encoded_dir = gnome_vfs_uri_extract_dirname (uri); + dir = gnome_vfs_unescape_string (encoded_dir, G_DIR_SEPARATOR_S); + g_free (encoded_dir); + g_assert (dir != NULL); + + /* FIXME bugzilla.eazel.com 645: This needs to return + * an error for incoming names with "/" characters in + * them, instead of moving the file. + */ + + if (dir[strlen(dir) - 1] != '/') { + new_name = g_strconcat (dir, "/", info->name, NULL); + } else { + new_name = g_strconcat (dir, info->name, NULL); + } + + result = rename_helper (full_name, new_name, FALSE, context); + + g_free (dir); + g_free (new_name); + + if (result != GNOME_VFS_OK) { + g_free (full_name); + return result; + } + } + + if (gnome_vfs_context_check_cancellation (context)) { + g_free (full_name); + return GNOME_VFS_ERROR_CANCELLED; + } + + if (mask & GNOME_VFS_SET_FILE_INFO_PERMISSIONS) { + if (chmod (full_name, info->permissions) != 0) { + g_free (full_name); + return gnome_vfs_result_from_errno (); + } + } + + if (gnome_vfs_context_check_cancellation (context)) { + g_free (full_name); + return GNOME_VFS_ERROR_CANCELLED; + } + + if (mask & GNOME_VFS_SET_FILE_INFO_OWNER) { + if (chown (full_name, info->uid, info->gid) != 0) { + g_free (full_name); + return gnome_vfs_result_from_errno (); + } + } + + if (gnome_vfs_context_check_cancellation (context)) { + g_free (full_name); + return GNOME_VFS_ERROR_CANCELLED; + } + + if (mask & GNOME_VFS_SET_FILE_INFO_TIME) { + struct utimbuf utimbuf; + + utimbuf.actime = info->atime; + utimbuf.modtime = info->mtime; + + if (utime (full_name, &utimbuf) != 0) { + g_free (full_name); + return gnome_vfs_result_from_errno (); + } + } + + g_free (full_name); + + return GNOME_VFS_OK; +} + +#ifdef HAVE_FAM +static gboolean +fam_do_iter_unlocked (void) +{ + while (fam_connection != NULL && FAMPending(fam_connection)) { + FAMEvent ev; + FileMonitorHandle *handle; + gboolean cancelled; + GnomeVFSMonitorEventType event_type; + + if (FAMNextEvent(fam_connection, &ev) != 1) { + FAMClose(fam_connection); + g_free(fam_connection); + fam_connection = NULL; + return FALSE; + } + + handle = (FileMonitorHandle *)ev.userdata; + cancelled = handle->cancelled; + event_type = -1; + + switch (ev.code) { + case FAMChanged: + event_type = GNOME_VFS_MONITOR_EVENT_CHANGED; + break; + case FAMDeleted: + event_type = GNOME_VFS_MONITOR_EVENT_DELETED; + break; + case FAMStartExecuting: + event_type = GNOME_VFS_MONITOR_EVENT_STARTEXECUTING; + break; + case FAMStopExecuting: + event_type = GNOME_VFS_MONITOR_EVENT_STOPEXECUTING; + break; + case FAMCreated: + event_type = GNOME_VFS_MONITOR_EVENT_CREATED; + break; + case FAMAcknowledge: + if (handle->cancelled) { + gnome_vfs_uri_unref (handle->uri); + g_free (handle); + } + break; + case FAMExists: + case FAMEndExist: + case FAMMoved: + /* Not supported */ + break; + } + + if (event_type != -1 && !cancelled) { + GnomeVFSURI *info_uri; + gchar *info_str; + + /* + * FAM can send events with either a absolute or + * relative (from the monitored URI) path, so check if + * the filename starts with '/'. + */ + if (ev.filename[0] == '/') { + info_str = gnome_vfs_get_uri_from_local_path (ev.filename); + info_uri = gnome_vfs_uri_new (info_str); + g_free (info_str); + } else + info_uri = gnome_vfs_uri_append_file_name (handle->uri, ev.filename); + + /* This queues an idle, so there are no reentrancy issues */ + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *)handle, + info_uri, + event_type); + gnome_vfs_uri_unref (info_uri); + } + } + + return TRUE; +} + +static gboolean +fam_callback (GIOChannel *source, + GIOCondition condition, + gpointer data) +{ + gboolean res; + G_LOCK (fam_connection); + + res = fam_do_iter_unlocked (); + + G_UNLOCK (fam_connection); + + return res; +} + + + +static gboolean +monitor_setup (void) +{ + GIOChannel *ioc; + gint watch_id; + + G_LOCK (fam_connection); + + if (fam_connection == NULL) { + fam_connection = g_malloc0(sizeof(FAMConnection)); + if (FAMOpen2(fam_connection, "test-monitor") != 0) { +#ifdef DEBUG_FAM + g_print ("FAMOpen failed, FAMErrno=%d\n", FAMErrno); +#endif + g_free(fam_connection); + fam_connection = NULL; + G_UNLOCK (fam_connection); + return FALSE; + } + ioc = g_io_channel_unix_new (FAMCONNECTION_GETFD(fam_connection)); + watch_id = g_io_add_watch (ioc, + G_IO_IN | G_IO_HUP | G_IO_ERR, + fam_callback, fam_connection); + g_io_channel_unref (ioc); + } + + G_UNLOCK (fam_connection); + + return TRUE; +} +#endif + +static GnomeVFSResult +do_monitor_add (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle_return, + GnomeVFSURI *uri, + GnomeVFSMonitorType monitor_type) +{ +#ifdef HAVE_FAM + FileMonitorHandle *handle; + char *filename; + + if (!monitor_setup ()) { + return GNOME_VFS_ERROR_NOT_SUPPORTED; + } + + handle = g_new0 (FileMonitorHandle, 1); + handle->uri = uri; + handle->cancelled = FALSE; + gnome_vfs_uri_ref (uri); + filename = get_path_from_uri (uri); + + G_LOCK (fam_connection); + /* We need to queue up incoming messages to avoid blocking on write + if there are many monitors being added */ + fam_do_iter_unlocked (); + + if (fam_connection == NULL) { + G_UNLOCK (fam_connection); + return GNOME_VFS_ERROR_NOT_SUPPORTED; + } + + if (monitor_type == GNOME_VFS_MONITOR_FILE) { + FAMMonitorFile (fam_connection, filename, + &handle->request, handle); + } else { + FAMMonitorDirectory (fam_connection, filename, + &handle->request, handle); + } + + G_UNLOCK (fam_connection); + + *method_handle_return = (GnomeVFSMethodHandle *)handle; + + g_free (filename); + + return GNOME_VFS_OK; +#else + return GNOME_VFS_ERROR_NOT_SUPPORTED; +#endif +} + +static GnomeVFSResult +do_monitor_cancel (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle) +{ +#ifdef HAVE_FAM + FileMonitorHandle *handle = (FileMonitorHandle *)method_handle; + + if (!monitor_setup ()) { + return GNOME_VFS_ERROR_NOT_SUPPORTED; + } + + if (handle->cancelled) + return GNOME_VFS_OK; + + handle->cancelled = TRUE; + G_LOCK (fam_connection); + + /* We need to queue up incoming messages to avoid blocking on write + if there are many monitors being canceled */ + fam_do_iter_unlocked (); + + if (fam_connection == NULL) { + G_UNLOCK (fam_connection); + return GNOME_VFS_ERROR_NOT_SUPPORTED; + } + + FAMCancelMonitor (fam_connection, &handle->request); + G_UNLOCK (fam_connection); + + return GNOME_VFS_OK; +#else + return GNOME_VFS_ERROR_NOT_SUPPORTED; +#endif +} + +static GnomeVFSResult +do_file_control (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + const char *operation, + gpointer operation_data, + GnomeVFSContext *context) +{ + if (strcmp (operation, "file:test") == 0) { + *(char **)operation_data = g_strdup ("test ok"); + return GNOME_VFS_OK; + } + return GNOME_VFS_ERROR_NOT_SUPPORTED; +} + +static GnomeVFSMethod method = { + sizeof (GnomeVFSMethod), + do_open, + do_create, + do_close, + do_read, + do_write, + do_seek, + do_tell, + do_truncate_handle, + do_open_directory, + do_close_directory, + do_read_directory, + do_get_file_info, + do_get_file_info_from_handle, + do_is_local, + do_make_directory, + do_remove_directory, + do_move, + do_unlink, + do_check_same_fs, + do_set_file_info, + do_truncate, + do_find_directory, + do_create_symbolic_link, + do_monitor_add, + do_monitor_cancel, + do_file_control +}; + +GnomeVFSMethod * +vfs_module_init (const char *method_name, const char *args) +{ + return &method; +} + +void +vfs_module_shutdown (GnomeVFSMethod *method) +{ +} diff --git a/modules/fstype.c b/modules/fstype.c new file mode 100644 index 0000000..aa87499 --- /dev/null +++ b/modules/fstype.c @@ -0,0 +1,424 @@ +/* fstype.c -- determine type of filesystems that files are on + Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* This code was relicensed by the FSF on May 1 2002 + + This file is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + this file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ +/* Written by David MacKenzie . */ + +#include +#include +#include +#include +#include +#ifdef STDC_HEADERS +#include +#else +extern int errno; +#endif +#include +#include + +#if __STDC__ +# define P_(s) s +#else +# define P_(s) () +#endif + +static char *filesystem_type_uncached P_((char *path, char *relpath, struct stat *statp)); + +void fstype_internal_error (int level, int num, char const *fmt, ...); + +#ifdef FSTYPE_MNTENT /* 4.3BSD etc. */ +static int xatoi P_((char *cp)); +#endif + +#ifdef FSTYPE_MNTENT /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */ +#include +#if !defined(MOUNTED) +# if defined(MNT_MNTTAB) /* HP-UX. */ +# define MOUNTED MNT_MNTTAB +# endif +# if defined(MNTTABNAME) /* Dynix. */ +# define MOUNTED MNTTABNAME +# endif +#endif +#endif + +#ifdef FSTYPE_GETMNT /* Ultrix. */ +#include +#include +#include +#endif + +#ifdef FSTYPE_USG_STATFS /* SVR3. */ +#include +#include +#endif + +#ifdef FSTYPE_STATVFS /* SVR4. */ +#include +#include +#endif + +#ifdef FSTYPE_STATFS /* 4.4BSD. */ +#include /* NetBSD needs this. */ +#include + +#ifndef MFSNAMELEN /* NetBSD defines this. */ +static char * +fstype_to_string (t) + short t; +{ +#ifdef INITMOUNTNAMES /* Defined in 4.4BSD, not in NET/2. */ + static char *mn[] = INITMOUNTNAMES; + if (t >= 0 && t <= MOUNT_MAXTYPE) + return mn[t]; + else + return "?"; +#else /* !INITMOUNTNAMES */ + switch (t) + { + case MOUNT_UFS: + return "ufs"; + case MOUNT_NFS: + return "nfs"; +#ifdef MOUNT_PC + case MOUNT_PC: + return "pc"; +#endif +#ifdef MOUNT_MFS + case MOUNT_MFS: + return "mfs"; +#endif +#ifdef MOUNT_LO + case MOUNT_LO: + return "lofs"; +#endif +#ifdef MOUNT_TFS + case MOUNT_TFS: + return "tfs"; +#endif +#ifdef MOUNT_TMP + case MOUNT_TMP: + return "tmp"; +#endif +#ifdef MOUNT_MSDOS + case MOUNT_MSDOS: + return "msdos"; +#endif +#ifdef MOUNT_ISO9660 + case MOUNT_ISO9660: + return "iso9660fs"; +#endif + default: + return "?"; + } +#endif /* !INITMOUNTNAMES */ +} +#endif /* !MFSNAMELEN */ +#endif /* FSTYPE_STATFS */ + +#ifdef FSTYPE_AIX_STATFS /* AIX. */ +#include +#include + +#define FSTYPE_STATFS /* Otherwise like 4.4BSD. */ +#define f_type f_vfstype + +static char * +fstype_to_string (t) + short t; +{ + switch (t) + { + case MNT_AIX: +#if 0 /* NFS filesystems are actually MNT_AIX. */ + return "aix"; +#endif + case MNT_NFS: + return "nfs"; + case MNT_JFS: + return "jfs"; + case MNT_CDROM: + return "cdrom"; + default: + return "?"; + } +} +#endif /* FSTYPE_AIX_STATFS */ + +#ifdef AFS +#include +#include +#if __STDC__ +/* On SunOS 4, afs/vice.h defines this to rely on a pre-ANSI cpp. */ +#undef _VICEIOCTL +#define _VICEIOCTL(id) ((unsigned int ) _IOW('V', id, struct ViceIoctl)) +#endif +#ifndef _IOW +/* AFS on Solaris 2.3 doesn't get this definition. */ +#include +#endif + +static int +in_afs (path) + char *path; +{ + static char space[2048]; + struct ViceIoctl vi; + + vi.in_size = 0; + vi.out_size = sizeof (space); + vi.out = space; + + if (pioctl (path, VIOC_FILE_CELL_NAME, &vi, 1) + && (errno == EINVAL || errno == ENOENT)) + return 0; + return 1; +} +#endif /* AFS */ + +/* Nonzero if the current filesystem's type is known. */ +static int fstype_known = 0; + +char *filesystem_type (char *path, char *relpath, struct stat *statp); +/* Return a static string naming the type of filesystem that the file PATH, + described by STATP, is on. + RELPATH is the file name relative to the current directory. + Return "unknown" if its filesystem type is unknown. */ + +char * +filesystem_type (path, relpath, statp) + char *path; + char *relpath; + struct stat *statp; +{ + static char *current_fstype = NULL; + static dev_t current_dev; + + if (current_fstype != NULL) + { + if (fstype_known && statp->st_dev == current_dev) + return current_fstype; /* Cached value. */ + g_free (current_fstype); + } + current_dev = statp->st_dev; + current_fstype = filesystem_type_uncached (path, relpath, statp); + return current_fstype; +} + +void +fstype_internal_error (int level, int num, char const *fmt, ...) +{ +} + +/* Return a newly allocated string naming the type of filesystem that the + file PATH, described by STATP, is on. + RELPATH is the file name relative to the current directory. + Return "unknown" if its filesystem type is unknown. */ + +static char * +filesystem_type_uncached (path, relpath, statp) + char *path; + char *relpath; + struct stat *statp; +{ + char *type = NULL; + +#ifdef FSTYPE_MNTENT /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */ + char *table = MOUNTED; + FILE *mfp; + struct mntent *mnt; + + mfp = setmntent (table, "r"); + if (mfp == NULL) { + fstype_internal_error (1, errno, "%s", table); + goto no_mtab; + } + + /* Find the entry with the same device number as STATP, and return + that entry's fstype. */ + while (type == NULL && (mnt = getmntent (mfp))) + { + char *devopt; + dev_t dev; + struct stat disk_stats; + +#ifdef MNTTYPE_IGNORE + if (!strcmp (mnt->mnt_type, MNTTYPE_IGNORE)) + continue; +#endif + + /* Newer systems like SunOS 4.1 keep the dev number in the mtab, + in the options string. For older systems, we need to stat the + directory that the filesystem is mounted on to get it. + + Unfortunately, the HPUX 9.x mnttab entries created by automountq + contain a dev= option but the option value does not match the + st_dev value of the file (maybe the lower 16 bits match?). */ + +#if !defined(hpux) && !defined(__hpux__) + devopt = strstr (mnt->mnt_opts, "dev="); + if (devopt) + { + if (devopt[4] == '0' && (devopt[5] == 'x' || devopt[5] == 'X')) + dev = xatoi (devopt + 6); + else + dev = xatoi (devopt + 4); + } + else +#endif /* not hpux */ + { + if (stat (mnt->mnt_dir, &disk_stats) == -1) { + if (errno == EACCES) + continue; + else + fstype_internal_error (1, errno, "error in %s: %s", table, mnt->mnt_dir); + } + dev = disk_stats.st_dev; + } + + if (dev == statp->st_dev) + type = mnt->mnt_type; + } + + if (endmntent (mfp) == 0) + fstype_internal_error (0, errno, "%s", table); + no_mtab: +#endif + +#ifdef FSTYPE_GETMNT /* Ultrix. */ + int offset = 0; + struct fs_data fsd; + + while (type == NULL + && getmnt (&offset, &fsd, sizeof (fsd), NOSTAT_MANY, 0) > 0) + { + if (fsd.fd_req.dev == statp->st_dev) + type = gt_names[fsd.fd_req.fstype]; + } +#endif + +#ifdef FSTYPE_USG_STATFS /* SVR3. */ + struct statfs fss; + char typebuf[FSTYPSZ]; + + if (statfs (relpath, &fss, sizeof (struct statfs), 0) == -1) + { + /* Don't die if a file was just removed. */ + if (errno != ENOENT) + fstype_internal_error (1, errno, "%s", path); + } + else if (!sysfs (GETFSTYP, fss.f_fstyp, typebuf)) + type = typebuf; +#endif + +#ifdef FSTYPE_STATVFS /* SVR4. */ + struct statvfs fss; + + if (statvfs (relpath, &fss) == -1) + { + /* Don't die if a file was just removed. */ + if (errno != ENOENT) + fstype_internal_error (1, errno, "%s", path); + } + else + type = fss.f_basetype; +#endif + +#ifdef FSTYPE_STATFS /* 4.4BSD. */ + struct statfs fss; + char *p; + + if (S_ISLNK (statp->st_mode)) + p = dirname (relpath); + else + p = relpath; + + if (statfs (p, &fss) == -1) + { + /* Don't die if symlink to nonexisting file, or a file that was + just removed. */ + if (errno != ENOENT) + fstype_internal_error (1, errno, "%s", path); + } + else + { +#ifdef MFSNAMELEN /* NetBSD. */ + type = fss.f_fstypename; +#else + type = fstype_to_string (fss.f_type); +#endif + } + if (p != relpath) + free (p); +#endif + +#ifdef AFS + if ((!type || !strcmp (type, "xx")) && in_afs (relpath)) + type = "afs"; +#endif + + /* An unknown value can be caused by an ENOENT error condition. + Don't cache those values. */ + fstype_known = (type != NULL); + + return g_strdup (type ? type : "unknown"); +} + +#ifdef FSTYPE_MNTENT /* 4.3BSD etc. */ +/* Return the value of the hexadecimal number represented by CP. + No prefix (like '0x') or suffix (like 'h') is expected to be + part of CP. */ + +static int +xatoi (cp) + char *cp; +{ + int val; + + val = 0; + while (*cp) + { + if (*cp >= 'a' && *cp <= 'f') + val = val * 16 + *cp - 'a' + 10; + else if (*cp >= 'A' && *cp <= 'F') + val = val * 16 + *cp - 'A' + 10; + else if (*cp >= '0' && *cp <= '9') + val = val * 16 + *cp - '0'; + else + break; + cp++; + } + return val; +} +#endif diff --git a/modules/ftp-method.c b/modules/ftp-method.c new file mode 100644 index 0000000..89dd5cc --- /dev/null +++ b/modules/ftp-method.c @@ -0,0 +1,1673 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: 8; c-basic-offset: 8 -*- */ + +/* ftp-method.c - VFS modules for FTP + + Copyright (C) 2000 Ian McKellar, Eazel Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ian McKellar */ + +/* see RFC 959 for protocol details */ + +#include + +/* Keep above any network includes for FreeBSD. */ +#include + +/* Keep above for FreeBSD. */ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* for sscanf */ +#include /* for atoi */ +#include +#ifdef HAVE_STRINGS_H +#include +#endif +#include + +/* maximum size of response we're expecting to get */ +#define MAX_RESPONSE_SIZE 4096 + +/* macros for the checking of FTP response codes */ +#define IS_100(X) ((X) >= 100 && (X) < 200) +#define IS_200(X) ((X) >= 200 && (X) < 300) +#define IS_300(X) ((X) >= 300 && (X) < 400) +#define IS_400(X) ((X) >= 400 && (X) < 500) +#define IS_500(X) ((X) >= 500 && (X) < 600) + +typedef struct { + GnomeVFSMethodHandle method_handle; + GnomeVFSInetConnection *inet_connection; + GnomeVFSSocketBuffer *socket_buf; + GnomeVFSURI *uri; + gchar *cwd; + GString *response_buffer; + gchar *response_message; + gint response_code; + GnomeVFSInetConnection *data_connection; + GnomeVFSSocketBuffer *data_socketbuf; + enum { + FTP_NOTHING, + FTP_READ, + FTP_WRITE, + FTP_READDIR + } operation; + gchar *dirlist; + gchar *dirlistptr; + gchar *server_type; /* the response from TYPE */ + gboolean anonymous; + GnomeVFSResult fivefifty; /* the result to return for an FTP 550 */ + GnomeVFSFileInfoOptions file_info_options; +} FtpConnection; + +static const char USE_PROXY_KEY[] = "/system/http_proxy/use_http_proxy"; + + +static GnomeVFSResult do_open (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + GnomeVFSContext *context); +static gboolean do_is_local (GnomeVFSMethod *method, + const GnomeVFSURI *uri); +static GnomeVFSResult do_open_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context); +static GnomeVFSResult do_close_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context); +static GnomeVFSResult do_read_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSContext *context); + +guint ftp_connection_uri_hash (gconstpointer c); +gint ftp_connection_uri_equal (gconstpointer c, gconstpointer d); +static GnomeVFSResult ftp_connection_acquire (GnomeVFSURI *uri, + FtpConnection **connection, + GnomeVFSContext *context); +static void ftp_connection_release (FtpConnection *conn); + + +static const char *anon_user = "anonymous"; +static const char *anon_pass = "nobody@gnome.org"; +static const int control_port = 21; + + +/* A GHashTable of GLists of FtpConnections */ +static GHashTable *spare_connections = NULL; +G_LOCK_DEFINE_STATIC (spare_connections); +static gint total_connections = 0; +static gint allocated_connections = 0; + +#if ENABLE_FTP_DEBUG + +#define ftp_debug(c,g) FTP_DEBUG((c),(g),__FILE__, __LINE__, __PRETTY_FUNCTION__) +static void +FTP_DEBUG (FtpConnection *conn, + gchar *text, + gchar *file, + gint line, + gchar *func) +{ + if (conn) { + g_print ("%s:%d (%s) [ftp conn=%p]\n %s\n", file, line, + func, conn, text); + } else { + g_print ("%s:%d (%s) [ftp]\n %s\n", file, line, func, text); + } + + g_free (text); +} + +#else + +#define ftp_debug(c,g) (g) + +#endif + +static GnomeVFSResult +ftp_response_to_vfs_result (FtpConnection *conn) +{ + gint response = conn->response_code; + + switch (response) { + case 421: + case 426: + return GNOME_VFS_ERROR_CANCELLED; + case 425: + /*FIXME this looks like a bad mapping. + * 425 is "could not open data connection" which + * probably doesn't have anything to do with file permissions + */ + return GNOME_VFS_ERROR_ACCESS_DENIED; + case 530: + case 331: + case 332: + case 532: + return GNOME_VFS_ERROR_LOGIN_FAILED; + case 450: + case 451: + case 551: + return GNOME_VFS_ERROR_NOT_FOUND; + case 550: + return conn->fivefifty; + case 452: + case 552: + return GNOME_VFS_ERROR_NO_SPACE; + case 553: + return GNOME_VFS_ERROR_BAD_FILE; + } + + /* is this the correct interpretation of this error? */ + if (IS_100 (response)) return GNOME_VFS_OK; + if (IS_200 (response)) return GNOME_VFS_OK; + /* is this the correct interpretation of this error? */ + if (IS_300 (response)) return GNOME_VFS_OK; + if (IS_400 (response)) return GNOME_VFS_ERROR_GENERIC; + if (IS_500 (response)) return GNOME_VFS_ERROR_INTERNAL; + + return GNOME_VFS_ERROR_GENERIC; + +} + +static GnomeVFSResult read_response_line(FtpConnection *conn, gchar **line) { + GnomeVFSFileSize bytes = MAX_RESPONSE_SIZE, bytes_read; + gchar *ptr, *buf = g_malloc (MAX_RESPONSE_SIZE+1); + gint line_length; + GnomeVFSResult result = GNOME_VFS_OK; + + while (!strstr (conn->response_buffer->str, "\r\n")) { + /* we don't have a full line. Lets read some... */ + /*ftp_debug (conn,g_strdup_printf ("response `%s' is incomplete", conn->response_buffer->str));*/ + bytes_read = 0; + result = gnome_vfs_socket_buffer_read (conn->socket_buf, buf, + bytes, &bytes_read); + buf[bytes_read] = '\0'; + /*ftp_debug (conn,g_strdup_printf ("read `%s'", buf));*/ + conn->response_buffer = g_string_append (conn->response_buffer, + buf); + if (result != GNOME_VFS_OK) { + g_warning ("Error `%s' during read\n", + gnome_vfs_result_to_string(result)); + g_free (buf); + return result; + } + } + + g_free (buf); + + ptr = strstr (conn->response_buffer->str, "\r\n"); + line_length = ptr - conn->response_buffer->str; + + *line = g_strndup (conn->response_buffer->str, line_length); + + g_string_erase (conn->response_buffer, 0 , line_length + 2); + + return result; +} + +static GnomeVFSResult +get_response (FtpConnection *conn) +{ + /* all that should be pending is a response to the last command */ + GnomeVFSResult result; + + /*ftp_debug (conn,g_strdup_printf ("get_response(%p)", conn));*/ + + while (TRUE) { + gchar *line = NULL; + result = read_response_line (conn, &line); + + if (result != GNOME_VFS_OK) { + g_free (line); + g_warning ("Error reading response line."); + return result; + } + +#ifdef FTP_RESPONSE_DEBUG + g_print ("FTP: %s\n", line); +#endif + + /* response needs to be at least: "### x" - I think*/ + if (g_ascii_isdigit (line[0]) && + g_ascii_isdigit (line[1]) && + g_ascii_isdigit (line[2]) && + g_ascii_isspace (line[3])) { + + conn->response_code = (line[0] - '0') * 100 + (line[1] - '0') * 10 + (line[2] - '0'); + + if (conn->response_message) g_free (conn->response_message); + conn->response_message = g_strdup (line+4); + +#if 0 + ftp_debug (conn,g_strdup_printf ("got response %d (%s)", + conn->response_code, conn->response_message)); +#endif + + g_free (line); + + return ftp_response_to_vfs_result (conn); + + } + + /* hmm - not a valid line - lets ignore it :-) */ + g_free (line); + + } + + return GNOME_VFS_OK; /* should never be reached */ + +} + +static GnomeVFSResult do_control_write (FtpConnection *conn, + gchar *command) +{ + gchar *actual_command = g_strdup_printf ("%s\r\n", command); + GnomeVFSFileSize bytes = strlen (actual_command), bytes_written; + GnomeVFSResult result = gnome_vfs_socket_buffer_write (conn->socket_buf, + actual_command, bytes, &bytes_written); +#if 0 + ftp_debug (conn, g_strdup_printf ("sent \"%s\\r\\n\"", command)); +#endif + gnome_vfs_socket_buffer_flush (conn->socket_buf); + + if(result != GNOME_VFS_OK) { + g_free (actual_command); + return result; + } + + if(bytes != bytes_written) { + g_free (actual_command); + return result; + } + + g_free (actual_command); + + return result; +} + +static GnomeVFSResult +do_basic_command (FtpConnection *conn, + gchar *command) +{ + GnomeVFSResult result = do_control_write(conn, command); + + if (result != GNOME_VFS_OK) { + return result; + } + + result = get_response (conn); + + return result; +} + +static GnomeVFSResult +do_path_command (FtpConnection *conn, + gchar *command, + GnomeVFSURI *uri) +{ + char *path; + char *actual_command; + GnomeVFSResult result; + + /* as some point we may need to make this execute a CD and then + * a command using the basename rather than the full path. I am yet + * to come across such a system. + */ + path = gnome_vfs_unescape_string (uri->text, G_DIR_SEPARATOR_S); + + if (path == NULL || path[0] == '\0') { + actual_command = g_strconcat (command, " /", NULL); + } else { + actual_command = g_strconcat (command, " ", path, NULL); + } + g_free (path); + + result = do_basic_command (conn, actual_command); + g_free (actual_command); + return result; +} + +static GnomeVFSResult +do_path_command_completely (gchar *command, + GnomeVFSURI *uri, + GnomeVFSContext *context, + GnomeVFSResult fivefifty) +{ + FtpConnection *conn; + GnomeVFSResult result; + + result = ftp_connection_acquire (uri, &conn, context); + if (result != GNOME_VFS_OK) { + return result; + } + + conn->fivefifty = fivefifty; + result = do_path_command (conn, command, uri); + ftp_connection_release (conn); + + return result; +} + +static GnomeVFSResult +do_transfer_command (FtpConnection *conn, gchar *command, GnomeVFSContext *context) +{ + char *host = NULL; + gint port; + GnomeVFSResult result; + GnomeVFSSocket *socket; + + /* Image mode (binary to the uninitiated) */ + do_basic_command (conn, "TYPE I"); + + /* FIXME bugzilla.eazel.com 1464: implement non-PASV mode */ + + /* send PASV */ + do_basic_command (conn, "PASV"); + + /* parse response */ + { + gint a1, a2, a3, a4, p1, p2; + gchar *ptr, *response = g_strdup (conn->response_message); + ptr = strchr (response, '('); + if (!ptr || + (sscanf (ptr+1,"%d,%d,%d,%d,%d,%d", &a1, &a2, &a3, + &a4, &p1, &p2) != 6)) { + g_free (response); + return GNOME_VFS_ERROR_CORRUPTED_DATA; + } + + host = g_strdup_printf ("%d.%d.%d.%d", a1, a2, a3, a4); + port = p1*256 + p2; + + g_free (response); + + } + + /* connect */ + result = gnome_vfs_inet_connection_create (&conn->data_connection, + host, + port, + context ? gnome_vfs_context_get_cancellation(context) : NULL); + + g_free (host); + if (result != GNOME_VFS_OK) { + return result; + } + + socket = gnome_vfs_inet_connection_to_socket (conn->data_connection); + conn->data_socketbuf = gnome_vfs_socket_buffer_new (socket); + + if (conn->socket_buf == NULL) { + gnome_vfs_inet_connection_destroy (conn->data_connection, NULL); + return GNOME_VFS_ERROR_GENERIC; + } + + result = do_control_write (conn, command); + + if (result != GNOME_VFS_OK) { + gnome_vfs_socket_buffer_destroy (conn->data_socketbuf, FALSE); + gnome_vfs_inet_connection_destroy (conn->data_connection, NULL); + return result; + } + + result = get_response (conn); + + if (result != GNOME_VFS_OK) { + gnome_vfs_socket_buffer_destroy (conn->data_socketbuf, FALSE); + gnome_vfs_inet_connection_destroy (conn->data_connection, NULL); + return result; + } + + return result; +} + +static GnomeVFSResult +do_path_transfer_command (FtpConnection *conn, gchar *command, GnomeVFSURI *uri, GnomeVFSContext *context) +{ + char *path; + char *actual_command; + GnomeVFSResult result; + + /* as some point we may need to make this execute a CD and then + * a command using the basename rather than the full path. I am yet + * to come across such a system. + */ + path = gnome_vfs_unescape_string (uri->text, G_DIR_SEPARATOR_S); + + if (path == NULL || path[0] == '\0') { + actual_command = g_strconcat (command, " /", NULL); + } else { + actual_command = g_strconcat (command, " ", path, NULL); + } + g_free (path); + + result = do_transfer_command (conn, actual_command, context); + g_free (actual_command); + return result; +} + + +static GnomeVFSResult +end_transfer (FtpConnection *conn) +{ + GnomeVFSResult result; + + /*ftp_debug (conn, g_strdup ("end_transfer()"));*/ + + if(conn->data_socketbuf) { + gnome_vfs_socket_buffer_flush (conn->data_socketbuf); + gnome_vfs_socket_buffer_destroy (conn->data_socketbuf, FALSE); + conn->data_socketbuf = NULL; + } + + if (conn->data_connection) { + gnome_vfs_inet_connection_destroy (conn->data_connection, NULL); + conn->data_connection = NULL; + } + + result = get_response (conn); + + return result; + +} + + +static GnomeVFSResult ftp_login (FtpConnection *conn, + const char *user, const char *password) +{ + gchar *tmpstring; + GnomeVFSResult result; + + tmpstring = g_strdup_printf ("USER %s", user); + result = do_basic_command (conn, tmpstring); + g_free (tmpstring); + + if (IS_300 (conn->response_code)) { + tmpstring = g_strdup_printf ("PASS %s", password); + result = do_basic_command (conn, tmpstring); + g_free (tmpstring); + } + + return result; +} + + +static GnomeVFSResult +ftp_connection_create (FtpConnection **connptr, GnomeVFSURI *uri, GnomeVFSContext *context) +{ + FtpConnection *conn = g_new0 (FtpConnection, 1); + GnomeVFSResult result; + gint port = control_port; + const gchar *user = anon_user; + const gchar *pass = anon_pass; + + conn->uri = gnome_vfs_uri_dup (uri); + conn->response_buffer = g_string_new (""); + conn->response_code = -1; + conn->anonymous = TRUE; + conn->fivefifty = GNOME_VFS_ERROR_NOT_FOUND; + + if (gnome_vfs_uri_get_host_port (uri)) { + port = gnome_vfs_uri_get_host_port (uri); + } + + if (gnome_vfs_uri_get_user_name (uri)) { + user = gnome_vfs_uri_get_user_name (uri); + conn->anonymous = FALSE; + } + + if (gnome_vfs_uri_get_password (uri)) { + pass = gnome_vfs_uri_get_password (uri); + } + + result = gnome_vfs_inet_connection_create (&conn->inet_connection, + gnome_vfs_uri_get_host_name (uri), + port, + context ? gnome_vfs_context_get_cancellation(context) : NULL); + + if (result != GNOME_VFS_OK) { + g_warning ("gnome_vfs_inet_connection_create (\"%s\", %d) = \"%s\"", + gnome_vfs_uri_get_host_name (uri), + gnome_vfs_uri_get_host_port (uri), + gnome_vfs_result_to_string (result)); + gnome_vfs_uri_unref (conn->uri); + g_string_free (conn->response_buffer, TRUE); + g_free (conn); + return result; + } + + conn->socket_buf = gnome_vfs_inet_connection_to_socket_buffer (conn->inet_connection); + + if (conn->socket_buf == NULL) { + g_warning ("Getting socket buffer failed"); + gnome_vfs_inet_connection_destroy (conn->inet_connection, NULL); + gnome_vfs_uri_unref (conn->uri); + g_string_free (conn->response_buffer, TRUE); + g_free (conn); + return GNOME_VFS_ERROR_GENERIC; + } + + result = get_response (conn); + + if (result != GNOME_VFS_OK) { + g_warning ("ftp server (%s:%d) said `%d %s'", + gnome_vfs_uri_get_host_name (uri), + gnome_vfs_uri_get_host_port (uri), + conn->response_code, conn->response_message); + gnome_vfs_uri_unref (conn->uri); + g_string_free (conn->response_buffer, TRUE); + g_free (conn); + return result; + } + + result = ftp_login(conn, user, pass); + + if (result != GNOME_VFS_OK) { + /* login failed */ + g_warning ("FTP server said: \"%d %s\"\n", conn->response_code, + conn->response_message); + gnome_vfs_socket_buffer_destroy (conn->socket_buf, FALSE); + gnome_vfs_inet_connection_destroy (conn->inet_connection, NULL); + gnome_vfs_uri_unref (conn->uri); + g_string_free (conn->response_buffer, TRUE); + g_free (conn); + + return result; + } + + /* okay, we should be connected now */ + + /* Image mode (binary to the uninitiated) */ + + do_basic_command (conn, "TYPE I"); + + /* Get the system type */ + + do_basic_command (conn, "SYST"); + conn->server_type=g_strdup(conn->response_message); + + *connptr = conn; + + ftp_debug (conn, g_strdup ("created")); + + total_connections++; + + return GNOME_VFS_OK; +} + +static void +ftp_connection_destroy (FtpConnection *conn) +{ + + if (conn->inet_connection) + gnome_vfs_inet_connection_destroy (conn->inet_connection, NULL); + + if (conn->socket_buf) + gnome_vfs_socket_buffer_destroy (conn->socket_buf, FALSE); + + gnome_vfs_uri_unref (conn->uri); + g_free (conn->cwd); + + if (conn->response_buffer) + g_string_free(conn->response_buffer, TRUE); + g_free (conn->response_message); + g_free (conn->server_type); + + if (conn->data_connection) + gnome_vfs_inet_connection_destroy(conn->data_connection, NULL); + + if (conn->data_socketbuf) + gnome_vfs_socket_buffer_destroy (conn->data_socketbuf, FALSE); + + g_free (conn->dirlist); + g_free (conn->dirlistptr); + g_free (conn); + total_connections--; +} + +/* g_str_hash and g_str_equal don't take null arguments */ + +static guint +my_str_hash (const char *c) +{ + if (c) + return g_str_hash (c); + return 0; +} + +static gboolean +my_str_equal (const char *c, + const char *d) +{ + if ((c && !d) || (d &&!c)) + return FALSE; + if (!c && !d) + return TRUE; + return strcmp (c,d) == 0; +} + +/* hash the bits of a GnomeVFSURI that distingush FTP connections */ +guint +ftp_connection_uri_hash (gconstpointer c) +{ + GnomeVFSURI *uri = (GnomeVFSURI *) c; + + return my_str_hash (gnome_vfs_uri_get_host_name (uri)) + + my_str_hash (gnome_vfs_uri_get_user_name (uri)) + + my_str_hash (gnome_vfs_uri_get_password (uri)) + + gnome_vfs_uri_get_host_port (uri); +} + +/* test the equality of the bits of a GnomeVFSURI that distingush FTP + * connections */ +gint +ftp_connection_uri_equal (gconstpointer c, + gconstpointer d) +{ + GnomeVFSURI *uri1 = (GnomeVFSURI *)c; + GnomeVFSURI *uri2 = (GnomeVFSURI *) d; + + return my_str_equal (gnome_vfs_uri_get_host_name(uri1), + gnome_vfs_uri_get_host_name (uri2)) && + my_str_equal (gnome_vfs_uri_get_user_name (uri1), + gnome_vfs_uri_get_user_name (uri2)) && + my_str_equal (gnome_vfs_uri_get_password (uri1), + gnome_vfs_uri_get_password (uri2)) && + gnome_vfs_uri_get_host_port (uri1) == + gnome_vfs_uri_get_host_port (uri2); +} + +static GnomeVFSResult +ftp_connection_acquire (GnomeVFSURI *uri, FtpConnection **connection, GnomeVFSContext *context) +{ + GList *possible_connections; + FtpConnection *conn = NULL; + GnomeVFSResult result = GNOME_VFS_OK; + + G_LOCK (spare_connections); + + if (spare_connections == NULL) { + spare_connections = g_hash_table_new (ftp_connection_uri_hash, + ftp_connection_uri_equal); + } + + possible_connections = g_hash_table_lookup (spare_connections, uri); + + if (possible_connections) { + /* spare connection(s) found */ + conn = (FtpConnection *) possible_connections->data; +#if 0 + ftp_debug (conn, strdup ("found a connection")); +#endif + possible_connections = g_list_remove (possible_connections, conn); + g_hash_table_insert (spare_connections, uri, possible_connections); + + /* make sure connection hasn't timed out */ + result = do_basic_command(conn, "PWD"); + if (result != GNOME_VFS_OK) { + ftp_connection_destroy (conn); + result = ftp_connection_create (&conn, uri, context); + } + + } else { + result = ftp_connection_create (&conn, uri, context); + } + + G_UNLOCK (spare_connections); + + *connection = conn; + + if (result == GNOME_VFS_OK) { + allocated_connections++; + } + + return result; +} + + +static void +ftp_connection_release (FtpConnection *conn) +{ + GList *possible_connections; + GnomeVFSURI *uri; + + g_return_if_fail (conn); + + /* reset the 550 result */ + conn->fivefifty = GNOME_VFS_ERROR_NOT_FOUND; + + G_LOCK (spare_connections); + if (spare_connections == NULL) + spare_connections = + g_hash_table_new (ftp_connection_uri_hash, + ftp_connection_uri_equal); + + possible_connections = g_hash_table_lookup (spare_connections, + conn->uri); +#if 0 + ftp_debug (conn, g_strdup_printf ("releasing [len = %d]", + g_list_length (possible_connections))); +#endif + possible_connections = g_list_append (possible_connections, conn); + + if (g_hash_table_lookup (spare_connections, conn->uri)) { + uri = conn->uri; /* no need to duplicate uri */ + } else { + /* uri will be used as key */ + uri = gnome_vfs_uri_dup (conn->uri); + } + g_hash_table_insert (spare_connections, uri, possible_connections); + allocated_connections--; + + G_UNLOCK(spare_connections); +} + +gboolean +do_is_local (GnomeVFSMethod *method, + const GnomeVFSURI *uri) +{ + return FALSE; +} + + +static GnomeVFSResult +do_open (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FtpConnection *conn; + + result = ftp_connection_acquire (uri, &conn, context); + if (result != GNOME_VFS_OK) + return result; + + if (mode == GNOME_VFS_OPEN_READ) { + conn->operation = FTP_READ; + result = do_path_transfer_command (conn, "RETR", uri, context); + } else if (mode == GNOME_VFS_OPEN_WRITE) { + conn->operation = FTP_WRITE; + conn->fivefifty = GNOME_VFS_ERROR_ACCESS_DENIED; + result = do_path_transfer_command (conn, "STOR", uri, context); + conn->fivefifty = GNOME_VFS_ERROR_NOT_FOUND; + } else { + g_warning ("Unsupported open mode %d\n", mode); + ftp_connection_release (conn); + return GNOME_VFS_ERROR_INVALID_OPEN_MODE; + } + if (result == GNOME_VFS_OK) { + *method_handle = (GnomeVFSMethodHandle *) conn; + } else { + *method_handle = NULL; + ftp_connection_release (conn); + } + return result; +} + +static GnomeVFSResult +do_create (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + gboolean exclusive, + guint perm, + GnomeVFSContext *context) { + return do_open(method, method_handle, uri, mode, context); +} + +static GnomeVFSResult +do_close (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + FtpConnection *conn = (FtpConnection *) method_handle; + + GnomeVFSResult result = end_transfer (conn); + + ftp_connection_release (conn); + + return result; +} + +static GnomeVFSResult +do_read (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read, + GnomeVFSContext *context) +{ + FtpConnection *conn = (FtpConnection * )method_handle; + GnomeVFSResult result; +#if 0 + /* + if (conn->operation != FTP_READ) { + g_print ("attempted to read when conn->operation = %d\n", conn->operation); + return GNOME_VFS_ERROR_NOT_PERMITTED; + }*/ + g_print ("do_read (%p)\n", method_handle); +#endif + + result = gnome_vfs_socket_buffer_read (conn->data_socketbuf, buffer, num_bytes, bytes_read); + + if (*bytes_read == 0) { + result = GNOME_VFS_ERROR_EOF; + } + return result; +} + +static GnomeVFSResult +do_write (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gconstpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_written, + GnomeVFSContext *context) +{ + FtpConnection *conn = (FtpConnection *) method_handle; + GnomeVFSResult result; + +#if 0 + g_print ("do_write ()\n"); +#endif + + if (conn->operation != FTP_WRITE) + return GNOME_VFS_ERROR_NOT_PERMITTED; + + result = gnome_vfs_socket_buffer_write (conn->data_socketbuf, buffer, + num_bytes, + bytes_written); + return result; +} + +/* parse one directory listing from the string pointed to by ls. Parse + * only one line from that string. Fill in the appropriate fields of file_info. + * return TRUE if a directory entry was found, FALSE otherwise + */ +static gboolean +winnt_ls_to_file_info (gchar *ls, GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options) +{ + char *mtime_str; + int m, d, y, h, mn; + const char *mime_type; + + /* check parameters */ + g_return_val_if_fail (file_info != NULL, FALSE); + + /* fill in bits of valid_fields as we go along */ + file_info->valid_fields = 0; + + /* First 17 chars are DOS date */ + file_info->mtime = 0; + mtime_str = g_strndup (ls, 17); + if (sscanf (mtime_str, "%2d-%2d-%2d %2d:%2d", + &m, &d, &y, &h, &mn) == 5) { + /* yes it's a dos date */ + struct tm mtime_parts; + mtime_parts.tm_mon = m - 1; /* tm_mon is zero-based */ + mtime_parts.tm_mday = d; + mtime_parts.tm_year = y >= 70 ? y : y + 100; /* handle y2k */ + mtime_parts.tm_hour = strcasecmp (mtime_str + 15, "pm") == 0 ? + h + 12 : h; + mtime_parts.tm_min = mn; + mtime_parts.tm_sec = 0; + mtime_parts.tm_isdst = -1; + file_info->mtime = mktime (&mtime_parts); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MTIME; + } + /* TODO: if there isn't a date it's probably a Unix-style ftp server + * running under Windows */ + + g_free (mtime_str); + + /* just in case client doesn't check valid_fields */ + file_info->atime = file_info->mtime; + file_info->ctime = file_info->mtime; + + /* filename begins in column 39 */ + if (strlen (ls) >= 39) { + int i; + i = strcspn (ls + 39, "\r\n"); + file_info->name = g_strndup (ls + 39, i); + } else { + file_info->name = NULL; + return FALSE; + } + + /* if it's a directory, columns 24-29 contains "" */ + file_info->type = GNOME_VFS_FILE_TYPE_REGULAR; + if (strlen (ls) >= 24) { + char *dirflag_str; + dirflag_str = g_strndup (ls + 24, 5); + if (strcmp (dirflag_str, "") == 0) { + file_info->type = GNOME_VFS_FILE_TYPE_DIRECTORY; + } + g_free (dirflag_str); + } + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_TYPE; + + /* if not a directory, we should find right-aligned size ending + * at column 37 */ + if (file_info->type == GNOME_VFS_FILE_TYPE_REGULAR && + strlen (ls) > 17) { + file_info->size = strtol (ls + 17, NULL, 0); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_SIZE; + } + + /* mime type */ + if (file_info->type == GNOME_VFS_FILE_TYPE_REGULAR) { + mime_type = gnome_vfs_mime_type_from_name_or_default ( + file_info->name, + GNOME_VFS_MIME_TYPE_UNKNOWN); + } else { + mime_type = gnome_vfs_mime_type_from_mode (S_IFDIR); + } + file_info->mime_type = g_strdup (mime_type); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + /* fill in other structures with meaningful data, even though + * it may not be valid */ + file_info->permissions = GNOME_VFS_PERM_USER_ALL | + GNOME_VFS_PERM_GROUP_ALL | + GNOME_VFS_PERM_OTHER_ALL; + file_info->flags = GNOME_VFS_FILE_FLAGS_NONE; + + return TRUE; +} + +/** + * return TRUE if entry found, FALSE otherwise + */ +static gboolean +netware_ls_to_file_info (gchar *ls, GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options) +{ + const char *mime_type; + + /* check parameters */ + g_return_val_if_fail (file_info != NULL, FALSE); + + /* start by knowing nothing */ + file_info->valid_fields = 0; + + /* If line starts with "total" then we should skip it */ + if (strncmp (ls, "total", 5) == 0) { + return FALSE; + } + + /* First char is 'd' for directory, '-' for regular file */ + file_info->type = GNOME_VFS_FILE_TYPE_UNKNOWN; + if (strlen (ls) >= 1) { + if (ls[0] == 'd') { + file_info->type = GNOME_VFS_FILE_TYPE_DIRECTORY; + } else if (ls[0] == '-') { + file_info->type = GNOME_VFS_FILE_TYPE_REGULAR; + } else { + g_warning ("netware_ls_to_file_info: unknown file type '%c'", ls[0]); + } + } + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_TYPE; + + /* Next is a listing of Netware permissions */ + /* ignored */ + + /* Following the permissions is the "owner/creator" of the file */ + /* file info structure requires a UID, which of course is not available */ + /* ignored */ + + /* following type, permissions, and owner is the size, right justified up + * to but not including column 50. */ + /* if we start at column 35, that allows 15 chars for size--that should be + * enough :) */ + if (strlen (ls) > 35) { + file_info->size = strtol (ls + 35, NULL, 0); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_SIZE; + } + + /* columns 51-63 contain modification date of file/directory */ + file_info->mtime = 0; + if (strlen (ls) >= 51) { + char *mtime_str = g_strndup (ls + 51, 12); + GDate *mtime_date; + + /* mtime_str is one of two formats... + * 1) "mmm dd hh:mm" (24hr time) + * 2) "mmm dd yyyy" + */ + mtime_date = g_date_new (); + if (index (mtime_str, ':') != NULL) { + /* separate time */ + char *date_str = g_strndup (mtime_str, 6); + g_date_set_parse (mtime_date, date_str); + g_free (date_str); + } else { + g_date_set_parse (mtime_date, mtime_str); + } + + if (!g_date_valid (mtime_date)) { + g_warning ("netware_ls_to_file_info: cannot parse date '%s'", + mtime_str); + } + else { + struct tm mtime_parts; + g_date_to_struct_tm (mtime_date, &mtime_parts); + mtime_parts.tm_hour = 0; + mtime_parts.tm_min = 0; + mtime_parts.tm_sec = 0; + mtime_parts.tm_isdst = -1; + if (index (mtime_str, ':')) { + /* get the time */ + int h, mn; + if (sscanf (mtime_str + 7, "%2d:%2d", &h, &mn) == 2) { + mtime_parts.tm_hour = h; + mtime_parts.tm_min = mn; + } else { + g_warning ("netware_ls_to_file_info: invalid time '%s'", + mtime_str + 7); + } + } + file_info->mtime = mktime (&mtime_parts); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MTIME; + } + + g_date_free (mtime_date); + g_free (mtime_str); + } + + /* just in case client doesn't check valid_fields */ + file_info->atime = file_info->mtime; + file_info->ctime = file_info->mtime; + + /* finally, the file/directory name (column 64) */ + if (strlen (ls) >= 64) { + int i; + i = strcspn (ls + 64, "\r\n"); + file_info->name = g_strndup (ls + 64, i); + } else { + file_info->name = NULL; + } + + /* mime type */ + if (file_info->type == GNOME_VFS_FILE_TYPE_REGULAR) { + mime_type = gnome_vfs_mime_type_from_name_or_default ( + file_info->name, + GNOME_VFS_MIME_TYPE_UNKNOWN); + } else { + mime_type = gnome_vfs_mime_type_from_mode (S_IFDIR); + } + file_info->mime_type = g_strdup (mime_type); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + /* fill in other structures with meaningful data, even though + * it may not be valid */ + file_info->permissions = GNOME_VFS_PERM_USER_ALL | + GNOME_VFS_PERM_GROUP_ALL | + GNOME_VFS_PERM_OTHER_ALL; + file_info->flags = GNOME_VFS_FILE_FLAGS_NONE; + + return TRUE; +} + +static gboolean +unix_ls_to_file_info (gchar *ls, GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options) +{ + struct stat s; + gchar *filename = NULL, *linkname = NULL; + const char *mime_type; + + gnome_vfs_parse_ls_lga (ls, &s, &filename, &linkname); + + /* g_print ("filename: %s, linkname: %s\n", filename, linkname); */ + + if (filename) { + + gnome_vfs_stat_to_file_info (file_info, &s); + + /* FIXME: This is a hack, but we can't change + the above API until after Gnome 1.4. Ideally, we + would give the stat_to_file_info function this + information. Also, there may be more fields here that are not + valid that we haven't dealt with. */ + file_info->valid_fields |= ~(GNOME_VFS_FILE_INFO_FIELDS_DEVICE + | GNOME_VFS_FILE_INFO_FIELDS_INODE + | GNOME_VFS_FILE_INFO_FIELDS_IO_BLOCK_SIZE); + file_info->io_block_size = 0; + + file_info->name = g_path_get_basename (filename); + + if(*(file_info->name) == '\0') { + g_free (file_info->name); + file_info->name = g_strdup ("/"); + } + + if(linkname) { + file_info->symlink_name = linkname; + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_SYMLINK_NAME; + file_info->flags |= GNOME_VFS_FILE_FLAGS_SYMLINK; + } + + if (file_info->type == GNOME_VFS_FILE_TYPE_REGULAR) { + mime_type = gnome_vfs_mime_type_from_name_or_default (file_info->name, GNOME_VFS_MIME_TYPE_UNKNOWN); + /*ftp_debug (conn, g_strdup_printf ("mimetype = %s", mime_type));*/ + } else { + mime_type = gnome_vfs_mime_type_from_mode (s.st_mode); + } + file_info->mime_type = g_strdup (mime_type); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + /*ftp_debug (conn, g_strdup_printf ("info got name `%s'", file_info->name));*/ + + g_free (filename); + + return TRUE; + } else { + return FALSE; + } +} + + +#if 0 +static GnomeVFSResult +internal_get_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + FtpConnection *conn; + /* FIXME bugzilla.eazel.com 1463 */ + GnomeVFSResult result; + GnomeVFSFileSize num_bytes = 1024, bytes_read; + gchar buffer[num_bytes+1]; + + result = ftp_connection_acquire(uri, &conn); + if (result != GNOME_VFS_OK) { + return result; + } + +#if 0 + g_print ("do_get_file_info()\n"); +#endif + + if(strstr(conn->server_type,"MACOS")) { + /* don't ask for symlinks from MacOS servers */ + do_path_transfer_command (conn, "LIST -ld", uri, context); + } else { + do_path_transfer_command (conn, "LIST -ldL", uri, context); + } + + result = gnome_vfs_socket_buffer_read (conn->data_socketbuf, buffer, + num_bytes, &bytes_read); + + if (result != GNOME_VFS_OK) { + /*ftp_debug (conn, g_strdup ("gnome_vfs_socket_buffer_read failed"));*/ + ftp_connection_release (conn); + return result; + } + + result = end_transfer (conn); + + /* FIXME bugzilla.eazel.com 2793: check return? */ + + ftp_connection_release (conn); + + if (result != GNOME_VFS_OK) { + /*ftp_debug (conn,g_strdup ("LIST for get_file_info failed."));*/ + return result; + } + + if (bytes_read>0) { + + buffer[bytes_read] = '\0'; + file_info->valid_fields = 0; /* make sure valid_fields is 0 */ + + if (ls_to_file_info (buffer, file_info)) { + return GNOME_VFS_OK; + } + + } + + return GNOME_VFS_ERROR_NOT_FOUND; + +} +#endif + +static GnomeVFSResult +do_get_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSURI *parent = gnome_vfs_uri_get_parent (uri); + GnomeVFSResult result; + + if (parent == NULL) { + FtpConnection *conn; + /* this is a request for info about the root directory */ + + /* is the host there? */ + result = ftp_connection_acquire (uri, &conn, context); + + if (result != GNOME_VFS_OK) { + /* doesn't look like it */ + return result; + } + + ftp_connection_release (conn); + + file_info->name = g_strdup ("/"); + file_info->type = GNOME_VFS_FILE_TYPE_DIRECTORY; + file_info->mime_type = g_strdup ("x-directory/normal"); + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_TYPE | + GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + } else { + GnomeVFSMethodHandle *method_handle; + gchar *name; + + + name = gnome_vfs_uri_extract_short_name (uri); + if (name == NULL) { + gnome_vfs_uri_unref (parent); + return GNOME_VFS_ERROR_NOT_SUPPORTED; + } + + result = do_open_directory (method, &method_handle, parent, + options, context); + + gnome_vfs_uri_unref (parent); + + if (result != GNOME_VFS_OK) { + g_free (name); + return result; + } + + while (1) { + result = do_read_directory (method, method_handle, + file_info, context); + if (result != GNOME_VFS_OK) { + result = GNOME_VFS_ERROR_NOT_FOUND; + break; + } + if (file_info->name != NULL + && strcmp (file_info->name, name) == 0) { + break; + } + } + g_free (name); + do_close_directory (method, method_handle, context); + } + + return result; +} + +static GnomeVFSResult +do_get_file_info_from_handle (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + return do_get_file_info (method, + ((FtpConnection *)method_handle)->uri, + file_info, options, context); +} + +static GnomeVFSResult +do_open_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + FtpConnection *conn; + GnomeVFSResult result; + GnomeVFSFileSize num_bytes = 1024, bytes_read; + gchar buffer[num_bytes+1]; + GString *dirlist = g_string_new (""); + + result = ftp_connection_acquire (uri, &conn, context); + if (result != GNOME_VFS_OK) { + g_string_free (dirlist, TRUE); + return result; + } + + /*g_print ("do_open_directory () in uri: %s\n", gnome_vfs_uri_get_path(uri));*/ + + /* LIST does not return an error if called on a file, but CWD + * should. This allows us to have proper gnome-vfs semantics. + * does the cwd break other things though? ie, are + * connections stateless? + */ + conn->fivefifty = GNOME_VFS_ERROR_NOT_A_DIRECTORY; + result = do_path_command (conn, "CWD", uri); + if (result != GNOME_VFS_OK) { + ftp_connection_release (conn); + return result; + } + + if(strstr(conn->server_type,"MACOS")) { + /* don't ask for symlinks from MacOS servers */ + result = do_transfer_command (conn, "LIST", context); + } else { + result = do_transfer_command (conn, "LIST -L", context); + } + + if (result != GNOME_VFS_OK) { + g_warning ("opendir failed because \"%s\"", + gnome_vfs_result_to_string (result)); + ftp_connection_release (conn); + g_string_free (dirlist, TRUE); + return result; + } + + while (result == GNOME_VFS_OK) { + result = gnome_vfs_socket_buffer_read (conn->data_socketbuf, buffer, + num_bytes, &bytes_read); + if (result == GNOME_VFS_OK && bytes_read > 0) { + buffer[bytes_read] = '\0'; + dirlist = g_string_append (dirlist, buffer); + } else { + break; + } + } + + result = end_transfer (conn); + + if(result != GNOME_VFS_OK) g_warning ("end_transfer (conn) failed!!!!"); + + conn->dirlist = g_strdup (dirlist->str); + conn->dirlistptr = conn->dirlist; + conn->file_info_options = options; + + g_string_free (dirlist,TRUE); + + *method_handle = (GnomeVFSMethodHandle *) conn; + + return result; +} + +static GnomeVFSResult +do_close_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + FtpConnection *conn = (FtpConnection *) method_handle; + +#if 0 + g_print ("do_close_directory ()\n"); +#endif + + g_free (conn->dirlist); + conn->dirlist = NULL; + conn->dirlistptr = NULL; + ftp_connection_release (conn); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_read_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSContext *context) +{ + FtpConnection *conn = (FtpConnection *) method_handle; + + if (!conn->dirlistptr || *(conn->dirlistptr) == '\0') + return GNOME_VFS_ERROR_EOF; + + while (TRUE) { + gboolean success; + + if (strncmp (conn->server_type, "Windows_NT", 10) == 0) { + success = winnt_ls_to_file_info (conn->dirlistptr, file_info, + conn->file_info_options); + } + else if (strncmp (conn->server_type, "NETWARE", 7) == 0) { + success = netware_ls_to_file_info (conn->dirlistptr, file_info, + conn->file_info_options); + } + else { + success = unix_ls_to_file_info (conn->dirlistptr, file_info, + conn->file_info_options); + } + + /* permissions aren't valid */ + file_info->valid_fields &= ~GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS; + + if ((conn->file_info_options & + GNOME_VFS_FILE_INFO_FOLLOW_LINKS) && + (file_info->type == + GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK)) { + /* Need to follow symbolic links to match behavior Nautilus + * requires for sensible display (otherwise symlinks all appear + * broken) + */ +#if 0 + g_print("[debug] expand symlink for: %s\n", file_info->name); +#endif + } + + + if (*(conn->dirlistptr) == '\0') + return GNOME_VFS_ERROR_EOF; + + /* go till we find \r\n */ + while (conn->dirlistptr && + *conn->dirlistptr && + *conn->dirlistptr != '\r' && + *conn->dirlistptr != '\n') { + conn->dirlistptr++; + } + /* go past \r\n */ + while (conn->dirlistptr && g_ascii_isspace (*conn->dirlistptr)) { + conn->dirlistptr++; + } + + if(success) break; + } + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_check_same_fs (GnomeVFSMethod *method, + GnomeVFSURI *a, + GnomeVFSURI *b, + gboolean *same_fs_return, + GnomeVFSContext *context) +{ + *same_fs_return = ftp_connection_uri_equal (a,b); + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_make_directory (GnomeVFSMethod *method, GnomeVFSURI *uri, guint perm, GnomeVFSContext *context) +{ + GnomeVFSResult result; + gchar *chmod_command; + + result = do_path_command_completely ("MKD", uri, context, + GNOME_VFS_ERROR_ACCESS_DENIED); + + if (result == GNOME_VFS_OK) { + /* try to set the permissions */ + /* this is a non-standard extension, so we'll just do our + * best. We can ignore error codes. */ + chmod_command = g_strdup_printf("SITE CHMOD %o", perm); + do_path_command_completely (chmod_command, uri, context, + GNOME_VFS_ERROR_ACCESS_DENIED); + g_free(chmod_command); + } + + return result; +} + + +static GnomeVFSResult +do_remove_directory (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSContext *context) +{ + return do_path_command_completely ("RMD", uri, context, + GNOME_VFS_ERROR_ACCESS_DENIED); +} + + +static GnomeVFSResult +do_move (GnomeVFSMethod *method, + GnomeVFSURI *old_uri, + GnomeVFSURI *new_uri, + gboolean force_replace, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + GnomeVFSFileInfo *p_file_info; + + if (!force_replace) { + p_file_info = gnome_vfs_file_info_new (); + result = do_get_file_info (method, new_uri, p_file_info, GNOME_VFS_FILE_INFO_DEFAULT, context); + gnome_vfs_file_info_unref (p_file_info); + p_file_info = NULL; + + if (result == GNOME_VFS_OK) { + return GNOME_VFS_ERROR_FILE_EXISTS; + } + } + + + if (ftp_connection_uri_equal (old_uri, new_uri)) { + FtpConnection *conn; + GnomeVFSResult result; + + result = ftp_connection_acquire (old_uri, &conn, context); + if (result != GNOME_VFS_OK) { + return result; + } + result = do_path_command (conn, "RNFR", old_uri); + + if (result == GNOME_VFS_OK) { + conn->fivefifty = GNOME_VFS_ERROR_ACCESS_DENIED; + result = do_path_command (conn, "RNTO", new_uri); + conn->fivefifty = GNOME_VFS_ERROR_NOT_FOUND; + } + + ftp_connection_release (conn); + + return result; + } else { + return GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM; + } +} + +static GnomeVFSResult +do_unlink (GnomeVFSMethod *method, GnomeVFSURI *uri, GnomeVFSContext *context) +{ + return do_path_command_completely ("DELE", uri, context, + GNOME_VFS_ERROR_ACCESS_DENIED); +} + +static GnomeVFSResult +do_set_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + const GnomeVFSFileInfo *info, + GnomeVFSSetFileInfoMask mask, + GnomeVFSContext *context) +{ + GnomeVFSURI *parent_uri, *new_uri; + GnomeVFSResult result; + + /* FIXME: For now, we only support changing the name. */ + if ((mask & ~(GNOME_VFS_SET_FILE_INFO_NAME)) != 0) { + return GNOME_VFS_ERROR_NOT_SUPPORTED; + } + + /* FIXME bugzilla.eazel.com 645: Make sure this returns an + * error for incoming names with "/" characters in them, + * instead of moving the file. + */ + + /* Share code with do_move. */ + parent_uri = gnome_vfs_uri_get_parent (uri); + if (parent_uri == NULL) { + return GNOME_VFS_ERROR_NOT_FOUND; + } + new_uri = gnome_vfs_uri_append_file_name (parent_uri, info->name); + gnome_vfs_uri_unref (parent_uri); + result = do_move (method, uri, new_uri, FALSE, context); + gnome_vfs_uri_unref (new_uri); + return result; +} + +static GnomeVFSMethod method = { + sizeof (GnomeVFSMethod), + do_open, + do_create, + do_close, + do_read, + do_write, + NULL, /* seek */ + NULL, /* tell */ + NULL, /* truncate */ + do_open_directory, + do_close_directory, + do_read_directory, + do_get_file_info, + do_get_file_info_from_handle, + do_is_local, + do_make_directory, + do_remove_directory, + do_move, + do_unlink, + do_check_same_fs, + do_set_file_info, + NULL, /* truncate */ + NULL, /* find_directory */ + NULL /* create_symbolic_link */ +}; + +GnomeVFSMethod * +vfs_module_init (const char *method_name, + const char *args) +{ + return &method; +} + +void +vfs_module_shutdown (GnomeVFSMethod *method) +{ +} diff --git a/modules/gzip-method.c b/modules/gzip-method.c new file mode 100644 index 0000000..6200e06 --- /dev/null +++ b/modules/gzip-method.c @@ -0,0 +1,771 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gzip-method.c - GZIP access method for the GNOME Virtual File + System. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct _GZipMethodHandle { + GnomeVFSURI *uri; + GnomeVFSHandle *parent_handle; + GnomeVFSOpenMode open_mode; + time_t modification_time; + + GnomeVFSResult last_vfs_result; + gint last_z_result; + z_stream zstream; + guchar *buffer; + guint32 crc; +}; +typedef struct _GZipMethodHandle GZipMethodHandle; + + +#define GZIP_MAGIC_1 0x1f +#define GZIP_MAGIC_2 0x8b + +#define GZIP_FLAG_ASCII 0x01 /* bit 0 set: file probably ascii text */ +#define GZIP_FLAG_HEAD_CRC 0x02 /* bit 1 set: header CRC present */ +#define GZIP_FLAG_EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +#define GZIP_FLAG_ORIG_NAME 0x08 /* bit 3 set: original file name present */ +#define GZIP_FLAG_COMMENT 0x10 /* bit 4 set: file comment present */ +#define GZIP_FLAG_RESERVED 0xE0 /* bits 5..7: reserved */ + +#define GZIP_HEADER_SIZE 10 +#define GZIP_FOOTER_SIZE 8 + +#define Z_BUFSIZE 16384 + + +static GnomeVFSResult do_open (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + GnomeVFSContext *context); + +static GnomeVFSResult do_create (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + gboolean exclusive, + guint perm, + GnomeVFSContext *context); + +static GnomeVFSResult do_close (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context); + +static GnomeVFSResult do_read (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read, + GnomeVFSContext *context); + +static GnomeVFSResult do_write (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gconstpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_written, + GnomeVFSContext *context); + +static GnomeVFSResult do_get_file_info(GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context); + +static gboolean do_is_local (GnomeVFSMethod *method, + const GnomeVFSURI *uri); + +static GnomeVFSMethod method = { + sizeof (GnomeVFSMethod), + do_open, + do_create, + do_close, + do_read, + do_write, + NULL, /* seek */ + NULL, /* tell */ + NULL, /* truncate_handle FIXME bugzilla.eazel.com 1175 */ + NULL, /* open_directory */ + NULL, /* close_directory */ + NULL, /* read_directory */ + do_get_file_info, + NULL, /* get_file_info_from_handle */ + do_is_local, + NULL, /* make_directory */ + NULL, /* remove_directory */ + NULL, /* move */ + NULL, /* unlink */ + NULL, /* check_same_fs */ + NULL, /* set_file_info */ + NULL, /* truncate */ + NULL, /* find_directory */ + NULL /* create_symbolic_link */ +}; + +#define RETURN_IF_FAIL(action) \ +G_STMT_START{ \ + GnomeVFSResult __tmp_result; \ + \ + __tmp_result = (action); \ + if (__tmp_result != GNOME_VFS_OK) \ + return __tmp_result; \ +}G_STMT_END + +#define VALID_URI(u) ((u)->parent!=NULL&&(((u)->text==NULL)||((u)->text[0]=='\0')||(((u)->text[0]=='/')&&((u)->text[1]=='\0')))) + + +/* GZip handle creation/destruction. */ + +static GZipMethodHandle * +gzip_method_handle_new (GnomeVFSHandle *parent_handle, + time_t modification_time, + GnomeVFSURI *uri, + GnomeVFSOpenMode open_mode) +{ + GZipMethodHandle *new; + + new = g_new (GZipMethodHandle, 1); + + new->parent_handle = parent_handle; + new->modification_time = modification_time; + new->uri = gnome_vfs_uri_ref (uri); + new->open_mode = open_mode; + + new->buffer = NULL; + new->crc = crc32 (0, Z_NULL, 0); + + return new; +} + +static void +gzip_method_handle_destroy (GZipMethodHandle *handle) +{ + gnome_vfs_uri_unref (handle->uri); + g_free (handle->buffer); + g_free (handle); +} + + +/* GZip method initialization for compression/decompression. */ + +static gboolean +gzip_method_handle_init_for_inflate (GZipMethodHandle *handle) +{ + handle->zstream.zalloc = NULL; + handle->zstream.zfree = NULL; + handle->zstream.opaque = NULL; + + g_free (handle->buffer); + + handle->buffer = g_malloc (Z_BUFSIZE); + handle->zstream.next_in = handle->buffer; + handle->zstream.avail_in = 0; + + if (inflateInit2 (&handle->zstream, -MAX_WBITS) != Z_OK) { + g_free (handle->buffer); + return FALSE; + } + + handle->last_z_result = Z_OK; + handle->last_vfs_result = GNOME_VFS_OK; + + return TRUE; +} + +static gboolean +gzip_method_handle_init_for_deflate (GZipMethodHandle *handle) +{ + handle->zstream.zalloc = NULL; + handle->zstream.zfree = NULL; + handle->zstream.opaque = NULL; + + g_free (handle->buffer); + + handle->buffer = g_malloc (Z_BUFSIZE); + handle->zstream.next_out = handle->buffer; + handle->zstream.avail_out = Z_BUFSIZE; + + /* FIXME bugzilla.eazel.com 1174: We want this to be user-configurable. */ + if (deflateInit2 (&handle->zstream, Z_DEFAULT_COMPRESSION, + Z_DEFLATED, -MAX_WBITS, MAX_MEM_LEVEL, + Z_DEFAULT_STRATEGY) != Z_OK) { + g_free (handle->buffer); + return FALSE; + } + + handle->last_z_result = Z_OK; + handle->last_vfs_result = GNOME_VFS_OK; + + return TRUE; +} + + +static GnomeVFSResult +result_from_z_result (gint z_result) +{ + switch (z_result) { + case Z_OK: + case Z_STREAM_END: /* FIXME bugzilla.eazel.com 1173: Is this right? */ + return GNOME_VFS_OK; + case Z_DATA_ERROR: + return GNOME_VFS_ERROR_CORRUPTED_DATA; + default: + return GNOME_VFS_ERROR_INTERNAL; + } +} + + +/* Functions to skip data in the file. */ + +static GnomeVFSResult +skip_string (GnomeVFSHandle *handle) +{ + GnomeVFSResult result; + guchar c; + GnomeVFSFileSize bytes_read; + + do { + result = gnome_vfs_read (handle, &c, 1, &bytes_read); + RETURN_IF_FAIL (result); + + if (bytes_read != 1) + return GNOME_VFS_ERROR_WRONG_FORMAT; + } while (c != 0); + + return GNOME_VFS_OK; +} + +static gboolean +skip (GnomeVFSHandle *handle, + GnomeVFSFileSize num_bytes) +{ + GnomeVFSResult result; + guchar *tmp; + GnomeVFSFileSize bytes_read; + + tmp = g_alloca (num_bytes); + + result = gnome_vfs_read (handle, tmp, num_bytes, &bytes_read); + RETURN_IF_FAIL (result); + + if (bytes_read != num_bytes) + return GNOME_VFS_ERROR_WRONG_FORMAT; + + return TRUE; +} + + +/* Utility function to write a gulong value. */ + +static GnomeVFSResult +write_guint32 (GnomeVFSHandle *handle, + guint32 value) +{ + guint i; + guchar buffer[4]; + GnomeVFSFileSize bytes_written; + + for (i = 0; i < 4; i++) { + buffer[i] = value & 0xff; + value >>= 8; + } + + return gnome_vfs_write (handle, buffer, 4, &bytes_written); +} + + +/* GZIP Header functions. */ + +static GnomeVFSResult +read_gzip_header (GnomeVFSHandle *handle, + time_t *modification_time) +{ + GnomeVFSResult result; + guchar buffer[GZIP_HEADER_SIZE]; + GnomeVFSFileSize bytes_read; + guint mode; + guint flags; + + result = gnome_vfs_read (handle, buffer, GZIP_HEADER_SIZE, + &bytes_read); + RETURN_IF_FAIL (result); + + if (bytes_read != GZIP_HEADER_SIZE) + return GNOME_VFS_ERROR_WRONG_FORMAT; + + if (buffer[0] != GZIP_MAGIC_1 || buffer[1] != GZIP_MAGIC_2) + return GNOME_VFS_ERROR_WRONG_FORMAT; + + mode = buffer[2]; + if (mode != 8) /* Mode: deflate */ + return GNOME_VFS_ERROR_WRONG_FORMAT; + + flags = buffer[3]; + + if (flags & GZIP_FLAG_RESERVED) + return GNOME_VFS_ERROR_WRONG_FORMAT; + + if (flags & GZIP_FLAG_EXTRA_FIELD) { + guchar tmp[2]; + GnomeVFSFileSize bytes_read; + + if (gnome_vfs_read (handle, tmp, 2, &bytes_read) + || bytes_read != 2) + return GNOME_VFS_ERROR_WRONG_FORMAT; + if (! skip (handle, tmp[0] | (tmp[0] << 8))) + return GNOME_VFS_ERROR_WRONG_FORMAT; + } + + if (flags & GZIP_FLAG_ORIG_NAME) + RETURN_IF_FAIL (skip_string (handle)); + + if (flags & GZIP_FLAG_COMMENT) + RETURN_IF_FAIL (skip_string (handle)); + + if (flags & GZIP_FLAG_HEAD_CRC) + RETURN_IF_FAIL (skip (handle, 2)); + + *modification_time = (buffer[4] | (buffer[5] << 8) + | (buffer[6] << 16) | (buffer[7] << 24)); + return GNOME_VFS_OK; +} + +static GnomeVFSResult +write_gzip_header (GnomeVFSHandle *handle, time_t modification_time) +{ + GnomeVFSResult result; + guchar buffer[GZIP_HEADER_SIZE]; + GnomeVFSFileSize bytes_written; + + buffer[0] = GZIP_MAGIC_1; /* magic 1 */ + buffer[1] = GZIP_MAGIC_2; /* magic 2 */ + buffer[2] = Z_DEFLATED; /* method */ + buffer[3] = 0; /* flags */ + buffer[4] = (guchar) ((modification_time >> 0) & 0xFF); /* time 1 */ + buffer[5] = (guchar) ((modification_time >> 8) & 0xFF); /* time 2 */ + buffer[6] = (guchar) ((modification_time >> 16) & 0xFF); /* time 3 */ + buffer[7] = (guchar) ((modification_time >> 24) & 0xFF); /* time 4 */ + buffer[8] = 0; /* xflags */ + buffer[9] = 3; /* OS (Unix) */ + + result = gnome_vfs_write (handle, buffer, GZIP_HEADER_SIZE, + &bytes_written); + RETURN_IF_FAIL (result); + + if (bytes_written != GZIP_HEADER_SIZE) + return GNOME_VFS_ERROR_IO; + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +flush_write (GZipMethodHandle *gzip_handle) +{ + GnomeVFSHandle *parent_handle; + GnomeVFSResult result; + gboolean done; + z_stream *zstream; + gint z_result; + + zstream = &gzip_handle->zstream; + zstream->avail_in = 0; /* (Should be zero already anyway.) */ + + parent_handle = gzip_handle->parent_handle; + + done = FALSE; + z_result = Z_OK; + while (z_result == Z_OK || z_result == Z_STREAM_END) { + GnomeVFSFileSize bytes_written; + GnomeVFSFileSize len; + + len = Z_BUFSIZE - zstream->avail_out; + + result = gnome_vfs_write (parent_handle, gzip_handle->buffer, + len, &bytes_written); + RETURN_IF_FAIL (result); + + zstream->next_out = gzip_handle->buffer; + zstream->avail_out = Z_BUFSIZE; + + if (done) + break; + + z_result = deflate(zstream, Z_FINISH); + + /* Ignore the second of two consecutive flushes. */ + if (z_result == Z_BUF_ERROR) + z_result = Z_OK; + + /* Deflate has finished flushing only when it hasn't used up + all the available space in the output buffer. */ + done = (zstream->avail_out != 0 || z_result == Z_STREAM_END); + } + + result = write_guint32 (parent_handle, gzip_handle->crc); + RETURN_IF_FAIL (result); + + result = write_guint32 (parent_handle, zstream->total_in); + RETURN_IF_FAIL (result); + + if (z_result == Z_OK || z_result == Z_STREAM_END) + return GNOME_VFS_OK; + else + return result_from_z_result (z_result); +} + + +/* Open. */ + +/* TODO: + - Check that there is no subpath. */ +static GnomeVFSResult +do_open (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode open_mode, + GnomeVFSContext *context) +{ + GnomeVFSHandle *parent_handle; + GnomeVFSURI *parent_uri; + GnomeVFSResult result; + GZipMethodHandle *gzip_handle; + time_t modification_time; + + _GNOME_VFS_METHOD_PARAM_CHECK (method_handle != NULL); + _GNOME_VFS_METHOD_PARAM_CHECK (uri != NULL); + + /* Check that the URI is valid. */ + if (!VALID_URI(uri)) return GNOME_VFS_ERROR_INVALID_URI; + + parent_uri = uri->parent; + + if (open_mode & GNOME_VFS_OPEN_RANDOM) + return GNOME_VFS_ERROR_NOT_SUPPORTED; + + result = gnome_vfs_open_uri (&parent_handle, parent_uri, open_mode); + RETURN_IF_FAIL (result); + + if (open_mode & GNOME_VFS_OPEN_READ) { + result = read_gzip_header (parent_handle, &modification_time); + if (result != GNOME_VFS_OK) { + gnome_vfs_close (parent_handle); + return result; + } + + gzip_handle = gzip_method_handle_new (parent_handle, + modification_time, + uri, + open_mode); + + if (! gzip_method_handle_init_for_inflate (gzip_handle)) { + gnome_vfs_close (parent_handle); + gzip_method_handle_destroy (gzip_handle); + return GNOME_VFS_ERROR_INTERNAL; + } + } else { /* GNOME_VFS_OPEN_WRITE */ + modification_time = time (NULL); + result = write_gzip_header (parent_handle, modification_time); + RETURN_IF_FAIL (result); + + /* FIXME bugzilla.eazel.com 1172: need to set modification_time */ + gzip_handle = gzip_method_handle_new (parent_handle, + modification_time, + uri, + open_mode); + + if (! gzip_method_handle_init_for_deflate (gzip_handle)) { + gnome_vfs_close (parent_handle); + gzip_method_handle_destroy (gzip_handle); + return GNOME_VFS_ERROR_INTERNAL; + } + } + + *method_handle = (GnomeVFSMethodHandle *) gzip_handle; + + return GNOME_VFS_OK; +} + + +/* Create. */ + +static GnomeVFSResult +do_create (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + gboolean exclusive, + guint perm, + GnomeVFSContext *context) +{ + _GNOME_VFS_METHOD_PARAM_CHECK (method_handle != NULL); + _GNOME_VFS_METHOD_PARAM_CHECK (uri != NULL); + + return GNOME_VFS_ERROR_NOT_SUPPORTED; /* FIXME bugzilla.eazel.com 1170 */ +} + + +/* Close. */ + +static GnomeVFSResult +do_close (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + GZipMethodHandle *gzip_handle; + GnomeVFSResult result; + + _GNOME_VFS_METHOD_PARAM_CHECK (method_handle != NULL); + + gzip_handle = (GZipMethodHandle *) method_handle; + + if (gzip_handle->open_mode & GNOME_VFS_OPEN_WRITE) + result = flush_write (gzip_handle); + else + result = GNOME_VFS_OK; + + if (result == GNOME_VFS_OK) + result = gnome_vfs_close (gzip_handle->parent_handle); + + gzip_method_handle_destroy (gzip_handle); + + return result; +} + + +/* Read. */ +static GnomeVFSResult +fill_buffer (GZipMethodHandle *gzip_handle, + GnomeVFSFileSize num_bytes) +{ + GnomeVFSResult result; + GnomeVFSFileSize count; + z_stream *zstream; + + zstream = &gzip_handle->zstream; + + if (zstream->avail_in > 0) + return GNOME_VFS_OK; + + result = gnome_vfs_read (gzip_handle->parent_handle, + gzip_handle->buffer, + Z_BUFSIZE, + &count); + + if (result != GNOME_VFS_OK) { + if (zstream->avail_out == num_bytes) + return result; + gzip_handle->last_vfs_result = result; + } else { + zstream->next_in = gzip_handle->buffer; + zstream->avail_in = count; + } + + return GNOME_VFS_OK; +} + +/* FIXME bugzilla.eazel.com 1165: TODO: + - Concatenated GZIP file handling. */ +static GnomeVFSResult +do_read (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read, + GnomeVFSContext *context) +{ + GZipMethodHandle *gzip_handle; + GnomeVFSResult result; + z_stream *zstream; + int z_result; + guchar *crc_start; + + *bytes_read = 0; + + crc_start = buffer; + + gzip_handle = (GZipMethodHandle *) method_handle; + + zstream = &gzip_handle->zstream; + + if (gzip_handle->last_z_result != Z_OK) { + if (gzip_handle->last_z_result == Z_STREAM_END) { + *bytes_read = 0; + return GNOME_VFS_OK; + } else + return result_from_z_result (gzip_handle->last_z_result); + } else if (gzip_handle->last_vfs_result != GNOME_VFS_OK) { + return gzip_handle->last_vfs_result; + } + + zstream->next_out = buffer; + zstream->avail_out = num_bytes; + + while (zstream->avail_out != 0) { + result = fill_buffer (gzip_handle, num_bytes); + RETURN_IF_FAIL (result); + + z_result = inflate (&gzip_handle->zstream, Z_NO_FLUSH); + if (z_result == Z_STREAM_END) { + gzip_handle->last_z_result = z_result; + break; + } else if (z_result != Z_OK) { + /* FIXME bugzilla.eazel.com 1165: Concatenated GZIP files? */ + gzip_handle->last_z_result = z_result; + } + + if (gzip_handle->last_z_result != Z_OK + && zstream->avail_out == num_bytes) + return result_from_z_result (gzip_handle->last_z_result); + } + + gzip_handle->crc = crc32 (gzip_handle->crc, + crc_start, + (guint) (zstream->next_out - crc_start)); + + *bytes_read = num_bytes - zstream->avail_out; + + return GNOME_VFS_OK; +} + + +/* Write. */ + +static GnomeVFSResult +do_write (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gconstpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_written, + GnomeVFSContext *context) +{ + GZipMethodHandle *gzip_handle; + GnomeVFSResult result; + z_stream *zstream; + gint z_result; + + gzip_handle = (GZipMethodHandle *) method_handle; + zstream = &gzip_handle->zstream; + + /* This cast sucks. It is not my fault, though. :-) */ + zstream->next_in = (gpointer) buffer; + zstream->avail_in = num_bytes; + + result = GNOME_VFS_OK; + + while (zstream->avail_in != 0 && result == GNOME_VFS_OK) { + if (zstream->avail_out == 0) { + GnomeVFSFileSize written; + + zstream->next_out = gzip_handle->buffer; + result = gnome_vfs_write (gzip_handle->parent_handle, + gzip_handle->buffer, + Z_BUFSIZE, &written); + + if (result != GNOME_VFS_OK) + break; + + zstream->avail_out += written; + } + + z_result = deflate (zstream, Z_NO_FLUSH); + result = result_from_z_result (z_result); + } + + gzip_handle->crc = crc32 (gzip_handle->crc, buffer, num_bytes); + + *bytes_written = num_bytes - zstream->avail_in; + + return result; +} + + +static GnomeVFSResult +do_get_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) { + GnomeVFSResult result; + + if (!VALID_URI(uri)) return GNOME_VFS_ERROR_INVALID_URI; + + result = gnome_vfs_get_file_info_uri(uri->parent, file_info, options); + if(result == GNOME_VFS_OK) { + gint namelen = strlen(file_info->name); + + /* work out the name */ + /* FIXME bugzilla.eazel.com 2790: handle uppercase */ + if(namelen > 3 && + file_info->name[namelen-1] == 'z' && + file_info->name[namelen-2] == 'g' && + file_info->name[namelen-3] == '.') + file_info->name[namelen-3] = '\0'; + + /* we can't tell the size without uncompressing it */ + //file_info->valid_fields &= ~GNOME_VFS_FILE_INFO_FIELDS_SIZE; + + /* guess the mime type of the file inside */ + /* FIXME bugzilla.eazel.com 2791: guess mime based on contents */ + g_free(file_info->mime_type); + file_info->mime_type = g_strdup(gnome_vfs_mime_type_from_name(file_info->name)); + } + + return result; +} + + + +static gboolean +do_is_local (GnomeVFSMethod *method, + const GnomeVFSURI *uri) +{ + g_return_val_if_fail (uri != NULL, FALSE); + + return gnome_vfs_uri_is_local (uri->parent); +} + + +/* Init. */ + +GnomeVFSMethod * +vfs_module_init (const char *method_name, const char *args) +{ + return &method; +} + +void +vfs_module_shutdown (GnomeVFSMethod *method) +{ +} + diff --git a/modules/http-authn.c b/modules/http-authn.c new file mode 100644 index 0000000..594a868 --- /dev/null +++ b/modules/http-authn.c @@ -0,0 +1,546 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* http-authn.c - Basic authentication handling for HTTP + + Copyright (C) 2001 Eazel, Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: + Michael Fleming +*/ + +#include +#include "http-authn.h" + +#include "http-method.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Authentication session information + * Key: host:port/path + * Value: Header line including + */ + +static GHashTable * gl_authn_table = NULL; +static GMutex *gl_mutex = NULL; + +void +http_authn_init (void) +{ + gl_authn_table = g_hash_table_new (g_str_hash, g_str_equal); + gl_mutex = g_mutex_new (); +} + +static void /* GHFunc */ +hfunc_free_string (gpointer key, gpointer value, gpointer user_data) +{ + g_free (key); + g_free (value); +} + +void +http_authn_shutdown (void) +{ + g_hash_table_foreach (gl_authn_table, hfunc_free_string, NULL); + g_hash_table_destroy (gl_authn_table); + gl_authn_table = NULL; + + g_mutex_free (gl_mutex); + gl_mutex = NULL; +} + +/* watch it here: # and ? may be legal in the authority field of a URI + * (eg: username:password) + * so don't feed the authority field in here + */ +static char * +strip_uri_query_and_fragment (const char *in) +{ + char *ret; + char *separator; + + ret = g_strdup (in); + + separator = strchr (ret, '#'); + + if (separator) { + *separator = '\0'; + } + + separator = strchr (ret, '?'); + + if (separator) { + *separator = '\0'; + } + + ret = g_realloc (ret, strlen (ret) + 1); + return ret; +} + +static char * +http_authn_get_key_string_from_uri (GnomeVFSURI *uri) +{ + size_t len; + char *uri_string; + char *uri_string_canonical; + char *ret; + + uri_string = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_USER_NAME + | GNOME_VFS_URI_HIDE_PASSWORD + | GNOME_VFS_URI_HIDE_FRAGMENT_IDENTIFIER); + + uri_string_canonical = gnome_vfs_make_uri_canonical (uri_string); + + ret = strip_uri_query_and_fragment (uri_string_canonical); + + /* strip any trailing / */ + len = strlen (ret); + if (ret [len-1] == '/') { + ret [len-1] = '\0'; + } + + g_free (uri_string_canonical); + uri_string_canonical = NULL; + g_free (uri_string); + uri_string = NULL; + + return ret; +} + +char * +http_authn_session_get_header_for_uri (GnomeVFSURI *uri) +{ + char *key_string; + char *marker; + char *authn_header; + char *ret; + + key_string = http_authn_get_key_string_from_uri (uri); + + g_mutex_lock (gl_mutex); + + ret = NULL; + while (NULL != strrchr (key_string, '/')) { + authn_header = (char *) g_hash_table_lookup (gl_authn_table, key_string); + if (authn_header != NULL) { + ret = g_strdup (authn_header); + break; + } + + /* Try the next level up in the heirarchy */ + marker = strrchr (key_string, '/'); + *marker = '\0'; + } + + g_mutex_unlock (gl_mutex); + + g_free (key_string); + key_string = NULL; + + return ret; +} + +void +http_authn_session_add_credentials (GnomeVFSURI *uri, const char *username, const char *password) +{ + char *key_string; + char *orig_key; + char *orig_value; + char *credentials; + char *credentials_encoded; + + g_return_if_fail (uri != NULL); + + key_string = http_authn_get_key_string_from_uri (uri); + + credentials = credentials_encoded = NULL; + + if (username != NULL) { + credentials = g_strdup_printf ("%s:%s", username, + password == NULL + ? "" : password); + credentials_encoded = http_util_base64 (credentials); + } + + g_mutex_lock (gl_mutex); + + if (g_hash_table_lookup_extended (gl_authn_table, key_string, (gpointer) &orig_key, (gpointer) &orig_value)) { + g_hash_table_remove (gl_authn_table, orig_key); + g_free (orig_key); + orig_key = NULL; + g_free (orig_value); + orig_value = NULL; + } + + if (credentials_encoded != NULL) { + g_hash_table_insert (gl_authn_table, key_string, g_strdup_printf ("Authorization: Basic %s\r\n", credentials_encoded)); + key_string = NULL; + } + + g_mutex_unlock (gl_mutex); + + g_free (key_string); + g_free (credentials); + g_free (credentials_encoded); +} + + +static gint /* GCompareFunc */ +http_authn_glist_find_header (gconstpointer a, gconstpointer b) +{ + if ( NULL != a && NULL != b) { + return g_ascii_strncasecmp ( (const char *)a, (const char *)b, strlen((const char *)b)); + } else { + return -1; + } +} + +/* "quoted-string" rfc 2616 section 2.1 */ +/* tolerant of lack of quotes (switches to space-delimited) */ +static char * +http_authn_parse_quoted_string (const char *in, const char **p_out) +{ + gboolean quote_next; + gboolean space_delimited; + GString *unquoted; + char *ret; + + ret = NULL; + + if (p_out != NULL) { + *p_out = NULL; + } + + if (*in != '"') { + space_delimited = TRUE; + } else { + space_delimited = FALSE; + in++; + } + + quote_next = FALSE; + unquoted = g_string_new (""); + for (; *in != '\0' + && (space_delimited + ? (*in != ' ' && *in != '\t') + : (*in != '"' || quote_next)) + ; in++) { + if (!quote_next && *in == '\\') { + quote_next = TRUE; + } else { + quote_next = FALSE; + g_string_append_c (unquoted, *in); + } + } + + if (p_out != NULL) { + if (*in != '\0') { + *p_out = in+1; + } else { + *p_out = in; + } + } + + ret = unquoted->str; + g_string_free (unquoted, FALSE); + + return ret; +} + +gboolean +http_authn_parse_response_header_basic (enum AuthnHeaderType type, GList *response_headers, /* OUT */ char **p_realm) +{ + const char *header_name; + char *header; + const char *marker; + GList *node; + gboolean ret; + + g_return_val_if_fail (p_realm != NULL, FALSE); + + *p_realm = NULL; + ret = FALSE; + + switch (type) { + case AuthnHeader_WWW: + header_name = "WWW-Authenticate:"; + break; + + case AuthnHeader_Proxy: + header_name = "Proxy-Authenticate:"; + break; + default: + g_return_val_if_fail (FALSE, FALSE); + } + + /* Apparently, there can be more than one authentication header + * (see RFC 2617 section 1.2 paragraph beginning with "Note:" + */ + node = g_list_find_custom (response_headers, (gpointer) header_name, http_authn_glist_find_header); + for (; node != NULL + ; node = g_list_find_custom (g_list_next (node), (gpointer) header_name, http_authn_glist_find_header)) { + + header = (char *)node->data; + + /* skip through the header name */ + marker = strchr (header, (unsigned char)':'); + + if (marker == NULL) { + continue; + } + + marker++; + + /* skip to the auth-scheme */ + for (; *marker != '\0' + && (*marker == ' ' || *marker == '\t') + ; marker++); + + if (0 != g_ascii_strncasecmp ("Basic", marker, strlen ("Basic"))) { + continue; + } + + marker += strlen ("Basic"); + + while (*marker != '\0') { + for (; *marker != '\0' + && (*marker == ' ' || *marker == '\t' || *marker == ',') + ; marker++); + + if (0 == g_ascii_strncasecmp ("realm=", marker, strlen ("realm="))) { + marker += strlen ("realm="); + *p_realm = http_authn_parse_quoted_string (marker, &marker); + break; + } + } + + if (*p_realm == NULL) { + *p_realm = strdup (""); + } + + ret = TRUE; + break; + } + + return ret; +} + + +char * +http_authn_get_header_for_uri (GnomeVFSURI *uri) +{ + char *result; + GnomeVFSToplevelURI *toplevel_uri; + + toplevel_uri = gnome_vfs_uri_get_toplevel (uri); + + result = NULL; + + /* If authn info was passed in the URI, then default to that */ + if(toplevel_uri != NULL && toplevel_uri->user_name) { + gchar *raw; + gchar *enc; + + raw = g_strdup_printf("%s:%s", toplevel_uri->user_name, + toplevel_uri->password?toplevel_uri->password:""); + + enc = http_util_base64(raw); + + result = g_strdup_printf("Authorization: Basic %s\r\n", enc); + g_free(enc); + g_free(raw); + } else { + result = http_authn_session_get_header_for_uri ((GnomeVFSURI *)toplevel_uri); + } + + return result; +} + +#define VERIFY_STRING_RESULT(function, expected) \ + G_STMT_START { \ + char *result = function; \ + if (!((result == NULL && expected == NULL) \ + || (result != NULL && expected != NULL && strcmp (result, (char *)expected) == 0))) { \ + test_failed ("%s:%s:%s: returned '%s' expected '%s'", __FILE__, __LINE__, #function, result, expected); \ + } \ + } G_STMT_END + +static gboolean at_least_one_test_failed = FALSE; + +static void +test_failed (const char *format, ...) +{ + va_list arguments; + char *message; + + va_start (arguments, format); + message = g_strdup_vprintf (format, arguments); + va_end (arguments); + + fprintf (stderr, "test failed: %s\n", message); + at_least_one_test_failed = TRUE; +} + +static void +test_parse_header (guint line, enum AuthnHeaderType type, const char *realm_expected, gboolean result_expected, ...) +{ + va_list arguments; + GList *header_list; + const char *header; + char *realm; + gboolean result; + + va_start (arguments, result_expected); + + header_list = NULL; + + for (header = va_arg (arguments, const char *) + ; header != NULL + ; header = va_arg (arguments, const char *)) { + + header_list = g_list_prepend (header_list, (gpointer)header); + } + + header_list = g_list_reverse (header_list); + va_end (arguments); + + result = http_authn_parse_response_header_basic (type, header_list, &realm); + + if (! (result == result_expected + && ((realm == NULL && realm_expected == NULL) + || (realm != NULL && realm_expected != NULL + && 0 == strcmp (realm, realm_expected))))) { + + test_failed ("%s:%u:http_authn_parse_response_header_basic failed, expected (%d,%s) but got (%d, %s)\n", + __FILE__, line, result_expected, realm_expected, result, realm); + } +} + +/* Hook for testing code to flush credentials */ +void +http_authentication_test_flush_credentials (void); + +void +http_authentication_test_flush_credentials (void) +{ + g_hash_table_foreach (gl_authn_table, hfunc_free_string, NULL); + g_hash_table_destroy (gl_authn_table); + gl_authn_table = g_hash_table_new (g_str_hash, g_str_equal); +} + +gboolean +http_authn_self_test (void) +{ + GnomeVFSURI *uri; + + at_least_one_test_failed = FALSE; + + fprintf (stderr, "self-test: http-authn\n"); + + VERIFY_STRING_RESULT (strip_uri_query_and_fragment ("/foo/bar"), "/foo/bar"); + VERIFY_STRING_RESULT (strip_uri_query_and_fragment ("/foo/bar?query"), "/foo/bar"); + VERIFY_STRING_RESULT (strip_uri_query_and_fragment ("/foo/bar?query#fragment"), "/foo/bar"); + VERIFY_STRING_RESULT (strip_uri_query_and_fragment ("/foo/bar#fragment"), "/foo/bar"); + VERIFY_STRING_RESULT (strip_uri_query_and_fragment ("#fragment"), ""); + VERIFY_STRING_RESULT (strip_uri_query_and_fragment ("?query#fragment"), ""); + VERIFY_STRING_RESULT (strip_uri_query_and_fragment ("?query"), ""); + VERIFY_STRING_RESULT (strip_uri_query_and_fragment ("?query#fragment"), ""); + + uri = gnome_vfs_uri_new ("http://host/path"); + VERIFY_STRING_RESULT (http_authn_get_key_string_from_uri (uri), "http://host/path"); + gnome_vfs_uri_unref (uri); + + /* FIXME I think make_uri_canonical should remove default ports */ + uri = gnome_vfs_uri_new ("http://host:80/path"); + VERIFY_STRING_RESULT (http_authn_get_key_string_from_uri (uri), "http://host:80/path"); + gnome_vfs_uri_unref (uri); + + uri = gnome_vfs_uri_new ("http://host:80/path/"); + VERIFY_STRING_RESULT (http_authn_get_key_string_from_uri (uri), "http://host:80/path"); + gnome_vfs_uri_unref (uri); + + uri = gnome_vfs_uri_new ("http://user:pass@host:80/path/?query#foo"); + VERIFY_STRING_RESULT (http_authn_get_key_string_from_uri (uri), "http://host:80/path"); + gnome_vfs_uri_unref (uri); + + VERIFY_STRING_RESULT (http_authn_parse_quoted_string ("\"quoted string\"", NULL), "quoted string"); + VERIFY_STRING_RESULT (http_authn_parse_quoted_string ("\"quoted\\\"str\\\\ing\"", NULL), "quoted\"str\\ing"); + VERIFY_STRING_RESULT (http_authn_parse_quoted_string ("unquoted-string", NULL), "unquoted-string"); + VERIFY_STRING_RESULT (http_authn_parse_quoted_string ("\"\"", NULL), ""); + VERIFY_STRING_RESULT (http_authn_parse_quoted_string ("", NULL), ""); + + test_parse_header (__LINE__, AuthnHeader_WWW, "realm" , TRUE, "WWW-Authenticate: Basic realm=\"realm\"", NULL); + test_parse_header (__LINE__, AuthnHeader_WWW, "realm" , TRUE, "WWW-Authenticate: Digest crap=\"crap\"", "WWW-Authenticate: Basic realm=\"realm\"", NULL); + test_parse_header (__LINE__, AuthnHeader_WWW, "realm" , TRUE, "WWW-Authenticate: Basic realm=\"realm\"", "WWW-Authenticate: Digest crap=\"crap\"", NULL); + test_parse_header (__LINE__, AuthnHeader_WWW, "" , TRUE, "WWW-Authenticate: Basic", "WWW-Authenticate: Digest crap=\"crap\"", "Proxy-Authenticate: Basic realm=\"crap\"", NULL); + test_parse_header (__LINE__, AuthnHeader_WWW, NULL , FALSE, "WWW-Authenticate: Digest crap=\"crap\"", "Proxy-Authenticate: Basic realm=\"crap\"", NULL); + + test_parse_header (__LINE__, AuthnHeader_Proxy, "realm" , TRUE, "WWW-Authenticate: Basic", "WWW-Authenticate: Digest crap=\"crap\"", "Proxy-Authenticate: Basic realm=\"realm\"", NULL); + test_parse_header (__LINE__, AuthnHeader_Proxy, "realm" , TRUE, "WWW-Authenticate: Basic", "WWW-Authenticate: Digest crap=\"crap\"", "proxy-authenticate: basic Realm=\"realm\"", NULL); + + uri = gnome_vfs_uri_new ("http://host/path/"); + + VERIFY_STRING_RESULT (http_authn_get_header_for_uri (uri), NULL); + + http_authn_session_add_credentials (uri, "myuser", "mypasswd"); + + VERIFY_STRING_RESULT (http_authn_get_header_for_uri (uri), + g_strconcat ("Authorization: Basic ", http_util_base64("myuser:mypasswd"), "\r\n", NULL)); + + gnome_vfs_uri_unref (uri); + uri = gnome_vfs_uri_new ("http://host/path/?query#foo"); + + VERIFY_STRING_RESULT (http_authn_get_header_for_uri (uri), + g_strconcat ("Authorization: Basic ", http_util_base64("myuser:mypasswd"), "\r\n", NULL)); + + http_authn_session_add_credentials (uri, "newuser", "newpasswd"); + + gnome_vfs_uri_unref (uri); + uri = gnome_vfs_uri_new ("http://host/path"); + + VERIFY_STRING_RESULT (http_authn_get_header_for_uri (uri), + g_strconcat ("Authorization: Basic ", http_util_base64("newuser:newpasswd"), "\r\n", NULL)); + + gnome_vfs_uri_unref (uri); + uri = gnome_vfs_uri_new ("http://host/"); + + VERIFY_STRING_RESULT (http_authn_get_header_for_uri (uri), NULL); + + gnome_vfs_uri_unref (uri); + uri = gnome_vfs_uri_new ("http://user:passwd@host/path"); + + VERIFY_STRING_RESULT (http_authn_get_header_for_uri (uri), + g_strconcat ("Authorization: Basic ", http_util_base64("user:passwd"), "\r\n", NULL)); + + gnome_vfs_uri_unref (uri); + uri = gnome_vfs_uri_new ("http://anotherhost/path"); + + VERIFY_STRING_RESULT (http_authn_get_header_for_uri (uri), NULL); + + http_authn_session_add_credentials (uri, "newuser", "newpasswd"); + http_authn_session_add_credentials (uri, NULL, NULL); + + VERIFY_STRING_RESULT (http_authn_get_header_for_uri (uri), NULL); + + return !at_least_one_test_failed; +} diff --git a/modules/http-authn.h b/modules/http-authn.h new file mode 100644 index 0000000..77b113e --- /dev/null +++ b/modules/http-authn.h @@ -0,0 +1,54 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* http-authn.h - Basic authentication handling for HTTP + + Copyright (C) 2001 Eazel, Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: + Michael Fleming +*/ + +#ifndef HTTP_AUTHN_H +#define HTTP_AUTHN_H + +#include + +enum AuthnHeaderType { + AuthnHeader_WWW, + AuthnHeader_Proxy +}; + +void http_authn_init (void); + +void http_authn_shutdown (void); + +char * http_authn_session_get_header_for_uri (GnomeVFSURI *uri); + +void http_authn_session_add_credentials (GnomeVFSURI *uri, + const char * username, + const char * password); + +gboolean http_authn_parse_response_header_basic (enum AuthnHeaderType type, + GList *response_headers, + /* OUT */ char **p_realm); + +char * http_authn_get_header_for_uri (GnomeVFSURI *uri); + +gboolean http_authn_self_test (void); + + +#endif /* HTTP_AUTHN_H */ diff --git a/modules/http-cache.c b/modules/http-cache.c new file mode 100644 index 0000000..7b4d103 --- /dev/null +++ b/modules/http-cache.c @@ -0,0 +1,526 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* http-cache.c - Property caching for DAV + + Copyright (C) 2000-2001 Eazel, Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: + Michael Fleming +*/ + +#include +#include "http-cache.h" + +#include "http-method.h" +#include +#include +#include +#include +#include + +/* Cache file info for 5 minutes */ +#define US_CACHE_FILE_INFO (1000 * 1000 * 60 * 5) +/* Cache directory listings for 500 ms */ +#define US_CACHE_DIRECTORY (1000 * 500) + +/* Mutex for cache data structures */ +static GStaticRecMutex cache_rlock = G_STATIC_REC_MUTEX_INIT; + +/* Hash maps char * URI ---> FileInfoCacheEntry */ +static GHashTable * gl_file_info_cache = NULL; +/* in-order list of cache entries for expiration */ +static GList * gl_file_info_cache_list = NULL; +static GList * gl_file_info_cache_list_last = NULL; + +typedef struct { + gchar * uri_string; + GnomeVFSFileInfo * file_info; + utime_t create_time; + GList * my_list_node; /*node for me in gl_file_info_cache_list*/ + GList * filenames; /* List of char * basenames for files that are in this + * collection/directory. Empty for non-directories + */ + gboolean has_filenames:1;/* For directories, FALSE if the cache does not contain + * the directory's children + */ + gboolean is_dav:1; /* Did this result from a PROPFIND or a GET ? */ +} FileInfoCacheEntry; + +static FileInfoCacheEntry * http_cache_entry_new (); +static void http_cache_entry_free (FileInfoCacheEntry * entry); +static FileInfoCacheEntry * http_cache_add_no_strdup (gchar *uri_string, GnomeVFSFileInfo *file_info, gboolean is_dav); +static FileInfoCacheEntry * http_cache_add (const gchar *uri_string, GnomeVFSFileInfo *file_info, gboolean is_dav); + +void +http_cache_init (void) +{ + gl_file_info_cache = g_hash_table_new (g_str_hash, g_str_equal); +} + +void +http_cache_shutdown (void) +{ + GList *node, *node_next; + + g_static_rec_mutex_lock (&cache_rlock); + + for ( node = g_list_first (gl_file_info_cache_list) ; + node != NULL; + node = node_next + ) { + node_next = g_list_next (node); + http_cache_entry_free ((FileInfoCacheEntry*) node->data); + } + + g_list_free (gl_file_info_cache_list); + + g_hash_table_destroy (gl_file_info_cache); + + g_static_rec_mutex_unlock (&cache_rlock); + +} + +static FileInfoCacheEntry * +http_cache_entry_new (void) +{ + FileInfoCacheEntry *ret; + + g_static_rec_mutex_lock (&cache_rlock); + + ret = g_new0 (FileInfoCacheEntry, 1); + ret->create_time = http_util_get_utime(); + + gl_file_info_cache_list = g_list_prepend (gl_file_info_cache_list, ret); + + /* Note that since we've prepended, gl_file_info_cache_list points to us*/ + + ret->my_list_node = gl_file_info_cache_list; + + if (gl_file_info_cache_list_last == NULL) { + gl_file_info_cache_list_last = ret->my_list_node; + } + + g_static_rec_mutex_unlock (&cache_rlock); + + return ret; +} + +/* Warning: as this function removes the cache entry from gl_file_info_cache_list, + * callee's must be careful when calling this during a list iteration + */ +static void +http_cache_entry_free (FileInfoCacheEntry * entry) +{ + if (entry) { + GList *node; + + g_static_rec_mutex_lock (&cache_rlock); + + g_hash_table_remove (gl_file_info_cache, entry->uri_string); + g_free (entry->uri_string); /* This is the same string as in the hash table */ + gnome_vfs_file_info_unref (entry->file_info); + + if (gl_file_info_cache_list_last == entry->my_list_node) { + gl_file_info_cache_list_last = g_list_previous (entry->my_list_node); + } + + gl_file_info_cache_list = g_list_remove_link (gl_file_info_cache_list, entry->my_list_node); + g_list_free_1 (entry->my_list_node); + + for (node = entry->filenames ; node ; node = g_list_next(node)) { + g_free (node->data); + } + + g_list_free (entry->filenames); + + g_free (entry); + + g_static_rec_mutex_unlock (&cache_rlock); + } +} + +void +http_cache_trim (void) +{ + GList *node, *node_previous; + utime_t utime_expire; + + g_static_rec_mutex_lock (&cache_rlock); + + utime_expire = http_util_get_utime() - US_CACHE_FILE_INFO; + + for ( node = gl_file_info_cache_list_last ; + node && (utime_expire > ((FileInfoCacheEntry *)node->data)->create_time) ; + node = node_previous + ) { + node_previous = g_list_previous (node); + + DEBUG_HTTP (("Cache: Expire: '%s'",((FileInfoCacheEntry *)node->data)->uri_string)); + + http_cache_entry_free ((FileInfoCacheEntry *)(node->data)); + } + + g_static_rec_mutex_unlock (&cache_rlock); +} + +/* Note: doesn't bother trimming entries, so the check can fast */ +GnomeVFSFileInfo * +http_cache_check (const gchar * uri_string) +{ + FileInfoCacheEntry *entry; + utime_t utime_expire; + GnomeVFSFileInfo *ret; + + g_static_rec_mutex_lock (&cache_rlock); + + utime_expire = http_util_get_utime() - US_CACHE_FILE_INFO; + + entry = (FileInfoCacheEntry *)g_hash_table_lookup (gl_file_info_cache, uri_string); + + if (entry && (utime_expire > entry->create_time)) { + entry = NULL; + } + + if (entry) { + gnome_vfs_file_info_ref (entry->file_info); + + DEBUG_HTTP (("Cache: Hit: '%s'", entry->uri_string)); + + ret = entry->file_info; + } else { + ret = NULL; + } + g_static_rec_mutex_unlock (&cache_rlock); + return ret; +} + +static gchar * +http_cache_uri_to_string (GnomeVFSURI *uri) +{ + gchar *uri_string; + size_t uri_length; + + uri_string = gnome_vfs_uri_to_string (uri, + GNOME_VFS_URI_HIDE_USER_NAME + | GNOME_VFS_URI_HIDE_PASSWORD + | GNOME_VFS_URI_HIDE_TOPLEVEL_METHOD); + + if (uri_string) { + uri_length = strlen (uri_string); + /* Trim off trailing '/'s */ + if ( '/' == uri_string[uri_length-1] ) { + uri_string[uri_length-1] = 0; + } + } + + return uri_string; +} + +GnomeVFSFileInfo * +http_cache_check_uri (GnomeVFSURI *uri) +{ + gchar *uri_string; + GnomeVFSFileInfo *ret; + + uri_string = http_cache_uri_to_string (uri); + + ret = http_cache_check (uri_string); + g_free (uri_string); + return ret; +} + + +/* Directory operations demand fresher cache entries */ +GnomeVFSFileInfo * +http_cache_check_directory (const gchar * uri_string, GList **p_child_file_info_list) +{ + FileInfoCacheEntry *entry; + utime_t utime_expire; + GnomeVFSFileInfo *ret; + GList *child_file_info_list = NULL; + gboolean cache_incomplete; + + g_static_rec_mutex_lock (&cache_rlock); + + utime_expire = http_util_get_utime() - US_CACHE_DIRECTORY; + + entry = (FileInfoCacheEntry *)g_hash_table_lookup (gl_file_info_cache, uri_string); + + if (entry && (utime_expire > entry->create_time)) { + entry = NULL; + } + + if (entry && entry->has_filenames) { + DEBUG_HTTP (("Cache: Hit: '%s'",entry->uri_string)); + + gnome_vfs_file_info_ref (entry->file_info); + ret = entry->file_info; + } else { + ret = NULL; + } + + if (ret && p_child_file_info_list != NULL) { + GList * filename_node; + + cache_incomplete = FALSE; + + for (filename_node = entry->filenames ; + filename_node ; + filename_node = g_list_next (filename_node) + ) { + char *child_filename; + FileInfoCacheEntry *child_entry; + + child_filename = g_strconcat (uri_string, "/", (gchar *)filename_node->data, NULL); + + child_entry = (FileInfoCacheEntry *)g_hash_table_lookup (gl_file_info_cache, child_filename); + + /* Other HTTP requests on children can cause them to expire before the parent directory */ + if (child_entry == NULL) { + cache_incomplete = TRUE; + break; + } + + gnome_vfs_file_info_ref (child_entry->file_info); + child_file_info_list = g_list_prepend (child_file_info_list, child_entry->file_info); + + g_free (child_filename); + } + + if (cache_incomplete) { + DEBUG_HTTP (("Cache: Directory was incomplete: '%s'",entry->uri_string)); + + gnome_vfs_file_info_unref (ret); + ret = NULL; + *p_child_file_info_list = NULL; + } else { + *p_child_file_info_list = child_file_info_list; + } + } + + g_static_rec_mutex_unlock (&cache_rlock); + + return ret; +} + +GnomeVFSFileInfo * +http_cache_check_directory_uri (GnomeVFSURI * uri, GList **p_child_file_info_list) +{ + gchar *uri_string; + GnomeVFSFileInfo *ret; + + uri_string = http_cache_uri_to_string (uri); + + ret = http_cache_check_directory (uri_string, p_child_file_info_list); + g_free (uri_string); + + return ret; +} + +/* Note that this neither strdups uri_string nor calls cache_trim() */ +static FileInfoCacheEntry * +http_cache_add_no_strdup (gchar * uri_string, GnomeVFSFileInfo * file_info, gboolean is_dav) +{ + FileInfoCacheEntry *entry_existing; + FileInfoCacheEntry *entry; + + g_static_rec_mutex_lock (&cache_rlock); + + entry_existing = (FileInfoCacheEntry *)g_hash_table_lookup (gl_file_info_cache, uri_string); + + DEBUG_HTTP (("Cache: Add: '%s'", uri_string)); + + if (entry_existing) { + http_cache_entry_free (entry_existing); + entry_existing = NULL; + } + + entry = http_cache_entry_new(); + + entry->uri_string = uri_string; + entry->file_info = file_info; + entry->is_dav = is_dav; + + gnome_vfs_file_info_ref (file_info); + + g_hash_table_insert (gl_file_info_cache, entry->uri_string, entry); + + g_static_rec_mutex_unlock (&cache_rlock); + + return entry; +} + +static FileInfoCacheEntry * +http_cache_add (const gchar * uri_string, GnomeVFSFileInfo * file_info, gboolean is_dav) +{ + http_cache_trim (); + return http_cache_add_no_strdup (g_strdup (uri_string), file_info, is_dav); +} + +void +http_cache_add_uri_and_children (GnomeVFSURI *uri, GnomeVFSFileInfo *file_info, GList *file_info_list) +{ + gchar *uri_string; + gchar *child_string; + GList *node; + FileInfoCacheEntry *parent_entry; + + http_cache_trim(); + + g_static_rec_mutex_lock (&cache_rlock); + + uri_string = http_cache_uri_to_string (uri); + + if (uri_string != NULL) { + /* Note--can't use no_strdup because we use uri_string below */ + parent_entry = http_cache_add (uri_string, file_info, TRUE); + + parent_entry->filenames = NULL; + + for (node = file_info_list ; node != NULL ; node = g_list_next (node)) { + GnomeVFSFileInfo *child_info; + gchar * child_name_escaped; + + child_info = (GnomeVFSFileInfo *) node->data; + + child_name_escaped = gnome_vfs_escape_path_string (child_info->name); + + child_string = g_strconcat (uri_string, "/", child_name_escaped, NULL); + + parent_entry->filenames = g_list_prepend ( + parent_entry->filenames, + child_name_escaped); + child_name_escaped = NULL; + + http_cache_add_no_strdup (child_string, child_info, TRUE); + } + /* I'm not sure that order matters... */ + parent_entry->filenames = g_list_reverse (parent_entry->filenames); + parent_entry->has_filenames = TRUE; + } + + g_static_rec_mutex_unlock (&cache_rlock); + + g_free (uri_string); +} + +void +http_cache_add_uri (GnomeVFSURI *uri, GnomeVFSFileInfo *file_info, gboolean is_dav) +{ + http_cache_trim (); + + http_cache_add_no_strdup (http_cache_uri_to_string (uri), file_info, is_dav); +} + + +void +http_cache_invalidate (const gchar * uri_string) +{ + FileInfoCacheEntry *entry; + + g_static_rec_mutex_lock (&cache_rlock); + + entry = (FileInfoCacheEntry *)g_hash_table_lookup (gl_file_info_cache, uri_string); + + if (entry) { + DEBUG_HTTP (("Cache: Invalidate: '%s'", entry->uri_string)); + + http_cache_entry_free (entry); + } + + g_static_rec_mutex_unlock (&cache_rlock); +} + +void +http_cache_invalidate_uri (GnomeVFSURI *uri) +{ + gchar *uri_string; + + uri_string = http_cache_uri_to_string (uri); + + if (uri_string) { + http_cache_invalidate (uri_string); + } + + g_free (uri_string); +} + + +/* Invalidates entry and everything cached immediately beneath it */ +void +http_cache_invalidate_entry_and_children (const gchar * uri_string) +{ + FileInfoCacheEntry *entry; + + g_static_rec_mutex_lock (&cache_rlock); + + entry = (FileInfoCacheEntry *)g_hash_table_lookup (gl_file_info_cache, uri_string); + + if (entry) { + GList *node; + + DEBUG_HTTP (("Cache: Invalidate Recursive: '%s'", entry->uri_string)); + + for (node = entry->filenames ; node ; node = g_list_next (node) ) { + char *child_filename; + child_filename = g_strconcat (uri_string, "/", (gchar *)node->data, NULL); + http_cache_invalidate (child_filename); + g_free (child_filename); + } + + http_cache_entry_free (entry); + } + + g_static_rec_mutex_unlock (&cache_rlock); +} + +/* Invalidates entry and everything cached immediately beneath it */ +void +http_cache_invalidate_uri_and_children (GnomeVFSURI *uri) +{ + gchar * uri_string; + + uri_string = http_cache_uri_to_string (uri); + + if (uri_string) { + http_cache_invalidate_entry_and_children (uri_string); + } + + g_free (uri_string); +} + +/* Invalidate all of this uri's children and all of its parent's children */ +void +http_cache_invalidate_uri_parent (GnomeVFSURI *uri) +{ + gchar * uri_string; + gchar * last_slash; + + uri_string = http_cache_uri_to_string (uri); + + if (uri_string) { + http_cache_invalidate_entry_and_children (uri_string); + + last_slash = strrchr (uri_string, (unsigned char)'/'); + if (last_slash) { + *last_slash = 0; + http_cache_invalidate_entry_and_children (uri_string); + } + } + + g_free (uri_string); +} diff --git a/modules/http-cache.h b/modules/http-cache.h new file mode 100644 index 0000000..4bfeaee --- /dev/null +++ b/modules/http-cache.h @@ -0,0 +1,53 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* http-cache.c - Property caching for DAV + + Copyright (C) 2000-2001 Eazel, Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: + Michael Fleming +*/ + +#ifndef HTTP_CACHE_H +#define HTTP_CACHE_H + +#include +#include + +void http_cache_init (void); +void http_cache_shutdown (void); + +void http_cache_trim (void); +GnomeVFSFileInfo * http_cache_check (const gchar * uri_string); +GnomeVFSFileInfo * http_cache_check_uri (GnomeVFSURI *uri); +GnomeVFSFileInfo * http_cache_check_directory (const gchar * uri_string, + GList **p_child_file_info_list); +GnomeVFSFileInfo * http_cache_check_directory_uri (GnomeVFSURI *uri, + GList **p_child_file_info_list); +void http_cache_add_uri_and_children (GnomeVFSURI *uri, + GnomeVFSFileInfo *file_info, + GList *file_info_list); +void http_cache_add_uri (GnomeVFSURI *uri, + GnomeVFSFileInfo *file_info, + gboolean is_dav); +void http_cache_invalidate (const gchar *uri_string); +void http_cache_invalidate_uri (GnomeVFSURI *uri); +void http_cache_invalidate_entry_and_children (const gchar * uri_string); +void http_cache_invalidate_uri_and_children (GnomeVFSURI *uri); +void http_cache_invalidate_uri_parent (GnomeVFSURI *uri); + +#endif /* HTTP_CACHE_H */ diff --git a/modules/http-method.c b/modules/http-method.c new file mode 100644 index 0000000..c2b3dc7 --- /dev/null +++ b/modules/http-method.c @@ -0,0 +1,3195 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* http-method.c - The HTTP method implementation for the GNOME Virtual File + System. + + Copyright (C) 1999 Free Software Foundation + Copyright (C) 2000-2001 Eazel, Inc + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: + Ettore Perazzoli (core HTTP) + Ian McKellar (WebDAV/PUT) + Michael Fleming (Caching, Cleanup) + The friendly GNU Wget sources + */ + +/* TODO: + - Handle redirection. + - Handle persistent connections. */ + +#include +#include "http-method.h" + +#include "http-authn.h" +#include "http-cache.h" +/* Keep above any network includes for FreeBSD. */ +#include +/* Keep above for FreeBSD. */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* for atoi */ +#include +#include +#include +#include +#include + +#ifdef DEBUG_HTTP_ENABLE +void +http_debug_printf (char *fmt, ...) +{ + va_list args; + gchar * out; + + g_assert (fmt); + + va_start (args, fmt); + + out = g_strdup_vprintf (fmt, args); + + fprintf (stderr, "HTTP: [0x%08x] [%p] %s\n", + (unsigned int) http_util_get_utime (), + g_thread_self (), out); + + g_free (out); + va_end (args); +} +#endif /* DEBUG_HTTP_ENABLE */ + +/* What do we qualify ourselves as? */ +/* FIXME bugzilla.gnome.org 41160: "gnome-vfs/1.0.0" may not be good. */ +#define USER_AGENT_STRING "gnome-vfs/" VERSION + +/* Custom User-Agent environment variable */ +#define CUSTOM_USER_AGENT_VARIABLE "GNOME_VFS_HTTP_USER_AGENT" + +/* Standard HTTP[S] port. */ +#define DEFAULT_HTTP_PORT 80 +#define DEFAULT_HTTPS_PORT 443 + +/* Standard HTTP proxy port */ +#define DEFAULT_HTTP_PROXY_PORT 8080 + +/* GConf paths and keys */ +#define PATH_GCONF_GNOME_VFS "/system/http_proxy" +#define ITEM_GCONF_HTTP_PROXY_PORT "port" +#define ITEM_GCONF_HTTP_PROXY_HOST "host" +#define KEY_GCONF_HTTP_PROXY_PORT (PATH_GCONF_GNOME_VFS "/" ITEM_GCONF_HTTP_PROXY_PORT) +#define KEY_GCONF_HTTP_PROXY_HOST (PATH_GCONF_GNOME_VFS "/" ITEM_GCONF_HTTP_PROXY_HOST) + +#define ITEM_GCONF_USE_HTTP_PROXY "use_http_proxy" +#define KEY_GCONF_USE_HTTP_PROXY (PATH_GCONF_GNOME_VFS "/" ITEM_GCONF_USE_HTTP_PROXY) + +#define KEY_GCONF_HTTP_AUTH_USER (PATH_GCONF_GNOME_VFS "/" "authentication_user") +#define KEY_GCONF_HTTP_AUTH_PW (PATH_GCONF_GNOME_VFS "/" "authentication_password") +#define KEY_GCONF_HTTP_USE_AUTH (PATH_GCONF_GNOME_VFS "/" "use_authentication") + +#define KEY_GCONF_HTTP_PROXY_IGNORE_HOSTS (PATH_GCONF_GNOME_VFS "/" "ignore_hosts") + + +/* Some status code validation macros. */ +#define HTTP_20X(x) (((x) >= 200) && ((x) < 300)) +#define HTTP_PARTIAL(x) ((x) == HTTP_STATUS_PARTIAL_CONTENTS) +#define HTTP_REDIRECTED(x) (((x) == HTTP_STATUS_MOVED_PERMANENTLY) \ + || ((x) == HTTP_STATUS_MOVED_TEMPORARILY)) + +/* HTTP/1.1 status codes from RFC2068, provided for reference. */ +/* Successful 2xx. */ +#define HTTP_STATUS_OK 200 +#define HTTP_STATUS_CREATED 201 +#define HTTP_STATUS_ACCEPTED 202 +#define HTTP_STATUS_NON_AUTHORITATIVE 203 +#define HTTP_STATUS_NO_CONTENT 204 +#define HTTP_STATUS_RESET_CONTENT 205 +#define HTTP_STATUS_PARTIAL_CONTENTS 206 + +/* Redirection 3xx. */ +#define HTTP_STATUS_MULTIPLE_CHOICES 300 +#define HTTP_STATUS_MOVED_PERMANENTLY 301 +#define HTTP_STATUS_MOVED_TEMPORARILY 302 +#define HTTP_STATUS_SEE_OTHER 303 +#define HTTP_STATUS_NOT_MODIFIED 304 +#define HTTP_STATUS_USE_PROXY 305 + +/* Client error 4xx. */ +#define HTTP_STATUS_BAD_REQUEST 400 +#define HTTP_STATUS_UNAUTHORIZED 401 +#define HTTP_STATUS_PAYMENT_REQUIRED 402 +#define HTTP_STATUS_FORBIDDEN 403 +#define HTTP_STATUS_NOT_FOUND 404 +#define HTTP_STATUS_METHOD_NOT_ALLOWED 405 +#define HTTP_STATUS_NOT_ACCEPTABLE 406 +#define HTTP_STATUS_PROXY_AUTH_REQUIRED 407 +#define HTTP_STATUS_REQUEST_TIMEOUT 408 +#define HTTP_STATUS_CONFLICT 409 +#define HTTP_STATUS_GONE 410 +#define HTTP_STATUS_LENGTH_REQUIRED 411 +#define HTTP_STATUS_PRECONDITION_FAILED 412 +#define HTTP_STATUS_REQENTITY_TOO_LARGE 413 +#define HTTP_STATUS_REQURI_TOO_LARGE 414 +#define HTTP_STATUS_UNSUPPORTED_MEDIA 415 +#define HTTP_STATUS_LOCKED 423 + +/* Server errors 5xx. */ +#define HTTP_STATUS_INTERNAL 500 +#define HTTP_STATUS_NOT_IMPLEMENTED 501 +#define HTTP_STATUS_BAD_GATEWAY 502 +#define HTTP_STATUS_UNAVAILABLE 503 +#define HTTP_STATUS_GATEWAY_TIMEOUT 504 +#define HTTP_STATUS_UNSUPPORTED_VERSION 505 +#define HTTP_STATUS_INSUFFICIENT_STORAGE 507 + +/* + * Static Variables + */ + +/* Global variables used by the HTTP proxy config */ +static GConfClient * gl_client = NULL; +static GMutex *gl_mutex = NULL; /* This mutex protects preference values + * and ensures serialization of authentication + * hook callbacks + */ +static gchar *gl_http_proxy = NULL; +static gchar *gl_http_proxy_auth = NULL; +static GSList *gl_ignore_hosts = NULL; /* Elements are strings. */ +static GSList *gl_ignore_addrs = NULL; /* Elements are ProxyHostAddrs */ + +/* Store IP addresses that may represent network or host addresses and may be + * IPv4 or IPv6. */ +typedef enum { + PROXY_IPv4 = 4, + PROXY_IPv6 = 6 +} ProxyAddrType; + +typedef struct { + ProxyAddrType type; + struct in_addr addr; + struct in_addr mask; +#ifdef ENABLE_IPV6 + struct in6_addr addr6; + struct in6_addr mask6; +#endif +} ProxyHostAddr; + +typedef struct { + GnomeVFSSocketBuffer *socket_buffer; + char *uri_string; + GnomeVFSURI *uri; + /* The list of headers returned with this response, newlines removed */ + GList *response_headers; + + /* File info for this file */ + GnomeVFSFileInfo *file_info; + + /* Bytes read so far. */ + GnomeVFSFileSize bytes_read; + + /* Bytes to be written... */ + GByteArray *to_be_written; + + /* List of GnomeVFSFileInfo from a directory listing */ + GList *files; + + /* The last HTTP status code returned */ + guint server_status; +} HttpFileHandle; + +static GnomeVFSResult resolve_409 (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSContext *context); +static void proxy_set_authn (const char *username, + const char *password); +static void proxy_unset_authn (void); +static gboolean invoke_callback_send_additional_headers (GnomeVFSURI *uri, + GList **list); +static gboolean invoke_callback_headers_received (HttpFileHandle *handle); +static gboolean invoke_callback_basic_authn (HttpFileHandle *handle, + enum AuthnHeaderType authn_which, + gboolean previous_attempt_failed); +static gboolean check_authn_retry_request (HttpFileHandle * http_handle, + enum AuthnHeaderType authn_which, + const char *prev_authn_header); +static void parse_ignore_host (gpointer data, + gpointer user_data); +#ifdef ENABLE_IPV6 +static void ipv6_network_addr (const struct in6_addr *addr, + const struct in6_addr *mask, + struct in6_addr *res); + +/*Check whether the node is IPv6 enabled.*/ +static gboolean +have_ipv6 (void) +{ + int s; + + s = socket (AF_INET6, SOCK_STREAM, 0); + if (s != -1) { + close (s); + return TRUE; + } + + return FALSE; +} +#endif + +static GnomeVFSFileInfo * +defaults_file_info_new (void) +{ + GnomeVFSFileInfo *ret; + + /* Fill up the file info structure with default values */ + /* Default to REGULAR unless we find out later via a PROPFIND that it's a collection */ + + ret = gnome_vfs_file_info_new(); + + ret->type = GNOME_VFS_FILE_TYPE_REGULAR; + ret->flags = GNOME_VFS_FILE_FLAGS_NONE; + + ret->valid_fields |= + GNOME_VFS_FILE_INFO_FIELDS_TYPE + | GNOME_VFS_FILE_INFO_FIELDS_FLAGS; + + + return ret; +} + +static HttpFileHandle * +http_file_handle_new (GnomeVFSSocketBuffer *socket_buffer, + GnomeVFSURI *uri) +{ + HttpFileHandle *result; + + result = g_new0 (HttpFileHandle, 1); + + result->socket_buffer = socket_buffer; + result->uri_string = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE ); + result->uri = uri; + gnome_vfs_uri_ref(result->uri); + + result->file_info = defaults_file_info_new(); + result->file_info->name = gnome_vfs_uri_extract_short_name (uri); + + return result; +} + +static void +http_file_handle_destroy (HttpFileHandle *handle) +{ + if (handle == NULL) { + return; + } + + gnome_vfs_uri_unref(handle->uri); + gnome_vfs_file_info_unref (handle->file_info); + g_free (handle->uri_string); + if (handle->to_be_written) { + g_byte_array_free(handle->to_be_written, TRUE); + } + + g_list_foreach (handle->response_headers, (GFunc) g_free, NULL); + g_list_free (handle->response_headers); + + g_list_foreach(handle->files, (GFunc)gnome_vfs_file_info_unref, NULL); + g_list_free(handle->files); + + g_free (handle); +} + +/* The following comes from GNU Wget with minor changes by myself. + Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. */ +/* Parse the HTTP status line, which is of format: + + HTTP-Version SP Status-Code SP Reason-Phrase + + The function returns the status-code, or -1 if the status line is + malformed. The pointer to reason-phrase is returned in RP. */ +static gboolean +parse_status (const char *cline, + guint *status_return) +{ + /* (the variables must not be named `major' and `minor', because + that breaks compilation with SunOS4 cc.) */ + guint mjr, mnr; + guint statcode; + const guchar *p, *line; + + line = (const guchar *)cline; + + /* The standard format of HTTP-Version is: `HTTP/X.Y', where X is + major version, and Y is minor version. */ + if (strncmp (line, "HTTP/", 5) == 0) { + line += 5; + + /* Calculate major HTTP version. */ + p = line; + for (mjr = 0; g_ascii_isdigit (*line); line++) + mjr = 10 * mjr + (*line - '0'); + if (*line != '.' || p == line) + return FALSE; + ++line; + + /* Calculate minor HTTP version. */ + p = line; + for (mnr = 0; g_ascii_isdigit (*line); line++) + mnr = 10 * mnr + (*line - '0'); + if (*line != ' ' || p == line) + return -1; + /* Wget will accept only 1.0 and higher HTTP-versions. The value of + minor version can be safely ignored. */ + if (mjr < 1) + return FALSE; + ++line; + } else if (strncmp (line, "ICY ", 4) == 0) { + /* FIXME: workaround for broken ShoutCast and IceCast status replies. + * They send things like "ICY 200 OK" instead of "HTTP/1.0 200 OK". + * Is there a better way to handle this? + */ + mjr = 1; + mnr = 0; + line += 4; + } else { + return FALSE; + } + + /* Calculate status code. */ + if (!(g_ascii_isdigit (*line) && g_ascii_isdigit (line[1]) && g_ascii_isdigit (line[2]))) + return -1; + statcode = 100 * (*line - '0') + 10 * (line[1] - '0') + (line[2] - '0'); + + *status_return = statcode; + return TRUE; +} + +static GnomeVFSResult +http_status_to_vfs_result (guint status) +{ + if (HTTP_20X (status)) + return GNOME_VFS_OK; + + /* FIXME bugzilla.gnome.org 41163 */ + /* mfleming--I've improved the situation slightly, but more + * test cases need to be written to ensure that HTTP (esp DAV) does compatibile + * things with the normal file method + */ + + switch (status) { + case HTTP_STATUS_PRECONDITION_FAILED: + /* This mapping is certainly true for MOVE with Overwrite: F, otherwise not so true */ + return GNOME_VFS_ERROR_FILE_EXISTS; + case HTTP_STATUS_UNAUTHORIZED: + case HTTP_STATUS_PROXY_AUTH_REQUIRED: + case HTTP_STATUS_FORBIDDEN: + /* Note that FORBIDDEN can also be returned on a MOVE in a case which + * should be VFS_ERROR_BAD_PARAMETERS + */ + return GNOME_VFS_ERROR_ACCESS_DENIED; + case HTTP_STATUS_NOT_FOUND: + return GNOME_VFS_ERROR_NOT_FOUND; + case HTTP_STATUS_METHOD_NOT_ALLOWED: + /* Note that METHOD_NOT_ALLOWED is also returned in a PROPFIND in a case which + * should be FILE_EXISTS. This is handled in do_make_directory + */ + case HTTP_STATUS_BAD_REQUEST: + case HTTP_STATUS_NOT_IMPLEMENTED: + case HTTP_STATUS_UNSUPPORTED_VERSION: + return GNOME_VFS_ERROR_NOT_SUPPORTED; + case HTTP_STATUS_CONFLICT: + /* _CONFLICT's usually happen when collection paths don't exist */ + return GNOME_VFS_ERROR_NOT_FOUND; + case HTTP_STATUS_LOCKED: + /* Maybe we need a separate GNOME_VFS_ERROR_LOCKED? */ + return GNOME_VFS_ERROR_DIRECTORY_BUSY; + case HTTP_STATUS_INSUFFICIENT_STORAGE: + return GNOME_VFS_ERROR_NO_SPACE; + default: + return GNOME_VFS_ERROR_GENERIC; + } +} + +/* Header parsing routines. */ + +static gboolean +header_value_to_number (const char *header_value, + gulong *number) +{ + const char *p; + gulong result; + + p = header_value; + + for (result = 0; g_ascii_isdigit (*p); p++) + result = 10 * result + (*p - '0'); + if (*p) + return FALSE; + + *number = result; + + return TRUE; +} + +static gboolean +set_content_length (HttpFileHandle *handle, + const char *value) +{ + gboolean result; + gulong size; + + result = header_value_to_number (value, &size); + if (! result) + return FALSE; + + DEBUG_HTTP (("Expected size is %lu.", size)); + handle->file_info->size = size; + handle->file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_SIZE; + return TRUE; +} + +static char * +strip_semicolon (const char *value) +{ + char *p; + + p = strchr (value, ';'); + + if (p != NULL) { + return g_strndup (value, p - value); + } + else { + return g_strdup (value); + } +} + +static gboolean +set_content_type (HttpFileHandle *handle, + const char *value) +{ + g_free (handle->file_info->mime_type); + + handle->file_info->mime_type = strip_semicolon (value); + handle->file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + return TRUE; +} + +static gboolean +set_last_modified (HttpFileHandle *handle, + const char *value) +{ + time_t time; + + if (! gnome_vfs_atotm (value, &time)) + return FALSE; + + handle->file_info->mtime = time; + handle->file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MTIME; + return TRUE; +} + +static gboolean +set_access_time (HttpFileHandle *handle, + const char *value) +{ + time_t time; + + if (! gnome_vfs_atotm (value, &time)) + return FALSE; + + handle->file_info->atime = time; + handle->file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_ATIME; + return TRUE; +} + +struct _Header { + const char *name; + gboolean (* set_func) (HttpFileHandle *handle, const char *value); +}; +typedef struct _Header Header; + +static Header headers[] = { + { "Content-Length", set_content_length }, + { "Content-Type", set_content_type }, + { "Last-Modified", set_last_modified }, + { "Date", set_access_time }, + { NULL, NULL } +}; + +static const char * +check_header (const char *header, + const char *name) +{ + const char *p, *q; + + for (p = header, q = name; *p != '\0' && *q != '\0'; p++, q++) { + if (g_ascii_tolower (*p) != g_ascii_tolower (*q)) + break; + } + + if (*q != '\0' || *p != ':') + return NULL; + + p++; /* Skip ':'. */ + while (*p == ' ' || *p == '\t') + p++; + + return p; +} + +static gboolean +parse_header (HttpFileHandle *handle, + const char *header) +{ + guint i; + + for (i = 0; headers[i].name != NULL; i++) { + const char *value; + + value = check_header (header, headers[i].name); + if (value != NULL) + return (* headers[i].set_func) (handle, value); + } + + /* Simply ignore headers we don't know. */ + return TRUE; +} + +/* Header/status reading. */ + +static GnomeVFSResult +get_header (GnomeVFSSocketBuffer *socket_buffer, + GString *s) +{ + GnomeVFSResult result; + GnomeVFSFileSize bytes_read; + guint count; + + ANALYZE_HTTP ("==> +get_header"); + + g_string_truncate (s, 0); + + count = 0; + while (1) { + char c; + + /* ANALYZE_HTTP ("==> +get_header read"); */ + result = gnome_vfs_socket_buffer_read (socket_buffer, &c, 1, + &bytes_read); + /* ANALYZE_HTTP ("==> -get_header read"); */ + + if (result != GNOME_VFS_OK) { + return result; + } + if (bytes_read == 0) { + return GNOME_VFS_ERROR_EOF; + } + + if (c == '\n') { + /* Handle continuation lines. */ + if (count != 0 && (count != 1 || s->str[0] != '\r')) { + char next; + + result = gnome_vfs_socket_buffer_peekc ( + socket_buffer, &next); + if (result != GNOME_VFS_OK) { + return result; + } + + if (next == '\t' || next == ' ') { + if (count > 0 + && s->str[count - 1] == '\r') + s->str[count - 1] = '\0'; + continue; + } + } + + if (count > 0 && s->str[count - 1] == '\r') + s->str[count - 1] = '\0'; + break; + } else { + g_string_append_c (s, c); + } + + count++; + } + + + ANALYZE_HTTP ("==> -get_header"); + + return GNOME_VFS_OK; +} + +/* rename this function? */ +static GnomeVFSResult +create_handle (GnomeVFSURI *uri, + GnomeVFSSocketBuffer *socket_buffer, + GnomeVFSContext *context, + /* OUT */ HttpFileHandle **p_handle) +{ + GString *header_string; + GnomeVFSResult result; + guint server_status; + + g_return_val_if_fail (p_handle != NULL, GNOME_VFS_ERROR_INTERNAL); + + *p_handle = http_file_handle_new (socket_buffer, uri); + + header_string = g_string_new (NULL); + + ANALYZE_HTTP ("==> +create_handle"); + + /* This is the status report string, which is the first header. */ + result = get_header (socket_buffer, header_string); + if (result != GNOME_VFS_OK) { + goto error; + } + + if (!parse_status (header_string->str, &server_status)) { + /* An unparsable status line is fatal */ + result = GNOME_VFS_ERROR_GENERIC; + goto error; + } + + (*p_handle)->server_status = server_status; + + ANALYZE_HTTP ("==> +create_handle: fetching headers"); + + /* Header fetching loop. */ + for (;;) { + result = get_header (socket_buffer, header_string); + if (result != GNOME_VFS_OK) { + break; + } + + /* Empty header ends header section. */ + if (header_string->str[0] == '\0') { + break; + } + + (*p_handle)->response_headers = g_list_prepend ((*p_handle)->response_headers, + g_strdup (header_string->str)); + + /* We don't really care if we successfully parse the + * header or not. It might be nice to tell someone we + * found a header we can't parse, but it's not clear + * who would be interested or how we tell them. In the + * past we would return NOT_FOUND if any header could + * not be parsed, but that seems wrong. + */ + parse_header (*p_handle, header_string->str); + } + + invoke_callback_headers_received (*p_handle); + + ANALYZE_HTTP ("==> -create_handle: fetching headers"); + + if (result != GNOME_VFS_OK) { + goto error; + } + + if (! HTTP_20X (server_status) && !HTTP_REDIRECTED(server_status)) { + result = http_status_to_vfs_result (server_status); + goto error; + } + + result = GNOME_VFS_OK; + error: + g_string_free (header_string, TRUE); + + ANALYZE_HTTP ("==> -create_handle"); + return result; +} + +/* + * Here's how the gconf gnome-vfs HTTP proxy variables + * are intended to be used + * + * /system/http_proxy/use_http_proxy + * Type: boolean + * If set to TRUE, the client should use an HTTP proxy to connect to all + * servers (except those specified in the ignore_hosts key -- see below). + * The proxy is specified in other gconf variables below. + * + * /system/http_proxy/host + * Type: string + * The hostname of the HTTP proxy this client should use. If + * use-http-proxy is TRUE, this should be set. If it is not set, the + * application should behave as if use-http-proxy is was set to FALSE. + * + * /system/http_proxy/port + * Type: int + * The port number on the HTTP proxy host that the client should connect to + * If use_http_proxy and host are set but this is not set, the application + * should use a default port value of 8080 + * + * /system/http_proxy/authentication-user + * Type: string + * Username to pass to an authenticating HTTP proxy. + * + * /system/http_proxy/authentication_password + * Type: string + * Password to pass to an authenticating HTTP proxy. + * + * /system/http_proxy/use-authentication + * Type: boolean + * TRUE if the client should pass http-proxy-authorization-user and + * http-proxy-authorization-password an HTTP proxy + * + * /system/http_proxy/ignore_hosts + * Type: list of strings + * A list of hosts (hostnames, wildcard domains, IP addresses, and CIDR + * network addresses) that should be accessed directly. + */ + +static void +construct_gl_http_proxy (gboolean use_proxy) +{ + g_free (gl_http_proxy); + gl_http_proxy = NULL; + + g_slist_foreach (gl_ignore_hosts, (GFunc) g_free, NULL); + g_slist_free (gl_ignore_hosts); + gl_ignore_hosts = NULL; + g_slist_foreach (gl_ignore_addrs, (GFunc) g_free, NULL); + g_slist_free (gl_ignore_addrs); + gl_ignore_addrs = NULL; + + if (use_proxy) { + char *proxy_host; + int proxy_port; + GSList *ignore; + + proxy_host = gconf_client_get_string (gl_client, KEY_GCONF_HTTP_PROXY_HOST, NULL); + proxy_port = gconf_client_get_int (gl_client, KEY_GCONF_HTTP_PROXY_PORT, NULL); + + if (proxy_host) { + if (0 != proxy_port && 0xffff >= (unsigned) proxy_port) { + gl_http_proxy = g_strdup_printf ("%s:%u", proxy_host, (unsigned)proxy_port); + } else { + gl_http_proxy = g_strdup_printf ("%s:%u", proxy_host, (unsigned)DEFAULT_HTTP_PROXY_PORT); + } + DEBUG_HTTP (("New HTTP proxy: '%s'", gl_http_proxy)); + } else { + DEBUG_HTTP (("HTTP proxy unset")); + } + + g_free (proxy_host); + proxy_host = NULL; + + ignore = gconf_client_get_list (gl_client, KEY_GCONF_HTTP_PROXY_IGNORE_HOSTS, GCONF_VALUE_STRING, NULL); + g_slist_foreach (ignore, (GFunc) parse_ignore_host, NULL); + g_slist_foreach (ignore, (GFunc) g_free, NULL); + g_slist_free (ignore); + ignore = NULL; + } +} + +static void +parse_ignore_host (gpointer data, gpointer user_data) +{ + gchar *hostname, *input, *netmask; + gboolean ip_addr = FALSE, has_error = FALSE; + struct in_addr host, mask; +#ifdef ENABLE_IPV6 + struct in6_addr host6, mask6; +#endif + ProxyHostAddr *elt; + gint i; + + input = (gchar*) data; + elt = g_new0 (ProxyHostAddr, 1); + if ((netmask = strchr (input, '/')) != NULL) { + hostname = g_strndup (input, netmask - input); + ++netmask; + } + else { + hostname = g_ascii_strdown (input, -1); + } + if (inet_pton (AF_INET, hostname, &host) > 0) { + ip_addr = TRUE; + elt->type = PROXY_IPv4; + elt->addr.s_addr = host.s_addr; + if (netmask) { + gchar *endptr; + gint width = strtol (netmask, &endptr, 10); + + if (*endptr != '\0' || width < 0 || width > 32) { + has_error = TRUE; + } + elt->mask.s_addr = htonl(~0 << width); + elt->addr.s_addr &= mask.s_addr; + } + else { + elt->mask.s_addr = 0xffffffff; + } + } +#ifdef ENABLE_IPV6 + else if (have_ipv6 () && inet_pton (AF_INET6, hostname, &host6) > 0) { + ip_addr = TRUE; + elt->type = PROXY_IPv6; + for (i = 0; i < 16; ++i) { + elt->addr6.s6_addr[i] = host6.s6_addr[i]; + } + if (netmask) { + gchar *endptr; + gint width = strtol (netmask, &endptr, 10); + + if (*endptr != '\0' || width < 0 || width > 128) { + has_error = TRUE; + } + for (i = 0; i < 16; ++i) { + elt->mask6.s6_addr[i] = 0; + } + for (i=0; i < width/8; i++) { + elt->mask6.s6_addr[i] = 0xff; + } + elt->mask6.s6_addr[i] = (0xff << (8 - width % 8)) & 0xff; + ipv6_network_addr (&elt->addr6, &mask6, &elt->addr6); + } + else { + for (i = 0; i < 16; ++i) { + elt->mask6.s6_addr[i] = 0xff; + } + } + } +#endif + + if (ip_addr) { + if (!has_error) { + gchar *dst = g_new0 (gchar, INET_ADDRSTRLEN); + + gl_ignore_addrs = g_slist_append (gl_ignore_addrs, elt); + DEBUG_HTTP (("Host %s/%s does not go through proxy.", + hostname, + inet_ntop(AF_INET, &elt->mask, dst, INET_ADDRSTRLEN))); + g_free (dst); + } + } + else { + /* It is a hostname. */ + gl_ignore_hosts = g_slist_append (gl_ignore_hosts, hostname); + DEBUG_HTTP (("Host %s does not go through proxy.", hostname)); + } +} + +static void +set_proxy_auth (gboolean use_proxy_auth) +{ + char *auth_user; + char *auth_pw; + + auth_user = gconf_client_get_string (gl_client, KEY_GCONF_HTTP_AUTH_USER, NULL); + auth_pw = gconf_client_get_string (gl_client, KEY_GCONF_HTTP_AUTH_PW, NULL); + + if (use_proxy_auth) { + proxy_set_authn (auth_user, auth_pw); + DEBUG_HTTP (("New HTTP proxy auth user: '%s'", auth_user)); + } else { + proxy_unset_authn (); + DEBUG_HTTP (("HTTP proxy auth unset")); + } + + g_free (auth_user); + g_free (auth_pw); +} + +/** + * sig_gconf_value_changed + * GGconf notify function for when HTTP proxy GConf key has changed. + */ +static void +notify_gconf_value_changed (GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + gpointer data) +{ + const char *key; + + key = gconf_entry_get_key (entry); + + if (strcmp (key, KEY_GCONF_USE_HTTP_PROXY) == 0 + || strcmp (key, KEY_GCONF_HTTP_PROXY_IGNORE_HOSTS) == 0 + || strcmp (key, KEY_GCONF_HTTP_PROXY_HOST) == 0 + || strcmp (key, KEY_GCONF_HTTP_PROXY_PORT) == 0) { + gboolean use_proxy_value; + + g_mutex_lock (gl_mutex); + + /* Check and see if we are using the proxy */ + use_proxy_value = gconf_client_get_bool (gl_client, KEY_GCONF_USE_HTTP_PROXY, NULL); + construct_gl_http_proxy (use_proxy_value); + + g_mutex_unlock (gl_mutex); + } else if (strcmp (key, KEY_GCONF_HTTP_AUTH_USER) == 0 + || strcmp (key, KEY_GCONF_HTTP_AUTH_PW) == 0 + || strcmp (key, KEY_GCONF_HTTP_USE_AUTH) == 0) { + gboolean use_proxy_auth; + + g_mutex_lock (gl_mutex); + + use_proxy_auth = gconf_client_get_bool (gl_client, KEY_GCONF_HTTP_USE_AUTH, NULL); + set_proxy_auth (use_proxy_auth); + + g_mutex_unlock (gl_mutex); + } +} + +/** + * host_port_from_string + * splits a : formatted string into its separate components + */ +static gboolean +host_port_from_string (const char *http_proxy, + char **p_proxy_host, + guint *p_proxy_port) +{ + char *port_part; + + port_part = strchr (http_proxy, ':'); + + if (port_part && '\0' != ++port_part && p_proxy_port) { + *p_proxy_port = (guint) strtoul (port_part, NULL, 10); + } else if (p_proxy_port) { + *p_proxy_port = DEFAULT_HTTP_PROXY_PORT; + } + + if (p_proxy_host) { + if ( port_part != http_proxy ) { + *p_proxy_host = g_strndup (http_proxy, port_part - http_proxy - 1); + } else { + return FALSE; + } + } + + return TRUE; +} + +/* FIXME: should be done using AC_REPLACE_FUNCS */ +#ifndef HAVE_INET_PTON +static int +inet_pton(int af, const char *hostname, void *pton) +{ + struct in_addr in; + if (!inet_aton(hostname, &in)) + return 0; + memcpy(pton, &in, sizeof(in)); + return 1; +} +#endif + +#ifdef ENABLE_IPV6 +static void +ipv6_network_addr (const struct in6_addr *addr, const struct in6_addr *mask, struct in6_addr *res) +{ + gint i; + + for (i = 0; i < 16; ++i) { + res->s6_addr[i] = addr->s6_addr[i] & mask->s6_addr[i]; + } +} +#endif + +static gboolean +proxy_should_for_hostname (const char *hostname) +{ +#ifdef ENABLE_IPV6 + struct in6_addr in6, net6; +#endif + struct in_addr in; + GSList *elt; + ProxyHostAddr *addr; + + + /* IPv4 address */ + if (inet_pton (AF_INET, hostname, &in) > 0) { + for (elt = gl_ignore_addrs; elt; elt = g_slist_next (elt)) { + addr = (ProxyHostAddr*) (elt->data); + if (addr->type == PROXY_IPv4 + && (in.s_addr & addr->mask.s_addr) == addr->addr.s_addr) { + DEBUG_HTTP (("Host %s using direct connection.", hostname)); + return FALSE; + } + } + } +#ifdef ENABLE_IPV6 + else if (have_ipv6 () && inet_pton (AF_INET6, hostname, &in6)) { + for (elt = gl_ignore_addrs; elt; elt = g_slist_next (elt)) { + addr = (ProxyHostAddr*) (elt->data); + ipv6_network_addr (&in6, &addr->mask6, &net6); + if (addr->type == PROXY_IPv6 + && IN6_ARE_ADDR_EQUAL (&net6, &addr->addr6)) { + DEBUG_HTTP (("Host %s using direct connection.", hostname)); + return FALSE; + } + /* Handle IPv6-wrapped IPv4 addresses. */ + else if (addr->type == PROXY_IPv4 + && IN6_IS_ADDR_V4MAPPED (&net6)) { + guint32 v4addr; + + v4addr = net6.s6_addr[12] << 24 | net6.s6_addr[13] << 16 | net6.s6_addr[14] << 8 | net6.s6_addr[15]; + if ((v4addr & addr->mask.s_addr) != addr->addr.s_addr) { + DEBUG_HTTP (("Host %s using direct connection.", hostname)); + return FALSE; + } + } + } + } +#endif + /* All hostnames (foo.bar.com) -- independent of IPv4 or IPv6 */ + + /* If there are IPv6 addresses in the ignore_hosts list but we do not + * have IPv6 available at runtime, then those addresses will also fall + * through to here (and harmlessly fail to match). */ + else { + gchar *hn = g_ascii_strdown (hostname, -1); + + for (elt = gl_ignore_hosts; elt; elt = g_slist_next (elt)) { + if (*(gchar*) (elt->data) == '*' ) { + if (g_str_has_suffix (hn, + (gchar*) (elt->data) + 1)) { + DEBUG_HTTP (("Host %s using direct connection.", hn)); + g_free (hn); + return FALSE; + } + } + else if (strcmp (hn, elt->data) == 0) { + DEBUG_HTTP (("Host %s using direct connection.", hn)); + g_free (hn); + return FALSE; + } + } + } + + return TRUE; +} + +static char * +proxy_get_authn_header_for_uri_nolock (GnomeVFSURI * uri) +{ + char * ret; + + ret = NULL; + + /* FIXME this needs to be atomic */ + if (gl_http_proxy_auth != NULL) { + ret = g_strdup_printf ("Proxy-Authorization: Basic %s\r\n", gl_http_proxy_auth); + } + + return ret; +} + +static char * +proxy_get_authn_header_for_uri (GnomeVFSURI * uri) +{ + char * ret; + + g_mutex_lock (gl_mutex); + + ret = proxy_get_authn_header_for_uri_nolock (uri); + + g_mutex_unlock (gl_mutex); + + return ret; +} + +/** + * proxy_for_uri + * Retrives an appropriate HTTP proxy for a given toplevel uri + * Currently, only a single HTTP proxy is implemented (there's no way for + * specifying non-proxy domain names's). Returns FALSE if the connect should + * take place directly + */ +static gboolean +proxy_for_uri ( + GnomeVFSToplevelURI * toplevel_uri, + gchar **p_proxy_host, /* Callee must free */ + guint *p_proxy_port) /* Callee must free */ +{ + gboolean ret; + + ret = proxy_should_for_hostname (toplevel_uri->host_name); + + g_mutex_lock (gl_mutex); + + if (ret && gl_http_proxy != NULL) { + ret = host_port_from_string (gl_http_proxy, p_proxy_host, p_proxy_port); + } else { + p_proxy_host = NULL; + p_proxy_port = NULL; + ret = FALSE; + } + + g_mutex_unlock (gl_mutex); + + return ret; +} + +static void +proxy_set_authn (const char *username, const char *password) +{ + char * credentials; + + g_free (gl_http_proxy_auth); + gl_http_proxy_auth = NULL; + + credentials = g_strdup_printf ("%s:%s", + username == NULL ? "" : username, + password == NULL ? "" : password); + + gl_http_proxy_auth = http_util_base64 (credentials); + + g_free (credentials); +} + +static void +proxy_unset_authn (void) +{ + g_free (gl_http_proxy_auth); + gl_http_proxy_auth = NULL; +} + + +static GnomeVFSResult +https_proxy (GnomeVFSSocket **socket_return, + gchar *proxy_host, + gint proxy_port, + gchar *server_host, + gint server_port) +{ + /* use CONNECT to do https proxying. It goes something like this: + * >CONNECT server:port HTTP/1.0 + * > + * uri), + "https")) { + if (!gnome_vfs_ssl_enabled ()) { + return GNOME_VFS_ERROR_NOT_SUPPORTED; + } + https = TRUE; + } + + if (toplevel_uri->host_port == 0) { + if (https) { + host_port = DEFAULT_HTTPS_PORT; + } else { + host_port = DEFAULT_HTTP_PORT; + } + } else { + host_port = toplevel_uri->host_port; + } + + ANALYZE_HTTP ("==> +Making connection"); + + if (toplevel_uri->host_name == NULL) { + result = GNOME_VFS_ERROR_INVALID_URI; + goto error; + } + + if (proxy_for_uri (toplevel_uri, &proxy_host, &proxy_port)) { + if (https) { + *p_proxy_connect = FALSE; + + result = https_proxy (&socket, proxy_host, proxy_port, + toplevel_uri->host_name, host_port); + + g_free (proxy_host); + proxy_host = NULL; + + if (result != GNOME_VFS_OK) { + return result; + } + + } else { + *p_proxy_connect = TRUE; + + result = gnome_vfs_inet_connection_create (&connection, + proxy_host, + proxy_port, + cancellation); + if (result != GNOME_VFS_OK) { + return result; + } + socket = gnome_vfs_inet_connection_to_socket + (connection); + + g_free (proxy_host); + proxy_host = NULL; + } + } else { + *p_proxy_connect = FALSE; + + if (https) { + result = gnome_vfs_ssl_create (&ssl, + toplevel_uri->host_name, host_port); + + if (result != GNOME_VFS_OK) { + return result; + } + socket = gnome_vfs_ssl_to_socket (ssl); + } else { + result = gnome_vfs_inet_connection_create (&connection, + toplevel_uri->host_name, + host_port, + cancellation); + if (result != GNOME_VFS_OK) { + return result; + } + socket = gnome_vfs_inet_connection_to_socket + (connection); + } + } + + *p_socket_buffer = gnome_vfs_socket_buffer_new (socket); + + if (*p_socket_buffer == NULL) { + gnome_vfs_socket_close (socket); + return GNOME_VFS_ERROR_INTERNAL; + } + + ANALYZE_HTTP ("==> -Making connection"); + +error: + return result; +} + +static GString * +build_request (const char * method, GnomeVFSToplevelURI * toplevel_uri, gboolean proxy_connect) +{ + gchar *uri_string = NULL; + GString *request; + GnomeVFSURI *uri; + gchar *user_agent; + + uri = (GnomeVFSURI *)toplevel_uri; + + if (proxy_connect) { + uri_string = gnome_vfs_uri_to_string (uri, + GNOME_VFS_URI_HIDE_USER_NAME + | GNOME_VFS_URI_HIDE_PASSWORD); + + } else { + uri_string = gnome_vfs_uri_to_string (uri, + GNOME_VFS_URI_HIDE_USER_NAME + | GNOME_VFS_URI_HIDE_PASSWORD + | GNOME_VFS_URI_HIDE_HOST_NAME + | GNOME_VFS_URI_HIDE_HOST_PORT + | GNOME_VFS_URI_HIDE_TOPLEVEL_METHOD); + } + + /* Request line. */ + request = g_string_new (""); + + g_string_append_printf (request, "%s %s%s HTTP/1.0\r\n", method, uri_string, + gnome_vfs_uri_get_path (uri)[0] == '\0' ? "/" : "" ); + + DEBUG_HTTP (("-->Making request '%s %s'", method, uri_string)); + + g_free (uri_string); + uri_string = NULL; + + /* `Host:' header. */ + if(toplevel_uri->host_port && toplevel_uri->host_port != 0) { + g_string_append_printf (request, "Host: %s:%d\r\n", + toplevel_uri->host_name, toplevel_uri->host_port); + } else { + g_string_append_printf (request, "Host: %s:80\r\n", + toplevel_uri->host_name); + } + + /* `Accept:' header. */ + g_string_append (request, "Accept: */*\r\n"); + + /* `User-Agent:' header. */ + user_agent = getenv (CUSTOM_USER_AGENT_VARIABLE); + + if(user_agent == NULL) { + user_agent = USER_AGENT_STRING; + } + + g_string_append_printf (request, "User-Agent: %s\r\n", user_agent); + + return request; +} + +static GnomeVFSResult +xmit_request (GnomeVFSSocketBuffer *socket_buffer, + GString *request, + GByteArray *data) +{ + GnomeVFSResult result; + GnomeVFSFileSize bytes_written; + + ANALYZE_HTTP ("==> Writing request and header"); + + /* Transmit the request headers. */ + result = gnome_vfs_socket_buffer_write (socket_buffer, request->str, + request->len, &bytes_written); + + if (result != GNOME_VFS_OK) { + goto error; + } + + /* Transmit the body */ + if(data && data->data) { + ANALYZE_HTTP ("==> Writing data"); + + result = gnome_vfs_socket_buffer_write (socket_buffer, + data->data, data->len, &bytes_written); + } + + if (result != GNOME_VFS_OK) { + goto error; + } + + result = gnome_vfs_socket_buffer_flush (socket_buffer); + +error: + return result; +} + +static GnomeVFSResult +make_request (HttpFileHandle **handle_return, + GnomeVFSURI *uri, + const gchar *method, + GByteArray *data, + gchar *extra_headers, + GnomeVFSContext *context) +{ + GnomeVFSSocketBuffer *socket_buffer; + GnomeVFSResult result; + GnomeVFSToplevelURI *toplevel_uri; + GString *request; + gboolean proxy_connect; + char *authn_header_request; + char *authn_header_proxy; + + g_return_val_if_fail (handle_return != NULL, GNOME_VFS_ERROR_INTERNAL); + *handle_return = NULL; + + ANALYZE_HTTP ("==> +make_request"); + + request = NULL; + proxy_connect = FALSE; + authn_header_request = NULL; + authn_header_proxy = NULL; + + toplevel_uri = (GnomeVFSToplevelURI *) uri; + + for (;;) { + GList *list; + + g_free (authn_header_request); + g_free (authn_header_proxy); + + socket_buffer = NULL; + result = connect_to_uri (toplevel_uri, &socket_buffer, + &proxy_connect); + + if (result != GNOME_VFS_OK) { + break; + } + + request = build_request (method, toplevel_uri, proxy_connect); + + authn_header_request = http_authn_get_header_for_uri (uri); + + if (authn_header_request != NULL) { + g_string_append (request, authn_header_request); + } + + if (proxy_connect) { + authn_header_proxy = proxy_get_authn_header_for_uri (uri); + + if (authn_header_proxy != NULL) { + g_string_append (request, authn_header_proxy); + } + } + + /* `Content-Length' header. */ + if (data != NULL) { + g_string_append_printf (request, "Content-Length: %d\r\n", data->len); + } + + /* Extra headers. */ + if (extra_headers != NULL) { + g_string_append (request, extra_headers); + } + + /* Extra headers from user */ + list = NULL; + + if (invoke_callback_send_additional_headers (uri, &list)) { + GList *i; + + for (i = list; i; i = i->next) { + g_string_append (request, i->data); + g_free (i->data); + i->data = NULL; + } + + g_list_free (list); + } + + /* Empty line ends header section. */ + g_string_append (request, "\r\n"); + + result = xmit_request (socket_buffer, request, data); + g_string_free (request, TRUE); + request = NULL; + + if (result != GNOME_VFS_OK) { + break; + } + + /* Read the headers and create our internal HTTP file handle. */ + result = create_handle (uri, socket_buffer, context, handle_return); + + if (result == GNOME_VFS_OK) { + socket_buffer = NULL; + break; + } + if ((*handle_return)->server_status == HTTP_STATUS_UNAUTHORIZED) { + if (! check_authn_retry_request (*handle_return, AuthnHeader_WWW, authn_header_request)) { + break; + } + } else if ((*handle_return)->server_status == HTTP_STATUS_PROXY_AUTH_REQUIRED) { + if (! check_authn_retry_request (*handle_return, AuthnHeader_WWW, authn_header_proxy)) { + break; + } + } else { + break; + } + http_file_handle_destroy (*handle_return); + *handle_return = NULL; + } + + g_free (authn_header_request); + g_free (authn_header_proxy); + + if (result != GNOME_VFS_OK && *handle_return != NULL) { + http_file_handle_destroy (*handle_return); + *handle_return = NULL; + } + + if (request != NULL) { + g_string_free (request, TRUE); + } + + if (socket_buffer != NULL) { + gnome_vfs_socket_buffer_destroy (socket_buffer, TRUE); + } + + ANALYZE_HTTP ("==> -make_request"); + return result; +} + +static void +http_handle_close (HttpFileHandle *handle, + GnomeVFSContext *context) +{ + ANALYZE_HTTP ("==> +http_handle_close"); + + if (handle != NULL) { + if (handle->socket_buffer) { + gnome_vfs_socket_buffer_flush (handle->socket_buffer); + gnome_vfs_socket_buffer_destroy (handle->socket_buffer, + TRUE); + handle->socket_buffer = NULL; + } + + http_file_handle_destroy (handle); + } + + ANALYZE_HTTP ("==> -http_handle_close"); +} + +static GnomeVFSResult +do_open (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + GnomeVFSContext *context) +{ + HttpFileHandle *handle; + GnomeVFSResult result = GNOME_VFS_OK; + + g_return_val_if_fail (uri->parent == NULL, GNOME_VFS_ERROR_INVALID_URI); + g_return_val_if_fail (!(mode & GNOME_VFS_OPEN_READ && + mode & GNOME_VFS_OPEN_WRITE), + GNOME_VFS_ERROR_INVALID_OPEN_MODE); + + ANALYZE_HTTP ("==> +do_open"); + DEBUG_HTTP (("+Open URI: '%s' mode:'%c'", gnome_vfs_uri_to_string(uri, 0), + mode & GNOME_VFS_OPEN_READ ? 'R' : 'W')); + + if (mode & GNOME_VFS_OPEN_READ) { + result = make_request (&handle, uri, "GET", NULL, NULL, + context); + } else { + handle = http_file_handle_new(NULL, uri); /* shrug */ + } + if (result == GNOME_VFS_OK) { + *method_handle = (GnomeVFSMethodHandle *) handle; + } else { + *method_handle = NULL; + } + + DEBUG_HTTP (("-Open (%d) handle:0x%08x", result, (unsigned int)handle)); + ANALYZE_HTTP ("==> -do_open"); + + return result; +} + +static GnomeVFSResult +do_create (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + gboolean exclusive, + guint perm, + GnomeVFSContext *context) +{ + /* try to write a zero length file - this appears to be the + * only reliable way of testing if a put will succeed. + * Xythos can apparently tell us if we have write permission by + * playing with LOCK, but mod_dav cannot. */ + HttpFileHandle *handle; + GnomeVFSResult result; + GByteArray *bytes = g_byte_array_new(); + + ANALYZE_HTTP ("==> +do_create"); + DEBUG_HTTP (("+Create URI: '%s'", gnome_vfs_uri_get_path (uri))); + + http_cache_invalidate_uri_parent (uri); + + /* Don't ignore exclusive; it should check first whether + the file exists, since the http protocol default is to + overwrite by default */ + /* FIXME we've stopped using HEAD -- we should use GET instead */ + /* FIXME we should check the cache here */ + if (exclusive) { + + ANALYZE_HTTP ("==> Checking to see if file exists"); + + result = make_request (&handle, uri, "HEAD", NULL, NULL, + context); + http_handle_close (handle, context); + + if (result != GNOME_VFS_OK && + result != GNOME_VFS_ERROR_NOT_FOUND) { + return result; + } + if (result == GNOME_VFS_OK) { + return GNOME_VFS_ERROR_FILE_EXISTS; + } + } + + ANALYZE_HTTP ("==> Creating initial file"); + + result = make_request (&handle, uri, "PUT", bytes, NULL, context); + http_handle_close(handle, context); + + if (result != GNOME_VFS_OK) { + /* the PUT failed */ + + /* FIXME bugzilla.gnome.org 45131 + * If you PUT a file with an invalid name to Xythos, it + * returns a 403 Forbidden, which is different from the behaviour + * in MKCOL or MOVE. Unfortunately, it is not possible to discern whether + * that 403 Forbidden is being returned because of invalid characters in the name + * or because of permissions problems + */ + + if (result == GNOME_VFS_ERROR_NOT_FOUND) { + result = resolve_409 (method, uri, context); + } + + return result; + } + + /* clean up */ + g_byte_array_free (bytes, TRUE); + + /* FIXME bugzilla.gnome.org 41159: do we need to do something more intelligent here? */ + result = do_open (method, method_handle, uri, GNOME_VFS_OPEN_WRITE, context); + + DEBUG_HTTP (("-Create (%d) handle:0x%08x", result, (unsigned int)handle)); + ANALYZE_HTTP ("==> -do_create"); + + return result; +} + +static GnomeVFSResult +do_close (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + HttpFileHandle *old_handle; + HttpFileHandle *new_handle; + GnomeVFSResult result; + + ANALYZE_HTTP ("==> +do_close"); + DEBUG_HTTP (("+Close handle:0x%08x", (unsigned int)method_handle)); + + old_handle = (HttpFileHandle *) method_handle; + + /* if the handle was opened in write mode then: + * 1) there won't be a connection open, and + * 2) there will be data to_be_written... + */ + if (old_handle->to_be_written != NULL) { + GnomeVFSURI *uri = old_handle->uri; + GByteArray *bytes = old_handle->to_be_written; + GnomeVFSMimeSniffBuffer *sniff_buffer; + char *extraheader = NULL; + const char *mime_type = NULL; + + sniff_buffer = + gnome_vfs_mime_sniff_buffer_new_from_existing_data (bytes->data, + bytes->len); + + if (sniff_buffer != NULL) { + mime_type = + gnome_vfs_get_mime_type_for_buffer ( + sniff_buffer); + if (mime_type != NULL) { + extraheader = g_strdup_printf( + "Content-type: %s\r\n", + mime_type); + } + gnome_vfs_mime_sniff_buffer_free (sniff_buffer); + + } + + http_cache_invalidate_uri (uri); + + ANALYZE_HTTP ("==> doing PUT"); + result = make_request (&new_handle, uri, "PUT", bytes, + extraheader, context); + g_free (extraheader); + http_handle_close (new_handle, context); + } else { + result = GNOME_VFS_OK; + } + + http_handle_close (old_handle, context); + + DEBUG_HTTP (("-Close (%d)", result)); + ANALYZE_HTTP ("==> -do_close"); + + return result; +} + +static GnomeVFSResult +do_write (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gconstpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read, + GnomeVFSContext *context) +{ + HttpFileHandle *handle; + + DEBUG_HTTP (("+Write handle:0x%08x", (unsigned int)method_handle)); + + handle = (HttpFileHandle *) method_handle; + + if(handle->to_be_written == NULL) { + handle->to_be_written = g_byte_array_new(); + } + handle->to_be_written = g_byte_array_append(handle->to_be_written, buffer, num_bytes); + *bytes_read = num_bytes; + + DEBUG_HTTP (("-Write (0)")); + + return GNOME_VFS_OK; +} + + +static GnomeVFSResult +do_read (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read, + GnomeVFSContext *context) +{ + HttpFileHandle *handle; + GnomeVFSResult result; + + ANALYZE_HTTP ("==> +do_read"); + DEBUG_HTTP (("+Read handle=0x%08x", (unsigned int) method_handle)); + + handle = (HttpFileHandle *) method_handle; + + if (handle->file_info->flags & GNOME_VFS_FILE_INFO_FIELDS_SIZE) { + GnomeVFSFileSize max_bytes; + + max_bytes = handle->file_info->size - handle->bytes_read; + num_bytes = MIN (max_bytes, num_bytes); + } + + result = gnome_vfs_socket_buffer_read (handle->socket_buffer, buffer, + num_bytes, bytes_read); + + if (*bytes_read == 0) { + return GNOME_VFS_ERROR_EOF; + } + + handle->bytes_read += *bytes_read; + + DEBUG_HTTP (("-Read (%d)", result)); + ANALYZE_HTTP ("==> -do_read"); + + return result; +} + +/* Directory handling - WebDAV servers only */ + +static void +process_propfind_propstat (xmlNodePtr node, + GnomeVFSFileInfo *file_info) +{ + xmlNodePtr l; + gboolean treat_as_directory; + + treat_as_directory = FALSE; + + while (node != NULL) { + if (strcmp ((char *)node->name, "prop") != 0) { + /* node name != "prop" - prop is all we care about */ + node = node->next; + continue; + } + /* properties of the file */ + l = node->xmlChildrenNode; + while (l != NULL) { + char *node_content_xml = xmlNodeGetContent(l); + if (node_content_xml) { + if (strcmp ((char *)l->name, "getcontenttype") == 0) { + + file_info->valid_fields |= + GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + if (!file_info->mime_type) { + file_info->mime_type = strip_semicolon (node_content_xml); + } + } else if (strcmp ((char *)l->name, "getcontentlength") == 0){ + file_info->valid_fields |= + GNOME_VFS_FILE_INFO_FIELDS_SIZE; + file_info->size = atoi(node_content_xml); + } else if (strcmp((char *)l->name, "getlastmodified") == 0) { + if (gnome_vfs_atotm (node_content_xml, &(file_info->mtime))) { + file_info->ctime = file_info->mtime; + file_info->valid_fields |= + GNOME_VFS_FILE_INFO_FIELDS_MTIME + | GNOME_VFS_FILE_INFO_FIELDS_CTIME; + } + } + /* Unfortunately, we don't have a mapping for "creationdate" */ + + xmlFree (node_content_xml); + node_content_xml = NULL; + } + if (strcmp ((char *)l->name, "resourcetype") == 0) { + file_info->valid_fields |= + GNOME_VFS_FILE_INFO_FIELDS_TYPE; + file_info->type = GNOME_VFS_FILE_TYPE_REGULAR; + + if (l->xmlChildrenNode && l->xmlChildrenNode->name + && strcmp ((char *)l->xmlChildrenNode->name, "collection") == 0) { + file_info->type = GNOME_VFS_FILE_TYPE_DIRECTORY; + } + } + l = l->next; + } + node = node->next; + } + + /* If this is a DAV collection, do we tell nautilus to treat it + * as a directory or as a web page? + */ + if (file_info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_TYPE + && file_info->type == GNOME_VFS_FILE_TYPE_DIRECTORY) { + g_free (file_info->mime_type); + if (treat_as_directory) { + file_info->mime_type = g_strdup ("x-directory/webdav-prefer-directory"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + } else { + file_info->mime_type = g_strdup ("x-directory/webdav"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + } + } + + + if ((file_info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE) == 0) { + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + file_info->mime_type = g_strdup (gnome_vfs_mime_type_from_name_or_default (file_info->name, "text/plain")); + } + + if ((file_info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_TYPE) == 0) { + /* Is this a reasonable assumption ? */ + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_TYPE; + file_info->type = GNOME_VFS_FILE_TYPE_REGULAR; + } +} + +/* a strcmp that doesn't barf on NULLs */ +static gint +null_handling_strcmp (const char *a, const char *b) +{ + if ((a == NULL) != (b == NULL)) { + return 1; + } + + if (a == NULL && b == NULL) { + return 0; + } + + return strcmp (a, b); +} + +#if 0 +static char * +unescape_unreserved_chars (const char *in_string) +{ + /* RFC 2396 section 2.2 */ + static const char * reserved_chars = "%;/?:@&=+$,"; + + char *ret, *write_char; + const char * read_char; + + if (in_string == NULL) { + return NULL; + } + + ret = g_new (char, strlen (in_string) + 1); + + for (read_char = in_string, write_char = ret ; *read_char != '\0' ; read_char++) { + if (read_char[0] == '%' + && g_ascii_isxdigit (read_char[1]) + && g_ascii_isxdigit (read_char[2])) { + char unescaped; + + unescaped = (g_ascii_xdigit_value (read_char[1]) << 4) | g_ascii_xdigit_value (read_char[2]); + + if (strchr (reserved_chars, unescaped)) { + *write_char++ = *read_char++; + *write_char++ = *read_char++; + *write_char++ = *read_char; /*The last ++ is done in the for statement */ + } else { + *write_char++ = unescaped; + read_char += 2; /*The last ++ is done in the for statement */ + } + } else { + *write_char++ = *read_char; + } + } + *write_char++ = '\0'; + + return ret; +} +#endif /* 0 */ + +static xmlNodePtr +find_child_node_named (xmlNodePtr node, + const char *child_node_name) +{ + xmlNodePtr child; + + child = node->xmlChildrenNode; + + for (child = node->xmlChildrenNode; child != NULL; child = child->next) { + if (0 == strcmp (child->name, child_node_name)) { + return child; + } + } + + return NULL; +} + +/* Look for a tag in the children of node, and returns + * the corresponding (HTTP) error code + */ +static gboolean +get_status_node (xmlNodePtr node, guint *status_code) +{ + xmlNodePtr status_node; + char *status_string; + gboolean ret; + + status_node = find_child_node_named (node, "status"); + + if (status_node != NULL) { + status_string = xmlNodeGetContent (status_node); + ret = parse_status (status_string, status_code); + xmlFree (status_string); + } else { + ret = FALSE; + } + + return ret; +} + +static GnomeVFSFileInfo * +process_propfind_response(xmlNodePtr n, + GnomeVFSURI *base_uri) +{ + GnomeVFSFileInfo *file_info = defaults_file_info_new (); + GnomeVFSURI *second_base = gnome_vfs_uri_append_path (base_uri, "/"); + guint status_code; + + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_NONE; + + while (n != NULL) { + if (strcmp ((char *)n->name, "href") == 0) { + char *nodecontent = xmlNodeGetContent (n); + GnomeVFSResult rv; + + rv = gnome_vfs_remove_optional_escapes (nodecontent); + + if (nodecontent != NULL && *nodecontent != '\0' && rv == GNOME_VFS_OK) { + gint len; + GnomeVFSURI *uri = gnome_vfs_uri_new (nodecontent); + + if (uri != NULL) { + if ((0 == null_handling_strcmp (base_uri->text, uri->text)) || + (0 == null_handling_strcmp (second_base->text, uri->text))) { + file_info->name = NULL; /* this file is the . directory */ + } else { + if (file_info->name != NULL) { + /* Don't leak if a (potentially malicious) + * server returns several href in its answer + */ + g_free (file_info->name); + } + file_info->name = gnome_vfs_uri_extract_short_name (uri); + if (file_info->name != NULL) { + len = strlen (file_info->name) -1; + if (file_info->name[len] == '/') { + /* trim trailing `/` - it confuses stuff */ + file_info->name[len] = '\0'; + } + } else { + g_warning ("Invalid filename in PROPFIND '%s'; silently skipping", nodecontent); + } + } + gnome_vfs_uri_unref (uri); + } else { + g_warning ("Can't make URI from href in PROPFIND '%s'; silently skipping", nodecontent); + } + } else { + g_warning ("got href without contents in PROPFIND response"); + } + + xmlFree (nodecontent); + } else if (strcmp ((char *)n->name, "propstat") == 0) { + if (get_status_node (n, &status_code) && status_code == 200) { + process_propfind_propstat (n->xmlChildrenNode, file_info); + } + } + n = n->next; + } + + gnome_vfs_uri_unref (second_base); + + return file_info; +} + + + +static GnomeVFSResult +make_propfind_request (HttpFileHandle **handle_return, + GnomeVFSURI *uri, + gint depth, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + GnomeVFSFileSize bytes_read, num_bytes=(64*1024); + char *buffer = g_malloc(num_bytes); + xmlParserCtxtPtr parserContext; + xmlDocPtr doc = NULL; + xmlNodePtr cur = NULL; + char *extraheaders = g_strdup_printf("Depth: %d\r\n", depth); + gboolean found_root_node_props; + + GByteArray *request = g_byte_array_new(); + char *request_str = "" + "" + "" + "" + "" + "" + "" + "" + "" + ""; + + ANALYZE_HTTP ("==> +make_propfind_request"); + + request = g_byte_array_append(request, request_str, + strlen(request_str)); + + parserContext = xmlCreatePushParserCtxt(NULL, NULL, "", 0, "PROPFIND"); + + if (depth > 0) { + http_cache_invalidate_uri_and_children (uri); + } + + result = make_request (handle_return, uri, "PROPFIND", request, + extraheaders, context); + + /* FIXME bugzilla.gnome.org 43834: It looks like some http + * servers (eg, www.yahoo.com) treat PROPFIND as a GET and + * return a 200 OK. Others may return access denied errors or + * redirects or any other legal response. This case probably + * needs to be made more robust. + */ + if (result == GNOME_VFS_OK && (*handle_return)->server_status != 207) { /* Multi-Status */ + DEBUG_HTTP (("HTTP server returned an invalid PROPFIND response: %d", (*handle_return)->server_status)); + result = GNOME_VFS_ERROR_NOT_SUPPORTED; + } + + if (result == GNOME_VFS_OK) { + do { + result = do_read (NULL, (GnomeVFSMethodHandle *) *handle_return, + buffer, num_bytes, &bytes_read, context); + + if (result != GNOME_VFS_OK ) { + break; + } + xmlParseChunk (parserContext, buffer, bytes_read, 0); + buffer[bytes_read]=0; + } while (bytes_read > 0); + } + + if (result == GNOME_VFS_ERROR_EOF) { + result = GNOME_VFS_OK; + } + + if (result != GNOME_VFS_OK) { + goto cleanup; + } + + xmlParseChunk (parserContext, "", 0, 1); + + doc = parserContext->myDoc; + if (doc == NULL) { + result = GNOME_VFS_ERROR_GENERIC; + goto cleanup; + } + + cur = doc->xmlRootNode; + if (strcmp ((char *)cur->name, "multistatus") != 0) { + DEBUG_HTTP (("Couldn't find .\n")); + result = GNOME_VFS_ERROR_GENERIC; + goto cleanup; + } + cur = cur->xmlChildrenNode; + + found_root_node_props = FALSE; + while (cur != NULL) { + if (strcmp ((char *)cur->name, "response") == 0) { + GnomeVFSFileInfo *file_info; + guint status; + + /* Some webdav servers (eg resin) put the HTTP status + * code for PROPFIND request in the xml answer instead + * of directly sending a 404 + */ + if (get_status_node (cur, &status) && !HTTP_20X(status)) { + result = http_status_to_vfs_result (status); + goto cleanup; + } + + file_info = + process_propfind_response (cur->xmlChildrenNode, uri); + + if (file_info->name != NULL) { + (*handle_return)->files = g_list_append ((*handle_return)->files, file_info); + } else { + /* This response refers to the root node */ + /* Abandon the old information that came from create_handle*/ + + file_info->name = (*handle_return)->file_info->name; + (*handle_return)->file_info->name = NULL; + gnome_vfs_file_info_unref ((*handle_return)->file_info); + (*handle_return)->file_info = file_info; + found_root_node_props = TRUE; + } + + } else { + DEBUG_HTTP(("expecting got <%s>\n", cur->name)); + } + cur = cur->next; + } + + if (!found_root_node_props) { + DEBUG_HTTP (("Failed to find root request node properties during propfind")); + result = GNOME_VFS_ERROR_GENERIC; + goto cleanup; + } + + /* + * RFC 2518 + * Section 8.1, final line + * "The results of this method [PROPFIND] SHOULD NOT be cached" + * Well, at least its not "MUST NOT" + */ + + if (depth == 0) { + http_cache_add_uri (uri, (*handle_return)->file_info, TRUE); + } else { + http_cache_add_uri_and_children (uri, (*handle_return)->file_info, (*handle_return)->files); + } + +cleanup: + g_free(buffer); + g_free(extraheaders); + xmlFreeParserCtxt(parserContext); + + if (result != GNOME_VFS_OK) { + http_handle_close (*handle_return, context); + *handle_return = NULL; + } + + ANALYZE_HTTP ("==> -make_propfind_request"); + + return result; +} + +static GnomeVFSResult +do_open_directory(GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + /* TODO move to using the gnome_vfs_file_info_list family of functions */ + GnomeVFSResult result; + HttpFileHandle *handle = NULL; + GnomeVFSFileInfo * file_info_cached; + GList *child_file_info_cached_list = NULL; + + ANALYZE_HTTP ("==> +do_open_directory"); + DEBUG_HTTP (("+Open_Directory options: %d URI: '%s'", options, gnome_vfs_uri_to_string (uri, 0))); + + /* Check the cache--is this even a directory? + * (Nautilus, in particular, seems to like to make this call on non directories + */ + + file_info_cached = http_cache_check_uri (uri); + + if (file_info_cached) { + if (GNOME_VFS_FILE_TYPE_DIRECTORY != file_info_cached->type) { + ANALYZE_HTTP ("==> Cache Hit (Negative)"); + gnome_vfs_file_info_unref (file_info_cached); + result = GNOME_VFS_ERROR_NOT_A_DIRECTORY; + goto error; + } + gnome_vfs_file_info_unref (file_info_cached); + file_info_cached = NULL; + } + + + /* The check for directory contents is more stringent */ + file_info_cached = http_cache_check_directory_uri (uri, &child_file_info_cached_list); + + if (file_info_cached) { + handle = http_file_handle_new (NULL, uri); + gnome_vfs_file_info_unref (handle->file_info); + handle->file_info = file_info_cached; + handle->files = child_file_info_cached_list; + result = GNOME_VFS_OK; + } else { + result = make_propfind_request(&handle, uri, 1, context); + /* mfleming -- is this necessary? Most DAV server's I've seen don't have the horrible + * lack-of-trailing-/-is-a-301 problem for PROPFIND's + */ + if (result == GNOME_VFS_ERROR_NOT_FOUND) { /* 404 not found */ + if (uri->text != NULL && *uri->text != '\0' + && uri->text[strlen (uri->text) - 1] != '/') { + GnomeVFSURI *tmpuri = gnome_vfs_uri_append_path (uri, "/"); + result = do_open_directory (method, (GnomeVFSMethodHandle **)&handle, tmpuri, options, context); + gnome_vfs_uri_unref (tmpuri); + + } + } + + if (result == GNOME_VFS_OK + && handle->file_info->type != GNOME_VFS_FILE_TYPE_DIRECTORY) { + result = GNOME_VFS_ERROR_NOT_A_DIRECTORY; + http_handle_close (handle, context); + handle = NULL; + } + } + + *method_handle = (GnomeVFSMethodHandle *)handle; + +error: + DEBUG_HTTP (("-Open_Directory (%d) handle:0x%08x", result, (unsigned int)handle)); + ANALYZE_HTTP ("==> -do_open_directory"); + + return result; +} + +static GnomeVFSResult +do_close_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + HttpFileHandle *handle; + + DEBUG_HTTP (("+Close_Directory")); + + handle = (HttpFileHandle *) method_handle; + + http_handle_close(handle, context); + + DEBUG_HTTP (("-Close_Directory (0) handle:0x%08x", (unsigned int) method_handle)); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_read_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSContext *context) +{ + HttpFileHandle *handle; + GnomeVFSResult result; + + DEBUG_HTTP (("+Read_Directory handle:0x%08x", (unsigned int) method_handle)); + + handle = (HttpFileHandle *) method_handle; + + if (handle->files && g_list_length (handle->files)) { + GnomeVFSFileInfo *original_info = g_list_nth_data (handle->files, 0); + gboolean found_entry = FALSE; + + /* mfleming -- Why is this check here? Does anyone set original_info->name to NULL? */ + if (original_info->name != NULL && original_info->name[0]) { + gnome_vfs_file_info_copy (file_info, original_info); + found_entry = TRUE; + } + + /* remove our GnomeVFSFileInfo from the list */ + handle->files = g_list_remove (handle->files, original_info); + gnome_vfs_file_info_unref (original_info); + + /* mfleming -- Is this necessary? */ + if (found_entry) { + result = GNOME_VFS_OK; + } else { + result = do_read_directory (method, method_handle, file_info, context); + } + } else { + result = GNOME_VFS_ERROR_EOF; + } + + DEBUG_HTTP (("-Read_Directory (%d)", result)); + return result; +} + + +static GnomeVFSResult +do_get_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + HttpFileHandle *handle; + GnomeVFSResult result; + GnomeVFSFileInfo * file_info_cached; + + ANALYZE_HTTP ("==> +do_get_file_info"); + DEBUG_HTTP (("+Get_File_Info options: %d URI: '%s'", options, gnome_vfs_uri_to_string( uri, 0))); + + file_info_cached = http_cache_check_uri (uri); + + if (file_info_cached != NULL) { + gnome_vfs_file_info_copy (file_info, file_info_cached); + gnome_vfs_file_info_unref (file_info_cached); + ANALYZE_HTTP ("==> Cache Hit"); + result = GNOME_VFS_OK; + } else { + /* + * Start off by making a PROPFIND request. Fall back to a HEAD if it fails + */ + + result = make_propfind_request (&handle, uri, 0, context); + + /* Note that theoretically we could not bother with this request if we get a 404 back, + * but since some servers seem to return wierd things on PROPFIND (mostly 200 OK's...) + * I'm not going to count on the PROPFIND response.... + */ + if (result == GNOME_VFS_OK) { + gnome_vfs_file_info_copy (file_info, handle->file_info); + http_handle_close (handle, context); + handle = NULL; + } else { + g_assert (handle == NULL); /* Make sure we're not leaking some old one */ + + /* Lame buggy servers (eg: www.mozilla.org, + * www.corel.com)) return an HTTP error for a + * HEAD where a GET would succeed. In these + * cases lets try to do a GET. + */ + if (result != GNOME_VFS_OK) { + g_assert (handle == NULL); /* Make sure we're not leaking some old one */ + + ANALYZE_HTTP ("==> do_get_file_info: do GET "); + + result = make_request (&handle, uri, "GET", NULL, NULL, context); + if (result == GNOME_VFS_OK) { + gnome_vfs_file_info_copy (file_info, handle->file_info); + http_cache_add_uri (uri, handle->file_info, FALSE); + http_handle_close (handle, context); + } + + /* If we get a redirect, we should be + * basing the MIME type on the type of + * the page we'll be redirected + * too. Maybe we even want to take the + * "follow_links" setting into account. + */ + /* FIXME: For now we treat all + * redirects as if they lead to a + * text/html. That works pretty well, + * but it's not correct. + */ + if (handle != NULL && HTTP_REDIRECTED (handle->server_status)) { + g_free (file_info->mime_type); + file_info->mime_type = g_strdup ("text/html"); + } + } + + if (result == GNOME_VFS_ERROR_NOT_FOUND) { /* 404 not found */ + /* FIXME bugzilla.gnome.org 43835: mfleming: Is this code really appropriate? + * In any case, it doesn't seem to be appropriate for a DAV-enabled + * server, since they don't seem to send 301's when you PROPFIND collections + * without a trailing '/'. + */ + if (uri->text != NULL && *uri->text != '\0' + && uri->text[strlen(uri->text)-1] != '/') { + GnomeVFSURI *tmpuri = gnome_vfs_uri_append_path (uri, "/"); + + result = do_get_file_info (method, tmpuri, file_info, options, context); + gnome_vfs_uri_unref (tmpuri); + } + } + } + } + + DEBUG_HTTP (("-Get_File_Info (%d)", result)); + ANALYZE_HTTP ("==> -do_get_file_info"); + + return result; +} + +static GnomeVFSResult +do_get_file_info_from_handle (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + HttpFileHandle *handle; + + DEBUG_HTTP (("+Get_File_Info_From_Handle")); + + handle = (HttpFileHandle *) method_handle; + + gnome_vfs_file_info_copy (file_info, handle->file_info); + + DEBUG_HTTP (("-Get_File_Info_From_Handle")); + + return GNOME_VFS_OK; +} + +static gboolean +do_is_local (GnomeVFSMethod *method, + const GnomeVFSURI *uri) +{ + DEBUG_HTTP (("+Is_Local")); + return FALSE; +} + +static GnomeVFSResult +do_make_directory (GnomeVFSMethod *method, + GnomeVFSURI *uri, + guint perm, + GnomeVFSContext *context) +{ + /* MKCOL /path HTTP/1.0 */ + + HttpFileHandle *handle; + GnomeVFSResult result; + + DEBUG_HTTP (("+Make_Directory URI: '%s'", gnome_vfs_uri_to_string (uri, 0))); + ANALYZE_HTTP ("==> +do_make_directory"); + + /* + * MKCOL returns a 405 if you try to MKCOL on something that + * already exists. Of course, we don't know whether that means that + * the server doesn't support DAV or the collection already exists. + * So we do a PROPFIND first to find out + */ + /* FIXME check cache here */ + result = make_propfind_request(&handle, uri, 0, context); + + if (result == GNOME_VFS_OK) { + result = GNOME_VFS_ERROR_FILE_EXISTS; + } else { + /* Make sure we're not leaking an old one */ + g_assert (handle == NULL); + + if (result == GNOME_VFS_ERROR_NOT_FOUND) { + http_cache_invalidate_uri_parent (uri); + result = make_request (&handle, uri, "MKCOL", NULL, NULL, context); + } + } + http_handle_close (handle, context); + + if (result == GNOME_VFS_ERROR_NOT_FOUND) { + result = resolve_409 (method, uri, context); + } + + ANALYZE_HTTP ("==> -do_make_directory"); + DEBUG_HTTP (("-Make_Directory (%d)", result)); + + return result; +} + +static GnomeVFSResult +do_remove_directory(GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSContext *context) +{ + /* DELETE /path HTTP/1.0 */ + HttpFileHandle *handle; + GnomeVFSResult result; + + ANALYZE_HTTP ("==> +do_remove_directory"); + DEBUG_HTTP (("+Remove_Directory URI: '%s'", gnome_vfs_uri_to_string (uri, 0))); + + http_cache_invalidate_uri_parent (uri); + + /* FIXME this should return GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY if the + * directory is not empty + */ + result = make_request (&handle, uri, "DELETE", NULL, NULL, + context); + http_handle_close (handle, context); + + DEBUG_HTTP (("-Remove_Directory (%d)", result)); + ANALYZE_HTTP ("==> -do_remove_directory"); + + return result; +} + +static gboolean +is_same_fs (const GnomeVFSURI *a, + const GnomeVFSURI *b) +{ + return null_handling_strcmp (gnome_vfs_uri_get_scheme (a), gnome_vfs_uri_get_scheme (b)) == 0 + && null_handling_strcmp (gnome_vfs_uri_get_host_name (a), gnome_vfs_uri_get_host_name (b)) == 0 + && null_handling_strcmp (gnome_vfs_uri_get_user_name (a), gnome_vfs_uri_get_user_name (b)) == 0 + && null_handling_strcmp (gnome_vfs_uri_get_password (a), gnome_vfs_uri_get_password (b)) == 0 + && (gnome_vfs_uri_get_host_port (a) == gnome_vfs_uri_get_host_port (b)); +} + +static GnomeVFSResult +do_move (GnomeVFSMethod *method, + GnomeVFSURI *old_uri, + GnomeVFSURI *new_uri, + gboolean force_replace, + GnomeVFSContext *context) +{ + + /* + * MOVE /path1 HTTP/1.0 + * Destination: /path2 + * Overwrite: (T|F) + */ + + HttpFileHandle *handle; + GnomeVFSResult result; + + char *destpath, *destheader; + + ANALYZE_HTTP ("==> +do_move"); + DEBUG_HTTP (("+Move URI: '%s' Dest: '%s'", + gnome_vfs_uri_to_string (old_uri, 0), + gnome_vfs_uri_to_string (new_uri, 0))); + + if (!is_same_fs (old_uri, new_uri)) { + return GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM; + } + + destpath = gnome_vfs_uri_to_string (new_uri, GNOME_VFS_URI_HIDE_USER_NAME|GNOME_VFS_URI_HIDE_PASSWORD); + destheader = g_strdup_printf ("Destination: %s\r\nOverwrite: %c\r\n", destpath, force_replace ? 'T' : 'F' ); + + result = make_request (&handle, old_uri, "MOVE", NULL, destheader, context); + http_handle_close (handle, context); + handle = NULL; + + if (result == GNOME_VFS_ERROR_NOT_FOUND) { + result = resolve_409 (method, new_uri, context); + } + + http_cache_invalidate_uri_parent (old_uri); + http_cache_invalidate_uri_parent (new_uri); + + DEBUG_HTTP (("-Move (%d)", result)); + ANALYZE_HTTP ("==> -do_move"); + + return result; +} + + +static GnomeVFSResult +do_unlink(GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + + /* FIXME need to make sure this fails on directories */ + ANALYZE_HTTP ("==> +do_unlink"); + DEBUG_HTTP (("+Unlink URI: '%s'", gnome_vfs_uri_to_string (uri, 0))); + result = do_remove_directory (method, uri, context); + DEBUG_HTTP (("-Unlink (%d)", result)); + ANALYZE_HTTP ("==> -do_unlink"); + + return result; +} + +static GnomeVFSResult +do_check_same_fs (GnomeVFSMethod *method, + GnomeVFSURI *a, + GnomeVFSURI *b, + gboolean *same_fs_return, + GnomeVFSContext *context) +{ + *same_fs_return = is_same_fs (a, b); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_set_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + const GnomeVFSFileInfo *info, + GnomeVFSSetFileInfoMask mask, + GnomeVFSContext *context) +{ + GnomeVFSURI *parent_uri, *new_uri; + GnomeVFSResult result; + + /* FIXME: For now, we only support changing the name. */ + if ((mask & ~(GNOME_VFS_SET_FILE_INFO_NAME)) != 0) { + return GNOME_VFS_ERROR_NOT_SUPPORTED; + } + + /* FIXME bugzillagnome.org 40645: Make sure this returns an + * error for incoming names with "/" characters in them, + * instead of moving the file. + */ + + /* Share code with do_move. */ + parent_uri = gnome_vfs_uri_get_parent (uri); + if (parent_uri == NULL) { + return GNOME_VFS_ERROR_NOT_FOUND; + } + new_uri = gnome_vfs_uri_append_file_name (parent_uri, info->name); + gnome_vfs_uri_unref (parent_uri); + result = do_move (method, uri, new_uri, FALSE, context); + gnome_vfs_uri_unref (new_uri); + return result; +} + +static GnomeVFSMethod method = { + sizeof (GnomeVFSMethod), + do_open, + do_create, + do_close, + do_read, + do_write, + NULL, /* seek */ + NULL, /* tell */ + NULL, /* truncate_handle */ + do_open_directory, + do_close_directory, + do_read_directory, + do_get_file_info, + do_get_file_info_from_handle, + do_is_local, + do_make_directory, + do_remove_directory, + do_move, + do_unlink, + do_check_same_fs, + do_set_file_info, + NULL, /* truncate */ + NULL, /* find_directory */ + NULL /* create_symbolic_link */ +}; + +GnomeVFSMethod * +vfs_module_init (const char *method_name, + const char *args) +{ + GError *gconf_error = NULL; + gboolean use_proxy; + gboolean use_proxy_auth; + + LIBXML_TEST_VERSION + + gl_client = gconf_client_get_default (); + + gl_mutex = g_mutex_new (); + + gconf_client_add_dir (gl_client, PATH_GCONF_GNOME_VFS, GCONF_CLIENT_PRELOAD_ONELEVEL, &gconf_error); + if (gconf_error) { + DEBUG_HTTP (("GConf error during client_add_dir '%s'", gconf_error->message)); + g_error_free (gconf_error); + gconf_error = NULL; + } + + gconf_client_notify_add (gl_client, PATH_GCONF_GNOME_VFS, notify_gconf_value_changed, NULL, NULL, &gconf_error); + if (gconf_error) { + DEBUG_HTTP (("GConf error during notify_error '%s'", gconf_error->message)); + g_error_free (gconf_error); + gconf_error = NULL; + } + + /* Load the http proxy setting */ + use_proxy = gconf_client_get_bool (gl_client, KEY_GCONF_USE_HTTP_PROXY, &gconf_error); + + if (gconf_error != NULL) { + DEBUG_HTTP (("GConf error during client_get_bool '%s'", gconf_error->message)); + g_error_free (gconf_error); + gconf_error = NULL; + } else { + construct_gl_http_proxy (use_proxy); + } + + use_proxy_auth = gconf_client_get_bool (gl_client, KEY_GCONF_HTTP_USE_AUTH, &gconf_error); + + if (gconf_error != NULL) { + DEBUG_HTTP (("GConf error during client_get_bool '%s'", gconf_error->message)); + g_error_free (gconf_error); + gconf_error = NULL; + } else { + set_proxy_auth (use_proxy_auth); + } + + http_authn_init (); + http_cache_init (); + + return &method; +} + +void +vfs_module_shutdown (GnomeVFSMethod *method) +{ + g_object_unref (G_OBJECT (gl_client)); + + http_authn_shutdown (); + + http_cache_shutdown(); + + g_mutex_free (gl_mutex); + + gl_client = NULL; +} + +/* A "409 Conflict" currently maps to GNOME_VFS_ERROR_NOT_FOUND because it can be returned + * when the parent collection/directory does not exist. Unfortunately, Xythos also returns + * this code when the destination filename of a PUT, MKCOL, or MOVE contains illegal characters, + * eg "my*file:name". + * + * The only way to resolve this is to ask... + */ + +static GnomeVFSResult +resolve_409 (GnomeVFSMethod *method, GnomeVFSURI *uri, GnomeVFSContext *context) +{ + GnomeVFSFileInfo *file_info; + GnomeVFSURI *parent_dest_uri; + GnomeVFSResult result; + + + ANALYZE_HTTP ("==> +resolving 409"); + + file_info = gnome_vfs_file_info_new (); + parent_dest_uri = gnome_vfs_uri_get_parent (uri); + + if (parent_dest_uri != NULL) { + result = do_get_file_info (method, + parent_dest_uri, + file_info, + GNOME_VFS_FILE_INFO_DEFAULT, + context); + + gnome_vfs_file_info_unref (file_info); + file_info = NULL; + + gnome_vfs_uri_unref (parent_dest_uri); + parent_dest_uri = NULL; + } else { + result = GNOME_VFS_ERROR_NOT_FOUND; + } + + if (result == GNOME_VFS_OK) { + /* The destination filename contains characters that are not allowed + * by the server. This is a bummer mapping, but EINVAL is what + * the Linux FAT filesystems return on bad filenames, so at least + * its not without precedent... + */ + result = GNOME_VFS_ERROR_BAD_PARAMETERS; + } else { + /* The destination's parent path does not exist */ + result = GNOME_VFS_ERROR_NOT_FOUND; + } + + ANALYZE_HTTP ("==> -resolving 409"); + + return result; +} + +static gboolean +invoke_callback_headers_received (HttpFileHandle *handle) +{ + GnomeVFSModuleCallbackReceivedHeadersIn in_args; + GnomeVFSModuleCallbackReceivedHeadersOut out_args; + gboolean ret = FALSE; + + memset (&in_args, 0, sizeof (in_args)); + memset (&out_args, 0, sizeof (out_args)); + + in_args.uri = handle->uri; + in_args.headers = handle->response_headers; + + ret = gnome_vfs_module_callback_invoke (GNOME_VFS_MODULE_CALLBACK_HTTP_RECEIVED_HEADERS, + &in_args, sizeof (in_args), + &out_args, sizeof (out_args)); + + return ret; +} + +static gboolean +invoke_callback_send_additional_headers (GnomeVFSURI *uri, + GList **headers) +{ + GnomeVFSModuleCallbackAdditionalHeadersIn in_args; + GnomeVFSModuleCallbackAdditionalHeadersOut out_args; + gboolean ret = FALSE; + + memset (&in_args, 0, sizeof (in_args)); + memset (&out_args, 0, sizeof (out_args)); + + in_args.uri = uri; + + ret = gnome_vfs_module_callback_invoke (GNOME_VFS_MODULE_CALLBACK_HTTP_SEND_ADDITIONAL_HEADERS, + &in_args, sizeof (in_args), + &out_args, sizeof (out_args)); + + if (ret) { + *headers = out_args.headers; + return TRUE; + } + + if (out_args.headers) { + g_list_foreach (out_args.headers, (GFunc)g_free, NULL); + g_list_free (out_args.headers); + } + + *headers = NULL; + + return FALSE; +} + +static gboolean +invoke_callback_basic_authn (HttpFileHandle *handle, + enum AuthnHeaderType authn_which, + gboolean previous_attempt_failed) +{ + GnomeVFSModuleCallbackAuthenticationIn in_args; + GnomeVFSModuleCallbackAuthenticationOut out_args; + gboolean ret; + + ret = FALSE; + + memset (&in_args, 0, sizeof (in_args)); + memset (&out_args, 0, sizeof (out_args)); + + in_args.previous_attempt_failed = previous_attempt_failed; + + in_args.uri = gnome_vfs_uri_to_string (handle->uri, GNOME_VFS_URI_HIDE_NONE); + + ret = http_authn_parse_response_header_basic (authn_which, handle->response_headers, &in_args.realm); + + if (!ret) { + goto error; + } + + DEBUG_HTTP (("Invoking %s authentication callback for uri %s", + authn_which == AuthnHeader_WWW ? "basic" : "proxy", in_args.uri)); + + in_args.auth_type = AuthTypeBasic; + + ret = gnome_vfs_module_callback_invoke (authn_which == AuthnHeader_WWW + ? GNOME_VFS_MODULE_CALLBACK_AUTHENTICATION + : GNOME_VFS_MODULE_CALLBACK_HTTP_PROXY_AUTHENTICATION, + &in_args, sizeof (in_args), + &out_args, sizeof (out_args)); + + if (!ret) { + DEBUG_HTTP (("No callback registered")); + goto error; + } + + ret = (out_args.username != NULL); + + if (!ret) { + DEBUG_HTTP (("No username provided by callback")); + goto error; + } + + DEBUG_HTTP (("Back from authentication callback, adding credentials")); + + if (authn_which == AuthnHeader_WWW) { + http_authn_session_add_credentials (handle->uri, out_args.username, out_args.password); + } else /* if (authn_which == AuthnHeader_Proxy) */ { + proxy_set_authn (out_args.username, out_args.password); + } +error: + g_free (in_args.uri); + g_free (in_args.realm); + g_free (out_args.username); + g_free (out_args.password); + + return ret; +} + +static int +strcmp_allow_nulls (const char *s1, const char *s2) +{ + return strcmp (s1 == NULL ? "" : s1, s2 == NULL ? "" : s2); +} + + +/* Returns TRUE if the given URL has changed authentication credentials + * from the last request (eg, another thread updated the authn information) + * or if the application provided new credentials via a callback + * + * prev_authn_header is NULL if the previous request contained no authn information. + */ + +gboolean +check_authn_retry_request (HttpFileHandle * http_handle, + enum AuthnHeaderType authn_which, + const char *prev_authn_header) +{ + gboolean ret; + char *current_authn_header; + + current_authn_header = NULL; + + g_mutex_lock (gl_mutex); + + if (authn_which == AuthnHeader_WWW) { + current_authn_header = http_authn_get_header_for_uri (http_handle->uri); + } else if (authn_which == AuthnHeader_Proxy) { + current_authn_header = proxy_get_authn_header_for_uri_nolock (http_handle->uri); + } else { + g_assert_not_reached (); + } + + ret = FALSE; + if (0 == strcmp_allow_nulls (current_authn_header, prev_authn_header)) { + ret = invoke_callback_basic_authn (http_handle, authn_which, prev_authn_header == NULL); + } else { + ret = TRUE; + } + + g_mutex_unlock (gl_mutex); + + g_free (current_authn_header); + + return ret; +} + + +utime_t +http_util_get_utime (void) +{ + struct timeval tmp; + gettimeofday (&tmp, NULL); + return (utime_t)tmp.tv_usec + ((gint64)tmp.tv_sec) * 1000000LL; +} + + +/* BASE64 code ported from neon (http://www.webdav.org/neon) */ +static const gchar b64_alphabet[65] = { + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/=" }; + +gchar * +http_util_base64 (const gchar *text) +{ + /* The tricky thing about this is doing the padding at the end, + * doing the bit manipulation requires a bit of concentration only */ + gchar *buffer, *point; + gint inlen, outlen; + + /* Use 'buffer' to store the output. Work out how big it should be... + * This must be a multiple of 4 bytes + */ + + inlen = strlen (text); + outlen = (inlen*4)/3; + if ((inlen % 3) > 0) { /* got to pad */ + outlen += 4 - (inlen % 3); + } + + buffer = g_malloc (outlen + 1); /* +1 for the \0 */ + + /* now do the main stage of conversion, 3 bytes at a time, + * leave the trailing bytes (if there are any) for later + */ + + for (point=buffer; inlen>=3; inlen-=3, text+=3) { + *(point++) = b64_alphabet[ (*text)>>2 ]; + *(point++) = b64_alphabet[ ((*text)<<4 & 0x30) | (*(text+1))>>4 ]; + *(point++) = b64_alphabet[ ((*(text+1))<<2 & 0x3c) | (*(text+2))>>6 ]; + *(point++) = b64_alphabet[ (*(text+2)) & 0x3f ]; + } + + /* Now deal with the trailing bytes */ + if (inlen) { + /* We always have one trailing byte */ + *(point++) = b64_alphabet[ (*text)>>2 ]; + *(point++) = b64_alphabet[ ( ((*text)<<4 & 0x30) | + (inlen==2?(*(text+1))>>4:0) ) ]; + *(point++) = (inlen==1?'=':b64_alphabet[ (*(text+1))<<2 & 0x3c ] ); + *(point++) = '='; + } + + /* Null-terminate */ + *point = '\0'; + + return buffer; +} + +static gboolean at_least_one_test_failed = FALSE; + +static void +test_failed (const char *format, ...) +{ + va_list arguments; + char *message; + + va_start (arguments, format); + message = g_strdup_vprintf (format, arguments); + va_end (arguments); + + g_message ("test failed: %s", message); + at_least_one_test_failed = TRUE; +} + +#define VERIFY_BOOLEAN_RESULT(function, expected) \ + G_STMT_START { \ + gboolean result = function; \ + if (! ((result && expected) || (!result && !expected))) { \ + test_failed ("%s: returned '%d' expected '%d'", #function, (int)result, (int)expected); \ + } \ + } G_STMT_END + + +static gboolean +http_self_test (void) +{ + g_message ("self-test: http\n"); + + VERIFY_BOOLEAN_RESULT (proxy_should_for_hostname ("localhost"), FALSE); + VERIFY_BOOLEAN_RESULT (proxy_should_for_hostname ("LocalHost"), FALSE); + VERIFY_BOOLEAN_RESULT (proxy_should_for_hostname ("127.0.0.1"), FALSE); + VERIFY_BOOLEAN_RESULT (proxy_should_for_hostname ("127.127.0.1"), FALSE); + VERIFY_BOOLEAN_RESULT (proxy_should_for_hostname ("www.yahoo.com"), TRUE); + + return !at_least_one_test_failed; +} + +gboolean vfs_module_self_test (void); + +gboolean +vfs_module_self_test (void) +{ + gboolean ret; + + ret = TRUE; + + ret = http_authn_self_test () && ret; + + ret = http_self_test () && ret; + + return ret; +} + diff --git a/modules/http-method.h b/modules/http-method.h new file mode 100644 index 0000000..798787c --- /dev/null +++ b/modules/http-method.h @@ -0,0 +1,51 @@ +/* http-method.h - HTTP access method for the GNOME Virtual File System. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli +*/ + +#ifndef HTTP_METHOD_H +#define HTTP_METHOD_H + +#include + +typedef gint64 utime_t; + +utime_t http_util_get_utime (void); + +gchar * http_util_base64 (const gchar *text); + +#undef DEBUG_HTTP_ENABLE + +#ifdef DEBUG_HTTP_ENABLE + +void http_debug_printf(char *fmt, ...) G_GNUC_PRINTF (1,2); + +#define DEBUG_HTTP(x) http_debug_printf x +/*#define ANALYZE_HTTP(x) http_debug_printf (x)*/ +#define ANALYZE_HTTP(x) + +#else /* DEBUG_HTTP_ENABLE */ + +#define DEBUG_HTTP(x) +#define ANALYZE_HTTP(x) + +#endif /* DEBUG_HTTP_ENABLE */ + +#endif /* HTTP_METHOD_H */ diff --git a/modules/nntp-method.c b/modules/nntp-method.c new file mode 100644 index 0000000..e573f96 --- /dev/null +++ b/modules/nntp-method.c @@ -0,0 +1,2275 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: 8; c-basic-offset: 8 -*- */ + +/* nntp-method.c - VFS module for NNTP + + Copyright (C) 2001 Andy Hertzfeld + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + based on Ian McKellar's (yakk@yakk.net) ftp method for gnome-vfs + + presents a high level, file-oriented view of a newsgroup, integrating file fragments + and organizing them in folders + + Author: Andy Hertzfeld December 2001 + + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include /* for atoi */ +#include /* for sscanf */ +#include + +#include +#include +#include + +#include + +#ifdef HAVE_GCONF +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "nntp-method.h" + + +#define MAX_RESPONSE_SIZE 4096 +#define READ_BUFFER_SIZE 16384 + +/* these parameters should eventually be fetched from gconf */ +#define MAX_MESSAGE_COUNT 2400 +#define MIN_FILE_SIZE_THRESHOLD 4095 + +/* macros for the checking of NNTP response codes */ +#define IS_100(X) ((X) >= 100 && (X) < 200) +#define IS_200(X) ((X) >= 200 && (X) < 300) +#define IS_300(X) ((X) >= 300 && (X) < 400) +#define IS_400(X) ((X) >= 400 && (X) < 500) +#define IS_500(X) ((X) >= 500 && (X) < 600) + +static GnomeVFSResult do_open (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + GnomeVFSContext *context); +static gboolean do_is_local (GnomeVFSMethod *method, + const GnomeVFSURI *uri); +static GnomeVFSResult do_open_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context); +static GnomeVFSResult do_close_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context); +static GnomeVFSResult do_read_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSContext *context); + +guint nntp_connection_uri_hash (gconstpointer c); +int nntp_connection_uri_equal (gconstpointer c, gconstpointer d); +static GnomeVFSResult nntp_connection_acquire (GnomeVFSURI *uri, + NNTPConnection **connection, + GnomeVFSContext *context); +static void nntp_connection_release (NNTPConnection *conn); + +static GList* assemble_files_from_overview (NNTPConnection *conn, char *command); + +static const char *anon_user = "anonymous"; +static const char *anon_pass = "nobody@gnome.org"; +static const int nntp_port = 119; + + +/* A GHashTable of GLists of NNTPConnections */ +static GHashTable *spare_connections = NULL; +G_LOCK_DEFINE_STATIC (spare_connections); +static int total_connections = 0; +static int allocated_connections = 0; + +/* single element cache of file objects for a given newsgroup */ +static char* current_newsgroup_name = NULL; +static GList* current_newsgroup_files = NULL; + +static GnomeVFSResult +nntp_response_to_vfs_result (NNTPConnection *conn) +{ + int response = conn->response_code; + + switch (response) { + case 421: + case 426: + return GNOME_VFS_ERROR_CANCELLED; + case 425: + return GNOME_VFS_ERROR_ACCESS_DENIED; + case 530: + case 331: + case 332: + case 532: + return GNOME_VFS_ERROR_LOGIN_FAILED; + case 450: + case 451: + case 550: + case 551: + return GNOME_VFS_ERROR_NOT_FOUND; + case 452: + case 552: + return GNOME_VFS_ERROR_NO_SPACE; + case 553: + return GNOME_VFS_ERROR_BAD_FILE; + } + + /* is this the correct interpretation of this error? */ + if (IS_100 (response)) return GNOME_VFS_OK; + if (IS_200 (response)) return GNOME_VFS_OK; + /* is this the correct interpretation of this error? */ + if (IS_300 (response)) return GNOME_VFS_OK; + if (IS_400 (response)) return GNOME_VFS_ERROR_GENERIC; + if (IS_500 (response)) return GNOME_VFS_ERROR_INTERNAL; + + return GNOME_VFS_ERROR_GENERIC; + +} + +static GnomeVFSResult read_response_line(NNTPConnection *conn, char **line) { + GnomeVFSFileSize bytes = MAX_RESPONSE_SIZE, bytes_read; + char *ptr, *buf = g_malloc (MAX_RESPONSE_SIZE+1); + int line_length; + GnomeVFSResult result = GNOME_VFS_OK; + + while (!strstr (conn->response_buffer->str, "\r\n")) { + /* we don't have a full line. Lets read some... */ + bytes_read = 0; + result = gnome_vfs_socket_buffer_read (conn->socketbuf, buf, + bytes, &bytes_read); + buf[bytes_read] = '\0'; + conn->response_buffer = g_string_append (conn->response_buffer, + buf); + if (result != GNOME_VFS_OK) { + g_warning ("Error `%s' during read\n", + gnome_vfs_result_to_string(result)); + g_free (buf); + return result; + } + } + + g_free (buf); + + ptr = strstr (conn->response_buffer->str, "\r\n"); + line_length = ptr - conn->response_buffer->str; + + *line = g_strndup (conn->response_buffer->str, line_length); + + g_string_erase (conn->response_buffer, 0 , line_length + 2); + + return result; +} + + +static GnomeVFSResult +get_response (NNTPConnection *conn) +{ + /* all that should be pending is a response to the last command */ + GnomeVFSResult result; + + while (TRUE) { + char *line = NULL; + result = read_response_line (conn, &line); + + if (result != GNOME_VFS_OK) { + g_free (line); + g_warning ("Error reading response line."); + return result; + } + + /* response needs to be at least: "### x" - I think*/ + if (g_ascii_isdigit (line[0]) && + g_ascii_isdigit (line[1]) && + g_ascii_isdigit (line[2]) && + g_ascii_isspace (line[3])) { + + conn->response_code = g_ascii_digit_value (line[0]) * 100 + + g_ascii_digit_value (line[1]) * 10 + + g_ascii_digit_value (line[2]); + + if (conn->response_message) g_free (conn->response_message); + conn->response_message = g_strdup (line+4); + + g_free (line); + + return nntp_response_to_vfs_result (conn); + + } + + /* hmm - not a valid line - lets ignore it :-) */ + g_free (line); + } + + return GNOME_VFS_OK; /* should never be reached */ + +} + +static GnomeVFSResult do_control_write (NNTPConnection *conn, + char *command) +{ + char *actual_command = g_strdup_printf ("%s\r\n", command); + GnomeVFSFileSize bytes = strlen (actual_command), bytes_written; + GnomeVFSResult result = gnome_vfs_socket_buffer_write (conn->socketbuf, + actual_command, bytes, &bytes_written); + gnome_vfs_socket_buffer_flush (conn->socketbuf); + g_free (actual_command); + + return result; +} + +static void +nntp_connection_reset_buffer (NNTPConnection *conn) +{ + g_string_erase (conn->response_buffer, 0, strlen(conn->response_buffer->str)); +} + +static GnomeVFSResult +do_basic_command (NNTPConnection *conn, + char *command) +{ + GnomeVFSResult result; + + nntp_connection_reset_buffer (conn); + + result = do_control_write(conn, command); + + if (result != GNOME_VFS_OK) { + return result; + } + + result = get_response (conn); + + return result; +} + +/* the following routines manage the connection with the news server */ + +/* create a new connection */ +static GnomeVFSResult +nntp_connection_create (NNTPConnection **connptr, GnomeVFSURI *uri, GnomeVFSContext *context) +{ + NNTPConnection *conn = g_new (NNTPConnection, 1); + GnomeVFSResult result; + char *tmpstring; + int port = nntp_port; + const char *user = anon_user; + const char *pass = anon_pass; + + conn->uri = gnome_vfs_uri_dup (uri); + + conn->response_buffer = g_string_new (""); + conn->response_message = NULL; + conn->response_code = -1; + + conn->anonymous = TRUE; + + /* allocate the read buffer */ + conn->buffer = g_malloc(READ_BUFFER_SIZE); + conn->buffer_size = READ_BUFFER_SIZE; + conn->amount_in_buffer = 0; + conn->buffer_offset = 0; + + conn->request_in_progress = FALSE; + + if (gnome_vfs_uri_get_host_port (uri)) { + port = gnome_vfs_uri_get_host_port (uri); + } + + if (gnome_vfs_uri_get_user_name (uri)) { + user = gnome_vfs_uri_get_user_name (uri); + conn->anonymous = FALSE; + } + + if (gnome_vfs_uri_get_password (uri)) { + pass = gnome_vfs_uri_get_password (uri); + } + + result = gnome_vfs_inet_connection_create (&conn->inet_connection, + gnome_vfs_uri_get_host_name (uri), + port, + context ? gnome_vfs_context_get_cancellation(context) : NULL); + + if (result != GNOME_VFS_OK) { + g_warning ("gnome_vfs_inet_connection_create (\"%s\", %d) = \"%s\"", + gnome_vfs_uri_get_host_name (uri), + gnome_vfs_uri_get_host_port (uri), + gnome_vfs_result_to_string (result)); + g_string_free (conn->response_buffer, TRUE); + g_free (conn); + return result; + } + + conn->socketbuf = gnome_vfs_inet_connection_to_socket_buffer (conn->inet_connection); + + if (conn->socketbuf == NULL) { + g_warning ("gnome_vfs_inet_connection_get_socket_buffer () failed"); + gnome_vfs_inet_connection_destroy (conn->inet_connection, NULL); + g_string_free (conn->response_buffer, TRUE); + g_free (conn); + return GNOME_VFS_ERROR_GENERIC; + } + + result = get_response (conn); + + if (result != GNOME_VFS_OK) { + g_warning ("nntp server (%s:%d) said `%d %s'", + gnome_vfs_uri_get_host_name (uri), + gnome_vfs_uri_get_host_port (uri), + conn->response_code, conn->response_message); + g_string_free (conn->response_buffer, TRUE); + g_free (conn); + return result; + } + + if (!conn->anonymous) { + tmpstring = g_strdup_printf ("AUTHINFO user %s", user); + result = do_basic_command (conn, tmpstring); + g_free (tmpstring); + + if (IS_300 (conn->response_code)) { + tmpstring = g_strdup_printf ("AUTHINFO pass %s", pass); + result = do_basic_command (conn, tmpstring); + g_free (tmpstring); + } + + if (result != GNOME_VFS_OK) { + /* login failed */ + g_warning ("NNTP server said: \"%d %s\"\n", conn->response_code, + conn->response_message); + gnome_vfs_socket_buffer_destroy (conn->socketbuf, FALSE); + gnome_vfs_inet_connection_destroy (conn->inet_connection, NULL); + g_free (conn); + return result; + } + } + *connptr = conn; + + total_connections++; + + /* g_message("successfully logged into server, total connections: %d", total_connections); */ + return GNOME_VFS_OK; +} + +/* destroy the connection object and deallocate the associated resources */ +static void +nntp_connection_destroy (NNTPConnection *conn) +{ + GnomeVFSResult result; + + if (conn->inet_connection) { + result = do_basic_command(conn, "QUIT"); + gnome_vfs_inet_connection_destroy (conn->inet_connection, NULL); + } + + if (conn->socketbuf) + gnome_vfs_socket_buffer_destroy (conn->socketbuf, FALSE); + + gnome_vfs_uri_unref (conn->uri); + + if (conn->response_buffer) + g_string_free(conn->response_buffer, TRUE); + + g_free (conn->response_message); + g_free (conn->server_type); + g_free (conn->buffer); + + g_free (conn); + total_connections--; +} + +/* hash routines for managing the pool of connections */ +/* g_str_hash and g_str_equal seem to fail with null arguments */ + +static int +my_str_hash (const char *c) +{ + if (c) + return g_str_hash (c); + else return 0; +} + +static int +my_str_equal (gconstpointer c, + gconstpointer d) +{ + if ((c && !d) || (d &&!c)) + return FALSE; + if (!c && !d) + return TRUE; + return g_str_equal (c,d); +} + +/* hash the bits of a GnomeVFSURI that distingush NNTP connections */ +guint +nntp_connection_uri_hash (gconstpointer c) +{ + GnomeVFSURI *uri = (GnomeVFSURI *) c; + + return my_str_hash (gnome_vfs_uri_get_host_name (uri)) + + my_str_hash (gnome_vfs_uri_get_user_name (uri)) + + my_str_hash (gnome_vfs_uri_get_password (uri)) + + gnome_vfs_uri_get_host_port (uri); +} + +/* test the equality of the bits of a GnomeVFSURI that distingush NNTP + * connections + */ +int +nntp_connection_uri_equal (gconstpointer c, + gconstpointer d) +{ + GnomeVFSURI *uri1 = (GnomeVFSURI *)c; + GnomeVFSURI *uri2 = (GnomeVFSURI *) d; + + return my_str_equal (gnome_vfs_uri_get_host_name(uri1), + gnome_vfs_uri_get_host_name (uri2)) && + my_str_equal (gnome_vfs_uri_get_user_name (uri1), + gnome_vfs_uri_get_user_name (uri2)) && + my_str_equal (gnome_vfs_uri_get_password (uri1), + gnome_vfs_uri_get_password (uri2)) && + gnome_vfs_uri_get_host_port (uri1) == + gnome_vfs_uri_get_host_port (uri2); +} + +static GnomeVFSResult +nntp_connection_acquire (GnomeVFSURI *uri, NNTPConnection **connection, GnomeVFSContext *context) +{ + GList *possible_connections; + NNTPConnection *conn = NULL; + GnomeVFSResult result = GNOME_VFS_OK; + + G_LOCK (spare_connections); + + if (spare_connections == NULL) { + spare_connections = g_hash_table_new (nntp_connection_uri_hash, + nntp_connection_uri_equal); + } + + possible_connections = g_hash_table_lookup (spare_connections, uri); + + if (possible_connections) { + /* spare connection(s) found */ + conn = (NNTPConnection *) possible_connections->data; + possible_connections = g_list_remove (possible_connections, conn); + + if(!g_hash_table_lookup (spare_connections, uri)) { + /* uri will be used as a key in the hashtable */ + uri = gnome_vfs_uri_dup (uri); + } + + g_hash_table_insert (spare_connections, uri, possible_connections); + + /* make sure connection hasn't timed out */ + result = do_basic_command(conn, "MODE READER"); + if (result != GNOME_VFS_OK) { + nntp_connection_destroy (conn); + result = nntp_connection_create (&conn, uri, context); + } + + } else { + result = nntp_connection_create (&conn, uri, context); + } + + G_UNLOCK (spare_connections); + + *connection = conn; + + if(result == GNOME_VFS_OK) allocated_connections++; + return result; +} + + +static void +nntp_connection_release (NNTPConnection *conn) +{ + GList *possible_connections; + GnomeVFSURI *uri; + + g_return_if_fail (conn); + + G_LOCK (spare_connections); + if (spare_connections == NULL) + spare_connections = + g_hash_table_new (nntp_connection_uri_hash, + nntp_connection_uri_equal); + + possible_connections = g_hash_table_lookup (spare_connections, + conn->uri); + possible_connections = g_list_append (possible_connections, conn); + + if (g_hash_table_lookup (spare_connections, conn->uri)) { + uri = conn->uri; /* no need to duplicate uri */ + } else { + /* uri will be used as key */ + uri = gnome_vfs_uri_dup (conn->uri); + } + g_hash_table_insert (spare_connections, uri, possible_connections); + allocated_connections--; + + G_UNLOCK(spare_connections); +} + +/* the following routines are the code for assembling the file list from the newsgroup headers. */ + +/* Here are the folder name filtering routines, which attempt to remove track numbers and other extraneous + * info from folder names, to make folder grouping work better. First, there are some character classifying + * helper routines + */ +static gboolean +is_number_or_space (char test_char) +{ + return g_ascii_isspace (test_char) || g_ascii_isdigit (test_char) + || test_char == '_' || test_char == '-' || test_char == '/'; +} + +static gboolean +all_numbers_or_spaces (char *left_ptr, char *right_ptr) +{ + char *current_char_ptr; + char current_char; + + current_char_ptr = left_ptr; + while (current_char_ptr < right_ptr) { + current_char = *current_char_ptr++; + if (!is_number_or_space(current_char)) { + return FALSE; + } + } + return TRUE; +} + +/* each of the next set of routines implement a specific filtering operation */ + +static void +remove_numbers_between_dashes(char *input_str) +{ + char *left_ptr, *right_ptr; + int length_to_end, segment_size; + + left_ptr = strchr (input_str, '-'); + while (left_ptr != NULL) { + right_ptr = strchr(left_ptr + 1, '-'); + if (right_ptr != NULL) { + segment_size = right_ptr - left_ptr; + if (all_numbers_or_spaces(left_ptr, right_ptr) && segment_size > 1) { + length_to_end = strlen(right_ptr + 1) + 1; + g_memmove(left_ptr, right_ptr + 1, length_to_end); + } else { + left_ptr = right_ptr; + } + + } else { + right_ptr = input_str + strlen(input_str) - 1; + if (all_numbers_or_spaces(left_ptr, right_ptr)) { + left_ptr = '\0'; + } + break; + } + } +} + + +static void +remove_number_at_end (char *input_str) +{ + char *space_ptr, *next_char; + gboolean is_digits; + + space_ptr = strrchr(input_str, ' '); + next_char = space_ptr + 1; + + if (space_ptr != NULL) { + is_digits = TRUE; + while (*next_char != '\0') { + if (!is_number_or_space (*next_char)) { + is_digits = FALSE; + break; + } + next_char += 1; + } + if (is_digits) { + *space_ptr = '\0'; + } + } +} + +static char* +trim_nonalpha_chars (char *input_str) +{ + char *left_ptr, *right_ptr; + + /* first handle the end of the string */ + right_ptr = input_str + strlen(input_str) - 1; + while (!g_ascii_isalnum (*right_ptr) && right_ptr > input_str) { + right_ptr -= 1; + } + + right_ptr += 1; + *right_ptr = '\0'; + + /* now handle the beginning */ + left_ptr = input_str; + while (*left_ptr && !g_ascii_isalnum(*left_ptr)) { + left_ptr++; + } + return left_ptr; +} + +static void +remove_of_expressions (char *input_str) +{ + char *left_ptr, *right_ptr; + int length_to_end; + gboolean found_number; + + left_ptr = strstr (input_str, "of"); + if (left_ptr == NULL) { + left_ptr = strstr (input_str, "OF"); + } + if (left_ptr == NULL) { + left_ptr = strstr (input_str, "/"); + } + + if (left_ptr != NULL) { + found_number = FALSE; + right_ptr = left_ptr + 2; + left_ptr = left_ptr - 1; + while (is_number_or_space(*left_ptr) && left_ptr >= input_str) { + found_number = found_number || g_ascii_isdigit(*left_ptr); + left_ptr -= 1; + } + while (is_number_or_space(*right_ptr)) { + found_number = found_number || g_ascii_isdigit(*right_ptr); + right_ptr += 1; + } + + if (found_number) { + length_to_end = strlen(right_ptr); + if (length_to_end > 0) { + g_memmove(left_ptr + 1, right_ptr, length_to_end + 1); + } else { + left_ptr += 1; + *left_ptr = '\0'; + } + } + } +} + +/* here is the main folder name filtering routine, which returns a new string containing the filtered + * version of the passed-in folder name + */ +static char * +filter_folder_name(char *folder_name) +{ + char *temp_str, *save_str, *result_str; + char *colon_ptr, *left_ptr, *right_ptr; + int length_to_end; + + temp_str = g_strdup(folder_name); + save_str = temp_str; + temp_str = g_strstrip(temp_str); + + /* if there is a colon, strip everything before it */ + colon_ptr = strchr(temp_str, ':'); + if (colon_ptr != NULL) { + temp_str = colon_ptr + 1; + } + + /* remove everything in brackets */ + left_ptr = strrchr(temp_str, '['); + if (left_ptr != NULL) { + right_ptr = strchr(left_ptr, ']'); + if (right_ptr != NULL && right_ptr > left_ptr) { + length_to_end = strlen(right_ptr + 1) + 1; + g_memmove(left_ptr, right_ptr + 1, length_to_end); + } + } + + /* eliminate "n of m" expressions */ + remove_of_expressions(temp_str); + + /* remove numbers at end of the string */ + remove_number_at_end(temp_str); + + /* remove numbers between dashes */ + remove_numbers_between_dashes(temp_str); + + /* trim leading and trailing non-alphanumeric characters */ + temp_str = trim_nonalpha_chars(temp_str); + + /* truncate if necessary */ + if (strlen(temp_str) > 30) { + left_ptr = temp_str + 29; + while (g_ascii_isalpha(*left_ptr)) { + left_ptr += 1; + } + + *left_ptr = '\0'; + } + + /* return the result */ + result_str = g_strdup(temp_str); + g_free(save_str); + return result_str; +} + +/* parse dates by allowing gnome-vfs to do most of the work */ + +static void +remove_commas(char *source_str) +{ + char *ptr; + + ptr = source_str; + while (*ptr != '\0') { + if (*ptr == ',') { + g_memmove(ptr, ptr+1, strlen(ptr)); + } else { + ptr += 1; + } + } +} + +static gboolean +is_number(char *input_str) { + char *cur_char; + + cur_char = input_str; + while (*cur_char) { + if (!g_ascii_isdigit(*cur_char)) { + return FALSE; + } + cur_char += 1; + } + return TRUE; +} + +static void +parse_date_string (const char* date_string, time_t *t) +{ + struct stat s; + char *filename, *linkname; + char *temp_str, *mapped_date; + gboolean result; + char **date_parts; + int offset; + + filename = NULL; + linkname = NULL; + + /* remove commas from day, and flip the day and month */ + date_parts = g_strsplit(date_string, " ", 0); + + if (is_number(date_parts[0])) { + offset = 0; + } else { + offset = 1; + remove_commas(date_parts[0]); + } + + temp_str = date_parts[offset]; + date_parts[offset] = date_parts[offset + 1]; + date_parts[offset + 1] = temp_str; + mapped_date = g_strjoinv(" ", date_parts); + + temp_str = g_strdup_printf("-rw-rw-rw- 1 500 500 %s x", mapped_date); + g_strfreev(date_parts); + g_free (mapped_date); + + result = gnome_vfs_parse_ls_lga (temp_str, &s, &filename, &linkname); + if (!result) { + g_message("error parsing %s, %s", date_string, temp_str); + } + + + g_free(temp_str); + *t = s.st_mtime; +} + +/* parse_header takes a message header an extracts the subject and id, and then + * parses the subject to get the file name and fragment sequence number + */ +static gboolean +parse_header(const char* header_str, char** filename, char** folder_name, char** message_id, + int* message_size, int* part_number, int* total_parts, time_t *mod_date) +{ + char* temp_str, *file_start; + char* left_paren, *right_paren, *slash_pos; + int slash_bump; + + char **header_parts; + gboolean has_count; + + *part_number = -1; + *total_parts = -1; + *message_size = 0; + + *filename = NULL; + *folder_name = NULL; + *message_id = NULL; + slash_pos = NULL; + + header_parts = g_strsplit(header_str, "\t", 0); + temp_str = g_strdup(header_parts[1]); + + *message_id = g_strdup(header_parts[4]); + + if (header_parts[6] != NULL) { + *message_size = atoi(header_parts[6]); + } + + parse_date_string(header_parts[3], mod_date); + + g_strfreev(header_parts); + + /* find the parentheses and extra the part number and total part count */ + + has_count = FALSE; + left_paren = strchr(temp_str,'('); + right_paren = strchr(temp_str, ')'); + + /* if we could't find parentheses, try braces */ + if (left_paren == NULL) { + left_paren = strchr(temp_str,'['); + right_paren = strchr(temp_str, ']'); + } + + while (!has_count && left_paren != NULL && right_paren != NULL) { + slash_pos = strchr(left_paren, '/'); + slash_bump = 1; + + if (slash_pos == NULL) { + slash_pos = strchr(left_paren, '-'); + } + if (slash_pos == NULL) { + slash_pos = strstr(left_paren, " of "); + slash_bump = 4; + } + + if (slash_pos != NULL) { + has_count = TRUE; + *slash_pos = '\0'; + *right_paren = '\0'; + + *part_number = atoi (left_paren + 1); + *total_parts = atoi (slash_pos + slash_bump); + } else { + left_paren = strchr(right_paren + 1, '('); + right_paren = strchr(right_paren + 1, ')'); + } + } + + if (!has_count) { + *part_number = 1; + *total_parts = 1; + } + + + /* isolate the filename and copy it to the result */ + if (has_count) { + *left_paren = '\0'; + file_start = strrchr (temp_str, '-'); + + if (file_start == NULL) { + return FALSE; + } + + *filename = g_strdup (g_strstrip (file_start + 1)); + *file_start = '\0'; + *folder_name = filter_folder_name (temp_str); + } else + { + *filename = g_strdup (temp_str); + } + + g_free(temp_str); + return TRUE; +} + + +/* create a new file fragment structure */ +static nntp_fragment* +nntp_fragment_new(int fragment_number, char* fragment_id, int fragment_size) +{ + nntp_fragment* new_fragment = (nntp_fragment*) g_malloc (sizeof (nntp_fragment)); + new_fragment->fragment_number = fragment_number; + new_fragment->fragment_id = g_strdup (fragment_id); + new_fragment->fragment_size = fragment_size; + new_fragment->bytes_read = 0; + + return new_fragment; +} + +/* deallocate the passed in file fragment */ +static void +nntp_fragment_destroy(nntp_fragment* fragment) +{ + g_free(fragment->fragment_id); + g_free(fragment); +} + +/* utility routine to map slashes to dashes in the passed in string so we never return + * a filename with slashes + */ +static char * +map_slashes(char *str) +{ + char *current_ptr; + + current_ptr = str; + while (*current_ptr != '\0') { + if (*current_ptr == '/') { + *current_ptr = '-'; + } + current_ptr += 1; + } + return str; +} + +/* allocate a file object */ +static nntp_file* +nntp_file_new(char* file_name, char *folder_name, int total_parts) +{ + + nntp_file* new_file = (nntp_file*) g_malloc (sizeof (nntp_file)); + + if (strlen(map_slashes(file_name)) < 1) { + file_name = "(Empty)"; + } + + new_file->file_name = map_slashes(g_strdup(file_name)); + new_file->folder_name = g_strdup(folder_name); + + new_file->file_type = NULL; + new_file->part_list = NULL; + + new_file->file_size = 0; + new_file->total_parts = total_parts; + new_file->is_directory = FALSE; + + return new_file; +} + +/* deallocate a file object */ +static void +nntp_file_destroy (nntp_file* file) +{ + GList *current_part; + + g_free(file->file_name); + g_free(file->folder_name); + + current_part = file->part_list; + while (current_part != NULL) { + if (file->is_directory) { + nntp_file_destroy((nntp_file*) current_part->data); + } else { + nntp_fragment_destroy((nntp_fragment*) current_part->data); + } + current_part = current_part->next; + } + + g_list_free(file->part_list); + g_free(file); +} + + +/* look up a fragment in a file */ +static nntp_fragment* +nntp_file_look_up_fragment (nntp_file *file, int fragment_number) +{ + nntp_fragment *fragment; + GList *current_fragment = file->part_list; + while (current_fragment != NULL) { + fragment = (nntp_fragment*) current_fragment->data; + if (fragment->fragment_number == fragment_number) { + return fragment; + } + current_fragment = current_fragment->next; + } + return NULL; +} + +/* compute the total size of a file by adding up the size of its fragments, then scale down by 3/4 to account for + * the uu or base64 encoding + */ +static int +nntp_file_get_total_size (nntp_file *file) +{ + nntp_fragment *fragment; + int total_size; + GList *current_fragment; + + total_size = 0; + current_fragment = file->part_list; + while (current_fragment != NULL) { + fragment = (nntp_fragment*) current_fragment->data; + total_size += fragment->fragment_size - 800; /* subtract out average header size */ + + current_fragment = current_fragment->next; + } + + return 3 * total_size / 4; +} + +/* add a fragment to a file */ +static void +nntp_file_add_part (nntp_file *file, int fragment_number, char* fragment_id, int fragment_size) +{ + /* make sure we don't already have this fragment */ + /* note: this isn't good for threads, where more than one message has the same subject line, + * so we really should collect them instead of discarding all but the first */ + + if (nntp_file_look_up_fragment (file, fragment_number) == NULL) { + nntp_fragment* fragment = nntp_fragment_new (fragment_number, fragment_id, fragment_size); + file->part_list = g_list_append (file->part_list, fragment); + } +} + + +/* look up a file object in the file list from its name; avoid lookup if same as last time (soon) */ +static nntp_file* +look_up_file (GList *file_list, char *filename, gboolean is_directory) +{ + nntp_file* file; + GList* current_file = file_list; + while (current_file != NULL) { + file = (nntp_file*) current_file->data; + if (g_ascii_strcasecmp( file->file_name, filename) == 0 && + file->is_directory == is_directory) { + return file; + } + current_file = current_file->next; + } + return NULL; +} + +/* start reading the article associated with the passed in fragment */ +static GnomeVFSResult +start_loading_article (NNTPConnection *conn, nntp_fragment *fragment) +{ + GnomeVFSResult result; + char *command_str; + char *line = NULL; + + /* issue the command to fetch the article */ + command_str = g_strdup_printf("BODY %s", fragment->fragment_id); + result = do_control_write(conn, command_str); + g_free(command_str); + + if (result != GNOME_VFS_OK) { + return result; + } + + /* read the response command, and check that it's the right number (eventually) */ + result = read_response_line (conn, &line); + g_free(line); + if (result != GNOME_VFS_OK) { + return result; + } + + conn->request_in_progress = TRUE; + return GNOME_VFS_OK; +} + +/* utility routine to uudecode the passed in text. Translate every four 6-bit bytes to 3 8 bit ones */ +static int +uu_decode_text(char *text_buffer, int text_len) +{ + int input_index, output_index; + int byte_0, byte_1, byte_2, byte_3; + + input_index = 1; /* skip length byte */ + output_index = 0; + while (input_index < text_len) { + byte_0 = text_buffer[input_index] - 32; + byte_1 = text_buffer[input_index + 1] - 32; + byte_2 = text_buffer[input_index + 2] - 32; + byte_3 = text_buffer[input_index + 3] - 32; + + text_buffer[output_index] = ((byte_0 << 2) & 252) | ((byte_1 >> 4) & 3); + text_buffer[output_index + 1] = ((byte_1 << 4) & 240) | ((byte_2 >> 2) & 15); + text_buffer[output_index + 2] = ((byte_2 << 6) & 192) | (byte_3 & 63); + + input_index += 4; + output_index += 3; + } + return output_index; +} + +/* utility to decode the passed in text using base 64 */ + +static int +base_64_map(char input_char) +{ + if (input_char >= 'A' && input_char <= 'Z') { + return input_char - 'A'; + } + + if (input_char >= 'a' && input_char <= 'z') { + return 26 + input_char - 'a'; + } + + if (input_char >= '0' && input_char <= '9') { + return 52 + input_char - '0'; + } + + if (input_char == '+') { + return 62; + } + + if (input_char == '/') { + return 63; + } + + if (input_char == '=') { + return 0; + } + + /* not a valid character, so return -1 */ + return -1; +} + +static int +base_64_decode_text(char* text_buffer, int text_len) +{ + int input_index, output_index; + int byte_0, byte_1, byte_2, byte_3; + + input_index = 1; /* skip length byte */ + output_index = 0; + while (input_index < text_len) { + byte_0 = base_64_map(text_buffer[input_index]); + byte_1 = base_64_map(text_buffer[input_index + 1]); + byte_2 = base_64_map(text_buffer[input_index + 2]); + byte_3 = base_64_map(text_buffer[input_index + 3]); + + /* if we hit a return, we're done */ + if (text_buffer[input_index] < 32) { + return output_index; + } + + /* if there are any unmappable characters, skip this line */ + if (byte_0 < 0 || byte_1 < 0 || byte_2 < 0 || byte_3 < 0) { + return 0; + } + + /* shift the bits into place and output them */ + text_buffer[output_index] = ((byte_0 << 2) & 252) | ((byte_1 >> 4) & 3); + text_buffer[output_index + 1] = ((byte_1 << 4) & 240) | ((byte_2 >> 2) & 15); + text_buffer[output_index + 2] = ((byte_2 << 6) & 192) | (byte_3 & 63); + + input_index += 4; + output_index += 3; + } + return output_index; +} + +/* utility that returns true if all the characters in the passed in line are valide for uudecoding */ +static gboolean +line_in_decode_range(char* input_line) +{ + char *line_ptr; + char current_char; + + line_ptr = input_line; + while (*line_ptr != '\0') { + current_char = *line_ptr++; + if (current_char < 32 || current_char > 95) { + return FALSE; + } + } + return TRUE; +} + +/* fill the buffer from the passed in article fragment. If the first line flag is set, + * test to see if uudecoding is required. + */ +static GnomeVFSResult +load_from_article (NNTPConnection *conn, nntp_fragment *fragment, gboolean first_line_flag) +{ + GnomeVFSResult result; + char *line = NULL; + char *dest_ptr; + int buffer_offset; + int line_len; + + /* loop, loading the article into the buffer */ + buffer_offset = 0; + + while (buffer_offset < conn->buffer_size - 1024) { + result = read_response_line (conn, &line); + if (first_line_flag && !conn->uu_decode_mode && !conn->base_64_decode_mode) { + /* FIXME: should apply additional checks here for the permission flags, etc */ + if (strncmp(line, "begin ", 6) == 0) { + conn->uu_decode_mode = TRUE; + g_free (line); + buffer_offset = 0; + continue; + } else if (strncmp(line, "Content-Transfer-Encoding: base64", 33) == 0) { + conn->base_64_decode_mode = TRUE; + g_free (line); + buffer_offset = 0; + continue; + } else if (line[0] == 'M' && strlen(line) == 61 && line_in_decode_range(line)) { + conn->uu_decode_mode = TRUE; + buffer_offset = 0; + } + + } + + if (line[0] != '.' && line[1] != '\r') { + line_len = strlen(line); + if (buffer_offset + line_len > conn->buffer_size) { + g_message("Error! exceeded buffer! %d", buffer_offset + line_len); + line_len = conn->buffer_size - buffer_offset; + } + dest_ptr = (char*) conn->buffer + buffer_offset; + g_memmove(dest_ptr, line, line_len); + if (conn->uu_decode_mode) { + line_len = uu_decode_text(dest_ptr, line_len); + buffer_offset += line_len; + fragment->bytes_read += line_len; + } else if (conn->base_64_decode_mode) { + line_len = base_64_decode_text(dest_ptr, line_len); + buffer_offset += line_len; + fragment->bytes_read += line_len; + } else { + buffer_offset += line_len + 1; + dest_ptr += line_len; + *dest_ptr = '\n'; + fragment->bytes_read += line_len + 1; + } + } else { + g_free(line); + conn->request_in_progress = FALSE; + break; + } + g_free(line); + } + conn->amount_in_buffer = buffer_offset; + conn->buffer_offset = 0; + + return GNOME_VFS_OK; +} + +/* load data from the current file fragment, advancing to a new one if necessary */ +static GnomeVFSResult +load_file_fragment(NNTPConnection *connection) +{ + nntp_fragment *fragment; + GnomeVFSResult result; + gboolean first_line_flag; + + first_line_flag = FALSE; + if (!connection->request_in_progress) { + if (connection->current_fragment == NULL) { + connection->current_fragment = connection->current_file->part_list; + first_line_flag = TRUE; + } else { + connection->current_fragment = connection->current_fragment->next; + if (connection->current_fragment == NULL) { + connection->eof_flag = TRUE; + return GNOME_VFS_ERROR_EOF; + } + } + fragment = (nntp_fragment *) connection->current_fragment->data; + result = start_loading_article(connection, fragment); + } + + if (connection->current_fragment == NULL) { + connection->eof_flag = TRUE; + return GNOME_VFS_ERROR_EOF; + } + + fragment = (nntp_fragment *) connection->current_fragment->data; + result = load_from_article(connection, fragment, first_line_flag); + return result; +} + +/* calculate the size of the data remaining in the buffer */ +static int +bytes_in_buffer(NNTPConnection *connection) +{ + return connection->amount_in_buffer - connection->buffer_offset; +} + +/* utility routine to move bytes from the fragment to the application */ +static int +copy_bytes_from_buffer(NNTPConnection *connection, + gpointer destination_buffer, + int bytes_to_read, + GnomeVFSFileSize *bytes_read) +{ + int size_to_move; + + size_to_move = bytes_in_buffer(connection); + if (size_to_move == 0) { + return 0; + } + + if (bytes_to_read < size_to_move) { + size_to_move = bytes_to_read; + } + /* move the bytes from the buffer */ + g_memmove(destination_buffer, ((char*) connection->buffer) + connection->buffer_offset, size_to_move); + + /* update the counts */ + connection->buffer_offset += size_to_move; + *bytes_read += size_to_move; + return size_to_move; +} + +/* read a byte range from the active connection */ +static GnomeVFSResult +nntp_file_read(NNTPConnection *connection, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read) +{ + int bytes_to_read; + GnomeVFSResult result; + + /* loop, loading fragments and copying data until the request is fulfilled or + * we're out of fragments + */ + bytes_to_read = num_bytes; + *bytes_read = 0; + while (bytes_to_read > 0) { + bytes_to_read -= copy_bytes_from_buffer(connection, ((char*) buffer) + *bytes_read, bytes_to_read, bytes_read); + if (bytes_to_read > bytes_in_buffer(connection)) { + if (connection->eof_flag) { + /* don't return EOF here as it will cause the last part to be discarded */ + return GNOME_VFS_OK; + } + result = load_file_fragment(connection); + } + } + return GNOME_VFS_OK; +} + +/* deallocate the passed in file list */ +static void +free_nntp_file_list (GList *file_list) +{ + GList* current_file; + if (file_list == NULL) { + return; + } + + current_file = file_list; + while (current_file != NULL) { + nntp_file_destroy ((nntp_file*) current_file->data); + current_file = current_file->next; + } + g_list_free (file_list); +} + +/* utility to obtain authorization info from gnome-vfs */ +static void +get_auth_info (NNTPConnection *conn, char** user, char** password) +{ + GnomeVFSResult res; + GnomeVFSModuleCallbackAuthenticationIn in_args; + GnomeVFSModuleCallbackAuthenticationOut out_args; + + *user = NULL; + *password = NULL; + + memset (&in_args, 0, sizeof (in_args)); + memset (&out_args, 0, sizeof (out_args)); + + in_args.uri = gnome_vfs_uri_to_string(conn->uri, 0); + res = gnome_vfs_module_callback_invoke (GNOME_VFS_MODULE_CALLBACK_AUTHENTICATION, + &in_args, sizeof (in_args), + &out_args, sizeof (out_args)); + g_free(in_args.uri); + + *user = out_args.username; + *password = out_args.password; +} + +/* key routine to load the newsgroup overview and return a list of nntp_file objects. + * It maintains a cache to avoid reloading. + * + * FIXME: for now, we use a single element cache, but eventually we want to cache multiple newsgroups + * also, we eventually want to reload it if enough time has passed + */ +static GnomeVFSResult +get_files_from_newsgroup (NNTPConnection *conn, const char* newsgroup_name, GList** result_file_list) +{ + GnomeVFSResult result; + char *group_command, *tmpstring; + int first_message, last_message, total_messages; + char *command_str; + GList *file_list; + gchar *user, *pass; + + /* see if we can load it from the cache */ + if (current_newsgroup_name != NULL && g_ascii_strcasecmp (newsgroup_name, current_newsgroup_name) == 0) { + *result_file_list = current_newsgroup_files; + return GNOME_VFS_OK; + } + + *result_file_list = NULL; + + /* we don't have it in the cache, so load it from the server */ + if (current_newsgroup_name != NULL) { + free_nntp_file_list (current_newsgroup_files); + g_free (current_newsgroup_name); + current_newsgroup_name = NULL; + } + + group_command = g_strdup_printf ("GROUP %s", newsgroup_name); + + result = do_basic_command (conn, group_command); + g_free (group_command); + + if (result != GNOME_VFS_OK || conn->response_code != 211) { + /* if we're anonymous, prompt for a password and try that */ + if (conn->anonymous) { + get_auth_info(conn, &user, &pass); + + if (user != NULL) { + conn->anonymous = FALSE; + tmpstring = g_strdup_printf ("AUTHINFO user %s", user); + result = do_basic_command (conn, tmpstring); + g_free (tmpstring); + + if (IS_300 (conn->response_code)) { + tmpstring = g_strdup_printf ("AUTHINFO pass %s", pass); + result = do_basic_command (conn, tmpstring); + g_free (tmpstring); + + group_command = g_strdup_printf ("GROUP %s", newsgroup_name); + result = do_basic_command (conn, group_command); + g_free (group_command); + + } + } + g_free (user); + g_free (pass); + } + + if (result != GNOME_VFS_OK || conn->response_code != 211) { + g_message ("couldnt set group to %s, code %d", newsgroup_name, conn->response_code); + return GNOME_VFS_ERROR_NOT_FOUND; /* could differentiate error better */ + } + } + + sscanf (conn->response_message, "%d %d %d", &total_messages, &first_message, &last_message); + + /* read in the header and build the file list for the connection */ + if ((last_message - first_message) > MAX_MESSAGE_COUNT) { + first_message = last_message - MAX_MESSAGE_COUNT; + } + + command_str = g_strdup_printf ("XOVER %d-%d", first_message, last_message); + file_list = assemble_files_from_overview (conn, command_str); + g_free (command_str); + + current_newsgroup_name = g_strdup (newsgroup_name); + current_newsgroup_files = file_list; + + *result_file_list = file_list; + return GNOME_VFS_OK; +} + +/* utility to strip leading and trailing slashes from a string. It frees the input string and + * returns a new one + */ +static char* +strip_slashes (char* source_string) +{ + char *temp_str, *result_str; + int last_offset; + + temp_str = source_string; + if (temp_str[0] == '/') { + temp_str += 1; + } + last_offset = strlen(temp_str) - 1; + if (temp_str[last_offset] == '/') { + temp_str[last_offset] = '\0'; + } + + result_str = g_strdup(temp_str); + g_free(source_string); + return result_str; +} + +/* parse the uri to extract the newsgroup name and the file name */ +static void +extract_newsgroup_and_filename(GnomeVFSURI *uri, char** newsgroup, char **directory, char **filename) +{ + char *dirname, *slash_pos; + + *filename = gnome_vfs_unescape_string(gnome_vfs_uri_extract_short_name (uri), ""); + *directory = NULL; + + dirname = strip_slashes(gnome_vfs_uri_extract_dirname(uri)); + + *newsgroup = gnome_vfs_unescape_string (dirname, ""); + slash_pos = strchr (*newsgroup, '/'); + if (slash_pos != NULL) { + *slash_pos = '\0'; + *directory = g_strdup (slash_pos + 1); + } + g_free (dirname); +} + +/* fetch the nntp_file object from the passed in uri */ +static nntp_file* +nntp_file_from_uri (NNTPConnection *conn, GnomeVFSURI *uri) +{ + GnomeVFSResult result; + char *newsgroup_name, *file_name, *directory_name; + nntp_file *file; + GList *file_list; + + /* extract the newsgroup name */ + extract_newsgroup_and_filename(uri, &newsgroup_name, &directory_name, &file_name); + + /* load the (cached) file list */ + result = get_files_from_newsgroup (conn, newsgroup_name, &file_list); + if (file_list == NULL) { + file = NULL; + } else { + /* parse the uri into the newsgroup and file */ + if (directory_name != NULL) { + file = look_up_file (file_list, directory_name, TRUE); + if (file != NULL) { + file = look_up_file (file->part_list, file_name, FALSE); + } + } else { + file = look_up_file (file_list, file_name, FALSE); + } + } + + g_free(newsgroup_name); + g_free(file_name); + g_free(directory_name); + + return file; +} + +/* determine if a file has all of it's fragments */ +static gboolean +has_all_fragments (nntp_file *file) +{ + return g_list_length (file->part_list) >= file->total_parts; +} + +/* add a file fragment to the file list, creating a new file object if necessary */ +static GList *add_file_fragment(GList* file_list, char* filename, char* folder_name, char* fragment_id, int fragment_size, + int part_number, int part_total, time_t mod_date) +{ + nntp_file *base_file; + + /* don't use part 0 */ + if (part_number == 0) { + return file_list; + } + + /* get the file object associated with the filename if any */ + base_file = look_up_file(file_list, filename, FALSE); + if (base_file == NULL) { + base_file = nntp_file_new(filename, folder_name, part_total); + base_file->mod_date = mod_date; + file_list = g_list_append(file_list, base_file); + } + + /* add the fragment to the file */ + nntp_file_add_part(base_file, part_number, fragment_id, fragment_size); + return file_list; +} + +/* remove any partial files from the file list */ +static GList *remove_partial_files (GList *file_list) +{ + nntp_file* file; + + GList* next_file; + GList* current_file = file_list; + + while (current_file != NULL) { + next_file = current_file->next; + file = (nntp_file*) current_file->data; + if (!has_all_fragments (file)) { + file_list = g_list_remove_link (file_list, current_file); + nntp_file_destroy (file); + } + current_file = next_file; + } + return file_list; +} + + +/* loop through the file list to update the size fields */ +static void +update_file_sizes(GList *file_list) +{ + nntp_file* file; + GList* current_file = file_list; + + while (current_file != NULL) { + file = (nntp_file*) current_file->data; + file->file_size = nntp_file_get_total_size(file); + current_file = current_file->next; + } +} + +/* the following set of routines are used to group the files into psuedo-directories by using + * a hash table containing lists of nntp_file objects. + */ + +/* add the passed in file's foldername to the hash table */ +static void +add_file_to_folder (GHashTable *folders, nntp_file *file) +{ + GList *folder_contents; + + if (file->folder_name == NULL) { + return; + } + + folder_contents = g_hash_table_lookup (folders, file->folder_name); + if (folder_contents != NULL) { + g_list_append(folder_contents, file); + } else { + folder_contents = g_list_append(NULL, file); + g_hash_table_insert (folders, g_strdup(file->folder_name), folder_contents); + } +} + +/* remove non-singleton files that are contained in folders from the file list */ +static void +remove_file_from_list (gpointer key, gpointer value, gpointer callback_data) +{ + GList *element_list; + nntp_file* file; + GList** file_list_ptr; + + file_list_ptr = (GList**) callback_data; + element_list = (GList*) value; + + /* if there is more than one element in the list, remove all of them from the file list */ + if (element_list != NULL && g_list_length(element_list) > 1) { + while (element_list != NULL) { + file = (nntp_file*) element_list->data; + *file_list_ptr = g_list_remove(*file_list_ptr, element_list->data); + element_list = element_list->next; + } + } +} + +static void +remove_contained_files(GHashTable *folders, GList** file_list_ptr) +{ + /* iterate through the passed in hash table to find the files to remove */ + g_hash_table_foreach (folders, remove_file_from_list, file_list_ptr); +} + +/* utility routine to calculate a folder's mod-date by inspecting the dates of it's constituents */ +static void +calculate_folder_mod_date (nntp_file *folder) +{ + time_t latest_mod_date; + GList *current_file; + nntp_file* current_file_data; + + latest_mod_date = 0; + current_file = folder->part_list; + while (current_file != NULL) { + current_file_data = (nntp_file*) current_file->data; + if (current_file_data->mod_date > latest_mod_date) { + latest_mod_date = current_file_data->mod_date; + } + current_file = current_file->next; + } + folder->mod_date = latest_mod_date; +} + +/* generate folder objects from the entries in the hash table */ +static void +generate_folder_from_element (gpointer key, gpointer value, gpointer callback_data) +{ + GList *element_list; + int number_of_elements; + nntp_file *new_folder; + char* key_as_string; + GList** file_list_ptr; + + file_list_ptr = (GList**) callback_data; + element_list = (GList*) value; + key_as_string = (char*) key; + + number_of_elements = g_list_length(element_list); + if (number_of_elements > 1) { + if (strlen(key_as_string) == 0) { + key_as_string = "Unknown Title"; + } + + new_folder = nntp_file_new (key_as_string, NULL, number_of_elements); + new_folder->is_directory = TRUE; + new_folder->file_type = g_strdup ("x-directory/normal"); + new_folder->part_list = g_list_copy (element_list); + + calculate_folder_mod_date (new_folder); + + *file_list_ptr = g_list_append (*file_list_ptr, new_folder); + } +} + +static void +generate_folders(GHashTable *folders, GList** file_list_ptr) +{ + /* iterate through the passed in hash table to generate a folder for each non-singleton entry */ + g_hash_table_foreach (folders, generate_folder_from_element, file_list_ptr); +} + +/* helper routine to deallocate hash table elements */ +static gboolean +destroy_element (gpointer key, gpointer value, gpointer data) +{ + g_free(key); + g_list_free((GList*) value); + return TRUE; +} + +/* deallocate the data structures associate with the folder hash table */ +static void +destroy_folder_hash(GHashTable *folders) +{ + /* iterate through the hash table to destroy the lists it contains, before destroying + *the table itself + */ + g_hash_table_foreach_remove (folders, destroy_element, NULL); + g_hash_table_destroy(folders); +} + +/* walk through the file list and try to generate folders to group files with similar subjects */ +static GList* +assemble_folders (GList *file_list) +{ + GList *current_item; + nntp_file *current_file; + GHashTable *folders; + GList* file_list_ptr; + + /* need indirection for file list head */ + file_list_ptr = file_list; + + /* make a pass through the files grouping the ones with matching foldernames. Use a hash + * table for fast lookups + */ + folders = g_hash_table_new (g_str_hash, g_str_equal); + current_item = file_list_ptr; + + while (current_item != NULL) { + current_file = (nntp_file*) current_item->data; + if (current_file->folder_name != NULL) { + add_file_to_folder (folders, current_file); + } + current_item = current_item->next; + } + + /* make a pass through the folder list to remove contained files from the file list */ + remove_contained_files (folders, &file_list_ptr); + + /* generate folders from the hash table (not singletons) */ + generate_folders (folders, &file_list_ptr); + + /* deallocate resources now that we're done */ + destroy_folder_hash (folders); + + return file_list_ptr; +} + +/* this is the main loop for assembling the files. It issues the passed in + * overview command and then reads the headers one at a time, processing the + * fragments into a list of files + */ +static GList* +assemble_files_from_overview (NNTPConnection *conn, char *command) +{ + GnomeVFSResult result; + char *line = NULL; + int message_size; + int part_number, total_parts; + char* filename, *folder_name, *message_id; + GList *file_list; + time_t mod_date; + + file_list = NULL; + + /* issue the overview command to the server */ + result = do_control_write (conn, command); + + if (result != GNOME_VFS_OK) { + return file_list; + } + + /* read the response command, and check that it's the right number (eventually) */ + result = read_response_line (conn, &line); + g_free(line); + + if (result != GNOME_VFS_OK) { + return file_list; + } + + while (TRUE) { + result = read_response_line (conn, &line); + if (line[0] != '.' && line[1] != '\r') { + if (parse_header (line, &filename, &folder_name, &message_id, &message_size, &part_number, &total_parts, &mod_date)) { + file_list = add_file_fragment (file_list, filename, folder_name, message_id, message_size, + part_number, total_parts, mod_date); + g_free (filename); + g_free (folder_name); + g_free (message_id); + } + } else { + break; + } + g_free(line); + } + + file_list = remove_partial_files (file_list); + update_file_sizes (file_list); + file_list = assemble_folders (file_list); + + return file_list; +} + +/* newsgroup files aren't local */ +gboolean +do_is_local (GnomeVFSMethod *method, + const GnomeVFSURI *uri) +{ + return FALSE; +} + +static void +prepare_to_read_file (NNTPConnection *conn, nntp_file *file) +{ + conn->current_file = file; + conn->current_fragment = NULL; + conn->buffer_offset = 0; + conn->amount_in_buffer = 0; + conn->eof_flag = FALSE; + conn->uu_decode_mode = FALSE; + conn->base_64_decode_mode = FALSE; + + nntp_connection_reset_buffer (conn); +} + +static GnomeVFSResult +do_open (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + NNTPConnection *conn; + nntp_file *file; + const char* basename; + + /* we can save allocating a connection to search for the .directory file */ + basename = gnome_vfs_uri_extract_short_name(uri); + if (strcmp(basename, ".directory") == 0) { + return GNOME_VFS_ERROR_NOT_FOUND; + } + + result = nntp_connection_acquire (uri, &conn, context); + if (result != GNOME_VFS_OK) + return result; + + /* make sure we have the file */ + file = nntp_file_from_uri(conn, uri); + if (file == NULL) { + nntp_connection_release (conn); + return GNOME_VFS_ERROR_NOT_FOUND; + } else { + prepare_to_read_file (conn, file); + } + + if (result == GNOME_VFS_OK) { + *method_handle = (GnomeVFSMethodHandle *) conn; + } else { + *method_handle = NULL; + nntp_connection_release (conn); + } + return result; +} + +static GnomeVFSResult +do_close (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + NNTPConnection *conn = (NNTPConnection *) method_handle; + + nntp_connection_release (conn); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_read (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read, + GnomeVFSContext *context) +{ + NNTPConnection *conn = (NNTPConnection * )method_handle; + return nntp_file_read(conn, buffer, num_bytes, bytes_read); +} + +static GnomeVFSResult +do_get_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + const char* host_name; + const char* temp_str, *first_slash; + + GnomeVFSURI *parent = gnome_vfs_uri_get_parent (uri); + GnomeVFSResult result; + + host_name = gnome_vfs_uri_get_host_name(uri); + if (host_name == NULL) { + return GNOME_VFS_ERROR_INVALID_HOST_NAME; + } + + /* if it's the top level newsgroup, treat it like a directory */ + temp_str = gnome_vfs_uri_get_path(uri); + first_slash = strchr(temp_str + 1, '/'); + if (parent == NULL || first_slash == NULL) { + /* this is a request for info about the root directory */ + file_info->name = g_strdup("/"); + file_info->type = GNOME_VFS_FILE_TYPE_DIRECTORY; + file_info->mime_type = g_strdup ("x-directory/normal"); + file_info->permissions = GNOME_VFS_PERM_USER_READ | GNOME_VFS_PERM_GROUP_READ | + GNOME_VFS_PERM_OTHER_READ; + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_TYPE | + GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE | + GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS; + + return GNOME_VFS_OK; + } else { + GnomeVFSMethodHandle *method_handle; + char *name; + + result = do_open_directory (method, &method_handle, parent, + options, context); + gnome_vfs_uri_unref (parent); + + if (result != GNOME_VFS_OK) { + return result; + } + + name = gnome_vfs_uri_extract_short_name (uri); + while (result == GNOME_VFS_OK) { + result = do_read_directory (method, method_handle, + file_info, context); + if (result == GNOME_VFS_OK) { + if (file_info->name && !strcmp (file_info->name, + name)) { + g_free (name); + do_close_directory( + method, method_handle, + context); + return GNOME_VFS_OK; + } + + gnome_vfs_file_info_clear (file_info); + } + } + do_close_directory(method, method_handle, context); + } + + return GNOME_VFS_ERROR_NOT_FOUND; +} + +static GnomeVFSResult +do_get_file_info_from_handle (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + return do_get_file_info (method, + ((NNTPConnection *)method_handle)->uri, + file_info, options, context); +} + +static GnomeVFSResult +do_open_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + const char *newsgroup_server; + char *newsgroup_name; + char *directory_name, *mapped_dirname; + + NNTPConnection *conn; + GnomeVFSResult result; + nntp_file *file; + GList *file_list; + + newsgroup_server = gnome_vfs_uri_get_host_name (uri); + newsgroup_name = gnome_vfs_uri_extract_dirname (uri); + directory_name = g_strdup (gnome_vfs_uri_extract_short_name (uri)); + + if (strcmp (newsgroup_name, "/") == 0 || strlen(newsgroup_name) == 0) { + g_free (newsgroup_name); + newsgroup_name = directory_name; + directory_name = NULL; + } + + if (newsgroup_name == NULL) { + g_free(directory_name); + return GNOME_VFS_ERROR_NOT_FOUND; + } + + newsgroup_name = strip_slashes (newsgroup_name); + result = nntp_connection_acquire (uri, &conn, context); + if (result != GNOME_VFS_OK) { + g_free (newsgroup_name); + g_free (directory_name); + return result; + } + + /* get the files from the newsgroup */ + result = get_files_from_newsgroup (conn, newsgroup_name, &file_list); + if (result != GNOME_VFS_OK) { + g_free (newsgroup_name); + g_free (directory_name); + nntp_connection_release(conn); + return result; + } + + if (directory_name == NULL) { + conn->next_file = file_list; + } else { + if (file_list == NULL) { + file = NULL; + } else { + mapped_dirname = gnome_vfs_unescape_string (directory_name, ""); + file = look_up_file (file_list, mapped_dirname, TRUE); + g_free (mapped_dirname); + } + + if (file == NULL) { + g_message ("couldnt find file %s", directory_name); + return GNOME_VFS_ERROR_NOT_FOUND; + } + if (file->is_directory) { + conn->next_file = file->part_list; + } else { + conn->next_file = NULL; + } + } + + if (result != GNOME_VFS_OK) { + g_message ("couldnt set group!"); + nntp_connection_release (conn); + + g_free (newsgroup_name); + g_free (directory_name); + return result; + } + *method_handle = (GnomeVFSMethodHandle *) conn; + + g_free (newsgroup_name); + g_free (directory_name); + + return result; +} + +static GnomeVFSResult +do_close_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + NNTPConnection *conn = (NNTPConnection *) method_handle; + + nntp_connection_release (conn); + + return GNOME_VFS_OK; +} + + +static GnomeVFSResult +do_read_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSContext *context) +{ + NNTPConnection *conn = (NNTPConnection *) method_handle; + nntp_file *file_data; + const char* mime_string; + + if (!conn->next_file) + return GNOME_VFS_ERROR_EOF; + + /* fill out the information for the current file, and bump the pointer */ + gnome_vfs_file_info_clear(file_info); + + /* implement the size threshold by skipping files smaller than the threshold */ + file_data = (nntp_file*) conn->next_file->data; + while (file_data->file_size < MIN_FILE_SIZE_THRESHOLD && !file_data->is_directory) { + conn->next_file = conn->next_file->next; + if (conn->next_file == NULL) { + return GNOME_VFS_ERROR_EOF; + } else { + file_data = (nntp_file*) conn->next_file->data; + } + } + + file_info->name = g_strdup(file_data->file_name); + + file_info->permissions = GNOME_VFS_PERM_USER_READ | GNOME_VFS_PERM_GROUP_READ | + GNOME_VFS_PERM_USER_WRITE |GNOME_VFS_PERM_OTHER_READ; + + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_TYPE | + GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE | + GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS | + GNOME_VFS_FILE_INFO_FIELDS_MTIME; + + /* handle the case when it's a directory */ + if (file_data->is_directory) { + file_info->type = GNOME_VFS_FILE_TYPE_DIRECTORY; + file_info->mime_type = g_strdup ("x-directory/normal"); + file_info->mtime = file_data->mod_date; + file_info->permissions = GNOME_VFS_PERM_USER_READ | GNOME_VFS_PERM_GROUP_READ | + GNOME_VFS_PERM_USER_WRITE | + GNOME_VFS_PERM_OTHER_READ | GNOME_VFS_PERM_USER_EXEC | + GNOME_VFS_PERM_GROUP_EXEC | GNOME_VFS_PERM_OTHER_EXEC; + } else { + + file_info->type = GNOME_VFS_FILE_TYPE_REGULAR; + + file_info->mtime = file_data->mod_date; + + /* figure out the mime type from the extension; if it's unrecognized, use "text/plain" + * instead of "application/octet-stream" + */ + mime_string = gnome_vfs_mime_type_from_name(file_data->file_name); + if (strcmp(mime_string, "application/octet-stream") == 0) { + file_info->mime_type = g_strdup("text/plain"); + } else { + file_info->mime_type = g_strdup(mime_string); + } + + file_info->size = file_data->file_size; + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_SIZE; + } + + conn->next_file = conn->next_file->next; + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_check_same_fs (GnomeVFSMethod *method, + GnomeVFSURI *a, + GnomeVFSURI *b, + gboolean *same_fs_return, + GnomeVFSContext *context) +{ + *same_fs_return = nntp_connection_uri_equal (a,b); + return GNOME_VFS_OK; +} + +static GnomeVFSMethod method = { + sizeof (GnomeVFSMethod), + do_open, + NULL, /* create */ + do_close, + do_read, + NULL, /* write */ + NULL, /* seek */ + NULL, /* tell */ + NULL, /* truncate */ + do_open_directory, + do_close_directory, + do_read_directory, + do_get_file_info, + do_get_file_info_from_handle, + do_is_local, + NULL, /* make_directory */ + NULL, /* remove directory */ + NULL, /* move */ + NULL, /* unlink */ + do_check_same_fs, + NULL, /* set_file_info */ + NULL, /* truncate */ + NULL, /* find_directory */ + NULL /* create_symbolic_link */ +}; + +GnomeVFSMethod * +vfs_module_init (const char *method_name, + const char *args) +{ +#ifdef HAVE_GCONF + char *argv[] = {"vfs-nntp-method"}; + int argc = 1; + + /* Ensure GConf is initialized. If more modules start to rely on + * GConf, then this should probably be moved into a more + * central location + */ + + if (!gconf_is_initialized ()) { + /* auto-initializes OAF if necessary */ + gconf_init (argc, argv, NULL); + } +#endif + + return &method; +} + +void +vfs_module_shutdown (GnomeVFSMethod *method) +{ +} diff --git a/modules/nntp-method.h b/modules/nntp-method.h new file mode 100644 index 0000000..a0cb451 --- /dev/null +++ b/modules/nntp-method.h @@ -0,0 +1,89 @@ +/* nntp-method.h - VFS modules for NNTP + + Copyright (C) 2001 Andy Hertzfeld + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + based on Ian McKellar's (yakk@yakk.net) ftp method for gnome-vfs + + presents a high level, file-oriented view of a newsgroup, integrating file fragments + and organizing them in folders + + Author: Andy Hertzfeld + + */ + +#ifndef NNTP_METHOD_H +#define NNTP_METHOD_H + +#include + +typedef struct +{ + int fragment_number; + char* fragment_id; + int fragment_size; + int bytes_read; +} nntp_fragment; + +typedef struct +{ + char* file_name; + char* folder_name; + char* file_type; + int file_size; + gboolean is_directory; + time_t mod_date; + + int total_parts; + GList *part_list; + } nntp_file; + +typedef struct { + GnomeVFSMethodHandle method_handle; + GnomeVFSInetConnection *inet_connection; + GnomeVFSSocketBuffer *socketbuf; + GnomeVFSURI *uri; + GString *response_buffer; + gchar *response_message; + gint response_code; + enum { + NNTP_NOTHING, + NNTP_READ, + NNTP_WRITE, + NNTP_READDIR + } operation; + + gchar *server_type; /* the response from TYPE */ + gboolean anonymous; + + GList *next_file; + nntp_file *current_file; + GList *current_fragment; + + gpointer buffer; + int buffer_size; + int amount_in_buffer; + int buffer_offset; + + gboolean request_in_progress; + gboolean eof_flag; + gboolean uu_decode_mode; + gboolean base_64_decode_mode; +} NNTPConnection; + + +#endif /* NNTP_METHOD_H */ diff --git a/modules/pipe-method.c b/modules/pipe-method.c new file mode 100644 index 0000000..76c4bb8 --- /dev/null +++ b/modules/pipe-method.c @@ -0,0 +1,280 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* pipe-method.c - pipe access method for GNOME Virtual File System + + Copyright (C) 1999, 2000 Red Hat Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Elliot Lee */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct _FileHandle { + GnomeVFSURI *uri; + FILE *fh; +}; +typedef struct _FileHandle FileHandle; + +static FileHandle * +file_handle_new (GnomeVFSURI *uri, + FILE *fh) +{ + FileHandle *new; + + new = g_new (FileHandle, 1); + + new->uri = gnome_vfs_uri_ref (uri); + new->fh = fh; + + return new; +} + +static void +file_handle_destroy (FileHandle *handle) +{ + pclose(handle->fh); + gnome_vfs_uri_unref (handle->uri); + g_free (handle); +} + +static char * +str_without_suffix (const char *str) +{ + const char *semicolon; + + semicolon = strchr (str, ';'); + + return g_strndup (str, (semicolon == NULL) ? strlen (str) : semicolon - str); +} + +static char * +mime_from_uri (const gchar *uri) +{ + const char *mime; + char *result; + + mime = uri == NULL ? NULL : strstr (uri, ";mime-type="); + if (mime != NULL) { + result = str_without_suffix (mime + 11); + if (result[0] == '\0') { + /* No mime-type specified */ + g_free (result); + result = g_strdup (GNOME_VFS_MIME_TYPE_UNKNOWN); + } + } else { + result = g_strdup (GNOME_VFS_MIME_TYPE_UNKNOWN); + } + return result; +} + + +static void +set_default_file_info (GnomeVFSFileInfo *file_info, + GnomeVFSURI *uri) +{ + file_info->name = g_strdup (uri->text); + file_info->flags = GNOME_VFS_FILE_FLAGS_NONE; + file_info->type = GNOME_VFS_FILE_TYPE_REGULAR; + file_info->permissions = (GNOME_VFS_PERM_USER_READ + | GNOME_VFS_PERM_GROUP_READ + | GNOME_VFS_PERM_OTHER_READ); + + file_info->valid_fields = (GNOME_VFS_FILE_INFO_FIELDS_FLAGS + | GNOME_VFS_FILE_INFO_FIELDS_TYPE + | GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS); +} + +#define SAFE_POPEN_CHARACTERS "?'/. +:-_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + + +static GnomeVFSResult +do_open (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + GnomeVFSContext *context) +{ + FileHandle *file_handle; + FILE *fh; + char *real_uri; + + _GNOME_VFS_METHOD_PARAM_CHECK (method_handle != NULL); + _GNOME_VFS_METHOD_PARAM_CHECK (uri != NULL); + + if (!(mode & GNOME_VFS_OPEN_READ)) + return GNOME_VFS_ERROR_INVALID_OPEN_MODE; + + real_uri = str_without_suffix (gnome_vfs_unescape_string (uri->text, "")); + + /* Check that all the characters being passed to popen are "safe" */ + /* If we allow just any characters through, it's easy to make URIs + * that make dangerous command lines here. If we prevent any + * interesting characters, then it's just simple parameters passed + * to the command that's the first thing passed in, which is much + * safer. + * Without this "man:ls&shutdown -h now" would have undesired effects. + */ + if (strspn (real_uri, SAFE_POPEN_CHARACTERS) != strlen (real_uri)) { + g_message ("real_uri is %s, has illegal chars, failing", real_uri); + g_free (real_uri); + return GNOME_VFS_ERROR_NOT_PERMITTED; + } + + fh = popen (real_uri, "r"); + g_free (real_uri); + + if (!fh) + return gnome_vfs_result_from_errno (); + + file_handle = file_handle_new (uri, fh); + + *method_handle = (GnomeVFSMethodHandle *) file_handle; + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_close (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + FileHandle *file_handle; + + g_return_val_if_fail (method_handle != NULL, GNOME_VFS_ERROR_INTERNAL); + + file_handle = (FileHandle *) method_handle; + + file_handle_destroy (file_handle); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_read (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read, + GnomeVFSContext *context) +{ + FileHandle *file_handle; + gint read_val; + + g_return_val_if_fail (method_handle != NULL, GNOME_VFS_ERROR_INTERNAL); + + file_handle = (FileHandle *) method_handle; + + read_val = fread (buffer, 1, num_bytes, file_handle->fh); + + if (read_val <= 0) { + *bytes_read = 0; + return GNOME_VFS_ERROR_EOF; + } else { + *bytes_read = read_val; + return GNOME_VFS_OK; + } +} + +static GnomeVFSResult +do_get_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + set_default_file_info (file_info, uri); + + file_info->mime_type = mime_from_uri (gnome_vfs_unescape_string (uri->text, "")); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_get_file_info_from_handle (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + FileHandle *handle; + + handle = (FileHandle *) method_handle; + + set_default_file_info (file_info, handle->uri); + + file_info->mime_type = mime_from_uri (gnome_vfs_unescape_string (handle->uri->text, "")); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + return GNOME_VFS_OK; +} + +static gboolean +is_local(GnomeVFSMethod *method, + const GnomeVFSURI *uri) +{ + return TRUE; +} + +static GnomeVFSMethod method = { + sizeof (GnomeVFSMethod), + do_open, + NULL, /* create */ + do_close, + do_read, + NULL, /* write */ + NULL, /* seek */ + NULL, /* tell */ + NULL, /* truncate_handle */ + NULL, /* open_directory */ + NULL, /* close_directory */ + NULL, /* read_directory */ + do_get_file_info, + do_get_file_info_from_handle, + is_local, + NULL, /* make_directory */ + NULL, /* remove_directory */ + NULL, /* move */ + NULL, /* unlink */ + NULL, /* check_same_fs */ + NULL, /* set_file_info */ + NULL, /* truncate */ + NULL, /* find_directory */ + NULL /* create_symbolic_link */ +}; + +GnomeVFSMethod * +vfs_module_init (const char *method_name, const char *args) +{ + return &method; +} + +void +vfs_module_shutdown (GnomeVFSMethod *method) +{ +} diff --git a/modules/ssh-method.c b/modules/ssh-method.c new file mode 100644 index 0000000..18446f1 --- /dev/null +++ b/modules/ssh-method.c @@ -0,0 +1,1104 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* ssh-method.c - VFS Access to the GConf configuration database. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ian McKellar */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define D(x) +/* #define D(x) g_print x */ + +#define LINE_LENGTH 4096 /* max line length we'll grok */ +#define SLEEP_TIME 300000 /* time we'll wait for the process to finish */ + +typedef struct { + GnomeVFSMethodHandle method_handle; + GnomeVFSURI *uri; + enum { + SSH_FILE, + SSH_LIST + } type; + GnomeVFSOpenMode open_mode; + int read_fd; + int write_fd; + int error_fd; + pid_t pid; + GnomeVFSFileInfoOptions info_opts; +} SshHandle; + +static GnomeVFSResult ssh_read_error (int error_fd, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read); +static GnomeVFSResult do_open (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + GnomeVFSContext *context); +static GnomeVFSResult do_create (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + gboolean exclusive, + guint perm, + GnomeVFSContext *context); +static GnomeVFSResult do_close (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context); +static GnomeVFSResult do_read (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read, + GnomeVFSContext *context); +static GnomeVFSResult do_write (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gconstpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_written, + GnomeVFSContext *context); +static GnomeVFSResult do_open_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context); +static GnomeVFSResult do_close_directory(GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context); +static GnomeVFSResult do_read_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSContext *context); +static GnomeVFSResult do_get_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context); +static GnomeVFSResult do_make_directory (GnomeVFSMethod *method, + GnomeVFSURI *uri, + guint perm, + GnomeVFSContext *context); +static GnomeVFSResult do_remove_directory(GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSContext *context); +static GnomeVFSResult do_move (GnomeVFSMethod *method, + GnomeVFSURI *old_uri, + GnomeVFSURI *new_uri, + gboolean force_replace, + GnomeVFSContext *context); +static GnomeVFSResult do_unlink (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSContext *context); +static GnomeVFSResult do_check_same_fs (GnomeVFSMethod *method, + GnomeVFSURI *a, + GnomeVFSURI *b, + gboolean *same_fs_return, + GnomeVFSContext *context); +static GnomeVFSResult do_set_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + const GnomeVFSFileInfo *info, + GnomeVFSSetFileInfoMask mask, + GnomeVFSContext *context); +#if 0 +static GnomeVFSResult do_get_file_info_from_handle + (GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options); +#endif +static gboolean do_is_local (GnomeVFSMethod *method, + const GnomeVFSURI *uri); + +static GnomeVFSMethod method = { + sizeof (GnomeVFSMethod), + do_open, + do_create, /* create */ + do_close, + do_read, /* read */ + do_write, /* write */ + NULL, /* seek */ + NULL, /* tell */ + NULL, /* truncate */ + do_open_directory, + do_close_directory, + do_read_directory, + do_get_file_info, + NULL, /* get_file_info_from_handle */ + do_is_local, + do_make_directory, /* make directory */ + do_remove_directory, /* remove directory */ + do_move, + do_unlink, /* unlink */ + do_check_same_fs, + do_set_file_info, /* set_file_info */ + NULL, /* truncate */ + NULL, /* find_directory */ + NULL /* create_symbolic_link */ +}; + +/* FIXME: does this like FDs? */ +static GnomeVFSResult +ssh_connect (SshHandle **handle_return, + GnomeVFSURI *uri, const char *command) +{ + char ** argv; + SshHandle *handle; + char *command_line, *host_port; + const gchar *username, *hostname; + int argc; + GError *gerror = NULL; + GnomeVFSFileSize bytes_read; + char buffer[LINE_LENGTH]; + GnomeVFSResult res; + + /* We do support ssh:/// as ssh://localhost/ */ + hostname = gnome_vfs_uri_get_host_name (uri); + if (hostname == NULL) { + hostname = "localhost"; + } + + username = gnome_vfs_uri_get_user_name(uri); + if (username == NULL) { + username = g_get_user_name(); + } + + host_port = g_strdup_printf("%d", gnome_vfs_uri_get_host_port(uri) ? + gnome_vfs_uri_get_host_port(uri) : 22); + + command_line = g_strconcat ("ssh -oBatchMode=yes -x -l ", + username, + " -p ", host_port, + " ", hostname, + " ", + "\"LC_ALL=C; echo READY > /dev/stderr;", + command, "; echo DONE > /dev/stderr\"", + NULL); + g_free (host_port); + + D(("ssh_connect () command: %s\n", command_line)); + + g_shell_parse_argv (command_line, &argc, &argv, &gerror); + + g_free (command_line); + if (gerror) { + g_warning (gerror->message); + return GNOME_VFS_ERROR_BAD_PARAMETERS; + } + + handle = g_new0 (SshHandle, 1); + handle->uri = uri; + + g_spawn_async_with_pipes (NULL, argv, NULL, + G_SPAWN_SEARCH_PATH, + NULL, NULL, + (gint *)&handle->pid, &handle->write_fd, + &handle->read_fd, &handle->error_fd, + &gerror); + g_strfreev (argv); + + if (gerror) { + g_warning (gerror->message); + g_free (handle); + return GNOME_VFS_ERROR_GENERIC; + } + + gnome_vfs_uri_ref (handle->uri); + + *handle_return = handle; + + /* You can add more error checking here */ + memset (buffer, '\0', LINE_LENGTH); + res = ssh_read_error (handle->error_fd, &buffer, + LINE_LENGTH, &bytes_read); + + if (bytes_read != 0 && res == GNOME_VFS_OK) { + if (strncmp ("READY", buffer, strlen ("READY")) == 0) { + res = GNOME_VFS_OK; + } else if (strncmp ("Permission denied", buffer, + strlen("Permission denied")) == 0) { + res = GNOME_VFS_ERROR_LOGIN_FAILED; + } else if (strncmp ("Host key verification failed", buffer, + strlen("Host key verification failed")) + == 0) { + res = GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE; + } else if (strstr (buffer, "Connection refused") != NULL) { + res = GNOME_VFS_ERROR_ACCESS_DENIED; + } + } + + return res; +} + +static GnomeVFSResult +ssh_destroy (SshHandle *handle) +{ + close (handle->read_fd); + close (handle->write_fd); + close (handle->error_fd); + gnome_vfs_uri_unref (handle->uri); + kill (handle->pid, SIGINT); + g_free (handle); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +ssh_read (SshHandle *handle, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read) +{ + GnomeVFSFileSize my_read; + + my_read = (GnomeVFSFileSize) read (handle->read_fd, buffer, + (size_t) num_bytes); + + if (my_read == -1) { + return gnome_vfs_result_from_errno (); + } + + *bytes_read = my_read; + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +ssh_read_error (int error_fd, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read) +{ + GnomeVFSFileSize my_read; + + my_read = (GnomeVFSFileSize) read (error_fd, buffer, + (size_t) num_bytes); + + if (my_read == -1) { + return gnome_vfs_result_from_errno (); + } + + *bytes_read = my_read; + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +ssh_check_for_done (SshHandle *handle) +{ + char buffer[LINE_LENGTH]; + GnomeVFSResult res; + GnomeVFSFileSize bytes_read; + + memset (buffer, '\0', LINE_LENGTH); + res = ssh_read_error (handle->error_fd, &buffer, + LINE_LENGTH, &bytes_read); + + if (bytes_read != 0 && res == GNOME_VFS_OK) { + if (strncmp ("DONE", buffer, strlen ("DONE")) == 0) { + return res; + } + } + + return GNOME_VFS_ERROR_GENERIC; +} + +static GnomeVFSResult +ssh_write (SshHandle *handle, + gconstpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_written) +{ + GnomeVFSFileSize written; + int count=0; + + do { + errno = 0; + written = (GnomeVFSFileSize) write (handle->write_fd, buffer, + (size_t) num_bytes); + if (written == -1 && errno == EINTR) { + count++; + usleep (10); + } + } while (written == -1 && errno == EINTR && count < 5); + + if (written == -1) { + return gnome_vfs_result_from_errno (); + } + + *bytes_written = written; + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +ssh_wait_and_destroy (SshHandle *handle, GnomeVFSContext *context) +{ + int i; + + /* That's 30 seconds */ + for (i = 0; i < 100 && kill (handle->pid, 0) != -1; i++) { + if (gnome_vfs_context_check_cancellation (context) == TRUE) { + break; + } + usleep (SLEEP_TIME); + } + + return ssh_destroy (handle); +} + + +#if 0 +static GnomeVFSResult +ssh_send (SshHandle *handle, + const char *string) +{ + GnomeVFSFileSize len, written; + GnomeVFSResult result = GNOME_VFS_OK; + + len = strlen (string); + + while (len > 0 && result == GNOME_VFS_OK) { + result = ssh_write (handle, string, len, &written); + len -= written; + string += written; + } + + return result; +} +#endif + +static GnomeVFSResult +do_open (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + char *cmd; + SshHandle *handle = NULL; + + if (mode == GNOME_VFS_OPEN_READ) { + char *name; + char *quoted_name; + name = gnome_vfs_unescape_string (uri->text, + G_DIR_SEPARATOR_S); + if (name == NULL) { + return GNOME_VFS_ERROR_INVALID_URI; + } + quoted_name = g_shell_quote (name); + g_free (name); + + cmd = g_strdup_printf ("cat %s", quoted_name); + result = ssh_connect (&handle, uri, cmd); + g_free (cmd); + g_free (quoted_name); + if (result != GNOME_VFS_OK) { + return result; + } + } else { + return GNOME_VFS_ERROR_INVALID_OPEN_MODE; + } + + handle->open_mode = mode; + handle->type = SSH_FILE; + *method_handle = (GnomeVFSMethodHandle *)handle; + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_create (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + gboolean exclusive, + guint perm, + GnomeVFSContext *context) +{ + SshHandle *handle = NULL; + char *cmd; + GnomeVFSResult result; + char *name; + char *quoted_name; + + if (mode != GNOME_VFS_OPEN_WRITE) { + return GNOME_VFS_ERROR_INVALID_OPEN_MODE; + } + + name = gnome_vfs_unescape_string (uri->text, G_DIR_SEPARATOR_S); + if (name == NULL) { + return GNOME_VFS_ERROR_INVALID_URI; + } + quoted_name = g_shell_quote (name); + + cmd = g_strdup_printf ("cat > %s", quoted_name); + result = ssh_connect (&handle, uri, cmd); + g_free (cmd); + g_free (name); + g_free (quoted_name); + + if (result != GNOME_VFS_OK) { + return result; + } + + /* FIXME: set perm */ + + handle->open_mode = mode; + handle->type = SSH_FILE; + *method_handle = (GnomeVFSMethodHandle *)handle; + + return result; +} + +static GnomeVFSResult +do_close (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + return ssh_wait_and_destroy ((SshHandle *)method_handle, context); +} + +static GnomeVFSResult +do_read (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read, + GnomeVFSContext *context) +{ + GnomeVFSResult result, res_secondary; + + result = ssh_read ((SshHandle *)method_handle, buffer, num_bytes, + bytes_read); + if (result != GNOME_VFS_OK) { + return result; + } + + if (*bytes_read == 0) { + res_secondary = ssh_check_for_done ((SshHandle *)method_handle); + if (res_secondary != GNOME_VFS_OK) { + result = res_secondary; + } else { + result = GNOME_VFS_ERROR_EOF; + } + } + return result; +} + +/* alternative impl: + * dd bs=1 conv=notrunc count=5 seek=60 of=/tmp/foo-test + */ +static GnomeVFSResult +do_write (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gconstpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_written, + GnomeVFSContext *context) +{ + return ssh_write ((SshHandle *)method_handle, buffer, num_bytes, + bytes_written); +} + +static GnomeVFSResult +do_open_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + SshHandle *handle = NULL; + char *cmd = NULL; + GnomeVFSResult result; + char *name; + char *quoted_name; + + name = gnome_vfs_unescape_string (uri->text, G_DIR_SEPARATOR_S); + if (name == NULL) { + return GNOME_VFS_ERROR_NOT_FOUND; + } + + quoted_name = g_shell_quote (name); + + if (*name != '\0') { + cmd = g_strdup_printf ("ls -l %s", quoted_name); + } else { + cmd = g_strdup_printf ("ls -l '/'"); + } + + result = ssh_connect (&handle, uri, cmd); + g_free (quoted_name); + g_free (name); + g_free (cmd); + + if (result != GNOME_VFS_OK) { + return result; + } + handle->info_opts = options; + handle->open_mode = GNOME_VFS_OPEN_NONE; + handle->type = SSH_LIST; + *method_handle = (GnomeVFSMethodHandle *)handle; + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_close_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + return ssh_destroy ((SshHandle *)method_handle); +} + +static void +get_access_info (GnomeVFSURI *uri, GnomeVFSFileInfo *file_info) +{ + gint i; + gchar *name; + gchar *quoted_name; + struct param { + char c; + GnomeVFSFilePermissions perm; + }; + struct param params[2] = {{'r', GNOME_VFS_PERM_ACCESS_READABLE}, + {'w', GNOME_VFS_PERM_ACCESS_WRITABLE}}; + + name = gnome_vfs_unescape_string (uri->text, G_DIR_SEPARATOR_S); + if (name == NULL) { + return; + } + + if ( *name == '\0' ) { + quoted_name = g_shell_quote ("/"); + } else { + quoted_name = g_shell_quote (name); + } + g_free (name); + + for (i = 0; i<2; i++) { + gchar c; + gchar *cmd; + SshHandle *handle; + GnomeVFSFileSize bytes_read; + GnomeVFSResult result; + + cmd = g_strdup_printf ("test -%c %s && echo $?", + params[i].c, quoted_name); + result = ssh_connect (&handle, uri, cmd); + g_free (cmd); + + if (result != GNOME_VFS_OK) { + g_free(quoted_name); + return; + } + + result = ssh_read (handle, &c, 1, &bytes_read); + if ((bytes_read > 0) && (c == '0')) { + file_info->permissions |= params[i].perm; + } else { + file_info->permissions &= ~params[i].perm; + } + + ssh_destroy (handle); + } + + file_info->permissions &= ~GNOME_VFS_PERM_ACCESS_EXECUTABLE; + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_ACCESS; + + g_free(quoted_name); +} + +static GnomeVFSResult +do_read_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK, res_secondary; + char line[LINE_LENGTH+1]; + char c; + int i=0; + GnomeVFSFileSize bytes_read; + struct stat st; + char *tempfilename, *filename, *linkname; + SshHandle *handle = (SshHandle *)method_handle; + const char *mime_type; + char *target_name, *parent; + GnomeVFSFileInfo *target_info; + GnomeVFSURI *target_uri; + + for (;;) { + tempfilename = NULL; + filename = NULL; + linkname = NULL; + i = 0; + bytes_read = 0; + + while (iname = filename; + if (linkname) { + GNOME_VFS_FILE_INFO_SET_SYMLINK (file_info, TRUE); + file_info->valid_fields + |= GNOME_VFS_FILE_INFO_FIELDS_SYMLINK_NAME; + file_info->symlink_name = linkname; + D(("symlink: %s\n", file_info->symlink_name)); + } + + /* FIXME: support symlinks to directories correctly */ + + if (file_info->type == GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK) { + parent = gnome_vfs_uri_to_string + (handle->uri, 0); + target_name = + gnome_vfs_make_uri_full_from_relative + (parent, file_info->symlink_name); + + if ((handle->info_opts + & GNOME_VFS_FILE_INFO_FOLLOW_LINKS) == 0) { + mime_type = "x-special/symlink"; + } else { + target_uri = gnome_vfs_uri_new (target_name); + mime_type = gnome_vfs_get_file_mime_type + (target_name, NULL, FALSE); + D(("Looking up mime-type for '%s'\n\n", + target_name)); + target_info = gnome_vfs_file_info_new (); + do_get_file_info (method, target_uri, + target_info, handle->info_opts, + context); + file_info->type = target_info->type; + gnome_vfs_file_info_unref (target_info); + gnome_vfs_uri_unref (target_uri); + } + + g_free (target_name); + g_free (parent); + } else { + mime_type = (gnome_vfs_get_file_mime_type + (filename, &st, FALSE)); + } + + if (handle->info_opts & GNOME_VFS_FILE_INFO_GET_MIME_TYPE) { + file_info->mime_type = g_strdup (mime_type); + file_info->valid_fields + |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + } + + file_info->valid_fields &= + ~GNOME_VFS_FILE_INFO_FIELDS_BLOCK_COUNT; + file_info->valid_fields &= + ~GNOME_VFS_FILE_INFO_FIELDS_IO_BLOCK_SIZE; + if (handle->info_opts & GNOME_VFS_FILE_INFO_GET_ACCESS_RIGHTS) { + get_access_info (handle->uri, file_info); + } + + /* Break out. + We are in a loop so we get the first 'ls' line; + often it starts with 'total 2213' etc. + */ + break; + } + + return result; +} + +GnomeVFSResult +do_get_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + SshHandle *handle = NULL; + char *cmd = NULL; + GnomeVFSResult result; + char *name; + char *quoted_name; + + name = gnome_vfs_unescape_string (uri->text, G_DIR_SEPARATOR_S); + if (name == NULL) { + return GNOME_VFS_ERROR_INVALID_URI; + } + + quoted_name = g_shell_quote (name); + + if (*name != '\0') { + cmd = g_strdup_printf ("ls -ld %s 2>&1", quoted_name); + } else { + cmd = g_strdup_printf ("ls -ld '/' 2>&1"); + } + + result = ssh_connect (&handle, uri, cmd); + g_free (cmd); + g_free (name); + g_free (quoted_name); + + if (result != GNOME_VFS_OK) { + return result; + } + handle->info_opts = options; + handle->open_mode = GNOME_VFS_OPEN_NONE; + handle->type = SSH_LIST; + + result = do_read_directory (method, (GnomeVFSMethodHandle *)handle, + file_info, context); + + ssh_destroy (handle); + + return (result == GNOME_VFS_ERROR_EOF ? GNOME_VFS_OK : result); +} + +static GnomeVFSResult +do_make_directory (GnomeVFSMethod *method, + GnomeVFSURI *uri, + guint perm, + GnomeVFSContext *context) +{ + SshHandle *handle = NULL; + char *cmd = NULL; + GnomeVFSResult result; + char *name; + char *quoted_name; + + name = gnome_vfs_unescape_string (uri->text, G_DIR_SEPARATOR_S); + if (name == NULL) { + return GNOME_VFS_ERROR_INVALID_URI; + } + quoted_name = g_shell_quote (name); + + cmd = g_strdup_printf ("mkdir %s", quoted_name); + result = ssh_connect (&handle, uri, cmd); + g_free (cmd); + g_free (name); + g_free (quoted_name); + + if (result != GNOME_VFS_OK) { + return result; + } + + ssh_wait_and_destroy (handle, context); + + return result; +} + +static GnomeVFSResult +do_remove_directory (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSContext *context) +{ + SshHandle *handle = NULL; + char *cmd = NULL; + GnomeVFSResult result; + gchar *name; + gchar *quoted_name; + + name = gnome_vfs_unescape_string (uri->text, G_DIR_SEPARATOR_S); + if (name == NULL) { + return GNOME_VFS_ERROR_INVALID_URI; + } + quoted_name = g_shell_quote (name); + + cmd = g_strdup_printf ("rm -rf %s", quoted_name); + result = ssh_connect (&handle, uri, cmd); + g_free (cmd); + g_free (name); + g_free (quoted_name); + + if (result != GNOME_VFS_OK) { + return result; + } + + ssh_wait_and_destroy (handle, context); + + return result; +} + +static GnomeVFSResult +do_move (GnomeVFSMethod *method, + GnomeVFSURI *old_uri, + GnomeVFSURI *new_uri, + gboolean force_replace, + GnomeVFSContext *context) +{ + SshHandle *handle = NULL; + GnomeVFSResult res; + gboolean same_fs; + char *old_name, *new_name; + char *quoted_old_name, *quoted_new_name; + char *cmd; + + res = do_check_same_fs (method, old_uri, new_uri, &same_fs, context); + if (res != GNOME_VFS_OK) { + return res; + } + + old_name = gnome_vfs_unescape_string (old_uri->text, G_DIR_SEPARATOR_S); + new_name = gnome_vfs_unescape_string (new_uri->text, G_DIR_SEPARATOR_S); + + if ((old_name == NULL) || (new_name == NULL)) { + g_free (old_name); + g_free (new_name); + return GNOME_VFS_ERROR_INVALID_URI; + } + quoted_old_name = g_shell_quote (old_name); + quoted_new_name = g_shell_quote (new_name); + + cmd = g_strdup_printf ("mv %s %s", quoted_old_name, quoted_new_name); + res = ssh_connect (&handle, old_uri, cmd); + g_free (cmd); + g_free (old_name); + g_free (new_name); + g_free (quoted_old_name); + g_free (quoted_new_name); + + if (res != GNOME_VFS_OK) { + return res; + } + + ssh_wait_and_destroy (handle, context); + + return res; +} + +GnomeVFSResult +do_unlink (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSContext *context) +{ + SshHandle *handle = NULL; + char *cmd; + GnomeVFSResult result; + gchar *name; + gchar *quoted_name; + + name = gnome_vfs_unescape_string (uri->text, G_DIR_SEPARATOR_S); + if (name == NULL) { + return GNOME_VFS_ERROR_INVALID_URI; + } + quoted_name = g_shell_quote (name); + + cmd = g_strdup_printf ("rm -rf %s", quoted_name); + result = ssh_connect (&handle, uri, cmd); + g_free (cmd); + g_free (name); + g_free (quoted_name); + + if (result != GNOME_VFS_OK) { + return result; + } + + ssh_wait_and_destroy (handle, context); + + return result; +} + +static GnomeVFSResult +do_check_same_fs (GnomeVFSMethod *method, + GnomeVFSURI *a, + GnomeVFSURI *b, + gboolean *same_fs_return, + GnomeVFSContext *context) +{ + const gchar *a_host_name, *b_host_name; + const gchar *a_user_name, *b_user_name; + + g_return_val_if_fail (a != NULL, GNOME_VFS_ERROR_INTERNAL); + g_return_val_if_fail (b != NULL, GNOME_VFS_ERROR_INTERNAL); + + a_host_name = gnome_vfs_uri_get_host_name (a); + b_host_name = gnome_vfs_uri_get_host_name (b); + a_user_name = gnome_vfs_uri_get_user_name (a); + b_user_name = gnome_vfs_uri_get_user_name (b); + + g_return_val_if_fail (a_host_name != NULL, GNOME_VFS_ERROR_INVALID_URI); g_return_val_if_fail (b_host_name != NULL, GNOME_VFS_ERROR_INVALID_URI); + if (a_user_name == NULL) { + a_user_name = g_get_user_name (); + } + if (b_user_name == NULL) { + b_user_name = g_get_user_name (); + } + + if (same_fs_return != NULL) { + *same_fs_return = + ((!strcmp (a_host_name, b_host_name)) + && (!strcmp (a_user_name, b_user_name))); + } + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_set_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + const GnomeVFSFileInfo *info, + GnomeVFSSetFileInfoMask mask, + GnomeVFSContext *context) +{ + SshHandle *handle = NULL; + char *cmd = NULL; + GnomeVFSResult result=GNOME_VFS_OK; + gchar *full_name; + + full_name = gnome_vfs_unescape_string (uri->text, G_DIR_SEPARATOR_S); + if (full_name == NULL) { + return GNOME_VFS_ERROR_INVALID_URI; + } + + if (mask & GNOME_VFS_SET_FILE_INFO_NAME) { + char *encoded_dir; + char *dir; + char *new_name; + char *quoted_full_name; + char *quoted_new_name; + + encoded_dir = gnome_vfs_uri_extract_dirname (uri); + dir = gnome_vfs_unescape_string (encoded_dir, G_DIR_SEPARATOR_S); + g_free (encoded_dir); + g_assert (dir != NULL); + + /* FIXME bugzilla.eazel.com 645: This needs to return + * an error for incoming names with "/" characters in + * them, instead of moving the file. + */ + + if (dir[strlen (dir) - 1] != '/') { + new_name = g_strconcat (dir, "/", info->name, NULL); + } else { + new_name = g_strconcat (dir, info->name, NULL); + } + + /* FIXME: escape for shell */ + quoted_new_name = g_shell_quote (new_name); + quoted_full_name = g_shell_quote (full_name); + cmd = g_strdup_printf ("mv %s %s", quoted_full_name, + quoted_new_name); + result = ssh_connect (&handle, uri, cmd); + g_free (cmd); + g_free (dir); + g_free (new_name); + g_free (quoted_new_name); + g_free (quoted_full_name); + g_free (full_name); + + if (result != GNOME_VFS_OK) { + return result; + } + + /* Read all info from remote host */ + while (1) { + char c; + GnomeVFSResult res; + GnomeVFSFileSize bytes_read; + res = ssh_read (handle, &c, 1, &bytes_read); + if (bytes_read == 0 || res != GNOME_VFS_OK) + break; + } + + ssh_wait_and_destroy (handle, context); + } + + return result; +} + +#if 0 +static GnomeVFSResult +do_get_file_info_from_handle (GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options) +{ + return GNOME_VFS_ERROR_WRONG_FORMAT; +} +#endif + +gboolean +do_is_local (GnomeVFSMethod *method, const GnomeVFSURI *uri) +{ + return FALSE; +} + +GnomeVFSMethod * +vfs_module_init (const char *method_name, const char *args) +{ + return &method; +} + +void +vfs_module_shutdown (GnomeVFSMethod *method) +{ +} diff --git a/modules/ssl-modules.conf b/modules/ssl-modules.conf new file mode 100644 index 0000000..de6536b --- /dev/null +++ b/modules/ssl-modules.conf @@ -0,0 +1 @@ +https: http diff --git a/modules/tar-method.c b/modules/tar-method.c new file mode 100644 index 0000000..ebd668d --- /dev/null +++ b/modules/tar-method.c @@ -0,0 +1,730 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* tar-method.c - The tar method implementation for the GNOME Virtual File + System. + + Copyright (C) 2002 Ximian, Inc + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Rachel Hestilow + Abigail Brady (tarpet.h) +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "tarpet.h" + +typedef struct +{ + union TARPET_block* blocks; + guint num_blocks; + GNode *info_tree; + int ref_count; + gchar *filename; +} TarFile; + +typedef struct +{ + TarFile *tar; + union TARPET_block* start; + union TARPET_block* current; + int current_offset; + int current_index; + gchar *filename; + gboolean is_directory; +} FileHandle; + +#define TARPET_BLOCKSIZE (sizeof (union TARPET_block)) + +static GHashTable *tar_cache; +G_LOCK_DEFINE_STATIC (tar_cache); + +#define iteration_initialize(condition, i, cond1, cond2) ((i) = (condition) ? (cond1) : (cond2)) +#define iteration_check(condition, i, op1, op2, val1, val2) ((condition) ? (i op1 val1) : (i op2 val2)) +#define iteration_iterate(condition, i, op1, op2) ((condition) ? (i op1) : (i op2)) + +#define parse_octal_field(v) (parse_octal ((v), sizeof (v))) +#define IS_OCTAL_DIGIT(c) ((c) >= '0' && (c) <= '8') +#define OCTAL_DIGIT(c) ((c) - '0') + +static int parse_octal (const char *str, int len) +{ + int i, ret = 0; + for (i = 0; i < len; i++) + { + if (str[i] == '\0') break; + else if (!IS_OCTAL_DIGIT (str[i])) return 0; + ret = ret * 8 + OCTAL_DIGIT (str[i]); + } + return ret; +} + +static void +split_name_with_level (const gchar *name, gchar **first, gchar **last, int level, gboolean backwards) +{ + int i; + gchar *found = NULL; + int num_found = 0; + if (name[strlen (name) - 1] == '/' && backwards) + level++; + + for (iteration_initialize (backwards, i, strlen (name) - 1, 0); + iteration_check (backwards, i, >=, <, 0, strlen (name)); + iteration_iterate (backwards, i, --, ++)) + { + if (name[i] == '/') + num_found++; + + if (num_found >= level) + { + found = (gchar*) name + i; + break; + } + } + + if (found) + { + *first = g_strndup (name, found - name + 1); + if (*(found + 1)) + *last = g_strdup (found + 1); + else + *last = NULL; + } + else + { + *first = g_strdup (name); + *last = NULL; + } +} + +static void +split_name (const gchar *name, gchar **first, gchar **last) +{ + split_name_with_level (name, first, last, 1, TRUE); +} + +static GNode* +real_lookup_entry (const GNode *tree, const gchar *name, int level) +{ + GNode *node, *ret = NULL; + gchar *first, *rest; + + split_name_with_level (name, &first, &rest, level, FALSE); + + for (node = tree->children; node; node = node->next) + { + union TARPET_block *b = (union TARPET_block*) node->data; + if (!strcmp (b->raw.data, first)) + { + if (rest) + ret = real_lookup_entry (node, name, level + 1); + else + ret = node; + break; + } + else if (!strcmp (b->raw.data, name)) + { + ret = node; + break; + } + } + g_free (first); + g_free (rest); + + + return ret; +} + +static GNode* +tree_lookup_entry (const GNode *tree, const gchar *name) +{ + GNode *ret; + char *root = g_strdup (name); + char *txt = root; + + if (txt[0] == '/') + txt++; + + ret = real_lookup_entry (tree, txt, 1); + if (!ret && txt[strlen (txt) - 1] != '/') + { + txt = g_strconcat (txt, "/", NULL); + g_free (root); + root = txt; + ret = real_lookup_entry (tree, txt, 1); + } + g_free (root); + + if (ret && ret != tree->children) + { + union TARPET_block *b = ret->data; + b--; + if (b->p.typeflag == TARPET_TYPE_LONGFILEN) + ret = ret->next; + } + + return ret; +} + +static TarFile* read_tar_file (GnomeVFSHandle *handle) +{ + GArray *arr = g_array_new (TRUE, TRUE, sizeof (union TARPET_block)); + GnomeVFSResult res; + TarFile* ret; + GnomeVFSFileSize bytes_read; + int i; + + do + { + union TARPET_block b; + res = gnome_vfs_read (handle, b.raw.data, + TARPET_BLOCKSIZE, &bytes_read); + if (res == GNOME_VFS_OK) + g_array_append_val (arr, b); + } while (res == GNOME_VFS_OK && bytes_read > 0); + + ret = g_new0 (TarFile, 1); + ret->blocks = (union TARPET_block*) arr->data; + ret->num_blocks = arr->len; + ret->info_tree = g_node_new (NULL); + + for (i = 0; i < ret->num_blocks;) + { + gchar *dir; + gchar *rest; + GNode *node; + int size = 0, maxsize; + int orig; + + if (!(*ret->blocks[i].p.name)) + { + i++; + continue; + } + + if (ret->blocks[i].p.typeflag == TARPET_TYPE_LONGFILEN) + { + i++; + continue; + } + + split_name (ret->blocks[i].p.name, &dir, &rest); + node = tree_lookup_entry (ret->info_tree, dir); + + if (!node) + { + node = ret->info_tree; + } + g_node_append (node, g_node_new (&(ret->blocks[i]))); + + g_free (dir); + g_free (rest); + + maxsize = parse_octal_field (ret->blocks[i].p.size); + if (maxsize) + { + for (orig = i; i < ret->num_blocks && size < maxsize; i++) + { + int wsize = TARPET_BLOCKSIZE; + if ((maxsize - size) < TARPET_BLOCKSIZE) + wsize = maxsize - size; + size += wsize; + } + i++; + } + else + { + i++; + } + } + + g_array_free (arr, FALSE); + + return ret; +} + +static TarFile* +ensure_tarfile (GnomeVFSURI *uri) +{ + TarFile *tar; + GnomeVFSHandle *handle; + gchar *parent_string; + + parent_string = gnome_vfs_uri_to_string (uri->parent, GNOME_VFS_URI_HIDE_NONE); + G_LOCK (tar_cache); + tar = g_hash_table_lookup (tar_cache, parent_string); + if (!tar) + { + if (gnome_vfs_open_uri (&handle, uri->parent, GNOME_VFS_OPEN_READ) != GNOME_VFS_OK) + return NULL; + tar = read_tar_file (handle); + tar->filename = parent_string; + gnome_vfs_close (handle); + g_hash_table_insert (tar_cache, parent_string, tar); + } + G_UNLOCK (tar_cache); + + tar->ref_count++; + return tar; +} + +static void +tar_file_unref (TarFile *tar) +{ + tar->ref_count--; + if (tar->ref_count < 0) + { + G_LOCK (tar_cache); + g_hash_table_remove (tar_cache, tar->filename); + G_UNLOCK (tar_cache); + g_free (tar->blocks); + g_node_destroy (tar->info_tree); + g_free (tar->filename); + g_free (tar); + } +} + +static GnomeVFSResult +do_open (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + GnomeVFSContext *context) +{ + TarFile *tar; + FileHandle *new_handle; + GNode *node; + union TARPET_block *start; + int i; + + if (!uri->parent) + return GNOME_VFS_ERROR_INVALID_URI; + + tar = ensure_tarfile (uri); + if (!tar) + return GNOME_VFS_ERROR_BAD_FILE; + node = tree_lookup_entry (tar->info_tree, uri->text); + if (!node) + { + tar_file_unref (tar); + return GNOME_VFS_ERROR_NOT_FOUND; + } + start = node->data; + + if (start->p.name[strlen (start->p.name) - 1] == '/') + return GNOME_VFS_ERROR_IS_DIRECTORY; + new_handle = g_new0 (FileHandle, 1); + new_handle->tar = tar; + new_handle->filename = g_strdup (uri->text); + new_handle->start = start; + new_handle->current = new_handle->start; + new_handle->current_offset = 0; + for (i = 0; i < tar->num_blocks; i++) + if (start == &(tar->blocks[i])) + break; + new_handle->current_index = i; + new_handle->is_directory = FALSE; + + *method_handle = (GnomeVFSMethodHandle*) new_handle; + + return GNOME_VFS_OK; +} + +static void +file_handle_unref (FileHandle *handle) +{ + tar_file_unref (handle->tar); + g_free (handle->filename); + g_free (handle); +} + +static GnomeVFSResult +do_close (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + FileHandle *handle = (FileHandle*) method_handle; + + file_handle_unref (handle); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_read (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read, + GnomeVFSContext *context) +{ + FileHandle *handle = (FileHandle*) method_handle; + int i, size = 0, maxsize; + + if (handle->is_directory) + return GNOME_VFS_ERROR_IS_DIRECTORY; + + maxsize = parse_octal_field (handle->start->p.size); + if (handle->current == handle->start) + { + handle->current_index++; + handle->current_offset = TARPET_BLOCKSIZE; + } + + for (i = handle->current_index; i < handle->tar->num_blocks && handle->current_offset < (maxsize + TARPET_BLOCKSIZE) && size < num_bytes; i++) + { + int wsize = TARPET_BLOCKSIZE; + gpointer target_buf = (gchar*)buffer + size; + if ((maxsize - (handle->current_offset - TARPET_BLOCKSIZE)) < TARPET_BLOCKSIZE + && (maxsize - (handle->current_offset - TARPET_BLOCKSIZE)) > 0) + wsize = maxsize - handle->current_offset + TARPET_BLOCKSIZE; + else if (num_bytes < (size + wsize)) + wsize = num_bytes - size; + else + handle->current_index = i + 1; + + memcpy (target_buf, handle->start->raw.data + handle->current_offset, wsize); + + size += wsize; + handle->current_offset += wsize; + } + if (handle->current_index < handle->tar->num_blocks) + handle->current = &handle->tar->blocks[handle->current_index]; + else + handle->current = NULL; + + *bytes_read = size; + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_seek (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSSeekPosition whence, + GnomeVFSFileOffset offset, + GnomeVFSContext *context) +{ + FileHandle *handle = (FileHandle*) method_handle; + GnomeVFSFileOffset current_offset; + + switch (whence) + { + case GNOME_VFS_SEEK_START: + current_offset = 0; + break; + case GNOME_VFS_SEEK_CURRENT: + current_offset = handle->current_offset; + break; + case GNOME_VFS_SEEK_END: + current_offset = parse_octal_field (handle->start->p.size); + break; + default: + current_offset = handle->current_offset; + break; + } + + handle->current_offset = current_offset + offset; + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_tell (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileOffset *offset_return) +{ + FileHandle *handle = (FileHandle*) method_handle; + *offset_return = handle->current_offset; + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_open_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + TarFile *tar; + FileHandle *new_handle; + union TARPET_block *start, *current; + GNode *node; + int i; + + if (!uri->parent) + return GNOME_VFS_ERROR_INVALID_URI; + tar = ensure_tarfile (uri); + if (uri->text) + { + node = tree_lookup_entry (tar->info_tree, uri->text); + if (!node) + { + tar_file_unref (tar); + return GNOME_VFS_ERROR_NOT_FOUND; + } + start = node->data; + + if (start->p.name[strlen (start->p.name) - 1] != '/') + return GNOME_VFS_ERROR_NOT_A_DIRECTORY; + + if (node->children) + current = node->children->data; + else + current = NULL; + } + else + { + node = tar->info_tree; + if (!node) + { + tar_file_unref (tar); + return GNOME_VFS_ERROR_NOT_FOUND; + } + + if (node->children) + start = node->children->data; + else + start = NULL; + current = start; + } + + new_handle = g_new0 (FileHandle, 1); + new_handle->tar = tar; + new_handle->filename = g_strdup (tar->filename); + new_handle->start = start; + new_handle->current = current; + for (i = 0; i < tar->num_blocks; i++) + if (start == &(tar->blocks[i])) + break; + new_handle->current_index = i; + new_handle->is_directory = TRUE; + + *method_handle = (GnomeVFSMethodHandle*) new_handle; + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_close_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + FileHandle *handle = (FileHandle*) method_handle; + + file_handle_unref (handle); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_get_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + TarFile *tar = ensure_tarfile (uri); + GNode *node; + union TARPET_block *current; + gchar *name; + gchar *path; + char *mime_type; + int i; + + if (uri->text) + node = tree_lookup_entry (tar->info_tree, uri->text); + else + node = tar->info_tree->children; + + if (!node) + { + tar_file_unref (tar); + return GNOME_VFS_ERROR_NOT_FOUND; + } + + current = node->data; + for (i = 0; i < tar->num_blocks; i++) + if (&(tar->blocks[i]) == current) + break; + if (i && tar->blocks[i - 2].p.typeflag == TARPET_TYPE_LONGFILEN) + name = g_strdup (tar->blocks[i - 1].raw.data); + else + name = g_strdup (current->p.name); + + file_info->name = g_path_get_basename (name); + if (name[strlen (name) - 1] == '/') + file_info->type = GNOME_VFS_FILE_TYPE_DIRECTORY; + else if (current->p.typeflag == TARPET_TYPE_SYMLINK) + { + file_info->type = GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK; + file_info->symlink_name = g_strdup (current->p.linkname); + } + else + file_info->type = GNOME_VFS_FILE_TYPE_REGULAR; + + file_info->permissions = parse_octal_field (current->p.mode); + file_info->uid = parse_octal_field (current->p.uid); + file_info->gid = parse_octal_field (current->p.gid); + file_info->size = parse_octal_field (current->p.size); + file_info->mtime = parse_octal_field (current->p.mtime); + file_info->atime = parse_octal_field (current->gnu.atime); + file_info->ctime = parse_octal_field (current->gnu.ctime); + + if (file_info->type == GNOME_VFS_FILE_TYPE_DIRECTORY) + mime_type = "x-directory/normal"; + else if (!(options & GNOME_VFS_FILE_INFO_FOLLOW_LINKS) && file_info->type == GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK) + mime_type = "x-special/symlink"; + else if (!file_info->size || (options & GNOME_VFS_FILE_INFO_FORCE_FAST_MIME_TYPE)) + { + path = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE); + mime_type = (char*) gnome_vfs_get_file_mime_type (path, NULL, TRUE); + g_free (path); + } + else + { + mime_type = (char*) gnome_vfs_get_mime_type_for_data ((current + 1)->raw.data, MIN (TARPET_BLOCKSIZE, file_info->size)); + if (!mime_type) + { + path = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE); + mime_type = (char*) gnome_vfs_get_file_mime_type (path, NULL, TRUE); + g_free (path); + } + } + + file_info->mime_type = g_strdup (mime_type); + + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_TYPE | + GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS | + GNOME_VFS_FILE_INFO_FIELDS_SIZE | + GNOME_VFS_FILE_INFO_FIELDS_ATIME | + GNOME_VFS_FILE_INFO_FIELDS_MTIME | + GNOME_VFS_FILE_INFO_FIELDS_CTIME | + GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + g_free (name); + tar_file_unref (tar); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_read_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSContext *context) +{ + FileHandle *handle = (FileHandle*) method_handle; + GnomeVFSURI *uri; + gchar *str; + GNode *node; + + if (!handle->current) + return GNOME_VFS_ERROR_EOF; + + str = g_strconcat (handle->filename, "#tar:", handle->current->p.name, NULL); + uri = gnome_vfs_uri_new (str); + do_get_file_info (method, uri, file_info, 0, context); + node = tree_lookup_entry (handle->tar->info_tree, uri->text); + if (!node) + { + gnome_vfs_uri_unref (uri); + return GNOME_VFS_ERROR_NOT_FOUND; + } + + if (node->next) + handle->current = node->next->data; + else + handle->current = NULL; + gnome_vfs_uri_unref (uri); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_get_file_info_from_handle (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + FileHandle *handle = (FileHandle*) method_handle; + GnomeVFSURI *uri; + + uri = gnome_vfs_uri_new (handle->start->p.name); + do_get_file_info (method, uri, file_info, options, context); + gnome_vfs_uri_unref (uri); + + return GNOME_VFS_OK; +} + +static gboolean +do_is_local (GnomeVFSMethod *method, + const GnomeVFSURI *uri) +{ + return gnome_vfs_uri_is_local (uri->parent); +} + +static GnomeVFSMethod method = +{ + sizeof (GnomeVFSMethod), + do_open, + NULL, + do_close, + do_read, + NULL, + do_seek, + do_tell, + NULL, + do_open_directory, + do_close_directory, + do_read_directory, + do_get_file_info, + do_get_file_info_from_handle, + do_is_local, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +GnomeVFSMethod * +vfs_module_init (const char *method_name, const char *args) +{ + G_LOCK (tar_cache); + tar_cache = g_hash_table_new (g_str_hash, g_str_equal); + G_UNLOCK (tar_cache); + return &method; +} + +void +vfs_module_shutdown (GnomeVFSMethod *method) +{ + G_LOCK (tar_cache); + g_hash_table_destroy (tar_cache); + G_UNLOCK (tar_cache); +} diff --git a/modules/tarpet.h b/modules/tarpet.h new file mode 100644 index 0000000..29679ad --- /dev/null +++ b/modules/tarpet.h @@ -0,0 +1,119 @@ +#ifndef TARPET_H +#define TARPET_H + +/* + * Tarpet - Tar struct definitions + * + * Placed in the public domain by Abigail Brady + * + * Implemented from a definition provided by Rachel Hestilow, + * md5sum 7606d69d61dfc7eed10857a888136b62 + * + * See documentation-1.1.txt for details. + * + */ + +struct TARPET_POSIX { + char name[100]; + char mode[8]; + char uid[8]; + char gid[8]; + char size[12]; + char mtime[12]; + char checksum[8]; + char typeflag; + char linkname[100]; + char magic[6]; + char version[2]; + char username[32]; + char groupname[32]; + char major[8]; + char minor[8]; + char extend[155]; +}; + +#define TARPET_TYPE_REGULAR '\0' +#define TARPET_TYPE_REGULAR2 '0' +#define TARPET_TYPE_LINK '1' +#define TARPET_TYPE_SYMLINK '2' +#define TARPET_TYPE_CHARDEV '3' +#define TARPET_TYPE_BLOCKDEV '4' +#define TARPET_TYPE_DIRECTORY '5' +#define TARPET_TYPE_FIFO '6' +#define TARPET_TYPE_CONTIGUOUS '7' + +#define TARPET_TYPE_DUMPDIR 'D' +#define TARPET_TYPE_LONGLINKN 'K' +#define TARPET_TYPE_LONGFILEN 'L' +#define TARPET_TYPE_MULTIVOL 'M' +#define TARPET_TYPE_LONGNAME 'N' +#define TARPET_TYPE_SPARSE 'S' +#define TARPET_TYPE_VOLUME 'V' + +#define TARPET_GNU_MAGIC "ustar" +#define TARPET_GNU_MAGIC_OLD "ustar " + +#define TARPET_GNU_VERSION "00" + +/* + * for the mode, #include and use + * + * S_ISUID + * S_ISGID + * + * S_IRUSR + * S_IWUSR + * S_IXUSR + * S_IRGRP + * S_IWGRP + * S_IXGRP + * S_IROTH + * S_IWOTH + * S_IXOTH + */ + +struct TARPET_sparsefile { + char padding[12]; + char numbytes[12]; +}; + +struct TARPET_GNU_ext { + char atime[12]; + char ctime[12]; + char offset[12]; + char realsize[12]; + char longnames[4]; + char padding[68]; + struct TARPET_sparsefile sparse[16]; + char extend; +}; + +struct TARPET_GNU_ext_old { + char padding[345]; + char atime[12]; + char ctime[12]; + char longnames[4]; + char padding2; + struct TARPET_sparsefile sparse[4]; + char extend; + char realsize[12]; +}; + +struct TARPET_GNU_sparseheader { + struct TARPET_sparsefile sparse[21]; + char extend; +}; + +struct TARPET_rawdata { + char data[512]; +}; + +union TARPET_block { + struct TARPET_POSIX p; + struct TARPET_GNU_ext gnu; + struct TARPET_GNU_ext_old gnu_old; + struct TARPET_GNU_sparseheader sparse; + struct TARPET_rawdata raw; +}; + +#endif diff --git a/modules/test-method.c b/modules/test-method.c new file mode 100644 index 0000000..16a037d --- /dev/null +++ b/modules/test-method.c @@ -0,0 +1,615 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* Test-method.c: Gnome-VFS testing method + + Copyright (C) 2000 Eazel + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Seth Nickell (seth@eazel.com) */ + +/* Create a settings file and put it at PREFIX/etc/vfs/Test-conf.xml, + * then point gnome-vfs clients to test: which will + * translate into the "real" method (e.g. test:///home/seth). + * + * The delay is in milliseconds. + * + * Here's a sample config file (pointing to the file method): + * + * + * + * + * + * */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TEST_CONF_ENV_VARIABLE "GNOME_VFS_TEST_CONFIG_FILE" + +typedef struct { + char *operation_name; + int delay; + gboolean skip; + gboolean override_result; + GnomeVFSResult overridden_result_value; +} OperationSettings; + +#define NUM_RESULT_STRINGS 41 + +static gboolean properly_initialized; + +static char *test_method_name; +static GList *settings_list; + +static const char * const +result_strings[NUM_RESULT_STRINGS] = { + "GNOME_VFS_OK", + "GNOME_VFS_ERROR_NOT_FOUND", + "GNOME_VFS_ERROR_GENERIC", + "GNOME_VFS_ERROR_INTERNAL", + "GNOME_VFS_ERROR_BAD_PARAMETERS", + "GNOME_VFS_ERROR_NOT_SUPPORTED", + "GNOME_VFS_ERROR_IO", + "GNOME_VFS_ERROR_CORRUPTED_DATA", + "GNOME_VFS_ERROR_WRONG_FORMAT", + "GNOME_VFS_ERROR_BAD_FILE", + "GNOME_VFS_ERROR_TOO_BIG", + "GNOME_VFS_ERROR_NO_SPACE", + "GNOME_VFS_ERROR_READ_ONLY", + "GNOME_VFS_ERROR_INVALID_URI", + "GNOME_VFS_ERROR_NOT_OPEN", + "GNOME_VFS_ERROR_INVALID_OPEN_MODE", + "GNOME_VFS_ERROR_ACCESS_DENIED", + "GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES", + "GNOME_VFS_ERROR_EOF", + "GNOME_VFS_ERROR_NOT_A_DIRECTORY", + "GNOME_VFS_ERROR_IN_PROGRESS", + "GNOME_VFS_ERROR_INTERRUPTED", + "GNOME_VFS_ERROR_FILE_EXISTS", + "GNOME_VFS_ERROR_LOOP", + "GNOME_VFS_ERROR_NOT_PERMITTED", + "GNOME_VFS_ERROR_IS_DIRECTORY", + "GNOME_VFS_ERROR_NO_MEMORY", + "GNOME_VFS_ERROR_HOST_NOT_FOUND", + "GNOME_VFS_ERROR_INVALID_HOST_NAME", + "GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS", + "GNOME_VFS_ERROR_LOGIN_FAILED", + "GNOME_VFS_ERROR_CANCELLED", + "GNOME_VFS_ERROR_DIRECTORY_BUSY", + "GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY", + "GNOME_VFS_ERROR_TOO_MANY_LINKS", + "GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM", + "GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM", + "GNOME_VFS_ERROR_NAME_TOO_LONG", + "GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE", + "GNOME_VFS_NUM_ERRORS" +}; + +/* Module entry points. */ +GnomeVFSMethod *vfs_module_init (const char *method_name, + const char *args); +void vfs_module_shutdown (GnomeVFSMethod *method); + +static GnomeVFSURI * +translate_uri (GnomeVFSURI *uri) +{ + GnomeVFSURI *translated_uri; + char *uri_text; + char *translated_uri_text; + char *no_method; + + uri_text = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE); + no_method = strchr (uri_text, ':'); + + if (test_method_name != NULL) { + translated_uri_text = g_strconcat (test_method_name, + no_method, NULL); + } else { + translated_uri_text = NULL; + } + + if (translated_uri_text != NULL) { + translated_uri = gnome_vfs_uri_new (translated_uri_text); + } else { + translated_uri = NULL; + } + + g_free (translated_uri_text); + g_free (uri_text); + + return translated_uri; +} + +/* reads the configuration file and returns TRUE if there are special options for + this execution of the operation. + + if TRUE is returned then result will contain the result the operation should return + and perform_operation will be TRUE if the operation should execute the underlying + operation anyway +*/ +static const OperationSettings * +get_operation_settings (const char *function_identifier) +{ + static OperationSettings empty_settings; + GList *node; + OperationSettings *settings; + + for (node = settings_list; node != NULL; node = node->next) { + settings = node->data; + if (g_ascii_strcasecmp (settings->operation_name, function_identifier) == 0) { + return settings; + } + } + + return &empty_settings; +} + +static const OperationSettings * +start_operation (const char *name, + GnomeVFSURI **uri, + GnomeVFSURI **saved_uri) +{ + const OperationSettings *settings; + struct timeval tv; + + settings = get_operation_settings (name); + + tv.tv_sec = settings->delay / 1000; + tv.tv_usec = 1000 * (settings->delay % 1000); + select (0, NULL, NULL, NULL, &tv); + + if (uri != NULL) { + *saved_uri = *uri; + *uri = translate_uri (*uri); + } + return settings; +} + +static GnomeVFSResult +finish_operation (const OperationSettings *settings, + GnomeVFSResult result, + GnomeVFSURI **uri, + GnomeVFSURI **saved_uri) +{ + if (uri != NULL) { + gnome_vfs_uri_unref (*uri); + *uri = *saved_uri; + } + + if (settings->override_result) { + return settings->overridden_result_value; + } + return result; +} + +#define PERFORM_OPERATION(name, operation) \ +do { \ + const OperationSettings *settings; \ + GnomeVFSURI *saved_uri; \ + GnomeVFSResult result; \ + \ + if (!properly_initialized) { \ + return GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE; \ + } \ + \ + settings = start_operation (#name, &uri, &saved_uri); \ + if (settings->skip) { \ + result = GNOME_VFS_OK; \ + } else { \ + result = operation; \ + } \ + return finish_operation (settings, result, \ + &uri, &saved_uri); \ +} while (0) + + +#define PERFORM_OPERATION_NO_URI(name, operation) \ +do { \ + const OperationSettings *settings; \ + GnomeVFSResult result; \ + \ + if (!properly_initialized) { \ + return GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE; \ + } \ + \ + settings = start_operation (#name, NULL, NULL); \ + if (settings->skip) { \ + result = GNOME_VFS_OK; \ + } else { \ + result = operation; \ + } \ + return finish_operation (settings, result, \ + NULL, NULL); \ +} while (0) + +static gboolean +parse_result_text (const char *result_text, + GnomeVFSResult *result_code) +{ + int i; + + for (i = 0; i < NUM_RESULT_STRINGS; i++) { + if (g_ascii_strcasecmp (result_text, result_strings[i]) == 0) { + *result_code = i; + return TRUE; + } + } + + return FALSE; +} + +static gboolean +load_settings (const char *filename) +{ + xmlDocPtr doc; + xmlNodePtr node; + char *name; + OperationSettings *operation; + char *str; + + doc = xmlParseFile (filename); + + if (doc == NULL + || doc->xmlRootNode == NULL + || doc->xmlRootNode->name == NULL + || g_ascii_strcasecmp (doc->xmlRootNode->name, "testmodule") != 0) { + xmlFreeDoc(doc); + return FALSE; + } + + test_method_name = xmlGetProp (doc->xmlRootNode, "method"); + + for (node = doc->xmlRootNode->xmlChildrenNode; node != NULL; node = node->next) { + name = xmlGetProp (node, "name"); + if (name == NULL) { + continue; + } + + operation = g_new0 (OperationSettings, 1); + operation->operation_name = name; + + str = xmlGetProp (node, "delay"); + if (str != NULL) { + sscanf (str, "%d", &operation->delay); + } + xmlFree (str); + + str = xmlGetProp(node, "execute_operation"); + if (str != NULL && g_ascii_strcasecmp (str, "FALSE") == 0) { + operation->skip = TRUE; + } + xmlFree (str); + + str = xmlGetProp (node, "result"); + if (str != NULL) { + operation->override_result = parse_result_text + (str, &operation->overridden_result_value); + } + xmlFree (str); + + settings_list = g_list_prepend (settings_list, operation); + } + return TRUE; +} + +static GnomeVFSResult +do_open (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + GnomeVFSContext *context) +{ + PERFORM_OPERATION (open, gnome_vfs_open_uri_cancellable ((GnomeVFSHandle **) method_handle, uri, mode, context)); +} + +static GnomeVFSResult +do_create (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + gboolean exclusive, + guint perm, + GnomeVFSContext *context) +{ + /* FIXME bugzilla.eazel.com 3837: Not implemented. */ + return GNOME_VFS_ERROR_INTERNAL; +} + +static GnomeVFSResult +do_close (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + PERFORM_OPERATION_NO_URI (close, gnome_vfs_close_cancellable ((GnomeVFSHandle *) method_handle, context)); +} + +static GnomeVFSResult +do_read (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read, + GnomeVFSContext *context) +{ + PERFORM_OPERATION_NO_URI (read, gnome_vfs_read_cancellable ((GnomeVFSHandle *) method_handle, buffer, num_bytes, bytes_read, context)); +} + +static GnomeVFSResult +do_write (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gconstpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_written, + GnomeVFSContext *context) +{ + PERFORM_OPERATION_NO_URI (write, gnome_vfs_write_cancellable((GnomeVFSHandle *) method_handle, buffer, num_bytes, bytes_written, context)); +} + +static GnomeVFSResult +do_seek (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSSeekPosition whence, + GnomeVFSFileOffset offset, + GnomeVFSContext *context) +{ + PERFORM_OPERATION_NO_URI (seek, gnome_vfs_seek_cancellable ((GnomeVFSHandle *) method_handle, whence, offset, context)); +} + +static GnomeVFSResult +do_tell (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileOffset *offset_return) +{ + PERFORM_OPERATION_NO_URI (tell, gnome_vfs_tell ((GnomeVFSHandle *) method_handle, offset_return)); +} + + +static GnomeVFSResult +do_open_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + PERFORM_OPERATION (open_directory, gnome_vfs_directory_open_from_uri ((GnomeVFSDirectoryHandle **) method_handle, uri, options)); +} + +static GnomeVFSResult +do_close_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + PERFORM_OPERATION_NO_URI (close_directory, gnome_vfs_directory_close ((GnomeVFSDirectoryHandle *) method_handle)); +} + +static GnomeVFSResult +do_read_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSContext *context) +{ + PERFORM_OPERATION_NO_URI (read_directory, gnome_vfs_directory_read_next ((GnomeVFSDirectoryHandle *) method_handle, file_info)); +} + +static GnomeVFSResult +do_get_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + PERFORM_OPERATION (get_file_info, gnome_vfs_get_file_info_uri_cancellable (uri, file_info, options, context)); +} + +static GnomeVFSResult +do_get_file_info_from_handle (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + PERFORM_OPERATION_NO_URI (get_file_info_from_handle, gnome_vfs_get_file_info_from_handle_cancellable ((GnomeVFSHandle *) method_handle, file_info, options, context)); +} + +static gboolean +do_is_local (GnomeVFSMethod *method, + const GnomeVFSURI *uri) +{ + /* FIXME bugzilla.eazel.com 3837: Not implemented. */ + return TRUE; +} + +static GnomeVFSResult +do_make_directory (GnomeVFSMethod *method, + GnomeVFSURI *uri, + guint perm, + GnomeVFSContext *context) +{ + PERFORM_OPERATION (make_directory, gnome_vfs_make_directory_for_uri_cancellable (uri, perm, context)); +} + +static GnomeVFSResult +do_remove_directory (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSContext *context) +{ + PERFORM_OPERATION (remove_directory, gnome_vfs_remove_directory_from_uri_cancellable (uri, context)); +} + +static GnomeVFSResult +do_move (GnomeVFSMethod *method, + GnomeVFSURI *old_uri, + GnomeVFSURI *new_uri, + gboolean force_replace, + GnomeVFSContext *context) +{ + /* FIXME bugzilla.eazel.com 3837: Not implemented. */ + return gnome_vfs_move_uri_cancellable (old_uri, new_uri, force_replace, context); +} + +static GnomeVFSResult +do_unlink (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSContext *context) +{ + PERFORM_OPERATION (unlink, gnome_vfs_unlink_from_uri_cancellable (uri, context)); +} + +static GnomeVFSResult +do_check_same_fs (GnomeVFSMethod *method, + GnomeVFSURI *a, + GnomeVFSURI *b, + gboolean *same_fs_return, + GnomeVFSContext *context) +{ + /* FIXME bugzilla.eazel.com 3837: Not implemented. */ + return gnome_vfs_check_same_fs_uris_cancellable (a, b, same_fs_return, context); +} + +static GnomeVFSResult +do_set_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + const GnomeVFSFileInfo *info, + GnomeVFSSetFileInfoMask mask, + GnomeVFSContext *context) +{ + PERFORM_OPERATION (set_file_info, gnome_vfs_set_file_info_cancellable (uri, info, mask, context)); +} + +static GnomeVFSResult +do_truncate (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileSize where, + GnomeVFSContext *context) +{ + PERFORM_OPERATION (truncate, gnome_vfs_truncate_uri_cancellable (uri, where, context)); +} + +static GnomeVFSResult +do_truncate_handle (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileSize where, + GnomeVFSContext *context) +{ + PERFORM_OPERATION_NO_URI (truncate_handle, gnome_vfs_truncate_handle_cancellable ((GnomeVFSHandle *) method_handle, where, context)); +} + +static GnomeVFSResult +do_find_directory (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFindDirectoryKind kind, + GnomeVFSURI **result_uri, + gboolean create_if_needed, + gboolean find_if_needed, + guint permissions, + GnomeVFSContext *context) +{ + PERFORM_OPERATION (find_directory, gnome_vfs_find_directory_cancellable (uri, kind, result_uri, create_if_needed, find_if_needed, permissions, context)); +} + +static GnomeVFSResult +do_create_symbolic_link (GnomeVFSMethod *method, + GnomeVFSURI *uri, + const char *target_reference, + GnomeVFSContext *context) +{ + PERFORM_OPERATION (create_symbolic_link, gnome_vfs_create_symbolic_link_cancellable (uri, target_reference, context)); +} + +static GnomeVFSMethod method = { + sizeof (GnomeVFSMethod), + do_open, + do_create, + do_close, + do_read, + do_write, + do_seek, + do_tell, + do_truncate_handle, + do_open_directory, + do_close_directory, + do_read_directory, + do_get_file_info, + do_get_file_info_from_handle, + do_is_local, + do_make_directory, + do_remove_directory, + do_move, + do_unlink, + do_check_same_fs, + do_set_file_info, + do_truncate, + do_find_directory, + do_create_symbolic_link +}; + + +GnomeVFSMethod * +vfs_module_init (const char *method_name, const char *args) +{ + char *conf_file; + + LIBXML_TEST_VERSION + + conf_file = getenv (TEST_CONF_ENV_VARIABLE); + + if (conf_file == NULL) { + conf_file = PREFIX "/etc/vfs/Test-conf.xml"; + } + + if (load_settings (conf_file) == FALSE) { + + // FIXME: we probably shouldn't use printf to output the message + printf (_("Didn't find a valid settings file at %s\n"), + conf_file); + printf (_("Use the %s environment variable to specify a different location.\n"), + TEST_CONF_ENV_VARIABLE); + properly_initialized = FALSE; + } else { + properly_initialized = TRUE; + } + + return &method; +} + +void +vfs_module_shutdown (GnomeVFSMethod *method) +{ + GList *node; + OperationSettings *settings; + + for (node = settings_list; node != NULL; node = node->next) { + settings = node->data; + xmlFree (settings->operation_name); + g_free (settings); + } + g_list_free (settings_list); + xmlFree (test_method_name); +} diff --git a/modules/translate-method.c b/modules/translate-method.c new file mode 100644 index 0000000..5151584 --- /dev/null +++ b/modules/translate-method.c @@ -0,0 +1,1257 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* translate-method.c - translator method for GNOME Virtual File System + + Copyright (C) 1999, 2000 Red Hat Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Elliot Lee */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct { + enum { + MODE_BASIC, MODE_EXEC + } mode; + + char *default_mime_type; + char *real_method_name; + + union { + struct { + char *trans_string; + } basic; + struct { + int argc; + char **argv; + char *orig_string; /* this string gets chopped up into argv--it exists for freeing only */ + gboolean retain; + } exec; + }u; +} ParsedArgs; + +/* State used for -exec -retain */ +typedef struct { + GMutex * retain_lock; + FILE * retain_to; /* pipe to child */ + FILE * retain_from; /* pipe from child */ + pid_t retain_pid; /* PID of child */ +} ExecState; + +typedef struct { + GnomeVFSMethod base_method; + ParsedArgs pa; + GnomeVFSMethod *real_method; + ExecState exec_state; +} TranslateMethod; + +static void +tr_apply_default_mime_type(TranslateMethod * tm, + GnomeVFSFileInfo * file_info) +{ + /* Only apply the default mime-type if the real method returns + * unknown mime-type and the the TranslateMethod /has/ a mime-type */ + if (file_info->mime_type == NULL) { + /* FIXME bugzilla.eazel.com 2799: + * this may not be needed since methods need to + * return application/octet-stream if it is an unknown + * mime-type, not NULL */ + if (tm->pa.default_mime_type) { + file_info->mime_type = + g_strdup (tm->pa.default_mime_type); + file_info->valid_fields |= + GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + } + + } else { + if ((strcmp (file_info->mime_type, GNOME_VFS_MIME_TYPE_UNKNOWN) == 0) && + (tm->pa.default_mime_type != NULL)) { + g_free (file_info->mime_type); + file_info->mime_type = + g_strdup (tm->pa.default_mime_type); + file_info->valid_fields |= + GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + } + } +} + +typedef struct { + int child_out_fd; + int child_in_fd; +} TrForkCBData; + +static void /* GnomeVFSProcessInitFunc */ tr_forkexec_cb (gpointer data) +{ + TrForkCBData *cb_data; + + g_assert (NULL != data); + cb_data = (TrForkCBData *) data; + + if ( -1 == dup2 (cb_data->child_in_fd, STDIN_FILENO) ) { + _exit (-1); + } + + if ( -1 == dup2 (cb_data->child_out_fd, STDOUT_FILENO) ) { + _exit (-1); + } + +} + + +static pid_t tr_exec_open_child (char **argv, /*OUT*/ FILE ** p_from_stream, /*OUT*/ FILE ** p_to_stream) +{ + pid_t ret; + int err; + TrForkCBData cb_data; + void *sigpipe_old; + int pipe_to_child[2] = { -1, -1 }; + int pipe_to_parent[2] = { -1, -1 }; + + g_assert ( NULL != p_from_stream ); + g_assert ( NULL != p_to_stream ); + + *p_to_stream = NULL; + *p_from_stream = NULL; + + /* Blocking SIGPIPE here is probably unnecessary -- + * GnomeVFS already does this on init + */ + sigpipe_old = signal (SIGPIPE, SIG_IGN); + + err = pipe (pipe_to_child); + + if ( 0 != err ) { + g_warning ("pipe returned error %d", errno); + ret = -1; + goto error; + } + + err = pipe (pipe_to_parent); + + if ( 0 != err ) { + g_warning ("pipe returned error %d", errno); + ret = -1; + goto error; + } + + cb_data.child_out_fd = pipe_to_parent[1]; + cb_data.child_in_fd = pipe_to_child[0]; + + /* Strictly speaking, this is unnecessary since these handles will be closed anyway*/ + err = fcntl ( pipe_to_parent[0], F_SETFD, FD_CLOEXEC ) ; + g_assert (0 == err ); + err = fcntl ( pipe_to_child[1], F_SETFD, FD_CLOEXEC ) ; + g_assert (0 == err ); + + ret = gnome_vfs_forkexec ( argv[0], + (const char * const*)argv, + GNOME_VFS_PROCESS_CLOSEFDS, + tr_forkexec_cb, + (gpointer) &cb_data + ); + + close (pipe_to_parent[1]); + pipe_to_parent[1] = -1; + close (pipe_to_child[0]); + pipe_to_child[0] = -1; + + if ( -1 == ret ) { + g_warning ("fork returned error %d", errno); + goto error; + } + + *p_to_stream = fdopen (pipe_to_child[1], "w"); + g_assert ( NULL != *p_to_stream ); + pipe_to_child[1] = -1; + + *p_from_stream = fdopen (pipe_to_parent[0], "r"); + g_assert ( NULL != *p_from_stream ); + pipe_to_parent[0] = -1; + + setvbuf (*p_to_stream, NULL, _IOLBF, 0); + setvbuf (*p_from_stream, NULL, _IOLBF, 0); + +error: + if ( -1 != pipe_to_parent[0] ) { close ( pipe_to_parent[0]); } + if ( -1 != pipe_to_parent[1] ) { close ( pipe_to_parent[1]); } + if ( -1 != pipe_to_child[0] ) { close ( pipe_to_child[0]); } + if ( -1 != pipe_to_child[1] ) { close ( pipe_to_child[1]); } + + signal (SIGPIPE, sigpipe_old); + + return ret; +} + +#define GETLINE_DELTA 256 +static char * tr_getline (FILE* stream) +{ + char *ret; + size_t ret_size; + size_t ret_used; + int char_read; + gboolean got_newline; + + ret = g_malloc( GETLINE_DELTA * sizeof(char) ); + ret_size = GETLINE_DELTA; + + for ( ret_used = 0, got_newline = FALSE ; + !got_newline && (EOF != (char_read = fgetc (stream))) ; + ret_used++ + ) { + if (ret_size == (ret_used + 1)) { + ret_size += GETLINE_DELTA; + ret = g_realloc (ret, ret_size); + } + if ('\n' == char_read || '\r' == char_read ) { + got_newline = TRUE; + ret [ret_used] = '\0'; + } else { + ret [ret_used] = char_read; + } + } + + if (got_newline) { + return ret; + } else { + g_free (ret); + return NULL; + } +} +#undef GETLINE_DELTA + +static void tr_exec_pass_uri (char *uri_string, FILE * out_stream) +{ + char *tmpstr; + + /*shave off the scheme--pass only the right hand side to the child*/ + tmpstr = strchr (uri_string, ':'); + fprintf (out_stream, "%s\n", tmpstr ? tmpstr + 1 : uri_string); + fflush (out_stream); + + tmpstr = NULL; + +} + +static char * tr_exec_do_retain (TranslateMethod *tm, char * uri_string) +{ + char * child_result = NULL; + int tries; + + g_mutex_lock (tm->exec_state.retain_lock); + + + /* re-execute the child process in case it unexpectedly disappears */ + for (tries = 0 ; ( ! child_result ) && tries < 3 ; tries ++) { + if ( 0 == tm->exec_state.retain_pid ) { + tm->exec_state.retain_pid = tr_exec_open_child (tm->pa.u.exec.argv, &(tm->exec_state.retain_from), &(tm->exec_state.retain_to)); + if ( -1 == tm->exec_state.retain_pid ) { + tm->exec_state.retain_pid = 0; + goto error; + } + } + + g_assert (uri_string); + tr_exec_pass_uri (uri_string, tm->exec_state.retain_to); + + child_result = tr_getline (tm->exec_state.retain_from); + + if (NULL == child_result) { + tm->exec_state.retain_pid = 0; + } + } + +error: + g_mutex_unlock (tm->exec_state.retain_lock); + + return child_result; +} + +/* + * -exec + * + * USAGE: -exec -real-method [-retain] + * + * -exec allows a child process to filter and translate URI's passed to GNOME-VFS. + * -exec requires a URI scheme to be specified via -real-method, and does not + * allow the child process to change that method + * + * is a string that will be tokenized and passed to execv() + * is the URI scheme that all requests will be translated to. + * + * Without -retain: + * The child process is exec()'d. The URI minus the scheme is presented + * as standard input. On success, the child is expected to print out + * a translated URI minus the scheme and exit(0). On failure, the child + * should print out ":\n" or exit with a non-zero value + * + * With -retain + * The child process is exec()'d and fed multiple URI's, each newline terminated, + * via standard in. For each URI, the child must print to standard out a + * translated URI followed by a newline or a ":" followed by a newline on error. + * + * Note than children written to work with -retain that use stdio need + * to set their stdin and stdout buffering discipline to "line" instead of "block" + * like this: + * setvbuf (stdin, NULL, _IOLBF, 0); + * setvbuf (stdout, NULL, _IOLBF, 0); + * + * Config file example: + * + * foo: libvfs-translate.so -real-method http -exec "/bin/sed -e s/\/\/www.microsoft.com/\/\/www.eazel.com/" + * + * (note that sed won't work with -retain) + */ + +/* FIXME bugzilla.eazel.com 2796: this may be broken when the child produces compound URI's */ +static GnomeVFSURI *tr_handle_exec (TranslateMethod *tm, const GnomeVFSURI * uri) +{ + + int err; + char *tmpstr; + + int child_status; + char *uri_string = NULL; + char *child_result = NULL; + GnomeVFSURI * retval = NULL; + + /* + * Note that normally having a parent and child communicate + * bi-directionally via pipes is a bad idea. However, in this case, + * the parent will write everything and then close, so it'll all be OK + * as long as the child doesnt intermix reads and writes and fill + * up their output pipe's buffer before the parent is done writing. + */ + + uri_string = gnome_vfs_uri_to_string (uri, 0); + + if ( NULL == uri_string ) { + goto error; + } + + if (tm->pa.u.exec.retain) { + child_result = tr_exec_do_retain (tm, uri_string); + + if ( NULL == child_result ) { + goto error; + } + } else { + pid_t child_pid; + FILE *from_stream, *to_stream; + + child_pid = tr_exec_open_child (tm->pa.u.exec.argv, &from_stream, &to_stream); + + if ( -1 == child_pid ) { + goto error; + } + + uri_string = gnome_vfs_uri_to_string (uri, 0); + g_assert (uri_string); + tr_exec_pass_uri (uri_string, to_stream); + + fclose (to_stream); + to_stream = NULL; + + child_result = tr_getline (from_stream); + + err = waitpid (child_pid, &child_status, 0); + + g_assert ( child_pid == err ); + + if (! WIFEXITED (child_status) ) { + goto error; + } + + if (NULL == child_result) { + g_warning ("Child produced no result"); + goto error; + } + } + + + /* FIXME bugzilla.eazel.com 2797: + * just because we've appended the same scheme, doesn't mean + * we're going to get the same method from gnome_vfs_uri_new + */ + + /* A child result that ends in a :\n indicates an error */ + if ( ':' != child_result[ strlen(child_result) - 1 ]) { + /* append the real scheme */ + tmpstr = g_strconcat (tm->pa.real_method_name, ":", child_result, NULL); + g_free (child_result); + child_result = tmpstr; + tmpstr = NULL; + + retval = gnome_vfs_uri_new_private (child_result, FALSE, TRUE, TRUE); + + if ( NULL == retval ) { + g_warning ("Unable to make URI from child process's result '%s'", child_result); + goto error; + } + } + + +error: + g_free (child_result); + g_free (uri_string); + + return retval; +} + +static void +tr_exec_init (ExecState *exec_state) +{ + exec_state->retain_lock = g_mutex_new(); +} + +static void +tr_exec_cleanup (ExecState *exec_state) +{ + if (NULL != exec_state->retain_lock) { + g_mutex_free (exec_state->retain_lock); + } + + if (NULL != exec_state->retain_to) { + fclose (exec_state->retain_to); + } + if (NULL != exec_state->retain_from) { + fclose (exec_state->retain_from); + } + + if ( 0 != exec_state->retain_pid ) { + int child_status, err; + + kill (exec_state->retain_pid, SIGTERM); + err = waitpid (exec_state->retain_pid, &child_status, 0); + g_assert (err == exec_state->retain_pid); + } +} + +static GnomeVFSURI *tr_uri_translate(TranslateMethod * tm, + const GnomeVFSURI * uri) +{ + const char *text_uri; + const char *text_uri_no_method; + char *translated_text; + char *translated_uri; + GnomeVFSURI *retval; + + retval = NULL; + + if (uri->method != (GnomeVFSMethod *) tm) + return gnome_vfs_uri_ref((GnomeVFSURI *) uri); /* Don't translate things that don't belong to us */ + + /* Hack it all up to pieces */ + + if (MODE_BASIC == tm->pa.mode) { + text_uri = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE); + text_uri_no_method = strchr (text_uri, ':'); + + if (text_uri_no_method == NULL) { + text_uri_no_method = text_uri; + } else { + text_uri_no_method = text_uri_no_method + 1; + } + + translated_text = g_strdup_printf (tm->pa.u.basic.trans_string, + uri->text, uri->text, + uri->text, uri->text, uri->text); + translated_uri = g_strconcat (tm->pa.real_method_name, ":", + translated_text, NULL); + + retval = gnome_vfs_uri_new_private (translated_uri, FALSE, TRUE, TRUE); + + g_free (translated_text); + g_free (translated_uri); + } else if (MODE_EXEC == tm->pa.mode) { + retval = tr_handle_exec (tm, uri); + } else { + g_assert (FALSE); + } + + return retval; +} + +static GnomeVFSResult +tr_do_open(GnomeVFSMethod * method, + GnomeVFSMethodHandle ** method_handle_return, + GnomeVFSURI * uri, + GnomeVFSOpenMode mode, GnomeVFSContext * context) +{ + TranslateMethod *tm = (TranslateMethod *) method; + GnomeVFSURI *real_uri; + GnomeVFSResult retval; + + real_uri = tr_uri_translate(tm, uri); + + if ( NULL != real_uri ) { + retval = + tm->real_method->open(tm->real_method, method_handle_return, + real_uri, mode, context); + + gnome_vfs_uri_unref(real_uri); + } else { + retval = GNOME_VFS_ERROR_NOT_FOUND; + } + + return retval; +} + +static GnomeVFSResult +tr_do_create(GnomeVFSMethod * method, + GnomeVFSMethodHandle + ** method_handle_return, + GnomeVFSURI * uri, + GnomeVFSOpenMode mode, + gboolean exclusive, guint perm, GnomeVFSContext * context) +{ + TranslateMethod *tm = (TranslateMethod *) method; + GnomeVFSURI *real_uri; + GnomeVFSResult retval; + + real_uri = tr_uri_translate(tm, uri); + + if ( NULL != real_uri ) { + retval = + tm->real_method->create(tm->real_method, method_handle_return, + real_uri, mode, exclusive, perm, + context); + gnome_vfs_uri_unref(real_uri); + } else { + retval = GNOME_VFS_ERROR_NOT_FOUND; + } + + return retval; +} + +static GnomeVFSResult +tr_do_close(GnomeVFSMethod * method, + GnomeVFSMethodHandle * method_handle, + GnomeVFSContext * context) +{ + TranslateMethod *tm = (TranslateMethod *) method; + return tm->real_method->close(tm->real_method, method_handle, + context); +} + +static GnomeVFSResult +tr_do_read(GnomeVFSMethod * method, + GnomeVFSMethodHandle * method_handle, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize * bytes_read_return, GnomeVFSContext * context) +{ + TranslateMethod *tm = (TranslateMethod *) method; + return tm->real_method->read(tm->real_method, method_handle, + buffer, num_bytes, bytes_read_return, + context); +} + +static GnomeVFSResult +tr_do_write(GnomeVFSMethod * method, + GnomeVFSMethodHandle * method_handle, + gconstpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize * bytes_written_return, + GnomeVFSContext * context) +{ + TranslateMethod *tm = (TranslateMethod *) method; + return tm->real_method->write(tm->real_method, method_handle, + buffer, num_bytes, + bytes_written_return, context); +} + +static GnomeVFSResult +tr_do_seek(GnomeVFSMethod * method, + GnomeVFSMethodHandle * method_handle, + GnomeVFSSeekPosition whence, + GnomeVFSFileOffset offset, GnomeVFSContext * context) +{ + TranslateMethod *tm = (TranslateMethod *) method; + return tm->real_method->seek(tm->real_method, method_handle, + whence, offset, context); +} + +static GnomeVFSResult +tr_do_tell(GnomeVFSMethod * method, + GnomeVFSMethodHandle * method_handle, + GnomeVFSFileOffset * offset_return) +{ + TranslateMethod *tm = (TranslateMethod *) method; + return tm->real_method->tell(tm->real_method, method_handle, + offset_return); +} + +static GnomeVFSResult +tr_do_open_directory(GnomeVFSMethod * method, + GnomeVFSMethodHandle ** method_handle, + GnomeVFSURI * uri, + GnomeVFSFileInfoOptions options, + GnomeVFSContext * context) +{ + TranslateMethod *tm = (TranslateMethod *) method; + GnomeVFSURI *real_uri; + GnomeVFSResult retval; + + real_uri = tr_uri_translate(tm, uri); + + if ( NULL != real_uri ) { + retval = + tm->real_method->open_directory(tm->real_method, method_handle, + real_uri, options, + context); + gnome_vfs_uri_unref(real_uri); + } else { + retval = GNOME_VFS_ERROR_NOT_FOUND; + } + + return retval; +} + +static GnomeVFSResult +tr_do_close_directory(GnomeVFSMethod * method, + GnomeVFSMethodHandle * method_handle, + GnomeVFSContext * context) +{ + TranslateMethod *tm = (TranslateMethod *) method; + return tm->real_method->close_directory(tm->real_method, + method_handle, context); +} + +static GnomeVFSResult +tr_do_read_directory(GnomeVFSMethod * method, + GnomeVFSMethodHandle * method_handle, + GnomeVFSFileInfo * file_info, + GnomeVFSContext * context) +{ + TranslateMethod *tm = (TranslateMethod *) method; + GnomeVFSResult retval; + + retval = + tm->real_method->read_directory(tm->real_method, method_handle, + file_info, context); + + tr_apply_default_mime_type(tm, file_info); + + return retval; +} + +static GnomeVFSResult +tr_do_get_file_info(GnomeVFSMethod * method, + GnomeVFSURI * uri, + GnomeVFSFileInfo * file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext * context) +{ + TranslateMethod *tm = (TranslateMethod *) method; + GnomeVFSURI *real_uri; + GnomeVFSResult retval; + + real_uri = tr_uri_translate(tm, uri); + + if ( NULL != real_uri ) { + retval = + tm->real_method->get_file_info(tm->real_method, real_uri, + file_info, options, + context); + + gnome_vfs_uri_unref(real_uri); + } else { + retval = GNOME_VFS_ERROR_NOT_FOUND; + } + + tr_apply_default_mime_type(tm, file_info); + + return retval; +} + +static GnomeVFSResult +tr_do_get_file_info_from_handle(GnomeVFSMethod * method, + GnomeVFSMethodHandle * method_handle, + GnomeVFSFileInfo * file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext * context) +{ + TranslateMethod *tm = (TranslateMethod *) method; + GnomeVFSResult retval; + + retval = + tm->real_method->get_file_info_from_handle(tm->real_method, + method_handle, + file_info, + options, + context); + + tr_apply_default_mime_type(tm, file_info); + + return retval; +} + +static GnomeVFSResult +tr_do_truncate(GnomeVFSMethod * method, + GnomeVFSURI * uri, + GnomeVFSFileSize length, GnomeVFSContext * context) +{ + TranslateMethod *tm = (TranslateMethod *) method; + GnomeVFSURI *real_uri; + GnomeVFSResult retval; + + real_uri = tr_uri_translate(tm, uri); + + if ( NULL != real_uri ) { + retval = + tm->real_method->truncate(tm->real_method, real_uri, length, + context); + + gnome_vfs_uri_unref(real_uri); + } else { + retval = GNOME_VFS_ERROR_NOT_FOUND; + } + + return retval; +} + +static GnomeVFSResult +tr_do_truncate_handle(GnomeVFSMethod * method, + GnomeVFSMethodHandle * method_handle, + GnomeVFSFileSize length, GnomeVFSContext * context) +{ + TranslateMethod *tm = (TranslateMethod *) method; + + return tm->real_method->truncate_handle(tm->real_method, + method_handle, length, + context); +} + +static gboolean +tr_do_is_local(GnomeVFSMethod * method, const GnomeVFSURI * uri) +{ + TranslateMethod *tm = (TranslateMethod *) method; + GnomeVFSURI *real_uri; + GnomeVFSResult retval; + + real_uri = tr_uri_translate(tm, uri); + + if ( NULL != real_uri ) { + retval = tm->real_method->is_local(tm->real_method, real_uri); + + gnome_vfs_uri_unref(real_uri); + } else { + retval = GNOME_VFS_ERROR_NOT_FOUND; + } + + return retval; +} + +static GnomeVFSResult +tr_do_make_directory(GnomeVFSMethod * method, + GnomeVFSURI * uri, + guint perm, GnomeVFSContext * context) +{ + TranslateMethod *tm = (TranslateMethod *) method; + GnomeVFSURI *real_uri; + GnomeVFSResult retval; + + real_uri = tr_uri_translate(tm, uri); + + if ( NULL != real_uri ) { + retval = + tm->real_method->make_directory(tm->real_method, real_uri, + perm, context); + + gnome_vfs_uri_unref(real_uri); + } else { + retval = GNOME_VFS_ERROR_NOT_FOUND; + } + + return retval; +} + +static GnomeVFSResult +tr_do_find_directory(GnomeVFSMethod * method, + GnomeVFSURI * near_uri, + GnomeVFSFindDirectoryKind kind, + GnomeVFSURI ** result_uri, + gboolean create_if_needed, + gboolean find_if_needed, + guint permissions, GnomeVFSContext * context) +{ + TranslateMethod *tm = (TranslateMethod *) method; + GnomeVFSURI *real_uri; + GnomeVFSResult retval; + + real_uri = tr_uri_translate(tm, near_uri); + + if ( NULL != real_uri ) { + retval = + tm->real_method->find_directory(tm->real_method, real_uri, + kind, result_uri, + create_if_needed, find_if_needed, + permissions, + context); + + gnome_vfs_uri_unref(real_uri); + } else { + retval = GNOME_VFS_ERROR_NOT_FOUND; + } + + return retval; +} + + + +static GnomeVFSResult +tr_do_remove_directory(GnomeVFSMethod * method, + GnomeVFSURI * uri, GnomeVFSContext * context) +{ + TranslateMethod *tm = (TranslateMethod *) method; + GnomeVFSURI *real_uri; + GnomeVFSResult retval; + + real_uri = tr_uri_translate(tm, uri); + + if ( NULL != real_uri ) { + retval = + tm->real_method->remove_directory(tm->real_method, real_uri, + context); + + gnome_vfs_uri_unref(real_uri); + } else { + retval = GNOME_VFS_ERROR_NOT_FOUND; + } + + return retval; +} + +static GnomeVFSResult +tr_do_move(GnomeVFSMethod * method, + GnomeVFSURI * old_uri, + GnomeVFSURI * new_uri, + gboolean force_replace, GnomeVFSContext * context) +{ + TranslateMethod *tm = (TranslateMethod *) method; + GnomeVFSURI *real_uri_old, *real_uri_new; + GnomeVFSResult retval; + + real_uri_old = tr_uri_translate(tm, old_uri); + real_uri_new = tr_uri_translate(tm, new_uri); + + if ( NULL != real_uri_old && NULL != real_uri_new ) { + retval = + tm->real_method->move(tm->real_method, real_uri_old, + real_uri_new, force_replace, context); + + } else { + retval = GNOME_VFS_ERROR_NOT_FOUND; + } + + if (real_uri_old) {gnome_vfs_uri_unref(real_uri_old);} + if (real_uri_new) {gnome_vfs_uri_unref(real_uri_new);} + + return retval; +} + +static GnomeVFSResult +tr_do_unlink(GnomeVFSMethod * method, + GnomeVFSURI * uri, GnomeVFSContext * context) +{ + TranslateMethod *tm = (TranslateMethod *) method; + GnomeVFSURI *real_uri; + GnomeVFSResult retval; + + real_uri = tr_uri_translate(tm, uri); + + if ( NULL != real_uri ) { + retval = + tm->real_method->unlink(tm->real_method, real_uri, context); + + gnome_vfs_uri_unref(real_uri); + } else { + retval = GNOME_VFS_ERROR_NOT_FOUND; + } + + return retval; +} + +static GnomeVFSResult +tr_do_check_same_fs(GnomeVFSMethod * method, + GnomeVFSURI * a, + GnomeVFSURI * b, + gboolean * same_fs_return, GnomeVFSContext * context) +{ + TranslateMethod *tm = (TranslateMethod *) method; + GnomeVFSURI *real_uri_a, *real_uri_b; + GnomeVFSResult retval; + + real_uri_a = tr_uri_translate(tm, a); + real_uri_b = tr_uri_translate(tm, b); + + if ( NULL != real_uri_a && NULL != real_uri_b ) { + retval = + tm->real_method->check_same_fs(tm->real_method, real_uri_a, + real_uri_b, same_fs_return, + context); + } else { + retval = GNOME_VFS_ERROR_NOT_FOUND; + } + + if (real_uri_a) {gnome_vfs_uri_unref(real_uri_a);} + if (real_uri_b) {gnome_vfs_uri_unref(real_uri_b);} + + return retval; +} + +static GnomeVFSResult +tr_do_set_file_info(GnomeVFSMethod * method, + GnomeVFSURI * a, + const GnomeVFSFileInfo * info, + GnomeVFSSetFileInfoMask mask, + GnomeVFSContext * context) +{ + TranslateMethod *tm = (TranslateMethod *) method; + GnomeVFSURI *real_uri_a; + GnomeVFSResult retval; + + real_uri_a = tr_uri_translate(tm, a); + + if ( NULL != real_uri_a ) { + retval = + tm->real_method->set_file_info(tm->real_method, real_uri_a, + info, mask, context); + + gnome_vfs_uri_unref(real_uri_a); + } else { + retval = GNOME_VFS_ERROR_NOT_FOUND; + } + + return retval; +} + +/******** from poptparse.c: + Copyright (c) 1998 Red Hat Software + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name of the X Consortium shall not be + used in advertising or otherwise to promote the sale, use or other dealings + in this Software without prior written authorization from the X Consortium. + +*/ + +#define POPT_ARGV_ARRAY_GROW_DELTA 5 +static int my_poptParseArgvString(char *buf, int *argcPtr, char ***argvPtr) +{ + char *src; + char quote = '\0'; + int argvAlloced = POPT_ARGV_ARRAY_GROW_DELTA; + char **argv = g_new(char *, argvAlloced); + int argc = 0; + char *s; + + s = g_alloca(strlen(buf) + 1); + strcpy(s, buf); + + argv[argc] = buf; + + for (src = s; *src; src++) { + if (quote == *src) { + quote = '\0'; + } else if (quote) { + if (*src == '\\') { + src++; + if (!*src) { + g_free(argv); + return -1; + } + if (*src != quote) + *(buf++) = '\\'; + } + *(buf++) = *src; + } else if (g_ascii_isspace(*src)) { + *buf = '\0'; + if (*argv[argc]) { + buf++, argc++; + /* leave one empty argv at the end */ + if (argc == argvAlloced - 1) { + argvAlloced += + POPT_ARGV_ARRAY_GROW_DELTA; + argv = + g_realloc(argv, + sizeof(*argv) * + argvAlloced); + } + argv[argc] = buf; + } + } else + switch (*src) { + case '"': + case '\'': + quote = *src; + break; + case '\\': + src++; + if (!*src) { + g_free(argv); + return -1; + } + /*@fallthrough@ */ + default: + *(buf++) = *src; + break; + } + } + + *buf = '\0'; + if (strlen(argv[argc])) { + argc++, buf++; + } + + /* add NULL to the end of argv */ + argv[argc] = NULL; + + *argcPtr = argc; + *argvPtr = argv; + + return 0; +} + +static gboolean tr_args_parse(ParsedArgs * pa, const char *args) +{ + char **argv; + int argc; + char *tmp_args; + int i; + gboolean badargs = FALSE; + gboolean mode_determined = FALSE; + + memset(pa, 0, sizeof(ParsedArgs)); + + tmp_args = g_alloca(strlen(args) + 1); + strcpy(tmp_args, args); + + if (my_poptParseArgvString(tmp_args, &argc, &argv)) { + g_warning("Failed to parse arguments: %s", args); + return FALSE; + } + + for (i = 0; i < argc; i++) { +#define CHECK_ARG() if((++i) >= argc) { badargs = TRUE; goto out; } +#define CHECK_MODE(my_mode) if (mode_determined && pa->mode != (my_mode)) { badargs = TRUE ; goto out; } else { pa->mode = my_mode; mode_determined = TRUE; } + if (g_ascii_strcasecmp(argv[i], "-pattern") == 0) { + CHECK_ARG(); + CHECK_MODE(MODE_BASIC); + pa->u.basic.trans_string = g_strdup(argv[i]); + } else if (g_ascii_strcasecmp(argv[i], "-real-method") == 0) { + CHECK_ARG(); + pa->real_method_name = g_strdup(argv[i]); + } else if (g_ascii_strcasecmp(argv[i], "-exec") == 0) { + CHECK_ARG(); + CHECK_MODE(MODE_EXEC); + pa->u.exec.orig_string = g_strdup(argv[i]); + } else if (g_ascii_strcasecmp(argv[i], "-retain") == 0) { + CHECK_MODE(MODE_EXEC); + pa->u.exec.retain = TRUE; + } else if (g_ascii_strcasecmp(argv[i], "-default-mime-type") == 0) { + CHECK_ARG(); + pa->default_mime_type = g_strdup(argv[i]); + } else { + g_warning("Unknown option `%s'", argv[i]); + badargs = TRUE; + goto out; + } +#undef CHECK_ARG +#undef CHECK_MODE + } + + if ( ! mode_determined ) { + g_warning("Need a -pattern option or -exec option"); + badargs = TRUE; + } else if (MODE_BASIC == pa->mode) { + if (!pa->real_method_name) { + g_warning("Need a -real-method option"); + badargs = TRUE; + } else if (!pa->u.basic.trans_string) { + g_warning("Need a -pattern option"); + badargs = TRUE; + } + } else if (MODE_EXEC == pa->mode) { + if (!pa->real_method_name) { + g_warning("Need a -real-method option"); + badargs = TRUE; + } else if (!pa->u.exec.orig_string) { + g_warning("Need a -exec option"); + badargs = TRUE; + } + + /* Chop up the exec string here */ + if (my_poptParseArgvString ( + pa->u.exec.orig_string, + &(pa->u.exec.argc), + &(pa->u.exec.argv)) + ) { + g_warning ("Failed to parse -exec args"); + badargs = TRUE; + } + } else { + g_assert (FALSE); + } + + out: + g_free(argv); + return !badargs; +} + +static GnomeVFSMethod base_vfs_method = { + sizeof (GnomeVFSMethod), + tr_do_open, + tr_do_create, + tr_do_close, + tr_do_read, + tr_do_write, + tr_do_seek, + tr_do_tell, + tr_do_truncate_handle, + tr_do_open_directory, + tr_do_close_directory, + tr_do_read_directory, + tr_do_get_file_info, + tr_do_get_file_info_from_handle, + tr_do_is_local, + tr_do_make_directory, + tr_do_remove_directory, + tr_do_move, + tr_do_unlink, + tr_do_check_same_fs, + tr_do_set_file_info, + tr_do_truncate, + tr_do_find_directory, + NULL /* create_symbolic_link can't be supported */ + /* Hey YOU! If you add a GnomeVFS method, you need to do two things + * in the translate-method module: + * + * 1. Add a line to the CHECK_NULL_METHOD list in vfs_module_init + * 2. Implement the function in this module. This is pretty simple-- + * just follow the pattern of existing functions + */ +}; + +static void tr_args_free(ParsedArgs * pa) +{ + g_free(pa->default_mime_type); + g_free(pa->real_method_name); + + if (MODE_BASIC == pa->mode) { + g_free(pa->u.basic.trans_string); + } else { + g_free(pa->u.exec.orig_string); + } +} + +GnomeVFSMethod *vfs_module_init(const char *method_name, const char *args) +{ + TranslateMethod *retval; + ParsedArgs pa; + + if (!tr_args_parse(&pa, args)) + return NULL; + + retval = g_new0(TranslateMethod, 1); + retval->pa = pa; + retval->real_method = gnome_vfs_method_get(pa.real_method_name); + + if (!retval->real_method) { + tr_args_free(&retval->pa); + g_free(retval); + return NULL; + } + + tr_exec_init(&(retval->exec_state)); + + retval->base_method = base_vfs_method; + +#define CHECK_NULL_METHOD(x) if(!VFS_METHOD_HAS_FUNC (retval->real_method, x)) retval->base_method.x = NULL + CHECK_NULL_METHOD(open); + CHECK_NULL_METHOD(create); + CHECK_NULL_METHOD(close); + CHECK_NULL_METHOD(read); + CHECK_NULL_METHOD(write); + CHECK_NULL_METHOD(seek); + CHECK_NULL_METHOD(tell); + CHECK_NULL_METHOD(truncate); + CHECK_NULL_METHOD(open_directory); + CHECK_NULL_METHOD(close_directory); + CHECK_NULL_METHOD(read_directory); + CHECK_NULL_METHOD(get_file_info); + CHECK_NULL_METHOD(get_file_info_from_handle); + CHECK_NULL_METHOD(is_local); + CHECK_NULL_METHOD(make_directory); + CHECK_NULL_METHOD(remove_directory); + CHECK_NULL_METHOD(move); + CHECK_NULL_METHOD(unlink); + CHECK_NULL_METHOD(check_same_fs); + CHECK_NULL_METHOD(set_file_info); + CHECK_NULL_METHOD(truncate_handle); + CHECK_NULL_METHOD(find_directory); + /*CHECK_NULL_METHOD(create_symbolic_link);*/ + retval->base_method.create_symbolic_link = NULL; +#undef CHECK_NULL_METHOD + + return (GnomeVFSMethod *) retval; +} + +void +vfs_module_shutdown (GnomeVFSMethod * method) +{ + TranslateMethod *tmethod = (TranslateMethod *) method; + + tr_exec_cleanup (&(tmethod->exec_state)); + + tr_args_free(&tmethod->pa); + + g_free(tmethod); +} diff --git a/modules/vfolder-desktop-method.c b/modules/vfolder-desktop-method.c new file mode 100644 index 0000000..2253a5f --- /dev/null +++ b/modules/vfolder-desktop-method.c @@ -0,0 +1,6148 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: 8; c-basic-offset: 8 -*- */ + +/* vfolder-desktop-method.c + + Copyright (C) 2001 Red Hat, Inc. + Copyright (C) 2001 The Dark Prince + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/* URI scheme for reading the "applications:" vfolder and other + * vfolder schemes. Lots of code stolen from the original desktop + * reading URI scheme. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +/* Debugging foo: */ +/*#define D(x) x */ +#define D(x) ; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#define DOT_GNOME ".gnome2" + +typedef struct _VFolderInfo VFolderInfo; +typedef struct _Query Query; +typedef struct _QueryKeyword QueryKeyword; +typedef struct _QueryFilename QueryFilename; +typedef struct _Entry Entry; +typedef struct _Folder Folder; +typedef struct _EntryFile EntryFile; +typedef struct _Keyword Keyword; +typedef struct _FileMonitorHandle FileMonitorHandle; +typedef struct _StatLoc StatLoc; +typedef struct _VFolderURI VFolderURI; + +/* TODO before 2.0: */ +/* FIXME: also check/monitor desktop_dirs like we do the vfolder + * file and the item dirs */ +/* FIXME: check if thread locks are not completely on crack which + * is likely given my experience with threads */ +/* FIXME: use filename locking, currently we are full of races if + * multiple processes write to this filesystem */ +/* FIXME: implement monitors */ + +/* TODO for later (star trek future): */ +/* FIXME: Maybe when chaining to file:, we should call the gnome-vfs wrapper + * functions, instead of the file: methods directly. */ +/* FIXME: related to the above: we should support things being on non + * file: filesystems. Such as having the vfolder info file on http + * somewhere or some such nonsense :) */ + +static GnomeVFSMethod *parent_method = NULL; + +static GHashTable *infos = NULL; + +/* Note: I have no clue about how to write thread safe code and this + * is my first attempt, so it's probably wrong + * -George */ +G_LOCK_DEFINE_STATIC (vfolder_lock); + +/* Note: all keywords are quarks */ +/* Note: basenames are unique */ + +#define UNSUPPORTED_INFO_FIELDS (GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS | \ + GNOME_VFS_FILE_INFO_FIELDS_DEVICE | \ + GNOME_VFS_FILE_INFO_FIELDS_INODE | \ + GNOME_VFS_FILE_INFO_FIELDS_LINK_COUNT | \ + GNOME_VFS_FILE_INFO_FIELDS_ATIME) + + +enum { + QUERY_OR, + QUERY_AND, + QUERY_KEYWORD, + QUERY_FILENAME +}; + +struct _Query { + int type; + gboolean not; + GSList *queries; +}; + +struct _QueryKeyword { + int type; + gboolean not; + GQuark keyword; +}; + +struct _QueryFilename { + int type; + gboolean not; + char *filename; +}; + +enum { + ENTRY_FILE, + ENTRY_FOLDER +}; + +struct _Entry { + int type; + int refcount; + int alloc; /* not really useful for folders, + but oh well, whatever. It's the number + of times this is queried in some directory, + used for the Unallocated query type */ + char *name; + + GSList *monitors; +}; + +struct _EntryFile { + Entry entry; + + char *filename; + gboolean per_user; + GSList *keywords; + + gboolean implicit_keywords; /* the keywords were added by us */ +}; + +struct _Folder { + Entry entry; + + Folder *parent; + + char *desktop_file; /* the .directory file */ + + Query *query; + + /* The following is for per file + * access */ + /* excluded by filename */ + GHashTable *excludes; + /* included by filename */ + GSList *includes; + GHashTable *includes_ht; + + GSList *subfolders; + + /* Some flags */ + gboolean read_only; + gboolean dont_show_if_empty; + gboolean only_unallocated; /* include only unallocated items */ + + /* lazily done, will run query only when it + * needs to */ + gboolean up_to_date; + gboolean sorted; + GSList *entries; +}; + +struct _StatLoc { + time_t ctime; + time_t last_stat; + gboolean trigger_next; /* if true, next check will fail */ + char name[1]; /* the structure will be long enough to + fit name */ +}; + +struct _VFolderInfo { + char *scheme; + + char *filename; + char *user_filename; + time_t user_filename_last_write; + char *desktop_dir; /* directory with .directorys */ + char *user_desktop_dir; /* directory with .directorys */ + gboolean user_file_active; /* if using user_filename and + not filename */ + + GSList *item_dirs; + char *user_item_dir; /* dir where user changes to + items are stored */ + + /* old style dirs to merge in */ + GSList *merge_dirs; + + /* if entries are valid, else + * they need to be (re)read */ + gboolean entries_valid; + + GSList *entries; + + /* entry hash by basename */ + GHashTable *entries_ht; + + /* The root folder */ + Folder *root; + + /* The unallocated folders, the folder which only + * include unallocated items */ + GSList *unallocated_folders; + + /* some flags */ + gboolean read_only; + + gboolean dirty; + + int inhibit_write; + + /* change monitoring stuff */ + GnomeVFSMonitorHandle *filename_monitor; + GnomeVFSMonitorHandle *user_filename_monitor; + + /* stat locations (in case we aren't monitoring) */ + StatLoc *filename_statloc; + StatLoc *user_filename_statloc; + + /* for .directory dirs */ + /* FIXME: */GnomeVFSMonitorHandle *desktop_dir_monitor; + /* FIXME: */GnomeVFSMonitorHandle *user_desktop_dir_monitor; + + /* stat locations (in case we aren't monitoring) */ + /* FIXME: */StatLoc *desktop_dir_statloc; + /* FIXME: */StatLoc *user_desktop_dir_statloc; + + /* FIXME: */GSList *file_monitors; /* FileMonitorHandle */ + /* FIXME: */GSList *free_file_monitors; /* FileMonitorHandle */ + GSList *folder_monitors; /* FileMonitorHandle */ + GSList *free_folder_monitors; /* FileMonitorHandle */ + + GSList *item_dir_monitors; /* GnomeVFSMonitorHandle */ + + /* item dirs to stat */ + GSList *stat_dirs; + + /* ctime for folders */ + time_t modification_time; + + guint reread_queue; +}; + +struct _FileMonitorHandle { + int refcount; + gboolean exists; + gboolean dir_monitor; /* TRUE if dir, FALSE if file */ + GnomeVFSURI *uri; + GnomeVFSMonitorHandle *handle; /* A real handle if we're monitoring + an actual file here, or NULL */ + char *filename; /* Just the basename, used in the free_file_list */ + gboolean is_directory_file; +}; + +struct _VFolderURI { + const gchar *scheme; + gboolean is_all_scheme; + gboolean ends_in_slash; + gchar *path; + gchar *file; + GnomeVFSURI *uri; +}; + + +static Entry * entry_ref (Entry *entry); +static Entry * entry_ref_alloc (Entry *entry); +static void entry_unref (Entry *entry); +static void entry_unref_dealloc (Entry *entry); +static void query_destroy (Query *query); +static void ensure_folder (VFolderInfo *info, + Folder *folder, + gboolean subfolders, + Folder *except, + gboolean ignore_unallocated); +static void ensure_folder_unlocked (VFolderInfo *info, + Folder *folder, + gboolean subfolders, + Folder *except, + gboolean ignore_unallocated); +/* An EVIL function for quick reading of .desktop files, + * only reads in one or two keys, but that's ALL we need */ +static void readitem_entry (const char *filename, + const char *key1, + char **result1, + const char *key2, + char **result2); +static gboolean vfolder_info_reload (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context, + gboolean force_read_items); +static gboolean vfolder_info_reload_unlocked (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context, + gboolean force_read_items); +static void invalidate_folder_subfolders (Folder *folder, + gboolean lock_taken); +static Folder * resolve_folder (VFolderInfo *info, + const char *path, + gboolean ignore_basename, + GnomeVFSResult *result, + GnomeVFSContext *context); +static gboolean vfolder_info_read_items (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context); + +/* assumes vuri->path already set */ +static gboolean +vfolder_uri_parse_internal (GnomeVFSURI *uri, VFolderURI *vuri) +{ + vuri->scheme = (gchar *) gnome_vfs_uri_get_scheme (uri); + + vuri->ends_in_slash = FALSE; + + if (strncmp (vuri->scheme, "all-", strlen ("all-")) == 0) { + vuri->scheme += strlen ("all-"); + vuri->is_all_scheme = TRUE; + } else + vuri->is_all_scheme = FALSE; + + if (vuri->path != NULL) { + int last_slash = strlen (vuri->path) - 1; + char *first; + + /* Note: This handling of paths is somewhat evil, may need a + * bit of a rework */ + + /* kill leading slashes, that is make sure there is + * only one */ + for (first = vuri->path; *first == '/'; first++) + ; + if (first != vuri->path) { + first--; + vuri->path = first; + } + + /* kill trailing slashes (leave first if all slashes) */ + while (last_slash > 0 && vuri->path [last_slash] == '/') { + vuri->path [last_slash--] = '\0'; + vuri->ends_in_slash = TRUE; + } + + /* get basename start */ + while (last_slash >= 0 && vuri->path [last_slash] != '/') + last_slash--; + + if (last_slash > -1) + vuri->file = vuri->path + last_slash + 1; + else + vuri->file = vuri->path; + + if (vuri->file[0] == '\0' && + strcmp (vuri->path, "/") == 0) { + vuri->file = NULL; + } + } else { + vuri->ends_in_slash = TRUE; + vuri->path = "/"; + vuri->file = NULL; + } + + vuri->uri = uri; + + return TRUE; +} + +#define VFOLDER_URI_PARSE(_uri, _vuri) { \ + gchar *path; \ + path = gnome_vfs_unescape_string ((_uri)->text, G_DIR_SEPARATOR_S); \ + if (path != NULL) { \ + (_vuri)->path = g_alloca (strlen (path) + 1); \ + strcpy ((_vuri)->path, path); \ + g_free (path); \ + } else { \ + (_vuri)->path = NULL; \ + } \ + vfolder_uri_parse_internal ((_uri), (_vuri)); \ +} + +static FileMonitorHandle * +file_monitor_handle_ref_unlocked (FileMonitorHandle *h) +{ + h->refcount ++; + return h; +} + +static void +file_monitor_handle_unref_unlocked (FileMonitorHandle *h) +{ + h->refcount --; + if (h->refcount == 0) { + gnome_vfs_uri_unref (h->uri); + h->uri = NULL; + + g_free (h->filename); + h->filename = NULL; + + if (h->handle != NULL) { + gnome_vfs_monitor_cancel (h->handle); + h->handle = NULL; + } + } +} + +/* This includes the .directory files */ +static void +emit_monitor (Folder *folder, int type) +{ + GSList *li; + for (li = ((Entry *)folder)->monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *handle = li->data; + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *) handle, + handle->uri, type); + } +} + +static void +emit_file_deleted_monitor (VFolderInfo *info, Entry *entry, Folder *folder) +{ + GSList *li; + for (li = entry->monitors; + li != NULL; + li = li->next) { + VFolderURI vuri; + Folder *f; + GnomeVFSResult result; + FileMonitorHandle *handle = li->data; + + /* Evil! EVIL URI PARSING. this will eat a lot of + * stack if we have lots of monitors */ + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + f = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + + if (f == folder) + gnome_vfs_monitor_callback + ((GnomeVFSMethodHandle *) handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_DELETED); + } +} + +static void +emit_and_delete_monitor (VFolderInfo *info, Folder *folder) +{ + GSList *li; + for (li = ((Entry *)folder)->monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *handle = li->data; + li->data = NULL; + + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *) handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_DELETED); + + if (handle->dir_monitor) + info->free_folder_monitors = + g_slist_prepend (info->free_folder_monitors, + handle); + else + info->free_file_monitors = + g_slist_prepend (info->free_file_monitors, + handle); + } + g_slist_free (((Entry *)folder)->monitors); + ((Entry *)folder)->monitors = NULL; +} + +static gboolean +check_ext (const char *name, const char *ext_check) +{ + const char *ext; + + ext = strrchr (name, '.'); + if (ext == NULL || + strcmp (ext, ext_check) != 0) + return FALSE; + else + return TRUE; +} + +static StatLoc * +bake_statloc (const char *name, + time_t curtime) +{ + struct stat s; + StatLoc *sl = NULL; + if (stat (name, &s) != 0) { + if (errno == ENOENT) { + sl = g_malloc0 (sizeof (StatLoc) + + strlen (name) + 1); + sl->last_stat = curtime; + sl->ctime = 0; + sl->trigger_next = FALSE; + strcpy (sl->name, name); + } + return sl; + } + + sl = g_malloc0 (sizeof (StatLoc) + + strlen (name) + 1); + sl->last_stat = curtime; + sl->ctime = s.st_ctime; + sl->trigger_next = FALSE; + strcpy (sl->name, name); + + return sl; +} + +/* returns FALSE if we must reread */ +static gboolean +check_statloc (StatLoc *sl, + time_t curtime) +{ + struct stat s; + + if (sl->trigger_next) { + sl->trigger_next = FALSE; + return FALSE; + } + + /* don't stat more then once every 3 seconds */ + if (curtime <= sl->last_stat + 3) + return TRUE; + + sl->last_stat = curtime; + + if (stat (sl->name, &s) != 0) { + if (errno == ENOENT && + sl->ctime == 0) + return TRUE; + else + return FALSE; + } + + if (sl->ctime == s.st_ctime) + return TRUE; + else + return FALSE; +} + +static gboolean +ensure_dir (const char *dirname, gboolean ignore_basename) +{ + char *parsed, *p; + + if (dirname == NULL) + return FALSE; + + if (ignore_basename) + parsed = g_path_get_dirname (dirname); + else + parsed = g_strdup (dirname); + + if (g_file_test (parsed, G_FILE_TEST_IS_DIR)) { + g_free (parsed); + return TRUE; + } + + p = strchr (parsed, '/'); + if (p == parsed) + p = strchr (p+1, '/'); + + while (p != NULL) { + *p = '\0'; + if (mkdir (parsed, 0700) != 0 && + errno != EEXIST) { + g_free (parsed); + return FALSE; + } + *p = '/'; + p = strchr (p+1, '/'); + } + + if (mkdir (parsed, 0700) != 0 && + errno != EEXIST) { + g_free (parsed); + return FALSE; + } + + g_free (parsed); + return TRUE; +} + +/* check for any directory name other then root */ +static gboolean +any_subdir (const char *dirname) +{ + const char *p; + if (dirname == NULL) + return FALSE; + + for (p = dirname; *p != '\0'; p++) { + if (*p != '/') { + return TRUE; + } + } + return FALSE; +} + +static void +destroy_entry_file (EntryFile *efile) +{ + if (efile == NULL) + return; + + g_free (efile->filename); + efile->filename = NULL; + + g_slist_free (efile->keywords); + efile->keywords = NULL; + + g_free (efile); +} + +static void +destroy_folder (Folder *folder) +{ + GSList *list; + + if (folder == NULL) + return; + + if (folder->parent != NULL) { + folder->parent->subfolders = + g_slist_remove (folder->parent->subfolders, folder); + folder->parent->up_to_date = FALSE; + folder->parent = NULL; + } + + g_free (folder->desktop_file); + folder->desktop_file = NULL; + + query_destroy (folder->query); + folder->query = NULL; + + if (folder->excludes != NULL) { + g_hash_table_destroy (folder->excludes); + folder->excludes = NULL; + } + + g_slist_foreach (folder->includes, (GFunc)g_free, NULL); + g_slist_free (folder->includes); + folder->includes = NULL; + if (folder->includes_ht != NULL) { + g_hash_table_destroy (folder->includes_ht); + folder->includes_ht = NULL; + } + + list = folder->subfolders; + folder->subfolders = NULL; + g_slist_foreach (list, (GFunc)entry_unref, NULL); + g_slist_free (list); + + list = folder->entries; + folder->entries = NULL; + g_slist_foreach (list, (GFunc)entry_unref, NULL); + g_slist_free (list); + + g_free (folder); +} + +static Entry * +entry_ref (Entry *entry) +{ + if (entry != NULL) + entry->refcount++; + return entry; +} + +static Entry * +entry_ref_alloc (Entry *entry) +{ + entry_ref (entry); + + if (entry != NULL) + entry->alloc++; + + return entry; +} + +static void +entry_unref (Entry *entry) +{ + if (entry == NULL) + return; + + entry->refcount--; + + if (entry->refcount == 0) { + g_free (entry->name); + entry->name = NULL; + + g_slist_foreach (entry->monitors, + (GFunc)file_monitor_handle_unref_unlocked, + NULL); + g_slist_free (entry->monitors); + entry->monitors = NULL; + + if (entry->type == ENTRY_FILE) + destroy_entry_file ((EntryFile *)entry); + else /* ENTRY_FOLDER */ + destroy_folder ((Folder *)entry); + } +} + +static void +entry_unref_dealloc (Entry *entry) +{ + if (entry != NULL) { + entry->alloc --; + entry_unref (entry); + } +} + +/* Handles ONLY files, not dirs */ +/* Also allocates the entries as well as refs them */ +static GSList * +alloc_entries_from_files (VFolderInfo *info, GSList *filenames) +{ + GSList *li; + GSList *files; + + files = NULL; + for (li = filenames; li != NULL; li = li->next) { + char *filename = li->data; + GSList *entry_list = g_hash_table_lookup (info->entries_ht, filename); + if (entry_list != NULL) + files = g_slist_prepend (files, + entry_ref_alloc (entry_list->data)); + } + + return files; +} + +static gboolean +matches_query (VFolderInfo *info, + Folder *folder, + EntryFile *efile, + Query *query) +{ + GSList *li; + + if (query == NULL) + return TRUE; + +#define INVERT_IF_NEEDED(val) (query->not ? !(val) : (val)) + switch (query->type) { + case QUERY_OR: + for (li = query->queries; li != NULL; li = li->next) { + Query *subquery = li->data; + if (matches_query (info, folder, efile, subquery)) + return INVERT_IF_NEEDED (TRUE); + } + return INVERT_IF_NEEDED (FALSE); + case QUERY_AND: + for (li = query->queries; li != NULL; li = li->next) { + Query *subquery = li->data; + if ( ! matches_query (info, folder, efile, subquery)) + return INVERT_IF_NEEDED (FALSE); + } + return INVERT_IF_NEEDED (TRUE); + case QUERY_KEYWORD: + { + QueryKeyword *qkeyword = (QueryKeyword *)query; + for (li = efile->keywords; li != NULL; li = li->next) { + GQuark keyword = GPOINTER_TO_INT (li->data); + if (keyword == qkeyword->keyword) + return INVERT_IF_NEEDED (TRUE); + } + return INVERT_IF_NEEDED (FALSE); + } + case QUERY_FILENAME: + { + QueryFilename *qfilename = (QueryFilename *)query; + if (strcmp (qfilename->filename, ((Entry *)efile)->name) == 0) { + return INVERT_IF_NEEDED (TRUE); + } else { + return INVERT_IF_NEEDED (FALSE); + } + } + } +#undef INVERT_IF_NEEDED + g_assert_not_reached (); + /* huh? */ + return FALSE; +} + +static void +dump_unallocated_folders (Folder *folder) +{ + GSList *li; + for (li = folder->subfolders; li != NULL; li = li->next) + dump_unallocated_folders (li->data); + + if (folder->only_unallocated && + folder->entries != NULL) { + g_slist_foreach (folder->entries, + (GFunc)entry_unref_dealloc, NULL); + g_slist_free (folder->entries); + folder->entries = NULL; + } +} + +/* Run query, allocs and refs the entries */ +static void +append_query (VFolderInfo *info, Folder *folder) +{ + GSList *li; + + if (folder->query == NULL && + ! folder->only_unallocated) + return; + + if (folder->only_unallocated) { + /* dump all folders that use unallocated + * items only. This sucks if you keep + * reading one and then another such + * folder, but oh well, life sucks for + * you then, but at least you get + * consistent results */ + dump_unallocated_folders (info->root); + + /* ensure all other folders, so that + * after this we know which ones are + * unallocated */ + ensure_folder_unlocked (info, + info->root, + TRUE /* subfolders */, + folder /* except */, + /* avoid infinite loops */ + TRUE /* ignore_unallocated */); + } + + for (li = info->entries; li != NULL; li = li->next) { + Entry *entry = li->data; + + if (/* if not file */ + entry->type != ENTRY_FILE || + /* if already included */ + (folder->includes_ht != NULL && + g_hash_table_lookup (folder->includes_ht, + entry->name) != NULL)) + continue; + + if (folder->only_unallocated && + entry->alloc != 0) + continue; + + if (matches_query (info, folder, (EntryFile *)entry, + folder->query)) + folder->entries = g_slist_prepend + (folder->entries, entry_ref_alloc (entry)); + } +} + +/* get entries in folder */ +/* FIXME: support cancellation here */ +static void +ensure_folder_unlocked (VFolderInfo *info, + Folder *folder, + gboolean subfolders, + Folder *except, + gboolean ignore_unallocated) +{ + if (subfolders) { + GSList *li; + for (li = folder->subfolders; li != NULL; li = li->next) + ensure_folder_unlocked (info, li->data, subfolders, + except, ignore_unallocated); + } + + if (except == folder) + return; + + if (ignore_unallocated && + folder->only_unallocated) + return; + + if (folder->up_to_date) + return; + + if (folder->entries != NULL) { + g_slist_foreach (folder->entries, + (GFunc)entry_unref_dealloc, NULL); + g_slist_free (folder->entries); + folder->entries = NULL; + } + + /* Include includes */ + folder->entries = alloc_entries_from_files (info, folder->includes); + + /* Run query */ + append_query (info, folder); + + /* We were prepending all this time */ + folder->entries = g_slist_reverse (folder->entries); + + /* Include subfolders */ + /* we always whack them onto the beginning */ + if (folder->subfolders != NULL) { + GSList *li; + GSList *subfolders; + subfolders = NULL; + li = folder->subfolders; + for (li = folder->subfolders; li != NULL; li = li->next) { + Folder *f = li->data; + /* always dont_show_if_empty */ + if (f->entries != NULL) { + entry_ref_alloc (&f->entry); + subfolders = g_slist_prepend (subfolders, f); + } + } + subfolders = g_slist_reverse (subfolders); + folder->entries = g_slist_concat (subfolders, folder->entries); + } + + /* Exclude excludes */ + if (folder->excludes != NULL) { + GSList *li; + GSList *entries = folder->entries; + folder->entries = NULL; + for (li = entries; li != NULL; li = li->next) { + Entry *entry = li->data; + if (g_hash_table_lookup (folder->excludes, entry->name) == NULL) + folder->entries = g_slist_prepend (folder->entries, entry); + else + entry_unref_dealloc (entry); + + } + g_slist_free (entries); + + /* to preserve the Folders then everything else order */ + folder->entries = g_slist_reverse (folder->entries); + } + + folder->up_to_date = TRUE; + /* not yet sorted */ + folder->sorted = FALSE; +} + +static void +ensure_folder (VFolderInfo *info, + Folder *folder, + gboolean subfolders, + Folder *except, + gboolean ignore_unallocated) +{ + G_LOCK (vfolder_lock); + ensure_folder_unlocked (info, folder, subfolders, except, ignore_unallocated); + G_UNLOCK (vfolder_lock); +} + +static char * +get_directory_file_unlocked (VFolderInfo *info, Folder *folder) +{ + char *filename; + + /* FIXME: cache dir_files */ + + if (folder->desktop_file == NULL) + return NULL; + + if (folder->desktop_file[0] == G_DIR_SEPARATOR) + return g_strdup (folder->desktop_file); + + /* Now try the user directory */ + if (info->user_desktop_dir != NULL) { + filename = g_build_filename (info->user_desktop_dir, + folder->desktop_file, + NULL); + if (access (filename, F_OK) == 0) { + return filename; + } + + g_free (filename); + } + + filename = g_build_filename (info->desktop_dir, folder->desktop_file, NULL); + if (access (filename, F_OK) == 0) { + return filename; + } + g_free (filename); + + return NULL; +} + +static char * +get_directory_file (VFolderInfo *info, Folder *folder) +{ + char *ret; + + G_LOCK (vfolder_lock); + ret = get_directory_file_unlocked (info, folder); + G_UNLOCK (vfolder_lock); + + return ret; +} + +static GSList * +get_sort_order (VFolderInfo *info, Folder *folder) +{ + GSList *list; + char **parsed; + char *order; + int i; + char *filename; + + filename = get_directory_file_unlocked (info, folder); + if (filename == NULL) + return NULL; + + order = NULL; + readitem_entry (filename, + "SortOrder", + &order, + NULL, + NULL); + g_free (filename); + + if (order == NULL) + return NULL; + + parsed = g_strsplit (order, ":", -1); + + g_free (order); + + list = NULL; + for (i = 0; parsed[i] != NULL; i++) { + char *word = parsed[i]; + /* steal */ + parsed[i] = NULL; + /* ignore empty */ + if (word[0] == '\0') { + g_free (word); + continue; + } + list = g_slist_prepend (list, word); + } + /* we've stolen all strings from it */ + g_free (parsed); + + return g_slist_reverse (list); +} + +/* get entries in folder */ +static void +ensure_folder_sort (VFolderInfo *info, Folder *folder) +{ + GSList *li, *sort_order; + GSList *entries; + GHashTable *entry_hash; + + ensure_folder (info, folder, + TRUE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + if (folder->sorted) + return; + + G_LOCK (vfolder_lock); + + sort_order = get_sort_order (info, folder); + if (sort_order == NULL) { + folder->sorted = TRUE; + G_UNLOCK (vfolder_lock); + return; + } + + entries = folder->entries; + folder->entries = NULL; + + entry_hash = g_hash_table_new (g_str_hash, g_str_equal); + for (li = entries; li != NULL; li = li->next) { + Entry *entry = li->data; + g_hash_table_insert (entry_hash, entry->name, li); + } + + for (li = sort_order; li != NULL; li = li->next) { + char *word = li->data; + GSList *entry_list; + Entry *entry; + + /* we kill the words here */ + li->data = NULL; + + entry_list = g_hash_table_lookup (entry_hash, word); + g_free (word); + + if (entry_list == NULL) + continue; + + entry = entry_list->data; + + entries = g_slist_delete_link (entries, entry_list); + + folder->entries = g_slist_prepend (folder->entries, + entry); + } + + /* put on those that weren't mentioned in the sort */ + for (li = entries; li != NULL; li = li->next) { + Entry *entry = li->data; + + folder->entries = g_slist_prepend (folder->entries, + entry); + } + + g_hash_table_destroy (entry_hash); + g_slist_free (entries); + g_slist_free (sort_order); + + folder->sorted = TRUE; + + G_UNLOCK (vfolder_lock); +} + +static EntryFile * +file_new (const char *name) +{ + EntryFile *efile = g_new0 (EntryFile, 1); + + efile->entry.type = ENTRY_FILE; + efile->entry.name = g_strdup (name); + efile->entry.refcount = 1; + + return efile; +} + +static Folder * +folder_new (const char *name) +{ + Folder *folder = g_new0 (Folder, 1); + + folder->entry.type = ENTRY_FOLDER; + folder->entry.name = g_strdup (name); + folder->entry.refcount = 1; + folder->read_only = TRUE; + folder->dont_show_if_empty = TRUE; + + return folder; +} + +static Query * +query_new (int type) +{ + Query *query; + + if (type == QUERY_KEYWORD) + query = (Query *)g_new0 (QueryKeyword, 1); + else if (type == QUERY_FILENAME) + query = (Query *)g_new0 (QueryFilename, 1); + else + query = g_new0 (Query, 1); + + query->type = type; + + return query; +} + +static void +query_destroy (Query *query) +{ + if (query == NULL) + return; + + if (query->type == QUERY_FILENAME) { + QueryFilename *qfile = (QueryFilename *)query; + g_free (qfile->filename); + qfile->filename = NULL; + } else if (query->type == QUERY_OR || + query->type == QUERY_AND) { + g_slist_foreach (query->queries, (GFunc)query_destroy, NULL); + g_slist_free (query->queries); + query->queries = NULL; + } + + g_free (query); +} + +static void +add_folder_monitor_unlocked (VFolderInfo *info, + FileMonitorHandle *handle) +{ + VFolderURI vuri; + GnomeVFSResult result; + Folder *folder; + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + file_monitor_handle_ref_unlocked (handle); + + info->folder_monitors = + g_slist_prepend (info->folder_monitors, handle); + + folder = resolve_folder (info, + vuri.path, + FALSE /* ignore_basename */, + &result, + NULL); + + if (folder == NULL) { + file_monitor_handle_ref_unlocked (handle); + + info->free_folder_monitors = + g_slist_prepend (info->free_folder_monitors, handle); + + if (handle->exists) { + handle->exists = FALSE; + gnome_vfs_monitor_callback + ((GnomeVFSMethodHandle *)handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_DELETED); + } + } else { + file_monitor_handle_ref_unlocked (handle); + + ((Entry *)folder)->monitors = + g_slist_prepend (((Entry *)folder)->monitors, handle); + + if ( ! handle->exists) { + handle->exists = TRUE; + gnome_vfs_monitor_callback + ((GnomeVFSMethodHandle *)handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_CREATED); + } + } + +} + +static inline void +invalidate_folder_T (Folder *folder) +{ + folder->up_to_date = FALSE; + + invalidate_folder_subfolders (folder, TRUE); +} + +static inline void +invalidate_folder (Folder *folder) +{ + G_LOCK (vfolder_lock); + folder->up_to_date = FALSE; + G_UNLOCK (vfolder_lock); + + invalidate_folder_subfolders (folder, FALSE); +} + +static void +invalidate_folder_subfolders (Folder *folder, + gboolean lock_taken) +{ + GSList *li; + + for (li = folder->subfolders; li != NULL; li = li->next) { + Folder *subfolder = li->data; + + if (!lock_taken) + invalidate_folder (subfolder); + else + invalidate_folder_T (subfolder); + } + + emit_monitor (folder, GNOME_VFS_MONITOR_EVENT_CHANGED); +} + +/* FIXME: this is UGLY!, we need to figure out when the file + * got finished changing! */ +static gboolean +reread_timeout (gpointer data) +{ + VFolderInfo *info = data; + gboolean force_read_items = info->file_monitors != NULL; + vfolder_info_reload (info, NULL, NULL, force_read_items); + return FALSE; +} + +static void +queue_reread_in (VFolderInfo *info, int msec) +{ + G_LOCK (vfolder_lock); + if (info->reread_queue != 0) + g_source_remove (info->reread_queue); + info->reread_queue = g_timeout_add (msec, reread_timeout, info); + G_UNLOCK (vfolder_lock); +} + +static void +vfolder_desktop_dir_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + /* FIXME: implement */ +} + +static void +vfolder_user_desktop_dir_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + /* FIXME: implement */ +} + +static void +vfolder_filename_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + VFolderInfo *info = user_data; + + if ((event_type == GNOME_VFS_MONITOR_EVENT_CREATED || + event_type == GNOME_VFS_MONITOR_EVENT_CHANGED) && + ! info->user_file_active) { + queue_reread_in (info, 200); + } else if (event_type == GNOME_VFS_MONITOR_EVENT_DELETED && + ! info->user_file_active) { + /* FIXME: is this correct? I mean now + * there probably isn't ANY vfolder file, so we + * init to default values really. I have no clue what's + * right here */ + vfolder_info_reload (info, NULL, NULL, + TRUE /* force read items */); + } +} + +static void +vfolder_user_filename_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + VFolderInfo *info = user_data; + + if ((event_type == GNOME_VFS_MONITOR_EVENT_CREATED || + event_type == GNOME_VFS_MONITOR_EVENT_CHANGED) && + info->user_file_active) { + struct stat s; + + /* see if this was really our own change */ + if (info->user_filename_last_write == time (NULL)) + return; + /* anal retentive */ + if (stat (info->user_filename, &s) == 0 && + info->user_filename_last_write == s.st_ctime) + return; + + queue_reread_in (info, 200); + } else if ((event_type == GNOME_VFS_MONITOR_EVENT_CREATED || + event_type == GNOME_VFS_MONITOR_EVENT_CHANGED) && + ! info->user_file_active) { + queue_reread_in (info, 200); + } else if (event_type == GNOME_VFS_MONITOR_EVENT_DELETED && + info->user_file_active) { + gboolean force_read_items = info->file_monitors != NULL; + vfolder_info_reload (info, NULL, NULL, force_read_items); + } +} + +static void +item_dir_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + VFolderInfo *info = user_data; + + if (event_type == GNOME_VFS_MONITOR_EVENT_CREATED || + event_type == GNOME_VFS_MONITOR_EVENT_CHANGED) { + /* first invalidate all folders */ + invalidate_folder (info->root); + /* second invalidate all entries */ + info->entries_valid = FALSE; + + if (info->file_monitors != NULL) { + GnomeVFSResult result; + GSList *li; + + /* Whack all monitors here! */ + for (li = info->file_monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *h = li->data; + if (h->handle != NULL) + gnome_vfs_monitor_cancel (h->handle); + h->handle = NULL; + } + + if (vfolder_info_read_items (info, &result, NULL)) { + info->entries_valid = TRUE; + } + } + } +} + +static gboolean +setup_dir_monitor (VFolderInfo *info, const char *dir, gboolean subdirs, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + GnomeVFSMonitorHandle *handle; + DIR *dh; + struct dirent *de; + char *uri; + + uri = gnome_vfs_get_uri_from_local_path (dir); + + if (gnome_vfs_monitor_add (&handle, + uri, + GNOME_VFS_MONITOR_DIRECTORY, + item_dir_monitor, + info) != GNOME_VFS_OK) { + StatLoc *sl = bake_statloc (dir, time (NULL)); + if (sl != NULL) + info->stat_dirs = g_slist_prepend (info->stat_dirs, sl); + g_free (uri); + return TRUE; + } + g_free (uri); + + if (gnome_vfs_context_check_cancellation (context)) { + gnome_vfs_monitor_cancel (handle); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + info->item_dir_monitors = + g_slist_prepend (info->item_dir_monitors, handle); + + if ( ! subdirs) + return TRUE; + + dh = opendir (dir); + if (dh == NULL) + return TRUE; + + while ((de = readdir (dh)) != NULL) { + char *full_path; + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + closedir (dh); + return FALSE; + } + + if (de->d_name[0] == '.') + continue; + + full_path = g_build_filename (dir, de->d_name, NULL); + if (g_file_test (full_path, G_FILE_TEST_IS_DIR)) { + if ( ! setup_dir_monitor (info, full_path, + TRUE /* subdirs */, + result, context)) { + closedir (dh); + return FALSE; + } + } + g_free (full_path); + } + + closedir (dh); + + return TRUE; +} + +static gboolean +monitor_setup (VFolderInfo *info, + gboolean setup_filenames, + gboolean setup_itemdirs, + gboolean setup_desktop_dirs, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + char *uri; + GSList *li; + + if (setup_filenames) { + uri = gnome_vfs_get_uri_from_local_path + (info->filename); + + if (gnome_vfs_monitor_add (&info->filename_monitor, + uri, + GNOME_VFS_MONITOR_FILE, + vfolder_filename_monitor, + info) != GNOME_VFS_OK) { + info->filename_monitor = NULL; + info->filename_statloc = bake_statloc (info->filename, + time (NULL)); + } + g_free (uri); + } + if (setup_filenames && + info->user_filename != NULL) { + uri = gnome_vfs_get_uri_from_local_path + (info->user_filename); + if (gnome_vfs_monitor_add (&info->user_filename_monitor, + uri, + GNOME_VFS_MONITOR_FILE, + vfolder_user_filename_monitor, + info) != GNOME_VFS_OK) { + info->user_filename_monitor = NULL; + info->user_filename_statloc = + bake_statloc (info->user_filename, + time (NULL)); + } + + g_free (uri); + } + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + if (setup_itemdirs) { + for (li = info->item_dirs; li != NULL; li = li->next) { + const char *dir = li->data; + if ( ! setup_dir_monitor (info, dir, + FALSE /* subdirs */, + result, context)) + return FALSE; + } + if (info->user_item_dir != NULL) { + if ( ! setup_dir_monitor (info, info->user_item_dir, + FALSE /* subdirs */, + result, context)) + return FALSE; + } + for (li = info->merge_dirs; li != NULL; li = li->next) { + const char *dir = li->data; + if ( ! setup_dir_monitor (info, dir, + TRUE /* subdirs */, + result, context)) + return FALSE; + } + } + + if (setup_desktop_dirs) { + uri = gnome_vfs_get_uri_from_local_path + (info->desktop_dir); + + if (gnome_vfs_monitor_add (&info->desktop_dir_monitor, + uri, + GNOME_VFS_MONITOR_FILE, + vfolder_desktop_dir_monitor, + info) != GNOME_VFS_OK) { + info->desktop_dir_monitor = NULL; + info->desktop_dir_statloc = + bake_statloc (info->desktop_dir, + time (NULL)); + } + g_free (uri); + } + if (setup_desktop_dirs && + info->user_desktop_dir != NULL) { + uri = gnome_vfs_get_uri_from_local_path + (info->user_desktop_dir); + if (gnome_vfs_monitor_add (&info->user_desktop_dir_monitor, + uri, + GNOME_VFS_MONITOR_DIRECTORY, + vfolder_user_desktop_dir_monitor, + info) != GNOME_VFS_OK) { + info->user_desktop_dir_monitor = NULL; + info->user_desktop_dir_statloc = + bake_statloc (info->user_desktop_dir, + time (NULL)); + } + + g_free (uri); + } + + return TRUE; +} + +static void +vfolder_info_init (VFolderInfo *info, const char *scheme) +{ + const char *path; + GSList *list; + + info->scheme = g_strdup (scheme); + + info->filename = g_strconcat (SYSCONFDIR, "/X11/desktop-menus/", + scheme, ".menu", + NULL); + info->user_filename = g_strconcat (g_get_home_dir (), + "/" DOT_GNOME "/vfolders/", + scheme, ".vfolder-info", + NULL); + info->desktop_dir = g_strconcat (SYSCONFDIR, + "/gnome-vfs-2.0/vfolders/", + NULL); + info->user_desktop_dir = g_strconcat (g_get_home_dir (), + "/" DOT_GNOME "/vfolders/", + NULL); + + /* Init the desktop paths */ + list = NULL; + list = g_slist_prepend (list, g_strdup ("/usr/share/applications/")); + if (strcmp ("/usr/share/applications/", DATADIR "/applications/") != 0) + list = g_slist_prepend (list, g_strdup (DATADIR "/applications/")); + path = g_getenv ("DESKTOP_FILE_PATH"); + if (path != NULL) { + int i; + char **ppath = g_strsplit (path, ":", -1); + for (i = 0; ppath[i] != NULL; i++) { + const char *dir = ppath[i]; + list = g_slist_prepend (list, g_strdup (dir)); + } + g_strfreev (ppath); + } + info->item_dirs = g_slist_reverse (list); + + info->user_item_dir = g_strconcat (g_get_home_dir (), + "/" DOT_GNOME "/vfolders/", + scheme, + NULL); + + info->entries_ht = g_hash_table_new (g_str_hash, g_str_equal); + + info->root = folder_new ("Root"); + + info->modification_time = time (NULL); +} + +static void +vfolder_info_free_internals_unlocked (VFolderInfo *info) +{ + if (info == NULL) + return; + + if (info->filename_monitor != NULL) { + gnome_vfs_monitor_cancel (info->filename_monitor); + info->filename_monitor = NULL; + } + + if (info->user_filename_monitor != NULL) { + gnome_vfs_monitor_cancel (info->user_filename_monitor); + info->user_filename_monitor = NULL; + } + + g_free (info->filename_statloc); + info->filename_statloc = NULL; + + g_free (info->user_filename_statloc); + info->user_filename_statloc = NULL; + + + if (info->desktop_dir_monitor != NULL) { + gnome_vfs_monitor_cancel (info->desktop_dir_monitor); + info->desktop_dir_monitor = NULL; + } + + if (info->user_desktop_dir_monitor != NULL) { + gnome_vfs_monitor_cancel (info->user_desktop_dir_monitor); + info->user_desktop_dir_monitor = NULL; + } + + g_free (info->desktop_dir_statloc); + info->desktop_dir_statloc = NULL; + + g_free (info->user_desktop_dir_statloc); + info->user_desktop_dir_statloc = NULL; + + + g_slist_foreach (info->item_dir_monitors, + (GFunc)gnome_vfs_monitor_cancel, NULL); + g_slist_free (info->item_dir_monitors); + info->item_dir_monitors = NULL; + + g_free (info->scheme); + info->scheme = NULL; + + g_free (info->filename); + info->filename = NULL; + + g_free (info->user_filename); + info->user_filename = NULL; + + g_free (info->desktop_dir); + info->desktop_dir = NULL; + + g_free (info->user_desktop_dir); + info->user_desktop_dir = NULL; + + g_slist_foreach (info->item_dirs, (GFunc)g_free, NULL); + g_slist_free (info->item_dirs); + info->item_dirs = NULL; + + g_free (info->user_item_dir); + info->user_item_dir = NULL; + + g_slist_foreach (info->merge_dirs, (GFunc)g_free, NULL); + g_slist_free (info->merge_dirs); + info->merge_dirs = NULL; + + g_slist_foreach (info->entries, (GFunc)entry_unref, NULL); + g_slist_free (info->entries); + info->entries = NULL; + + if (info->entries_ht != NULL) + g_hash_table_destroy (info->entries_ht); + info->entries_ht = NULL; + + g_slist_foreach (info->unallocated_folders, + (GFunc)entry_unref, + NULL); + g_slist_free (info->unallocated_folders); + info->unallocated_folders = NULL; + + entry_unref ((Entry *)info->root); + info->root = NULL; + + g_slist_foreach (info->stat_dirs, (GFunc)g_free, NULL); + g_slist_free (info->stat_dirs); + info->stat_dirs = NULL; + + g_slist_foreach (info->folder_monitors, + (GFunc)file_monitor_handle_unref_unlocked, NULL); + g_slist_free (info->folder_monitors); + info->folder_monitors = NULL; + + g_slist_foreach (info->free_folder_monitors, + (GFunc)file_monitor_handle_unref_unlocked, NULL); + g_slist_free (info->free_folder_monitors); + info->free_folder_monitors = NULL; + + g_slist_foreach (info->file_monitors, + (GFunc)file_monitor_handle_unref_unlocked, NULL); + g_slist_free (info->file_monitors); + info->file_monitors = NULL; + + g_slist_foreach (info->free_file_monitors, + (GFunc)file_monitor_handle_unref_unlocked, NULL); + g_slist_free (info->free_file_monitors); + info->free_file_monitors = NULL; + + if (info->reread_queue != 0) + g_source_remove (info->reread_queue); + info->reread_queue = 0; +} + +static void +vfolder_info_free_internals (VFolderInfo *info) +{ + G_LOCK (vfolder_lock); + vfolder_info_free_internals_unlocked (info); + G_UNLOCK (vfolder_lock); +} + +static void +vfolder_info_destroy (VFolderInfo *info) +{ + vfolder_info_free_internals (info); + g_free (info); +} + +static Query * +single_query_read (xmlNode *qnode) +{ + Query *query; + xmlNode *node; + + if (qnode->type != XML_ELEMENT_NODE || + qnode->name == NULL) + return NULL; + + query = NULL; + + if (g_ascii_strcasecmp (qnode->name, "Not") == 0 && + qnode->xmlChildrenNode != NULL) { + xmlNode *iter; + query = NULL; + for (iter = qnode->xmlChildrenNode; + iter != NULL && query == NULL; + iter = iter->next) + query = single_query_read (iter); + if (query != NULL) { + query->not = ! query->not; + } + return query; + } else if (g_ascii_strcasecmp (qnode->name, "Keyword") == 0) { + xmlChar *word = xmlNodeGetContent (qnode); + if (word != NULL) { + query = query_new (QUERY_KEYWORD); + ((QueryKeyword *)query)->keyword = + g_quark_from_string (word); + + xmlFree (word); + } + return query; + } else if (g_ascii_strcasecmp (qnode->name, "Filename") == 0) { + xmlChar *file = xmlNodeGetContent (qnode); + if (file != NULL) { + query = query_new (QUERY_FILENAME); + ((QueryFilename *)query)->filename = + g_strdup (file); + + xmlFree (file); + } + return query; + } else if (g_ascii_strcasecmp (qnode->name, "And") == 0) { + query = query_new (QUERY_AND); + } else if (g_ascii_strcasecmp (qnode->name, "Or") == 0) { + query = query_new (QUERY_OR); + } else { + /* We don't understand */ + return NULL; + } + + /* This must be OR or AND */ + g_assert (query != NULL); + + for (node = qnode->xmlChildrenNode; node != NULL; node = node->next) { + Query *new_query = single_query_read (node); + + if (new_query != NULL) + query->queries = g_slist_prepend + (query->queries, new_query); + } + + query->queries = g_slist_reverse (query->queries); + + return query; +} + +static void +add_or_set_query (Query **query, Query *new_query) +{ + if (*query == NULL) { + *query = new_query; + } else { + Query *old_query = *query; + *query = query_new (QUERY_OR); + (*query)->queries = + g_slist_append ((*query)->queries, old_query); + (*query)->queries = + g_slist_append ((*query)->queries, new_query); + } +} + +static Query * +query_read (xmlNode *qnode) +{ + Query *query; + xmlNode *node; + + query = NULL; + + for (node = qnode->xmlChildrenNode; node != NULL; node = node->next) { + if (node->type != XML_ELEMENT_NODE || + node->name == NULL) + continue; + + if (g_ascii_strcasecmp (node->name, "Not") == 0 && + node->xmlChildrenNode != NULL) { + xmlNode *iter; + Query *new_query = NULL; + + for (iter = node->xmlChildrenNode; + iter != NULL && new_query == NULL; + iter = iter->next) + new_query = single_query_read (iter); + if (new_query != NULL) { + new_query->not = ! new_query->not; + add_or_set_query (&query, new_query); + } + } else { + Query *new_query = single_query_read (node); + if (new_query != NULL) + add_or_set_query (&query, new_query); + } + } + + return query; +} + +static Folder * +folder_read (VFolderInfo *info, xmlNode *fnode) +{ + Folder *folder; + xmlNode *node; + + folder = folder_new (NULL); + + for (node = fnode->xmlChildrenNode; node != NULL; node = node->next) { + if (node->type != XML_ELEMENT_NODE || + node->name == NULL) + continue; + + if (g_ascii_strcasecmp (node->name, "Name") == 0) { + xmlChar *name = xmlNodeGetContent (node); + if (name != NULL) { + g_free (folder->entry.name); + folder->entry.name = g_strdup (name); + xmlFree (name); + } + } else if (g_ascii_strcasecmp (node->name, "Desktop") == 0) { + xmlChar *desktop = xmlNodeGetContent (node); + if (desktop != NULL) { + g_free (folder->desktop_file); + folder->desktop_file = g_strdup (desktop); + xmlFree (desktop); + } + } else if (g_ascii_strcasecmp (node->name, "Include") == 0) { + xmlChar *file = xmlNodeGetContent (node); + if (file != NULL) { + GSList *li; + char *str = g_strdup (file); + folder->includes = g_slist_prepend + (folder->includes, str); + if (folder->includes_ht == NULL) { + folder->includes_ht = + g_hash_table_new_full + (g_str_hash, + g_str_equal, + NULL, + NULL); + } + li = g_hash_table_lookup (folder->includes_ht, + file); + if (li != NULL) { + g_free (li->data); + /* Note: this will NOT change folder->includes + * pointer! */ + folder->includes = g_slist_delete_link + (folder->includes, li); + } + g_hash_table_replace (folder->includes_ht, + file, folder->includes); + xmlFree (file); + } + } else if (g_ascii_strcasecmp (node->name, "Exclude") == 0) { + xmlChar *file = xmlNodeGetContent (node); + if (file != NULL) { + char *s; + if (folder->excludes == NULL) { + folder->excludes = g_hash_table_new_full + (g_str_hash, + g_str_equal, + (GDestroyNotify)g_free, + NULL); + } + s = g_strdup (file); + g_hash_table_replace (folder->excludes, s, s); + xmlFree (file); + } + } else if (g_ascii_strcasecmp (node->name, "Query") == 0) { + Query *query; + + query = query_read (node); + + if (query != NULL) { + if (folder->query != NULL) + query_destroy (folder->query); + folder->query = query; + } + } else if (g_ascii_strcasecmp (node->name, "OnlyUnallocated") == 0) { + info->unallocated_folders = + g_slist_prepend (info->unallocated_folders, + (Folder *)entry_ref ((Entry *)folder)); + folder->only_unallocated = TRUE; + } else if (g_ascii_strcasecmp (node->name, "Folder") == 0) { + Folder *new_folder = folder_read (info, node); + if (new_folder != NULL) { + folder->subfolders = + g_slist_append (folder->subfolders, + new_folder); + new_folder->parent = folder; + } + } else if (g_ascii_strcasecmp (node->name, "ReadOnly") == 0) { + folder->read_only = TRUE; + } else if (g_ascii_strcasecmp (node->name, + "DontShowIfEmpty") == 0) { + folder->dont_show_if_empty = TRUE; + } + } + + /* Name is required */ + if (folder->entry.name == NULL) { + entry_unref ((Entry *)folder); + folder = NULL; + } + + folder->includes = g_slist_reverse (folder->includes); + + return folder; +} + +static char * +subst_home (const char *dir) +{ + if (dir[0] == '~') + return g_strconcat (g_get_home_dir (), + &dir[1], + NULL); + else + return g_strdup (dir); +} + +/* FORMAT looks like: + * + * + * /etc/X11/applnk + * + * /usr/share/applications + * + * /etc/X11/gnome/vfolders + * + * + * Root + * + * important.desktop + * + * + * + * SomeFolder + * + * + * Test_Folder + * + * Test_Folder.directory + * + * + * + * Application + * Game + * + * Clock + * + * + * somefile.desktop + * someotherfile.desktop + * yetanother.desktop + * + * + * + */ + +static gboolean +vfolder_info_read_info (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + xmlDoc *doc; + xmlNode *node; + gboolean got_a_vfolder_dir = FALSE; + + doc = NULL; + if (info->user_filename != NULL && + access (info->user_filename, F_OK) == 0) { + doc = xmlParseFile (info->user_filename); + if (doc != NULL) + info->user_file_active = TRUE; + } + if (doc == NULL && + access (info->filename, F_OK) == 0) + doc = xmlParseFile (info->filename); + + if (gnome_vfs_context_check_cancellation (context)) { + xmlFreeDoc(doc); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + if (doc == NULL + || doc->xmlRootNode == NULL + || doc->xmlRootNode->name == NULL + || g_ascii_strcasecmp (doc->xmlRootNode->name, "VFolderInfo") != 0) { + xmlFreeDoc(doc); + return TRUE; /* FIXME: really, shouldn't we error out? */ + } + + for (node = doc->xmlRootNode->xmlChildrenNode; node != NULL; node = node->next) { + if (node->type != XML_ELEMENT_NODE || + node->name == NULL) + continue; + + if (gnome_vfs_context_check_cancellation (context)) { + xmlFreeDoc(doc); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + if (g_ascii_strcasecmp (node->name, "MergeDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + if (dir != NULL) { + info->merge_dirs = g_slist_append (info->merge_dirs, + g_strdup (dir)); + xmlFree (dir); + } + } else if (g_ascii_strcasecmp (node->name, "ItemDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + if (dir != NULL) { + if ( ! got_a_vfolder_dir) { + g_slist_foreach (info->item_dirs, + (GFunc)g_free, NULL); + g_slist_free (info->item_dirs); + info->item_dirs = NULL; + } + got_a_vfolder_dir = TRUE; + info->item_dirs = g_slist_append (info->item_dirs, + g_strdup (dir)); + xmlFree (dir); + } + } else if (g_ascii_strcasecmp (node->name, "UserItemDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + if (dir != NULL) { + g_free (info->user_item_dir); + info->user_item_dir = subst_home (dir); + xmlFree (dir); + } + } else if (g_ascii_strcasecmp (node->name, "DesktopDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + if (dir != NULL) { + g_free (info->desktop_dir); + info->desktop_dir = g_strdup (dir); + xmlFree (dir); + } + } else if (g_ascii_strcasecmp (node->name, "UserDesktopDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + if (dir != NULL) { + g_free (info->user_desktop_dir); + info->user_desktop_dir = subst_home (dir); + xmlFree (dir); + } + } else if (g_ascii_strcasecmp (node->name, "Folder") == 0) { + Folder *folder = folder_read (info, node); + if (folder != NULL) { + if (info->root != NULL) + entry_unref ((Entry *)info->root); + info->root = folder; + } + } else if (g_ascii_strcasecmp (node->name, "ReadOnly") == 0) { + info->read_only = TRUE; + } + } + + xmlFreeDoc(doc); + + return TRUE; +} + +static void +add_xml_tree_from_query (xmlNode *parent, Query *query) +{ + xmlNode *real_parent; + + if (query->not) + real_parent = xmlNewChild (parent /* parent */, + NULL /* ns */, + "Not" /* name */, + NULL /* content */); + else + real_parent = parent; + + if (query->type == QUERY_KEYWORD) { + QueryKeyword *qkeyword = (QueryKeyword *)query; + const char *string = g_quark_to_string (qkeyword->keyword); + + xmlNewChild (real_parent /* parent */, + NULL /* ns */, + "Keyword" /* name */, + string /* content */); + } else if (query->type == QUERY_FILENAME) { + QueryFilename *qfilename = (QueryFilename *)query; + + xmlNewChild (real_parent /* parent */, + NULL /* ns */, + "Filename" /* name */, + qfilename->filename /* content */); + } else if (query->type == QUERY_OR || + query->type == QUERY_AND) { + xmlNode *node; + const char *name; + GSList *li; + + if (query->type == QUERY_OR) + name = "Or"; + else /* QUERY_AND */ + name = "And"; + + node = xmlNewChild (real_parent /* parent */, + NULL /* ns */, + name /* name */, + NULL /* content */); + + for (li = query->queries; li != NULL; li = li->next) { + Query *subquery = li->data; + add_xml_tree_from_query (node, subquery); + } + } else { + g_assert_not_reached (); + } +} + +static void +add_excludes_to_xml (gpointer key, gpointer value, gpointer user_data) +{ + const char *filename = key; + xmlNode *folder_node = user_data; + + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Exclude" /* name */, + filename /* content */); +} + +static void +add_xml_tree_from_folder (xmlNode *parent, Folder *folder) +{ + GSList *li; + xmlNode *folder_node; + + + folder_node = xmlNewChild (parent /* parent */, + NULL /* ns */, + "Folder" /* name */, + NULL /* content */); + + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Name" /* name */, + folder->entry.name /* content */); + + if (folder->desktop_file != NULL) { + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Desktop" /* name */, + folder->desktop_file /* content */); + } + + if (folder->read_only) + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "ReadOnly" /* name */, + NULL /* content */); + if (folder->dont_show_if_empty) + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "DontShowIfEmpty" /* name */, + NULL /* content */); + if (folder->only_unallocated) + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "OnlyUnallocated" /* name */, + NULL /* content */); + + for (li = folder->subfolders; li != NULL; li = li->next) { + Folder *subfolder = li->data; + add_xml_tree_from_folder (folder_node, subfolder); + } + + for (li = folder->includes; li != NULL; li = li->next) { + const char *include = li->data; + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Include" /* name */, + include /* content */); + } + + if (folder->excludes) { + g_hash_table_foreach (folder->excludes, + add_excludes_to_xml, + folder_node); + } + + if (folder->query != NULL) { + xmlNode *query_node; + query_node = xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Query" /* name */, + NULL /* content */); + + add_xml_tree_from_query (query_node, folder->query); + } +} + +static xmlDoc * +xml_tree_from_vfolder (VFolderInfo *info) +{ + xmlDoc *doc; + xmlNode *topnode; + GSList *li; + + doc = xmlNewDoc ("1.0"); + + topnode = xmlNewDocNode (doc /* doc */, + NULL /* ns */, + "VFolderInfo" /* name */, + NULL /* content */); + doc->xmlRootNode = topnode; + + for (li = info->merge_dirs; li != NULL; li = li->next) { + const char *merge_dir = li->data; + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "MergeDir" /* name */, + merge_dir /* content */); + } + + for (li = info->item_dirs; li != NULL; li = li->next) { + const char *item_dir = li->data; + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "ItemDir" /* name */, + item_dir /* content */); + } + + if (info->user_item_dir != NULL) { + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "UserItemDir" /* name */, + info->user_item_dir /* content */); + } + + if (info->desktop_dir != NULL) { + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "DesktopDir" /* name */, + info->desktop_dir /* content */); + } + + if (info->user_desktop_dir != NULL) { + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "UserDesktopDir" /* name */, + info->user_desktop_dir /* content */); + } + + if (info->root != NULL) + add_xml_tree_from_folder (topnode, info->root); + + return doc; +} + +/* FIXME: what to do about errors */ +static void +vfolder_info_write_user (VFolderInfo *info) +{ + xmlDoc *doc; + + if (info->inhibit_write > 0) + return; + + if (info->user_filename == NULL) + return; + + doc = xml_tree_from_vfolder (info); + if (doc == NULL) + return; + + /* FIXME: errors, anyone? */ + ensure_dir (info->user_filename, + TRUE /* ignore_basename */); + + xmlSaveFormatFile (info->user_filename, doc, TRUE /* format */); + /* not as good as a stat, but cheaper ... hmmm what is + * the likelyhood of this not being the same as ctime */ + info->user_filename_last_write = time (NULL); + + xmlFreeDoc(doc); + + info->user_file_active = TRUE; + info->dirty = FALSE; + + info->modification_time = time (NULL); +} + +/* An EVIL function for quick reading of .desktop files, + * only reads in one or two keys, but that's ALL we need */ +static void +readitem_entry (const char *filename, + const char *key1, + char **result1, + const char *key2, + char **result2) +{ + FILE *fp; + char buf[1024]; + int keylen1, keylen2; + + *result1 = NULL; + if (result2 != NULL) + *result2 = NULL; + + fp = fopen (filename, "r"); + + if (fp == NULL) + return; + + keylen1 = strlen (key1); + if (key2 != NULL) + keylen2 = strlen (key2); + else + keylen2 = -1; + + /* This is slightly wrong, it should only look + * at the correct section */ + while (fgets (buf, sizeof (buf), fp) != NULL) { + char *p; + int len; + int keylen; + char **result = NULL; + + /* check if it's one of the keys */ + if (strncmp (buf, key1, keylen1) == 0) { + result = result1; + keylen = keylen1; + } else if (keylen2 >= 0 && + strncmp (buf, key2, keylen2) == 0) { + result = result2; + keylen = keylen2; + } else { + continue; + } + + p = &buf[keylen]; + + /* still not our key */ + if (!(*p == '=' || *p == ' ')) { + continue; + } + do + p++; + while (*p == ' ' || *p == '='); + + /* get rid of trailing \n */ + len = strlen (p); + if (p[len-1] == '\n' || + p[len-1] == '\r') + p[len-1] = '\0'; + + *result = g_strdup (p); + + if (*result1 != NULL && + (result2 == NULL || *result2 != NULL)) + break; + } + + fclose (fp); +} + +static void +vfolder_info_insert_entry (VFolderInfo *info, EntryFile *efile) +{ + GSList *entry_list; + + entry_ref ((Entry *)efile); + + entry_list = g_hash_table_lookup (info->entries_ht, efile->entry.name); + + info->entries = g_slist_prepend (info->entries, efile); + /* The hash table contains the GSList pointer */ + g_hash_table_replace (info->entries_ht, efile->entry.name, + info->entries); + + if (entry_list != NULL) { + Entry *entry = entry_list->data; + info->entries = g_slist_delete_link (info->entries, + entry_list); + entry_unref (entry); + } +} + +static void +set_keywords (EntryFile *efile, const char *keywords) +{ + if (keywords != NULL) { + int i; + char **parsed = g_strsplit (keywords, ";", -1); + for (i = 0; parsed[i] != NULL; i++) { + GQuark quark; + const char *word = parsed[i]; + /* ignore empties (including end of list) */ + if (word[0] == '\0') + continue; + quark = g_quark_from_string (word); + efile->keywords = g_slist_prepend + (efile->keywords, + GINT_TO_POINTER (quark)); + } + g_strfreev (parsed); + } +} + +static EntryFile * +make_entry_file (const char *dir, const char *name) +{ + EntryFile *efile; + char *categories; + char *only_show_in; + char *filename; + int i; + + filename = g_build_filename (dir, name, NULL); + + readitem_entry (filename, + "Categories", + &categories, + "OnlyShowIn", + &only_show_in); + + if (only_show_in != NULL) { + gboolean show = FALSE; + char **parsed = g_strsplit (only_show_in, ";", -1); + for (i = 0; parsed[i] != NULL; i++) { + if (strcmp (parsed[i], "GNOME") == 0) { + show = TRUE; + break; + } + } + g_strfreev (parsed); + if ( ! show) { + g_free (filename); + g_free (only_show_in); + g_free (categories); + return NULL; + } + } + + efile = file_new (name); + efile->filename = filename; + + set_keywords (efile, categories); + + g_free (only_show_in); + g_free (categories); + + return efile; +} + +static gboolean +vfolder_info_read_items_from (VFolderInfo *info, + const char *item_dir, + gboolean per_user, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + DIR *dir; + struct dirent *de; + + dir = opendir (item_dir); + if (dir == NULL) + return TRUE; + + while ((de = readdir (dir)) != NULL) { + EntryFile *efile; + + if (gnome_vfs_context_check_cancellation (context)) { + closedir (dir); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + /* files MUST be called .desktop */ + if (de->d_name[0] == '.' || + ! check_ext (de->d_name, ".desktop")) + continue; + + efile = make_entry_file (item_dir, de->d_name); + if (efile == NULL) + continue; + + efile->per_user = per_user; + + vfolder_info_insert_entry (info, efile); + entry_unref ((Entry *)efile); + } + + closedir (dir); + + return TRUE; +} + +static gboolean +vfolder_info_read_items_merge (VFolderInfo *info, + const char *merge_dir, + const char *subdir, + GQuark inherited_keyword, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + DIR *dir; + struct dirent *de; + GQuark extra_keyword; + GQuark Application; + GQuark Merged; + GQuark inheritance; + gboolean pass_down_extra_keyword = TRUE; + + dir = opendir (merge_dir); + if (dir == NULL) + return TRUE; + + Application = g_quark_from_static_string ("Application"); + Merged = g_quark_from_static_string ("Merged"); + + /* FIXME: this should be a hash or something */ + extra_keyword = 0; + if (subdir == NULL) { + extra_keyword = g_quark_from_static_string ("Core"); + pass_down_extra_keyword = FALSE; + } else if (g_ascii_strcasecmp (subdir, "Development") == 0) + extra_keyword = g_quark_from_static_string ("Development"); + else if (g_ascii_strcasecmp (subdir, "Editors") == 0) + extra_keyword = g_quark_from_static_string ("TextEditor"); + else if (g_ascii_strcasecmp (subdir, "Games") == 0) + extra_keyword = g_quark_from_static_string ("Game"); + else if (g_ascii_strcasecmp (subdir, "Graphics") == 0) + extra_keyword = g_quark_from_static_string ("Graphics"); + else if (g_ascii_strcasecmp (subdir, "Internet") == 0) + extra_keyword = g_quark_from_static_string ("Network"); + else if (g_ascii_strcasecmp (subdir, "Multimedia") == 0) + extra_keyword = g_quark_from_static_string ("AudioVideo"); + else if (g_ascii_strcasecmp (subdir, "Office") == 0) + extra_keyword = g_quark_from_static_string ("Office"); + else if (g_ascii_strcasecmp (subdir, "Settings") == 0) + extra_keyword = g_quark_from_static_string ("Settings"); + else if (g_ascii_strcasecmp (subdir, "System") == 0) + extra_keyword = g_quark_from_static_string ("System"); + else if (g_ascii_strcasecmp (subdir, "Utilities") == 0) + extra_keyword = g_quark_from_static_string ("Utility"); + + while ((de = readdir (dir)) != NULL) { + EntryFile *efile; + + if (gnome_vfs_context_check_cancellation (context)) { + closedir (dir); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + /* ignore hidden */ + if (de->d_name[0] == '.') + continue; + + /* files MUST be called .desktop, so + * treat all others as dirs. If we're wrong, + * the open will fail, which is ok */ + if ( ! check_ext (de->d_name, ".desktop")) { + /* if this is a directory recurse */ + char *fullname = g_build_filename (merge_dir, de->d_name, NULL); + if ((pass_down_extra_keyword == TRUE) && (extra_keyword != 0)) { + inheritance = extra_keyword; + } else { + inheritance = inherited_keyword; + } + + if ( ! vfolder_info_read_items_merge (info, + fullname, + de->d_name, + inheritance, + result, + context)) { + g_free (fullname); + return FALSE; + } + g_free (fullname); + continue; + } + + /* FIXME: add some keywords about some known apps + * like gimp and whatnot, perhaps take these from the vfolder + * file or some such */ + + efile = make_entry_file (merge_dir, de->d_name); + if (efile == NULL) + continue; + + /* If no keywords set, then add the standard ones */ + if (efile->keywords == NULL) { + efile->keywords = g_slist_prepend + (efile->keywords, + GINT_TO_POINTER (Application)); + + efile->keywords = g_slist_prepend + (efile->keywords, + GINT_TO_POINTER (Merged)); + + if (inherited_keyword != 0) { + efile->keywords = g_slist_prepend + (efile->keywords, + GINT_TO_POINTER (inherited_keyword)); + } + + if (extra_keyword != 0) { + efile->keywords = g_slist_prepend + (efile->keywords, + GINT_TO_POINTER (extra_keyword)); + } + efile->implicit_keywords = TRUE; + } + + vfolder_info_insert_entry (info, efile); + entry_unref ((Entry *)efile); + } + + closedir (dir); + + return TRUE; +} + +static Entry * +find_entry (GSList *list, const char *name) +{ + GSList *li; + + for (li = list; li != NULL; li = li->next) { + Entry *entry = li->data; + if (strcmp (name, entry->name) == 0) + return entry; + } + return NULL; +} + +static void +file_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + FileMonitorHandle *h = user_data; + + /* proxy the event through if it is a changed event + * only */ + + if (event_type == GNOME_VFS_MONITOR_EVENT_CHANGED && + h->handle != NULL) + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *) h, + h->uri, event_type); +} + +static void +try_free_file_monitors_create_files_unlocked (VFolderInfo *info) +{ + GSList *li, *list; + + list = g_slist_copy (info->free_file_monitors); + + for (li = list; li != NULL; li = li->next) { + FileMonitorHandle *handle = li->data; + Entry *entry; + GnomeVFSResult result; + char *dirfile = NULL; + + if (handle->is_directory_file) { + VFolderURI vuri; + Folder *folder; + + /* Evil! EVIL URI PARSING. this will eat a lot of + * stack if we have lots of free monitors */ + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + folder = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + + if (folder == NULL) + continue; + + dirfile = get_directory_file_unlocked (info, folder); + if (dirfile == NULL) + continue; + + entry = (Entry *)folder; + } else { + VFolderURI vuri; + Folder *f; + GnomeVFSResult result; + + entry = NULL; + + /* Evil! EVIL URI PARSING. this will eat a lot of + * stack if we have lots of monitors */ + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + f = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + + if (f != NULL) { + ensure_folder_unlocked ( + info, f, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + entry = find_entry (f->entries, vuri.file); + } + + if (entry == NULL) + continue; + } + + info->free_file_monitors = + g_slist_remove (info->free_file_monitors, handle); + entry->monitors = + g_slist_prepend (entry->monitors, handle); + + handle->exists = TRUE; + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *)handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_CREATED); + + /* recreate a handle */ + if (handle->handle == NULL && + entry->type == ENTRY_FILE) { + EntryFile *efile = (EntryFile *)entry; + char *uri = gnome_vfs_get_uri_from_local_path + (efile->filename); + + gnome_vfs_monitor_add (&(handle->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + handle); + + g_free (uri); + } else if (handle->handle == NULL && + dirfile != NULL) { + char *uri = gnome_vfs_get_uri_from_local_path (dirfile); + + gnome_vfs_monitor_add (&(handle->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + handle); + + g_free (uri); + } + + g_free (dirfile); + } + + g_slist_free (list); +} + +static void /* unlocked */ +rescan_monitors (VFolderInfo *info) +{ + GSList *li; + + if (info->file_monitors == NULL) + return; + + for (li = info->file_monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + GnomeVFSResult result; + Entry *entry; + char *dirfile = NULL; + + /* these are handled below */ + if ( ! h->exists) + continue; + + if (h->is_directory_file) { + VFolderURI vuri; + Folder *folder; + + /* Evil! EVIL URI PARSING. this will eat a lot of + * stack if we have lots of monitors */ + + VFOLDER_URI_PARSE (h->uri, &vuri); + + folder = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + if (folder != NULL) + dirfile = get_directory_file_unlocked (info, + folder); + + if (dirfile == NULL) { + h->exists = FALSE; + gnome_vfs_monitor_callback + ((GnomeVFSMethodHandle *)h, + h->uri, + GNOME_VFS_MONITOR_EVENT_DELETED); + info->free_file_monitors = g_slist_prepend + (info->free_file_monitors, h); + file_monitor_handle_ref_unlocked (h); + /* it has been unreffed when the entry was + * whacked */ + continue; + } + + entry = (Entry *)folder; + } else { + VFolderURI vuri; + Folder *f; + GnomeVFSResult result; + + entry = NULL; + + /* Evil! EVIL URI PARSING. this will eat a lot of + * stack if we have lots of monitors */ + + VFOLDER_URI_PARSE (h->uri, &vuri); + + f = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + + if (f != NULL) { + ensure_folder_unlocked ( + info, f, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + entry = find_entry (f->entries, vuri.file); + } + + if (entry == NULL) { + h->exists = FALSE; + gnome_vfs_monitor_callback + ((GnomeVFSMethodHandle *)h, + h->uri, + GNOME_VFS_MONITOR_EVENT_DELETED); + info->free_file_monitors = g_slist_prepend + (info->free_file_monitors, h); + file_monitor_handle_ref_unlocked (h); + /* it has been unreffed when the entry was + * whacked */ + continue; + } + } + + /* recreate a handle */ + if (h->handle == NULL && + entry->type == ENTRY_FILE) { + EntryFile *efile = (EntryFile *)entry; + char *uri = gnome_vfs_get_uri_from_local_path + (efile->filename); + + gnome_vfs_monitor_add (&(h->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + h); + + g_free (uri); + } else if (h->handle == NULL && + dirfile != NULL) { + char *uri = gnome_vfs_get_uri_from_local_path (dirfile); + + gnome_vfs_monitor_add (&(h->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + h); + + g_free (uri); + } + + g_free (dirfile); + } + + try_free_file_monitors_create_files_unlocked (info); +} + +static gboolean /* unlocked */ +vfolder_info_read_items (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + GSList *li; + + /* First merge */ + for (li = info->merge_dirs; li != NULL; li = li->next) { + const char *merge_dir = li->data; + + if ( ! vfolder_info_read_items_merge (info, merge_dir, NULL, FALSE, + result, context)) + return FALSE; + } + + /* Then read the real thing (later overrides) */ + for (li = info->item_dirs; li != NULL; li = li->next) { + const char *item_dir = li->data; + + if ( ! vfolder_info_read_items_from (info, item_dir, + FALSE /* per_user */, + result, context)) + return FALSE; + } + + if (info->user_item_dir != NULL) { + if ( ! vfolder_info_read_items_from (info, + info->user_item_dir, + TRUE /* per_user */, + result, context)) + return FALSE; + } + + rescan_monitors (info); + + return TRUE; +} + +static gboolean +string_slist_equal (GSList *list1, GSList *list2) +{ + GSList *li1, *li2; + + for (li1 = list1, li2 = list2; + li1 != NULL && li2 != NULL; + li1 = li1->next, li2 = li2->next) { + const char *s1 = li1->data; + const char *s2 = li2->data; + if (strcmp (s1, s2) != 0) + return FALSE; + } + /* if both are not NULL, then lengths are + * different */ + if (li1 != li2) + return FALSE; + return TRUE; +} + +static gboolean +safe_string_same (const char *string1, const char *string2) +{ + if (string1 == string2 && + string1 == NULL) + return TRUE; + + if (string1 != NULL && string2 != NULL && + strcmp (string1, string2) == 0) + return TRUE; + + return FALSE; +} + +static gboolean +vfolder_info_item_dirs_same (VFolderInfo *info1, VFolderInfo *info2) +{ + if ( ! string_slist_equal (info1->item_dirs, + info2->item_dirs)) + return FALSE; + + if ( ! string_slist_equal (info1->merge_dirs, + info2->merge_dirs)) + return FALSE; + + if ( ! safe_string_same (info1->user_item_dir, + info2->user_item_dir)) + return FALSE; + + return TRUE; +} + +static gboolean +vfolder_info_reload_unlocked (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context, + gboolean force_read_items) +{ + VFolderInfo *newinfo; + gboolean setup_filenames; + gboolean setup_itemdirs; + GSList *li; + + /* FIXME: Hmmm, race, there is no locking YAIKES, + * we need filename locking for changes. eek, eek, eek */ + if (info->dirty) { + return TRUE; + } + + newinfo = g_new0 (VFolderInfo, 1); + vfolder_info_init (newinfo, info->scheme); + + g_free (newinfo->filename); + g_free (newinfo->user_filename); + newinfo->filename = g_strdup (info->filename); + newinfo->user_filename = g_strdup (info->user_filename); + + if (gnome_vfs_context_check_cancellation (context)) { + vfolder_info_destroy (newinfo); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + if ( ! vfolder_info_read_info (newinfo, result, context)) { + vfolder_info_destroy (newinfo); + return FALSE; + } + + /* FIXME: reload logic for 'desktop_dir' and + * 'user_desktop_dir' */ + + setup_itemdirs = TRUE; + + /* Validity of entries and item dirs and all that is unchanged */ + if (vfolder_info_item_dirs_same (info, newinfo)) { + newinfo->entries = info->entries; + info->entries = NULL; + newinfo->entries_ht = info->entries_ht; + info->entries_ht = NULL /* some places assume this + non-null, but we're only + going to destroy this */; + newinfo->entries_valid = info->entries_valid; + + /* move over the monitors/statlocs since those are valid */ + newinfo->item_dir_monitors = info->item_dir_monitors; + info->item_dir_monitors = NULL; + newinfo->stat_dirs = info->stat_dirs; + info->stat_dirs = NULL; + + /* No need to resetup dir monitors */ + setup_itemdirs = FALSE; + + /* No need to do anything with file monitors */ + } else { + /* Whack all monitors here! */ + for (li = info->file_monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + if (h->handle != NULL) + gnome_vfs_monitor_cancel (h->handle); + h->handle = NULL; + } + } + + setup_filenames = TRUE; + + if (safe_string_same (info->filename, newinfo->filename) && + safe_string_same (info->user_filename, newinfo->user_filename)) { + newinfo->user_filename_last_write = + info->user_filename_last_write; + + /* move over the monitors/statlocs since those are valid */ + newinfo->filename_monitor = info->filename_monitor; + info->filename_monitor = NULL; + newinfo->user_filename_monitor = info->user_filename_monitor; + info->user_filename_monitor = NULL; + + if (info->filename_statloc != NULL && + info->filename != NULL) + newinfo->filename_statloc = + bake_statloc (info->filename, + time (NULL)); + if (info->user_filename_statloc != NULL && + info->user_filename != NULL) + newinfo->user_filename_statloc = + bake_statloc (info->user_filename, + time (NULL)); + + /* No need to resetup filename monitors */ + setup_filenames = FALSE; + } + + /* Note: not cancellable anymore, since we've + * already started nibbling on the info structure, + * so we'd need to back things out or some such, + * too complex, so screw that */ + monitor_setup (info, + setup_filenames, + setup_itemdirs, + /* FIXME: setup_desktop_dirs */ TRUE, + NULL, NULL); + + for (li = info->folder_monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *handle = li->data; + li->data = NULL; + + add_folder_monitor_unlocked (newinfo, handle); + + file_monitor_handle_unref_unlocked (handle); + } + g_slist_free (info->folder_monitors); + info->folder_monitors = NULL; + + g_slist_foreach (info->free_folder_monitors, + (GFunc)file_monitor_handle_unref_unlocked, NULL); + g_slist_free (info->free_folder_monitors); + info->folder_monitors = NULL; + + /* we can just copy these for now, they will be readded + * and all the fun stuff will be done with them later */ + newinfo->file_monitors = info->file_monitors; + info->file_monitors = NULL; + newinfo->free_file_monitors = info->free_file_monitors; + info->free_file_monitors = NULL; + + /* emit changed on all folders, a bit drastic, but oh well, + * we also invalidate all folders at the same time, but that is + * irrelevant since they should all just be invalid to begin with */ + invalidate_folder_T (info->root); + + /* FIXME: make sure if this was enough, I think it was */ + + vfolder_info_free_internals_unlocked (info); + memcpy (info, newinfo, sizeof (VFolderInfo)); + g_free (newinfo); + + /* must rescan the monitors here */ + if (info->entries_valid) { + rescan_monitors (info); + } + + if ( ! info->entries_valid && + force_read_items) { + GnomeVFSResult res; + /* FIXME: I bet cancelation plays havoc with monitors, + * I'm not sure however */ + if (info->file_monitors != NULL) { + vfolder_info_read_items (info, &res, NULL); + } else { + if ( ! vfolder_info_read_items (info, result, context)) + return FALSE; + } + info->entries_valid = TRUE; + } + + return TRUE; +} + +static gboolean +vfolder_info_reload (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context, + gboolean force_read_items) +{ + G_LOCK (vfolder_lock); + if (vfolder_info_reload_unlocked (info, result, context, + force_read_items)) { + G_UNLOCK (vfolder_lock); + return TRUE; + } else { + G_UNLOCK (vfolder_lock); + return FALSE; + } +} + +static gboolean +vfolder_info_recheck (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + GSList *li; + time_t curtime = time (NULL); + gboolean reread = FALSE; + + if (info->filename_statloc != NULL && + ! check_statloc (info->filename_statloc, curtime)) { + if ( ! vfolder_info_reload_unlocked (info, result, context, + FALSE /* force read items */)) { + /* we have failed, make sure we fail + * next time too */ + info->filename_statloc->trigger_next = TRUE; + return FALSE; + } + reread = TRUE; + } + if ( ! reread && + info->user_filename_statloc != NULL && + ! check_statloc (info->user_filename_statloc, curtime)) { + if ( ! vfolder_info_reload_unlocked (info, result, context, + FALSE /* force read items */)) { + /* we have failed, make sure we fail + * next time too */ + info->user_filename_statloc->trigger_next = TRUE; + return FALSE; + } + reread = TRUE; + } + + if (info->entries_valid) { + for (li = info->stat_dirs; li != NULL; li = li->next) { + StatLoc *sl = li->data; + if ( ! check_statloc (sl, curtime)) { + info->entries_valid = FALSE; + break; + } + } + } + return TRUE; +} + +static VFolderInfo * +get_vfolder_info_unlocked (const char *scheme, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + VFolderInfo *info; + + if (infos != NULL && + (info = g_hash_table_lookup (infos, scheme)) != NULL) { + if ( ! vfolder_info_recheck (info, result, context)) { + return NULL; + } + if ( ! info->entries_valid) { + g_slist_foreach (info->entries, + (GFunc)entry_unref, NULL); + g_slist_free (info->entries); + info->entries = NULL; + + if (info->entries_ht != NULL) + g_hash_table_destroy (info->entries_ht); + info->entries_ht = g_hash_table_new (g_str_hash, + g_str_equal); + + if ( ! vfolder_info_read_items (info, + result, context)) { + info->entries_valid = FALSE; + return NULL; + } + + invalidate_folder_T (info->root); + + info->entries_valid = TRUE; + + /* Update modification time of all folders, + * kind of evil, but it will make adding new items work + * I hope. This is because rereading usually means + * something changed */ + info->modification_time = time (NULL); + } + return info; + } + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if (infos == NULL) + infos = g_hash_table_new_full + (g_str_hash, g_str_equal, + (GDestroyNotify)g_free, + (GDestroyNotify)vfolder_info_destroy); + + info = g_new0 (VFolderInfo, 1); + vfolder_info_init (info, scheme); + + if (gnome_vfs_context_check_cancellation (context)) { + vfolder_info_destroy (info); + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if ( ! vfolder_info_read_info (info, result, context)) { + vfolder_info_destroy (info); + return NULL; + } + + if ( ! monitor_setup (info, + TRUE /* setup_filenames */, + TRUE /* setup_itemdirs */, + TRUE /* setup_desktop_dirs */, + result, context)) { + vfolder_info_destroy (info); + return NULL; + } + + g_hash_table_insert (infos, g_strdup (scheme), info); + + if ( ! vfolder_info_read_items (info, result, context)) { + info->entries_valid = FALSE; + return NULL; + } + info->entries_valid = TRUE; + + return info; +} + +static VFolderInfo * +get_vfolder_info (const char *scheme, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + VFolderInfo *info; + G_LOCK (vfolder_lock); + info = get_vfolder_info_unlocked (scheme, result, context); + G_UNLOCK (vfolder_lock); + return info; +} + + +static char * +keywords_to_string (GSList *keywords) +{ + GSList *li; + GString *str = g_string_new (NULL); + + for (li = keywords; li != NULL; li = li->next) { + GQuark word = GPOINTER_TO_INT (li->data); + g_string_append (str, g_quark_to_string (word)); + g_string_append_c (str, ';'); + } + + return g_string_free (str, FALSE); +} + +/* copy file and add keywords line */ +static gboolean +copy_file_with_keywords (const char *from, const char *to, GSList *keywords) +{ + FILE *fp; + FILE *wfp; + int wfd; + char buf[BUFSIZ]; + char *keyword_string; + + if ( ! ensure_dir (to, + TRUE /* ignore_basename */)) + return FALSE; + + wfd = open (to, O_CREAT | O_WRONLY | O_TRUNC, 0600); + if (wfd < 0) { + return FALSE; + } + + keyword_string = keywords_to_string (keywords); + + wfp = fdopen (wfd, "w"); + + fp = fopen (from, "r"); + if (fp != NULL) { + gboolean wrote_keywords = FALSE; + while (fgets (buf, sizeof (buf), fp) != NULL) { + fprintf (wfp, "%s", buf); + if ( ! wrote_keywords && + (strncmp (buf, "[Desktop Entry]", + strlen ("[Desktop Entry]")) == 0 || + strncmp (buf, "[KDE Desktop Entry]", + strlen ("[KDE Desktop Entry]")) == 0)) { + fprintf (wfp, "Categories=%s\n", + keyword_string); + wrote_keywords = TRUE; + } + } + + fclose (fp); + } else { + fprintf (wfp, "[Desktop Entry]\nCategories=%s\n", + keyword_string); + } + + /* FIXME: does this close wfd???? */ + fclose (wfp); + + close (wfd); + + g_free (keyword_string); + + return TRUE; +} + +static gboolean +copy_file (const char *from, const char *to) +{ + int fd; + int wfd; + + if ( ! ensure_dir (to, + TRUE /* ignore_basename */)) + return FALSE; + + wfd = open (to, O_CREAT | O_WRONLY | O_TRUNC, 0600); + if (wfd < 0) { + return FALSE; + } + + fd = open (from, O_RDONLY); + if (fd >= 0) { + char buf[1024]; + ssize_t n; + + while ((n = read (fd, buf, sizeof(buf))) > 0) { + write (wfd, buf, n); + } + + close (fd); + } + + close (wfd); + + return TRUE; +} + +static gboolean +make_file_private (VFolderInfo *info, EntryFile *efile) +{ + char *newfname; + Entry *entry = (Entry *)efile; + + if (efile->per_user) + return TRUE; + + /* this file already exists so whack its monitors */ + if (efile->filename != NULL) { + GSList *li; + + for (li = entry->monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + if (h->handle != NULL) + gnome_vfs_monitor_cancel (h->handle); + h->handle = NULL; + } + } + + newfname = g_build_filename (g_get_home_dir (), + DOT_GNOME, + "vfolders", + info->scheme, + efile->entry.name, + NULL); + + if (efile->implicit_keywords) { + if (efile->filename != NULL && + ! copy_file_with_keywords (efile->filename, + newfname, + efile->keywords)) { + /* FIXME: what to do with monitors here, they + * have already been whacked, a corner case + * not handled! */ + g_free (newfname); + return FALSE; + } + } else { + if (efile->filename != NULL && + ! copy_file (efile->filename, newfname)) { + /* FIXME: what to do with monitors here, they + * have already been whacked, a corner case + * not handled! */ + g_free (newfname); + return FALSE; + } + } + + /* we didn't copy but ensure path anyway */ + if (efile->filename == NULL && + ! ensure_dir (newfname, + TRUE /* ignore_basename */)) { + g_free (newfname); + return FALSE; + } + + /* this file already exists so re-add monitors at the new location */ + if (efile->filename != NULL) { + GSList *li; + char *uri = gnome_vfs_get_uri_from_local_path (newfname); + + for (li = entry->monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + + gnome_vfs_monitor_add (&(h->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + h); + } + + g_free (uri); + } + + g_free (efile->filename); + efile->filename = newfname; + efile->per_user = TRUE; + + return TRUE; +} + +static void +try_free_file_monitors_create_dirfile_unlocked (VFolderInfo *info, + Folder *folder) +{ + GSList *li, *list; + + list = g_slist_copy (info->free_file_monitors); + + for (li = list; li != NULL; li = li->next) { + FileMonitorHandle *handle = li->data; + Folder *f; + VFolderURI vuri; + GnomeVFSResult result; + + if ( ! handle->is_directory_file) + continue; + + /* Evil! EVIL URI PARSING. this will eat a lot of stack if we + * have lots of free monitors */ + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + f = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + + if (folder != f) + continue; + + info->free_file_monitors = + g_slist_remove (info->free_file_monitors, handle); + ((Entry *)folder)->monitors = + g_slist_prepend (((Entry *)folder)->monitors, handle); + + handle->exists = TRUE; + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *)handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_CREATED); + } + + g_slist_free (list); +} + +static void +make_new_dirfile (VFolderInfo *info, Folder *folder) +{ + char *name = g_strdup (folder->entry.name); + char *fname; + char *p; + int i; + int fd; + + for (p = name; *p != '\0'; p++) { + if ( ! ( (*p >= 'a' && *p <= 'z') || + (*p >= 'A' && *p <= 'Z') || + (*p >= '0' && *p <= '9') || + *p == '_')) { + *p = '_'; + } + } + + i = 0; + fname = NULL; + do { + char *fullname; + + g_free (fname); + + if (i > 0) { + fname = g_strdup_printf ("%s-%d.directory", name, i); + } else { + fname = g_strdup_printf ("%s.directory", name); + } + + fullname = g_build_filename + (info->user_desktop_dir, fname, NULL); + fd = open (fullname, O_CREAT | O_WRONLY | O_EXCL, 0600); + g_free (fullname); + } while (fd < 0); + + close (fd); + + folder->desktop_file = fname; + info->dirty = TRUE; + + try_free_file_monitors_create_dirfile_unlocked (info, folder); +} + +static gboolean +make_dirfile_private (VFolderInfo *info, Folder *folder) +{ + char *fname; + char *desktop_file; + GSList *li; + char *uri; + gboolean ret; + + if (info->user_desktop_dir == NULL) + return FALSE; + + if ( ! ensure_dir (info->user_desktop_dir, + FALSE /* ignore_basename */)) + return FALSE; + + + if (folder->desktop_file == NULL) { + make_new_dirfile (info, folder); + return TRUE; + } + + /* FIXME: this is broken! What if the desktop file exists + * in the local but there is a different (but with a same name) + * .directory in the system. */ + fname = g_build_filename (info->user_desktop_dir, + folder->desktop_file, + NULL); + + if (access (fname, F_OK) == 0) { + g_free (fname); + return TRUE; + } + + desktop_file = get_directory_file (info, folder); + + if (desktop_file == NULL) { + int fd = open (fname, O_CREAT | O_EXCL | O_WRONLY, 0600); + g_free (fname); + if (fd >= 0) { + close (fd); + return TRUE; + } + return FALSE; + } + + for (li = ((Entry *)folder)->monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + if (h->is_directory_file) { + if (h->handle != NULL) + gnome_vfs_monitor_cancel (h->handle); + h->handle = NULL; + } + } + + ret = TRUE; + + if ( ! copy_file (desktop_file, fname)) { + ret = FALSE; + g_free (fname); + fname = desktop_file; + desktop_file = NULL; + } + + uri = gnome_vfs_get_uri_from_local_path (fname); + + for (li = ((Entry *)folder)->monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + + if (h->is_directory_file) { + gnome_vfs_monitor_add (&(h->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + h); + } + } + + g_free (uri); + + g_free (desktop_file); + g_free (fname); + + return ret; +} + +static Folder * +resolve_folder (VFolderInfo *info, + const char *path, + gboolean ignore_basename, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + char **ppath; + int i; + Folder *folder = info->root; + + ppath = g_strsplit (path, "/", -1); + + if (ppath == NULL || + ppath[0] == NULL) { + g_strfreev (ppath); + *result = GNOME_VFS_ERROR_INVALID_URI; + return NULL; + } + + for (i = 0; ppath [i] != NULL; i++) { + const char *segment = ppath[i]; + + if (*segment == '\0') + continue; + + if (ignore_basename && ppath [i + 1] == NULL) + break; + else { + folder = (Folder *) find_entry (folder->subfolders, + segment); + if (folder == NULL) + break; + } + } + g_strfreev (ppath); + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if (folder == NULL) + *result = GNOME_VFS_ERROR_NOT_FOUND; + + return folder; +} + +static Entry * +resolve_path (VFolderInfo *info, + const char *path, + const char *basename, + Folder **return_folder, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + Entry *entry; + Folder *folder; + + if (strcmp (path, "/") == 0) + return (Entry *)info->root; + + folder = resolve_folder (info, path, + TRUE /* ignore_basename */, + result, context); + + if (return_folder != NULL) + *return_folder = folder; + + if (folder == NULL) { + return NULL; + } + + /* Make sure we have the entries here */ + ensure_folder_unlocked (info, folder, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + + entry = find_entry (folder->entries, basename); + + if (entry == NULL) + *result = GNOME_VFS_ERROR_NOT_FOUND; + + return entry; +} + +static Entry * +get_entry_unlocked (VFolderURI *vuri, + Folder **parent, + gboolean *is_directory_file, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + VFolderInfo *info; + Entry *entry; + + if (is_directory_file != NULL) + *is_directory_file = FALSE; + if (parent != NULL) + *parent = NULL; + + info = get_vfolder_info_unlocked (vuri->scheme, result, context); + if (info == NULL) + return NULL; + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if (vuri->is_all_scheme) { + GSList *efile_list; + + if (vuri->file == NULL) { + entry = resolve_path (info, + vuri->path, + vuri->file, + parent, + result, + context); + return entry; + } + + efile_list = g_hash_table_lookup (info->entries_ht, vuri->file); + + if (efile_list == NULL) { + *result = GNOME_VFS_ERROR_NOT_FOUND; + return NULL; + } else { + return efile_list->data; + } + } + + if (vuri->file != NULL && + check_ext (vuri->file, ".directory") == TRUE) { + Folder *folder; + + folder = resolve_folder (info, vuri->path, + TRUE /* ignore_basename */, + result, context); + if (folder == NULL) { + return NULL; + } + + if (is_directory_file != NULL) + *is_directory_file = TRUE; + + if (parent != NULL) + *parent = folder; + + return (Entry *)folder; + } else { + entry = resolve_path (info, vuri->path, vuri->file, parent, + result, context); + return entry; + } +} + +static Entry * +get_entry (VFolderURI *vuri, + Folder **parent, + gboolean *is_directory_file, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + Entry *entry; + + G_LOCK (vfolder_lock); + entry = get_entry_unlocked (vuri, + parent, + is_directory_file, + result, context); + G_UNLOCK (vfolder_lock); + + return entry; +} + +/* only works for files and only those that exist */ +/* unlocked function */ +static GnomeVFSURI * +desktop_uri_to_file_uri (VFolderInfo *info, + VFolderURI *desktop_vuri, + Entry **the_entry, + gboolean *the_is_directory_file, + Folder **the_folder, + gboolean privatize, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + gboolean is_directory_file; + GnomeVFSURI *ret_uri; + Folder *folder = NULL; + Entry *entry; + + entry = get_entry_unlocked (desktop_vuri, + &folder, + &is_directory_file, + result, + context); + if (entry == NULL) + return NULL; + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if (the_folder != NULL) + *the_folder = folder; + + if (the_entry != NULL) + *the_entry = entry; + if (the_is_directory_file != NULL) + *the_is_directory_file = is_directory_file; + + if (is_directory_file && + entry->type == ENTRY_FOLDER) { + char *desktop_file; + + folder = (Folder *)entry; + + if (the_folder != NULL) + *the_folder = folder; + + /* we'll be doing something write like */ + if (folder->read_only && + privatize) { + *result = GNOME_VFS_ERROR_READ_ONLY; + return NULL; + } + + if (privatize) { + char *fname; + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if ( ! make_dirfile_private (info, folder)) { + *result = GNOME_VFS_ERROR_GENERIC; + return NULL; + } + fname = g_build_filename (g_get_home_dir (), + folder->desktop_file, + NULL); + ret_uri = gnome_vfs_uri_new (fname); + g_free (fname); + return ret_uri; + } + + desktop_file = get_directory_file_unlocked (info, folder); + if (desktop_file != NULL) { + char *s = gnome_vfs_get_uri_from_local_path + (desktop_file); + + g_free (desktop_file); + + ret_uri = gnome_vfs_uri_new (s); + g_free (s); + + return ret_uri; + } else { + *result = GNOME_VFS_ERROR_NOT_FOUND; + return NULL; + } + } else if (entry->type == ENTRY_FILE) { + EntryFile *efile = (EntryFile *)entry; + char *s; + + /* we'll be doing something write like */ + if (folder != NULL && + folder->read_only && + privatize) { + *result = GNOME_VFS_ERROR_READ_ONLY; + return NULL; + } + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if (privatize && + ! make_file_private (info, efile)) { + *result = GNOME_VFS_ERROR_GENERIC; + return NULL; + } + + s = gnome_vfs_get_uri_from_local_path (efile->filename); + ret_uri = gnome_vfs_uri_new (s); + g_free (s); + + return ret_uri; + } else { + if (the_folder != NULL) + *the_folder = (Folder *)entry; + *result = GNOME_VFS_ERROR_IS_DIRECTORY; + return NULL; + } +} + +static void +remove_file (Folder *folder, const char *basename) +{ + GSList *li; + char *s; + + if (folder->includes_ht != NULL) { + li = g_hash_table_lookup (folder->includes_ht, basename); + if (li != NULL) { + char *name = li->data; + folder->includes = g_slist_delete_link + (folder->includes, li); + g_hash_table_remove (folder->includes_ht, basename); + g_free (name); + } + } + + if (folder->excludes == NULL) { + folder->excludes = g_hash_table_new_full + (g_str_hash, g_str_equal, + (GDestroyNotify)g_free, + NULL); + } + s = g_strdup (basename); + g_hash_table_replace (folder->excludes, s, s); +} + +static void +add_file (Folder *folder, const char *basename) +{ + GSList *li = NULL; + + if (folder->includes_ht != NULL) { + li = g_hash_table_lookup (folder->includes_ht, basename); + } + + /* if not found */ + if (li == NULL) { + char *str = g_strdup (basename); + folder->includes = + g_slist_prepend (folder->includes, str); + if (folder->includes_ht == NULL) { + folder->includes_ht = + g_hash_table_new_full (g_str_hash, + g_str_equal, + NULL, + NULL); + } + g_hash_table_replace (folder->includes_ht, + str, folder->includes); + } + if (folder->excludes != NULL) + g_hash_table_remove (folder->excludes, basename); +} + +typedef struct _FileHandle FileHandle; +struct _FileHandle { + VFolderInfo *info; + GnomeVFSMethodHandle *handle; + Entry *entry; + gboolean write; + gboolean is_directory_file; +}; + +static void +make_handle (GnomeVFSMethodHandle **method_handle, + GnomeVFSMethodHandle *file_handle, + VFolderInfo *info, + Entry *entry, + gboolean is_directory_file, + gboolean write) +{ + if (file_handle != NULL) { + FileHandle *handle = g_new0 (FileHandle, 1); + + handle->info = info; + handle->handle = file_handle; + handle->entry = entry_ref (entry); + handle->is_directory_file = is_directory_file; + handle->write = write; + + *method_handle = (GnomeVFSMethodHandle *) handle; + } else { + *method_handle = NULL; + } +} + +static void +whack_handle (FileHandle *handle) +{ + entry_unref (handle->entry); + handle->entry = NULL; + + handle->handle = NULL; + handle->info = NULL; + + g_free (handle); +} + +static GnomeVFSResult +do_open (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result = GNOME_VFS_OK; + VFolderInfo *info; + Entry *entry; + gboolean is_directory_file; + GnomeVFSMethodHandle *file_handle = NULL; + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + /* These can't be very nice FILE names */ + if (vuri.file == NULL || + vuri.ends_in_slash) + return GNOME_VFS_ERROR_INVALID_URI; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (mode & GNOME_VFS_OPEN_WRITE && + (info->read_only || vuri.is_all_scheme)) + return GNOME_VFS_ERROR_READ_ONLY; + + G_LOCK (vfolder_lock); + file_uri = desktop_uri_to_file_uri (info, + &vuri, + &entry, + &is_directory_file, + NULL /* the_folder */, + mode & GNOME_VFS_OPEN_WRITE, + &result, + context); + + if (file_uri == NULL) { + G_UNLOCK (vfolder_lock); + return result; + } + + result = (* parent_method->open) (parent_method, + &file_handle, + file_uri, + mode, + context); + + if (result == GNOME_VFS_ERROR_CANCELLED) { + G_UNLOCK (vfolder_lock); + gnome_vfs_uri_unref (file_uri); + return result; + } + + make_handle (method_handle, + file_handle, + info, + entry, + is_directory_file, + mode & GNOME_VFS_OPEN_WRITE); + + gnome_vfs_uri_unref (file_uri); + + if (info->dirty) { + vfolder_info_write_user (info); + } + + G_UNLOCK (vfolder_lock); + + return result; +} + +static void +remove_from_all_except (Folder *root, + const char *name, + Folder *except) +{ + GSList *li; + + if (root != except) { + remove_file (root, name); + if (root->up_to_date) { + for (li = root->entries; li != NULL; li = li->next) { + Entry *entry = li->data; + if (strcmp (name, entry->name) == 0) { + root->entries = + g_slist_delete_link + (root->entries, li); + break; + } + } + } + } + + for (li = root->subfolders; li != NULL; li = li->next) { + Folder *subfolder = li->data; + + remove_from_all_except (subfolder, name, except); + } +} + +static GnomeVFSResult +do_create (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + gboolean exclusive, + guint perm, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + GnomeVFSMethodHandle *file_handle; + GnomeVFSURI *file_uri; + VFolderURI vuri; + VFolderInfo *info; + Folder *parent; + Entry *entry; + EntryFile *efile; + char *s; + GSList *li; + + VFOLDER_URI_PARSE (uri, &vuri); + + /* These can't be very nice FILE names */ + if (vuri.file == NULL || + vuri.ends_in_slash) + return GNOME_VFS_ERROR_INVALID_URI; + + if ( ! check_ext (vuri.file, ".desktop") && + ! strcmp (vuri.file, ".directory") == 0) { + return GNOME_VFS_ERROR_INVALID_URI; + } + + /* all scheme is read only */ + if (vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (info->user_filename == NULL || + info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + parent = resolve_folder (info, vuri.path, + TRUE /* ignore_basename */, + &result, context); + if (parent == NULL) + return result; + + if (parent->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + if (strcmp (vuri.file, ".directory") == 0) { + char *fname; + + G_LOCK (vfolder_lock); + + if (exclusive) { + char *desktop_file; + desktop_file = get_directory_file_unlocked (info, parent); + if (desktop_file != NULL) { + g_free (desktop_file); + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_FILE_EXISTS; + } + } + + if ( ! make_dirfile_private (info, parent)) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_GENERIC; + } + fname = g_build_filename (g_get_home_dir (), + parent->desktop_file, + NULL); + s = gnome_vfs_get_uri_from_local_path (fname); + file_uri = gnome_vfs_uri_new (s); + g_free (fname); + g_free (s); + + if (file_uri == NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_GENERIC; + } + + result = (* parent_method->create) (parent_method, + &file_handle, + file_uri, + mode, + exclusive, + perm, + context); + gnome_vfs_uri_unref (file_uri); + + make_handle (method_handle, + file_handle, + info, + (Entry *)parent, + TRUE /* is_directory_file */, + TRUE /* write */); + + if (info->dirty) + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return result; + } + + ensure_folder (info, parent, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + + entry = find_entry (parent->entries, vuri.file); + + if (entry != NULL && + entry->type == ENTRY_FOLDER) + return GNOME_VFS_ERROR_IS_DIRECTORY; + + efile = (EntryFile *)entry; + + if (efile != NULL) { + if (exclusive) + return GNOME_VFS_ERROR_FILE_EXISTS; + + G_LOCK (vfolder_lock); + if ( ! make_file_private (info, efile)) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_GENERIC; + } + + s = gnome_vfs_get_uri_from_local_path (efile->filename); + file_uri = gnome_vfs_uri_new (s); + g_free (s); + + if (file_uri == NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_GENERIC; + } + + result = (* parent_method->create) (parent_method, + &file_handle, + file_uri, + mode, + exclusive, + perm, + context); + gnome_vfs_uri_unref (file_uri); + + make_handle (method_handle, + file_handle, + info, + (Entry *)efile, + FALSE /* is_directory_file */, + TRUE /* write */); + + G_UNLOCK (vfolder_lock); + + return result; + } + + G_LOCK (vfolder_lock); + + li = g_hash_table_lookup (info->entries_ht, vuri.file); + + if (exclusive && li != NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_FILE_EXISTS; + } + + if (li == NULL) { + efile = file_new (vuri.file); + vfolder_info_insert_entry (info, efile); + entry_unref ((Entry *)efile); + } else { + efile = li->data; + } + + /* this will make a private name for this */ + if ( ! make_file_private (info, efile)) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_GENERIC; + } + + add_file (parent, vuri.file); + parent->sorted = FALSE; + + if (parent->up_to_date) + parent->entries = g_slist_prepend (parent->entries, efile); + + /* if we created a brand new name, then we exclude it + * from everywhere else to ensure overall sanity */ + if (li == NULL) + remove_from_all_except (info->root, vuri.file, parent); + + s = gnome_vfs_get_uri_from_local_path (efile->filename); + file_uri = gnome_vfs_uri_new (s); + g_free (s); + + result = (* parent_method->create) (parent_method, + &file_handle, + file_uri, + mode, + exclusive, + perm, + context); + gnome_vfs_uri_unref (file_uri); + + make_handle (method_handle, + file_handle, + info, + (Entry *)efile, + FALSE /* is_directory_file */, + TRUE /* write */); + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return result; +} + +static GnomeVFSResult +do_close (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + if (method_handle == (GnomeVFSMethodHandle *)method) + return GNOME_VFS_OK; + + G_LOCK (vfolder_lock); + + result = (* parent_method->close) (parent_method, + handle->handle, + context); + handle->handle = NULL; + + /* we reread the Categories keyword */ + if (handle->write && + handle->entry != NULL && + handle->entry->type == ENTRY_FILE) { + EntryFile *efile = (EntryFile *)handle->entry; + char *categories; + readitem_entry (efile->filename, + "Categories", + &categories, + NULL, + NULL); + set_keywords (efile, categories); + g_free (categories); + /* FIXME: what about OnlyShowIn */ + + /* FIXME: check if the keywords changed, if not, do + * nothing */ + + /* Perhaps a bit drastic */ + /* also this emits the CHANGED monitor signal */ + invalidate_folder_T (handle->info->root); + + /* the file changed monitor will happen by itself + * as the underlying file is changed */ + } else if (handle->write && + handle->entry != NULL && + handle->entry->type == ENTRY_FOLDER && + handle->is_directory_file) { + /* if we're monitoring this directory, emit the CHANGED + * monitor thing, it will also emit a changed on + * the file itself. It is better to emit changed + * just in case. */ + emit_monitor ((Folder *)(handle->entry), + GNOME_VFS_MONITOR_EVENT_CHANGED); + } + + whack_handle (handle); + + G_UNLOCK (vfolder_lock); + + return result; +} + +static void +fill_buffer (gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read) +{ + char *buf = buffer; + GnomeVFSFileSize i; + for (i = 0; i < num_bytes; i++) { + if (rand () % 32 == 0 || + i == num_bytes-1) + buf[i] = '\n'; + else + buf[i] = ((rand()>>4) % 94) + 32; + } + if (bytes_read != 0) + *bytes_read = i; +} + +static GnomeVFSResult +do_read (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + if (method_handle == (GnomeVFSMethodHandle *)method) { + if ((rand () >> 4) & 0x3) { + fill_buffer (buffer, num_bytes, bytes_read); + return GNOME_VFS_OK; + } else { + return GNOME_VFS_ERROR_EOF; + } + } + + result = (* parent_method->read) (parent_method, + handle->handle, + buffer, num_bytes, + bytes_read, + context); + + return result; +} + +static GnomeVFSResult +do_write (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gconstpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_written, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + if (method_handle == (GnomeVFSMethodHandle *)method) + return GNOME_VFS_OK; + + result = (* parent_method->write) (parent_method, + handle->handle, + buffer, num_bytes, + bytes_written, + context); + + return result; +} + + +static GnomeVFSResult +do_seek (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSSeekPosition whence, + GnomeVFSFileOffset offset, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + if (method_handle == (GnomeVFSMethodHandle *)method) + return GNOME_VFS_OK; + + result = (* parent_method->seek) (parent_method, + handle->handle, + whence, offset, + context); + + return result; +} + +static GnomeVFSResult +do_tell (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileOffset *offset_return) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + result = (* parent_method->tell) (parent_method, + handle->handle, + offset_return); + + return result; +} + + +static GnomeVFSResult +do_truncate_handle (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileSize where, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + if (method_handle == (GnomeVFSMethodHandle *)method) + return GNOME_VFS_OK; + + result = (* parent_method->truncate_handle) (parent_method, + handle->handle, + where, + context); + + return result; +} + +static GnomeVFSResult +do_truncate (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileSize where, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result = GNOME_VFS_OK; + VFolderInfo *info; + Entry *entry; + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + /* These can't be very nice FILE names */ + if (vuri.file == NULL || + vuri.ends_in_slash) + return GNOME_VFS_ERROR_INVALID_URI; + + if (vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + G_LOCK (vfolder_lock); + file_uri = desktop_uri_to_file_uri (info, + &vuri, + &entry, + NULL /* the_is_directory_file */, + NULL /* the_folder */, + TRUE /* privatize */, + &result, + context); + G_UNLOCK (vfolder_lock); + + if (file_uri == NULL) + return result; + + result = (* parent_method->truncate) (parent_method, + file_uri, + where, + context); + + gnome_vfs_uri_unref (file_uri); + + if (info->dirty) { + G_LOCK (vfolder_lock); + vfolder_info_write_user (info); + G_UNLOCK (vfolder_lock); + } + + if (entry->type == ENTRY_FILE) { + EntryFile *efile = (EntryFile *)entry; + + G_LOCK (vfolder_lock); + g_slist_free (efile->keywords); + efile->keywords = NULL; + G_UNLOCK (vfolder_lock); + } + + /* Perhaps a bit drastic, but oh well */ + invalidate_folder (info->root); + + return result; +} + +typedef struct _DirHandle DirHandle; +struct _DirHandle { + VFolderInfo *info; + Folder *folder; + + GnomeVFSFileInfoOptions options; + + /* List of Entries */ + GSList *list; + GSList *current; +}; + +static GnomeVFSResult +do_open_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + VFolderURI vuri; + DirHandle *dh; + Folder *folder; + VFolderInfo *info; + char *desktop_file; + + VFOLDER_URI_PARSE (uri, &vuri); + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + /* In the all- scheme just list all filenames */ + if (vuri.is_all_scheme) { + if (any_subdir (vuri.path)) + return GNOME_VFS_ERROR_NOT_FOUND; + + dh = g_new0 (DirHandle, 1); + dh->info = info; + dh->options = options; + dh->folder = NULL; + + G_LOCK (vfolder_lock); + dh->list = g_slist_copy (info->entries); + g_slist_foreach (dh->list, (GFunc)entry_ref, NULL); + dh->current = dh->list; + G_UNLOCK (vfolder_lock); + + *method_handle = (GnomeVFSMethodHandle*) dh; + return GNOME_VFS_OK; + } + + folder = resolve_folder (info, vuri.path, + FALSE /* ignore_basename */, + &result, context); + if (folder == NULL) + return result; + + /* Make sure we have the entries and sorted here */ + ensure_folder_sort (info, folder); + + dh = g_new0 (DirHandle, 1); + dh->info = info; + dh->options = options; + + G_LOCK (vfolder_lock); + dh->folder = (Folder *)entry_ref ((Entry *)folder); + dh->list = g_slist_copy (folder->entries); + g_slist_foreach (folder->entries, (GFunc)entry_ref, NULL); + G_UNLOCK (vfolder_lock); + + desktop_file = get_directory_file (info, folder); + if (desktop_file != NULL) { + EntryFile *efile = file_new (".directory"); + dh->list = g_slist_prepend (dh->list, efile); + g_free (desktop_file); + } + + dh->current = dh->list; + + *method_handle = (GnomeVFSMethodHandle*) dh; + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_close_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + DirHandle *dh; + + dh = (DirHandle*) method_handle; + + G_LOCK (vfolder_lock); + + g_slist_foreach (dh->list, (GFunc)entry_unref, NULL); + g_slist_free (dh->list); + dh->list = NULL; + + dh->current = NULL; + + if (dh->folder != NULL) + entry_unref ((Entry *)dh->folder); + dh->folder = NULL; + + dh->info = NULL; + + g_free (dh); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_read_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSContext *context) +{ + DirHandle *dh; + Entry *entry; + GnomeVFSFileInfoOptions options; + + dh = (DirHandle*) method_handle; + +read_directory_again: + + if (dh->current == NULL) { + return GNOME_VFS_ERROR_EOF; + } + + entry = dh->current->data; + dh->current = dh->current->next; + + options = dh->options; + + if (entry->type == ENTRY_FILE && + ((EntryFile *)entry)->filename != NULL) { + EntryFile *efile = (EntryFile *)entry; + char *furi = gnome_vfs_get_uri_from_local_path (efile->filename); + GnomeVFSURI *uri = gnome_vfs_uri_new (furi); + + /* we always get mime-type by forcing it below */ + if (options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE) + options &= ~GNOME_VFS_FILE_INFO_GET_MIME_TYPE; + + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_NONE; + + /* Get the file info for this */ + (* parent_method->get_file_info) (parent_method, + uri, + file_info, + options, + context); + + /* we ignore errors from this since the file_info just + * won't be filled completely if there's an error, that's all */ + + g_free (file_info->mime_type); + file_info->mime_type = g_strdup ("application/x-gnome-app-info"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + /* Now we wipe those fields we don't support */ + file_info->valid_fields &= ~(UNSUPPORTED_INFO_FIELDS); + + gnome_vfs_uri_unref (uri); + g_free (furi); + } else if (entry->type == ENTRY_FILE) { + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_NONE; + + file_info->name = g_strdup (entry->name); + GNOME_VFS_FILE_INFO_SET_LOCAL (file_info, TRUE); + + file_info->type = GNOME_VFS_FILE_TYPE_REGULAR; + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_TYPE; + + /* FIXME: Is this correct? isn't there an xdg mime type? */ + file_info->mime_type = g_strdup ("application/x-gnome-app-info"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + /* FIXME: get some ctime/mtime */ + } else /* ENTRY_FOLDER */ { + Folder *folder = (Folder *)entry; + + /* Skip empty folders if they have + * the flag set */ + if (folder->dont_show_if_empty) { + /* Make sure we have the entries */ + ensure_folder (dh->info, folder, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + + if (folder->entries == NULL) { + /* start this function over on the + * next item */ + goto read_directory_again; + } + } + + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_NONE; + + file_info->name = g_strdup (entry->name); + GNOME_VFS_FILE_INFO_SET_LOCAL (file_info, TRUE); + + file_info->type = GNOME_VFS_FILE_TYPE_DIRECTORY; + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_TYPE; + + file_info->mime_type = g_strdup ("x-directory/vfolder-desktop"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + file_info->ctime = dh->info->modification_time; + file_info->mtime = dh->info->modification_time; + file_info->valid_fields |= (GNOME_VFS_FILE_INFO_FIELDS_CTIME | + GNOME_VFS_FILE_INFO_FIELDS_MTIME); + } + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_get_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result = GNOME_VFS_OK; + Folder *folder; + VFolderInfo *info; + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + G_LOCK (vfolder_lock); + file_uri = desktop_uri_to_file_uri (info, + &vuri, + NULL /* the_entry */, + NULL /* the_is_directory_file */, + &folder, + FALSE /* privatize */, + &result, + context); + G_UNLOCK (vfolder_lock); + + if (file_uri == NULL && + result != GNOME_VFS_ERROR_IS_DIRECTORY) + return result; + + if (file_uri != NULL) { + /* we always get mime-type by forcing it below */ + if (options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE) + options &= ~GNOME_VFS_FILE_INFO_GET_MIME_TYPE; + + result = (* parent_method->get_file_info) (parent_method, + file_uri, + file_info, + options, + context); + + g_free (file_info->mime_type); + file_info->mime_type = g_strdup ("application/x-gnome-app-info"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + /* Now we wipe those fields we don't support */ + file_info->valid_fields &= ~(UNSUPPORTED_INFO_FIELDS); + + gnome_vfs_uri_unref (file_uri); + + return result; + } else if (folder != NULL) { + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_NONE; + + file_info->name = g_strdup (folder->entry.name); + GNOME_VFS_FILE_INFO_SET_LOCAL (file_info, TRUE); + + file_info->type = GNOME_VFS_FILE_TYPE_DIRECTORY; + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_TYPE; + + file_info->mime_type = g_strdup ("x-directory/vfolder-desktop"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + file_info->ctime = info->modification_time; + file_info->mtime = info->modification_time; + file_info->valid_fields |= (GNOME_VFS_FILE_INFO_FIELDS_CTIME | + GNOME_VFS_FILE_INFO_FIELDS_MTIME); + + return GNOME_VFS_OK; + } else { + return GNOME_VFS_ERROR_NOT_FOUND; + } +} + +static GnomeVFSResult +do_get_file_info_from_handle (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + if (method_handle == (GnomeVFSMethodHandle *)method) { + g_free (file_info->mime_type); + file_info->mime_type = g_strdup ("text/plain"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + return GNOME_VFS_OK; + } + + /* we always get mime-type by forcing it below */ + if (options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE) + options &= ~GNOME_VFS_FILE_INFO_GET_MIME_TYPE; + + result = (* parent_method->get_file_info_from_handle) (parent_method, + handle->handle, + file_info, + options, + context); + + /* any file is of the .desktop type */ + g_free (file_info->mime_type); + file_info->mime_type = g_strdup ("application/x-gnome-app-info"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + /* Now we wipe those fields we don't support */ + file_info->valid_fields &= ~(UNSUPPORTED_INFO_FIELDS); + + return result; +} + + +static gboolean +do_is_local (GnomeVFSMethod *method, + const GnomeVFSURI *uri) +{ + return TRUE; +} + +static void +try_free_folder_monitors_create_unlocked (VFolderInfo *info, + Folder *folder) +{ + GSList *li, *list; + + list = g_slist_copy (info->free_folder_monitors); + + for (li = list; li != NULL; li = li->next) { + FileMonitorHandle *handle = li->data; + Folder *f; + VFolderURI vuri; + GnomeVFSResult result; + + /* Evil! EVIL URI PARSING. this will eat a lot of stack if we + * have lots of free monitors */ + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + f = resolve_folder (info, + vuri.path, + FALSE /* ignore_basename */, + &result, + NULL); + + if (folder != f) + continue; + + info->free_folder_monitors = + g_slist_remove (info->free_folder_monitors, handle); + ((Entry *)folder)->monitors = + g_slist_prepend (((Entry *)folder)->monitors, handle); + + handle->exists = TRUE; + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *)handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_CREATED); + } +} + + +static GnomeVFSResult +do_make_directory (GnomeVFSMethod *method, + GnomeVFSURI *uri, + guint perm, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + VFolderInfo *info; + Folder *parent, *folder; + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + if (vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (info->user_filename == NULL || + info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + parent = resolve_folder (info, vuri.path, + TRUE /* ignore_basename */, + &result, context); + if (parent == NULL) + return result; + else if (parent->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + G_LOCK (vfolder_lock); + + folder = (Folder *)find_entry (parent->subfolders, + vuri.file); + if (folder != NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_FILE_EXISTS; + } + + folder = folder_new (vuri.file); + parent->subfolders = g_slist_append (parent->subfolders, folder); + folder->parent = parent; + parent->up_to_date = FALSE; + + try_free_folder_monitors_create_unlocked (info, folder); + + /* parent changed */ + emit_monitor (parent, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_remove_directory (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + Folder *folder; + VFolderInfo *info; + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + if (vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (info->user_filename == NULL || + info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + G_LOCK (vfolder_lock); + + folder = resolve_folder (info, vuri.path, + FALSE /* ignore_basename */, + &result, context); + if (folder == NULL) { + G_UNLOCK (vfolder_lock); + return result; + } + + if (folder->read_only || + (folder->parent != NULL && + folder->parent->read_only)) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_READ_ONLY; + } + + /* don't make removing directories easy */ + if (folder->desktop_file != NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY; + } + + /* Make sure we have the entries */ + ensure_folder_unlocked (info, folder, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + + /* don't make removing directories easy */ + if (folder->entries != NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY; + } + + emit_and_delete_monitor (info, folder); + + if (folder->only_unallocated) { + GSList *li = g_slist_find (info->unallocated_folders, + folder); + if (li != NULL) { + info->unallocated_folders = g_slist_delete_link + (info->unallocated_folders, li); + entry_unref ((Entry *)folder); + } + } + + if (folder == info->root) { + info->root = NULL; + entry_unref ((Entry *)folder); + info->root = folder_new ("Root"); + } else { + Folder *parent = folder->parent; + + g_assert (parent != NULL); + + parent->subfolders = + g_slist_remove (parent->subfolders, folder); + + parent->up_to_date = FALSE; + + entry_unref ((Entry *)folder); + + /* parent changed */ + emit_monitor (parent, GNOME_VFS_MONITOR_EVENT_CHANGED); + } + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; +} + +/* a fairly evil function that does the whole move bit by copy and + * remove */ +static GnomeVFSResult +long_move (GnomeVFSMethod *method, + VFolderURI *old_vuri, + VFolderURI *new_vuri, + gboolean force_replace, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + GnomeVFSMethodHandle *handle; + GnomeVFSURI *file_uri; + const char *path; + int fd; + char buf[BUFSIZ]; + int bytes; + VFolderInfo *info; + + info = get_vfolder_info (old_vuri->scheme, &result, context); + if (info == NULL) + return result; + + G_LOCK (vfolder_lock); + file_uri = desktop_uri_to_file_uri (info, + old_vuri, + NULL /* the_entry */, + NULL /* the_is_directory_file */, + NULL /* the_folder */, + FALSE /* privatize */, + &result, + context); + G_UNLOCK (vfolder_lock); + + if (file_uri == NULL) + return result; + + path = gnome_vfs_uri_get_path (file_uri); + if (path == NULL) { + gnome_vfs_uri_unref (file_uri); + return GNOME_VFS_ERROR_INVALID_URI; + } + + fd = open (path, O_RDONLY); + if (fd < 0) { + gnome_vfs_uri_unref (file_uri); + return gnome_vfs_result_from_errno (); + } + + gnome_vfs_uri_unref (file_uri); + + info->inhibit_write++; + + result = method->create (method, + &handle, + new_vuri->uri, + GNOME_VFS_OPEN_WRITE, + force_replace /* exclusive */, + 0600 /* perm */, + context); + if (result != GNOME_VFS_OK) { + close (fd); + info->inhibit_write--; + return result; + } + + while ((bytes = read (fd, buf, BUFSIZ)) > 0) { + GnomeVFSFileSize bytes_written = 0; + result = method->write (method, + handle, + buf, + bytes, + &bytes_written, + context); + if (result == GNOME_VFS_OK && + bytes_written != bytes) + result = GNOME_VFS_ERROR_NO_SPACE; + if (result != GNOME_VFS_OK) { + close (fd); + method->close (method, handle, context); + /* FIXME: is this completely correct ? */ + method->unlink (method, + new_vuri->uri, + context); + G_LOCK (vfolder_lock); + info->inhibit_write--; + vfolder_info_write_user (info); + G_UNLOCK (vfolder_lock); + return result; + } + } + + close (fd); + + result = method->close (method, handle, context); + if (result != GNOME_VFS_OK) { + G_LOCK (vfolder_lock); + info->inhibit_write--; + vfolder_info_write_user (info); + G_UNLOCK (vfolder_lock); + return result; + } + + result = method->unlink (method, old_vuri->uri, context); + + G_LOCK (vfolder_lock); + info->inhibit_write--; + vfolder_info_write_user (info); + G_UNLOCK (vfolder_lock); + + return result; +} + +static GnomeVFSResult +move_directory_file (VFolderInfo *info, + Folder *old_folder, + Folder *new_folder) +{ + if (old_folder->desktop_file == NULL) + return GNOME_VFS_ERROR_NOT_FOUND; + + /* "move" the desktop file */ + g_free (new_folder->desktop_file); + new_folder->desktop_file = old_folder->desktop_file; + old_folder->desktop_file = NULL; + + /* is this too drastic, it will requery the folder? */ + new_folder->up_to_date = FALSE; + old_folder->up_to_date = FALSE; + + emit_monitor (new_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + emit_monitor (old_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + + return GNOME_VFS_OK; +} + +static gboolean +is_sub (Folder *master, Folder *sub) +{ + GSList *li; + + for (li = master->subfolders; li != NULL; li = li->next) { + Folder *subfolder = li->data; + + if (subfolder == sub || + is_sub (subfolder, sub)) + return TRUE; + } + + return FALSE; +} + +static GnomeVFSResult +move_folder (VFolderInfo *info, + Folder *old_folder, Entry *old_entry, + Folder *new_folder, Entry *new_entry) +{ + Folder *source = (Folder *)old_entry; + Folder *target; + + if (new_entry != NULL && + new_entry->type != ENTRY_FOLDER) + return GNOME_VFS_ERROR_NOT_A_DIRECTORY; + + if (new_entry != NULL) { + target = (Folder *)new_entry; + } else { + target = new_folder; + } + + /* move to where we are, yay, we're done :) */ + if (source->parent == target) + return GNOME_VFS_OK; + + if (source == target || + is_sub (source, target)) + return GNOME_VFS_ERROR_LOOP; + + /* this will never happen, but we're paranoid */ + if (source->parent == NULL) + return GNOME_VFS_ERROR_LOOP; + + source->parent->subfolders = g_slist_remove (source->parent->subfolders, + source); + target->subfolders = g_slist_append (target->subfolders, + source); + + source->parent = target; + + source->up_to_date = FALSE; + target->up_to_date = FALSE; + + emit_monitor (source, GNOME_VFS_MONITOR_EVENT_CHANGED); + emit_monitor (target, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_move (GnomeVFSMethod *method, + GnomeVFSURI *old_uri, + GnomeVFSURI *new_uri, + gboolean force_replace, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + VFolderInfo *info; + Folder *old_folder, *new_folder; + Entry *old_entry, *new_entry; + gboolean old_is_directory_file, new_is_directory_file; + VFolderURI old_vuri, new_vuri; + + VFOLDER_URI_PARSE (old_uri, &old_vuri); + VFOLDER_URI_PARSE (new_uri, &new_vuri); + + if (old_vuri.file == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + if (old_vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + if (strcmp (old_vuri.scheme, new_vuri.scheme) != 0) + return GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM; + + info = get_vfolder_info (old_vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + old_entry = get_entry (&old_vuri, + &old_folder, + &old_is_directory_file, + &result, + context); + if (old_entry == NULL) + return result; + + if (old_folder != NULL && old_folder->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + new_entry = get_entry (&new_vuri, + &new_folder, + &new_is_directory_file, + &result, + context); + if (new_entry == NULL && new_folder == NULL) + return result; + + if (new_folder != NULL && new_folder->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + if (new_is_directory_file != old_is_directory_file) { + /* this will do another set of lookups + * perhaps this can be done in a nicer way, + * but is this the common case? I don't think so */ + return long_move (method, &old_vuri, &new_vuri, + force_replace, context); + } + + if (new_is_directory_file) { + g_assert (old_entry != NULL); + g_assert (new_entry != NULL); + G_LOCK (vfolder_lock); + result = move_directory_file (info, + (Folder *)old_entry, + (Folder *)new_entry); + G_UNLOCK (vfolder_lock); + return result; + } + + if (old_entry->type == ENTRY_FOLDER) { + G_LOCK (vfolder_lock); + result = move_folder (info, + old_folder, old_entry, + new_folder, new_entry); + G_UNLOCK (vfolder_lock); + return result; + } + + /* move into self, just whack the old one */ + if (old_entry == new_entry) { + /* same folder */ + if (new_folder == old_folder) + return GNOME_VFS_OK; + + if ( ! force_replace) + return GNOME_VFS_ERROR_FILE_EXISTS; + + G_LOCK (vfolder_lock); + + remove_file (old_folder, old_vuri.file); + + old_folder->entries = g_slist_remove (old_folder->entries, + old_entry); + entry_unref (old_entry); + + emit_monitor (old_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; + } + + /* this is a simple move */ + if (new_entry == NULL || + new_entry->type == ENTRY_FOLDER) { + if (new_entry != NULL) { + new_folder = (Folder *)new_entry; + } else { + /* a file and a totally different one */ + if (strcmp (new_vuri.file, old_entry->name) != 0) { + /* yay, a long move */ + /* this will do another set of lookups + * perhaps this can be done in a nicer way, + * but is this the common case? I don't think + * so */ + return long_move (method, &old_vuri, &new_vuri, + force_replace, context); + } + } + + /* same folder */ + if (new_folder == old_folder) + return GNOME_VFS_OK; + + G_LOCK (vfolder_lock); + + remove_file (old_folder, old_entry->name); + add_file (new_folder, old_entry->name); + + new_folder->entries = g_slist_prepend (new_folder->entries, + old_entry); + entry_ref (old_entry); + new_folder->sorted = FALSE; + + old_folder->entries = g_slist_remove (old_folder->entries, + old_entry); + entry_unref (old_entry); + + emit_monitor (new_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + emit_monitor (old_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; + } + + /* do we EVER get here? */ + + /* this will do another set of lookups + * perhaps this can be done in a nicer way, + * but is this the common case? I don't think so */ + return long_move (method, &old_vuri, &new_vuri, + force_replace, context); +} + +static GnomeVFSResult +do_unlink (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + Entry *entry; + Folder *the_folder; + gboolean is_directory_file; + VFolderInfo *info; + VFolderURI vuri; + GSList *li; + + VFOLDER_URI_PARSE (uri, &vuri); + + if (vuri.file == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + if (vuri.is_all_scheme == TRUE) + return GNOME_VFS_ERROR_READ_ONLY; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + else if (info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + entry = get_entry (&vuri, + &the_folder, + &is_directory_file, + &result, context); + if (entry == NULL) + return result; + else if (the_folder != NULL && + the_folder->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + if (entry->type == ENTRY_FOLDER && + is_directory_file) { + Folder *folder = (Folder *)entry; + + if (folder->desktop_file == NULL) + return GNOME_VFS_ERROR_NOT_FOUND; + + G_LOCK (vfolder_lock); + + g_free (folder->desktop_file); + folder->desktop_file = NULL; + + emit_monitor (folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; + } else if (entry->type == ENTRY_FOLDER) { + return GNOME_VFS_ERROR_IS_DIRECTORY; + } else if (the_folder == NULL) { + return GNOME_VFS_ERROR_NOT_FOUND; + } + + G_LOCK (vfolder_lock); + + the_folder->entries = g_slist_remove (the_folder->entries, + entry); + entry_unref (entry); + + remove_file (the_folder, vuri.file); + + emit_monitor (the_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + + /* evil, we must remove this from the unallocated folders as well + * so that it magically doesn't appear there. But it's not so simple. + * We only want to remove it if it isn't in that folder already. */ + for (li = info->unallocated_folders; + li != NULL; + li = li->next) { + Folder *folder = li->data; + GSList *l; + + /* This is actually really evil since ensuring + * an unallocated folder clears all other unallocated + * folders in it's wake. I'm not sure it's worth + * optimizing however */ + ensure_folder_unlocked (info, folder, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + l = g_slist_find (folder->entries, entry); + if (l == NULL) { + remove_file (folder, vuri.file); + } + } + + emit_file_deleted_monitor (info, entry, the_folder); + + /* FIXME: if this was a user file and this is the only + * reference to it, unlink it. */ + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_check_same_fs (GnomeVFSMethod *method, + GnomeVFSURI *source_uri, + GnomeVFSURI *target_uri, + gboolean *same_fs_return, + GnomeVFSContext *context) +{ + VFolderURI source_vuri, target_vuri; + + *same_fs_return = FALSE; + + VFOLDER_URI_PARSE (source_uri, &source_vuri); + VFOLDER_URI_PARSE (target_uri, &target_vuri); + + if (strcmp (source_vuri.scheme, target_vuri.scheme) != 0 || + source_vuri.is_all_scheme != target_vuri.is_all_scheme) + *same_fs_return = FALSE; + else + *same_fs_return = TRUE; + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_set_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + const GnomeVFSFileInfo *info, + GnomeVFSSetFileInfoMask mask, + GnomeVFSContext *context) +{ + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + if (vuri.file == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + if (mask & GNOME_VFS_SET_FILE_INFO_NAME) { + GnomeVFSResult result = GNOME_VFS_OK; + char *dirname = gnome_vfs_uri_extract_dirname (uri); + GnomeVFSURI *new_uri = gnome_vfs_uri_dup (uri); + + G_LOCK (vfolder_lock); + g_free (new_uri->text); + new_uri->text = g_build_path ("/", dirname, info->name, NULL); + G_UNLOCK (vfolder_lock); + + result = do_move (method, + uri, + new_uri, + FALSE /* force_replace */, + context); + + g_free (dirname); + gnome_vfs_uri_unref (new_uri); + return result; + } else { + /* We don't support setting any of this other permission, + * times and all that voodoo */ + return GNOME_VFS_ERROR_NOT_SUPPORTED; + } +} + +static GnomeVFSResult +do_monitor_add (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle_return, + GnomeVFSURI *uri, + GnomeVFSMonitorType monitor_type) +{ + VFolderInfo *info; + VFolderURI vuri; + GnomeVFSResult result; + Folder *folder; + Entry *entry; + GnomeVFSURI *file_uri; + FileMonitorHandle *handle; + gboolean is_directory_file; + + VFOLDER_URI_PARSE (uri, &vuri); + + info = get_vfolder_info (vuri.scheme, &result, NULL); + if (info == NULL) + return result; + + if (monitor_type == GNOME_VFS_MONITOR_DIRECTORY) { + G_LOCK (vfolder_lock); + + folder = resolve_folder (info, + vuri.path, + FALSE /* ignore_basename */, + &result, + NULL); + + handle = g_new0 (FileMonitorHandle, 1); + handle->refcount = 2; + handle->uri = gnome_vfs_uri_dup (uri); + handle->dir_monitor = TRUE; + handle->handle = NULL; + handle->filename = NULL; + + if (folder == NULL) { + handle->exists = FALSE; + info->free_folder_monitors = + g_slist_prepend (info->free_folder_monitors, + handle); + } else { + handle->exists = TRUE; + ((Entry *)folder)->monitors = + g_slist_prepend (((Entry *)folder)->monitors, + handle); + } + + info->folder_monitors = + g_slist_prepend (info->folder_monitors, handle); + + G_UNLOCK (vfolder_lock); + + *method_handle_return = (GnomeVFSMethodHandle *) handle; + + return GNOME_VFS_OK; + } else { + /* These can't be very nice FILE names */ + if (vuri.file == NULL || + vuri.ends_in_slash) + return GNOME_VFS_ERROR_INVALID_URI; + + G_LOCK (vfolder_lock); + file_uri = desktop_uri_to_file_uri (info, + &vuri, + &entry, + &is_directory_file, + NULL /* the_folder */, + FALSE, + &result, + NULL); + + handle = g_new0 (FileMonitorHandle, 1); + handle->refcount = 2; + handle->uri = gnome_vfs_uri_dup (uri); + handle->dir_monitor = FALSE; + handle->handle = NULL; + handle->filename = g_strdup (vuri.file); + handle->is_directory_file = is_directory_file; + + info->file_monitors = + g_slist_prepend (info->file_monitors, handle); + + + if (file_uri == NULL) { + handle->exists = FALSE; + info->free_file_monitors = + g_slist_prepend (info->free_file_monitors, + handle); + } else { + char *uri_string = gnome_vfs_uri_to_string (file_uri, 0); + handle->exists = TRUE; + gnome_vfs_monitor_add (&(handle->handle), + uri_string, + GNOME_VFS_MONITOR_FILE, + file_monitor, + handle); + g_free (uri_string); + + entry->monitors = g_slist_prepend (entry->monitors, + handle); + gnome_vfs_uri_unref (file_uri); + } + + *method_handle_return = (GnomeVFSMethodHandle *) handle; + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; + } +} + +static GnomeVFSResult +do_monitor_cancel (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle) +{ + FileMonitorHandle *handle; + VFolderInfo *info; + VFolderURI vuri; + GnomeVFSResult result; + Folder *folder; + GSList *li; + + handle = (FileMonitorHandle *)method_handle; + + /* FIXME: is this correct? */ + if (method_handle == NULL) + return GNOME_VFS_OK; + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + info = get_vfolder_info (vuri.scheme, &result, NULL); + if (info == NULL) + return result; + + if (handle->dir_monitor) { + G_LOCK (vfolder_lock); + + folder = resolve_folder (info, + vuri.path, + FALSE /* ignore_basename */, + &result, + NULL); + + for (li = info->folder_monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + if (h != handle) + continue; + info->folder_monitors = g_slist_delete_link + (info->folder_monitors, li); + file_monitor_handle_unref_unlocked (h); + break; + } + + if (folder == NULL) { + for (li = info->free_folder_monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *h = li->data; + if (h != handle) + continue; + info->free_folder_monitors = g_slist_delete_link + (info->free_folder_monitors, li); + file_monitor_handle_unref_unlocked (h); + break; + } + } else { + for (li = ((Entry *)folder)->monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *h = li->data; + if (h != handle) + continue; + ((Entry *)folder)->monitors = + g_slist_delete_link + (((Entry *)folder)->monitors, li); + file_monitor_handle_unref_unlocked (h); + break; + } + } + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; + } else { + G_LOCK (vfolder_lock); + + for (li = info->file_monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + if (h != handle) + continue; + info->file_monitors = g_slist_delete_link + (info->file_monitors, li); + file_monitor_handle_unref_unlocked (h); + break; + } + + for (li = info->free_file_monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *h = li->data; + if (h != handle) + continue; + info->free_file_monitors = g_slist_delete_link + (info->free_file_monitors, li); + file_monitor_handle_unref_unlocked (h); + break; + } + + for (li = info->entries; li != NULL; li = li->next) { + Entry *e = li->data; + GSList *link = g_slist_find (e->monitors, handle); + + if (link == NULL) + continue; + link->data = NULL; + e->monitors = g_slist_delete_link (e->monitors, link); + + file_monitor_handle_unref_unlocked (handle); + break; + } + + G_UNLOCK (vfolder_lock); + + /* Note: last unref of our monitor will cancel the + * underlying handle */ + + return GNOME_VFS_OK; + } +} + + +/* gnome-vfs bureaucracy */ + +static GnomeVFSMethod method = { + sizeof (GnomeVFSMethod), + do_open, + NULL, /* do_create, */ + do_close, + do_read, + NULL, /* do_write, */ + do_seek, + do_tell, + NULL, /* do_truncate_handle, */ + do_open_directory, + do_close_directory, + do_read_directory, + do_get_file_info, + do_get_file_info_from_handle, + do_is_local, + NULL, /* do_make_directory, */ + NULL, /* do_remove_directory, */ + NULL, /* do_move, */ + NULL, /* do_unlink, */ + do_check_same_fs, + NULL, /* do_set_file_info, */ + NULL, /* do_truncate, */ + NULL /* find_directory */, + NULL /* create_symbolic_link */, + do_monitor_add, + do_monitor_cancel +}; + +GnomeVFSMethod * +vfs_module_init (const char *method_name, + const char *args) +{ + parent_method = gnome_vfs_method_get ("file"); + + if (parent_method == NULL) { + g_error ("Could not find 'file' method for gnome-vfs"); + return NULL; + } + + return &method; +} + +void +vfs_module_shutdown (GnomeVFSMethod *method) +{ + if (infos == NULL) + return; + + g_hash_table_destroy (infos); + infos = NULL; +} diff --git a/modules/vfolder-desktop-method.c.hide-with-empty-subfolders b/modules/vfolder-desktop-method.c.hide-with-empty-subfolders new file mode 100644 index 0000000..97a2d48 --- /dev/null +++ b/modules/vfolder-desktop-method.c.hide-with-empty-subfolders @@ -0,0 +1,6137 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: 8; c-basic-offset: 8 -*- */ + +/* vfolder-desktop-method.c + + Copyright (C) 2001 Red Hat, Inc. + Copyright (C) 2001 The Dark Prince + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/* URI scheme for reading the "applications:" vfolder and other + * vfolder schemes. Lots of code stolen from the original desktop + * reading URI scheme. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +/* Debugging foo: */ +/*#define D(x) x */ +#define D(x) ; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#define DOT_GNOME ".gnome2" + +typedef struct _VFolderInfo VFolderInfo; +typedef struct _Query Query; +typedef struct _QueryKeyword QueryKeyword; +typedef struct _QueryFilename QueryFilename; +typedef struct _Entry Entry; +typedef struct _Folder Folder; +typedef struct _EntryFile EntryFile; +typedef struct _Keyword Keyword; +typedef struct _FileMonitorHandle FileMonitorHandle; +typedef struct _StatLoc StatLoc; +typedef struct _VFolderURI VFolderURI; + +/* TODO before 2.0: */ +/* FIXME: also check/monitor desktop_dirs like we do the vfolder + * file and the item dirs */ +/* FIXME: check if thread locks are not completely on crack which + * is likely given my experience with threads */ +/* FIXME: use filename locking, currently we are full of races if + * multiple processes write to this filesystem */ +/* FIXME: implement monitors */ + +/* TODO for later (star trek future): */ +/* FIXME: Maybe when chaining to file:, we should call the gnome-vfs wrapper + * functions, instead of the file: methods directly. */ +/* FIXME: related to the above: we should support things being on non + * file: filesystems. Such as having the vfolder info file on http + * somewhere or some such nonsense :) */ + +static GnomeVFSMethod *parent_method = NULL; + +static GHashTable *infos = NULL; + +/* Note: I have no clue about how to write thread safe code and this + * is my first attempt, so it's probably wrong + * -George */ +G_LOCK_DEFINE_STATIC (vfolder_lock); + +/* Note: all keywords are quarks */ +/* Note: basenames are unique */ + +#define UNSUPPORTED_INFO_FIELDS (GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS | \ + GNOME_VFS_FILE_INFO_FIELDS_DEVICE | \ + GNOME_VFS_FILE_INFO_FIELDS_INODE | \ + GNOME_VFS_FILE_INFO_FIELDS_LINK_COUNT | \ + GNOME_VFS_FILE_INFO_FIELDS_ATIME) + + +enum { + QUERY_OR, + QUERY_AND, + QUERY_KEYWORD, + QUERY_FILENAME +}; + +struct _Query { + int type; + gboolean not; + GSList *queries; +}; + +struct _QueryKeyword { + int type; + gboolean not; + GQuark keyword; +}; + +struct _QueryFilename { + int type; + gboolean not; + char *filename; +}; + +enum { + ENTRY_FILE, + ENTRY_FOLDER +}; + +struct _Entry { + int type; + int refcount; + int alloc; /* not really useful for folders, + but oh well, whatever. It's the number + of times this is queried in some directory, + used for the Unallocated query type */ + char *name; + + GSList *monitors; +}; + +struct _EntryFile { + Entry entry; + + char *filename; + gboolean per_user; + GSList *keywords; + + gboolean implicit_keywords; /* the keywords were added by us */ +}; + +struct _Folder { + Entry entry; + + Folder *parent; + + char *desktop_file; /* the .directory file */ + + Query *query; + + /* The following is for per file + * access */ + /* excluded by filename */ + GHashTable *excludes; + /* included by filename */ + GSList *includes; + GHashTable *includes_ht; + + GSList *subfolders; + + /* Some flags */ + gboolean read_only; + gboolean dont_show_if_empty; + gboolean only_unallocated; /* include only unallocated items */ + + /* lazily done, will run query only when it + * needs to */ + gboolean up_to_date; + gboolean sorted; + GSList *entries; +}; + +struct _StatLoc { + time_t ctime; + time_t last_stat; + gboolean trigger_next; /* if true, next check will fail */ + char name[1]; /* the structure will be long enough to + fit name */ +}; + +struct _VFolderInfo { + char *scheme; + + char *filename; + char *user_filename; + time_t user_filename_last_write; + char *desktop_dir; /* directory with .directorys */ + char *user_desktop_dir; /* directory with .directorys */ + gboolean user_file_active; /* if using user_filename and + not filename */ + + GSList *item_dirs; + char *user_item_dir; /* dir where user changes to + items are stored */ + + /* old style dirs to merge in */ + GSList *merge_dirs; + + /* if entries are valid, else + * they need to be (re)read */ + gboolean entries_valid; + + GSList *entries; + + /* entry hash by basename */ + GHashTable *entries_ht; + + /* The root folder */ + Folder *root; + + /* The unallocated folders, the folder which only + * include unallocated items */ + GSList *unallocated_folders; + + /* some flags */ + gboolean read_only; + + gboolean dirty; + + int inhibit_write; + + /* change monitoring stuff */ + GnomeVFSMonitorHandle *filename_monitor; + GnomeVFSMonitorHandle *user_filename_monitor; + + /* stat locations (in case we aren't monitoring) */ + StatLoc *filename_statloc; + StatLoc *user_filename_statloc; + + /* for .directory dirs */ + /* FIXME: */GnomeVFSMonitorHandle *desktop_dir_monitor; + /* FIXME: */GnomeVFSMonitorHandle *user_desktop_dir_monitor; + + /* stat locations (in case we aren't monitoring) */ + /* FIXME: */StatLoc *desktop_dir_statloc; + /* FIXME: */StatLoc *user_desktop_dir_statloc; + + /* FIXME: */GSList *file_monitors; /* FileMonitorHandle */ + /* FIXME: */GSList *free_file_monitors; /* FileMonitorHandle */ + GSList *folder_monitors; /* FileMonitorHandle */ + GSList *free_folder_monitors; /* FileMonitorHandle */ + + GSList *item_dir_monitors; /* GnomeVFSMonitorHandle */ + + /* item dirs to stat */ + GSList *stat_dirs; + + /* ctime for folders */ + time_t modification_time; + + guint reread_queue; +}; + +struct _FileMonitorHandle { + int refcount; + gboolean exists; + gboolean dir_monitor; /* TRUE if dir, FALSE if file */ + GnomeVFSURI *uri; + GnomeVFSMonitorHandle *handle; /* A real handle if we're monitoring + an actual file here, or NULL */ + char *filename; /* Just the basename, used in the free_file_list */ + gboolean is_directory_file; +}; + +struct _VFolderURI { + const gchar *scheme; + gboolean is_all_scheme; + gboolean ends_in_slash; + gchar *path; + gchar *file; + GnomeVFSURI *uri; +}; + + +static Entry * entry_ref (Entry *entry); +static Entry * entry_ref_alloc (Entry *entry); +static void entry_unref (Entry *entry); +static void entry_unref_dealloc (Entry *entry); +static void query_destroy (Query *query); +static void ensure_folder (VFolderInfo *info, + Folder *folder, + gboolean subfolders, + Folder *except, + gboolean ignore_unallocated); +static void ensure_folder_unlocked (VFolderInfo *info, + Folder *folder, + gboolean subfolders, + Folder *except, + gboolean ignore_unallocated); +/* An EVIL function for quick reading of .desktop files, + * only reads in one or two keys, but that's ALL we need */ +static void readitem_entry (const char *filename, + const char *key1, + char **result1, + const char *key2, + char **result2); +static gboolean vfolder_info_reload (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context, + gboolean force_read_items); +static gboolean vfolder_info_reload_unlocked (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context, + gboolean force_read_items); +static void invalidate_folder_subfolders (Folder *folder, + gboolean lock_taken); +static Folder * resolve_folder (VFolderInfo *info, + const char *path, + gboolean ignore_basename, + GnomeVFSResult *result, + GnomeVFSContext *context); +static gboolean vfolder_info_read_items (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context); + +/* assumes vuri->path already set */ +static gboolean +vfolder_uri_parse_internal (GnomeVFSURI *uri, VFolderURI *vuri) +{ + vuri->scheme = (gchar *) gnome_vfs_uri_get_scheme (uri); + + vuri->ends_in_slash = FALSE; + + if (strncmp (vuri->scheme, "all-", strlen ("all-")) == 0) { + vuri->scheme += strlen ("all-"); + vuri->is_all_scheme = TRUE; + } else + vuri->is_all_scheme = FALSE; + + if (vuri->path != NULL) { + int last_slash = strlen (vuri->path) - 1; + char *first; + + /* Note: This handling of paths is somewhat evil, may need a + * bit of a rework */ + + /* kill leading slashes, that is make sure there is + * only one */ + for (first = vuri->path; *first == '/'; first++) + ; + if (first != vuri->path) { + first--; + vuri->path = first; + } + + /* kill trailing slashes (leave first if all slashes) */ + while (last_slash > 0 && vuri->path [last_slash] == '/') { + vuri->path [last_slash--] = '\0'; + vuri->ends_in_slash = TRUE; + } + + /* get basename start */ + while (last_slash >= 0 && vuri->path [last_slash] != '/') + last_slash--; + + if (last_slash > -1) + vuri->file = vuri->path + last_slash + 1; + else + vuri->file = vuri->path; + + if (vuri->file[0] == '\0' && + strcmp (vuri->path, "/") == 0) { + vuri->file = NULL; + } + } else { + vuri->ends_in_slash = TRUE; + vuri->path = "/"; + vuri->file = NULL; + } + + vuri->uri = uri; + + return TRUE; +} + +#define VFOLDER_URI_PARSE(_uri, _vuri) { \ + gchar *path; \ + path = gnome_vfs_unescape_string ((_uri)->text, G_DIR_SEPARATOR_S); \ + if (path != NULL) { \ + (_vuri)->path = g_alloca (strlen (path) + 1); \ + strcpy ((_vuri)->path, path); \ + g_free (path); \ + } else { \ + (_vuri)->path = NULL; \ + } \ + vfolder_uri_parse_internal ((_uri), (_vuri)); \ +} + +static FileMonitorHandle * +file_monitor_handle_ref_unlocked (FileMonitorHandle *h) +{ + h->refcount ++; + return h; +} + +static void +file_monitor_handle_unref_unlocked (FileMonitorHandle *h) +{ + h->refcount --; + if (h->refcount == 0) { + gnome_vfs_uri_unref (h->uri); + h->uri = NULL; + + g_free (h->filename); + h->filename = NULL; + + if (h->handle != NULL) { + gnome_vfs_monitor_cancel (h->handle); + h->handle = NULL; + } + } +} + +/* This includes the .directory files */ +static void +emit_monitor (Folder *folder, int type) +{ + GSList *li; + for (li = ((Entry *)folder)->monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *handle = li->data; + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *) handle, + handle->uri, type); + } +} + +static void +emit_file_deleted_monitor (VFolderInfo *info, Entry *entry, Folder *folder) +{ + GSList *li; + for (li = entry->monitors; + li != NULL; + li = li->next) { + VFolderURI vuri; + Folder *f; + GnomeVFSResult result; + FileMonitorHandle *handle = li->data; + + /* Evil! EVIL URI PARSING. this will eat a lot of + * stack if we have lots of monitors */ + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + f = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + + if (f == folder) + gnome_vfs_monitor_callback + ((GnomeVFSMethodHandle *) handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_DELETED); + } +} + +static void +emit_and_delete_monitor (VFolderInfo *info, Folder *folder) +{ + GSList *li; + for (li = ((Entry *)folder)->monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *handle = li->data; + li->data = NULL; + + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *) handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_DELETED); + + if (handle->dir_monitor) + info->free_folder_monitors = + g_slist_prepend (info->free_folder_monitors, + handle); + else + info->free_file_monitors = + g_slist_prepend (info->free_file_monitors, + handle); + } + g_slist_free (((Entry *)folder)->monitors); + ((Entry *)folder)->monitors = NULL; +} + +static gboolean +check_ext (const char *name, const char *ext_check) +{ + const char *ext; + + ext = strrchr (name, '.'); + if (ext == NULL || + strcmp (ext, ext_check) != 0) + return FALSE; + else + return TRUE; +} + +static StatLoc * +bake_statloc (const char *name, + time_t curtime) +{ + struct stat s; + StatLoc *sl = NULL; + if (stat (name, &s) != 0) { + if (errno == ENOENT) { + sl = g_malloc0 (sizeof (StatLoc) + + strlen (name) + 1); + sl->last_stat = curtime; + sl->ctime = 0; + sl->trigger_next = FALSE; + strcpy (sl->name, name); + } + return sl; + } + + sl = g_malloc0 (sizeof (StatLoc) + + strlen (name) + 1); + sl->last_stat = curtime; + sl->ctime = s.st_ctime; + sl->trigger_next = FALSE; + strcpy (sl->name, name); + + return sl; +} + +/* returns FALSE if we must reread */ +static gboolean +check_statloc (StatLoc *sl, + time_t curtime) +{ + struct stat s; + + if (sl->trigger_next) { + sl->trigger_next = FALSE; + return FALSE; + } + + /* don't stat more then once every 3 seconds */ + if (curtime <= sl->last_stat + 3) + return TRUE; + + sl->last_stat = curtime; + + if (stat (sl->name, &s) != 0) { + if (errno == ENOENT && + sl->ctime == 0) + return TRUE; + else + return FALSE; + } + + if (sl->ctime == s.st_ctime) + return TRUE; + else + return FALSE; +} + +static gboolean +ensure_dir (const char *dirname, gboolean ignore_basename) +{ + char *parsed, *p; + + if (dirname == NULL) + return FALSE; + + if (ignore_basename) + parsed = g_path_get_dirname (dirname); + else + parsed = g_strdup (dirname); + + if (g_file_test (parsed, G_FILE_TEST_IS_DIR)) { + g_free (parsed); + return TRUE; + } + + p = strchr (parsed, '/'); + if (p == parsed) + p = strchr (p+1, '/'); + + while (p != NULL) { + *p = '\0'; + if (mkdir (parsed, 0700) != 0 && + errno != EEXIST) { + g_free (parsed); + return FALSE; + } + *p = '/'; + p = strchr (p+1, '/'); + } + + if (mkdir (parsed, 0700) != 0 && + errno != EEXIST) { + g_free (parsed); + return FALSE; + } + + g_free (parsed); + return TRUE; +} + +/* check for any directory name other then root */ +static gboolean +any_subdir (const char *dirname) +{ + const char *p; + if (dirname == NULL) + return FALSE; + + for (p = dirname; *p != '\0'; p++) { + if (*p != '/') { + return TRUE; + } + } + return FALSE; +} + +static void +destroy_entry_file (EntryFile *efile) +{ + if (efile == NULL) + return; + + g_free (efile->filename); + efile->filename = NULL; + + g_slist_free (efile->keywords); + efile->keywords = NULL; + + g_free (efile); +} + +static void +destroy_folder (Folder *folder) +{ + GSList *list; + + if (folder == NULL) + return; + + if (folder->parent != NULL) { + folder->parent->subfolders = + g_slist_remove (folder->parent->subfolders, folder); + folder->parent->up_to_date = FALSE; + folder->parent = NULL; + } + + g_free (folder->desktop_file); + folder->desktop_file = NULL; + + query_destroy (folder->query); + folder->query = NULL; + + if (folder->excludes != NULL) { + g_hash_table_destroy (folder->excludes); + folder->excludes = NULL; + } + + g_slist_foreach (folder->includes, (GFunc)g_free, NULL); + g_slist_free (folder->includes); + folder->includes = NULL; + if (folder->includes_ht != NULL) { + g_hash_table_destroy (folder->includes_ht); + folder->includes_ht = NULL; + } + + list = folder->subfolders; + folder->subfolders = NULL; + g_slist_foreach (list, (GFunc)entry_unref, NULL); + g_slist_free (list); + + list = folder->entries; + folder->entries = NULL; + g_slist_foreach (list, (GFunc)entry_unref, NULL); + g_slist_free (list); + + g_free (folder); +} + +static Entry * +entry_ref (Entry *entry) +{ + if (entry != NULL) + entry->refcount++; + return entry; +} + +static Entry * +entry_ref_alloc (Entry *entry) +{ + entry_ref (entry); + + if (entry != NULL) + entry->alloc++; + + return entry; +} + +static void +entry_unref (Entry *entry) +{ + if (entry == NULL) + return; + + entry->refcount--; + + if (entry->refcount == 0) { + g_free (entry->name); + entry->name = NULL; + + g_slist_foreach (entry->monitors, + (GFunc)file_monitor_handle_unref_unlocked, + NULL); + g_slist_free (entry->monitors); + entry->monitors = NULL; + + if (entry->type == ENTRY_FILE) + destroy_entry_file ((EntryFile *)entry); + else /* ENTRY_FOLDER */ + destroy_folder ((Folder *)entry); + } +} + +static void +entry_unref_dealloc (Entry *entry) +{ + if (entry != NULL) { + entry->alloc --; + entry_unref (entry); + } +} + +/* Handles ONLY files, not dirs */ +/* Also allocates the entries as well as refs them */ +static GSList * +alloc_entries_from_files (VFolderInfo *info, GSList *filenames) +{ + GSList *li; + GSList *files; + + files = NULL; + for (li = filenames; li != NULL; li = li->next) { + char *filename = li->data; + GSList *entry_list = g_hash_table_lookup (info->entries_ht, filename); + if (entry_list != NULL) + files = g_slist_prepend (files, + entry_ref_alloc (entry_list->data)); + } + + return files; +} + +static gboolean +matches_query (VFolderInfo *info, + Folder *folder, + EntryFile *efile, + Query *query) +{ + GSList *li; + + if (query == NULL) + return TRUE; + +#define INVERT_IF_NEEDED(val) (query->not ? !(val) : (val)) + switch (query->type) { + case QUERY_OR: + for (li = query->queries; li != NULL; li = li->next) { + Query *subquery = li->data; + if (matches_query (info, folder, efile, subquery)) + return INVERT_IF_NEEDED (TRUE); + } + return INVERT_IF_NEEDED (FALSE); + case QUERY_AND: + for (li = query->queries; li != NULL; li = li->next) { + Query *subquery = li->data; + if ( ! matches_query (info, folder, efile, subquery)) + return INVERT_IF_NEEDED (FALSE); + } + return INVERT_IF_NEEDED (TRUE); + case QUERY_KEYWORD: + { + QueryKeyword *qkeyword = (QueryKeyword *)query; + for (li = efile->keywords; li != NULL; li = li->next) { + GQuark keyword = GPOINTER_TO_INT (li->data); + if (keyword == qkeyword->keyword) + return INVERT_IF_NEEDED (TRUE); + } + return INVERT_IF_NEEDED (FALSE); + } + case QUERY_FILENAME: + { + QueryFilename *qfilename = (QueryFilename *)query; + if (strcmp (qfilename->filename, ((Entry *)efile)->name) == 0) { + return INVERT_IF_NEEDED (TRUE); + } else { + return INVERT_IF_NEEDED (FALSE); + } + } + } +#undef INVERT_IF_NEEDED + g_assert_not_reached (); + /* huh? */ + return FALSE; +} + +static void +dump_unallocated_folders (Folder *folder) +{ + GSList *li; + for (li = folder->subfolders; li != NULL; li = li->next) + dump_unallocated_folders (li->data); + + if (folder->only_unallocated && + folder->entries != NULL) { + g_slist_foreach (folder->entries, + (GFunc)entry_unref_dealloc, NULL); + g_slist_free (folder->entries); + folder->entries = NULL; + } +} + +/* Run query, allocs and refs the entries */ +static void +append_query (VFolderInfo *info, Folder *folder) +{ + GSList *li; + + if (folder->query == NULL && + ! folder->only_unallocated) + return; + + if (folder->only_unallocated) { + /* dump all folders that use unallocated + * items only. This sucks if you keep + * reading one and then another such + * folder, but oh well, life sucks for + * you then, but at least you get + * consistent results */ + dump_unallocated_folders (info->root); + + /* ensure all other folders, so that + * after this we know which ones are + * unallocated */ + ensure_folder_unlocked (info, + info->root, + TRUE /* subfolders */, + folder /* except */, + /* avoid infinite loops */ + TRUE /* ignore_unallocated */); + } + + for (li = info->entries; li != NULL; li = li->next) { + Entry *entry = li->data; + + if (/* if not file */ + entry->type != ENTRY_FILE || + /* if already included */ + (folder->includes_ht != NULL && + g_hash_table_lookup (folder->includes_ht, + entry->name) != NULL)) + continue; + + if (folder->only_unallocated && + entry->alloc != 0) + continue; + + if (matches_query (info, folder, (EntryFile *)entry, + folder->query)) + folder->entries = g_slist_prepend + (folder->entries, entry_ref_alloc (entry)); + } +} + +/* get entries in folder */ +/* FIXME: support cancellation here */ +static void +ensure_folder_unlocked (VFolderInfo *info, + Folder *folder, + gboolean subfolders, + Folder *except, + gboolean ignore_unallocated) +{ + if (subfolders) { + GSList *li; + for (li = folder->subfolders; li != NULL; li = li->next) + ensure_folder_unlocked (info, li->data, subfolders, + except, ignore_unallocated); + } + + if (except == folder) + return; + + if (ignore_unallocated && + folder->only_unallocated) + return; + + if (folder->up_to_date) + return; + + if (folder->entries != NULL) { + g_slist_foreach (folder->entries, + (GFunc)entry_unref_dealloc, NULL); + g_slist_free (folder->entries); + folder->entries = NULL; + } + + /* Include includes */ + folder->entries = alloc_entries_from_files (info, folder->includes); + + /* Run query */ + append_query (info, folder); + + /* We were prepending all this time */ + folder->entries = g_slist_reverse (folder->entries); + + /* Include subfolders */ + /* we always whack them onto the beginning */ + if (folder->subfolders != NULL) { + GSList *subfolders = g_slist_copy (folder->subfolders); + g_slist_foreach (subfolders, (GFunc)entry_ref_alloc, NULL); + folder->entries = g_slist_concat (subfolders, folder->entries); + } + + /* Exclude excludes */ + if (folder->excludes != NULL) { + GSList *li; + GSList *entries = folder->entries; + folder->entries = NULL; + for (li = entries; li != NULL; li = li->next) { + Entry *entry = li->data; + if (g_hash_table_lookup (folder->excludes, entry->name) == NULL) + folder->entries = g_slist_prepend (folder->entries, entry); + else + entry_unref_dealloc (entry); + + } + g_slist_free (entries); + + /* to preserve the Folders then everything else order */ + folder->entries = g_slist_reverse (folder->entries); + } + + folder->up_to_date = TRUE; + /* not yet sorted */ + folder->sorted = FALSE; +} + +static void +ensure_folder (VFolderInfo *info, + Folder *folder, + gboolean subfolders, + Folder *except, + gboolean ignore_unallocated) +{ + G_LOCK (vfolder_lock); + ensure_folder_unlocked (info, folder, subfolders, except, ignore_unallocated); + G_UNLOCK (vfolder_lock); +} + +static char * +get_directory_file_unlocked (VFolderInfo *info, Folder *folder) +{ + char *filename; + + /* FIXME: cache dir_files */ + + if (folder->desktop_file == NULL) + return NULL; + + if (folder->desktop_file[0] == G_DIR_SEPARATOR) + return g_strdup (folder->desktop_file); + + /* Now try the user directory */ + if (info->user_desktop_dir != NULL) { + filename = g_build_filename (info->user_desktop_dir, + folder->desktop_file, + NULL); + if (access (filename, F_OK) == 0) { + return filename; + } + + g_free (filename); + } + + filename = g_build_filename (info->desktop_dir, folder->desktop_file, NULL); + if (access (filename, F_OK) == 0) { + return filename; + } + g_free (filename); + + return NULL; +} + +static char * +get_directory_file (VFolderInfo *info, Folder *folder) +{ + char *ret; + + G_LOCK (vfolder_lock); + ret = get_directory_file_unlocked (info, folder); + G_UNLOCK (vfolder_lock); + + return ret; +} + +static GSList * +get_sort_order (VFolderInfo *info, Folder *folder) +{ + GSList *list; + char **parsed; + char *order; + int i; + char *filename; + + filename = get_directory_file_unlocked (info, folder); + if (filename == NULL) + return NULL; + + order = NULL; + readitem_entry (filename, + "SortOrder", + &order, + NULL, + NULL); + g_free (filename); + + if (order == NULL) + return NULL; + + parsed = g_strsplit (order, ":", -1); + + g_free (order); + + list = NULL; + for (i = 0; parsed[i] != NULL; i++) { + char *word = parsed[i]; + /* steal */ + parsed[i] = NULL; + /* ignore empty */ + if (word[0] == '\0') { + g_free (word); + continue; + } + list = g_slist_prepend (list, word); + } + /* we've stolen all strings from it */ + g_free (parsed); + + return g_slist_reverse (list); +} + +/* get entries in folder */ +static void +ensure_folder_sort (VFolderInfo *info, Folder *folder) +{ + GSList *li, *sort_order; + GSList *entries; + GHashTable *entry_hash; + + ensure_folder (info, folder, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + if (folder->sorted) + return; + + G_LOCK (vfolder_lock); + + sort_order = get_sort_order (info, folder); + if (sort_order == NULL) { + folder->sorted = TRUE; + G_UNLOCK (vfolder_lock); + return; + } + + entries = folder->entries; + folder->entries = NULL; + + entry_hash = g_hash_table_new (g_str_hash, g_str_equal); + for (li = entries; li != NULL; li = li->next) { + Entry *entry = li->data; + g_hash_table_insert (entry_hash, entry->name, li); + } + + for (li = sort_order; li != NULL; li = li->next) { + char *word = li->data; + GSList *entry_list; + Entry *entry; + + /* we kill the words here */ + li->data = NULL; + + entry_list = g_hash_table_lookup (entry_hash, word); + g_free (word); + + if (entry_list == NULL) + continue; + + entry = entry_list->data; + + entries = g_slist_delete_link (entries, entry_list); + + folder->entries = g_slist_prepend (folder->entries, + entry); + } + + /* put on those that weren't mentioned in the sort */ + for (li = entries; li != NULL; li = li->next) { + Entry *entry = li->data; + + folder->entries = g_slist_prepend (folder->entries, + entry); + } + + g_hash_table_destroy (entry_hash); + g_slist_free (entries); + g_slist_free (sort_order); + + folder->sorted = TRUE; + + G_UNLOCK (vfolder_lock); +} + +static EntryFile * +file_new (const char *name) +{ + EntryFile *efile = g_new0 (EntryFile, 1); + + efile->entry.type = ENTRY_FILE; + efile->entry.name = g_strdup (name); + efile->entry.refcount = 1; + + return efile; +} + +static Folder * +folder_new (const char *name) +{ + Folder *folder = g_new0 (Folder, 1); + + folder->entry.type = ENTRY_FOLDER; + folder->entry.name = g_strdup (name); + folder->entry.refcount = 1; + folder->read_only = TRUE; + folder->dont_show_if_empty = TRUE; + + return folder; +} + +static Query * +query_new (int type) +{ + Query *query; + + if (type == QUERY_KEYWORD) + query = (Query *)g_new0 (QueryKeyword, 1); + else if (type == QUERY_FILENAME) + query = (Query *)g_new0 (QueryFilename, 1); + else + query = g_new0 (Query, 1); + + query->type = type; + + return query; +} + +static void +query_destroy (Query *query) +{ + if (query == NULL) + return; + + if (query->type == QUERY_FILENAME) { + QueryFilename *qfile = (QueryFilename *)query; + g_free (qfile->filename); + qfile->filename = NULL; + } else if (query->type == QUERY_OR || + query->type == QUERY_AND) { + g_slist_foreach (query->queries, (GFunc)query_destroy, NULL); + g_slist_free (query->queries); + query->queries = NULL; + } + + g_free (query); +} + +static void +add_folder_monitor_unlocked (VFolderInfo *info, + FileMonitorHandle *handle) +{ + VFolderURI vuri; + GnomeVFSResult result; + Folder *folder; + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + file_monitor_handle_ref_unlocked (handle); + + info->folder_monitors = + g_slist_prepend (info->folder_monitors, handle); + + folder = resolve_folder (info, + vuri.path, + FALSE /* ignore_basename */, + &result, + NULL); + + if (folder == NULL) { + file_monitor_handle_ref_unlocked (handle); + + info->free_folder_monitors = + g_slist_prepend (info->free_folder_monitors, handle); + + if (handle->exists) { + handle->exists = FALSE; + gnome_vfs_monitor_callback + ((GnomeVFSMethodHandle *)handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_DELETED); + } + } else { + file_monitor_handle_ref_unlocked (handle); + + ((Entry *)folder)->monitors = + g_slist_prepend (((Entry *)folder)->monitors, handle); + + if ( ! handle->exists) { + handle->exists = TRUE; + gnome_vfs_monitor_callback + ((GnomeVFSMethodHandle *)handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_CREATED); + } + } + +} + +static inline void +invalidate_folder_T (Folder *folder) +{ + folder->up_to_date = FALSE; + + invalidate_folder_subfolders (folder, TRUE); +} + +static inline void +invalidate_folder (Folder *folder) +{ + G_LOCK (vfolder_lock); + folder->up_to_date = FALSE; + G_UNLOCK (vfolder_lock); + + invalidate_folder_subfolders (folder, FALSE); +} + +static void +invalidate_folder_subfolders (Folder *folder, + gboolean lock_taken) +{ + GSList *li; + + for (li = folder->subfolders; li != NULL; li = li->next) { + Folder *subfolder = li->data; + + if (!lock_taken) + invalidate_folder (subfolder); + else + invalidate_folder_T (subfolder); + } + + emit_monitor (folder, GNOME_VFS_MONITOR_EVENT_CHANGED); +} + +/* FIXME: this is UGLY!, we need to figure out when the file + * got finished changing! */ +static gboolean +reread_timeout (gpointer data) +{ + VFolderInfo *info = data; + gboolean force_read_items = info->file_monitors != NULL; + vfolder_info_reload (info, NULL, NULL, force_read_items); + return FALSE; +} + +static void +queue_reread_in (VFolderInfo *info, int msec) +{ + G_LOCK (vfolder_lock); + if (info->reread_queue != 0) + g_source_remove (info->reread_queue); + info->reread_queue = g_timeout_add (msec, reread_timeout, info); + G_UNLOCK (vfolder_lock); +} + +static void +vfolder_desktop_dir_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + /* FIXME: implement */ +} + +static void +vfolder_user_desktop_dir_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + /* FIXME: implement */ +} + +static void +vfolder_filename_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + VFolderInfo *info = user_data; + + if ((event_type == GNOME_VFS_MONITOR_EVENT_CREATED || + event_type == GNOME_VFS_MONITOR_EVENT_CHANGED) && + ! info->user_file_active) { + queue_reread_in (info, 200); + } else if (event_type == GNOME_VFS_MONITOR_EVENT_DELETED && + ! info->user_file_active) { + /* FIXME: is this correct? I mean now + * there probably isn't ANY vfolder file, so we + * init to default values really. I have no clue what's + * right here */ + vfolder_info_reload (info, NULL, NULL, + TRUE /* force read items */); + } +} + +static void +vfolder_user_filename_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + VFolderInfo *info = user_data; + + if ((event_type == GNOME_VFS_MONITOR_EVENT_CREATED || + event_type == GNOME_VFS_MONITOR_EVENT_CHANGED) && + info->user_file_active) { + struct stat s; + + /* see if this was really our own change */ + if (info->user_filename_last_write == time (NULL)) + return; + /* anal retentive */ + if (stat (info->user_filename, &s) == 0 && + info->user_filename_last_write == s.st_ctime) + return; + + queue_reread_in (info, 200); + } else if ((event_type == GNOME_VFS_MONITOR_EVENT_CREATED || + event_type == GNOME_VFS_MONITOR_EVENT_CHANGED) && + ! info->user_file_active) { + queue_reread_in (info, 200); + } else if (event_type == GNOME_VFS_MONITOR_EVENT_DELETED && + info->user_file_active) { + gboolean force_read_items = info->file_monitors != NULL; + vfolder_info_reload (info, NULL, NULL, force_read_items); + } +} + +static void +item_dir_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + VFolderInfo *info = user_data; + + if (event_type == GNOME_VFS_MONITOR_EVENT_CREATED || + event_type == GNOME_VFS_MONITOR_EVENT_CHANGED) { + /* first invalidate all folders */ + invalidate_folder (info->root); + /* second invalidate all entries */ + info->entries_valid = FALSE; + + if (info->file_monitors != NULL) { + GnomeVFSResult result; + GSList *li; + + /* Whack all monitors here! */ + for (li = info->file_monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *h = li->data; + if (h->handle != NULL) + gnome_vfs_monitor_cancel (h->handle); + h->handle = NULL; + } + + if (vfolder_info_read_items (info, &result, NULL)) { + info->entries_valid = TRUE; + } + } + } +} + +static gboolean +setup_dir_monitor (VFolderInfo *info, const char *dir, gboolean subdirs, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + GnomeVFSMonitorHandle *handle; + DIR *dh; + struct dirent *de; + char *uri; + + uri = gnome_vfs_get_uri_from_local_path (dir); + + if (gnome_vfs_monitor_add (&handle, + uri, + GNOME_VFS_MONITOR_DIRECTORY, + item_dir_monitor, + info) != GNOME_VFS_OK) { + StatLoc *sl = bake_statloc (dir, time (NULL)); + if (sl != NULL) + info->stat_dirs = g_slist_prepend (info->stat_dirs, sl); + g_free (uri); + return TRUE; + } + g_free (uri); + + if (gnome_vfs_context_check_cancellation (context)) { + gnome_vfs_monitor_cancel (handle); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + info->item_dir_monitors = + g_slist_prepend (info->item_dir_monitors, handle); + + if ( ! subdirs) + return TRUE; + + dh = opendir (dir); + if (dh == NULL) + return TRUE; + + while ((de = readdir (dh)) != NULL) { + char *full_path; + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + closedir (dh); + return FALSE; + } + + if (de->d_name[0] == '.') + continue; + + full_path = g_build_filename (dir, de->d_name, NULL); + if (g_file_test (full_path, G_FILE_TEST_IS_DIR)) { + if ( ! setup_dir_monitor (info, full_path, + TRUE /* subdirs */, + result, context)) { + closedir (dh); + return FALSE; + } + } + g_free (full_path); + } + + closedir (dh); + + return TRUE; +} + +static gboolean +monitor_setup (VFolderInfo *info, + gboolean setup_filenames, + gboolean setup_itemdirs, + gboolean setup_desktop_dirs, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + char *uri; + GSList *li; + + if (setup_filenames) { + uri = gnome_vfs_get_uri_from_local_path + (info->filename); + + if (gnome_vfs_monitor_add (&info->filename_monitor, + uri, + GNOME_VFS_MONITOR_FILE, + vfolder_filename_monitor, + info) != GNOME_VFS_OK) { + info->filename_monitor = NULL; + info->filename_statloc = bake_statloc (info->filename, + time (NULL)); + } + g_free (uri); + } + if (setup_filenames && + info->user_filename != NULL) { + uri = gnome_vfs_get_uri_from_local_path + (info->user_filename); + if (gnome_vfs_monitor_add (&info->user_filename_monitor, + uri, + GNOME_VFS_MONITOR_FILE, + vfolder_user_filename_monitor, + info) != GNOME_VFS_OK) { + info->user_filename_monitor = NULL; + info->user_filename_statloc = + bake_statloc (info->user_filename, + time (NULL)); + } + + g_free (uri); + } + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + if (setup_itemdirs) { + for (li = info->item_dirs; li != NULL; li = li->next) { + const char *dir = li->data; + if ( ! setup_dir_monitor (info, dir, + FALSE /* subdirs */, + result, context)) + return FALSE; + } + if (info->user_item_dir != NULL) { + if ( ! setup_dir_monitor (info, info->user_item_dir, + FALSE /* subdirs */, + result, context)) + return FALSE; + } + for (li = info->merge_dirs; li != NULL; li = li->next) { + const char *dir = li->data; + if ( ! setup_dir_monitor (info, dir, + TRUE /* subdirs */, + result, context)) + return FALSE; + } + } + + if (setup_desktop_dirs) { + uri = gnome_vfs_get_uri_from_local_path + (info->desktop_dir); + + if (gnome_vfs_monitor_add (&info->desktop_dir_monitor, + uri, + GNOME_VFS_MONITOR_FILE, + vfolder_desktop_dir_monitor, + info) != GNOME_VFS_OK) { + info->desktop_dir_monitor = NULL; + info->desktop_dir_statloc = + bake_statloc (info->desktop_dir, + time (NULL)); + } + g_free (uri); + } + if (setup_desktop_dirs && + info->user_desktop_dir != NULL) { + uri = gnome_vfs_get_uri_from_local_path + (info->user_desktop_dir); + if (gnome_vfs_monitor_add (&info->user_desktop_dir_monitor, + uri, + GNOME_VFS_MONITOR_DIRECTORY, + vfolder_user_desktop_dir_monitor, + info) != GNOME_VFS_OK) { + info->user_desktop_dir_monitor = NULL; + info->user_desktop_dir_statloc = + bake_statloc (info->user_desktop_dir, + time (NULL)); + } + + g_free (uri); + } + + return TRUE; +} + +static void +vfolder_info_init (VFolderInfo *info, const char *scheme) +{ + const char *path; + GSList *list; + + info->scheme = g_strdup (scheme); + + info->filename = g_strconcat (SYSCONFDIR, "/X11/desktop-menus/", + scheme, ".menu", + NULL); + info->user_filename = g_strconcat (g_get_home_dir (), + "/" DOT_GNOME "/vfolders/", + scheme, ".vfolder-info", + NULL); + info->desktop_dir = g_strconcat (SYSCONFDIR, + "/gnome-vfs-2.0/vfolders/", + NULL); + info->user_desktop_dir = g_strconcat (g_get_home_dir (), + "/" DOT_GNOME "/vfolders/", + NULL); + + /* Init the desktop paths */ + list = NULL; + list = g_slist_prepend (list, g_strdup ("/usr/share/applications/")); + if (strcmp ("/usr/share/applications/", DATADIR "/applications/") != 0) + list = g_slist_prepend (list, g_strdup (DATADIR "/applications/")); + path = g_getenv ("DESKTOP_FILE_PATH"); + if (path != NULL) { + int i; + char **ppath = g_strsplit (path, ":", -1); + for (i = 0; ppath[i] != NULL; i++) { + const char *dir = ppath[i]; + list = g_slist_prepend (list, g_strdup (dir)); + } + g_strfreev (ppath); + } + info->item_dirs = g_slist_reverse (list); + + info->user_item_dir = g_strconcat (g_get_home_dir (), + "/" DOT_GNOME "/vfolders/", + scheme, + NULL); + + info->entries_ht = g_hash_table_new (g_str_hash, g_str_equal); + + info->root = folder_new ("Root"); + + info->modification_time = time (NULL); +} + +static void +vfolder_info_free_internals_unlocked (VFolderInfo *info) +{ + if (info == NULL) + return; + + if (info->filename_monitor != NULL) { + gnome_vfs_monitor_cancel (info->filename_monitor); + info->filename_monitor = NULL; + } + + if (info->user_filename_monitor != NULL) { + gnome_vfs_monitor_cancel (info->user_filename_monitor); + info->user_filename_monitor = NULL; + } + + g_free (info->filename_statloc); + info->filename_statloc = NULL; + + g_free (info->user_filename_statloc); + info->user_filename_statloc = NULL; + + + if (info->desktop_dir_monitor != NULL) { + gnome_vfs_monitor_cancel (info->desktop_dir_monitor); + info->desktop_dir_monitor = NULL; + } + + if (info->user_desktop_dir_monitor != NULL) { + gnome_vfs_monitor_cancel (info->user_desktop_dir_monitor); + info->user_desktop_dir_monitor = NULL; + } + + g_free (info->desktop_dir_statloc); + info->desktop_dir_statloc = NULL; + + g_free (info->user_desktop_dir_statloc); + info->user_desktop_dir_statloc = NULL; + + + g_slist_foreach (info->item_dir_monitors, + (GFunc)gnome_vfs_monitor_cancel, NULL); + g_slist_free (info->item_dir_monitors); + info->item_dir_monitors = NULL; + + g_free (info->scheme); + info->scheme = NULL; + + g_free (info->filename); + info->filename = NULL; + + g_free (info->user_filename); + info->user_filename = NULL; + + g_free (info->desktop_dir); + info->desktop_dir = NULL; + + g_free (info->user_desktop_dir); + info->user_desktop_dir = NULL; + + g_slist_foreach (info->item_dirs, (GFunc)g_free, NULL); + g_slist_free (info->item_dirs); + info->item_dirs = NULL; + + g_free (info->user_item_dir); + info->user_item_dir = NULL; + + g_slist_foreach (info->merge_dirs, (GFunc)g_free, NULL); + g_slist_free (info->merge_dirs); + info->merge_dirs = NULL; + + g_slist_foreach (info->entries, (GFunc)entry_unref, NULL); + g_slist_free (info->entries); + info->entries = NULL; + + if (info->entries_ht != NULL) + g_hash_table_destroy (info->entries_ht); + info->entries_ht = NULL; + + g_slist_foreach (info->unallocated_folders, + (GFunc)entry_unref, + NULL); + g_slist_free (info->unallocated_folders); + info->unallocated_folders = NULL; + + entry_unref ((Entry *)info->root); + info->root = NULL; + + g_slist_foreach (info->stat_dirs, (GFunc)g_free, NULL); + g_slist_free (info->stat_dirs); + info->stat_dirs = NULL; + + g_slist_foreach (info->folder_monitors, + (GFunc)file_monitor_handle_unref_unlocked, NULL); + g_slist_free (info->folder_monitors); + info->folder_monitors = NULL; + + g_slist_foreach (info->free_folder_monitors, + (GFunc)file_monitor_handle_unref_unlocked, NULL); + g_slist_free (info->free_folder_monitors); + info->free_folder_monitors = NULL; + + g_slist_foreach (info->file_monitors, + (GFunc)file_monitor_handle_unref_unlocked, NULL); + g_slist_free (info->file_monitors); + info->file_monitors = NULL; + + g_slist_foreach (info->free_file_monitors, + (GFunc)file_monitor_handle_unref_unlocked, NULL); + g_slist_free (info->free_file_monitors); + info->free_file_monitors = NULL; + + if (info->reread_queue != 0) + g_source_remove (info->reread_queue); + info->reread_queue = 0; +} + +static void +vfolder_info_free_internals (VFolderInfo *info) +{ + G_LOCK (vfolder_lock); + vfolder_info_free_internals_unlocked (info); + G_UNLOCK (vfolder_lock); +} + +static void +vfolder_info_destroy (VFolderInfo *info) +{ + vfolder_info_free_internals (info); + g_free (info); +} + +static Query * +single_query_read (xmlNode *qnode) +{ + Query *query; + xmlNode *node; + + if (qnode->type != XML_ELEMENT_NODE || + qnode->name == NULL) + return NULL; + + query = NULL; + + if (g_ascii_strcasecmp (qnode->name, "Not") == 0 && + qnode->xmlChildrenNode != NULL) { + xmlNode *iter; + query = NULL; + for (iter = qnode->xmlChildrenNode; + iter != NULL && query == NULL; + iter = iter->next) + query = single_query_read (iter); + if (query != NULL) { + query->not = ! query->not; + } + return query; + } else if (g_ascii_strcasecmp (qnode->name, "Keyword") == 0) { + xmlChar *word = xmlNodeGetContent (qnode); + if (word != NULL) { + query = query_new (QUERY_KEYWORD); + ((QueryKeyword *)query)->keyword = + g_quark_from_string (word); + + xmlFree (word); + } + return query; + } else if (g_ascii_strcasecmp (qnode->name, "Filename") == 0) { + xmlChar *file = xmlNodeGetContent (qnode); + if (file != NULL) { + query = query_new (QUERY_FILENAME); + ((QueryFilename *)query)->filename = + g_strdup (file); + + xmlFree (file); + } + return query; + } else if (g_ascii_strcasecmp (qnode->name, "And") == 0) { + query = query_new (QUERY_AND); + } else if (g_ascii_strcasecmp (qnode->name, "Or") == 0) { + query = query_new (QUERY_OR); + } else { + /* We don't understand */ + return NULL; + } + + /* This must be OR or AND */ + g_assert (query != NULL); + + for (node = qnode->xmlChildrenNode; node != NULL; node = node->next) { + Query *new_query = single_query_read (node); + + if (new_query != NULL) + query->queries = g_slist_prepend + (query->queries, new_query); + } + + query->queries = g_slist_reverse (query->queries); + + return query; +} + +static void +add_or_set_query (Query **query, Query *new_query) +{ + if (*query == NULL) { + *query = new_query; + } else { + Query *old_query = *query; + *query = query_new (QUERY_OR); + (*query)->queries = + g_slist_append ((*query)->queries, old_query); + (*query)->queries = + g_slist_append ((*query)->queries, new_query); + } +} + +static Query * +query_read (xmlNode *qnode) +{ + Query *query; + xmlNode *node; + + query = NULL; + + for (node = qnode->xmlChildrenNode; node != NULL; node = node->next) { + if (node->type != XML_ELEMENT_NODE || + node->name == NULL) + continue; + + if (g_ascii_strcasecmp (node->name, "Not") == 0 && + node->xmlChildrenNode != NULL) { + xmlNode *iter; + Query *new_query = NULL; + + for (iter = node->xmlChildrenNode; + iter != NULL && new_query == NULL; + iter = iter->next) + new_query = single_query_read (iter); + if (new_query != NULL) { + new_query->not = ! new_query->not; + add_or_set_query (&query, new_query); + } + } else { + Query *new_query = single_query_read (node); + if (new_query != NULL) + add_or_set_query (&query, new_query); + } + } + + return query; +} + +static Folder * +folder_read (VFolderInfo *info, xmlNode *fnode) +{ + Folder *folder; + xmlNode *node; + + folder = folder_new (NULL); + + for (node = fnode->xmlChildrenNode; node != NULL; node = node->next) { + if (node->type != XML_ELEMENT_NODE || + node->name == NULL) + continue; + + if (g_ascii_strcasecmp (node->name, "Name") == 0) { + xmlChar *name = xmlNodeGetContent (node); + if (name != NULL) { + g_free (folder->entry.name); + folder->entry.name = g_strdup (name); + xmlFree (name); + } + } else if (g_ascii_strcasecmp (node->name, "Desktop") == 0) { + xmlChar *desktop = xmlNodeGetContent (node); + if (desktop != NULL) { + g_free (folder->desktop_file); + folder->desktop_file = g_strdup (desktop); + xmlFree (desktop); + } + } else if (g_ascii_strcasecmp (node->name, "Include") == 0) { + xmlChar *file = xmlNodeGetContent (node); + if (file != NULL) { + GSList *li; + char *str = g_strdup (file); + folder->includes = g_slist_prepend + (folder->includes, str); + if (folder->includes_ht == NULL) { + folder->includes_ht = + g_hash_table_new_full + (g_str_hash, + g_str_equal, + NULL, + NULL); + } + li = g_hash_table_lookup (folder->includes_ht, + file); + if (li != NULL) { + g_free (li->data); + /* Note: this will NOT change folder->includes + * pointer! */ + folder->includes = g_slist_delete_link + (folder->includes, li); + } + g_hash_table_replace (folder->includes_ht, + file, folder->includes); + xmlFree (file); + } + } else if (g_ascii_strcasecmp (node->name, "Exclude") == 0) { + xmlChar *file = xmlNodeGetContent (node); + if (file != NULL) { + char *s; + if (folder->excludes == NULL) { + folder->excludes = g_hash_table_new_full + (g_str_hash, + g_str_equal, + (GDestroyNotify)g_free, + NULL); + } + s = g_strdup (file); + g_hash_table_replace (folder->excludes, s, s); + xmlFree (file); + } + } else if (g_ascii_strcasecmp (node->name, "Query") == 0) { + Query *query; + + query = query_read (node); + + if (query != NULL) { + if (folder->query != NULL) + query_destroy (folder->query); + folder->query = query; + } + } else if (g_ascii_strcasecmp (node->name, "OnlyUnallocated") == 0) { + info->unallocated_folders = + g_slist_prepend (info->unallocated_folders, + (Folder *)entry_ref ((Entry *)folder)); + folder->only_unallocated = TRUE; + } else if (g_ascii_strcasecmp (node->name, "Folder") == 0) { + Folder *new_folder = folder_read (info, node); + if (new_folder != NULL) { + folder->subfolders = + g_slist_append (folder->subfolders, + new_folder); + new_folder->parent = folder; + } + } else if (g_ascii_strcasecmp (node->name, "ReadOnly") == 0) { + folder->read_only = TRUE; + } else if (g_ascii_strcasecmp (node->name, + "DontShowIfEmpty") == 0) { + folder->dont_show_if_empty = TRUE; + } + } + + /* Name is required */ + if (folder->entry.name == NULL) { + entry_unref ((Entry *)folder); + folder = NULL; + } + + folder->includes = g_slist_reverse (folder->includes); + + return folder; +} + +static char * +subst_home (const char *dir) +{ + if (dir[0] == '~') + return g_strconcat (g_get_home_dir (), + &dir[1], + NULL); + else + return g_strdup (dir); +} + +/* FORMAT looks like: + * + * + * /etc/X11/applnk + * + * /usr/share/applications + * + * /etc/X11/gnome/vfolders + * + * + * Root + * + * important.desktop + * + * + * + * SomeFolder + * + * + * Test_Folder + * + * Test_Folder.directory + * + * + * + * Application + * Game + * + * Clock + * + * + * somefile.desktop + * someotherfile.desktop + * yetanother.desktop + * + * + * + */ + +static gboolean +vfolder_info_read_info (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + xmlDoc *doc; + xmlNode *node; + gboolean got_a_vfolder_dir = FALSE; + + doc = NULL; + if (info->user_filename != NULL && + access (info->user_filename, F_OK) == 0) { + doc = xmlParseFile (info->user_filename); + if (doc != NULL) + info->user_file_active = TRUE; + } + if (doc == NULL && + access (info->filename, F_OK) == 0) + doc = xmlParseFile (info->filename); + + if (gnome_vfs_context_check_cancellation (context)) { + xmlFreeDoc(doc); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + if (doc == NULL + || doc->xmlRootNode == NULL + || doc->xmlRootNode->name == NULL + || g_ascii_strcasecmp (doc->xmlRootNode->name, "VFolderInfo") != 0) { + xmlFreeDoc(doc); + return TRUE; /* FIXME: really, shouldn't we error out? */ + } + + for (node = doc->xmlRootNode->xmlChildrenNode; node != NULL; node = node->next) { + if (node->type != XML_ELEMENT_NODE || + node->name == NULL) + continue; + + if (gnome_vfs_context_check_cancellation (context)) { + xmlFreeDoc(doc); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + if (g_ascii_strcasecmp (node->name, "MergeDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + if (dir != NULL) { + info->merge_dirs = g_slist_append (info->merge_dirs, + g_strdup (dir)); + xmlFree (dir); + } + } else if (g_ascii_strcasecmp (node->name, "ItemDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + if (dir != NULL) { + if ( ! got_a_vfolder_dir) { + g_slist_foreach (info->item_dirs, + (GFunc)g_free, NULL); + g_slist_free (info->item_dirs); + info->item_dirs = NULL; + } + got_a_vfolder_dir = TRUE; + info->item_dirs = g_slist_append (info->item_dirs, + g_strdup (dir)); + xmlFree (dir); + } + } else if (g_ascii_strcasecmp (node->name, "UserItemDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + if (dir != NULL) { + g_free (info->user_item_dir); + info->user_item_dir = subst_home (dir); + xmlFree (dir); + } + } else if (g_ascii_strcasecmp (node->name, "DesktopDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + if (dir != NULL) { + g_free (info->desktop_dir); + info->desktop_dir = g_strdup (dir); + xmlFree (dir); + } + } else if (g_ascii_strcasecmp (node->name, "UserDesktopDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + if (dir != NULL) { + g_free (info->user_desktop_dir); + info->user_desktop_dir = subst_home (dir); + xmlFree (dir); + } + } else if (g_ascii_strcasecmp (node->name, "Folder") == 0) { + Folder *folder = folder_read (info, node); + if (folder != NULL) { + if (info->root != NULL) + entry_unref ((Entry *)info->root); + info->root = folder; + } + } else if (g_ascii_strcasecmp (node->name, "ReadOnly") == 0) { + info->read_only = TRUE; + } + } + + xmlFreeDoc(doc); + + return TRUE; +} + +static void +add_xml_tree_from_query (xmlNode *parent, Query *query) +{ + xmlNode *real_parent; + + if (query->not) + real_parent = xmlNewChild (parent /* parent */, + NULL /* ns */, + "Not" /* name */, + NULL /* content */); + else + real_parent = parent; + + if (query->type == QUERY_KEYWORD) { + QueryKeyword *qkeyword = (QueryKeyword *)query; + const char *string = g_quark_to_string (qkeyword->keyword); + + xmlNewChild (real_parent /* parent */, + NULL /* ns */, + "Keyword" /* name */, + string /* content */); + } else if (query->type == QUERY_FILENAME) { + QueryFilename *qfilename = (QueryFilename *)query; + + xmlNewChild (real_parent /* parent */, + NULL /* ns */, + "Filename" /* name */, + qfilename->filename /* content */); + } else if (query->type == QUERY_OR || + query->type == QUERY_AND) { + xmlNode *node; + const char *name; + GSList *li; + + if (query->type == QUERY_OR) + name = "Or"; + else /* QUERY_AND */ + name = "And"; + + node = xmlNewChild (real_parent /* parent */, + NULL /* ns */, + name /* name */, + NULL /* content */); + + for (li = query->queries; li != NULL; li = li->next) { + Query *subquery = li->data; + add_xml_tree_from_query (node, subquery); + } + } else { + g_assert_not_reached (); + } +} + +static void +add_excludes_to_xml (gpointer key, gpointer value, gpointer user_data) +{ + const char *filename = key; + xmlNode *folder_node = user_data; + + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Exclude" /* name */, + filename /* content */); +} + +static void +add_xml_tree_from_folder (xmlNode *parent, Folder *folder) +{ + GSList *li; + xmlNode *folder_node; + + + folder_node = xmlNewChild (parent /* parent */, + NULL /* ns */, + "Folder" /* name */, + NULL /* content */); + + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Name" /* name */, + folder->entry.name /* content */); + + if (folder->desktop_file != NULL) { + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Desktop" /* name */, + folder->desktop_file /* content */); + } + + if (folder->read_only) + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "ReadOnly" /* name */, + NULL /* content */); + if (folder->dont_show_if_empty) + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "DontShowIfEmpty" /* name */, + NULL /* content */); + if (folder->only_unallocated) + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "OnlyUnallocated" /* name */, + NULL /* content */); + + for (li = folder->subfolders; li != NULL; li = li->next) { + Folder *subfolder = li->data; + add_xml_tree_from_folder (folder_node, subfolder); + } + + for (li = folder->includes; li != NULL; li = li->next) { + const char *include = li->data; + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Include" /* name */, + include /* content */); + } + + if (folder->excludes) { + g_hash_table_foreach (folder->excludes, + add_excludes_to_xml, + folder_node); + } + + if (folder->query != NULL) { + xmlNode *query_node; + query_node = xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Query" /* name */, + NULL /* content */); + + add_xml_tree_from_query (query_node, folder->query); + } +} + +static xmlDoc * +xml_tree_from_vfolder (VFolderInfo *info) +{ + xmlDoc *doc; + xmlNode *topnode; + GSList *li; + + doc = xmlNewDoc ("1.0"); + + topnode = xmlNewDocNode (doc /* doc */, + NULL /* ns */, + "VFolderInfo" /* name */, + NULL /* content */); + doc->xmlRootNode = topnode; + + for (li = info->merge_dirs; li != NULL; li = li->next) { + const char *merge_dir = li->data; + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "MergeDir" /* name */, + merge_dir /* content */); + } + + for (li = info->item_dirs; li != NULL; li = li->next) { + const char *item_dir = li->data; + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "ItemDir" /* name */, + item_dir /* content */); + } + + if (info->user_item_dir != NULL) { + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "UserItemDir" /* name */, + info->user_item_dir /* content */); + } + + if (info->desktop_dir != NULL) { + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "DesktopDir" /* name */, + info->desktop_dir /* content */); + } + + if (info->user_desktop_dir != NULL) { + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "UserDesktopDir" /* name */, + info->user_desktop_dir /* content */); + } + + if (info->root != NULL) + add_xml_tree_from_folder (topnode, info->root); + + return doc; +} + +/* FIXME: what to do about errors */ +static void +vfolder_info_write_user (VFolderInfo *info) +{ + xmlDoc *doc; + + if (info->inhibit_write > 0) + return; + + if (info->user_filename == NULL) + return; + + doc = xml_tree_from_vfolder (info); + if (doc == NULL) + return; + + /* FIXME: errors, anyone? */ + ensure_dir (info->user_filename, + TRUE /* ignore_basename */); + + xmlSaveFormatFile (info->user_filename, doc, TRUE /* format */); + /* not as good as a stat, but cheaper ... hmmm what is + * the likelyhood of this not being the same as ctime */ + info->user_filename_last_write = time (NULL); + + xmlFreeDoc(doc); + + info->user_file_active = TRUE; + info->dirty = FALSE; + + info->modification_time = time (NULL); +} + +/* An EVIL function for quick reading of .desktop files, + * only reads in one or two keys, but that's ALL we need */ +static void +readitem_entry (const char *filename, + const char *key1, + char **result1, + const char *key2, + char **result2) +{ + FILE *fp; + char buf[1024]; + int keylen1, keylen2; + + *result1 = NULL; + if (result2 != NULL) + *result2 = NULL; + + fp = fopen (filename, "r"); + + if (fp == NULL) + return; + + keylen1 = strlen (key1); + if (key2 != NULL) + keylen2 = strlen (key2); + else + keylen2 = -1; + + /* This is slightly wrong, it should only look + * at the correct section */ + while (fgets (buf, sizeof (buf), fp) != NULL) { + char *p; + int len; + int keylen; + char **result = NULL; + + /* check if it's one of the keys */ + if (strncmp (buf, key1, keylen1) == 0) { + result = result1; + keylen = keylen1; + } else if (keylen2 >= 0 && + strncmp (buf, key2, keylen2) == 0) { + result = result2; + keylen = keylen2; + } else { + continue; + } + + p = &buf[keylen]; + + /* still not our key */ + if (!(*p == '=' || *p == ' ')) { + continue; + } + do + p++; + while (*p == ' ' || *p == '='); + + /* get rid of trailing \n */ + len = strlen (p); + if (p[len-1] == '\n' || + p[len-1] == '\r') + p[len-1] = '\0'; + + *result = g_strdup (p); + + if (*result1 != NULL && + (result2 == NULL || *result2 != NULL)) + break; + } + + fclose (fp); +} + +static void +vfolder_info_insert_entry (VFolderInfo *info, EntryFile *efile) +{ + GSList *entry_list; + + entry_ref ((Entry *)efile); + + entry_list = g_hash_table_lookup (info->entries_ht, efile->entry.name); + + info->entries = g_slist_prepend (info->entries, efile); + /* The hash table contains the GSList pointer */ + g_hash_table_replace (info->entries_ht, efile->entry.name, + info->entries); + + if (entry_list != NULL) { + Entry *entry = entry_list->data; + info->entries = g_slist_delete_link (info->entries, + entry_list); + entry_unref (entry); + } +} + +static void +set_keywords (EntryFile *efile, const char *keywords) +{ + if (keywords != NULL) { + int i; + char **parsed = g_strsplit (keywords, ";", -1); + for (i = 0; parsed[i] != NULL; i++) { + GQuark quark; + const char *word = parsed[i]; + /* ignore empties (including end of list) */ + if (word[0] == '\0') + continue; + quark = g_quark_from_string (word); + efile->keywords = g_slist_prepend + (efile->keywords, + GINT_TO_POINTER (quark)); + } + g_strfreev (parsed); + } +} + +static EntryFile * +make_entry_file (const char *dir, const char *name) +{ + EntryFile *efile; + char *categories; + char *only_show_in; + char *filename; + int i; + + filename = g_build_filename (dir, name, NULL); + + readitem_entry (filename, + "Categories", + &categories, + "OnlyShowIn", + &only_show_in); + + if (only_show_in != NULL) { + gboolean show = FALSE; + char **parsed = g_strsplit (only_show_in, ";", -1); + for (i = 0; parsed[i] != NULL; i++) { + if (strcmp (parsed[i], "GNOME") == 0) { + show = TRUE; + break; + } + } + g_strfreev (parsed); + if ( ! show) { + g_free (filename); + g_free (only_show_in); + g_free (categories); + return NULL; + } + } + + efile = file_new (name); + efile->filename = filename; + + set_keywords (efile, categories); + + g_free (only_show_in); + g_free (categories); + + return efile; +} + +static gboolean +vfolder_info_read_items_from (VFolderInfo *info, + const char *item_dir, + gboolean per_user, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + DIR *dir; + struct dirent *de; + + dir = opendir (item_dir); + if (dir == NULL) + return TRUE; + + while ((de = readdir (dir)) != NULL) { + EntryFile *efile; + + if (gnome_vfs_context_check_cancellation (context)) { + closedir (dir); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + /* files MUST be called .desktop */ + if (de->d_name[0] == '.' || + ! check_ext (de->d_name, ".desktop")) + continue; + + efile = make_entry_file (item_dir, de->d_name); + if (efile == NULL) + continue; + + efile->per_user = per_user; + + vfolder_info_insert_entry (info, efile); + entry_unref ((Entry *)efile); + } + + closedir (dir); + + return TRUE; +} + +static gboolean +vfolder_info_read_items_merge (VFolderInfo *info, + const char *merge_dir, + const char *subdir, + GQuark inherited_keyword, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + DIR *dir; + struct dirent *de; + GQuark extra_keyword; + GQuark Application; + GQuark Merged; + GQuark inheritance; + gboolean pass_down_extra_keyword = TRUE; + + dir = opendir (merge_dir); + if (dir == NULL) + return TRUE; + + Application = g_quark_from_static_string ("Application"); + Merged = g_quark_from_static_string ("Merged"); + + /* FIXME: this should be a hash or something */ + extra_keyword = 0; + if (subdir == NULL) { + extra_keyword = g_quark_from_static_string ("Core"); + pass_down_extra_keyword = FALSE; + } else if (g_ascii_strcasecmp (subdir, "Development") == 0) + extra_keyword = g_quark_from_static_string ("Development"); + else if (g_ascii_strcasecmp (subdir, "Editors") == 0) + extra_keyword = g_quark_from_static_string ("TextEditor"); + else if (g_ascii_strcasecmp (subdir, "Games") == 0) + extra_keyword = g_quark_from_static_string ("Game"); + else if (g_ascii_strcasecmp (subdir, "Graphics") == 0) + extra_keyword = g_quark_from_static_string ("Graphics"); + else if (g_ascii_strcasecmp (subdir, "Internet") == 0) + extra_keyword = g_quark_from_static_string ("Network"); + else if (g_ascii_strcasecmp (subdir, "Multimedia") == 0) + extra_keyword = g_quark_from_static_string ("AudioVideo"); + else if (g_ascii_strcasecmp (subdir, "Office") == 0) + extra_keyword = g_quark_from_static_string ("Office"); + else if (g_ascii_strcasecmp (subdir, "Settings") == 0) + extra_keyword = g_quark_from_static_string ("Settings"); + else if (g_ascii_strcasecmp (subdir, "System") == 0) + extra_keyword = g_quark_from_static_string ("System"); + else if (g_ascii_strcasecmp (subdir, "Utilities") == 0) + extra_keyword = g_quark_from_static_string ("Utility"); + + while ((de = readdir (dir)) != NULL) { + EntryFile *efile; + + if (gnome_vfs_context_check_cancellation (context)) { + closedir (dir); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + /* ignore hidden */ + if (de->d_name[0] == '.') + continue; + + /* files MUST be called .desktop, so + * treat all others as dirs. If we're wrong, + * the open will fail, which is ok */ + if ( ! check_ext (de->d_name, ".desktop")) { + /* if this is a directory recurse */ + char *fullname = g_build_filename (merge_dir, de->d_name, NULL); + if ((pass_down_extra_keyword == TRUE) && (extra_keyword != 0)) { + inheritance = extra_keyword; + } else { + inheritance = inherited_keyword; + } + + if ( ! vfolder_info_read_items_merge (info, + fullname, + de->d_name, + inheritance, + result, + context)) { + g_free (fullname); + return FALSE; + } + g_free (fullname); + continue; + } + + /* FIXME: add some keywords about some known apps + * like gimp and whatnot, perhaps take these from the vfolder + * file or some such */ + + efile = make_entry_file (merge_dir, de->d_name); + if (efile == NULL) + continue; + + /* If no keywords set, then add the standard ones */ + if (efile->keywords == NULL) { + efile->keywords = g_slist_prepend + (efile->keywords, + GINT_TO_POINTER (Application)); + + efile->keywords = g_slist_prepend + (efile->keywords, + GINT_TO_POINTER (Merged)); + + if (inherited_keyword != 0) { + efile->keywords = g_slist_prepend + (efile->keywords, + GINT_TO_POINTER (inherited_keyword)); + } + + if (extra_keyword != 0) { + efile->keywords = g_slist_prepend + (efile->keywords, + GINT_TO_POINTER (extra_keyword)); + } + efile->implicit_keywords = TRUE; + } + + vfolder_info_insert_entry (info, efile); + entry_unref ((Entry *)efile); + } + + closedir (dir); + + return TRUE; +} + +static Entry * +find_entry (GSList *list, const char *name) +{ + GSList *li; + + for (li = list; li != NULL; li = li->next) { + Entry *entry = li->data; + if (strcmp (name, entry->name) == 0) + return entry; + } + return NULL; +} + +static void +file_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + FileMonitorHandle *h = user_data; + + /* proxy the event through if it is a changed event + * only */ + + if (event_type == GNOME_VFS_MONITOR_EVENT_CHANGED && + h->handle != NULL) + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *) h, + h->uri, event_type); +} + +static void +try_free_file_monitors_create_files_unlocked (VFolderInfo *info) +{ + GSList *li, *list; + + list = g_slist_copy (info->free_file_monitors); + + for (li = list; li != NULL; li = li->next) { + FileMonitorHandle *handle = li->data; + Entry *entry; + GnomeVFSResult result; + char *dirfile = NULL; + + if (handle->is_directory_file) { + VFolderURI vuri; + Folder *folder; + + /* Evil! EVIL URI PARSING. this will eat a lot of + * stack if we have lots of free monitors */ + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + folder = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + + if (folder == NULL) + continue; + + dirfile = get_directory_file_unlocked (info, folder); + if (dirfile == NULL) + continue; + + entry = (Entry *)folder; + } else { + VFolderURI vuri; + Folder *f; + GnomeVFSResult result; + + entry = NULL; + + /* Evil! EVIL URI PARSING. this will eat a lot of + * stack if we have lots of monitors */ + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + f = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + + if (f != NULL) { + ensure_folder_unlocked ( + info, f, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + entry = find_entry (f->entries, vuri.file); + } + + if (entry == NULL) + continue; + } + + info->free_file_monitors = + g_slist_remove (info->free_file_monitors, handle); + entry->monitors = + g_slist_prepend (entry->monitors, handle); + + handle->exists = TRUE; + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *)handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_CREATED); + + /* recreate a handle */ + if (handle->handle == NULL && + entry->type == ENTRY_FILE) { + EntryFile *efile = (EntryFile *)entry; + char *uri = gnome_vfs_get_uri_from_local_path + (efile->filename); + + gnome_vfs_monitor_add (&(handle->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + handle); + + g_free (uri); + } else if (handle->handle == NULL && + dirfile != NULL) { + char *uri = gnome_vfs_get_uri_from_local_path (dirfile); + + gnome_vfs_monitor_add (&(handle->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + handle); + + g_free (uri); + } + + g_free (dirfile); + } + + g_slist_free (list); +} + +static void /* unlocked */ +rescan_monitors (VFolderInfo *info) +{ + GSList *li; + + if (info->file_monitors == NULL) + return; + + for (li = info->file_monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + GnomeVFSResult result; + Entry *entry; + char *dirfile = NULL; + + /* these are handled below */ + if ( ! h->exists) + continue; + + if (h->is_directory_file) { + VFolderURI vuri; + Folder *folder; + + /* Evil! EVIL URI PARSING. this will eat a lot of + * stack if we have lots of monitors */ + + VFOLDER_URI_PARSE (h->uri, &vuri); + + folder = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + if (folder != NULL) + dirfile = get_directory_file_unlocked (info, + folder); + + if (dirfile == NULL) { + h->exists = FALSE; + gnome_vfs_monitor_callback + ((GnomeVFSMethodHandle *)h, + h->uri, + GNOME_VFS_MONITOR_EVENT_DELETED); + info->free_file_monitors = g_slist_prepend + (info->free_file_monitors, h); + file_monitor_handle_ref_unlocked (h); + /* it has been unreffed when the entry was + * whacked */ + continue; + } + + entry = (Entry *)folder; + } else { + VFolderURI vuri; + Folder *f; + GnomeVFSResult result; + + entry = NULL; + + /* Evil! EVIL URI PARSING. this will eat a lot of + * stack if we have lots of monitors */ + + VFOLDER_URI_PARSE (h->uri, &vuri); + + f = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + + if (f != NULL) { + ensure_folder_unlocked ( + info, f, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + entry = find_entry (f->entries, vuri.file); + } + + if (entry == NULL) { + h->exists = FALSE; + gnome_vfs_monitor_callback + ((GnomeVFSMethodHandle *)h, + h->uri, + GNOME_VFS_MONITOR_EVENT_DELETED); + info->free_file_monitors = g_slist_prepend + (info->free_file_monitors, h); + file_monitor_handle_ref_unlocked (h); + /* it has been unreffed when the entry was + * whacked */ + continue; + } + } + + /* recreate a handle */ + if (h->handle == NULL && + entry->type == ENTRY_FILE) { + EntryFile *efile = (EntryFile *)entry; + char *uri = gnome_vfs_get_uri_from_local_path + (efile->filename); + + gnome_vfs_monitor_add (&(h->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + h); + + g_free (uri); + } else if (h->handle == NULL && + dirfile != NULL) { + char *uri = gnome_vfs_get_uri_from_local_path (dirfile); + + gnome_vfs_monitor_add (&(h->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + h); + + g_free (uri); + } + + g_free (dirfile); + } + + try_free_file_monitors_create_files_unlocked (info); +} + +static gboolean /* unlocked */ +vfolder_info_read_items (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + GSList *li; + + /* First merge */ + for (li = info->merge_dirs; li != NULL; li = li->next) { + const char *merge_dir = li->data; + + if ( ! vfolder_info_read_items_merge (info, merge_dir, NULL, FALSE, + result, context)) + return FALSE; + } + + /* Then read the real thing (later overrides) */ + for (li = info->item_dirs; li != NULL; li = li->next) { + const char *item_dir = li->data; + + if ( ! vfolder_info_read_items_from (info, item_dir, + FALSE /* per_user */, + result, context)) + return FALSE; + } + + if (info->user_item_dir != NULL) { + if ( ! vfolder_info_read_items_from (info, + info->user_item_dir, + TRUE /* per_user */, + result, context)) + return FALSE; + } + + rescan_monitors (info); + + return TRUE; +} + +static gboolean +string_slist_equal (GSList *list1, GSList *list2) +{ + GSList *li1, *li2; + + for (li1 = list1, li2 = list2; + li1 != NULL && li2 != NULL; + li1 = li1->next, li2 = li2->next) { + const char *s1 = li1->data; + const char *s2 = li2->data; + if (strcmp (s1, s2) != 0) + return FALSE; + } + /* if both are not NULL, then lengths are + * different */ + if (li1 != li2) + return FALSE; + return TRUE; +} + +static gboolean +safe_string_same (const char *string1, const char *string2) +{ + if (string1 == string2 && + string1 == NULL) + return TRUE; + + if (string1 != NULL && string2 != NULL && + strcmp (string1, string2) == 0) + return TRUE; + + return FALSE; +} + +static gboolean +vfolder_info_item_dirs_same (VFolderInfo *info1, VFolderInfo *info2) +{ + if ( ! string_slist_equal (info1->item_dirs, + info2->item_dirs)) + return FALSE; + + if ( ! string_slist_equal (info1->merge_dirs, + info2->merge_dirs)) + return FALSE; + + if ( ! safe_string_same (info1->user_item_dir, + info2->user_item_dir)) + return FALSE; + + return TRUE; +} + +static gboolean +vfolder_info_reload_unlocked (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context, + gboolean force_read_items) +{ + VFolderInfo *newinfo; + gboolean setup_filenames; + gboolean setup_itemdirs; + GSList *li; + + /* FIXME: Hmmm, race, there is no locking YAIKES, + * we need filename locking for changes. eek, eek, eek */ + if (info->dirty) { + return TRUE; + } + + newinfo = g_new0 (VFolderInfo, 1); + vfolder_info_init (newinfo, info->scheme); + + g_free (newinfo->filename); + g_free (newinfo->user_filename); + newinfo->filename = g_strdup (info->filename); + newinfo->user_filename = g_strdup (info->user_filename); + + if (gnome_vfs_context_check_cancellation (context)) { + vfolder_info_destroy (newinfo); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + if ( ! vfolder_info_read_info (newinfo, result, context)) { + vfolder_info_destroy (newinfo); + return FALSE; + } + + /* FIXME: reload logic for 'desktop_dir' and + * 'user_desktop_dir' */ + + setup_itemdirs = TRUE; + + /* Validity of entries and item dirs and all that is unchanged */ + if (vfolder_info_item_dirs_same (info, newinfo)) { + newinfo->entries = info->entries; + info->entries = NULL; + newinfo->entries_ht = info->entries_ht; + info->entries_ht = NULL /* some places assume this + non-null, but we're only + going to destroy this */; + newinfo->entries_valid = info->entries_valid; + + /* move over the monitors/statlocs since those are valid */ + newinfo->item_dir_monitors = info->item_dir_monitors; + info->item_dir_monitors = NULL; + newinfo->stat_dirs = info->stat_dirs; + info->stat_dirs = NULL; + + /* No need to resetup dir monitors */ + setup_itemdirs = FALSE; + + /* No need to do anything with file monitors */ + } else { + /* Whack all monitors here! */ + for (li = info->file_monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + if (h->handle != NULL) + gnome_vfs_monitor_cancel (h->handle); + h->handle = NULL; + } + } + + setup_filenames = TRUE; + + if (safe_string_same (info->filename, newinfo->filename) && + safe_string_same (info->user_filename, newinfo->user_filename)) { + newinfo->user_filename_last_write = + info->user_filename_last_write; + + /* move over the monitors/statlocs since those are valid */ + newinfo->filename_monitor = info->filename_monitor; + info->filename_monitor = NULL; + newinfo->user_filename_monitor = info->user_filename_monitor; + info->user_filename_monitor = NULL; + + if (info->filename_statloc != NULL && + info->filename != NULL) + newinfo->filename_statloc = + bake_statloc (info->filename, + time (NULL)); + if (info->user_filename_statloc != NULL && + info->user_filename != NULL) + newinfo->user_filename_statloc = + bake_statloc (info->user_filename, + time (NULL)); + + /* No need to resetup filename monitors */ + setup_filenames = FALSE; + } + + /* Note: not cancellable anymore, since we've + * already started nibbling on the info structure, + * so we'd need to back things out or some such, + * too complex, so screw that */ + monitor_setup (info, + setup_filenames, + setup_itemdirs, + /* FIXME: setup_desktop_dirs */ TRUE, + NULL, NULL); + + for (li = info->folder_monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *handle = li->data; + li->data = NULL; + + add_folder_monitor_unlocked (newinfo, handle); + + file_monitor_handle_unref_unlocked (handle); + } + g_slist_free (info->folder_monitors); + info->folder_monitors = NULL; + + g_slist_foreach (info->free_folder_monitors, + (GFunc)file_monitor_handle_unref_unlocked, NULL); + g_slist_free (info->free_folder_monitors); + info->folder_monitors = NULL; + + /* we can just copy these for now, they will be readded + * and all the fun stuff will be done with them later */ + newinfo->file_monitors = info->file_monitors; + info->file_monitors = NULL; + newinfo->free_file_monitors = info->free_file_monitors; + info->free_file_monitors = NULL; + + /* emit changed on all folders, a bit drastic, but oh well, + * we also invalidate all folders at the same time, but that is + * irrelevant since they should all just be invalid to begin with */ + invalidate_folder_T (info->root); + + /* FIXME: make sure if this was enough, I think it was */ + + vfolder_info_free_internals_unlocked (info); + memcpy (info, newinfo, sizeof (VFolderInfo)); + g_free (newinfo); + + /* must rescan the monitors here */ + if (info->entries_valid) { + rescan_monitors (info); + } + + if ( ! info->entries_valid && + force_read_items) { + GnomeVFSResult res; + /* FIXME: I bet cancelation plays havoc with monitors, + * I'm not sure however */ + if (info->file_monitors != NULL) { + vfolder_info_read_items (info, &res, NULL); + } else { + if ( ! vfolder_info_read_items (info, result, context)) + return FALSE; + } + info->entries_valid = TRUE; + } + + return TRUE; +} + +static gboolean +vfolder_info_reload (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context, + gboolean force_read_items) +{ + G_LOCK (vfolder_lock); + if (vfolder_info_reload_unlocked (info, result, context, + force_read_items)) { + G_UNLOCK (vfolder_lock); + return TRUE; + } else { + G_UNLOCK (vfolder_lock); + return FALSE; + } +} + +static gboolean +vfolder_info_recheck (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + GSList *li; + time_t curtime = time (NULL); + gboolean reread = FALSE; + + if (info->filename_statloc != NULL && + ! check_statloc (info->filename_statloc, curtime)) { + if ( ! vfolder_info_reload_unlocked (info, result, context, + FALSE /* force read items */)) { + /* we have failed, make sure we fail + * next time too */ + info->filename_statloc->trigger_next = TRUE; + return FALSE; + } + reread = TRUE; + } + if ( ! reread && + info->user_filename_statloc != NULL && + ! check_statloc (info->user_filename_statloc, curtime)) { + if ( ! vfolder_info_reload_unlocked (info, result, context, + FALSE /* force read items */)) { + /* we have failed, make sure we fail + * next time too */ + info->user_filename_statloc->trigger_next = TRUE; + return FALSE; + } + reread = TRUE; + } + + if (info->entries_valid) { + for (li = info->stat_dirs; li != NULL; li = li->next) { + StatLoc *sl = li->data; + if ( ! check_statloc (sl, curtime)) { + info->entries_valid = FALSE; + break; + } + } + } + return TRUE; +} + +static VFolderInfo * +get_vfolder_info_unlocked (const char *scheme, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + VFolderInfo *info; + + if (infos != NULL && + (info = g_hash_table_lookup (infos, scheme)) != NULL) { + if ( ! vfolder_info_recheck (info, result, context)) { + return NULL; + } + if ( ! info->entries_valid) { + g_slist_foreach (info->entries, + (GFunc)entry_unref, NULL); + g_slist_free (info->entries); + info->entries = NULL; + + if (info->entries_ht != NULL) + g_hash_table_destroy (info->entries_ht); + info->entries_ht = g_hash_table_new (g_str_hash, + g_str_equal); + + if ( ! vfolder_info_read_items (info, + result, context)) { + info->entries_valid = FALSE; + return NULL; + } + + invalidate_folder_T (info->root); + + info->entries_valid = TRUE; + + /* Update modification time of all folders, + * kind of evil, but it will make adding new items work + * I hope. This is because rereading usually means + * something changed */ + info->modification_time = time (NULL); + } + return info; + } + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if (infos == NULL) + infos = g_hash_table_new_full + (g_str_hash, g_str_equal, + (GDestroyNotify)g_free, + (GDestroyNotify)vfolder_info_destroy); + + info = g_new0 (VFolderInfo, 1); + vfolder_info_init (info, scheme); + + if (gnome_vfs_context_check_cancellation (context)) { + vfolder_info_destroy (info); + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if ( ! vfolder_info_read_info (info, result, context)) { + vfolder_info_destroy (info); + return NULL; + } + + if ( ! monitor_setup (info, + TRUE /* setup_filenames */, + TRUE /* setup_itemdirs */, + TRUE /* setup_desktop_dirs */, + result, context)) { + vfolder_info_destroy (info); + return NULL; + } + + g_hash_table_insert (infos, g_strdup (scheme), info); + + if ( ! vfolder_info_read_items (info, result, context)) { + info->entries_valid = FALSE; + return NULL; + } + info->entries_valid = TRUE; + + return info; +} + +static VFolderInfo * +get_vfolder_info (const char *scheme, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + VFolderInfo *info; + G_LOCK (vfolder_lock); + info = get_vfolder_info_unlocked (scheme, result, context); + G_UNLOCK (vfolder_lock); + return info; +} + + +static char * +keywords_to_string (GSList *keywords) +{ + GSList *li; + GString *str = g_string_new (NULL); + + for (li = keywords; li != NULL; li = li->next) { + GQuark word = GPOINTER_TO_INT (li->data); + g_string_append (str, g_quark_to_string (word)); + g_string_append_c (str, ';'); + } + + return g_string_free (str, FALSE); +} + +/* copy file and add keywords line */ +static gboolean +copy_file_with_keywords (const char *from, const char *to, GSList *keywords) +{ + FILE *fp; + FILE *wfp; + int wfd; + char buf[BUFSIZ]; + char *keyword_string; + + if ( ! ensure_dir (to, + TRUE /* ignore_basename */)) + return FALSE; + + wfd = open (to, O_CREAT | O_WRONLY | O_TRUNC, 0600); + if (wfd < 0) { + return FALSE; + } + + keyword_string = keywords_to_string (keywords); + + wfp = fdopen (wfd, "w"); + + fp = fopen (from, "r"); + if (fp != NULL) { + gboolean wrote_keywords = FALSE; + while (fgets (buf, sizeof (buf), fp) != NULL) { + fprintf (wfp, "%s", buf); + if ( ! wrote_keywords && + (strncmp (buf, "[Desktop Entry]", + strlen ("[Desktop Entry]")) == 0 || + strncmp (buf, "[KDE Desktop Entry]", + strlen ("[KDE Desktop Entry]")) == 0)) { + fprintf (wfp, "Categories=%s\n", + keyword_string); + wrote_keywords = TRUE; + } + } + + fclose (fp); + } else { + fprintf (wfp, "[Desktop Entry]\nCategories=%s\n", + keyword_string); + } + + /* FIXME: does this close wfd???? */ + fclose (wfp); + + close (wfd); + + g_free (keyword_string); + + return TRUE; +} + +static gboolean +copy_file (const char *from, const char *to) +{ + int fd; + int wfd; + + if ( ! ensure_dir (to, + TRUE /* ignore_basename */)) + return FALSE; + + wfd = open (to, O_CREAT | O_WRONLY | O_TRUNC, 0600); + if (wfd < 0) { + return FALSE; + } + + fd = open (from, O_RDONLY); + if (fd >= 0) { + char buf[1024]; + ssize_t n; + + while ((n = read (fd, buf, sizeof(buf))) > 0) { + write (wfd, buf, n); + } + + close (fd); + } + + close (wfd); + + return TRUE; +} + +static gboolean +make_file_private (VFolderInfo *info, EntryFile *efile) +{ + char *newfname; + Entry *entry = (Entry *)efile; + + if (efile->per_user) + return TRUE; + + /* this file already exists so whack its monitors */ + if (efile->filename != NULL) { + GSList *li; + + for (li = entry->monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + if (h->handle != NULL) + gnome_vfs_monitor_cancel (h->handle); + h->handle = NULL; + } + } + + newfname = g_build_filename (g_get_home_dir (), + DOT_GNOME, + "vfolders", + info->scheme, + efile->entry.name, + NULL); + + if (efile->implicit_keywords) { + if (efile->filename != NULL && + ! copy_file_with_keywords (efile->filename, + newfname, + efile->keywords)) { + /* FIXME: what to do with monitors here, they + * have already been whacked, a corner case + * not handled! */ + g_free (newfname); + return FALSE; + } + } else { + if (efile->filename != NULL && + ! copy_file (efile->filename, newfname)) { + /* FIXME: what to do with monitors here, they + * have already been whacked, a corner case + * not handled! */ + g_free (newfname); + return FALSE; + } + } + + /* we didn't copy but ensure path anyway */ + if (efile->filename == NULL && + ! ensure_dir (newfname, + TRUE /* ignore_basename */)) { + g_free (newfname); + return FALSE; + } + + /* this file already exists so re-add monitors at the new location */ + if (efile->filename != NULL) { + GSList *li; + char *uri = gnome_vfs_get_uri_from_local_path (newfname); + + for (li = entry->monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + + gnome_vfs_monitor_add (&(h->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + h); + } + + g_free (uri); + } + + g_free (efile->filename); + efile->filename = newfname; + efile->per_user = TRUE; + + return TRUE; +} + +static void +try_free_file_monitors_create_dirfile_unlocked (VFolderInfo *info, + Folder *folder) +{ + GSList *li, *list; + + list = g_slist_copy (info->free_file_monitors); + + for (li = list; li != NULL; li = li->next) { + FileMonitorHandle *handle = li->data; + Folder *f; + VFolderURI vuri; + GnomeVFSResult result; + + if ( ! handle->is_directory_file) + continue; + + /* Evil! EVIL URI PARSING. this will eat a lot of stack if we + * have lots of free monitors */ + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + f = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + + if (folder != f) + continue; + + info->free_file_monitors = + g_slist_remove (info->free_file_monitors, handle); + ((Entry *)folder)->monitors = + g_slist_prepend (((Entry *)folder)->monitors, handle); + + handle->exists = TRUE; + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *)handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_CREATED); + } + + g_slist_free (list); +} + +static void +make_new_dirfile (VFolderInfo *info, Folder *folder) +{ + char *name = g_strdup (folder->entry.name); + char *fname; + char *p; + int i; + int fd; + + for (p = name; *p != '\0'; p++) { + if ( ! ( (*p >= 'a' && *p <= 'z') || + (*p >= 'A' && *p <= 'Z') || + (*p >= '0' && *p <= '9') || + *p == '_')) { + *p = '_'; + } + } + + i = 0; + fname = NULL; + do { + char *fullname; + + g_free (fname); + + if (i > 0) { + fname = g_strdup_printf ("%s-%d.directory", name, i); + } else { + fname = g_strdup_printf ("%s.directory", name); + } + + fullname = g_build_filename + (info->user_desktop_dir, fname, NULL); + fd = open (fullname, O_CREAT | O_WRONLY | O_EXCL, 0600); + g_free (fullname); + } while (fd < 0); + + close (fd); + + folder->desktop_file = fname; + info->dirty = TRUE; + + try_free_file_monitors_create_dirfile_unlocked (info, folder); +} + +static gboolean +make_dirfile_private (VFolderInfo *info, Folder *folder) +{ + char *fname; + char *desktop_file; + GSList *li; + char *uri; + gboolean ret; + + if (info->user_desktop_dir == NULL) + return FALSE; + + if ( ! ensure_dir (info->user_desktop_dir, + FALSE /* ignore_basename */)) + return FALSE; + + + if (folder->desktop_file == NULL) { + make_new_dirfile (info, folder); + return TRUE; + } + + /* FIXME: this is broken! What if the desktop file exists + * in the local but there is a different (but with a same name) + * .directory in the system. */ + fname = g_build_filename (info->user_desktop_dir, + folder->desktop_file, + NULL); + + if (access (fname, F_OK) == 0) { + g_free (fname); + return TRUE; + } + + desktop_file = get_directory_file (info, folder); + + if (desktop_file == NULL) { + int fd = open (fname, O_CREAT | O_EXCL | O_WRONLY, 0600); + g_free (fname); + if (fd >= 0) { + close (fd); + return TRUE; + } + return FALSE; + } + + for (li = ((Entry *)folder)->monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + if (h->is_directory_file) { + if (h->handle != NULL) + gnome_vfs_monitor_cancel (h->handle); + h->handle = NULL; + } + } + + ret = TRUE; + + if ( ! copy_file (desktop_file, fname)) { + ret = FALSE; + g_free (fname); + fname = desktop_file; + desktop_file = NULL; + } + + uri = gnome_vfs_get_uri_from_local_path (fname); + + for (li = ((Entry *)folder)->monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + + if (h->is_directory_file) { + gnome_vfs_monitor_add (&(h->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + h); + } + } + + g_free (uri); + + g_free (desktop_file); + g_free (fname); + + return ret; +} + +static Folder * +resolve_folder (VFolderInfo *info, + const char *path, + gboolean ignore_basename, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + char **ppath; + int i; + Folder *folder = info->root; + + ppath = g_strsplit (path, "/", -1); + + if (ppath == NULL || + ppath[0] == NULL) { + g_strfreev (ppath); + *result = GNOME_VFS_ERROR_INVALID_URI; + return NULL; + } + + for (i = 0; ppath [i] != NULL; i++) { + const char *segment = ppath[i]; + + if (*segment == '\0') + continue; + + if (ignore_basename && ppath [i + 1] == NULL) + break; + else { + folder = (Folder *) find_entry (folder->subfolders, + segment); + if (folder == NULL) + break; + } + } + g_strfreev (ppath); + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if (folder == NULL) + *result = GNOME_VFS_ERROR_NOT_FOUND; + + return folder; +} + +static Entry * +resolve_path (VFolderInfo *info, + const char *path, + const char *basename, + Folder **return_folder, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + Entry *entry; + Folder *folder; + + if (strcmp (path, "/") == 0) + return (Entry *)info->root; + + folder = resolve_folder (info, path, + TRUE /* ignore_basename */, + result, context); + + if (return_folder != NULL) + *return_folder = folder; + + if (folder == NULL) { + return NULL; + } + + /* Make sure we have the entries here */ + ensure_folder_unlocked (info, folder, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + + entry = find_entry (folder->entries, basename); + + if (entry == NULL) + *result = GNOME_VFS_ERROR_NOT_FOUND; + + return entry; +} + +static Entry * +get_entry_unlocked (VFolderURI *vuri, + Folder **parent, + gboolean *is_directory_file, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + VFolderInfo *info; + Entry *entry; + + if (is_directory_file != NULL) + *is_directory_file = FALSE; + if (parent != NULL) + *parent = NULL; + + info = get_vfolder_info_unlocked (vuri->scheme, result, context); + if (info == NULL) + return NULL; + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if (vuri->is_all_scheme) { + GSList *efile_list; + + if (vuri->file == NULL) { + entry = resolve_path (info, + vuri->path, + vuri->file, + parent, + result, + context); + return entry; + } + + efile_list = g_hash_table_lookup (info->entries_ht, vuri->file); + + if (efile_list == NULL) { + *result = GNOME_VFS_ERROR_NOT_FOUND; + return NULL; + } else { + return efile_list->data; + } + } + + if (vuri->file != NULL && + check_ext (vuri->file, ".directory") == TRUE) { + Folder *folder; + + folder = resolve_folder (info, vuri->path, + TRUE /* ignore_basename */, + result, context); + if (folder == NULL) { + return NULL; + } + + if (is_directory_file != NULL) + *is_directory_file = TRUE; + + if (parent != NULL) + *parent = folder; + + return (Entry *)folder; + } else { + entry = resolve_path (info, vuri->path, vuri->file, parent, + result, context); + return entry; + } +} + +static Entry * +get_entry (VFolderURI *vuri, + Folder **parent, + gboolean *is_directory_file, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + Entry *entry; + + G_LOCK (vfolder_lock); + entry = get_entry_unlocked (vuri, + parent, + is_directory_file, + result, context); + G_UNLOCK (vfolder_lock); + + return entry; +} + +/* only works for files and only those that exist */ +/* unlocked function */ +static GnomeVFSURI * +desktop_uri_to_file_uri (VFolderInfo *info, + VFolderURI *desktop_vuri, + Entry **the_entry, + gboolean *the_is_directory_file, + Folder **the_folder, + gboolean privatize, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + gboolean is_directory_file; + GnomeVFSURI *ret_uri; + Folder *folder = NULL; + Entry *entry; + + entry = get_entry_unlocked (desktop_vuri, + &folder, + &is_directory_file, + result, + context); + if (entry == NULL) + return NULL; + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if (the_folder != NULL) + *the_folder = folder; + + if (the_entry != NULL) + *the_entry = entry; + if (the_is_directory_file != NULL) + *the_is_directory_file = is_directory_file; + + if (is_directory_file && + entry->type == ENTRY_FOLDER) { + char *desktop_file; + + folder = (Folder *)entry; + + if (the_folder != NULL) + *the_folder = folder; + + /* we'll be doing something write like */ + if (folder->read_only && + privatize) { + *result = GNOME_VFS_ERROR_READ_ONLY; + return NULL; + } + + if (privatize) { + char *fname; + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if ( ! make_dirfile_private (info, folder)) { + *result = GNOME_VFS_ERROR_GENERIC; + return NULL; + } + fname = g_build_filename (g_get_home_dir (), + folder->desktop_file, + NULL); + ret_uri = gnome_vfs_uri_new (fname); + g_free (fname); + return ret_uri; + } + + desktop_file = get_directory_file_unlocked (info, folder); + if (desktop_file != NULL) { + char *s = gnome_vfs_get_uri_from_local_path + (desktop_file); + + g_free (desktop_file); + + ret_uri = gnome_vfs_uri_new (s); + g_free (s); + + return ret_uri; + } else { + *result = GNOME_VFS_ERROR_NOT_FOUND; + return NULL; + } + } else if (entry->type == ENTRY_FILE) { + EntryFile *efile = (EntryFile *)entry; + char *s; + + /* we'll be doing something write like */ + if (folder != NULL && + folder->read_only && + privatize) { + *result = GNOME_VFS_ERROR_READ_ONLY; + return NULL; + } + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if (privatize && + ! make_file_private (info, efile)) { + *result = GNOME_VFS_ERROR_GENERIC; + return NULL; + } + + s = gnome_vfs_get_uri_from_local_path (efile->filename); + ret_uri = gnome_vfs_uri_new (s); + g_free (s); + + return ret_uri; + } else { + if (the_folder != NULL) + *the_folder = (Folder *)entry; + *result = GNOME_VFS_ERROR_IS_DIRECTORY; + return NULL; + } +} + +static void +remove_file (Folder *folder, const char *basename) +{ + GSList *li; + char *s; + + if (folder->includes_ht != NULL) { + li = g_hash_table_lookup (folder->includes_ht, basename); + if (li != NULL) { + char *name = li->data; + folder->includes = g_slist_delete_link + (folder->includes, li); + g_hash_table_remove (folder->includes_ht, basename); + g_free (name); + } + } + + if (folder->excludes == NULL) { + folder->excludes = g_hash_table_new_full + (g_str_hash, g_str_equal, + (GDestroyNotify)g_free, + NULL); + } + s = g_strdup (basename); + g_hash_table_replace (folder->excludes, s, s); +} + +static void +add_file (Folder *folder, const char *basename) +{ + GSList *li = NULL; + + if (folder->includes_ht != NULL) { + li = g_hash_table_lookup (folder->includes_ht, basename); + } + + /* if not found */ + if (li == NULL) { + char *str = g_strdup (basename); + folder->includes = + g_slist_prepend (folder->includes, str); + if (folder->includes_ht == NULL) { + folder->includes_ht = + g_hash_table_new_full (g_str_hash, + g_str_equal, + NULL, + NULL); + } + g_hash_table_replace (folder->includes_ht, + str, folder->includes); + } + if (folder->excludes != NULL) + g_hash_table_remove (folder->excludes, basename); +} + +typedef struct _FileHandle FileHandle; +struct _FileHandle { + VFolderInfo *info; + GnomeVFSMethodHandle *handle; + Entry *entry; + gboolean write; + gboolean is_directory_file; +}; + +static void +make_handle (GnomeVFSMethodHandle **method_handle, + GnomeVFSMethodHandle *file_handle, + VFolderInfo *info, + Entry *entry, + gboolean is_directory_file, + gboolean write) +{ + if (file_handle != NULL) { + FileHandle *handle = g_new0 (FileHandle, 1); + + handle->info = info; + handle->handle = file_handle; + handle->entry = entry_ref (entry); + handle->is_directory_file = is_directory_file; + handle->write = write; + + *method_handle = (GnomeVFSMethodHandle *) handle; + } else { + *method_handle = NULL; + } +} + +static void +whack_handle (FileHandle *handle) +{ + entry_unref (handle->entry); + handle->entry = NULL; + + handle->handle = NULL; + handle->info = NULL; + + g_free (handle); +} + +static GnomeVFSResult +do_open (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result = GNOME_VFS_OK; + VFolderInfo *info; + Entry *entry; + gboolean is_directory_file; + GnomeVFSMethodHandle *file_handle = NULL; + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + /* These can't be very nice FILE names */ + if (vuri.file == NULL || + vuri.ends_in_slash) + return GNOME_VFS_ERROR_INVALID_URI; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (mode & GNOME_VFS_OPEN_WRITE && + (info->read_only || vuri.is_all_scheme)) + return GNOME_VFS_ERROR_READ_ONLY; + + G_LOCK (vfolder_lock); + file_uri = desktop_uri_to_file_uri (info, + &vuri, + &entry, + &is_directory_file, + NULL /* the_folder */, + mode & GNOME_VFS_OPEN_WRITE, + &result, + context); + + if (file_uri == NULL) { + G_UNLOCK (vfolder_lock); + return result; + } + + result = (* parent_method->open) (parent_method, + &file_handle, + file_uri, + mode, + context); + + if (result == GNOME_VFS_ERROR_CANCELLED) { + G_UNLOCK (vfolder_lock); + gnome_vfs_uri_unref (file_uri); + return result; + } + + make_handle (method_handle, + file_handle, + info, + entry, + is_directory_file, + mode & GNOME_VFS_OPEN_WRITE); + + gnome_vfs_uri_unref (file_uri); + + if (info->dirty) { + vfolder_info_write_user (info); + } + + G_UNLOCK (vfolder_lock); + + return result; +} + +static void +remove_from_all_except (Folder *root, + const char *name, + Folder *except) +{ + GSList *li; + + if (root != except) { + remove_file (root, name); + if (root->up_to_date) { + for (li = root->entries; li != NULL; li = li->next) { + Entry *entry = li->data; + if (strcmp (name, entry->name) == 0) { + root->entries = + g_slist_delete_link + (root->entries, li); + break; + } + } + } + } + + for (li = root->subfolders; li != NULL; li = li->next) { + Folder *subfolder = li->data; + + remove_from_all_except (subfolder, name, except); + } +} + +static GnomeVFSResult +do_create (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + gboolean exclusive, + guint perm, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + GnomeVFSMethodHandle *file_handle; + GnomeVFSURI *file_uri; + VFolderURI vuri; + VFolderInfo *info; + Folder *parent; + Entry *entry; + EntryFile *efile; + char *s; + GSList *li; + + VFOLDER_URI_PARSE (uri, &vuri); + + /* These can't be very nice FILE names */ + if (vuri.file == NULL || + vuri.ends_in_slash) + return GNOME_VFS_ERROR_INVALID_URI; + + if ( ! check_ext (vuri.file, ".desktop") && + ! strcmp (vuri.file, ".directory") == 0) { + return GNOME_VFS_ERROR_INVALID_URI; + } + + /* all scheme is read only */ + if (vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (info->user_filename == NULL || + info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + parent = resolve_folder (info, vuri.path, + TRUE /* ignore_basename */, + &result, context); + if (parent == NULL) + return result; + + if (parent->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + if (strcmp (vuri.file, ".directory") == 0) { + char *fname; + + G_LOCK (vfolder_lock); + + if (exclusive) { + char *desktop_file; + desktop_file = get_directory_file_unlocked (info, parent); + if (desktop_file != NULL) { + g_free (desktop_file); + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_FILE_EXISTS; + } + } + + if ( ! make_dirfile_private (info, parent)) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_GENERIC; + } + fname = g_build_filename (g_get_home_dir (), + parent->desktop_file, + NULL); + s = gnome_vfs_get_uri_from_local_path (fname); + file_uri = gnome_vfs_uri_new (s); + g_free (fname); + g_free (s); + + if (file_uri == NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_GENERIC; + } + + result = (* parent_method->create) (parent_method, + &file_handle, + file_uri, + mode, + exclusive, + perm, + context); + gnome_vfs_uri_unref (file_uri); + + make_handle (method_handle, + file_handle, + info, + (Entry *)parent, + TRUE /* is_directory_file */, + TRUE /* write */); + + if (info->dirty) + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return result; + } + + ensure_folder (info, parent, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + + entry = find_entry (parent->entries, vuri.file); + + if (entry != NULL && + entry->type == ENTRY_FOLDER) + return GNOME_VFS_ERROR_IS_DIRECTORY; + + efile = (EntryFile *)entry; + + if (efile != NULL) { + if (exclusive) + return GNOME_VFS_ERROR_FILE_EXISTS; + + G_LOCK (vfolder_lock); + if ( ! make_file_private (info, efile)) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_GENERIC; + } + + s = gnome_vfs_get_uri_from_local_path (efile->filename); + file_uri = gnome_vfs_uri_new (s); + g_free (s); + + if (file_uri == NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_GENERIC; + } + + result = (* parent_method->create) (parent_method, + &file_handle, + file_uri, + mode, + exclusive, + perm, + context); + gnome_vfs_uri_unref (file_uri); + + make_handle (method_handle, + file_handle, + info, + (Entry *)efile, + FALSE /* is_directory_file */, + TRUE /* write */); + + G_UNLOCK (vfolder_lock); + + return result; + } + + G_LOCK (vfolder_lock); + + li = g_hash_table_lookup (info->entries_ht, vuri.file); + + if (exclusive && li != NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_FILE_EXISTS; + } + + if (li == NULL) { + efile = file_new (vuri.file); + vfolder_info_insert_entry (info, efile); + entry_unref ((Entry *)efile); + } else { + efile = li->data; + } + + /* this will make a private name for this */ + if ( ! make_file_private (info, efile)) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_GENERIC; + } + + add_file (parent, vuri.file); + parent->sorted = FALSE; + + if (parent->up_to_date) + parent->entries = g_slist_prepend (parent->entries, efile); + + /* if we created a brand new name, then we exclude it + * from everywhere else to ensure overall sanity */ + if (li == NULL) + remove_from_all_except (info->root, vuri.file, parent); + + s = gnome_vfs_get_uri_from_local_path (efile->filename); + file_uri = gnome_vfs_uri_new (s); + g_free (s); + + result = (* parent_method->create) (parent_method, + &file_handle, + file_uri, + mode, + exclusive, + perm, + context); + gnome_vfs_uri_unref (file_uri); + + make_handle (method_handle, + file_handle, + info, + (Entry *)efile, + FALSE /* is_directory_file */, + TRUE /* write */); + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return result; +} + +static GnomeVFSResult +do_close (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + if (method_handle == (GnomeVFSMethodHandle *)method) + return GNOME_VFS_OK; + + G_LOCK (vfolder_lock); + + result = (* parent_method->close) (parent_method, + handle->handle, + context); + handle->handle = NULL; + + /* we reread the Categories keyword */ + if (handle->write && + handle->entry != NULL && + handle->entry->type == ENTRY_FILE) { + EntryFile *efile = (EntryFile *)handle->entry; + char *categories; + readitem_entry (efile->filename, + "Categories", + &categories, + NULL, + NULL); + set_keywords (efile, categories); + g_free (categories); + /* FIXME: what about OnlyShowIn */ + + /* FIXME: check if the keywords changed, if not, do + * nothing */ + + /* Perhaps a bit drastic */ + /* also this emits the CHANGED monitor signal */ + invalidate_folder_T (handle->info->root); + + /* the file changed monitor will happen by itself + * as the underlying file is changed */ + } else if (handle->write && + handle->entry != NULL && + handle->entry->type == ENTRY_FOLDER && + handle->is_directory_file) { + /* if we're monitoring this directory, emit the CHANGED + * monitor thing, it will also emit a changed on + * the file itself. It is better to emit changed + * just in case. */ + emit_monitor ((Folder *)(handle->entry), + GNOME_VFS_MONITOR_EVENT_CHANGED); + } + + whack_handle (handle); + + G_UNLOCK (vfolder_lock); + + return result; +} + +static void +fill_buffer (gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read) +{ + char *buf = buffer; + GnomeVFSFileSize i; + for (i = 0; i < num_bytes; i++) { + if (rand () % 32 == 0 || + i == num_bytes-1) + buf[i] = '\n'; + else + buf[i] = ((rand()>>4) % 94) + 32; + } + if (bytes_read != 0) + *bytes_read = i; +} + +static GnomeVFSResult +do_read (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + if (method_handle == (GnomeVFSMethodHandle *)method) { + if ((rand () >> 4) & 0x3) { + fill_buffer (buffer, num_bytes, bytes_read); + return GNOME_VFS_OK; + } else { + return GNOME_VFS_ERROR_EOF; + } + } + + result = (* parent_method->read) (parent_method, + handle->handle, + buffer, num_bytes, + bytes_read, + context); + + return result; +} + +static GnomeVFSResult +do_write (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gconstpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_written, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + if (method_handle == (GnomeVFSMethodHandle *)method) + return GNOME_VFS_OK; + + result = (* parent_method->write) (parent_method, + handle->handle, + buffer, num_bytes, + bytes_written, + context); + + return result; +} + + +static GnomeVFSResult +do_seek (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSSeekPosition whence, + GnomeVFSFileOffset offset, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + if (method_handle == (GnomeVFSMethodHandle *)method) + return GNOME_VFS_OK; + + result = (* parent_method->seek) (parent_method, + handle->handle, + whence, offset, + context); + + return result; +} + +static GnomeVFSResult +do_tell (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileOffset *offset_return) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + result = (* parent_method->tell) (parent_method, + handle->handle, + offset_return); + + return result; +} + + +static GnomeVFSResult +do_truncate_handle (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileSize where, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + if (method_handle == (GnomeVFSMethodHandle *)method) + return GNOME_VFS_OK; + + result = (* parent_method->truncate_handle) (parent_method, + handle->handle, + where, + context); + + return result; +} + +static GnomeVFSResult +do_truncate (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileSize where, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result = GNOME_VFS_OK; + VFolderInfo *info; + Entry *entry; + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + /* These can't be very nice FILE names */ + if (vuri.file == NULL || + vuri.ends_in_slash) + return GNOME_VFS_ERROR_INVALID_URI; + + if (vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + G_LOCK (vfolder_lock); + file_uri = desktop_uri_to_file_uri (info, + &vuri, + &entry, + NULL /* the_is_directory_file */, + NULL /* the_folder */, + TRUE /* privatize */, + &result, + context); + G_UNLOCK (vfolder_lock); + + if (file_uri == NULL) + return result; + + result = (* parent_method->truncate) (parent_method, + file_uri, + where, + context); + + gnome_vfs_uri_unref (file_uri); + + if (info->dirty) { + G_LOCK (vfolder_lock); + vfolder_info_write_user (info); + G_UNLOCK (vfolder_lock); + } + + if (entry->type == ENTRY_FILE) { + EntryFile *efile = (EntryFile *)entry; + + G_LOCK (vfolder_lock); + g_slist_free (efile->keywords); + efile->keywords = NULL; + G_UNLOCK (vfolder_lock); + } + + /* Perhaps a bit drastic, but oh well */ + invalidate_folder (info->root); + + return result; +} + +typedef struct _DirHandle DirHandle; +struct _DirHandle { + VFolderInfo *info; + Folder *folder; + + GnomeVFSFileInfoOptions options; + + /* List of Entries */ + GSList *list; + GSList *current; +}; + +static GnomeVFSResult +do_open_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + VFolderURI vuri; + DirHandle *dh; + Folder *folder; + VFolderInfo *info; + char *desktop_file; + + VFOLDER_URI_PARSE (uri, &vuri); + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + /* In the all- scheme just list all filenames */ + if (vuri.is_all_scheme) { + if (any_subdir (vuri.path)) + return GNOME_VFS_ERROR_NOT_FOUND; + + dh = g_new0 (DirHandle, 1); + dh->info = info; + dh->options = options; + dh->folder = NULL; + + G_LOCK (vfolder_lock); + dh->list = g_slist_copy (info->entries); + g_slist_foreach (dh->list, (GFunc)entry_ref, NULL); + dh->current = dh->list; + G_UNLOCK (vfolder_lock); + + *method_handle = (GnomeVFSMethodHandle*) dh; + return GNOME_VFS_OK; + } + + folder = resolve_folder (info, vuri.path, + FALSE /* ignore_basename */, + &result, context); + if (folder == NULL) + return result; + + /* Make sure we have the entries and sorted here */ + ensure_folder_sort (info, folder); + + dh = g_new0 (DirHandle, 1); + dh->info = info; + dh->options = options; + + G_LOCK (vfolder_lock); + dh->folder = (Folder *)entry_ref ((Entry *)folder); + dh->list = g_slist_copy (folder->entries); + g_slist_foreach (folder->entries, (GFunc)entry_ref, NULL); + G_UNLOCK (vfolder_lock); + + desktop_file = get_directory_file (info, folder); + if (desktop_file != NULL) { + EntryFile *efile = file_new (".directory"); + dh->list = g_slist_prepend (dh->list, efile); + g_free (desktop_file); + } + + dh->current = dh->list; + + *method_handle = (GnomeVFSMethodHandle*) dh; + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_close_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + DirHandle *dh; + + dh = (DirHandle*) method_handle; + + G_LOCK (vfolder_lock); + + g_slist_foreach (dh->list, (GFunc)entry_unref, NULL); + g_slist_free (dh->list); + dh->list = NULL; + + dh->current = NULL; + + if (dh->folder != NULL) + entry_unref ((Entry *)dh->folder); + dh->folder = NULL; + + dh->info = NULL; + + g_free (dh); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_read_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSContext *context) +{ + DirHandle *dh; + Entry *entry; + GnomeVFSFileInfoOptions options; + + dh = (DirHandle*) method_handle; + +read_directory_again: + + if (dh->current == NULL) { + return GNOME_VFS_ERROR_EOF; + } + + entry = dh->current->data; + dh->current = dh->current->next; + + options = dh->options; + + if (entry->type == ENTRY_FILE && + ((EntryFile *)entry)->filename != NULL) { + EntryFile *efile = (EntryFile *)entry; + char *furi = gnome_vfs_get_uri_from_local_path (efile->filename); + GnomeVFSURI *uri = gnome_vfs_uri_new (furi); + + /* we always get mime-type by forcing it below */ + if (options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE) + options &= ~GNOME_VFS_FILE_INFO_GET_MIME_TYPE; + + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_NONE; + + /* Get the file info for this */ + (* parent_method->get_file_info) (parent_method, + uri, + file_info, + options, + context); + + /* we ignore errors from this since the file_info just + * won't be filled completely if there's an error, that's all */ + + g_free (file_info->mime_type); + file_info->mime_type = g_strdup ("application/x-gnome-app-info"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + /* Now we wipe those fields we don't support */ + file_info->valid_fields &= ~(UNSUPPORTED_INFO_FIELDS); + + gnome_vfs_uri_unref (uri); + g_free (furi); + } else if (entry->type == ENTRY_FILE) { + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_NONE; + + file_info->name = g_strdup (entry->name); + GNOME_VFS_FILE_INFO_SET_LOCAL (file_info, TRUE); + + file_info->type = GNOME_VFS_FILE_TYPE_REGULAR; + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_TYPE; + + /* FIXME: Is this correct? isn't there an xdg mime type? */ + file_info->mime_type = g_strdup ("application/x-gnome-app-info"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + /* FIXME: get some ctime/mtime */ + } else /* ENTRY_FOLDER */ { + Folder *folder = (Folder *)entry; + + /* Skip empty folders if they have + * the flag set */ + if (folder->dont_show_if_empty) { + /* Make sure we have the entries */ + ensure_folder (dh->info, folder, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + + if (folder->entries == NULL) { + /* start this function over on the + * next item */ + goto read_directory_again; + } + } + + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_NONE; + + file_info->name = g_strdup (entry->name); + GNOME_VFS_FILE_INFO_SET_LOCAL (file_info, TRUE); + + file_info->type = GNOME_VFS_FILE_TYPE_DIRECTORY; + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_TYPE; + + file_info->mime_type = g_strdup ("x-directory/vfolder-desktop"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + file_info->ctime = dh->info->modification_time; + file_info->mtime = dh->info->modification_time; + file_info->valid_fields |= (GNOME_VFS_FILE_INFO_FIELDS_CTIME | + GNOME_VFS_FILE_INFO_FIELDS_MTIME); + } + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_get_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result = GNOME_VFS_OK; + Folder *folder; + VFolderInfo *info; + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + G_LOCK (vfolder_lock); + file_uri = desktop_uri_to_file_uri (info, + &vuri, + NULL /* the_entry */, + NULL /* the_is_directory_file */, + &folder, + FALSE /* privatize */, + &result, + context); + G_UNLOCK (vfolder_lock); + + if (file_uri == NULL && + result != GNOME_VFS_ERROR_IS_DIRECTORY) + return result; + + if (file_uri != NULL) { + /* we always get mime-type by forcing it below */ + if (options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE) + options &= ~GNOME_VFS_FILE_INFO_GET_MIME_TYPE; + + result = (* parent_method->get_file_info) (parent_method, + file_uri, + file_info, + options, + context); + + g_free (file_info->mime_type); + file_info->mime_type = g_strdup ("application/x-gnome-app-info"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + /* Now we wipe those fields we don't support */ + file_info->valid_fields &= ~(UNSUPPORTED_INFO_FIELDS); + + gnome_vfs_uri_unref (file_uri); + + return result; + } else if (folder != NULL) { + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_NONE; + + file_info->name = g_strdup (folder->entry.name); + GNOME_VFS_FILE_INFO_SET_LOCAL (file_info, TRUE); + + file_info->type = GNOME_VFS_FILE_TYPE_DIRECTORY; + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_TYPE; + + file_info->mime_type = g_strdup ("x-directory/vfolder-desktop"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + file_info->ctime = info->modification_time; + file_info->mtime = info->modification_time; + file_info->valid_fields |= (GNOME_VFS_FILE_INFO_FIELDS_CTIME | + GNOME_VFS_FILE_INFO_FIELDS_MTIME); + + return GNOME_VFS_OK; + } else { + return GNOME_VFS_ERROR_NOT_FOUND; + } +} + +static GnomeVFSResult +do_get_file_info_from_handle (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + if (method_handle == (GnomeVFSMethodHandle *)method) { + g_free (file_info->mime_type); + file_info->mime_type = g_strdup ("text/plain"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + return GNOME_VFS_OK; + } + + /* we always get mime-type by forcing it below */ + if (options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE) + options &= ~GNOME_VFS_FILE_INFO_GET_MIME_TYPE; + + result = (* parent_method->get_file_info_from_handle) (parent_method, + handle->handle, + file_info, + options, + context); + + /* any file is of the .desktop type */ + g_free (file_info->mime_type); + file_info->mime_type = g_strdup ("application/x-gnome-app-info"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + /* Now we wipe those fields we don't support */ + file_info->valid_fields &= ~(UNSUPPORTED_INFO_FIELDS); + + return result; +} + + +static gboolean +do_is_local (GnomeVFSMethod *method, + const GnomeVFSURI *uri) +{ + return TRUE; +} + +static void +try_free_folder_monitors_create_unlocked (VFolderInfo *info, + Folder *folder) +{ + GSList *li, *list; + + list = g_slist_copy (info->free_folder_monitors); + + for (li = list; li != NULL; li = li->next) { + FileMonitorHandle *handle = li->data; + Folder *f; + VFolderURI vuri; + GnomeVFSResult result; + + /* Evil! EVIL URI PARSING. this will eat a lot of stack if we + * have lots of free monitors */ + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + f = resolve_folder (info, + vuri.path, + FALSE /* ignore_basename */, + &result, + NULL); + + if (folder != f) + continue; + + info->free_folder_monitors = + g_slist_remove (info->free_folder_monitors, handle); + ((Entry *)folder)->monitors = + g_slist_prepend (((Entry *)folder)->monitors, handle); + + handle->exists = TRUE; + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *)handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_CREATED); + } +} + + +static GnomeVFSResult +do_make_directory (GnomeVFSMethod *method, + GnomeVFSURI *uri, + guint perm, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + VFolderInfo *info; + Folder *parent, *folder; + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + if (vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (info->user_filename == NULL || + info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + parent = resolve_folder (info, vuri.path, + TRUE /* ignore_basename */, + &result, context); + if (parent == NULL) + return result; + else if (parent->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + G_LOCK (vfolder_lock); + + folder = (Folder *)find_entry (parent->subfolders, + vuri.file); + if (folder != NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_FILE_EXISTS; + } + + folder = folder_new (vuri.file); + parent->subfolders = g_slist_append (parent->subfolders, folder); + folder->parent = parent; + parent->up_to_date = FALSE; + + try_free_folder_monitors_create_unlocked (info, folder); + + /* parent changed */ + emit_monitor (parent, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_remove_directory (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + Folder *folder; + VFolderInfo *info; + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + if (vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (info->user_filename == NULL || + info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + G_LOCK (vfolder_lock); + + folder = resolve_folder (info, vuri.path, + FALSE /* ignore_basename */, + &result, context); + if (folder == NULL) { + G_UNLOCK (vfolder_lock); + return result; + } + + if (folder->read_only || + (folder->parent != NULL && + folder->parent->read_only)) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_READ_ONLY; + } + + /* don't make removing directories easy */ + if (folder->desktop_file != NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY; + } + + /* Make sure we have the entries */ + ensure_folder_unlocked (info, folder, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + + /* don't make removing directories easy */ + if (folder->entries != NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY; + } + + emit_and_delete_monitor (info, folder); + + if (folder->only_unallocated) { + GSList *li = g_slist_find (info->unallocated_folders, + folder); + if (li != NULL) { + info->unallocated_folders = g_slist_delete_link + (info->unallocated_folders, li); + entry_unref ((Entry *)folder); + } + } + + if (folder == info->root) { + info->root = NULL; + entry_unref ((Entry *)folder); + info->root = folder_new ("Root"); + } else { + Folder *parent = folder->parent; + + g_assert (parent != NULL); + + parent->subfolders = + g_slist_remove (parent->subfolders, folder); + + parent->up_to_date = FALSE; + + entry_unref ((Entry *)folder); + + /* parent changed */ + emit_monitor (parent, GNOME_VFS_MONITOR_EVENT_CHANGED); + } + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; +} + +/* a fairly evil function that does the whole move bit by copy and + * remove */ +static GnomeVFSResult +long_move (GnomeVFSMethod *method, + VFolderURI *old_vuri, + VFolderURI *new_vuri, + gboolean force_replace, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + GnomeVFSMethodHandle *handle; + GnomeVFSURI *file_uri; + const char *path; + int fd; + char buf[BUFSIZ]; + int bytes; + VFolderInfo *info; + + info = get_vfolder_info (old_vuri->scheme, &result, context); + if (info == NULL) + return result; + + G_LOCK (vfolder_lock); + file_uri = desktop_uri_to_file_uri (info, + old_vuri, + NULL /* the_entry */, + NULL /* the_is_directory_file */, + NULL /* the_folder */, + FALSE /* privatize */, + &result, + context); + G_UNLOCK (vfolder_lock); + + if (file_uri == NULL) + return result; + + path = gnome_vfs_uri_get_path (file_uri); + if (path == NULL) { + gnome_vfs_uri_unref (file_uri); + return GNOME_VFS_ERROR_INVALID_URI; + } + + fd = open (path, O_RDONLY); + if (fd < 0) { + gnome_vfs_uri_unref (file_uri); + return gnome_vfs_result_from_errno (); + } + + gnome_vfs_uri_unref (file_uri); + + info->inhibit_write++; + + result = method->create (method, + &handle, + new_vuri->uri, + GNOME_VFS_OPEN_WRITE, + force_replace /* exclusive */, + 0600 /* perm */, + context); + if (result != GNOME_VFS_OK) { + close (fd); + info->inhibit_write--; + return result; + } + + while ((bytes = read (fd, buf, BUFSIZ)) > 0) { + GnomeVFSFileSize bytes_written = 0; + result = method->write (method, + handle, + buf, + bytes, + &bytes_written, + context); + if (result == GNOME_VFS_OK && + bytes_written != bytes) + result = GNOME_VFS_ERROR_NO_SPACE; + if (result != GNOME_VFS_OK) { + close (fd); + method->close (method, handle, context); + /* FIXME: is this completely correct ? */ + method->unlink (method, + new_vuri->uri, + context); + G_LOCK (vfolder_lock); + info->inhibit_write--; + vfolder_info_write_user (info); + G_UNLOCK (vfolder_lock); + return result; + } + } + + close (fd); + + result = method->close (method, handle, context); + if (result != GNOME_VFS_OK) { + G_LOCK (vfolder_lock); + info->inhibit_write--; + vfolder_info_write_user (info); + G_UNLOCK (vfolder_lock); + return result; + } + + result = method->unlink (method, old_vuri->uri, context); + + G_LOCK (vfolder_lock); + info->inhibit_write--; + vfolder_info_write_user (info); + G_UNLOCK (vfolder_lock); + + return result; +} + +static GnomeVFSResult +move_directory_file (VFolderInfo *info, + Folder *old_folder, + Folder *new_folder) +{ + if (old_folder->desktop_file == NULL) + return GNOME_VFS_ERROR_NOT_FOUND; + + /* "move" the desktop file */ + g_free (new_folder->desktop_file); + new_folder->desktop_file = old_folder->desktop_file; + old_folder->desktop_file = NULL; + + /* is this too drastic, it will requery the folder? */ + new_folder->up_to_date = FALSE; + old_folder->up_to_date = FALSE; + + emit_monitor (new_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + emit_monitor (old_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + + return GNOME_VFS_OK; +} + +static gboolean +is_sub (Folder *master, Folder *sub) +{ + GSList *li; + + for (li = master->subfolders; li != NULL; li = li->next) { + Folder *subfolder = li->data; + + if (subfolder == sub || + is_sub (subfolder, sub)) + return TRUE; + } + + return FALSE; +} + +static GnomeVFSResult +move_folder (VFolderInfo *info, + Folder *old_folder, Entry *old_entry, + Folder *new_folder, Entry *new_entry) +{ + Folder *source = (Folder *)old_entry; + Folder *target; + + if (new_entry != NULL && + new_entry->type != ENTRY_FOLDER) + return GNOME_VFS_ERROR_NOT_A_DIRECTORY; + + if (new_entry != NULL) { + target = (Folder *)new_entry; + } else { + target = new_folder; + } + + /* move to where we are, yay, we're done :) */ + if (source->parent == target) + return GNOME_VFS_OK; + + if (source == target || + is_sub (source, target)) + return GNOME_VFS_ERROR_LOOP; + + /* this will never happen, but we're paranoid */ + if (source->parent == NULL) + return GNOME_VFS_ERROR_LOOP; + + source->parent->subfolders = g_slist_remove (source->parent->subfolders, + source); + target->subfolders = g_slist_append (target->subfolders, + source); + + source->parent = target; + + source->up_to_date = FALSE; + target->up_to_date = FALSE; + + emit_monitor (source, GNOME_VFS_MONITOR_EVENT_CHANGED); + emit_monitor (target, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_move (GnomeVFSMethod *method, + GnomeVFSURI *old_uri, + GnomeVFSURI *new_uri, + gboolean force_replace, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + VFolderInfo *info; + Folder *old_folder, *new_folder; + Entry *old_entry, *new_entry; + gboolean old_is_directory_file, new_is_directory_file; + VFolderURI old_vuri, new_vuri; + + VFOLDER_URI_PARSE (old_uri, &old_vuri); + VFOLDER_URI_PARSE (new_uri, &new_vuri); + + if (old_vuri.file == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + if (old_vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + if (strcmp (old_vuri.scheme, new_vuri.scheme) != 0) + return GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM; + + info = get_vfolder_info (old_vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + old_entry = get_entry (&old_vuri, + &old_folder, + &old_is_directory_file, + &result, + context); + if (old_entry == NULL) + return result; + + if (old_folder != NULL && old_folder->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + new_entry = get_entry (&new_vuri, + &new_folder, + &new_is_directory_file, + &result, + context); + if (new_entry == NULL && new_folder == NULL) + return result; + + if (new_folder != NULL && new_folder->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + if (new_is_directory_file != old_is_directory_file) { + /* this will do another set of lookups + * perhaps this can be done in a nicer way, + * but is this the common case? I don't think so */ + return long_move (method, &old_vuri, &new_vuri, + force_replace, context); + } + + if (new_is_directory_file) { + g_assert (old_entry != NULL); + g_assert (new_entry != NULL); + G_LOCK (vfolder_lock); + result = move_directory_file (info, + (Folder *)old_entry, + (Folder *)new_entry); + G_UNLOCK (vfolder_lock); + return result; + } + + if (old_entry->type == ENTRY_FOLDER) { + G_LOCK (vfolder_lock); + result = move_folder (info, + old_folder, old_entry, + new_folder, new_entry); + G_UNLOCK (vfolder_lock); + return result; + } + + /* move into self, just whack the old one */ + if (old_entry == new_entry) { + /* same folder */ + if (new_folder == old_folder) + return GNOME_VFS_OK; + + if ( ! force_replace) + return GNOME_VFS_ERROR_FILE_EXISTS; + + G_LOCK (vfolder_lock); + + remove_file (old_folder, old_vuri.file); + + old_folder->entries = g_slist_remove (old_folder->entries, + old_entry); + entry_unref (old_entry); + + emit_monitor (old_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; + } + + /* this is a simple move */ + if (new_entry == NULL || + new_entry->type == ENTRY_FOLDER) { + if (new_entry != NULL) { + new_folder = (Folder *)new_entry; + } else { + /* a file and a totally different one */ + if (strcmp (new_vuri.file, old_entry->name) != 0) { + /* yay, a long move */ + /* this will do another set of lookups + * perhaps this can be done in a nicer way, + * but is this the common case? I don't think + * so */ + return long_move (method, &old_vuri, &new_vuri, + force_replace, context); + } + } + + /* same folder */ + if (new_folder == old_folder) + return GNOME_VFS_OK; + + G_LOCK (vfolder_lock); + + remove_file (old_folder, old_entry->name); + add_file (new_folder, old_entry->name); + + new_folder->entries = g_slist_prepend (new_folder->entries, + old_entry); + entry_ref (old_entry); + new_folder->sorted = FALSE; + + old_folder->entries = g_slist_remove (old_folder->entries, + old_entry); + entry_unref (old_entry); + + emit_monitor (new_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + emit_monitor (old_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; + } + + /* do we EVER get here? */ + + /* this will do another set of lookups + * perhaps this can be done in a nicer way, + * but is this the common case? I don't think so */ + return long_move (method, &old_vuri, &new_vuri, + force_replace, context); +} + +static GnomeVFSResult +do_unlink (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + Entry *entry; + Folder *the_folder; + gboolean is_directory_file; + VFolderInfo *info; + VFolderURI vuri; + GSList *li; + + VFOLDER_URI_PARSE (uri, &vuri); + + if (vuri.file == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + if (vuri.is_all_scheme == TRUE) + return GNOME_VFS_ERROR_READ_ONLY; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + else if (info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + entry = get_entry (&vuri, + &the_folder, + &is_directory_file, + &result, context); + if (entry == NULL) + return result; + else if (the_folder != NULL && + the_folder->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + if (entry->type == ENTRY_FOLDER && + is_directory_file) { + Folder *folder = (Folder *)entry; + + if (folder->desktop_file == NULL) + return GNOME_VFS_ERROR_NOT_FOUND; + + G_LOCK (vfolder_lock); + + g_free (folder->desktop_file); + folder->desktop_file = NULL; + + emit_monitor (folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; + } else if (entry->type == ENTRY_FOLDER) { + return GNOME_VFS_ERROR_IS_DIRECTORY; + } else if (the_folder == NULL) { + return GNOME_VFS_ERROR_NOT_FOUND; + } + + G_LOCK (vfolder_lock); + + the_folder->entries = g_slist_remove (the_folder->entries, + entry); + entry_unref (entry); + + remove_file (the_folder, vuri.file); + + emit_monitor (the_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + + /* evil, we must remove this from the unallocated folders as well + * so that it magically doesn't appear there. But it's not so simple. + * We only want to remove it if it isn't in that folder already. */ + for (li = info->unallocated_folders; + li != NULL; + li = li->next) { + Folder *folder = li->data; + GSList *l; + + /* This is actually really evil since ensuring + * an unallocated folder clears all other unallocated + * folders in it's wake. I'm not sure it's worth + * optimizing however */ + ensure_folder_unlocked (info, folder, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + l = g_slist_find (folder->entries, entry); + if (l == NULL) { + remove_file (folder, vuri.file); + } + } + + emit_file_deleted_monitor (info, entry, the_folder); + + /* FIXME: if this was a user file and this is the only + * reference to it, unlink it. */ + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_check_same_fs (GnomeVFSMethod *method, + GnomeVFSURI *source_uri, + GnomeVFSURI *target_uri, + gboolean *same_fs_return, + GnomeVFSContext *context) +{ + VFolderURI source_vuri, target_vuri; + + *same_fs_return = FALSE; + + VFOLDER_URI_PARSE (source_uri, &source_vuri); + VFOLDER_URI_PARSE (target_uri, &target_vuri); + + if (strcmp (source_vuri.scheme, target_vuri.scheme) != 0 || + source_vuri.is_all_scheme != target_vuri.is_all_scheme) + *same_fs_return = FALSE; + else + *same_fs_return = TRUE; + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_set_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + const GnomeVFSFileInfo *info, + GnomeVFSSetFileInfoMask mask, + GnomeVFSContext *context) +{ + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + if (vuri.file == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + if (mask & GNOME_VFS_SET_FILE_INFO_NAME) { + GnomeVFSResult result = GNOME_VFS_OK; + char *dirname = gnome_vfs_uri_extract_dirname (uri); + GnomeVFSURI *new_uri = gnome_vfs_uri_dup (uri); + + G_LOCK (vfolder_lock); + g_free (new_uri->text); + new_uri->text = g_build_path ("/", dirname, info->name, NULL); + G_UNLOCK (vfolder_lock); + + result = do_move (method, + uri, + new_uri, + FALSE /* force_replace */, + context); + + g_free (dirname); + gnome_vfs_uri_unref (new_uri); + return result; + } else { + /* We don't support setting any of this other permission, + * times and all that voodoo */ + return GNOME_VFS_ERROR_NOT_SUPPORTED; + } +} + +static GnomeVFSResult +do_monitor_add (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle_return, + GnomeVFSURI *uri, + GnomeVFSMonitorType monitor_type) +{ + VFolderInfo *info; + VFolderURI vuri; + GnomeVFSResult result; + Folder *folder; + Entry *entry; + GnomeVFSURI *file_uri; + FileMonitorHandle *handle; + gboolean is_directory_file; + + VFOLDER_URI_PARSE (uri, &vuri); + + info = get_vfolder_info (vuri.scheme, &result, NULL); + if (info == NULL) + return result; + + if (monitor_type == GNOME_VFS_MONITOR_DIRECTORY) { + G_LOCK (vfolder_lock); + + folder = resolve_folder (info, + vuri.path, + FALSE /* ignore_basename */, + &result, + NULL); + + handle = g_new0 (FileMonitorHandle, 1); + handle->refcount = 2; + handle->uri = gnome_vfs_uri_dup (uri); + handle->dir_monitor = TRUE; + handle->handle = NULL; + handle->filename = NULL; + + if (folder == NULL) { + handle->exists = FALSE; + info->free_folder_monitors = + g_slist_prepend (info->free_folder_monitors, + handle); + } else { + handle->exists = TRUE; + ((Entry *)folder)->monitors = + g_slist_prepend (((Entry *)folder)->monitors, + handle); + } + + info->folder_monitors = + g_slist_prepend (info->folder_monitors, handle); + + G_UNLOCK (vfolder_lock); + + *method_handle_return = (GnomeVFSMethodHandle *) handle; + + return GNOME_VFS_OK; + } else { + /* These can't be very nice FILE names */ + if (vuri.file == NULL || + vuri.ends_in_slash) + return GNOME_VFS_ERROR_INVALID_URI; + + G_LOCK (vfolder_lock); + file_uri = desktop_uri_to_file_uri (info, + &vuri, + &entry, + &is_directory_file, + NULL /* the_folder */, + FALSE, + &result, + NULL); + + handle = g_new0 (FileMonitorHandle, 1); + handle->refcount = 2; + handle->uri = gnome_vfs_uri_dup (uri); + handle->dir_monitor = FALSE; + handle->handle = NULL; + handle->filename = g_strdup (vuri.file); + handle->is_directory_file = is_directory_file; + + info->file_monitors = + g_slist_prepend (info->file_monitors, handle); + + + if (file_uri == NULL) { + handle->exists = FALSE; + info->free_file_monitors = + g_slist_prepend (info->free_file_monitors, + handle); + } else { + char *uri_string = gnome_vfs_uri_to_string (file_uri, 0); + handle->exists = TRUE; + gnome_vfs_monitor_add (&(handle->handle), + uri_string, + GNOME_VFS_MONITOR_FILE, + file_monitor, + handle); + g_free (uri_string); + + entry->monitors = g_slist_prepend (entry->monitors, + handle); + gnome_vfs_uri_unref (file_uri); + } + + *method_handle_return = (GnomeVFSMethodHandle *) handle; + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; + } +} + +static GnomeVFSResult +do_monitor_cancel (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle) +{ + FileMonitorHandle *handle; + VFolderInfo *info; + VFolderURI vuri; + GnomeVFSResult result; + Folder *folder; + GSList *li; + + handle = (FileMonitorHandle *)method_handle; + + /* FIXME: is this correct? */ + if (method_handle == NULL) + return GNOME_VFS_OK; + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + info = get_vfolder_info (vuri.scheme, &result, NULL); + if (info == NULL) + return result; + + if (handle->dir_monitor) { + G_LOCK (vfolder_lock); + + folder = resolve_folder (info, + vuri.path, + FALSE /* ignore_basename */, + &result, + NULL); + + for (li = info->folder_monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + if (h != handle) + continue; + info->folder_monitors = g_slist_delete_link + (info->folder_monitors, li); + file_monitor_handle_unref_unlocked (h); + break; + } + + if (folder == NULL) { + for (li = info->free_folder_monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *h = li->data; + if (h != handle) + continue; + info->free_folder_monitors = g_slist_delete_link + (info->free_folder_monitors, li); + file_monitor_handle_unref_unlocked (h); + break; + } + } else { + for (li = ((Entry *)folder)->monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *h = li->data; + if (h != handle) + continue; + ((Entry *)folder)->monitors = + g_slist_delete_link + (((Entry *)folder)->monitors, li); + file_monitor_handle_unref_unlocked (h); + break; + } + } + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; + } else { + G_LOCK (vfolder_lock); + + for (li = info->file_monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + if (h != handle) + continue; + info->file_monitors = g_slist_delete_link + (info->file_monitors, li); + file_monitor_handle_unref_unlocked (h); + break; + } + + for (li = info->free_file_monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *h = li->data; + if (h != handle) + continue; + info->free_file_monitors = g_slist_delete_link + (info->free_file_monitors, li); + file_monitor_handle_unref_unlocked (h); + break; + } + + for (li = info->entries; li != NULL; li = li->next) { + Entry *e = li->data; + GSList *link = g_slist_find (e->monitors, handle); + + if (link == NULL) + continue; + link->data = NULL; + e->monitors = g_slist_delete_link (e->monitors, link); + + file_monitor_handle_unref_unlocked (handle); + break; + } + + G_UNLOCK (vfolder_lock); + + /* Note: last unref of our monitor will cancel the + * underlying handle */ + + return GNOME_VFS_OK; + } +} + + +/* gnome-vfs bureaucracy */ + +static GnomeVFSMethod method = { + sizeof (GnomeVFSMethod), + do_open, + NULL, /* do_create, */ + do_close, + do_read, + NULL, /* do_write, */ + do_seek, + do_tell, + NULL, /* do_truncate_handle, */ + do_open_directory, + do_close_directory, + do_read_directory, + do_get_file_info, + do_get_file_info_from_handle, + do_is_local, + NULL, /* do_make_directory, */ + NULL, /* do_remove_directory, */ + NULL, /* do_move, */ + NULL, /* do_unlink, */ + do_check_same_fs, + NULL, /* do_set_file_info, */ + NULL, /* do_truncate, */ + NULL /* find_directory */, + NULL /* create_symbolic_link */, + do_monitor_add, + do_monitor_cancel +}; + +GnomeVFSMethod * +vfs_module_init (const char *method_name, + const char *args) +{ + parent_method = gnome_vfs_method_get ("file"); + + if (parent_method == NULL) { + g_error ("Could not find 'file' method for gnome-vfs"); + return NULL; + } + + return &method; +} + +void +vfs_module_shutdown (GnomeVFSMethod *method) +{ + if (infos == NULL) + return; + + g_hash_table_destroy (infos); + infos = NULL; +} diff --git a/modules/vfolder-desktop-method.c.moved-menu-files b/modules/vfolder-desktop-method.c.moved-menu-files new file mode 100644 index 0000000..d945be9 --- /dev/null +++ b/modules/vfolder-desktop-method.c.moved-menu-files @@ -0,0 +1,6130 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: 8; c-basic-offset: 8 -*- */ + +/* vfolder-desktop-method.c + + Copyright (C) 2001 Red Hat, Inc. + Copyright (C) 2001 The Dark Prince + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/* URI scheme for reading the "applications:" vfolder and other + * vfolder schemes. Lots of code stolen from the original desktop + * reading URI scheme. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +/* Debugging foo: */ +/*#define D(x) x */ +#define D(x) ; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#define DOT_GNOME ".gnome2" + +typedef struct _VFolderInfo VFolderInfo; +typedef struct _Query Query; +typedef struct _QueryKeyword QueryKeyword; +typedef struct _QueryFilename QueryFilename; +typedef struct _Entry Entry; +typedef struct _Folder Folder; +typedef struct _EntryFile EntryFile; +typedef struct _Keyword Keyword; +typedef struct _FileMonitorHandle FileMonitorHandle; +typedef struct _StatLoc StatLoc; +typedef struct _VFolderURI VFolderURI; + +/* TODO before 2.0: */ +/* FIXME: also check/monitor desktop_dirs like we do the vfolder + * file and the item dirs */ +/* FIXME: check if thread locks are not completely on crack which + * is likely given my experience with threads */ +/* FIXME: use filename locking, currently we are full of races if + * multiple processes write to this filesystem */ +/* FIXME: implement monitors */ + +/* TODO for later (star trek future): */ +/* FIXME: Maybe when chaining to file:, we should call the gnome-vfs wrapper + * functions, instead of the file: methods directly. */ +/* FIXME: related to the above: we should support things being on non + * file: filesystems. Such as having the vfolder info file on http + * somewhere or some such nonsense :) */ + +static GnomeVFSMethod *parent_method = NULL; + +static GHashTable *infos = NULL; + +/* Note: I have no clue about how to write thread safe code and this + * is my first attempt, so it's probably wrong + * -George */ +G_LOCK_DEFINE_STATIC (vfolder_lock); + +/* Note: all keywords are quarks */ +/* Note: basenames are unique */ + +#define UNSUPPORTED_INFO_FIELDS (GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS | \ + GNOME_VFS_FILE_INFO_FIELDS_DEVICE | \ + GNOME_VFS_FILE_INFO_FIELDS_INODE | \ + GNOME_VFS_FILE_INFO_FIELDS_LINK_COUNT | \ + GNOME_VFS_FILE_INFO_FIELDS_ATIME) + + +enum { + QUERY_OR, + QUERY_AND, + QUERY_KEYWORD, + QUERY_FILENAME +}; + +struct _Query { + int type; + gboolean not; + GSList *queries; +}; + +struct _QueryKeyword { + int type; + gboolean not; + GQuark keyword; +}; + +struct _QueryFilename { + int type; + gboolean not; + char *filename; +}; + +enum { + ENTRY_FILE, + ENTRY_FOLDER +}; + +struct _Entry { + int type; + int refcount; + int alloc; /* not really useful for folders, + but oh well, whatever. It's the number + of times this is queried in some directory, + used for the Unallocated query type */ + char *name; + + GSList *monitors; +}; + +struct _EntryFile { + Entry entry; + + char *filename; + gboolean per_user; + GSList *keywords; + + gboolean implicit_keywords; /* the keywords were added by us */ +}; + +struct _Folder { + Entry entry; + + Folder *parent; + + char *desktop_file; /* the .directory file */ + + Query *query; + + /* The following is for per file + * access */ + /* excluded by filename */ + GHashTable *excludes; + /* included by filename */ + GSList *includes; + GHashTable *includes_ht; + + GSList *subfolders; + + /* Some flags */ + gboolean read_only; + gboolean dont_show_if_empty; + gboolean only_unallocated; /* include only unallocated items */ + + /* lazily done, will run query only when it + * needs to */ + gboolean up_to_date; + gboolean sorted; + GSList *entries; +}; + +struct _StatLoc { + time_t ctime; + time_t last_stat; + gboolean trigger_next; /* if true, next check will fail */ + char name[1]; /* the structure will be long enough to + fit name */ +}; + +struct _VFolderInfo { + char *scheme; + + char *filename; + char *user_filename; + time_t user_filename_last_write; + char *desktop_dir; /* directory with .directorys */ + char *user_desktop_dir; /* directory with .directorys */ + gboolean user_file_active; /* if using user_filename and + not filename */ + + GSList *item_dirs; + char *user_item_dir; /* dir where user changes to + items are stored */ + + /* old style dirs to merge in */ + GSList *merge_dirs; + + /* if entries are valid, else + * they need to be (re)read */ + gboolean entries_valid; + + GSList *entries; + + /* entry hash by basename */ + GHashTable *entries_ht; + + /* The root folder */ + Folder *root; + + /* The unallocated folders, the folder which only + * include unallocated items */ + GSList *unallocated_folders; + + /* some flags */ + gboolean read_only; + + gboolean dirty; + + int inhibit_write; + + /* change monitoring stuff */ + GnomeVFSMonitorHandle *filename_monitor; + GnomeVFSMonitorHandle *user_filename_monitor; + + /* stat locations (in case we aren't monitoring) */ + StatLoc *filename_statloc; + StatLoc *user_filename_statloc; + + /* for .directory dirs */ + /* FIXME: */GnomeVFSMonitorHandle *desktop_dir_monitor; + /* FIXME: */GnomeVFSMonitorHandle *user_desktop_dir_monitor; + + /* stat locations (in case we aren't monitoring) */ + /* FIXME: */StatLoc *desktop_dir_statloc; + /* FIXME: */StatLoc *user_desktop_dir_statloc; + + /* FIXME: */GSList *file_monitors; /* FileMonitorHandle */ + /* FIXME: */GSList *free_file_monitors; /* FileMonitorHandle */ + GSList *folder_monitors; /* FileMonitorHandle */ + GSList *free_folder_monitors; /* FileMonitorHandle */ + + GSList *item_dir_monitors; /* GnomeVFSMonitorHandle */ + + /* item dirs to stat */ + GSList *stat_dirs; + + /* ctime for folders */ + time_t modification_time; + + guint reread_queue; +}; + +struct _FileMonitorHandle { + int refcount; + gboolean exists; + gboolean dir_monitor; /* TRUE if dir, FALSE if file */ + GnomeVFSURI *uri; + GnomeVFSMonitorHandle *handle; /* A real handle if we're monitoring + an actual file here, or NULL */ + char *filename; /* Just the basename, used in the free_file_list */ + gboolean is_directory_file; +}; + +struct _VFolderURI { + const gchar *scheme; + gboolean is_all_scheme; + gboolean ends_in_slash; + gchar *path; + gchar *file; + GnomeVFSURI *uri; +}; + + +static Entry * entry_ref (Entry *entry); +static Entry * entry_ref_alloc (Entry *entry); +static void entry_unref (Entry *entry); +static void entry_unref_dealloc (Entry *entry); +static void query_destroy (Query *query); +static void ensure_folder (VFolderInfo *info, + Folder *folder, + gboolean subfolders, + Folder *except, + gboolean ignore_unallocated); +static void ensure_folder_unlocked (VFolderInfo *info, + Folder *folder, + gboolean subfolders, + Folder *except, + gboolean ignore_unallocated); +/* An EVIL function for quick reading of .desktop files, + * only reads in one or two keys, but that's ALL we need */ +static void readitem_entry (const char *filename, + const char *key1, + char **result1, + const char *key2, + char **result2); +static gboolean vfolder_info_reload (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context, + gboolean force_read_items); +static gboolean vfolder_info_reload_unlocked (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context, + gboolean force_read_items); +static void invalidate_folder_subfolders (Folder *folder, + gboolean lock_taken); +static Folder * resolve_folder (VFolderInfo *info, + const char *path, + gboolean ignore_basename, + GnomeVFSResult *result, + GnomeVFSContext *context); +static gboolean vfolder_info_read_items (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context); + +/* assumes vuri->path already set */ +static gboolean +vfolder_uri_parse_internal (GnomeVFSURI *uri, VFolderURI *vuri) +{ + vuri->scheme = (gchar *) gnome_vfs_uri_get_scheme (uri); + + vuri->ends_in_slash = FALSE; + + if (strncmp (vuri->scheme, "all-", strlen ("all-")) == 0) { + vuri->scheme += strlen ("all-"); + vuri->is_all_scheme = TRUE; + } else + vuri->is_all_scheme = FALSE; + + if (vuri->path != NULL) { + int last_slash = strlen (vuri->path) - 1; + char *first; + + /* Note: This handling of paths is somewhat evil, may need a + * bit of a rework */ + + /* kill leading slashes, that is make sure there is + * only one */ + for (first = vuri->path; *first == '/'; first++) + ; + if (first != vuri->path) { + first--; + vuri->path = first; + } + + /* kill trailing slashes (leave first if all slashes) */ + while (last_slash > 0 && vuri->path [last_slash] == '/') { + vuri->path [last_slash--] = '\0'; + vuri->ends_in_slash = TRUE; + } + + /* get basename start */ + while (last_slash >= 0 && vuri->path [last_slash] != '/') + last_slash--; + + if (last_slash > -1) + vuri->file = vuri->path + last_slash + 1; + else + vuri->file = vuri->path; + + if (vuri->file[0] == '\0' && + strcmp (vuri->path, "/") == 0) { + vuri->file = NULL; + } + } else { + vuri->ends_in_slash = TRUE; + vuri->path = "/"; + vuri->file = NULL; + } + + vuri->uri = uri; + + return TRUE; +} + +#define VFOLDER_URI_PARSE(_uri, _vuri) { \ + gchar *path; \ + path = gnome_vfs_unescape_string ((_uri)->text, G_DIR_SEPARATOR_S); \ + if (path != NULL) { \ + (_vuri)->path = g_alloca (strlen (path) + 1); \ + strcpy ((_vuri)->path, path); \ + g_free (path); \ + } else { \ + (_vuri)->path = NULL; \ + } \ + vfolder_uri_parse_internal ((_uri), (_vuri)); \ +} + +static FileMonitorHandle * +file_monitor_handle_ref_unlocked (FileMonitorHandle *h) +{ + h->refcount ++; + return h; +} + +static void +file_monitor_handle_unref_unlocked (FileMonitorHandle *h) +{ + h->refcount --; + if (h->refcount == 0) { + gnome_vfs_uri_unref (h->uri); + h->uri = NULL; + + g_free (h->filename); + h->filename = NULL; + + if (h->handle != NULL) { + gnome_vfs_monitor_cancel (h->handle); + h->handle = NULL; + } + } +} + +/* This includes the .directory files */ +static void +emit_monitor (Folder *folder, int type) +{ + GSList *li; + for (li = ((Entry *)folder)->monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *handle = li->data; + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *) handle, + handle->uri, type); + } +} + +static void +emit_file_deleted_monitor (VFolderInfo *info, Entry *entry, Folder *folder) +{ + GSList *li; + for (li = entry->monitors; + li != NULL; + li = li->next) { + VFolderURI vuri; + Folder *f; + GnomeVFSResult result; + FileMonitorHandle *handle = li->data; + + /* Evil! EVIL URI PARSING. this will eat a lot of + * stack if we have lots of monitors */ + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + f = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + + if (f == folder) + gnome_vfs_monitor_callback + ((GnomeVFSMethodHandle *) handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_DELETED); + } +} + +static void +emit_and_delete_monitor (VFolderInfo *info, Folder *folder) +{ + GSList *li; + for (li = ((Entry *)folder)->monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *handle = li->data; + li->data = NULL; + + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *) handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_DELETED); + + if (handle->dir_monitor) + info->free_folder_monitors = + g_slist_prepend (info->free_folder_monitors, + handle); + else + info->free_file_monitors = + g_slist_prepend (info->free_file_monitors, + handle); + } + g_slist_free (((Entry *)folder)->monitors); + ((Entry *)folder)->monitors = NULL; +} + +static gboolean +check_ext (const char *name, const char *ext_check) +{ + const char *ext; + + ext = strrchr (name, '.'); + if (ext == NULL || + strcmp (ext, ext_check) != 0) + return FALSE; + else + return TRUE; +} + +static StatLoc * +bake_statloc (const char *name, + time_t curtime) +{ + struct stat s; + StatLoc *sl = NULL; + if (stat (name, &s) != 0) { + if (errno == ENOENT) { + sl = g_malloc0 (sizeof (StatLoc) + + strlen (name) + 1); + sl->last_stat = curtime; + sl->ctime = 0; + sl->trigger_next = FALSE; + strcpy (sl->name, name); + } + return sl; + } + + sl = g_malloc0 (sizeof (StatLoc) + + strlen (name) + 1); + sl->last_stat = curtime; + sl->ctime = s.st_ctime; + sl->trigger_next = FALSE; + strcpy (sl->name, name); + + return sl; +} + +/* returns FALSE if we must reread */ +static gboolean +check_statloc (StatLoc *sl, + time_t curtime) +{ + struct stat s; + + if (sl->trigger_next) { + sl->trigger_next = FALSE; + return FALSE; + } + + /* don't stat more then once every 3 seconds */ + if (curtime <= sl->last_stat + 3) + return TRUE; + + sl->last_stat = curtime; + + if (stat (sl->name, &s) != 0) { + if (errno == ENOENT && + sl->ctime == 0) + return TRUE; + else + return FALSE; + } + + if (sl->ctime == s.st_ctime) + return TRUE; + else + return FALSE; +} + +static gboolean +ensure_dir (const char *dirname, gboolean ignore_basename) +{ + char *parsed, *p; + + if (dirname == NULL) + return FALSE; + + if (ignore_basename) + parsed = g_path_get_dirname (dirname); + else + parsed = g_strdup (dirname); + + if (g_file_test (parsed, G_FILE_TEST_IS_DIR)) { + g_free (parsed); + return TRUE; + } + + p = strchr (parsed, '/'); + if (p == parsed) + p = strchr (p+1, '/'); + + while (p != NULL) { + *p = '\0'; + if (mkdir (parsed, 0700) != 0 && + errno != EEXIST) { + g_free (parsed); + return FALSE; + } + *p = '/'; + p = strchr (p+1, '/'); + } + + if (mkdir (parsed, 0700) != 0 && + errno != EEXIST) { + g_free (parsed); + return FALSE; + } + + g_free (parsed); + return TRUE; +} + +/* check for any directory name other then root */ +static gboolean +any_subdir (const char *dirname) +{ + const char *p; + if (dirname == NULL) + return FALSE; + + for (p = dirname; *p != '\0'; p++) { + if (*p != '/') { + return TRUE; + } + } + return FALSE; +} + +static void +destroy_entry_file (EntryFile *efile) +{ + if (efile == NULL) + return; + + g_free (efile->filename); + efile->filename = NULL; + + g_slist_free (efile->keywords); + efile->keywords = NULL; + + g_free (efile); +} + +static void +destroy_folder (Folder *folder) +{ + GSList *list; + + if (folder == NULL) + return; + + if (folder->parent != NULL) { + folder->parent->subfolders = + g_slist_remove (folder->parent->subfolders, folder); + folder->parent->up_to_date = FALSE; + folder->parent = NULL; + } + + g_free (folder->desktop_file); + folder->desktop_file = NULL; + + query_destroy (folder->query); + folder->query = NULL; + + if (folder->excludes != NULL) { + g_hash_table_destroy (folder->excludes); + folder->excludes = NULL; + } + + g_slist_foreach (folder->includes, (GFunc)g_free, NULL); + g_slist_free (folder->includes); + folder->includes = NULL; + if (folder->includes_ht != NULL) { + g_hash_table_destroy (folder->includes_ht); + folder->includes_ht = NULL; + } + + list = folder->subfolders; + folder->subfolders = NULL; + g_slist_foreach (list, (GFunc)entry_unref, NULL); + g_slist_free (list); + + list = folder->entries; + folder->entries = NULL; + g_slist_foreach (list, (GFunc)entry_unref, NULL); + g_slist_free (list); + + g_free (folder); +} + +static Entry * +entry_ref (Entry *entry) +{ + if (entry != NULL) + entry->refcount++; + return entry; +} + +static Entry * +entry_ref_alloc (Entry *entry) +{ + entry_ref (entry); + + if (entry != NULL) + entry->alloc++; + + return entry; +} + +static void +entry_unref (Entry *entry) +{ + if (entry == NULL) + return; + + entry->refcount--; + + if (entry->refcount == 0) { + g_free (entry->name); + entry->name = NULL; + + g_slist_foreach (entry->monitors, + (GFunc)file_monitor_handle_unref_unlocked, + NULL); + g_slist_free (entry->monitors); + entry->monitors = NULL; + + if (entry->type == ENTRY_FILE) + destroy_entry_file ((EntryFile *)entry); + else /* ENTRY_FOLDER */ + destroy_folder ((Folder *)entry); + } +} + +static void +entry_unref_dealloc (Entry *entry) +{ + if (entry != NULL) { + entry->alloc --; + entry_unref (entry); + } +} + +/* Handles ONLY files, not dirs */ +/* Also allocates the entries as well as refs them */ +static GSList * +alloc_entries_from_files (VFolderInfo *info, GSList *filenames) +{ + GSList *li; + GSList *files; + + files = NULL; + for (li = filenames; li != NULL; li = li->next) { + char *filename = li->data; + GSList *entry_list = g_hash_table_lookup (info->entries_ht, filename); + if (entry_list != NULL) + files = g_slist_prepend (files, + entry_ref_alloc (entry_list->data)); + } + + return files; +} + +static gboolean +matches_query (VFolderInfo *info, + Folder *folder, + EntryFile *efile, + Query *query) +{ + GSList *li; + + if (query == NULL) + return TRUE; + +#define INVERT_IF_NEEDED(val) (query->not ? !(val) : (val)) + switch (query->type) { + case QUERY_OR: + for (li = query->queries; li != NULL; li = li->next) { + Query *subquery = li->data; + if (matches_query (info, folder, efile, subquery)) + return INVERT_IF_NEEDED (TRUE); + } + return INVERT_IF_NEEDED (FALSE); + case QUERY_AND: + for (li = query->queries; li != NULL; li = li->next) { + Query *subquery = li->data; + if ( ! matches_query (info, folder, efile, subquery)) + return INVERT_IF_NEEDED (FALSE); + } + return INVERT_IF_NEEDED (TRUE); + case QUERY_KEYWORD: + { + QueryKeyword *qkeyword = (QueryKeyword *)query; + for (li = efile->keywords; li != NULL; li = li->next) { + GQuark keyword = GPOINTER_TO_INT (li->data); + if (keyword == qkeyword->keyword) + return INVERT_IF_NEEDED (TRUE); + } + return INVERT_IF_NEEDED (FALSE); + } + case QUERY_FILENAME: + { + QueryFilename *qfilename = (QueryFilename *)query; + if (strcmp (qfilename->filename, ((Entry *)efile)->name) == 0) { + return INVERT_IF_NEEDED (TRUE); + } else { + return INVERT_IF_NEEDED (FALSE); + } + } + } +#undef INVERT_IF_NEEDED + g_assert_not_reached (); + /* huh? */ + return FALSE; +} + +static void +dump_unallocated_folders (Folder *folder) +{ + GSList *li; + for (li = folder->subfolders; li != NULL; li = li->next) + dump_unallocated_folders (li->data); + + if (folder->only_unallocated && + folder->entries != NULL) { + g_slist_foreach (folder->entries, + (GFunc)entry_unref_dealloc, NULL); + g_slist_free (folder->entries); + folder->entries = NULL; + } +} + +/* Run query, allocs and refs the entries */ +static void +append_query (VFolderInfo *info, Folder *folder) +{ + GSList *li; + + if (folder->query == NULL && + ! folder->only_unallocated) + return; + + if (folder->only_unallocated) { + /* dump all folders that use unallocated + * items only. This sucks if you keep + * reading one and then another such + * folder, but oh well, life sucks for + * you then, but at least you get + * consistent results */ + dump_unallocated_folders (info->root); + + /* ensure all other folders, so that + * after this we know which ones are + * unallocated */ + ensure_folder_unlocked (info, + info->root, + TRUE /* subfolders */, + folder /* except */, + /* avoid infinite loops */ + TRUE /* ignore_unallocated */); + } + + for (li = info->entries; li != NULL; li = li->next) { + Entry *entry = li->data; + + if (/* if not file */ + entry->type != ENTRY_FILE || + /* if already included */ + (folder->includes_ht != NULL && + g_hash_table_lookup (folder->includes_ht, + entry->name) != NULL)) + continue; + + if (folder->only_unallocated && + entry->alloc != 0) + continue; + + if (matches_query (info, folder, (EntryFile *)entry, + folder->query)) + folder->entries = g_slist_prepend + (folder->entries, entry_ref_alloc (entry)); + } +} + +/* get entries in folder */ +/* FIXME: support cancellation here */ +static void +ensure_folder_unlocked (VFolderInfo *info, + Folder *folder, + gboolean subfolders, + Folder *except, + gboolean ignore_unallocated) +{ + if (subfolders) { + GSList *li; + for (li = folder->subfolders; li != NULL; li = li->next) + ensure_folder_unlocked (info, li->data, subfolders, + except, ignore_unallocated); + } + + if (except == folder) + return; + + if (ignore_unallocated && + folder->only_unallocated) + return; + + if (folder->up_to_date) + return; + + if (folder->entries != NULL) { + g_slist_foreach (folder->entries, + (GFunc)entry_unref_dealloc, NULL); + g_slist_free (folder->entries); + folder->entries = NULL; + } + + /* Include includes */ + folder->entries = alloc_entries_from_files (info, folder->includes); + + /* Run query */ + append_query (info, folder); + + /* We were prepending all this time */ + folder->entries = g_slist_reverse (folder->entries); + + /* Include subfolders */ + /* we always whack them onto the beginning */ + if (folder->subfolders != NULL) { + GSList *subfolders = g_slist_copy (folder->subfolders); + g_slist_foreach (subfolders, (GFunc)entry_ref_alloc, NULL); + folder->entries = g_slist_concat (subfolders, folder->entries); + } + + /* Exclude excludes */ + if (folder->excludes != NULL) { + GSList *li; + GSList *entries = folder->entries; + folder->entries = NULL; + for (li = entries; li != NULL; li = li->next) { + Entry *entry = li->data; + if (g_hash_table_lookup (folder->excludes, entry->name) == NULL) + folder->entries = g_slist_prepend (folder->entries, entry); + else + entry_unref_dealloc (entry); + + } + g_slist_free (entries); + + /* to preserve the Folders then everything else order */ + folder->entries = g_slist_reverse (folder->entries); + } + + folder->up_to_date = TRUE; + /* not yet sorted */ + folder->sorted = FALSE; +} + +static void +ensure_folder (VFolderInfo *info, + Folder *folder, + gboolean subfolders, + Folder *except, + gboolean ignore_unallocated) +{ + G_LOCK (vfolder_lock); + ensure_folder_unlocked (info, folder, subfolders, except, ignore_unallocated); + G_UNLOCK (vfolder_lock); +} + +static char * +get_directory_file_unlocked (VFolderInfo *info, Folder *folder) +{ + char *filename; + + /* FIXME: cache dir_files */ + + if (folder->desktop_file == NULL) + return NULL; + + if (folder->desktop_file[0] == G_DIR_SEPARATOR) + return g_strdup (folder->desktop_file); + + /* Now try the user directory */ + if (info->user_desktop_dir != NULL) { + filename = g_build_filename (info->user_desktop_dir, + folder->desktop_file, + NULL); + if (access (filename, F_OK) == 0) { + return filename; + } + + g_free (filename); + } + + filename = g_build_filename (info->desktop_dir, folder->desktop_file, NULL); + if (access (filename, F_OK) == 0) { + return filename; + } + g_free (filename); + + return NULL; +} + +static char * +get_directory_file (VFolderInfo *info, Folder *folder) +{ + char *ret; + + G_LOCK (vfolder_lock); + ret = get_directory_file_unlocked (info, folder); + G_UNLOCK (vfolder_lock); + + return ret; +} + +static GSList * +get_sort_order (VFolderInfo *info, Folder *folder) +{ + GSList *list; + char **parsed; + char *order; + int i; + char *filename; + + filename = get_directory_file_unlocked (info, folder); + if (filename == NULL) + return NULL; + + order = NULL; + readitem_entry (filename, + "SortOrder", + &order, + NULL, + NULL); + g_free (filename); + + if (order == NULL) + return NULL; + + parsed = g_strsplit (order, ":", -1); + + g_free (order); + + list = NULL; + for (i = 0; parsed[i] != NULL; i++) { + char *word = parsed[i]; + /* steal */ + parsed[i] = NULL; + /* ignore empty */ + if (word[0] == '\0') { + g_free (word); + continue; + } + list = g_slist_prepend (list, word); + } + /* we've stolen all strings from it */ + g_free (parsed); + + return g_slist_reverse (list); +} + +/* get entries in folder */ +static void +ensure_folder_sort (VFolderInfo *info, Folder *folder) +{ + GSList *li, *sort_order; + GSList *entries; + GHashTable *entry_hash; + + ensure_folder (info, folder, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + if (folder->sorted) + return; + + G_LOCK (vfolder_lock); + + sort_order = get_sort_order (info, folder); + if (sort_order == NULL) { + folder->sorted = TRUE; + G_UNLOCK (vfolder_lock); + return; + } + + entries = folder->entries; + folder->entries = NULL; + + entry_hash = g_hash_table_new (g_str_hash, g_str_equal); + for (li = entries; li != NULL; li = li->next) { + Entry *entry = li->data; + g_hash_table_insert (entry_hash, entry->name, li); + } + + for (li = sort_order; li != NULL; li = li->next) { + char *word = li->data; + GSList *entry_list; + Entry *entry; + + /* we kill the words here */ + li->data = NULL; + + entry_list = g_hash_table_lookup (entry_hash, word); + g_free (word); + + if (entry_list == NULL) + continue; + + entry = entry_list->data; + + entries = g_slist_delete_link (entries, entry_list); + + folder->entries = g_slist_prepend (folder->entries, + entry); + } + + /* put on those that weren't mentioned in the sort */ + for (li = entries; li != NULL; li = li->next) { + Entry *entry = li->data; + + folder->entries = g_slist_prepend (folder->entries, + entry); + } + + g_hash_table_destroy (entry_hash); + g_slist_free (entries); + g_slist_free (sort_order); + + folder->sorted = TRUE; + + G_UNLOCK (vfolder_lock); +} + +static EntryFile * +file_new (const char *name) +{ + EntryFile *efile = g_new0 (EntryFile, 1); + + efile->entry.type = ENTRY_FILE; + efile->entry.name = g_strdup (name); + efile->entry.refcount = 1; + + return efile; +} + +static Folder * +folder_new (const char *name) +{ + Folder *folder = g_new0 (Folder, 1); + + folder->entry.type = ENTRY_FOLDER; + folder->entry.name = g_strdup (name); + folder->entry.refcount = 1; + + return folder; +} + +static Query * +query_new (int type) +{ + Query *query; + + if (type == QUERY_KEYWORD) + query = (Query *)g_new0 (QueryKeyword, 1); + else if (type == QUERY_FILENAME) + query = (Query *)g_new0 (QueryFilename, 1); + else + query = g_new0 (Query, 1); + + query->type = type; + + return query; +} + +static void +query_destroy (Query *query) +{ + if (query == NULL) + return; + + if (query->type == QUERY_FILENAME) { + QueryFilename *qfile = (QueryFilename *)query; + g_free (qfile->filename); + qfile->filename = NULL; + } else if (query->type == QUERY_OR || + query->type == QUERY_AND) { + g_slist_foreach (query->queries, (GFunc)query_destroy, NULL); + g_slist_free (query->queries); + query->queries = NULL; + } + + g_free (query); +} + +static void +add_folder_monitor_unlocked (VFolderInfo *info, + FileMonitorHandle *handle) +{ + VFolderURI vuri; + GnomeVFSResult result; + Folder *folder; + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + file_monitor_handle_ref_unlocked (handle); + + info->folder_monitors = + g_slist_prepend (info->folder_monitors, handle); + + folder = resolve_folder (info, + vuri.path, + FALSE /* ignore_basename */, + &result, + NULL); + + if (folder == NULL) { + file_monitor_handle_ref_unlocked (handle); + + info->free_folder_monitors = + g_slist_prepend (info->free_folder_monitors, handle); + + if (handle->exists) { + handle->exists = FALSE; + gnome_vfs_monitor_callback + ((GnomeVFSMethodHandle *)handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_DELETED); + } + } else { + file_monitor_handle_ref_unlocked (handle); + + ((Entry *)folder)->monitors = + g_slist_prepend (((Entry *)folder)->monitors, handle); + + if ( ! handle->exists) { + handle->exists = TRUE; + gnome_vfs_monitor_callback + ((GnomeVFSMethodHandle *)handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_CREATED); + } + } + +} + +static inline void +invalidate_folder_T (Folder *folder) +{ + folder->up_to_date = FALSE; + + invalidate_folder_subfolders (folder, TRUE); +} + +static inline void +invalidate_folder (Folder *folder) +{ + G_LOCK (vfolder_lock); + folder->up_to_date = FALSE; + G_UNLOCK (vfolder_lock); + + invalidate_folder_subfolders (folder, FALSE); +} + +static void +invalidate_folder_subfolders (Folder *folder, + gboolean lock_taken) +{ + GSList *li; + + for (li = folder->subfolders; li != NULL; li = li->next) { + Folder *subfolder = li->data; + + if (!lock_taken) + invalidate_folder (subfolder); + else + invalidate_folder_T (subfolder); + } + + emit_monitor (folder, GNOME_VFS_MONITOR_EVENT_CHANGED); +} + +/* FIXME: this is UGLY!, we need to figure out when the file + * got finished changing! */ +static gboolean +reread_timeout (gpointer data) +{ + VFolderInfo *info = data; + gboolean force_read_items = info->file_monitors != NULL; + vfolder_info_reload (info, NULL, NULL, force_read_items); + return FALSE; +} + +static void +queue_reread_in (VFolderInfo *info, int msec) +{ + G_LOCK (vfolder_lock); + if (info->reread_queue != 0) + g_source_remove (info->reread_queue); + info->reread_queue = g_timeout_add (msec, reread_timeout, info); + G_UNLOCK (vfolder_lock); +} + +static void +vfolder_desktop_dir_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + /* FIXME: implement */ +} + +static void +vfolder_user_desktop_dir_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + /* FIXME: implement */ +} + +static void +vfolder_filename_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + VFolderInfo *info = user_data; + + if ((event_type == GNOME_VFS_MONITOR_EVENT_CREATED || + event_type == GNOME_VFS_MONITOR_EVENT_CHANGED) && + ! info->user_file_active) { + queue_reread_in (info, 200); + } else if (event_type == GNOME_VFS_MONITOR_EVENT_DELETED && + ! info->user_file_active) { + /* FIXME: is this correct? I mean now + * there probably isn't ANY vfolder file, so we + * init to default values really. I have no clue what's + * right here */ + vfolder_info_reload (info, NULL, NULL, + TRUE /* force read items */); + } +} + +static void +vfolder_user_filename_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + VFolderInfo *info = user_data; + + if ((event_type == GNOME_VFS_MONITOR_EVENT_CREATED || + event_type == GNOME_VFS_MONITOR_EVENT_CHANGED) && + info->user_file_active) { + struct stat s; + + /* see if this was really our own change */ + if (info->user_filename_last_write == time (NULL)) + return; + /* anal retentive */ + if (stat (info->user_filename, &s) == 0 && + info->user_filename_last_write == s.st_ctime) + return; + + queue_reread_in (info, 200); + } else if ((event_type == GNOME_VFS_MONITOR_EVENT_CREATED || + event_type == GNOME_VFS_MONITOR_EVENT_CHANGED) && + ! info->user_file_active) { + queue_reread_in (info, 200); + } else if (event_type == GNOME_VFS_MONITOR_EVENT_DELETED && + info->user_file_active) { + gboolean force_read_items = info->file_monitors != NULL; + vfolder_info_reload (info, NULL, NULL, force_read_items); + } +} + +static void +item_dir_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + VFolderInfo *info = user_data; + + if (event_type == GNOME_VFS_MONITOR_EVENT_CREATED || + event_type == GNOME_VFS_MONITOR_EVENT_CHANGED) { + /* first invalidate all folders */ + invalidate_folder (info->root); + /* second invalidate all entries */ + info->entries_valid = FALSE; + + if (info->file_monitors != NULL) { + GnomeVFSResult result; + GSList *li; + + /* Whack all monitors here! */ + for (li = info->file_monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *h = li->data; + if (h->handle != NULL) + gnome_vfs_monitor_cancel (h->handle); + h->handle = NULL; + } + + if (vfolder_info_read_items (info, &result, NULL)) { + info->entries_valid = TRUE; + } + } + } +} + +static gboolean +setup_dir_monitor (VFolderInfo *info, const char *dir, gboolean subdirs, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + GnomeVFSMonitorHandle *handle; + DIR *dh; + struct dirent *de; + char *uri; + + uri = gnome_vfs_get_uri_from_local_path (dir); + + if (gnome_vfs_monitor_add (&handle, + uri, + GNOME_VFS_MONITOR_DIRECTORY, + item_dir_monitor, + info) != GNOME_VFS_OK) { + StatLoc *sl = bake_statloc (dir, time (NULL)); + if (sl != NULL) + info->stat_dirs = g_slist_prepend (info->stat_dirs, sl); + g_free (uri); + return TRUE; + } + g_free (uri); + + if (gnome_vfs_context_check_cancellation (context)) { + gnome_vfs_monitor_cancel (handle); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + info->item_dir_monitors = + g_slist_prepend (info->item_dir_monitors, handle); + + if ( ! subdirs) + return TRUE; + + dh = opendir (dir); + if (dh == NULL) + return TRUE; + + while ((de = readdir (dh)) != NULL) { + char *full_path; + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + closedir (dh); + return FALSE; + } + + if (de->d_name[0] == '.') + continue; + + full_path = g_build_filename (dir, de->d_name, NULL); + if (g_file_test (full_path, G_FILE_TEST_IS_DIR)) { + if ( ! setup_dir_monitor (info, full_path, + TRUE /* subdirs */, + result, context)) { + closedir (dh); + return FALSE; + } + } + g_free (full_path); + } + + closedir (dh); + + return TRUE; +} + +static gboolean +monitor_setup (VFolderInfo *info, + gboolean setup_filenames, + gboolean setup_itemdirs, + gboolean setup_desktop_dirs, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + char *uri; + GSList *li; + + if (setup_filenames) { + uri = gnome_vfs_get_uri_from_local_path + (info->filename); + + if (gnome_vfs_monitor_add (&info->filename_monitor, + uri, + GNOME_VFS_MONITOR_FILE, + vfolder_filename_monitor, + info) != GNOME_VFS_OK) { + info->filename_monitor = NULL; + info->filename_statloc = bake_statloc (info->filename, + time (NULL)); + } + g_free (uri); + } + if (setup_filenames && + info->user_filename != NULL) { + uri = gnome_vfs_get_uri_from_local_path + (info->user_filename); + if (gnome_vfs_monitor_add (&info->user_filename_monitor, + uri, + GNOME_VFS_MONITOR_FILE, + vfolder_user_filename_monitor, + info) != GNOME_VFS_OK) { + info->user_filename_monitor = NULL; + info->user_filename_statloc = + bake_statloc (info->user_filename, + time (NULL)); + } + + g_free (uri); + } + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + if (setup_itemdirs) { + for (li = info->item_dirs; li != NULL; li = li->next) { + const char *dir = li->data; + if ( ! setup_dir_monitor (info, dir, + FALSE /* subdirs */, + result, context)) + return FALSE; + } + if (info->user_item_dir != NULL) { + if ( ! setup_dir_monitor (info, info->user_item_dir, + FALSE /* subdirs */, + result, context)) + return FALSE; + } + for (li = info->merge_dirs; li != NULL; li = li->next) { + const char *dir = li->data; + if ( ! setup_dir_monitor (info, dir, + TRUE /* subdirs */, + result, context)) + return FALSE; + } + } + + if (setup_desktop_dirs) { + uri = gnome_vfs_get_uri_from_local_path + (info->desktop_dir); + + if (gnome_vfs_monitor_add (&info->desktop_dir_monitor, + uri, + GNOME_VFS_MONITOR_FILE, + vfolder_desktop_dir_monitor, + info) != GNOME_VFS_OK) { + info->desktop_dir_monitor = NULL; + info->desktop_dir_statloc = + bake_statloc (info->desktop_dir, + time (NULL)); + } + g_free (uri); + } + if (setup_desktop_dirs && + info->user_desktop_dir != NULL) { + uri = gnome_vfs_get_uri_from_local_path + (info->user_desktop_dir); + if (gnome_vfs_monitor_add (&info->user_desktop_dir_monitor, + uri, + GNOME_VFS_MONITOR_DIRECTORY, + vfolder_user_desktop_dir_monitor, + info) != GNOME_VFS_OK) { + info->user_desktop_dir_monitor = NULL; + info->user_desktop_dir_statloc = + bake_statloc (info->user_desktop_dir, + time (NULL)); + } + + g_free (uri); + } + + return TRUE; +} + +static void +vfolder_info_init (VFolderInfo *info, const char *scheme) +{ + const char *path; + GSList *list; + + info->scheme = g_strdup (scheme); + + info->filename = g_strconcat (SYSCONFDIR, + "/gnome-vfs-2.0/vfolders/", + scheme, ".vfolder-info", + NULL); + info->user_filename = g_strconcat (g_get_home_dir (), + "/" DOT_GNOME "/vfolders/", + scheme, ".vfolder-info", + NULL); + info->desktop_dir = g_strconcat (SYSCONFDIR, + "/gnome-vfs-2.0/vfolders/", + NULL); + info->user_desktop_dir = g_strconcat (g_get_home_dir (), + "/" DOT_GNOME "/vfolders/", + NULL); + + /* Init the desktop paths */ + list = NULL; + list = g_slist_prepend (list, g_strdup ("/usr/share/applications/")); + if (strcmp ("/usr/share/applications/", DATADIR "/applications/") != 0) + list = g_slist_prepend (list, g_strdup (DATADIR "/applications/")); + path = g_getenv ("DESKTOP_FILE_PATH"); + if (path != NULL) { + int i; + char **ppath = g_strsplit (path, ":", -1); + for (i = 0; ppath[i] != NULL; i++) { + const char *dir = ppath[i]; + list = g_slist_prepend (list, g_strdup (dir)); + } + g_strfreev (ppath); + } + info->item_dirs = g_slist_reverse (list); + + info->user_item_dir = g_strconcat (g_get_home_dir (), + "/" DOT_GNOME "/vfolders/", + scheme, + NULL); + + info->entries_ht = g_hash_table_new (g_str_hash, g_str_equal); + + info->root = folder_new ("Root"); + + info->modification_time = time (NULL); +} + +static void +vfolder_info_free_internals_unlocked (VFolderInfo *info) +{ + if (info == NULL) + return; + + if (info->filename_monitor != NULL) { + gnome_vfs_monitor_cancel (info->filename_monitor); + info->filename_monitor = NULL; + } + + if (info->user_filename_monitor != NULL) { + gnome_vfs_monitor_cancel (info->user_filename_monitor); + info->user_filename_monitor = NULL; + } + + g_free (info->filename_statloc); + info->filename_statloc = NULL; + + g_free (info->user_filename_statloc); + info->user_filename_statloc = NULL; + + + if (info->desktop_dir_monitor != NULL) { + gnome_vfs_monitor_cancel (info->desktop_dir_monitor); + info->desktop_dir_monitor = NULL; + } + + if (info->user_desktop_dir_monitor != NULL) { + gnome_vfs_monitor_cancel (info->user_desktop_dir_monitor); + info->user_desktop_dir_monitor = NULL; + } + + g_free (info->desktop_dir_statloc); + info->desktop_dir_statloc = NULL; + + g_free (info->user_desktop_dir_statloc); + info->user_desktop_dir_statloc = NULL; + + + g_slist_foreach (info->item_dir_monitors, + (GFunc)gnome_vfs_monitor_cancel, NULL); + g_slist_free (info->item_dir_monitors); + info->item_dir_monitors = NULL; + + g_free (info->scheme); + info->scheme = NULL; + + g_free (info->filename); + info->filename = NULL; + + g_free (info->user_filename); + info->user_filename = NULL; + + g_free (info->desktop_dir); + info->desktop_dir = NULL; + + g_free (info->user_desktop_dir); + info->user_desktop_dir = NULL; + + g_slist_foreach (info->item_dirs, (GFunc)g_free, NULL); + g_slist_free (info->item_dirs); + info->item_dirs = NULL; + + g_free (info->user_item_dir); + info->user_item_dir = NULL; + + g_slist_foreach (info->merge_dirs, (GFunc)g_free, NULL); + g_slist_free (info->merge_dirs); + info->merge_dirs = NULL; + + g_slist_foreach (info->entries, (GFunc)entry_unref, NULL); + g_slist_free (info->entries); + info->entries = NULL; + + if (info->entries_ht != NULL) + g_hash_table_destroy (info->entries_ht); + info->entries_ht = NULL; + + g_slist_foreach (info->unallocated_folders, + (GFunc)entry_unref, + NULL); + g_slist_free (info->unallocated_folders); + info->unallocated_folders = NULL; + + entry_unref ((Entry *)info->root); + info->root = NULL; + + g_slist_foreach (info->stat_dirs, (GFunc)g_free, NULL); + g_slist_free (info->stat_dirs); + info->stat_dirs = NULL; + + g_slist_foreach (info->folder_monitors, + (GFunc)file_monitor_handle_unref_unlocked, NULL); + g_slist_free (info->folder_monitors); + info->folder_monitors = NULL; + + g_slist_foreach (info->free_folder_monitors, + (GFunc)file_monitor_handle_unref_unlocked, NULL); + g_slist_free (info->free_folder_monitors); + info->free_folder_monitors = NULL; + + g_slist_foreach (info->file_monitors, + (GFunc)file_monitor_handle_unref_unlocked, NULL); + g_slist_free (info->file_monitors); + info->file_monitors = NULL; + + g_slist_foreach (info->free_file_monitors, + (GFunc)file_monitor_handle_unref_unlocked, NULL); + g_slist_free (info->free_file_monitors); + info->free_file_monitors = NULL; + + if (info->reread_queue != 0) + g_source_remove (info->reread_queue); + info->reread_queue = 0; +} + +static void +vfolder_info_free_internals (VFolderInfo *info) +{ + G_LOCK (vfolder_lock); + vfolder_info_free_internals_unlocked (info); + G_UNLOCK (vfolder_lock); +} + +static void +vfolder_info_destroy (VFolderInfo *info) +{ + vfolder_info_free_internals (info); + g_free (info); +} + +static Query * +single_query_read (xmlNode *qnode) +{ + Query *query; + xmlNode *node; + + if (qnode->type != XML_ELEMENT_NODE || + qnode->name == NULL) + return NULL; + + query = NULL; + + if (g_ascii_strcasecmp (qnode->name, "Not") == 0 && + qnode->xmlChildrenNode != NULL) { + xmlNode *iter; + query = NULL; + for (iter = qnode->xmlChildrenNode; + iter != NULL && query == NULL; + iter = iter->next) + query = single_query_read (iter); + if (query != NULL) { + query->not = ! query->not; + } + return query; + } else if (g_ascii_strcasecmp (qnode->name, "Keyword") == 0) { + xmlChar *word = xmlNodeGetContent (qnode); + if (word != NULL) { + query = query_new (QUERY_KEYWORD); + ((QueryKeyword *)query)->keyword = + g_quark_from_string (word); + + xmlFree (word); + } + return query; + } else if (g_ascii_strcasecmp (qnode->name, "Filename") == 0) { + xmlChar *file = xmlNodeGetContent (qnode); + if (file != NULL) { + query = query_new (QUERY_FILENAME); + ((QueryFilename *)query)->filename = + g_strdup (file); + + xmlFree (file); + } + return query; + } else if (g_ascii_strcasecmp (qnode->name, "And") == 0) { + query = query_new (QUERY_AND); + } else if (g_ascii_strcasecmp (qnode->name, "Or") == 0) { + query = query_new (QUERY_OR); + } else { + /* We don't understand */ + return NULL; + } + + /* This must be OR or AND */ + g_assert (query != NULL); + + for (node = qnode->xmlChildrenNode; node != NULL; node = node->next) { + Query *new_query = single_query_read (node); + + if (new_query != NULL) + query->queries = g_slist_prepend + (query->queries, new_query); + } + + query->queries = g_slist_reverse (query->queries); + + return query; +} + +static void +add_or_set_query (Query **query, Query *new_query) +{ + if (*query == NULL) { + *query = new_query; + } else { + Query *old_query = *query; + *query = query_new (QUERY_OR); + (*query)->queries = + g_slist_append ((*query)->queries, old_query); + (*query)->queries = + g_slist_append ((*query)->queries, new_query); + } +} + +static Query * +query_read (xmlNode *qnode) +{ + Query *query; + xmlNode *node; + + query = NULL; + + for (node = qnode->xmlChildrenNode; node != NULL; node = node->next) { + if (node->type != XML_ELEMENT_NODE || + node->name == NULL) + continue; + + if (g_ascii_strcasecmp (node->name, "Not") == 0 && + node->xmlChildrenNode != NULL) { + xmlNode *iter; + Query *new_query = NULL; + + for (iter = node->xmlChildrenNode; + iter != NULL && new_query == NULL; + iter = iter->next) + new_query = single_query_read (iter); + if (new_query != NULL) { + new_query->not = ! new_query->not; + add_or_set_query (&query, new_query); + } + } else { + Query *new_query = single_query_read (node); + if (new_query != NULL) + add_or_set_query (&query, new_query); + } + } + + return query; +} + +static Folder * +folder_read (VFolderInfo *info, xmlNode *fnode) +{ + Folder *folder; + xmlNode *node; + + folder = folder_new (NULL); + + for (node = fnode->xmlChildrenNode; node != NULL; node = node->next) { + if (node->type != XML_ELEMENT_NODE || + node->name == NULL) + continue; + + if (g_ascii_strcasecmp (node->name, "Name") == 0) { + xmlChar *name = xmlNodeGetContent (node); + if (name != NULL) { + g_free (folder->entry.name); + folder->entry.name = g_strdup (name); + xmlFree (name); + } + } else if (g_ascii_strcasecmp (node->name, "Desktop") == 0) { + xmlChar *desktop = xmlNodeGetContent (node); + if (desktop != NULL) { + g_free (folder->desktop_file); + folder->desktop_file = g_strdup (desktop); + xmlFree (desktop); + } + } else if (g_ascii_strcasecmp (node->name, "Include") == 0) { + xmlChar *file = xmlNodeGetContent (node); + if (file != NULL) { + GSList *li; + char *str = g_strdup (file); + folder->includes = g_slist_prepend + (folder->includes, str); + if (folder->includes_ht == NULL) { + folder->includes_ht = + g_hash_table_new_full + (g_str_hash, + g_str_equal, + NULL, + NULL); + } + li = g_hash_table_lookup (folder->includes_ht, + file); + if (li != NULL) { + g_free (li->data); + /* Note: this will NOT change folder->includes + * pointer! */ + folder->includes = g_slist_delete_link + (folder->includes, li); + } + g_hash_table_replace (folder->includes_ht, + file, folder->includes); + xmlFree (file); + } + } else if (g_ascii_strcasecmp (node->name, "Exclude") == 0) { + xmlChar *file = xmlNodeGetContent (node); + if (file != NULL) { + char *s; + if (folder->excludes == NULL) { + folder->excludes = g_hash_table_new_full + (g_str_hash, + g_str_equal, + (GDestroyNotify)g_free, + NULL); + } + s = g_strdup (file); + g_hash_table_replace (folder->excludes, s, s); + xmlFree (file); + } + } else if (g_ascii_strcasecmp (node->name, "Query") == 0) { + Query *query; + + query = query_read (node); + + if (query != NULL) { + if (folder->query != NULL) + query_destroy (folder->query); + folder->query = query; + } + } else if (g_ascii_strcasecmp (node->name, "OnlyUnallocated") == 0) { + info->unallocated_folders = + g_slist_prepend (info->unallocated_folders, + (Folder *)entry_ref ((Entry *)folder)); + folder->only_unallocated = TRUE; + } else if (g_ascii_strcasecmp (node->name, "Folder") == 0) { + Folder *new_folder = folder_read (info, node); + if (new_folder != NULL) { + folder->subfolders = + g_slist_append (folder->subfolders, + new_folder); + new_folder->parent = folder; + } + } else if (g_ascii_strcasecmp (node->name, "ReadOnly") == 0) { + folder->read_only = TRUE; + } else if (g_ascii_strcasecmp (node->name, + "DontShowIfEmpty") == 0) { + folder->dont_show_if_empty = TRUE; + } + } + + /* Name is required */ + if (folder->entry.name == NULL) { + entry_unref ((Entry *)folder); + folder = NULL; + } + + folder->includes = g_slist_reverse (folder->includes); + + return folder; +} + +static char * +subst_home (const char *dir) +{ + if (dir[0] == '~') + return g_strconcat (g_get_home_dir (), + &dir[1], + NULL); + else + return g_strdup (dir); +} + +/* FORMAT looks like: + * + * + * /etc/X11/applnk + * + * /usr/share/applications + * + * /etc/X11/gnome/vfolders + * + * + * Root + * + * important.desktop + * + * + * + * SomeFolder + * + * + * Test_Folder + * + * Test_Folder.directory + * + * + * + * Application + * Game + * + * Clock + * + * + * somefile.desktop + * someotherfile.desktop + * yetanother.desktop + * + * + * + */ + +static gboolean +vfolder_info_read_info (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + xmlDoc *doc; + xmlNode *node; + gboolean got_a_vfolder_dir = FALSE; + + doc = NULL; + if (info->user_filename != NULL && + access (info->user_filename, F_OK) == 0) { + doc = xmlParseFile (info->user_filename); + if (doc != NULL) + info->user_file_active = TRUE; + } + if (doc == NULL && + access (info->filename, F_OK) == 0) + doc = xmlParseFile (info->filename); + + if (gnome_vfs_context_check_cancellation (context)) { + xmlFreeDoc(doc); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + if (doc == NULL + || doc->xmlRootNode == NULL + || doc->xmlRootNode->name == NULL + || g_ascii_strcasecmp (doc->xmlRootNode->name, "VFolderInfo") != 0) { + xmlFreeDoc(doc); + return TRUE; /* FIXME: really, shouldn't we error out? */ + } + + for (node = doc->xmlRootNode->xmlChildrenNode; node != NULL; node = node->next) { + if (node->type != XML_ELEMENT_NODE || + node->name == NULL) + continue; + + if (gnome_vfs_context_check_cancellation (context)) { + xmlFreeDoc(doc); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + if (g_ascii_strcasecmp (node->name, "MergeDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + if (dir != NULL) { + info->merge_dirs = g_slist_append (info->merge_dirs, + g_strdup (dir)); + xmlFree (dir); + } + } else if (g_ascii_strcasecmp (node->name, "ItemDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + if (dir != NULL) { + if ( ! got_a_vfolder_dir) { + g_slist_foreach (info->item_dirs, + (GFunc)g_free, NULL); + g_slist_free (info->item_dirs); + info->item_dirs = NULL; + } + got_a_vfolder_dir = TRUE; + info->item_dirs = g_slist_append (info->item_dirs, + g_strdup (dir)); + xmlFree (dir); + } + } else if (g_ascii_strcasecmp (node->name, "UserItemDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + if (dir != NULL) { + g_free (info->user_item_dir); + info->user_item_dir = subst_home (dir); + xmlFree (dir); + } + } else if (g_ascii_strcasecmp (node->name, "DesktopDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + if (dir != NULL) { + g_free (info->desktop_dir); + info->desktop_dir = g_strdup (dir); + xmlFree (dir); + } + } else if (g_ascii_strcasecmp (node->name, "UserDesktopDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + if (dir != NULL) { + g_free (info->user_desktop_dir); + info->user_desktop_dir = subst_home (dir); + xmlFree (dir); + } + } else if (g_ascii_strcasecmp (node->name, "Folder") == 0) { + Folder *folder = folder_read (info, node); + if (folder != NULL) { + if (info->root != NULL) + entry_unref ((Entry *)info->root); + info->root = folder; + } + } else if (g_ascii_strcasecmp (node->name, "ReadOnly") == 0) { + info->read_only = TRUE; + } + } + + xmlFreeDoc(doc); + + return TRUE; +} + +static void +add_xml_tree_from_query (xmlNode *parent, Query *query) +{ + xmlNode *real_parent; + + if (query->not) + real_parent = xmlNewChild (parent /* parent */, + NULL /* ns */, + "Not" /* name */, + NULL /* content */); + else + real_parent = parent; + + if (query->type == QUERY_KEYWORD) { + QueryKeyword *qkeyword = (QueryKeyword *)query; + const char *string = g_quark_to_string (qkeyword->keyword); + + xmlNewChild (real_parent /* parent */, + NULL /* ns */, + "Keyword" /* name */, + string /* content */); + } else if (query->type == QUERY_FILENAME) { + QueryFilename *qfilename = (QueryFilename *)query; + + xmlNewChild (real_parent /* parent */, + NULL /* ns */, + "Filename" /* name */, + qfilename->filename /* content */); + } else if (query->type == QUERY_OR || + query->type == QUERY_AND) { + xmlNode *node; + const char *name; + GSList *li; + + if (query->type == QUERY_OR) + name = "Or"; + else /* QUERY_AND */ + name = "And"; + + node = xmlNewChild (real_parent /* parent */, + NULL /* ns */, + name /* name */, + NULL /* content */); + + for (li = query->queries; li != NULL; li = li->next) { + Query *subquery = li->data; + add_xml_tree_from_query (node, subquery); + } + } else { + g_assert_not_reached (); + } +} + +static void +add_excludes_to_xml (gpointer key, gpointer value, gpointer user_data) +{ + const char *filename = key; + xmlNode *folder_node = user_data; + + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Exclude" /* name */, + filename /* content */); +} + +static void +add_xml_tree_from_folder (xmlNode *parent, Folder *folder) +{ + GSList *li; + xmlNode *folder_node; + + + folder_node = xmlNewChild (parent /* parent */, + NULL /* ns */, + "Folder" /* name */, + NULL /* content */); + + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Name" /* name */, + folder->entry.name /* content */); + + if (folder->desktop_file != NULL) { + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Desktop" /* name */, + folder->desktop_file /* content */); + } + + if (folder->read_only) + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "ReadOnly" /* name */, + NULL /* content */); + if (folder->dont_show_if_empty) + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "DontShowIfEmpty" /* name */, + NULL /* content */); + if (folder->only_unallocated) + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "OnlyUnallocated" /* name */, + NULL /* content */); + + for (li = folder->subfolders; li != NULL; li = li->next) { + Folder *subfolder = li->data; + add_xml_tree_from_folder (folder_node, subfolder); + } + + for (li = folder->includes; li != NULL; li = li->next) { + const char *include = li->data; + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Include" /* name */, + include /* content */); + } + + if (folder->excludes) { + g_hash_table_foreach (folder->excludes, + add_excludes_to_xml, + folder_node); + } + + if (folder->query != NULL) { + xmlNode *query_node; + query_node = xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Query" /* name */, + NULL /* content */); + + add_xml_tree_from_query (query_node, folder->query); + } +} + +static xmlDoc * +xml_tree_from_vfolder (VFolderInfo *info) +{ + xmlDoc *doc; + xmlNode *topnode; + GSList *li; + + doc = xmlNewDoc ("1.0"); + + topnode = xmlNewDocNode (doc /* doc */, + NULL /* ns */, + "VFolderInfo" /* name */, + NULL /* content */); + doc->xmlRootNode = topnode; + + for (li = info->merge_dirs; li != NULL; li = li->next) { + const char *merge_dir = li->data; + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "MergeDir" /* name */, + merge_dir /* content */); + } + + for (li = info->item_dirs; li != NULL; li = li->next) { + const char *item_dir = li->data; + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "ItemDir" /* name */, + item_dir /* content */); + } + + if (info->user_item_dir != NULL) { + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "UserItemDir" /* name */, + info->user_item_dir /* content */); + } + + if (info->desktop_dir != NULL) { + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "DesktopDir" /* name */, + info->desktop_dir /* content */); + } + + if (info->user_desktop_dir != NULL) { + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "UserDesktopDir" /* name */, + info->user_desktop_dir /* content */); + } + + if (info->root != NULL) + add_xml_tree_from_folder (topnode, info->root); + + return doc; +} + +/* FIXME: what to do about errors */ +static void +vfolder_info_write_user (VFolderInfo *info) +{ + xmlDoc *doc; + + if (info->inhibit_write > 0) + return; + + if (info->user_filename == NULL) + return; + + doc = xml_tree_from_vfolder (info); + if (doc == NULL) + return; + + /* FIXME: errors, anyone? */ + ensure_dir (info->user_filename, + TRUE /* ignore_basename */); + + xmlSaveFormatFile (info->user_filename, doc, TRUE /* format */); + /* not as good as a stat, but cheaper ... hmmm what is + * the likelyhood of this not being the same as ctime */ + info->user_filename_last_write = time (NULL); + + xmlFreeDoc(doc); + + info->user_file_active = TRUE; + info->dirty = FALSE; + + info->modification_time = time (NULL); +} + +/* An EVIL function for quick reading of .desktop files, + * only reads in one or two keys, but that's ALL we need */ +static void +readitem_entry (const char *filename, + const char *key1, + char **result1, + const char *key2, + char **result2) +{ + FILE *fp; + char buf[1024]; + int keylen1, keylen2; + + *result1 = NULL; + if (result2 != NULL) + *result2 = NULL; + + fp = fopen (filename, "r"); + + if (fp == NULL) + return; + + keylen1 = strlen (key1); + if (key2 != NULL) + keylen2 = strlen (key2); + else + keylen2 = -1; + + /* This is slightly wrong, it should only look + * at the correct section */ + while (fgets (buf, sizeof (buf), fp) != NULL) { + char *p; + int len; + int keylen; + char **result = NULL; + + /* check if it's one of the keys */ + if (strncmp (buf, key1, keylen1) == 0) { + result = result1; + keylen = keylen1; + } else if (keylen2 >= 0 && + strncmp (buf, key2, keylen2) == 0) { + result = result2; + keylen = keylen2; + } else { + continue; + } + + p = &buf[keylen]; + + /* still not our key */ + if (!(*p == '=' || *p == ' ')) { + continue; + } + do + p++; + while (*p == ' ' || *p == '='); + + /* get rid of trailing \n */ + len = strlen (p); + if (p[len-1] == '\n' || + p[len-1] == '\r') + p[len-1] = '\0'; + + *result = g_strdup (p); + + if (*result1 == NULL || + (result2 != NULL && *result2 == NULL)) + break; + } + + fclose (fp); +} + +static void +vfolder_info_insert_entry (VFolderInfo *info, EntryFile *efile) +{ + GSList *entry_list; + + entry_ref ((Entry *)efile); + + entry_list = g_hash_table_lookup (info->entries_ht, efile->entry.name); + + info->entries = g_slist_prepend (info->entries, efile); + /* The hash table contains the GSList pointer */ + g_hash_table_replace (info->entries_ht, efile->entry.name, + info->entries); + + if (entry_list != NULL) { + Entry *entry = entry_list->data; + info->entries = g_slist_delete_link (info->entries, + entry_list); + entry_unref (entry); + } +} + +static void +set_keywords (EntryFile *efile, const char *keywords) +{ + if (keywords != NULL) { + int i; + char **parsed = g_strsplit (keywords, ";", -1); + for (i = 0; parsed[i] != NULL; i++) { + GQuark quark; + const char *word = parsed[i]; + /* ignore empties (including end of list) */ + if (word[0] == '\0') + continue; + quark = g_quark_from_string (word); + efile->keywords = g_slist_prepend + (efile->keywords, + GINT_TO_POINTER (quark)); + } + g_strfreev (parsed); + } +} + +static EntryFile * +make_entry_file (const char *dir, const char *name) +{ + EntryFile *efile; + char *categories; + char *only_show_in; + char *filename; + int i; + + filename = g_build_filename (dir, name, NULL); + + readitem_entry (filename, + "Categories", + &categories, + "OnlyShowIn", + &only_show_in); + + if (only_show_in != NULL) { + gboolean show = FALSE; + char **parsed = g_strsplit (only_show_in, ";", -1); + for (i = 0; parsed[i] != NULL; i++) { + if (strcmp (parsed[i], "GNOME") == 0) { + show = TRUE; + break; + } + } + g_strfreev (parsed); + if ( ! show) { + g_free (filename); + g_free (only_show_in); + g_free (categories); + return NULL; + } + } + + efile = file_new (name); + efile->filename = filename; + + set_keywords (efile, categories); + + g_free (only_show_in); + g_free (categories); + + return efile; +} + +static gboolean +vfolder_info_read_items_from (VFolderInfo *info, + const char *item_dir, + gboolean per_user, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + DIR *dir; + struct dirent *de; + + dir = opendir (item_dir); + if (dir == NULL) + return TRUE; + + while ((de = readdir (dir)) != NULL) { + EntryFile *efile; + + if (gnome_vfs_context_check_cancellation (context)) { + closedir (dir); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + /* files MUST be called .desktop */ + if (de->d_name[0] == '.' || + ! check_ext (de->d_name, ".desktop")) + continue; + + efile = make_entry_file (item_dir, de->d_name); + if (efile == NULL) + continue; + + efile->per_user = per_user; + + vfolder_info_insert_entry (info, efile); + entry_unref ((Entry *)efile); + } + + closedir (dir); + + return TRUE; +} + +static gboolean +vfolder_info_read_items_merge (VFolderInfo *info, + const char *merge_dir, + const char *subdir, + GQuark inherited_keyword, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + DIR *dir; + struct dirent *de; + GQuark extra_keyword; + GQuark Application; + GQuark Merged; + GQuark inheritance; + gboolean pass_down_extra_keyword = TRUE; + + dir = opendir (merge_dir); + if (dir == NULL) + return TRUE; + + Application = g_quark_from_static_string ("Application"); + Merged = g_quark_from_static_string ("Merged"); + + /* FIXME: this should be a hash or something */ + extra_keyword = 0; + if (subdir == NULL) { + extra_keyword = g_quark_from_static_string ("Core"); + pass_down_extra_keyword = FALSE; + } else if (g_ascii_strcasecmp (subdir, "Development") == 0) + extra_keyword = g_quark_from_static_string ("Development"); + else if (g_ascii_strcasecmp (subdir, "Editors") == 0) + extra_keyword = g_quark_from_static_string ("TextEditor"); + else if (g_ascii_strcasecmp (subdir, "Games") == 0) + extra_keyword = g_quark_from_static_string ("Game"); + else if (g_ascii_strcasecmp (subdir, "Graphics") == 0) + extra_keyword = g_quark_from_static_string ("Graphics"); + else if (g_ascii_strcasecmp (subdir, "Internet") == 0) + extra_keyword = g_quark_from_static_string ("Network"); + else if (g_ascii_strcasecmp (subdir, "Multimedia") == 0) + extra_keyword = g_quark_from_static_string ("AudioVideo"); + else if (g_ascii_strcasecmp (subdir, "Office") == 0) + extra_keyword = g_quark_from_static_string ("Office"); + else if (g_ascii_strcasecmp (subdir, "Settings") == 0) + extra_keyword = g_quark_from_static_string ("Settings"); + else if (g_ascii_strcasecmp (subdir, "System") == 0) + extra_keyword = g_quark_from_static_string ("System"); + else if (g_ascii_strcasecmp (subdir, "Utilities") == 0) + extra_keyword = g_quark_from_static_string ("Utility"); + + while ((de = readdir (dir)) != NULL) { + EntryFile *efile; + + if (gnome_vfs_context_check_cancellation (context)) { + closedir (dir); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + /* ignore hidden */ + if (de->d_name[0] == '.') + continue; + + /* files MUST be called .desktop, so + * treat all others as dirs. If we're wrong, + * the open will fail, which is ok */ + if ( ! check_ext (de->d_name, ".desktop")) { + /* if this is a directory recurse */ + char *fullname = g_build_filename (merge_dir, de->d_name, NULL); + if ((pass_down_extra_keyword == TRUE) && (extra_keyword != 0)) { + inheritance = extra_keyword; + } else { + inheritance = inherited_keyword; + } + + if ( ! vfolder_info_read_items_merge (info, + fullname, + de->d_name, + inheritance, + result, + context)) { + g_free (fullname); + return FALSE; + } + g_free (fullname); + continue; + } + + /* FIXME: add some keywords about some known apps + * like gimp and whatnot, perhaps take these from the vfolder + * file or some such */ + + efile = make_entry_file (merge_dir, de->d_name); + if (efile == NULL) + continue; + + /* If no keywords set, then add the standard ones */ + if (efile->keywords == NULL) { + efile->keywords = g_slist_prepend + (efile->keywords, + GINT_TO_POINTER (Application)); + + efile->keywords = g_slist_prepend + (efile->keywords, + GINT_TO_POINTER (Merged)); + + if (inherited_keyword != 0) { + efile->keywords = g_slist_prepend + (efile->keywords, + GINT_TO_POINTER (inherited_keyword)); + } + + if (extra_keyword != 0) { + efile->keywords = g_slist_prepend + (efile->keywords, + GINT_TO_POINTER (extra_keyword)); + } + efile->implicit_keywords = TRUE; + } + + vfolder_info_insert_entry (info, efile); + entry_unref ((Entry *)efile); + } + + closedir (dir); + + return TRUE; +} + +static Entry * +find_entry (GSList *list, const char *name) +{ + GSList *li; + + for (li = list; li != NULL; li = li->next) { + Entry *entry = li->data; + if (strcmp (name, entry->name) == 0) + return entry; + } + return NULL; +} + +static void +file_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + FileMonitorHandle *h = user_data; + + /* proxy the event through if it is a changed event + * only */ + + if (event_type == GNOME_VFS_MONITOR_EVENT_CHANGED && + h->handle != NULL) + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *) h, + h->uri, event_type); +} + +static void +try_free_file_monitors_create_files_unlocked (VFolderInfo *info) +{ + GSList *li, *list; + + list = g_slist_copy (info->free_file_monitors); + + for (li = list; li != NULL; li = li->next) { + FileMonitorHandle *handle = li->data; + Entry *entry; + GnomeVFSResult result; + char *dirfile = NULL; + + if (handle->is_directory_file) { + VFolderURI vuri; + Folder *folder; + + /* Evil! EVIL URI PARSING. this will eat a lot of + * stack if we have lots of free monitors */ + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + folder = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + + if (folder == NULL) + continue; + + dirfile = get_directory_file_unlocked (info, folder); + if (dirfile == NULL) + continue; + + entry = (Entry *)folder; + } else { + VFolderURI vuri; + Folder *f; + GnomeVFSResult result; + + entry = NULL; + + /* Evil! EVIL URI PARSING. this will eat a lot of + * stack if we have lots of monitors */ + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + f = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + + if (f != NULL) { + ensure_folder_unlocked ( + info, f, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + entry = find_entry (f->entries, vuri.file); + } + + if (entry == NULL) + continue; + } + + info->free_file_monitors = + g_slist_remove (info->free_file_monitors, handle); + entry->monitors = + g_slist_prepend (entry->monitors, handle); + + handle->exists = TRUE; + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *)handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_CREATED); + + /* recreate a handle */ + if (handle->handle == NULL && + entry->type == ENTRY_FILE) { + EntryFile *efile = (EntryFile *)entry; + char *uri = gnome_vfs_get_uri_from_local_path + (efile->filename); + + gnome_vfs_monitor_add (&(handle->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + handle); + + g_free (uri); + } else if (handle->handle == NULL && + dirfile != NULL) { + char *uri = gnome_vfs_get_uri_from_local_path (dirfile); + + gnome_vfs_monitor_add (&(handle->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + handle); + + g_free (uri); + } + + g_free (dirfile); + } + + g_slist_free (list); +} + +static void /* unlocked */ +rescan_monitors (VFolderInfo *info) +{ + GSList *li; + + if (info->file_monitors == NULL) + return; + + for (li = info->file_monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + GnomeVFSResult result; + Entry *entry; + char *dirfile = NULL; + + /* these are handled below */ + if ( ! h->exists) + continue; + + if (h->is_directory_file) { + VFolderURI vuri; + Folder *folder; + + /* Evil! EVIL URI PARSING. this will eat a lot of + * stack if we have lots of monitors */ + + VFOLDER_URI_PARSE (h->uri, &vuri); + + folder = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + if (folder != NULL) + dirfile = get_directory_file_unlocked (info, + folder); + + if (dirfile == NULL) { + h->exists = FALSE; + gnome_vfs_monitor_callback + ((GnomeVFSMethodHandle *)h, + h->uri, + GNOME_VFS_MONITOR_EVENT_DELETED); + info->free_file_monitors = g_slist_prepend + (info->free_file_monitors, h); + file_monitor_handle_ref_unlocked (h); + /* it has been unreffed when the entry was + * whacked */ + continue; + } + + entry = (Entry *)folder; + } else { + VFolderURI vuri; + Folder *f; + GnomeVFSResult result; + + entry = NULL; + + /* Evil! EVIL URI PARSING. this will eat a lot of + * stack if we have lots of monitors */ + + VFOLDER_URI_PARSE (h->uri, &vuri); + + f = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + + if (f != NULL) { + ensure_folder_unlocked ( + info, f, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + entry = find_entry (f->entries, vuri.file); + } + + if (entry == NULL) { + h->exists = FALSE; + gnome_vfs_monitor_callback + ((GnomeVFSMethodHandle *)h, + h->uri, + GNOME_VFS_MONITOR_EVENT_DELETED); + info->free_file_monitors = g_slist_prepend + (info->free_file_monitors, h); + file_monitor_handle_ref_unlocked (h); + /* it has been unreffed when the entry was + * whacked */ + continue; + } + } + + /* recreate a handle */ + if (h->handle == NULL && + entry->type == ENTRY_FILE) { + EntryFile *efile = (EntryFile *)entry; + char *uri = gnome_vfs_get_uri_from_local_path + (efile->filename); + + gnome_vfs_monitor_add (&(h->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + h); + + g_free (uri); + } else if (h->handle == NULL && + dirfile != NULL) { + char *uri = gnome_vfs_get_uri_from_local_path (dirfile); + + gnome_vfs_monitor_add (&(h->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + h); + + g_free (uri); + } + + g_free (dirfile); + } + + try_free_file_monitors_create_files_unlocked (info); +} + +static gboolean /* unlocked */ +vfolder_info_read_items (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + GSList *li; + + /* First merge */ + for (li = info->merge_dirs; li != NULL; li = li->next) { + const char *merge_dir = li->data; + + if ( ! vfolder_info_read_items_merge (info, merge_dir, NULL, FALSE, + result, context)) + return FALSE; + } + + /* Then read the real thing (later overrides) */ + for (li = info->item_dirs; li != NULL; li = li->next) { + const char *item_dir = li->data; + + if ( ! vfolder_info_read_items_from (info, item_dir, + FALSE /* per_user */, + result, context)) + return FALSE; + } + + if (info->user_item_dir != NULL) { + if ( ! vfolder_info_read_items_from (info, + info->user_item_dir, + TRUE /* per_user */, + result, context)) + return FALSE; + } + + rescan_monitors (info); + + return TRUE; +} + +static gboolean +string_slist_equal (GSList *list1, GSList *list2) +{ + GSList *li1, *li2; + + for (li1 = list1, li2 = list2; + li1 != NULL && li2 != NULL; + li1 = li1->next, li2 = li2->next) { + const char *s1 = li1->data; + const char *s2 = li2->data; + if (strcmp (s1, s2) != 0) + return FALSE; + } + /* if both are not NULL, then lengths are + * different */ + if (li1 != li2) + return FALSE; + return TRUE; +} + +static gboolean +safe_string_same (const char *string1, const char *string2) +{ + if (string1 == string2 && + string1 == NULL) + return TRUE; + + if (string1 != NULL && string2 != NULL && + strcmp (string1, string2) == 0) + return TRUE; + + return FALSE; +} + +static gboolean +vfolder_info_item_dirs_same (VFolderInfo *info1, VFolderInfo *info2) +{ + if ( ! string_slist_equal (info1->item_dirs, + info2->item_dirs)) + return FALSE; + + if ( ! string_slist_equal (info1->merge_dirs, + info2->merge_dirs)) + return FALSE; + + if ( ! safe_string_same (info1->user_item_dir, + info2->user_item_dir)) + return FALSE; + + return TRUE; +} + +static gboolean +vfolder_info_reload_unlocked (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context, + gboolean force_read_items) +{ + VFolderInfo *newinfo; + gboolean setup_filenames; + gboolean setup_itemdirs; + GSList *li; + + /* FIXME: Hmmm, race, there is no locking YAIKES, + * we need filename locking for changes. eek, eek, eek */ + if (info->dirty) { + return TRUE; + } + + newinfo = g_new0 (VFolderInfo, 1); + vfolder_info_init (newinfo, info->scheme); + + g_free (newinfo->filename); + g_free (newinfo->user_filename); + newinfo->filename = g_strdup (info->filename); + newinfo->user_filename = g_strdup (info->user_filename); + + if (gnome_vfs_context_check_cancellation (context)) { + vfolder_info_destroy (newinfo); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + if ( ! vfolder_info_read_info (newinfo, result, context)) { + vfolder_info_destroy (newinfo); + return FALSE; + } + + /* FIXME: reload logic for 'desktop_dir' and + * 'user_desktop_dir' */ + + setup_itemdirs = TRUE; + + /* Validity of entries and item dirs and all that is unchanged */ + if (vfolder_info_item_dirs_same (info, newinfo)) { + newinfo->entries = info->entries; + info->entries = NULL; + newinfo->entries_ht = info->entries_ht; + info->entries_ht = NULL /* some places assume this + non-null, but we're only + going to destroy this */; + newinfo->entries_valid = info->entries_valid; + + /* move over the monitors/statlocs since those are valid */ + newinfo->item_dir_monitors = info->item_dir_monitors; + info->item_dir_monitors = NULL; + newinfo->stat_dirs = info->stat_dirs; + info->stat_dirs = NULL; + + /* No need to resetup dir monitors */ + setup_itemdirs = FALSE; + + /* No need to do anything with file monitors */ + } else { + /* Whack all monitors here! */ + for (li = info->file_monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + if (h->handle != NULL) + gnome_vfs_monitor_cancel (h->handle); + h->handle = NULL; + } + } + + setup_filenames = TRUE; + + if (safe_string_same (info->filename, newinfo->filename) && + safe_string_same (info->user_filename, newinfo->user_filename)) { + newinfo->user_filename_last_write = + info->user_filename_last_write; + + /* move over the monitors/statlocs since those are valid */ + newinfo->filename_monitor = info->filename_monitor; + info->filename_monitor = NULL; + newinfo->user_filename_monitor = info->user_filename_monitor; + info->user_filename_monitor = NULL; + + if (info->filename_statloc != NULL && + info->filename != NULL) + newinfo->filename_statloc = + bake_statloc (info->filename, + time (NULL)); + if (info->user_filename_statloc != NULL && + info->user_filename != NULL) + newinfo->user_filename_statloc = + bake_statloc (info->user_filename, + time (NULL)); + + /* No need to resetup filename monitors */ + setup_filenames = FALSE; + } + + /* Note: not cancellable anymore, since we've + * already started nibbling on the info structure, + * so we'd need to back things out or some such, + * too complex, so screw that */ + monitor_setup (info, + setup_filenames, + setup_itemdirs, + /* FIXME: setup_desktop_dirs */ TRUE, + NULL, NULL); + + for (li = info->folder_monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *handle = li->data; + li->data = NULL; + + add_folder_monitor_unlocked (newinfo, handle); + + file_monitor_handle_unref_unlocked (handle); + } + g_slist_free (info->folder_monitors); + info->folder_monitors = NULL; + + g_slist_foreach (info->free_folder_monitors, + (GFunc)file_monitor_handle_unref_unlocked, NULL); + g_slist_free (info->free_folder_monitors); + info->folder_monitors = NULL; + + /* we can just copy these for now, they will be readded + * and all the fun stuff will be done with them later */ + newinfo->file_monitors = info->file_monitors; + info->file_monitors = NULL; + newinfo->free_file_monitors = info->free_file_monitors; + info->free_file_monitors = NULL; + + /* emit changed on all folders, a bit drastic, but oh well, + * we also invalidate all folders at the same time, but that is + * irrelevant since they should all just be invalid to begin with */ + invalidate_folder_T (info->root); + + /* FIXME: make sure if this was enough, I think it was */ + + vfolder_info_free_internals_unlocked (info); + memcpy (info, newinfo, sizeof (VFolderInfo)); + g_free (newinfo); + + /* must rescan the monitors here */ + if (info->entries_valid) { + rescan_monitors (info); + } + + if ( ! info->entries_valid && + force_read_items) { + GnomeVFSResult res; + /* FIXME: I bet cancelation plays havoc with monitors, + * I'm not sure however */ + if (info->file_monitors != NULL) { + vfolder_info_read_items (info, &res, NULL); + } else { + if ( ! vfolder_info_read_items (info, result, context)) + return FALSE; + } + info->entries_valid = TRUE; + } + + return TRUE; +} + +static gboolean +vfolder_info_reload (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context, + gboolean force_read_items) +{ + G_LOCK (vfolder_lock); + if (vfolder_info_reload_unlocked (info, result, context, + force_read_items)) { + G_UNLOCK (vfolder_lock); + return TRUE; + } else { + G_UNLOCK (vfolder_lock); + return FALSE; + } +} + +static gboolean +vfolder_info_recheck (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + GSList *li; + time_t curtime = time (NULL); + gboolean reread = FALSE; + + if (info->filename_statloc != NULL && + ! check_statloc (info->filename_statloc, curtime)) { + if ( ! vfolder_info_reload_unlocked (info, result, context, + FALSE /* force read items */)) { + /* we have failed, make sure we fail + * next time too */ + info->filename_statloc->trigger_next = TRUE; + return FALSE; + } + reread = TRUE; + } + if ( ! reread && + info->user_filename_statloc != NULL && + ! check_statloc (info->user_filename_statloc, curtime)) { + if ( ! vfolder_info_reload_unlocked (info, result, context, + FALSE /* force read items */)) { + /* we have failed, make sure we fail + * next time too */ + info->user_filename_statloc->trigger_next = TRUE; + return FALSE; + } + reread = TRUE; + } + + if (info->entries_valid) { + for (li = info->stat_dirs; li != NULL; li = li->next) { + StatLoc *sl = li->data; + if ( ! check_statloc (sl, curtime)) { + info->entries_valid = FALSE; + break; + } + } + } + return TRUE; +} + +static VFolderInfo * +get_vfolder_info_unlocked (const char *scheme, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + VFolderInfo *info; + + if (infos != NULL && + (info = g_hash_table_lookup (infos, scheme)) != NULL) { + if ( ! vfolder_info_recheck (info, result, context)) { + return NULL; + } + if ( ! info->entries_valid) { + g_slist_foreach (info->entries, + (GFunc)entry_unref, NULL); + g_slist_free (info->entries); + info->entries = NULL; + + if (info->entries_ht != NULL) + g_hash_table_destroy (info->entries_ht); + info->entries_ht = g_hash_table_new (g_str_hash, + g_str_equal); + + if ( ! vfolder_info_read_items (info, + result, context)) { + info->entries_valid = FALSE; + return NULL; + } + + invalidate_folder_T (info->root); + + info->entries_valid = TRUE; + } + return info; + } + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if (infos == NULL) + infos = g_hash_table_new_full + (g_str_hash, g_str_equal, + (GDestroyNotify)g_free, + (GDestroyNotify)vfolder_info_destroy); + + info = g_new0 (VFolderInfo, 1); + vfolder_info_init (info, scheme); + + if (gnome_vfs_context_check_cancellation (context)) { + vfolder_info_destroy (info); + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if ( ! vfolder_info_read_info (info, result, context)) { + vfolder_info_destroy (info); + return NULL; + } + + if ( ! monitor_setup (info, + TRUE /* setup_filenames */, + TRUE /* setup_itemdirs */, + TRUE /* setup_desktop_dirs */, + result, context)) { + vfolder_info_destroy (info); + return NULL; + } + + g_hash_table_insert (infos, g_strdup (scheme), info); + + if ( ! vfolder_info_read_items (info, result, context)) { + info->entries_valid = FALSE; + return NULL; + } + info->entries_valid = TRUE; + + return info; +} + +static VFolderInfo * +get_vfolder_info (const char *scheme, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + VFolderInfo *info; + G_LOCK (vfolder_lock); + info = get_vfolder_info_unlocked (scheme, result, context); + G_UNLOCK (vfolder_lock); + return info; +} + + +static char * +keywords_to_string (GSList *keywords) +{ + GSList *li; + GString *str = g_string_new (NULL); + + for (li = keywords; li != NULL; li = li->next) { + GQuark word = GPOINTER_TO_INT (li->data); + g_string_append (str, g_quark_to_string (word)); + g_string_append_c (str, ';'); + } + + return g_string_free (str, FALSE); +} + +/* copy file and add keywords line */ +static gboolean +copy_file_with_keywords (const char *from, const char *to, GSList *keywords) +{ + FILE *fp; + FILE *wfp; + int wfd; + char buf[BUFSIZ]; + char *keyword_string; + + if ( ! ensure_dir (to, + TRUE /* ignore_basename */)) + return FALSE; + + wfd = open (to, O_CREAT | O_WRONLY | O_TRUNC, 0600); + if (wfd < 0) { + return FALSE; + } + + keyword_string = keywords_to_string (keywords); + + wfp = fdopen (wfd, "w"); + + fp = fopen (from, "r"); + if (fp != NULL) { + gboolean wrote_keywords = FALSE; + while (fgets (buf, sizeof (buf), fp) != NULL) { + fprintf (wfp, "%s", buf); + if ( ! wrote_keywords && + (strncmp (buf, "[Desktop Entry]", + strlen ("[Desktop Entry]")) == 0 || + strncmp (buf, "[KDE Desktop Entry]", + strlen ("[KDE Desktop Entry]")) == 0)) { + fprintf (wfp, "Categories=%s\n", + keyword_string); + wrote_keywords = TRUE; + } + } + + fclose (fp); + } else { + fprintf (wfp, "[Desktop Entry]\nCategories=%s\n", + keyword_string); + } + + /* FIXME: does this close wfd???? */ + fclose (wfp); + + close (wfd); + + g_free (keyword_string); + + return TRUE; +} + +static gboolean +copy_file (const char *from, const char *to) +{ + int fd; + int wfd; + + if ( ! ensure_dir (to, + TRUE /* ignore_basename */)) + return FALSE; + + wfd = open (to, O_CREAT | O_WRONLY | O_TRUNC, 0600); + if (wfd < 0) { + return FALSE; + } + + fd = open (from, O_RDONLY); + if (fd >= 0) { + char buf[1024]; + ssize_t n; + + while ((n = read (fd, buf, sizeof(buf))) > 0) { + write (wfd, buf, n); + } + + close (fd); + } + + close (wfd); + + return TRUE; +} + +static gboolean +make_file_private (VFolderInfo *info, EntryFile *efile) +{ + char *newfname; + Entry *entry = (Entry *)efile; + + if (efile->per_user) + return TRUE; + + /* this file already exists so whack its monitors */ + if (efile->filename != NULL) { + GSList *li; + + for (li = entry->monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + if (h->handle != NULL) + gnome_vfs_monitor_cancel (h->handle); + h->handle = NULL; + } + } + + newfname = g_build_filename (g_get_home_dir (), + DOT_GNOME, + "vfolders", + info->scheme, + efile->entry.name, + NULL); + + if (efile->implicit_keywords) { + if (efile->filename != NULL && + ! copy_file_with_keywords (efile->filename, + newfname, + efile->keywords)) { + /* FIXME: what to do with monitors here, they + * have already been whacked, a corner case + * not handled! */ + g_free (newfname); + return FALSE; + } + } else { + if (efile->filename != NULL && + ! copy_file (efile->filename, newfname)) { + /* FIXME: what to do with monitors here, they + * have already been whacked, a corner case + * not handled! */ + g_free (newfname); + return FALSE; + } + } + + /* we didn't copy but ensure path anyway */ + if (efile->filename == NULL && + ! ensure_dir (newfname, + TRUE /* ignore_basename */)) { + g_free (newfname); + return FALSE; + } + + /* this file already exists so re-add monitors at the new location */ + if (efile->filename != NULL) { + GSList *li; + char *uri = gnome_vfs_get_uri_from_local_path (newfname); + + for (li = entry->monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + + gnome_vfs_monitor_add (&(h->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + h); + } + + g_free (uri); + } + + g_free (efile->filename); + efile->filename = newfname; + efile->per_user = TRUE; + + return TRUE; +} + +static void +try_free_file_monitors_create_dirfile_unlocked (VFolderInfo *info, + Folder *folder) +{ + GSList *li, *list; + + list = g_slist_copy (info->free_file_monitors); + + for (li = list; li != NULL; li = li->next) { + FileMonitorHandle *handle = li->data; + Folder *f; + VFolderURI vuri; + GnomeVFSResult result; + + if ( ! handle->is_directory_file) + continue; + + /* Evil! EVIL URI PARSING. this will eat a lot of stack if we + * have lots of free monitors */ + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + f = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + + if (folder != f) + continue; + + info->free_file_monitors = + g_slist_remove (info->free_file_monitors, handle); + ((Entry *)folder)->monitors = + g_slist_prepend (((Entry *)folder)->monitors, handle); + + handle->exists = TRUE; + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *)handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_CREATED); + } + + g_slist_free (list); +} + +static void +make_new_dirfile (VFolderInfo *info, Folder *folder) +{ + char *name = g_strdup (folder->entry.name); + char *fname; + char *p; + int i; + int fd; + + for (p = name; *p != '\0'; p++) { + if ( ! ( (*p >= 'a' && *p <= 'z') || + (*p >= 'A' && *p <= 'Z') || + (*p >= '0' && *p <= '9') || + *p == '_')) { + *p = '_'; + } + } + + i = 0; + fname = NULL; + do { + char *fullname; + + g_free (fname); + + if (i > 0) { + fname = g_strdup_printf ("%s-%d.directory", name, i); + } else { + fname = g_strdup_printf ("%s.directory", name); + } + + fullname = g_build_filename + (info->user_desktop_dir, fname, NULL); + fd = open (fullname, O_CREAT | O_WRONLY | O_EXCL, 0600); + g_free (fullname); + } while (fd < 0); + + close (fd); + + folder->desktop_file = fname; + info->dirty = TRUE; + + try_free_file_monitors_create_dirfile_unlocked (info, folder); +} + +static gboolean +make_dirfile_private (VFolderInfo *info, Folder *folder) +{ + char *fname; + char *desktop_file; + GSList *li; + char *uri; + gboolean ret; + + if (info->user_desktop_dir == NULL) + return FALSE; + + if ( ! ensure_dir (info->user_desktop_dir, + FALSE /* ignore_basename */)) + return FALSE; + + + if (folder->desktop_file == NULL) { + make_new_dirfile (info, folder); + return TRUE; + } + + /* FIXME: this is broken! What if the desktop file exists + * in the local but there is a different (but with a same name) + * .directory in the system. */ + fname = g_build_filename (info->user_desktop_dir, + folder->desktop_file, + NULL); + + if (access (fname, F_OK) == 0) { + g_free (fname); + return TRUE; + } + + desktop_file = get_directory_file (info, folder); + + if (desktop_file == NULL) { + int fd = open (fname, O_CREAT | O_EXCL | O_WRONLY, 0600); + g_free (fname); + if (fd >= 0) { + close (fd); + return TRUE; + } + return FALSE; + } + + for (li = ((Entry *)folder)->monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + if (h->is_directory_file) { + if (h->handle != NULL) + gnome_vfs_monitor_cancel (h->handle); + h->handle = NULL; + } + } + + ret = TRUE; + + if ( ! copy_file (desktop_file, fname)) { + ret = FALSE; + g_free (fname); + fname = desktop_file; + desktop_file = NULL; + } + + uri = gnome_vfs_get_uri_from_local_path (fname); + + for (li = ((Entry *)folder)->monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + + if (h->is_directory_file) { + gnome_vfs_monitor_add (&(h->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + h); + } + } + + g_free (uri); + + g_free (desktop_file); + g_free (fname); + + return ret; +} + +static Folder * +resolve_folder (VFolderInfo *info, + const char *path, + gboolean ignore_basename, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + char **ppath; + int i; + Folder *folder = info->root; + + ppath = g_strsplit (path, "/", -1); + + if (ppath == NULL || + ppath[0] == NULL) { + g_strfreev (ppath); + *result = GNOME_VFS_ERROR_INVALID_URI; + return NULL; + } + + for (i = 0; ppath [i] != NULL; i++) { + const char *segment = ppath[i]; + + if (*segment == '\0') + continue; + + if (ignore_basename && ppath [i + 1] == NULL) + break; + else { + folder = (Folder *) find_entry (folder->subfolders, + segment); + if (folder == NULL) + break; + } + } + g_strfreev (ppath); + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if (folder == NULL) + *result = GNOME_VFS_ERROR_NOT_FOUND; + + return folder; +} + +static Entry * +resolve_path (VFolderInfo *info, + const char *path, + const char *basename, + Folder **return_folder, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + Entry *entry; + Folder *folder; + + if (strcmp (path, "/") == 0) + return (Entry *)info->root; + + folder = resolve_folder (info, path, + TRUE /* ignore_basename */, + result, context); + + if (return_folder != NULL) + *return_folder = folder; + + if (folder == NULL) { + return NULL; + } + + /* Make sure we have the entries here */ + ensure_folder_unlocked (info, folder, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + + entry = find_entry (folder->entries, basename); + + if (entry == NULL) + *result = GNOME_VFS_ERROR_NOT_FOUND; + + return entry; +} + +static Entry * +get_entry_unlocked (VFolderURI *vuri, + Folder **parent, + gboolean *is_directory_file, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + VFolderInfo *info; + Entry *entry; + + if (is_directory_file != NULL) + *is_directory_file = FALSE; + if (parent != NULL) + *parent = NULL; + + info = get_vfolder_info_unlocked (vuri->scheme, result, context); + if (info == NULL) + return NULL; + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if (vuri->is_all_scheme) { + GSList *efile_list; + + if (vuri->file == NULL) { + entry = resolve_path (info, + vuri->path, + vuri->file, + parent, + result, + context); + return entry; + } + + efile_list = g_hash_table_lookup (info->entries_ht, vuri->file); + + if (efile_list == NULL) { + *result = GNOME_VFS_ERROR_NOT_FOUND; + return NULL; + } else { + return efile_list->data; + } + } + + if (vuri->file != NULL && + check_ext (vuri->file, ".directory") == TRUE) { + Folder *folder; + + folder = resolve_folder (info, vuri->path, + TRUE /* ignore_basename */, + result, context); + if (folder == NULL) { + return NULL; + } + + if (is_directory_file != NULL) + *is_directory_file = TRUE; + + if (parent != NULL) + *parent = folder; + + return (Entry *)folder; + } else { + entry = resolve_path (info, vuri->path, vuri->file, parent, + result, context); + return entry; + } +} + +static Entry * +get_entry (VFolderURI *vuri, + Folder **parent, + gboolean *is_directory_file, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + Entry *entry; + + G_LOCK (vfolder_lock); + entry = get_entry_unlocked (vuri, + parent, + is_directory_file, + result, context); + G_UNLOCK (vfolder_lock); + + return entry; +} + +/* only works for files and only those that exist */ +/* unlocked function */ +static GnomeVFSURI * +desktop_uri_to_file_uri (VFolderInfo *info, + VFolderURI *desktop_vuri, + Entry **the_entry, + gboolean *the_is_directory_file, + Folder **the_folder, + gboolean privatize, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + gboolean is_directory_file; + GnomeVFSURI *ret_uri; + Folder *folder = NULL; + Entry *entry; + + entry = get_entry_unlocked (desktop_vuri, + &folder, + &is_directory_file, + result, + context); + if (entry == NULL) + return NULL; + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if (the_folder != NULL) + *the_folder = folder; + + if (the_entry != NULL) + *the_entry = entry; + if (the_is_directory_file != NULL) + *the_is_directory_file = is_directory_file; + + if (is_directory_file && + entry->type == ENTRY_FOLDER) { + char *desktop_file; + + folder = (Folder *)entry; + + if (the_folder != NULL) + *the_folder = folder; + + /* we'll be doing something write like */ + if (folder->read_only && + privatize) { + *result = GNOME_VFS_ERROR_READ_ONLY; + return NULL; + } + + if (privatize) { + char *fname; + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if ( ! make_dirfile_private (info, folder)) { + *result = GNOME_VFS_ERROR_GENERIC; + return NULL; + } + fname = g_build_filename (g_get_home_dir (), + folder->desktop_file, + NULL); + ret_uri = gnome_vfs_uri_new (fname); + g_free (fname); + return ret_uri; + } + + desktop_file = get_directory_file_unlocked (info, folder); + if (desktop_file != NULL) { + char *s = gnome_vfs_get_uri_from_local_path + (desktop_file); + + g_free (desktop_file); + + ret_uri = gnome_vfs_uri_new (s); + g_free (s); + + return ret_uri; + } else { + *result = GNOME_VFS_ERROR_NOT_FOUND; + return NULL; + } + } else if (entry->type == ENTRY_FILE) { + EntryFile *efile = (EntryFile *)entry; + char *s; + + /* we'll be doing something write like */ + if (folder != NULL && + folder->read_only && + privatize) { + *result = GNOME_VFS_ERROR_READ_ONLY; + return NULL; + } + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if (privatize && + ! make_file_private (info, efile)) { + *result = GNOME_VFS_ERROR_GENERIC; + return NULL; + } + + s = gnome_vfs_get_uri_from_local_path (efile->filename); + ret_uri = gnome_vfs_uri_new (s); + g_free (s); + + return ret_uri; + } else { + if (the_folder != NULL) + *the_folder = (Folder *)entry; + *result = GNOME_VFS_ERROR_IS_DIRECTORY; + return NULL; + } +} + +static void +remove_file (Folder *folder, const char *basename) +{ + GSList *li; + char *s; + + if (folder->includes_ht != NULL) { + li = g_hash_table_lookup (folder->includes_ht, basename); + if (li != NULL) { + char *name = li->data; + folder->includes = g_slist_delete_link + (folder->includes, li); + g_hash_table_remove (folder->includes_ht, basename); + g_free (name); + } + } + + if (folder->excludes == NULL) { + folder->excludes = g_hash_table_new_full + (g_str_hash, g_str_equal, + (GDestroyNotify)g_free, + NULL); + } + s = g_strdup (basename); + g_hash_table_replace (folder->excludes, s, s); +} + +static void +add_file (Folder *folder, const char *basename) +{ + GSList *li = NULL; + + if (folder->includes_ht != NULL) { + li = g_hash_table_lookup (folder->includes_ht, basename); + } + + /* if not found */ + if (li == NULL) { + char *str = g_strdup (basename); + folder->includes = + g_slist_prepend (folder->includes, str); + if (folder->includes_ht == NULL) { + folder->includes_ht = + g_hash_table_new_full (g_str_hash, + g_str_equal, + NULL, + NULL); + } + g_hash_table_replace (folder->includes_ht, + str, folder->includes); + } + if (folder->excludes != NULL) + g_hash_table_remove (folder->excludes, basename); +} + +typedef struct _FileHandle FileHandle; +struct _FileHandle { + VFolderInfo *info; + GnomeVFSMethodHandle *handle; + Entry *entry; + gboolean write; + gboolean is_directory_file; +}; + +static void +make_handle (GnomeVFSMethodHandle **method_handle, + GnomeVFSMethodHandle *file_handle, + VFolderInfo *info, + Entry *entry, + gboolean is_directory_file, + gboolean write) +{ + if (file_handle != NULL) { + FileHandle *handle = g_new0 (FileHandle, 1); + + handle->info = info; + handle->handle = file_handle; + handle->entry = entry_ref (entry); + handle->is_directory_file = is_directory_file; + handle->write = write; + + *method_handle = (GnomeVFSMethodHandle *) handle; + } else { + *method_handle = NULL; + } +} + +static void +whack_handle (FileHandle *handle) +{ + entry_unref (handle->entry); + handle->entry = NULL; + + handle->handle = NULL; + handle->info = NULL; + + g_free (handle); +} + +static GnomeVFSResult +do_open (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result = GNOME_VFS_OK; + VFolderInfo *info; + Entry *entry; + gboolean is_directory_file; + GnomeVFSMethodHandle *file_handle = NULL; + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + /* These can't be very nice FILE names */ + if (vuri.file == NULL || + vuri.ends_in_slash) + return GNOME_VFS_ERROR_INVALID_URI; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (mode & GNOME_VFS_OPEN_WRITE && + (info->read_only || vuri.is_all_scheme)) + return GNOME_VFS_ERROR_READ_ONLY; + + G_LOCK (vfolder_lock); + file_uri = desktop_uri_to_file_uri (info, + &vuri, + &entry, + &is_directory_file, + NULL /* the_folder */, + mode & GNOME_VFS_OPEN_WRITE, + &result, + context); + + if (file_uri == NULL) { + G_UNLOCK (vfolder_lock); + return result; + } + + result = (* parent_method->open) (parent_method, + &file_handle, + file_uri, + mode, + context); + + if (result == GNOME_VFS_ERROR_CANCELLED) { + G_UNLOCK (vfolder_lock); + gnome_vfs_uri_unref (file_uri); + return result; + } + + make_handle (method_handle, + file_handle, + info, + entry, + is_directory_file, + mode & GNOME_VFS_OPEN_WRITE); + + gnome_vfs_uri_unref (file_uri); + + if (info->dirty) { + vfolder_info_write_user (info); + } + + G_UNLOCK (vfolder_lock); + + return result; +} + +static void +remove_from_all_except (Folder *root, + const char *name, + Folder *except) +{ + GSList *li; + + if (root != except) { + remove_file (root, name); + if (root->up_to_date) { + for (li = root->entries; li != NULL; li = li->next) { + Entry *entry = li->data; + if (strcmp (name, entry->name) == 0) { + root->entries = + g_slist_delete_link + (root->entries, li); + break; + } + } + } + } + + for (li = root->subfolders; li != NULL; li = li->next) { + Folder *subfolder = li->data; + + remove_from_all_except (subfolder, name, except); + } +} + +static GnomeVFSResult +do_create (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + gboolean exclusive, + guint perm, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + GnomeVFSMethodHandle *file_handle; + GnomeVFSURI *file_uri; + VFolderURI vuri; + VFolderInfo *info; + Folder *parent; + Entry *entry; + EntryFile *efile; + char *s; + GSList *li; + + VFOLDER_URI_PARSE (uri, &vuri); + + /* These can't be very nice FILE names */ + if (vuri.file == NULL || + vuri.ends_in_slash) + return GNOME_VFS_ERROR_INVALID_URI; + + if ( ! check_ext (vuri.file, ".desktop") && + ! strcmp (vuri.file, ".directory") == 0) { + return GNOME_VFS_ERROR_INVALID_URI; + } + + /* all scheme is read only */ + if (vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (info->user_filename == NULL || + info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + parent = resolve_folder (info, vuri.path, + TRUE /* ignore_basename */, + &result, context); + if (parent == NULL) + return result; + + if (parent->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + if (strcmp (vuri.file, ".directory") == 0) { + char *fname; + + G_LOCK (vfolder_lock); + + if (exclusive) { + char *desktop_file; + desktop_file = get_directory_file_unlocked (info, parent); + if (desktop_file != NULL) { + g_free (desktop_file); + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_FILE_EXISTS; + } + } + + if ( ! make_dirfile_private (info, parent)) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_GENERIC; + } + fname = g_build_filename (g_get_home_dir (), + parent->desktop_file, + NULL); + s = gnome_vfs_get_uri_from_local_path (fname); + file_uri = gnome_vfs_uri_new (s); + g_free (fname); + g_free (s); + + if (file_uri == NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_GENERIC; + } + + result = (* parent_method->create) (parent_method, + &file_handle, + file_uri, + mode, + exclusive, + perm, + context); + gnome_vfs_uri_unref (file_uri); + + make_handle (method_handle, + file_handle, + info, + (Entry *)parent, + TRUE /* is_directory_file */, + TRUE /* write */); + + if (info->dirty) + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return result; + } + + ensure_folder (info, parent, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + + entry = find_entry (parent->entries, vuri.file); + + if (entry != NULL && + entry->type == ENTRY_FOLDER) + return GNOME_VFS_ERROR_IS_DIRECTORY; + + efile = (EntryFile *)entry; + + if (efile != NULL) { + if (exclusive) + return GNOME_VFS_ERROR_FILE_EXISTS; + + G_LOCK (vfolder_lock); + if ( ! make_file_private (info, efile)) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_GENERIC; + } + + s = gnome_vfs_get_uri_from_local_path (efile->filename); + file_uri = gnome_vfs_uri_new (s); + g_free (s); + + if (file_uri == NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_GENERIC; + } + + result = (* parent_method->create) (parent_method, + &file_handle, + file_uri, + mode, + exclusive, + perm, + context); + gnome_vfs_uri_unref (file_uri); + + make_handle (method_handle, + file_handle, + info, + (Entry *)efile, + FALSE /* is_directory_file */, + TRUE /* write */); + + G_UNLOCK (vfolder_lock); + + return result; + } + + G_LOCK (vfolder_lock); + + li = g_hash_table_lookup (info->entries_ht, vuri.file); + + if (exclusive && li != NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_FILE_EXISTS; + } + + if (li == NULL) { + efile = file_new (vuri.file); + vfolder_info_insert_entry (info, efile); + entry_unref ((Entry *)efile); + } else { + efile = li->data; + } + + /* this will make a private name for this */ + if ( ! make_file_private (info, efile)) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_GENERIC; + } + + add_file (parent, vuri.file); + parent->sorted = FALSE; + + if (parent->up_to_date) + parent->entries = g_slist_prepend (parent->entries, efile); + + /* if we created a brand new name, then we exclude it + * from everywhere else to ensure overall sanity */ + if (li == NULL) + remove_from_all_except (info->root, vuri.file, parent); + + s = gnome_vfs_get_uri_from_local_path (efile->filename); + file_uri = gnome_vfs_uri_new (s); + g_free (s); + + result = (* parent_method->create) (parent_method, + &file_handle, + file_uri, + mode, + exclusive, + perm, + context); + gnome_vfs_uri_unref (file_uri); + + make_handle (method_handle, + file_handle, + info, + (Entry *)efile, + FALSE /* is_directory_file */, + TRUE /* write */); + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return result; +} + +static GnomeVFSResult +do_close (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + if (method_handle == (GnomeVFSMethodHandle *)method) + return GNOME_VFS_OK; + + G_LOCK (vfolder_lock); + + result = (* parent_method->close) (parent_method, + handle->handle, + context); + handle->handle = NULL; + + /* we reread the Categories keyword */ + if (handle->write && + handle->entry != NULL && + handle->entry->type == ENTRY_FILE) { + EntryFile *efile = (EntryFile *)handle->entry; + char *categories; + readitem_entry (efile->filename, + "Categories", + &categories, + NULL, + NULL); + set_keywords (efile, categories); + g_free (categories); + /* FIXME: what about OnlyShowIn */ + + /* FIXME: check if the keywords changed, if not, do + * nothing */ + + /* Perhaps a bit drastic */ + /* also this emits the CHANGED monitor signal */ + invalidate_folder_T (handle->info->root); + + /* the file changed monitor will happen by itself + * as the underlying file is changed */ + } else if (handle->write && + handle->entry != NULL && + handle->entry->type == ENTRY_FOLDER && + handle->is_directory_file) { + /* if we're monitoring this directory, emit the CHANGED + * monitor thing, it will also emit a changed on + * the file itself. It is better to emit changed + * just in case. */ + emit_monitor ((Folder *)(handle->entry), + GNOME_VFS_MONITOR_EVENT_CHANGED); + } + + whack_handle (handle); + + G_UNLOCK (vfolder_lock); + + return result; +} + +static void +fill_buffer (gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read) +{ + char *buf = buffer; + GnomeVFSFileSize i; + for (i = 0; i < num_bytes; i++) { + if (rand () % 32 == 0 || + i == num_bytes-1) + buf[i] = '\n'; + else + buf[i] = ((rand()>>4) % 94) + 32; + } + if (bytes_read != 0) + *bytes_read = i; +} + +static GnomeVFSResult +do_read (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + if (method_handle == (GnomeVFSMethodHandle *)method) { + if ((rand () >> 4) & 0x3) { + fill_buffer (buffer, num_bytes, bytes_read); + return GNOME_VFS_OK; + } else { + return GNOME_VFS_ERROR_EOF; + } + } + + result = (* parent_method->read) (parent_method, + handle->handle, + buffer, num_bytes, + bytes_read, + context); + + return result; +} + +static GnomeVFSResult +do_write (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gconstpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_written, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + if (method_handle == (GnomeVFSMethodHandle *)method) + return GNOME_VFS_OK; + + result = (* parent_method->write) (parent_method, + handle->handle, + buffer, num_bytes, + bytes_written, + context); + + return result; +} + + +static GnomeVFSResult +do_seek (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSSeekPosition whence, + GnomeVFSFileOffset offset, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + if (method_handle == (GnomeVFSMethodHandle *)method) + return GNOME_VFS_OK; + + result = (* parent_method->seek) (parent_method, + handle->handle, + whence, offset, + context); + + return result; +} + +static GnomeVFSResult +do_tell (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileOffset *offset_return) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + result = (* parent_method->tell) (parent_method, + handle->handle, + offset_return); + + return result; +} + + +static GnomeVFSResult +do_truncate_handle (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileSize where, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + if (method_handle == (GnomeVFSMethodHandle *)method) + return GNOME_VFS_OK; + + result = (* parent_method->truncate_handle) (parent_method, + handle->handle, + where, + context); + + return result; +} + +static GnomeVFSResult +do_truncate (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileSize where, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result = GNOME_VFS_OK; + VFolderInfo *info; + Entry *entry; + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + /* These can't be very nice FILE names */ + if (vuri.file == NULL || + vuri.ends_in_slash) + return GNOME_VFS_ERROR_INVALID_URI; + + if (vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + G_LOCK (vfolder_lock); + file_uri = desktop_uri_to_file_uri (info, + &vuri, + &entry, + NULL /* the_is_directory_file */, + NULL /* the_folder */, + TRUE /* privatize */, + &result, + context); + G_UNLOCK (vfolder_lock); + + if (file_uri == NULL) + return result; + + result = (* parent_method->truncate) (parent_method, + file_uri, + where, + context); + + gnome_vfs_uri_unref (file_uri); + + if (info->dirty) { + G_LOCK (vfolder_lock); + vfolder_info_write_user (info); + G_UNLOCK (vfolder_lock); + } + + if (entry->type == ENTRY_FILE) { + EntryFile *efile = (EntryFile *)entry; + + G_LOCK (vfolder_lock); + g_slist_free (efile->keywords); + efile->keywords = NULL; + G_UNLOCK (vfolder_lock); + } + + /* Perhaps a bit drastic, but oh well */ + invalidate_folder (info->root); + + return result; +} + +typedef struct _DirHandle DirHandle; +struct _DirHandle { + VFolderInfo *info; + Folder *folder; + + GnomeVFSFileInfoOptions options; + + /* List of Entries */ + GSList *list; + GSList *current; +}; + +static GnomeVFSResult +do_open_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + VFolderURI vuri; + DirHandle *dh; + Folder *folder; + VFolderInfo *info; + char *desktop_file; + + VFOLDER_URI_PARSE (uri, &vuri); + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + /* In the all- scheme just list all filenames */ + if (vuri.is_all_scheme) { + if (any_subdir (vuri.path)) + return GNOME_VFS_ERROR_NOT_FOUND; + + dh = g_new0 (DirHandle, 1); + dh->info = info; + dh->options = options; + dh->folder = NULL; + + G_LOCK (vfolder_lock); + dh->list = g_slist_copy (info->entries); + g_slist_foreach (dh->list, (GFunc)entry_ref, NULL); + dh->current = dh->list; + G_UNLOCK (vfolder_lock); + + *method_handle = (GnomeVFSMethodHandle*) dh; + return GNOME_VFS_OK; + } + + folder = resolve_folder (info, vuri.path, + FALSE /* ignore_basename */, + &result, context); + if (folder == NULL) + return result; + + /* Make sure we have the entries and sorted here */ + ensure_folder_sort (info, folder); + + dh = g_new0 (DirHandle, 1); + dh->info = info; + dh->options = options; + + G_LOCK (vfolder_lock); + dh->folder = (Folder *)entry_ref ((Entry *)folder); + dh->list = g_slist_copy (folder->entries); + g_slist_foreach (folder->entries, (GFunc)entry_ref, NULL); + G_UNLOCK (vfolder_lock); + + desktop_file = get_directory_file (info, folder); + if (desktop_file != NULL) { + EntryFile *efile = file_new (".directory"); + dh->list = g_slist_prepend (dh->list, efile); + g_free (desktop_file); + } + + dh->current = dh->list; + + *method_handle = (GnomeVFSMethodHandle*) dh; + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_close_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + DirHandle *dh; + + dh = (DirHandle*) method_handle; + + G_LOCK (vfolder_lock); + + g_slist_foreach (dh->list, (GFunc)entry_unref, NULL); + g_slist_free (dh->list); + dh->list = NULL; + + dh->current = NULL; + + if (dh->folder != NULL) + entry_unref ((Entry *)dh->folder); + dh->folder = NULL; + + dh->info = NULL; + + g_free (dh); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_read_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSContext *context) +{ + DirHandle *dh; + Entry *entry; + GnomeVFSFileInfoOptions options; + + dh = (DirHandle*) method_handle; + +read_directory_again: + + if (dh->current == NULL) { + return GNOME_VFS_ERROR_EOF; + } + + entry = dh->current->data; + dh->current = dh->current->next; + + options = dh->options; + + if (entry->type == ENTRY_FILE && + ((EntryFile *)entry)->filename != NULL) { + EntryFile *efile = (EntryFile *)entry; + char *furi = gnome_vfs_get_uri_from_local_path (efile->filename); + GnomeVFSURI *uri = gnome_vfs_uri_new (furi); + + /* we always get mime-type by forcing it below */ + if (options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE) + options &= ~GNOME_VFS_FILE_INFO_GET_MIME_TYPE; + + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_NONE; + + /* Get the file info for this */ + (* parent_method->get_file_info) (parent_method, + uri, + file_info, + options, + context); + + /* we ignore errors from this since the file_info just + * won't be filled completely if there's an error, that's all */ + + g_free (file_info->mime_type); + file_info->mime_type = g_strdup ("application/x-gnome-app-info"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + /* Now we wipe those fields we don't support */ + file_info->valid_fields &= ~(UNSUPPORTED_INFO_FIELDS); + + gnome_vfs_uri_unref (uri); + g_free (furi); + } else if (entry->type == ENTRY_FILE) { + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_NONE; + + file_info->name = g_strdup (entry->name); + GNOME_VFS_FILE_INFO_SET_LOCAL (file_info, TRUE); + + file_info->type = GNOME_VFS_FILE_TYPE_REGULAR; + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_TYPE; + + /* FIXME: Is this correct? isn't there an xdg mime type? */ + file_info->mime_type = g_strdup ("application/x-gnome-app-info"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + /* FIXME: get some ctime/mtime */ + } else /* ENTRY_FOLDER */ { + Folder *folder = (Folder *)entry; + + /* Skip empty folders if they have + * the flag set */ + if (folder->dont_show_if_empty) { + /* Make sure we have the entries */ + ensure_folder (dh->info, folder, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + + if (folder->entries == NULL) { + /* start this function over on the + * next item */ + goto read_directory_again; + } + } + + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_NONE; + + file_info->name = g_strdup (entry->name); + GNOME_VFS_FILE_INFO_SET_LOCAL (file_info, TRUE); + + file_info->type = GNOME_VFS_FILE_TYPE_DIRECTORY; + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_TYPE; + + file_info->mime_type = g_strdup ("x-directory/vfolder-desktop"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + file_info->ctime = dh->info->modification_time; + file_info->mtime = dh->info->modification_time; + file_info->valid_fields |= (GNOME_VFS_FILE_INFO_FIELDS_CTIME | + GNOME_VFS_FILE_INFO_FIELDS_MTIME); + } + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_get_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result = GNOME_VFS_OK; + Folder *folder; + VFolderInfo *info; + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + G_LOCK (vfolder_lock); + file_uri = desktop_uri_to_file_uri (info, + &vuri, + NULL /* the_entry */, + NULL /* the_is_directory_file */, + &folder, + FALSE /* privatize */, + &result, + context); + G_UNLOCK (vfolder_lock); + + if (file_uri == NULL && + result != GNOME_VFS_ERROR_IS_DIRECTORY) + return result; + + if (file_uri != NULL) { + /* we always get mime-type by forcing it below */ + if (options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE) + options &= ~GNOME_VFS_FILE_INFO_GET_MIME_TYPE; + + result = (* parent_method->get_file_info) (parent_method, + file_uri, + file_info, + options, + context); + + g_free (file_info->mime_type); + file_info->mime_type = g_strdup ("application/x-gnome-app-info"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + /* Now we wipe those fields we don't support */ + file_info->valid_fields &= ~(UNSUPPORTED_INFO_FIELDS); + + gnome_vfs_uri_unref (file_uri); + + return result; + } else if (folder != NULL) { + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_NONE; + + file_info->name = g_strdup (folder->entry.name); + GNOME_VFS_FILE_INFO_SET_LOCAL (file_info, TRUE); + + file_info->type = GNOME_VFS_FILE_TYPE_DIRECTORY; + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_TYPE; + + file_info->mime_type = g_strdup ("x-directory/vfolder-desktop"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + file_info->ctime = info->modification_time; + file_info->mtime = info->modification_time; + file_info->valid_fields |= (GNOME_VFS_FILE_INFO_FIELDS_CTIME | + GNOME_VFS_FILE_INFO_FIELDS_MTIME); + + return GNOME_VFS_OK; + } else { + return GNOME_VFS_ERROR_NOT_FOUND; + } +} + +static GnomeVFSResult +do_get_file_info_from_handle (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + if (method_handle == (GnomeVFSMethodHandle *)method) { + g_free (file_info->mime_type); + file_info->mime_type = g_strdup ("text/plain"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + return GNOME_VFS_OK; + } + + /* we always get mime-type by forcing it below */ + if (options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE) + options &= ~GNOME_VFS_FILE_INFO_GET_MIME_TYPE; + + result = (* parent_method->get_file_info_from_handle) (parent_method, + handle->handle, + file_info, + options, + context); + + /* any file is of the .desktop type */ + g_free (file_info->mime_type); + file_info->mime_type = g_strdup ("application/x-gnome-app-info"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + /* Now we wipe those fields we don't support */ + file_info->valid_fields &= ~(UNSUPPORTED_INFO_FIELDS); + + return result; +} + + +static gboolean +do_is_local (GnomeVFSMethod *method, + const GnomeVFSURI *uri) +{ + return TRUE; +} + +static void +try_free_folder_monitors_create_unlocked (VFolderInfo *info, + Folder *folder) +{ + GSList *li, *list; + + list = g_slist_copy (info->free_folder_monitors); + + for (li = list; li != NULL; li = li->next) { + FileMonitorHandle *handle = li->data; + Folder *f; + VFolderURI vuri; + GnomeVFSResult result; + + /* Evil! EVIL URI PARSING. this will eat a lot of stack if we + * have lots of free monitors */ + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + f = resolve_folder (info, + vuri.path, + FALSE /* ignore_basename */, + &result, + NULL); + + if (folder != f) + continue; + + info->free_folder_monitors = + g_slist_remove (info->free_folder_monitors, handle); + ((Entry *)folder)->monitors = + g_slist_prepend (((Entry *)folder)->monitors, handle); + + handle->exists = TRUE; + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *)handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_CREATED); + } +} + + +static GnomeVFSResult +do_make_directory (GnomeVFSMethod *method, + GnomeVFSURI *uri, + guint perm, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + VFolderInfo *info; + Folder *parent, *folder; + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + if (vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (info->user_filename == NULL || + info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + parent = resolve_folder (info, vuri.path, + TRUE /* ignore_basename */, + &result, context); + if (parent == NULL) + return result; + else if (parent->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + G_LOCK (vfolder_lock); + + folder = (Folder *)find_entry (parent->subfolders, + vuri.file); + if (folder != NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_FILE_EXISTS; + } + + folder = folder_new (vuri.file); + parent->subfolders = g_slist_append (parent->subfolders, folder); + folder->parent = parent; + parent->up_to_date = FALSE; + + try_free_folder_monitors_create_unlocked (info, folder); + + /* parent changed */ + emit_monitor (parent, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_remove_directory (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + Folder *folder; + VFolderInfo *info; + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + if (vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (info->user_filename == NULL || + info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + G_LOCK (vfolder_lock); + + folder = resolve_folder (info, vuri.path, + FALSE /* ignore_basename */, + &result, context); + if (folder == NULL) { + G_UNLOCK (vfolder_lock); + return result; + } + + if (folder->read_only || + (folder->parent != NULL && + folder->parent->read_only)) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_READ_ONLY; + } + + /* don't make removing directories easy */ + if (folder->desktop_file != NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY; + } + + /* Make sure we have the entries */ + ensure_folder_unlocked (info, folder, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + + /* don't make removing directories easy */ + if (folder->entries != NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY; + } + + emit_and_delete_monitor (info, folder); + + if (folder->only_unallocated) { + GSList *li = g_slist_find (info->unallocated_folders, + folder); + if (li != NULL) { + info->unallocated_folders = g_slist_delete_link + (info->unallocated_folders, li); + entry_unref ((Entry *)folder); + } + } + + if (folder == info->root) { + info->root = NULL; + entry_unref ((Entry *)folder); + info->root = folder_new ("Root"); + } else { + Folder *parent = folder->parent; + + g_assert (parent != NULL); + + parent->subfolders = + g_slist_remove (parent->subfolders, folder); + + parent->up_to_date = FALSE; + + entry_unref ((Entry *)folder); + + /* parent changed */ + emit_monitor (parent, GNOME_VFS_MONITOR_EVENT_CHANGED); + } + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; +} + +/* a fairly evil function that does the whole move bit by copy and + * remove */ +static GnomeVFSResult +long_move (GnomeVFSMethod *method, + VFolderURI *old_vuri, + VFolderURI *new_vuri, + gboolean force_replace, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + GnomeVFSMethodHandle *handle; + GnomeVFSURI *file_uri; + const char *path; + int fd; + char buf[BUFSIZ]; + int bytes; + VFolderInfo *info; + + info = get_vfolder_info (old_vuri->scheme, &result, context); + if (info == NULL) + return result; + + G_LOCK (vfolder_lock); + file_uri = desktop_uri_to_file_uri (info, + old_vuri, + NULL /* the_entry */, + NULL /* the_is_directory_file */, + NULL /* the_folder */, + FALSE /* privatize */, + &result, + context); + G_UNLOCK (vfolder_lock); + + if (file_uri == NULL) + return result; + + path = gnome_vfs_uri_get_path (file_uri); + if (path == NULL) { + gnome_vfs_uri_unref (file_uri); + return GNOME_VFS_ERROR_INVALID_URI; + } + + fd = open (path, O_RDONLY); + if (fd < 0) { + gnome_vfs_uri_unref (file_uri); + return gnome_vfs_result_from_errno (); + } + + gnome_vfs_uri_unref (file_uri); + + info->inhibit_write++; + + result = method->create (method, + &handle, + new_vuri->uri, + GNOME_VFS_OPEN_WRITE, + force_replace /* exclusive */, + 0600 /* perm */, + context); + if (result != GNOME_VFS_OK) { + close (fd); + info->inhibit_write--; + return result; + } + + while ((bytes = read (fd, buf, BUFSIZ)) > 0) { + GnomeVFSFileSize bytes_written = 0; + result = method->write (method, + handle, + buf, + bytes, + &bytes_written, + context); + if (result == GNOME_VFS_OK && + bytes_written != bytes) + result = GNOME_VFS_ERROR_NO_SPACE; + if (result != GNOME_VFS_OK) { + close (fd); + method->close (method, handle, context); + /* FIXME: is this completely correct ? */ + method->unlink (method, + new_vuri->uri, + context); + G_LOCK (vfolder_lock); + info->inhibit_write--; + vfolder_info_write_user (info); + G_UNLOCK (vfolder_lock); + return result; + } + } + + close (fd); + + result = method->close (method, handle, context); + if (result != GNOME_VFS_OK) { + G_LOCK (vfolder_lock); + info->inhibit_write--; + vfolder_info_write_user (info); + G_UNLOCK (vfolder_lock); + return result; + } + + result = method->unlink (method, old_vuri->uri, context); + + G_LOCK (vfolder_lock); + info->inhibit_write--; + vfolder_info_write_user (info); + G_UNLOCK (vfolder_lock); + + return result; +} + +static GnomeVFSResult +move_directory_file (VFolderInfo *info, + Folder *old_folder, + Folder *new_folder) +{ + if (old_folder->desktop_file == NULL) + return GNOME_VFS_ERROR_NOT_FOUND; + + /* "move" the desktop file */ + g_free (new_folder->desktop_file); + new_folder->desktop_file = old_folder->desktop_file; + old_folder->desktop_file = NULL; + + /* is this too drastic, it will requery the folder? */ + new_folder->up_to_date = FALSE; + old_folder->up_to_date = FALSE; + + emit_monitor (new_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + emit_monitor (old_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + + return GNOME_VFS_OK; +} + +static gboolean +is_sub (Folder *master, Folder *sub) +{ + GSList *li; + + for (li = master->subfolders; li != NULL; li = li->next) { + Folder *subfolder = li->data; + + if (subfolder == sub || + is_sub (subfolder, sub)) + return TRUE; + } + + return FALSE; +} + +static GnomeVFSResult +move_folder (VFolderInfo *info, + Folder *old_folder, Entry *old_entry, + Folder *new_folder, Entry *new_entry) +{ + Folder *source = (Folder *)old_entry; + Folder *target; + + if (new_entry != NULL && + new_entry->type != ENTRY_FOLDER) + return GNOME_VFS_ERROR_NOT_A_DIRECTORY; + + if (new_entry != NULL) { + target = (Folder *)new_entry; + } else { + target = new_folder; + } + + /* move to where we are, yay, we're done :) */ + if (source->parent == target) + return GNOME_VFS_OK; + + if (source == target || + is_sub (source, target)) + return GNOME_VFS_ERROR_LOOP; + + /* this will never happen, but we're paranoid */ + if (source->parent == NULL) + return GNOME_VFS_ERROR_LOOP; + + source->parent->subfolders = g_slist_remove (source->parent->subfolders, + source); + target->subfolders = g_slist_append (target->subfolders, + source); + + source->parent = target; + + source->up_to_date = FALSE; + target->up_to_date = FALSE; + + emit_monitor (source, GNOME_VFS_MONITOR_EVENT_CHANGED); + emit_monitor (target, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_move (GnomeVFSMethod *method, + GnomeVFSURI *old_uri, + GnomeVFSURI *new_uri, + gboolean force_replace, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + VFolderInfo *info; + Folder *old_folder, *new_folder; + Entry *old_entry, *new_entry; + gboolean old_is_directory_file, new_is_directory_file; + VFolderURI old_vuri, new_vuri; + + VFOLDER_URI_PARSE (old_uri, &old_vuri); + VFOLDER_URI_PARSE (new_uri, &new_vuri); + + if (old_vuri.file == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + if (old_vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + if (strcmp (old_vuri.scheme, new_vuri.scheme) != 0) + return GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM; + + info = get_vfolder_info (old_vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + old_entry = get_entry (&old_vuri, + &old_folder, + &old_is_directory_file, + &result, + context); + if (old_entry == NULL) + return result; + + if (old_folder != NULL && old_folder->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + new_entry = get_entry (&new_vuri, + &new_folder, + &new_is_directory_file, + &result, + context); + if (new_entry == NULL && new_folder == NULL) + return result; + + if (new_folder != NULL && new_folder->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + if (new_is_directory_file != old_is_directory_file) { + /* this will do another set of lookups + * perhaps this can be done in a nicer way, + * but is this the common case? I don't think so */ + return long_move (method, &old_vuri, &new_vuri, + force_replace, context); + } + + if (new_is_directory_file) { + g_assert (old_entry != NULL); + g_assert (new_entry != NULL); + G_LOCK (vfolder_lock); + result = move_directory_file (info, + (Folder *)old_entry, + (Folder *)new_entry); + G_UNLOCK (vfolder_lock); + return result; + } + + if (old_entry->type == ENTRY_FOLDER) { + G_LOCK (vfolder_lock); + result = move_folder (info, + old_folder, old_entry, + new_folder, new_entry); + G_UNLOCK (vfolder_lock); + return result; + } + + /* move into self, just whack the old one */ + if (old_entry == new_entry) { + /* same folder */ + if (new_folder == old_folder) + return GNOME_VFS_OK; + + if ( ! force_replace) + return GNOME_VFS_ERROR_FILE_EXISTS; + + G_LOCK (vfolder_lock); + + remove_file (old_folder, old_vuri.file); + + old_folder->entries = g_slist_remove (old_folder->entries, + old_entry); + entry_unref (old_entry); + + emit_monitor (old_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; + } + + /* this is a simple move */ + if (new_entry == NULL || + new_entry->type == ENTRY_FOLDER) { + if (new_entry != NULL) { + new_folder = (Folder *)new_entry; + } else { + /* a file and a totally different one */ + if (strcmp (new_vuri.file, old_entry->name) != 0) { + /* yay, a long move */ + /* this will do another set of lookups + * perhaps this can be done in a nicer way, + * but is this the common case? I don't think + * so */ + return long_move (method, &old_vuri, &new_vuri, + force_replace, context); + } + } + + /* same folder */ + if (new_folder == old_folder) + return GNOME_VFS_OK; + + G_LOCK (vfolder_lock); + + remove_file (old_folder, old_entry->name); + add_file (new_folder, old_entry->name); + + new_folder->entries = g_slist_prepend (new_folder->entries, + old_entry); + entry_ref (old_entry); + new_folder->sorted = FALSE; + + old_folder->entries = g_slist_remove (old_folder->entries, + old_entry); + entry_unref (old_entry); + + emit_monitor (new_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + emit_monitor (old_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; + } + + /* do we EVER get here? */ + + /* this will do another set of lookups + * perhaps this can be done in a nicer way, + * but is this the common case? I don't think so */ + return long_move (method, &old_vuri, &new_vuri, + force_replace, context); +} + +static GnomeVFSResult +do_unlink (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + Entry *entry; + Folder *the_folder; + gboolean is_directory_file; + VFolderInfo *info; + VFolderURI vuri; + GSList *li; + + VFOLDER_URI_PARSE (uri, &vuri); + + if (vuri.file == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + if (vuri.is_all_scheme == TRUE) + return GNOME_VFS_ERROR_READ_ONLY; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + else if (info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + entry = get_entry (&vuri, + &the_folder, + &is_directory_file, + &result, context); + if (entry == NULL) + return result; + else if (the_folder != NULL && + the_folder->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + if (entry->type == ENTRY_FOLDER && + is_directory_file) { + Folder *folder = (Folder *)entry; + + if (folder->desktop_file == NULL) + return GNOME_VFS_ERROR_NOT_FOUND; + + G_LOCK (vfolder_lock); + + g_free (folder->desktop_file); + folder->desktop_file = NULL; + + emit_monitor (folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; + } else if (entry->type == ENTRY_FOLDER) { + return GNOME_VFS_ERROR_IS_DIRECTORY; + } else if (the_folder == NULL) { + return GNOME_VFS_ERROR_NOT_FOUND; + } + + G_LOCK (vfolder_lock); + + the_folder->entries = g_slist_remove (the_folder->entries, + entry); + entry_unref (entry); + + remove_file (the_folder, vuri.file); + + emit_monitor (the_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + + /* evil, we must remove this from the unallocated folders as well + * so that it magically doesn't appear there. But it's not so simple. + * We only want to remove it if it isn't in that folder already. */ + for (li = info->unallocated_folders; + li != NULL; + li = li->next) { + Folder *folder = li->data; + GSList *l; + + /* This is actually really evil since ensuring + * an unallocated folder clears all other unallocated + * folders in it's wake. I'm not sure it's worth + * optimizing however */ + ensure_folder_unlocked (info, folder, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + l = g_slist_find (folder->entries, entry); + if (l == NULL) { + remove_file (folder, vuri.file); + } + } + + emit_file_deleted_monitor (info, entry, the_folder); + + /* FIXME: if this was a user file and this is the only + * reference to it, unlink it. */ + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_check_same_fs (GnomeVFSMethod *method, + GnomeVFSURI *source_uri, + GnomeVFSURI *target_uri, + gboolean *same_fs_return, + GnomeVFSContext *context) +{ + VFolderURI source_vuri, target_vuri; + + *same_fs_return = FALSE; + + VFOLDER_URI_PARSE (source_uri, &source_vuri); + VFOLDER_URI_PARSE (target_uri, &target_vuri); + + if (strcmp (source_vuri.scheme, target_vuri.scheme) != 0 || + source_vuri.is_all_scheme != target_vuri.is_all_scheme) + *same_fs_return = FALSE; + else + *same_fs_return = TRUE; + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_set_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + const GnomeVFSFileInfo *info, + GnomeVFSSetFileInfoMask mask, + GnomeVFSContext *context) +{ + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + if (vuri.file == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + if (mask & GNOME_VFS_SET_FILE_INFO_NAME) { + GnomeVFSResult result = GNOME_VFS_OK; + char *dirname = gnome_vfs_uri_extract_dirname (uri); + GnomeVFSURI *new_uri = gnome_vfs_uri_dup (uri); + + G_LOCK (vfolder_lock); + g_free (new_uri->text); + new_uri->text = g_build_path ("/", dirname, info->name, NULL); + G_UNLOCK (vfolder_lock); + + result = do_move (method, + uri, + new_uri, + FALSE /* force_replace */, + context); + + g_free (dirname); + gnome_vfs_uri_unref (new_uri); + return result; + } else { + /* We don't support setting any of this other permission, + * times and all that voodoo */ + return GNOME_VFS_ERROR_NOT_SUPPORTED; + } +} + +static GnomeVFSResult +do_monitor_add (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle_return, + GnomeVFSURI *uri, + GnomeVFSMonitorType monitor_type) +{ + VFolderInfo *info; + VFolderURI vuri; + GnomeVFSResult result; + Folder *folder; + Entry *entry; + GnomeVFSURI *file_uri; + FileMonitorHandle *handle; + gboolean is_directory_file; + + VFOLDER_URI_PARSE (uri, &vuri); + + info = get_vfolder_info (vuri.scheme, &result, NULL); + if (info == NULL) + return result; + + if (monitor_type == GNOME_VFS_MONITOR_DIRECTORY) { + G_LOCK (vfolder_lock); + + folder = resolve_folder (info, + vuri.path, + FALSE /* ignore_basename */, + &result, + NULL); + + handle = g_new0 (FileMonitorHandle, 1); + handle->refcount = 2; + handle->uri = gnome_vfs_uri_dup (uri); + handle->dir_monitor = TRUE; + handle->handle = NULL; + handle->filename = NULL; + + if (folder == NULL) { + handle->exists = FALSE; + info->free_folder_monitors = + g_slist_prepend (info->free_folder_monitors, + handle); + } else { + handle->exists = TRUE; + ((Entry *)folder)->monitors = + g_slist_prepend (((Entry *)folder)->monitors, + handle); + } + + info->folder_monitors = + g_slist_prepend (info->folder_monitors, handle); + + G_UNLOCK (vfolder_lock); + + *method_handle_return = (GnomeVFSMethodHandle *) handle; + + return GNOME_VFS_OK; + } else { + /* These can't be very nice FILE names */ + if (vuri.file == NULL || + vuri.ends_in_slash) + return GNOME_VFS_ERROR_INVALID_URI; + + G_LOCK (vfolder_lock); + file_uri = desktop_uri_to_file_uri (info, + &vuri, + &entry, + &is_directory_file, + NULL /* the_folder */, + FALSE, + &result, + NULL); + + handle = g_new0 (FileMonitorHandle, 1); + handle->refcount = 2; + handle->uri = gnome_vfs_uri_dup (uri); + handle->dir_monitor = FALSE; + handle->handle = NULL; + handle->filename = g_strdup (vuri.file); + handle->is_directory_file = is_directory_file; + + info->file_monitors = + g_slist_prepend (info->file_monitors, handle); + + + if (file_uri == NULL) { + handle->exists = FALSE; + info->free_file_monitors = + g_slist_prepend (info->free_file_monitors, + handle); + } else { + char *uri_string = gnome_vfs_uri_to_string (file_uri, 0); + handle->exists = TRUE; + gnome_vfs_monitor_add (&(handle->handle), + uri_string, + GNOME_VFS_MONITOR_FILE, + file_monitor, + handle); + g_free (uri_string); + + entry->monitors = g_slist_prepend (entry->monitors, + handle); + gnome_vfs_uri_unref (file_uri); + } + + *method_handle_return = (GnomeVFSMethodHandle *) handle; + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; + } +} + +static GnomeVFSResult +do_monitor_cancel (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle) +{ + FileMonitorHandle *handle; + VFolderInfo *info; + VFolderURI vuri; + GnomeVFSResult result; + Folder *folder; + GSList *li; + + handle = (FileMonitorHandle *)method_handle; + + /* FIXME: is this correct? */ + if (method_handle == NULL) + return GNOME_VFS_OK; + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + info = get_vfolder_info (vuri.scheme, &result, NULL); + if (info == NULL) + return result; + + if (handle->dir_monitor) { + G_LOCK (vfolder_lock); + + folder = resolve_folder (info, + vuri.path, + FALSE /* ignore_basename */, + &result, + NULL); + + for (li = info->folder_monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + if (h != handle) + continue; + info->folder_monitors = g_slist_delete_link + (info->folder_monitors, li); + file_monitor_handle_unref_unlocked (h); + break; + } + + if (folder == NULL) { + for (li = info->free_folder_monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *h = li->data; + if (h != handle) + continue; + info->free_folder_monitors = g_slist_delete_link + (info->free_folder_monitors, li); + file_monitor_handle_unref_unlocked (h); + break; + } + } else { + for (li = ((Entry *)folder)->monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *h = li->data; + if (h != handle) + continue; + ((Entry *)folder)->monitors = + g_slist_delete_link + (((Entry *)folder)->monitors, li); + file_monitor_handle_unref_unlocked (h); + break; + } + } + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; + } else { + G_LOCK (vfolder_lock); + + for (li = info->file_monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + if (h != handle) + continue; + info->file_monitors = g_slist_delete_link + (info->file_monitors, li); + file_monitor_handle_unref_unlocked (h); + break; + } + + for (li = info->free_file_monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *h = li->data; + if (h != handle) + continue; + info->free_file_monitors = g_slist_delete_link + (info->free_file_monitors, li); + file_monitor_handle_unref_unlocked (h); + break; + } + + for (li = info->entries; li != NULL; li = li->next) { + Entry *e = li->data; + GSList *link = g_slist_find (e->monitors, handle); + + if (link == NULL) + continue; + link->data = NULL; + e->monitors = g_slist_delete_link (e->monitors, link); + + file_monitor_handle_unref_unlocked (handle); + break; + } + + G_UNLOCK (vfolder_lock); + + /* Note: last unref of our monitor will cancel the + * underlying handle */ + + return GNOME_VFS_OK; + } +} + + +/* gnome-vfs bureaucracy */ + +static GnomeVFSMethod method = { + sizeof (GnomeVFSMethod), + do_open, + do_create, + do_close, + do_read, + do_write, + do_seek, + do_tell, + do_truncate_handle, + do_open_directory, + do_close_directory, + do_read_directory, + do_get_file_info, + do_get_file_info_from_handle, + do_is_local, + do_make_directory, + do_remove_directory, + do_move, + do_unlink, + do_check_same_fs, + do_set_file_info, + do_truncate, + NULL /* find_directory */, + NULL /* create_symbolic_link */, + do_monitor_add, + do_monitor_cancel +}; + +GnomeVFSMethod * +vfs_module_init (const char *method_name, + const char *args) +{ + parent_method = gnome_vfs_method_get ("file"); + + if (parent_method == NULL) { + g_error ("Could not find 'file' method for gnome-vfs"); + return NULL; + } + + return &method; +} + +void +vfs_module_shutdown (GnomeVFSMethod *method) +{ + if (infos == NULL) + return; + + g_hash_table_destroy (infos); + infos = NULL; +} diff --git a/modules/vfolder-desktop-method.c.never-show-if-empty b/modules/vfolder-desktop-method.c.never-show-if-empty new file mode 100644 index 0000000..40a3bfa --- /dev/null +++ b/modules/vfolder-desktop-method.c.never-show-if-empty @@ -0,0 +1,6136 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: 8; c-basic-offset: 8 -*- */ + +/* vfolder-desktop-method.c + + Copyright (C) 2001 Red Hat, Inc. + Copyright (C) 2001 The Dark Prince + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/* URI scheme for reading the "applications:" vfolder and other + * vfolder schemes. Lots of code stolen from the original desktop + * reading URI scheme. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +/* Debugging foo: */ +/*#define D(x) x */ +#define D(x) ; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#define DOT_GNOME ".gnome2" + +typedef struct _VFolderInfo VFolderInfo; +typedef struct _Query Query; +typedef struct _QueryKeyword QueryKeyword; +typedef struct _QueryFilename QueryFilename; +typedef struct _Entry Entry; +typedef struct _Folder Folder; +typedef struct _EntryFile EntryFile; +typedef struct _Keyword Keyword; +typedef struct _FileMonitorHandle FileMonitorHandle; +typedef struct _StatLoc StatLoc; +typedef struct _VFolderURI VFolderURI; + +/* TODO before 2.0: */ +/* FIXME: also check/monitor desktop_dirs like we do the vfolder + * file and the item dirs */ +/* FIXME: check if thread locks are not completely on crack which + * is likely given my experience with threads */ +/* FIXME: use filename locking, currently we are full of races if + * multiple processes write to this filesystem */ +/* FIXME: implement monitors */ + +/* TODO for later (star trek future): */ +/* FIXME: Maybe when chaining to file:, we should call the gnome-vfs wrapper + * functions, instead of the file: methods directly. */ +/* FIXME: related to the above: we should support things being on non + * file: filesystems. Such as having the vfolder info file on http + * somewhere or some such nonsense :) */ + +static GnomeVFSMethod *parent_method = NULL; + +static GHashTable *infos = NULL; + +/* Note: I have no clue about how to write thread safe code and this + * is my first attempt, so it's probably wrong + * -George */ +G_LOCK_DEFINE_STATIC (vfolder_lock); + +/* Note: all keywords are quarks */ +/* Note: basenames are unique */ + +#define UNSUPPORTED_INFO_FIELDS (GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS | \ + GNOME_VFS_FILE_INFO_FIELDS_DEVICE | \ + GNOME_VFS_FILE_INFO_FIELDS_INODE | \ + GNOME_VFS_FILE_INFO_FIELDS_LINK_COUNT | \ + GNOME_VFS_FILE_INFO_FIELDS_ATIME) + + +enum { + QUERY_OR, + QUERY_AND, + QUERY_KEYWORD, + QUERY_FILENAME +}; + +struct _Query { + int type; + gboolean not; + GSList *queries; +}; + +struct _QueryKeyword { + int type; + gboolean not; + GQuark keyword; +}; + +struct _QueryFilename { + int type; + gboolean not; + char *filename; +}; + +enum { + ENTRY_FILE, + ENTRY_FOLDER +}; + +struct _Entry { + int type; + int refcount; + int alloc; /* not really useful for folders, + but oh well, whatever. It's the number + of times this is queried in some directory, + used for the Unallocated query type */ + char *name; + + GSList *monitors; +}; + +struct _EntryFile { + Entry entry; + + char *filename; + gboolean per_user; + GSList *keywords; + + gboolean implicit_keywords; /* the keywords were added by us */ +}; + +struct _Folder { + Entry entry; + + Folder *parent; + + char *desktop_file; /* the .directory file */ + + Query *query; + + /* The following is for per file + * access */ + /* excluded by filename */ + GHashTable *excludes; + /* included by filename */ + GSList *includes; + GHashTable *includes_ht; + + GSList *subfolders; + + /* Some flags */ + gboolean read_only; + gboolean dont_show_if_empty; + gboolean only_unallocated; /* include only unallocated items */ + + /* lazily done, will run query only when it + * needs to */ + gboolean up_to_date; + gboolean sorted; + GSList *entries; +}; + +struct _StatLoc { + time_t ctime; + time_t last_stat; + gboolean trigger_next; /* if true, next check will fail */ + char name[1]; /* the structure will be long enough to + fit name */ +}; + +struct _VFolderInfo { + char *scheme; + + char *filename; + char *user_filename; + time_t user_filename_last_write; + char *desktop_dir; /* directory with .directorys */ + char *user_desktop_dir; /* directory with .directorys */ + gboolean user_file_active; /* if using user_filename and + not filename */ + + GSList *item_dirs; + char *user_item_dir; /* dir where user changes to + items are stored */ + + /* old style dirs to merge in */ + GSList *merge_dirs; + + /* if entries are valid, else + * they need to be (re)read */ + gboolean entries_valid; + + GSList *entries; + + /* entry hash by basename */ + GHashTable *entries_ht; + + /* The root folder */ + Folder *root; + + /* The unallocated folders, the folder which only + * include unallocated items */ + GSList *unallocated_folders; + + /* some flags */ + gboolean read_only; + + gboolean dirty; + + int inhibit_write; + + /* change monitoring stuff */ + GnomeVFSMonitorHandle *filename_monitor; + GnomeVFSMonitorHandle *user_filename_monitor; + + /* stat locations (in case we aren't monitoring) */ + StatLoc *filename_statloc; + StatLoc *user_filename_statloc; + + /* for .directory dirs */ + /* FIXME: */GnomeVFSMonitorHandle *desktop_dir_monitor; + /* FIXME: */GnomeVFSMonitorHandle *user_desktop_dir_monitor; + + /* stat locations (in case we aren't monitoring) */ + /* FIXME: */StatLoc *desktop_dir_statloc; + /* FIXME: */StatLoc *user_desktop_dir_statloc; + + /* FIXME: */GSList *file_monitors; /* FileMonitorHandle */ + /* FIXME: */GSList *free_file_monitors; /* FileMonitorHandle */ + GSList *folder_monitors; /* FileMonitorHandle */ + GSList *free_folder_monitors; /* FileMonitorHandle */ + + GSList *item_dir_monitors; /* GnomeVFSMonitorHandle */ + + /* item dirs to stat */ + GSList *stat_dirs; + + /* ctime for folders */ + time_t modification_time; + + guint reread_queue; +}; + +struct _FileMonitorHandle { + int refcount; + gboolean exists; + gboolean dir_monitor; /* TRUE if dir, FALSE if file */ + GnomeVFSURI *uri; + GnomeVFSMonitorHandle *handle; /* A real handle if we're monitoring + an actual file here, or NULL */ + char *filename; /* Just the basename, used in the free_file_list */ + gboolean is_directory_file; +}; + +struct _VFolderURI { + const gchar *scheme; + gboolean is_all_scheme; + gboolean ends_in_slash; + gchar *path; + gchar *file; + GnomeVFSURI *uri; +}; + + +static Entry * entry_ref (Entry *entry); +static Entry * entry_ref_alloc (Entry *entry); +static void entry_unref (Entry *entry); +static void entry_unref_dealloc (Entry *entry); +static void query_destroy (Query *query); +static void ensure_folder (VFolderInfo *info, + Folder *folder, + gboolean subfolders, + Folder *except, + gboolean ignore_unallocated); +static void ensure_folder_unlocked (VFolderInfo *info, + Folder *folder, + gboolean subfolders, + Folder *except, + gboolean ignore_unallocated); +/* An EVIL function for quick reading of .desktop files, + * only reads in one or two keys, but that's ALL we need */ +static void readitem_entry (const char *filename, + const char *key1, + char **result1, + const char *key2, + char **result2); +static gboolean vfolder_info_reload (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context, + gboolean force_read_items); +static gboolean vfolder_info_reload_unlocked (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context, + gboolean force_read_items); +static void invalidate_folder_subfolders (Folder *folder, + gboolean lock_taken); +static Folder * resolve_folder (VFolderInfo *info, + const char *path, + gboolean ignore_basename, + GnomeVFSResult *result, + GnomeVFSContext *context); +static gboolean vfolder_info_read_items (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context); + +/* assumes vuri->path already set */ +static gboolean +vfolder_uri_parse_internal (GnomeVFSURI *uri, VFolderURI *vuri) +{ + vuri->scheme = (gchar *) gnome_vfs_uri_get_scheme (uri); + + vuri->ends_in_slash = FALSE; + + if (strncmp (vuri->scheme, "all-", strlen ("all-")) == 0) { + vuri->scheme += strlen ("all-"); + vuri->is_all_scheme = TRUE; + } else + vuri->is_all_scheme = FALSE; + + if (vuri->path != NULL) { + int last_slash = strlen (vuri->path) - 1; + char *first; + + /* Note: This handling of paths is somewhat evil, may need a + * bit of a rework */ + + /* kill leading slashes, that is make sure there is + * only one */ + for (first = vuri->path; *first == '/'; first++) + ; + if (first != vuri->path) { + first--; + vuri->path = first; + } + + /* kill trailing slashes (leave first if all slashes) */ + while (last_slash > 0 && vuri->path [last_slash] == '/') { + vuri->path [last_slash--] = '\0'; + vuri->ends_in_slash = TRUE; + } + + /* get basename start */ + while (last_slash >= 0 && vuri->path [last_slash] != '/') + last_slash--; + + if (last_slash > -1) + vuri->file = vuri->path + last_slash + 1; + else + vuri->file = vuri->path; + + if (vuri->file[0] == '\0' && + strcmp (vuri->path, "/") == 0) { + vuri->file = NULL; + } + } else { + vuri->ends_in_slash = TRUE; + vuri->path = "/"; + vuri->file = NULL; + } + + vuri->uri = uri; + + return TRUE; +} + +#define VFOLDER_URI_PARSE(_uri, _vuri) { \ + gchar *path; \ + path = gnome_vfs_unescape_string ((_uri)->text, G_DIR_SEPARATOR_S); \ + if (path != NULL) { \ + (_vuri)->path = g_alloca (strlen (path) + 1); \ + strcpy ((_vuri)->path, path); \ + g_free (path); \ + } else { \ + (_vuri)->path = NULL; \ + } \ + vfolder_uri_parse_internal ((_uri), (_vuri)); \ +} + +static FileMonitorHandle * +file_monitor_handle_ref_unlocked (FileMonitorHandle *h) +{ + h->refcount ++; + return h; +} + +static void +file_monitor_handle_unref_unlocked (FileMonitorHandle *h) +{ + h->refcount --; + if (h->refcount == 0) { + gnome_vfs_uri_unref (h->uri); + h->uri = NULL; + + g_free (h->filename); + h->filename = NULL; + + if (h->handle != NULL) { + gnome_vfs_monitor_cancel (h->handle); + h->handle = NULL; + } + } +} + +/* This includes the .directory files */ +static void +emit_monitor (Folder *folder, int type) +{ + GSList *li; + for (li = ((Entry *)folder)->monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *handle = li->data; + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *) handle, + handle->uri, type); + } +} + +static void +emit_file_deleted_monitor (VFolderInfo *info, Entry *entry, Folder *folder) +{ + GSList *li; + for (li = entry->monitors; + li != NULL; + li = li->next) { + VFolderURI vuri; + Folder *f; + GnomeVFSResult result; + FileMonitorHandle *handle = li->data; + + /* Evil! EVIL URI PARSING. this will eat a lot of + * stack if we have lots of monitors */ + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + f = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + + if (f == folder) + gnome_vfs_monitor_callback + ((GnomeVFSMethodHandle *) handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_DELETED); + } +} + +static void +emit_and_delete_monitor (VFolderInfo *info, Folder *folder) +{ + GSList *li; + for (li = ((Entry *)folder)->monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *handle = li->data; + li->data = NULL; + + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *) handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_DELETED); + + if (handle->dir_monitor) + info->free_folder_monitors = + g_slist_prepend (info->free_folder_monitors, + handle); + else + info->free_file_monitors = + g_slist_prepend (info->free_file_monitors, + handle); + } + g_slist_free (((Entry *)folder)->monitors); + ((Entry *)folder)->monitors = NULL; +} + +static gboolean +check_ext (const char *name, const char *ext_check) +{ + const char *ext; + + ext = strrchr (name, '.'); + if (ext == NULL || + strcmp (ext, ext_check) != 0) + return FALSE; + else + return TRUE; +} + +static StatLoc * +bake_statloc (const char *name, + time_t curtime) +{ + struct stat s; + StatLoc *sl = NULL; + if (stat (name, &s) != 0) { + if (errno == ENOENT) { + sl = g_malloc0 (sizeof (StatLoc) + + strlen (name) + 1); + sl->last_stat = curtime; + sl->ctime = 0; + sl->trigger_next = FALSE; + strcpy (sl->name, name); + } + return sl; + } + + sl = g_malloc0 (sizeof (StatLoc) + + strlen (name) + 1); + sl->last_stat = curtime; + sl->ctime = s.st_ctime; + sl->trigger_next = FALSE; + strcpy (sl->name, name); + + return sl; +} + +/* returns FALSE if we must reread */ +static gboolean +check_statloc (StatLoc *sl, + time_t curtime) +{ + struct stat s; + + if (sl->trigger_next) { + sl->trigger_next = FALSE; + return FALSE; + } + + /* don't stat more then once every 3 seconds */ + if (curtime <= sl->last_stat + 3) + return TRUE; + + sl->last_stat = curtime; + + if (stat (sl->name, &s) != 0) { + if (errno == ENOENT && + sl->ctime == 0) + return TRUE; + else + return FALSE; + } + + if (sl->ctime == s.st_ctime) + return TRUE; + else + return FALSE; +} + +static gboolean +ensure_dir (const char *dirname, gboolean ignore_basename) +{ + char *parsed, *p; + + if (dirname == NULL) + return FALSE; + + if (ignore_basename) + parsed = g_path_get_dirname (dirname); + else + parsed = g_strdup (dirname); + + if (g_file_test (parsed, G_FILE_TEST_IS_DIR)) { + g_free (parsed); + return TRUE; + } + + p = strchr (parsed, '/'); + if (p == parsed) + p = strchr (p+1, '/'); + + while (p != NULL) { + *p = '\0'; + if (mkdir (parsed, 0700) != 0 && + errno != EEXIST) { + g_free (parsed); + return FALSE; + } + *p = '/'; + p = strchr (p+1, '/'); + } + + if (mkdir (parsed, 0700) != 0 && + errno != EEXIST) { + g_free (parsed); + return FALSE; + } + + g_free (parsed); + return TRUE; +} + +/* check for any directory name other then root */ +static gboolean +any_subdir (const char *dirname) +{ + const char *p; + if (dirname == NULL) + return FALSE; + + for (p = dirname; *p != '\0'; p++) { + if (*p != '/') { + return TRUE; + } + } + return FALSE; +} + +static void +destroy_entry_file (EntryFile *efile) +{ + if (efile == NULL) + return; + + g_free (efile->filename); + efile->filename = NULL; + + g_slist_free (efile->keywords); + efile->keywords = NULL; + + g_free (efile); +} + +static void +destroy_folder (Folder *folder) +{ + GSList *list; + + if (folder == NULL) + return; + + if (folder->parent != NULL) { + folder->parent->subfolders = + g_slist_remove (folder->parent->subfolders, folder); + folder->parent->up_to_date = FALSE; + folder->parent = NULL; + } + + g_free (folder->desktop_file); + folder->desktop_file = NULL; + + query_destroy (folder->query); + folder->query = NULL; + + if (folder->excludes != NULL) { + g_hash_table_destroy (folder->excludes); + folder->excludes = NULL; + } + + g_slist_foreach (folder->includes, (GFunc)g_free, NULL); + g_slist_free (folder->includes); + folder->includes = NULL; + if (folder->includes_ht != NULL) { + g_hash_table_destroy (folder->includes_ht); + folder->includes_ht = NULL; + } + + list = folder->subfolders; + folder->subfolders = NULL; + g_slist_foreach (list, (GFunc)entry_unref, NULL); + g_slist_free (list); + + list = folder->entries; + folder->entries = NULL; + g_slist_foreach (list, (GFunc)entry_unref, NULL); + g_slist_free (list); + + g_free (folder); +} + +static Entry * +entry_ref (Entry *entry) +{ + if (entry != NULL) + entry->refcount++; + return entry; +} + +static Entry * +entry_ref_alloc (Entry *entry) +{ + entry_ref (entry); + + if (entry != NULL) + entry->alloc++; + + return entry; +} + +static void +entry_unref (Entry *entry) +{ + if (entry == NULL) + return; + + entry->refcount--; + + if (entry->refcount == 0) { + g_free (entry->name); + entry->name = NULL; + + g_slist_foreach (entry->monitors, + (GFunc)file_monitor_handle_unref_unlocked, + NULL); + g_slist_free (entry->monitors); + entry->monitors = NULL; + + if (entry->type == ENTRY_FILE) + destroy_entry_file ((EntryFile *)entry); + else /* ENTRY_FOLDER */ + destroy_folder ((Folder *)entry); + } +} + +static void +entry_unref_dealloc (Entry *entry) +{ + if (entry != NULL) { + entry->alloc --; + entry_unref (entry); + } +} + +/* Handles ONLY files, not dirs */ +/* Also allocates the entries as well as refs them */ +static GSList * +alloc_entries_from_files (VFolderInfo *info, GSList *filenames) +{ + GSList *li; + GSList *files; + + files = NULL; + for (li = filenames; li != NULL; li = li->next) { + char *filename = li->data; + GSList *entry_list = g_hash_table_lookup (info->entries_ht, filename); + if (entry_list != NULL) + files = g_slist_prepend (files, + entry_ref_alloc (entry_list->data)); + } + + return files; +} + +static gboolean +matches_query (VFolderInfo *info, + Folder *folder, + EntryFile *efile, + Query *query) +{ + GSList *li; + + if (query == NULL) + return TRUE; + +#define INVERT_IF_NEEDED(val) (query->not ? !(val) : (val)) + switch (query->type) { + case QUERY_OR: + for (li = query->queries; li != NULL; li = li->next) { + Query *subquery = li->data; + if (matches_query (info, folder, efile, subquery)) + return INVERT_IF_NEEDED (TRUE); + } + return INVERT_IF_NEEDED (FALSE); + case QUERY_AND: + for (li = query->queries; li != NULL; li = li->next) { + Query *subquery = li->data; + if ( ! matches_query (info, folder, efile, subquery)) + return INVERT_IF_NEEDED (FALSE); + } + return INVERT_IF_NEEDED (TRUE); + case QUERY_KEYWORD: + { + QueryKeyword *qkeyword = (QueryKeyword *)query; + for (li = efile->keywords; li != NULL; li = li->next) { + GQuark keyword = GPOINTER_TO_INT (li->data); + if (keyword == qkeyword->keyword) + return INVERT_IF_NEEDED (TRUE); + } + return INVERT_IF_NEEDED (FALSE); + } + case QUERY_FILENAME: + { + QueryFilename *qfilename = (QueryFilename *)query; + if (strcmp (qfilename->filename, ((Entry *)efile)->name) == 0) { + return INVERT_IF_NEEDED (TRUE); + } else { + return INVERT_IF_NEEDED (FALSE); + } + } + } +#undef INVERT_IF_NEEDED + g_assert_not_reached (); + /* huh? */ + return FALSE; +} + +static void +dump_unallocated_folders (Folder *folder) +{ + GSList *li; + for (li = folder->subfolders; li != NULL; li = li->next) + dump_unallocated_folders (li->data); + + if (folder->only_unallocated && + folder->entries != NULL) { + g_slist_foreach (folder->entries, + (GFunc)entry_unref_dealloc, NULL); + g_slist_free (folder->entries); + folder->entries = NULL; + } +} + +/* Run query, allocs and refs the entries */ +static void +append_query (VFolderInfo *info, Folder *folder) +{ + GSList *li; + + if (folder->query == NULL && + ! folder->only_unallocated) + return; + + if (folder->only_unallocated) { + /* dump all folders that use unallocated + * items only. This sucks if you keep + * reading one and then another such + * folder, but oh well, life sucks for + * you then, but at least you get + * consistent results */ + dump_unallocated_folders (info->root); + + /* ensure all other folders, so that + * after this we know which ones are + * unallocated */ + ensure_folder_unlocked (info, + info->root, + TRUE /* subfolders */, + folder /* except */, + /* avoid infinite loops */ + TRUE /* ignore_unallocated */); + } + + for (li = info->entries; li != NULL; li = li->next) { + Entry *entry = li->data; + + if (/* if not file */ + entry->type != ENTRY_FILE || + /* if already included */ + (folder->includes_ht != NULL && + g_hash_table_lookup (folder->includes_ht, + entry->name) != NULL)) + continue; + + if (folder->only_unallocated && + entry->alloc != 0) + continue; + + if (matches_query (info, folder, (EntryFile *)entry, + folder->query)) + folder->entries = g_slist_prepend + (folder->entries, entry_ref_alloc (entry)); + } +} + +/* get entries in folder */ +/* FIXME: support cancellation here */ +static void +ensure_folder_unlocked (VFolderInfo *info, + Folder *folder, + gboolean subfolders, + Folder *except, + gboolean ignore_unallocated) +{ + if (subfolders) { + GSList *li; + for (li = folder->subfolders; li != NULL; li = li->next) + ensure_folder_unlocked (info, li->data, subfolders, + except, ignore_unallocated); + } + + if (except == folder) + return; + + if (ignore_unallocated && + folder->only_unallocated) + return; + + if (folder->up_to_date) + return; + + if (folder->entries != NULL) { + g_slist_foreach (folder->entries, + (GFunc)entry_unref_dealloc, NULL); + g_slist_free (folder->entries); + folder->entries = NULL; + } + + /* Include includes */ + folder->entries = alloc_entries_from_files (info, folder->includes); + + /* Run query */ + append_query (info, folder); + + /* We were prepending all this time */ + folder->entries = g_slist_reverse (folder->entries); + + /* Include subfolders */ + /* we always whack them onto the beginning */ + if (folder->subfolders != NULL) { + GSList *subfolders = g_slist_copy (folder->subfolders); + g_slist_foreach (subfolders, (GFunc)entry_ref_alloc, NULL); + folder->entries = g_slist_concat (subfolders, folder->entries); + } + + /* Exclude excludes */ + if (folder->excludes != NULL) { + GSList *li; + GSList *entries = folder->entries; + folder->entries = NULL; + for (li = entries; li != NULL; li = li->next) { + Entry *entry = li->data; + if (g_hash_table_lookup (folder->excludes, entry->name) == NULL) + folder->entries = g_slist_prepend (folder->entries, entry); + else + entry_unref_dealloc (entry); + + } + g_slist_free (entries); + + /* to preserve the Folders then everything else order */ + folder->entries = g_slist_reverse (folder->entries); + } + + folder->up_to_date = TRUE; + /* not yet sorted */ + folder->sorted = FALSE; +} + +static void +ensure_folder (VFolderInfo *info, + Folder *folder, + gboolean subfolders, + Folder *except, + gboolean ignore_unallocated) +{ + G_LOCK (vfolder_lock); + ensure_folder_unlocked (info, folder, subfolders, except, ignore_unallocated); + G_UNLOCK (vfolder_lock); +} + +static char * +get_directory_file_unlocked (VFolderInfo *info, Folder *folder) +{ + char *filename; + + /* FIXME: cache dir_files */ + + if (folder->desktop_file == NULL) + return NULL; + + if (folder->desktop_file[0] == G_DIR_SEPARATOR) + return g_strdup (folder->desktop_file); + + /* Now try the user directory */ + if (info->user_desktop_dir != NULL) { + filename = g_build_filename (info->user_desktop_dir, + folder->desktop_file, + NULL); + if (access (filename, F_OK) == 0) { + return filename; + } + + g_free (filename); + } + + filename = g_build_filename (info->desktop_dir, folder->desktop_file, NULL); + if (access (filename, F_OK) == 0) { + return filename; + } + g_free (filename); + + return NULL; +} + +static char * +get_directory_file (VFolderInfo *info, Folder *folder) +{ + char *ret; + + G_LOCK (vfolder_lock); + ret = get_directory_file_unlocked (info, folder); + G_UNLOCK (vfolder_lock); + + return ret; +} + +static GSList * +get_sort_order (VFolderInfo *info, Folder *folder) +{ + GSList *list; + char **parsed; + char *order; + int i; + char *filename; + + filename = get_directory_file_unlocked (info, folder); + if (filename == NULL) + return NULL; + + order = NULL; + readitem_entry (filename, + "SortOrder", + &order, + NULL, + NULL); + g_free (filename); + + if (order == NULL) + return NULL; + + parsed = g_strsplit (order, ":", -1); + + g_free (order); + + list = NULL; + for (i = 0; parsed[i] != NULL; i++) { + char *word = parsed[i]; + /* steal */ + parsed[i] = NULL; + /* ignore empty */ + if (word[0] == '\0') { + g_free (word); + continue; + } + list = g_slist_prepend (list, word); + } + /* we've stolen all strings from it */ + g_free (parsed); + + return g_slist_reverse (list); +} + +/* get entries in folder */ +static void +ensure_folder_sort (VFolderInfo *info, Folder *folder) +{ + GSList *li, *sort_order; + GSList *entries; + GHashTable *entry_hash; + + ensure_folder (info, folder, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + if (folder->sorted) + return; + + G_LOCK (vfolder_lock); + + sort_order = get_sort_order (info, folder); + if (sort_order == NULL) { + folder->sorted = TRUE; + G_UNLOCK (vfolder_lock); + return; + } + + entries = folder->entries; + folder->entries = NULL; + + entry_hash = g_hash_table_new (g_str_hash, g_str_equal); + for (li = entries; li != NULL; li = li->next) { + Entry *entry = li->data; + g_hash_table_insert (entry_hash, entry->name, li); + } + + for (li = sort_order; li != NULL; li = li->next) { + char *word = li->data; + GSList *entry_list; + Entry *entry; + + /* we kill the words here */ + li->data = NULL; + + entry_list = g_hash_table_lookup (entry_hash, word); + g_free (word); + + if (entry_list == NULL) + continue; + + entry = entry_list->data; + + entries = g_slist_delete_link (entries, entry_list); + + folder->entries = g_slist_prepend (folder->entries, + entry); + } + + /* put on those that weren't mentioned in the sort */ + for (li = entries; li != NULL; li = li->next) { + Entry *entry = li->data; + + folder->entries = g_slist_prepend (folder->entries, + entry); + } + + g_hash_table_destroy (entry_hash); + g_slist_free (entries); + g_slist_free (sort_order); + + folder->sorted = TRUE; + + G_UNLOCK (vfolder_lock); +} + +static EntryFile * +file_new (const char *name) +{ + EntryFile *efile = g_new0 (EntryFile, 1); + + efile->entry.type = ENTRY_FILE; + efile->entry.name = g_strdup (name); + efile->entry.refcount = 1; + + return efile; +} + +static Folder * +folder_new (const char *name) +{ + Folder *folder = g_new0 (Folder, 1); + + folder->entry.type = ENTRY_FOLDER; + folder->entry.name = g_strdup (name); + folder->entry.refcount = 1; + folder->read_only = TRUE; + + return folder; +} + +static Query * +query_new (int type) +{ + Query *query; + + if (type == QUERY_KEYWORD) + query = (Query *)g_new0 (QueryKeyword, 1); + else if (type == QUERY_FILENAME) + query = (Query *)g_new0 (QueryFilename, 1); + else + query = g_new0 (Query, 1); + + query->type = type; + + return query; +} + +static void +query_destroy (Query *query) +{ + if (query == NULL) + return; + + if (query->type == QUERY_FILENAME) { + QueryFilename *qfile = (QueryFilename *)query; + g_free (qfile->filename); + qfile->filename = NULL; + } else if (query->type == QUERY_OR || + query->type == QUERY_AND) { + g_slist_foreach (query->queries, (GFunc)query_destroy, NULL); + g_slist_free (query->queries); + query->queries = NULL; + } + + g_free (query); +} + +static void +add_folder_monitor_unlocked (VFolderInfo *info, + FileMonitorHandle *handle) +{ + VFolderURI vuri; + GnomeVFSResult result; + Folder *folder; + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + file_monitor_handle_ref_unlocked (handle); + + info->folder_monitors = + g_slist_prepend (info->folder_monitors, handle); + + folder = resolve_folder (info, + vuri.path, + FALSE /* ignore_basename */, + &result, + NULL); + + if (folder == NULL) { + file_monitor_handle_ref_unlocked (handle); + + info->free_folder_monitors = + g_slist_prepend (info->free_folder_monitors, handle); + + if (handle->exists) { + handle->exists = FALSE; + gnome_vfs_monitor_callback + ((GnomeVFSMethodHandle *)handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_DELETED); + } + } else { + file_monitor_handle_ref_unlocked (handle); + + ((Entry *)folder)->monitors = + g_slist_prepend (((Entry *)folder)->monitors, handle); + + if ( ! handle->exists) { + handle->exists = TRUE; + gnome_vfs_monitor_callback + ((GnomeVFSMethodHandle *)handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_CREATED); + } + } + +} + +static inline void +invalidate_folder_T (Folder *folder) +{ + folder->up_to_date = FALSE; + + invalidate_folder_subfolders (folder, TRUE); +} + +static inline void +invalidate_folder (Folder *folder) +{ + G_LOCK (vfolder_lock); + folder->up_to_date = FALSE; + G_UNLOCK (vfolder_lock); + + invalidate_folder_subfolders (folder, FALSE); +} + +static void +invalidate_folder_subfolders (Folder *folder, + gboolean lock_taken) +{ + GSList *li; + + for (li = folder->subfolders; li != NULL; li = li->next) { + Folder *subfolder = li->data; + + if (!lock_taken) + invalidate_folder (subfolder); + else + invalidate_folder_T (subfolder); + } + + emit_monitor (folder, GNOME_VFS_MONITOR_EVENT_CHANGED); +} + +/* FIXME: this is UGLY!, we need to figure out when the file + * got finished changing! */ +static gboolean +reread_timeout (gpointer data) +{ + VFolderInfo *info = data; + gboolean force_read_items = info->file_monitors != NULL; + vfolder_info_reload (info, NULL, NULL, force_read_items); + return FALSE; +} + +static void +queue_reread_in (VFolderInfo *info, int msec) +{ + G_LOCK (vfolder_lock); + if (info->reread_queue != 0) + g_source_remove (info->reread_queue); + info->reread_queue = g_timeout_add (msec, reread_timeout, info); + G_UNLOCK (vfolder_lock); +} + +static void +vfolder_desktop_dir_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + /* FIXME: implement */ +} + +static void +vfolder_user_desktop_dir_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + /* FIXME: implement */ +} + +static void +vfolder_filename_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + VFolderInfo *info = user_data; + + if ((event_type == GNOME_VFS_MONITOR_EVENT_CREATED || + event_type == GNOME_VFS_MONITOR_EVENT_CHANGED) && + ! info->user_file_active) { + queue_reread_in (info, 200); + } else if (event_type == GNOME_VFS_MONITOR_EVENT_DELETED && + ! info->user_file_active) { + /* FIXME: is this correct? I mean now + * there probably isn't ANY vfolder file, so we + * init to default values really. I have no clue what's + * right here */ + vfolder_info_reload (info, NULL, NULL, + TRUE /* force read items */); + } +} + +static void +vfolder_user_filename_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + VFolderInfo *info = user_data; + + if ((event_type == GNOME_VFS_MONITOR_EVENT_CREATED || + event_type == GNOME_VFS_MONITOR_EVENT_CHANGED) && + info->user_file_active) { + struct stat s; + + /* see if this was really our own change */ + if (info->user_filename_last_write == time (NULL)) + return; + /* anal retentive */ + if (stat (info->user_filename, &s) == 0 && + info->user_filename_last_write == s.st_ctime) + return; + + queue_reread_in (info, 200); + } else if ((event_type == GNOME_VFS_MONITOR_EVENT_CREATED || + event_type == GNOME_VFS_MONITOR_EVENT_CHANGED) && + ! info->user_file_active) { + queue_reread_in (info, 200); + } else if (event_type == GNOME_VFS_MONITOR_EVENT_DELETED && + info->user_file_active) { + gboolean force_read_items = info->file_monitors != NULL; + vfolder_info_reload (info, NULL, NULL, force_read_items); + } +} + +static void +item_dir_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + VFolderInfo *info = user_data; + + if (event_type == GNOME_VFS_MONITOR_EVENT_CREATED || + event_type == GNOME_VFS_MONITOR_EVENT_CHANGED) { + /* first invalidate all folders */ + invalidate_folder (info->root); + /* second invalidate all entries */ + info->entries_valid = FALSE; + + if (info->file_monitors != NULL) { + GnomeVFSResult result; + GSList *li; + + /* Whack all monitors here! */ + for (li = info->file_monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *h = li->data; + if (h->handle != NULL) + gnome_vfs_monitor_cancel (h->handle); + h->handle = NULL; + } + + if (vfolder_info_read_items (info, &result, NULL)) { + info->entries_valid = TRUE; + } + } + } +} + +static gboolean +setup_dir_monitor (VFolderInfo *info, const char *dir, gboolean subdirs, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + GnomeVFSMonitorHandle *handle; + DIR *dh; + struct dirent *de; + char *uri; + + uri = gnome_vfs_get_uri_from_local_path (dir); + + if (gnome_vfs_monitor_add (&handle, + uri, + GNOME_VFS_MONITOR_DIRECTORY, + item_dir_monitor, + info) != GNOME_VFS_OK) { + StatLoc *sl = bake_statloc (dir, time (NULL)); + if (sl != NULL) + info->stat_dirs = g_slist_prepend (info->stat_dirs, sl); + g_free (uri); + return TRUE; + } + g_free (uri); + + if (gnome_vfs_context_check_cancellation (context)) { + gnome_vfs_monitor_cancel (handle); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + info->item_dir_monitors = + g_slist_prepend (info->item_dir_monitors, handle); + + if ( ! subdirs) + return TRUE; + + dh = opendir (dir); + if (dh == NULL) + return TRUE; + + while ((de = readdir (dh)) != NULL) { + char *full_path; + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + closedir (dh); + return FALSE; + } + + if (de->d_name[0] == '.') + continue; + + full_path = g_build_filename (dir, de->d_name, NULL); + if (g_file_test (full_path, G_FILE_TEST_IS_DIR)) { + if ( ! setup_dir_monitor (info, full_path, + TRUE /* subdirs */, + result, context)) { + closedir (dh); + return FALSE; + } + } + g_free (full_path); + } + + closedir (dh); + + return TRUE; +} + +static gboolean +monitor_setup (VFolderInfo *info, + gboolean setup_filenames, + gboolean setup_itemdirs, + gboolean setup_desktop_dirs, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + char *uri; + GSList *li; + + if (setup_filenames) { + uri = gnome_vfs_get_uri_from_local_path + (info->filename); + + if (gnome_vfs_monitor_add (&info->filename_monitor, + uri, + GNOME_VFS_MONITOR_FILE, + vfolder_filename_monitor, + info) != GNOME_VFS_OK) { + info->filename_monitor = NULL; + info->filename_statloc = bake_statloc (info->filename, + time (NULL)); + } + g_free (uri); + } + if (setup_filenames && + info->user_filename != NULL) { + uri = gnome_vfs_get_uri_from_local_path + (info->user_filename); + if (gnome_vfs_monitor_add (&info->user_filename_monitor, + uri, + GNOME_VFS_MONITOR_FILE, + vfolder_user_filename_monitor, + info) != GNOME_VFS_OK) { + info->user_filename_monitor = NULL; + info->user_filename_statloc = + bake_statloc (info->user_filename, + time (NULL)); + } + + g_free (uri); + } + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + if (setup_itemdirs) { + for (li = info->item_dirs; li != NULL; li = li->next) { + const char *dir = li->data; + if ( ! setup_dir_monitor (info, dir, + FALSE /* subdirs */, + result, context)) + return FALSE; + } + if (info->user_item_dir != NULL) { + if ( ! setup_dir_monitor (info, info->user_item_dir, + FALSE /* subdirs */, + result, context)) + return FALSE; + } + for (li = info->merge_dirs; li != NULL; li = li->next) { + const char *dir = li->data; + if ( ! setup_dir_monitor (info, dir, + TRUE /* subdirs */, + result, context)) + return FALSE; + } + } + + if (setup_desktop_dirs) { + uri = gnome_vfs_get_uri_from_local_path + (info->desktop_dir); + + if (gnome_vfs_monitor_add (&info->desktop_dir_monitor, + uri, + GNOME_VFS_MONITOR_FILE, + vfolder_desktop_dir_monitor, + info) != GNOME_VFS_OK) { + info->desktop_dir_monitor = NULL; + info->desktop_dir_statloc = + bake_statloc (info->desktop_dir, + time (NULL)); + } + g_free (uri); + } + if (setup_desktop_dirs && + info->user_desktop_dir != NULL) { + uri = gnome_vfs_get_uri_from_local_path + (info->user_desktop_dir); + if (gnome_vfs_monitor_add (&info->user_desktop_dir_monitor, + uri, + GNOME_VFS_MONITOR_DIRECTORY, + vfolder_user_desktop_dir_monitor, + info) != GNOME_VFS_OK) { + info->user_desktop_dir_monitor = NULL; + info->user_desktop_dir_statloc = + bake_statloc (info->user_desktop_dir, + time (NULL)); + } + + g_free (uri); + } + + return TRUE; +} + +static void +vfolder_info_init (VFolderInfo *info, const char *scheme) +{ + const char *path; + GSList *list; + + info->scheme = g_strdup (scheme); + + info->filename = g_strconcat (SYSCONFDIR, "/X11/desktop-menus/", + scheme, ".menu", + NULL); + info->user_filename = g_strconcat (g_get_home_dir (), + "/" DOT_GNOME "/vfolders/", + scheme, ".vfolder-info", + NULL); + info->desktop_dir = g_strconcat (SYSCONFDIR, + "/gnome-vfs-2.0/vfolders/", + NULL); + info->user_desktop_dir = g_strconcat (g_get_home_dir (), + "/" DOT_GNOME "/vfolders/", + NULL); + + /* Init the desktop paths */ + list = NULL; + list = g_slist_prepend (list, g_strdup ("/usr/share/applications/")); + if (strcmp ("/usr/share/applications/", DATADIR "/applications/") != 0) + list = g_slist_prepend (list, g_strdup (DATADIR "/applications/")); + path = g_getenv ("DESKTOP_FILE_PATH"); + if (path != NULL) { + int i; + char **ppath = g_strsplit (path, ":", -1); + for (i = 0; ppath[i] != NULL; i++) { + const char *dir = ppath[i]; + list = g_slist_prepend (list, g_strdup (dir)); + } + g_strfreev (ppath); + } + info->item_dirs = g_slist_reverse (list); + + info->user_item_dir = g_strconcat (g_get_home_dir (), + "/" DOT_GNOME "/vfolders/", + scheme, + NULL); + + info->entries_ht = g_hash_table_new (g_str_hash, g_str_equal); + + info->root = folder_new ("Root"); + + info->modification_time = time (NULL); +} + +static void +vfolder_info_free_internals_unlocked (VFolderInfo *info) +{ + if (info == NULL) + return; + + if (info->filename_monitor != NULL) { + gnome_vfs_monitor_cancel (info->filename_monitor); + info->filename_monitor = NULL; + } + + if (info->user_filename_monitor != NULL) { + gnome_vfs_monitor_cancel (info->user_filename_monitor); + info->user_filename_monitor = NULL; + } + + g_free (info->filename_statloc); + info->filename_statloc = NULL; + + g_free (info->user_filename_statloc); + info->user_filename_statloc = NULL; + + + if (info->desktop_dir_monitor != NULL) { + gnome_vfs_monitor_cancel (info->desktop_dir_monitor); + info->desktop_dir_monitor = NULL; + } + + if (info->user_desktop_dir_monitor != NULL) { + gnome_vfs_monitor_cancel (info->user_desktop_dir_monitor); + info->user_desktop_dir_monitor = NULL; + } + + g_free (info->desktop_dir_statloc); + info->desktop_dir_statloc = NULL; + + g_free (info->user_desktop_dir_statloc); + info->user_desktop_dir_statloc = NULL; + + + g_slist_foreach (info->item_dir_monitors, + (GFunc)gnome_vfs_monitor_cancel, NULL); + g_slist_free (info->item_dir_monitors); + info->item_dir_monitors = NULL; + + g_free (info->scheme); + info->scheme = NULL; + + g_free (info->filename); + info->filename = NULL; + + g_free (info->user_filename); + info->user_filename = NULL; + + g_free (info->desktop_dir); + info->desktop_dir = NULL; + + g_free (info->user_desktop_dir); + info->user_desktop_dir = NULL; + + g_slist_foreach (info->item_dirs, (GFunc)g_free, NULL); + g_slist_free (info->item_dirs); + info->item_dirs = NULL; + + g_free (info->user_item_dir); + info->user_item_dir = NULL; + + g_slist_foreach (info->merge_dirs, (GFunc)g_free, NULL); + g_slist_free (info->merge_dirs); + info->merge_dirs = NULL; + + g_slist_foreach (info->entries, (GFunc)entry_unref, NULL); + g_slist_free (info->entries); + info->entries = NULL; + + if (info->entries_ht != NULL) + g_hash_table_destroy (info->entries_ht); + info->entries_ht = NULL; + + g_slist_foreach (info->unallocated_folders, + (GFunc)entry_unref, + NULL); + g_slist_free (info->unallocated_folders); + info->unallocated_folders = NULL; + + entry_unref ((Entry *)info->root); + info->root = NULL; + + g_slist_foreach (info->stat_dirs, (GFunc)g_free, NULL); + g_slist_free (info->stat_dirs); + info->stat_dirs = NULL; + + g_slist_foreach (info->folder_monitors, + (GFunc)file_monitor_handle_unref_unlocked, NULL); + g_slist_free (info->folder_monitors); + info->folder_monitors = NULL; + + g_slist_foreach (info->free_folder_monitors, + (GFunc)file_monitor_handle_unref_unlocked, NULL); + g_slist_free (info->free_folder_monitors); + info->free_folder_monitors = NULL; + + g_slist_foreach (info->file_monitors, + (GFunc)file_monitor_handle_unref_unlocked, NULL); + g_slist_free (info->file_monitors); + info->file_monitors = NULL; + + g_slist_foreach (info->free_file_monitors, + (GFunc)file_monitor_handle_unref_unlocked, NULL); + g_slist_free (info->free_file_monitors); + info->free_file_monitors = NULL; + + if (info->reread_queue != 0) + g_source_remove (info->reread_queue); + info->reread_queue = 0; +} + +static void +vfolder_info_free_internals (VFolderInfo *info) +{ + G_LOCK (vfolder_lock); + vfolder_info_free_internals_unlocked (info); + G_UNLOCK (vfolder_lock); +} + +static void +vfolder_info_destroy (VFolderInfo *info) +{ + vfolder_info_free_internals (info); + g_free (info); +} + +static Query * +single_query_read (xmlNode *qnode) +{ + Query *query; + xmlNode *node; + + if (qnode->type != XML_ELEMENT_NODE || + qnode->name == NULL) + return NULL; + + query = NULL; + + if (g_ascii_strcasecmp (qnode->name, "Not") == 0 && + qnode->xmlChildrenNode != NULL) { + xmlNode *iter; + query = NULL; + for (iter = qnode->xmlChildrenNode; + iter != NULL && query == NULL; + iter = iter->next) + query = single_query_read (iter); + if (query != NULL) { + query->not = ! query->not; + } + return query; + } else if (g_ascii_strcasecmp (qnode->name, "Keyword") == 0) { + xmlChar *word = xmlNodeGetContent (qnode); + if (word != NULL) { + query = query_new (QUERY_KEYWORD); + ((QueryKeyword *)query)->keyword = + g_quark_from_string (word); + + xmlFree (word); + } + return query; + } else if (g_ascii_strcasecmp (qnode->name, "Filename") == 0) { + xmlChar *file = xmlNodeGetContent (qnode); + if (file != NULL) { + query = query_new (QUERY_FILENAME); + ((QueryFilename *)query)->filename = + g_strdup (file); + + xmlFree (file); + } + return query; + } else if (g_ascii_strcasecmp (qnode->name, "And") == 0) { + query = query_new (QUERY_AND); + } else if (g_ascii_strcasecmp (qnode->name, "Or") == 0) { + query = query_new (QUERY_OR); + } else { + /* We don't understand */ + return NULL; + } + + /* This must be OR or AND */ + g_assert (query != NULL); + + for (node = qnode->xmlChildrenNode; node != NULL; node = node->next) { + Query *new_query = single_query_read (node); + + if (new_query != NULL) + query->queries = g_slist_prepend + (query->queries, new_query); + } + + query->queries = g_slist_reverse (query->queries); + + return query; +} + +static void +add_or_set_query (Query **query, Query *new_query) +{ + if (*query == NULL) { + *query = new_query; + } else { + Query *old_query = *query; + *query = query_new (QUERY_OR); + (*query)->queries = + g_slist_append ((*query)->queries, old_query); + (*query)->queries = + g_slist_append ((*query)->queries, new_query); + } +} + +static Query * +query_read (xmlNode *qnode) +{ + Query *query; + xmlNode *node; + + query = NULL; + + for (node = qnode->xmlChildrenNode; node != NULL; node = node->next) { + if (node->type != XML_ELEMENT_NODE || + node->name == NULL) + continue; + + if (g_ascii_strcasecmp (node->name, "Not") == 0 && + node->xmlChildrenNode != NULL) { + xmlNode *iter; + Query *new_query = NULL; + + for (iter = node->xmlChildrenNode; + iter != NULL && new_query == NULL; + iter = iter->next) + new_query = single_query_read (iter); + if (new_query != NULL) { + new_query->not = ! new_query->not; + add_or_set_query (&query, new_query); + } + } else { + Query *new_query = single_query_read (node); + if (new_query != NULL) + add_or_set_query (&query, new_query); + } + } + + return query; +} + +static Folder * +folder_read (VFolderInfo *info, xmlNode *fnode) +{ + Folder *folder; + xmlNode *node; + + folder = folder_new (NULL); + + for (node = fnode->xmlChildrenNode; node != NULL; node = node->next) { + if (node->type != XML_ELEMENT_NODE || + node->name == NULL) + continue; + + if (g_ascii_strcasecmp (node->name, "Name") == 0) { + xmlChar *name = xmlNodeGetContent (node); + if (name != NULL) { + g_free (folder->entry.name); + folder->entry.name = g_strdup (name); + xmlFree (name); + } + } else if (g_ascii_strcasecmp (node->name, "Desktop") == 0) { + xmlChar *desktop = xmlNodeGetContent (node); + if (desktop != NULL) { + g_free (folder->desktop_file); + folder->desktop_file = g_strdup (desktop); + xmlFree (desktop); + } + } else if (g_ascii_strcasecmp (node->name, "Include") == 0) { + xmlChar *file = xmlNodeGetContent (node); + if (file != NULL) { + GSList *li; + char *str = g_strdup (file); + folder->includes = g_slist_prepend + (folder->includes, str); + if (folder->includes_ht == NULL) { + folder->includes_ht = + g_hash_table_new_full + (g_str_hash, + g_str_equal, + NULL, + NULL); + } + li = g_hash_table_lookup (folder->includes_ht, + file); + if (li != NULL) { + g_free (li->data); + /* Note: this will NOT change folder->includes + * pointer! */ + folder->includes = g_slist_delete_link + (folder->includes, li); + } + g_hash_table_replace (folder->includes_ht, + file, folder->includes); + xmlFree (file); + } + } else if (g_ascii_strcasecmp (node->name, "Exclude") == 0) { + xmlChar *file = xmlNodeGetContent (node); + if (file != NULL) { + char *s; + if (folder->excludes == NULL) { + folder->excludes = g_hash_table_new_full + (g_str_hash, + g_str_equal, + (GDestroyNotify)g_free, + NULL); + } + s = g_strdup (file); + g_hash_table_replace (folder->excludes, s, s); + xmlFree (file); + } + } else if (g_ascii_strcasecmp (node->name, "Query") == 0) { + Query *query; + + query = query_read (node); + + if (query != NULL) { + if (folder->query != NULL) + query_destroy (folder->query); + folder->query = query; + } + } else if (g_ascii_strcasecmp (node->name, "OnlyUnallocated") == 0) { + info->unallocated_folders = + g_slist_prepend (info->unallocated_folders, + (Folder *)entry_ref ((Entry *)folder)); + folder->only_unallocated = TRUE; + } else if (g_ascii_strcasecmp (node->name, "Folder") == 0) { + Folder *new_folder = folder_read (info, node); + if (new_folder != NULL) { + folder->subfolders = + g_slist_append (folder->subfolders, + new_folder); + new_folder->parent = folder; + } + } else if (g_ascii_strcasecmp (node->name, "ReadOnly") == 0) { + folder->read_only = TRUE; + } else if (g_ascii_strcasecmp (node->name, + "DontShowIfEmpty") == 0) { + folder->dont_show_if_empty = TRUE; + } + } + + /* Name is required */ + if (folder->entry.name == NULL) { + entry_unref ((Entry *)folder); + folder = NULL; + } + + folder->includes = g_slist_reverse (folder->includes); + + return folder; +} + +static char * +subst_home (const char *dir) +{ + if (dir[0] == '~') + return g_strconcat (g_get_home_dir (), + &dir[1], + NULL); + else + return g_strdup (dir); +} + +/* FORMAT looks like: + * + * + * /etc/X11/applnk + * + * /usr/share/applications + * + * /etc/X11/gnome/vfolders + * + * + * Root + * + * important.desktop + * + * + * + * SomeFolder + * + * + * Test_Folder + * + * Test_Folder.directory + * + * + * + * Application + * Game + * + * Clock + * + * + * somefile.desktop + * someotherfile.desktop + * yetanother.desktop + * + * + * + */ + +static gboolean +vfolder_info_read_info (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + xmlDoc *doc; + xmlNode *node; + gboolean got_a_vfolder_dir = FALSE; + + doc = NULL; + if (info->user_filename != NULL && + access (info->user_filename, F_OK) == 0) { + doc = xmlParseFile (info->user_filename); + if (doc != NULL) + info->user_file_active = TRUE; + } + if (doc == NULL && + access (info->filename, F_OK) == 0) + doc = xmlParseFile (info->filename); + + if (gnome_vfs_context_check_cancellation (context)) { + xmlFreeDoc(doc); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + if (doc == NULL + || doc->xmlRootNode == NULL + || doc->xmlRootNode->name == NULL + || g_ascii_strcasecmp (doc->xmlRootNode->name, "VFolderInfo") != 0) { + xmlFreeDoc(doc); + return TRUE; /* FIXME: really, shouldn't we error out? */ + } + + for (node = doc->xmlRootNode->xmlChildrenNode; node != NULL; node = node->next) { + if (node->type != XML_ELEMENT_NODE || + node->name == NULL) + continue; + + if (gnome_vfs_context_check_cancellation (context)) { + xmlFreeDoc(doc); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + if (g_ascii_strcasecmp (node->name, "MergeDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + if (dir != NULL) { + info->merge_dirs = g_slist_append (info->merge_dirs, + g_strdup (dir)); + xmlFree (dir); + } + } else if (g_ascii_strcasecmp (node->name, "ItemDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + if (dir != NULL) { + if ( ! got_a_vfolder_dir) { + g_slist_foreach (info->item_dirs, + (GFunc)g_free, NULL); + g_slist_free (info->item_dirs); + info->item_dirs = NULL; + } + got_a_vfolder_dir = TRUE; + info->item_dirs = g_slist_append (info->item_dirs, + g_strdup (dir)); + xmlFree (dir); + } + } else if (g_ascii_strcasecmp (node->name, "UserItemDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + if (dir != NULL) { + g_free (info->user_item_dir); + info->user_item_dir = subst_home (dir); + xmlFree (dir); + } + } else if (g_ascii_strcasecmp (node->name, "DesktopDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + if (dir != NULL) { + g_free (info->desktop_dir); + info->desktop_dir = g_strdup (dir); + xmlFree (dir); + } + } else if (g_ascii_strcasecmp (node->name, "UserDesktopDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + if (dir != NULL) { + g_free (info->user_desktop_dir); + info->user_desktop_dir = subst_home (dir); + xmlFree (dir); + } + } else if (g_ascii_strcasecmp (node->name, "Folder") == 0) { + Folder *folder = folder_read (info, node); + if (folder != NULL) { + if (info->root != NULL) + entry_unref ((Entry *)info->root); + info->root = folder; + } + } else if (g_ascii_strcasecmp (node->name, "ReadOnly") == 0) { + info->read_only = TRUE; + } + } + + xmlFreeDoc(doc); + + return TRUE; +} + +static void +add_xml_tree_from_query (xmlNode *parent, Query *query) +{ + xmlNode *real_parent; + + if (query->not) + real_parent = xmlNewChild (parent /* parent */, + NULL /* ns */, + "Not" /* name */, + NULL /* content */); + else + real_parent = parent; + + if (query->type == QUERY_KEYWORD) { + QueryKeyword *qkeyword = (QueryKeyword *)query; + const char *string = g_quark_to_string (qkeyword->keyword); + + xmlNewChild (real_parent /* parent */, + NULL /* ns */, + "Keyword" /* name */, + string /* content */); + } else if (query->type == QUERY_FILENAME) { + QueryFilename *qfilename = (QueryFilename *)query; + + xmlNewChild (real_parent /* parent */, + NULL /* ns */, + "Filename" /* name */, + qfilename->filename /* content */); + } else if (query->type == QUERY_OR || + query->type == QUERY_AND) { + xmlNode *node; + const char *name; + GSList *li; + + if (query->type == QUERY_OR) + name = "Or"; + else /* QUERY_AND */ + name = "And"; + + node = xmlNewChild (real_parent /* parent */, + NULL /* ns */, + name /* name */, + NULL /* content */); + + for (li = query->queries; li != NULL; li = li->next) { + Query *subquery = li->data; + add_xml_tree_from_query (node, subquery); + } + } else { + g_assert_not_reached (); + } +} + +static void +add_excludes_to_xml (gpointer key, gpointer value, gpointer user_data) +{ + const char *filename = key; + xmlNode *folder_node = user_data; + + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Exclude" /* name */, + filename /* content */); +} + +static void +add_xml_tree_from_folder (xmlNode *parent, Folder *folder) +{ + GSList *li; + xmlNode *folder_node; + + + folder_node = xmlNewChild (parent /* parent */, + NULL /* ns */, + "Folder" /* name */, + NULL /* content */); + + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Name" /* name */, + folder->entry.name /* content */); + + if (folder->desktop_file != NULL) { + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Desktop" /* name */, + folder->desktop_file /* content */); + } + + if (folder->read_only) + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "ReadOnly" /* name */, + NULL /* content */); + if (folder->dont_show_if_empty) + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "DontShowIfEmpty" /* name */, + NULL /* content */); + if (folder->only_unallocated) + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "OnlyUnallocated" /* name */, + NULL /* content */); + + for (li = folder->subfolders; li != NULL; li = li->next) { + Folder *subfolder = li->data; + add_xml_tree_from_folder (folder_node, subfolder); + } + + for (li = folder->includes; li != NULL; li = li->next) { + const char *include = li->data; + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Include" /* name */, + include /* content */); + } + + if (folder->excludes) { + g_hash_table_foreach (folder->excludes, + add_excludes_to_xml, + folder_node); + } + + if (folder->query != NULL) { + xmlNode *query_node; + query_node = xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Query" /* name */, + NULL /* content */); + + add_xml_tree_from_query (query_node, folder->query); + } +} + +static xmlDoc * +xml_tree_from_vfolder (VFolderInfo *info) +{ + xmlDoc *doc; + xmlNode *topnode; + GSList *li; + + doc = xmlNewDoc ("1.0"); + + topnode = xmlNewDocNode (doc /* doc */, + NULL /* ns */, + "VFolderInfo" /* name */, + NULL /* content */); + doc->xmlRootNode = topnode; + + for (li = info->merge_dirs; li != NULL; li = li->next) { + const char *merge_dir = li->data; + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "MergeDir" /* name */, + merge_dir /* content */); + } + + for (li = info->item_dirs; li != NULL; li = li->next) { + const char *item_dir = li->data; + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "ItemDir" /* name */, + item_dir /* content */); + } + + if (info->user_item_dir != NULL) { + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "UserItemDir" /* name */, + info->user_item_dir /* content */); + } + + if (info->desktop_dir != NULL) { + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "DesktopDir" /* name */, + info->desktop_dir /* content */); + } + + if (info->user_desktop_dir != NULL) { + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "UserDesktopDir" /* name */, + info->user_desktop_dir /* content */); + } + + if (info->root != NULL) + add_xml_tree_from_folder (topnode, info->root); + + return doc; +} + +/* FIXME: what to do about errors */ +static void +vfolder_info_write_user (VFolderInfo *info) +{ + xmlDoc *doc; + + if (info->inhibit_write > 0) + return; + + if (info->user_filename == NULL) + return; + + doc = xml_tree_from_vfolder (info); + if (doc == NULL) + return; + + /* FIXME: errors, anyone? */ + ensure_dir (info->user_filename, + TRUE /* ignore_basename */); + + xmlSaveFormatFile (info->user_filename, doc, TRUE /* format */); + /* not as good as a stat, but cheaper ... hmmm what is + * the likelyhood of this not being the same as ctime */ + info->user_filename_last_write = time (NULL); + + xmlFreeDoc(doc); + + info->user_file_active = TRUE; + info->dirty = FALSE; + + info->modification_time = time (NULL); +} + +/* An EVIL function for quick reading of .desktop files, + * only reads in one or two keys, but that's ALL we need */ +static void +readitem_entry (const char *filename, + const char *key1, + char **result1, + const char *key2, + char **result2) +{ + FILE *fp; + char buf[1024]; + int keylen1, keylen2; + + *result1 = NULL; + if (result2 != NULL) + *result2 = NULL; + + fp = fopen (filename, "r"); + + if (fp == NULL) + return; + + keylen1 = strlen (key1); + if (key2 != NULL) + keylen2 = strlen (key2); + else + keylen2 = -1; + + /* This is slightly wrong, it should only look + * at the correct section */ + while (fgets (buf, sizeof (buf), fp) != NULL) { + char *p; + int len; + int keylen; + char **result = NULL; + + /* check if it's one of the keys */ + if (strncmp (buf, key1, keylen1) == 0) { + result = result1; + keylen = keylen1; + } else if (keylen2 >= 0 && + strncmp (buf, key2, keylen2) == 0) { + result = result2; + keylen = keylen2; + } else { + continue; + } + + p = &buf[keylen]; + + /* still not our key */ + if (!(*p == '=' || *p == ' ')) { + continue; + } + do + p++; + while (*p == ' ' || *p == '='); + + /* get rid of trailing \n */ + len = strlen (p); + if (p[len-1] == '\n' || + p[len-1] == '\r') + p[len-1] = '\0'; + + *result = g_strdup (p); + + if (*result1 != NULL && + (result2 == NULL || *result2 != NULL)) + break; + } + + fclose (fp); +} + +static void +vfolder_info_insert_entry (VFolderInfo *info, EntryFile *efile) +{ + GSList *entry_list; + + entry_ref ((Entry *)efile); + + entry_list = g_hash_table_lookup (info->entries_ht, efile->entry.name); + + info->entries = g_slist_prepend (info->entries, efile); + /* The hash table contains the GSList pointer */ + g_hash_table_replace (info->entries_ht, efile->entry.name, + info->entries); + + if (entry_list != NULL) { + Entry *entry = entry_list->data; + info->entries = g_slist_delete_link (info->entries, + entry_list); + entry_unref (entry); + } +} + +static void +set_keywords (EntryFile *efile, const char *keywords) +{ + if (keywords != NULL) { + int i; + char **parsed = g_strsplit (keywords, ";", -1); + for (i = 0; parsed[i] != NULL; i++) { + GQuark quark; + const char *word = parsed[i]; + /* ignore empties (including end of list) */ + if (word[0] == '\0') + continue; + quark = g_quark_from_string (word); + efile->keywords = g_slist_prepend + (efile->keywords, + GINT_TO_POINTER (quark)); + } + g_strfreev (parsed); + } +} + +static EntryFile * +make_entry_file (const char *dir, const char *name) +{ + EntryFile *efile; + char *categories; + char *only_show_in; + char *filename; + int i; + + filename = g_build_filename (dir, name, NULL); + + readitem_entry (filename, + "Categories", + &categories, + "OnlyShowIn", + &only_show_in); + + if (only_show_in != NULL) { + gboolean show = FALSE; + char **parsed = g_strsplit (only_show_in, ";", -1); + for (i = 0; parsed[i] != NULL; i++) { + if (strcmp (parsed[i], "GNOME") == 0) { + show = TRUE; + break; + } + } + g_strfreev (parsed); + if ( ! show) { + g_free (filename); + g_free (only_show_in); + g_free (categories); + return NULL; + } + } + + efile = file_new (name); + efile->filename = filename; + + set_keywords (efile, categories); + + g_free (only_show_in); + g_free (categories); + + return efile; +} + +static gboolean +vfolder_info_read_items_from (VFolderInfo *info, + const char *item_dir, + gboolean per_user, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + DIR *dir; + struct dirent *de; + + dir = opendir (item_dir); + if (dir == NULL) + return TRUE; + + while ((de = readdir (dir)) != NULL) { + EntryFile *efile; + + if (gnome_vfs_context_check_cancellation (context)) { + closedir (dir); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + /* files MUST be called .desktop */ + if (de->d_name[0] == '.' || + ! check_ext (de->d_name, ".desktop")) + continue; + + efile = make_entry_file (item_dir, de->d_name); + if (efile == NULL) + continue; + + efile->per_user = per_user; + + vfolder_info_insert_entry (info, efile); + entry_unref ((Entry *)efile); + } + + closedir (dir); + + return TRUE; +} + +static gboolean +vfolder_info_read_items_merge (VFolderInfo *info, + const char *merge_dir, + const char *subdir, + GQuark inherited_keyword, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + DIR *dir; + struct dirent *de; + GQuark extra_keyword; + GQuark Application; + GQuark Merged; + GQuark inheritance; + gboolean pass_down_extra_keyword = TRUE; + + dir = opendir (merge_dir); + if (dir == NULL) + return TRUE; + + Application = g_quark_from_static_string ("Application"); + Merged = g_quark_from_static_string ("Merged"); + + /* FIXME: this should be a hash or something */ + extra_keyword = 0; + if (subdir == NULL) { + extra_keyword = g_quark_from_static_string ("Core"); + pass_down_extra_keyword = FALSE; + } else if (g_ascii_strcasecmp (subdir, "Development") == 0) + extra_keyword = g_quark_from_static_string ("Development"); + else if (g_ascii_strcasecmp (subdir, "Editors") == 0) + extra_keyword = g_quark_from_static_string ("TextEditor"); + else if (g_ascii_strcasecmp (subdir, "Games") == 0) + extra_keyword = g_quark_from_static_string ("Game"); + else if (g_ascii_strcasecmp (subdir, "Graphics") == 0) + extra_keyword = g_quark_from_static_string ("Graphics"); + else if (g_ascii_strcasecmp (subdir, "Internet") == 0) + extra_keyword = g_quark_from_static_string ("Network"); + else if (g_ascii_strcasecmp (subdir, "Multimedia") == 0) + extra_keyword = g_quark_from_static_string ("AudioVideo"); + else if (g_ascii_strcasecmp (subdir, "Office") == 0) + extra_keyword = g_quark_from_static_string ("Office"); + else if (g_ascii_strcasecmp (subdir, "Settings") == 0) + extra_keyword = g_quark_from_static_string ("Settings"); + else if (g_ascii_strcasecmp (subdir, "System") == 0) + extra_keyword = g_quark_from_static_string ("System"); + else if (g_ascii_strcasecmp (subdir, "Utilities") == 0) + extra_keyword = g_quark_from_static_string ("Utility"); + + while ((de = readdir (dir)) != NULL) { + EntryFile *efile; + + if (gnome_vfs_context_check_cancellation (context)) { + closedir (dir); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + /* ignore hidden */ + if (de->d_name[0] == '.') + continue; + + /* files MUST be called .desktop, so + * treat all others as dirs. If we're wrong, + * the open will fail, which is ok */ + if ( ! check_ext (de->d_name, ".desktop")) { + /* if this is a directory recurse */ + char *fullname = g_build_filename (merge_dir, de->d_name, NULL); + if ((pass_down_extra_keyword == TRUE) && (extra_keyword != 0)) { + inheritance = extra_keyword; + } else { + inheritance = inherited_keyword; + } + + if ( ! vfolder_info_read_items_merge (info, + fullname, + de->d_name, + inheritance, + result, + context)) { + g_free (fullname); + return FALSE; + } + g_free (fullname); + continue; + } + + /* FIXME: add some keywords about some known apps + * like gimp and whatnot, perhaps take these from the vfolder + * file or some such */ + + efile = make_entry_file (merge_dir, de->d_name); + if (efile == NULL) + continue; + + /* If no keywords set, then add the standard ones */ + if (efile->keywords == NULL) { + efile->keywords = g_slist_prepend + (efile->keywords, + GINT_TO_POINTER (Application)); + + efile->keywords = g_slist_prepend + (efile->keywords, + GINT_TO_POINTER (Merged)); + + if (inherited_keyword != 0) { + efile->keywords = g_slist_prepend + (efile->keywords, + GINT_TO_POINTER (inherited_keyword)); + } + + if (extra_keyword != 0) { + efile->keywords = g_slist_prepend + (efile->keywords, + GINT_TO_POINTER (extra_keyword)); + } + efile->implicit_keywords = TRUE; + } + + vfolder_info_insert_entry (info, efile); + entry_unref ((Entry *)efile); + } + + closedir (dir); + + return TRUE; +} + +static Entry * +find_entry (GSList *list, const char *name) +{ + GSList *li; + + for (li = list; li != NULL; li = li->next) { + Entry *entry = li->data; + if (strcmp (name, entry->name) == 0) + return entry; + } + return NULL; +} + +static void +file_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + FileMonitorHandle *h = user_data; + + /* proxy the event through if it is a changed event + * only */ + + if (event_type == GNOME_VFS_MONITOR_EVENT_CHANGED && + h->handle != NULL) + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *) h, + h->uri, event_type); +} + +static void +try_free_file_monitors_create_files_unlocked (VFolderInfo *info) +{ + GSList *li, *list; + + list = g_slist_copy (info->free_file_monitors); + + for (li = list; li != NULL; li = li->next) { + FileMonitorHandle *handle = li->data; + Entry *entry; + GnomeVFSResult result; + char *dirfile = NULL; + + if (handle->is_directory_file) { + VFolderURI vuri; + Folder *folder; + + /* Evil! EVIL URI PARSING. this will eat a lot of + * stack if we have lots of free monitors */ + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + folder = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + + if (folder == NULL) + continue; + + dirfile = get_directory_file_unlocked (info, folder); + if (dirfile == NULL) + continue; + + entry = (Entry *)folder; + } else { + VFolderURI vuri; + Folder *f; + GnomeVFSResult result; + + entry = NULL; + + /* Evil! EVIL URI PARSING. this will eat a lot of + * stack if we have lots of monitors */ + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + f = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + + if (f != NULL) { + ensure_folder_unlocked ( + info, f, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + entry = find_entry (f->entries, vuri.file); + } + + if (entry == NULL) + continue; + } + + info->free_file_monitors = + g_slist_remove (info->free_file_monitors, handle); + entry->monitors = + g_slist_prepend (entry->monitors, handle); + + handle->exists = TRUE; + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *)handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_CREATED); + + /* recreate a handle */ + if (handle->handle == NULL && + entry->type == ENTRY_FILE) { + EntryFile *efile = (EntryFile *)entry; + char *uri = gnome_vfs_get_uri_from_local_path + (efile->filename); + + gnome_vfs_monitor_add (&(handle->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + handle); + + g_free (uri); + } else if (handle->handle == NULL && + dirfile != NULL) { + char *uri = gnome_vfs_get_uri_from_local_path (dirfile); + + gnome_vfs_monitor_add (&(handle->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + handle); + + g_free (uri); + } + + g_free (dirfile); + } + + g_slist_free (list); +} + +static void /* unlocked */ +rescan_monitors (VFolderInfo *info) +{ + GSList *li; + + if (info->file_monitors == NULL) + return; + + for (li = info->file_monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + GnomeVFSResult result; + Entry *entry; + char *dirfile = NULL; + + /* these are handled below */ + if ( ! h->exists) + continue; + + if (h->is_directory_file) { + VFolderURI vuri; + Folder *folder; + + /* Evil! EVIL URI PARSING. this will eat a lot of + * stack if we have lots of monitors */ + + VFOLDER_URI_PARSE (h->uri, &vuri); + + folder = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + if (folder != NULL) + dirfile = get_directory_file_unlocked (info, + folder); + + if (dirfile == NULL) { + h->exists = FALSE; + gnome_vfs_monitor_callback + ((GnomeVFSMethodHandle *)h, + h->uri, + GNOME_VFS_MONITOR_EVENT_DELETED); + info->free_file_monitors = g_slist_prepend + (info->free_file_monitors, h); + file_monitor_handle_ref_unlocked (h); + /* it has been unreffed when the entry was + * whacked */ + continue; + } + + entry = (Entry *)folder; + } else { + VFolderURI vuri; + Folder *f; + GnomeVFSResult result; + + entry = NULL; + + /* Evil! EVIL URI PARSING. this will eat a lot of + * stack if we have lots of monitors */ + + VFOLDER_URI_PARSE (h->uri, &vuri); + + f = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + + if (f != NULL) { + ensure_folder_unlocked ( + info, f, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + entry = find_entry (f->entries, vuri.file); + } + + if (entry == NULL) { + h->exists = FALSE; + gnome_vfs_monitor_callback + ((GnomeVFSMethodHandle *)h, + h->uri, + GNOME_VFS_MONITOR_EVENT_DELETED); + info->free_file_monitors = g_slist_prepend + (info->free_file_monitors, h); + file_monitor_handle_ref_unlocked (h); + /* it has been unreffed when the entry was + * whacked */ + continue; + } + } + + /* recreate a handle */ + if (h->handle == NULL && + entry->type == ENTRY_FILE) { + EntryFile *efile = (EntryFile *)entry; + char *uri = gnome_vfs_get_uri_from_local_path + (efile->filename); + + gnome_vfs_monitor_add (&(h->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + h); + + g_free (uri); + } else if (h->handle == NULL && + dirfile != NULL) { + char *uri = gnome_vfs_get_uri_from_local_path (dirfile); + + gnome_vfs_monitor_add (&(h->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + h); + + g_free (uri); + } + + g_free (dirfile); + } + + try_free_file_monitors_create_files_unlocked (info); +} + +static gboolean /* unlocked */ +vfolder_info_read_items (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + GSList *li; + + /* First merge */ + for (li = info->merge_dirs; li != NULL; li = li->next) { + const char *merge_dir = li->data; + + if ( ! vfolder_info_read_items_merge (info, merge_dir, NULL, FALSE, + result, context)) + return FALSE; + } + + /* Then read the real thing (later overrides) */ + for (li = info->item_dirs; li != NULL; li = li->next) { + const char *item_dir = li->data; + + if ( ! vfolder_info_read_items_from (info, item_dir, + FALSE /* per_user */, + result, context)) + return FALSE; + } + + if (info->user_item_dir != NULL) { + if ( ! vfolder_info_read_items_from (info, + info->user_item_dir, + TRUE /* per_user */, + result, context)) + return FALSE; + } + + rescan_monitors (info); + + return TRUE; +} + +static gboolean +string_slist_equal (GSList *list1, GSList *list2) +{ + GSList *li1, *li2; + + for (li1 = list1, li2 = list2; + li1 != NULL && li2 != NULL; + li1 = li1->next, li2 = li2->next) { + const char *s1 = li1->data; + const char *s2 = li2->data; + if (strcmp (s1, s2) != 0) + return FALSE; + } + /* if both are not NULL, then lengths are + * different */ + if (li1 != li2) + return FALSE; + return TRUE; +} + +static gboolean +safe_string_same (const char *string1, const char *string2) +{ + if (string1 == string2 && + string1 == NULL) + return TRUE; + + if (string1 != NULL && string2 != NULL && + strcmp (string1, string2) == 0) + return TRUE; + + return FALSE; +} + +static gboolean +vfolder_info_item_dirs_same (VFolderInfo *info1, VFolderInfo *info2) +{ + if ( ! string_slist_equal (info1->item_dirs, + info2->item_dirs)) + return FALSE; + + if ( ! string_slist_equal (info1->merge_dirs, + info2->merge_dirs)) + return FALSE; + + if ( ! safe_string_same (info1->user_item_dir, + info2->user_item_dir)) + return FALSE; + + return TRUE; +} + +static gboolean +vfolder_info_reload_unlocked (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context, + gboolean force_read_items) +{ + VFolderInfo *newinfo; + gboolean setup_filenames; + gboolean setup_itemdirs; + GSList *li; + + /* FIXME: Hmmm, race, there is no locking YAIKES, + * we need filename locking for changes. eek, eek, eek */ + if (info->dirty) { + return TRUE; + } + + newinfo = g_new0 (VFolderInfo, 1); + vfolder_info_init (newinfo, info->scheme); + + g_free (newinfo->filename); + g_free (newinfo->user_filename); + newinfo->filename = g_strdup (info->filename); + newinfo->user_filename = g_strdup (info->user_filename); + + if (gnome_vfs_context_check_cancellation (context)) { + vfolder_info_destroy (newinfo); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + if ( ! vfolder_info_read_info (newinfo, result, context)) { + vfolder_info_destroy (newinfo); + return FALSE; + } + + /* FIXME: reload logic for 'desktop_dir' and + * 'user_desktop_dir' */ + + setup_itemdirs = TRUE; + + /* Validity of entries and item dirs and all that is unchanged */ + if (vfolder_info_item_dirs_same (info, newinfo)) { + newinfo->entries = info->entries; + info->entries = NULL; + newinfo->entries_ht = info->entries_ht; + info->entries_ht = NULL /* some places assume this + non-null, but we're only + going to destroy this */; + newinfo->entries_valid = info->entries_valid; + + /* move over the monitors/statlocs since those are valid */ + newinfo->item_dir_monitors = info->item_dir_monitors; + info->item_dir_monitors = NULL; + newinfo->stat_dirs = info->stat_dirs; + info->stat_dirs = NULL; + + /* No need to resetup dir monitors */ + setup_itemdirs = FALSE; + + /* No need to do anything with file monitors */ + } else { + /* Whack all monitors here! */ + for (li = info->file_monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + if (h->handle != NULL) + gnome_vfs_monitor_cancel (h->handle); + h->handle = NULL; + } + } + + setup_filenames = TRUE; + + if (safe_string_same (info->filename, newinfo->filename) && + safe_string_same (info->user_filename, newinfo->user_filename)) { + newinfo->user_filename_last_write = + info->user_filename_last_write; + + /* move over the monitors/statlocs since those are valid */ + newinfo->filename_monitor = info->filename_monitor; + info->filename_monitor = NULL; + newinfo->user_filename_monitor = info->user_filename_monitor; + info->user_filename_monitor = NULL; + + if (info->filename_statloc != NULL && + info->filename != NULL) + newinfo->filename_statloc = + bake_statloc (info->filename, + time (NULL)); + if (info->user_filename_statloc != NULL && + info->user_filename != NULL) + newinfo->user_filename_statloc = + bake_statloc (info->user_filename, + time (NULL)); + + /* No need to resetup filename monitors */ + setup_filenames = FALSE; + } + + /* Note: not cancellable anymore, since we've + * already started nibbling on the info structure, + * so we'd need to back things out or some such, + * too complex, so screw that */ + monitor_setup (info, + setup_filenames, + setup_itemdirs, + /* FIXME: setup_desktop_dirs */ TRUE, + NULL, NULL); + + for (li = info->folder_monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *handle = li->data; + li->data = NULL; + + add_folder_monitor_unlocked (newinfo, handle); + + file_monitor_handle_unref_unlocked (handle); + } + g_slist_free (info->folder_monitors); + info->folder_monitors = NULL; + + g_slist_foreach (info->free_folder_monitors, + (GFunc)file_monitor_handle_unref_unlocked, NULL); + g_slist_free (info->free_folder_monitors); + info->folder_monitors = NULL; + + /* we can just copy these for now, they will be readded + * and all the fun stuff will be done with them later */ + newinfo->file_monitors = info->file_monitors; + info->file_monitors = NULL; + newinfo->free_file_monitors = info->free_file_monitors; + info->free_file_monitors = NULL; + + /* emit changed on all folders, a bit drastic, but oh well, + * we also invalidate all folders at the same time, but that is + * irrelevant since they should all just be invalid to begin with */ + invalidate_folder_T (info->root); + + /* FIXME: make sure if this was enough, I think it was */ + + vfolder_info_free_internals_unlocked (info); + memcpy (info, newinfo, sizeof (VFolderInfo)); + g_free (newinfo); + + /* must rescan the monitors here */ + if (info->entries_valid) { + rescan_monitors (info); + } + + if ( ! info->entries_valid && + force_read_items) { + GnomeVFSResult res; + /* FIXME: I bet cancelation plays havoc with monitors, + * I'm not sure however */ + if (info->file_monitors != NULL) { + vfolder_info_read_items (info, &res, NULL); + } else { + if ( ! vfolder_info_read_items (info, result, context)) + return FALSE; + } + info->entries_valid = TRUE; + } + + return TRUE; +} + +static gboolean +vfolder_info_reload (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context, + gboolean force_read_items) +{ + G_LOCK (vfolder_lock); + if (vfolder_info_reload_unlocked (info, result, context, + force_read_items)) { + G_UNLOCK (vfolder_lock); + return TRUE; + } else { + G_UNLOCK (vfolder_lock); + return FALSE; + } +} + +static gboolean +vfolder_info_recheck (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + GSList *li; + time_t curtime = time (NULL); + gboolean reread = FALSE; + + if (info->filename_statloc != NULL && + ! check_statloc (info->filename_statloc, curtime)) { + if ( ! vfolder_info_reload_unlocked (info, result, context, + FALSE /* force read items */)) { + /* we have failed, make sure we fail + * next time too */ + info->filename_statloc->trigger_next = TRUE; + return FALSE; + } + reread = TRUE; + } + if ( ! reread && + info->user_filename_statloc != NULL && + ! check_statloc (info->user_filename_statloc, curtime)) { + if ( ! vfolder_info_reload_unlocked (info, result, context, + FALSE /* force read items */)) { + /* we have failed, make sure we fail + * next time too */ + info->user_filename_statloc->trigger_next = TRUE; + return FALSE; + } + reread = TRUE; + } + + if (info->entries_valid) { + for (li = info->stat_dirs; li != NULL; li = li->next) { + StatLoc *sl = li->data; + if ( ! check_statloc (sl, curtime)) { + info->entries_valid = FALSE; + break; + } + } + } + return TRUE; +} + +static VFolderInfo * +get_vfolder_info_unlocked (const char *scheme, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + VFolderInfo *info; + + if (infos != NULL && + (info = g_hash_table_lookup (infos, scheme)) != NULL) { + if ( ! vfolder_info_recheck (info, result, context)) { + return NULL; + } + if ( ! info->entries_valid) { + g_slist_foreach (info->entries, + (GFunc)entry_unref, NULL); + g_slist_free (info->entries); + info->entries = NULL; + + if (info->entries_ht != NULL) + g_hash_table_destroy (info->entries_ht); + info->entries_ht = g_hash_table_new (g_str_hash, + g_str_equal); + + if ( ! vfolder_info_read_items (info, + result, context)) { + info->entries_valid = FALSE; + return NULL; + } + + invalidate_folder_T (info->root); + + info->entries_valid = TRUE; + + /* Update modification time of all folders, + * kind of evil, but it will make adding new items work + * I hope. This is because rereading usually means + * something changed */ + info->modification_time = time (NULL); + } + return info; + } + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if (infos == NULL) + infos = g_hash_table_new_full + (g_str_hash, g_str_equal, + (GDestroyNotify)g_free, + (GDestroyNotify)vfolder_info_destroy); + + info = g_new0 (VFolderInfo, 1); + vfolder_info_init (info, scheme); + + if (gnome_vfs_context_check_cancellation (context)) { + vfolder_info_destroy (info); + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if ( ! vfolder_info_read_info (info, result, context)) { + vfolder_info_destroy (info); + return NULL; + } + + if ( ! monitor_setup (info, + TRUE /* setup_filenames */, + TRUE /* setup_itemdirs */, + TRUE /* setup_desktop_dirs */, + result, context)) { + vfolder_info_destroy (info); + return NULL; + } + + g_hash_table_insert (infos, g_strdup (scheme), info); + + if ( ! vfolder_info_read_items (info, result, context)) { + info->entries_valid = FALSE; + return NULL; + } + info->entries_valid = TRUE; + + return info; +} + +static VFolderInfo * +get_vfolder_info (const char *scheme, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + VFolderInfo *info; + G_LOCK (vfolder_lock); + info = get_vfolder_info_unlocked (scheme, result, context); + G_UNLOCK (vfolder_lock); + return info; +} + + +static char * +keywords_to_string (GSList *keywords) +{ + GSList *li; + GString *str = g_string_new (NULL); + + for (li = keywords; li != NULL; li = li->next) { + GQuark word = GPOINTER_TO_INT (li->data); + g_string_append (str, g_quark_to_string (word)); + g_string_append_c (str, ';'); + } + + return g_string_free (str, FALSE); +} + +/* copy file and add keywords line */ +static gboolean +copy_file_with_keywords (const char *from, const char *to, GSList *keywords) +{ + FILE *fp; + FILE *wfp; + int wfd; + char buf[BUFSIZ]; + char *keyword_string; + + if ( ! ensure_dir (to, + TRUE /* ignore_basename */)) + return FALSE; + + wfd = open (to, O_CREAT | O_WRONLY | O_TRUNC, 0600); + if (wfd < 0) { + return FALSE; + } + + keyword_string = keywords_to_string (keywords); + + wfp = fdopen (wfd, "w"); + + fp = fopen (from, "r"); + if (fp != NULL) { + gboolean wrote_keywords = FALSE; + while (fgets (buf, sizeof (buf), fp) != NULL) { + fprintf (wfp, "%s", buf); + if ( ! wrote_keywords && + (strncmp (buf, "[Desktop Entry]", + strlen ("[Desktop Entry]")) == 0 || + strncmp (buf, "[KDE Desktop Entry]", + strlen ("[KDE Desktop Entry]")) == 0)) { + fprintf (wfp, "Categories=%s\n", + keyword_string); + wrote_keywords = TRUE; + } + } + + fclose (fp); + } else { + fprintf (wfp, "[Desktop Entry]\nCategories=%s\n", + keyword_string); + } + + /* FIXME: does this close wfd???? */ + fclose (wfp); + + close (wfd); + + g_free (keyword_string); + + return TRUE; +} + +static gboolean +copy_file (const char *from, const char *to) +{ + int fd; + int wfd; + + if ( ! ensure_dir (to, + TRUE /* ignore_basename */)) + return FALSE; + + wfd = open (to, O_CREAT | O_WRONLY | O_TRUNC, 0600); + if (wfd < 0) { + return FALSE; + } + + fd = open (from, O_RDONLY); + if (fd >= 0) { + char buf[1024]; + ssize_t n; + + while ((n = read (fd, buf, sizeof(buf))) > 0) { + write (wfd, buf, n); + } + + close (fd); + } + + close (wfd); + + return TRUE; +} + +static gboolean +make_file_private (VFolderInfo *info, EntryFile *efile) +{ + char *newfname; + Entry *entry = (Entry *)efile; + + if (efile->per_user) + return TRUE; + + /* this file already exists so whack its monitors */ + if (efile->filename != NULL) { + GSList *li; + + for (li = entry->monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + if (h->handle != NULL) + gnome_vfs_monitor_cancel (h->handle); + h->handle = NULL; + } + } + + newfname = g_build_filename (g_get_home_dir (), + DOT_GNOME, + "vfolders", + info->scheme, + efile->entry.name, + NULL); + + if (efile->implicit_keywords) { + if (efile->filename != NULL && + ! copy_file_with_keywords (efile->filename, + newfname, + efile->keywords)) { + /* FIXME: what to do with monitors here, they + * have already been whacked, a corner case + * not handled! */ + g_free (newfname); + return FALSE; + } + } else { + if (efile->filename != NULL && + ! copy_file (efile->filename, newfname)) { + /* FIXME: what to do with monitors here, they + * have already been whacked, a corner case + * not handled! */ + g_free (newfname); + return FALSE; + } + } + + /* we didn't copy but ensure path anyway */ + if (efile->filename == NULL && + ! ensure_dir (newfname, + TRUE /* ignore_basename */)) { + g_free (newfname); + return FALSE; + } + + /* this file already exists so re-add monitors at the new location */ + if (efile->filename != NULL) { + GSList *li; + char *uri = gnome_vfs_get_uri_from_local_path (newfname); + + for (li = entry->monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + + gnome_vfs_monitor_add (&(h->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + h); + } + + g_free (uri); + } + + g_free (efile->filename); + efile->filename = newfname; + efile->per_user = TRUE; + + return TRUE; +} + +static void +try_free_file_monitors_create_dirfile_unlocked (VFolderInfo *info, + Folder *folder) +{ + GSList *li, *list; + + list = g_slist_copy (info->free_file_monitors); + + for (li = list; li != NULL; li = li->next) { + FileMonitorHandle *handle = li->data; + Folder *f; + VFolderURI vuri; + GnomeVFSResult result; + + if ( ! handle->is_directory_file) + continue; + + /* Evil! EVIL URI PARSING. this will eat a lot of stack if we + * have lots of free monitors */ + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + f = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + + if (folder != f) + continue; + + info->free_file_monitors = + g_slist_remove (info->free_file_monitors, handle); + ((Entry *)folder)->monitors = + g_slist_prepend (((Entry *)folder)->monitors, handle); + + handle->exists = TRUE; + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *)handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_CREATED); + } + + g_slist_free (list); +} + +static void +make_new_dirfile (VFolderInfo *info, Folder *folder) +{ + char *name = g_strdup (folder->entry.name); + char *fname; + char *p; + int i; + int fd; + + for (p = name; *p != '\0'; p++) { + if ( ! ( (*p >= 'a' && *p <= 'z') || + (*p >= 'A' && *p <= 'Z') || + (*p >= '0' && *p <= '9') || + *p == '_')) { + *p = '_'; + } + } + + i = 0; + fname = NULL; + do { + char *fullname; + + g_free (fname); + + if (i > 0) { + fname = g_strdup_printf ("%s-%d.directory", name, i); + } else { + fname = g_strdup_printf ("%s.directory", name); + } + + fullname = g_build_filename + (info->user_desktop_dir, fname, NULL); + fd = open (fullname, O_CREAT | O_WRONLY | O_EXCL, 0600); + g_free (fullname); + } while (fd < 0); + + close (fd); + + folder->desktop_file = fname; + info->dirty = TRUE; + + try_free_file_monitors_create_dirfile_unlocked (info, folder); +} + +static gboolean +make_dirfile_private (VFolderInfo *info, Folder *folder) +{ + char *fname; + char *desktop_file; + GSList *li; + char *uri; + gboolean ret; + + if (info->user_desktop_dir == NULL) + return FALSE; + + if ( ! ensure_dir (info->user_desktop_dir, + FALSE /* ignore_basename */)) + return FALSE; + + + if (folder->desktop_file == NULL) { + make_new_dirfile (info, folder); + return TRUE; + } + + /* FIXME: this is broken! What if the desktop file exists + * in the local but there is a different (but with a same name) + * .directory in the system. */ + fname = g_build_filename (info->user_desktop_dir, + folder->desktop_file, + NULL); + + if (access (fname, F_OK) == 0) { + g_free (fname); + return TRUE; + } + + desktop_file = get_directory_file (info, folder); + + if (desktop_file == NULL) { + int fd = open (fname, O_CREAT | O_EXCL | O_WRONLY, 0600); + g_free (fname); + if (fd >= 0) { + close (fd); + return TRUE; + } + return FALSE; + } + + for (li = ((Entry *)folder)->monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + if (h->is_directory_file) { + if (h->handle != NULL) + gnome_vfs_monitor_cancel (h->handle); + h->handle = NULL; + } + } + + ret = TRUE; + + if ( ! copy_file (desktop_file, fname)) { + ret = FALSE; + g_free (fname); + fname = desktop_file; + desktop_file = NULL; + } + + uri = gnome_vfs_get_uri_from_local_path (fname); + + for (li = ((Entry *)folder)->monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + + if (h->is_directory_file) { + gnome_vfs_monitor_add (&(h->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + h); + } + } + + g_free (uri); + + g_free (desktop_file); + g_free (fname); + + return ret; +} + +static Folder * +resolve_folder (VFolderInfo *info, + const char *path, + gboolean ignore_basename, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + char **ppath; + int i; + Folder *folder = info->root; + + ppath = g_strsplit (path, "/", -1); + + if (ppath == NULL || + ppath[0] == NULL) { + g_strfreev (ppath); + *result = GNOME_VFS_ERROR_INVALID_URI; + return NULL; + } + + for (i = 0; ppath [i] != NULL; i++) { + const char *segment = ppath[i]; + + if (*segment == '\0') + continue; + + if (ignore_basename && ppath [i + 1] == NULL) + break; + else { + folder = (Folder *) find_entry (folder->subfolders, + segment); + if (folder == NULL) + break; + } + } + g_strfreev (ppath); + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if (folder == NULL) + *result = GNOME_VFS_ERROR_NOT_FOUND; + + return folder; +} + +static Entry * +resolve_path (VFolderInfo *info, + const char *path, + const char *basename, + Folder **return_folder, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + Entry *entry; + Folder *folder; + + if (strcmp (path, "/") == 0) + return (Entry *)info->root; + + folder = resolve_folder (info, path, + TRUE /* ignore_basename */, + result, context); + + if (return_folder != NULL) + *return_folder = folder; + + if (folder == NULL) { + return NULL; + } + + /* Make sure we have the entries here */ + ensure_folder_unlocked (info, folder, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + + entry = find_entry (folder->entries, basename); + + if (entry == NULL) + *result = GNOME_VFS_ERROR_NOT_FOUND; + + return entry; +} + +static Entry * +get_entry_unlocked (VFolderURI *vuri, + Folder **parent, + gboolean *is_directory_file, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + VFolderInfo *info; + Entry *entry; + + if (is_directory_file != NULL) + *is_directory_file = FALSE; + if (parent != NULL) + *parent = NULL; + + info = get_vfolder_info_unlocked (vuri->scheme, result, context); + if (info == NULL) + return NULL; + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if (vuri->is_all_scheme) { + GSList *efile_list; + + if (vuri->file == NULL) { + entry = resolve_path (info, + vuri->path, + vuri->file, + parent, + result, + context); + return entry; + } + + efile_list = g_hash_table_lookup (info->entries_ht, vuri->file); + + if (efile_list == NULL) { + *result = GNOME_VFS_ERROR_NOT_FOUND; + return NULL; + } else { + return efile_list->data; + } + } + + if (vuri->file != NULL && + check_ext (vuri->file, ".directory") == TRUE) { + Folder *folder; + + folder = resolve_folder (info, vuri->path, + TRUE /* ignore_basename */, + result, context); + if (folder == NULL) { + return NULL; + } + + if (is_directory_file != NULL) + *is_directory_file = TRUE; + + if (parent != NULL) + *parent = folder; + + return (Entry *)folder; + } else { + entry = resolve_path (info, vuri->path, vuri->file, parent, + result, context); + return entry; + } +} + +static Entry * +get_entry (VFolderURI *vuri, + Folder **parent, + gboolean *is_directory_file, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + Entry *entry; + + G_LOCK (vfolder_lock); + entry = get_entry_unlocked (vuri, + parent, + is_directory_file, + result, context); + G_UNLOCK (vfolder_lock); + + return entry; +} + +/* only works for files and only those that exist */ +/* unlocked function */ +static GnomeVFSURI * +desktop_uri_to_file_uri (VFolderInfo *info, + VFolderURI *desktop_vuri, + Entry **the_entry, + gboolean *the_is_directory_file, + Folder **the_folder, + gboolean privatize, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + gboolean is_directory_file; + GnomeVFSURI *ret_uri; + Folder *folder = NULL; + Entry *entry; + + entry = get_entry_unlocked (desktop_vuri, + &folder, + &is_directory_file, + result, + context); + if (entry == NULL) + return NULL; + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if (the_folder != NULL) + *the_folder = folder; + + if (the_entry != NULL) + *the_entry = entry; + if (the_is_directory_file != NULL) + *the_is_directory_file = is_directory_file; + + if (is_directory_file && + entry->type == ENTRY_FOLDER) { + char *desktop_file; + + folder = (Folder *)entry; + + if (the_folder != NULL) + *the_folder = folder; + + /* we'll be doing something write like */ + if (folder->read_only && + privatize) { + *result = GNOME_VFS_ERROR_READ_ONLY; + return NULL; + } + + if (privatize) { + char *fname; + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if ( ! make_dirfile_private (info, folder)) { + *result = GNOME_VFS_ERROR_GENERIC; + return NULL; + } + fname = g_build_filename (g_get_home_dir (), + folder->desktop_file, + NULL); + ret_uri = gnome_vfs_uri_new (fname); + g_free (fname); + return ret_uri; + } + + desktop_file = get_directory_file_unlocked (info, folder); + if (desktop_file != NULL) { + char *s = gnome_vfs_get_uri_from_local_path + (desktop_file); + + g_free (desktop_file); + + ret_uri = gnome_vfs_uri_new (s); + g_free (s); + + return ret_uri; + } else { + *result = GNOME_VFS_ERROR_NOT_FOUND; + return NULL; + } + } else if (entry->type == ENTRY_FILE) { + EntryFile *efile = (EntryFile *)entry; + char *s; + + /* we'll be doing something write like */ + if (folder != NULL && + folder->read_only && + privatize) { + *result = GNOME_VFS_ERROR_READ_ONLY; + return NULL; + } + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if (privatize && + ! make_file_private (info, efile)) { + *result = GNOME_VFS_ERROR_GENERIC; + return NULL; + } + + s = gnome_vfs_get_uri_from_local_path (efile->filename); + ret_uri = gnome_vfs_uri_new (s); + g_free (s); + + return ret_uri; + } else { + if (the_folder != NULL) + *the_folder = (Folder *)entry; + *result = GNOME_VFS_ERROR_IS_DIRECTORY; + return NULL; + } +} + +static void +remove_file (Folder *folder, const char *basename) +{ + GSList *li; + char *s; + + if (folder->includes_ht != NULL) { + li = g_hash_table_lookup (folder->includes_ht, basename); + if (li != NULL) { + char *name = li->data; + folder->includes = g_slist_delete_link + (folder->includes, li); + g_hash_table_remove (folder->includes_ht, basename); + g_free (name); + } + } + + if (folder->excludes == NULL) { + folder->excludes = g_hash_table_new_full + (g_str_hash, g_str_equal, + (GDestroyNotify)g_free, + NULL); + } + s = g_strdup (basename); + g_hash_table_replace (folder->excludes, s, s); +} + +static void +add_file (Folder *folder, const char *basename) +{ + GSList *li = NULL; + + if (folder->includes_ht != NULL) { + li = g_hash_table_lookup (folder->includes_ht, basename); + } + + /* if not found */ + if (li == NULL) { + char *str = g_strdup (basename); + folder->includes = + g_slist_prepend (folder->includes, str); + if (folder->includes_ht == NULL) { + folder->includes_ht = + g_hash_table_new_full (g_str_hash, + g_str_equal, + NULL, + NULL); + } + g_hash_table_replace (folder->includes_ht, + str, folder->includes); + } + if (folder->excludes != NULL) + g_hash_table_remove (folder->excludes, basename); +} + +typedef struct _FileHandle FileHandle; +struct _FileHandle { + VFolderInfo *info; + GnomeVFSMethodHandle *handle; + Entry *entry; + gboolean write; + gboolean is_directory_file; +}; + +static void +make_handle (GnomeVFSMethodHandle **method_handle, + GnomeVFSMethodHandle *file_handle, + VFolderInfo *info, + Entry *entry, + gboolean is_directory_file, + gboolean write) +{ + if (file_handle != NULL) { + FileHandle *handle = g_new0 (FileHandle, 1); + + handle->info = info; + handle->handle = file_handle; + handle->entry = entry_ref (entry); + handle->is_directory_file = is_directory_file; + handle->write = write; + + *method_handle = (GnomeVFSMethodHandle *) handle; + } else { + *method_handle = NULL; + } +} + +static void +whack_handle (FileHandle *handle) +{ + entry_unref (handle->entry); + handle->entry = NULL; + + handle->handle = NULL; + handle->info = NULL; + + g_free (handle); +} + +static GnomeVFSResult +do_open (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result = GNOME_VFS_OK; + VFolderInfo *info; + Entry *entry; + gboolean is_directory_file; + GnomeVFSMethodHandle *file_handle = NULL; + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + /* These can't be very nice FILE names */ + if (vuri.file == NULL || + vuri.ends_in_slash) + return GNOME_VFS_ERROR_INVALID_URI; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (mode & GNOME_VFS_OPEN_WRITE && + (info->read_only || vuri.is_all_scheme)) + return GNOME_VFS_ERROR_READ_ONLY; + + G_LOCK (vfolder_lock); + file_uri = desktop_uri_to_file_uri (info, + &vuri, + &entry, + &is_directory_file, + NULL /* the_folder */, + mode & GNOME_VFS_OPEN_WRITE, + &result, + context); + + if (file_uri == NULL) { + G_UNLOCK (vfolder_lock); + return result; + } + + result = (* parent_method->open) (parent_method, + &file_handle, + file_uri, + mode, + context); + + if (result == GNOME_VFS_ERROR_CANCELLED) { + G_UNLOCK (vfolder_lock); + gnome_vfs_uri_unref (file_uri); + return result; + } + + make_handle (method_handle, + file_handle, + info, + entry, + is_directory_file, + mode & GNOME_VFS_OPEN_WRITE); + + gnome_vfs_uri_unref (file_uri); + + if (info->dirty) { + vfolder_info_write_user (info); + } + + G_UNLOCK (vfolder_lock); + + return result; +} + +static void +remove_from_all_except (Folder *root, + const char *name, + Folder *except) +{ + GSList *li; + + if (root != except) { + remove_file (root, name); + if (root->up_to_date) { + for (li = root->entries; li != NULL; li = li->next) { + Entry *entry = li->data; + if (strcmp (name, entry->name) == 0) { + root->entries = + g_slist_delete_link + (root->entries, li); + break; + } + } + } + } + + for (li = root->subfolders; li != NULL; li = li->next) { + Folder *subfolder = li->data; + + remove_from_all_except (subfolder, name, except); + } +} + +static GnomeVFSResult +do_create (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + gboolean exclusive, + guint perm, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + GnomeVFSMethodHandle *file_handle; + GnomeVFSURI *file_uri; + VFolderURI vuri; + VFolderInfo *info; + Folder *parent; + Entry *entry; + EntryFile *efile; + char *s; + GSList *li; + + VFOLDER_URI_PARSE (uri, &vuri); + + /* These can't be very nice FILE names */ + if (vuri.file == NULL || + vuri.ends_in_slash) + return GNOME_VFS_ERROR_INVALID_URI; + + if ( ! check_ext (vuri.file, ".desktop") && + ! strcmp (vuri.file, ".directory") == 0) { + return GNOME_VFS_ERROR_INVALID_URI; + } + + /* all scheme is read only */ + if (vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (info->user_filename == NULL || + info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + parent = resolve_folder (info, vuri.path, + TRUE /* ignore_basename */, + &result, context); + if (parent == NULL) + return result; + + if (parent->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + if (strcmp (vuri.file, ".directory") == 0) { + char *fname; + + G_LOCK (vfolder_lock); + + if (exclusive) { + char *desktop_file; + desktop_file = get_directory_file_unlocked (info, parent); + if (desktop_file != NULL) { + g_free (desktop_file); + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_FILE_EXISTS; + } + } + + if ( ! make_dirfile_private (info, parent)) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_GENERIC; + } + fname = g_build_filename (g_get_home_dir (), + parent->desktop_file, + NULL); + s = gnome_vfs_get_uri_from_local_path (fname); + file_uri = gnome_vfs_uri_new (s); + g_free (fname); + g_free (s); + + if (file_uri == NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_GENERIC; + } + + result = (* parent_method->create) (parent_method, + &file_handle, + file_uri, + mode, + exclusive, + perm, + context); + gnome_vfs_uri_unref (file_uri); + + make_handle (method_handle, + file_handle, + info, + (Entry *)parent, + TRUE /* is_directory_file */, + TRUE /* write */); + + if (info->dirty) + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return result; + } + + ensure_folder (info, parent, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + + entry = find_entry (parent->entries, vuri.file); + + if (entry != NULL && + entry->type == ENTRY_FOLDER) + return GNOME_VFS_ERROR_IS_DIRECTORY; + + efile = (EntryFile *)entry; + + if (efile != NULL) { + if (exclusive) + return GNOME_VFS_ERROR_FILE_EXISTS; + + G_LOCK (vfolder_lock); + if ( ! make_file_private (info, efile)) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_GENERIC; + } + + s = gnome_vfs_get_uri_from_local_path (efile->filename); + file_uri = gnome_vfs_uri_new (s); + g_free (s); + + if (file_uri == NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_GENERIC; + } + + result = (* parent_method->create) (parent_method, + &file_handle, + file_uri, + mode, + exclusive, + perm, + context); + gnome_vfs_uri_unref (file_uri); + + make_handle (method_handle, + file_handle, + info, + (Entry *)efile, + FALSE /* is_directory_file */, + TRUE /* write */); + + G_UNLOCK (vfolder_lock); + + return result; + } + + G_LOCK (vfolder_lock); + + li = g_hash_table_lookup (info->entries_ht, vuri.file); + + if (exclusive && li != NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_FILE_EXISTS; + } + + if (li == NULL) { + efile = file_new (vuri.file); + vfolder_info_insert_entry (info, efile); + entry_unref ((Entry *)efile); + } else { + efile = li->data; + } + + /* this will make a private name for this */ + if ( ! make_file_private (info, efile)) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_GENERIC; + } + + add_file (parent, vuri.file); + parent->sorted = FALSE; + + if (parent->up_to_date) + parent->entries = g_slist_prepend (parent->entries, efile); + + /* if we created a brand new name, then we exclude it + * from everywhere else to ensure overall sanity */ + if (li == NULL) + remove_from_all_except (info->root, vuri.file, parent); + + s = gnome_vfs_get_uri_from_local_path (efile->filename); + file_uri = gnome_vfs_uri_new (s); + g_free (s); + + result = (* parent_method->create) (parent_method, + &file_handle, + file_uri, + mode, + exclusive, + perm, + context); + gnome_vfs_uri_unref (file_uri); + + make_handle (method_handle, + file_handle, + info, + (Entry *)efile, + FALSE /* is_directory_file */, + TRUE /* write */); + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return result; +} + +static GnomeVFSResult +do_close (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + if (method_handle == (GnomeVFSMethodHandle *)method) + return GNOME_VFS_OK; + + G_LOCK (vfolder_lock); + + result = (* parent_method->close) (parent_method, + handle->handle, + context); + handle->handle = NULL; + + /* we reread the Categories keyword */ + if (handle->write && + handle->entry != NULL && + handle->entry->type == ENTRY_FILE) { + EntryFile *efile = (EntryFile *)handle->entry; + char *categories; + readitem_entry (efile->filename, + "Categories", + &categories, + NULL, + NULL); + set_keywords (efile, categories); + g_free (categories); + /* FIXME: what about OnlyShowIn */ + + /* FIXME: check if the keywords changed, if not, do + * nothing */ + + /* Perhaps a bit drastic */ + /* also this emits the CHANGED monitor signal */ + invalidate_folder_T (handle->info->root); + + /* the file changed monitor will happen by itself + * as the underlying file is changed */ + } else if (handle->write && + handle->entry != NULL && + handle->entry->type == ENTRY_FOLDER && + handle->is_directory_file) { + /* if we're monitoring this directory, emit the CHANGED + * monitor thing, it will also emit a changed on + * the file itself. It is better to emit changed + * just in case. */ + emit_monitor ((Folder *)(handle->entry), + GNOME_VFS_MONITOR_EVENT_CHANGED); + } + + whack_handle (handle); + + G_UNLOCK (vfolder_lock); + + return result; +} + +static void +fill_buffer (gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read) +{ + char *buf = buffer; + GnomeVFSFileSize i; + for (i = 0; i < num_bytes; i++) { + if (rand () % 32 == 0 || + i == num_bytes-1) + buf[i] = '\n'; + else + buf[i] = ((rand()>>4) % 94) + 32; + } + if (bytes_read != 0) + *bytes_read = i; +} + +static GnomeVFSResult +do_read (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + if (method_handle == (GnomeVFSMethodHandle *)method) { + if ((rand () >> 4) & 0x3) { + fill_buffer (buffer, num_bytes, bytes_read); + return GNOME_VFS_OK; + } else { + return GNOME_VFS_ERROR_EOF; + } + } + + result = (* parent_method->read) (parent_method, + handle->handle, + buffer, num_bytes, + bytes_read, + context); + + return result; +} + +static GnomeVFSResult +do_write (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gconstpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_written, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + if (method_handle == (GnomeVFSMethodHandle *)method) + return GNOME_VFS_OK; + + result = (* parent_method->write) (parent_method, + handle->handle, + buffer, num_bytes, + bytes_written, + context); + + return result; +} + + +static GnomeVFSResult +do_seek (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSSeekPosition whence, + GnomeVFSFileOffset offset, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + if (method_handle == (GnomeVFSMethodHandle *)method) + return GNOME_VFS_OK; + + result = (* parent_method->seek) (parent_method, + handle->handle, + whence, offset, + context); + + return result; +} + +static GnomeVFSResult +do_tell (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileOffset *offset_return) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + result = (* parent_method->tell) (parent_method, + handle->handle, + offset_return); + + return result; +} + + +static GnomeVFSResult +do_truncate_handle (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileSize where, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + if (method_handle == (GnomeVFSMethodHandle *)method) + return GNOME_VFS_OK; + + result = (* parent_method->truncate_handle) (parent_method, + handle->handle, + where, + context); + + return result; +} + +static GnomeVFSResult +do_truncate (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileSize where, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result = GNOME_VFS_OK; + VFolderInfo *info; + Entry *entry; + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + /* These can't be very nice FILE names */ + if (vuri.file == NULL || + vuri.ends_in_slash) + return GNOME_VFS_ERROR_INVALID_URI; + + if (vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + G_LOCK (vfolder_lock); + file_uri = desktop_uri_to_file_uri (info, + &vuri, + &entry, + NULL /* the_is_directory_file */, + NULL /* the_folder */, + TRUE /* privatize */, + &result, + context); + G_UNLOCK (vfolder_lock); + + if (file_uri == NULL) + return result; + + result = (* parent_method->truncate) (parent_method, + file_uri, + where, + context); + + gnome_vfs_uri_unref (file_uri); + + if (info->dirty) { + G_LOCK (vfolder_lock); + vfolder_info_write_user (info); + G_UNLOCK (vfolder_lock); + } + + if (entry->type == ENTRY_FILE) { + EntryFile *efile = (EntryFile *)entry; + + G_LOCK (vfolder_lock); + g_slist_free (efile->keywords); + efile->keywords = NULL; + G_UNLOCK (vfolder_lock); + } + + /* Perhaps a bit drastic, but oh well */ + invalidate_folder (info->root); + + return result; +} + +typedef struct _DirHandle DirHandle; +struct _DirHandle { + VFolderInfo *info; + Folder *folder; + + GnomeVFSFileInfoOptions options; + + /* List of Entries */ + GSList *list; + GSList *current; +}; + +static GnomeVFSResult +do_open_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + VFolderURI vuri; + DirHandle *dh; + Folder *folder; + VFolderInfo *info; + char *desktop_file; + + VFOLDER_URI_PARSE (uri, &vuri); + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + /* In the all- scheme just list all filenames */ + if (vuri.is_all_scheme) { + if (any_subdir (vuri.path)) + return GNOME_VFS_ERROR_NOT_FOUND; + + dh = g_new0 (DirHandle, 1); + dh->info = info; + dh->options = options; + dh->folder = NULL; + + G_LOCK (vfolder_lock); + dh->list = g_slist_copy (info->entries); + g_slist_foreach (dh->list, (GFunc)entry_ref, NULL); + dh->current = dh->list; + G_UNLOCK (vfolder_lock); + + *method_handle = (GnomeVFSMethodHandle*) dh; + return GNOME_VFS_OK; + } + + folder = resolve_folder (info, vuri.path, + FALSE /* ignore_basename */, + &result, context); + if (folder == NULL) + return result; + + /* Make sure we have the entries and sorted here */ + ensure_folder_sort (info, folder); + + dh = g_new0 (DirHandle, 1); + dh->info = info; + dh->options = options; + + G_LOCK (vfolder_lock); + dh->folder = (Folder *)entry_ref ((Entry *)folder); + dh->list = g_slist_copy (folder->entries); + g_slist_foreach (folder->entries, (GFunc)entry_ref, NULL); + G_UNLOCK (vfolder_lock); + + desktop_file = get_directory_file (info, folder); + if (desktop_file != NULL) { + EntryFile *efile = file_new (".directory"); + dh->list = g_slist_prepend (dh->list, efile); + g_free (desktop_file); + } + + dh->current = dh->list; + + *method_handle = (GnomeVFSMethodHandle*) dh; + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_close_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + DirHandle *dh; + + dh = (DirHandle*) method_handle; + + G_LOCK (vfolder_lock); + + g_slist_foreach (dh->list, (GFunc)entry_unref, NULL); + g_slist_free (dh->list); + dh->list = NULL; + + dh->current = NULL; + + if (dh->folder != NULL) + entry_unref ((Entry *)dh->folder); + dh->folder = NULL; + + dh->info = NULL; + + g_free (dh); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_read_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSContext *context) +{ + DirHandle *dh; + Entry *entry; + GnomeVFSFileInfoOptions options; + + dh = (DirHandle*) method_handle; + +read_directory_again: + + if (dh->current == NULL) { + return GNOME_VFS_ERROR_EOF; + } + + entry = dh->current->data; + dh->current = dh->current->next; + + options = dh->options; + + if (entry->type == ENTRY_FILE && + ((EntryFile *)entry)->filename != NULL) { + EntryFile *efile = (EntryFile *)entry; + char *furi = gnome_vfs_get_uri_from_local_path (efile->filename); + GnomeVFSURI *uri = gnome_vfs_uri_new (furi); + + /* we always get mime-type by forcing it below */ + if (options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE) + options &= ~GNOME_VFS_FILE_INFO_GET_MIME_TYPE; + + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_NONE; + + /* Get the file info for this */ + (* parent_method->get_file_info) (parent_method, + uri, + file_info, + options, + context); + + /* we ignore errors from this since the file_info just + * won't be filled completely if there's an error, that's all */ + + g_free (file_info->mime_type); + file_info->mime_type = g_strdup ("application/x-gnome-app-info"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + /* Now we wipe those fields we don't support */ + file_info->valid_fields &= ~(UNSUPPORTED_INFO_FIELDS); + + gnome_vfs_uri_unref (uri); + g_free (furi); + } else if (entry->type == ENTRY_FILE) { + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_NONE; + + file_info->name = g_strdup (entry->name); + GNOME_VFS_FILE_INFO_SET_LOCAL (file_info, TRUE); + + file_info->type = GNOME_VFS_FILE_TYPE_REGULAR; + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_TYPE; + + /* FIXME: Is this correct? isn't there an xdg mime type? */ + file_info->mime_type = g_strdup ("application/x-gnome-app-info"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + /* FIXME: get some ctime/mtime */ + } else /* ENTRY_FOLDER */ { + Folder *folder = (Folder *)entry; + + /* Skip empty folders if they have + * the flag set */ + if (folder->dont_show_if_empty) { + /* Make sure we have the entries */ + ensure_folder (dh->info, folder, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + + if (folder->entries == NULL) { + /* start this function over on the + * next item */ + goto read_directory_again; + } + } + + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_NONE; + + file_info->name = g_strdup (entry->name); + GNOME_VFS_FILE_INFO_SET_LOCAL (file_info, TRUE); + + file_info->type = GNOME_VFS_FILE_TYPE_DIRECTORY; + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_TYPE; + + file_info->mime_type = g_strdup ("x-directory/vfolder-desktop"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + file_info->ctime = dh->info->modification_time; + file_info->mtime = dh->info->modification_time; + file_info->valid_fields |= (GNOME_VFS_FILE_INFO_FIELDS_CTIME | + GNOME_VFS_FILE_INFO_FIELDS_MTIME); + } + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_get_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result = GNOME_VFS_OK; + Folder *folder; + VFolderInfo *info; + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + G_LOCK (vfolder_lock); + file_uri = desktop_uri_to_file_uri (info, + &vuri, + NULL /* the_entry */, + NULL /* the_is_directory_file */, + &folder, + FALSE /* privatize */, + &result, + context); + G_UNLOCK (vfolder_lock); + + if (file_uri == NULL && + result != GNOME_VFS_ERROR_IS_DIRECTORY) + return result; + + if (file_uri != NULL) { + /* we always get mime-type by forcing it below */ + if (options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE) + options &= ~GNOME_VFS_FILE_INFO_GET_MIME_TYPE; + + result = (* parent_method->get_file_info) (parent_method, + file_uri, + file_info, + options, + context); + + g_free (file_info->mime_type); + file_info->mime_type = g_strdup ("application/x-gnome-app-info"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + /* Now we wipe those fields we don't support */ + file_info->valid_fields &= ~(UNSUPPORTED_INFO_FIELDS); + + gnome_vfs_uri_unref (file_uri); + + return result; + } else if (folder != NULL) { + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_NONE; + + file_info->name = g_strdup (folder->entry.name); + GNOME_VFS_FILE_INFO_SET_LOCAL (file_info, TRUE); + + file_info->type = GNOME_VFS_FILE_TYPE_DIRECTORY; + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_TYPE; + + file_info->mime_type = g_strdup ("x-directory/vfolder-desktop"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + file_info->ctime = info->modification_time; + file_info->mtime = info->modification_time; + file_info->valid_fields |= (GNOME_VFS_FILE_INFO_FIELDS_CTIME | + GNOME_VFS_FILE_INFO_FIELDS_MTIME); + + return GNOME_VFS_OK; + } else { + return GNOME_VFS_ERROR_NOT_FOUND; + } +} + +static GnomeVFSResult +do_get_file_info_from_handle (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + if (method_handle == (GnomeVFSMethodHandle *)method) { + g_free (file_info->mime_type); + file_info->mime_type = g_strdup ("text/plain"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + return GNOME_VFS_OK; + } + + /* we always get mime-type by forcing it below */ + if (options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE) + options &= ~GNOME_VFS_FILE_INFO_GET_MIME_TYPE; + + result = (* parent_method->get_file_info_from_handle) (parent_method, + handle->handle, + file_info, + options, + context); + + /* any file is of the .desktop type */ + g_free (file_info->mime_type); + file_info->mime_type = g_strdup ("application/x-gnome-app-info"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + /* Now we wipe those fields we don't support */ + file_info->valid_fields &= ~(UNSUPPORTED_INFO_FIELDS); + + return result; +} + + +static gboolean +do_is_local (GnomeVFSMethod *method, + const GnomeVFSURI *uri) +{ + return TRUE; +} + +static void +try_free_folder_monitors_create_unlocked (VFolderInfo *info, + Folder *folder) +{ + GSList *li, *list; + + list = g_slist_copy (info->free_folder_monitors); + + for (li = list; li != NULL; li = li->next) { + FileMonitorHandle *handle = li->data; + Folder *f; + VFolderURI vuri; + GnomeVFSResult result; + + /* Evil! EVIL URI PARSING. this will eat a lot of stack if we + * have lots of free monitors */ + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + f = resolve_folder (info, + vuri.path, + FALSE /* ignore_basename */, + &result, + NULL); + + if (folder != f) + continue; + + info->free_folder_monitors = + g_slist_remove (info->free_folder_monitors, handle); + ((Entry *)folder)->monitors = + g_slist_prepend (((Entry *)folder)->monitors, handle); + + handle->exists = TRUE; + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *)handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_CREATED); + } +} + + +static GnomeVFSResult +do_make_directory (GnomeVFSMethod *method, + GnomeVFSURI *uri, + guint perm, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + VFolderInfo *info; + Folder *parent, *folder; + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + if (vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (info->user_filename == NULL || + info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + parent = resolve_folder (info, vuri.path, + TRUE /* ignore_basename */, + &result, context); + if (parent == NULL) + return result; + else if (parent->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + G_LOCK (vfolder_lock); + + folder = (Folder *)find_entry (parent->subfolders, + vuri.file); + if (folder != NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_FILE_EXISTS; + } + + folder = folder_new (vuri.file); + parent->subfolders = g_slist_append (parent->subfolders, folder); + folder->parent = parent; + parent->up_to_date = FALSE; + + try_free_folder_monitors_create_unlocked (info, folder); + + /* parent changed */ + emit_monitor (parent, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_remove_directory (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + Folder *folder; + VFolderInfo *info; + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + if (vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (info->user_filename == NULL || + info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + G_LOCK (vfolder_lock); + + folder = resolve_folder (info, vuri.path, + FALSE /* ignore_basename */, + &result, context); + if (folder == NULL) { + G_UNLOCK (vfolder_lock); + return result; + } + + if (folder->read_only || + (folder->parent != NULL && + folder->parent->read_only)) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_READ_ONLY; + } + + /* don't make removing directories easy */ + if (folder->desktop_file != NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY; + } + + /* Make sure we have the entries */ + ensure_folder_unlocked (info, folder, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + + /* don't make removing directories easy */ + if (folder->entries != NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY; + } + + emit_and_delete_monitor (info, folder); + + if (folder->only_unallocated) { + GSList *li = g_slist_find (info->unallocated_folders, + folder); + if (li != NULL) { + info->unallocated_folders = g_slist_delete_link + (info->unallocated_folders, li); + entry_unref ((Entry *)folder); + } + } + + if (folder == info->root) { + info->root = NULL; + entry_unref ((Entry *)folder); + info->root = folder_new ("Root"); + } else { + Folder *parent = folder->parent; + + g_assert (parent != NULL); + + parent->subfolders = + g_slist_remove (parent->subfolders, folder); + + parent->up_to_date = FALSE; + + entry_unref ((Entry *)folder); + + /* parent changed */ + emit_monitor (parent, GNOME_VFS_MONITOR_EVENT_CHANGED); + } + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; +} + +/* a fairly evil function that does the whole move bit by copy and + * remove */ +static GnomeVFSResult +long_move (GnomeVFSMethod *method, + VFolderURI *old_vuri, + VFolderURI *new_vuri, + gboolean force_replace, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + GnomeVFSMethodHandle *handle; + GnomeVFSURI *file_uri; + const char *path; + int fd; + char buf[BUFSIZ]; + int bytes; + VFolderInfo *info; + + info = get_vfolder_info (old_vuri->scheme, &result, context); + if (info == NULL) + return result; + + G_LOCK (vfolder_lock); + file_uri = desktop_uri_to_file_uri (info, + old_vuri, + NULL /* the_entry */, + NULL /* the_is_directory_file */, + NULL /* the_folder */, + FALSE /* privatize */, + &result, + context); + G_UNLOCK (vfolder_lock); + + if (file_uri == NULL) + return result; + + path = gnome_vfs_uri_get_path (file_uri); + if (path == NULL) { + gnome_vfs_uri_unref (file_uri); + return GNOME_VFS_ERROR_INVALID_URI; + } + + fd = open (path, O_RDONLY); + if (fd < 0) { + gnome_vfs_uri_unref (file_uri); + return gnome_vfs_result_from_errno (); + } + + gnome_vfs_uri_unref (file_uri); + + info->inhibit_write++; + + result = method->create (method, + &handle, + new_vuri->uri, + GNOME_VFS_OPEN_WRITE, + force_replace /* exclusive */, + 0600 /* perm */, + context); + if (result != GNOME_VFS_OK) { + close (fd); + info->inhibit_write--; + return result; + } + + while ((bytes = read (fd, buf, BUFSIZ)) > 0) { + GnomeVFSFileSize bytes_written = 0; + result = method->write (method, + handle, + buf, + bytes, + &bytes_written, + context); + if (result == GNOME_VFS_OK && + bytes_written != bytes) + result = GNOME_VFS_ERROR_NO_SPACE; + if (result != GNOME_VFS_OK) { + close (fd); + method->close (method, handle, context); + /* FIXME: is this completely correct ? */ + method->unlink (method, + new_vuri->uri, + context); + G_LOCK (vfolder_lock); + info->inhibit_write--; + vfolder_info_write_user (info); + G_UNLOCK (vfolder_lock); + return result; + } + } + + close (fd); + + result = method->close (method, handle, context); + if (result != GNOME_VFS_OK) { + G_LOCK (vfolder_lock); + info->inhibit_write--; + vfolder_info_write_user (info); + G_UNLOCK (vfolder_lock); + return result; + } + + result = method->unlink (method, old_vuri->uri, context); + + G_LOCK (vfolder_lock); + info->inhibit_write--; + vfolder_info_write_user (info); + G_UNLOCK (vfolder_lock); + + return result; +} + +static GnomeVFSResult +move_directory_file (VFolderInfo *info, + Folder *old_folder, + Folder *new_folder) +{ + if (old_folder->desktop_file == NULL) + return GNOME_VFS_ERROR_NOT_FOUND; + + /* "move" the desktop file */ + g_free (new_folder->desktop_file); + new_folder->desktop_file = old_folder->desktop_file; + old_folder->desktop_file = NULL; + + /* is this too drastic, it will requery the folder? */ + new_folder->up_to_date = FALSE; + old_folder->up_to_date = FALSE; + + emit_monitor (new_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + emit_monitor (old_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + + return GNOME_VFS_OK; +} + +static gboolean +is_sub (Folder *master, Folder *sub) +{ + GSList *li; + + for (li = master->subfolders; li != NULL; li = li->next) { + Folder *subfolder = li->data; + + if (subfolder == sub || + is_sub (subfolder, sub)) + return TRUE; + } + + return FALSE; +} + +static GnomeVFSResult +move_folder (VFolderInfo *info, + Folder *old_folder, Entry *old_entry, + Folder *new_folder, Entry *new_entry) +{ + Folder *source = (Folder *)old_entry; + Folder *target; + + if (new_entry != NULL && + new_entry->type != ENTRY_FOLDER) + return GNOME_VFS_ERROR_NOT_A_DIRECTORY; + + if (new_entry != NULL) { + target = (Folder *)new_entry; + } else { + target = new_folder; + } + + /* move to where we are, yay, we're done :) */ + if (source->parent == target) + return GNOME_VFS_OK; + + if (source == target || + is_sub (source, target)) + return GNOME_VFS_ERROR_LOOP; + + /* this will never happen, but we're paranoid */ + if (source->parent == NULL) + return GNOME_VFS_ERROR_LOOP; + + source->parent->subfolders = g_slist_remove (source->parent->subfolders, + source); + target->subfolders = g_slist_append (target->subfolders, + source); + + source->parent = target; + + source->up_to_date = FALSE; + target->up_to_date = FALSE; + + emit_monitor (source, GNOME_VFS_MONITOR_EVENT_CHANGED); + emit_monitor (target, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_move (GnomeVFSMethod *method, + GnomeVFSURI *old_uri, + GnomeVFSURI *new_uri, + gboolean force_replace, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + VFolderInfo *info; + Folder *old_folder, *new_folder; + Entry *old_entry, *new_entry; + gboolean old_is_directory_file, new_is_directory_file; + VFolderURI old_vuri, new_vuri; + + VFOLDER_URI_PARSE (old_uri, &old_vuri); + VFOLDER_URI_PARSE (new_uri, &new_vuri); + + if (old_vuri.file == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + if (old_vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + if (strcmp (old_vuri.scheme, new_vuri.scheme) != 0) + return GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM; + + info = get_vfolder_info (old_vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + old_entry = get_entry (&old_vuri, + &old_folder, + &old_is_directory_file, + &result, + context); + if (old_entry == NULL) + return result; + + if (old_folder != NULL && old_folder->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + new_entry = get_entry (&new_vuri, + &new_folder, + &new_is_directory_file, + &result, + context); + if (new_entry == NULL && new_folder == NULL) + return result; + + if (new_folder != NULL && new_folder->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + if (new_is_directory_file != old_is_directory_file) { + /* this will do another set of lookups + * perhaps this can be done in a nicer way, + * but is this the common case? I don't think so */ + return long_move (method, &old_vuri, &new_vuri, + force_replace, context); + } + + if (new_is_directory_file) { + g_assert (old_entry != NULL); + g_assert (new_entry != NULL); + G_LOCK (vfolder_lock); + result = move_directory_file (info, + (Folder *)old_entry, + (Folder *)new_entry); + G_UNLOCK (vfolder_lock); + return result; + } + + if (old_entry->type == ENTRY_FOLDER) { + G_LOCK (vfolder_lock); + result = move_folder (info, + old_folder, old_entry, + new_folder, new_entry); + G_UNLOCK (vfolder_lock); + return result; + } + + /* move into self, just whack the old one */ + if (old_entry == new_entry) { + /* same folder */ + if (new_folder == old_folder) + return GNOME_VFS_OK; + + if ( ! force_replace) + return GNOME_VFS_ERROR_FILE_EXISTS; + + G_LOCK (vfolder_lock); + + remove_file (old_folder, old_vuri.file); + + old_folder->entries = g_slist_remove (old_folder->entries, + old_entry); + entry_unref (old_entry); + + emit_monitor (old_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; + } + + /* this is a simple move */ + if (new_entry == NULL || + new_entry->type == ENTRY_FOLDER) { + if (new_entry != NULL) { + new_folder = (Folder *)new_entry; + } else { + /* a file and a totally different one */ + if (strcmp (new_vuri.file, old_entry->name) != 0) { + /* yay, a long move */ + /* this will do another set of lookups + * perhaps this can be done in a nicer way, + * but is this the common case? I don't think + * so */ + return long_move (method, &old_vuri, &new_vuri, + force_replace, context); + } + } + + /* same folder */ + if (new_folder == old_folder) + return GNOME_VFS_OK; + + G_LOCK (vfolder_lock); + + remove_file (old_folder, old_entry->name); + add_file (new_folder, old_entry->name); + + new_folder->entries = g_slist_prepend (new_folder->entries, + old_entry); + entry_ref (old_entry); + new_folder->sorted = FALSE; + + old_folder->entries = g_slist_remove (old_folder->entries, + old_entry); + entry_unref (old_entry); + + emit_monitor (new_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + emit_monitor (old_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; + } + + /* do we EVER get here? */ + + /* this will do another set of lookups + * perhaps this can be done in a nicer way, + * but is this the common case? I don't think so */ + return long_move (method, &old_vuri, &new_vuri, + force_replace, context); +} + +static GnomeVFSResult +do_unlink (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + Entry *entry; + Folder *the_folder; + gboolean is_directory_file; + VFolderInfo *info; + VFolderURI vuri; + GSList *li; + + VFOLDER_URI_PARSE (uri, &vuri); + + if (vuri.file == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + if (vuri.is_all_scheme == TRUE) + return GNOME_VFS_ERROR_READ_ONLY; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + else if (info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + entry = get_entry (&vuri, + &the_folder, + &is_directory_file, + &result, context); + if (entry == NULL) + return result; + else if (the_folder != NULL && + the_folder->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + if (entry->type == ENTRY_FOLDER && + is_directory_file) { + Folder *folder = (Folder *)entry; + + if (folder->desktop_file == NULL) + return GNOME_VFS_ERROR_NOT_FOUND; + + G_LOCK (vfolder_lock); + + g_free (folder->desktop_file); + folder->desktop_file = NULL; + + emit_monitor (folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; + } else if (entry->type == ENTRY_FOLDER) { + return GNOME_VFS_ERROR_IS_DIRECTORY; + } else if (the_folder == NULL) { + return GNOME_VFS_ERROR_NOT_FOUND; + } + + G_LOCK (vfolder_lock); + + the_folder->entries = g_slist_remove (the_folder->entries, + entry); + entry_unref (entry); + + remove_file (the_folder, vuri.file); + + emit_monitor (the_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + + /* evil, we must remove this from the unallocated folders as well + * so that it magically doesn't appear there. But it's not so simple. + * We only want to remove it if it isn't in that folder already. */ + for (li = info->unallocated_folders; + li != NULL; + li = li->next) { + Folder *folder = li->data; + GSList *l; + + /* This is actually really evil since ensuring + * an unallocated folder clears all other unallocated + * folders in it's wake. I'm not sure it's worth + * optimizing however */ + ensure_folder_unlocked (info, folder, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + l = g_slist_find (folder->entries, entry); + if (l == NULL) { + remove_file (folder, vuri.file); + } + } + + emit_file_deleted_monitor (info, entry, the_folder); + + /* FIXME: if this was a user file and this is the only + * reference to it, unlink it. */ + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_check_same_fs (GnomeVFSMethod *method, + GnomeVFSURI *source_uri, + GnomeVFSURI *target_uri, + gboolean *same_fs_return, + GnomeVFSContext *context) +{ + VFolderURI source_vuri, target_vuri; + + *same_fs_return = FALSE; + + VFOLDER_URI_PARSE (source_uri, &source_vuri); + VFOLDER_URI_PARSE (target_uri, &target_vuri); + + if (strcmp (source_vuri.scheme, target_vuri.scheme) != 0 || + source_vuri.is_all_scheme != target_vuri.is_all_scheme) + *same_fs_return = FALSE; + else + *same_fs_return = TRUE; + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_set_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + const GnomeVFSFileInfo *info, + GnomeVFSSetFileInfoMask mask, + GnomeVFSContext *context) +{ + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + if (vuri.file == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + if (mask & GNOME_VFS_SET_FILE_INFO_NAME) { + GnomeVFSResult result = GNOME_VFS_OK; + char *dirname = gnome_vfs_uri_extract_dirname (uri); + GnomeVFSURI *new_uri = gnome_vfs_uri_dup (uri); + + G_LOCK (vfolder_lock); + g_free (new_uri->text); + new_uri->text = g_build_path ("/", dirname, info->name, NULL); + G_UNLOCK (vfolder_lock); + + result = do_move (method, + uri, + new_uri, + FALSE /* force_replace */, + context); + + g_free (dirname); + gnome_vfs_uri_unref (new_uri); + return result; + } else { + /* We don't support setting any of this other permission, + * times and all that voodoo */ + return GNOME_VFS_ERROR_NOT_SUPPORTED; + } +} + +static GnomeVFSResult +do_monitor_add (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle_return, + GnomeVFSURI *uri, + GnomeVFSMonitorType monitor_type) +{ + VFolderInfo *info; + VFolderURI vuri; + GnomeVFSResult result; + Folder *folder; + Entry *entry; + GnomeVFSURI *file_uri; + FileMonitorHandle *handle; + gboolean is_directory_file; + + VFOLDER_URI_PARSE (uri, &vuri); + + info = get_vfolder_info (vuri.scheme, &result, NULL); + if (info == NULL) + return result; + + if (monitor_type == GNOME_VFS_MONITOR_DIRECTORY) { + G_LOCK (vfolder_lock); + + folder = resolve_folder (info, + vuri.path, + FALSE /* ignore_basename */, + &result, + NULL); + + handle = g_new0 (FileMonitorHandle, 1); + handle->refcount = 2; + handle->uri = gnome_vfs_uri_dup (uri); + handle->dir_monitor = TRUE; + handle->handle = NULL; + handle->filename = NULL; + + if (folder == NULL) { + handle->exists = FALSE; + info->free_folder_monitors = + g_slist_prepend (info->free_folder_monitors, + handle); + } else { + handle->exists = TRUE; + ((Entry *)folder)->monitors = + g_slist_prepend (((Entry *)folder)->monitors, + handle); + } + + info->folder_monitors = + g_slist_prepend (info->folder_monitors, handle); + + G_UNLOCK (vfolder_lock); + + *method_handle_return = (GnomeVFSMethodHandle *) handle; + + return GNOME_VFS_OK; + } else { + /* These can't be very nice FILE names */ + if (vuri.file == NULL || + vuri.ends_in_slash) + return GNOME_VFS_ERROR_INVALID_URI; + + G_LOCK (vfolder_lock); + file_uri = desktop_uri_to_file_uri (info, + &vuri, + &entry, + &is_directory_file, + NULL /* the_folder */, + FALSE, + &result, + NULL); + + handle = g_new0 (FileMonitorHandle, 1); + handle->refcount = 2; + handle->uri = gnome_vfs_uri_dup (uri); + handle->dir_monitor = FALSE; + handle->handle = NULL; + handle->filename = g_strdup (vuri.file); + handle->is_directory_file = is_directory_file; + + info->file_monitors = + g_slist_prepend (info->file_monitors, handle); + + + if (file_uri == NULL) { + handle->exists = FALSE; + info->free_file_monitors = + g_slist_prepend (info->free_file_monitors, + handle); + } else { + char *uri_string = gnome_vfs_uri_to_string (file_uri, 0); + handle->exists = TRUE; + gnome_vfs_monitor_add (&(handle->handle), + uri_string, + GNOME_VFS_MONITOR_FILE, + file_monitor, + handle); + g_free (uri_string); + + entry->monitors = g_slist_prepend (entry->monitors, + handle); + gnome_vfs_uri_unref (file_uri); + } + + *method_handle_return = (GnomeVFSMethodHandle *) handle; + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; + } +} + +static GnomeVFSResult +do_monitor_cancel (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle) +{ + FileMonitorHandle *handle; + VFolderInfo *info; + VFolderURI vuri; + GnomeVFSResult result; + Folder *folder; + GSList *li; + + handle = (FileMonitorHandle *)method_handle; + + /* FIXME: is this correct? */ + if (method_handle == NULL) + return GNOME_VFS_OK; + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + info = get_vfolder_info (vuri.scheme, &result, NULL); + if (info == NULL) + return result; + + if (handle->dir_monitor) { + G_LOCK (vfolder_lock); + + folder = resolve_folder (info, + vuri.path, + FALSE /* ignore_basename */, + &result, + NULL); + + for (li = info->folder_monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + if (h != handle) + continue; + info->folder_monitors = g_slist_delete_link + (info->folder_monitors, li); + file_monitor_handle_unref_unlocked (h); + break; + } + + if (folder == NULL) { + for (li = info->free_folder_monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *h = li->data; + if (h != handle) + continue; + info->free_folder_monitors = g_slist_delete_link + (info->free_folder_monitors, li); + file_monitor_handle_unref_unlocked (h); + break; + } + } else { + for (li = ((Entry *)folder)->monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *h = li->data; + if (h != handle) + continue; + ((Entry *)folder)->monitors = + g_slist_delete_link + (((Entry *)folder)->monitors, li); + file_monitor_handle_unref_unlocked (h); + break; + } + } + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; + } else { + G_LOCK (vfolder_lock); + + for (li = info->file_monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + if (h != handle) + continue; + info->file_monitors = g_slist_delete_link + (info->file_monitors, li); + file_monitor_handle_unref_unlocked (h); + break; + } + + for (li = info->free_file_monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *h = li->data; + if (h != handle) + continue; + info->free_file_monitors = g_slist_delete_link + (info->free_file_monitors, li); + file_monitor_handle_unref_unlocked (h); + break; + } + + for (li = info->entries; li != NULL; li = li->next) { + Entry *e = li->data; + GSList *link = g_slist_find (e->monitors, handle); + + if (link == NULL) + continue; + link->data = NULL; + e->monitors = g_slist_delete_link (e->monitors, link); + + file_monitor_handle_unref_unlocked (handle); + break; + } + + G_UNLOCK (vfolder_lock); + + /* Note: last unref of our monitor will cancel the + * underlying handle */ + + return GNOME_VFS_OK; + } +} + + +/* gnome-vfs bureaucracy */ + +static GnomeVFSMethod method = { + sizeof (GnomeVFSMethod), + do_open, + NULL, /* do_create, */ + do_close, + do_read, + NULL, /* do_write, */ + do_seek, + do_tell, + NULL, /* do_truncate_handle, */ + do_open_directory, + do_close_directory, + do_read_directory, + do_get_file_info, + do_get_file_info_from_handle, + do_is_local, + NULL, /* do_make_directory, */ + NULL, /* do_remove_directory, */ + NULL, /* do_move, */ + NULL, /* do_unlink, */ + do_check_same_fs, + NULL, /* do_set_file_info, */ + NULL, /* do_truncate, */ + NULL /* find_directory */, + NULL /* create_symbolic_link */, + do_monitor_add, + do_monitor_cancel +}; + +GnomeVFSMethod * +vfs_module_init (const char *method_name, + const char *args) +{ + parent_method = gnome_vfs_method_get ("file"); + + if (parent_method == NULL) { + g_error ("Could not find 'file' method for gnome-vfs"); + return NULL; + } + + return &method; +} + +void +vfs_module_shutdown (GnomeVFSMethod *method) +{ + if (infos == NULL) + return; + + g_hash_table_destroy (infos); + infos = NULL; +} diff --git a/modules/vfolder-desktop-method.c.newstat b/modules/vfolder-desktop-method.c.newstat new file mode 100644 index 0000000..4344fba --- /dev/null +++ b/modules/vfolder-desktop-method.c.newstat @@ -0,0 +1,6129 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: 8; c-basic-offset: 8 -*- */ + +/* vfolder-desktop-method.c + + Copyright (C) 2001 Red Hat, Inc. + Copyright (C) 2001 The Dark Prince + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/* URI scheme for reading the "applications:" vfolder and other + * vfolder schemes. Lots of code stolen from the original desktop + * reading URI scheme. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +/* Debugging foo: */ +/*#define D(x) x */ +#define D(x) ; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#define DOT_GNOME ".gnome2" + +typedef struct _VFolderInfo VFolderInfo; +typedef struct _Query Query; +typedef struct _QueryKeyword QueryKeyword; +typedef struct _QueryFilename QueryFilename; +typedef struct _Entry Entry; +typedef struct _Folder Folder; +typedef struct _EntryFile EntryFile; +typedef struct _Keyword Keyword; +typedef struct _FileMonitorHandle FileMonitorHandle; +typedef struct _StatLoc StatLoc; +typedef struct _VFolderURI VFolderURI; + +/* TODO before 2.0: */ +/* FIXME: also check/monitor desktop_dirs like we do the vfolder + * file and the item dirs */ +/* FIXME: check if thread locks are not completely on crack which + * is likely given my experience with threads */ +/* FIXME: use filename locking, currently we are full of races if + * multiple processes write to this filesystem */ +/* FIXME: implement monitors */ + +/* TODO for later (star trek future): */ +/* FIXME: Maybe when chaining to file:, we should call the gnome-vfs wrapper + * functions, instead of the file: methods directly. */ +/* FIXME: related to the above: we should support things being on non + * file: filesystems. Such as having the vfolder info file on http + * somewhere or some such nonsense :) */ + +static GnomeVFSMethod *parent_method = NULL; + +static GHashTable *infos = NULL; + +/* Note: I have no clue about how to write thread safe code and this + * is my first attempt, so it's probably wrong + * -George */ +G_LOCK_DEFINE_STATIC (vfolder_lock); + +/* Note: all keywords are quarks */ +/* Note: basenames are unique */ + +#define UNSUPPORTED_INFO_FIELDS (GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS | \ + GNOME_VFS_FILE_INFO_FIELDS_DEVICE | \ + GNOME_VFS_FILE_INFO_FIELDS_INODE | \ + GNOME_VFS_FILE_INFO_FIELDS_LINK_COUNT | \ + GNOME_VFS_FILE_INFO_FIELDS_ATIME) + + +enum { + QUERY_OR, + QUERY_AND, + QUERY_KEYWORD, + QUERY_FILENAME +}; + +struct _Query { + int type; + gboolean not; + GSList *queries; +}; + +struct _QueryKeyword { + int type; + gboolean not; + GQuark keyword; +}; + +struct _QueryFilename { + int type; + gboolean not; + char *filename; +}; + +enum { + ENTRY_FILE, + ENTRY_FOLDER +}; + +struct _Entry { + int type; + int refcount; + int alloc; /* not really useful for folders, + but oh well, whatever. It's the number + of times this is queried in some directory, + used for the Unallocated query type */ + char *name; + + GSList *monitors; +}; + +struct _EntryFile { + Entry entry; + + char *filename; + gboolean per_user; + GSList *keywords; + + gboolean implicit_keywords; /* the keywords were added by us */ +}; + +struct _Folder { + Entry entry; + + Folder *parent; + + char *desktop_file; /* the .directory file */ + + Query *query; + + /* The following is for per file + * access */ + /* excluded by filename */ + GHashTable *excludes; + /* included by filename */ + GSList *includes; + GHashTable *includes_ht; + + GSList *subfolders; + + /* Some flags */ + gboolean read_only; + gboolean dont_show_if_empty; + gboolean only_unallocated; /* include only unallocated items */ + + /* lazily done, will run query only when it + * needs to */ + gboolean up_to_date; + gboolean sorted; + GSList *entries; +}; + +struct _StatLoc { + time_t ctime; + time_t last_stat; + gboolean trigger_next; /* if true, next check will fail */ + char name[1]; /* the structure will be long enough to + fit name */ +}; + +struct _VFolderInfo { + char *scheme; + + char *filename; + char *user_filename; + time_t user_filename_last_write; + char *desktop_dir; /* directory with .directorys */ + char *user_desktop_dir; /* directory with .directorys */ + gboolean user_file_active; /* if using user_filename and + not filename */ + + GSList *item_dirs; + char *user_item_dir; /* dir where user changes to + items are stored */ + + /* old style dirs to merge in */ + GSList *merge_dirs; + + /* if entries are valid, else + * they need to be (re)read */ + gboolean entries_valid; + + GSList *entries; + + /* entry hash by basename */ + GHashTable *entries_ht; + + /* The root folder */ + Folder *root; + + /* The unallocated folders, the folder which only + * include unallocated items */ + GSList *unallocated_folders; + + /* some flags */ + gboolean read_only; + + gboolean dirty; + + int inhibit_write; + + /* change monitoring stuff */ + GnomeVFSMonitorHandle *filename_monitor; + GnomeVFSMonitorHandle *user_filename_monitor; + + /* stat locations (in case we aren't monitoring) */ + StatLoc *filename_statloc; + StatLoc *user_filename_statloc; + + /* for .directory dirs */ + /* FIXME: */GnomeVFSMonitorHandle *desktop_dir_monitor; + /* FIXME: */GnomeVFSMonitorHandle *user_desktop_dir_monitor; + + /* stat locations (in case we aren't monitoring) */ + /* FIXME: */StatLoc *desktop_dir_statloc; + /* FIXME: */StatLoc *user_desktop_dir_statloc; + + /* FIXME: */GSList *file_monitors; /* FileMonitorHandle */ + /* FIXME: */GSList *free_file_monitors; /* FileMonitorHandle */ + GSList *folder_monitors; /* FileMonitorHandle */ + GSList *free_folder_monitors; /* FileMonitorHandle */ + + GSList *item_dir_monitors; /* GnomeVFSMonitorHandle */ + + /* item dirs to stat */ + GSList *stat_dirs; + + /* ctime for folders */ + time_t modification_time; + + guint reread_queue; +}; + +struct _FileMonitorHandle { + int refcount; + gboolean exists; + gboolean dir_monitor; /* TRUE if dir, FALSE if file */ + GnomeVFSURI *uri; + GnomeVFSMonitorHandle *handle; /* A real handle if we're monitoring + an actual file here, or NULL */ + char *filename; /* Just the basename, used in the free_file_list */ + gboolean is_directory_file; +}; + +struct _VFolderURI { + const gchar *scheme; + gboolean is_all_scheme; + gboolean ends_in_slash; + gchar *path; + gchar *file; + GnomeVFSURI *uri; +}; + + +static Entry * entry_ref (Entry *entry); +static Entry * entry_ref_alloc (Entry *entry); +static void entry_unref (Entry *entry); +static void entry_unref_dealloc (Entry *entry); +static void query_destroy (Query *query); +static void ensure_folder (VFolderInfo *info, + Folder *folder, + gboolean subfolders, + Folder *except, + gboolean ignore_unallocated); +static void ensure_folder_unlocked (VFolderInfo *info, + Folder *folder, + gboolean subfolders, + Folder *except, + gboolean ignore_unallocated); +/* An EVIL function for quick reading of .desktop files, + * only reads in one or two keys, but that's ALL we need */ +static void readitem_entry (const char *filename, + const char *key1, + char **result1, + const char *key2, + char **result2); +static gboolean vfolder_info_reload (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context, + gboolean force_read_items); +static gboolean vfolder_info_reload_unlocked (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context, + gboolean force_read_items); +static void invalidate_folder_subfolders (Folder *folder, + gboolean lock_taken); +static Folder * resolve_folder (VFolderInfo *info, + const char *path, + gboolean ignore_basename, + GnomeVFSResult *result, + GnomeVFSContext *context); +static gboolean vfolder_info_read_items (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context); + +/* assumes vuri->path already set */ +static gboolean +vfolder_uri_parse_internal (GnomeVFSURI *uri, VFolderURI *vuri) +{ + vuri->scheme = (gchar *) gnome_vfs_uri_get_scheme (uri); + + vuri->ends_in_slash = FALSE; + + if (strncmp (vuri->scheme, "all-", strlen ("all-")) == 0) { + vuri->scheme += strlen ("all-"); + vuri->is_all_scheme = TRUE; + } else + vuri->is_all_scheme = FALSE; + + if (vuri->path != NULL) { + int last_slash = strlen (vuri->path) - 1; + char *first; + + /* Note: This handling of paths is somewhat evil, may need a + * bit of a rework */ + + /* kill leading slashes, that is make sure there is + * only one */ + for (first = vuri->path; *first == '/'; first++) + ; + if (first != vuri->path) { + first--; + vuri->path = first; + } + + /* kill trailing slashes (leave first if all slashes) */ + while (last_slash > 0 && vuri->path [last_slash] == '/') { + vuri->path [last_slash--] = '\0'; + vuri->ends_in_slash = TRUE; + } + + /* get basename start */ + while (last_slash >= 0 && vuri->path [last_slash] != '/') + last_slash--; + + if (last_slash > -1) + vuri->file = vuri->path + last_slash + 1; + else + vuri->file = vuri->path; + + if (vuri->file[0] == '\0' && + strcmp (vuri->path, "/") == 0) { + vuri->file = NULL; + } + } else { + vuri->ends_in_slash = TRUE; + vuri->path = "/"; + vuri->file = NULL; + } + + vuri->uri = uri; + + return TRUE; +} + +#define VFOLDER_URI_PARSE(_uri, _vuri) { \ + gchar *path; \ + path = gnome_vfs_unescape_string ((_uri)->text, G_DIR_SEPARATOR_S); \ + if (path != NULL) { \ + (_vuri)->path = g_alloca (strlen (path) + 1); \ + strcpy ((_vuri)->path, path); \ + g_free (path); \ + } else { \ + (_vuri)->path = NULL; \ + } \ + vfolder_uri_parse_internal ((_uri), (_vuri)); \ +} + +static FileMonitorHandle * +file_monitor_handle_ref_unlocked (FileMonitorHandle *h) +{ + h->refcount ++; + return h; +} + +static void +file_monitor_handle_unref_unlocked (FileMonitorHandle *h) +{ + h->refcount --; + if (h->refcount == 0) { + gnome_vfs_uri_unref (h->uri); + h->uri = NULL; + + g_free (h->filename); + h->filename = NULL; + + if (h->handle != NULL) { + gnome_vfs_monitor_cancel (h->handle); + h->handle = NULL; + } + } +} + +/* This includes the .directory files */ +static void +emit_monitor (Folder *folder, int type) +{ + GSList *li; + for (li = ((Entry *)folder)->monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *handle = li->data; + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *) handle, + handle->uri, type); + } +} + +static void +emit_file_deleted_monitor (VFolderInfo *info, Entry *entry, Folder *folder) +{ + GSList *li; + for (li = entry->monitors; + li != NULL; + li = li->next) { + VFolderURI vuri; + Folder *f; + GnomeVFSResult result; + FileMonitorHandle *handle = li->data; + + /* Evil! EVIL URI PARSING. this will eat a lot of + * stack if we have lots of monitors */ + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + f = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + + if (f == folder) + gnome_vfs_monitor_callback + ((GnomeVFSMethodHandle *) handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_DELETED); + } +} + +static void +emit_and_delete_monitor (VFolderInfo *info, Folder *folder) +{ + GSList *li; + for (li = ((Entry *)folder)->monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *handle = li->data; + li->data = NULL; + + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *) handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_DELETED); + + if (handle->dir_monitor) + info->free_folder_monitors = + g_slist_prepend (info->free_folder_monitors, + handle); + else + info->free_file_monitors = + g_slist_prepend (info->free_file_monitors, + handle); + } + g_slist_free (((Entry *)folder)->monitors); + ((Entry *)folder)->monitors = NULL; +} + +static gboolean +check_ext (const char *name, const char *ext_check) +{ + const char *ext; + + ext = strrchr (name, '.'); + if (ext == NULL || + strcmp (ext, ext_check) != 0) + return FALSE; + else + return TRUE; +} + +static StatLoc * +bake_statloc (const char *name, + time_t curtime) +{ + struct stat s; + StatLoc *sl = NULL; + if (stat (name, &s) != 0) { + if (errno == ENOENT) { + sl = g_malloc0 (sizeof (StatLoc) + + strlen (name) + 1); + sl->last_stat = curtime; + sl->ctime = 0; + sl->trigger_next = FALSE; + strcpy (sl->name, name); + } + return sl; + } + + sl = g_malloc0 (sizeof (StatLoc) + + strlen (name) + 1); + sl->last_stat = curtime; + sl->ctime = s.st_ctime; + sl->trigger_next = FALSE; + strcpy (sl->name, name); + + return sl; +} + +/* returns FALSE if we must reread */ +static gboolean +check_statloc (StatLoc *sl, + time_t curtime) +{ + struct stat s; + + if (sl->trigger_next) { + sl->trigger_next = FALSE; + return FALSE; + } + + /* don't stat more then once every 3 seconds */ + if (curtime <= sl->last_stat + 3) + return TRUE; + + sl->last_stat = curtime; + + if (stat (sl->name, &s) != 0) { + if (errno == ENOENT && + sl->ctime == 0) + return TRUE; + else + return FALSE; + } + + if (sl->ctime == s.st_ctime) + return TRUE; + else + return FALSE; +} + +static gboolean +ensure_dir (const char *dirname, gboolean ignore_basename) +{ + char *parsed, *p; + + if (dirname == NULL) + return FALSE; + + if (ignore_basename) + parsed = g_path_get_dirname (dirname); + else + parsed = g_strdup (dirname); + + if (g_file_test (parsed, G_FILE_TEST_IS_DIR)) { + g_free (parsed); + return TRUE; + } + + p = strchr (parsed, '/'); + if (p == parsed) + p = strchr (p+1, '/'); + + while (p != NULL) { + *p = '\0'; + if (mkdir (parsed, 0700) != 0 && + errno != EEXIST) { + g_free (parsed); + return FALSE; + } + *p = '/'; + p = strchr (p+1, '/'); + } + + if (mkdir (parsed, 0700) != 0 && + errno != EEXIST) { + g_free (parsed); + return FALSE; + } + + g_free (parsed); + return TRUE; +} + +/* check for any directory name other then root */ +static gboolean +any_subdir (const char *dirname) +{ + const char *p; + if (dirname == NULL) + return FALSE; + + for (p = dirname; *p != '\0'; p++) { + if (*p != '/') { + return TRUE; + } + } + return FALSE; +} + +static void +destroy_entry_file (EntryFile *efile) +{ + if (efile == NULL) + return; + + g_free (efile->filename); + efile->filename = NULL; + + g_slist_free (efile->keywords); + efile->keywords = NULL; + + g_free (efile); +} + +static void +destroy_folder (Folder *folder) +{ + GSList *list; + + if (folder == NULL) + return; + + if (folder->parent != NULL) { + folder->parent->subfolders = + g_slist_remove (folder->parent->subfolders, folder); + folder->parent->up_to_date = FALSE; + folder->parent = NULL; + } + + g_free (folder->desktop_file); + folder->desktop_file = NULL; + + query_destroy (folder->query); + folder->query = NULL; + + if (folder->excludes != NULL) { + g_hash_table_destroy (folder->excludes); + folder->excludes = NULL; + } + + g_slist_foreach (folder->includes, (GFunc)g_free, NULL); + g_slist_free (folder->includes); + folder->includes = NULL; + if (folder->includes_ht != NULL) { + g_hash_table_destroy (folder->includes_ht); + folder->includes_ht = NULL; + } + + list = folder->subfolders; + folder->subfolders = NULL; + g_slist_foreach (list, (GFunc)entry_unref, NULL); + g_slist_free (list); + + list = folder->entries; + folder->entries = NULL; + g_slist_foreach (list, (GFunc)entry_unref, NULL); + g_slist_free (list); + + g_free (folder); +} + +static Entry * +entry_ref (Entry *entry) +{ + if (entry != NULL) + entry->refcount++; + return entry; +} + +static Entry * +entry_ref_alloc (Entry *entry) +{ + entry_ref (entry); + + if (entry != NULL) + entry->alloc++; + + return entry; +} + +static void +entry_unref (Entry *entry) +{ + if (entry == NULL) + return; + + entry->refcount--; + + if (entry->refcount == 0) { + g_free (entry->name); + entry->name = NULL; + + g_slist_foreach (entry->monitors, + (GFunc)file_monitor_handle_unref_unlocked, + NULL); + g_slist_free (entry->monitors); + entry->monitors = NULL; + + if (entry->type == ENTRY_FILE) + destroy_entry_file ((EntryFile *)entry); + else /* ENTRY_FOLDER */ + destroy_folder ((Folder *)entry); + } +} + +static void +entry_unref_dealloc (Entry *entry) +{ + if (entry != NULL) { + entry->alloc --; + entry_unref (entry); + } +} + +/* Handles ONLY files, not dirs */ +/* Also allocates the entries as well as refs them */ +static GSList * +alloc_entries_from_files (VFolderInfo *info, GSList *filenames) +{ + GSList *li; + GSList *files; + + files = NULL; + for (li = filenames; li != NULL; li = li->next) { + char *filename = li->data; + GSList *entry_list = g_hash_table_lookup (info->entries_ht, filename); + if (entry_list != NULL) + files = g_slist_prepend (files, + entry_ref_alloc (entry_list->data)); + } + + return files; +} + +static gboolean +matches_query (VFolderInfo *info, + Folder *folder, + EntryFile *efile, + Query *query) +{ + GSList *li; + + if (query == NULL) + return TRUE; + +#define INVERT_IF_NEEDED(val) (query->not ? !(val) : (val)) + switch (query->type) { + case QUERY_OR: + for (li = query->queries; li != NULL; li = li->next) { + Query *subquery = li->data; + if (matches_query (info, folder, efile, subquery)) + return INVERT_IF_NEEDED (TRUE); + } + return INVERT_IF_NEEDED (FALSE); + case QUERY_AND: + for (li = query->queries; li != NULL; li = li->next) { + Query *subquery = li->data; + if ( ! matches_query (info, folder, efile, subquery)) + return INVERT_IF_NEEDED (FALSE); + } + return INVERT_IF_NEEDED (TRUE); + case QUERY_KEYWORD: + { + QueryKeyword *qkeyword = (QueryKeyword *)query; + for (li = efile->keywords; li != NULL; li = li->next) { + GQuark keyword = GPOINTER_TO_INT (li->data); + if (keyword == qkeyword->keyword) + return INVERT_IF_NEEDED (TRUE); + } + return INVERT_IF_NEEDED (FALSE); + } + case QUERY_FILENAME: + { + QueryFilename *qfilename = (QueryFilename *)query; + if (strcmp (qfilename->filename, ((Entry *)efile)->name) == 0) { + return INVERT_IF_NEEDED (TRUE); + } else { + return INVERT_IF_NEEDED (FALSE); + } + } + } +#undef INVERT_IF_NEEDED + g_assert_not_reached (); + /* huh? */ + return FALSE; +} + +static void +dump_unallocated_folders (Folder *folder) +{ + GSList *li; + for (li = folder->subfolders; li != NULL; li = li->next) + dump_unallocated_folders (li->data); + + if (folder->only_unallocated && + folder->entries != NULL) { + g_slist_foreach (folder->entries, + (GFunc)entry_unref_dealloc, NULL); + g_slist_free (folder->entries); + folder->entries = NULL; + } +} + +/* Run query, allocs and refs the entries */ +static void +append_query (VFolderInfo *info, Folder *folder) +{ + GSList *li; + + if (folder->query == NULL && + ! folder->only_unallocated) + return; + + if (folder->only_unallocated) { + /* dump all folders that use unallocated + * items only. This sucks if you keep + * reading one and then another such + * folder, but oh well, life sucks for + * you then, but at least you get + * consistent results */ + dump_unallocated_folders (info->root); + + /* ensure all other folders, so that + * after this we know which ones are + * unallocated */ + ensure_folder_unlocked (info, + info->root, + TRUE /* subfolders */, + folder /* except */, + /* avoid infinite loops */ + TRUE /* ignore_unallocated */); + } + + for (li = info->entries; li != NULL; li = li->next) { + Entry *entry = li->data; + + if (/* if not file */ + entry->type != ENTRY_FILE || + /* if already included */ + (folder->includes_ht != NULL && + g_hash_table_lookup (folder->includes_ht, + entry->name) != NULL)) + continue; + + if (folder->only_unallocated && + entry->alloc != 0) + continue; + + if (matches_query (info, folder, (EntryFile *)entry, + folder->query)) + folder->entries = g_slist_prepend + (folder->entries, entry_ref_alloc (entry)); + } +} + +/* get entries in folder */ +/* FIXME: support cancellation here */ +static void +ensure_folder_unlocked (VFolderInfo *info, + Folder *folder, + gboolean subfolders, + Folder *except, + gboolean ignore_unallocated) +{ + if (subfolders) { + GSList *li; + for (li = folder->subfolders; li != NULL; li = li->next) + ensure_folder_unlocked (info, li->data, subfolders, + except, ignore_unallocated); + } + + if (except == folder) + return; + + if (ignore_unallocated && + folder->only_unallocated) + return; + + if (folder->up_to_date) + return; + + if (folder->entries != NULL) { + g_slist_foreach (folder->entries, + (GFunc)entry_unref_dealloc, NULL); + g_slist_free (folder->entries); + folder->entries = NULL; + } + + /* Include includes */ + folder->entries = alloc_entries_from_files (info, folder->includes); + + /* Run query */ + append_query (info, folder); + + /* We were prepending all this time */ + folder->entries = g_slist_reverse (folder->entries); + + /* Include subfolders */ + /* we always whack them onto the beginning */ + if (folder->subfolders != NULL) { + GSList *subfolders = g_slist_copy (folder->subfolders); + g_slist_foreach (subfolders, (GFunc)entry_ref_alloc, NULL); + folder->entries = g_slist_concat (subfolders, folder->entries); + } + + /* Exclude excludes */ + if (folder->excludes != NULL) { + GSList *li; + GSList *entries = folder->entries; + folder->entries = NULL; + for (li = entries; li != NULL; li = li->next) { + Entry *entry = li->data; + if (g_hash_table_lookup (folder->excludes, entry->name) == NULL) + folder->entries = g_slist_prepend (folder->entries, entry); + else + entry_unref_dealloc (entry); + + } + g_slist_free (entries); + + /* to preserve the Folders then everything else order */ + folder->entries = g_slist_reverse (folder->entries); + } + + folder->up_to_date = TRUE; + /* not yet sorted */ + folder->sorted = FALSE; +} + +static void +ensure_folder (VFolderInfo *info, + Folder *folder, + gboolean subfolders, + Folder *except, + gboolean ignore_unallocated) +{ + G_LOCK (vfolder_lock); + ensure_folder_unlocked (info, folder, subfolders, except, ignore_unallocated); + G_UNLOCK (vfolder_lock); +} + +static char * +get_directory_file_unlocked (VFolderInfo *info, Folder *folder) +{ + char *filename; + + /* FIXME: cache dir_files */ + + if (folder->desktop_file == NULL) + return NULL; + + if (folder->desktop_file[0] == G_DIR_SEPARATOR) + return g_strdup (folder->desktop_file); + + /* Now try the user directory */ + if (info->user_desktop_dir != NULL) { + filename = g_build_filename (info->user_desktop_dir, + folder->desktop_file, + NULL); + if (access (filename, F_OK) == 0) { + return filename; + } + + g_free (filename); + } + + filename = g_build_filename (info->desktop_dir, folder->desktop_file, NULL); + if (access (filename, F_OK) == 0) { + return filename; + } + g_free (filename); + + return NULL; +} + +static char * +get_directory_file (VFolderInfo *info, Folder *folder) +{ + char *ret; + + G_LOCK (vfolder_lock); + ret = get_directory_file_unlocked (info, folder); + G_UNLOCK (vfolder_lock); + + return ret; +} + +static GSList * +get_sort_order (VFolderInfo *info, Folder *folder) +{ + GSList *list; + char **parsed; + char *order; + int i; + char *filename; + + filename = get_directory_file_unlocked (info, folder); + if (filename == NULL) + return NULL; + + order = NULL; + readitem_entry (filename, + "SortOrder", + &order, + NULL, + NULL); + g_free (filename); + + if (order == NULL) + return NULL; + + parsed = g_strsplit (order, ":", -1); + + g_free (order); + + list = NULL; + for (i = 0; parsed[i] != NULL; i++) { + char *word = parsed[i]; + /* steal */ + parsed[i] = NULL; + /* ignore empty */ + if (word[0] == '\0') { + g_free (word); + continue; + } + list = g_slist_prepend (list, word); + } + /* we've stolen all strings from it */ + g_free (parsed); + + return g_slist_reverse (list); +} + +/* get entries in folder */ +static void +ensure_folder_sort (VFolderInfo *info, Folder *folder) +{ + GSList *li, *sort_order; + GSList *entries; + GHashTable *entry_hash; + + ensure_folder (info, folder, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + if (folder->sorted) + return; + + G_LOCK (vfolder_lock); + + sort_order = get_sort_order (info, folder); + if (sort_order == NULL) { + folder->sorted = TRUE; + G_UNLOCK (vfolder_lock); + return; + } + + entries = folder->entries; + folder->entries = NULL; + + entry_hash = g_hash_table_new (g_str_hash, g_str_equal); + for (li = entries; li != NULL; li = li->next) { + Entry *entry = li->data; + g_hash_table_insert (entry_hash, entry->name, li); + } + + for (li = sort_order; li != NULL; li = li->next) { + char *word = li->data; + GSList *entry_list; + Entry *entry; + + /* we kill the words here */ + li->data = NULL; + + entry_list = g_hash_table_lookup (entry_hash, word); + g_free (word); + + if (entry_list == NULL) + continue; + + entry = entry_list->data; + + entries = g_slist_delete_link (entries, entry_list); + + folder->entries = g_slist_prepend (folder->entries, + entry); + } + + /* put on those that weren't mentioned in the sort */ + for (li = entries; li != NULL; li = li->next) { + Entry *entry = li->data; + + folder->entries = g_slist_prepend (folder->entries, + entry); + } + + g_hash_table_destroy (entry_hash); + g_slist_free (entries); + g_slist_free (sort_order); + + folder->sorted = TRUE; + + G_UNLOCK (vfolder_lock); +} + +static EntryFile * +file_new (const char *name) +{ + EntryFile *efile = g_new0 (EntryFile, 1); + + efile->entry.type = ENTRY_FILE; + efile->entry.name = g_strdup (name); + efile->entry.refcount = 1; + + return efile; +} + +static Folder * +folder_new (const char *name) +{ + Folder *folder = g_new0 (Folder, 1); + + folder->entry.type = ENTRY_FOLDER; + folder->entry.name = g_strdup (name); + folder->entry.refcount = 1; + + return folder; +} + +static Query * +query_new (int type) +{ + Query *query; + + if (type == QUERY_KEYWORD) + query = (Query *)g_new0 (QueryKeyword, 1); + else if (type == QUERY_FILENAME) + query = (Query *)g_new0 (QueryFilename, 1); + else + query = g_new0 (Query, 1); + + query->type = type; + + return query; +} + +static void +query_destroy (Query *query) +{ + if (query == NULL) + return; + + if (query->type == QUERY_FILENAME) { + QueryFilename *qfile = (QueryFilename *)query; + g_free (qfile->filename); + qfile->filename = NULL; + } else if (query->type == QUERY_OR || + query->type == QUERY_AND) { + g_slist_foreach (query->queries, (GFunc)query_destroy, NULL); + g_slist_free (query->queries); + query->queries = NULL; + } + + g_free (query); +} + +static void +add_folder_monitor_unlocked (VFolderInfo *info, + FileMonitorHandle *handle) +{ + VFolderURI vuri; + GnomeVFSResult result; + Folder *folder; + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + file_monitor_handle_ref_unlocked (handle); + + info->folder_monitors = + g_slist_prepend (info->folder_monitors, handle); + + folder = resolve_folder (info, + vuri.path, + FALSE /* ignore_basename */, + &result, + NULL); + + if (folder == NULL) { + file_monitor_handle_ref_unlocked (handle); + + info->free_folder_monitors = + g_slist_prepend (info->free_folder_monitors, handle); + + if (handle->exists) { + handle->exists = FALSE; + gnome_vfs_monitor_callback + ((GnomeVFSMethodHandle *)handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_DELETED); + } + } else { + file_monitor_handle_ref_unlocked (handle); + + ((Entry *)folder)->monitors = + g_slist_prepend (((Entry *)folder)->monitors, handle); + + if ( ! handle->exists) { + handle->exists = TRUE; + gnome_vfs_monitor_callback + ((GnomeVFSMethodHandle *)handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_CREATED); + } + } + +} + +static inline void +invalidate_folder_T (Folder *folder) +{ + folder->up_to_date = FALSE; + + invalidate_folder_subfolders (folder, TRUE); +} + +static inline void +invalidate_folder (Folder *folder) +{ + G_LOCK (vfolder_lock); + folder->up_to_date = FALSE; + G_UNLOCK (vfolder_lock); + + invalidate_folder_subfolders (folder, FALSE); +} + +static void +invalidate_folder_subfolders (Folder *folder, + gboolean lock_taken) +{ + GSList *li; + + for (li = folder->subfolders; li != NULL; li = li->next) { + Folder *subfolder = li->data; + + if (!lock_taken) + invalidate_folder (subfolder); + else + invalidate_folder_T (subfolder); + } + + emit_monitor (folder, GNOME_VFS_MONITOR_EVENT_CHANGED); +} + +/* FIXME: this is UGLY!, we need to figure out when the file + * got finished changing! */ +static gboolean +reread_timeout (gpointer data) +{ + VFolderInfo *info = data; + gboolean force_read_items = info->file_monitors != NULL; + vfolder_info_reload (info, NULL, NULL, force_read_items); + return FALSE; +} + +static void +queue_reread_in (VFolderInfo *info, int msec) +{ + G_LOCK (vfolder_lock); + if (info->reread_queue != 0) + g_source_remove (info->reread_queue); + info->reread_queue = g_timeout_add (msec, reread_timeout, info); + G_UNLOCK (vfolder_lock); +} + +static void +vfolder_desktop_dir_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + /* FIXME: implement */ +} + +static void +vfolder_user_desktop_dir_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + /* FIXME: implement */ +} + +static void +vfolder_filename_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + VFolderInfo *info = user_data; + + if ((event_type == GNOME_VFS_MONITOR_EVENT_CREATED || + event_type == GNOME_VFS_MONITOR_EVENT_CHANGED) && + ! info->user_file_active) { + queue_reread_in (info, 200); + } else if (event_type == GNOME_VFS_MONITOR_EVENT_DELETED && + ! info->user_file_active) { + /* FIXME: is this correct? I mean now + * there probably isn't ANY vfolder file, so we + * init to default values really. I have no clue what's + * right here */ + vfolder_info_reload (info, NULL, NULL, + TRUE /* force read items */); + } +} + +static void +vfolder_user_filename_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + VFolderInfo *info = user_data; + + if ((event_type == GNOME_VFS_MONITOR_EVENT_CREATED || + event_type == GNOME_VFS_MONITOR_EVENT_CHANGED) && + info->user_file_active) { + struct stat s; + + /* see if this was really our own change */ + if (info->user_filename_last_write == time (NULL)) + return; + /* anal retentive */ + if (stat (info->user_filename, &s) == 0 && + info->user_filename_last_write == s.st_ctime) + return; + + queue_reread_in (info, 200); + } else if ((event_type == GNOME_VFS_MONITOR_EVENT_CREATED || + event_type == GNOME_VFS_MONITOR_EVENT_CHANGED) && + ! info->user_file_active) { + queue_reread_in (info, 200); + } else if (event_type == GNOME_VFS_MONITOR_EVENT_DELETED && + info->user_file_active) { + gboolean force_read_items = info->file_monitors != NULL; + vfolder_info_reload (info, NULL, NULL, force_read_items); + } +} + +static void +item_dir_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + VFolderInfo *info = user_data; + + if (event_type == GNOME_VFS_MONITOR_EVENT_CREATED || + event_type == GNOME_VFS_MONITOR_EVENT_CHANGED) { + /* first invalidate all folders */ + invalidate_folder (info->root); + /* second invalidate all entries */ + info->entries_valid = FALSE; + + if (info->file_monitors != NULL) { + GnomeVFSResult result; + GSList *li; + + /* Whack all monitors here! */ + for (li = info->file_monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *h = li->data; + if (h->handle != NULL) + gnome_vfs_monitor_cancel (h->handle); + h->handle = NULL; + } + + if (vfolder_info_read_items (info, &result, NULL)) { + info->entries_valid = TRUE; + } + } + } +} + +static gboolean +setup_dir_monitor (VFolderInfo *info, const char *dir, gboolean subdirs, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + GnomeVFSMonitorHandle *handle; + DIR *dh; + struct dirent *de; + char *uri; + + uri = gnome_vfs_get_uri_from_local_path (dir); + + if (gnome_vfs_monitor_add (&handle, + uri, + GNOME_VFS_MONITOR_DIRECTORY, + item_dir_monitor, + info) != GNOME_VFS_OK) { + StatLoc *sl = bake_statloc (dir, time (NULL)); + if (sl != NULL) + info->stat_dirs = g_slist_prepend (info->stat_dirs, sl); + g_free (uri); + return TRUE; + } + g_free (uri); + + if (gnome_vfs_context_check_cancellation (context)) { + gnome_vfs_monitor_cancel (handle); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + info->item_dir_monitors = + g_slist_prepend (info->item_dir_monitors, handle); + + if ( ! subdirs) + return TRUE; + + dh = opendir (dir); + if (dh == NULL) + return TRUE; + + while ((de = readdir (dh)) != NULL) { + char *full_path; + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + closedir (dh); + return FALSE; + } + + if (de->d_name[0] == '.') + continue; + + full_path = g_build_filename (dir, de->d_name, NULL); + if (g_file_test (full_path, G_FILE_TEST_IS_DIR)) { + if ( ! setup_dir_monitor (info, full_path, + TRUE /* subdirs */, + result, context)) { + closedir (dh); + return FALSE; + } + } + g_free (full_path); + } + + closedir (dh); + + return TRUE; +} + +static gboolean +monitor_setup (VFolderInfo *info, + gboolean setup_filenames, + gboolean setup_itemdirs, + gboolean setup_desktop_dirs, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + char *uri; + GSList *li; + + if (setup_filenames) { + uri = gnome_vfs_get_uri_from_local_path + (info->filename); + + if (gnome_vfs_monitor_add (&info->filename_monitor, + uri, + GNOME_VFS_MONITOR_FILE, + vfolder_filename_monitor, + info) != GNOME_VFS_OK) { + info->filename_monitor = NULL; + info->filename_statloc = bake_statloc (info->filename, + time (NULL)); + } + g_free (uri); + } + if (setup_filenames && + info->user_filename != NULL) { + uri = gnome_vfs_get_uri_from_local_path + (info->user_filename); + if (gnome_vfs_monitor_add (&info->user_filename_monitor, + uri, + GNOME_VFS_MONITOR_FILE, + vfolder_user_filename_monitor, + info) != GNOME_VFS_OK) { + info->user_filename_monitor = NULL; + info->user_filename_statloc = + bake_statloc (info->user_filename, + time (NULL)); + } + + g_free (uri); + } + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + if (setup_itemdirs) { + for (li = info->item_dirs; li != NULL; li = li->next) { + const char *dir = li->data; + if ( ! setup_dir_monitor (info, dir, + FALSE /* subdirs */, + result, context)) + return FALSE; + } + if (info->user_item_dir != NULL) { + if ( ! setup_dir_monitor (info, info->user_item_dir, + FALSE /* subdirs */, + result, context)) + return FALSE; + } + for (li = info->merge_dirs; li != NULL; li = li->next) { + const char *dir = li->data; + if ( ! setup_dir_monitor (info, dir, + TRUE /* subdirs */, + result, context)) + return FALSE; + } + } + + if (setup_desktop_dirs) { + uri = gnome_vfs_get_uri_from_local_path + (info->desktop_dir); + + if (gnome_vfs_monitor_add (&info->desktop_dir_monitor, + uri, + GNOME_VFS_MONITOR_FILE, + vfolder_desktop_dir_monitor, + info) != GNOME_VFS_OK) { + info->desktop_dir_monitor = NULL; + info->desktop_dir_statloc = + bake_statloc (info->desktop_dir, + time (NULL)); + } + g_free (uri); + } + if (setup_desktop_dirs && + info->user_desktop_dir != NULL) { + uri = gnome_vfs_get_uri_from_local_path + (info->user_desktop_dir); + if (gnome_vfs_monitor_add (&info->user_desktop_dir_monitor, + uri, + GNOME_VFS_MONITOR_DIRECTORY, + vfolder_user_desktop_dir_monitor, + info) != GNOME_VFS_OK) { + info->user_desktop_dir_monitor = NULL; + info->user_desktop_dir_statloc = + bake_statloc (info->user_desktop_dir, + time (NULL)); + } + + g_free (uri); + } + + return TRUE; +} + +static void +vfolder_info_init (VFolderInfo *info, const char *scheme) +{ + const char *path; + GSList *list; + + info->scheme = g_strdup (scheme); + + info->filename = g_strconcat (SYSCONFDIR, "/X11/desktop-menus/", + scheme, ".menu", + NULL); + info->user_filename = g_strconcat (g_get_home_dir (), + "/" DOT_GNOME "/vfolders/", + scheme, ".vfolder-info", + NULL); + info->desktop_dir = g_strconcat (SYSCONFDIR, + "/gnome-vfs-2.0/vfolders/", + NULL); + info->user_desktop_dir = g_strconcat (g_get_home_dir (), + "/" DOT_GNOME "/vfolders/", + NULL); + + /* Init the desktop paths */ + list = NULL; + list = g_slist_prepend (list, g_strdup ("/usr/share/applications/")); + if (strcmp ("/usr/share/applications/", DATADIR "/applications/") != 0) + list = g_slist_prepend (list, g_strdup (DATADIR "/applications/")); + path = g_getenv ("DESKTOP_FILE_PATH"); + if (path != NULL) { + int i; + char **ppath = g_strsplit (path, ":", -1); + for (i = 0; ppath[i] != NULL; i++) { + const char *dir = ppath[i]; + list = g_slist_prepend (list, g_strdup (dir)); + } + g_strfreev (ppath); + } + info->item_dirs = g_slist_reverse (list); + + info->user_item_dir = g_strconcat (g_get_home_dir (), + "/" DOT_GNOME "/vfolders/", + scheme, + NULL); + + info->entries_ht = g_hash_table_new (g_str_hash, g_str_equal); + + info->root = folder_new ("Root"); + + info->modification_time = time (NULL); +} + +static void +vfolder_info_free_internals_unlocked (VFolderInfo *info) +{ + if (info == NULL) + return; + + if (info->filename_monitor != NULL) { + gnome_vfs_monitor_cancel (info->filename_monitor); + info->filename_monitor = NULL; + } + + if (info->user_filename_monitor != NULL) { + gnome_vfs_monitor_cancel (info->user_filename_monitor); + info->user_filename_monitor = NULL; + } + + g_free (info->filename_statloc); + info->filename_statloc = NULL; + + g_free (info->user_filename_statloc); + info->user_filename_statloc = NULL; + + + if (info->desktop_dir_monitor != NULL) { + gnome_vfs_monitor_cancel (info->desktop_dir_monitor); + info->desktop_dir_monitor = NULL; + } + + if (info->user_desktop_dir_monitor != NULL) { + gnome_vfs_monitor_cancel (info->user_desktop_dir_monitor); + info->user_desktop_dir_monitor = NULL; + } + + g_free (info->desktop_dir_statloc); + info->desktop_dir_statloc = NULL; + + g_free (info->user_desktop_dir_statloc); + info->user_desktop_dir_statloc = NULL; + + + g_slist_foreach (info->item_dir_monitors, + (GFunc)gnome_vfs_monitor_cancel, NULL); + g_slist_free (info->item_dir_monitors); + info->item_dir_monitors = NULL; + + g_free (info->scheme); + info->scheme = NULL; + + g_free (info->filename); + info->filename = NULL; + + g_free (info->user_filename); + info->user_filename = NULL; + + g_free (info->desktop_dir); + info->desktop_dir = NULL; + + g_free (info->user_desktop_dir); + info->user_desktop_dir = NULL; + + g_slist_foreach (info->item_dirs, (GFunc)g_free, NULL); + g_slist_free (info->item_dirs); + info->item_dirs = NULL; + + g_free (info->user_item_dir); + info->user_item_dir = NULL; + + g_slist_foreach (info->merge_dirs, (GFunc)g_free, NULL); + g_slist_free (info->merge_dirs); + info->merge_dirs = NULL; + + g_slist_foreach (info->entries, (GFunc)entry_unref, NULL); + g_slist_free (info->entries); + info->entries = NULL; + + if (info->entries_ht != NULL) + g_hash_table_destroy (info->entries_ht); + info->entries_ht = NULL; + + g_slist_foreach (info->unallocated_folders, + (GFunc)entry_unref, + NULL); + g_slist_free (info->unallocated_folders); + info->unallocated_folders = NULL; + + entry_unref ((Entry *)info->root); + info->root = NULL; + + g_slist_foreach (info->stat_dirs, (GFunc)g_free, NULL); + g_slist_free (info->stat_dirs); + info->stat_dirs = NULL; + + g_slist_foreach (info->folder_monitors, + (GFunc)file_monitor_handle_unref_unlocked, NULL); + g_slist_free (info->folder_monitors); + info->folder_monitors = NULL; + + g_slist_foreach (info->free_folder_monitors, + (GFunc)file_monitor_handle_unref_unlocked, NULL); + g_slist_free (info->free_folder_monitors); + info->free_folder_monitors = NULL; + + g_slist_foreach (info->file_monitors, + (GFunc)file_monitor_handle_unref_unlocked, NULL); + g_slist_free (info->file_monitors); + info->file_monitors = NULL; + + g_slist_foreach (info->free_file_monitors, + (GFunc)file_monitor_handle_unref_unlocked, NULL); + g_slist_free (info->free_file_monitors); + info->free_file_monitors = NULL; + + if (info->reread_queue != 0) + g_source_remove (info->reread_queue); + info->reread_queue = 0; +} + +static void +vfolder_info_free_internals (VFolderInfo *info) +{ + G_LOCK (vfolder_lock); + vfolder_info_free_internals_unlocked (info); + G_UNLOCK (vfolder_lock); +} + +static void +vfolder_info_destroy (VFolderInfo *info) +{ + vfolder_info_free_internals (info); + g_free (info); +} + +static Query * +single_query_read (xmlNode *qnode) +{ + Query *query; + xmlNode *node; + + if (qnode->type != XML_ELEMENT_NODE || + qnode->name == NULL) + return NULL; + + query = NULL; + + if (g_ascii_strcasecmp (qnode->name, "Not") == 0 && + qnode->xmlChildrenNode != NULL) { + xmlNode *iter; + query = NULL; + for (iter = qnode->xmlChildrenNode; + iter != NULL && query == NULL; + iter = iter->next) + query = single_query_read (iter); + if (query != NULL) { + query->not = ! query->not; + } + return query; + } else if (g_ascii_strcasecmp (qnode->name, "Keyword") == 0) { + xmlChar *word = xmlNodeGetContent (qnode); + if (word != NULL) { + query = query_new (QUERY_KEYWORD); + ((QueryKeyword *)query)->keyword = + g_quark_from_string (word); + + xmlFree (word); + } + return query; + } else if (g_ascii_strcasecmp (qnode->name, "Filename") == 0) { + xmlChar *file = xmlNodeGetContent (qnode); + if (file != NULL) { + query = query_new (QUERY_FILENAME); + ((QueryFilename *)query)->filename = + g_strdup (file); + + xmlFree (file); + } + return query; + } else if (g_ascii_strcasecmp (qnode->name, "And") == 0) { + query = query_new (QUERY_AND); + } else if (g_ascii_strcasecmp (qnode->name, "Or") == 0) { + query = query_new (QUERY_OR); + } else { + /* We don't understand */ + return NULL; + } + + /* This must be OR or AND */ + g_assert (query != NULL); + + for (node = qnode->xmlChildrenNode; node != NULL; node = node->next) { + Query *new_query = single_query_read (node); + + if (new_query != NULL) + query->queries = g_slist_prepend + (query->queries, new_query); + } + + query->queries = g_slist_reverse (query->queries); + + return query; +} + +static void +add_or_set_query (Query **query, Query *new_query) +{ + if (*query == NULL) { + *query = new_query; + } else { + Query *old_query = *query; + *query = query_new (QUERY_OR); + (*query)->queries = + g_slist_append ((*query)->queries, old_query); + (*query)->queries = + g_slist_append ((*query)->queries, new_query); + } +} + +static Query * +query_read (xmlNode *qnode) +{ + Query *query; + xmlNode *node; + + query = NULL; + + for (node = qnode->xmlChildrenNode; node != NULL; node = node->next) { + if (node->type != XML_ELEMENT_NODE || + node->name == NULL) + continue; + + if (g_ascii_strcasecmp (node->name, "Not") == 0 && + node->xmlChildrenNode != NULL) { + xmlNode *iter; + Query *new_query = NULL; + + for (iter = node->xmlChildrenNode; + iter != NULL && new_query == NULL; + iter = iter->next) + new_query = single_query_read (iter); + if (new_query != NULL) { + new_query->not = ! new_query->not; + add_or_set_query (&query, new_query); + } + } else { + Query *new_query = single_query_read (node); + if (new_query != NULL) + add_or_set_query (&query, new_query); + } + } + + return query; +} + +static Folder * +folder_read (VFolderInfo *info, xmlNode *fnode) +{ + Folder *folder; + xmlNode *node; + + folder = folder_new (NULL); + + for (node = fnode->xmlChildrenNode; node != NULL; node = node->next) { + if (node->type != XML_ELEMENT_NODE || + node->name == NULL) + continue; + + if (g_ascii_strcasecmp (node->name, "Name") == 0) { + xmlChar *name = xmlNodeGetContent (node); + if (name != NULL) { + g_free (folder->entry.name); + folder->entry.name = g_strdup (name); + xmlFree (name); + } + } else if (g_ascii_strcasecmp (node->name, "Desktop") == 0) { + xmlChar *desktop = xmlNodeGetContent (node); + if (desktop != NULL) { + g_free (folder->desktop_file); + folder->desktop_file = g_strdup (desktop); + xmlFree (desktop); + } + } else if (g_ascii_strcasecmp (node->name, "Include") == 0) { + xmlChar *file = xmlNodeGetContent (node); + if (file != NULL) { + GSList *li; + char *str = g_strdup (file); + folder->includes = g_slist_prepend + (folder->includes, str); + if (folder->includes_ht == NULL) { + folder->includes_ht = + g_hash_table_new_full + (g_str_hash, + g_str_equal, + NULL, + NULL); + } + li = g_hash_table_lookup (folder->includes_ht, + file); + if (li != NULL) { + g_free (li->data); + /* Note: this will NOT change folder->includes + * pointer! */ + folder->includes = g_slist_delete_link + (folder->includes, li); + } + g_hash_table_replace (folder->includes_ht, + file, folder->includes); + xmlFree (file); + } + } else if (g_ascii_strcasecmp (node->name, "Exclude") == 0) { + xmlChar *file = xmlNodeGetContent (node); + if (file != NULL) { + char *s; + if (folder->excludes == NULL) { + folder->excludes = g_hash_table_new_full + (g_str_hash, + g_str_equal, + (GDestroyNotify)g_free, + NULL); + } + s = g_strdup (file); + g_hash_table_replace (folder->excludes, s, s); + xmlFree (file); + } + } else if (g_ascii_strcasecmp (node->name, "Query") == 0) { + Query *query; + + query = query_read (node); + + if (query != NULL) { + if (folder->query != NULL) + query_destroy (folder->query); + folder->query = query; + } + } else if (g_ascii_strcasecmp (node->name, "OnlyUnallocated") == 0) { + info->unallocated_folders = + g_slist_prepend (info->unallocated_folders, + (Folder *)entry_ref ((Entry *)folder)); + folder->only_unallocated = TRUE; + } else if (g_ascii_strcasecmp (node->name, "Folder") == 0) { + Folder *new_folder = folder_read (info, node); + if (new_folder != NULL) { + folder->subfolders = + g_slist_append (folder->subfolders, + new_folder); + new_folder->parent = folder; + } + } else if (g_ascii_strcasecmp (node->name, "ReadOnly") == 0) { + folder->read_only = TRUE; + } else if (g_ascii_strcasecmp (node->name, + "DontShowIfEmpty") == 0) { + folder->dont_show_if_empty = TRUE; + } + } + + /* Name is required */ + if (folder->entry.name == NULL) { + entry_unref ((Entry *)folder); + folder = NULL; + } + + folder->includes = g_slist_reverse (folder->includes); + + return folder; +} + +static char * +subst_home (const char *dir) +{ + if (dir[0] == '~') + return g_strconcat (g_get_home_dir (), + &dir[1], + NULL); + else + return g_strdup (dir); +} + +/* FORMAT looks like: + * + * + * /etc/X11/applnk + * + * /usr/share/applications + * + * /etc/X11/gnome/vfolders + * + * + * Root + * + * important.desktop + * + * + * + * SomeFolder + * + * + * Test_Folder + * + * Test_Folder.directory + * + * + * + * Application + * Game + * + * Clock + * + * + * somefile.desktop + * someotherfile.desktop + * yetanother.desktop + * + * + * + */ + +static gboolean +vfolder_info_read_info (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + xmlDoc *doc; + xmlNode *node; + gboolean got_a_vfolder_dir = FALSE; + + doc = NULL; + if (info->user_filename != NULL && + access (info->user_filename, F_OK) == 0) { + doc = xmlParseFile (info->user_filename); + if (doc != NULL) + info->user_file_active = TRUE; + } + if (doc == NULL && + access (info->filename, F_OK) == 0) + doc = xmlParseFile (info->filename); + + if (gnome_vfs_context_check_cancellation (context)) { + xmlFreeDoc(doc); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + if (doc == NULL + || doc->xmlRootNode == NULL + || doc->xmlRootNode->name == NULL + || g_ascii_strcasecmp (doc->xmlRootNode->name, "VFolderInfo") != 0) { + xmlFreeDoc(doc); + return TRUE; /* FIXME: really, shouldn't we error out? */ + } + + for (node = doc->xmlRootNode->xmlChildrenNode; node != NULL; node = node->next) { + if (node->type != XML_ELEMENT_NODE || + node->name == NULL) + continue; + + if (gnome_vfs_context_check_cancellation (context)) { + xmlFreeDoc(doc); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + if (g_ascii_strcasecmp (node->name, "MergeDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + if (dir != NULL) { + info->merge_dirs = g_slist_append (info->merge_dirs, + g_strdup (dir)); + xmlFree (dir); + } + } else if (g_ascii_strcasecmp (node->name, "ItemDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + if (dir != NULL) { + if ( ! got_a_vfolder_dir) { + g_slist_foreach (info->item_dirs, + (GFunc)g_free, NULL); + g_slist_free (info->item_dirs); + info->item_dirs = NULL; + } + got_a_vfolder_dir = TRUE; + info->item_dirs = g_slist_append (info->item_dirs, + g_strdup (dir)); + xmlFree (dir); + } + } else if (g_ascii_strcasecmp (node->name, "UserItemDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + if (dir != NULL) { + g_free (info->user_item_dir); + info->user_item_dir = subst_home (dir); + xmlFree (dir); + } + } else if (g_ascii_strcasecmp (node->name, "DesktopDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + if (dir != NULL) { + g_free (info->desktop_dir); + info->desktop_dir = g_strdup (dir); + xmlFree (dir); + } + } else if (g_ascii_strcasecmp (node->name, "UserDesktopDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + if (dir != NULL) { + g_free (info->user_desktop_dir); + info->user_desktop_dir = subst_home (dir); + xmlFree (dir); + } + } else if (g_ascii_strcasecmp (node->name, "Folder") == 0) { + Folder *folder = folder_read (info, node); + if (folder != NULL) { + if (info->root != NULL) + entry_unref ((Entry *)info->root); + info->root = folder; + } + } else if (g_ascii_strcasecmp (node->name, "ReadOnly") == 0) { + info->read_only = TRUE; + } + } + + xmlFreeDoc(doc); + + return TRUE; +} + +static void +add_xml_tree_from_query (xmlNode *parent, Query *query) +{ + xmlNode *real_parent; + + if (query->not) + real_parent = xmlNewChild (parent /* parent */, + NULL /* ns */, + "Not" /* name */, + NULL /* content */); + else + real_parent = parent; + + if (query->type == QUERY_KEYWORD) { + QueryKeyword *qkeyword = (QueryKeyword *)query; + const char *string = g_quark_to_string (qkeyword->keyword); + + xmlNewChild (real_parent /* parent */, + NULL /* ns */, + "Keyword" /* name */, + string /* content */); + } else if (query->type == QUERY_FILENAME) { + QueryFilename *qfilename = (QueryFilename *)query; + + xmlNewChild (real_parent /* parent */, + NULL /* ns */, + "Filename" /* name */, + qfilename->filename /* content */); + } else if (query->type == QUERY_OR || + query->type == QUERY_AND) { + xmlNode *node; + const char *name; + GSList *li; + + if (query->type == QUERY_OR) + name = "Or"; + else /* QUERY_AND */ + name = "And"; + + node = xmlNewChild (real_parent /* parent */, + NULL /* ns */, + name /* name */, + NULL /* content */); + + for (li = query->queries; li != NULL; li = li->next) { + Query *subquery = li->data; + add_xml_tree_from_query (node, subquery); + } + } else { + g_assert_not_reached (); + } +} + +static void +add_excludes_to_xml (gpointer key, gpointer value, gpointer user_data) +{ + const char *filename = key; + xmlNode *folder_node = user_data; + + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Exclude" /* name */, + filename /* content */); +} + +static void +add_xml_tree_from_folder (xmlNode *parent, Folder *folder) +{ + GSList *li; + xmlNode *folder_node; + + + folder_node = xmlNewChild (parent /* parent */, + NULL /* ns */, + "Folder" /* name */, + NULL /* content */); + + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Name" /* name */, + folder->entry.name /* content */); + + if (folder->desktop_file != NULL) { + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Desktop" /* name */, + folder->desktop_file /* content */); + } + + if (folder->read_only) + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "ReadOnly" /* name */, + NULL /* content */); + if (folder->dont_show_if_empty) + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "DontShowIfEmpty" /* name */, + NULL /* content */); + if (folder->only_unallocated) + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "OnlyUnallocated" /* name */, + NULL /* content */); + + for (li = folder->subfolders; li != NULL; li = li->next) { + Folder *subfolder = li->data; + add_xml_tree_from_folder (folder_node, subfolder); + } + + for (li = folder->includes; li != NULL; li = li->next) { + const char *include = li->data; + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Include" /* name */, + include /* content */); + } + + if (folder->excludes) { + g_hash_table_foreach (folder->excludes, + add_excludes_to_xml, + folder_node); + } + + if (folder->query != NULL) { + xmlNode *query_node; + query_node = xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Query" /* name */, + NULL /* content */); + + add_xml_tree_from_query (query_node, folder->query); + } +} + +static xmlDoc * +xml_tree_from_vfolder (VFolderInfo *info) +{ + xmlDoc *doc; + xmlNode *topnode; + GSList *li; + + doc = xmlNewDoc ("1.0"); + + topnode = xmlNewDocNode (doc /* doc */, + NULL /* ns */, + "VFolderInfo" /* name */, + NULL /* content */); + doc->xmlRootNode = topnode; + + for (li = info->merge_dirs; li != NULL; li = li->next) { + const char *merge_dir = li->data; + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "MergeDir" /* name */, + merge_dir /* content */); + } + + for (li = info->item_dirs; li != NULL; li = li->next) { + const char *item_dir = li->data; + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "ItemDir" /* name */, + item_dir /* content */); + } + + if (info->user_item_dir != NULL) { + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "UserItemDir" /* name */, + info->user_item_dir /* content */); + } + + if (info->desktop_dir != NULL) { + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "DesktopDir" /* name */, + info->desktop_dir /* content */); + } + + if (info->user_desktop_dir != NULL) { + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "UserDesktopDir" /* name */, + info->user_desktop_dir /* content */); + } + + if (info->root != NULL) + add_xml_tree_from_folder (topnode, info->root); + + return doc; +} + +/* FIXME: what to do about errors */ +static void +vfolder_info_write_user (VFolderInfo *info) +{ + xmlDoc *doc; + + if (info->inhibit_write > 0) + return; + + if (info->user_filename == NULL) + return; + + doc = xml_tree_from_vfolder (info); + if (doc == NULL) + return; + + /* FIXME: errors, anyone? */ + ensure_dir (info->user_filename, + TRUE /* ignore_basename */); + + xmlSaveFormatFile (info->user_filename, doc, TRUE /* format */); + /* not as good as a stat, but cheaper ... hmmm what is + * the likelyhood of this not being the same as ctime */ + info->user_filename_last_write = time (NULL); + + xmlFreeDoc(doc); + + info->user_file_active = TRUE; + info->dirty = FALSE; + + info->modification_time = time (NULL); +} + +/* An EVIL function for quick reading of .desktop files, + * only reads in one or two keys, but that's ALL we need */ +static void +readitem_entry (const char *filename, + const char *key1, + char **result1, + const char *key2, + char **result2) +{ + FILE *fp; + char buf[1024]; + int keylen1, keylen2; + + *result1 = NULL; + if (result2 != NULL) + *result2 = NULL; + + fp = fopen (filename, "r"); + + if (fp == NULL) + return; + + keylen1 = strlen (key1); + if (key2 != NULL) + keylen2 = strlen (key2); + else + keylen2 = -1; + + /* This is slightly wrong, it should only look + * at the correct section */ + while (fgets (buf, sizeof (buf), fp) != NULL) { + char *p; + int len; + int keylen; + char **result = NULL; + + /* check if it's one of the keys */ + if (strncmp (buf, key1, keylen1) == 0) { + result = result1; + keylen = keylen1; + } else if (keylen2 >= 0 && + strncmp (buf, key2, keylen2) == 0) { + result = result2; + keylen = keylen2; + } else { + continue; + } + + p = &buf[keylen]; + + /* still not our key */ + if (!(*p == '=' || *p == ' ')) { + continue; + } + do + p++; + while (*p == ' ' || *p == '='); + + /* get rid of trailing \n */ + len = strlen (p); + if (p[len-1] == '\n' || + p[len-1] == '\r') + p[len-1] = '\0'; + + *result = g_strdup (p); + + if (*result1 != NULL && + (result2 == NULL || *result2 != NULL)) + break; + } + + fclose (fp); +} + +static void +vfolder_info_insert_entry (VFolderInfo *info, EntryFile *efile) +{ + GSList *entry_list; + + entry_ref ((Entry *)efile); + + entry_list = g_hash_table_lookup (info->entries_ht, efile->entry.name); + + info->entries = g_slist_prepend (info->entries, efile); + /* The hash table contains the GSList pointer */ + g_hash_table_replace (info->entries_ht, efile->entry.name, + info->entries); + + if (entry_list != NULL) { + Entry *entry = entry_list->data; + info->entries = g_slist_delete_link (info->entries, + entry_list); + entry_unref (entry); + } +} + +static void +set_keywords (EntryFile *efile, const char *keywords) +{ + if (keywords != NULL) { + int i; + char **parsed = g_strsplit (keywords, ";", -1); + for (i = 0; parsed[i] != NULL; i++) { + GQuark quark; + const char *word = parsed[i]; + /* ignore empties (including end of list) */ + if (word[0] == '\0') + continue; + quark = g_quark_from_string (word); + efile->keywords = g_slist_prepend + (efile->keywords, + GINT_TO_POINTER (quark)); + } + g_strfreev (parsed); + } +} + +static EntryFile * +make_entry_file (const char *dir, const char *name) +{ + EntryFile *efile; + char *categories; + char *only_show_in; + char *filename; + int i; + + filename = g_build_filename (dir, name, NULL); + + readitem_entry (filename, + "Categories", + &categories, + "OnlyShowIn", + &only_show_in); + + if (only_show_in != NULL) { + gboolean show = FALSE; + char **parsed = g_strsplit (only_show_in, ";", -1); + for (i = 0; parsed[i] != NULL; i++) { + if (strcmp (parsed[i], "GNOME") == 0) { + show = TRUE; + break; + } + } + g_strfreev (parsed); + if ( ! show) { + g_free (filename); + g_free (only_show_in); + g_free (categories); + return NULL; + } + } + + efile = file_new (name); + efile->filename = filename; + + set_keywords (efile, categories); + + g_free (only_show_in); + g_free (categories); + + return efile; +} + +static gboolean +vfolder_info_read_items_from (VFolderInfo *info, + const char *item_dir, + gboolean per_user, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + DIR *dir; + struct dirent *de; + + dir = opendir (item_dir); + if (dir == NULL) + return TRUE; + + while ((de = readdir (dir)) != NULL) { + EntryFile *efile; + + if (gnome_vfs_context_check_cancellation (context)) { + closedir (dir); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + /* files MUST be called .desktop */ + if (de->d_name[0] == '.' || + ! check_ext (de->d_name, ".desktop")) + continue; + + efile = make_entry_file (item_dir, de->d_name); + if (efile == NULL) + continue; + + efile->per_user = per_user; + + vfolder_info_insert_entry (info, efile); + entry_unref ((Entry *)efile); + } + + closedir (dir); + + return TRUE; +} + +static gboolean +vfolder_info_read_items_merge (VFolderInfo *info, + const char *merge_dir, + const char *subdir, + GQuark inherited_keyword, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + DIR *dir; + struct dirent *de; + GQuark extra_keyword; + GQuark Application; + GQuark Merged; + GQuark inheritance; + gboolean pass_down_extra_keyword = TRUE; + + dir = opendir (merge_dir); + if (dir == NULL) + return TRUE; + + Application = g_quark_from_static_string ("Application"); + Merged = g_quark_from_static_string ("Merged"); + + /* FIXME: this should be a hash or something */ + extra_keyword = 0; + if (subdir == NULL) { + extra_keyword = g_quark_from_static_string ("Core"); + pass_down_extra_keyword = FALSE; + } else if (g_ascii_strcasecmp (subdir, "Development") == 0) + extra_keyword = g_quark_from_static_string ("Development"); + else if (g_ascii_strcasecmp (subdir, "Editors") == 0) + extra_keyword = g_quark_from_static_string ("TextEditor"); + else if (g_ascii_strcasecmp (subdir, "Games") == 0) + extra_keyword = g_quark_from_static_string ("Game"); + else if (g_ascii_strcasecmp (subdir, "Graphics") == 0) + extra_keyword = g_quark_from_static_string ("Graphics"); + else if (g_ascii_strcasecmp (subdir, "Internet") == 0) + extra_keyword = g_quark_from_static_string ("Network"); + else if (g_ascii_strcasecmp (subdir, "Multimedia") == 0) + extra_keyword = g_quark_from_static_string ("AudioVideo"); + else if (g_ascii_strcasecmp (subdir, "Office") == 0) + extra_keyword = g_quark_from_static_string ("Office"); + else if (g_ascii_strcasecmp (subdir, "Settings") == 0) + extra_keyword = g_quark_from_static_string ("Settings"); + else if (g_ascii_strcasecmp (subdir, "System") == 0) + extra_keyword = g_quark_from_static_string ("System"); + else if (g_ascii_strcasecmp (subdir, "Utilities") == 0) + extra_keyword = g_quark_from_static_string ("Utility"); + + while ((de = readdir (dir)) != NULL) { + EntryFile *efile; + + if (gnome_vfs_context_check_cancellation (context)) { + closedir (dir); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + /* ignore hidden */ + if (de->d_name[0] == '.') + continue; + + /* files MUST be called .desktop, so + * treat all others as dirs. If we're wrong, + * the open will fail, which is ok */ + if ( ! check_ext (de->d_name, ".desktop")) { + /* if this is a directory recurse */ + char *fullname = g_build_filename (merge_dir, de->d_name, NULL); + if ((pass_down_extra_keyword == TRUE) && (extra_keyword != 0)) { + inheritance = extra_keyword; + } else { + inheritance = inherited_keyword; + } + + if ( ! vfolder_info_read_items_merge (info, + fullname, + de->d_name, + inheritance, + result, + context)) { + g_free (fullname); + return FALSE; + } + g_free (fullname); + continue; + } + + /* FIXME: add some keywords about some known apps + * like gimp and whatnot, perhaps take these from the vfolder + * file or some such */ + + efile = make_entry_file (merge_dir, de->d_name); + if (efile == NULL) + continue; + + /* If no keywords set, then add the standard ones */ + if (efile->keywords == NULL) { + efile->keywords = g_slist_prepend + (efile->keywords, + GINT_TO_POINTER (Application)); + + efile->keywords = g_slist_prepend + (efile->keywords, + GINT_TO_POINTER (Merged)); + + if (inherited_keyword != 0) { + efile->keywords = g_slist_prepend + (efile->keywords, + GINT_TO_POINTER (inherited_keyword)); + } + + if (extra_keyword != 0) { + efile->keywords = g_slist_prepend + (efile->keywords, + GINT_TO_POINTER (extra_keyword)); + } + efile->implicit_keywords = TRUE; + } + + vfolder_info_insert_entry (info, efile); + entry_unref ((Entry *)efile); + } + + closedir (dir); + + return TRUE; +} + +static Entry * +find_entry (GSList *list, const char *name) +{ + GSList *li; + + for (li = list; li != NULL; li = li->next) { + Entry *entry = li->data; + if (strcmp (name, entry->name) == 0) + return entry; + } + return NULL; +} + +static void +file_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + FileMonitorHandle *h = user_data; + + /* proxy the event through if it is a changed event + * only */ + + if (event_type == GNOME_VFS_MONITOR_EVENT_CHANGED && + h->handle != NULL) + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *) h, + h->uri, event_type); +} + +static void +try_free_file_monitors_create_files_unlocked (VFolderInfo *info) +{ + GSList *li, *list; + + list = g_slist_copy (info->free_file_monitors); + + for (li = list; li != NULL; li = li->next) { + FileMonitorHandle *handle = li->data; + Entry *entry; + GnomeVFSResult result; + char *dirfile = NULL; + + if (handle->is_directory_file) { + VFolderURI vuri; + Folder *folder; + + /* Evil! EVIL URI PARSING. this will eat a lot of + * stack if we have lots of free monitors */ + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + folder = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + + if (folder == NULL) + continue; + + dirfile = get_directory_file_unlocked (info, folder); + if (dirfile == NULL) + continue; + + entry = (Entry *)folder; + } else { + VFolderURI vuri; + Folder *f; + GnomeVFSResult result; + + entry = NULL; + + /* Evil! EVIL URI PARSING. this will eat a lot of + * stack if we have lots of monitors */ + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + f = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + + if (f != NULL) { + ensure_folder_unlocked ( + info, f, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + entry = find_entry (f->entries, vuri.file); + } + + if (entry == NULL) + continue; + } + + info->free_file_monitors = + g_slist_remove (info->free_file_monitors, handle); + entry->monitors = + g_slist_prepend (entry->monitors, handle); + + handle->exists = TRUE; + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *)handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_CREATED); + + /* recreate a handle */ + if (handle->handle == NULL && + entry->type == ENTRY_FILE) { + EntryFile *efile = (EntryFile *)entry; + char *uri = gnome_vfs_get_uri_from_local_path + (efile->filename); + + gnome_vfs_monitor_add (&(handle->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + handle); + + g_free (uri); + } else if (handle->handle == NULL && + dirfile != NULL) { + char *uri = gnome_vfs_get_uri_from_local_path (dirfile); + + gnome_vfs_monitor_add (&(handle->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + handle); + + g_free (uri); + } + + g_free (dirfile); + } + + g_slist_free (list); +} + +static void /* unlocked */ +rescan_monitors (VFolderInfo *info) +{ + GSList *li; + + if (info->file_monitors == NULL) + return; + + for (li = info->file_monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + GnomeVFSResult result; + Entry *entry; + char *dirfile = NULL; + + /* these are handled below */ + if ( ! h->exists) + continue; + + if (h->is_directory_file) { + VFolderURI vuri; + Folder *folder; + + /* Evil! EVIL URI PARSING. this will eat a lot of + * stack if we have lots of monitors */ + + VFOLDER_URI_PARSE (h->uri, &vuri); + + folder = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + if (folder != NULL) + dirfile = get_directory_file_unlocked (info, + folder); + + if (dirfile == NULL) { + h->exists = FALSE; + gnome_vfs_monitor_callback + ((GnomeVFSMethodHandle *)h, + h->uri, + GNOME_VFS_MONITOR_EVENT_DELETED); + info->free_file_monitors = g_slist_prepend + (info->free_file_monitors, h); + file_monitor_handle_ref_unlocked (h); + /* it has been unreffed when the entry was + * whacked */ + continue; + } + + entry = (Entry *)folder; + } else { + VFolderURI vuri; + Folder *f; + GnomeVFSResult result; + + entry = NULL; + + /* Evil! EVIL URI PARSING. this will eat a lot of + * stack if we have lots of monitors */ + + VFOLDER_URI_PARSE (h->uri, &vuri); + + f = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + + if (f != NULL) { + ensure_folder_unlocked ( + info, f, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + entry = find_entry (f->entries, vuri.file); + } + + if (entry == NULL) { + h->exists = FALSE; + gnome_vfs_monitor_callback + ((GnomeVFSMethodHandle *)h, + h->uri, + GNOME_VFS_MONITOR_EVENT_DELETED); + info->free_file_monitors = g_slist_prepend + (info->free_file_monitors, h); + file_monitor_handle_ref_unlocked (h); + /* it has been unreffed when the entry was + * whacked */ + continue; + } + } + + /* recreate a handle */ + if (h->handle == NULL && + entry->type == ENTRY_FILE) { + EntryFile *efile = (EntryFile *)entry; + char *uri = gnome_vfs_get_uri_from_local_path + (efile->filename); + + gnome_vfs_monitor_add (&(h->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + h); + + g_free (uri); + } else if (h->handle == NULL && + dirfile != NULL) { + char *uri = gnome_vfs_get_uri_from_local_path (dirfile); + + gnome_vfs_monitor_add (&(h->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + h); + + g_free (uri); + } + + g_free (dirfile); + } + + try_free_file_monitors_create_files_unlocked (info); +} + +static gboolean /* unlocked */ +vfolder_info_read_items (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + GSList *li; + + /* First merge */ + for (li = info->merge_dirs; li != NULL; li = li->next) { + const char *merge_dir = li->data; + + if ( ! vfolder_info_read_items_merge (info, merge_dir, NULL, FALSE, + result, context)) + return FALSE; + } + + /* Then read the real thing (later overrides) */ + for (li = info->item_dirs; li != NULL; li = li->next) { + const char *item_dir = li->data; + + if ( ! vfolder_info_read_items_from (info, item_dir, + FALSE /* per_user */, + result, context)) + return FALSE; + } + + if (info->user_item_dir != NULL) { + if ( ! vfolder_info_read_items_from (info, + info->user_item_dir, + TRUE /* per_user */, + result, context)) + return FALSE; + } + + rescan_monitors (info); + + return TRUE; +} + +static gboolean +string_slist_equal (GSList *list1, GSList *list2) +{ + GSList *li1, *li2; + + for (li1 = list1, li2 = list2; + li1 != NULL && li2 != NULL; + li1 = li1->next, li2 = li2->next) { + const char *s1 = li1->data; + const char *s2 = li2->data; + if (strcmp (s1, s2) != 0) + return FALSE; + } + /* if both are not NULL, then lengths are + * different */ + if (li1 != li2) + return FALSE; + return TRUE; +} + +static gboolean +safe_string_same (const char *string1, const char *string2) +{ + if (string1 == string2 && + string1 == NULL) + return TRUE; + + if (string1 != NULL && string2 != NULL && + strcmp (string1, string2) == 0) + return TRUE; + + return FALSE; +} + +static gboolean +vfolder_info_item_dirs_same (VFolderInfo *info1, VFolderInfo *info2) +{ + if ( ! string_slist_equal (info1->item_dirs, + info2->item_dirs)) + return FALSE; + + if ( ! string_slist_equal (info1->merge_dirs, + info2->merge_dirs)) + return FALSE; + + if ( ! safe_string_same (info1->user_item_dir, + info2->user_item_dir)) + return FALSE; + + return TRUE; +} + +static gboolean +vfolder_info_reload_unlocked (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context, + gboolean force_read_items) +{ + VFolderInfo *newinfo; + gboolean setup_filenames; + gboolean setup_itemdirs; + GSList *li; + + /* FIXME: Hmmm, race, there is no locking YAIKES, + * we need filename locking for changes. eek, eek, eek */ + if (info->dirty) { + return TRUE; + } + + newinfo = g_new0 (VFolderInfo, 1); + vfolder_info_init (newinfo, info->scheme); + + g_free (newinfo->filename); + g_free (newinfo->user_filename); + newinfo->filename = g_strdup (info->filename); + newinfo->user_filename = g_strdup (info->user_filename); + + if (gnome_vfs_context_check_cancellation (context)) { + vfolder_info_destroy (newinfo); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + if ( ! vfolder_info_read_info (newinfo, result, context)) { + vfolder_info_destroy (newinfo); + return FALSE; + } + + /* FIXME: reload logic for 'desktop_dir' and + * 'user_desktop_dir' */ + + setup_itemdirs = TRUE; + + /* Validity of entries and item dirs and all that is unchanged */ + if (vfolder_info_item_dirs_same (info, newinfo)) { + newinfo->entries = info->entries; + info->entries = NULL; + newinfo->entries_ht = info->entries_ht; + info->entries_ht = NULL /* some places assume this + non-null, but we're only + going to destroy this */; + newinfo->entries_valid = info->entries_valid; + + /* move over the monitors/statlocs since those are valid */ + newinfo->item_dir_monitors = info->item_dir_monitors; + info->item_dir_monitors = NULL; + newinfo->stat_dirs = info->stat_dirs; + info->stat_dirs = NULL; + + /* No need to resetup dir monitors */ + setup_itemdirs = FALSE; + + /* No need to do anything with file monitors */ + } else { + /* Whack all monitors here! */ + for (li = info->file_monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + if (h->handle != NULL) + gnome_vfs_monitor_cancel (h->handle); + h->handle = NULL; + } + } + + setup_filenames = TRUE; + + if (safe_string_same (info->filename, newinfo->filename) && + safe_string_same (info->user_filename, newinfo->user_filename)) { + newinfo->user_filename_last_write = + info->user_filename_last_write; + + /* move over the monitors/statlocs since those are valid */ + newinfo->filename_monitor = info->filename_monitor; + info->filename_monitor = NULL; + newinfo->user_filename_monitor = info->user_filename_monitor; + info->user_filename_monitor = NULL; + + if (info->filename_statloc != NULL && + info->filename != NULL) + newinfo->filename_statloc = + bake_statloc (info->filename, + time (NULL)); + if (info->user_filename_statloc != NULL && + info->user_filename != NULL) + newinfo->user_filename_statloc = + bake_statloc (info->user_filename, + time (NULL)); + + /* No need to resetup filename monitors */ + setup_filenames = FALSE; + } + + /* Note: not cancellable anymore, since we've + * already started nibbling on the info structure, + * so we'd need to back things out or some such, + * too complex, so screw that */ + monitor_setup (info, + setup_filenames, + setup_itemdirs, + /* FIXME: setup_desktop_dirs */ TRUE, + NULL, NULL); + + for (li = info->folder_monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *handle = li->data; + li->data = NULL; + + add_folder_monitor_unlocked (newinfo, handle); + + file_monitor_handle_unref_unlocked (handle); + } + g_slist_free (info->folder_monitors); + info->folder_monitors = NULL; + + g_slist_foreach (info->free_folder_monitors, + (GFunc)file_monitor_handle_unref_unlocked, NULL); + g_slist_free (info->free_folder_monitors); + info->folder_monitors = NULL; + + /* we can just copy these for now, they will be readded + * and all the fun stuff will be done with them later */ + newinfo->file_monitors = info->file_monitors; + info->file_monitors = NULL; + newinfo->free_file_monitors = info->free_file_monitors; + info->free_file_monitors = NULL; + + /* emit changed on all folders, a bit drastic, but oh well, + * we also invalidate all folders at the same time, but that is + * irrelevant since they should all just be invalid to begin with */ + invalidate_folder_T (info->root); + + /* FIXME: make sure if this was enough, I think it was */ + + vfolder_info_free_internals_unlocked (info); + memcpy (info, newinfo, sizeof (VFolderInfo)); + g_free (newinfo); + + /* must rescan the monitors here */ + if (info->entries_valid) { + rescan_monitors (info); + } + + if ( ! info->entries_valid && + force_read_items) { + GnomeVFSResult res; + /* FIXME: I bet cancelation plays havoc with monitors, + * I'm not sure however */ + if (info->file_monitors != NULL) { + vfolder_info_read_items (info, &res, NULL); + } else { + if ( ! vfolder_info_read_items (info, result, context)) + return FALSE; + } + info->entries_valid = TRUE; + } + + return TRUE; +} + +static gboolean +vfolder_info_reload (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context, + gboolean force_read_items) +{ + G_LOCK (vfolder_lock); + if (vfolder_info_reload_unlocked (info, result, context, + force_read_items)) { + G_UNLOCK (vfolder_lock); + return TRUE; + } else { + G_UNLOCK (vfolder_lock); + return FALSE; + } +} + +static gboolean +vfolder_info_recheck (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + GSList *li; + time_t curtime = time (NULL); + gboolean reread = FALSE; + + if (info->filename_statloc != NULL && + ! check_statloc (info->filename_statloc, curtime)) { + if ( ! vfolder_info_reload_unlocked (info, result, context, + FALSE /* force read items */)) { + /* we have failed, make sure we fail + * next time too */ + info->filename_statloc->trigger_next = TRUE; + return FALSE; + } + reread = TRUE; + } + if ( ! reread && + info->user_filename_statloc != NULL && + ! check_statloc (info->user_filename_statloc, curtime)) { + if ( ! vfolder_info_reload_unlocked (info, result, context, + FALSE /* force read items */)) { + /* we have failed, make sure we fail + * next time too */ + info->user_filename_statloc->trigger_next = TRUE; + return FALSE; + } + reread = TRUE; + } + + if (info->entries_valid) { + for (li = info->stat_dirs; li != NULL; li = li->next) { + StatLoc *sl = li->data; + if ( ! check_statloc (sl, curtime)) { + info->entries_valid = FALSE; + break; + } + } + } + return TRUE; +} + +static VFolderInfo * +get_vfolder_info_unlocked (const char *scheme, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + VFolderInfo *info; + + if (infos != NULL && + (info = g_hash_table_lookup (infos, scheme)) != NULL) { + if ( ! vfolder_info_recheck (info, result, context)) { + return NULL; + } + if ( ! info->entries_valid) { + g_slist_foreach (info->entries, + (GFunc)entry_unref, NULL); + g_slist_free (info->entries); + info->entries = NULL; + + if (info->entries_ht != NULL) + g_hash_table_destroy (info->entries_ht); + info->entries_ht = g_hash_table_new (g_str_hash, + g_str_equal); + + if ( ! vfolder_info_read_items (info, + result, context)) { + info->entries_valid = FALSE; + return NULL; + } + + invalidate_folder_T (info->root); + + info->entries_valid = TRUE; + } + return info; + } + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if (infos == NULL) + infos = g_hash_table_new_full + (g_str_hash, g_str_equal, + (GDestroyNotify)g_free, + (GDestroyNotify)vfolder_info_destroy); + + info = g_new0 (VFolderInfo, 1); + vfolder_info_init (info, scheme); + + if (gnome_vfs_context_check_cancellation (context)) { + vfolder_info_destroy (info); + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if ( ! vfolder_info_read_info (info, result, context)) { + vfolder_info_destroy (info); + return NULL; + } + + if ( ! monitor_setup (info, + TRUE /* setup_filenames */, + TRUE /* setup_itemdirs */, + TRUE /* setup_desktop_dirs */, + result, context)) { + vfolder_info_destroy (info); + return NULL; + } + + g_hash_table_insert (infos, g_strdup (scheme), info); + + if ( ! vfolder_info_read_items (info, result, context)) { + info->entries_valid = FALSE; + return NULL; + } + info->entries_valid = TRUE; + + return info; +} + +static VFolderInfo * +get_vfolder_info (const char *scheme, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + VFolderInfo *info; + G_LOCK (vfolder_lock); + info = get_vfolder_info_unlocked (scheme, result, context); + G_UNLOCK (vfolder_lock); + return info; +} + + +static char * +keywords_to_string (GSList *keywords) +{ + GSList *li; + GString *str = g_string_new (NULL); + + for (li = keywords; li != NULL; li = li->next) { + GQuark word = GPOINTER_TO_INT (li->data); + g_string_append (str, g_quark_to_string (word)); + g_string_append_c (str, ';'); + } + + return g_string_free (str, FALSE); +} + +/* copy file and add keywords line */ +static gboolean +copy_file_with_keywords (const char *from, const char *to, GSList *keywords) +{ + FILE *fp; + FILE *wfp; + int wfd; + char buf[BUFSIZ]; + char *keyword_string; + + if ( ! ensure_dir (to, + TRUE /* ignore_basename */)) + return FALSE; + + wfd = open (to, O_CREAT | O_WRONLY | O_TRUNC, 0600); + if (wfd < 0) { + return FALSE; + } + + keyword_string = keywords_to_string (keywords); + + wfp = fdopen (wfd, "w"); + + fp = fopen (from, "r"); + if (fp != NULL) { + gboolean wrote_keywords = FALSE; + while (fgets (buf, sizeof (buf), fp) != NULL) { + fprintf (wfp, "%s", buf); + if ( ! wrote_keywords && + (strncmp (buf, "[Desktop Entry]", + strlen ("[Desktop Entry]")) == 0 || + strncmp (buf, "[KDE Desktop Entry]", + strlen ("[KDE Desktop Entry]")) == 0)) { + fprintf (wfp, "Categories=%s\n", + keyword_string); + wrote_keywords = TRUE; + } + } + + fclose (fp); + } else { + fprintf (wfp, "[Desktop Entry]\nCategories=%s\n", + keyword_string); + } + + /* FIXME: does this close wfd???? */ + fclose (wfp); + + close (wfd); + + g_free (keyword_string); + + return TRUE; +} + +static gboolean +copy_file (const char *from, const char *to) +{ + int fd; + int wfd; + + if ( ! ensure_dir (to, + TRUE /* ignore_basename */)) + return FALSE; + + wfd = open (to, O_CREAT | O_WRONLY | O_TRUNC, 0600); + if (wfd < 0) { + return FALSE; + } + + fd = open (from, O_RDONLY); + if (fd >= 0) { + char buf[1024]; + ssize_t n; + + while ((n = read (fd, buf, sizeof(buf))) > 0) { + write (wfd, buf, n); + } + + close (fd); + } + + close (wfd); + + return TRUE; +} + +static gboolean +make_file_private (VFolderInfo *info, EntryFile *efile) +{ + char *newfname; + Entry *entry = (Entry *)efile; + + if (efile->per_user) + return TRUE; + + /* this file already exists so whack its monitors */ + if (efile->filename != NULL) { + GSList *li; + + for (li = entry->monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + if (h->handle != NULL) + gnome_vfs_monitor_cancel (h->handle); + h->handle = NULL; + } + } + + newfname = g_build_filename (g_get_home_dir (), + DOT_GNOME, + "vfolders", + info->scheme, + efile->entry.name, + NULL); + + if (efile->implicit_keywords) { + if (efile->filename != NULL && + ! copy_file_with_keywords (efile->filename, + newfname, + efile->keywords)) { + /* FIXME: what to do with monitors here, they + * have already been whacked, a corner case + * not handled! */ + g_free (newfname); + return FALSE; + } + } else { + if (efile->filename != NULL && + ! copy_file (efile->filename, newfname)) { + /* FIXME: what to do with monitors here, they + * have already been whacked, a corner case + * not handled! */ + g_free (newfname); + return FALSE; + } + } + + /* we didn't copy but ensure path anyway */ + if (efile->filename == NULL && + ! ensure_dir (newfname, + TRUE /* ignore_basename */)) { + g_free (newfname); + return FALSE; + } + + /* this file already exists so re-add monitors at the new location */ + if (efile->filename != NULL) { + GSList *li; + char *uri = gnome_vfs_get_uri_from_local_path (newfname); + + for (li = entry->monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + + gnome_vfs_monitor_add (&(h->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + h); + } + + g_free (uri); + } + + g_free (efile->filename); + efile->filename = newfname; + efile->per_user = TRUE; + + return TRUE; +} + +static void +try_free_file_monitors_create_dirfile_unlocked (VFolderInfo *info, + Folder *folder) +{ + GSList *li, *list; + + list = g_slist_copy (info->free_file_monitors); + + for (li = list; li != NULL; li = li->next) { + FileMonitorHandle *handle = li->data; + Folder *f; + VFolderURI vuri; + GnomeVFSResult result; + + if ( ! handle->is_directory_file) + continue; + + /* Evil! EVIL URI PARSING. this will eat a lot of stack if we + * have lots of free monitors */ + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + f = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + + if (folder != f) + continue; + + info->free_file_monitors = + g_slist_remove (info->free_file_monitors, handle); + ((Entry *)folder)->monitors = + g_slist_prepend (((Entry *)folder)->monitors, handle); + + handle->exists = TRUE; + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *)handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_CREATED); + } + + g_slist_free (list); +} + +static void +make_new_dirfile (VFolderInfo *info, Folder *folder) +{ + char *name = g_strdup (folder->entry.name); + char *fname; + char *p; + int i; + int fd; + + for (p = name; *p != '\0'; p++) { + if ( ! ( (*p >= 'a' && *p <= 'z') || + (*p >= 'A' && *p <= 'Z') || + (*p >= '0' && *p <= '9') || + *p == '_')) { + *p = '_'; + } + } + + i = 0; + fname = NULL; + do { + char *fullname; + + g_free (fname); + + if (i > 0) { + fname = g_strdup_printf ("%s-%d.directory", name, i); + } else { + fname = g_strdup_printf ("%s.directory", name); + } + + fullname = g_build_filename + (info->user_desktop_dir, fname, NULL); + fd = open (fullname, O_CREAT | O_WRONLY | O_EXCL, 0600); + g_free (fullname); + } while (fd < 0); + + close (fd); + + folder->desktop_file = fname; + info->dirty = TRUE; + + try_free_file_monitors_create_dirfile_unlocked (info, folder); +} + +static gboolean +make_dirfile_private (VFolderInfo *info, Folder *folder) +{ + char *fname; + char *desktop_file; + GSList *li; + char *uri; + gboolean ret; + + if (info->user_desktop_dir == NULL) + return FALSE; + + if ( ! ensure_dir (info->user_desktop_dir, + FALSE /* ignore_basename */)) + return FALSE; + + + if (folder->desktop_file == NULL) { + make_new_dirfile (info, folder); + return TRUE; + } + + /* FIXME: this is broken! What if the desktop file exists + * in the local but there is a different (but with a same name) + * .directory in the system. */ + fname = g_build_filename (info->user_desktop_dir, + folder->desktop_file, + NULL); + + if (access (fname, F_OK) == 0) { + g_free (fname); + return TRUE; + } + + desktop_file = get_directory_file (info, folder); + + if (desktop_file == NULL) { + int fd = open (fname, O_CREAT | O_EXCL | O_WRONLY, 0600); + g_free (fname); + if (fd >= 0) { + close (fd); + return TRUE; + } + return FALSE; + } + + for (li = ((Entry *)folder)->monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + if (h->is_directory_file) { + if (h->handle != NULL) + gnome_vfs_monitor_cancel (h->handle); + h->handle = NULL; + } + } + + ret = TRUE; + + if ( ! copy_file (desktop_file, fname)) { + ret = FALSE; + g_free (fname); + fname = desktop_file; + desktop_file = NULL; + } + + uri = gnome_vfs_get_uri_from_local_path (fname); + + for (li = ((Entry *)folder)->monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + + if (h->is_directory_file) { + gnome_vfs_monitor_add (&(h->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + h); + } + } + + g_free (uri); + + g_free (desktop_file); + g_free (fname); + + return ret; +} + +static Folder * +resolve_folder (VFolderInfo *info, + const char *path, + gboolean ignore_basename, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + char **ppath; + int i; + Folder *folder = info->root; + + ppath = g_strsplit (path, "/", -1); + + if (ppath == NULL || + ppath[0] == NULL) { + g_strfreev (ppath); + *result = GNOME_VFS_ERROR_INVALID_URI; + return NULL; + } + + for (i = 0; ppath [i] != NULL; i++) { + const char *segment = ppath[i]; + + if (*segment == '\0') + continue; + + if (ignore_basename && ppath [i + 1] == NULL) + break; + else { + folder = (Folder *) find_entry (folder->subfolders, + segment); + if (folder == NULL) + break; + } + } + g_strfreev (ppath); + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if (folder == NULL) + *result = GNOME_VFS_ERROR_NOT_FOUND; + + return folder; +} + +static Entry * +resolve_path (VFolderInfo *info, + const char *path, + const char *basename, + Folder **return_folder, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + Entry *entry; + Folder *folder; + + if (strcmp (path, "/") == 0) + return (Entry *)info->root; + + folder = resolve_folder (info, path, + TRUE /* ignore_basename */, + result, context); + + if (return_folder != NULL) + *return_folder = folder; + + if (folder == NULL) { + return NULL; + } + + /* Make sure we have the entries here */ + ensure_folder_unlocked (info, folder, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + + entry = find_entry (folder->entries, basename); + + if (entry == NULL) + *result = GNOME_VFS_ERROR_NOT_FOUND; + + return entry; +} + +static Entry * +get_entry_unlocked (VFolderURI *vuri, + Folder **parent, + gboolean *is_directory_file, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + VFolderInfo *info; + Entry *entry; + + if (is_directory_file != NULL) + *is_directory_file = FALSE; + if (parent != NULL) + *parent = NULL; + + info = get_vfolder_info_unlocked (vuri->scheme, result, context); + if (info == NULL) + return NULL; + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if (vuri->is_all_scheme) { + GSList *efile_list; + + if (vuri->file == NULL) { + entry = resolve_path (info, + vuri->path, + vuri->file, + parent, + result, + context); + return entry; + } + + efile_list = g_hash_table_lookup (info->entries_ht, vuri->file); + + if (efile_list == NULL) { + *result = GNOME_VFS_ERROR_NOT_FOUND; + return NULL; + } else { + return efile_list->data; + } + } + + if (vuri->file != NULL && + check_ext (vuri->file, ".directory") == TRUE) { + Folder *folder; + + folder = resolve_folder (info, vuri->path, + TRUE /* ignore_basename */, + result, context); + if (folder == NULL) { + return NULL; + } + + if (is_directory_file != NULL) + *is_directory_file = TRUE; + + if (parent != NULL) + *parent = folder; + + return (Entry *)folder; + } else { + entry = resolve_path (info, vuri->path, vuri->file, parent, + result, context); + return entry; + } +} + +static Entry * +get_entry (VFolderURI *vuri, + Folder **parent, + gboolean *is_directory_file, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + Entry *entry; + + G_LOCK (vfolder_lock); + entry = get_entry_unlocked (vuri, + parent, + is_directory_file, + result, context); + G_UNLOCK (vfolder_lock); + + return entry; +} + +/* only works for files and only those that exist */ +/* unlocked function */ +static GnomeVFSURI * +desktop_uri_to_file_uri (VFolderInfo *info, + VFolderURI *desktop_vuri, + Entry **the_entry, + gboolean *the_is_directory_file, + Folder **the_folder, + gboolean privatize, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + gboolean is_directory_file; + GnomeVFSURI *ret_uri; + Folder *folder = NULL; + Entry *entry; + + entry = get_entry_unlocked (desktop_vuri, + &folder, + &is_directory_file, + result, + context); + if (entry == NULL) + return NULL; + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if (the_folder != NULL) + *the_folder = folder; + + if (the_entry != NULL) + *the_entry = entry; + if (the_is_directory_file != NULL) + *the_is_directory_file = is_directory_file; + + if (is_directory_file && + entry->type == ENTRY_FOLDER) { + char *desktop_file; + + folder = (Folder *)entry; + + if (the_folder != NULL) + *the_folder = folder; + + /* we'll be doing something write like */ + if (folder->read_only && + privatize) { + *result = GNOME_VFS_ERROR_READ_ONLY; + return NULL; + } + + if (privatize) { + char *fname; + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if ( ! make_dirfile_private (info, folder)) { + *result = GNOME_VFS_ERROR_GENERIC; + return NULL; + } + fname = g_build_filename (g_get_home_dir (), + folder->desktop_file, + NULL); + ret_uri = gnome_vfs_uri_new (fname); + g_free (fname); + return ret_uri; + } + + desktop_file = get_directory_file_unlocked (info, folder); + if (desktop_file != NULL) { + char *s = gnome_vfs_get_uri_from_local_path + (desktop_file); + + g_free (desktop_file); + + ret_uri = gnome_vfs_uri_new (s); + g_free (s); + + return ret_uri; + } else { + *result = GNOME_VFS_ERROR_NOT_FOUND; + return NULL; + } + } else if (entry->type == ENTRY_FILE) { + EntryFile *efile = (EntryFile *)entry; + char *s; + + /* we'll be doing something write like */ + if (folder != NULL && + folder->read_only && + privatize) { + *result = GNOME_VFS_ERROR_READ_ONLY; + return NULL; + } + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if (privatize && + ! make_file_private (info, efile)) { + *result = GNOME_VFS_ERROR_GENERIC; + return NULL; + } + + s = gnome_vfs_get_uri_from_local_path (efile->filename); + ret_uri = gnome_vfs_uri_new (s); + g_free (s); + + return ret_uri; + } else { + if (the_folder != NULL) + *the_folder = (Folder *)entry; + *result = GNOME_VFS_ERROR_IS_DIRECTORY; + return NULL; + } +} + +static void +remove_file (Folder *folder, const char *basename) +{ + GSList *li; + char *s; + + if (folder->includes_ht != NULL) { + li = g_hash_table_lookup (folder->includes_ht, basename); + if (li != NULL) { + char *name = li->data; + folder->includes = g_slist_delete_link + (folder->includes, li); + g_hash_table_remove (folder->includes_ht, basename); + g_free (name); + } + } + + if (folder->excludes == NULL) { + folder->excludes = g_hash_table_new_full + (g_str_hash, g_str_equal, + (GDestroyNotify)g_free, + NULL); + } + s = g_strdup (basename); + g_hash_table_replace (folder->excludes, s, s); +} + +static void +add_file (Folder *folder, const char *basename) +{ + GSList *li = NULL; + + if (folder->includes_ht != NULL) { + li = g_hash_table_lookup (folder->includes_ht, basename); + } + + /* if not found */ + if (li == NULL) { + char *str = g_strdup (basename); + folder->includes = + g_slist_prepend (folder->includes, str); + if (folder->includes_ht == NULL) { + folder->includes_ht = + g_hash_table_new_full (g_str_hash, + g_str_equal, + NULL, + NULL); + } + g_hash_table_replace (folder->includes_ht, + str, folder->includes); + } + if (folder->excludes != NULL) + g_hash_table_remove (folder->excludes, basename); +} + +typedef struct _FileHandle FileHandle; +struct _FileHandle { + VFolderInfo *info; + GnomeVFSMethodHandle *handle; + Entry *entry; + gboolean write; + gboolean is_directory_file; +}; + +static void +make_handle (GnomeVFSMethodHandle **method_handle, + GnomeVFSMethodHandle *file_handle, + VFolderInfo *info, + Entry *entry, + gboolean is_directory_file, + gboolean write) +{ + if (file_handle != NULL) { + FileHandle *handle = g_new0 (FileHandle, 1); + + handle->info = info; + handle->handle = file_handle; + handle->entry = entry_ref (entry); + handle->is_directory_file = is_directory_file; + handle->write = write; + + *method_handle = (GnomeVFSMethodHandle *) handle; + } else { + *method_handle = NULL; + } +} + +static void +whack_handle (FileHandle *handle) +{ + entry_unref (handle->entry); + handle->entry = NULL; + + handle->handle = NULL; + handle->info = NULL; + + g_free (handle); +} + +static GnomeVFSResult +do_open (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result = GNOME_VFS_OK; + VFolderInfo *info; + Entry *entry; + gboolean is_directory_file; + GnomeVFSMethodHandle *file_handle = NULL; + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + /* These can't be very nice FILE names */ + if (vuri.file == NULL || + vuri.ends_in_slash) + return GNOME_VFS_ERROR_INVALID_URI; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (mode & GNOME_VFS_OPEN_WRITE && + (info->read_only || vuri.is_all_scheme)) + return GNOME_VFS_ERROR_READ_ONLY; + + G_LOCK (vfolder_lock); + file_uri = desktop_uri_to_file_uri (info, + &vuri, + &entry, + &is_directory_file, + NULL /* the_folder */, + mode & GNOME_VFS_OPEN_WRITE, + &result, + context); + + if (file_uri == NULL) { + G_UNLOCK (vfolder_lock); + return result; + } + + result = (* parent_method->open) (parent_method, + &file_handle, + file_uri, + mode, + context); + + if (result == GNOME_VFS_ERROR_CANCELLED) { + G_UNLOCK (vfolder_lock); + gnome_vfs_uri_unref (file_uri); + return result; + } + + make_handle (method_handle, + file_handle, + info, + entry, + is_directory_file, + mode & GNOME_VFS_OPEN_WRITE); + + gnome_vfs_uri_unref (file_uri); + + if (info->dirty) { + vfolder_info_write_user (info); + } + + G_UNLOCK (vfolder_lock); + + return result; +} + +static void +remove_from_all_except (Folder *root, + const char *name, + Folder *except) +{ + GSList *li; + + if (root != except) { + remove_file (root, name); + if (root->up_to_date) { + for (li = root->entries; li != NULL; li = li->next) { + Entry *entry = li->data; + if (strcmp (name, entry->name) == 0) { + root->entries = + g_slist_delete_link + (root->entries, li); + break; + } + } + } + } + + for (li = root->subfolders; li != NULL; li = li->next) { + Folder *subfolder = li->data; + + remove_from_all_except (subfolder, name, except); + } +} + +static GnomeVFSResult +do_create (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + gboolean exclusive, + guint perm, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + GnomeVFSMethodHandle *file_handle; + GnomeVFSURI *file_uri; + VFolderURI vuri; + VFolderInfo *info; + Folder *parent; + Entry *entry; + EntryFile *efile; + char *s; + GSList *li; + + VFOLDER_URI_PARSE (uri, &vuri); + + /* These can't be very nice FILE names */ + if (vuri.file == NULL || + vuri.ends_in_slash) + return GNOME_VFS_ERROR_INVALID_URI; + + if ( ! check_ext (vuri.file, ".desktop") && + ! strcmp (vuri.file, ".directory") == 0) { + return GNOME_VFS_ERROR_INVALID_URI; + } + + /* all scheme is read only */ + if (vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (info->user_filename == NULL || + info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + parent = resolve_folder (info, vuri.path, + TRUE /* ignore_basename */, + &result, context); + if (parent == NULL) + return result; + + if (parent->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + if (strcmp (vuri.file, ".directory") == 0) { + char *fname; + + G_LOCK (vfolder_lock); + + if (exclusive) { + char *desktop_file; + desktop_file = get_directory_file_unlocked (info, parent); + if (desktop_file != NULL) { + g_free (desktop_file); + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_FILE_EXISTS; + } + } + + if ( ! make_dirfile_private (info, parent)) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_GENERIC; + } + fname = g_build_filename (g_get_home_dir (), + parent->desktop_file, + NULL); + s = gnome_vfs_get_uri_from_local_path (fname); + file_uri = gnome_vfs_uri_new (s); + g_free (fname); + g_free (s); + + if (file_uri == NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_GENERIC; + } + + result = (* parent_method->create) (parent_method, + &file_handle, + file_uri, + mode, + exclusive, + perm, + context); + gnome_vfs_uri_unref (file_uri); + + make_handle (method_handle, + file_handle, + info, + (Entry *)parent, + TRUE /* is_directory_file */, + TRUE /* write */); + + if (info->dirty) + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return result; + } + + ensure_folder (info, parent, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + + entry = find_entry (parent->entries, vuri.file); + + if (entry != NULL && + entry->type == ENTRY_FOLDER) + return GNOME_VFS_ERROR_IS_DIRECTORY; + + efile = (EntryFile *)entry; + + if (efile != NULL) { + if (exclusive) + return GNOME_VFS_ERROR_FILE_EXISTS; + + G_LOCK (vfolder_lock); + if ( ! make_file_private (info, efile)) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_GENERIC; + } + + s = gnome_vfs_get_uri_from_local_path (efile->filename); + file_uri = gnome_vfs_uri_new (s); + g_free (s); + + if (file_uri == NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_GENERIC; + } + + result = (* parent_method->create) (parent_method, + &file_handle, + file_uri, + mode, + exclusive, + perm, + context); + gnome_vfs_uri_unref (file_uri); + + make_handle (method_handle, + file_handle, + info, + (Entry *)efile, + FALSE /* is_directory_file */, + TRUE /* write */); + + G_UNLOCK (vfolder_lock); + + return result; + } + + G_LOCK (vfolder_lock); + + li = g_hash_table_lookup (info->entries_ht, vuri.file); + + if (exclusive && li != NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_FILE_EXISTS; + } + + if (li == NULL) { + efile = file_new (vuri.file); + vfolder_info_insert_entry (info, efile); + entry_unref ((Entry *)efile); + } else { + efile = li->data; + } + + /* this will make a private name for this */ + if ( ! make_file_private (info, efile)) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_GENERIC; + } + + add_file (parent, vuri.file); + parent->sorted = FALSE; + + if (parent->up_to_date) + parent->entries = g_slist_prepend (parent->entries, efile); + + /* if we created a brand new name, then we exclude it + * from everywhere else to ensure overall sanity */ + if (li == NULL) + remove_from_all_except (info->root, vuri.file, parent); + + s = gnome_vfs_get_uri_from_local_path (efile->filename); + file_uri = gnome_vfs_uri_new (s); + g_free (s); + + result = (* parent_method->create) (parent_method, + &file_handle, + file_uri, + mode, + exclusive, + perm, + context); + gnome_vfs_uri_unref (file_uri); + + make_handle (method_handle, + file_handle, + info, + (Entry *)efile, + FALSE /* is_directory_file */, + TRUE /* write */); + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return result; +} + +static GnomeVFSResult +do_close (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + if (method_handle == (GnomeVFSMethodHandle *)method) + return GNOME_VFS_OK; + + G_LOCK (vfolder_lock); + + result = (* parent_method->close) (parent_method, + handle->handle, + context); + handle->handle = NULL; + + /* we reread the Categories keyword */ + if (handle->write && + handle->entry != NULL && + handle->entry->type == ENTRY_FILE) { + EntryFile *efile = (EntryFile *)handle->entry; + char *categories; + readitem_entry (efile->filename, + "Categories", + &categories, + NULL, + NULL); + set_keywords (efile, categories); + g_free (categories); + /* FIXME: what about OnlyShowIn */ + + /* FIXME: check if the keywords changed, if not, do + * nothing */ + + /* Perhaps a bit drastic */ + /* also this emits the CHANGED monitor signal */ + invalidate_folder_T (handle->info->root); + + /* the file changed monitor will happen by itself + * as the underlying file is changed */ + } else if (handle->write && + handle->entry != NULL && + handle->entry->type == ENTRY_FOLDER && + handle->is_directory_file) { + /* if we're monitoring this directory, emit the CHANGED + * monitor thing, it will also emit a changed on + * the file itself. It is better to emit changed + * just in case. */ + emit_monitor ((Folder *)(handle->entry), + GNOME_VFS_MONITOR_EVENT_CHANGED); + } + + whack_handle (handle); + + G_UNLOCK (vfolder_lock); + + return result; +} + +static void +fill_buffer (gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read) +{ + char *buf = buffer; + GnomeVFSFileSize i; + for (i = 0; i < num_bytes; i++) { + if (rand () % 32 == 0 || + i == num_bytes-1) + buf[i] = '\n'; + else + buf[i] = ((rand()>>4) % 94) + 32; + } + if (bytes_read != 0) + *bytes_read = i; +} + +static GnomeVFSResult +do_read (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + if (method_handle == (GnomeVFSMethodHandle *)method) { + if ((rand () >> 4) & 0x3) { + fill_buffer (buffer, num_bytes, bytes_read); + return GNOME_VFS_OK; + } else { + return GNOME_VFS_ERROR_EOF; + } + } + + result = (* parent_method->read) (parent_method, + handle->handle, + buffer, num_bytes, + bytes_read, + context); + + return result; +} + +static GnomeVFSResult +do_write (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gconstpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_written, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + if (method_handle == (GnomeVFSMethodHandle *)method) + return GNOME_VFS_OK; + + result = (* parent_method->write) (parent_method, + handle->handle, + buffer, num_bytes, + bytes_written, + context); + + return result; +} + + +static GnomeVFSResult +do_seek (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSSeekPosition whence, + GnomeVFSFileOffset offset, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + if (method_handle == (GnomeVFSMethodHandle *)method) + return GNOME_VFS_OK; + + result = (* parent_method->seek) (parent_method, + handle->handle, + whence, offset, + context); + + return result; +} + +static GnomeVFSResult +do_tell (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileOffset *offset_return) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + result = (* parent_method->tell) (parent_method, + handle->handle, + offset_return); + + return result; +} + + +static GnomeVFSResult +do_truncate_handle (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileSize where, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + if (method_handle == (GnomeVFSMethodHandle *)method) + return GNOME_VFS_OK; + + result = (* parent_method->truncate_handle) (parent_method, + handle->handle, + where, + context); + + return result; +} + +static GnomeVFSResult +do_truncate (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileSize where, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result = GNOME_VFS_OK; + VFolderInfo *info; + Entry *entry; + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + /* These can't be very nice FILE names */ + if (vuri.file == NULL || + vuri.ends_in_slash) + return GNOME_VFS_ERROR_INVALID_URI; + + if (vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + G_LOCK (vfolder_lock); + file_uri = desktop_uri_to_file_uri (info, + &vuri, + &entry, + NULL /* the_is_directory_file */, + NULL /* the_folder */, + TRUE /* privatize */, + &result, + context); + G_UNLOCK (vfolder_lock); + + if (file_uri == NULL) + return result; + + result = (* parent_method->truncate) (parent_method, + file_uri, + where, + context); + + gnome_vfs_uri_unref (file_uri); + + if (info->dirty) { + G_LOCK (vfolder_lock); + vfolder_info_write_user (info); + G_UNLOCK (vfolder_lock); + } + + if (entry->type == ENTRY_FILE) { + EntryFile *efile = (EntryFile *)entry; + + G_LOCK (vfolder_lock); + g_slist_free (efile->keywords); + efile->keywords = NULL; + G_UNLOCK (vfolder_lock); + } + + /* Perhaps a bit drastic, but oh well */ + invalidate_folder (info->root); + + return result; +} + +typedef struct _DirHandle DirHandle; +struct _DirHandle { + VFolderInfo *info; + Folder *folder; + + GnomeVFSFileInfoOptions options; + + /* List of Entries */ + GSList *list; + GSList *current; +}; + +static GnomeVFSResult +do_open_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + VFolderURI vuri; + DirHandle *dh; + Folder *folder; + VFolderInfo *info; + char *desktop_file; + + VFOLDER_URI_PARSE (uri, &vuri); + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + /* In the all- scheme just list all filenames */ + if (vuri.is_all_scheme) { + if (any_subdir (vuri.path)) + return GNOME_VFS_ERROR_NOT_FOUND; + + dh = g_new0 (DirHandle, 1); + dh->info = info; + dh->options = options; + dh->folder = NULL; + + G_LOCK (vfolder_lock); + dh->list = g_slist_copy (info->entries); + g_slist_foreach (dh->list, (GFunc)entry_ref, NULL); + dh->current = dh->list; + G_UNLOCK (vfolder_lock); + + *method_handle = (GnomeVFSMethodHandle*) dh; + return GNOME_VFS_OK; + } + + folder = resolve_folder (info, vuri.path, + FALSE /* ignore_basename */, + &result, context); + if (folder == NULL) + return result; + + /* Make sure we have the entries and sorted here */ + ensure_folder_sort (info, folder); + + dh = g_new0 (DirHandle, 1); + dh->info = info; + dh->options = options; + + G_LOCK (vfolder_lock); + dh->folder = (Folder *)entry_ref ((Entry *)folder); + dh->list = g_slist_copy (folder->entries); + g_slist_foreach (folder->entries, (GFunc)entry_ref, NULL); + G_UNLOCK (vfolder_lock); + + desktop_file = get_directory_file (info, folder); + if (desktop_file != NULL) { + EntryFile *efile = file_new (".directory"); + dh->list = g_slist_prepend (dh->list, efile); + g_free (desktop_file); + } + + dh->current = dh->list; + + *method_handle = (GnomeVFSMethodHandle*) dh; + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_close_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + DirHandle *dh; + + dh = (DirHandle*) method_handle; + + G_LOCK (vfolder_lock); + + g_slist_foreach (dh->list, (GFunc)entry_unref, NULL); + g_slist_free (dh->list); + dh->list = NULL; + + dh->current = NULL; + + if (dh->folder != NULL) + entry_unref ((Entry *)dh->folder); + dh->folder = NULL; + + dh->info = NULL; + + g_free (dh); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_read_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSContext *context) +{ + DirHandle *dh; + Entry *entry; + GnomeVFSFileInfoOptions options; + + dh = (DirHandle*) method_handle; + +read_directory_again: + + if (dh->current == NULL) { + return GNOME_VFS_ERROR_EOF; + } + + entry = dh->current->data; + dh->current = dh->current->next; + + options = dh->options; + + if (entry->type == ENTRY_FILE && + ((EntryFile *)entry)->filename != NULL) { + EntryFile *efile = (EntryFile *)entry; + char *furi = gnome_vfs_get_uri_from_local_path (efile->filename); + GnomeVFSURI *uri = gnome_vfs_uri_new (furi); + + /* we always get mime-type by forcing it below */ + if (options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE) + options &= ~GNOME_VFS_FILE_INFO_GET_MIME_TYPE; + + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_NONE; + + /* Get the file info for this */ + (* parent_method->get_file_info) (parent_method, + uri, + file_info, + options, + context); + + /* we ignore errors from this since the file_info just + * won't be filled completely if there's an error, that's all */ + + g_free (file_info->mime_type); + file_info->mime_type = g_strdup ("application/x-gnome-app-info"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + /* Now we wipe those fields we don't support */ + file_info->valid_fields &= ~(UNSUPPORTED_INFO_FIELDS); + + gnome_vfs_uri_unref (uri); + g_free (furi); + } else if (entry->type == ENTRY_FILE) { + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_NONE; + + file_info->name = g_strdup (entry->name); + GNOME_VFS_FILE_INFO_SET_LOCAL (file_info, TRUE); + + file_info->type = GNOME_VFS_FILE_TYPE_REGULAR; + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_TYPE; + + /* FIXME: Is this correct? isn't there an xdg mime type? */ + file_info->mime_type = g_strdup ("application/x-gnome-app-info"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + /* FIXME: get some ctime/mtime */ + } else /* ENTRY_FOLDER */ { + Folder *folder = (Folder *)entry; + + /* Skip empty folders if they have + * the flag set */ + if (folder->dont_show_if_empty) { + /* Make sure we have the entries */ + ensure_folder (dh->info, folder, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + + if (folder->entries == NULL) { + /* start this function over on the + * next item */ + goto read_directory_again; + } + } + + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_NONE; + + file_info->name = g_strdup (entry->name); + GNOME_VFS_FILE_INFO_SET_LOCAL (file_info, TRUE); + + file_info->type = GNOME_VFS_FILE_TYPE_DIRECTORY; + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_TYPE; + + file_info->mime_type = g_strdup ("x-directory/vfolder-desktop"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + file_info->ctime = dh->info->modification_time; + file_info->mtime = dh->info->modification_time; + file_info->valid_fields |= (GNOME_VFS_FILE_INFO_FIELDS_CTIME | + GNOME_VFS_FILE_INFO_FIELDS_MTIME); + } + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_get_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result = GNOME_VFS_OK; + Folder *folder; + VFolderInfo *info; + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + G_LOCK (vfolder_lock); + file_uri = desktop_uri_to_file_uri (info, + &vuri, + NULL /* the_entry */, + NULL /* the_is_directory_file */, + &folder, + FALSE /* privatize */, + &result, + context); + G_UNLOCK (vfolder_lock); + + if (file_uri == NULL && + result != GNOME_VFS_ERROR_IS_DIRECTORY) + return result; + + if (file_uri != NULL) { + /* we always get mime-type by forcing it below */ + if (options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE) + options &= ~GNOME_VFS_FILE_INFO_GET_MIME_TYPE; + + result = (* parent_method->get_file_info) (parent_method, + file_uri, + file_info, + options, + context); + + g_free (file_info->mime_type); + file_info->mime_type = g_strdup ("application/x-gnome-app-info"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + /* Now we wipe those fields we don't support */ + file_info->valid_fields &= ~(UNSUPPORTED_INFO_FIELDS); + + gnome_vfs_uri_unref (file_uri); + + return result; + } else if (folder != NULL) { + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_NONE; + + file_info->name = g_strdup (folder->entry.name); + GNOME_VFS_FILE_INFO_SET_LOCAL (file_info, TRUE); + + file_info->type = GNOME_VFS_FILE_TYPE_DIRECTORY; + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_TYPE; + + file_info->mime_type = g_strdup ("x-directory/vfolder-desktop"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + file_info->ctime = info->modification_time; + file_info->mtime = info->modification_time; + file_info->valid_fields |= (GNOME_VFS_FILE_INFO_FIELDS_CTIME | + GNOME_VFS_FILE_INFO_FIELDS_MTIME); + + return GNOME_VFS_OK; + } else { + return GNOME_VFS_ERROR_NOT_FOUND; + } +} + +static GnomeVFSResult +do_get_file_info_from_handle (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + if (method_handle == (GnomeVFSMethodHandle *)method) { + g_free (file_info->mime_type); + file_info->mime_type = g_strdup ("text/plain"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + return GNOME_VFS_OK; + } + + /* we always get mime-type by forcing it below */ + if (options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE) + options &= ~GNOME_VFS_FILE_INFO_GET_MIME_TYPE; + + result = (* parent_method->get_file_info_from_handle) (parent_method, + handle->handle, + file_info, + options, + context); + + /* any file is of the .desktop type */ + g_free (file_info->mime_type); + file_info->mime_type = g_strdup ("application/x-gnome-app-info"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + /* Now we wipe those fields we don't support */ + file_info->valid_fields &= ~(UNSUPPORTED_INFO_FIELDS); + + return result; +} + + +static gboolean +do_is_local (GnomeVFSMethod *method, + const GnomeVFSURI *uri) +{ + return TRUE; +} + +static void +try_free_folder_monitors_create_unlocked (VFolderInfo *info, + Folder *folder) +{ + GSList *li, *list; + + list = g_slist_copy (info->free_folder_monitors); + + for (li = list; li != NULL; li = li->next) { + FileMonitorHandle *handle = li->data; + Folder *f; + VFolderURI vuri; + GnomeVFSResult result; + + /* Evil! EVIL URI PARSING. this will eat a lot of stack if we + * have lots of free monitors */ + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + f = resolve_folder (info, + vuri.path, + FALSE /* ignore_basename */, + &result, + NULL); + + if (folder != f) + continue; + + info->free_folder_monitors = + g_slist_remove (info->free_folder_monitors, handle); + ((Entry *)folder)->monitors = + g_slist_prepend (((Entry *)folder)->monitors, handle); + + handle->exists = TRUE; + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *)handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_CREATED); + } +} + + +static GnomeVFSResult +do_make_directory (GnomeVFSMethod *method, + GnomeVFSURI *uri, + guint perm, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + VFolderInfo *info; + Folder *parent, *folder; + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + if (vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (info->user_filename == NULL || + info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + parent = resolve_folder (info, vuri.path, + TRUE /* ignore_basename */, + &result, context); + if (parent == NULL) + return result; + else if (parent->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + G_LOCK (vfolder_lock); + + folder = (Folder *)find_entry (parent->subfolders, + vuri.file); + if (folder != NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_FILE_EXISTS; + } + + folder = folder_new (vuri.file); + parent->subfolders = g_slist_append (parent->subfolders, folder); + folder->parent = parent; + parent->up_to_date = FALSE; + + try_free_folder_monitors_create_unlocked (info, folder); + + /* parent changed */ + emit_monitor (parent, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_remove_directory (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + Folder *folder; + VFolderInfo *info; + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + if (vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (info->user_filename == NULL || + info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + G_LOCK (vfolder_lock); + + folder = resolve_folder (info, vuri.path, + FALSE /* ignore_basename */, + &result, context); + if (folder == NULL) { + G_UNLOCK (vfolder_lock); + return result; + } + + if (folder->read_only || + (folder->parent != NULL && + folder->parent->read_only)) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_READ_ONLY; + } + + /* don't make removing directories easy */ + if (folder->desktop_file != NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY; + } + + /* Make sure we have the entries */ + ensure_folder_unlocked (info, folder, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + + /* don't make removing directories easy */ + if (folder->entries != NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY; + } + + emit_and_delete_monitor (info, folder); + + if (folder->only_unallocated) { + GSList *li = g_slist_find (info->unallocated_folders, + folder); + if (li != NULL) { + info->unallocated_folders = g_slist_delete_link + (info->unallocated_folders, li); + entry_unref ((Entry *)folder); + } + } + + if (folder == info->root) { + info->root = NULL; + entry_unref ((Entry *)folder); + info->root = folder_new ("Root"); + } else { + Folder *parent = folder->parent; + + g_assert (parent != NULL); + + parent->subfolders = + g_slist_remove (parent->subfolders, folder); + + parent->up_to_date = FALSE; + + entry_unref ((Entry *)folder); + + /* parent changed */ + emit_monitor (parent, GNOME_VFS_MONITOR_EVENT_CHANGED); + } + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; +} + +/* a fairly evil function that does the whole move bit by copy and + * remove */ +static GnomeVFSResult +long_move (GnomeVFSMethod *method, + VFolderURI *old_vuri, + VFolderURI *new_vuri, + gboolean force_replace, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + GnomeVFSMethodHandle *handle; + GnomeVFSURI *file_uri; + const char *path; + int fd; + char buf[BUFSIZ]; + int bytes; + VFolderInfo *info; + + info = get_vfolder_info (old_vuri->scheme, &result, context); + if (info == NULL) + return result; + + G_LOCK (vfolder_lock); + file_uri = desktop_uri_to_file_uri (info, + old_vuri, + NULL /* the_entry */, + NULL /* the_is_directory_file */, + NULL /* the_folder */, + FALSE /* privatize */, + &result, + context); + G_UNLOCK (vfolder_lock); + + if (file_uri == NULL) + return result; + + path = gnome_vfs_uri_get_path (file_uri); + if (path == NULL) { + gnome_vfs_uri_unref (file_uri); + return GNOME_VFS_ERROR_INVALID_URI; + } + + fd = open (path, O_RDONLY); + if (fd < 0) { + gnome_vfs_uri_unref (file_uri); + return gnome_vfs_result_from_errno (); + } + + gnome_vfs_uri_unref (file_uri); + + info->inhibit_write++; + + result = method->create (method, + &handle, + new_vuri->uri, + GNOME_VFS_OPEN_WRITE, + force_replace /* exclusive */, + 0600 /* perm */, + context); + if (result != GNOME_VFS_OK) { + close (fd); + info->inhibit_write--; + return result; + } + + while ((bytes = read (fd, buf, BUFSIZ)) > 0) { + GnomeVFSFileSize bytes_written = 0; + result = method->write (method, + handle, + buf, + bytes, + &bytes_written, + context); + if (result == GNOME_VFS_OK && + bytes_written != bytes) + result = GNOME_VFS_ERROR_NO_SPACE; + if (result != GNOME_VFS_OK) { + close (fd); + method->close (method, handle, context); + /* FIXME: is this completely correct ? */ + method->unlink (method, + new_vuri->uri, + context); + G_LOCK (vfolder_lock); + info->inhibit_write--; + vfolder_info_write_user (info); + G_UNLOCK (vfolder_lock); + return result; + } + } + + close (fd); + + result = method->close (method, handle, context); + if (result != GNOME_VFS_OK) { + G_LOCK (vfolder_lock); + info->inhibit_write--; + vfolder_info_write_user (info); + G_UNLOCK (vfolder_lock); + return result; + } + + result = method->unlink (method, old_vuri->uri, context); + + G_LOCK (vfolder_lock); + info->inhibit_write--; + vfolder_info_write_user (info); + G_UNLOCK (vfolder_lock); + + return result; +} + +static GnomeVFSResult +move_directory_file (VFolderInfo *info, + Folder *old_folder, + Folder *new_folder) +{ + if (old_folder->desktop_file == NULL) + return GNOME_VFS_ERROR_NOT_FOUND; + + /* "move" the desktop file */ + g_free (new_folder->desktop_file); + new_folder->desktop_file = old_folder->desktop_file; + old_folder->desktop_file = NULL; + + /* is this too drastic, it will requery the folder? */ + new_folder->up_to_date = FALSE; + old_folder->up_to_date = FALSE; + + emit_monitor (new_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + emit_monitor (old_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + + return GNOME_VFS_OK; +} + +static gboolean +is_sub (Folder *master, Folder *sub) +{ + GSList *li; + + for (li = master->subfolders; li != NULL; li = li->next) { + Folder *subfolder = li->data; + + if (subfolder == sub || + is_sub (subfolder, sub)) + return TRUE; + } + + return FALSE; +} + +static GnomeVFSResult +move_folder (VFolderInfo *info, + Folder *old_folder, Entry *old_entry, + Folder *new_folder, Entry *new_entry) +{ + Folder *source = (Folder *)old_entry; + Folder *target; + + if (new_entry != NULL && + new_entry->type != ENTRY_FOLDER) + return GNOME_VFS_ERROR_NOT_A_DIRECTORY; + + if (new_entry != NULL) { + target = (Folder *)new_entry; + } else { + target = new_folder; + } + + /* move to where we are, yay, we're done :) */ + if (source->parent == target) + return GNOME_VFS_OK; + + if (source == target || + is_sub (source, target)) + return GNOME_VFS_ERROR_LOOP; + + /* this will never happen, but we're paranoid */ + if (source->parent == NULL) + return GNOME_VFS_ERROR_LOOP; + + source->parent->subfolders = g_slist_remove (source->parent->subfolders, + source); + target->subfolders = g_slist_append (target->subfolders, + source); + + source->parent = target; + + source->up_to_date = FALSE; + target->up_to_date = FALSE; + + emit_monitor (source, GNOME_VFS_MONITOR_EVENT_CHANGED); + emit_monitor (target, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_move (GnomeVFSMethod *method, + GnomeVFSURI *old_uri, + GnomeVFSURI *new_uri, + gboolean force_replace, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + VFolderInfo *info; + Folder *old_folder, *new_folder; + Entry *old_entry, *new_entry; + gboolean old_is_directory_file, new_is_directory_file; + VFolderURI old_vuri, new_vuri; + + VFOLDER_URI_PARSE (old_uri, &old_vuri); + VFOLDER_URI_PARSE (new_uri, &new_vuri); + + if (old_vuri.file == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + if (old_vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + if (strcmp (old_vuri.scheme, new_vuri.scheme) != 0) + return GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM; + + info = get_vfolder_info (old_vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + old_entry = get_entry (&old_vuri, + &old_folder, + &old_is_directory_file, + &result, + context); + if (old_entry == NULL) + return result; + + if (old_folder != NULL && old_folder->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + new_entry = get_entry (&new_vuri, + &new_folder, + &new_is_directory_file, + &result, + context); + if (new_entry == NULL && new_folder == NULL) + return result; + + if (new_folder != NULL && new_folder->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + if (new_is_directory_file != old_is_directory_file) { + /* this will do another set of lookups + * perhaps this can be done in a nicer way, + * but is this the common case? I don't think so */ + return long_move (method, &old_vuri, &new_vuri, + force_replace, context); + } + + if (new_is_directory_file) { + g_assert (old_entry != NULL); + g_assert (new_entry != NULL); + G_LOCK (vfolder_lock); + result = move_directory_file (info, + (Folder *)old_entry, + (Folder *)new_entry); + G_UNLOCK (vfolder_lock); + return result; + } + + if (old_entry->type == ENTRY_FOLDER) { + G_LOCK (vfolder_lock); + result = move_folder (info, + old_folder, old_entry, + new_folder, new_entry); + G_UNLOCK (vfolder_lock); + return result; + } + + /* move into self, just whack the old one */ + if (old_entry == new_entry) { + /* same folder */ + if (new_folder == old_folder) + return GNOME_VFS_OK; + + if ( ! force_replace) + return GNOME_VFS_ERROR_FILE_EXISTS; + + G_LOCK (vfolder_lock); + + remove_file (old_folder, old_vuri.file); + + old_folder->entries = g_slist_remove (old_folder->entries, + old_entry); + entry_unref (old_entry); + + emit_monitor (old_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; + } + + /* this is a simple move */ + if (new_entry == NULL || + new_entry->type == ENTRY_FOLDER) { + if (new_entry != NULL) { + new_folder = (Folder *)new_entry; + } else { + /* a file and a totally different one */ + if (strcmp (new_vuri.file, old_entry->name) != 0) { + /* yay, a long move */ + /* this will do another set of lookups + * perhaps this can be done in a nicer way, + * but is this the common case? I don't think + * so */ + return long_move (method, &old_vuri, &new_vuri, + force_replace, context); + } + } + + /* same folder */ + if (new_folder == old_folder) + return GNOME_VFS_OK; + + G_LOCK (vfolder_lock); + + remove_file (old_folder, old_entry->name); + add_file (new_folder, old_entry->name); + + new_folder->entries = g_slist_prepend (new_folder->entries, + old_entry); + entry_ref (old_entry); + new_folder->sorted = FALSE; + + old_folder->entries = g_slist_remove (old_folder->entries, + old_entry); + entry_unref (old_entry); + + emit_monitor (new_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + emit_monitor (old_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; + } + + /* do we EVER get here? */ + + /* this will do another set of lookups + * perhaps this can be done in a nicer way, + * but is this the common case? I don't think so */ + return long_move (method, &old_vuri, &new_vuri, + force_replace, context); +} + +static GnomeVFSResult +do_unlink (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + Entry *entry; + Folder *the_folder; + gboolean is_directory_file; + VFolderInfo *info; + VFolderURI vuri; + GSList *li; + + VFOLDER_URI_PARSE (uri, &vuri); + + if (vuri.file == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + if (vuri.is_all_scheme == TRUE) + return GNOME_VFS_ERROR_READ_ONLY; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + else if (info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + entry = get_entry (&vuri, + &the_folder, + &is_directory_file, + &result, context); + if (entry == NULL) + return result; + else if (the_folder != NULL && + the_folder->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + if (entry->type == ENTRY_FOLDER && + is_directory_file) { + Folder *folder = (Folder *)entry; + + if (folder->desktop_file == NULL) + return GNOME_VFS_ERROR_NOT_FOUND; + + G_LOCK (vfolder_lock); + + g_free (folder->desktop_file); + folder->desktop_file = NULL; + + emit_monitor (folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; + } else if (entry->type == ENTRY_FOLDER) { + return GNOME_VFS_ERROR_IS_DIRECTORY; + } else if (the_folder == NULL) { + return GNOME_VFS_ERROR_NOT_FOUND; + } + + G_LOCK (vfolder_lock); + + the_folder->entries = g_slist_remove (the_folder->entries, + entry); + entry_unref (entry); + + remove_file (the_folder, vuri.file); + + emit_monitor (the_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + + /* evil, we must remove this from the unallocated folders as well + * so that it magically doesn't appear there. But it's not so simple. + * We only want to remove it if it isn't in that folder already. */ + for (li = info->unallocated_folders; + li != NULL; + li = li->next) { + Folder *folder = li->data; + GSList *l; + + /* This is actually really evil since ensuring + * an unallocated folder clears all other unallocated + * folders in it's wake. I'm not sure it's worth + * optimizing however */ + ensure_folder_unlocked (info, folder, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + l = g_slist_find (folder->entries, entry); + if (l == NULL) { + remove_file (folder, vuri.file); + } + } + + emit_file_deleted_monitor (info, entry, the_folder); + + /* FIXME: if this was a user file and this is the only + * reference to it, unlink it. */ + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_check_same_fs (GnomeVFSMethod *method, + GnomeVFSURI *source_uri, + GnomeVFSURI *target_uri, + gboolean *same_fs_return, + GnomeVFSContext *context) +{ + VFolderURI source_vuri, target_vuri; + + *same_fs_return = FALSE; + + VFOLDER_URI_PARSE (source_uri, &source_vuri); + VFOLDER_URI_PARSE (target_uri, &target_vuri); + + if (strcmp (source_vuri.scheme, target_vuri.scheme) != 0 || + source_vuri.is_all_scheme != target_vuri.is_all_scheme) + *same_fs_return = FALSE; + else + *same_fs_return = TRUE; + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_set_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + const GnomeVFSFileInfo *info, + GnomeVFSSetFileInfoMask mask, + GnomeVFSContext *context) +{ + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + if (vuri.file == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + if (mask & GNOME_VFS_SET_FILE_INFO_NAME) { + GnomeVFSResult result = GNOME_VFS_OK; + char *dirname = gnome_vfs_uri_extract_dirname (uri); + GnomeVFSURI *new_uri = gnome_vfs_uri_dup (uri); + + G_LOCK (vfolder_lock); + g_free (new_uri->text); + new_uri->text = g_build_path ("/", dirname, info->name, NULL); + G_UNLOCK (vfolder_lock); + + result = do_move (method, + uri, + new_uri, + FALSE /* force_replace */, + context); + + g_free (dirname); + gnome_vfs_uri_unref (new_uri); + return result; + } else { + /* We don't support setting any of this other permission, + * times and all that voodoo */ + return GNOME_VFS_ERROR_NOT_SUPPORTED; + } +} + +static GnomeVFSResult +do_monitor_add (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle_return, + GnomeVFSURI *uri, + GnomeVFSMonitorType monitor_type) +{ + VFolderInfo *info; + VFolderURI vuri; + GnomeVFSResult result; + Folder *folder; + Entry *entry; + GnomeVFSURI *file_uri; + FileMonitorHandle *handle; + gboolean is_directory_file; + + VFOLDER_URI_PARSE (uri, &vuri); + + info = get_vfolder_info (vuri.scheme, &result, NULL); + if (info == NULL) + return result; + + if (monitor_type == GNOME_VFS_MONITOR_DIRECTORY) { + G_LOCK (vfolder_lock); + + folder = resolve_folder (info, + vuri.path, + FALSE /* ignore_basename */, + &result, + NULL); + + handle = g_new0 (FileMonitorHandle, 1); + handle->refcount = 2; + handle->uri = gnome_vfs_uri_dup (uri); + handle->dir_monitor = TRUE; + handle->handle = NULL; + handle->filename = NULL; + + if (folder == NULL) { + handle->exists = FALSE; + info->free_folder_monitors = + g_slist_prepend (info->free_folder_monitors, + handle); + } else { + handle->exists = TRUE; + ((Entry *)folder)->monitors = + g_slist_prepend (((Entry *)folder)->monitors, + handle); + } + + info->folder_monitors = + g_slist_prepend (info->folder_monitors, handle); + + G_UNLOCK (vfolder_lock); + + *method_handle_return = (GnomeVFSMethodHandle *) handle; + + return GNOME_VFS_OK; + } else { + /* These can't be very nice FILE names */ + if (vuri.file == NULL || + vuri.ends_in_slash) + return GNOME_VFS_ERROR_INVALID_URI; + + G_LOCK (vfolder_lock); + file_uri = desktop_uri_to_file_uri (info, + &vuri, + &entry, + &is_directory_file, + NULL /* the_folder */, + FALSE, + &result, + NULL); + + handle = g_new0 (FileMonitorHandle, 1); + handle->refcount = 2; + handle->uri = gnome_vfs_uri_dup (uri); + handle->dir_monitor = FALSE; + handle->handle = NULL; + handle->filename = g_strdup (vuri.file); + handle->is_directory_file = is_directory_file; + + info->file_monitors = + g_slist_prepend (info->file_monitors, handle); + + + if (file_uri == NULL) { + handle->exists = FALSE; + info->free_file_monitors = + g_slist_prepend (info->free_file_monitors, + handle); + } else { + char *uri_string = gnome_vfs_uri_to_string (file_uri, 0); + handle->exists = TRUE; + gnome_vfs_monitor_add (&(handle->handle), + uri_string, + GNOME_VFS_MONITOR_FILE, + file_monitor, + handle); + g_free (uri_string); + + entry->monitors = g_slist_prepend (entry->monitors, + handle); + gnome_vfs_uri_unref (file_uri); + } + + *method_handle_return = (GnomeVFSMethodHandle *) handle; + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; + } +} + +static GnomeVFSResult +do_monitor_cancel (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle) +{ + FileMonitorHandle *handle; + VFolderInfo *info; + VFolderURI vuri; + GnomeVFSResult result; + Folder *folder; + GSList *li; + + handle = (FileMonitorHandle *)method_handle; + + /* FIXME: is this correct? */ + if (method_handle == NULL) + return GNOME_VFS_OK; + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + info = get_vfolder_info (vuri.scheme, &result, NULL); + if (info == NULL) + return result; + + if (handle->dir_monitor) { + G_LOCK (vfolder_lock); + + folder = resolve_folder (info, + vuri.path, + FALSE /* ignore_basename */, + &result, + NULL); + + for (li = info->folder_monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + if (h != handle) + continue; + info->folder_monitors = g_slist_delete_link + (info->folder_monitors, li); + file_monitor_handle_unref_unlocked (h); + break; + } + + if (folder == NULL) { + for (li = info->free_folder_monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *h = li->data; + if (h != handle) + continue; + info->free_folder_monitors = g_slist_delete_link + (info->free_folder_monitors, li); + file_monitor_handle_unref_unlocked (h); + break; + } + } else { + for (li = ((Entry *)folder)->monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *h = li->data; + if (h != handle) + continue; + ((Entry *)folder)->monitors = + g_slist_delete_link + (((Entry *)folder)->monitors, li); + file_monitor_handle_unref_unlocked (h); + break; + } + } + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; + } else { + G_LOCK (vfolder_lock); + + for (li = info->file_monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + if (h != handle) + continue; + info->file_monitors = g_slist_delete_link + (info->file_monitors, li); + file_monitor_handle_unref_unlocked (h); + break; + } + + for (li = info->free_file_monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *h = li->data; + if (h != handle) + continue; + info->free_file_monitors = g_slist_delete_link + (info->free_file_monitors, li); + file_monitor_handle_unref_unlocked (h); + break; + } + + for (li = info->entries; li != NULL; li = li->next) { + Entry *e = li->data; + GSList *link = g_slist_find (e->monitors, handle); + + if (link == NULL) + continue; + link->data = NULL; + e->monitors = g_slist_delete_link (e->monitors, link); + + file_monitor_handle_unref_unlocked (handle); + break; + } + + G_UNLOCK (vfolder_lock); + + /* Note: last unref of our monitor will cancel the + * underlying handle */ + + return GNOME_VFS_OK; + } +} + + +/* gnome-vfs bureaucracy */ + +static GnomeVFSMethod method = { + sizeof (GnomeVFSMethod), + do_open, + do_create, + do_close, + do_read, + do_write, + do_seek, + do_tell, + do_truncate_handle, + do_open_directory, + do_close_directory, + do_read_directory, + do_get_file_info, + do_get_file_info_from_handle, + do_is_local, + do_make_directory, + do_remove_directory, + do_move, + do_unlink, + do_check_same_fs, + do_set_file_info, + do_truncate, + NULL /* find_directory */, + NULL /* create_symbolic_link */, + do_monitor_add, + do_monitor_cancel +}; + +GnomeVFSMethod * +vfs_module_init (const char *method_name, + const char *args) +{ + parent_method = gnome_vfs_method_get ("file"); + + if (parent_method == NULL) { + g_error ("Could not find 'file' method for gnome-vfs"); + return NULL; + } + + return &method; +} + +void +vfs_module_shutdown (GnomeVFSMethod *method) +{ + if (infos == NULL) + return; + + g_hash_table_destroy (infos); + infos = NULL; +} diff --git a/modules/vfolder-desktop-method.c.only-show-in b/modules/vfolder-desktop-method.c.only-show-in new file mode 100644 index 0000000..554f8cd --- /dev/null +++ b/modules/vfolder-desktop-method.c.only-show-in @@ -0,0 +1,6129 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: 8; c-basic-offset: 8 -*- */ + +/* vfolder-desktop-method.c + + Copyright (C) 2001 Red Hat, Inc. + Copyright (C) 2001 The Dark Prince + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/* URI scheme for reading the "applications:" vfolder and other + * vfolder schemes. Lots of code stolen from the original desktop + * reading URI scheme. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +/* Debugging foo: */ +/*#define D(x) x */ +#define D(x) ; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#define DOT_GNOME ".gnome2" + +typedef struct _VFolderInfo VFolderInfo; +typedef struct _Query Query; +typedef struct _QueryKeyword QueryKeyword; +typedef struct _QueryFilename QueryFilename; +typedef struct _Entry Entry; +typedef struct _Folder Folder; +typedef struct _EntryFile EntryFile; +typedef struct _Keyword Keyword; +typedef struct _FileMonitorHandle FileMonitorHandle; +typedef struct _StatLoc StatLoc; +typedef struct _VFolderURI VFolderURI; + +/* TODO before 2.0: */ +/* FIXME: also check/monitor desktop_dirs like we do the vfolder + * file and the item dirs */ +/* FIXME: check if thread locks are not completely on crack which + * is likely given my experience with threads */ +/* FIXME: use filename locking, currently we are full of races if + * multiple processes write to this filesystem */ +/* FIXME: implement monitors */ + +/* TODO for later (star trek future): */ +/* FIXME: Maybe when chaining to file:, we should call the gnome-vfs wrapper + * functions, instead of the file: methods directly. */ +/* FIXME: related to the above: we should support things being on non + * file: filesystems. Such as having the vfolder info file on http + * somewhere or some such nonsense :) */ + +static GnomeVFSMethod *parent_method = NULL; + +static GHashTable *infos = NULL; + +/* Note: I have no clue about how to write thread safe code and this + * is my first attempt, so it's probably wrong + * -George */ +G_LOCK_DEFINE_STATIC (vfolder_lock); + +/* Note: all keywords are quarks */ +/* Note: basenames are unique */ + +#define UNSUPPORTED_INFO_FIELDS (GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS | \ + GNOME_VFS_FILE_INFO_FIELDS_DEVICE | \ + GNOME_VFS_FILE_INFO_FIELDS_INODE | \ + GNOME_VFS_FILE_INFO_FIELDS_LINK_COUNT | \ + GNOME_VFS_FILE_INFO_FIELDS_ATIME) + + +enum { + QUERY_OR, + QUERY_AND, + QUERY_KEYWORD, + QUERY_FILENAME +}; + +struct _Query { + int type; + gboolean not; + GSList *queries; +}; + +struct _QueryKeyword { + int type; + gboolean not; + GQuark keyword; +}; + +struct _QueryFilename { + int type; + gboolean not; + char *filename; +}; + +enum { + ENTRY_FILE, + ENTRY_FOLDER +}; + +struct _Entry { + int type; + int refcount; + int alloc; /* not really useful for folders, + but oh well, whatever. It's the number + of times this is queried in some directory, + used for the Unallocated query type */ + char *name; + + GSList *monitors; +}; + +struct _EntryFile { + Entry entry; + + char *filename; + gboolean per_user; + GSList *keywords; + + gboolean implicit_keywords; /* the keywords were added by us */ +}; + +struct _Folder { + Entry entry; + + Folder *parent; + + char *desktop_file; /* the .directory file */ + + Query *query; + + /* The following is for per file + * access */ + /* excluded by filename */ + GHashTable *excludes; + /* included by filename */ + GSList *includes; + GHashTable *includes_ht; + + GSList *subfolders; + + /* Some flags */ + gboolean read_only; + gboolean dont_show_if_empty; + gboolean only_unallocated; /* include only unallocated items */ + + /* lazily done, will run query only when it + * needs to */ + gboolean up_to_date; + gboolean sorted; + GSList *entries; +}; + +struct _StatLoc { + time_t ctime; + time_t last_stat; + gboolean trigger_next; /* if true, next check will fail */ + char name[1]; /* the structure will be long enough to + fit name */ +}; + +struct _VFolderInfo { + char *scheme; + + char *filename; + char *user_filename; + time_t user_filename_last_write; + char *desktop_dir; /* directory with .directorys */ + char *user_desktop_dir; /* directory with .directorys */ + gboolean user_file_active; /* if using user_filename and + not filename */ + + GSList *item_dirs; + char *user_item_dir; /* dir where user changes to + items are stored */ + + /* old style dirs to merge in */ + GSList *merge_dirs; + + /* if entries are valid, else + * they need to be (re)read */ + gboolean entries_valid; + + GSList *entries; + + /* entry hash by basename */ + GHashTable *entries_ht; + + /* The root folder */ + Folder *root; + + /* The unallocated folders, the folder which only + * include unallocated items */ + GSList *unallocated_folders; + + /* some flags */ + gboolean read_only; + + gboolean dirty; + + int inhibit_write; + + /* change monitoring stuff */ + GnomeVFSMonitorHandle *filename_monitor; + GnomeVFSMonitorHandle *user_filename_monitor; + + /* stat locations (in case we aren't monitoring) */ + StatLoc *filename_statloc; + StatLoc *user_filename_statloc; + + /* for .directory dirs */ + /* FIXME: */GnomeVFSMonitorHandle *desktop_dir_monitor; + /* FIXME: */GnomeVFSMonitorHandle *user_desktop_dir_monitor; + + /* stat locations (in case we aren't monitoring) */ + /* FIXME: */StatLoc *desktop_dir_statloc; + /* FIXME: */StatLoc *user_desktop_dir_statloc; + + /* FIXME: */GSList *file_monitors; /* FileMonitorHandle */ + /* FIXME: */GSList *free_file_monitors; /* FileMonitorHandle */ + GSList *folder_monitors; /* FileMonitorHandle */ + GSList *free_folder_monitors; /* FileMonitorHandle */ + + GSList *item_dir_monitors; /* GnomeVFSMonitorHandle */ + + /* item dirs to stat */ + GSList *stat_dirs; + + /* ctime for folders */ + time_t modification_time; + + guint reread_queue; +}; + +struct _FileMonitorHandle { + int refcount; + gboolean exists; + gboolean dir_monitor; /* TRUE if dir, FALSE if file */ + GnomeVFSURI *uri; + GnomeVFSMonitorHandle *handle; /* A real handle if we're monitoring + an actual file here, or NULL */ + char *filename; /* Just the basename, used in the free_file_list */ + gboolean is_directory_file; +}; + +struct _VFolderURI { + const gchar *scheme; + gboolean is_all_scheme; + gboolean ends_in_slash; + gchar *path; + gchar *file; + GnomeVFSURI *uri; +}; + + +static Entry * entry_ref (Entry *entry); +static Entry * entry_ref_alloc (Entry *entry); +static void entry_unref (Entry *entry); +static void entry_unref_dealloc (Entry *entry); +static void query_destroy (Query *query); +static void ensure_folder (VFolderInfo *info, + Folder *folder, + gboolean subfolders, + Folder *except, + gboolean ignore_unallocated); +static void ensure_folder_unlocked (VFolderInfo *info, + Folder *folder, + gboolean subfolders, + Folder *except, + gboolean ignore_unallocated); +/* An EVIL function for quick reading of .desktop files, + * only reads in one or two keys, but that's ALL we need */ +static void readitem_entry (const char *filename, + const char *key1, + char **result1, + const char *key2, + char **result2); +static gboolean vfolder_info_reload (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context, + gboolean force_read_items); +static gboolean vfolder_info_reload_unlocked (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context, + gboolean force_read_items); +static void invalidate_folder_subfolders (Folder *folder, + gboolean lock_taken); +static Folder * resolve_folder (VFolderInfo *info, + const char *path, + gboolean ignore_basename, + GnomeVFSResult *result, + GnomeVFSContext *context); +static gboolean vfolder_info_read_items (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context); + +/* assumes vuri->path already set */ +static gboolean +vfolder_uri_parse_internal (GnomeVFSURI *uri, VFolderURI *vuri) +{ + vuri->scheme = (gchar *) gnome_vfs_uri_get_scheme (uri); + + vuri->ends_in_slash = FALSE; + + if (strncmp (vuri->scheme, "all-", strlen ("all-")) == 0) { + vuri->scheme += strlen ("all-"); + vuri->is_all_scheme = TRUE; + } else + vuri->is_all_scheme = FALSE; + + if (vuri->path != NULL) { + int last_slash = strlen (vuri->path) - 1; + char *first; + + /* Note: This handling of paths is somewhat evil, may need a + * bit of a rework */ + + /* kill leading slashes, that is make sure there is + * only one */ + for (first = vuri->path; *first == '/'; first++) + ; + if (first != vuri->path) { + first--; + vuri->path = first; + } + + /* kill trailing slashes (leave first if all slashes) */ + while (last_slash > 0 && vuri->path [last_slash] == '/') { + vuri->path [last_slash--] = '\0'; + vuri->ends_in_slash = TRUE; + } + + /* get basename start */ + while (last_slash >= 0 && vuri->path [last_slash] != '/') + last_slash--; + + if (last_slash > -1) + vuri->file = vuri->path + last_slash + 1; + else + vuri->file = vuri->path; + + if (vuri->file[0] == '\0' && + strcmp (vuri->path, "/") == 0) { + vuri->file = NULL; + } + } else { + vuri->ends_in_slash = TRUE; + vuri->path = "/"; + vuri->file = NULL; + } + + vuri->uri = uri; + + return TRUE; +} + +#define VFOLDER_URI_PARSE(_uri, _vuri) { \ + gchar *path; \ + path = gnome_vfs_unescape_string ((_uri)->text, G_DIR_SEPARATOR_S); \ + if (path != NULL) { \ + (_vuri)->path = g_alloca (strlen (path) + 1); \ + strcpy ((_vuri)->path, path); \ + g_free (path); \ + } else { \ + (_vuri)->path = NULL; \ + } \ + vfolder_uri_parse_internal ((_uri), (_vuri)); \ +} + +static FileMonitorHandle * +file_monitor_handle_ref_unlocked (FileMonitorHandle *h) +{ + h->refcount ++; + return h; +} + +static void +file_monitor_handle_unref_unlocked (FileMonitorHandle *h) +{ + h->refcount --; + if (h->refcount == 0) { + gnome_vfs_uri_unref (h->uri); + h->uri = NULL; + + g_free (h->filename); + h->filename = NULL; + + if (h->handle != NULL) { + gnome_vfs_monitor_cancel (h->handle); + h->handle = NULL; + } + } +} + +/* This includes the .directory files */ +static void +emit_monitor (Folder *folder, int type) +{ + GSList *li; + for (li = ((Entry *)folder)->monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *handle = li->data; + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *) handle, + handle->uri, type); + } +} + +static void +emit_file_deleted_monitor (VFolderInfo *info, Entry *entry, Folder *folder) +{ + GSList *li; + for (li = entry->monitors; + li != NULL; + li = li->next) { + VFolderURI vuri; + Folder *f; + GnomeVFSResult result; + FileMonitorHandle *handle = li->data; + + /* Evil! EVIL URI PARSING. this will eat a lot of + * stack if we have lots of monitors */ + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + f = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + + if (f == folder) + gnome_vfs_monitor_callback + ((GnomeVFSMethodHandle *) handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_DELETED); + } +} + +static void +emit_and_delete_monitor (VFolderInfo *info, Folder *folder) +{ + GSList *li; + for (li = ((Entry *)folder)->monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *handle = li->data; + li->data = NULL; + + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *) handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_DELETED); + + if (handle->dir_monitor) + info->free_folder_monitors = + g_slist_prepend (info->free_folder_monitors, + handle); + else + info->free_file_monitors = + g_slist_prepend (info->free_file_monitors, + handle); + } + g_slist_free (((Entry *)folder)->monitors); + ((Entry *)folder)->monitors = NULL; +} + +static gboolean +check_ext (const char *name, const char *ext_check) +{ + const char *ext; + + ext = strrchr (name, '.'); + if (ext == NULL || + strcmp (ext, ext_check) != 0) + return FALSE; + else + return TRUE; +} + +static StatLoc * +bake_statloc (const char *name, + time_t curtime) +{ + struct stat s; + StatLoc *sl = NULL; + if (stat (name, &s) != 0) { + if (errno == ENOENT) { + sl = g_malloc0 (sizeof (StatLoc) + + strlen (name) + 1); + sl->last_stat = curtime; + sl->ctime = 0; + sl->trigger_next = FALSE; + strcpy (sl->name, name); + } + return sl; + } + + sl = g_malloc0 (sizeof (StatLoc) + + strlen (name) + 1); + sl->last_stat = curtime; + sl->ctime = s.st_ctime; + sl->trigger_next = FALSE; + strcpy (sl->name, name); + + return sl; +} + +/* returns FALSE if we must reread */ +static gboolean +check_statloc (StatLoc *sl, + time_t curtime) +{ + struct stat s; + + if (sl->trigger_next) { + sl->trigger_next = FALSE; + return FALSE; + } + + /* don't stat more then once every 3 seconds */ + if (curtime <= sl->last_stat + 3) + return TRUE; + + sl->last_stat = curtime; + + if (stat (sl->name, &s) != 0) { + if (errno == ENOENT && + sl->ctime == 0) + return TRUE; + else + return FALSE; + } + + if (sl->ctime == s.st_ctime) + return TRUE; + else + return FALSE; +} + +static gboolean +ensure_dir (const char *dirname, gboolean ignore_basename) +{ + char *parsed, *p; + + if (dirname == NULL) + return FALSE; + + if (ignore_basename) + parsed = g_path_get_dirname (dirname); + else + parsed = g_strdup (dirname); + + if (g_file_test (parsed, G_FILE_TEST_IS_DIR)) { + g_free (parsed); + return TRUE; + } + + p = strchr (parsed, '/'); + if (p == parsed) + p = strchr (p+1, '/'); + + while (p != NULL) { + *p = '\0'; + if (mkdir (parsed, 0700) != 0 && + errno != EEXIST) { + g_free (parsed); + return FALSE; + } + *p = '/'; + p = strchr (p+1, '/'); + } + + if (mkdir (parsed, 0700) != 0 && + errno != EEXIST) { + g_free (parsed); + return FALSE; + } + + g_free (parsed); + return TRUE; +} + +/* check for any directory name other then root */ +static gboolean +any_subdir (const char *dirname) +{ + const char *p; + if (dirname == NULL) + return FALSE; + + for (p = dirname; *p != '\0'; p++) { + if (*p != '/') { + return TRUE; + } + } + return FALSE; +} + +static void +destroy_entry_file (EntryFile *efile) +{ + if (efile == NULL) + return; + + g_free (efile->filename); + efile->filename = NULL; + + g_slist_free (efile->keywords); + efile->keywords = NULL; + + g_free (efile); +} + +static void +destroy_folder (Folder *folder) +{ + GSList *list; + + if (folder == NULL) + return; + + if (folder->parent != NULL) { + folder->parent->subfolders = + g_slist_remove (folder->parent->subfolders, folder); + folder->parent->up_to_date = FALSE; + folder->parent = NULL; + } + + g_free (folder->desktop_file); + folder->desktop_file = NULL; + + query_destroy (folder->query); + folder->query = NULL; + + if (folder->excludes != NULL) { + g_hash_table_destroy (folder->excludes); + folder->excludes = NULL; + } + + g_slist_foreach (folder->includes, (GFunc)g_free, NULL); + g_slist_free (folder->includes); + folder->includes = NULL; + if (folder->includes_ht != NULL) { + g_hash_table_destroy (folder->includes_ht); + folder->includes_ht = NULL; + } + + list = folder->subfolders; + folder->subfolders = NULL; + g_slist_foreach (list, (GFunc)entry_unref, NULL); + g_slist_free (list); + + list = folder->entries; + folder->entries = NULL; + g_slist_foreach (list, (GFunc)entry_unref, NULL); + g_slist_free (list); + + g_free (folder); +} + +static Entry * +entry_ref (Entry *entry) +{ + if (entry != NULL) + entry->refcount++; + return entry; +} + +static Entry * +entry_ref_alloc (Entry *entry) +{ + entry_ref (entry); + + if (entry != NULL) + entry->alloc++; + + return entry; +} + +static void +entry_unref (Entry *entry) +{ + if (entry == NULL) + return; + + entry->refcount--; + + if (entry->refcount == 0) { + g_free (entry->name); + entry->name = NULL; + + g_slist_foreach (entry->monitors, + (GFunc)file_monitor_handle_unref_unlocked, + NULL); + g_slist_free (entry->monitors); + entry->monitors = NULL; + + if (entry->type == ENTRY_FILE) + destroy_entry_file ((EntryFile *)entry); + else /* ENTRY_FOLDER */ + destroy_folder ((Folder *)entry); + } +} + +static void +entry_unref_dealloc (Entry *entry) +{ + if (entry != NULL) { + entry->alloc --; + entry_unref (entry); + } +} + +/* Handles ONLY files, not dirs */ +/* Also allocates the entries as well as refs them */ +static GSList * +alloc_entries_from_files (VFolderInfo *info, GSList *filenames) +{ + GSList *li; + GSList *files; + + files = NULL; + for (li = filenames; li != NULL; li = li->next) { + char *filename = li->data; + GSList *entry_list = g_hash_table_lookup (info->entries_ht, filename); + if (entry_list != NULL) + files = g_slist_prepend (files, + entry_ref_alloc (entry_list->data)); + } + + return files; +} + +static gboolean +matches_query (VFolderInfo *info, + Folder *folder, + EntryFile *efile, + Query *query) +{ + GSList *li; + + if (query == NULL) + return TRUE; + +#define INVERT_IF_NEEDED(val) (query->not ? !(val) : (val)) + switch (query->type) { + case QUERY_OR: + for (li = query->queries; li != NULL; li = li->next) { + Query *subquery = li->data; + if (matches_query (info, folder, efile, subquery)) + return INVERT_IF_NEEDED (TRUE); + } + return INVERT_IF_NEEDED (FALSE); + case QUERY_AND: + for (li = query->queries; li != NULL; li = li->next) { + Query *subquery = li->data; + if ( ! matches_query (info, folder, efile, subquery)) + return INVERT_IF_NEEDED (FALSE); + } + return INVERT_IF_NEEDED (TRUE); + case QUERY_KEYWORD: + { + QueryKeyword *qkeyword = (QueryKeyword *)query; + for (li = efile->keywords; li != NULL; li = li->next) { + GQuark keyword = GPOINTER_TO_INT (li->data); + if (keyword == qkeyword->keyword) + return INVERT_IF_NEEDED (TRUE); + } + return INVERT_IF_NEEDED (FALSE); + } + case QUERY_FILENAME: + { + QueryFilename *qfilename = (QueryFilename *)query; + if (strcmp (qfilename->filename, ((Entry *)efile)->name) == 0) { + return INVERT_IF_NEEDED (TRUE); + } else { + return INVERT_IF_NEEDED (FALSE); + } + } + } +#undef INVERT_IF_NEEDED + g_assert_not_reached (); + /* huh? */ + return FALSE; +} + +static void +dump_unallocated_folders (Folder *folder) +{ + GSList *li; + for (li = folder->subfolders; li != NULL; li = li->next) + dump_unallocated_folders (li->data); + + if (folder->only_unallocated && + folder->entries != NULL) { + g_slist_foreach (folder->entries, + (GFunc)entry_unref_dealloc, NULL); + g_slist_free (folder->entries); + folder->entries = NULL; + } +} + +/* Run query, allocs and refs the entries */ +static void +append_query (VFolderInfo *info, Folder *folder) +{ + GSList *li; + + if (folder->query == NULL && + ! folder->only_unallocated) + return; + + if (folder->only_unallocated) { + /* dump all folders that use unallocated + * items only. This sucks if you keep + * reading one and then another such + * folder, but oh well, life sucks for + * you then, but at least you get + * consistent results */ + dump_unallocated_folders (info->root); + + /* ensure all other folders, so that + * after this we know which ones are + * unallocated */ + ensure_folder_unlocked (info, + info->root, + TRUE /* subfolders */, + folder /* except */, + /* avoid infinite loops */ + TRUE /* ignore_unallocated */); + } + + for (li = info->entries; li != NULL; li = li->next) { + Entry *entry = li->data; + + if (/* if not file */ + entry->type != ENTRY_FILE || + /* if already included */ + (folder->includes_ht != NULL && + g_hash_table_lookup (folder->includes_ht, + entry->name) != NULL)) + continue; + + if (folder->only_unallocated && + entry->alloc != 0) + continue; + + if (matches_query (info, folder, (EntryFile *)entry, + folder->query)) + folder->entries = g_slist_prepend + (folder->entries, entry_ref_alloc (entry)); + } +} + +/* get entries in folder */ +/* FIXME: support cancellation here */ +static void +ensure_folder_unlocked (VFolderInfo *info, + Folder *folder, + gboolean subfolders, + Folder *except, + gboolean ignore_unallocated) +{ + if (subfolders) { + GSList *li; + for (li = folder->subfolders; li != NULL; li = li->next) + ensure_folder_unlocked (info, li->data, subfolders, + except, ignore_unallocated); + } + + if (except == folder) + return; + + if (ignore_unallocated && + folder->only_unallocated) + return; + + if (folder->up_to_date) + return; + + if (folder->entries != NULL) { + g_slist_foreach (folder->entries, + (GFunc)entry_unref_dealloc, NULL); + g_slist_free (folder->entries); + folder->entries = NULL; + } + + /* Include includes */ + folder->entries = alloc_entries_from_files (info, folder->includes); + + /* Run query */ + append_query (info, folder); + + /* We were prepending all this time */ + folder->entries = g_slist_reverse (folder->entries); + + /* Include subfolders */ + /* we always whack them onto the beginning */ + if (folder->subfolders != NULL) { + GSList *subfolders = g_slist_copy (folder->subfolders); + g_slist_foreach (subfolders, (GFunc)entry_ref_alloc, NULL); + folder->entries = g_slist_concat (subfolders, folder->entries); + } + + /* Exclude excludes */ + if (folder->excludes != NULL) { + GSList *li; + GSList *entries = folder->entries; + folder->entries = NULL; + for (li = entries; li != NULL; li = li->next) { + Entry *entry = li->data; + if (g_hash_table_lookup (folder->excludes, entry->name) == NULL) + folder->entries = g_slist_prepend (folder->entries, entry); + else + entry_unref_dealloc (entry); + + } + g_slist_free (entries); + + /* to preserve the Folders then everything else order */ + folder->entries = g_slist_reverse (folder->entries); + } + + folder->up_to_date = TRUE; + /* not yet sorted */ + folder->sorted = FALSE; +} + +static void +ensure_folder (VFolderInfo *info, + Folder *folder, + gboolean subfolders, + Folder *except, + gboolean ignore_unallocated) +{ + G_LOCK (vfolder_lock); + ensure_folder_unlocked (info, folder, subfolders, except, ignore_unallocated); + G_UNLOCK (vfolder_lock); +} + +static char * +get_directory_file_unlocked (VFolderInfo *info, Folder *folder) +{ + char *filename; + + /* FIXME: cache dir_files */ + + if (folder->desktop_file == NULL) + return NULL; + + if (folder->desktop_file[0] == G_DIR_SEPARATOR) + return g_strdup (folder->desktop_file); + + /* Now try the user directory */ + if (info->user_desktop_dir != NULL) { + filename = g_build_filename (info->user_desktop_dir, + folder->desktop_file, + NULL); + if (access (filename, F_OK) == 0) { + return filename; + } + + g_free (filename); + } + + filename = g_build_filename (info->desktop_dir, folder->desktop_file, NULL); + if (access (filename, F_OK) == 0) { + return filename; + } + g_free (filename); + + return NULL; +} + +static char * +get_directory_file (VFolderInfo *info, Folder *folder) +{ + char *ret; + + G_LOCK (vfolder_lock); + ret = get_directory_file_unlocked (info, folder); + G_UNLOCK (vfolder_lock); + + return ret; +} + +static GSList * +get_sort_order (VFolderInfo *info, Folder *folder) +{ + GSList *list; + char **parsed; + char *order; + int i; + char *filename; + + filename = get_directory_file_unlocked (info, folder); + if (filename == NULL) + return NULL; + + order = NULL; + readitem_entry (filename, + "SortOrder", + &order, + NULL, + NULL); + g_free (filename); + + if (order == NULL) + return NULL; + + parsed = g_strsplit (order, ":", -1); + + g_free (order); + + list = NULL; + for (i = 0; parsed[i] != NULL; i++) { + char *word = parsed[i]; + /* steal */ + parsed[i] = NULL; + /* ignore empty */ + if (word[0] == '\0') { + g_free (word); + continue; + } + list = g_slist_prepend (list, word); + } + /* we've stolen all strings from it */ + g_free (parsed); + + return g_slist_reverse (list); +} + +/* get entries in folder */ +static void +ensure_folder_sort (VFolderInfo *info, Folder *folder) +{ + GSList *li, *sort_order; + GSList *entries; + GHashTable *entry_hash; + + ensure_folder (info, folder, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + if (folder->sorted) + return; + + G_LOCK (vfolder_lock); + + sort_order = get_sort_order (info, folder); + if (sort_order == NULL) { + folder->sorted = TRUE; + G_UNLOCK (vfolder_lock); + return; + } + + entries = folder->entries; + folder->entries = NULL; + + entry_hash = g_hash_table_new (g_str_hash, g_str_equal); + for (li = entries; li != NULL; li = li->next) { + Entry *entry = li->data; + g_hash_table_insert (entry_hash, entry->name, li); + } + + for (li = sort_order; li != NULL; li = li->next) { + char *word = li->data; + GSList *entry_list; + Entry *entry; + + /* we kill the words here */ + li->data = NULL; + + entry_list = g_hash_table_lookup (entry_hash, word); + g_free (word); + + if (entry_list == NULL) + continue; + + entry = entry_list->data; + + entries = g_slist_delete_link (entries, entry_list); + + folder->entries = g_slist_prepend (folder->entries, + entry); + } + + /* put on those that weren't mentioned in the sort */ + for (li = entries; li != NULL; li = li->next) { + Entry *entry = li->data; + + folder->entries = g_slist_prepend (folder->entries, + entry); + } + + g_hash_table_destroy (entry_hash); + g_slist_free (entries); + g_slist_free (sort_order); + + folder->sorted = TRUE; + + G_UNLOCK (vfolder_lock); +} + +static EntryFile * +file_new (const char *name) +{ + EntryFile *efile = g_new0 (EntryFile, 1); + + efile->entry.type = ENTRY_FILE; + efile->entry.name = g_strdup (name); + efile->entry.refcount = 1; + + return efile; +} + +static Folder * +folder_new (const char *name) +{ + Folder *folder = g_new0 (Folder, 1); + + folder->entry.type = ENTRY_FOLDER; + folder->entry.name = g_strdup (name); + folder->entry.refcount = 1; + + return folder; +} + +static Query * +query_new (int type) +{ + Query *query; + + if (type == QUERY_KEYWORD) + query = (Query *)g_new0 (QueryKeyword, 1); + else if (type == QUERY_FILENAME) + query = (Query *)g_new0 (QueryFilename, 1); + else + query = g_new0 (Query, 1); + + query->type = type; + + return query; +} + +static void +query_destroy (Query *query) +{ + if (query == NULL) + return; + + if (query->type == QUERY_FILENAME) { + QueryFilename *qfile = (QueryFilename *)query; + g_free (qfile->filename); + qfile->filename = NULL; + } else if (query->type == QUERY_OR || + query->type == QUERY_AND) { + g_slist_foreach (query->queries, (GFunc)query_destroy, NULL); + g_slist_free (query->queries); + query->queries = NULL; + } + + g_free (query); +} + +static void +add_folder_monitor_unlocked (VFolderInfo *info, + FileMonitorHandle *handle) +{ + VFolderURI vuri; + GnomeVFSResult result; + Folder *folder; + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + file_monitor_handle_ref_unlocked (handle); + + info->folder_monitors = + g_slist_prepend (info->folder_monitors, handle); + + folder = resolve_folder (info, + vuri.path, + FALSE /* ignore_basename */, + &result, + NULL); + + if (folder == NULL) { + file_monitor_handle_ref_unlocked (handle); + + info->free_folder_monitors = + g_slist_prepend (info->free_folder_monitors, handle); + + if (handle->exists) { + handle->exists = FALSE; + gnome_vfs_monitor_callback + ((GnomeVFSMethodHandle *)handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_DELETED); + } + } else { + file_monitor_handle_ref_unlocked (handle); + + ((Entry *)folder)->monitors = + g_slist_prepend (((Entry *)folder)->monitors, handle); + + if ( ! handle->exists) { + handle->exists = TRUE; + gnome_vfs_monitor_callback + ((GnomeVFSMethodHandle *)handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_CREATED); + } + } + +} + +static inline void +invalidate_folder_T (Folder *folder) +{ + folder->up_to_date = FALSE; + + invalidate_folder_subfolders (folder, TRUE); +} + +static inline void +invalidate_folder (Folder *folder) +{ + G_LOCK (vfolder_lock); + folder->up_to_date = FALSE; + G_UNLOCK (vfolder_lock); + + invalidate_folder_subfolders (folder, FALSE); +} + +static void +invalidate_folder_subfolders (Folder *folder, + gboolean lock_taken) +{ + GSList *li; + + for (li = folder->subfolders; li != NULL; li = li->next) { + Folder *subfolder = li->data; + + if (!lock_taken) + invalidate_folder (subfolder); + else + invalidate_folder_T (subfolder); + } + + emit_monitor (folder, GNOME_VFS_MONITOR_EVENT_CHANGED); +} + +/* FIXME: this is UGLY!, we need to figure out when the file + * got finished changing! */ +static gboolean +reread_timeout (gpointer data) +{ + VFolderInfo *info = data; + gboolean force_read_items = info->file_monitors != NULL; + vfolder_info_reload (info, NULL, NULL, force_read_items); + return FALSE; +} + +static void +queue_reread_in (VFolderInfo *info, int msec) +{ + G_LOCK (vfolder_lock); + if (info->reread_queue != 0) + g_source_remove (info->reread_queue); + info->reread_queue = g_timeout_add (msec, reread_timeout, info); + G_UNLOCK (vfolder_lock); +} + +static void +vfolder_desktop_dir_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + /* FIXME: implement */ +} + +static void +vfolder_user_desktop_dir_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + /* FIXME: implement */ +} + +static void +vfolder_filename_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + VFolderInfo *info = user_data; + + if ((event_type == GNOME_VFS_MONITOR_EVENT_CREATED || + event_type == GNOME_VFS_MONITOR_EVENT_CHANGED) && + ! info->user_file_active) { + queue_reread_in (info, 200); + } else if (event_type == GNOME_VFS_MONITOR_EVENT_DELETED && + ! info->user_file_active) { + /* FIXME: is this correct? I mean now + * there probably isn't ANY vfolder file, so we + * init to default values really. I have no clue what's + * right here */ + vfolder_info_reload (info, NULL, NULL, + TRUE /* force read items */); + } +} + +static void +vfolder_user_filename_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + VFolderInfo *info = user_data; + + if ((event_type == GNOME_VFS_MONITOR_EVENT_CREATED || + event_type == GNOME_VFS_MONITOR_EVENT_CHANGED) && + info->user_file_active) { + struct stat s; + + /* see if this was really our own change */ + if (info->user_filename_last_write == time (NULL)) + return; + /* anal retentive */ + if (stat (info->user_filename, &s) == 0 && + info->user_filename_last_write == s.st_ctime) + return; + + queue_reread_in (info, 200); + } else if ((event_type == GNOME_VFS_MONITOR_EVENT_CREATED || + event_type == GNOME_VFS_MONITOR_EVENT_CHANGED) && + ! info->user_file_active) { + queue_reread_in (info, 200); + } else if (event_type == GNOME_VFS_MONITOR_EVENT_DELETED && + info->user_file_active) { + gboolean force_read_items = info->file_monitors != NULL; + vfolder_info_reload (info, NULL, NULL, force_read_items); + } +} + +static void +item_dir_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + VFolderInfo *info = user_data; + + if (event_type == GNOME_VFS_MONITOR_EVENT_CREATED || + event_type == GNOME_VFS_MONITOR_EVENT_CHANGED) { + /* first invalidate all folders */ + invalidate_folder (info->root); + /* second invalidate all entries */ + info->entries_valid = FALSE; + + if (info->file_monitors != NULL) { + GnomeVFSResult result; + GSList *li; + + /* Whack all monitors here! */ + for (li = info->file_monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *h = li->data; + if (h->handle != NULL) + gnome_vfs_monitor_cancel (h->handle); + h->handle = NULL; + } + + if (vfolder_info_read_items (info, &result, NULL)) { + info->entries_valid = TRUE; + } + } + } +} + +static gboolean +setup_dir_monitor (VFolderInfo *info, const char *dir, gboolean subdirs, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + GnomeVFSMonitorHandle *handle; + DIR *dh; + struct dirent *de; + char *uri; + + uri = gnome_vfs_get_uri_from_local_path (dir); + + if (gnome_vfs_monitor_add (&handle, + uri, + GNOME_VFS_MONITOR_DIRECTORY, + item_dir_monitor, + info) != GNOME_VFS_OK) { + StatLoc *sl = bake_statloc (dir, time (NULL)); + if (sl != NULL) + info->stat_dirs = g_slist_prepend (info->stat_dirs, sl); + g_free (uri); + return TRUE; + } + g_free (uri); + + if (gnome_vfs_context_check_cancellation (context)) { + gnome_vfs_monitor_cancel (handle); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + info->item_dir_monitors = + g_slist_prepend (info->item_dir_monitors, handle); + + if ( ! subdirs) + return TRUE; + + dh = opendir (dir); + if (dh == NULL) + return TRUE; + + while ((de = readdir (dh)) != NULL) { + char *full_path; + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + closedir (dh); + return FALSE; + } + + if (de->d_name[0] == '.') + continue; + + full_path = g_build_filename (dir, de->d_name, NULL); + if (g_file_test (full_path, G_FILE_TEST_IS_DIR)) { + if ( ! setup_dir_monitor (info, full_path, + TRUE /* subdirs */, + result, context)) { + closedir (dh); + return FALSE; + } + } + g_free (full_path); + } + + closedir (dh); + + return TRUE; +} + +static gboolean +monitor_setup (VFolderInfo *info, + gboolean setup_filenames, + gboolean setup_itemdirs, + gboolean setup_desktop_dirs, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + char *uri; + GSList *li; + + if (setup_filenames) { + uri = gnome_vfs_get_uri_from_local_path + (info->filename); + + if (gnome_vfs_monitor_add (&info->filename_monitor, + uri, + GNOME_VFS_MONITOR_FILE, + vfolder_filename_monitor, + info) != GNOME_VFS_OK) { + info->filename_monitor = NULL; + info->filename_statloc = bake_statloc (info->filename, + time (NULL)); + } + g_free (uri); + } + if (setup_filenames && + info->user_filename != NULL) { + uri = gnome_vfs_get_uri_from_local_path + (info->user_filename); + if (gnome_vfs_monitor_add (&info->user_filename_monitor, + uri, + GNOME_VFS_MONITOR_FILE, + vfolder_user_filename_monitor, + info) != GNOME_VFS_OK) { + info->user_filename_monitor = NULL; + info->user_filename_statloc = + bake_statloc (info->user_filename, + time (NULL)); + } + + g_free (uri); + } + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + if (setup_itemdirs) { + for (li = info->item_dirs; li != NULL; li = li->next) { + const char *dir = li->data; + if ( ! setup_dir_monitor (info, dir, + FALSE /* subdirs */, + result, context)) + return FALSE; + } + if (info->user_item_dir != NULL) { + if ( ! setup_dir_monitor (info, info->user_item_dir, + FALSE /* subdirs */, + result, context)) + return FALSE; + } + for (li = info->merge_dirs; li != NULL; li = li->next) { + const char *dir = li->data; + if ( ! setup_dir_monitor (info, dir, + TRUE /* subdirs */, + result, context)) + return FALSE; + } + } + + if (setup_desktop_dirs) { + uri = gnome_vfs_get_uri_from_local_path + (info->desktop_dir); + + if (gnome_vfs_monitor_add (&info->desktop_dir_monitor, + uri, + GNOME_VFS_MONITOR_FILE, + vfolder_desktop_dir_monitor, + info) != GNOME_VFS_OK) { + info->desktop_dir_monitor = NULL; + info->desktop_dir_statloc = + bake_statloc (info->desktop_dir, + time (NULL)); + } + g_free (uri); + } + if (setup_desktop_dirs && + info->user_desktop_dir != NULL) { + uri = gnome_vfs_get_uri_from_local_path + (info->user_desktop_dir); + if (gnome_vfs_monitor_add (&info->user_desktop_dir_monitor, + uri, + GNOME_VFS_MONITOR_DIRECTORY, + vfolder_user_desktop_dir_monitor, + info) != GNOME_VFS_OK) { + info->user_desktop_dir_monitor = NULL; + info->user_desktop_dir_statloc = + bake_statloc (info->user_desktop_dir, + time (NULL)); + } + + g_free (uri); + } + + return TRUE; +} + +static void +vfolder_info_init (VFolderInfo *info, const char *scheme) +{ + const char *path; + GSList *list; + + info->scheme = g_strdup (scheme); + + info->filename = g_strconcat (SYSCONFDIR, "/X11/desktop-menus/", + scheme, ".menu", + NULL); + info->user_filename = g_strconcat (g_get_home_dir (), + "/" DOT_GNOME "/vfolders/", + scheme, ".vfolder-info", + NULL); + info->desktop_dir = g_strconcat (SYSCONFDIR, + "/gnome-vfs-2.0/vfolders/", + NULL); + info->user_desktop_dir = g_strconcat (g_get_home_dir (), + "/" DOT_GNOME "/vfolders/", + NULL); + + /* Init the desktop paths */ + list = NULL; + list = g_slist_prepend (list, g_strdup ("/usr/share/applications/")); + if (strcmp ("/usr/share/applications/", DATADIR "/applications/") != 0) + list = g_slist_prepend (list, g_strdup (DATADIR "/applications/")); + path = g_getenv ("DESKTOP_FILE_PATH"); + if (path != NULL) { + int i; + char **ppath = g_strsplit (path, ":", -1); + for (i = 0; ppath[i] != NULL; i++) { + const char *dir = ppath[i]; + list = g_slist_prepend (list, g_strdup (dir)); + } + g_strfreev (ppath); + } + info->item_dirs = g_slist_reverse (list); + + info->user_item_dir = g_strconcat (g_get_home_dir (), + "/" DOT_GNOME "/vfolders/", + scheme, + NULL); + + info->entries_ht = g_hash_table_new (g_str_hash, g_str_equal); + + info->root = folder_new ("Root"); + + info->modification_time = time (NULL); +} + +static void +vfolder_info_free_internals_unlocked (VFolderInfo *info) +{ + if (info == NULL) + return; + + if (info->filename_monitor != NULL) { + gnome_vfs_monitor_cancel (info->filename_monitor); + info->filename_monitor = NULL; + } + + if (info->user_filename_monitor != NULL) { + gnome_vfs_monitor_cancel (info->user_filename_monitor); + info->user_filename_monitor = NULL; + } + + g_free (info->filename_statloc); + info->filename_statloc = NULL; + + g_free (info->user_filename_statloc); + info->user_filename_statloc = NULL; + + + if (info->desktop_dir_monitor != NULL) { + gnome_vfs_monitor_cancel (info->desktop_dir_monitor); + info->desktop_dir_monitor = NULL; + } + + if (info->user_desktop_dir_monitor != NULL) { + gnome_vfs_monitor_cancel (info->user_desktop_dir_monitor); + info->user_desktop_dir_monitor = NULL; + } + + g_free (info->desktop_dir_statloc); + info->desktop_dir_statloc = NULL; + + g_free (info->user_desktop_dir_statloc); + info->user_desktop_dir_statloc = NULL; + + + g_slist_foreach (info->item_dir_monitors, + (GFunc)gnome_vfs_monitor_cancel, NULL); + g_slist_free (info->item_dir_monitors); + info->item_dir_monitors = NULL; + + g_free (info->scheme); + info->scheme = NULL; + + g_free (info->filename); + info->filename = NULL; + + g_free (info->user_filename); + info->user_filename = NULL; + + g_free (info->desktop_dir); + info->desktop_dir = NULL; + + g_free (info->user_desktop_dir); + info->user_desktop_dir = NULL; + + g_slist_foreach (info->item_dirs, (GFunc)g_free, NULL); + g_slist_free (info->item_dirs); + info->item_dirs = NULL; + + g_free (info->user_item_dir); + info->user_item_dir = NULL; + + g_slist_foreach (info->merge_dirs, (GFunc)g_free, NULL); + g_slist_free (info->merge_dirs); + info->merge_dirs = NULL; + + g_slist_foreach (info->entries, (GFunc)entry_unref, NULL); + g_slist_free (info->entries); + info->entries = NULL; + + if (info->entries_ht != NULL) + g_hash_table_destroy (info->entries_ht); + info->entries_ht = NULL; + + g_slist_foreach (info->unallocated_folders, + (GFunc)entry_unref, + NULL); + g_slist_free (info->unallocated_folders); + info->unallocated_folders = NULL; + + entry_unref ((Entry *)info->root); + info->root = NULL; + + g_slist_foreach (info->stat_dirs, (GFunc)g_free, NULL); + g_slist_free (info->stat_dirs); + info->stat_dirs = NULL; + + g_slist_foreach (info->folder_monitors, + (GFunc)file_monitor_handle_unref_unlocked, NULL); + g_slist_free (info->folder_monitors); + info->folder_monitors = NULL; + + g_slist_foreach (info->free_folder_monitors, + (GFunc)file_monitor_handle_unref_unlocked, NULL); + g_slist_free (info->free_folder_monitors); + info->free_folder_monitors = NULL; + + g_slist_foreach (info->file_monitors, + (GFunc)file_monitor_handle_unref_unlocked, NULL); + g_slist_free (info->file_monitors); + info->file_monitors = NULL; + + g_slist_foreach (info->free_file_monitors, + (GFunc)file_monitor_handle_unref_unlocked, NULL); + g_slist_free (info->free_file_monitors); + info->free_file_monitors = NULL; + + if (info->reread_queue != 0) + g_source_remove (info->reread_queue); + info->reread_queue = 0; +} + +static void +vfolder_info_free_internals (VFolderInfo *info) +{ + G_LOCK (vfolder_lock); + vfolder_info_free_internals_unlocked (info); + G_UNLOCK (vfolder_lock); +} + +static void +vfolder_info_destroy (VFolderInfo *info) +{ + vfolder_info_free_internals (info); + g_free (info); +} + +static Query * +single_query_read (xmlNode *qnode) +{ + Query *query; + xmlNode *node; + + if (qnode->type != XML_ELEMENT_NODE || + qnode->name == NULL) + return NULL; + + query = NULL; + + if (g_ascii_strcasecmp (qnode->name, "Not") == 0 && + qnode->xmlChildrenNode != NULL) { + xmlNode *iter; + query = NULL; + for (iter = qnode->xmlChildrenNode; + iter != NULL && query == NULL; + iter = iter->next) + query = single_query_read (iter); + if (query != NULL) { + query->not = ! query->not; + } + return query; + } else if (g_ascii_strcasecmp (qnode->name, "Keyword") == 0) { + xmlChar *word = xmlNodeGetContent (qnode); + if (word != NULL) { + query = query_new (QUERY_KEYWORD); + ((QueryKeyword *)query)->keyword = + g_quark_from_string (word); + + xmlFree (word); + } + return query; + } else if (g_ascii_strcasecmp (qnode->name, "Filename") == 0) { + xmlChar *file = xmlNodeGetContent (qnode); + if (file != NULL) { + query = query_new (QUERY_FILENAME); + ((QueryFilename *)query)->filename = + g_strdup (file); + + xmlFree (file); + } + return query; + } else if (g_ascii_strcasecmp (qnode->name, "And") == 0) { + query = query_new (QUERY_AND); + } else if (g_ascii_strcasecmp (qnode->name, "Or") == 0) { + query = query_new (QUERY_OR); + } else { + /* We don't understand */ + return NULL; + } + + /* This must be OR or AND */ + g_assert (query != NULL); + + for (node = qnode->xmlChildrenNode; node != NULL; node = node->next) { + Query *new_query = single_query_read (node); + + if (new_query != NULL) + query->queries = g_slist_prepend + (query->queries, new_query); + } + + query->queries = g_slist_reverse (query->queries); + + return query; +} + +static void +add_or_set_query (Query **query, Query *new_query) +{ + if (*query == NULL) { + *query = new_query; + } else { + Query *old_query = *query; + *query = query_new (QUERY_OR); + (*query)->queries = + g_slist_append ((*query)->queries, old_query); + (*query)->queries = + g_slist_append ((*query)->queries, new_query); + } +} + +static Query * +query_read (xmlNode *qnode) +{ + Query *query; + xmlNode *node; + + query = NULL; + + for (node = qnode->xmlChildrenNode; node != NULL; node = node->next) { + if (node->type != XML_ELEMENT_NODE || + node->name == NULL) + continue; + + if (g_ascii_strcasecmp (node->name, "Not") == 0 && + node->xmlChildrenNode != NULL) { + xmlNode *iter; + Query *new_query = NULL; + + for (iter = node->xmlChildrenNode; + iter != NULL && new_query == NULL; + iter = iter->next) + new_query = single_query_read (iter); + if (new_query != NULL) { + new_query->not = ! new_query->not; + add_or_set_query (&query, new_query); + } + } else { + Query *new_query = single_query_read (node); + if (new_query != NULL) + add_or_set_query (&query, new_query); + } + } + + return query; +} + +static Folder * +folder_read (VFolderInfo *info, xmlNode *fnode) +{ + Folder *folder; + xmlNode *node; + + folder = folder_new (NULL); + + for (node = fnode->xmlChildrenNode; node != NULL; node = node->next) { + if (node->type != XML_ELEMENT_NODE || + node->name == NULL) + continue; + + if (g_ascii_strcasecmp (node->name, "Name") == 0) { + xmlChar *name = xmlNodeGetContent (node); + if (name != NULL) { + g_free (folder->entry.name); + folder->entry.name = g_strdup (name); + xmlFree (name); + } + } else if (g_ascii_strcasecmp (node->name, "Desktop") == 0) { + xmlChar *desktop = xmlNodeGetContent (node); + if (desktop != NULL) { + g_free (folder->desktop_file); + folder->desktop_file = g_strdup (desktop); + xmlFree (desktop); + } + } else if (g_ascii_strcasecmp (node->name, "Include") == 0) { + xmlChar *file = xmlNodeGetContent (node); + if (file != NULL) { + GSList *li; + char *str = g_strdup (file); + folder->includes = g_slist_prepend + (folder->includes, str); + if (folder->includes_ht == NULL) { + folder->includes_ht = + g_hash_table_new_full + (g_str_hash, + g_str_equal, + NULL, + NULL); + } + li = g_hash_table_lookup (folder->includes_ht, + file); + if (li != NULL) { + g_free (li->data); + /* Note: this will NOT change folder->includes + * pointer! */ + folder->includes = g_slist_delete_link + (folder->includes, li); + } + g_hash_table_replace (folder->includes_ht, + file, folder->includes); + xmlFree (file); + } + } else if (g_ascii_strcasecmp (node->name, "Exclude") == 0) { + xmlChar *file = xmlNodeGetContent (node); + if (file != NULL) { + char *s; + if (folder->excludes == NULL) { + folder->excludes = g_hash_table_new_full + (g_str_hash, + g_str_equal, + (GDestroyNotify)g_free, + NULL); + } + s = g_strdup (file); + g_hash_table_replace (folder->excludes, s, s); + xmlFree (file); + } + } else if (g_ascii_strcasecmp (node->name, "Query") == 0) { + Query *query; + + query = query_read (node); + + if (query != NULL) { + if (folder->query != NULL) + query_destroy (folder->query); + folder->query = query; + } + } else if (g_ascii_strcasecmp (node->name, "OnlyUnallocated") == 0) { + info->unallocated_folders = + g_slist_prepend (info->unallocated_folders, + (Folder *)entry_ref ((Entry *)folder)); + folder->only_unallocated = TRUE; + } else if (g_ascii_strcasecmp (node->name, "Folder") == 0) { + Folder *new_folder = folder_read (info, node); + if (new_folder != NULL) { + folder->subfolders = + g_slist_append (folder->subfolders, + new_folder); + new_folder->parent = folder; + } + } else if (g_ascii_strcasecmp (node->name, "ReadOnly") == 0) { + folder->read_only = TRUE; + } else if (g_ascii_strcasecmp (node->name, + "DontShowIfEmpty") == 0) { + folder->dont_show_if_empty = TRUE; + } + } + + /* Name is required */ + if (folder->entry.name == NULL) { + entry_unref ((Entry *)folder); + folder = NULL; + } + + folder->includes = g_slist_reverse (folder->includes); + + return folder; +} + +static char * +subst_home (const char *dir) +{ + if (dir[0] == '~') + return g_strconcat (g_get_home_dir (), + &dir[1], + NULL); + else + return g_strdup (dir); +} + +/* FORMAT looks like: + * + * + * /etc/X11/applnk + * + * /usr/share/applications + * + * /etc/X11/gnome/vfolders + * + * + * Root + * + * important.desktop + * + * + * + * SomeFolder + * + * + * Test_Folder + * + * Test_Folder.directory + * + * + * + * Application + * Game + * + * Clock + * + * + * somefile.desktop + * someotherfile.desktop + * yetanother.desktop + * + * + * + */ + +static gboolean +vfolder_info_read_info (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + xmlDoc *doc; + xmlNode *node; + gboolean got_a_vfolder_dir = FALSE; + + doc = NULL; + if (info->user_filename != NULL && + access (info->user_filename, F_OK) == 0) { + doc = xmlParseFile (info->user_filename); + if (doc != NULL) + info->user_file_active = TRUE; + } + if (doc == NULL && + access (info->filename, F_OK) == 0) + doc = xmlParseFile (info->filename); + + if (gnome_vfs_context_check_cancellation (context)) { + xmlFreeDoc(doc); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + if (doc == NULL + || doc->xmlRootNode == NULL + || doc->xmlRootNode->name == NULL + || g_ascii_strcasecmp (doc->xmlRootNode->name, "VFolderInfo") != 0) { + xmlFreeDoc(doc); + return TRUE; /* FIXME: really, shouldn't we error out? */ + } + + for (node = doc->xmlRootNode->xmlChildrenNode; node != NULL; node = node->next) { + if (node->type != XML_ELEMENT_NODE || + node->name == NULL) + continue; + + if (gnome_vfs_context_check_cancellation (context)) { + xmlFreeDoc(doc); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + if (g_ascii_strcasecmp (node->name, "MergeDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + if (dir != NULL) { + info->merge_dirs = g_slist_append (info->merge_dirs, + g_strdup (dir)); + xmlFree (dir); + } + } else if (g_ascii_strcasecmp (node->name, "ItemDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + if (dir != NULL) { + if ( ! got_a_vfolder_dir) { + g_slist_foreach (info->item_dirs, + (GFunc)g_free, NULL); + g_slist_free (info->item_dirs); + info->item_dirs = NULL; + } + got_a_vfolder_dir = TRUE; + info->item_dirs = g_slist_append (info->item_dirs, + g_strdup (dir)); + xmlFree (dir); + } + } else if (g_ascii_strcasecmp (node->name, "UserItemDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + if (dir != NULL) { + g_free (info->user_item_dir); + info->user_item_dir = subst_home (dir); + xmlFree (dir); + } + } else if (g_ascii_strcasecmp (node->name, "DesktopDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + if (dir != NULL) { + g_free (info->desktop_dir); + info->desktop_dir = g_strdup (dir); + xmlFree (dir); + } + } else if (g_ascii_strcasecmp (node->name, "UserDesktopDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + if (dir != NULL) { + g_free (info->user_desktop_dir); + info->user_desktop_dir = subst_home (dir); + xmlFree (dir); + } + } else if (g_ascii_strcasecmp (node->name, "Folder") == 0) { + Folder *folder = folder_read (info, node); + if (folder != NULL) { + if (info->root != NULL) + entry_unref ((Entry *)info->root); + info->root = folder; + } + } else if (g_ascii_strcasecmp (node->name, "ReadOnly") == 0) { + info->read_only = TRUE; + } + } + + xmlFreeDoc(doc); + + return TRUE; +} + +static void +add_xml_tree_from_query (xmlNode *parent, Query *query) +{ + xmlNode *real_parent; + + if (query->not) + real_parent = xmlNewChild (parent /* parent */, + NULL /* ns */, + "Not" /* name */, + NULL /* content */); + else + real_parent = parent; + + if (query->type == QUERY_KEYWORD) { + QueryKeyword *qkeyword = (QueryKeyword *)query; + const char *string = g_quark_to_string (qkeyword->keyword); + + xmlNewChild (real_parent /* parent */, + NULL /* ns */, + "Keyword" /* name */, + string /* content */); + } else if (query->type == QUERY_FILENAME) { + QueryFilename *qfilename = (QueryFilename *)query; + + xmlNewChild (real_parent /* parent */, + NULL /* ns */, + "Filename" /* name */, + qfilename->filename /* content */); + } else if (query->type == QUERY_OR || + query->type == QUERY_AND) { + xmlNode *node; + const char *name; + GSList *li; + + if (query->type == QUERY_OR) + name = "Or"; + else /* QUERY_AND */ + name = "And"; + + node = xmlNewChild (real_parent /* parent */, + NULL /* ns */, + name /* name */, + NULL /* content */); + + for (li = query->queries; li != NULL; li = li->next) { + Query *subquery = li->data; + add_xml_tree_from_query (node, subquery); + } + } else { + g_assert_not_reached (); + } +} + +static void +add_excludes_to_xml (gpointer key, gpointer value, gpointer user_data) +{ + const char *filename = key; + xmlNode *folder_node = user_data; + + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Exclude" /* name */, + filename /* content */); +} + +static void +add_xml_tree_from_folder (xmlNode *parent, Folder *folder) +{ + GSList *li; + xmlNode *folder_node; + + + folder_node = xmlNewChild (parent /* parent */, + NULL /* ns */, + "Folder" /* name */, + NULL /* content */); + + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Name" /* name */, + folder->entry.name /* content */); + + if (folder->desktop_file != NULL) { + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Desktop" /* name */, + folder->desktop_file /* content */); + } + + if (folder->read_only) + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "ReadOnly" /* name */, + NULL /* content */); + if (folder->dont_show_if_empty) + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "DontShowIfEmpty" /* name */, + NULL /* content */); + if (folder->only_unallocated) + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "OnlyUnallocated" /* name */, + NULL /* content */); + + for (li = folder->subfolders; li != NULL; li = li->next) { + Folder *subfolder = li->data; + add_xml_tree_from_folder (folder_node, subfolder); + } + + for (li = folder->includes; li != NULL; li = li->next) { + const char *include = li->data; + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Include" /* name */, + include /* content */); + } + + if (folder->excludes) { + g_hash_table_foreach (folder->excludes, + add_excludes_to_xml, + folder_node); + } + + if (folder->query != NULL) { + xmlNode *query_node; + query_node = xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Query" /* name */, + NULL /* content */); + + add_xml_tree_from_query (query_node, folder->query); + } +} + +static xmlDoc * +xml_tree_from_vfolder (VFolderInfo *info) +{ + xmlDoc *doc; + xmlNode *topnode; + GSList *li; + + doc = xmlNewDoc ("1.0"); + + topnode = xmlNewDocNode (doc /* doc */, + NULL /* ns */, + "VFolderInfo" /* name */, + NULL /* content */); + doc->xmlRootNode = topnode; + + for (li = info->merge_dirs; li != NULL; li = li->next) { + const char *merge_dir = li->data; + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "MergeDir" /* name */, + merge_dir /* content */); + } + + for (li = info->item_dirs; li != NULL; li = li->next) { + const char *item_dir = li->data; + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "ItemDir" /* name */, + item_dir /* content */); + } + + if (info->user_item_dir != NULL) { + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "UserItemDir" /* name */, + info->user_item_dir /* content */); + } + + if (info->desktop_dir != NULL) { + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "DesktopDir" /* name */, + info->desktop_dir /* content */); + } + + if (info->user_desktop_dir != NULL) { + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "UserDesktopDir" /* name */, + info->user_desktop_dir /* content */); + } + + if (info->root != NULL) + add_xml_tree_from_folder (topnode, info->root); + + return doc; +} + +/* FIXME: what to do about errors */ +static void +vfolder_info_write_user (VFolderInfo *info) +{ + xmlDoc *doc; + + if (info->inhibit_write > 0) + return; + + if (info->user_filename == NULL) + return; + + doc = xml_tree_from_vfolder (info); + if (doc == NULL) + return; + + /* FIXME: errors, anyone? */ + ensure_dir (info->user_filename, + TRUE /* ignore_basename */); + + xmlSaveFormatFile (info->user_filename, doc, TRUE /* format */); + /* not as good as a stat, but cheaper ... hmmm what is + * the likelyhood of this not being the same as ctime */ + info->user_filename_last_write = time (NULL); + + xmlFreeDoc(doc); + + info->user_file_active = TRUE; + info->dirty = FALSE; + + info->modification_time = time (NULL); +} + +/* An EVIL function for quick reading of .desktop files, + * only reads in one or two keys, but that's ALL we need */ +static void +readitem_entry (const char *filename, + const char *key1, + char **result1, + const char *key2, + char **result2) +{ + FILE *fp; + char buf[1024]; + int keylen1, keylen2; + + *result1 = NULL; + if (result2 != NULL) + *result2 = NULL; + + fp = fopen (filename, "r"); + + if (fp == NULL) + return; + + keylen1 = strlen (key1); + if (key2 != NULL) + keylen2 = strlen (key2); + else + keylen2 = -1; + + /* This is slightly wrong, it should only look + * at the correct section */ + while (fgets (buf, sizeof (buf), fp) != NULL) { + char *p; + int len; + int keylen; + char **result = NULL; + + /* check if it's one of the keys */ + if (strncmp (buf, key1, keylen1) == 0) { + result = result1; + keylen = keylen1; + } else if (keylen2 >= 0 && + strncmp (buf, key2, keylen2) == 0) { + result = result2; + keylen = keylen2; + } else { + continue; + } + + p = &buf[keylen]; + + /* still not our key */ + if (!(*p == '=' || *p == ' ')) { + continue; + } + do + p++; + while (*p == ' ' || *p == '='); + + /* get rid of trailing \n */ + len = strlen (p); + if (p[len-1] == '\n' || + p[len-1] == '\r') + p[len-1] = '\0'; + + *result = g_strdup (p); + + if (*result1 == NULL || + (result2 != NULL && *result2 == NULL)) + break; + } + + fclose (fp); +} + +static void +vfolder_info_insert_entry (VFolderInfo *info, EntryFile *efile) +{ + GSList *entry_list; + + entry_ref ((Entry *)efile); + + entry_list = g_hash_table_lookup (info->entries_ht, efile->entry.name); + + info->entries = g_slist_prepend (info->entries, efile); + /* The hash table contains the GSList pointer */ + g_hash_table_replace (info->entries_ht, efile->entry.name, + info->entries); + + if (entry_list != NULL) { + Entry *entry = entry_list->data; + info->entries = g_slist_delete_link (info->entries, + entry_list); + entry_unref (entry); + } +} + +static void +set_keywords (EntryFile *efile, const char *keywords) +{ + if (keywords != NULL) { + int i; + char **parsed = g_strsplit (keywords, ";", -1); + for (i = 0; parsed[i] != NULL; i++) { + GQuark quark; + const char *word = parsed[i]; + /* ignore empties (including end of list) */ + if (word[0] == '\0') + continue; + quark = g_quark_from_string (word); + efile->keywords = g_slist_prepend + (efile->keywords, + GINT_TO_POINTER (quark)); + } + g_strfreev (parsed); + } +} + +static EntryFile * +make_entry_file (const char *dir, const char *name) +{ + EntryFile *efile; + char *categories; + char *only_show_in; + char *filename; + int i; + + filename = g_build_filename (dir, name, NULL); + + readitem_entry (filename, + "Categories", + &categories, + "OnlyShowIn", + &only_show_in); + + if (only_show_in != NULL) { + gboolean show = FALSE; + char **parsed = g_strsplit (only_show_in, ";", -1); + for (i = 0; parsed[i] != NULL; i++) { + if (strcmp (parsed[i], "GNOME") == 0) { + show = TRUE; + break; + } + } + g_strfreev (parsed); + if ( ! show) { + g_free (filename); + g_free (only_show_in); + g_free (categories); + return NULL; + } + } + + efile = file_new (name); + efile->filename = filename; + + set_keywords (efile, categories); + + g_free (only_show_in); + g_free (categories); + + return efile; +} + +static gboolean +vfolder_info_read_items_from (VFolderInfo *info, + const char *item_dir, + gboolean per_user, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + DIR *dir; + struct dirent *de; + + dir = opendir (item_dir); + if (dir == NULL) + return TRUE; + + while ((de = readdir (dir)) != NULL) { + EntryFile *efile; + + if (gnome_vfs_context_check_cancellation (context)) { + closedir (dir); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + /* files MUST be called .desktop */ + if (de->d_name[0] == '.' || + ! check_ext (de->d_name, ".desktop")) + continue; + + efile = make_entry_file (item_dir, de->d_name); + if (efile == NULL) + continue; + + efile->per_user = per_user; + + vfolder_info_insert_entry (info, efile); + entry_unref ((Entry *)efile); + } + + closedir (dir); + + return TRUE; +} + +static gboolean +vfolder_info_read_items_merge (VFolderInfo *info, + const char *merge_dir, + const char *subdir, + GQuark inherited_keyword, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + DIR *dir; + struct dirent *de; + GQuark extra_keyword; + GQuark Application; + GQuark Merged; + GQuark inheritance; + gboolean pass_down_extra_keyword = TRUE; + + dir = opendir (merge_dir); + if (dir == NULL) + return TRUE; + + Application = g_quark_from_static_string ("Application"); + Merged = g_quark_from_static_string ("Merged"); + + /* FIXME: this should be a hash or something */ + extra_keyword = 0; + if (subdir == NULL) { + extra_keyword = g_quark_from_static_string ("Core"); + pass_down_extra_keyword = FALSE; + } else if (g_ascii_strcasecmp (subdir, "Development") == 0) + extra_keyword = g_quark_from_static_string ("Development"); + else if (g_ascii_strcasecmp (subdir, "Editors") == 0) + extra_keyword = g_quark_from_static_string ("TextEditor"); + else if (g_ascii_strcasecmp (subdir, "Games") == 0) + extra_keyword = g_quark_from_static_string ("Game"); + else if (g_ascii_strcasecmp (subdir, "Graphics") == 0) + extra_keyword = g_quark_from_static_string ("Graphics"); + else if (g_ascii_strcasecmp (subdir, "Internet") == 0) + extra_keyword = g_quark_from_static_string ("Network"); + else if (g_ascii_strcasecmp (subdir, "Multimedia") == 0) + extra_keyword = g_quark_from_static_string ("AudioVideo"); + else if (g_ascii_strcasecmp (subdir, "Office") == 0) + extra_keyword = g_quark_from_static_string ("Office"); + else if (g_ascii_strcasecmp (subdir, "Settings") == 0) + extra_keyword = g_quark_from_static_string ("Settings"); + else if (g_ascii_strcasecmp (subdir, "System") == 0) + extra_keyword = g_quark_from_static_string ("System"); + else if (g_ascii_strcasecmp (subdir, "Utilities") == 0) + extra_keyword = g_quark_from_static_string ("Utility"); + + while ((de = readdir (dir)) != NULL) { + EntryFile *efile; + + if (gnome_vfs_context_check_cancellation (context)) { + closedir (dir); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + /* ignore hidden */ + if (de->d_name[0] == '.') + continue; + + /* files MUST be called .desktop, so + * treat all others as dirs. If we're wrong, + * the open will fail, which is ok */ + if ( ! check_ext (de->d_name, ".desktop")) { + /* if this is a directory recurse */ + char *fullname = g_build_filename (merge_dir, de->d_name, NULL); + if ((pass_down_extra_keyword == TRUE) && (extra_keyword != 0)) { + inheritance = extra_keyword; + } else { + inheritance = inherited_keyword; + } + + if ( ! vfolder_info_read_items_merge (info, + fullname, + de->d_name, + inheritance, + result, + context)) { + g_free (fullname); + return FALSE; + } + g_free (fullname); + continue; + } + + /* FIXME: add some keywords about some known apps + * like gimp and whatnot, perhaps take these from the vfolder + * file or some such */ + + efile = make_entry_file (merge_dir, de->d_name); + if (efile == NULL) + continue; + + /* If no keywords set, then add the standard ones */ + if (efile->keywords == NULL) { + efile->keywords = g_slist_prepend + (efile->keywords, + GINT_TO_POINTER (Application)); + + efile->keywords = g_slist_prepend + (efile->keywords, + GINT_TO_POINTER (Merged)); + + if (inherited_keyword != 0) { + efile->keywords = g_slist_prepend + (efile->keywords, + GINT_TO_POINTER (inherited_keyword)); + } + + if (extra_keyword != 0) { + efile->keywords = g_slist_prepend + (efile->keywords, + GINT_TO_POINTER (extra_keyword)); + } + efile->implicit_keywords = TRUE; + } + + vfolder_info_insert_entry (info, efile); + entry_unref ((Entry *)efile); + } + + closedir (dir); + + return TRUE; +} + +static Entry * +find_entry (GSList *list, const char *name) +{ + GSList *li; + + for (li = list; li != NULL; li = li->next) { + Entry *entry = li->data; + if (strcmp (name, entry->name) == 0) + return entry; + } + return NULL; +} + +static void +file_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + FileMonitorHandle *h = user_data; + + /* proxy the event through if it is a changed event + * only */ + + if (event_type == GNOME_VFS_MONITOR_EVENT_CHANGED && + h->handle != NULL) + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *) h, + h->uri, event_type); +} + +static void +try_free_file_monitors_create_files_unlocked (VFolderInfo *info) +{ + GSList *li, *list; + + list = g_slist_copy (info->free_file_monitors); + + for (li = list; li != NULL; li = li->next) { + FileMonitorHandle *handle = li->data; + Entry *entry; + GnomeVFSResult result; + char *dirfile = NULL; + + if (handle->is_directory_file) { + VFolderURI vuri; + Folder *folder; + + /* Evil! EVIL URI PARSING. this will eat a lot of + * stack if we have lots of free monitors */ + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + folder = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + + if (folder == NULL) + continue; + + dirfile = get_directory_file_unlocked (info, folder); + if (dirfile == NULL) + continue; + + entry = (Entry *)folder; + } else { + VFolderURI vuri; + Folder *f; + GnomeVFSResult result; + + entry = NULL; + + /* Evil! EVIL URI PARSING. this will eat a lot of + * stack if we have lots of monitors */ + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + f = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + + if (f != NULL) { + ensure_folder_unlocked ( + info, f, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + entry = find_entry (f->entries, vuri.file); + } + + if (entry == NULL) + continue; + } + + info->free_file_monitors = + g_slist_remove (info->free_file_monitors, handle); + entry->monitors = + g_slist_prepend (entry->monitors, handle); + + handle->exists = TRUE; + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *)handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_CREATED); + + /* recreate a handle */ + if (handle->handle == NULL && + entry->type == ENTRY_FILE) { + EntryFile *efile = (EntryFile *)entry; + char *uri = gnome_vfs_get_uri_from_local_path + (efile->filename); + + gnome_vfs_monitor_add (&(handle->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + handle); + + g_free (uri); + } else if (handle->handle == NULL && + dirfile != NULL) { + char *uri = gnome_vfs_get_uri_from_local_path (dirfile); + + gnome_vfs_monitor_add (&(handle->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + handle); + + g_free (uri); + } + + g_free (dirfile); + } + + g_slist_free (list); +} + +static void /* unlocked */ +rescan_monitors (VFolderInfo *info) +{ + GSList *li; + + if (info->file_monitors == NULL) + return; + + for (li = info->file_monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + GnomeVFSResult result; + Entry *entry; + char *dirfile = NULL; + + /* these are handled below */ + if ( ! h->exists) + continue; + + if (h->is_directory_file) { + VFolderURI vuri; + Folder *folder; + + /* Evil! EVIL URI PARSING. this will eat a lot of + * stack if we have lots of monitors */ + + VFOLDER_URI_PARSE (h->uri, &vuri); + + folder = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + if (folder != NULL) + dirfile = get_directory_file_unlocked (info, + folder); + + if (dirfile == NULL) { + h->exists = FALSE; + gnome_vfs_monitor_callback + ((GnomeVFSMethodHandle *)h, + h->uri, + GNOME_VFS_MONITOR_EVENT_DELETED); + info->free_file_monitors = g_slist_prepend + (info->free_file_monitors, h); + file_monitor_handle_ref_unlocked (h); + /* it has been unreffed when the entry was + * whacked */ + continue; + } + + entry = (Entry *)folder; + } else { + VFolderURI vuri; + Folder *f; + GnomeVFSResult result; + + entry = NULL; + + /* Evil! EVIL URI PARSING. this will eat a lot of + * stack if we have lots of monitors */ + + VFOLDER_URI_PARSE (h->uri, &vuri); + + f = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + + if (f != NULL) { + ensure_folder_unlocked ( + info, f, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + entry = find_entry (f->entries, vuri.file); + } + + if (entry == NULL) { + h->exists = FALSE; + gnome_vfs_monitor_callback + ((GnomeVFSMethodHandle *)h, + h->uri, + GNOME_VFS_MONITOR_EVENT_DELETED); + info->free_file_monitors = g_slist_prepend + (info->free_file_monitors, h); + file_monitor_handle_ref_unlocked (h); + /* it has been unreffed when the entry was + * whacked */ + continue; + } + } + + /* recreate a handle */ + if (h->handle == NULL && + entry->type == ENTRY_FILE) { + EntryFile *efile = (EntryFile *)entry; + char *uri = gnome_vfs_get_uri_from_local_path + (efile->filename); + + gnome_vfs_monitor_add (&(h->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + h); + + g_free (uri); + } else if (h->handle == NULL && + dirfile != NULL) { + char *uri = gnome_vfs_get_uri_from_local_path (dirfile); + + gnome_vfs_monitor_add (&(h->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + h); + + g_free (uri); + } + + g_free (dirfile); + } + + try_free_file_monitors_create_files_unlocked (info); +} + +static gboolean /* unlocked */ +vfolder_info_read_items (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + GSList *li; + + /* First merge */ + for (li = info->merge_dirs; li != NULL; li = li->next) { + const char *merge_dir = li->data; + + if ( ! vfolder_info_read_items_merge (info, merge_dir, NULL, FALSE, + result, context)) + return FALSE; + } + + /* Then read the real thing (later overrides) */ + for (li = info->item_dirs; li != NULL; li = li->next) { + const char *item_dir = li->data; + + if ( ! vfolder_info_read_items_from (info, item_dir, + FALSE /* per_user */, + result, context)) + return FALSE; + } + + if (info->user_item_dir != NULL) { + if ( ! vfolder_info_read_items_from (info, + info->user_item_dir, + TRUE /* per_user */, + result, context)) + return FALSE; + } + + rescan_monitors (info); + + return TRUE; +} + +static gboolean +string_slist_equal (GSList *list1, GSList *list2) +{ + GSList *li1, *li2; + + for (li1 = list1, li2 = list2; + li1 != NULL && li2 != NULL; + li1 = li1->next, li2 = li2->next) { + const char *s1 = li1->data; + const char *s2 = li2->data; + if (strcmp (s1, s2) != 0) + return FALSE; + } + /* if both are not NULL, then lengths are + * different */ + if (li1 != li2) + return FALSE; + return TRUE; +} + +static gboolean +safe_string_same (const char *string1, const char *string2) +{ + if (string1 == string2 && + string1 == NULL) + return TRUE; + + if (string1 != NULL && string2 != NULL && + strcmp (string1, string2) == 0) + return TRUE; + + return FALSE; +} + +static gboolean +vfolder_info_item_dirs_same (VFolderInfo *info1, VFolderInfo *info2) +{ + if ( ! string_slist_equal (info1->item_dirs, + info2->item_dirs)) + return FALSE; + + if ( ! string_slist_equal (info1->merge_dirs, + info2->merge_dirs)) + return FALSE; + + if ( ! safe_string_same (info1->user_item_dir, + info2->user_item_dir)) + return FALSE; + + return TRUE; +} + +static gboolean +vfolder_info_reload_unlocked (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context, + gboolean force_read_items) +{ + VFolderInfo *newinfo; + gboolean setup_filenames; + gboolean setup_itemdirs; + GSList *li; + + /* FIXME: Hmmm, race, there is no locking YAIKES, + * we need filename locking for changes. eek, eek, eek */ + if (info->dirty) { + return TRUE; + } + + newinfo = g_new0 (VFolderInfo, 1); + vfolder_info_init (newinfo, info->scheme); + + g_free (newinfo->filename); + g_free (newinfo->user_filename); + newinfo->filename = g_strdup (info->filename); + newinfo->user_filename = g_strdup (info->user_filename); + + if (gnome_vfs_context_check_cancellation (context)) { + vfolder_info_destroy (newinfo); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + if ( ! vfolder_info_read_info (newinfo, result, context)) { + vfolder_info_destroy (newinfo); + return FALSE; + } + + /* FIXME: reload logic for 'desktop_dir' and + * 'user_desktop_dir' */ + + setup_itemdirs = TRUE; + + /* Validity of entries and item dirs and all that is unchanged */ + if (vfolder_info_item_dirs_same (info, newinfo)) { + newinfo->entries = info->entries; + info->entries = NULL; + newinfo->entries_ht = info->entries_ht; + info->entries_ht = NULL /* some places assume this + non-null, but we're only + going to destroy this */; + newinfo->entries_valid = info->entries_valid; + + /* move over the monitors/statlocs since those are valid */ + newinfo->item_dir_monitors = info->item_dir_monitors; + info->item_dir_monitors = NULL; + newinfo->stat_dirs = info->stat_dirs; + info->stat_dirs = NULL; + + /* No need to resetup dir monitors */ + setup_itemdirs = FALSE; + + /* No need to do anything with file monitors */ + } else { + /* Whack all monitors here! */ + for (li = info->file_monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + if (h->handle != NULL) + gnome_vfs_monitor_cancel (h->handle); + h->handle = NULL; + } + } + + setup_filenames = TRUE; + + if (safe_string_same (info->filename, newinfo->filename) && + safe_string_same (info->user_filename, newinfo->user_filename)) { + newinfo->user_filename_last_write = + info->user_filename_last_write; + + /* move over the monitors/statlocs since those are valid */ + newinfo->filename_monitor = info->filename_monitor; + info->filename_monitor = NULL; + newinfo->user_filename_monitor = info->user_filename_monitor; + info->user_filename_monitor = NULL; + + if (info->filename_statloc != NULL && + info->filename != NULL) + newinfo->filename_statloc = + bake_statloc (info->filename, + time (NULL)); + if (info->user_filename_statloc != NULL && + info->user_filename != NULL) + newinfo->user_filename_statloc = + bake_statloc (info->user_filename, + time (NULL)); + + /* No need to resetup filename monitors */ + setup_filenames = FALSE; + } + + /* Note: not cancellable anymore, since we've + * already started nibbling on the info structure, + * so we'd need to back things out or some such, + * too complex, so screw that */ + monitor_setup (info, + setup_filenames, + setup_itemdirs, + /* FIXME: setup_desktop_dirs */ TRUE, + NULL, NULL); + + for (li = info->folder_monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *handle = li->data; + li->data = NULL; + + add_folder_monitor_unlocked (newinfo, handle); + + file_monitor_handle_unref_unlocked (handle); + } + g_slist_free (info->folder_monitors); + info->folder_monitors = NULL; + + g_slist_foreach (info->free_folder_monitors, + (GFunc)file_monitor_handle_unref_unlocked, NULL); + g_slist_free (info->free_folder_monitors); + info->folder_monitors = NULL; + + /* we can just copy these for now, they will be readded + * and all the fun stuff will be done with them later */ + newinfo->file_monitors = info->file_monitors; + info->file_monitors = NULL; + newinfo->free_file_monitors = info->free_file_monitors; + info->free_file_monitors = NULL; + + /* emit changed on all folders, a bit drastic, but oh well, + * we also invalidate all folders at the same time, but that is + * irrelevant since they should all just be invalid to begin with */ + invalidate_folder_T (info->root); + + /* FIXME: make sure if this was enough, I think it was */ + + vfolder_info_free_internals_unlocked (info); + memcpy (info, newinfo, sizeof (VFolderInfo)); + g_free (newinfo); + + /* must rescan the monitors here */ + if (info->entries_valid) { + rescan_monitors (info); + } + + if ( ! info->entries_valid && + force_read_items) { + GnomeVFSResult res; + /* FIXME: I bet cancelation plays havoc with monitors, + * I'm not sure however */ + if (info->file_monitors != NULL) { + vfolder_info_read_items (info, &res, NULL); + } else { + if ( ! vfolder_info_read_items (info, result, context)) + return FALSE; + } + info->entries_valid = TRUE; + } + + return TRUE; +} + +static gboolean +vfolder_info_reload (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context, + gboolean force_read_items) +{ + G_LOCK (vfolder_lock); + if (vfolder_info_reload_unlocked (info, result, context, + force_read_items)) { + G_UNLOCK (vfolder_lock); + return TRUE; + } else { + G_UNLOCK (vfolder_lock); + return FALSE; + } +} + +static gboolean +vfolder_info_recheck (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + GSList *li; + time_t curtime = time (NULL); + gboolean reread = FALSE; + + if (info->filename_statloc != NULL && + ! check_statloc (info->filename_statloc, curtime)) { + if ( ! vfolder_info_reload_unlocked (info, result, context, + FALSE /* force read items */)) { + /* we have failed, make sure we fail + * next time too */ + info->filename_statloc->trigger_next = TRUE; + return FALSE; + } + reread = TRUE; + } + if ( ! reread && + info->user_filename_statloc != NULL && + ! check_statloc (info->user_filename_statloc, curtime)) { + if ( ! vfolder_info_reload_unlocked (info, result, context, + FALSE /* force read items */)) { + /* we have failed, make sure we fail + * next time too */ + info->user_filename_statloc->trigger_next = TRUE; + return FALSE; + } + reread = TRUE; + } + + if (info->entries_valid) { + for (li = info->stat_dirs; li != NULL; li = li->next) { + StatLoc *sl = li->data; + if ( ! check_statloc (sl, curtime)) { + info->entries_valid = FALSE; + break; + } + } + } + return TRUE; +} + +static VFolderInfo * +get_vfolder_info_unlocked (const char *scheme, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + VFolderInfo *info; + + if (infos != NULL && + (info = g_hash_table_lookup (infos, scheme)) != NULL) { + if ( ! vfolder_info_recheck (info, result, context)) { + return NULL; + } + if ( ! info->entries_valid) { + g_slist_foreach (info->entries, + (GFunc)entry_unref, NULL); + g_slist_free (info->entries); + info->entries = NULL; + + if (info->entries_ht != NULL) + g_hash_table_destroy (info->entries_ht); + info->entries_ht = g_hash_table_new (g_str_hash, + g_str_equal); + + if ( ! vfolder_info_read_items (info, + result, context)) { + info->entries_valid = FALSE; + return NULL; + } + + invalidate_folder_T (info->root); + + info->entries_valid = TRUE; + } + return info; + } + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if (infos == NULL) + infos = g_hash_table_new_full + (g_str_hash, g_str_equal, + (GDestroyNotify)g_free, + (GDestroyNotify)vfolder_info_destroy); + + info = g_new0 (VFolderInfo, 1); + vfolder_info_init (info, scheme); + + if (gnome_vfs_context_check_cancellation (context)) { + vfolder_info_destroy (info); + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if ( ! vfolder_info_read_info (info, result, context)) { + vfolder_info_destroy (info); + return NULL; + } + + if ( ! monitor_setup (info, + TRUE /* setup_filenames */, + TRUE /* setup_itemdirs */, + TRUE /* setup_desktop_dirs */, + result, context)) { + vfolder_info_destroy (info); + return NULL; + } + + g_hash_table_insert (infos, g_strdup (scheme), info); + + if ( ! vfolder_info_read_items (info, result, context)) { + info->entries_valid = FALSE; + return NULL; + } + info->entries_valid = TRUE; + + return info; +} + +static VFolderInfo * +get_vfolder_info (const char *scheme, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + VFolderInfo *info; + G_LOCK (vfolder_lock); + info = get_vfolder_info_unlocked (scheme, result, context); + G_UNLOCK (vfolder_lock); + return info; +} + + +static char * +keywords_to_string (GSList *keywords) +{ + GSList *li; + GString *str = g_string_new (NULL); + + for (li = keywords; li != NULL; li = li->next) { + GQuark word = GPOINTER_TO_INT (li->data); + g_string_append (str, g_quark_to_string (word)); + g_string_append_c (str, ';'); + } + + return g_string_free (str, FALSE); +} + +/* copy file and add keywords line */ +static gboolean +copy_file_with_keywords (const char *from, const char *to, GSList *keywords) +{ + FILE *fp; + FILE *wfp; + int wfd; + char buf[BUFSIZ]; + char *keyword_string; + + if ( ! ensure_dir (to, + TRUE /* ignore_basename */)) + return FALSE; + + wfd = open (to, O_CREAT | O_WRONLY | O_TRUNC, 0600); + if (wfd < 0) { + return FALSE; + } + + keyword_string = keywords_to_string (keywords); + + wfp = fdopen (wfd, "w"); + + fp = fopen (from, "r"); + if (fp != NULL) { + gboolean wrote_keywords = FALSE; + while (fgets (buf, sizeof (buf), fp) != NULL) { + fprintf (wfp, "%s", buf); + if ( ! wrote_keywords && + (strncmp (buf, "[Desktop Entry]", + strlen ("[Desktop Entry]")) == 0 || + strncmp (buf, "[KDE Desktop Entry]", + strlen ("[KDE Desktop Entry]")) == 0)) { + fprintf (wfp, "Categories=%s\n", + keyword_string); + wrote_keywords = TRUE; + } + } + + fclose (fp); + } else { + fprintf (wfp, "[Desktop Entry]\nCategories=%s\n", + keyword_string); + } + + /* FIXME: does this close wfd???? */ + fclose (wfp); + + close (wfd); + + g_free (keyword_string); + + return TRUE; +} + +static gboolean +copy_file (const char *from, const char *to) +{ + int fd; + int wfd; + + if ( ! ensure_dir (to, + TRUE /* ignore_basename */)) + return FALSE; + + wfd = open (to, O_CREAT | O_WRONLY | O_TRUNC, 0600); + if (wfd < 0) { + return FALSE; + } + + fd = open (from, O_RDONLY); + if (fd >= 0) { + char buf[1024]; + ssize_t n; + + while ((n = read (fd, buf, sizeof(buf))) > 0) { + write (wfd, buf, n); + } + + close (fd); + } + + close (wfd); + + return TRUE; +} + +static gboolean +make_file_private (VFolderInfo *info, EntryFile *efile) +{ + char *newfname; + Entry *entry = (Entry *)efile; + + if (efile->per_user) + return TRUE; + + /* this file already exists so whack its monitors */ + if (efile->filename != NULL) { + GSList *li; + + for (li = entry->monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + if (h->handle != NULL) + gnome_vfs_monitor_cancel (h->handle); + h->handle = NULL; + } + } + + newfname = g_build_filename (g_get_home_dir (), + DOT_GNOME, + "vfolders", + info->scheme, + efile->entry.name, + NULL); + + if (efile->implicit_keywords) { + if (efile->filename != NULL && + ! copy_file_with_keywords (efile->filename, + newfname, + efile->keywords)) { + /* FIXME: what to do with monitors here, they + * have already been whacked, a corner case + * not handled! */ + g_free (newfname); + return FALSE; + } + } else { + if (efile->filename != NULL && + ! copy_file (efile->filename, newfname)) { + /* FIXME: what to do with monitors here, they + * have already been whacked, a corner case + * not handled! */ + g_free (newfname); + return FALSE; + } + } + + /* we didn't copy but ensure path anyway */ + if (efile->filename == NULL && + ! ensure_dir (newfname, + TRUE /* ignore_basename */)) { + g_free (newfname); + return FALSE; + } + + /* this file already exists so re-add monitors at the new location */ + if (efile->filename != NULL) { + GSList *li; + char *uri = gnome_vfs_get_uri_from_local_path (newfname); + + for (li = entry->monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + + gnome_vfs_monitor_add (&(h->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + h); + } + + g_free (uri); + } + + g_free (efile->filename); + efile->filename = newfname; + efile->per_user = TRUE; + + return TRUE; +} + +static void +try_free_file_monitors_create_dirfile_unlocked (VFolderInfo *info, + Folder *folder) +{ + GSList *li, *list; + + list = g_slist_copy (info->free_file_monitors); + + for (li = list; li != NULL; li = li->next) { + FileMonitorHandle *handle = li->data; + Folder *f; + VFolderURI vuri; + GnomeVFSResult result; + + if ( ! handle->is_directory_file) + continue; + + /* Evil! EVIL URI PARSING. this will eat a lot of stack if we + * have lots of free monitors */ + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + f = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + + if (folder != f) + continue; + + info->free_file_monitors = + g_slist_remove (info->free_file_monitors, handle); + ((Entry *)folder)->monitors = + g_slist_prepend (((Entry *)folder)->monitors, handle); + + handle->exists = TRUE; + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *)handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_CREATED); + } + + g_slist_free (list); +} + +static void +make_new_dirfile (VFolderInfo *info, Folder *folder) +{ + char *name = g_strdup (folder->entry.name); + char *fname; + char *p; + int i; + int fd; + + for (p = name; *p != '\0'; p++) { + if ( ! ( (*p >= 'a' && *p <= 'z') || + (*p >= 'A' && *p <= 'Z') || + (*p >= '0' && *p <= '9') || + *p == '_')) { + *p = '_'; + } + } + + i = 0; + fname = NULL; + do { + char *fullname; + + g_free (fname); + + if (i > 0) { + fname = g_strdup_printf ("%s-%d.directory", name, i); + } else { + fname = g_strdup_printf ("%s.directory", name); + } + + fullname = g_build_filename + (info->user_desktop_dir, fname, NULL); + fd = open (fullname, O_CREAT | O_WRONLY | O_EXCL, 0600); + g_free (fullname); + } while (fd < 0); + + close (fd); + + folder->desktop_file = fname; + info->dirty = TRUE; + + try_free_file_monitors_create_dirfile_unlocked (info, folder); +} + +static gboolean +make_dirfile_private (VFolderInfo *info, Folder *folder) +{ + char *fname; + char *desktop_file; + GSList *li; + char *uri; + gboolean ret; + + if (info->user_desktop_dir == NULL) + return FALSE; + + if ( ! ensure_dir (info->user_desktop_dir, + FALSE /* ignore_basename */)) + return FALSE; + + + if (folder->desktop_file == NULL) { + make_new_dirfile (info, folder); + return TRUE; + } + + /* FIXME: this is broken! What if the desktop file exists + * in the local but there is a different (but with a same name) + * .directory in the system. */ + fname = g_build_filename (info->user_desktop_dir, + folder->desktop_file, + NULL); + + if (access (fname, F_OK) == 0) { + g_free (fname); + return TRUE; + } + + desktop_file = get_directory_file (info, folder); + + if (desktop_file == NULL) { + int fd = open (fname, O_CREAT | O_EXCL | O_WRONLY, 0600); + g_free (fname); + if (fd >= 0) { + close (fd); + return TRUE; + } + return FALSE; + } + + for (li = ((Entry *)folder)->monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + if (h->is_directory_file) { + if (h->handle != NULL) + gnome_vfs_monitor_cancel (h->handle); + h->handle = NULL; + } + } + + ret = TRUE; + + if ( ! copy_file (desktop_file, fname)) { + ret = FALSE; + g_free (fname); + fname = desktop_file; + desktop_file = NULL; + } + + uri = gnome_vfs_get_uri_from_local_path (fname); + + for (li = ((Entry *)folder)->monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + + if (h->is_directory_file) { + gnome_vfs_monitor_add (&(h->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + h); + } + } + + g_free (uri); + + g_free (desktop_file); + g_free (fname); + + return ret; +} + +static Folder * +resolve_folder (VFolderInfo *info, + const char *path, + gboolean ignore_basename, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + char **ppath; + int i; + Folder *folder = info->root; + + ppath = g_strsplit (path, "/", -1); + + if (ppath == NULL || + ppath[0] == NULL) { + g_strfreev (ppath); + *result = GNOME_VFS_ERROR_INVALID_URI; + return NULL; + } + + for (i = 0; ppath [i] != NULL; i++) { + const char *segment = ppath[i]; + + if (*segment == '\0') + continue; + + if (ignore_basename && ppath [i + 1] == NULL) + break; + else { + folder = (Folder *) find_entry (folder->subfolders, + segment); + if (folder == NULL) + break; + } + } + g_strfreev (ppath); + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if (folder == NULL) + *result = GNOME_VFS_ERROR_NOT_FOUND; + + return folder; +} + +static Entry * +resolve_path (VFolderInfo *info, + const char *path, + const char *basename, + Folder **return_folder, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + Entry *entry; + Folder *folder; + + if (strcmp (path, "/") == 0) + return (Entry *)info->root; + + folder = resolve_folder (info, path, + TRUE /* ignore_basename */, + result, context); + + if (return_folder != NULL) + *return_folder = folder; + + if (folder == NULL) { + return NULL; + } + + /* Make sure we have the entries here */ + ensure_folder_unlocked (info, folder, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + + entry = find_entry (folder->entries, basename); + + if (entry == NULL) + *result = GNOME_VFS_ERROR_NOT_FOUND; + + return entry; +} + +static Entry * +get_entry_unlocked (VFolderURI *vuri, + Folder **parent, + gboolean *is_directory_file, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + VFolderInfo *info; + Entry *entry; + + if (is_directory_file != NULL) + *is_directory_file = FALSE; + if (parent != NULL) + *parent = NULL; + + info = get_vfolder_info_unlocked (vuri->scheme, result, context); + if (info == NULL) + return NULL; + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if (vuri->is_all_scheme) { + GSList *efile_list; + + if (vuri->file == NULL) { + entry = resolve_path (info, + vuri->path, + vuri->file, + parent, + result, + context); + return entry; + } + + efile_list = g_hash_table_lookup (info->entries_ht, vuri->file); + + if (efile_list == NULL) { + *result = GNOME_VFS_ERROR_NOT_FOUND; + return NULL; + } else { + return efile_list->data; + } + } + + if (vuri->file != NULL && + check_ext (vuri->file, ".directory") == TRUE) { + Folder *folder; + + folder = resolve_folder (info, vuri->path, + TRUE /* ignore_basename */, + result, context); + if (folder == NULL) { + return NULL; + } + + if (is_directory_file != NULL) + *is_directory_file = TRUE; + + if (parent != NULL) + *parent = folder; + + return (Entry *)folder; + } else { + entry = resolve_path (info, vuri->path, vuri->file, parent, + result, context); + return entry; + } +} + +static Entry * +get_entry (VFolderURI *vuri, + Folder **parent, + gboolean *is_directory_file, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + Entry *entry; + + G_LOCK (vfolder_lock); + entry = get_entry_unlocked (vuri, + parent, + is_directory_file, + result, context); + G_UNLOCK (vfolder_lock); + + return entry; +} + +/* only works for files and only those that exist */ +/* unlocked function */ +static GnomeVFSURI * +desktop_uri_to_file_uri (VFolderInfo *info, + VFolderURI *desktop_vuri, + Entry **the_entry, + gboolean *the_is_directory_file, + Folder **the_folder, + gboolean privatize, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + gboolean is_directory_file; + GnomeVFSURI *ret_uri; + Folder *folder = NULL; + Entry *entry; + + entry = get_entry_unlocked (desktop_vuri, + &folder, + &is_directory_file, + result, + context); + if (entry == NULL) + return NULL; + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if (the_folder != NULL) + *the_folder = folder; + + if (the_entry != NULL) + *the_entry = entry; + if (the_is_directory_file != NULL) + *the_is_directory_file = is_directory_file; + + if (is_directory_file && + entry->type == ENTRY_FOLDER) { + char *desktop_file; + + folder = (Folder *)entry; + + if (the_folder != NULL) + *the_folder = folder; + + /* we'll be doing something write like */ + if (folder->read_only && + privatize) { + *result = GNOME_VFS_ERROR_READ_ONLY; + return NULL; + } + + if (privatize) { + char *fname; + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if ( ! make_dirfile_private (info, folder)) { + *result = GNOME_VFS_ERROR_GENERIC; + return NULL; + } + fname = g_build_filename (g_get_home_dir (), + folder->desktop_file, + NULL); + ret_uri = gnome_vfs_uri_new (fname); + g_free (fname); + return ret_uri; + } + + desktop_file = get_directory_file_unlocked (info, folder); + if (desktop_file != NULL) { + char *s = gnome_vfs_get_uri_from_local_path + (desktop_file); + + g_free (desktop_file); + + ret_uri = gnome_vfs_uri_new (s); + g_free (s); + + return ret_uri; + } else { + *result = GNOME_VFS_ERROR_NOT_FOUND; + return NULL; + } + } else if (entry->type == ENTRY_FILE) { + EntryFile *efile = (EntryFile *)entry; + char *s; + + /* we'll be doing something write like */ + if (folder != NULL && + folder->read_only && + privatize) { + *result = GNOME_VFS_ERROR_READ_ONLY; + return NULL; + } + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if (privatize && + ! make_file_private (info, efile)) { + *result = GNOME_VFS_ERROR_GENERIC; + return NULL; + } + + s = gnome_vfs_get_uri_from_local_path (efile->filename); + ret_uri = gnome_vfs_uri_new (s); + g_free (s); + + return ret_uri; + } else { + if (the_folder != NULL) + *the_folder = (Folder *)entry; + *result = GNOME_VFS_ERROR_IS_DIRECTORY; + return NULL; + } +} + +static void +remove_file (Folder *folder, const char *basename) +{ + GSList *li; + char *s; + + if (folder->includes_ht != NULL) { + li = g_hash_table_lookup (folder->includes_ht, basename); + if (li != NULL) { + char *name = li->data; + folder->includes = g_slist_delete_link + (folder->includes, li); + g_hash_table_remove (folder->includes_ht, basename); + g_free (name); + } + } + + if (folder->excludes == NULL) { + folder->excludes = g_hash_table_new_full + (g_str_hash, g_str_equal, + (GDestroyNotify)g_free, + NULL); + } + s = g_strdup (basename); + g_hash_table_replace (folder->excludes, s, s); +} + +static void +add_file (Folder *folder, const char *basename) +{ + GSList *li = NULL; + + if (folder->includes_ht != NULL) { + li = g_hash_table_lookup (folder->includes_ht, basename); + } + + /* if not found */ + if (li == NULL) { + char *str = g_strdup (basename); + folder->includes = + g_slist_prepend (folder->includes, str); + if (folder->includes_ht == NULL) { + folder->includes_ht = + g_hash_table_new_full (g_str_hash, + g_str_equal, + NULL, + NULL); + } + g_hash_table_replace (folder->includes_ht, + str, folder->includes); + } + if (folder->excludes != NULL) + g_hash_table_remove (folder->excludes, basename); +} + +typedef struct _FileHandle FileHandle; +struct _FileHandle { + VFolderInfo *info; + GnomeVFSMethodHandle *handle; + Entry *entry; + gboolean write; + gboolean is_directory_file; +}; + +static void +make_handle (GnomeVFSMethodHandle **method_handle, + GnomeVFSMethodHandle *file_handle, + VFolderInfo *info, + Entry *entry, + gboolean is_directory_file, + gboolean write) +{ + if (file_handle != NULL) { + FileHandle *handle = g_new0 (FileHandle, 1); + + handle->info = info; + handle->handle = file_handle; + handle->entry = entry_ref (entry); + handle->is_directory_file = is_directory_file; + handle->write = write; + + *method_handle = (GnomeVFSMethodHandle *) handle; + } else { + *method_handle = NULL; + } +} + +static void +whack_handle (FileHandle *handle) +{ + entry_unref (handle->entry); + handle->entry = NULL; + + handle->handle = NULL; + handle->info = NULL; + + g_free (handle); +} + +static GnomeVFSResult +do_open (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result = GNOME_VFS_OK; + VFolderInfo *info; + Entry *entry; + gboolean is_directory_file; + GnomeVFSMethodHandle *file_handle = NULL; + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + /* These can't be very nice FILE names */ + if (vuri.file == NULL || + vuri.ends_in_slash) + return GNOME_VFS_ERROR_INVALID_URI; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (mode & GNOME_VFS_OPEN_WRITE && + (info->read_only || vuri.is_all_scheme)) + return GNOME_VFS_ERROR_READ_ONLY; + + G_LOCK (vfolder_lock); + file_uri = desktop_uri_to_file_uri (info, + &vuri, + &entry, + &is_directory_file, + NULL /* the_folder */, + mode & GNOME_VFS_OPEN_WRITE, + &result, + context); + + if (file_uri == NULL) { + G_UNLOCK (vfolder_lock); + return result; + } + + result = (* parent_method->open) (parent_method, + &file_handle, + file_uri, + mode, + context); + + if (result == GNOME_VFS_ERROR_CANCELLED) { + G_UNLOCK (vfolder_lock); + gnome_vfs_uri_unref (file_uri); + return result; + } + + make_handle (method_handle, + file_handle, + info, + entry, + is_directory_file, + mode & GNOME_VFS_OPEN_WRITE); + + gnome_vfs_uri_unref (file_uri); + + if (info->dirty) { + vfolder_info_write_user (info); + } + + G_UNLOCK (vfolder_lock); + + return result; +} + +static void +remove_from_all_except (Folder *root, + const char *name, + Folder *except) +{ + GSList *li; + + if (root != except) { + remove_file (root, name); + if (root->up_to_date) { + for (li = root->entries; li != NULL; li = li->next) { + Entry *entry = li->data; + if (strcmp (name, entry->name) == 0) { + root->entries = + g_slist_delete_link + (root->entries, li); + break; + } + } + } + } + + for (li = root->subfolders; li != NULL; li = li->next) { + Folder *subfolder = li->data; + + remove_from_all_except (subfolder, name, except); + } +} + +static GnomeVFSResult +do_create (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + gboolean exclusive, + guint perm, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + GnomeVFSMethodHandle *file_handle; + GnomeVFSURI *file_uri; + VFolderURI vuri; + VFolderInfo *info; + Folder *parent; + Entry *entry; + EntryFile *efile; + char *s; + GSList *li; + + VFOLDER_URI_PARSE (uri, &vuri); + + /* These can't be very nice FILE names */ + if (vuri.file == NULL || + vuri.ends_in_slash) + return GNOME_VFS_ERROR_INVALID_URI; + + if ( ! check_ext (vuri.file, ".desktop") && + ! strcmp (vuri.file, ".directory") == 0) { + return GNOME_VFS_ERROR_INVALID_URI; + } + + /* all scheme is read only */ + if (vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (info->user_filename == NULL || + info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + parent = resolve_folder (info, vuri.path, + TRUE /* ignore_basename */, + &result, context); + if (parent == NULL) + return result; + + if (parent->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + if (strcmp (vuri.file, ".directory") == 0) { + char *fname; + + G_LOCK (vfolder_lock); + + if (exclusive) { + char *desktop_file; + desktop_file = get_directory_file_unlocked (info, parent); + if (desktop_file != NULL) { + g_free (desktop_file); + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_FILE_EXISTS; + } + } + + if ( ! make_dirfile_private (info, parent)) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_GENERIC; + } + fname = g_build_filename (g_get_home_dir (), + parent->desktop_file, + NULL); + s = gnome_vfs_get_uri_from_local_path (fname); + file_uri = gnome_vfs_uri_new (s); + g_free (fname); + g_free (s); + + if (file_uri == NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_GENERIC; + } + + result = (* parent_method->create) (parent_method, + &file_handle, + file_uri, + mode, + exclusive, + perm, + context); + gnome_vfs_uri_unref (file_uri); + + make_handle (method_handle, + file_handle, + info, + (Entry *)parent, + TRUE /* is_directory_file */, + TRUE /* write */); + + if (info->dirty) + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return result; + } + + ensure_folder (info, parent, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + + entry = find_entry (parent->entries, vuri.file); + + if (entry != NULL && + entry->type == ENTRY_FOLDER) + return GNOME_VFS_ERROR_IS_DIRECTORY; + + efile = (EntryFile *)entry; + + if (efile != NULL) { + if (exclusive) + return GNOME_VFS_ERROR_FILE_EXISTS; + + G_LOCK (vfolder_lock); + if ( ! make_file_private (info, efile)) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_GENERIC; + } + + s = gnome_vfs_get_uri_from_local_path (efile->filename); + file_uri = gnome_vfs_uri_new (s); + g_free (s); + + if (file_uri == NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_GENERIC; + } + + result = (* parent_method->create) (parent_method, + &file_handle, + file_uri, + mode, + exclusive, + perm, + context); + gnome_vfs_uri_unref (file_uri); + + make_handle (method_handle, + file_handle, + info, + (Entry *)efile, + FALSE /* is_directory_file */, + TRUE /* write */); + + G_UNLOCK (vfolder_lock); + + return result; + } + + G_LOCK (vfolder_lock); + + li = g_hash_table_lookup (info->entries_ht, vuri.file); + + if (exclusive && li != NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_FILE_EXISTS; + } + + if (li == NULL) { + efile = file_new (vuri.file); + vfolder_info_insert_entry (info, efile); + entry_unref ((Entry *)efile); + } else { + efile = li->data; + } + + /* this will make a private name for this */ + if ( ! make_file_private (info, efile)) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_GENERIC; + } + + add_file (parent, vuri.file); + parent->sorted = FALSE; + + if (parent->up_to_date) + parent->entries = g_slist_prepend (parent->entries, efile); + + /* if we created a brand new name, then we exclude it + * from everywhere else to ensure overall sanity */ + if (li == NULL) + remove_from_all_except (info->root, vuri.file, parent); + + s = gnome_vfs_get_uri_from_local_path (efile->filename); + file_uri = gnome_vfs_uri_new (s); + g_free (s); + + result = (* parent_method->create) (parent_method, + &file_handle, + file_uri, + mode, + exclusive, + perm, + context); + gnome_vfs_uri_unref (file_uri); + + make_handle (method_handle, + file_handle, + info, + (Entry *)efile, + FALSE /* is_directory_file */, + TRUE /* write */); + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return result; +} + +static GnomeVFSResult +do_close (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + if (method_handle == (GnomeVFSMethodHandle *)method) + return GNOME_VFS_OK; + + G_LOCK (vfolder_lock); + + result = (* parent_method->close) (parent_method, + handle->handle, + context); + handle->handle = NULL; + + /* we reread the Categories keyword */ + if (handle->write && + handle->entry != NULL && + handle->entry->type == ENTRY_FILE) { + EntryFile *efile = (EntryFile *)handle->entry; + char *categories; + readitem_entry (efile->filename, + "Categories", + &categories, + NULL, + NULL); + set_keywords (efile, categories); + g_free (categories); + /* FIXME: what about OnlyShowIn */ + + /* FIXME: check if the keywords changed, if not, do + * nothing */ + + /* Perhaps a bit drastic */ + /* also this emits the CHANGED monitor signal */ + invalidate_folder_T (handle->info->root); + + /* the file changed monitor will happen by itself + * as the underlying file is changed */ + } else if (handle->write && + handle->entry != NULL && + handle->entry->type == ENTRY_FOLDER && + handle->is_directory_file) { + /* if we're monitoring this directory, emit the CHANGED + * monitor thing, it will also emit a changed on + * the file itself. It is better to emit changed + * just in case. */ + emit_monitor ((Folder *)(handle->entry), + GNOME_VFS_MONITOR_EVENT_CHANGED); + } + + whack_handle (handle); + + G_UNLOCK (vfolder_lock); + + return result; +} + +static void +fill_buffer (gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read) +{ + char *buf = buffer; + GnomeVFSFileSize i; + for (i = 0; i < num_bytes; i++) { + if (rand () % 32 == 0 || + i == num_bytes-1) + buf[i] = '\n'; + else + buf[i] = ((rand()>>4) % 94) + 32; + } + if (bytes_read != 0) + *bytes_read = i; +} + +static GnomeVFSResult +do_read (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + if (method_handle == (GnomeVFSMethodHandle *)method) { + if ((rand () >> 4) & 0x3) { + fill_buffer (buffer, num_bytes, bytes_read); + return GNOME_VFS_OK; + } else { + return GNOME_VFS_ERROR_EOF; + } + } + + result = (* parent_method->read) (parent_method, + handle->handle, + buffer, num_bytes, + bytes_read, + context); + + return result; +} + +static GnomeVFSResult +do_write (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gconstpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_written, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + if (method_handle == (GnomeVFSMethodHandle *)method) + return GNOME_VFS_OK; + + result = (* parent_method->write) (parent_method, + handle->handle, + buffer, num_bytes, + bytes_written, + context); + + return result; +} + + +static GnomeVFSResult +do_seek (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSSeekPosition whence, + GnomeVFSFileOffset offset, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + if (method_handle == (GnomeVFSMethodHandle *)method) + return GNOME_VFS_OK; + + result = (* parent_method->seek) (parent_method, + handle->handle, + whence, offset, + context); + + return result; +} + +static GnomeVFSResult +do_tell (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileOffset *offset_return) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + result = (* parent_method->tell) (parent_method, + handle->handle, + offset_return); + + return result; +} + + +static GnomeVFSResult +do_truncate_handle (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileSize where, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + if (method_handle == (GnomeVFSMethodHandle *)method) + return GNOME_VFS_OK; + + result = (* parent_method->truncate_handle) (parent_method, + handle->handle, + where, + context); + + return result; +} + +static GnomeVFSResult +do_truncate (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileSize where, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result = GNOME_VFS_OK; + VFolderInfo *info; + Entry *entry; + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + /* These can't be very nice FILE names */ + if (vuri.file == NULL || + vuri.ends_in_slash) + return GNOME_VFS_ERROR_INVALID_URI; + + if (vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + G_LOCK (vfolder_lock); + file_uri = desktop_uri_to_file_uri (info, + &vuri, + &entry, + NULL /* the_is_directory_file */, + NULL /* the_folder */, + TRUE /* privatize */, + &result, + context); + G_UNLOCK (vfolder_lock); + + if (file_uri == NULL) + return result; + + result = (* parent_method->truncate) (parent_method, + file_uri, + where, + context); + + gnome_vfs_uri_unref (file_uri); + + if (info->dirty) { + G_LOCK (vfolder_lock); + vfolder_info_write_user (info); + G_UNLOCK (vfolder_lock); + } + + if (entry->type == ENTRY_FILE) { + EntryFile *efile = (EntryFile *)entry; + + G_LOCK (vfolder_lock); + g_slist_free (efile->keywords); + efile->keywords = NULL; + G_UNLOCK (vfolder_lock); + } + + /* Perhaps a bit drastic, but oh well */ + invalidate_folder (info->root); + + return result; +} + +typedef struct _DirHandle DirHandle; +struct _DirHandle { + VFolderInfo *info; + Folder *folder; + + GnomeVFSFileInfoOptions options; + + /* List of Entries */ + GSList *list; + GSList *current; +}; + +static GnomeVFSResult +do_open_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + VFolderURI vuri; + DirHandle *dh; + Folder *folder; + VFolderInfo *info; + char *desktop_file; + + VFOLDER_URI_PARSE (uri, &vuri); + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + /* In the all- scheme just list all filenames */ + if (vuri.is_all_scheme) { + if (any_subdir (vuri.path)) + return GNOME_VFS_ERROR_NOT_FOUND; + + dh = g_new0 (DirHandle, 1); + dh->info = info; + dh->options = options; + dh->folder = NULL; + + G_LOCK (vfolder_lock); + dh->list = g_slist_copy (info->entries); + g_slist_foreach (dh->list, (GFunc)entry_ref, NULL); + dh->current = dh->list; + G_UNLOCK (vfolder_lock); + + *method_handle = (GnomeVFSMethodHandle*) dh; + return GNOME_VFS_OK; + } + + folder = resolve_folder (info, vuri.path, + FALSE /* ignore_basename */, + &result, context); + if (folder == NULL) + return result; + + /* Make sure we have the entries and sorted here */ + ensure_folder_sort (info, folder); + + dh = g_new0 (DirHandle, 1); + dh->info = info; + dh->options = options; + + G_LOCK (vfolder_lock); + dh->folder = (Folder *)entry_ref ((Entry *)folder); + dh->list = g_slist_copy (folder->entries); + g_slist_foreach (folder->entries, (GFunc)entry_ref, NULL); + G_UNLOCK (vfolder_lock); + + desktop_file = get_directory_file (info, folder); + if (desktop_file != NULL) { + EntryFile *efile = file_new (".directory"); + dh->list = g_slist_prepend (dh->list, efile); + g_free (desktop_file); + } + + dh->current = dh->list; + + *method_handle = (GnomeVFSMethodHandle*) dh; + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_close_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + DirHandle *dh; + + dh = (DirHandle*) method_handle; + + G_LOCK (vfolder_lock); + + g_slist_foreach (dh->list, (GFunc)entry_unref, NULL); + g_slist_free (dh->list); + dh->list = NULL; + + dh->current = NULL; + + if (dh->folder != NULL) + entry_unref ((Entry *)dh->folder); + dh->folder = NULL; + + dh->info = NULL; + + g_free (dh); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_read_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSContext *context) +{ + DirHandle *dh; + Entry *entry; + GnomeVFSFileInfoOptions options; + + dh = (DirHandle*) method_handle; + +read_directory_again: + + if (dh->current == NULL) { + return GNOME_VFS_ERROR_EOF; + } + + entry = dh->current->data; + dh->current = dh->current->next; + + options = dh->options; + + if (entry->type == ENTRY_FILE && + ((EntryFile *)entry)->filename != NULL) { + EntryFile *efile = (EntryFile *)entry; + char *furi = gnome_vfs_get_uri_from_local_path (efile->filename); + GnomeVFSURI *uri = gnome_vfs_uri_new (furi); + + /* we always get mime-type by forcing it below */ + if (options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE) + options &= ~GNOME_VFS_FILE_INFO_GET_MIME_TYPE; + + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_NONE; + + /* Get the file info for this */ + (* parent_method->get_file_info) (parent_method, + uri, + file_info, + options, + context); + + /* we ignore errors from this since the file_info just + * won't be filled completely if there's an error, that's all */ + + g_free (file_info->mime_type); + file_info->mime_type = g_strdup ("application/x-gnome-app-info"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + /* Now we wipe those fields we don't support */ + file_info->valid_fields &= ~(UNSUPPORTED_INFO_FIELDS); + + gnome_vfs_uri_unref (uri); + g_free (furi); + } else if (entry->type == ENTRY_FILE) { + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_NONE; + + file_info->name = g_strdup (entry->name); + GNOME_VFS_FILE_INFO_SET_LOCAL (file_info, TRUE); + + file_info->type = GNOME_VFS_FILE_TYPE_REGULAR; + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_TYPE; + + /* FIXME: Is this correct? isn't there an xdg mime type? */ + file_info->mime_type = g_strdup ("application/x-gnome-app-info"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + /* FIXME: get some ctime/mtime */ + } else /* ENTRY_FOLDER */ { + Folder *folder = (Folder *)entry; + + /* Skip empty folders if they have + * the flag set */ + if (folder->dont_show_if_empty) { + /* Make sure we have the entries */ + ensure_folder (dh->info, folder, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + + if (folder->entries == NULL) { + /* start this function over on the + * next item */ + goto read_directory_again; + } + } + + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_NONE; + + file_info->name = g_strdup (entry->name); + GNOME_VFS_FILE_INFO_SET_LOCAL (file_info, TRUE); + + file_info->type = GNOME_VFS_FILE_TYPE_DIRECTORY; + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_TYPE; + + file_info->mime_type = g_strdup ("x-directory/vfolder-desktop"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + file_info->ctime = dh->info->modification_time; + file_info->mtime = dh->info->modification_time; + file_info->valid_fields |= (GNOME_VFS_FILE_INFO_FIELDS_CTIME | + GNOME_VFS_FILE_INFO_FIELDS_MTIME); + } + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_get_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result = GNOME_VFS_OK; + Folder *folder; + VFolderInfo *info; + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + G_LOCK (vfolder_lock); + file_uri = desktop_uri_to_file_uri (info, + &vuri, + NULL /* the_entry */, + NULL /* the_is_directory_file */, + &folder, + FALSE /* privatize */, + &result, + context); + G_UNLOCK (vfolder_lock); + + if (file_uri == NULL && + result != GNOME_VFS_ERROR_IS_DIRECTORY) + return result; + + if (file_uri != NULL) { + /* we always get mime-type by forcing it below */ + if (options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE) + options &= ~GNOME_VFS_FILE_INFO_GET_MIME_TYPE; + + result = (* parent_method->get_file_info) (parent_method, + file_uri, + file_info, + options, + context); + + g_free (file_info->mime_type); + file_info->mime_type = g_strdup ("application/x-gnome-app-info"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + /* Now we wipe those fields we don't support */ + file_info->valid_fields &= ~(UNSUPPORTED_INFO_FIELDS); + + gnome_vfs_uri_unref (file_uri); + + return result; + } else if (folder != NULL) { + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_NONE; + + file_info->name = g_strdup (folder->entry.name); + GNOME_VFS_FILE_INFO_SET_LOCAL (file_info, TRUE); + + file_info->type = GNOME_VFS_FILE_TYPE_DIRECTORY; + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_TYPE; + + file_info->mime_type = g_strdup ("x-directory/vfolder-desktop"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + file_info->ctime = info->modification_time; + file_info->mtime = info->modification_time; + file_info->valid_fields |= (GNOME_VFS_FILE_INFO_FIELDS_CTIME | + GNOME_VFS_FILE_INFO_FIELDS_MTIME); + + return GNOME_VFS_OK; + } else { + return GNOME_VFS_ERROR_NOT_FOUND; + } +} + +static GnomeVFSResult +do_get_file_info_from_handle (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + if (method_handle == (GnomeVFSMethodHandle *)method) { + g_free (file_info->mime_type); + file_info->mime_type = g_strdup ("text/plain"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + return GNOME_VFS_OK; + } + + /* we always get mime-type by forcing it below */ + if (options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE) + options &= ~GNOME_VFS_FILE_INFO_GET_MIME_TYPE; + + result = (* parent_method->get_file_info_from_handle) (parent_method, + handle->handle, + file_info, + options, + context); + + /* any file is of the .desktop type */ + g_free (file_info->mime_type); + file_info->mime_type = g_strdup ("application/x-gnome-app-info"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + /* Now we wipe those fields we don't support */ + file_info->valid_fields &= ~(UNSUPPORTED_INFO_FIELDS); + + return result; +} + + +static gboolean +do_is_local (GnomeVFSMethod *method, + const GnomeVFSURI *uri) +{ + return TRUE; +} + +static void +try_free_folder_monitors_create_unlocked (VFolderInfo *info, + Folder *folder) +{ + GSList *li, *list; + + list = g_slist_copy (info->free_folder_monitors); + + for (li = list; li != NULL; li = li->next) { + FileMonitorHandle *handle = li->data; + Folder *f; + VFolderURI vuri; + GnomeVFSResult result; + + /* Evil! EVIL URI PARSING. this will eat a lot of stack if we + * have lots of free monitors */ + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + f = resolve_folder (info, + vuri.path, + FALSE /* ignore_basename */, + &result, + NULL); + + if (folder != f) + continue; + + info->free_folder_monitors = + g_slist_remove (info->free_folder_monitors, handle); + ((Entry *)folder)->monitors = + g_slist_prepend (((Entry *)folder)->monitors, handle); + + handle->exists = TRUE; + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *)handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_CREATED); + } +} + + +static GnomeVFSResult +do_make_directory (GnomeVFSMethod *method, + GnomeVFSURI *uri, + guint perm, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + VFolderInfo *info; + Folder *parent, *folder; + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + if (vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (info->user_filename == NULL || + info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + parent = resolve_folder (info, vuri.path, + TRUE /* ignore_basename */, + &result, context); + if (parent == NULL) + return result; + else if (parent->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + G_LOCK (vfolder_lock); + + folder = (Folder *)find_entry (parent->subfolders, + vuri.file); + if (folder != NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_FILE_EXISTS; + } + + folder = folder_new (vuri.file); + parent->subfolders = g_slist_append (parent->subfolders, folder); + folder->parent = parent; + parent->up_to_date = FALSE; + + try_free_folder_monitors_create_unlocked (info, folder); + + /* parent changed */ + emit_monitor (parent, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_remove_directory (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + Folder *folder; + VFolderInfo *info; + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + if (vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (info->user_filename == NULL || + info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + G_LOCK (vfolder_lock); + + folder = resolve_folder (info, vuri.path, + FALSE /* ignore_basename */, + &result, context); + if (folder == NULL) { + G_UNLOCK (vfolder_lock); + return result; + } + + if (folder->read_only || + (folder->parent != NULL && + folder->parent->read_only)) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_READ_ONLY; + } + + /* don't make removing directories easy */ + if (folder->desktop_file != NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY; + } + + /* Make sure we have the entries */ + ensure_folder_unlocked (info, folder, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + + /* don't make removing directories easy */ + if (folder->entries != NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY; + } + + emit_and_delete_monitor (info, folder); + + if (folder->only_unallocated) { + GSList *li = g_slist_find (info->unallocated_folders, + folder); + if (li != NULL) { + info->unallocated_folders = g_slist_delete_link + (info->unallocated_folders, li); + entry_unref ((Entry *)folder); + } + } + + if (folder == info->root) { + info->root = NULL; + entry_unref ((Entry *)folder); + info->root = folder_new ("Root"); + } else { + Folder *parent = folder->parent; + + g_assert (parent != NULL); + + parent->subfolders = + g_slist_remove (parent->subfolders, folder); + + parent->up_to_date = FALSE; + + entry_unref ((Entry *)folder); + + /* parent changed */ + emit_monitor (parent, GNOME_VFS_MONITOR_EVENT_CHANGED); + } + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; +} + +/* a fairly evil function that does the whole move bit by copy and + * remove */ +static GnomeVFSResult +long_move (GnomeVFSMethod *method, + VFolderURI *old_vuri, + VFolderURI *new_vuri, + gboolean force_replace, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + GnomeVFSMethodHandle *handle; + GnomeVFSURI *file_uri; + const char *path; + int fd; + char buf[BUFSIZ]; + int bytes; + VFolderInfo *info; + + info = get_vfolder_info (old_vuri->scheme, &result, context); + if (info == NULL) + return result; + + G_LOCK (vfolder_lock); + file_uri = desktop_uri_to_file_uri (info, + old_vuri, + NULL /* the_entry */, + NULL /* the_is_directory_file */, + NULL /* the_folder */, + FALSE /* privatize */, + &result, + context); + G_UNLOCK (vfolder_lock); + + if (file_uri == NULL) + return result; + + path = gnome_vfs_uri_get_path (file_uri); + if (path == NULL) { + gnome_vfs_uri_unref (file_uri); + return GNOME_VFS_ERROR_INVALID_URI; + } + + fd = open (path, O_RDONLY); + if (fd < 0) { + gnome_vfs_uri_unref (file_uri); + return gnome_vfs_result_from_errno (); + } + + gnome_vfs_uri_unref (file_uri); + + info->inhibit_write++; + + result = method->create (method, + &handle, + new_vuri->uri, + GNOME_VFS_OPEN_WRITE, + force_replace /* exclusive */, + 0600 /* perm */, + context); + if (result != GNOME_VFS_OK) { + close (fd); + info->inhibit_write--; + return result; + } + + while ((bytes = read (fd, buf, BUFSIZ)) > 0) { + GnomeVFSFileSize bytes_written = 0; + result = method->write (method, + handle, + buf, + bytes, + &bytes_written, + context); + if (result == GNOME_VFS_OK && + bytes_written != bytes) + result = GNOME_VFS_ERROR_NO_SPACE; + if (result != GNOME_VFS_OK) { + close (fd); + method->close (method, handle, context); + /* FIXME: is this completely correct ? */ + method->unlink (method, + new_vuri->uri, + context); + G_LOCK (vfolder_lock); + info->inhibit_write--; + vfolder_info_write_user (info); + G_UNLOCK (vfolder_lock); + return result; + } + } + + close (fd); + + result = method->close (method, handle, context); + if (result != GNOME_VFS_OK) { + G_LOCK (vfolder_lock); + info->inhibit_write--; + vfolder_info_write_user (info); + G_UNLOCK (vfolder_lock); + return result; + } + + result = method->unlink (method, old_vuri->uri, context); + + G_LOCK (vfolder_lock); + info->inhibit_write--; + vfolder_info_write_user (info); + G_UNLOCK (vfolder_lock); + + return result; +} + +static GnomeVFSResult +move_directory_file (VFolderInfo *info, + Folder *old_folder, + Folder *new_folder) +{ + if (old_folder->desktop_file == NULL) + return GNOME_VFS_ERROR_NOT_FOUND; + + /* "move" the desktop file */ + g_free (new_folder->desktop_file); + new_folder->desktop_file = old_folder->desktop_file; + old_folder->desktop_file = NULL; + + /* is this too drastic, it will requery the folder? */ + new_folder->up_to_date = FALSE; + old_folder->up_to_date = FALSE; + + emit_monitor (new_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + emit_monitor (old_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + + return GNOME_VFS_OK; +} + +static gboolean +is_sub (Folder *master, Folder *sub) +{ + GSList *li; + + for (li = master->subfolders; li != NULL; li = li->next) { + Folder *subfolder = li->data; + + if (subfolder == sub || + is_sub (subfolder, sub)) + return TRUE; + } + + return FALSE; +} + +static GnomeVFSResult +move_folder (VFolderInfo *info, + Folder *old_folder, Entry *old_entry, + Folder *new_folder, Entry *new_entry) +{ + Folder *source = (Folder *)old_entry; + Folder *target; + + if (new_entry != NULL && + new_entry->type != ENTRY_FOLDER) + return GNOME_VFS_ERROR_NOT_A_DIRECTORY; + + if (new_entry != NULL) { + target = (Folder *)new_entry; + } else { + target = new_folder; + } + + /* move to where we are, yay, we're done :) */ + if (source->parent == target) + return GNOME_VFS_OK; + + if (source == target || + is_sub (source, target)) + return GNOME_VFS_ERROR_LOOP; + + /* this will never happen, but we're paranoid */ + if (source->parent == NULL) + return GNOME_VFS_ERROR_LOOP; + + source->parent->subfolders = g_slist_remove (source->parent->subfolders, + source); + target->subfolders = g_slist_append (target->subfolders, + source); + + source->parent = target; + + source->up_to_date = FALSE; + target->up_to_date = FALSE; + + emit_monitor (source, GNOME_VFS_MONITOR_EVENT_CHANGED); + emit_monitor (target, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_move (GnomeVFSMethod *method, + GnomeVFSURI *old_uri, + GnomeVFSURI *new_uri, + gboolean force_replace, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + VFolderInfo *info; + Folder *old_folder, *new_folder; + Entry *old_entry, *new_entry; + gboolean old_is_directory_file, new_is_directory_file; + VFolderURI old_vuri, new_vuri; + + VFOLDER_URI_PARSE (old_uri, &old_vuri); + VFOLDER_URI_PARSE (new_uri, &new_vuri); + + if (old_vuri.file == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + if (old_vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + if (strcmp (old_vuri.scheme, new_vuri.scheme) != 0) + return GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM; + + info = get_vfolder_info (old_vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + old_entry = get_entry (&old_vuri, + &old_folder, + &old_is_directory_file, + &result, + context); + if (old_entry == NULL) + return result; + + if (old_folder != NULL && old_folder->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + new_entry = get_entry (&new_vuri, + &new_folder, + &new_is_directory_file, + &result, + context); + if (new_entry == NULL && new_folder == NULL) + return result; + + if (new_folder != NULL && new_folder->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + if (new_is_directory_file != old_is_directory_file) { + /* this will do another set of lookups + * perhaps this can be done in a nicer way, + * but is this the common case? I don't think so */ + return long_move (method, &old_vuri, &new_vuri, + force_replace, context); + } + + if (new_is_directory_file) { + g_assert (old_entry != NULL); + g_assert (new_entry != NULL); + G_LOCK (vfolder_lock); + result = move_directory_file (info, + (Folder *)old_entry, + (Folder *)new_entry); + G_UNLOCK (vfolder_lock); + return result; + } + + if (old_entry->type == ENTRY_FOLDER) { + G_LOCK (vfolder_lock); + result = move_folder (info, + old_folder, old_entry, + new_folder, new_entry); + G_UNLOCK (vfolder_lock); + return result; + } + + /* move into self, just whack the old one */ + if (old_entry == new_entry) { + /* same folder */ + if (new_folder == old_folder) + return GNOME_VFS_OK; + + if ( ! force_replace) + return GNOME_VFS_ERROR_FILE_EXISTS; + + G_LOCK (vfolder_lock); + + remove_file (old_folder, old_vuri.file); + + old_folder->entries = g_slist_remove (old_folder->entries, + old_entry); + entry_unref (old_entry); + + emit_monitor (old_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; + } + + /* this is a simple move */ + if (new_entry == NULL || + new_entry->type == ENTRY_FOLDER) { + if (new_entry != NULL) { + new_folder = (Folder *)new_entry; + } else { + /* a file and a totally different one */ + if (strcmp (new_vuri.file, old_entry->name) != 0) { + /* yay, a long move */ + /* this will do another set of lookups + * perhaps this can be done in a nicer way, + * but is this the common case? I don't think + * so */ + return long_move (method, &old_vuri, &new_vuri, + force_replace, context); + } + } + + /* same folder */ + if (new_folder == old_folder) + return GNOME_VFS_OK; + + G_LOCK (vfolder_lock); + + remove_file (old_folder, old_entry->name); + add_file (new_folder, old_entry->name); + + new_folder->entries = g_slist_prepend (new_folder->entries, + old_entry); + entry_ref (old_entry); + new_folder->sorted = FALSE; + + old_folder->entries = g_slist_remove (old_folder->entries, + old_entry); + entry_unref (old_entry); + + emit_monitor (new_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + emit_monitor (old_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; + } + + /* do we EVER get here? */ + + /* this will do another set of lookups + * perhaps this can be done in a nicer way, + * but is this the common case? I don't think so */ + return long_move (method, &old_vuri, &new_vuri, + force_replace, context); +} + +static GnomeVFSResult +do_unlink (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + Entry *entry; + Folder *the_folder; + gboolean is_directory_file; + VFolderInfo *info; + VFolderURI vuri; + GSList *li; + + VFOLDER_URI_PARSE (uri, &vuri); + + if (vuri.file == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + if (vuri.is_all_scheme == TRUE) + return GNOME_VFS_ERROR_READ_ONLY; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + else if (info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + entry = get_entry (&vuri, + &the_folder, + &is_directory_file, + &result, context); + if (entry == NULL) + return result; + else if (the_folder != NULL && + the_folder->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + if (entry->type == ENTRY_FOLDER && + is_directory_file) { + Folder *folder = (Folder *)entry; + + if (folder->desktop_file == NULL) + return GNOME_VFS_ERROR_NOT_FOUND; + + G_LOCK (vfolder_lock); + + g_free (folder->desktop_file); + folder->desktop_file = NULL; + + emit_monitor (folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; + } else if (entry->type == ENTRY_FOLDER) { + return GNOME_VFS_ERROR_IS_DIRECTORY; + } else if (the_folder == NULL) { + return GNOME_VFS_ERROR_NOT_FOUND; + } + + G_LOCK (vfolder_lock); + + the_folder->entries = g_slist_remove (the_folder->entries, + entry); + entry_unref (entry); + + remove_file (the_folder, vuri.file); + + emit_monitor (the_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + + /* evil, we must remove this from the unallocated folders as well + * so that it magically doesn't appear there. But it's not so simple. + * We only want to remove it if it isn't in that folder already. */ + for (li = info->unallocated_folders; + li != NULL; + li = li->next) { + Folder *folder = li->data; + GSList *l; + + /* This is actually really evil since ensuring + * an unallocated folder clears all other unallocated + * folders in it's wake. I'm not sure it's worth + * optimizing however */ + ensure_folder_unlocked (info, folder, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + l = g_slist_find (folder->entries, entry); + if (l == NULL) { + remove_file (folder, vuri.file); + } + } + + emit_file_deleted_monitor (info, entry, the_folder); + + /* FIXME: if this was a user file and this is the only + * reference to it, unlink it. */ + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_check_same_fs (GnomeVFSMethod *method, + GnomeVFSURI *source_uri, + GnomeVFSURI *target_uri, + gboolean *same_fs_return, + GnomeVFSContext *context) +{ + VFolderURI source_vuri, target_vuri; + + *same_fs_return = FALSE; + + VFOLDER_URI_PARSE (source_uri, &source_vuri); + VFOLDER_URI_PARSE (target_uri, &target_vuri); + + if (strcmp (source_vuri.scheme, target_vuri.scheme) != 0 || + source_vuri.is_all_scheme != target_vuri.is_all_scheme) + *same_fs_return = FALSE; + else + *same_fs_return = TRUE; + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_set_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + const GnomeVFSFileInfo *info, + GnomeVFSSetFileInfoMask mask, + GnomeVFSContext *context) +{ + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + if (vuri.file == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + if (mask & GNOME_VFS_SET_FILE_INFO_NAME) { + GnomeVFSResult result = GNOME_VFS_OK; + char *dirname = gnome_vfs_uri_extract_dirname (uri); + GnomeVFSURI *new_uri = gnome_vfs_uri_dup (uri); + + G_LOCK (vfolder_lock); + g_free (new_uri->text); + new_uri->text = g_build_path ("/", dirname, info->name, NULL); + G_UNLOCK (vfolder_lock); + + result = do_move (method, + uri, + new_uri, + FALSE /* force_replace */, + context); + + g_free (dirname); + gnome_vfs_uri_unref (new_uri); + return result; + } else { + /* We don't support setting any of this other permission, + * times and all that voodoo */ + return GNOME_VFS_ERROR_NOT_SUPPORTED; + } +} + +static GnomeVFSResult +do_monitor_add (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle_return, + GnomeVFSURI *uri, + GnomeVFSMonitorType monitor_type) +{ + VFolderInfo *info; + VFolderURI vuri; + GnomeVFSResult result; + Folder *folder; + Entry *entry; + GnomeVFSURI *file_uri; + FileMonitorHandle *handle; + gboolean is_directory_file; + + VFOLDER_URI_PARSE (uri, &vuri); + + info = get_vfolder_info (vuri.scheme, &result, NULL); + if (info == NULL) + return result; + + if (monitor_type == GNOME_VFS_MONITOR_DIRECTORY) { + G_LOCK (vfolder_lock); + + folder = resolve_folder (info, + vuri.path, + FALSE /* ignore_basename */, + &result, + NULL); + + handle = g_new0 (FileMonitorHandle, 1); + handle->refcount = 2; + handle->uri = gnome_vfs_uri_dup (uri); + handle->dir_monitor = TRUE; + handle->handle = NULL; + handle->filename = NULL; + + if (folder == NULL) { + handle->exists = FALSE; + info->free_folder_monitors = + g_slist_prepend (info->free_folder_monitors, + handle); + } else { + handle->exists = TRUE; + ((Entry *)folder)->monitors = + g_slist_prepend (((Entry *)folder)->monitors, + handle); + } + + info->folder_monitors = + g_slist_prepend (info->folder_monitors, handle); + + G_UNLOCK (vfolder_lock); + + *method_handle_return = (GnomeVFSMethodHandle *) handle; + + return GNOME_VFS_OK; + } else { + /* These can't be very nice FILE names */ + if (vuri.file == NULL || + vuri.ends_in_slash) + return GNOME_VFS_ERROR_INVALID_URI; + + G_LOCK (vfolder_lock); + file_uri = desktop_uri_to_file_uri (info, + &vuri, + &entry, + &is_directory_file, + NULL /* the_folder */, + FALSE, + &result, + NULL); + + handle = g_new0 (FileMonitorHandle, 1); + handle->refcount = 2; + handle->uri = gnome_vfs_uri_dup (uri); + handle->dir_monitor = FALSE; + handle->handle = NULL; + handle->filename = g_strdup (vuri.file); + handle->is_directory_file = is_directory_file; + + info->file_monitors = + g_slist_prepend (info->file_monitors, handle); + + + if (file_uri == NULL) { + handle->exists = FALSE; + info->free_file_monitors = + g_slist_prepend (info->free_file_monitors, + handle); + } else { + char *uri_string = gnome_vfs_uri_to_string (file_uri, 0); + handle->exists = TRUE; + gnome_vfs_monitor_add (&(handle->handle), + uri_string, + GNOME_VFS_MONITOR_FILE, + file_monitor, + handle); + g_free (uri_string); + + entry->monitors = g_slist_prepend (entry->monitors, + handle); + gnome_vfs_uri_unref (file_uri); + } + + *method_handle_return = (GnomeVFSMethodHandle *) handle; + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; + } +} + +static GnomeVFSResult +do_monitor_cancel (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle) +{ + FileMonitorHandle *handle; + VFolderInfo *info; + VFolderURI vuri; + GnomeVFSResult result; + Folder *folder; + GSList *li; + + handle = (FileMonitorHandle *)method_handle; + + /* FIXME: is this correct? */ + if (method_handle == NULL) + return GNOME_VFS_OK; + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + info = get_vfolder_info (vuri.scheme, &result, NULL); + if (info == NULL) + return result; + + if (handle->dir_monitor) { + G_LOCK (vfolder_lock); + + folder = resolve_folder (info, + vuri.path, + FALSE /* ignore_basename */, + &result, + NULL); + + for (li = info->folder_monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + if (h != handle) + continue; + info->folder_monitors = g_slist_delete_link + (info->folder_monitors, li); + file_monitor_handle_unref_unlocked (h); + break; + } + + if (folder == NULL) { + for (li = info->free_folder_monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *h = li->data; + if (h != handle) + continue; + info->free_folder_monitors = g_slist_delete_link + (info->free_folder_monitors, li); + file_monitor_handle_unref_unlocked (h); + break; + } + } else { + for (li = ((Entry *)folder)->monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *h = li->data; + if (h != handle) + continue; + ((Entry *)folder)->monitors = + g_slist_delete_link + (((Entry *)folder)->monitors, li); + file_monitor_handle_unref_unlocked (h); + break; + } + } + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; + } else { + G_LOCK (vfolder_lock); + + for (li = info->file_monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + if (h != handle) + continue; + info->file_monitors = g_slist_delete_link + (info->file_monitors, li); + file_monitor_handle_unref_unlocked (h); + break; + } + + for (li = info->free_file_monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *h = li->data; + if (h != handle) + continue; + info->free_file_monitors = g_slist_delete_link + (info->free_file_monitors, li); + file_monitor_handle_unref_unlocked (h); + break; + } + + for (li = info->entries; li != NULL; li = li->next) { + Entry *e = li->data; + GSList *link = g_slist_find (e->monitors, handle); + + if (link == NULL) + continue; + link->data = NULL; + e->monitors = g_slist_delete_link (e->monitors, link); + + file_monitor_handle_unref_unlocked (handle); + break; + } + + G_UNLOCK (vfolder_lock); + + /* Note: last unref of our monitor will cancel the + * underlying handle */ + + return GNOME_VFS_OK; + } +} + + +/* gnome-vfs bureaucracy */ + +static GnomeVFSMethod method = { + sizeof (GnomeVFSMethod), + do_open, + do_create, + do_close, + do_read, + do_write, + do_seek, + do_tell, + do_truncate_handle, + do_open_directory, + do_close_directory, + do_read_directory, + do_get_file_info, + do_get_file_info_from_handle, + do_is_local, + do_make_directory, + do_remove_directory, + do_move, + do_unlink, + do_check_same_fs, + do_set_file_info, + do_truncate, + NULL /* find_directory */, + NULL /* create_symbolic_link */, + do_monitor_add, + do_monitor_cancel +}; + +GnomeVFSMethod * +vfs_module_init (const char *method_name, + const char *args) +{ + parent_method = gnome_vfs_method_get ("file"); + + if (parent_method == NULL) { + g_error ("Could not find 'file' method for gnome-vfs"); + return NULL; + } + + return &method; +} + +void +vfs_module_shutdown (GnomeVFSMethod *method) +{ + if (infos == NULL) + return; + + g_hash_table_destroy (infos); + infos = NULL; +} diff --git a/modules/vfolder-desktop-method.c.read-only b/modules/vfolder-desktop-method.c.read-only new file mode 100644 index 0000000..db3c2c7 --- /dev/null +++ b/modules/vfolder-desktop-method.c.read-only @@ -0,0 +1,6135 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: 8; c-basic-offset: 8 -*- */ + +/* vfolder-desktop-method.c + + Copyright (C) 2001 Red Hat, Inc. + Copyright (C) 2001 The Dark Prince + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/* URI scheme for reading the "applications:" vfolder and other + * vfolder schemes. Lots of code stolen from the original desktop + * reading URI scheme. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +/* Debugging foo: */ +/*#define D(x) x */ +#define D(x) ; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#define DOT_GNOME ".gnome2" + +typedef struct _VFolderInfo VFolderInfo; +typedef struct _Query Query; +typedef struct _QueryKeyword QueryKeyword; +typedef struct _QueryFilename QueryFilename; +typedef struct _Entry Entry; +typedef struct _Folder Folder; +typedef struct _EntryFile EntryFile; +typedef struct _Keyword Keyword; +typedef struct _FileMonitorHandle FileMonitorHandle; +typedef struct _StatLoc StatLoc; +typedef struct _VFolderURI VFolderURI; + +/* TODO before 2.0: */ +/* FIXME: also check/monitor desktop_dirs like we do the vfolder + * file and the item dirs */ +/* FIXME: check if thread locks are not completely on crack which + * is likely given my experience with threads */ +/* FIXME: use filename locking, currently we are full of races if + * multiple processes write to this filesystem */ +/* FIXME: implement monitors */ + +/* TODO for later (star trek future): */ +/* FIXME: Maybe when chaining to file:, we should call the gnome-vfs wrapper + * functions, instead of the file: methods directly. */ +/* FIXME: related to the above: we should support things being on non + * file: filesystems. Such as having the vfolder info file on http + * somewhere or some such nonsense :) */ + +static GnomeVFSMethod *parent_method = NULL; + +static GHashTable *infos = NULL; + +/* Note: I have no clue about how to write thread safe code and this + * is my first attempt, so it's probably wrong + * -George */ +G_LOCK_DEFINE_STATIC (vfolder_lock); + +/* Note: all keywords are quarks */ +/* Note: basenames are unique */ + +#define UNSUPPORTED_INFO_FIELDS (GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS | \ + GNOME_VFS_FILE_INFO_FIELDS_DEVICE | \ + GNOME_VFS_FILE_INFO_FIELDS_INODE | \ + GNOME_VFS_FILE_INFO_FIELDS_LINK_COUNT | \ + GNOME_VFS_FILE_INFO_FIELDS_ATIME) + + +enum { + QUERY_OR, + QUERY_AND, + QUERY_KEYWORD, + QUERY_FILENAME +}; + +struct _Query { + int type; + gboolean not; + GSList *queries; +}; + +struct _QueryKeyword { + int type; + gboolean not; + GQuark keyword; +}; + +struct _QueryFilename { + int type; + gboolean not; + char *filename; +}; + +enum { + ENTRY_FILE, + ENTRY_FOLDER +}; + +struct _Entry { + int type; + int refcount; + int alloc; /* not really useful for folders, + but oh well, whatever. It's the number + of times this is queried in some directory, + used for the Unallocated query type */ + char *name; + + GSList *monitors; +}; + +struct _EntryFile { + Entry entry; + + char *filename; + gboolean per_user; + GSList *keywords; + + gboolean implicit_keywords; /* the keywords were added by us */ +}; + +struct _Folder { + Entry entry; + + Folder *parent; + + char *desktop_file; /* the .directory file */ + + Query *query; + + /* The following is for per file + * access */ + /* excluded by filename */ + GHashTable *excludes; + /* included by filename */ + GSList *includes; + GHashTable *includes_ht; + + GSList *subfolders; + + /* Some flags */ + gboolean read_only; + gboolean dont_show_if_empty; + gboolean only_unallocated; /* include only unallocated items */ + + /* lazily done, will run query only when it + * needs to */ + gboolean up_to_date; + gboolean sorted; + GSList *entries; +}; + +struct _StatLoc { + time_t ctime; + time_t last_stat; + gboolean trigger_next; /* if true, next check will fail */ + char name[1]; /* the structure will be long enough to + fit name */ +}; + +struct _VFolderInfo { + char *scheme; + + char *filename; + char *user_filename; + time_t user_filename_last_write; + char *desktop_dir; /* directory with .directorys */ + char *user_desktop_dir; /* directory with .directorys */ + gboolean user_file_active; /* if using user_filename and + not filename */ + + GSList *item_dirs; + char *user_item_dir; /* dir where user changes to + items are stored */ + + /* old style dirs to merge in */ + GSList *merge_dirs; + + /* if entries are valid, else + * they need to be (re)read */ + gboolean entries_valid; + + GSList *entries; + + /* entry hash by basename */ + GHashTable *entries_ht; + + /* The root folder */ + Folder *root; + + /* The unallocated folders, the folder which only + * include unallocated items */ + GSList *unallocated_folders; + + /* some flags */ + gboolean read_only; + + gboolean dirty; + + int inhibit_write; + + /* change monitoring stuff */ + GnomeVFSMonitorHandle *filename_monitor; + GnomeVFSMonitorHandle *user_filename_monitor; + + /* stat locations (in case we aren't monitoring) */ + StatLoc *filename_statloc; + StatLoc *user_filename_statloc; + + /* for .directory dirs */ + /* FIXME: */GnomeVFSMonitorHandle *desktop_dir_monitor; + /* FIXME: */GnomeVFSMonitorHandle *user_desktop_dir_monitor; + + /* stat locations (in case we aren't monitoring) */ + /* FIXME: */StatLoc *desktop_dir_statloc; + /* FIXME: */StatLoc *user_desktop_dir_statloc; + + /* FIXME: */GSList *file_monitors; /* FileMonitorHandle */ + /* FIXME: */GSList *free_file_monitors; /* FileMonitorHandle */ + GSList *folder_monitors; /* FileMonitorHandle */ + GSList *free_folder_monitors; /* FileMonitorHandle */ + + GSList *item_dir_monitors; /* GnomeVFSMonitorHandle */ + + /* item dirs to stat */ + GSList *stat_dirs; + + /* ctime for folders */ + time_t modification_time; + + guint reread_queue; +}; + +struct _FileMonitorHandle { + int refcount; + gboolean exists; + gboolean dir_monitor; /* TRUE if dir, FALSE if file */ + GnomeVFSURI *uri; + GnomeVFSMonitorHandle *handle; /* A real handle if we're monitoring + an actual file here, or NULL */ + char *filename; /* Just the basename, used in the free_file_list */ + gboolean is_directory_file; +}; + +struct _VFolderURI { + const gchar *scheme; + gboolean is_all_scheme; + gboolean ends_in_slash; + gchar *path; + gchar *file; + GnomeVFSURI *uri; +}; + + +static Entry * entry_ref (Entry *entry); +static Entry * entry_ref_alloc (Entry *entry); +static void entry_unref (Entry *entry); +static void entry_unref_dealloc (Entry *entry); +static void query_destroy (Query *query); +static void ensure_folder (VFolderInfo *info, + Folder *folder, + gboolean subfolders, + Folder *except, + gboolean ignore_unallocated); +static void ensure_folder_unlocked (VFolderInfo *info, + Folder *folder, + gboolean subfolders, + Folder *except, + gboolean ignore_unallocated); +/* An EVIL function for quick reading of .desktop files, + * only reads in one or two keys, but that's ALL we need */ +static void readitem_entry (const char *filename, + const char *key1, + char **result1, + const char *key2, + char **result2); +static gboolean vfolder_info_reload (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context, + gboolean force_read_items); +static gboolean vfolder_info_reload_unlocked (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context, + gboolean force_read_items); +static void invalidate_folder_subfolders (Folder *folder, + gboolean lock_taken); +static Folder * resolve_folder (VFolderInfo *info, + const char *path, + gboolean ignore_basename, + GnomeVFSResult *result, + GnomeVFSContext *context); +static gboolean vfolder_info_read_items (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context); + +/* assumes vuri->path already set */ +static gboolean +vfolder_uri_parse_internal (GnomeVFSURI *uri, VFolderURI *vuri) +{ + vuri->scheme = (gchar *) gnome_vfs_uri_get_scheme (uri); + + vuri->ends_in_slash = FALSE; + + if (strncmp (vuri->scheme, "all-", strlen ("all-")) == 0) { + vuri->scheme += strlen ("all-"); + vuri->is_all_scheme = TRUE; + } else + vuri->is_all_scheme = FALSE; + + if (vuri->path != NULL) { + int last_slash = strlen (vuri->path) - 1; + char *first; + + /* Note: This handling of paths is somewhat evil, may need a + * bit of a rework */ + + /* kill leading slashes, that is make sure there is + * only one */ + for (first = vuri->path; *first == '/'; first++) + ; + if (first != vuri->path) { + first--; + vuri->path = first; + } + + /* kill trailing slashes (leave first if all slashes) */ + while (last_slash > 0 && vuri->path [last_slash] == '/') { + vuri->path [last_slash--] = '\0'; + vuri->ends_in_slash = TRUE; + } + + /* get basename start */ + while (last_slash >= 0 && vuri->path [last_slash] != '/') + last_slash--; + + if (last_slash > -1) + vuri->file = vuri->path + last_slash + 1; + else + vuri->file = vuri->path; + + if (vuri->file[0] == '\0' && + strcmp (vuri->path, "/") == 0) { + vuri->file = NULL; + } + } else { + vuri->ends_in_slash = TRUE; + vuri->path = "/"; + vuri->file = NULL; + } + + vuri->uri = uri; + + return TRUE; +} + +#define VFOLDER_URI_PARSE(_uri, _vuri) { \ + gchar *path; \ + path = gnome_vfs_unescape_string ((_uri)->text, G_DIR_SEPARATOR_S); \ + if (path != NULL) { \ + (_vuri)->path = g_alloca (strlen (path) + 1); \ + strcpy ((_vuri)->path, path); \ + g_free (path); \ + } else { \ + (_vuri)->path = NULL; \ + } \ + vfolder_uri_parse_internal ((_uri), (_vuri)); \ +} + +static FileMonitorHandle * +file_monitor_handle_ref_unlocked (FileMonitorHandle *h) +{ + h->refcount ++; + return h; +} + +static void +file_monitor_handle_unref_unlocked (FileMonitorHandle *h) +{ + h->refcount --; + if (h->refcount == 0) { + gnome_vfs_uri_unref (h->uri); + h->uri = NULL; + + g_free (h->filename); + h->filename = NULL; + + if (h->handle != NULL) { + gnome_vfs_monitor_cancel (h->handle); + h->handle = NULL; + } + } +} + +/* This includes the .directory files */ +static void +emit_monitor (Folder *folder, int type) +{ + GSList *li; + for (li = ((Entry *)folder)->monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *handle = li->data; + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *) handle, + handle->uri, type); + } +} + +static void +emit_file_deleted_monitor (VFolderInfo *info, Entry *entry, Folder *folder) +{ + GSList *li; + for (li = entry->monitors; + li != NULL; + li = li->next) { + VFolderURI vuri; + Folder *f; + GnomeVFSResult result; + FileMonitorHandle *handle = li->data; + + /* Evil! EVIL URI PARSING. this will eat a lot of + * stack if we have lots of monitors */ + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + f = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + + if (f == folder) + gnome_vfs_monitor_callback + ((GnomeVFSMethodHandle *) handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_DELETED); + } +} + +static void +emit_and_delete_monitor (VFolderInfo *info, Folder *folder) +{ + GSList *li; + for (li = ((Entry *)folder)->monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *handle = li->data; + li->data = NULL; + + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *) handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_DELETED); + + if (handle->dir_monitor) + info->free_folder_monitors = + g_slist_prepend (info->free_folder_monitors, + handle); + else + info->free_file_monitors = + g_slist_prepend (info->free_file_monitors, + handle); + } + g_slist_free (((Entry *)folder)->monitors); + ((Entry *)folder)->monitors = NULL; +} + +static gboolean +check_ext (const char *name, const char *ext_check) +{ + const char *ext; + + ext = strrchr (name, '.'); + if (ext == NULL || + strcmp (ext, ext_check) != 0) + return FALSE; + else + return TRUE; +} + +static StatLoc * +bake_statloc (const char *name, + time_t curtime) +{ + struct stat s; + StatLoc *sl = NULL; + if (stat (name, &s) != 0) { + if (errno == ENOENT) { + sl = g_malloc0 (sizeof (StatLoc) + + strlen (name) + 1); + sl->last_stat = curtime; + sl->ctime = 0; + sl->trigger_next = FALSE; + strcpy (sl->name, name); + } + return sl; + } + + sl = g_malloc0 (sizeof (StatLoc) + + strlen (name) + 1); + sl->last_stat = curtime; + sl->ctime = s.st_ctime; + sl->trigger_next = FALSE; + strcpy (sl->name, name); + + return sl; +} + +/* returns FALSE if we must reread */ +static gboolean +check_statloc (StatLoc *sl, + time_t curtime) +{ + struct stat s; + + if (sl->trigger_next) { + sl->trigger_next = FALSE; + return FALSE; + } + + /* don't stat more then once every 3 seconds */ + if (curtime <= sl->last_stat + 3) + return TRUE; + + sl->last_stat = curtime; + + if (stat (sl->name, &s) != 0) { + if (errno == ENOENT && + sl->ctime == 0) + return TRUE; + else + return FALSE; + } + + if (sl->ctime == s.st_ctime) + return TRUE; + else + return FALSE; +} + +static gboolean +ensure_dir (const char *dirname, gboolean ignore_basename) +{ + char *parsed, *p; + + if (dirname == NULL) + return FALSE; + + if (ignore_basename) + parsed = g_path_get_dirname (dirname); + else + parsed = g_strdup (dirname); + + if (g_file_test (parsed, G_FILE_TEST_IS_DIR)) { + g_free (parsed); + return TRUE; + } + + p = strchr (parsed, '/'); + if (p == parsed) + p = strchr (p+1, '/'); + + while (p != NULL) { + *p = '\0'; + if (mkdir (parsed, 0700) != 0 && + errno != EEXIST) { + g_free (parsed); + return FALSE; + } + *p = '/'; + p = strchr (p+1, '/'); + } + + if (mkdir (parsed, 0700) != 0 && + errno != EEXIST) { + g_free (parsed); + return FALSE; + } + + g_free (parsed); + return TRUE; +} + +/* check for any directory name other then root */ +static gboolean +any_subdir (const char *dirname) +{ + const char *p; + if (dirname == NULL) + return FALSE; + + for (p = dirname; *p != '\0'; p++) { + if (*p != '/') { + return TRUE; + } + } + return FALSE; +} + +static void +destroy_entry_file (EntryFile *efile) +{ + if (efile == NULL) + return; + + g_free (efile->filename); + efile->filename = NULL; + + g_slist_free (efile->keywords); + efile->keywords = NULL; + + g_free (efile); +} + +static void +destroy_folder (Folder *folder) +{ + GSList *list; + + if (folder == NULL) + return; + + if (folder->parent != NULL) { + folder->parent->subfolders = + g_slist_remove (folder->parent->subfolders, folder); + folder->parent->up_to_date = FALSE; + folder->parent = NULL; + } + + g_free (folder->desktop_file); + folder->desktop_file = NULL; + + query_destroy (folder->query); + folder->query = NULL; + + if (folder->excludes != NULL) { + g_hash_table_destroy (folder->excludes); + folder->excludes = NULL; + } + + g_slist_foreach (folder->includes, (GFunc)g_free, NULL); + g_slist_free (folder->includes); + folder->includes = NULL; + if (folder->includes_ht != NULL) { + g_hash_table_destroy (folder->includes_ht); + folder->includes_ht = NULL; + } + + list = folder->subfolders; + folder->subfolders = NULL; + g_slist_foreach (list, (GFunc)entry_unref, NULL); + g_slist_free (list); + + list = folder->entries; + folder->entries = NULL; + g_slist_foreach (list, (GFunc)entry_unref, NULL); + g_slist_free (list); + + g_free (folder); +} + +static Entry * +entry_ref (Entry *entry) +{ + if (entry != NULL) + entry->refcount++; + return entry; +} + +static Entry * +entry_ref_alloc (Entry *entry) +{ + entry_ref (entry); + + if (entry != NULL) + entry->alloc++; + + return entry; +} + +static void +entry_unref (Entry *entry) +{ + if (entry == NULL) + return; + + entry->refcount--; + + if (entry->refcount == 0) { + g_free (entry->name); + entry->name = NULL; + + g_slist_foreach (entry->monitors, + (GFunc)file_monitor_handle_unref_unlocked, + NULL); + g_slist_free (entry->monitors); + entry->monitors = NULL; + + if (entry->type == ENTRY_FILE) + destroy_entry_file ((EntryFile *)entry); + else /* ENTRY_FOLDER */ + destroy_folder ((Folder *)entry); + } +} + +static void +entry_unref_dealloc (Entry *entry) +{ + if (entry != NULL) { + entry->alloc --; + entry_unref (entry); + } +} + +/* Handles ONLY files, not dirs */ +/* Also allocates the entries as well as refs them */ +static GSList * +alloc_entries_from_files (VFolderInfo *info, GSList *filenames) +{ + GSList *li; + GSList *files; + + files = NULL; + for (li = filenames; li != NULL; li = li->next) { + char *filename = li->data; + GSList *entry_list = g_hash_table_lookup (info->entries_ht, filename); + if (entry_list != NULL) + files = g_slist_prepend (files, + entry_ref_alloc (entry_list->data)); + } + + return files; +} + +static gboolean +matches_query (VFolderInfo *info, + Folder *folder, + EntryFile *efile, + Query *query) +{ + GSList *li; + + if (query == NULL) + return TRUE; + +#define INVERT_IF_NEEDED(val) (query->not ? !(val) : (val)) + switch (query->type) { + case QUERY_OR: + for (li = query->queries; li != NULL; li = li->next) { + Query *subquery = li->data; + if (matches_query (info, folder, efile, subquery)) + return INVERT_IF_NEEDED (TRUE); + } + return INVERT_IF_NEEDED (FALSE); + case QUERY_AND: + for (li = query->queries; li != NULL; li = li->next) { + Query *subquery = li->data; + if ( ! matches_query (info, folder, efile, subquery)) + return INVERT_IF_NEEDED (FALSE); + } + return INVERT_IF_NEEDED (TRUE); + case QUERY_KEYWORD: + { + QueryKeyword *qkeyword = (QueryKeyword *)query; + for (li = efile->keywords; li != NULL; li = li->next) { + GQuark keyword = GPOINTER_TO_INT (li->data); + if (keyword == qkeyword->keyword) + return INVERT_IF_NEEDED (TRUE); + } + return INVERT_IF_NEEDED (FALSE); + } + case QUERY_FILENAME: + { + QueryFilename *qfilename = (QueryFilename *)query; + if (strcmp (qfilename->filename, ((Entry *)efile)->name) == 0) { + return INVERT_IF_NEEDED (TRUE); + } else { + return INVERT_IF_NEEDED (FALSE); + } + } + } +#undef INVERT_IF_NEEDED + g_assert_not_reached (); + /* huh? */ + return FALSE; +} + +static void +dump_unallocated_folders (Folder *folder) +{ + GSList *li; + for (li = folder->subfolders; li != NULL; li = li->next) + dump_unallocated_folders (li->data); + + if (folder->only_unallocated && + folder->entries != NULL) { + g_slist_foreach (folder->entries, + (GFunc)entry_unref_dealloc, NULL); + g_slist_free (folder->entries); + folder->entries = NULL; + } +} + +/* Run query, allocs and refs the entries */ +static void +append_query (VFolderInfo *info, Folder *folder) +{ + GSList *li; + + if (folder->query == NULL && + ! folder->only_unallocated) + return; + + if (folder->only_unallocated) { + /* dump all folders that use unallocated + * items only. This sucks if you keep + * reading one and then another such + * folder, but oh well, life sucks for + * you then, but at least you get + * consistent results */ + dump_unallocated_folders (info->root); + + /* ensure all other folders, so that + * after this we know which ones are + * unallocated */ + ensure_folder_unlocked (info, + info->root, + TRUE /* subfolders */, + folder /* except */, + /* avoid infinite loops */ + TRUE /* ignore_unallocated */); + } + + for (li = info->entries; li != NULL; li = li->next) { + Entry *entry = li->data; + + if (/* if not file */ + entry->type != ENTRY_FILE || + /* if already included */ + (folder->includes_ht != NULL && + g_hash_table_lookup (folder->includes_ht, + entry->name) != NULL)) + continue; + + if (folder->only_unallocated && + entry->alloc != 0) + continue; + + if (matches_query (info, folder, (EntryFile *)entry, + folder->query)) + folder->entries = g_slist_prepend + (folder->entries, entry_ref_alloc (entry)); + } +} + +/* get entries in folder */ +/* FIXME: support cancellation here */ +static void +ensure_folder_unlocked (VFolderInfo *info, + Folder *folder, + gboolean subfolders, + Folder *except, + gboolean ignore_unallocated) +{ + if (subfolders) { + GSList *li; + for (li = folder->subfolders; li != NULL; li = li->next) + ensure_folder_unlocked (info, li->data, subfolders, + except, ignore_unallocated); + } + + if (except == folder) + return; + + if (ignore_unallocated && + folder->only_unallocated) + return; + + if (folder->up_to_date) + return; + + if (folder->entries != NULL) { + g_slist_foreach (folder->entries, + (GFunc)entry_unref_dealloc, NULL); + g_slist_free (folder->entries); + folder->entries = NULL; + } + + /* Include includes */ + folder->entries = alloc_entries_from_files (info, folder->includes); + + /* Run query */ + append_query (info, folder); + + /* We were prepending all this time */ + folder->entries = g_slist_reverse (folder->entries); + + /* Include subfolders */ + /* we always whack them onto the beginning */ + if (folder->subfolders != NULL) { + GSList *subfolders = g_slist_copy (folder->subfolders); + g_slist_foreach (subfolders, (GFunc)entry_ref_alloc, NULL); + folder->entries = g_slist_concat (subfolders, folder->entries); + } + + /* Exclude excludes */ + if (folder->excludes != NULL) { + GSList *li; + GSList *entries = folder->entries; + folder->entries = NULL; + for (li = entries; li != NULL; li = li->next) { + Entry *entry = li->data; + if (g_hash_table_lookup (folder->excludes, entry->name) == NULL) + folder->entries = g_slist_prepend (folder->entries, entry); + else + entry_unref_dealloc (entry); + + } + g_slist_free (entries); + + /* to preserve the Folders then everything else order */ + folder->entries = g_slist_reverse (folder->entries); + } + + folder->up_to_date = TRUE; + /* not yet sorted */ + folder->sorted = FALSE; +} + +static void +ensure_folder (VFolderInfo *info, + Folder *folder, + gboolean subfolders, + Folder *except, + gboolean ignore_unallocated) +{ + G_LOCK (vfolder_lock); + ensure_folder_unlocked (info, folder, subfolders, except, ignore_unallocated); + G_UNLOCK (vfolder_lock); +} + +static char * +get_directory_file_unlocked (VFolderInfo *info, Folder *folder) +{ + char *filename; + + /* FIXME: cache dir_files */ + + if (folder->desktop_file == NULL) + return NULL; + + if (folder->desktop_file[0] == G_DIR_SEPARATOR) + return g_strdup (folder->desktop_file); + + /* Now try the user directory */ + if (info->user_desktop_dir != NULL) { + filename = g_build_filename (info->user_desktop_dir, + folder->desktop_file, + NULL); + if (access (filename, F_OK) == 0) { + return filename; + } + + g_free (filename); + } + + filename = g_build_filename (info->desktop_dir, folder->desktop_file, NULL); + if (access (filename, F_OK) == 0) { + return filename; + } + g_free (filename); + + return NULL; +} + +static char * +get_directory_file (VFolderInfo *info, Folder *folder) +{ + char *ret; + + G_LOCK (vfolder_lock); + ret = get_directory_file_unlocked (info, folder); + G_UNLOCK (vfolder_lock); + + return ret; +} + +static GSList * +get_sort_order (VFolderInfo *info, Folder *folder) +{ + GSList *list; + char **parsed; + char *order; + int i; + char *filename; + + filename = get_directory_file_unlocked (info, folder); + if (filename == NULL) + return NULL; + + order = NULL; + readitem_entry (filename, + "SortOrder", + &order, + NULL, + NULL); + g_free (filename); + + if (order == NULL) + return NULL; + + parsed = g_strsplit (order, ":", -1); + + g_free (order); + + list = NULL; + for (i = 0; parsed[i] != NULL; i++) { + char *word = parsed[i]; + /* steal */ + parsed[i] = NULL; + /* ignore empty */ + if (word[0] == '\0') { + g_free (word); + continue; + } + list = g_slist_prepend (list, word); + } + /* we've stolen all strings from it */ + g_free (parsed); + + return g_slist_reverse (list); +} + +/* get entries in folder */ +static void +ensure_folder_sort (VFolderInfo *info, Folder *folder) +{ + GSList *li, *sort_order; + GSList *entries; + GHashTable *entry_hash; + + ensure_folder (info, folder, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + if (folder->sorted) + return; + + G_LOCK (vfolder_lock); + + sort_order = get_sort_order (info, folder); + if (sort_order == NULL) { + folder->sorted = TRUE; + G_UNLOCK (vfolder_lock); + return; + } + + entries = folder->entries; + folder->entries = NULL; + + entry_hash = g_hash_table_new (g_str_hash, g_str_equal); + for (li = entries; li != NULL; li = li->next) { + Entry *entry = li->data; + g_hash_table_insert (entry_hash, entry->name, li); + } + + for (li = sort_order; li != NULL; li = li->next) { + char *word = li->data; + GSList *entry_list; + Entry *entry; + + /* we kill the words here */ + li->data = NULL; + + entry_list = g_hash_table_lookup (entry_hash, word); + g_free (word); + + if (entry_list == NULL) + continue; + + entry = entry_list->data; + + entries = g_slist_delete_link (entries, entry_list); + + folder->entries = g_slist_prepend (folder->entries, + entry); + } + + /* put on those that weren't mentioned in the sort */ + for (li = entries; li != NULL; li = li->next) { + Entry *entry = li->data; + + folder->entries = g_slist_prepend (folder->entries, + entry); + } + + g_hash_table_destroy (entry_hash); + g_slist_free (entries); + g_slist_free (sort_order); + + folder->sorted = TRUE; + + G_UNLOCK (vfolder_lock); +} + +static EntryFile * +file_new (const char *name) +{ + EntryFile *efile = g_new0 (EntryFile, 1); + + efile->entry.type = ENTRY_FILE; + efile->entry.name = g_strdup (name); + efile->entry.refcount = 1; + + return efile; +} + +static Folder * +folder_new (const char *name) +{ + Folder *folder = g_new0 (Folder, 1); + + folder->entry.type = ENTRY_FOLDER; + folder->entry.name = g_strdup (name); + folder->entry.refcount = 1; + + return folder; +} + +static Query * +query_new (int type) +{ + Query *query; + + if (type == QUERY_KEYWORD) + query = (Query *)g_new0 (QueryKeyword, 1); + else if (type == QUERY_FILENAME) + query = (Query *)g_new0 (QueryFilename, 1); + else + query = g_new0 (Query, 1); + + query->type = type; + + return query; +} + +static void +query_destroy (Query *query) +{ + if (query == NULL) + return; + + if (query->type == QUERY_FILENAME) { + QueryFilename *qfile = (QueryFilename *)query; + g_free (qfile->filename); + qfile->filename = NULL; + } else if (query->type == QUERY_OR || + query->type == QUERY_AND) { + g_slist_foreach (query->queries, (GFunc)query_destroy, NULL); + g_slist_free (query->queries); + query->queries = NULL; + } + + g_free (query); +} + +static void +add_folder_monitor_unlocked (VFolderInfo *info, + FileMonitorHandle *handle) +{ + VFolderURI vuri; + GnomeVFSResult result; + Folder *folder; + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + file_monitor_handle_ref_unlocked (handle); + + info->folder_monitors = + g_slist_prepend (info->folder_monitors, handle); + + folder = resolve_folder (info, + vuri.path, + FALSE /* ignore_basename */, + &result, + NULL); + + if (folder == NULL) { + file_monitor_handle_ref_unlocked (handle); + + info->free_folder_monitors = + g_slist_prepend (info->free_folder_monitors, handle); + + if (handle->exists) { + handle->exists = FALSE; + gnome_vfs_monitor_callback + ((GnomeVFSMethodHandle *)handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_DELETED); + } + } else { + file_monitor_handle_ref_unlocked (handle); + + ((Entry *)folder)->monitors = + g_slist_prepend (((Entry *)folder)->monitors, handle); + + if ( ! handle->exists) { + handle->exists = TRUE; + gnome_vfs_monitor_callback + ((GnomeVFSMethodHandle *)handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_CREATED); + } + } + +} + +static inline void +invalidate_folder_T (Folder *folder) +{ + folder->up_to_date = FALSE; + + invalidate_folder_subfolders (folder, TRUE); +} + +static inline void +invalidate_folder (Folder *folder) +{ + G_LOCK (vfolder_lock); + folder->up_to_date = FALSE; + G_UNLOCK (vfolder_lock); + + invalidate_folder_subfolders (folder, FALSE); +} + +static void +invalidate_folder_subfolders (Folder *folder, + gboolean lock_taken) +{ + GSList *li; + + for (li = folder->subfolders; li != NULL; li = li->next) { + Folder *subfolder = li->data; + + if (!lock_taken) + invalidate_folder (subfolder); + else + invalidate_folder_T (subfolder); + } + + emit_monitor (folder, GNOME_VFS_MONITOR_EVENT_CHANGED); +} + +/* FIXME: this is UGLY!, we need to figure out when the file + * got finished changing! */ +static gboolean +reread_timeout (gpointer data) +{ + VFolderInfo *info = data; + gboolean force_read_items = info->file_monitors != NULL; + vfolder_info_reload (info, NULL, NULL, force_read_items); + return FALSE; +} + +static void +queue_reread_in (VFolderInfo *info, int msec) +{ + G_LOCK (vfolder_lock); + if (info->reread_queue != 0) + g_source_remove (info->reread_queue); + info->reread_queue = g_timeout_add (msec, reread_timeout, info); + G_UNLOCK (vfolder_lock); +} + +static void +vfolder_desktop_dir_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + /* FIXME: implement */ +} + +static void +vfolder_user_desktop_dir_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + /* FIXME: implement */ +} + +static void +vfolder_filename_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + VFolderInfo *info = user_data; + + if ((event_type == GNOME_VFS_MONITOR_EVENT_CREATED || + event_type == GNOME_VFS_MONITOR_EVENT_CHANGED) && + ! info->user_file_active) { + queue_reread_in (info, 200); + } else if (event_type == GNOME_VFS_MONITOR_EVENT_DELETED && + ! info->user_file_active) { + /* FIXME: is this correct? I mean now + * there probably isn't ANY vfolder file, so we + * init to default values really. I have no clue what's + * right here */ + vfolder_info_reload (info, NULL, NULL, + TRUE /* force read items */); + } +} + +static void +vfolder_user_filename_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + VFolderInfo *info = user_data; + + if ((event_type == GNOME_VFS_MONITOR_EVENT_CREATED || + event_type == GNOME_VFS_MONITOR_EVENT_CHANGED) && + info->user_file_active) { + struct stat s; + + /* see if this was really our own change */ + if (info->user_filename_last_write == time (NULL)) + return; + /* anal retentive */ + if (stat (info->user_filename, &s) == 0 && + info->user_filename_last_write == s.st_ctime) + return; + + queue_reread_in (info, 200); + } else if ((event_type == GNOME_VFS_MONITOR_EVENT_CREATED || + event_type == GNOME_VFS_MONITOR_EVENT_CHANGED) && + ! info->user_file_active) { + queue_reread_in (info, 200); + } else if (event_type == GNOME_VFS_MONITOR_EVENT_DELETED && + info->user_file_active) { + gboolean force_read_items = info->file_monitors != NULL; + vfolder_info_reload (info, NULL, NULL, force_read_items); + } +} + +static void +item_dir_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + VFolderInfo *info = user_data; + + if (event_type == GNOME_VFS_MONITOR_EVENT_CREATED || + event_type == GNOME_VFS_MONITOR_EVENT_CHANGED) { + /* first invalidate all folders */ + invalidate_folder (info->root); + /* second invalidate all entries */ + info->entries_valid = FALSE; + + if (info->file_monitors != NULL) { + GnomeVFSResult result; + GSList *li; + + /* Whack all monitors here! */ + for (li = info->file_monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *h = li->data; + if (h->handle != NULL) + gnome_vfs_monitor_cancel (h->handle); + h->handle = NULL; + } + + if (vfolder_info_read_items (info, &result, NULL)) { + info->entries_valid = TRUE; + } + } + } +} + +static gboolean +setup_dir_monitor (VFolderInfo *info, const char *dir, gboolean subdirs, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + GnomeVFSMonitorHandle *handle; + DIR *dh; + struct dirent *de; + char *uri; + + uri = gnome_vfs_get_uri_from_local_path (dir); + + if (gnome_vfs_monitor_add (&handle, + uri, + GNOME_VFS_MONITOR_DIRECTORY, + item_dir_monitor, + info) != GNOME_VFS_OK) { + StatLoc *sl = bake_statloc (dir, time (NULL)); + if (sl != NULL) + info->stat_dirs = g_slist_prepend (info->stat_dirs, sl); + g_free (uri); + return TRUE; + } + g_free (uri); + + if (gnome_vfs_context_check_cancellation (context)) { + gnome_vfs_monitor_cancel (handle); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + info->item_dir_monitors = + g_slist_prepend (info->item_dir_monitors, handle); + + if ( ! subdirs) + return TRUE; + + dh = opendir (dir); + if (dh == NULL) + return TRUE; + + while ((de = readdir (dh)) != NULL) { + char *full_path; + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + closedir (dh); + return FALSE; + } + + if (de->d_name[0] == '.') + continue; + + full_path = g_build_filename (dir, de->d_name, NULL); + if (g_file_test (full_path, G_FILE_TEST_IS_DIR)) { + if ( ! setup_dir_monitor (info, full_path, + TRUE /* subdirs */, + result, context)) { + closedir (dh); + return FALSE; + } + } + g_free (full_path); + } + + closedir (dh); + + return TRUE; +} + +static gboolean +monitor_setup (VFolderInfo *info, + gboolean setup_filenames, + gboolean setup_itemdirs, + gboolean setup_desktop_dirs, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + char *uri; + GSList *li; + + if (setup_filenames) { + uri = gnome_vfs_get_uri_from_local_path + (info->filename); + + if (gnome_vfs_monitor_add (&info->filename_monitor, + uri, + GNOME_VFS_MONITOR_FILE, + vfolder_filename_monitor, + info) != GNOME_VFS_OK) { + info->filename_monitor = NULL; + info->filename_statloc = bake_statloc (info->filename, + time (NULL)); + } + g_free (uri); + } + if (setup_filenames && + info->user_filename != NULL) { + uri = gnome_vfs_get_uri_from_local_path + (info->user_filename); + if (gnome_vfs_monitor_add (&info->user_filename_monitor, + uri, + GNOME_VFS_MONITOR_FILE, + vfolder_user_filename_monitor, + info) != GNOME_VFS_OK) { + info->user_filename_monitor = NULL; + info->user_filename_statloc = + bake_statloc (info->user_filename, + time (NULL)); + } + + g_free (uri); + } + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + if (setup_itemdirs) { + for (li = info->item_dirs; li != NULL; li = li->next) { + const char *dir = li->data; + if ( ! setup_dir_monitor (info, dir, + FALSE /* subdirs */, + result, context)) + return FALSE; + } + if (info->user_item_dir != NULL) { + if ( ! setup_dir_monitor (info, info->user_item_dir, + FALSE /* subdirs */, + result, context)) + return FALSE; + } + for (li = info->merge_dirs; li != NULL; li = li->next) { + const char *dir = li->data; + if ( ! setup_dir_monitor (info, dir, + TRUE /* subdirs */, + result, context)) + return FALSE; + } + } + + if (setup_desktop_dirs) { + uri = gnome_vfs_get_uri_from_local_path + (info->desktop_dir); + + if (gnome_vfs_monitor_add (&info->desktop_dir_monitor, + uri, + GNOME_VFS_MONITOR_FILE, + vfolder_desktop_dir_monitor, + info) != GNOME_VFS_OK) { + info->desktop_dir_monitor = NULL; + info->desktop_dir_statloc = + bake_statloc (info->desktop_dir, + time (NULL)); + } + g_free (uri); + } + if (setup_desktop_dirs && + info->user_desktop_dir != NULL) { + uri = gnome_vfs_get_uri_from_local_path + (info->user_desktop_dir); + if (gnome_vfs_monitor_add (&info->user_desktop_dir_monitor, + uri, + GNOME_VFS_MONITOR_DIRECTORY, + vfolder_user_desktop_dir_monitor, + info) != GNOME_VFS_OK) { + info->user_desktop_dir_monitor = NULL; + info->user_desktop_dir_statloc = + bake_statloc (info->user_desktop_dir, + time (NULL)); + } + + g_free (uri); + } + + return TRUE; +} + +static void +vfolder_info_init (VFolderInfo *info, const char *scheme) +{ + const char *path; + GSList *list; + + info->scheme = g_strdup (scheme); + + info->filename = g_strconcat (SYSCONFDIR, "/X11/desktop-menus/", + scheme, ".menu", + NULL); + info->user_filename = g_strconcat (g_get_home_dir (), + "/" DOT_GNOME "/vfolders/", + scheme, ".vfolder-info", + NULL); + info->desktop_dir = g_strconcat (SYSCONFDIR, + "/gnome-vfs-2.0/vfolders/", + NULL); + info->user_desktop_dir = g_strconcat (g_get_home_dir (), + "/" DOT_GNOME "/vfolders/", + NULL); + + /* Init the desktop paths */ + list = NULL; + list = g_slist_prepend (list, g_strdup ("/usr/share/applications/")); + if (strcmp ("/usr/share/applications/", DATADIR "/applications/") != 0) + list = g_slist_prepend (list, g_strdup (DATADIR "/applications/")); + path = g_getenv ("DESKTOP_FILE_PATH"); + if (path != NULL) { + int i; + char **ppath = g_strsplit (path, ":", -1); + for (i = 0; ppath[i] != NULL; i++) { + const char *dir = ppath[i]; + list = g_slist_prepend (list, g_strdup (dir)); + } + g_strfreev (ppath); + } + info->item_dirs = g_slist_reverse (list); + + info->user_item_dir = g_strconcat (g_get_home_dir (), + "/" DOT_GNOME "/vfolders/", + scheme, + NULL); + + info->entries_ht = g_hash_table_new (g_str_hash, g_str_equal); + + info->root = folder_new ("Root"); + + info->modification_time = time (NULL); +} + +static void +vfolder_info_free_internals_unlocked (VFolderInfo *info) +{ + if (info == NULL) + return; + + if (info->filename_monitor != NULL) { + gnome_vfs_monitor_cancel (info->filename_monitor); + info->filename_monitor = NULL; + } + + if (info->user_filename_monitor != NULL) { + gnome_vfs_monitor_cancel (info->user_filename_monitor); + info->user_filename_monitor = NULL; + } + + g_free (info->filename_statloc); + info->filename_statloc = NULL; + + g_free (info->user_filename_statloc); + info->user_filename_statloc = NULL; + + + if (info->desktop_dir_monitor != NULL) { + gnome_vfs_monitor_cancel (info->desktop_dir_monitor); + info->desktop_dir_monitor = NULL; + } + + if (info->user_desktop_dir_monitor != NULL) { + gnome_vfs_monitor_cancel (info->user_desktop_dir_monitor); + info->user_desktop_dir_monitor = NULL; + } + + g_free (info->desktop_dir_statloc); + info->desktop_dir_statloc = NULL; + + g_free (info->user_desktop_dir_statloc); + info->user_desktop_dir_statloc = NULL; + + + g_slist_foreach (info->item_dir_monitors, + (GFunc)gnome_vfs_monitor_cancel, NULL); + g_slist_free (info->item_dir_monitors); + info->item_dir_monitors = NULL; + + g_free (info->scheme); + info->scheme = NULL; + + g_free (info->filename); + info->filename = NULL; + + g_free (info->user_filename); + info->user_filename = NULL; + + g_free (info->desktop_dir); + info->desktop_dir = NULL; + + g_free (info->user_desktop_dir); + info->user_desktop_dir = NULL; + + g_slist_foreach (info->item_dirs, (GFunc)g_free, NULL); + g_slist_free (info->item_dirs); + info->item_dirs = NULL; + + g_free (info->user_item_dir); + info->user_item_dir = NULL; + + g_slist_foreach (info->merge_dirs, (GFunc)g_free, NULL); + g_slist_free (info->merge_dirs); + info->merge_dirs = NULL; + + g_slist_foreach (info->entries, (GFunc)entry_unref, NULL); + g_slist_free (info->entries); + info->entries = NULL; + + if (info->entries_ht != NULL) + g_hash_table_destroy (info->entries_ht); + info->entries_ht = NULL; + + g_slist_foreach (info->unallocated_folders, + (GFunc)entry_unref, + NULL); + g_slist_free (info->unallocated_folders); + info->unallocated_folders = NULL; + + entry_unref ((Entry *)info->root); + info->root = NULL; + + g_slist_foreach (info->stat_dirs, (GFunc)g_free, NULL); + g_slist_free (info->stat_dirs); + info->stat_dirs = NULL; + + g_slist_foreach (info->folder_monitors, + (GFunc)file_monitor_handle_unref_unlocked, NULL); + g_slist_free (info->folder_monitors); + info->folder_monitors = NULL; + + g_slist_foreach (info->free_folder_monitors, + (GFunc)file_monitor_handle_unref_unlocked, NULL); + g_slist_free (info->free_folder_monitors); + info->free_folder_monitors = NULL; + + g_slist_foreach (info->file_monitors, + (GFunc)file_monitor_handle_unref_unlocked, NULL); + g_slist_free (info->file_monitors); + info->file_monitors = NULL; + + g_slist_foreach (info->free_file_monitors, + (GFunc)file_monitor_handle_unref_unlocked, NULL); + g_slist_free (info->free_file_monitors); + info->free_file_monitors = NULL; + + if (info->reread_queue != 0) + g_source_remove (info->reread_queue); + info->reread_queue = 0; +} + +static void +vfolder_info_free_internals (VFolderInfo *info) +{ + G_LOCK (vfolder_lock); + vfolder_info_free_internals_unlocked (info); + G_UNLOCK (vfolder_lock); +} + +static void +vfolder_info_destroy (VFolderInfo *info) +{ + vfolder_info_free_internals (info); + g_free (info); +} + +static Query * +single_query_read (xmlNode *qnode) +{ + Query *query; + xmlNode *node; + + if (qnode->type != XML_ELEMENT_NODE || + qnode->name == NULL) + return NULL; + + query = NULL; + + if (g_ascii_strcasecmp (qnode->name, "Not") == 0 && + qnode->xmlChildrenNode != NULL) { + xmlNode *iter; + query = NULL; + for (iter = qnode->xmlChildrenNode; + iter != NULL && query == NULL; + iter = iter->next) + query = single_query_read (iter); + if (query != NULL) { + query->not = ! query->not; + } + return query; + } else if (g_ascii_strcasecmp (qnode->name, "Keyword") == 0) { + xmlChar *word = xmlNodeGetContent (qnode); + if (word != NULL) { + query = query_new (QUERY_KEYWORD); + ((QueryKeyword *)query)->keyword = + g_quark_from_string (word); + + xmlFree (word); + } + return query; + } else if (g_ascii_strcasecmp (qnode->name, "Filename") == 0) { + xmlChar *file = xmlNodeGetContent (qnode); + if (file != NULL) { + query = query_new (QUERY_FILENAME); + ((QueryFilename *)query)->filename = + g_strdup (file); + + xmlFree (file); + } + return query; + } else if (g_ascii_strcasecmp (qnode->name, "And") == 0) { + query = query_new (QUERY_AND); + } else if (g_ascii_strcasecmp (qnode->name, "Or") == 0) { + query = query_new (QUERY_OR); + } else { + /* We don't understand */ + return NULL; + } + + /* This must be OR or AND */ + g_assert (query != NULL); + + for (node = qnode->xmlChildrenNode; node != NULL; node = node->next) { + Query *new_query = single_query_read (node); + + if (new_query != NULL) + query->queries = g_slist_prepend + (query->queries, new_query); + } + + query->queries = g_slist_reverse (query->queries); + + return query; +} + +static void +add_or_set_query (Query **query, Query *new_query) +{ + if (*query == NULL) { + *query = new_query; + } else { + Query *old_query = *query; + *query = query_new (QUERY_OR); + (*query)->queries = + g_slist_append ((*query)->queries, old_query); + (*query)->queries = + g_slist_append ((*query)->queries, new_query); + } +} + +static Query * +query_read (xmlNode *qnode) +{ + Query *query; + xmlNode *node; + + query = NULL; + + for (node = qnode->xmlChildrenNode; node != NULL; node = node->next) { + if (node->type != XML_ELEMENT_NODE || + node->name == NULL) + continue; + + if (g_ascii_strcasecmp (node->name, "Not") == 0 && + node->xmlChildrenNode != NULL) { + xmlNode *iter; + Query *new_query = NULL; + + for (iter = node->xmlChildrenNode; + iter != NULL && new_query == NULL; + iter = iter->next) + new_query = single_query_read (iter); + if (new_query != NULL) { + new_query->not = ! new_query->not; + add_or_set_query (&query, new_query); + } + } else { + Query *new_query = single_query_read (node); + if (new_query != NULL) + add_or_set_query (&query, new_query); + } + } + + return query; +} + +static Folder * +folder_read (VFolderInfo *info, xmlNode *fnode) +{ + Folder *folder; + xmlNode *node; + + folder = folder_new (NULL); + + for (node = fnode->xmlChildrenNode; node != NULL; node = node->next) { + if (node->type != XML_ELEMENT_NODE || + node->name == NULL) + continue; + + if (g_ascii_strcasecmp (node->name, "Name") == 0) { + xmlChar *name = xmlNodeGetContent (node); + if (name != NULL) { + g_free (folder->entry.name); + folder->entry.name = g_strdup (name); + xmlFree (name); + } + } else if (g_ascii_strcasecmp (node->name, "Desktop") == 0) { + xmlChar *desktop = xmlNodeGetContent (node); + if (desktop != NULL) { + g_free (folder->desktop_file); + folder->desktop_file = g_strdup (desktop); + xmlFree (desktop); + } + } else if (g_ascii_strcasecmp (node->name, "Include") == 0) { + xmlChar *file = xmlNodeGetContent (node); + if (file != NULL) { + GSList *li; + char *str = g_strdup (file); + folder->includes = g_slist_prepend + (folder->includes, str); + if (folder->includes_ht == NULL) { + folder->includes_ht = + g_hash_table_new_full + (g_str_hash, + g_str_equal, + NULL, + NULL); + } + li = g_hash_table_lookup (folder->includes_ht, + file); + if (li != NULL) { + g_free (li->data); + /* Note: this will NOT change folder->includes + * pointer! */ + folder->includes = g_slist_delete_link + (folder->includes, li); + } + g_hash_table_replace (folder->includes_ht, + file, folder->includes); + xmlFree (file); + } + } else if (g_ascii_strcasecmp (node->name, "Exclude") == 0) { + xmlChar *file = xmlNodeGetContent (node); + if (file != NULL) { + char *s; + if (folder->excludes == NULL) { + folder->excludes = g_hash_table_new_full + (g_str_hash, + g_str_equal, + (GDestroyNotify)g_free, + NULL); + } + s = g_strdup (file); + g_hash_table_replace (folder->excludes, s, s); + xmlFree (file); + } + } else if (g_ascii_strcasecmp (node->name, "Query") == 0) { + Query *query; + + query = query_read (node); + + if (query != NULL) { + if (folder->query != NULL) + query_destroy (folder->query); + folder->query = query; + } + } else if (g_ascii_strcasecmp (node->name, "OnlyUnallocated") == 0) { + info->unallocated_folders = + g_slist_prepend (info->unallocated_folders, + (Folder *)entry_ref ((Entry *)folder)); + folder->only_unallocated = TRUE; + } else if (g_ascii_strcasecmp (node->name, "Folder") == 0) { + Folder *new_folder = folder_read (info, node); + if (new_folder != NULL) { + folder->subfolders = + g_slist_append (folder->subfolders, + new_folder); + new_folder->parent = folder; + } + } else if (g_ascii_strcasecmp (node->name, "ReadOnly") == 0) { + folder->read_only = TRUE; + } else if (g_ascii_strcasecmp (node->name, + "DontShowIfEmpty") == 0) { + folder->dont_show_if_empty = TRUE; + } + } + + /* Name is required */ + if (folder->entry.name == NULL) { + entry_unref ((Entry *)folder); + folder = NULL; + } + + folder->includes = g_slist_reverse (folder->includes); + + return folder; +} + +static char * +subst_home (const char *dir) +{ + if (dir[0] == '~') + return g_strconcat (g_get_home_dir (), + &dir[1], + NULL); + else + return g_strdup (dir); +} + +/* FORMAT looks like: + * + * + * /etc/X11/applnk + * + * /usr/share/applications + * + * /etc/X11/gnome/vfolders + * + * + * Root + * + * important.desktop + * + * + * + * SomeFolder + * + * + * Test_Folder + * + * Test_Folder.directory + * + * + * + * Application + * Game + * + * Clock + * + * + * somefile.desktop + * someotherfile.desktop + * yetanother.desktop + * + * + * + */ + +static gboolean +vfolder_info_read_info (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + xmlDoc *doc; + xmlNode *node; + gboolean got_a_vfolder_dir = FALSE; + + doc = NULL; + if (info->user_filename != NULL && + access (info->user_filename, F_OK) == 0) { + doc = xmlParseFile (info->user_filename); + if (doc != NULL) + info->user_file_active = TRUE; + } + if (doc == NULL && + access (info->filename, F_OK) == 0) + doc = xmlParseFile (info->filename); + + if (gnome_vfs_context_check_cancellation (context)) { + xmlFreeDoc(doc); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + if (doc == NULL + || doc->xmlRootNode == NULL + || doc->xmlRootNode->name == NULL + || g_ascii_strcasecmp (doc->xmlRootNode->name, "VFolderInfo") != 0) { + xmlFreeDoc(doc); + return TRUE; /* FIXME: really, shouldn't we error out? */ + } + + for (node = doc->xmlRootNode->xmlChildrenNode; node != NULL; node = node->next) { + if (node->type != XML_ELEMENT_NODE || + node->name == NULL) + continue; + + if (gnome_vfs_context_check_cancellation (context)) { + xmlFreeDoc(doc); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + if (g_ascii_strcasecmp (node->name, "MergeDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + if (dir != NULL) { + info->merge_dirs = g_slist_append (info->merge_dirs, + g_strdup (dir)); + xmlFree (dir); + } + } else if (g_ascii_strcasecmp (node->name, "ItemDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + if (dir != NULL) { + if ( ! got_a_vfolder_dir) { + g_slist_foreach (info->item_dirs, + (GFunc)g_free, NULL); + g_slist_free (info->item_dirs); + info->item_dirs = NULL; + } + got_a_vfolder_dir = TRUE; + info->item_dirs = g_slist_append (info->item_dirs, + g_strdup (dir)); + xmlFree (dir); + } + } else if (g_ascii_strcasecmp (node->name, "UserItemDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + if (dir != NULL) { + g_free (info->user_item_dir); + info->user_item_dir = subst_home (dir); + xmlFree (dir); + } + } else if (g_ascii_strcasecmp (node->name, "DesktopDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + if (dir != NULL) { + g_free (info->desktop_dir); + info->desktop_dir = g_strdup (dir); + xmlFree (dir); + } + } else if (g_ascii_strcasecmp (node->name, "UserDesktopDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + if (dir != NULL) { + g_free (info->user_desktop_dir); + info->user_desktop_dir = subst_home (dir); + xmlFree (dir); + } + } else if (g_ascii_strcasecmp (node->name, "Folder") == 0) { + Folder *folder = folder_read (info, node); + if (folder != NULL) { + if (info->root != NULL) + entry_unref ((Entry *)info->root); + info->root = folder; + } + } else if (g_ascii_strcasecmp (node->name, "ReadOnly") == 0) { + info->read_only = TRUE; + } + } + + xmlFreeDoc(doc); + + return TRUE; +} + +static void +add_xml_tree_from_query (xmlNode *parent, Query *query) +{ + xmlNode *real_parent; + + if (query->not) + real_parent = xmlNewChild (parent /* parent */, + NULL /* ns */, + "Not" /* name */, + NULL /* content */); + else + real_parent = parent; + + if (query->type == QUERY_KEYWORD) { + QueryKeyword *qkeyword = (QueryKeyword *)query; + const char *string = g_quark_to_string (qkeyword->keyword); + + xmlNewChild (real_parent /* parent */, + NULL /* ns */, + "Keyword" /* name */, + string /* content */); + } else if (query->type == QUERY_FILENAME) { + QueryFilename *qfilename = (QueryFilename *)query; + + xmlNewChild (real_parent /* parent */, + NULL /* ns */, + "Filename" /* name */, + qfilename->filename /* content */); + } else if (query->type == QUERY_OR || + query->type == QUERY_AND) { + xmlNode *node; + const char *name; + GSList *li; + + if (query->type == QUERY_OR) + name = "Or"; + else /* QUERY_AND */ + name = "And"; + + node = xmlNewChild (real_parent /* parent */, + NULL /* ns */, + name /* name */, + NULL /* content */); + + for (li = query->queries; li != NULL; li = li->next) { + Query *subquery = li->data; + add_xml_tree_from_query (node, subquery); + } + } else { + g_assert_not_reached (); + } +} + +static void +add_excludes_to_xml (gpointer key, gpointer value, gpointer user_data) +{ + const char *filename = key; + xmlNode *folder_node = user_data; + + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Exclude" /* name */, + filename /* content */); +} + +static void +add_xml_tree_from_folder (xmlNode *parent, Folder *folder) +{ + GSList *li; + xmlNode *folder_node; + + + folder_node = xmlNewChild (parent /* parent */, + NULL /* ns */, + "Folder" /* name */, + NULL /* content */); + + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Name" /* name */, + folder->entry.name /* content */); + + if (folder->desktop_file != NULL) { + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Desktop" /* name */, + folder->desktop_file /* content */); + } + + if (folder->read_only) + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "ReadOnly" /* name */, + NULL /* content */); + if (folder->dont_show_if_empty) + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "DontShowIfEmpty" /* name */, + NULL /* content */); + if (folder->only_unallocated) + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "OnlyUnallocated" /* name */, + NULL /* content */); + + for (li = folder->subfolders; li != NULL; li = li->next) { + Folder *subfolder = li->data; + add_xml_tree_from_folder (folder_node, subfolder); + } + + for (li = folder->includes; li != NULL; li = li->next) { + const char *include = li->data; + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Include" /* name */, + include /* content */); + } + + if (folder->excludes) { + g_hash_table_foreach (folder->excludes, + add_excludes_to_xml, + folder_node); + } + + if (folder->query != NULL) { + xmlNode *query_node; + query_node = xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Query" /* name */, + NULL /* content */); + + add_xml_tree_from_query (query_node, folder->query); + } +} + +static xmlDoc * +xml_tree_from_vfolder (VFolderInfo *info) +{ + xmlDoc *doc; + xmlNode *topnode; + GSList *li; + + doc = xmlNewDoc ("1.0"); + + topnode = xmlNewDocNode (doc /* doc */, + NULL /* ns */, + "VFolderInfo" /* name */, + NULL /* content */); + doc->xmlRootNode = topnode; + + for (li = info->merge_dirs; li != NULL; li = li->next) { + const char *merge_dir = li->data; + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "MergeDir" /* name */, + merge_dir /* content */); + } + + for (li = info->item_dirs; li != NULL; li = li->next) { + const char *item_dir = li->data; + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "ItemDir" /* name */, + item_dir /* content */); + } + + if (info->user_item_dir != NULL) { + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "UserItemDir" /* name */, + info->user_item_dir /* content */); + } + + if (info->desktop_dir != NULL) { + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "DesktopDir" /* name */, + info->desktop_dir /* content */); + } + + if (info->user_desktop_dir != NULL) { + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "UserDesktopDir" /* name */, + info->user_desktop_dir /* content */); + } + + if (info->root != NULL) + add_xml_tree_from_folder (topnode, info->root); + + return doc; +} + +/* FIXME: what to do about errors */ +static void +vfolder_info_write_user (VFolderInfo *info) +{ + xmlDoc *doc; + + if (info->inhibit_write > 0) + return; + + if (info->user_filename == NULL) + return; + + doc = xml_tree_from_vfolder (info); + if (doc == NULL) + return; + + /* FIXME: errors, anyone? */ + ensure_dir (info->user_filename, + TRUE /* ignore_basename */); + + xmlSaveFormatFile (info->user_filename, doc, TRUE /* format */); + /* not as good as a stat, but cheaper ... hmmm what is + * the likelyhood of this not being the same as ctime */ + info->user_filename_last_write = time (NULL); + + xmlFreeDoc(doc); + + info->user_file_active = TRUE; + info->dirty = FALSE; + + info->modification_time = time (NULL); +} + +/* An EVIL function for quick reading of .desktop files, + * only reads in one or two keys, but that's ALL we need */ +static void +readitem_entry (const char *filename, + const char *key1, + char **result1, + const char *key2, + char **result2) +{ + FILE *fp; + char buf[1024]; + int keylen1, keylen2; + + *result1 = NULL; + if (result2 != NULL) + *result2 = NULL; + + fp = fopen (filename, "r"); + + if (fp == NULL) + return; + + keylen1 = strlen (key1); + if (key2 != NULL) + keylen2 = strlen (key2); + else + keylen2 = -1; + + /* This is slightly wrong, it should only look + * at the correct section */ + while (fgets (buf, sizeof (buf), fp) != NULL) { + char *p; + int len; + int keylen; + char **result = NULL; + + /* check if it's one of the keys */ + if (strncmp (buf, key1, keylen1) == 0) { + result = result1; + keylen = keylen1; + } else if (keylen2 >= 0 && + strncmp (buf, key2, keylen2) == 0) { + result = result2; + keylen = keylen2; + } else { + continue; + } + + p = &buf[keylen]; + + /* still not our key */ + if (!(*p == '=' || *p == ' ')) { + continue; + } + do + p++; + while (*p == ' ' || *p == '='); + + /* get rid of trailing \n */ + len = strlen (p); + if (p[len-1] == '\n' || + p[len-1] == '\r') + p[len-1] = '\0'; + + *result = g_strdup (p); + + if (*result1 != NULL && + (result2 == NULL || *result2 != NULL)) + break; + } + + fclose (fp); +} + +static void +vfolder_info_insert_entry (VFolderInfo *info, EntryFile *efile) +{ + GSList *entry_list; + + entry_ref ((Entry *)efile); + + entry_list = g_hash_table_lookup (info->entries_ht, efile->entry.name); + + info->entries = g_slist_prepend (info->entries, efile); + /* The hash table contains the GSList pointer */ + g_hash_table_replace (info->entries_ht, efile->entry.name, + info->entries); + + if (entry_list != NULL) { + Entry *entry = entry_list->data; + info->entries = g_slist_delete_link (info->entries, + entry_list); + entry_unref (entry); + } +} + +static void +set_keywords (EntryFile *efile, const char *keywords) +{ + if (keywords != NULL) { + int i; + char **parsed = g_strsplit (keywords, ";", -1); + for (i = 0; parsed[i] != NULL; i++) { + GQuark quark; + const char *word = parsed[i]; + /* ignore empties (including end of list) */ + if (word[0] == '\0') + continue; + quark = g_quark_from_string (word); + efile->keywords = g_slist_prepend + (efile->keywords, + GINT_TO_POINTER (quark)); + } + g_strfreev (parsed); + } +} + +static EntryFile * +make_entry_file (const char *dir, const char *name) +{ + EntryFile *efile; + char *categories; + char *only_show_in; + char *filename; + int i; + + filename = g_build_filename (dir, name, NULL); + + readitem_entry (filename, + "Categories", + &categories, + "OnlyShowIn", + &only_show_in); + + if (only_show_in != NULL) { + gboolean show = FALSE; + char **parsed = g_strsplit (only_show_in, ";", -1); + for (i = 0; parsed[i] != NULL; i++) { + if (strcmp (parsed[i], "GNOME") == 0) { + show = TRUE; + break; + } + } + g_strfreev (parsed); + if ( ! show) { + g_free (filename); + g_free (only_show_in); + g_free (categories); + return NULL; + } + } + + efile = file_new (name); + efile->filename = filename; + + set_keywords (efile, categories); + + g_free (only_show_in); + g_free (categories); + + return efile; +} + +static gboolean +vfolder_info_read_items_from (VFolderInfo *info, + const char *item_dir, + gboolean per_user, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + DIR *dir; + struct dirent *de; + + dir = opendir (item_dir); + if (dir == NULL) + return TRUE; + + while ((de = readdir (dir)) != NULL) { + EntryFile *efile; + + if (gnome_vfs_context_check_cancellation (context)) { + closedir (dir); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + /* files MUST be called .desktop */ + if (de->d_name[0] == '.' || + ! check_ext (de->d_name, ".desktop")) + continue; + + efile = make_entry_file (item_dir, de->d_name); + if (efile == NULL) + continue; + + efile->per_user = per_user; + + vfolder_info_insert_entry (info, efile); + entry_unref ((Entry *)efile); + } + + closedir (dir); + + return TRUE; +} + +static gboolean +vfolder_info_read_items_merge (VFolderInfo *info, + const char *merge_dir, + const char *subdir, + GQuark inherited_keyword, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + DIR *dir; + struct dirent *de; + GQuark extra_keyword; + GQuark Application; + GQuark Merged; + GQuark inheritance; + gboolean pass_down_extra_keyword = TRUE; + + dir = opendir (merge_dir); + if (dir == NULL) + return TRUE; + + Application = g_quark_from_static_string ("Application"); + Merged = g_quark_from_static_string ("Merged"); + + /* FIXME: this should be a hash or something */ + extra_keyword = 0; + if (subdir == NULL) { + extra_keyword = g_quark_from_static_string ("Core"); + pass_down_extra_keyword = FALSE; + } else if (g_ascii_strcasecmp (subdir, "Development") == 0) + extra_keyword = g_quark_from_static_string ("Development"); + else if (g_ascii_strcasecmp (subdir, "Editors") == 0) + extra_keyword = g_quark_from_static_string ("TextEditor"); + else if (g_ascii_strcasecmp (subdir, "Games") == 0) + extra_keyword = g_quark_from_static_string ("Game"); + else if (g_ascii_strcasecmp (subdir, "Graphics") == 0) + extra_keyword = g_quark_from_static_string ("Graphics"); + else if (g_ascii_strcasecmp (subdir, "Internet") == 0) + extra_keyword = g_quark_from_static_string ("Network"); + else if (g_ascii_strcasecmp (subdir, "Multimedia") == 0) + extra_keyword = g_quark_from_static_string ("AudioVideo"); + else if (g_ascii_strcasecmp (subdir, "Office") == 0) + extra_keyword = g_quark_from_static_string ("Office"); + else if (g_ascii_strcasecmp (subdir, "Settings") == 0) + extra_keyword = g_quark_from_static_string ("Settings"); + else if (g_ascii_strcasecmp (subdir, "System") == 0) + extra_keyword = g_quark_from_static_string ("System"); + else if (g_ascii_strcasecmp (subdir, "Utilities") == 0) + extra_keyword = g_quark_from_static_string ("Utility"); + + while ((de = readdir (dir)) != NULL) { + EntryFile *efile; + + if (gnome_vfs_context_check_cancellation (context)) { + closedir (dir); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + /* ignore hidden */ + if (de->d_name[0] == '.') + continue; + + /* files MUST be called .desktop, so + * treat all others as dirs. If we're wrong, + * the open will fail, which is ok */ + if ( ! check_ext (de->d_name, ".desktop")) { + /* if this is a directory recurse */ + char *fullname = g_build_filename (merge_dir, de->d_name, NULL); + if ((pass_down_extra_keyword == TRUE) && (extra_keyword != 0)) { + inheritance = extra_keyword; + } else { + inheritance = inherited_keyword; + } + + if ( ! vfolder_info_read_items_merge (info, + fullname, + de->d_name, + inheritance, + result, + context)) { + g_free (fullname); + return FALSE; + } + g_free (fullname); + continue; + } + + /* FIXME: add some keywords about some known apps + * like gimp and whatnot, perhaps take these from the vfolder + * file or some such */ + + efile = make_entry_file (merge_dir, de->d_name); + if (efile == NULL) + continue; + + /* If no keywords set, then add the standard ones */ + if (efile->keywords == NULL) { + efile->keywords = g_slist_prepend + (efile->keywords, + GINT_TO_POINTER (Application)); + + efile->keywords = g_slist_prepend + (efile->keywords, + GINT_TO_POINTER (Merged)); + + if (inherited_keyword != 0) { + efile->keywords = g_slist_prepend + (efile->keywords, + GINT_TO_POINTER (inherited_keyword)); + } + + if (extra_keyword != 0) { + efile->keywords = g_slist_prepend + (efile->keywords, + GINT_TO_POINTER (extra_keyword)); + } + efile->implicit_keywords = TRUE; + } + + vfolder_info_insert_entry (info, efile); + entry_unref ((Entry *)efile); + } + + closedir (dir); + + return TRUE; +} + +static Entry * +find_entry (GSList *list, const char *name) +{ + GSList *li; + + for (li = list; li != NULL; li = li->next) { + Entry *entry = li->data; + if (strcmp (name, entry->name) == 0) + return entry; + } + return NULL; +} + +static void +file_monitor (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + FileMonitorHandle *h = user_data; + + /* proxy the event through if it is a changed event + * only */ + + if (event_type == GNOME_VFS_MONITOR_EVENT_CHANGED && + h->handle != NULL) + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *) h, + h->uri, event_type); +} + +static void +try_free_file_monitors_create_files_unlocked (VFolderInfo *info) +{ + GSList *li, *list; + + list = g_slist_copy (info->free_file_monitors); + + for (li = list; li != NULL; li = li->next) { + FileMonitorHandle *handle = li->data; + Entry *entry; + GnomeVFSResult result; + char *dirfile = NULL; + + if (handle->is_directory_file) { + VFolderURI vuri; + Folder *folder; + + /* Evil! EVIL URI PARSING. this will eat a lot of + * stack if we have lots of free monitors */ + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + folder = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + + if (folder == NULL) + continue; + + dirfile = get_directory_file_unlocked (info, folder); + if (dirfile == NULL) + continue; + + entry = (Entry *)folder; + } else { + VFolderURI vuri; + Folder *f; + GnomeVFSResult result; + + entry = NULL; + + /* Evil! EVIL URI PARSING. this will eat a lot of + * stack if we have lots of monitors */ + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + f = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + + if (f != NULL) { + ensure_folder_unlocked ( + info, f, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + entry = find_entry (f->entries, vuri.file); + } + + if (entry == NULL) + continue; + } + + info->free_file_monitors = + g_slist_remove (info->free_file_monitors, handle); + entry->monitors = + g_slist_prepend (entry->monitors, handle); + + handle->exists = TRUE; + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *)handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_CREATED); + + /* recreate a handle */ + if (handle->handle == NULL && + entry->type == ENTRY_FILE) { + EntryFile *efile = (EntryFile *)entry; + char *uri = gnome_vfs_get_uri_from_local_path + (efile->filename); + + gnome_vfs_monitor_add (&(handle->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + handle); + + g_free (uri); + } else if (handle->handle == NULL && + dirfile != NULL) { + char *uri = gnome_vfs_get_uri_from_local_path (dirfile); + + gnome_vfs_monitor_add (&(handle->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + handle); + + g_free (uri); + } + + g_free (dirfile); + } + + g_slist_free (list); +} + +static void /* unlocked */ +rescan_monitors (VFolderInfo *info) +{ + GSList *li; + + if (info->file_monitors == NULL) + return; + + for (li = info->file_monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + GnomeVFSResult result; + Entry *entry; + char *dirfile = NULL; + + /* these are handled below */ + if ( ! h->exists) + continue; + + if (h->is_directory_file) { + VFolderURI vuri; + Folder *folder; + + /* Evil! EVIL URI PARSING. this will eat a lot of + * stack if we have lots of monitors */ + + VFOLDER_URI_PARSE (h->uri, &vuri); + + folder = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + if (folder != NULL) + dirfile = get_directory_file_unlocked (info, + folder); + + if (dirfile == NULL) { + h->exists = FALSE; + gnome_vfs_monitor_callback + ((GnomeVFSMethodHandle *)h, + h->uri, + GNOME_VFS_MONITOR_EVENT_DELETED); + info->free_file_monitors = g_slist_prepend + (info->free_file_monitors, h); + file_monitor_handle_ref_unlocked (h); + /* it has been unreffed when the entry was + * whacked */ + continue; + } + + entry = (Entry *)folder; + } else { + VFolderURI vuri; + Folder *f; + GnomeVFSResult result; + + entry = NULL; + + /* Evil! EVIL URI PARSING. this will eat a lot of + * stack if we have lots of monitors */ + + VFOLDER_URI_PARSE (h->uri, &vuri); + + f = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + + if (f != NULL) { + ensure_folder_unlocked ( + info, f, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + entry = find_entry (f->entries, vuri.file); + } + + if (entry == NULL) { + h->exists = FALSE; + gnome_vfs_monitor_callback + ((GnomeVFSMethodHandle *)h, + h->uri, + GNOME_VFS_MONITOR_EVENT_DELETED); + info->free_file_monitors = g_slist_prepend + (info->free_file_monitors, h); + file_monitor_handle_ref_unlocked (h); + /* it has been unreffed when the entry was + * whacked */ + continue; + } + } + + /* recreate a handle */ + if (h->handle == NULL && + entry->type == ENTRY_FILE) { + EntryFile *efile = (EntryFile *)entry; + char *uri = gnome_vfs_get_uri_from_local_path + (efile->filename); + + gnome_vfs_monitor_add (&(h->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + h); + + g_free (uri); + } else if (h->handle == NULL && + dirfile != NULL) { + char *uri = gnome_vfs_get_uri_from_local_path (dirfile); + + gnome_vfs_monitor_add (&(h->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + h); + + g_free (uri); + } + + g_free (dirfile); + } + + try_free_file_monitors_create_files_unlocked (info); +} + +static gboolean /* unlocked */ +vfolder_info_read_items (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + GSList *li; + + /* First merge */ + for (li = info->merge_dirs; li != NULL; li = li->next) { + const char *merge_dir = li->data; + + if ( ! vfolder_info_read_items_merge (info, merge_dir, NULL, FALSE, + result, context)) + return FALSE; + } + + /* Then read the real thing (later overrides) */ + for (li = info->item_dirs; li != NULL; li = li->next) { + const char *item_dir = li->data; + + if ( ! vfolder_info_read_items_from (info, item_dir, + FALSE /* per_user */, + result, context)) + return FALSE; + } + + if (info->user_item_dir != NULL) { + if ( ! vfolder_info_read_items_from (info, + info->user_item_dir, + TRUE /* per_user */, + result, context)) + return FALSE; + } + + rescan_monitors (info); + + return TRUE; +} + +static gboolean +string_slist_equal (GSList *list1, GSList *list2) +{ + GSList *li1, *li2; + + for (li1 = list1, li2 = list2; + li1 != NULL && li2 != NULL; + li1 = li1->next, li2 = li2->next) { + const char *s1 = li1->data; + const char *s2 = li2->data; + if (strcmp (s1, s2) != 0) + return FALSE; + } + /* if both are not NULL, then lengths are + * different */ + if (li1 != li2) + return FALSE; + return TRUE; +} + +static gboolean +safe_string_same (const char *string1, const char *string2) +{ + if (string1 == string2 && + string1 == NULL) + return TRUE; + + if (string1 != NULL && string2 != NULL && + strcmp (string1, string2) == 0) + return TRUE; + + return FALSE; +} + +static gboolean +vfolder_info_item_dirs_same (VFolderInfo *info1, VFolderInfo *info2) +{ + if ( ! string_slist_equal (info1->item_dirs, + info2->item_dirs)) + return FALSE; + + if ( ! string_slist_equal (info1->merge_dirs, + info2->merge_dirs)) + return FALSE; + + if ( ! safe_string_same (info1->user_item_dir, + info2->user_item_dir)) + return FALSE; + + return TRUE; +} + +static gboolean +vfolder_info_reload_unlocked (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context, + gboolean force_read_items) +{ + VFolderInfo *newinfo; + gboolean setup_filenames; + gboolean setup_itemdirs; + GSList *li; + + /* FIXME: Hmmm, race, there is no locking YAIKES, + * we need filename locking for changes. eek, eek, eek */ + if (info->dirty) { + return TRUE; + } + + newinfo = g_new0 (VFolderInfo, 1); + vfolder_info_init (newinfo, info->scheme); + + g_free (newinfo->filename); + g_free (newinfo->user_filename); + newinfo->filename = g_strdup (info->filename); + newinfo->user_filename = g_strdup (info->user_filename); + + if (gnome_vfs_context_check_cancellation (context)) { + vfolder_info_destroy (newinfo); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + if ( ! vfolder_info_read_info (newinfo, result, context)) { + vfolder_info_destroy (newinfo); + return FALSE; + } + + /* FIXME: reload logic for 'desktop_dir' and + * 'user_desktop_dir' */ + + setup_itemdirs = TRUE; + + /* Validity of entries and item dirs and all that is unchanged */ + if (vfolder_info_item_dirs_same (info, newinfo)) { + newinfo->entries = info->entries; + info->entries = NULL; + newinfo->entries_ht = info->entries_ht; + info->entries_ht = NULL /* some places assume this + non-null, but we're only + going to destroy this */; + newinfo->entries_valid = info->entries_valid; + + /* move over the monitors/statlocs since those are valid */ + newinfo->item_dir_monitors = info->item_dir_monitors; + info->item_dir_monitors = NULL; + newinfo->stat_dirs = info->stat_dirs; + info->stat_dirs = NULL; + + /* No need to resetup dir monitors */ + setup_itemdirs = FALSE; + + /* No need to do anything with file monitors */ + } else { + /* Whack all monitors here! */ + for (li = info->file_monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + if (h->handle != NULL) + gnome_vfs_monitor_cancel (h->handle); + h->handle = NULL; + } + } + + setup_filenames = TRUE; + + if (safe_string_same (info->filename, newinfo->filename) && + safe_string_same (info->user_filename, newinfo->user_filename)) { + newinfo->user_filename_last_write = + info->user_filename_last_write; + + /* move over the monitors/statlocs since those are valid */ + newinfo->filename_monitor = info->filename_monitor; + info->filename_monitor = NULL; + newinfo->user_filename_monitor = info->user_filename_monitor; + info->user_filename_monitor = NULL; + + if (info->filename_statloc != NULL && + info->filename != NULL) + newinfo->filename_statloc = + bake_statloc (info->filename, + time (NULL)); + if (info->user_filename_statloc != NULL && + info->user_filename != NULL) + newinfo->user_filename_statloc = + bake_statloc (info->user_filename, + time (NULL)); + + /* No need to resetup filename monitors */ + setup_filenames = FALSE; + } + + /* Note: not cancellable anymore, since we've + * already started nibbling on the info structure, + * so we'd need to back things out or some such, + * too complex, so screw that */ + monitor_setup (info, + setup_filenames, + setup_itemdirs, + /* FIXME: setup_desktop_dirs */ TRUE, + NULL, NULL); + + for (li = info->folder_monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *handle = li->data; + li->data = NULL; + + add_folder_monitor_unlocked (newinfo, handle); + + file_monitor_handle_unref_unlocked (handle); + } + g_slist_free (info->folder_monitors); + info->folder_monitors = NULL; + + g_slist_foreach (info->free_folder_monitors, + (GFunc)file_monitor_handle_unref_unlocked, NULL); + g_slist_free (info->free_folder_monitors); + info->folder_monitors = NULL; + + /* we can just copy these for now, they will be readded + * and all the fun stuff will be done with them later */ + newinfo->file_monitors = info->file_monitors; + info->file_monitors = NULL; + newinfo->free_file_monitors = info->free_file_monitors; + info->free_file_monitors = NULL; + + /* emit changed on all folders, a bit drastic, but oh well, + * we also invalidate all folders at the same time, but that is + * irrelevant since they should all just be invalid to begin with */ + invalidate_folder_T (info->root); + + /* FIXME: make sure if this was enough, I think it was */ + + vfolder_info_free_internals_unlocked (info); + memcpy (info, newinfo, sizeof (VFolderInfo)); + g_free (newinfo); + + /* must rescan the monitors here */ + if (info->entries_valid) { + rescan_monitors (info); + } + + if ( ! info->entries_valid && + force_read_items) { + GnomeVFSResult res; + /* FIXME: I bet cancelation plays havoc with monitors, + * I'm not sure however */ + if (info->file_monitors != NULL) { + vfolder_info_read_items (info, &res, NULL); + } else { + if ( ! vfolder_info_read_items (info, result, context)) + return FALSE; + } + info->entries_valid = TRUE; + } + + return TRUE; +} + +static gboolean +vfolder_info_reload (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context, + gboolean force_read_items) +{ + G_LOCK (vfolder_lock); + if (vfolder_info_reload_unlocked (info, result, context, + force_read_items)) { + G_UNLOCK (vfolder_lock); + return TRUE; + } else { + G_UNLOCK (vfolder_lock); + return FALSE; + } +} + +static gboolean +vfolder_info_recheck (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + GSList *li; + time_t curtime = time (NULL); + gboolean reread = FALSE; + + if (info->filename_statloc != NULL && + ! check_statloc (info->filename_statloc, curtime)) { + if ( ! vfolder_info_reload_unlocked (info, result, context, + FALSE /* force read items */)) { + /* we have failed, make sure we fail + * next time too */ + info->filename_statloc->trigger_next = TRUE; + return FALSE; + } + reread = TRUE; + } + if ( ! reread && + info->user_filename_statloc != NULL && + ! check_statloc (info->user_filename_statloc, curtime)) { + if ( ! vfolder_info_reload_unlocked (info, result, context, + FALSE /* force read items */)) { + /* we have failed, make sure we fail + * next time too */ + info->user_filename_statloc->trigger_next = TRUE; + return FALSE; + } + reread = TRUE; + } + + if (info->entries_valid) { + for (li = info->stat_dirs; li != NULL; li = li->next) { + StatLoc *sl = li->data; + if ( ! check_statloc (sl, curtime)) { + info->entries_valid = FALSE; + break; + } + } + } + return TRUE; +} + +static VFolderInfo * +get_vfolder_info_unlocked (const char *scheme, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + VFolderInfo *info; + + if (infos != NULL && + (info = g_hash_table_lookup (infos, scheme)) != NULL) { + if ( ! vfolder_info_recheck (info, result, context)) { + return NULL; + } + if ( ! info->entries_valid) { + g_slist_foreach (info->entries, + (GFunc)entry_unref, NULL); + g_slist_free (info->entries); + info->entries = NULL; + + if (info->entries_ht != NULL) + g_hash_table_destroy (info->entries_ht); + info->entries_ht = g_hash_table_new (g_str_hash, + g_str_equal); + + if ( ! vfolder_info_read_items (info, + result, context)) { + info->entries_valid = FALSE; + return NULL; + } + + invalidate_folder_T (info->root); + + info->entries_valid = TRUE; + + /* Update modification time of all folders, + * kind of evil, but it will make adding new items work + * I hope. This is because rereading usually means + * something changed */ + info->modification_time = time (NULL); + } + return info; + } + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if (infos == NULL) + infos = g_hash_table_new_full + (g_str_hash, g_str_equal, + (GDestroyNotify)g_free, + (GDestroyNotify)vfolder_info_destroy); + + info = g_new0 (VFolderInfo, 1); + vfolder_info_init (info, scheme); + + if (gnome_vfs_context_check_cancellation (context)) { + vfolder_info_destroy (info); + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if ( ! vfolder_info_read_info (info, result, context)) { + vfolder_info_destroy (info); + return NULL; + } + + if ( ! monitor_setup (info, + TRUE /* setup_filenames */, + TRUE /* setup_itemdirs */, + TRUE /* setup_desktop_dirs */, + result, context)) { + vfolder_info_destroy (info); + return NULL; + } + + g_hash_table_insert (infos, g_strdup (scheme), info); + + if ( ! vfolder_info_read_items (info, result, context)) { + info->entries_valid = FALSE; + return NULL; + } + info->entries_valid = TRUE; + + return info; +} + +static VFolderInfo * +get_vfolder_info (const char *scheme, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + VFolderInfo *info; + G_LOCK (vfolder_lock); + info = get_vfolder_info_unlocked (scheme, result, context); + G_UNLOCK (vfolder_lock); + return info; +} + + +static char * +keywords_to_string (GSList *keywords) +{ + GSList *li; + GString *str = g_string_new (NULL); + + for (li = keywords; li != NULL; li = li->next) { + GQuark word = GPOINTER_TO_INT (li->data); + g_string_append (str, g_quark_to_string (word)); + g_string_append_c (str, ';'); + } + + return g_string_free (str, FALSE); +} + +/* copy file and add keywords line */ +static gboolean +copy_file_with_keywords (const char *from, const char *to, GSList *keywords) +{ + FILE *fp; + FILE *wfp; + int wfd; + char buf[BUFSIZ]; + char *keyword_string; + + if ( ! ensure_dir (to, + TRUE /* ignore_basename */)) + return FALSE; + + wfd = open (to, O_CREAT | O_WRONLY | O_TRUNC, 0600); + if (wfd < 0) { + return FALSE; + } + + keyword_string = keywords_to_string (keywords); + + wfp = fdopen (wfd, "w"); + + fp = fopen (from, "r"); + if (fp != NULL) { + gboolean wrote_keywords = FALSE; + while (fgets (buf, sizeof (buf), fp) != NULL) { + fprintf (wfp, "%s", buf); + if ( ! wrote_keywords && + (strncmp (buf, "[Desktop Entry]", + strlen ("[Desktop Entry]")) == 0 || + strncmp (buf, "[KDE Desktop Entry]", + strlen ("[KDE Desktop Entry]")) == 0)) { + fprintf (wfp, "Categories=%s\n", + keyword_string); + wrote_keywords = TRUE; + } + } + + fclose (fp); + } else { + fprintf (wfp, "[Desktop Entry]\nCategories=%s\n", + keyword_string); + } + + /* FIXME: does this close wfd???? */ + fclose (wfp); + + close (wfd); + + g_free (keyword_string); + + return TRUE; +} + +static gboolean +copy_file (const char *from, const char *to) +{ + int fd; + int wfd; + + if ( ! ensure_dir (to, + TRUE /* ignore_basename */)) + return FALSE; + + wfd = open (to, O_CREAT | O_WRONLY | O_TRUNC, 0600); + if (wfd < 0) { + return FALSE; + } + + fd = open (from, O_RDONLY); + if (fd >= 0) { + char buf[1024]; + ssize_t n; + + while ((n = read (fd, buf, sizeof(buf))) > 0) { + write (wfd, buf, n); + } + + close (fd); + } + + close (wfd); + + return TRUE; +} + +static gboolean +make_file_private (VFolderInfo *info, EntryFile *efile) +{ + char *newfname; + Entry *entry = (Entry *)efile; + + if (efile->per_user) + return TRUE; + + /* this file already exists so whack its monitors */ + if (efile->filename != NULL) { + GSList *li; + + for (li = entry->monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + if (h->handle != NULL) + gnome_vfs_monitor_cancel (h->handle); + h->handle = NULL; + } + } + + newfname = g_build_filename (g_get_home_dir (), + DOT_GNOME, + "vfolders", + info->scheme, + efile->entry.name, + NULL); + + if (efile->implicit_keywords) { + if (efile->filename != NULL && + ! copy_file_with_keywords (efile->filename, + newfname, + efile->keywords)) { + /* FIXME: what to do with monitors here, they + * have already been whacked, a corner case + * not handled! */ + g_free (newfname); + return FALSE; + } + } else { + if (efile->filename != NULL && + ! copy_file (efile->filename, newfname)) { + /* FIXME: what to do with monitors here, they + * have already been whacked, a corner case + * not handled! */ + g_free (newfname); + return FALSE; + } + } + + /* we didn't copy but ensure path anyway */ + if (efile->filename == NULL && + ! ensure_dir (newfname, + TRUE /* ignore_basename */)) { + g_free (newfname); + return FALSE; + } + + /* this file already exists so re-add monitors at the new location */ + if (efile->filename != NULL) { + GSList *li; + char *uri = gnome_vfs_get_uri_from_local_path (newfname); + + for (li = entry->monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + + gnome_vfs_monitor_add (&(h->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + h); + } + + g_free (uri); + } + + g_free (efile->filename); + efile->filename = newfname; + efile->per_user = TRUE; + + return TRUE; +} + +static void +try_free_file_monitors_create_dirfile_unlocked (VFolderInfo *info, + Folder *folder) +{ + GSList *li, *list; + + list = g_slist_copy (info->free_file_monitors); + + for (li = list; li != NULL; li = li->next) { + FileMonitorHandle *handle = li->data; + Folder *f; + VFolderURI vuri; + GnomeVFSResult result; + + if ( ! handle->is_directory_file) + continue; + + /* Evil! EVIL URI PARSING. this will eat a lot of stack if we + * have lots of free monitors */ + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + f = resolve_folder (info, + vuri.path, + TRUE /* ignore_basename */, + &result, + NULL); + + if (folder != f) + continue; + + info->free_file_monitors = + g_slist_remove (info->free_file_monitors, handle); + ((Entry *)folder)->monitors = + g_slist_prepend (((Entry *)folder)->monitors, handle); + + handle->exists = TRUE; + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *)handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_CREATED); + } + + g_slist_free (list); +} + +static void +make_new_dirfile (VFolderInfo *info, Folder *folder) +{ + char *name = g_strdup (folder->entry.name); + char *fname; + char *p; + int i; + int fd; + + for (p = name; *p != '\0'; p++) { + if ( ! ( (*p >= 'a' && *p <= 'z') || + (*p >= 'A' && *p <= 'Z') || + (*p >= '0' && *p <= '9') || + *p == '_')) { + *p = '_'; + } + } + + i = 0; + fname = NULL; + do { + char *fullname; + + g_free (fname); + + if (i > 0) { + fname = g_strdup_printf ("%s-%d.directory", name, i); + } else { + fname = g_strdup_printf ("%s.directory", name); + } + + fullname = g_build_filename + (info->user_desktop_dir, fname, NULL); + fd = open (fullname, O_CREAT | O_WRONLY | O_EXCL, 0600); + g_free (fullname); + } while (fd < 0); + + close (fd); + + folder->desktop_file = fname; + info->dirty = TRUE; + + try_free_file_monitors_create_dirfile_unlocked (info, folder); +} + +static gboolean +make_dirfile_private (VFolderInfo *info, Folder *folder) +{ + char *fname; + char *desktop_file; + GSList *li; + char *uri; + gboolean ret; + + if (info->user_desktop_dir == NULL) + return FALSE; + + if ( ! ensure_dir (info->user_desktop_dir, + FALSE /* ignore_basename */)) + return FALSE; + + + if (folder->desktop_file == NULL) { + make_new_dirfile (info, folder); + return TRUE; + } + + /* FIXME: this is broken! What if the desktop file exists + * in the local but there is a different (but with a same name) + * .directory in the system. */ + fname = g_build_filename (info->user_desktop_dir, + folder->desktop_file, + NULL); + + if (access (fname, F_OK) == 0) { + g_free (fname); + return TRUE; + } + + desktop_file = get_directory_file (info, folder); + + if (desktop_file == NULL) { + int fd = open (fname, O_CREAT | O_EXCL | O_WRONLY, 0600); + g_free (fname); + if (fd >= 0) { + close (fd); + return TRUE; + } + return FALSE; + } + + for (li = ((Entry *)folder)->monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + if (h->is_directory_file) { + if (h->handle != NULL) + gnome_vfs_monitor_cancel (h->handle); + h->handle = NULL; + } + } + + ret = TRUE; + + if ( ! copy_file (desktop_file, fname)) { + ret = FALSE; + g_free (fname); + fname = desktop_file; + desktop_file = NULL; + } + + uri = gnome_vfs_get_uri_from_local_path (fname); + + for (li = ((Entry *)folder)->monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + + if (h->is_directory_file) { + gnome_vfs_monitor_add (&(h->handle), + uri, + GNOME_VFS_MONITOR_FILE, + file_monitor, + h); + } + } + + g_free (uri); + + g_free (desktop_file); + g_free (fname); + + return ret; +} + +static Folder * +resolve_folder (VFolderInfo *info, + const char *path, + gboolean ignore_basename, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + char **ppath; + int i; + Folder *folder = info->root; + + ppath = g_strsplit (path, "/", -1); + + if (ppath == NULL || + ppath[0] == NULL) { + g_strfreev (ppath); + *result = GNOME_VFS_ERROR_INVALID_URI; + return NULL; + } + + for (i = 0; ppath [i] != NULL; i++) { + const char *segment = ppath[i]; + + if (*segment == '\0') + continue; + + if (ignore_basename && ppath [i + 1] == NULL) + break; + else { + folder = (Folder *) find_entry (folder->subfolders, + segment); + if (folder == NULL) + break; + } + } + g_strfreev (ppath); + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if (folder == NULL) + *result = GNOME_VFS_ERROR_NOT_FOUND; + + return folder; +} + +static Entry * +resolve_path (VFolderInfo *info, + const char *path, + const char *basename, + Folder **return_folder, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + Entry *entry; + Folder *folder; + + if (strcmp (path, "/") == 0) + return (Entry *)info->root; + + folder = resolve_folder (info, path, + TRUE /* ignore_basename */, + result, context); + + if (return_folder != NULL) + *return_folder = folder; + + if (folder == NULL) { + return NULL; + } + + /* Make sure we have the entries here */ + ensure_folder_unlocked (info, folder, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + + entry = find_entry (folder->entries, basename); + + if (entry == NULL) + *result = GNOME_VFS_ERROR_NOT_FOUND; + + return entry; +} + +static Entry * +get_entry_unlocked (VFolderURI *vuri, + Folder **parent, + gboolean *is_directory_file, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + VFolderInfo *info; + Entry *entry; + + if (is_directory_file != NULL) + *is_directory_file = FALSE; + if (parent != NULL) + *parent = NULL; + + info = get_vfolder_info_unlocked (vuri->scheme, result, context); + if (info == NULL) + return NULL; + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if (vuri->is_all_scheme) { + GSList *efile_list; + + if (vuri->file == NULL) { + entry = resolve_path (info, + vuri->path, + vuri->file, + parent, + result, + context); + return entry; + } + + efile_list = g_hash_table_lookup (info->entries_ht, vuri->file); + + if (efile_list == NULL) { + *result = GNOME_VFS_ERROR_NOT_FOUND; + return NULL; + } else { + return efile_list->data; + } + } + + if (vuri->file != NULL && + check_ext (vuri->file, ".directory") == TRUE) { + Folder *folder; + + folder = resolve_folder (info, vuri->path, + TRUE /* ignore_basename */, + result, context); + if (folder == NULL) { + return NULL; + } + + if (is_directory_file != NULL) + *is_directory_file = TRUE; + + if (parent != NULL) + *parent = folder; + + return (Entry *)folder; + } else { + entry = resolve_path (info, vuri->path, vuri->file, parent, + result, context); + return entry; + } +} + +static Entry * +get_entry (VFolderURI *vuri, + Folder **parent, + gboolean *is_directory_file, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + Entry *entry; + + G_LOCK (vfolder_lock); + entry = get_entry_unlocked (vuri, + parent, + is_directory_file, + result, context); + G_UNLOCK (vfolder_lock); + + return entry; +} + +/* only works for files and only those that exist */ +/* unlocked function */ +static GnomeVFSURI * +desktop_uri_to_file_uri (VFolderInfo *info, + VFolderURI *desktop_vuri, + Entry **the_entry, + gboolean *the_is_directory_file, + Folder **the_folder, + gboolean privatize, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + gboolean is_directory_file; + GnomeVFSURI *ret_uri; + Folder *folder = NULL; + Entry *entry; + + entry = get_entry_unlocked (desktop_vuri, + &folder, + &is_directory_file, + result, + context); + if (entry == NULL) + return NULL; + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if (the_folder != NULL) + *the_folder = folder; + + if (the_entry != NULL) + *the_entry = entry; + if (the_is_directory_file != NULL) + *the_is_directory_file = is_directory_file; + + if (is_directory_file && + entry->type == ENTRY_FOLDER) { + char *desktop_file; + + folder = (Folder *)entry; + + if (the_folder != NULL) + *the_folder = folder; + + /* we'll be doing something write like */ + if (folder->read_only && + privatize) { + *result = GNOME_VFS_ERROR_READ_ONLY; + return NULL; + } + + if (privatize) { + char *fname; + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if ( ! make_dirfile_private (info, folder)) { + *result = GNOME_VFS_ERROR_GENERIC; + return NULL; + } + fname = g_build_filename (g_get_home_dir (), + folder->desktop_file, + NULL); + ret_uri = gnome_vfs_uri_new (fname); + g_free (fname); + return ret_uri; + } + + desktop_file = get_directory_file_unlocked (info, folder); + if (desktop_file != NULL) { + char *s = gnome_vfs_get_uri_from_local_path + (desktop_file); + + g_free (desktop_file); + + ret_uri = gnome_vfs_uri_new (s); + g_free (s); + + return ret_uri; + } else { + *result = GNOME_VFS_ERROR_NOT_FOUND; + return NULL; + } + } else if (entry->type == ENTRY_FILE) { + EntryFile *efile = (EntryFile *)entry; + char *s; + + /* we'll be doing something write like */ + if (folder != NULL && + folder->read_only && + privatize) { + *result = GNOME_VFS_ERROR_READ_ONLY; + return NULL; + } + + if (gnome_vfs_context_check_cancellation (context)) { + *result = GNOME_VFS_ERROR_CANCELLED; + return NULL; + } + + if (privatize && + ! make_file_private (info, efile)) { + *result = GNOME_VFS_ERROR_GENERIC; + return NULL; + } + + s = gnome_vfs_get_uri_from_local_path (efile->filename); + ret_uri = gnome_vfs_uri_new (s); + g_free (s); + + return ret_uri; + } else { + if (the_folder != NULL) + *the_folder = (Folder *)entry; + *result = GNOME_VFS_ERROR_IS_DIRECTORY; + return NULL; + } +} + +static void +remove_file (Folder *folder, const char *basename) +{ + GSList *li; + char *s; + + if (folder->includes_ht != NULL) { + li = g_hash_table_lookup (folder->includes_ht, basename); + if (li != NULL) { + char *name = li->data; + folder->includes = g_slist_delete_link + (folder->includes, li); + g_hash_table_remove (folder->includes_ht, basename); + g_free (name); + } + } + + if (folder->excludes == NULL) { + folder->excludes = g_hash_table_new_full + (g_str_hash, g_str_equal, + (GDestroyNotify)g_free, + NULL); + } + s = g_strdup (basename); + g_hash_table_replace (folder->excludes, s, s); +} + +static void +add_file (Folder *folder, const char *basename) +{ + GSList *li = NULL; + + if (folder->includes_ht != NULL) { + li = g_hash_table_lookup (folder->includes_ht, basename); + } + + /* if not found */ + if (li == NULL) { + char *str = g_strdup (basename); + folder->includes = + g_slist_prepend (folder->includes, str); + if (folder->includes_ht == NULL) { + folder->includes_ht = + g_hash_table_new_full (g_str_hash, + g_str_equal, + NULL, + NULL); + } + g_hash_table_replace (folder->includes_ht, + str, folder->includes); + } + if (folder->excludes != NULL) + g_hash_table_remove (folder->excludes, basename); +} + +typedef struct _FileHandle FileHandle; +struct _FileHandle { + VFolderInfo *info; + GnomeVFSMethodHandle *handle; + Entry *entry; + gboolean write; + gboolean is_directory_file; +}; + +static void +make_handle (GnomeVFSMethodHandle **method_handle, + GnomeVFSMethodHandle *file_handle, + VFolderInfo *info, + Entry *entry, + gboolean is_directory_file, + gboolean write) +{ + if (file_handle != NULL) { + FileHandle *handle = g_new0 (FileHandle, 1); + + handle->info = info; + handle->handle = file_handle; + handle->entry = entry_ref (entry); + handle->is_directory_file = is_directory_file; + handle->write = write; + + *method_handle = (GnomeVFSMethodHandle *) handle; + } else { + *method_handle = NULL; + } +} + +static void +whack_handle (FileHandle *handle) +{ + entry_unref (handle->entry); + handle->entry = NULL; + + handle->handle = NULL; + handle->info = NULL; + + g_free (handle); +} + +static GnomeVFSResult +do_open (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result = GNOME_VFS_OK; + VFolderInfo *info; + Entry *entry; + gboolean is_directory_file; + GnomeVFSMethodHandle *file_handle = NULL; + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + /* These can't be very nice FILE names */ + if (vuri.file == NULL || + vuri.ends_in_slash) + return GNOME_VFS_ERROR_INVALID_URI; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (mode & GNOME_VFS_OPEN_WRITE && + (info->read_only || vuri.is_all_scheme)) + return GNOME_VFS_ERROR_READ_ONLY; + + G_LOCK (vfolder_lock); + file_uri = desktop_uri_to_file_uri (info, + &vuri, + &entry, + &is_directory_file, + NULL /* the_folder */, + mode & GNOME_VFS_OPEN_WRITE, + &result, + context); + + if (file_uri == NULL) { + G_UNLOCK (vfolder_lock); + return result; + } + + result = (* parent_method->open) (parent_method, + &file_handle, + file_uri, + mode, + context); + + if (result == GNOME_VFS_ERROR_CANCELLED) { + G_UNLOCK (vfolder_lock); + gnome_vfs_uri_unref (file_uri); + return result; + } + + make_handle (method_handle, + file_handle, + info, + entry, + is_directory_file, + mode & GNOME_VFS_OPEN_WRITE); + + gnome_vfs_uri_unref (file_uri); + + if (info->dirty) { + vfolder_info_write_user (info); + } + + G_UNLOCK (vfolder_lock); + + return result; +} + +static void +remove_from_all_except (Folder *root, + const char *name, + Folder *except) +{ + GSList *li; + + if (root != except) { + remove_file (root, name); + if (root->up_to_date) { + for (li = root->entries; li != NULL; li = li->next) { + Entry *entry = li->data; + if (strcmp (name, entry->name) == 0) { + root->entries = + g_slist_delete_link + (root->entries, li); + break; + } + } + } + } + + for (li = root->subfolders; li != NULL; li = li->next) { + Folder *subfolder = li->data; + + remove_from_all_except (subfolder, name, except); + } +} + +static GnomeVFSResult +do_create (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + gboolean exclusive, + guint perm, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + GnomeVFSMethodHandle *file_handle; + GnomeVFSURI *file_uri; + VFolderURI vuri; + VFolderInfo *info; + Folder *parent; + Entry *entry; + EntryFile *efile; + char *s; + GSList *li; + + VFOLDER_URI_PARSE (uri, &vuri); + + /* These can't be very nice FILE names */ + if (vuri.file == NULL || + vuri.ends_in_slash) + return GNOME_VFS_ERROR_INVALID_URI; + + if ( ! check_ext (vuri.file, ".desktop") && + ! strcmp (vuri.file, ".directory") == 0) { + return GNOME_VFS_ERROR_INVALID_URI; + } + + /* all scheme is read only */ + if (vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (info->user_filename == NULL || + info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + parent = resolve_folder (info, vuri.path, + TRUE /* ignore_basename */, + &result, context); + if (parent == NULL) + return result; + + if (parent->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + if (strcmp (vuri.file, ".directory") == 0) { + char *fname; + + G_LOCK (vfolder_lock); + + if (exclusive) { + char *desktop_file; + desktop_file = get_directory_file_unlocked (info, parent); + if (desktop_file != NULL) { + g_free (desktop_file); + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_FILE_EXISTS; + } + } + + if ( ! make_dirfile_private (info, parent)) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_GENERIC; + } + fname = g_build_filename (g_get_home_dir (), + parent->desktop_file, + NULL); + s = gnome_vfs_get_uri_from_local_path (fname); + file_uri = gnome_vfs_uri_new (s); + g_free (fname); + g_free (s); + + if (file_uri == NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_GENERIC; + } + + result = (* parent_method->create) (parent_method, + &file_handle, + file_uri, + mode, + exclusive, + perm, + context); + gnome_vfs_uri_unref (file_uri); + + make_handle (method_handle, + file_handle, + info, + (Entry *)parent, + TRUE /* is_directory_file */, + TRUE /* write */); + + if (info->dirty) + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return result; + } + + ensure_folder (info, parent, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + + entry = find_entry (parent->entries, vuri.file); + + if (entry != NULL && + entry->type == ENTRY_FOLDER) + return GNOME_VFS_ERROR_IS_DIRECTORY; + + efile = (EntryFile *)entry; + + if (efile != NULL) { + if (exclusive) + return GNOME_VFS_ERROR_FILE_EXISTS; + + G_LOCK (vfolder_lock); + if ( ! make_file_private (info, efile)) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_GENERIC; + } + + s = gnome_vfs_get_uri_from_local_path (efile->filename); + file_uri = gnome_vfs_uri_new (s); + g_free (s); + + if (file_uri == NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_GENERIC; + } + + result = (* parent_method->create) (parent_method, + &file_handle, + file_uri, + mode, + exclusive, + perm, + context); + gnome_vfs_uri_unref (file_uri); + + make_handle (method_handle, + file_handle, + info, + (Entry *)efile, + FALSE /* is_directory_file */, + TRUE /* write */); + + G_UNLOCK (vfolder_lock); + + return result; + } + + G_LOCK (vfolder_lock); + + li = g_hash_table_lookup (info->entries_ht, vuri.file); + + if (exclusive && li != NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_FILE_EXISTS; + } + + if (li == NULL) { + efile = file_new (vuri.file); + vfolder_info_insert_entry (info, efile); + entry_unref ((Entry *)efile); + } else { + efile = li->data; + } + + /* this will make a private name for this */ + if ( ! make_file_private (info, efile)) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_GENERIC; + } + + add_file (parent, vuri.file); + parent->sorted = FALSE; + + if (parent->up_to_date) + parent->entries = g_slist_prepend (parent->entries, efile); + + /* if we created a brand new name, then we exclude it + * from everywhere else to ensure overall sanity */ + if (li == NULL) + remove_from_all_except (info->root, vuri.file, parent); + + s = gnome_vfs_get_uri_from_local_path (efile->filename); + file_uri = gnome_vfs_uri_new (s); + g_free (s); + + result = (* parent_method->create) (parent_method, + &file_handle, + file_uri, + mode, + exclusive, + perm, + context); + gnome_vfs_uri_unref (file_uri); + + make_handle (method_handle, + file_handle, + info, + (Entry *)efile, + FALSE /* is_directory_file */, + TRUE /* write */); + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return result; +} + +static GnomeVFSResult +do_close (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + if (method_handle == (GnomeVFSMethodHandle *)method) + return GNOME_VFS_OK; + + G_LOCK (vfolder_lock); + + result = (* parent_method->close) (parent_method, + handle->handle, + context); + handle->handle = NULL; + + /* we reread the Categories keyword */ + if (handle->write && + handle->entry != NULL && + handle->entry->type == ENTRY_FILE) { + EntryFile *efile = (EntryFile *)handle->entry; + char *categories; + readitem_entry (efile->filename, + "Categories", + &categories, + NULL, + NULL); + set_keywords (efile, categories); + g_free (categories); + /* FIXME: what about OnlyShowIn */ + + /* FIXME: check if the keywords changed, if not, do + * nothing */ + + /* Perhaps a bit drastic */ + /* also this emits the CHANGED monitor signal */ + invalidate_folder_T (handle->info->root); + + /* the file changed monitor will happen by itself + * as the underlying file is changed */ + } else if (handle->write && + handle->entry != NULL && + handle->entry->type == ENTRY_FOLDER && + handle->is_directory_file) { + /* if we're monitoring this directory, emit the CHANGED + * monitor thing, it will also emit a changed on + * the file itself. It is better to emit changed + * just in case. */ + emit_monitor ((Folder *)(handle->entry), + GNOME_VFS_MONITOR_EVENT_CHANGED); + } + + whack_handle (handle); + + G_UNLOCK (vfolder_lock); + + return result; +} + +static void +fill_buffer (gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read) +{ + char *buf = buffer; + GnomeVFSFileSize i; + for (i = 0; i < num_bytes; i++) { + if (rand () % 32 == 0 || + i == num_bytes-1) + buf[i] = '\n'; + else + buf[i] = ((rand()>>4) % 94) + 32; + } + if (bytes_read != 0) + *bytes_read = i; +} + +static GnomeVFSResult +do_read (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + if (method_handle == (GnomeVFSMethodHandle *)method) { + if ((rand () >> 4) & 0x3) { + fill_buffer (buffer, num_bytes, bytes_read); + return GNOME_VFS_OK; + } else { + return GNOME_VFS_ERROR_EOF; + } + } + + result = (* parent_method->read) (parent_method, + handle->handle, + buffer, num_bytes, + bytes_read, + context); + + return result; +} + +static GnomeVFSResult +do_write (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gconstpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_written, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + if (method_handle == (GnomeVFSMethodHandle *)method) + return GNOME_VFS_OK; + + result = (* parent_method->write) (parent_method, + handle->handle, + buffer, num_bytes, + bytes_written, + context); + + return result; +} + + +static GnomeVFSResult +do_seek (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSSeekPosition whence, + GnomeVFSFileOffset offset, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + if (method_handle == (GnomeVFSMethodHandle *)method) + return GNOME_VFS_OK; + + result = (* parent_method->seek) (parent_method, + handle->handle, + whence, offset, + context); + + return result; +} + +static GnomeVFSResult +do_tell (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileOffset *offset_return) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + result = (* parent_method->tell) (parent_method, + handle->handle, + offset_return); + + return result; +} + + +static GnomeVFSResult +do_truncate_handle (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileSize where, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + if (method_handle == (GnomeVFSMethodHandle *)method) + return GNOME_VFS_OK; + + result = (* parent_method->truncate_handle) (parent_method, + handle->handle, + where, + context); + + return result; +} + +static GnomeVFSResult +do_truncate (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileSize where, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result = GNOME_VFS_OK; + VFolderInfo *info; + Entry *entry; + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + /* These can't be very nice FILE names */ + if (vuri.file == NULL || + vuri.ends_in_slash) + return GNOME_VFS_ERROR_INVALID_URI; + + if (vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + G_LOCK (vfolder_lock); + file_uri = desktop_uri_to_file_uri (info, + &vuri, + &entry, + NULL /* the_is_directory_file */, + NULL /* the_folder */, + TRUE /* privatize */, + &result, + context); + G_UNLOCK (vfolder_lock); + + if (file_uri == NULL) + return result; + + result = (* parent_method->truncate) (parent_method, + file_uri, + where, + context); + + gnome_vfs_uri_unref (file_uri); + + if (info->dirty) { + G_LOCK (vfolder_lock); + vfolder_info_write_user (info); + G_UNLOCK (vfolder_lock); + } + + if (entry->type == ENTRY_FILE) { + EntryFile *efile = (EntryFile *)entry; + + G_LOCK (vfolder_lock); + g_slist_free (efile->keywords); + efile->keywords = NULL; + G_UNLOCK (vfolder_lock); + } + + /* Perhaps a bit drastic, but oh well */ + invalidate_folder (info->root); + + return result; +} + +typedef struct _DirHandle DirHandle; +struct _DirHandle { + VFolderInfo *info; + Folder *folder; + + GnomeVFSFileInfoOptions options; + + /* List of Entries */ + GSList *list; + GSList *current; +}; + +static GnomeVFSResult +do_open_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + VFolderURI vuri; + DirHandle *dh; + Folder *folder; + VFolderInfo *info; + char *desktop_file; + + VFOLDER_URI_PARSE (uri, &vuri); + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + /* In the all- scheme just list all filenames */ + if (vuri.is_all_scheme) { + if (any_subdir (vuri.path)) + return GNOME_VFS_ERROR_NOT_FOUND; + + dh = g_new0 (DirHandle, 1); + dh->info = info; + dh->options = options; + dh->folder = NULL; + + G_LOCK (vfolder_lock); + dh->list = g_slist_copy (info->entries); + g_slist_foreach (dh->list, (GFunc)entry_ref, NULL); + dh->current = dh->list; + G_UNLOCK (vfolder_lock); + + *method_handle = (GnomeVFSMethodHandle*) dh; + return GNOME_VFS_OK; + } + + folder = resolve_folder (info, vuri.path, + FALSE /* ignore_basename */, + &result, context); + if (folder == NULL) + return result; + + /* Make sure we have the entries and sorted here */ + ensure_folder_sort (info, folder); + + dh = g_new0 (DirHandle, 1); + dh->info = info; + dh->options = options; + + G_LOCK (vfolder_lock); + dh->folder = (Folder *)entry_ref ((Entry *)folder); + dh->list = g_slist_copy (folder->entries); + g_slist_foreach (folder->entries, (GFunc)entry_ref, NULL); + G_UNLOCK (vfolder_lock); + + desktop_file = get_directory_file (info, folder); + if (desktop_file != NULL) { + EntryFile *efile = file_new (".directory"); + dh->list = g_slist_prepend (dh->list, efile); + g_free (desktop_file); + } + + dh->current = dh->list; + + *method_handle = (GnomeVFSMethodHandle*) dh; + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_close_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + DirHandle *dh; + + dh = (DirHandle*) method_handle; + + G_LOCK (vfolder_lock); + + g_slist_foreach (dh->list, (GFunc)entry_unref, NULL); + g_slist_free (dh->list); + dh->list = NULL; + + dh->current = NULL; + + if (dh->folder != NULL) + entry_unref ((Entry *)dh->folder); + dh->folder = NULL; + + dh->info = NULL; + + g_free (dh); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_read_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSContext *context) +{ + DirHandle *dh; + Entry *entry; + GnomeVFSFileInfoOptions options; + + dh = (DirHandle*) method_handle; + +read_directory_again: + + if (dh->current == NULL) { + return GNOME_VFS_ERROR_EOF; + } + + entry = dh->current->data; + dh->current = dh->current->next; + + options = dh->options; + + if (entry->type == ENTRY_FILE && + ((EntryFile *)entry)->filename != NULL) { + EntryFile *efile = (EntryFile *)entry; + char *furi = gnome_vfs_get_uri_from_local_path (efile->filename); + GnomeVFSURI *uri = gnome_vfs_uri_new (furi); + + /* we always get mime-type by forcing it below */ + if (options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE) + options &= ~GNOME_VFS_FILE_INFO_GET_MIME_TYPE; + + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_NONE; + + /* Get the file info for this */ + (* parent_method->get_file_info) (parent_method, + uri, + file_info, + options, + context); + + /* we ignore errors from this since the file_info just + * won't be filled completely if there's an error, that's all */ + + g_free (file_info->mime_type); + file_info->mime_type = g_strdup ("application/x-gnome-app-info"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + /* Now we wipe those fields we don't support */ + file_info->valid_fields &= ~(UNSUPPORTED_INFO_FIELDS); + + gnome_vfs_uri_unref (uri); + g_free (furi); + } else if (entry->type == ENTRY_FILE) { + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_NONE; + + file_info->name = g_strdup (entry->name); + GNOME_VFS_FILE_INFO_SET_LOCAL (file_info, TRUE); + + file_info->type = GNOME_VFS_FILE_TYPE_REGULAR; + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_TYPE; + + /* FIXME: Is this correct? isn't there an xdg mime type? */ + file_info->mime_type = g_strdup ("application/x-gnome-app-info"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + /* FIXME: get some ctime/mtime */ + } else /* ENTRY_FOLDER */ { + Folder *folder = (Folder *)entry; + + /* Skip empty folders if they have + * the flag set */ + if (folder->dont_show_if_empty) { + /* Make sure we have the entries */ + ensure_folder (dh->info, folder, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + + if (folder->entries == NULL) { + /* start this function over on the + * next item */ + goto read_directory_again; + } + } + + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_NONE; + + file_info->name = g_strdup (entry->name); + GNOME_VFS_FILE_INFO_SET_LOCAL (file_info, TRUE); + + file_info->type = GNOME_VFS_FILE_TYPE_DIRECTORY; + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_TYPE; + + file_info->mime_type = g_strdup ("x-directory/vfolder-desktop"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + file_info->ctime = dh->info->modification_time; + file_info->mtime = dh->info->modification_time; + file_info->valid_fields |= (GNOME_VFS_FILE_INFO_FIELDS_CTIME | + GNOME_VFS_FILE_INFO_FIELDS_MTIME); + } + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_get_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result = GNOME_VFS_OK; + Folder *folder; + VFolderInfo *info; + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + G_LOCK (vfolder_lock); + file_uri = desktop_uri_to_file_uri (info, + &vuri, + NULL /* the_entry */, + NULL /* the_is_directory_file */, + &folder, + FALSE /* privatize */, + &result, + context); + G_UNLOCK (vfolder_lock); + + if (file_uri == NULL && + result != GNOME_VFS_ERROR_IS_DIRECTORY) + return result; + + if (file_uri != NULL) { + /* we always get mime-type by forcing it below */ + if (options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE) + options &= ~GNOME_VFS_FILE_INFO_GET_MIME_TYPE; + + result = (* parent_method->get_file_info) (parent_method, + file_uri, + file_info, + options, + context); + + g_free (file_info->mime_type); + file_info->mime_type = g_strdup ("application/x-gnome-app-info"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + /* Now we wipe those fields we don't support */ + file_info->valid_fields &= ~(UNSUPPORTED_INFO_FIELDS); + + gnome_vfs_uri_unref (file_uri); + + return result; + } else if (folder != NULL) { + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_NONE; + + file_info->name = g_strdup (folder->entry.name); + GNOME_VFS_FILE_INFO_SET_LOCAL (file_info, TRUE); + + file_info->type = GNOME_VFS_FILE_TYPE_DIRECTORY; + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_TYPE; + + file_info->mime_type = g_strdup ("x-directory/vfolder-desktop"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + file_info->ctime = info->modification_time; + file_info->mtime = info->modification_time; + file_info->valid_fields |= (GNOME_VFS_FILE_INFO_FIELDS_CTIME | + GNOME_VFS_FILE_INFO_FIELDS_MTIME); + + return GNOME_VFS_OK; + } else { + return GNOME_VFS_ERROR_NOT_FOUND; + } +} + +static GnomeVFSResult +do_get_file_info_from_handle (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + if (method_handle == (GnomeVFSMethodHandle *)method) { + g_free (file_info->mime_type); + file_info->mime_type = g_strdup ("text/plain"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + return GNOME_VFS_OK; + } + + /* we always get mime-type by forcing it below */ + if (options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE) + options &= ~GNOME_VFS_FILE_INFO_GET_MIME_TYPE; + + result = (* parent_method->get_file_info_from_handle) (parent_method, + handle->handle, + file_info, + options, + context); + + /* any file is of the .desktop type */ + g_free (file_info->mime_type); + file_info->mime_type = g_strdup ("application/x-gnome-app-info"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + /* Now we wipe those fields we don't support */ + file_info->valid_fields &= ~(UNSUPPORTED_INFO_FIELDS); + + return result; +} + + +static gboolean +do_is_local (GnomeVFSMethod *method, + const GnomeVFSURI *uri) +{ + return TRUE; +} + +static void +try_free_folder_monitors_create_unlocked (VFolderInfo *info, + Folder *folder) +{ + GSList *li, *list; + + list = g_slist_copy (info->free_folder_monitors); + + for (li = list; li != NULL; li = li->next) { + FileMonitorHandle *handle = li->data; + Folder *f; + VFolderURI vuri; + GnomeVFSResult result; + + /* Evil! EVIL URI PARSING. this will eat a lot of stack if we + * have lots of free monitors */ + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + f = resolve_folder (info, + vuri.path, + FALSE /* ignore_basename */, + &result, + NULL); + + if (folder != f) + continue; + + info->free_folder_monitors = + g_slist_remove (info->free_folder_monitors, handle); + ((Entry *)folder)->monitors = + g_slist_prepend (((Entry *)folder)->monitors, handle); + + handle->exists = TRUE; + gnome_vfs_monitor_callback ((GnomeVFSMethodHandle *)handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_CREATED); + } +} + + +static GnomeVFSResult +do_make_directory (GnomeVFSMethod *method, + GnomeVFSURI *uri, + guint perm, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + VFolderInfo *info; + Folder *parent, *folder; + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + if (vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (info->user_filename == NULL || + info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + parent = resolve_folder (info, vuri.path, + TRUE /* ignore_basename */, + &result, context); + if (parent == NULL) + return result; + else if (parent->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + G_LOCK (vfolder_lock); + + folder = (Folder *)find_entry (parent->subfolders, + vuri.file); + if (folder != NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_FILE_EXISTS; + } + + folder = folder_new (vuri.file); + parent->subfolders = g_slist_append (parent->subfolders, folder); + folder->parent = parent; + parent->up_to_date = FALSE; + + try_free_folder_monitors_create_unlocked (info, folder); + + /* parent changed */ + emit_monitor (parent, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_remove_directory (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + Folder *folder; + VFolderInfo *info; + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + if (vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (info->user_filename == NULL || + info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + G_LOCK (vfolder_lock); + + folder = resolve_folder (info, vuri.path, + FALSE /* ignore_basename */, + &result, context); + if (folder == NULL) { + G_UNLOCK (vfolder_lock); + return result; + } + + if (folder->read_only || + (folder->parent != NULL && + folder->parent->read_only)) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_READ_ONLY; + } + + /* don't make removing directories easy */ + if (folder->desktop_file != NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY; + } + + /* Make sure we have the entries */ + ensure_folder_unlocked (info, folder, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + + /* don't make removing directories easy */ + if (folder->entries != NULL) { + G_UNLOCK (vfolder_lock); + return GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY; + } + + emit_and_delete_monitor (info, folder); + + if (folder->only_unallocated) { + GSList *li = g_slist_find (info->unallocated_folders, + folder); + if (li != NULL) { + info->unallocated_folders = g_slist_delete_link + (info->unallocated_folders, li); + entry_unref ((Entry *)folder); + } + } + + if (folder == info->root) { + info->root = NULL; + entry_unref ((Entry *)folder); + info->root = folder_new ("Root"); + } else { + Folder *parent = folder->parent; + + g_assert (parent != NULL); + + parent->subfolders = + g_slist_remove (parent->subfolders, folder); + + parent->up_to_date = FALSE; + + entry_unref ((Entry *)folder); + + /* parent changed */ + emit_monitor (parent, GNOME_VFS_MONITOR_EVENT_CHANGED); + } + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; +} + +/* a fairly evil function that does the whole move bit by copy and + * remove */ +static GnomeVFSResult +long_move (GnomeVFSMethod *method, + VFolderURI *old_vuri, + VFolderURI *new_vuri, + gboolean force_replace, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + GnomeVFSMethodHandle *handle; + GnomeVFSURI *file_uri; + const char *path; + int fd; + char buf[BUFSIZ]; + int bytes; + VFolderInfo *info; + + info = get_vfolder_info (old_vuri->scheme, &result, context); + if (info == NULL) + return result; + + G_LOCK (vfolder_lock); + file_uri = desktop_uri_to_file_uri (info, + old_vuri, + NULL /* the_entry */, + NULL /* the_is_directory_file */, + NULL /* the_folder */, + FALSE /* privatize */, + &result, + context); + G_UNLOCK (vfolder_lock); + + if (file_uri == NULL) + return result; + + path = gnome_vfs_uri_get_path (file_uri); + if (path == NULL) { + gnome_vfs_uri_unref (file_uri); + return GNOME_VFS_ERROR_INVALID_URI; + } + + fd = open (path, O_RDONLY); + if (fd < 0) { + gnome_vfs_uri_unref (file_uri); + return gnome_vfs_result_from_errno (); + } + + gnome_vfs_uri_unref (file_uri); + + info->inhibit_write++; + + result = method->create (method, + &handle, + new_vuri->uri, + GNOME_VFS_OPEN_WRITE, + force_replace /* exclusive */, + 0600 /* perm */, + context); + if (result != GNOME_VFS_OK) { + close (fd); + info->inhibit_write--; + return result; + } + + while ((bytes = read (fd, buf, BUFSIZ)) > 0) { + GnomeVFSFileSize bytes_written = 0; + result = method->write (method, + handle, + buf, + bytes, + &bytes_written, + context); + if (result == GNOME_VFS_OK && + bytes_written != bytes) + result = GNOME_VFS_ERROR_NO_SPACE; + if (result != GNOME_VFS_OK) { + close (fd); + method->close (method, handle, context); + /* FIXME: is this completely correct ? */ + method->unlink (method, + new_vuri->uri, + context); + G_LOCK (vfolder_lock); + info->inhibit_write--; + vfolder_info_write_user (info); + G_UNLOCK (vfolder_lock); + return result; + } + } + + close (fd); + + result = method->close (method, handle, context); + if (result != GNOME_VFS_OK) { + G_LOCK (vfolder_lock); + info->inhibit_write--; + vfolder_info_write_user (info); + G_UNLOCK (vfolder_lock); + return result; + } + + result = method->unlink (method, old_vuri->uri, context); + + G_LOCK (vfolder_lock); + info->inhibit_write--; + vfolder_info_write_user (info); + G_UNLOCK (vfolder_lock); + + return result; +} + +static GnomeVFSResult +move_directory_file (VFolderInfo *info, + Folder *old_folder, + Folder *new_folder) +{ + if (old_folder->desktop_file == NULL) + return GNOME_VFS_ERROR_NOT_FOUND; + + /* "move" the desktop file */ + g_free (new_folder->desktop_file); + new_folder->desktop_file = old_folder->desktop_file; + old_folder->desktop_file = NULL; + + /* is this too drastic, it will requery the folder? */ + new_folder->up_to_date = FALSE; + old_folder->up_to_date = FALSE; + + emit_monitor (new_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + emit_monitor (old_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + + return GNOME_VFS_OK; +} + +static gboolean +is_sub (Folder *master, Folder *sub) +{ + GSList *li; + + for (li = master->subfolders; li != NULL; li = li->next) { + Folder *subfolder = li->data; + + if (subfolder == sub || + is_sub (subfolder, sub)) + return TRUE; + } + + return FALSE; +} + +static GnomeVFSResult +move_folder (VFolderInfo *info, + Folder *old_folder, Entry *old_entry, + Folder *new_folder, Entry *new_entry) +{ + Folder *source = (Folder *)old_entry; + Folder *target; + + if (new_entry != NULL && + new_entry->type != ENTRY_FOLDER) + return GNOME_VFS_ERROR_NOT_A_DIRECTORY; + + if (new_entry != NULL) { + target = (Folder *)new_entry; + } else { + target = new_folder; + } + + /* move to where we are, yay, we're done :) */ + if (source->parent == target) + return GNOME_VFS_OK; + + if (source == target || + is_sub (source, target)) + return GNOME_VFS_ERROR_LOOP; + + /* this will never happen, but we're paranoid */ + if (source->parent == NULL) + return GNOME_VFS_ERROR_LOOP; + + source->parent->subfolders = g_slist_remove (source->parent->subfolders, + source); + target->subfolders = g_slist_append (target->subfolders, + source); + + source->parent = target; + + source->up_to_date = FALSE; + target->up_to_date = FALSE; + + emit_monitor (source, GNOME_VFS_MONITOR_EVENT_CHANGED); + emit_monitor (target, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_move (GnomeVFSMethod *method, + GnomeVFSURI *old_uri, + GnomeVFSURI *new_uri, + gboolean force_replace, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + VFolderInfo *info; + Folder *old_folder, *new_folder; + Entry *old_entry, *new_entry; + gboolean old_is_directory_file, new_is_directory_file; + VFolderURI old_vuri, new_vuri; + + VFOLDER_URI_PARSE (old_uri, &old_vuri); + VFOLDER_URI_PARSE (new_uri, &new_vuri); + + if (old_vuri.file == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + if (old_vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + if (strcmp (old_vuri.scheme, new_vuri.scheme) != 0) + return GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM; + + info = get_vfolder_info (old_vuri.scheme, &result, context); + if (info == NULL) + return result; + + if (info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + old_entry = get_entry (&old_vuri, + &old_folder, + &old_is_directory_file, + &result, + context); + if (old_entry == NULL) + return result; + + if (old_folder != NULL && old_folder->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + new_entry = get_entry (&new_vuri, + &new_folder, + &new_is_directory_file, + &result, + context); + if (new_entry == NULL && new_folder == NULL) + return result; + + if (new_folder != NULL && new_folder->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + if (new_is_directory_file != old_is_directory_file) { + /* this will do another set of lookups + * perhaps this can be done in a nicer way, + * but is this the common case? I don't think so */ + return long_move (method, &old_vuri, &new_vuri, + force_replace, context); + } + + if (new_is_directory_file) { + g_assert (old_entry != NULL); + g_assert (new_entry != NULL); + G_LOCK (vfolder_lock); + result = move_directory_file (info, + (Folder *)old_entry, + (Folder *)new_entry); + G_UNLOCK (vfolder_lock); + return result; + } + + if (old_entry->type == ENTRY_FOLDER) { + G_LOCK (vfolder_lock); + result = move_folder (info, + old_folder, old_entry, + new_folder, new_entry); + G_UNLOCK (vfolder_lock); + return result; + } + + /* move into self, just whack the old one */ + if (old_entry == new_entry) { + /* same folder */ + if (new_folder == old_folder) + return GNOME_VFS_OK; + + if ( ! force_replace) + return GNOME_VFS_ERROR_FILE_EXISTS; + + G_LOCK (vfolder_lock); + + remove_file (old_folder, old_vuri.file); + + old_folder->entries = g_slist_remove (old_folder->entries, + old_entry); + entry_unref (old_entry); + + emit_monitor (old_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; + } + + /* this is a simple move */ + if (new_entry == NULL || + new_entry->type == ENTRY_FOLDER) { + if (new_entry != NULL) { + new_folder = (Folder *)new_entry; + } else { + /* a file and a totally different one */ + if (strcmp (new_vuri.file, old_entry->name) != 0) { + /* yay, a long move */ + /* this will do another set of lookups + * perhaps this can be done in a nicer way, + * but is this the common case? I don't think + * so */ + return long_move (method, &old_vuri, &new_vuri, + force_replace, context); + } + } + + /* same folder */ + if (new_folder == old_folder) + return GNOME_VFS_OK; + + G_LOCK (vfolder_lock); + + remove_file (old_folder, old_entry->name); + add_file (new_folder, old_entry->name); + + new_folder->entries = g_slist_prepend (new_folder->entries, + old_entry); + entry_ref (old_entry); + new_folder->sorted = FALSE; + + old_folder->entries = g_slist_remove (old_folder->entries, + old_entry); + entry_unref (old_entry); + + emit_monitor (new_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + emit_monitor (old_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; + } + + /* do we EVER get here? */ + + /* this will do another set of lookups + * perhaps this can be done in a nicer way, + * but is this the common case? I don't think so */ + return long_move (method, &old_vuri, &new_vuri, + force_replace, context); +} + +static GnomeVFSResult +do_unlink (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + Entry *entry; + Folder *the_folder; + gboolean is_directory_file; + VFolderInfo *info; + VFolderURI vuri; + GSList *li; + + VFOLDER_URI_PARSE (uri, &vuri); + + if (vuri.file == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + if (vuri.is_all_scheme == TRUE) + return GNOME_VFS_ERROR_READ_ONLY; + + info = get_vfolder_info (vuri.scheme, &result, context); + if (info == NULL) + return result; + else if (info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + entry = get_entry (&vuri, + &the_folder, + &is_directory_file, + &result, context); + if (entry == NULL) + return result; + else if (the_folder != NULL && + the_folder->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + if (entry->type == ENTRY_FOLDER && + is_directory_file) { + Folder *folder = (Folder *)entry; + + if (folder->desktop_file == NULL) + return GNOME_VFS_ERROR_NOT_FOUND; + + G_LOCK (vfolder_lock); + + g_free (folder->desktop_file); + folder->desktop_file = NULL; + + emit_monitor (folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; + } else if (entry->type == ENTRY_FOLDER) { + return GNOME_VFS_ERROR_IS_DIRECTORY; + } else if (the_folder == NULL) { + return GNOME_VFS_ERROR_NOT_FOUND; + } + + G_LOCK (vfolder_lock); + + the_folder->entries = g_slist_remove (the_folder->entries, + entry); + entry_unref (entry); + + remove_file (the_folder, vuri.file); + + emit_monitor (the_folder, GNOME_VFS_MONITOR_EVENT_CHANGED); + + /* evil, we must remove this from the unallocated folders as well + * so that it magically doesn't appear there. But it's not so simple. + * We only want to remove it if it isn't in that folder already. */ + for (li = info->unallocated_folders; + li != NULL; + li = li->next) { + Folder *folder = li->data; + GSList *l; + + /* This is actually really evil since ensuring + * an unallocated folder clears all other unallocated + * folders in it's wake. I'm not sure it's worth + * optimizing however */ + ensure_folder_unlocked (info, folder, + FALSE /* subfolders */, + NULL /* except */, + FALSE /* ignore_unallocated */); + l = g_slist_find (folder->entries, entry); + if (l == NULL) { + remove_file (folder, vuri.file); + } + } + + emit_file_deleted_monitor (info, entry, the_folder); + + /* FIXME: if this was a user file and this is the only + * reference to it, unlink it. */ + + vfolder_info_write_user (info); + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_check_same_fs (GnomeVFSMethod *method, + GnomeVFSURI *source_uri, + GnomeVFSURI *target_uri, + gboolean *same_fs_return, + GnomeVFSContext *context) +{ + VFolderURI source_vuri, target_vuri; + + *same_fs_return = FALSE; + + VFOLDER_URI_PARSE (source_uri, &source_vuri); + VFOLDER_URI_PARSE (target_uri, &target_vuri); + + if (strcmp (source_vuri.scheme, target_vuri.scheme) != 0 || + source_vuri.is_all_scheme != target_vuri.is_all_scheme) + *same_fs_return = FALSE; + else + *same_fs_return = TRUE; + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_set_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + const GnomeVFSFileInfo *info, + GnomeVFSSetFileInfoMask mask, + GnomeVFSContext *context) +{ + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + if (vuri.file == NULL) + return GNOME_VFS_ERROR_INVALID_URI; + + if (mask & GNOME_VFS_SET_FILE_INFO_NAME) { + GnomeVFSResult result = GNOME_VFS_OK; + char *dirname = gnome_vfs_uri_extract_dirname (uri); + GnomeVFSURI *new_uri = gnome_vfs_uri_dup (uri); + + G_LOCK (vfolder_lock); + g_free (new_uri->text); + new_uri->text = g_build_path ("/", dirname, info->name, NULL); + G_UNLOCK (vfolder_lock); + + result = do_move (method, + uri, + new_uri, + FALSE /* force_replace */, + context); + + g_free (dirname); + gnome_vfs_uri_unref (new_uri); + return result; + } else { + /* We don't support setting any of this other permission, + * times and all that voodoo */ + return GNOME_VFS_ERROR_NOT_SUPPORTED; + } +} + +static GnomeVFSResult +do_monitor_add (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle_return, + GnomeVFSURI *uri, + GnomeVFSMonitorType monitor_type) +{ + VFolderInfo *info; + VFolderURI vuri; + GnomeVFSResult result; + Folder *folder; + Entry *entry; + GnomeVFSURI *file_uri; + FileMonitorHandle *handle; + gboolean is_directory_file; + + VFOLDER_URI_PARSE (uri, &vuri); + + info = get_vfolder_info (vuri.scheme, &result, NULL); + if (info == NULL) + return result; + + if (monitor_type == GNOME_VFS_MONITOR_DIRECTORY) { + G_LOCK (vfolder_lock); + + folder = resolve_folder (info, + vuri.path, + FALSE /* ignore_basename */, + &result, + NULL); + + handle = g_new0 (FileMonitorHandle, 1); + handle->refcount = 2; + handle->uri = gnome_vfs_uri_dup (uri); + handle->dir_monitor = TRUE; + handle->handle = NULL; + handle->filename = NULL; + + if (folder == NULL) { + handle->exists = FALSE; + info->free_folder_monitors = + g_slist_prepend (info->free_folder_monitors, + handle); + } else { + handle->exists = TRUE; + ((Entry *)folder)->monitors = + g_slist_prepend (((Entry *)folder)->monitors, + handle); + } + + info->folder_monitors = + g_slist_prepend (info->folder_monitors, handle); + + G_UNLOCK (vfolder_lock); + + *method_handle_return = (GnomeVFSMethodHandle *) handle; + + return GNOME_VFS_OK; + } else { + /* These can't be very nice FILE names */ + if (vuri.file == NULL || + vuri.ends_in_slash) + return GNOME_VFS_ERROR_INVALID_URI; + + G_LOCK (vfolder_lock); + file_uri = desktop_uri_to_file_uri (info, + &vuri, + &entry, + &is_directory_file, + NULL /* the_folder */, + FALSE, + &result, + NULL); + + handle = g_new0 (FileMonitorHandle, 1); + handle->refcount = 2; + handle->uri = gnome_vfs_uri_dup (uri); + handle->dir_monitor = FALSE; + handle->handle = NULL; + handle->filename = g_strdup (vuri.file); + handle->is_directory_file = is_directory_file; + + info->file_monitors = + g_slist_prepend (info->file_monitors, handle); + + + if (file_uri == NULL) { + handle->exists = FALSE; + info->free_file_monitors = + g_slist_prepend (info->free_file_monitors, + handle); + } else { + char *uri_string = gnome_vfs_uri_to_string (file_uri, 0); + handle->exists = TRUE; + gnome_vfs_monitor_add (&(handle->handle), + uri_string, + GNOME_VFS_MONITOR_FILE, + file_monitor, + handle); + g_free (uri_string); + + entry->monitors = g_slist_prepend (entry->monitors, + handle); + gnome_vfs_uri_unref (file_uri); + } + + *method_handle_return = (GnomeVFSMethodHandle *) handle; + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; + } +} + +static GnomeVFSResult +do_monitor_cancel (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle) +{ + FileMonitorHandle *handle; + VFolderInfo *info; + VFolderURI vuri; + GnomeVFSResult result; + Folder *folder; + GSList *li; + + handle = (FileMonitorHandle *)method_handle; + + /* FIXME: is this correct? */ + if (method_handle == NULL) + return GNOME_VFS_OK; + + VFOLDER_URI_PARSE (handle->uri, &vuri); + + info = get_vfolder_info (vuri.scheme, &result, NULL); + if (info == NULL) + return result; + + if (handle->dir_monitor) { + G_LOCK (vfolder_lock); + + folder = resolve_folder (info, + vuri.path, + FALSE /* ignore_basename */, + &result, + NULL); + + for (li = info->folder_monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + if (h != handle) + continue; + info->folder_monitors = g_slist_delete_link + (info->folder_monitors, li); + file_monitor_handle_unref_unlocked (h); + break; + } + + if (folder == NULL) { + for (li = info->free_folder_monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *h = li->data; + if (h != handle) + continue; + info->free_folder_monitors = g_slist_delete_link + (info->free_folder_monitors, li); + file_monitor_handle_unref_unlocked (h); + break; + } + } else { + for (li = ((Entry *)folder)->monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *h = li->data; + if (h != handle) + continue; + ((Entry *)folder)->monitors = + g_slist_delete_link + (((Entry *)folder)->monitors, li); + file_monitor_handle_unref_unlocked (h); + break; + } + } + + G_UNLOCK (vfolder_lock); + + return GNOME_VFS_OK; + } else { + G_LOCK (vfolder_lock); + + for (li = info->file_monitors; li != NULL; li = li->next) { + FileMonitorHandle *h = li->data; + if (h != handle) + continue; + info->file_monitors = g_slist_delete_link + (info->file_monitors, li); + file_monitor_handle_unref_unlocked (h); + break; + } + + for (li = info->free_file_monitors; + li != NULL; + li = li->next) { + FileMonitorHandle *h = li->data; + if (h != handle) + continue; + info->free_file_monitors = g_slist_delete_link + (info->free_file_monitors, li); + file_monitor_handle_unref_unlocked (h); + break; + } + + for (li = info->entries; li != NULL; li = li->next) { + Entry *e = li->data; + GSList *link = g_slist_find (e->monitors, handle); + + if (link == NULL) + continue; + link->data = NULL; + e->monitors = g_slist_delete_link (e->monitors, link); + + file_monitor_handle_unref_unlocked (handle); + break; + } + + G_UNLOCK (vfolder_lock); + + /* Note: last unref of our monitor will cancel the + * underlying handle */ + + return GNOME_VFS_OK; + } +} + + +/* gnome-vfs bureaucracy */ + +static GnomeVFSMethod method = { + sizeof (GnomeVFSMethod), + do_open, + do_create, + do_close, + do_read, + do_write, + do_seek, + do_tell, + do_truncate_handle, + do_open_directory, + do_close_directory, + do_read_directory, + do_get_file_info, + do_get_file_info_from_handle, + do_is_local, + do_make_directory, + do_remove_directory, + do_move, + do_unlink, + do_check_same_fs, + do_set_file_info, + do_truncate, + NULL /* find_directory */, + NULL /* create_symbolic_link */, + do_monitor_add, + do_monitor_cancel +}; + +GnomeVFSMethod * +vfs_module_init (const char *method_name, + const char *args) +{ + parent_method = gnome_vfs_method_get ("file"); + + if (parent_method == NULL) { + g_error ("Could not find 'file' method for gnome-vfs"); + return NULL; + } + + return &method; +} + +void +vfs_module_shutdown (GnomeVFSMethod *method) +{ + if (infos == NULL) + return; + + g_hash_table_destroy (infos); + infos = NULL; +} diff --git a/modules/vfolder/Makefile.am b/modules/vfolder/Makefile.am new file mode 100644 index 0000000..c20d9f4 --- /dev/null +++ b/modules/vfolder/Makefile.am @@ -0,0 +1,95 @@ +NULL = + +INCLUDES = \ + -I$(top_srcdir) \ + -I$(top_builddir) \ + $(MODULES_XML_GCONF_CFLAGS) \ + $(MODULES_FILE_CFLAGS) \ + $(LIBEFS_CFLAGS) \ + $(VFS_CFLAGS) \ + -D_FILE_OFFSET_BITS=64 \ + -D_BSD_SOURCE \ + -D_GNU_SOURCE \ + -D_LARGEFILE64_SOURCE \ + -D_POSIX_PTHREAD_SEMANTICS \ + -D_REENTRANT \ + -DG_DISABLE_DEPRECATED \ + -DDATADIR=\"$(datadir)\" \ + -DPREFIX=\"$(prefix)\" \ + -DSYSCONFDIR=\"$(sysconfdir)\" \ + -DG_LOG_DOMAIN=\"gnome-vfs-modules\" \ + $(TESTS_INCLUDES) \ + $(NULL) + +EXTRA_DIST = \ + applications-all-users.vfolder-info.in \ + preferences-all-users.vfolder-info.in \ + favorites.vfolder-info.in \ + network.vfolder-info.in \ + start-here.vfolder-info.in \ + server-settings.vfolder-info.in \ + system-settings.vfolder-info.in \ + test-vfolder.vfolder-info.in \ + test-vfolder-parent.vfolder-info.in \ + test-vfolder-modules.conf + +### Module setup + +module_flags = -export_dynamic -avoid-version -module -no-undefined +modulesdir = $(libdir)/gnome-vfs-2.0/modules + +modules_LTLIBRARIES = libvfolder-desktop.la + +### `vfolder-desktop' method + +libvfolder_desktop_la_SOURCES = \ + vfolder-info.c \ + vfolder-util.c \ + vfolder-util.h \ + vfolder-common.c \ + vfolder-common.h \ + vfolder-method.c +libvfolder_desktop_la_LDFLAGS = $(module_flags) +libvfolder_desktop_la_LIBADD = \ + $(top_builddir)/libgnomevfs/libgnomevfs-2.la \ + $(TEST_LIBS) \ + $(MODULES_XML_LIBS) + +### Default .vfolder-info files + +vfolderdir = $(sysconfdir)/gnome-vfs-2.0/vfolders +vfolder_DATA = \ + applications-all-users.vfolder-info \ + network.vfolder-info \ + preferences-all-users.vfolder-info \ + favorites.vfolder-info \ + start-here.vfolder-info \ + server-settings.vfolder-info \ + system-settings.vfolder-info + +VFOLDER_INFO_CREATE = \ + sed -e "s,\@datadir\@,$(datadir)," \ + -e "s,\@sysconfdir\@,$(sysconfdir)," \ + -e "s,\@prefix\@,$(prefix)," \ + -e "s,\@vfolderdir\@,$(vfolderdir)," \ + < $< > $@ + +%.vfolder-info: %.vfolder-info.in + $(VFOLDER_INFO_CREATE) + +### test-vfolder regression test + +noinst_PROGRAMS = test-vfolder +noinst_DATA = test-vfolder-parent.vfolder-info test-vfolder.vfolder-info + +module_path = \ + $(top_builddir)/modules/vfolder/.libs:$(top_builddir)/modules/.libs + +TESTS_INCLUDES = \ + -DGNOME_VFS_MODULE_PATH=\"$(module_path)\" \ + -DGNOME_VFS_MODULE_CONFIG_PATH=\"$(top_srcdir)/modules/vfolder\" + +# TESTS = test-vfolder + +test_vfolder_SOURCES = test-vfolder.c +test_vfolder_LDADD = $(top_builddir)/libgnomevfs/libgnomevfs-2.la diff --git a/modules/vfolder/Makefile.in b/modules/vfolder/Makefile.in new file mode 100644 index 0000000..1ab0f88 --- /dev/null +++ b/modules/vfolder/Makefile.in @@ -0,0 +1,649 @@ +# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = ../.. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ +AS = @AS@ +AWK = @AWK@ +BONOBO_ACTIVATION_REQUIRED = @BONOBO_ACTIVATION_REQUIRED@ +BONOBO_IDLDIR = @BONOBO_IDLDIR@ +BONOBO_REQUIRED = @BONOBO_REQUIRED@ +BZ2_LIBS = @BZ2_LIBS@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +DATADIRNAME = @DATADIRNAME@ +DB2HTML = @DB2HTML@ +DLLTOOL = @DLLTOOL@ +ECHO = @ECHO@ +ENABLE_PROFILER = @ENABLE_PROFILER@ +EXEEXT = @EXEEXT@ +FAM_LIBS = @FAM_LIBS@ +GCONFTOOL = @GCONFTOOL@ +GCONF_REQUIRED = @GCONF_REQUIRED@ +GCONF_SCHEMA_CONFIG_SOURCE = @GCONF_SCHEMA_CONFIG_SOURCE@ +GCONF_SCHEMA_FILE_DIR = @GCONF_SCHEMA_FILE_DIR@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GLIB_REQUIRED = @GLIB_REQUIRED@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GNOME_ACLOCAL_DIR = @GNOME_ACLOCAL_DIR@ +GNOME_ACLOCAL_FLAGS = @GNOME_ACLOCAL_FLAGS@ +GNOME_VFS_DIR = @GNOME_VFS_DIR@ +GTKDOC = @GTKDOC@ +HAVE_GTK_DOC = @HAVE_GTK_DOC@ +HTML_DIR = @HTML_DIR@ +INSTOBJEXT = @INSTOBJEXT@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_CAVES_RULE = @INTLTOOL_CAVES_RULE@ +INTLTOOL_DESKTOP_RULE = @INTLTOOL_DESKTOP_RULE@ +INTLTOOL_DIRECTORY_RULE = @INTLTOOL_DIRECTORY_RULE@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_KEYS_RULE = @INTLTOOL_KEYS_RULE@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_OAF_RULE = @INTLTOOL_OAF_RULE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_PONG_RULE = @INTLTOOL_PONG_RULE@ +INTLTOOL_PROP_RULE = @INTLTOOL_PROP_RULE@ +INTLTOOL_SCHEMAS_RULE = @INTLTOOL_SCHEMAS_RULE@ +INTLTOOL_SERVER_RULE = @INTLTOOL_SERVER_RULE@ +INTLTOOL_SHEET_RULE = @INTLTOOL_SHEET_RULE@ +INTLTOOL_SOUNDLIST_RULE = @INTLTOOL_SOUNDLIST_RULE@ +INTLTOOL_THEME_RULE = @INTLTOOL_THEME_RULE@ +INTLTOOL_UI_RULE = @INTLTOOL_UI_RULE@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTLTOOL_XML_RULE = @INTLTOOL_XML_RULE@ +LDFLAGS = @LDFLAGS@ +LIBEFS_CFLAGS = @LIBEFS_CFLAGS@ +LIBEFS_LIBS = @LIBEFS_LIBS@ +LIBGNOMEVFS_AGE = @LIBGNOMEVFS_AGE@ +LIBGNOMEVFS_CFLAGS = @LIBGNOMEVFS_CFLAGS@ +LIBGNOMEVFS_CURRENT = @LIBGNOMEVFS_CURRENT@ +LIBGNOMEVFS_LIBS = @LIBGNOMEVFS_LIBS@ +LIBGNOMEVFS_REVISION = @LIBGNOMEVFS_REVISION@ +LIBGNUTLS_CFLAGS = @LIBGNUTLS_CFLAGS@ +LIBGNUTLS_CONFIG = @LIBGNUTLS_CONFIG@ +LIBGNUTLS_LIBS = @LIBGNUTLS_LIBS@ +LIBIDL_REQUIRED = @LIBIDL_REQUIRED@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MODULES_CFLAGS = @MODULES_CFLAGS@ +MODULES_FILE_CFLAGS = @MODULES_FILE_CFLAGS@ +MODULES_FILE_LIBS = @MODULES_FILE_LIBS@ +MODULES_GCONF_CFLAGS = @MODULES_GCONF_CFLAGS@ +MODULES_GCONF_LIBS = @MODULES_GCONF_LIBS@ +MODULES_LIBS = @MODULES_LIBS@ +MODULES_XML_CFLAGS = @MODULES_XML_CFLAGS@ +MODULES_XML_GCONF_CFLAGS = @MODULES_XML_GCONF_CFLAGS@ +MODULES_XML_GCONF_LIBS = @MODULES_XML_GCONF_LIBS@ +MODULES_XML_LIBS = @MODULES_XML_LIBS@ +MONIKERS_CFLAGS = @MONIKERS_CFLAGS@ +MONIKERS_LIBS = @MONIKERS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ORBIT_IDL = @ORBIT_IDL@ +ORBIT_REQUIRED = @ORBIT_REQUIRED@ +PACKAGE = @PACKAGE@ +PKG_CONFIG = @PKG_CONFIG@ +POFILES = @POFILES@ +POPT_LIBS = @POPT_LIBS@ +POSUB = @POSUB@ +PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ +PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ +RANLIB = @RANLIB@ +STRIP = @STRIP@ +TEST_CFLAGS = @TEST_CFLAGS@ +TEST_LIBS = @TEST_LIBS@ +TOP_BUILDDIR = @TOP_BUILDDIR@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +VFS_CFLAGS = @VFS_CFLAGS@ +VFS_INCLUDEDIR = @VFS_INCLUDEDIR@ +VFS_LIBDIR = @VFS_LIBDIR@ +VFS_LIBS = @VFS_LIBS@ +VFS_OFFSET = @VFS_OFFSET@ +VFS_OFFSET_IS = @VFS_OFFSET_IS@ +VFS_OFFSET_PRINTF = @VFS_OFFSET_PRINTF@ +VFS_SIZE = @VFS_SIZE@ +VFS_SIZE_IS = @VFS_SIZE_IS@ +VFS_SIZE_PRINTF = @VFS_SIZE_PRINTF@ +WARN_CFLAGS = @WARN_CFLAGS@ +XML_REQUIRED = @XML_REQUIRED@ +cxxflags_set = @cxxflags_set@ + +NULL = + +INCLUDES = \ + -I$(top_srcdir) \ + -I$(top_builddir) \ + $(MODULES_XML_GCONF_CFLAGS) \ + $(MODULES_FILE_CFLAGS) \ + $(LIBEFS_CFLAGS) \ + $(VFS_CFLAGS) \ + -D_FILE_OFFSET_BITS=64 \ + -D_BSD_SOURCE \ + -D_GNU_SOURCE \ + -D_LARGEFILE64_SOURCE \ + -D_POSIX_PTHREAD_SEMANTICS \ + -D_REENTRANT \ + -DG_DISABLE_DEPRECATED \ + -DDATADIR=\"$(datadir)\" \ + -DPREFIX=\"$(prefix)\" \ + -DSYSCONFDIR=\"$(sysconfdir)\" \ + -DG_LOG_DOMAIN=\"gnome-vfs-modules\" \ + $(TESTS_INCLUDES) \ + $(NULL) + + +EXTRA_DIST = \ + applications-all-users.vfolder-info.in \ + preferences-all-users.vfolder-info.in \ + favorites.vfolder-info.in \ + network.vfolder-info.in \ + start-here.vfolder-info.in \ + server-settings.vfolder-info.in \ + system-settings.vfolder-info.in \ + test-vfolder.vfolder-info.in \ + test-vfolder-parent.vfolder-info.in \ + test-vfolder-modules.conf + + +### Module setup + +module_flags = -export_dynamic -avoid-version -module -no-undefined +modulesdir = $(libdir)/gnome-vfs-2.0/modules + +modules_LTLIBRARIES = libvfolder-desktop.la + +### `vfolder-desktop' method + +libvfolder_desktop_la_SOURCES = \ + vfolder-info.c \ + vfolder-util.c \ + vfolder-util.h \ + vfolder-common.c \ + vfolder-common.h \ + vfolder-method.c + +libvfolder_desktop_la_LDFLAGS = $(module_flags) +libvfolder_desktop_la_LIBADD = \ + $(top_builddir)/libgnomevfs/libgnomevfs-2.la \ + $(TEST_LIBS) \ + $(MODULES_XML_LIBS) + + +### Default .vfolder-info files + +vfolderdir = $(sysconfdir)/gnome-vfs-2.0/vfolders +vfolder_DATA = \ + applications-all-users.vfolder-info \ + network.vfolder-info \ + preferences-all-users.vfolder-info \ + favorites.vfolder-info \ + start-here.vfolder-info \ + server-settings.vfolder-info \ + system-settings.vfolder-info + + +VFOLDER_INFO_CREATE = \ + sed -e "s,\@datadir\@,$(datadir)," \ + -e "s,\@sysconfdir\@,$(sysconfdir)," \ + -e "s,\@prefix\@,$(prefix)," \ + -e "s,\@vfolderdir\@,$(vfolderdir)," \ + < $< > $@ + + +### test-vfolder regression test + +noinst_PROGRAMS = test-vfolder +noinst_DATA = test-vfolder-parent.vfolder-info test-vfolder.vfolder-info + +module_path = \ + $(top_builddir)/modules/vfolder/.libs:$(top_builddir)/modules/.libs + + +TESTS_INCLUDES = \ + -DGNOME_VFS_MODULE_PATH=\"$(module_path)\" \ + -DGNOME_VFS_MODULE_CONFIG_PATH=\"$(top_srcdir)/modules/vfolder\" + + +# TESTS = test-vfolder + +test_vfolder_SOURCES = test-vfolder.c +test_vfolder_LDADD = $(top_builddir)/libgnomevfs/libgnomevfs-2.la +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../../config.h +CONFIG_CLEAN_FILES = +LTLIBRARIES = $(modules_LTLIBRARIES) + + +DEFS = @DEFS@ -I. -I$(srcdir) -I../.. +LIBS = @LIBS@ +libvfolder_desktop_la_DEPENDENCIES = \ +$(top_builddir)/libgnomevfs/libgnomevfs-2.la +libvfolder_desktop_la_OBJECTS = vfolder-info.lo vfolder-util.lo \ +vfolder-common.lo vfolder-method.lo +noinst_PROGRAMS = test-vfolder$(EXEEXT) +PROGRAMS = $(noinst_PROGRAMS) + +test_vfolder_OBJECTS = test-vfolder.$(OBJEXT) +test_vfolder_DEPENDENCIES = \ +$(top_builddir)/libgnomevfs/libgnomevfs-2.la +test_vfolder_LDFLAGS = +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +DATA = $(noinst_DATA) $(vfolder_DATA) + +DIST_COMMON = Makefile.am Makefile.in TODO + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +SOURCES = $(libvfolder_desktop_la_SOURCES) $(test_vfolder_SOURCES) +OBJECTS = $(libvfolder_desktop_la_OBJECTS) $(test_vfolder_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .lo .o .obj .s +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps modules/vfolder/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-modulesLTLIBRARIES: + +clean-modulesLTLIBRARIES: + -test -z "$(modules_LTLIBRARIES)" || rm -f $(modules_LTLIBRARIES) + +distclean-modulesLTLIBRARIES: + +maintainer-clean-modulesLTLIBRARIES: + +install-modulesLTLIBRARIES: $(modules_LTLIBRARIES) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(modulesdir) + @list='$(modules_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(modulesdir)/$$p"; \ + $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(modulesdir)/$$p; \ + else :; fi; \ + done + +uninstall-modulesLTLIBRARIES: + @$(NORMAL_UNINSTALL) + list='$(modules_LTLIBRARIES)'; for p in $$list; do \ + $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(modulesdir)/$$p; \ + done + +.c.o: + $(COMPILE) -c $< + +# FIXME: We should only use cygpath when building on Windows, +# and only if it is available. +.c.obj: + $(COMPILE) -c `cygpath -w $<` + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + -rm -f *.$(OBJEXT) + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +.c.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.s.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.S.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + +maintainer-clean-libtool: + +libvfolder-desktop.la: $(libvfolder_desktop_la_OBJECTS) $(libvfolder_desktop_la_DEPENDENCIES) + $(LINK) -rpath $(modulesdir) $(libvfolder_desktop_la_LDFLAGS) $(libvfolder_desktop_la_OBJECTS) $(libvfolder_desktop_la_LIBADD) $(LIBS) + +mostlyclean-noinstPROGRAMS: + +clean-noinstPROGRAMS: + -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) + +distclean-noinstPROGRAMS: + +maintainer-clean-noinstPROGRAMS: + +test-vfolder$(EXEEXT): $(test_vfolder_OBJECTS) $(test_vfolder_DEPENDENCIES) + @rm -f test-vfolder$(EXEEXT) + $(LINK) $(test_vfolder_LDFLAGS) $(test_vfolder_OBJECTS) $(test_vfolder_LDADD) $(LIBS) + +install-vfolderDATA: $(vfolder_DATA) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(vfolderdir) + @list='$(vfolder_DATA)'; for p in $$list; do \ + if test -f $(srcdir)/$$p; then \ + echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(vfolderdir)/$$p"; \ + $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(vfolderdir)/$$p; \ + else if test -f $$p; then \ + echo " $(INSTALL_DATA) $$p $(DESTDIR)$(vfolderdir)/$$p"; \ + $(INSTALL_DATA) $$p $(DESTDIR)$(vfolderdir)/$$p; \ + fi; fi; \ + done + +uninstall-vfolderDATA: + @$(NORMAL_UNINSTALL) + list='$(vfolder_DATA)'; for p in $$list; do \ + rm -f $(DESTDIR)$(vfolderdir)/$$p; \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = modules/vfolder + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +test-vfolder.o: test-vfolder.c ../../libgnomevfs/gnome-vfs.h \ + ../../libgnomevfs/gnome-vfs-async-ops.h \ + ../../libgnomevfs/gnome-vfs-file-info.h \ + ../../libgnomevfs/gnome-vfs-file-size.h \ + ../../libgnomevfs/gnome-vfs-result.h \ + ../../libgnomevfs/gnome-vfs-uri.h \ + ../../libgnomevfs/gnome-vfs-find-directory.h \ + ../../libgnomevfs/gnome-vfs-handle.h \ + ../../libgnomevfs/gnome-vfs-context.h \ + ../../libgnomevfs/gnome-vfs-cancellation.h \ + ../../libgnomevfs/gnome-vfs-xfer.h \ + ../../libgnomevfs/gnome-vfs-directory.h \ + ../../libgnomevfs/gnome-vfs-init.h \ + ../../libgnomevfs/gnome-vfs-module-callback.h \ + ../../libgnomevfs/gnome-vfs-monitor.h \ + ../../libgnomevfs/gnome-vfs-ops.h \ + ../../libgnomevfs/gnome-vfs-utils.h +vfolder-common.lo vfolder-common.o : vfolder-common.c ../../config.h \ + ../../libgnomevfs/gnome-vfs-directory.h \ + ../../libgnomevfs/gnome-vfs-file-info.h \ + ../../libgnomevfs/gnome-vfs-file-size.h \ + ../../libgnomevfs/gnome-vfs-result.h \ + ../../libgnomevfs/gnome-vfs-uri.h \ + ../../libgnomevfs/gnome-vfs-ops.h \ + ../../libgnomevfs/gnome-vfs-handle.h \ + ../../libgnomevfs/gnome-vfs-context.h \ + ../../libgnomevfs/gnome-vfs-cancellation.h \ + ../../libgnomevfs/gnome-vfs-monitor.h \ + ../../libgnomevfs/gnome-vfs-xfer.h vfolder-common.h \ + ../../libgnomevfs/gnome-vfs-method.h \ + ../../libgnomevfs/gnome-vfs-find-directory.h \ + ../../libgnomevfs/gnome-vfs-transform.h vfolder-util.h \ + ../../libgnomevfs/gnome-vfs-utils.h +vfolder-info.lo vfolder-info.o : vfolder-info.c ../../config.h \ + ../../libgnomevfs/gnome-vfs.h \ + ../../libgnomevfs/gnome-vfs-async-ops.h \ + ../../libgnomevfs/gnome-vfs-file-info.h \ + ../../libgnomevfs/gnome-vfs-file-size.h \ + ../../libgnomevfs/gnome-vfs-result.h \ + ../../libgnomevfs/gnome-vfs-uri.h \ + ../../libgnomevfs/gnome-vfs-find-directory.h \ + ../../libgnomevfs/gnome-vfs-handle.h \ + ../../libgnomevfs/gnome-vfs-context.h \ + ../../libgnomevfs/gnome-vfs-cancellation.h \ + ../../libgnomevfs/gnome-vfs-xfer.h \ + ../../libgnomevfs/gnome-vfs-directory.h \ + ../../libgnomevfs/gnome-vfs-init.h \ + ../../libgnomevfs/gnome-vfs-module-callback.h \ + ../../libgnomevfs/gnome-vfs-monitor.h \ + ../../libgnomevfs/gnome-vfs-ops.h \ + ../../libgnomevfs/gnome-vfs-utils.h \ + ../../libgnomevfs/gnome-vfs-monitor-private.h \ + ../../libgnomevfs/gnome-vfs-method.h \ + ../../libgnomevfs/gnome-vfs-transform.h vfolder-common.h \ + vfolder-util.h +vfolder-method.lo vfolder-method.o : vfolder-method.c ../../config.h \ + ../../libgnomevfs/gnome-vfs-cancellable-ops.h \ + ../../libgnomevfs/gnome-vfs-directory.h \ + ../../libgnomevfs/gnome-vfs-file-info.h \ + ../../libgnomevfs/gnome-vfs-file-size.h \ + ../../libgnomevfs/gnome-vfs-result.h \ + ../../libgnomevfs/gnome-vfs-uri.h \ + ../../libgnomevfs/gnome-vfs-find-directory.h \ + ../../libgnomevfs/gnome-vfs-handle.h \ + ../../libgnomevfs/gnome-vfs-context.h \ + ../../libgnomevfs/gnome-vfs-cancellation.h \ + ../../libgnomevfs/gnome-vfs-xfer.h \ + ../../libgnomevfs/gnome-vfs-module.h \ + ../../libgnomevfs/gnome-vfs-method.h \ + ../../libgnomevfs/gnome-vfs-transform.h \ + ../../libgnomevfs/gnome-vfs-monitor.h \ + ../../libgnomevfs/gnome-vfs-ops.h \ + ../../libgnomevfs/gnome-vfs-utils.h \ + ../../libgnomevfs/gnome-vfs-private-utils.h \ + ../../libgnomevfs/gnome-vfs-process.h vfolder-common.h \ + vfolder-util.h +vfolder-util.lo vfolder-util.o : vfolder-util.c ../../config.h \ + ../../libgnomevfs/gnome-vfs-file-info.h \ + ../../libgnomevfs/gnome-vfs-file-size.h \ + ../../libgnomevfs/gnome-vfs-result.h \ + ../../libgnomevfs/gnome-vfs-uri.h \ + ../../libgnomevfs/gnome-vfs-ops.h \ + ../../libgnomevfs/gnome-vfs-handle.h \ + ../../libgnomevfs/gnome-vfs-context.h \ + ../../libgnomevfs/gnome-vfs-cancellation.h \ + ../../libgnomevfs/gnome-vfs-monitor.h vfolder-util.h \ + ../../libgnomevfs/gnome-vfs-utils.h vfolder-common.h \ + ../../libgnomevfs/gnome-vfs-method.h \ + ../../libgnomevfs/gnome-vfs-find-directory.h \ + ../../libgnomevfs/gnome-vfs-transform.h + +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: +install-exec: install-exec-am + +install-data-am: install-modulesLTLIBRARIES install-vfolderDATA +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-modulesLTLIBRARIES uninstall-vfolderDATA +uninstall: uninstall-am +all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(DATA) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(modulesdir) $(DESTDIR)$(vfolderdir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-modulesLTLIBRARIES mostlyclean-compile \ + mostlyclean-libtool mostlyclean-noinstPROGRAMS \ + mostlyclean-tags mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-modulesLTLIBRARIES clean-compile clean-libtool \ + clean-noinstPROGRAMS clean-tags clean-generic \ + mostlyclean-am + +clean: clean-am + +distclean-am: distclean-modulesLTLIBRARIES distclean-compile \ + distclean-libtool distclean-noinstPROGRAMS \ + distclean-tags distclean-generic clean-am + -rm -f libtool + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-modulesLTLIBRARIES \ + maintainer-clean-compile maintainer-clean-libtool \ + maintainer-clean-noinstPROGRAMS maintainer-clean-tags \ + maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: mostlyclean-modulesLTLIBRARIES distclean-modulesLTLIBRARIES \ +clean-modulesLTLIBRARIES maintainer-clean-modulesLTLIBRARIES \ +uninstall-modulesLTLIBRARIES install-modulesLTLIBRARIES \ +mostlyclean-compile distclean-compile clean-compile \ +maintainer-clean-compile mostlyclean-libtool distclean-libtool \ +clean-libtool maintainer-clean-libtool mostlyclean-noinstPROGRAMS \ +distclean-noinstPROGRAMS clean-noinstPROGRAMS \ +maintainer-clean-noinstPROGRAMS uninstall-vfolderDATA \ +install-vfolderDATA tags mostlyclean-tags distclean-tags clean-tags \ +maintainer-clean-tags distdir info-am info dvi-am dvi check check-am \ +installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +%.vfolder-info: %.vfolder-info.in + $(VFOLDER_INFO_CREATE) + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/modules/vfolder/TODO b/modules/vfolder/TODO new file mode 100644 index 0000000..0019cc7 --- /dev/null +++ b/modules/vfolder/TODO @@ -0,0 +1,31 @@ + +STUFF TO DO +=========== + +X keywords aren't being pulled from itemdir files. bug in + entry_quick_read_keys? + +X all pool files are read on startup. should load when get_keywords is called. + +X filename uniqueness mess... need use a unique name when writing user-private + files, but need to present the non-unique name to apps. use a special vfolder + postfix filename probably. + +X all-applications doesn't work. probably need to use the pool files from +.vfolder-info, and add an all-applications-all-users (ick) method. + +X ensure ~/.gnome2/vfolders exists before writing config file + +X ensure ~/.gnome2/vfolders// dir exists before writing user-private + changes + +X dir files list duplicates of regularly listed entries, + because the alloc count is not correct for folders that are not yet loaded. + +Directory VFolderMonitors relying on stat() (and not FAM) will not pick up new +files. + +Add GConf keys for getting .vfolder-info file to use for a given +scheme (puntable). + +Support set/get_file_info of read-only permissions on folders? \ No newline at end of file diff --git a/modules/vfolder/applications-all-users.vfolder-info.in b/modules/vfolder/applications-all-users.vfolder-info.in new file mode 100644 index 0000000..ff1bb42 --- /dev/null +++ b/modules/vfolder/applications-all-users.vfolder-info.in @@ -0,0 +1,209 @@ + + + @vfolderdir@/applications-all-users/ + + + @datadir@/applications/ + + + /usr/share/applications/ + + + @datadir@/gnome/vfolders/ + + + /usr/share/gnome/ximian/Programs/ + + + @datadir@/gnome/apps/ + /usr/share/gnome/apps/ + + + /etc/X11/applnk/ + + + + Applications + Applications.directory + + gnome-search-tool.desktop + Gmc.desktop + nautilus-help.desktop + gnome-help.desktop + + + + Core + + + + + + + + Accessories + Accessories.directory + + + Application + Utility + + System + + + + + + + + + Accessibility + Accessibility.directory + + + Application + Accessibility + + Settings + + + + + + + + + Other + Other.directory + + + + Application + + Settings + + + + + vumeter.desktop + reclevel.desktop + gnome-search-tool.desktop + gnomecc.desktop + + + + + + + Programming + Development.directory + + + Application + Development + + + + + + + + Games + Games.directory + + + Application + Game + + + + + + + + Graphics + Graphics.directory + + + Application + Graphics + + + + + + + + Internet + Internet.directory + + + Application + Network + + + + + + + + Multimedia + Multimedia.directory + + + Application + AudioVideo + + + + vumeter.desktop + reclevel.desktop + + + + + + + Office + Office.directory + + + Application + + Office + Spreadsheet + WordProcessor + Calendar + ProjectManagement + + + + + + + + + Preferences + preferences:/// + + + + + System + System.directory + + + Application + + Settings + + System + + + + + + + diff --git a/modules/vfolder/favorites.vfolder-info.in b/modules/vfolder/favorites.vfolder-info.in new file mode 100644 index 0000000..a7c4415 --- /dev/null +++ b/modules/vfolder/favorites.vfolder-info.in @@ -0,0 +1,6 @@ + + + Favorites + ~/.gnome/apps + + diff --git a/modules/vfolder/network.vfolder-info.in b/modules/vfolder/network.vfolder-info.in new file mode 100644 index 0000000..e4333bd --- /dev/null +++ b/modules/vfolder/network.vfolder-info.in @@ -0,0 +1,17 @@ + + + ~/.gnome2/vfolders/network/ + + + + @datadir@/gnome/network/ + Network Shares + + + Merged + + + + + + diff --git a/modules/vfolder/preferences-all-users.vfolder-info.in b/modules/vfolder/preferences-all-users.vfolder-info.in new file mode 100644 index 0000000..e09a8b4 --- /dev/null +++ b/modules/vfolder/preferences-all-users.vfolder-info.in @@ -0,0 +1,100 @@ + + + @vfolderdir@/preferences-all-users/ + + + @datadir@/control-center-2.0/capplets/ + + + @datadir@/gnome/apps/Settings + @datadir@/gnome/capplets + + @datadir@/gnome/vfolders + + + + Preferences + Settings.directory + + + Settings + + + AdvancedSettings + Sawfish + X-GNOME-Sawfish + System + Accessibility + Merged + + + + + + gnomecc.desktop + + + Advanced + Advanced.directory + + + + Settings + Merged + + + Settings + AdvancedSettings + + + Sawfish + X-GNOME-Sawfish + + + + + + + + + Sawfish + Sawfish.directory + + + + Sawfish + X-GNOME-Sawfish + + Settings + + + + + + + + Accessibility + Accessibility.directory + + + Settings + Accessibility + + + + + + + System + System.directory + + + System + Settings + + + + + + + diff --git a/modules/vfolder/server-settings.vfolder-info.in b/modules/vfolder/server-settings.vfolder-info.in new file mode 100644 index 0000000..38e0ba5 --- /dev/null +++ b/modules/vfolder/server-settings.vfolder-info.in @@ -0,0 +1,6 @@ + + + Server Settings + @sysconfdir@/X11/serverconfig + + diff --git a/modules/vfolder/start-here.vfolder-info.in b/modules/vfolder/start-here.vfolder-info.in new file mode 100644 index 0000000..e129cf6 --- /dev/null +++ b/modules/vfolder/start-here.vfolder-info.in @@ -0,0 +1,6 @@ + + + Start Here + @sysconfdir@/X11/starthere + + diff --git a/modules/vfolder/system-settings.vfolder-info.in b/modules/vfolder/system-settings.vfolder-info.in new file mode 100644 index 0000000..991828b --- /dev/null +++ b/modules/vfolder/system-settings.vfolder-info.in @@ -0,0 +1,6 @@ + + + System Settings + @sysconfdir@/X11/sysconfig + + diff --git a/modules/vfolder/test-vfolder-modules.conf b/modules/vfolder/test-vfolder-modules.conf new file mode 100644 index 0000000..6da02dd --- /dev/null +++ b/modules/vfolder/test-vfolder-modules.conf @@ -0,0 +1,3 @@ + +test-vfolder: vfolder-desktop +test-vfolder-parent: vfolder-desktop diff --git a/modules/vfolder/test-vfolder-parent.vfolder-info.in b/modules/vfolder/test-vfolder-parent.vfolder-info.in new file mode 100644 index 0000000..b466ee6 --- /dev/null +++ b/modules/vfolder/test-vfolder-parent.vfolder-info.in @@ -0,0 +1,14 @@ + + + Top Folder + + + EmptyFolder + + + + EmptyHiddenFolder + + + + \ No newline at end of file diff --git a/modules/vfolder/test-vfolder.c b/modules/vfolder/test-vfolder.c new file mode 100644 index 0000000..93fb131 --- /dev/null +++ b/modules/vfolder/test-vfolder.c @@ -0,0 +1,529 @@ + +#include +#include +#include +#include +#include + +static gboolean +check_dir_exists (gchar *file_uri) +{ + GnomeVFSDirectoryHandle *handle; + GnomeVFSResult result; + + result = gnome_vfs_directory_open (&handle, + file_uri, + GNOME_VFS_FILE_INFO_DEFAULT); + if (result == GNOME_VFS_OK) { + gnome_vfs_directory_close (handle); + return TRUE; + } else + return FALSE; +} + +#if 0 +static gint +check_dir_count (gchar *file_uri) +{ + GnomeVFSResult result; + GList *files; + gint retval; + + result = gnome_vfs_directory_list_load (&files, + file_uri, + GNOME_VFS_FILE_INFO_DEFAULT); + if (result != GNOME_VFS_OK) + return FALSE; + + retval = g_list_length (files); + + gnome_vfs_file_info_list_free (files); + + return retval; +} +#endif + +static gboolean +check_file_exists (gchar *file_uri) +{ + GnomeVFSHandle *handle; + GnomeVFSResult result; + + result = gnome_vfs_open (&handle, + file_uri, + GNOME_VFS_OPEN_READ); + if (result == GNOME_VFS_OK) { + gnome_vfs_close (handle); + return TRUE; + } else + return FALSE; +} + +static gboolean +check_file_content (gchar *file_uri, gchar *content) +{ + GnomeVFSHandle *handle; + GnomeVFSResult result; + GnomeVFSFileSize readlen; + gchar readbuf [2048]; + gint idx = 0, len; + + len = strlen (content); + + result = gnome_vfs_open (&handle, + file_uri, + GNOME_VFS_OPEN_READ); + if (result != GNOME_VFS_OK) + return FALSE; + + while (idx < len) { + result = gnome_vfs_read (handle, + readbuf, + sizeof (readbuf), + &readlen); + if (result != GNOME_VFS_OK) + goto ERROR; + + idx += readlen; + if (idx > len) + goto ERROR; + + if (memcmp (readbuf, + &content [idx], + MIN (len - idx, readlen)) != 0) + goto ERROR; + } + + gnome_vfs_close (handle); + return TRUE; + + ERROR: + gnome_vfs_close (handle); + return FALSE; +} + +#define TEST_FAILURE(errstr) \ + do { \ + g_print (" " errstr ": %s\n", \ + gnome_vfs_result_to_string (result)); \ + return 1; \ + } while (0) + +#define TEST_SUCCESS g_print (" DONE.\n") + +#define TEST_RESULT(predicate, error) \ + if (predicate) TEST_FAILURE (error); \ + else TEST_SUCCESS + +static gint +test_vfolder_ops (void) +{ + GnomeVFSHandle *handle; + GnomeVFSDirectoryHandle *dhandle; + GnomeVFSResult result; + gchar *uri, *realuri, *content; + GnomeVFSFileSize writelen; + + uri = "test-vfolder:///"; + g_print ("Opening %s...\n", uri); + result = gnome_vfs_directory_open (&dhandle, + uri, + GNOME_VFS_FILE_INFO_DEFAULT); + TEST_RESULT (result != GNOME_VFS_OK, "ERROR OPENNING"); + + /* + * Directory Tests + */ + + /* + * TEST 1: + * Create a new directory and delete it + */ + /* Simple directory create */ + uri = "test-vfolder:///MyTestFolder1"; + g_print ("Creating new directory..."); + result = gnome_vfs_make_directory (uri, GNOME_VFS_PERM_USER_ALL); + TEST_RESULT (result != GNOME_VFS_OK || !check_dir_exists (uri), + "ERROR CREATING DIR"); + + /* Simple directory delete */ + uri = "test-vfolder:///MyTestFolder1"; + g_print ("Deleting new empty directory..."); + result = gnome_vfs_remove_directory (uri); + TEST_RESULT (result != GNOME_VFS_OK || check_dir_exists (uri), + "ERROR DELETING DIR"); + + + /* + * TEST 2: + * Create a new directory, add a file to it, check file exists, + * check we can't delete a non-empty dir, delete file, then delete + * directory. + */ + /* Simple Create 2 */ + uri = "test-vfolder:///MyTestFolder2/"; + g_print ("Creating new directory..."); + result = gnome_vfs_make_directory (uri, GNOME_VFS_PERM_USER_ALL); + TEST_RESULT (result != GNOME_VFS_OK || !check_dir_exists (uri), + "ERROR CREATING DIR"); + + /* Create Empty File */ + uri = "test-vfolder:///MyTestFolder2/a_fake_file.desktop"; + g_print ("Creating new file..."); + result = gnome_vfs_create (&handle, + uri, + GNOME_VFS_OPEN_READ | GNOME_VFS_OPEN_WRITE, + FALSE, + GNOME_VFS_PERM_USER_ALL); + TEST_RESULT (result != GNOME_VFS_OK || + !check_file_exists (uri) || + !check_file_content (uri, ""), + "ERROR CREATING FILE"); + + /* Try removing dir (should fail) */ + uri = "test-vfolder:///MyTestFolder2"; + g_print ("Deleting new non-empty directory..."); + result = gnome_vfs_remove_directory (uri); + TEST_RESULT (result != GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY || + !check_dir_exists (uri), + "ERROR DELETING DIR"); + + /* Delete file */ + uri = "test-vfolder:///MyTestFolder2/a_fake_file.desktop"; + g_print ("Deleting new file..."); + result = gnome_vfs_unlink (uri); + TEST_RESULT (result != GNOME_VFS_OK || check_file_exists (uri), + "ERROR DELETING FILE"); + + /* Try removing dir */ + uri = "test-vfolder:///MyTestFolder2/"; + g_print ("Deleting new empty directory..."); + result = gnome_vfs_remove_directory (uri); + TEST_RESULT (result != GNOME_VFS_OK || check_dir_exists (uri), + "ERROR DELETING DIR"); + + + /* + * TEST 3: + * Check creating an existing directory fails. Only run during first + * iteration. + */ + /* Try to create existing empty dir (should fail) */ + uri = "test-vfolder:///EmptyFolder"; + if (check_dir_exists (uri)) { + g_print ("Creating existing empty directory..."); + result = gnome_vfs_make_directory (uri, + GNOME_VFS_PERM_USER_ALL); + TEST_RESULT (result != GNOME_VFS_ERROR_FILE_EXISTS, + "ABLE TO CREATE EXISTING DIR"); + + /* Try to delete existing empty dir */ + g_print ("Deleting existing empty directory..."); + result = gnome_vfs_remove_directory (uri); + TEST_RESULT (result != GNOME_VFS_OK || check_dir_exists (uri), + "ERROR DELETING DIR"); + } + + /* + * TEST 4: + * Check we can't delete an existing hidden directory, check we can't + * add a file to an existing hidden directory, check we can create the + * existing hidden directory, create a file in now non-hidden dir, + * delete created file and check dir is still visible, delete dir. + */ + /* First, see if its hidden */ + uri = "test-vfolder:///EmptyHiddenFolder"; + g_print ("Checking if hidden directory is visible ..."); + TEST_RESULT (check_dir_exists (uri), + "ABLE TO SEE HIDDEN DIR"); + + /* Try to delete existing empty hidden dir (should fail) */ + uri = "test-vfolder:///EmptyHiddenFolder"; + g_print ("Deleting existing empty hidden directory..."); + result = gnome_vfs_remove_directory (uri); + TEST_RESULT (result == GNOME_VFS_OK || check_dir_exists (uri), + "ABLE TO DELETE HIDDEN DIR"); + + /* Try to add file to existing empty hidden dir (should fail) */ + uri = "test-vfolder:///EmptyHiddenFolder/a_fake_file.desktop"; + g_print ("Creating file in existing empty hidden directory..."); + result = gnome_vfs_create (&handle, + uri, + GNOME_VFS_OPEN_WRITE, + FALSE, + GNOME_VFS_PERM_USER_ALL); + TEST_RESULT (result == GNOME_VFS_OK || check_dir_exists (uri), + "ABLE TO CREATE FILE IN HIDDEN DIR"); + + /* Try to create existing empty hidden dir */ + uri = "test-vfolder:///EmptyHiddenFolder"; + g_print ("Deleting existing empty hidden directory..."); + result = gnome_vfs_make_directory (uri, GNOME_VFS_PERM_USER_ALL); + TEST_RESULT (result != GNOME_VFS_OK || !check_dir_exists (uri), + "ERROR OVERRIDING HIDDEN DIR"); + + /* Try to add file to existing empty (now) non-hidden dir */ + uri = "test-vfolder:///EmptyHiddenFolder/a_fake_file.desktop"; + g_print ("Creating file in existing empty hidden directory..."); + result = gnome_vfs_create (&handle, + uri, + GNOME_VFS_OPEN_WRITE, + FALSE, + GNOME_VFS_PERM_USER_ALL); + TEST_RESULT (result != GNOME_VFS_OK || !check_file_exists (uri), + "ERROR CREATING FILE IN DIR"); + + /* Try to delete existing empty hidden dir */ + uri = "test-vfolder:///EmptyHiddenFolder"; + g_print ("Deleting existing empty hidden directory..."); + result = gnome_vfs_remove_directory (uri); + TEST_RESULT (result == GNOME_VFS_OK || !check_dir_exists (uri), + "ABLE TO DELETE NON-EMPTY FOLDER"); + + /* Try to delete the file we created */ + uri = "test-vfolder:///EmptyHiddenFolder/a_fake_file.desktop"; + g_print ("Deleting created file..."); + result = gnome_vfs_unlink (uri); + TEST_RESULT (result != GNOME_VFS_OK || check_file_exists (uri), + "ERROR DELETING FILE"); + + /* Try to delete the directory */ + uri = "test-vfolder:///EmptyHiddenFolder"; + g_print ("Deleting overridden directory..."); + result = gnome_vfs_remove_directory (uri); + TEST_RESULT (result != GNOME_VFS_OK || check_dir_exists (uri), + "ERROR DELETING DIR"); + + /* + * TEST 5: + * Add file to writedir with keywords, check presence in non-hidden + * folder, check presence in previsouly hidden folder, delete file, + * check it is not present in non-hidden folder, and check that the + * hidden folder is back to being not visible + */ + /* Create file with keywords, check visibility */ + realuri = g_build_filename (getenv ("GNOME_VFS_VFOLDER_WRITEDIR"), + "test-vfolder", + "my_keyworded_file.desktop", + NULL); + g_print ("Creating file in writedir to check keyword inclusion..."); + result = gnome_vfs_create (&handle, + realuri, + GNOME_VFS_OPEN_WRITE, + FALSE, + GNOME_VFS_PERM_USER_ALL); + TEST_RESULT (result != GNOME_VFS_OK, "ERROR CREATING FILE IN WRITEDIR"); + + content = "Categories=FakeCategory1;FakeCategory2;FakeCategory3\n\n"; + g_print ("Writing content..."); + result = gnome_vfs_write (handle, + content, + strlen (content), + &writelen); + TEST_RESULT (result != GNOME_VFS_OK, "ERROR WRITING FILE IN WRITEDIR"); + + g_print ("Closing file..."); + result = gnome_vfs_close (handle); + TEST_RESULT (result != GNOME_VFS_OK, "ERROR CLOSING FILE"); + + uri = "test-vfolder:///KeywordFolder/my_keyworded_file.desktop"; + g_print ("Checking file presence in /KeywordFolder/..."); + TEST_RESULT (!check_file_content (uri, content), + "KEYWORDED FILE NOT PRESENT"); + + uri = "test-vfolder:///EmptyHiddenFolder"; + g_print ("Checking /EmptyHiddenFolder/ is now visible..."); + TEST_RESULT (!check_dir_exists (uri), + "HIDDEN DIRECTORY NOT VISIBLE"); + + uri = "test-vfolder:///EmptyHiddenFolder/my_keyworded_file.desktop"; + g_print ("Checking file presence in /EmptyHiddenFolder/..."); + TEST_RESULT (!check_file_content (uri, content), + "KEYWORDED FILE NOT PRESENT IN HIDDEN DIRECTORY"); + + g_print ("Deleting new file from writedir..."); + result = gnome_vfs_unlink (realuri); + TEST_RESULT (result != GNOME_VFS_OK || !check_file_exists (realuri), + "ERROR DELETING FILE"); + + uri = "test-vfolder:///KeywordFolder/my_keyworded_file.desktop"; + g_print ("Checking file is missing from /KeywordFolder/..."); + TEST_RESULT (check_file_exists (uri), + "KEYWORDED FILE STILL PRESENT"); + + uri = "test-vfolder:///EmptyHiddenFolder"; + g_print ("Checking /EmptyHiddenFolder/ is hidden again..."); + TEST_RESULT (check_dir_exists (uri), + "HIDDEN DIRECTORY STILL VISIBLE"); + + g_free (realuri); + + + /* + * TEST 6: + * Create file and move to a different directory. + */ + uri = "test-vfolder:///MyTestFolder1"; + g_print ("Creating src directory..."); + result = gnome_vfs_make_directory (uri, GNOME_VFS_PERM_USER_ALL); + TEST_RESULT (result != GNOME_VFS_OK || !check_dir_exists (uri), + "ERROR CREATING DIR"); + + uri = "test-vfolder:///MyTestFolder1/a_fake_file.desktop"; + g_print ("Creating src file..."); + result = gnome_vfs_create (&handle, + uri, + GNOME_VFS_OPEN_WRITE, + FALSE, + GNOME_VFS_PERM_USER_ALL); + TEST_RESULT (result != GNOME_VFS_OK || !check_file_exists (uri), + "ERROR CREATING FILE"); + + uri = "test-vfolder:///MyTestFolder2"; + g_print ("Creating dest directory..."); + result = gnome_vfs_make_directory (uri, GNOME_VFS_PERM_USER_ALL); + TEST_RESULT (result != GNOME_VFS_OK || !check_dir_exists (uri), + "ERROR CREATING DIR"); + + g_print ("Moving dir..."); + result = gnome_vfs_move ("test-vfolder:///MyTestFolder1", + "test-vfolder:///MyTestFolder2/MyButt", + TRUE); + TEST_RESULT (result != GNOME_VFS_OK || + !check_dir_exists ("test-vfolder:///MyTestFolder2/MyButt") || + check_dir_exists ("test-vfolder:///MyTestFolder1"), + "ERROR MOVING DIR"); + + g_print ("Moving file..."); + result = gnome_vfs_move ("test-vfolder:///MyTestFolder2/MyButt/a_fake_file.desktop", + "test-vfolder:///MyTestFolder2", + TRUE); + TEST_RESULT (result != GNOME_VFS_OK || + !check_file_exists ("test-vfolder:///MyTestFolder2/a_fake_file.desktop") || + check_file_exists ("test-vfolder:///MyTestFolder2/MyButt/a_fake_file.desktop"), + "ERROR MOVING FILE"); + + uri = "test-vfolder:///MyTestFolder2/a_fake_file.desktop"; + g_print ("Deleting dest file..."); + result = gnome_vfs_unlink (uri); + TEST_RESULT (result != GNOME_VFS_OK || check_file_exists (uri), + "ERROR DELETING FILE"); + + /* Leave these around for future tests */ + /* + uri = "test-vfolder:///MyTestFolder1"; + g_print ("Deleting src directory..."); + result = gnome_vfs_remove_directory (uri); + TEST_RESULT (result != GNOME_VFS_OK || check_dir_exists (uri), + "ERROR DELETING DIR"); + + uri = "test-vfolder:///MyTestFolder2"; + g_print ("Deleting dest directory..."); + result = gnome_vfs_remove_directory (uri); + TEST_RESULT (result != GNOME_VFS_OK || check_dir_exists (uri), + "ERROR DELETING DIR"); + */ + + /* + * TEST 7: + * Create file and rename. + */ + uri = "test-vfolder:///MyTestFolder1/a_file_to_rename.desktop"; + g_print ("Creating file..."); + result = gnome_vfs_create (&handle, + uri, + GNOME_VFS_OPEN_WRITE, + FALSE, + GNOME_VFS_PERM_USER_ALL); + TEST_RESULT (result != GNOME_VFS_OK || check_file_exists (uri), + "ERROR CREATING FILE"); + + { + GnomeVFSFileInfo info; + gchar *desturi; + + info.name = "a_renamed_file.desktop"; + + g_print ("Renaming file..."); + result = gnome_vfs_set_file_info (uri, + &info, + GNOME_VFS_SET_FILE_INFO_NAME); + desturi = + "test-vfolder:///MyTestFolder1/a_renamed_file.desktop"; + TEST_RESULT (result != GNOME_VFS_OK || + check_file_exists (uri) || + !check_file_exists (desturi), + "ERROR RENAMING FILE"); + } + + /* + * TEST 8: + * Move new directory inside another directory. + */ + + /* + * TEST 9: + * Move existing directory with children inside a new directory. + */ + + // create dir + // delete new dir + // delete existing dir + + // create file + // create file with keywords, check appearance in vfolders + // edit new file + // edit existing file + // move new file + // move existing file + // set filename new file + // set filename existing file + // delete new file + // delete existing file + + // monitor file creation + // monitor file edit + // monitor file delete + // monitor dir creation + // monitor dir delete + + return 0; +} + +int +main (int argc, char **argv) +{ + gint iterations = 10; + gchar *cwd, cwdbuf [2048], *path; + + putenv ("GNOME_VFS_MODULE_PATH=" GNOME_VFS_MODULE_PATH); + putenv ("GNOME_VFS_MODULE_CONFIG_PATH=" GNOME_VFS_MODULE_CONFIG_PATH); + + cwd = getcwd (cwdbuf, sizeof (cwdbuf)); + + putenv (g_strconcat ("GNOME_VFS_VFOLDER_INFODIR=", cwd, NULL)); + + path = g_build_filename (cwd, "test-vfolder-tmp", NULL); + putenv (g_strconcat ("GNOME_VFS_VFOLDER_WRITEDIR=", path, NULL)); + g_free (path); + + gnome_vfs_init (); + + if (argc > 1) + iterations = atoi (argv [1]); + + do { + if (test_vfolder_ops () != 0) { + g_print ("\nFAILURE!!\n"); + gnome_vfs_shutdown (); + return 1; + } + g_print ("\n\n"); + } while (--iterations); + + gnome_vfs_shutdown (); + + g_print ("\nSUCCESS!\n"); + + return 0; +} diff --git a/modules/vfolder/test-vfolder.vfolder-info.in b/modules/vfolder/test-vfolder.vfolder-info.in new file mode 100644 index 0000000..122daa9 --- /dev/null +++ b/modules/vfolder/test-vfolder.vfolder-info.in @@ -0,0 +1,32 @@ + + + + + Top Folder + test-vfolder-parent:/// + + + EmptyFolder + + + + EmptyHiddenFolder + + + + + EmptyParentedFolder + test-vfolder-parent:///EmptyFolder + + + + EmptyHiddenParentedFolder + test-vfolder-parent:///EmptyHiddenFolder + + + + BadlyParentedFolder + test-vfolder-parent:///FolderThatDoesntExist + + + diff --git a/modules/vfolder/vfolder-common.c b/modules/vfolder/vfolder-common.c new file mode 100644 index 0000000..26dbe42 --- /dev/null +++ b/modules/vfolder/vfolder-common.c @@ -0,0 +1,1743 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* + * vfolder-common.c - Implementation of abstract Folder, Entry, and Query + * interfaces. + * + * Copyright (C) 2002 Ximian, Inc. + * + * The Gnome Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Gnome Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Alex Graveley + * Based on original code by George Lebl . + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include +#include +#include +#include + +#include "vfolder-common.h" + + +/* + * Entry Implementation + */ +Entry * +entry_new (VFolderInfo *info, + const gchar *filename, + const gchar *displayname, + gboolean user_private, + gushort weight) +{ + Entry *entry; + + entry = g_new0 (Entry, 1); + entry->refcnt = 1; + entry->allocs = 0; + entry->info = info; + entry->filename = g_strdup (filename); + entry->displayname = g_strdup (displayname); + entry->user_private = user_private; + entry->weight = weight; + + entry->dirty = TRUE; + entry->not_shown = FALSE; + + /* + * Lame-O special case .directory handling, as we don't want them + * showing up for all-applications:///. + */ + if (strcmp (displayname, ".directory") != 0) + vfolder_info_add_entry (info, entry); + + return entry; +} + +void +entry_ref (Entry *entry) +{ + entry->refcnt++; +} + +void +entry_unref (Entry *entry) +{ + entry->refcnt--; + + if (entry->refcnt == 0) { + D (g_print ("-- KILLING ENTRY: (%p) %s---\n", + entry, + entry->displayname)); + + vfolder_info_remove_entry (entry->info, entry); + + g_free (entry->filename); + g_free (entry->displayname); + g_slist_free (entry->keywords); + g_slist_free (entry->implicit_keywords); + g_free (entry); + } +} + +void +entry_alloc (Entry *entry) +{ + entry->allocs++; +} + +void +entry_dealloc (Entry *entry) +{ + entry->allocs--; +} + +gboolean +entry_is_allocated (Entry *entry) +{ + return entry->allocs > 0; +} + +gboolean +entry_make_user_private (Entry *entry, Folder *folder) +{ + GnomeVFSURI *src_uri, *dest_uri; + GnomeVFSResult result; + gchar *uniqname, *filename; + + if (entry->user_private) + return TRUE; + + /* Don't write privately if folder is link */ + if (folder->is_link) + return TRUE; + + /* Need a writedir, otherwise just modify the original */ + if (!entry->info->write_dir) + return TRUE; + + /* Need a filename to progress further */ + if (!entry_get_filename (entry)) + return FALSE; + + /* Make sure the destination directory exists */ + result = vfolder_make_directory_and_parents (entry->info->write_dir, + FALSE, + 0700); + if (result != GNOME_VFS_OK) + return FALSE; + + /* + * Add a timestamp to the filename since we don't want conflicts between + * files in different logical folders with the same filename. + */ + uniqname = vfolder_timestamp_file_name (entry_get_displayname (entry)); + filename = vfolder_build_uri (entry->info->write_dir, uniqname, NULL); + g_free (uniqname); + + src_uri = entry_get_real_uri (entry); + dest_uri = gnome_vfs_uri_new (filename); + + result = gnome_vfs_xfer_uri (src_uri, + dest_uri, + GNOME_VFS_XFER_USE_UNIQUE_NAMES, + GNOME_VFS_XFER_ERROR_MODE_ABORT, + GNOME_VFS_XFER_OVERWRITE_MODE_ABORT, + NULL, + NULL); + + gnome_vfs_uri_unref (src_uri); + gnome_vfs_uri_unref (dest_uri); + + if (result == GNOME_VFS_OK) { + if (!strcmp (entry_get_displayname (entry), ".directory")) { + folder_set_desktop_file (folder, filename); + } else { + /* Exclude current displayname. */ + folder_add_exclude (folder, + entry_get_displayname (entry)); + /* Remove include for current filename. */ + folder_remove_include (folder, + entry_get_filename (entry)); + /* Add include for new private filename. */ + folder_add_include (folder, filename); + } + + entry_set_filename (entry, filename); + entry_set_weight (entry, 1000); + entry->user_private = TRUE; + } + + g_free (filename); + + return result == GNOME_VFS_OK; +} + +gboolean +entry_is_user_private (Entry *entry) +{ + return entry->user_private; +} + +static void +entry_reload_if_needed (Entry *entry) +{ + gboolean changed = FALSE; + gchar *keywords, *deprecates, *onlyshowin; + int i; + + if (!entry->dirty) + return; + + entry_quick_read_keys (entry, + "Categories", + &keywords, + "Deprecates", + &deprecates, + "OnlyShowIn", + &onlyshowin); + +#if 0 + g_printerr ("Read cats=%s onlyshowin=%s from entry %s\n", + keywords ? keywords : "none", + onlyshowin ? onlyshowin : "none", + entry->filename); +#endif + + /* + * Clear keywords from file, leaving only ones added from + * the directory. + */ + g_slist_free (entry->keywords); + entry->keywords = g_slist_copy (entry->implicit_keywords); + + if (keywords) { + char **parsed = g_strsplit (keywords, ";", -1); + GSList *keylist = entry->keywords; + + for (i = 0; parsed[i] != NULL; i++) { + GQuark quark; + const char *word = parsed[i]; + + /* ignore empties (including end of list) */ + if (word[0] == '\0') + continue; + + quark = g_quark_from_string (word); + if (g_slist_find (keylist, GINT_TO_POINTER (quark))) + continue; + + D (g_print ("ADDING KEYWORD: %s, %s\n", + entry_get_displayname (entry), + word)); + + entry->keywords = + g_slist_prepend (entry->keywords, + GINT_TO_POINTER (quark)); + changed = TRUE; + } + g_strfreev (parsed); + } + + /* FIXME: Support this */ + if (deprecates) { + char **parsed = g_strsplit (keywords, ";", -1); + Entry *dep; + + for (i = 0; parsed[i] != NULL; i++) { + dep = vfolder_info_lookup_entry (entry->info, + parsed[i]); + if (dep) { + vfolder_info_remove_entry (entry->info, dep); +#if 0 /* vfolder_monitor_emit is not defined */ + vfolder_monitor_emit ( + entry_get_filename (dep), + GNOME_VFS_MONITOR_EVENT_DELETED); +#endif + entry_unref (dep); + } + } + g_strfreev (parsed); + } + + if (onlyshowin) { + char **parsed = g_strsplit (onlyshowin, ";", -1); + + /* If OnlyShowIn exists, then the default is + * that we don't show the entry, unless the + * value includes "GNOME" + */ + entry->not_shown = TRUE; + + for (i = 0; parsed[i] != NULL; i++) { + if (strcmp (parsed[i], "GNOME") == 0) + entry->not_shown = FALSE; + } + + /* FIXME do we need to emit some kind of notification here? */ + + g_strfreev (parsed); + } + + g_free (keywords); + g_free (deprecates); + g_free (onlyshowin); + + entry->dirty = FALSE; +} + +gushort +entry_get_weight (Entry *entry) +{ + return entry->weight; +} + +void +entry_set_weight (Entry *entry, gushort weight) +{ + entry->weight = weight; +} + +void +entry_set_dirty (Entry *entry) +{ + entry->dirty = TRUE; +} + +void +entry_set_filename (Entry *entry, const gchar *name) +{ + g_free (entry->filename); + entry->filename = g_strdup (name); + + if (entry->uri) { + gnome_vfs_uri_unref (entry->uri); + entry->uri = NULL; + } + + entry_set_dirty (entry); +} + +const gchar * +entry_get_filename (Entry *entry) +{ + return entry->filename; +} + +void +entry_set_displayname (Entry *entry, const gchar *name) +{ + g_free (entry->displayname); + entry->displayname = g_strdup (name); +} + +const gchar * +entry_get_displayname (Entry *entry) +{ + return entry->displayname; +} + +GnomeVFSURI * +entry_get_real_uri (Entry *entry) +{ + if (!entry->filename) + return NULL; + + if (!entry->uri) + entry->uri = gnome_vfs_uri_new (entry->filename); + + gnome_vfs_uri_ref (entry->uri); + return entry->uri; +} + +const GSList * +entry_get_keywords (Entry *entry) +{ + entry_reload_if_needed (entry); + return entry->keywords; +} + +void +entry_add_implicit_keyword (Entry *entry, GQuark keyword) +{ + entry->keywords = g_slist_prepend (entry->keywords, + GINT_TO_POINTER (keyword)); + entry->implicit_keywords = g_slist_prepend (entry->implicit_keywords, + GINT_TO_POINTER (keyword)); +} + +static void +entry_key_val_from_string (gchar *src, const gchar *key, gchar **result) +{ + gchar *start; + gint keylen = strlen (key), end; + + *result = NULL; + + start = strstr (src, key); + if (start && + (start == src || (*(start-1) == '\r') || (*(start-1) == '\n')) && + ((*(start+keylen) == ' ') || (*(start+keylen) == '='))) { + start += keylen; + start += strspn (start, "= "); + end = strcspn (start, "\r\n"); + if (end > 0) + *result = g_strndup (start, end); + } +} + +void +entry_quick_read_keys (Entry *entry, + const gchar *key1, + gchar **result1, + const gchar *key2, + gchar **result2, + const gchar *key3, + gchar **result3) +{ + GnomeVFSHandle *handle; + GnomeVFSFileSize readlen; + GString *fullbuf; + char buf[2048]; + + *result1 = NULL; + if (key2) + *result2 = NULL; + if (key3) + *result3 = NULL; + + if (gnome_vfs_open (&handle, + entry_get_filename (entry), + GNOME_VFS_OPEN_READ) != GNOME_VFS_OK) + return; + + fullbuf = g_string_new (NULL); + while (gnome_vfs_read (handle, + buf, + sizeof (buf), + &readlen) == GNOME_VFS_OK) { + g_string_append_len (fullbuf, buf, readlen); + } + + gnome_vfs_close (handle); + + if (!fullbuf->len) { + g_string_free (fullbuf, TRUE); + return; + } + + entry_key_val_from_string (fullbuf->str, key1, result1); + + if (key2) + entry_key_val_from_string (fullbuf->str, key2, result2); + + if (key3) + entry_key_val_from_string (fullbuf->str, key3, result3); + + g_string_free (fullbuf, TRUE); +} + +void +entry_dump (Entry *entry, int indent) +{ + gchar *space = g_strnfill (indent, ' '); + GSList *keywords = entry->keywords, *iter; + + D (g_print ("%s%s\n%s Filename: %s\n%s Keywords: ", + space, + entry_get_displayname (entry), + space, + entry_get_filename (entry), + space)); + + for (iter = keywords; iter; iter = iter->next) { + G_GNUC_UNUSED GQuark quark = GPOINTER_TO_INT (iter->data); + D (g_print (g_quark_to_string (quark))); + } + + D (g_print ("\n")); + + g_free (space); +} + + + +/* + * Folder Implementation + */ +Folder * +folder_new (VFolderInfo *info, const gchar *name, gboolean user_private) +{ + Folder *folder = g_new0 (Folder, 1); + + folder->name = g_strdup (name); + folder->user_private = user_private; + folder->info = info; + folder->refcnt = 1; + + folder->dirty = TRUE; + + return folder; +} + +void +folder_ref (Folder *folder) +{ + folder->refcnt++; +} + +static void +unalloc_exclude (gpointer key, gpointer val, gpointer user_data) +{ + gchar *filename = key; + VFolderInfo *info = user_data; + Entry *entry; + + /* Skip excludes which probably from the parent URI */ + if (strchr (filename, '/')) + return; + + entry = vfolder_info_lookup_entry (info, filename); + if (entry) + entry_dealloc (entry); +} + +static void +folder_reset_entries (Folder *folder) +{ + /* entries */ + g_slist_foreach (folder->entries, (GFunc) entry_dealloc, NULL); + g_slist_foreach (folder->entries, (GFunc) entry_unref, NULL); + g_slist_free (folder->entries); + folder->entries = NULL; + + if (folder->entries_ht) { + g_hash_table_destroy (folder->entries_ht); + folder->entries_ht = NULL; + } +} + +void +folder_unref (Folder *folder) +{ + folder->refcnt--; + + if (folder->refcnt == 0) { + D (g_print ("DESTORYING FOLDER: %p, %s\n", + folder, + folder->name)); + + g_free (folder->name); + g_free (folder->extend_uri); + g_free (folder->desktop_file); + + if (folder->extend_monitor) + vfolder_monitor_cancel (folder->extend_monitor); + + query_free (folder->query); + + if (folder->excludes) { + g_hash_table_foreach (folder->excludes, + (GHFunc) unalloc_exclude, + folder->info); + g_hash_table_destroy (folder->excludes); + } + + g_slist_foreach (folder->includes, (GFunc) g_free, NULL); + g_slist_free (folder->includes); + + /* subfolders */ + g_slist_foreach (folder->subfolders, + (GFunc) folder_unref, + NULL); + g_slist_free (folder->subfolders); + + if (folder->subfolders_ht) + g_hash_table_destroy (folder->subfolders_ht); + + folder_reset_entries (folder); + + g_free (folder); + } +} + +static gboolean read_one_extended_entry (Folder *folder, + const gchar *file_uri, + GnomeVFSFileInfo *file_info); + +static void +folder_extend_monitor_cb (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + Folder *folder = user_data; + FolderChild child; + GnomeVFSFileInfo *file_info; + GnomeVFSResult result; + GnomeVFSURI *uri, *entry_uri; + gchar *filename; + + /* Operating on the whole directory, ignore */ + if (!strcmp (monitor_uri, info_uri)) + return; + + D (g_print ("*** Exdended folder %s ('%s') monitor %s%s%s called! ***\n", + folder->name, + info_uri, + event_type == GNOME_VFS_MONITOR_EVENT_CREATED ? "CREATED":"", + event_type == GNOME_VFS_MONITOR_EVENT_DELETED ? "DELETED":"", + event_type == GNOME_VFS_MONITOR_EVENT_CHANGED ? "CHANGED":"")); + + uri = gnome_vfs_uri_new (info_uri); + filename = gnome_vfs_uri_extract_short_name (uri); + + VFOLDER_INFO_WRITE_LOCK (folder->info); + + switch (event_type) { + case GNOME_VFS_MONITOR_EVENT_CHANGED: + /* + * We only care about entries here, as the extend_monitor_cb on + * the subfolders themselves should take care of emitting + * changes. + */ + child.entry = folder_get_entry (folder, filename); + if (child.entry) { + entry_uri = entry_get_real_uri (child.entry); + + if (gnome_vfs_uri_equal (entry_uri, uri)) { + entry_set_dirty (child.entry); + folder_emit_changed ( + folder, + entry_get_displayname (child.entry), + GNOME_VFS_MONITOR_EVENT_CHANGED); + } + + gnome_vfs_uri_unref (entry_uri); + } + break; + case GNOME_VFS_MONITOR_EVENT_DELETED: + folder_get_child (folder, filename, &child); + + /* + * FIXME: should look for replacement in info's entry + * pool here, before sending event + */ + + if (child.type == DESKTOP_FILE) { + entry_uri = entry_get_real_uri (child.entry); + + if (gnome_vfs_uri_equal (uri, entry_uri)) { + folder_remove_entry (folder, child.entry); + folder_emit_changed ( + folder, + filename, + GNOME_VFS_MONITOR_EVENT_DELETED); + } + + gnome_vfs_uri_unref (entry_uri); + } + else if (child.type == FOLDER) { + if (folder_is_user_private (child.folder)) { + folder_set_dirty (child.folder); + } else { + folder_remove_subfolder (folder, child.folder); + folder_emit_changed ( + folder, + filename, + GNOME_VFS_MONITOR_EVENT_DELETED); + } + } + break; + case GNOME_VFS_MONITOR_EVENT_CREATED: + file_info = gnome_vfs_file_info_new (); + result = + gnome_vfs_get_file_info_uri ( + uri, + file_info, + GNOME_VFS_FILE_INFO_DEFAULT); + + if (result == GNOME_VFS_OK && + read_one_extended_entry (folder, info_uri, file_info)) + folder_emit_changed (folder, + file_info->name, + GNOME_VFS_MONITOR_EVENT_CREATED); + + gnome_vfs_file_info_unref (file_info); + break; + default: + break; + } + + folder->info->modification_time = time (NULL); + + VFOLDER_INFO_WRITE_UNLOCK (folder->info); + + gnome_vfs_uri_unref (uri); + g_free (filename); +} + +gboolean +folder_make_user_private (Folder *folder) +{ + if (folder->user_private) + return TRUE; + + if (folder->parent) { + if (folder->parent->read_only || + !folder_make_user_private (folder->parent)) + return FALSE; + + if (!folder->parent->has_user_private_subfolders) { + Folder *iter; + + for (iter = folder->parent; iter; iter = iter->parent) + iter->has_user_private_subfolders = TRUE; + } + } + + folder->user_private = TRUE; + + vfolder_info_set_dirty (folder->info); + + return TRUE; +} + +gboolean +folder_is_user_private (Folder *folder) +{ + return folder->user_private; +} + +static gboolean +create_dot_directory_entry (Folder *folder) +{ + Entry *entry = NULL, *existing; + const gchar *dot_directory = folder_get_desktop_file (folder); + + /* Only replace if existing isn't user-private */ + existing = folder_get_entry (folder, ".directory"); + if (existing && entry_get_weight (existing) == 1000) + return FALSE; + + if (strchr (dot_directory, '/')) { + /* Assume full path or URI */ + entry = entry_new (folder->info, + dot_directory, + ".directory", + TRUE /*user_private*/, + 950 /*weight*/); + } else { + gchar *dirpath = NULL; + gchar *full_path; + + if (folder->info->desktop_dir) + dirpath = folder->info->desktop_dir; + else if (folder->info->write_dir) + dirpath = folder->info->write_dir; + else + return FALSE; + + if (dirpath) { + full_path = vfolder_build_uri (dirpath, + dot_directory, + NULL); + entry = entry_new (folder->info, + full_path, + ".directory", + TRUE /*user_private*/, + 950 /*weight*/); + g_free (full_path); + } + } + + if (entry) { + folder_add_entry (folder, entry); + entry_unref (entry); + } + + return entry != NULL; +} + +static gboolean +read_one_include (Folder *folder, const gchar *file_uri) +{ + Entry *entry = NULL, *existing; + GnomeVFSURI *uri; + gchar *basename, *basename_ts; + + if (!strchr (file_uri, '/')) { + entry = vfolder_info_lookup_entry (folder->info, file_uri); + if (entry && entry != folder_get_entry (folder, file_uri)) { + folder_add_entry (folder, entry); + return TRUE; + } + return FALSE; + } + else { + uri = gnome_vfs_uri_new (file_uri); + if (!uri || !gnome_vfs_uri_exists (uri)) + return FALSE; + + basename = gnome_vfs_uri_extract_short_name (uri); + + /* If including something from the WriteDir, untimestamp it. */ + if (folder->info->write_dir && + strstr (file_uri, folder->info->write_dir)) { + basename_ts = basename; + basename = vfolder_untimestamp_file_name (basename_ts); + g_free (basename_ts); + } + + /* Only replace if existing is not user-private */ + existing = folder_get_entry (folder, basename); + if (existing && entry_get_weight (existing) == 1000) { + gnome_vfs_uri_unref (uri); + g_free (basename); + return FALSE; + } + + entry = entry_new (folder->info, + file_uri, + basename, + TRUE, + 1000 /*weight*/); + folder_add_entry (folder, entry); + + entry_unref (entry); + gnome_vfs_uri_unref (uri); + g_free (basename); + + return TRUE; + } +} + +static gboolean +read_includes (Folder *folder) +{ + GSList *iter; + gboolean changed = FALSE; + + for (iter = folder->includes; iter; iter = iter->next) { + gchar *include = iter->data; + + changed |= read_one_include (folder, include); + } + + return changed; +} + +static gboolean +is_excluded (Folder *folder, const gchar *filename, const gchar *displayname) +{ + if (!folder->excludes) + return FALSE; + + if (displayname && g_hash_table_lookup (folder->excludes, displayname)) + return TRUE; + + if (filename && g_hash_table_lookup (folder->excludes, filename)) + return TRUE; + + return FALSE; +} + +static gboolean +read_one_extended_entry (Folder *folder, + const gchar *file_uri, + GnomeVFSFileInfo *file_info) +{ + Query *query = folder_get_query (folder); + +#if 0 + g_printerr ("reading one extended entry %s\n", file_uri ? file_uri : "null"); +#endif + + if (is_excluded (folder, file_uri, file_info->name)) + return FALSE; + + if (file_info->type == GNOME_VFS_FILE_TYPE_DIRECTORY) { + Folder *sub; + + if (folder_get_subfolder (folder, file_info->name)) + return FALSE; + + sub = folder_new (folder->info, file_info->name, FALSE); + + folder_set_extend_uri (sub, file_uri); + sub->is_link = folder->is_link; + + folder_add_subfolder (folder, sub); + folder_unref (sub); + + return TRUE; + } else { + Entry *entry, *existing; + gboolean retval = FALSE; + + /* Only replace if entry is more important than existing */ + existing = folder_get_entry (folder, file_info->name); + if (existing && entry_get_weight (existing) >= 900) + return FALSE; + + entry = entry_new (folder->info, + file_uri, + file_info->name, + FALSE /*user_private*/, + 900 /*weight*/); + + /* Include unless specifically excluded by query */ + if (!query || query_try_match (query, folder, entry)) { + D (g_print ("ADDING EXTENDED ENTRY: " + "%s, %s, #%d!\n", + folder_get_name (folder), + entry_get_displayname (entry), + g_slist_length ((GSList*) + folder_list_entries (folder)))); + + folder_add_entry (folder, entry); + retval = TRUE; + } + + entry_unref (entry); + return retval; + } +} + +static gboolean +read_extended_entries (Folder *folder) +{ + GnomeVFSResult result; + GnomeVFSDirectoryHandle *handle; + GnomeVFSFileInfo *file_info; + const gchar *extend_uri; + gboolean changed = FALSE; + + extend_uri = folder_get_extend_uri (folder); + + result = gnome_vfs_directory_open (&handle, + extend_uri, + GNOME_VFS_FILE_INFO_DEFAULT); + +#if 0 + g_printerr ("reading extended entries from %s result = %s\n"< + extend_uri ? extend_uri : "null", + result == GNOME_VFS_OK ? "ok" : "failed"); +#endif + + if (result != GNOME_VFS_OK) + return FALSE; + + file_info = gnome_vfs_file_info_new (); + + while (TRUE) { + gchar *file_uri; + + result = gnome_vfs_directory_read_next (handle, file_info); + if (result != GNOME_VFS_OK) + break; + + if (!strcmp (file_info->name, ".") || + !strcmp (file_info->name, "..")) + continue; + + file_uri = vfolder_build_uri (extend_uri, + file_info->name, + NULL); + + changed |= read_one_extended_entry (folder, + file_uri, + file_info); + + g_free (file_uri); + } + + gnome_vfs_file_info_unref (file_info); + gnome_vfs_directory_close (handle); + + return changed; +} + +static gboolean +read_one_info_entry_pool (Folder *folder, Entry *entry) +{ + Query *query = folder_get_query (folder); + Entry *existing; + + if (is_excluded (folder, + entry_get_filename (entry), + entry_get_displayname (entry))) { + /* + * Being excluded counts as a ref because we don't want + * them showing up in the Others menu. + */ + entry_alloc (entry); + return FALSE; + } + + /* Only replace if entry is more important than existing */ + existing = folder_get_entry (folder, entry_get_displayname (entry)); + if (existing && entry_get_weight (existing) >= entry_get_weight (entry)) + return FALSE; + + /* Only include if matches a mandatory query. */ + if (query && query_try_match (query, folder, entry)) { + D (g_print ("ADDING POOL ENTRY: %s, %s, #%d!!!!\n", + folder_get_name (folder), + entry_get_displayname (entry), + g_slist_length ( + (GSList*) folder_list_entries (folder)))); + + folder_add_entry (folder, entry); + + return TRUE; + } else + return FALSE; +} + +static gboolean +read_info_entry_pool (Folder *folder) +{ + const GSList *all_entries, *iter; + Query *query; + gboolean changed = FALSE; + + if (folder->only_unallocated) + return FALSE; + + query = folder_get_query (folder); + all_entries = vfolder_info_list_all_entries (folder->info); + + for (iter = all_entries; iter; iter = iter->next) { + Entry *entry = iter->data; + + changed |= read_one_info_entry_pool (folder, entry); + } + + return changed; +} + +void +folder_emit_changed (Folder *folder, + const gchar *child, + GnomeVFSMonitorEventType event_type) +{ + Folder *iter; + GString *buf; + + buf = g_string_new (NULL); + + if (child) { + g_string_prepend (buf, child); + g_string_prepend_c (buf, '/'); + } + + for (iter = folder; + iter != NULL && iter != folder->info->root; + iter = iter->parent) { + g_string_prepend (buf, folder_get_name (iter)); + g_string_prepend_c (buf, '/'); + } + + vfolder_info_emit_change (folder->info, + buf->len ? buf->str : "/", + event_type); + + g_string_free (buf, TRUE); +} + +static void +remove_extended_subfolders (Folder *folder) +{ + GSList *iter, *copy; + Folder *sub; + + copy = g_slist_copy ((GSList *) folder_list_subfolders (folder)); + for (iter = copy; iter; iter = iter->next) { + sub = iter->data; + if (!folder_is_user_private (sub)) + folder_remove_subfolder (folder, sub); + } + g_slist_free (copy); +} + +static void +folder_reload_if_needed (Folder *folder) +{ + gboolean changed = FALSE; + +#if 0 + g_printerr ("folder maybe reload dirty = %d loading = %d\n", + folder->dirty, folder->loading); +#endif + + if (!folder->dirty || folder->loading) + return; + + D (g_print ("----- RELOADING FOLDER: %s -----\n", + folder->name)); + + folder->loading = TRUE; + folder->info->loading = TRUE; + + folder_reset_entries (folder); + remove_extended_subfolders (folder); + + if (folder_get_desktop_file (folder)) + changed |= create_dot_directory_entry (folder); + + if (folder->includes) + changed |= read_includes (folder); + + if (folder_get_extend_uri (folder)) { + changed |= read_extended_entries (folder); + + /* Start monitoring here, to cut down on unneeded events */ + if (!folder->extend_monitor) + folder->extend_monitor = + vfolder_monitor_dir_new ( + folder_get_extend_uri (folder), + folder_extend_monitor_cb, + folder); + } else { +#if 0 + g_printerr ("folder %s has no extend uri, not reading\n", + folder->name); +#endif + } + + if (folder_get_query (folder)) + changed |= read_info_entry_pool (folder); + + if (changed) + folder_emit_changed (folder, + NULL, + GNOME_VFS_MONITOR_EVENT_CHANGED); + + folder->info->loading = FALSE; + folder->loading = FALSE; + folder->dirty = FALSE; +} + +void +folder_set_dirty (Folder *folder) +{ + folder->dirty = TRUE; +} + +void +folder_set_name (Folder *folder, const gchar *name) +{ + g_free (folder->name); + folder->name = g_strdup (name); + + vfolder_info_set_dirty (folder->info); +} + +const gchar * +folder_get_name (Folder *folder) +{ + return folder->name; +} + +void +folder_set_query (Folder *folder, Query *query) +{ + if (folder->query) + query_free (folder->query); + + folder->query = query; + + folder_set_dirty (folder); + vfolder_info_set_dirty (folder->info); +} + +Query * +folder_get_query (Folder *folder) +{ + return folder->query; +} + +void +folder_set_extend_uri (Folder *folder, const gchar *uri) +{ +#if 0 + g_printerr ("setting extend URI of %s to %s\n", + folder->name, + uri ? uri : "null"); +#endif + + g_free (folder->extend_uri); + folder->extend_uri = g_strdup (uri); + + if (folder->extend_monitor) { + vfolder_monitor_cancel (folder->extend_monitor); + folder->extend_monitor = NULL; + } + + folder_set_dirty (folder); + vfolder_info_set_dirty (folder->info); +} + +const gchar * +folder_get_extend_uri (Folder *folder) +{ + return folder->extend_uri; +} + +void +folder_set_desktop_file (Folder *folder, const gchar *filename) +{ + g_free (folder->desktop_file); + folder->desktop_file = g_strdup (filename); + + vfolder_info_set_dirty (folder->info); +} + +const gchar * +folder_get_desktop_file (Folder *folder) +{ + return folder->desktop_file; +} + +gboolean +folder_get_child (Folder *folder, const gchar *name, FolderChild *child) +{ + Folder *subdir; + Entry *file; + + memset (child, 0, sizeof (FolderChild)); + + if (name) + subdir = folder_get_subfolder (folder, name); + else + /* No name, just return the parent folder */ + subdir = folder; + + if (subdir) { + child->type = FOLDER; + child->folder = subdir; + return TRUE; + } + + file = folder_get_entry (folder, name); + if (file) { + child->type = DESKTOP_FILE; + child->entry = file; + return TRUE; + } + + return FALSE; +} + +static void +child_list_foreach_prepend (gpointer key, + gpointer val, + gpointer user_data) +{ + gchar *name = key; + GSList **list = user_data; + + *list = g_slist_prepend (*list, g_strdup (name)); +} + +static GSList * +child_list_prepend_sorted (gchar *sortorder, + GHashTable *name_hash) +{ + GSList *ret = NULL; + gchar **split_ord; + int i; + + if (!sortorder) + return NULL; + + split_ord = g_strsplit (sortorder, ":", -1); + if (split_ord && split_ord [0]) { + for (i = 0; split_ord [i]; i++) { + gchar *name = split_ord [i]; + + if (g_hash_table_lookup (name_hash, name)) { + g_hash_table_remove (name_hash, name); + ret = g_slist_prepend (ret, g_strdup (name)); + } + } + } + + return ret; +} + +GSList * +folder_list_children (Folder *folder) +{ + Entry *dot_directory; + GHashTable *name_hash; + const GSList *iter; + GSList *list = NULL; + + /* FIXME: handle duplicate names here, by not using a hashtable */ + + name_hash = g_hash_table_new (g_str_hash, g_str_equal); + + for (iter = folder_list_subfolders (folder); iter; iter = iter->next) { + Folder *child = iter->data; + g_hash_table_insert (name_hash, + (gchar *) folder_get_name (child), + NULL); + } + + for (iter = folder_list_entries (folder); iter; iter = iter->next) { + Entry *entry = iter->data; + g_hash_table_insert (name_hash, + (gchar *) entry_get_displayname (entry), + NULL); + } + + if (folder->only_unallocated) { + Query *query = folder_get_query (folder); + + iter = vfolder_info_list_all_entries (folder->info); + for (; iter; iter = iter->next) { + Entry *entry = iter->data; + + if (entry_is_allocated (entry)) + continue; + + if (query && !query_try_match (query, folder, entry)) + continue; + + if (entry->not_shown) + continue; + + g_hash_table_insert ( + name_hash, + (gchar *) entry_get_displayname (entry), + NULL); + } + } + + dot_directory = folder_get_entry (folder, ".directory"); + if (dot_directory) { + gchar *sortorder; + entry_quick_read_keys (dot_directory, + "SortOrder", + &sortorder, + NULL, + NULL, + NULL, + NULL); + if (sortorder) { + list = child_list_prepend_sorted (sortorder, + name_hash); + g_free (sortorder); + } + } + + g_hash_table_foreach (name_hash, + (GHFunc) child_list_foreach_prepend, + &list); + g_hash_table_destroy (name_hash); + + list = g_slist_reverse (list); + + return list; +} + +Entry * +folder_get_entry (Folder *folder, const gchar *filename) +{ + Entry *retval = NULL; + + folder_reload_if_needed (folder); + + if (folder->entries_ht) + retval = g_hash_table_lookup (folder->entries_ht, filename); + + if (!retval && folder->only_unallocated) + retval = vfolder_info_lookup_entry (folder->info, filename); + + return retval; +} + +const GSList * +folder_list_entries (Folder *folder) +{ + folder_reload_if_needed (folder); + + return folder->entries; +} + +/* + * This doesn't set the folder dirty. + * Use the include/exclude functions for that. + */ +void +folder_remove_entry (Folder *folder, Entry *entry) +{ + const gchar *name; + Entry *existing; + + if (!folder->entries_ht) + return; + + name = entry_get_displayname (entry); + existing = g_hash_table_lookup (folder->entries_ht, name); + if (existing) { + g_hash_table_remove (folder->entries_ht, name); + folder->entries = g_slist_remove (folder->entries, existing); + + entry_dealloc (existing); + entry_unref (existing); + } +} + +/* + * This doesn't set the folder dirty. + * Use the include/exclude functions for that. + */ +void +folder_add_entry (Folder *folder, Entry *entry) +{ + entry_alloc (entry); + entry_ref (entry); + + folder_remove_entry (folder, entry); + + if (!folder->entries_ht) + folder->entries_ht = g_hash_table_new (g_str_hash, g_str_equal); + + g_hash_table_insert (folder->entries_ht, + (gchar *) entry_get_displayname (entry), + entry); + folder->entries = g_slist_append (folder->entries, entry); +} + +void +folder_add_include (Folder *folder, const gchar *include) +{ + folder_remove_exclude (folder, include); + + folder->includes = g_slist_prepend (folder->includes, + g_strdup (include)); + + vfolder_info_set_dirty (folder->info); +} + +void +folder_remove_include (Folder *folder, const gchar *file) +{ + GSList *li; + + if (!folder->includes) + return; + + li = g_slist_find_custom (folder->includes, + file, + (GCompareFunc) strcmp); + if (li) { + folder->includes = g_slist_delete_link (folder->includes, li); + vfolder_info_set_dirty (folder->info); + } +} + +void +folder_add_exclude (Folder *parent, const gchar *exclude) +{ + char *s; + + folder_remove_include (parent, exclude); + + if (!parent->excludes) + parent->excludes = + g_hash_table_new_full (g_str_hash, + g_str_equal, + (GDestroyNotify) g_free, + NULL); + + s = g_strdup (exclude); + g_hash_table_replace (parent->excludes, s, s); + + vfolder_info_set_dirty (parent->info); +} + +void +folder_remove_exclude (Folder *folder, const gchar *file) +{ + if (!folder->excludes) + return; + + g_hash_table_remove (folder->excludes, file); + + vfolder_info_set_dirty (folder->info); +} + +Folder * +folder_get_subfolder (Folder *folder, const gchar *name) +{ + folder_reload_if_needed (folder); + + if (!folder->subfolders_ht) + return NULL; + + return g_hash_table_lookup (folder->subfolders_ht, name); +} + +const GSList * +folder_list_subfolders (Folder *parent) +{ + folder_reload_if_needed (parent); + + return parent->subfolders; +} + +void +folder_remove_subfolder (Folder *parent, Folder *child) +{ + const gchar *name; + Folder *existing; + + if (!parent->subfolders_ht) + return; + + name = folder_get_name (child); + existing = g_hash_table_lookup (parent->subfolders_ht, name); + if (existing) { + g_hash_table_remove (parent->subfolders_ht, name); + parent->subfolders = g_slist_remove (parent->subfolders, + existing); + existing->parent = NULL; + folder_unref (existing); + vfolder_info_set_dirty (parent->info); + } +} + +void +folder_add_subfolder (Folder *parent, Folder *child) +{ + if (child->user_private && !parent->has_user_private_subfolders) { + Folder *iter; + for (iter = parent; iter != NULL; iter = iter->parent) + iter->has_user_private_subfolders = TRUE; + } + + folder_ref (child); + child->parent = parent; + + if (!parent->subfolders_ht) + parent->subfolders_ht = g_hash_table_new (g_str_hash, + g_str_equal); + else + folder_remove_subfolder (parent, child); + + g_hash_table_insert (parent->subfolders_ht, + (gchar *) folder_get_name (child), + child); + parent->subfolders = g_slist_append (parent->subfolders, child); + + vfolder_info_set_dirty (parent->info); +} + +void +folder_dump_tree (Folder *folder, int indent) +{ + const GSList *iter; + gchar *space = g_strnfill (indent, ' '); + + D (g_print ("%s(%p): %s\n", + space, + folder, + folder ? folder_get_name (folder) : NULL)); + + g_free (space); + + for (iter = folder_list_subfolders (folder); iter; iter = iter->next) { + Folder *child = iter->data; + + folder_dump_tree (child, indent + 2); + } +} + +/* This is a pretty lame hack */ +gboolean +folder_is_hidden (Folder *folder) +{ + const GSList *iter, *ents; + + if (folder->dont_show_if_empty == FALSE) + return FALSE; + + if (folder->only_unallocated) { + Query *query = folder_get_query (folder); + + iter = vfolder_info_list_all_entries (folder->info); + for (; iter; iter = iter->next) { + Entry *entry = iter->data; + + if (entry_is_allocated (entry)) + continue; + + if (entry->not_shown) + continue; + + if (query && !query_try_match (query, folder, entry)) + continue; + + return FALSE; + } + } + + ents = folder_list_entries (folder); + if (ents) { + /* If there is only one entry, check it is not .directory */ + if (!ents->next) { + Entry *dot_directory = ents->data; + const gchar *name; + + name = entry_get_displayname (dot_directory); + if (strcmp (".directory", name) != 0) + return FALSE; + } else + return FALSE; + } + + for (iter = folder_list_subfolders (folder); iter; iter = iter->next) { + Folder *child = iter->data; + + if (!folder_is_hidden (child)) + return FALSE; + } + + return TRUE; +} + + + +/* + * Query Implementation + */ +Query * +query_new (int type) +{ + Query *query; + + query = g_new0 (Query, 1); + query->type = type; + + return query; +} + +void +query_free (Query *query) +{ + if (query == NULL) + return; + + if (query->type == QUERY_OR || query->type == QUERY_AND) { + g_slist_foreach (query->val.queries, + (GFunc) query_free, + NULL); + g_slist_free (query->val.queries); + } + else if (query->type == QUERY_FILENAME) + g_free (query->val.filename); + + g_free (query); +} + +#define INVERT_IF_NEEDED(val) (query->not ? !(val) : (val)) + +gboolean +query_try_match (Query *query, + Folder *folder, + Entry *efile) +{ + GSList *li; + + if (efile->not_shown) + return FALSE; + + if (query == NULL) + return TRUE; + + switch (query->type) { + case QUERY_OR: + for (li = query->val.queries; li != NULL; li = li->next) { + Query *subquery = li->data; + + if (query_try_match (subquery, folder, efile)) + return INVERT_IF_NEEDED (TRUE); + } + return INVERT_IF_NEEDED (FALSE); + case QUERY_AND: + for (li = query->val.queries; li != NULL; li = li->next) { + Query *subquery = li->data; + + if (!query_try_match (subquery, folder, efile)) + return INVERT_IF_NEEDED (FALSE); + } + return INVERT_IF_NEEDED (TRUE); + case QUERY_PARENT: + { + const gchar *extend_uri; + + /* + * Check that entry's path starts with that of the + * folder's extend_uri, so that we know that it matches + * the parent query. + */ + extend_uri = folder_get_extend_uri (folder); + if (extend_uri && + strncmp (entry_get_filename (efile), + extend_uri, + strlen (extend_uri)) == 0) + return INVERT_IF_NEEDED (TRUE); + else + return INVERT_IF_NEEDED (FALSE); + } + case QUERY_KEYWORD: + { + const GSList *keywords; + GQuark keyword; + + keywords = entry_get_keywords (efile); + for (; keywords; keywords = keywords->next) { + keyword = GPOINTER_TO_INT (keywords->data); + if (keyword == query->val.keyword) + return INVERT_IF_NEEDED (TRUE); + } + } + return INVERT_IF_NEEDED (FALSE); + case QUERY_FILENAME: + if (strchr (query->val.filename, '/') && + !strcmp (query->val.filename, entry_get_filename (efile))) + return INVERT_IF_NEEDED (TRUE); + else if (!strcmp (query->val.filename, + entry_get_displayname (efile))) + return INVERT_IF_NEEDED (TRUE); + else + return INVERT_IF_NEEDED (FALSE); + } + + g_assert_not_reached (); + return FALSE; +} diff --git a/modules/vfolder/vfolder-common.c.vfolder-hacks b/modules/vfolder/vfolder-common.c.vfolder-hacks new file mode 100644 index 0000000..2b9b73c --- /dev/null +++ b/modules/vfolder/vfolder-common.c.vfolder-hacks @@ -0,0 +1,1668 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* + * vfolder-common.c - Implementation of abstract Folder, Entry, and Query + * interfaces. + * + * Copyright (C) 2002 Ximian, Inc. + * + * The Gnome Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Gnome Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Alex Graveley + * Based on original code by George Lebl . + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include +#include +#include +#include + +#include "vfolder-common.h" + + +/* + * Entry Implementation + */ +Entry * +entry_new (VFolderInfo *info, + const gchar *filename, + const gchar *displayname, + gboolean user_private, + gushort weight) +{ + Entry *entry; + + entry = g_new0 (Entry, 1); + entry->refcnt = 1; + entry->allocs = 0; + entry->info = info; + entry->filename = g_strdup (filename); + entry->displayname = g_strdup (displayname); + entry->user_private = user_private; + entry->weight = weight; + + entry->dirty = TRUE; + + /* + * Lame-O special case .directory handling, as we don't want them + * showing up for all-applications:///. + */ + if (strcmp (displayname, ".directory") != 0) + vfolder_info_add_entry (info, entry); + + return entry; +} + +void +entry_ref (Entry *entry) +{ + entry->refcnt++; +} + +void +entry_unref (Entry *entry) +{ + entry->refcnt--; + + if (entry->refcnt == 0) { + D (g_print ("-- KILLING ENTRY: (%p) %s---\n", + entry, + entry->displayname)); + + vfolder_info_remove_entry (entry->info, entry); + + g_free (entry->filename); + g_free (entry->displayname); + g_slist_free (entry->keywords); + g_slist_free (entry->implicit_keywords); + g_free (entry); + } +} + +void +entry_alloc (Entry *entry) +{ + entry->allocs++; +} + +void +entry_dealloc (Entry *entry) +{ + entry->allocs--; +} + +gboolean +entry_is_allocated (Entry *entry) +{ + return entry->allocs > 0; +} + +gboolean +entry_make_user_private (Entry *entry, Folder *folder) +{ + GnomeVFSURI *src_uri, *dest_uri; + GnomeVFSResult result; + gchar *uniqname, *filename; + + if (entry->user_private) + return TRUE; + + /* Don't write privately if folder is link */ + if (folder->is_link) + return TRUE; + + /* Need a writedir, otherwise just modify the original */ + if (!entry->info->write_dir) + return TRUE; + + /* Need a filename to progress further */ + if (!entry_get_filename (entry)) + return FALSE; + + /* Make sure the destination directory exists */ + result = vfolder_make_directory_and_parents (entry->info->write_dir, + FALSE, + 0700); + if (result != GNOME_VFS_OK) + return FALSE; + + /* + * Add a timestamp to the filename since we don't want conflicts between + * files in different logical folders with the same filename. + */ + uniqname = vfolder_timestamp_file_name (entry_get_displayname (entry)); + filename = vfolder_build_uri (entry->info->write_dir, uniqname, NULL); + g_free (uniqname); + + src_uri = entry_get_real_uri (entry); + dest_uri = gnome_vfs_uri_new (filename); + + result = gnome_vfs_xfer_uri (src_uri, + dest_uri, + GNOME_VFS_XFER_USE_UNIQUE_NAMES, + GNOME_VFS_XFER_ERROR_MODE_ABORT, + GNOME_VFS_XFER_OVERWRITE_MODE_ABORT, + NULL, + NULL); + + gnome_vfs_uri_unref (src_uri); + gnome_vfs_uri_unref (dest_uri); + + if (result == GNOME_VFS_OK) { + if (!strcmp (entry_get_displayname (entry), ".directory")) { + folder_set_desktop_file (folder, filename); + } else { + /* Exclude current displayname. */ + folder_add_exclude (folder, + entry_get_displayname (entry)); + /* Remove include for current filename. */ + folder_remove_include (folder, + entry_get_filename (entry)); + /* Add include for new private filename. */ + folder_add_include (folder, filename); + } + + entry_set_filename (entry, filename); + entry_set_weight (entry, 1000); + entry->user_private = TRUE; + } + + g_free (filename); + + return result == GNOME_VFS_OK; +} + +gboolean +entry_is_user_private (Entry *entry) +{ + return entry->user_private; +} + +static void +entry_reload_if_needed (Entry *entry) +{ + gboolean changed = FALSE; + gchar *keywords, *deprecates; + int i; + + if (!entry->dirty) + return; + + entry_quick_read_keys (entry, + "Categories", + &keywords, + "Deprecates", + &deprecates); + + /* + * Clear keywords from file, leaving only ones added from + * the directory. + */ + g_slist_free (entry->keywords); + entry->keywords = g_slist_copy (entry->implicit_keywords); + + if (keywords) { + char **parsed = g_strsplit (keywords, ";", -1); + GSList *keylist = entry->keywords; + + for (i = 0; parsed[i] != NULL; i++) { + GQuark quark; + const char *word = parsed[i]; + + /* ignore empties (including end of list) */ + if (word[0] == '\0') + continue; + + quark = g_quark_from_string (word); + if (g_slist_find (keylist, GINT_TO_POINTER (quark))) + continue; + + D (g_print ("ADDING KEYWORD: %s, %s\n", + entry_get_displayname (entry), + word)); + + entry->keywords = + g_slist_prepend (entry->keywords, + GINT_TO_POINTER (quark)); + changed = TRUE; + } + g_strfreev (parsed); + } + + /* FIXME: Support this */ + if (deprecates) { + char **parsed = g_strsplit (keywords, ";", -1); + Entry *dep; + + for (i = 0; parsed[i] != NULL; i++) { + dep = vfolder_info_lookup_entry (entry->info, + parsed[i]); + if (dep) { + vfolder_info_remove_entry (entry->info, dep); +#if 0 /* vfolder_monitor_emit is not defined */ + vfolder_monitor_emit ( + entry_get_filename (dep), + GNOME_VFS_MONITOR_EVENT_DELETED); +#endif + entry_unref (dep); + } + } + g_strfreev (parsed); + } + + g_free (keywords); + g_free (deprecates); + + entry->dirty = FALSE; +} + +gushort +entry_get_weight (Entry *entry) +{ + return entry->weight; +} + +void +entry_set_weight (Entry *entry, gushort weight) +{ + entry->weight = weight; +} + +void +entry_set_dirty (Entry *entry) +{ + entry->dirty = TRUE; +} + +void +entry_set_filename (Entry *entry, const gchar *name) +{ + g_free (entry->filename); + entry->filename = g_strdup (name); + + if (entry->uri) { + gnome_vfs_uri_unref (entry->uri); + entry->uri = NULL; + } + + entry_set_dirty (entry); +} + +const gchar * +entry_get_filename (Entry *entry) +{ + return entry->filename; +} + +void +entry_set_displayname (Entry *entry, const gchar *name) +{ + g_free (entry->displayname); + entry->displayname = g_strdup (name); +} + +const gchar * +entry_get_displayname (Entry *entry) +{ + return entry->displayname; +} + +GnomeVFSURI * +entry_get_real_uri (Entry *entry) +{ + if (!entry->filename) + return NULL; + + if (!entry->uri) + entry->uri = gnome_vfs_uri_new (entry->filename); + + gnome_vfs_uri_ref (entry->uri); + return entry->uri; +} + +const GSList * +entry_get_keywords (Entry *entry) +{ + entry_reload_if_needed (entry); + return entry->keywords; +} + +void +entry_add_implicit_keyword (Entry *entry, GQuark keyword) +{ + entry->keywords = g_slist_prepend (entry->keywords, + GINT_TO_POINTER (keyword)); + entry->implicit_keywords = g_slist_prepend (entry->implicit_keywords, + GINT_TO_POINTER (keyword)); +} + +static void +entry_key_val_from_string (gchar *src, const gchar *key, gchar **result) +{ + gchar *start; + gint keylen = strlen (key), end; + + *result = NULL; + + start = strstr (src, key); + if (start && + (start == src || (*(start-1) == '\r') || (*(start-1) == '\n')) && + ((*(start+keylen) == ' ') || (*(start+keylen) == '='))) { + start += keylen; + start += strspn (start, "= "); + end = strcspn (start, "\r\n"); + if (end > 0) + *result = g_strndup (start, end); + } +} + +void +entry_quick_read_keys (Entry *entry, + const gchar *key1, + gchar **result1, + const gchar *key2, + gchar **result2) +{ + GnomeVFSHandle *handle; + GnomeVFSFileSize readlen; + GString *fullbuf; + char buf[2048]; + + *result1 = NULL; + if (key2) + *result2 = NULL; + + if (gnome_vfs_open (&handle, + entry_get_filename (entry), + GNOME_VFS_OPEN_READ) != GNOME_VFS_OK) + return; + + fullbuf = g_string_new (NULL); + while (gnome_vfs_read (handle, + buf, + sizeof (buf), + &readlen) == GNOME_VFS_OK) { + g_string_append_len (fullbuf, buf, readlen); + } + + gnome_vfs_close (handle); + + if (!fullbuf->len) { + g_string_free (fullbuf, TRUE); + return; + } + + entry_key_val_from_string (fullbuf->str, key1, result1); + + if (key2) + entry_key_val_from_string (fullbuf->str, key2, result2); + + g_string_free (fullbuf, TRUE); +} + +void +entry_dump (Entry *entry, int indent) +{ + gchar *space = g_strnfill (indent, ' '); + GSList *keywords = entry->keywords, *iter; + + D (g_print ("%s%s\n%s Filename: %s\n%s Keywords: ", + space, + entry_get_displayname (entry), + space, + entry_get_filename (entry), + space)); + + for (iter = keywords; iter; iter = iter->next) { + G_GNUC_UNUSED GQuark quark = GPOINTER_TO_INT (iter->data); + D (g_print (g_quark_to_string (quark))); + } + + D (g_print ("\n")); + + g_free (space); +} + + + +/* + * Folder Implementation + */ +Folder * +folder_new (VFolderInfo *info, const gchar *name, gboolean user_private) +{ + Folder *folder = g_new0 (Folder, 1); + + folder->name = g_strdup (name); + folder->user_private = user_private; + folder->info = info; + folder->refcnt = 1; + + folder->dirty = TRUE; + + return folder; +} + +void +folder_ref (Folder *folder) +{ + folder->refcnt++; +} + +static void +unalloc_exclude (gpointer key, gpointer val, gpointer user_data) +{ + gchar *filename = key; + VFolderInfo *info = user_data; + Entry *entry; + + /* Skip excludes which probably from the parent URI */ + if (strchr (filename, '/')) + return; + + entry = vfolder_info_lookup_entry (info, filename); + if (entry) + entry_dealloc (entry); +} + +static void +folder_reset_entries (Folder *folder) +{ + /* entries */ + g_slist_foreach (folder->entries, (GFunc) entry_dealloc, NULL); + g_slist_foreach (folder->entries, (GFunc) entry_unref, NULL); + g_slist_free (folder->entries); + folder->entries = NULL; + + if (folder->entries_ht) { + g_hash_table_destroy (folder->entries_ht); + folder->entries_ht = NULL; + } +} + +void +folder_unref (Folder *folder) +{ + folder->refcnt--; + + if (folder->refcnt == 0) { + D (g_print ("DESTORYING FOLDER: %p, %s\n", + folder, + folder->name)); + + g_free (folder->name); + g_free (folder->extend_uri); + g_free (folder->desktop_file); + + if (folder->extend_monitor) + vfolder_monitor_cancel (folder->extend_monitor); + + query_free (folder->query); + + if (folder->excludes) { + g_hash_table_foreach (folder->excludes, + (GHFunc) unalloc_exclude, + folder->info); + g_hash_table_destroy (folder->excludes); + } + + g_slist_foreach (folder->includes, (GFunc) g_free, NULL); + g_slist_free (folder->includes); + + /* subfolders */ + g_slist_foreach (folder->subfolders, + (GFunc) folder_unref, + NULL); + g_slist_free (folder->subfolders); + + if (folder->subfolders_ht) + g_hash_table_destroy (folder->subfolders_ht); + + folder_reset_entries (folder); + + g_free (folder); + } +} + +static gboolean read_one_extended_entry (Folder *folder, + const gchar *file_uri, + GnomeVFSFileInfo *file_info); + +static void +folder_extend_monitor_cb (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + Folder *folder = user_data; + FolderChild child; + GnomeVFSFileInfo *file_info; + GnomeVFSResult result; + GnomeVFSURI *uri, *entry_uri; + gchar *filename; + + /* Operating on the whole directory, ignore */ + if (!strcmp (monitor_uri, info_uri)) + return; + + D (g_print ("*** Exdended folder %s ('%s') monitor %s%s%s called! ***\n", + folder->name, + info_uri, + event_type == GNOME_VFS_MONITOR_EVENT_CREATED ? "CREATED":"", + event_type == GNOME_VFS_MONITOR_EVENT_DELETED ? "DELETED":"", + event_type == GNOME_VFS_MONITOR_EVENT_CHANGED ? "CHANGED":"")); + + uri = gnome_vfs_uri_new (info_uri); + filename = gnome_vfs_uri_extract_short_name (uri); + + VFOLDER_INFO_WRITE_LOCK (folder->info); + + switch (event_type) { + case GNOME_VFS_MONITOR_EVENT_CHANGED: + /* + * We only care about entries here, as the extend_monitor_cb on + * the subfolders themselves should take care of emitting + * changes. + */ + child.entry = folder_get_entry (folder, filename); + if (child.entry) { + entry_uri = entry_get_real_uri (child.entry); + + if (gnome_vfs_uri_equal (entry_uri, uri)) { + entry_set_dirty (child.entry); + folder_emit_changed ( + folder, + entry_get_displayname (child.entry), + GNOME_VFS_MONITOR_EVENT_CHANGED); + } + + gnome_vfs_uri_unref (entry_uri); + } + break; + case GNOME_VFS_MONITOR_EVENT_DELETED: + folder_get_child (folder, filename, &child); + + /* + * FIXME: should look for replacement in info's entry + * pool here, before sending event + */ + + if (child.type == DESKTOP_FILE) { + entry_uri = entry_get_real_uri (child.entry); + + if (gnome_vfs_uri_equal (uri, entry_uri)) { + folder_remove_entry (folder, child.entry); + folder_emit_changed ( + folder, + filename, + GNOME_VFS_MONITOR_EVENT_DELETED); + } + + gnome_vfs_uri_unref (entry_uri); + } + else if (child.type == FOLDER) { + if (folder_is_user_private (child.folder)) { + folder_set_dirty (child.folder); + } else { + folder_remove_subfolder (folder, child.folder); + folder_emit_changed ( + folder, + filename, + GNOME_VFS_MONITOR_EVENT_DELETED); + } + } + break; + case GNOME_VFS_MONITOR_EVENT_CREATED: + file_info = gnome_vfs_file_info_new (); + result = + gnome_vfs_get_file_info_uri ( + uri, + file_info, + GNOME_VFS_FILE_INFO_DEFAULT); + + if (result == GNOME_VFS_OK && + read_one_extended_entry (folder, info_uri, file_info)) + folder_emit_changed (folder, + file_info->name, + GNOME_VFS_MONITOR_EVENT_CREATED); + + gnome_vfs_file_info_unref (file_info); + break; + default: + break; + } + + folder->info->modification_time = time (NULL); + + VFOLDER_INFO_WRITE_UNLOCK (folder->info); + + gnome_vfs_uri_unref (uri); + g_free (filename); +} + +gboolean +folder_make_user_private (Folder *folder) +{ + if (folder->user_private) + return TRUE; + + if (folder->parent) { + if (folder->parent->read_only || + !folder_make_user_private (folder->parent)) + return FALSE; + + if (!folder->parent->has_user_private_subfolders) { + Folder *iter; + + for (iter = folder->parent; iter; iter = iter->parent) + iter->has_user_private_subfolders = TRUE; + } + } + + folder->user_private = TRUE; + + vfolder_info_set_dirty (folder->info); + + return TRUE; +} + +gboolean +folder_is_user_private (Folder *folder) +{ + return folder->user_private; +} + +static gboolean +create_dot_directory_entry (Folder *folder) +{ + Entry *entry = NULL, *existing; + const gchar *dot_directory = folder_get_desktop_file (folder); + + /* Only replace if existing isn't user-private */ + existing = folder_get_entry (folder, ".directory"); + if (existing && entry_get_weight (existing) == 1000) + return FALSE; + + if (strchr (dot_directory, '/')) { + /* Assume full path or URI */ + entry = entry_new (folder->info, + dot_directory, + ".directory", + TRUE /*user_private*/, + 950 /*weight*/); + } else { + gchar *dirpath = NULL; + gchar *full_path; + + if (folder->info->desktop_dir) + dirpath = folder->info->desktop_dir; + else if (folder->info->write_dir) + dirpath = folder->info->write_dir; + else + return FALSE; + + if (dirpath) { + full_path = vfolder_build_uri (dirpath, + dot_directory, + NULL); + entry = entry_new (folder->info, + full_path, + ".directory", + TRUE /*user_private*/, + 950 /*weight*/); + g_free (full_path); + } + } + + if (entry) { + folder_add_entry (folder, entry); + entry_unref (entry); + } + + return entry != NULL; +} + +static gboolean +read_one_include (Folder *folder, const gchar *file_uri) +{ + Entry *entry = NULL, *existing; + GnomeVFSURI *uri; + gchar *basename, *basename_ts; + + if (!strchr (file_uri, '/')) { + entry = vfolder_info_lookup_entry (folder->info, file_uri); + if (entry && entry != folder_get_entry (folder, file_uri)) { + folder_add_entry (folder, entry); + return TRUE; + } + return FALSE; + } + else { + uri = gnome_vfs_uri_new (file_uri); + if (!uri || !gnome_vfs_uri_exists (uri)) + return FALSE; + + basename = gnome_vfs_uri_extract_short_name (uri); + + /* If including something from the WriteDir, untimestamp it. */ + if (folder->info->write_dir && + strstr (file_uri, folder->info->write_dir)) { + basename_ts = basename; + basename = vfolder_untimestamp_file_name (basename_ts); + g_free (basename_ts); + } + + /* Only replace if existing is not user-private */ + existing = folder_get_entry (folder, basename); + if (existing && entry_get_weight (existing) == 1000) { + gnome_vfs_uri_unref (uri); + g_free (basename); + return FALSE; + } + + entry = entry_new (folder->info, + file_uri, + basename, + TRUE, + 1000 /*weight*/); + folder_add_entry (folder, entry); + + entry_unref (entry); + gnome_vfs_uri_unref (uri); + g_free (basename); + + return TRUE; + } +} + +static gboolean +read_includes (Folder *folder) +{ + GSList *iter; + gboolean changed = FALSE; + + for (iter = folder->includes; iter; iter = iter->next) { + gchar *include = iter->data; + + changed |= read_one_include (folder, include); + } + + return changed; +} + +static gboolean +is_excluded (Folder *folder, const gchar *filename, const gchar *displayname) +{ + if (!folder->excludes) + return FALSE; + + if (displayname && g_hash_table_lookup (folder->excludes, displayname)) + return TRUE; + + if (filename && g_hash_table_lookup (folder->excludes, filename)) + return TRUE; + + return FALSE; +} + +static gboolean +read_one_extended_entry (Folder *folder, + const gchar *file_uri, + GnomeVFSFileInfo *file_info) +{ + Query *query = folder_get_query (folder); + + if (is_excluded (folder, file_uri, file_info->name)) + return FALSE; + + if (file_info->type == GNOME_VFS_FILE_TYPE_DIRECTORY) { + Folder *sub; + + if (folder_get_subfolder (folder, file_info->name)) + return FALSE; + + sub = folder_new (folder->info, file_info->name, FALSE); + + folder_set_extend_uri (sub, file_uri); + sub->is_link = folder->is_link; + + folder_add_subfolder (folder, sub); + folder_unref (sub); + + return TRUE; + } else { + Entry *entry, *existing; + gboolean retval = FALSE; + + /* Only replace if entry is more important than existing */ + existing = folder_get_entry (folder, file_info->name); + if (existing && entry_get_weight (existing) >= 900) + return FALSE; + + entry = entry_new (folder->info, + file_uri, + file_info->name, + FALSE /*user_private*/, + 900 /*weight*/); + + /* Include unless specifically excluded by query */ + if (!query || query_try_match (query, folder, entry)) { + D (g_print ("ADDING EXTENDED ENTRY: " + "%s, %s, #%d!\n", + folder_get_name (folder), + entry_get_displayname (entry), + g_slist_length ((GSList*) + folder_list_entries (folder)))); + + folder_add_entry (folder, entry); + retval = TRUE; + } + + entry_unref (entry); + return retval; + } +} + +static gboolean +read_extended_entries (Folder *folder) +{ + GnomeVFSResult result; + GnomeVFSDirectoryHandle *handle; + GnomeVFSFileInfo *file_info; + const gchar *extend_uri; + gboolean changed = FALSE; + + extend_uri = folder_get_extend_uri (folder); + + result = gnome_vfs_directory_open (&handle, + extend_uri, + GNOME_VFS_FILE_INFO_DEFAULT); + if (result != GNOME_VFS_OK) + return FALSE; + + file_info = gnome_vfs_file_info_new (); + + while (TRUE) { + gchar *file_uri; + + result = gnome_vfs_directory_read_next (handle, file_info); + if (result != GNOME_VFS_OK) + break; + + if (!strcmp (file_info->name, ".") || + !strcmp (file_info->name, "..")) + continue; + + file_uri = vfolder_build_uri (extend_uri, + file_info->name, + NULL); + + changed |= read_one_extended_entry (folder, + file_uri, + file_info); + + g_free (file_uri); + } + + gnome_vfs_file_info_unref (file_info); + gnome_vfs_directory_close (handle); + + return changed; +} + +static gboolean +read_one_info_entry_pool (Folder *folder, Entry *entry) +{ + Query *query = folder_get_query (folder); + Entry *existing; + + if (is_excluded (folder, + entry_get_filename (entry), + entry_get_displayname (entry))) { + /* + * Being excluded counts as a ref because we don't want + * them showing up in the Others menu. + */ + entry_alloc (entry); + return FALSE; + } + + /* Only replace if entry is more important than existing */ + existing = folder_get_entry (folder, entry_get_displayname (entry)); + if (existing && entry_get_weight (existing) >= entry_get_weight (entry)) + return FALSE; + + /* Only include if matches a mandatory query. */ + if (query && query_try_match (query, folder, entry)) { + D (g_print ("ADDING POOL ENTRY: %s, %s, #%d!!!!\n", + folder_get_name (folder), + entry_get_displayname (entry), + g_slist_length ( + (GSList*) folder_list_entries (folder)))); + + folder_add_entry (folder, entry); + + return TRUE; + } else + return FALSE; +} + +static gboolean +read_info_entry_pool (Folder *folder) +{ + const GSList *all_entries, *iter; + Query *query; + gboolean changed = FALSE; + + if (folder->only_unallocated) + return FALSE; + + query = folder_get_query (folder); + all_entries = vfolder_info_list_all_entries (folder->info); + + for (iter = all_entries; iter; iter = iter->next) { + Entry *entry = iter->data; + + changed |= read_one_info_entry_pool (folder, entry); + } + + return changed; +} + +void +folder_emit_changed (Folder *folder, + const gchar *child, + GnomeVFSMonitorEventType event_type) +{ + Folder *iter; + GString *buf; + + buf = g_string_new (NULL); + + if (child) { + g_string_prepend (buf, child); + g_string_prepend_c (buf, '/'); + } + + for (iter = folder; + iter != NULL && iter != folder->info->root; + iter = iter->parent) { + g_string_prepend (buf, folder_get_name (iter)); + g_string_prepend_c (buf, '/'); + } + + vfolder_info_emit_change (folder->info, + buf->len ? buf->str : "/", + event_type); + + g_string_free (buf, TRUE); +} + +static void +remove_extended_subfolders (Folder *folder) +{ + GSList *iter, *copy; + Folder *sub; + + copy = g_slist_copy ((GSList *) folder_list_subfolders (folder)); + for (iter = copy; iter; iter = iter->next) { + sub = iter->data; + if (!folder_is_user_private (sub)) + folder_remove_subfolder (folder, sub); + } + g_slist_free (copy); +} + +static void +folder_reload_if_needed (Folder *folder) +{ + gboolean changed = FALSE; + + if (!folder->dirty || folder->loading) + return; + + D (g_print ("----- RELOADING FOLDER: %s -----\n", + folder->name)); + + folder->loading = TRUE; + folder->info->loading = TRUE; + + folder_reset_entries (folder); + remove_extended_subfolders (folder); + + if (folder_get_desktop_file (folder)) + changed |= create_dot_directory_entry (folder); + + if (folder->includes) + changed |= read_includes (folder); + + if (folder_get_extend_uri (folder)) { + changed |= read_extended_entries (folder); + + /* Start monitoring here, to cut down on unneeded events */ + if (!folder->extend_monitor) + folder->extend_monitor = + vfolder_monitor_dir_new ( + folder_get_extend_uri (folder), + folder_extend_monitor_cb, + folder); + } + + if (folder_get_query (folder)) + changed |= read_info_entry_pool (folder); + + if (changed) + folder_emit_changed (folder, + NULL, + GNOME_VFS_MONITOR_EVENT_CHANGED); + + folder->info->loading = FALSE; + folder->loading = FALSE; + folder->dirty = FALSE; +} + +void +folder_set_dirty (Folder *folder) +{ + folder->dirty = TRUE; +} + +void +folder_set_name (Folder *folder, const gchar *name) +{ + g_free (folder->name); + folder->name = g_strdup (name); + + vfolder_info_set_dirty (folder->info); +} + +const gchar * +folder_get_name (Folder *folder) +{ + return folder->name; +} + +void +folder_set_query (Folder *folder, Query *query) +{ + if (folder->query) + query_free (folder->query); + + folder->query = query; + + folder_set_dirty (folder); + vfolder_info_set_dirty (folder->info); +} + +Query * +folder_get_query (Folder *folder) +{ + return folder->query; +} + +void +folder_set_extend_uri (Folder *folder, const gchar *uri) +{ + g_free (folder->extend_uri); + folder->extend_uri = g_strdup (uri); + + if (folder->extend_monitor) { + vfolder_monitor_cancel (folder->extend_monitor); + folder->extend_monitor = NULL; + } + + folder_set_dirty (folder); + vfolder_info_set_dirty (folder->info); +} + +const gchar * +folder_get_extend_uri (Folder *folder) +{ + return folder->extend_uri; +} + +void +folder_set_desktop_file (Folder *folder, const gchar *filename) +{ + g_free (folder->desktop_file); + folder->desktop_file = g_strdup (filename); + + vfolder_info_set_dirty (folder->info); +} + +const gchar * +folder_get_desktop_file (Folder *folder) +{ + return folder->desktop_file; +} + +gboolean +folder_get_child (Folder *folder, const gchar *name, FolderChild *child) +{ + Folder *subdir; + Entry *file; + + memset (child, 0, sizeof (FolderChild)); + + if (name) + subdir = folder_get_subfolder (folder, name); + else + /* No name, just return the parent folder */ + subdir = folder; + + if (subdir) { + child->type = FOLDER; + child->folder = subdir; + return TRUE; + } + + file = folder_get_entry (folder, name); + if (file) { + child->type = DESKTOP_FILE; + child->entry = file; + return TRUE; + } + + return FALSE; +} + +static void +child_list_foreach_prepend (gpointer key, + gpointer val, + gpointer user_data) +{ + gchar *name = key; + GSList **list = user_data; + + *list = g_slist_prepend (*list, g_strdup (name)); +} + +static GSList * +child_list_prepend_sorted (gchar *sortorder, + GHashTable *name_hash) +{ + GSList *ret = NULL; + gchar **split_ord; + int i; + + if (!sortorder) + return NULL; + + split_ord = g_strsplit (sortorder, ":", -1); + if (split_ord && split_ord [0]) { + for (i = 0; split_ord [i]; i++) { + gchar *name = split_ord [i]; + + if (g_hash_table_lookup (name_hash, name)) { + g_hash_table_remove (name_hash, name); + ret = g_slist_prepend (ret, g_strdup (name)); + } + } + } + + return ret; +} + +GSList * +folder_list_children (Folder *folder) +{ + Entry *dot_directory; + GHashTable *name_hash; + const GSList *iter; + GSList *list = NULL; + + /* FIXME: handle duplicate names here, by not using a hashtable */ + + name_hash = g_hash_table_new (g_str_hash, g_str_equal); + + for (iter = folder_list_subfolders (folder); iter; iter = iter->next) { + Folder *child = iter->data; + g_hash_table_insert (name_hash, + (gchar *) folder_get_name (child), + NULL); + } + + for (iter = folder_list_entries (folder); iter; iter = iter->next) { + Entry *entry = iter->data; + g_hash_table_insert (name_hash, + (gchar *) entry_get_displayname (entry), + NULL); + } + + if (folder->only_unallocated) { + Query *query = folder_get_query (folder); + + iter = vfolder_info_list_all_entries (folder->info); + for (; iter; iter = iter->next) { + Entry *entry = iter->data; + + if (entry_is_allocated (entry)) + continue; + + if (query && !query_try_match (query, folder, entry)) + continue; + + g_hash_table_insert ( + name_hash, + (gchar *) entry_get_displayname (entry), + NULL); + } + } + + dot_directory = folder_get_entry (folder, ".directory"); + if (dot_directory) { + gchar *sortorder; + entry_quick_read_keys (dot_directory, + "SortOrder", + &sortorder, + NULL, + NULL); + if (sortorder) { + list = child_list_prepend_sorted (sortorder, + name_hash); + g_free (sortorder); + } + } + + g_hash_table_foreach (name_hash, + (GHFunc) child_list_foreach_prepend, + &list); + g_hash_table_destroy (name_hash); + + list = g_slist_reverse (list); + + return list; +} + +Entry * +folder_get_entry (Folder *folder, const gchar *filename) +{ + Entry *retval = NULL; + + folder_reload_if_needed (folder); + + if (folder->entries_ht) + retval = g_hash_table_lookup (folder->entries_ht, filename); + + if (!retval && folder->only_unallocated) + retval = vfolder_info_lookup_entry (folder->info, filename); + + return retval; +} + +const GSList * +folder_list_entries (Folder *folder) +{ + folder_reload_if_needed (folder); + + return folder->entries; +} + +/* + * This doesn't set the folder dirty. + * Use the include/exclude functions for that. + */ +void +folder_remove_entry (Folder *folder, Entry *entry) +{ + const gchar *name; + Entry *existing; + + if (!folder->entries_ht) + return; + + name = entry_get_displayname (entry); + existing = g_hash_table_lookup (folder->entries_ht, name); + if (existing) { + g_hash_table_remove (folder->entries_ht, name); + folder->entries = g_slist_remove (folder->entries, existing); + + entry_dealloc (existing); + entry_unref (existing); + } +} + +/* + * This doesn't set the folder dirty. + * Use the include/exclude functions for that. + */ +void +folder_add_entry (Folder *folder, Entry *entry) +{ + entry_alloc (entry); + entry_ref (entry); + + folder_remove_entry (folder, entry); + + if (!folder->entries_ht) + folder->entries_ht = g_hash_table_new (g_str_hash, g_str_equal); + + g_hash_table_insert (folder->entries_ht, + (gchar *) entry_get_displayname (entry), + entry); + folder->entries = g_slist_append (folder->entries, entry); +} + +void +folder_add_include (Folder *folder, const gchar *include) +{ + folder_remove_exclude (folder, include); + + folder->includes = g_slist_prepend (folder->includes, + g_strdup (include)); + + vfolder_info_set_dirty (folder->info); +} + +void +folder_remove_include (Folder *folder, const gchar *file) +{ + GSList *li; + + if (!folder->includes) + return; + + li = g_slist_find_custom (folder->includes, + file, + (GCompareFunc) strcmp); + if (li) { + folder->includes = g_slist_delete_link (folder->includes, li); + vfolder_info_set_dirty (folder->info); + } +} + +void +folder_add_exclude (Folder *parent, const gchar *exclude) +{ + char *s; + + folder_remove_include (parent, exclude); + + if (!parent->excludes) + parent->excludes = + g_hash_table_new_full (g_str_hash, + g_str_equal, + (GDestroyNotify) g_free, + NULL); + + s = g_strdup (exclude); + g_hash_table_replace (parent->excludes, s, s); + + vfolder_info_set_dirty (parent->info); +} + +void +folder_remove_exclude (Folder *folder, const gchar *file) +{ + if (!folder->excludes) + return; + + g_hash_table_remove (folder->excludes, file); + + vfolder_info_set_dirty (folder->info); +} + +Folder * +folder_get_subfolder (Folder *folder, const gchar *name) +{ + folder_reload_if_needed (folder); + + if (!folder->subfolders_ht) + return NULL; + + return g_hash_table_lookup (folder->subfolders_ht, name); +} + +const GSList * +folder_list_subfolders (Folder *parent) +{ + folder_reload_if_needed (parent); + + return parent->subfolders; +} + +void +folder_remove_subfolder (Folder *parent, Folder *child) +{ + const gchar *name; + Folder *existing; + + if (!parent->subfolders_ht) + return; + + name = folder_get_name (child); + existing = g_hash_table_lookup (parent->subfolders_ht, name); + if (existing) { + g_hash_table_remove (parent->subfolders_ht, name); + parent->subfolders = g_slist_remove (parent->subfolders, + existing); + existing->parent = NULL; + folder_unref (existing); + vfolder_info_set_dirty (parent->info); + } +} + +void +folder_add_subfolder (Folder *parent, Folder *child) +{ + if (child->user_private && !parent->has_user_private_subfolders) { + Folder *iter; + for (iter = parent; iter != NULL; iter = iter->parent) + iter->has_user_private_subfolders = TRUE; + } + + folder_ref (child); + child->parent = parent; + + if (!parent->subfolders_ht) + parent->subfolders_ht = g_hash_table_new (g_str_hash, + g_str_equal); + else + folder_remove_subfolder (parent, child); + + g_hash_table_insert (parent->subfolders_ht, + (gchar *) folder_get_name (child), + child); + parent->subfolders = g_slist_append (parent->subfolders, child); + + vfolder_info_set_dirty (parent->info); +} + +void +folder_dump_tree (Folder *folder, int indent) +{ + const GSList *iter; + gchar *space = g_strnfill (indent, ' '); + + D (g_print ("%s(%p): %s\n", + space, + folder, + folder ? folder_get_name (folder) : NULL)); + + g_free (space); + + for (iter = folder_list_subfolders (folder); iter; iter = iter->next) { + Folder *child = iter->data; + + folder_dump_tree (child, indent + 2); + } +} + +/* This is a pretty lame hack */ +gboolean +folder_is_hidden (Folder *folder) +{ + const GSList *iter, *ents; + + if (folder->dont_show_if_empty == FALSE) + return FALSE; + + if (folder->only_unallocated) { + Query *query = folder_get_query (folder); + + iter = vfolder_info_list_all_entries (folder->info); + for (; iter; iter = iter->next) { + Entry *entry = iter->data; + + if (entry_is_allocated (entry)) + continue; + + if (query && !query_try_match (query, folder, entry)) + continue; + + return FALSE; + } + } + + ents = folder_list_entries (folder); + if (ents) { + /* If there is only one entry, check it is not .directory */ + if (!ents->next) { + Entry *dot_directory = ents->data; + const gchar *name; + + name = entry_get_displayname (dot_directory); + if (strcmp (".directory", name) != 0) + return FALSE; + } else + return FALSE; + } + + for (iter = folder_list_subfolders (folder); iter; iter = iter->next) { + Folder *child = iter->data; + + if (!folder_is_hidden (child)) + return FALSE; + } + + return TRUE; +} + + + +/* + * Query Implementation + */ +Query * +query_new (int type) +{ + Query *query; + + query = g_new0 (Query, 1); + query->type = type; + + return query; +} + +void +query_free (Query *query) +{ + if (query == NULL) + return; + + if (query->type == QUERY_OR || query->type == QUERY_AND) { + g_slist_foreach (query->val.queries, + (GFunc) query_free, + NULL); + g_slist_free (query->val.queries); + } + else if (query->type == QUERY_FILENAME) + g_free (query->val.filename); + + g_free (query); +} + +#define INVERT_IF_NEEDED(val) (query->not ? !(val) : (val)) + +gboolean +query_try_match (Query *query, + Folder *folder, + Entry *efile) +{ + GSList *li; + + if (query == NULL) + return TRUE; + + switch (query->type) { + case QUERY_OR: + for (li = query->val.queries; li != NULL; li = li->next) { + Query *subquery = li->data; + + if (query_try_match (subquery, folder, efile)) + return INVERT_IF_NEEDED (TRUE); + } + return INVERT_IF_NEEDED (FALSE); + case QUERY_AND: + for (li = query->val.queries; li != NULL; li = li->next) { + Query *subquery = li->data; + + if (!query_try_match (subquery, folder, efile)) + return INVERT_IF_NEEDED (FALSE); + } + return INVERT_IF_NEEDED (TRUE); + case QUERY_PARENT: + { + const gchar *extend_uri; + + /* + * Check that entry's path starts with that of the + * folder's extend_uri, so that we know that it matches + * the parent query. + */ + extend_uri = folder_get_extend_uri (folder); + if (extend_uri && + strncmp (entry_get_filename (efile), + extend_uri, + strlen (extend_uri)) == 0) + return INVERT_IF_NEEDED (TRUE); + else + return INVERT_IF_NEEDED (FALSE); + } + case QUERY_KEYWORD: + { + const GSList *keywords; + GQuark keyword; + + keywords = entry_get_keywords (efile); + for (; keywords; keywords = keywords->next) { + keyword = GPOINTER_TO_INT (keywords->data); + if (keyword == query->val.keyword) + return INVERT_IF_NEEDED (TRUE); + } + } + return INVERT_IF_NEEDED (FALSE); + case QUERY_FILENAME: + if (strchr (query->val.filename, '/') && + !strcmp (query->val.filename, entry_get_filename (efile))) + return INVERT_IF_NEEDED (TRUE); + else if (!strcmp (query->val.filename, + entry_get_displayname (efile))) + return INVERT_IF_NEEDED (TRUE); + else + return INVERT_IF_NEEDED (FALSE); + } + + g_assert_not_reached (); + return FALSE; +} diff --git a/modules/vfolder/vfolder-common.h b/modules/vfolder/vfolder-common.h new file mode 100644 index 0000000..46827db --- /dev/null +++ b/modules/vfolder/vfolder-common.h @@ -0,0 +1,363 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* + * vfolder-common.h - Abstract Folder, Entry, Query, and VFolderInfo + * interfaces. + * + * Copyright (C) 2002 Ximian, Inc. + * + * The Gnome Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Gnome Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Alex Graveley + * Based on original code by George Lebl . + */ + +#ifndef VFOLDER_COMMON_H +#define VFOLDER_COMMON_H + +#include +#include +#include + +#include "vfolder-util.h" + +G_BEGIN_DECLS + +/* Turn this on to test the non-FAM monitoring code + */ +#undef VFOLDER_DEBUG_WITHOUT_MONITORING + +/* Turn this on to spew debugging info + */ +#undef VFOLDER_DEBUG + +#ifdef VFOLDER_DEBUG +#define D(x) x +#else +#define D(x) do {} while (0) +#endif + +typedef struct _VFolderInfo VFolderInfo; +typedef struct _Query Query; +typedef struct _Folder Folder; + +/* + * Entry API + */ +typedef struct { + gushort refcnt; + gushort allocs; + + /* + * Weight lets us determine if a monitor's file created (or changed) + * event should replace an existing visible entry. Higher weights + * are more valuable: + * 1000 - WriteDir entries + * 900 - folder parent entries + * 800 - GNOME2_PATH entries in order + * 700 - MergeDir/ItemDir entries in order + */ + gushort weight; + + VFolderInfo *info; + + char *displayname; + char *filename; + GnomeVFSURI *uri; + + GSList *keywords; /* GQuark */ + GSList *implicit_keywords; /* GQuark */ + + guint dirty : 1; + guint user_private : 1; + guint not_shown : 1; /* OnlyShowIn=SomeOtherDesktop */ +} Entry; + +Entry *entry_new (VFolderInfo *info, + const gchar *filename, + const gchar *displayname, + gboolean user_private, + gushort weight); + +void entry_ref (Entry *entry); +void entry_unref (Entry *entry); + +void entry_alloc (Entry *entry); +void entry_dealloc (Entry *entry); +gboolean entry_is_allocated (Entry *entry); + +gboolean entry_make_user_private (Entry *entry, Folder *folder); +gboolean entry_is_user_private (Entry *entry); + +gushort entry_get_weight (Entry *entry); +void entry_set_weight (Entry *entry, gushort weight); + +void entry_set_dirty (Entry *entry); + +void entry_set_filename (Entry *entry, const gchar *name); +const gchar *entry_get_filename (Entry *entry); + +void entry_set_displayname (Entry *entry, const gchar *name); +const gchar *entry_get_displayname (Entry *entry); + +GnomeVFSURI *entry_get_real_uri (Entry *entry); + +const GSList *entry_get_keywords (Entry *entry); +void entry_add_implicit_keyword (Entry *entry, GQuark keyword); + +void entry_quick_read_keys (Entry *entry, + const gchar *key1, + gchar **value1, + const gchar *key2, + gchar **value2, + const gchar *key3, + gchar **value3); + +void entry_dump (Entry *entry, int indent); + + +/* + * Folder API + */ +struct _Folder { + gint refcnt; + + VFolderInfo *info; + + char *name; + + gchar *extend_uri; + VFolderMonitor *extend_monitor; + + Folder *parent; + + char *desktop_file; /* the .directory file */ + + Query *query; + + /* The following is for per file access */ + GHashTable *excludes; /* excluded by dirname/fileuri */ + GSList *includes; /* included by dirname/fileuri */ + + GSList *subfolders; + GHashTable *subfolders_ht; + + GSList *entries; + GHashTable *entries_ht; + + /* Some flags */ + guint read_only : 1; + guint dont_show_if_empty : 1; + guint only_unallocated : 1; /* include only unallocated */ + guint is_link : 1; + + guint has_user_private_subfolders : 1; + guint user_private : 1; + + /* lazily done, will run query only when it needs to */ + guint dirty : 1; + guint loading : 1; + guint sorted : 1; +}; + +typedef struct { + enum { + FOLDER = 1, + DESKTOP_FILE, + UNKNOWN_URI + } type; + + Folder *folder; + Entry *entry; + GnomeVFSURI *uri; +} FolderChild; + +Folder *folder_new (VFolderInfo *info, + const gchar *name, + gboolean user_private); + +void folder_ref (Folder *folder); +void folder_unref (Folder *folder); + +gboolean folder_make_user_private (Folder *folder); +gboolean folder_is_user_private (Folder *folder); + +void folder_set_dirty (Folder *folder); + +void folder_set_name (Folder *folder, const gchar *name); +const gchar *folder_get_name (Folder *folder); + +void folder_set_query (Folder *folder, Query *query); +Query *folder_get_query (Folder *folder); + +void folder_set_extend_uri (Folder *folder, const gchar *uri); +const gchar *folder_get_extend_uri (Folder *folder); + +void folder_set_desktop_file (Folder *folder, const gchar *filename); +const gchar *folder_get_desktop_file (Folder *folder); + +gboolean folder_get_child (Folder *folder, + const gchar *name, + FolderChild *child); +GSList *folder_list_children (Folder *folder); + +Entry *folder_get_entry (Folder *folder, const gchar *filename); +const GSList *folder_list_entries (Folder *folder); +void folder_remove_entry (Folder *folder, Entry *entry); +void folder_add_entry (Folder *folder, Entry *entry); + +void folder_add_include (Folder *folder, const gchar *file); +void folder_remove_include (Folder *folder, const gchar *file); + +void folder_add_exclude (Folder *folder, const gchar *file); +void folder_remove_exclude (Folder *folder, const gchar *file); + +Folder *folder_get_subfolder (Folder *folder, const gchar *name); +const GSList *folder_list_subfolders (Folder *folder); +void folder_remove_subfolder (Folder *folder, Folder *sub); +void folder_add_subfolder (Folder *folder, Folder *sub); + +gboolean folder_is_hidden (Folder *folder); + +void folder_dump_tree (Folder *folder, int indent); + +void folder_emit_changed (Folder *folder, + const gchar *child, + GnomeVFSMonitorEventType event_type); + + +/* + * Query API + */ +struct _Query { + enum { + QUERY_OR, + QUERY_AND, + QUERY_PARENT, + QUERY_KEYWORD, + QUERY_FILENAME + } type; + union { + GSList *queries; + GQuark keyword; + gchar *filename; + } val; + guint not : 1; +}; + +Query *query_new (int type); + +void query_free (Query *query); + +gboolean query_try_match (Query *query, + Folder *folder, + Entry *efile); + +/* + * VFolderInfo API + */ +/* NOTE: Exposed only so do_monitor_cancel can lock the VFolderInfo */ +typedef struct { + GnomeVFSURI *uri; + GnomeVFSMonitorType type; + VFolderInfo *info; +} MonitorHandle; + +struct _VFolderInfo { + GStaticRWLock rw_lock; + + char *scheme; + + char *filename; + VFolderMonitor *filename_monitor; + guint filename_reload_tag; + + /* dir where user changes to items are stored */ + char *write_dir; + VFolderMonitor *write_dir_monitor; + + /* deprecated */ + char *desktop_dir; /* directory with .directorys */ + VFolderMonitor *desktop_dir_monitor; + + /* Consider item dirs and mergedirs writeable?? */ + /* Monitoring on mergedirs?? */ + GSList *item_dirs; /* CONTAINS: ItemDir */ + + GSList *entries; /* CONTAINS: Entry */ + GHashTable *entries_ht; /* KEY: Entry->name, VALUE: Entry */ + + /* The root folder */ + Folder *root; + + /* some flags */ + guint read_only : 1; + guint dirty : 1; + guint loading : 1; + guint has_unallocated_folder : 1; + + GSList *requested_monitors; /* CONTAINS: MonitorHandle */ + + /* ctime for folders */ + time_t modification_time; +}; + +#define VFOLDER_INFO_READ_LOCK(vi) \ + g_static_rw_lock_reader_lock (&(vi->rw_lock)) +#define VFOLDER_INFO_READ_UNLOCK(vi) \ + g_static_rw_lock_reader_unlock (&(vi->rw_lock)) + +#define VFOLDER_INFO_WRITE_LOCK(vi) \ + g_static_rw_lock_writer_lock (&(vi->rw_lock)) +/* Writes out .vfolder-info file if there are changes */ +#define VFOLDER_INFO_WRITE_UNLOCK(vi) \ + vfolder_info_write_user (vi); \ + g_static_rw_lock_writer_unlock (&(vi->rw_lock)) + +VFolderInfo *vfolder_info_locate (const gchar *scheme); + +void vfolder_info_set_dirty (VFolderInfo *info); +void vfolder_info_write_user (VFolderInfo *info); + +Folder *vfolder_info_get_folder (VFolderInfo *info, + const gchar *path); +Folder *vfolder_info_get_parent (VFolderInfo *info, + const gchar *path); +Entry *vfolder_info_get_entry (VFolderInfo *info, + const gchar *path); + +const GSList *vfolder_info_list_all_entries (VFolderInfo *info); +Entry *vfolder_info_lookup_entry (VFolderInfo *info, + const gchar *name); +void vfolder_info_add_entry (VFolderInfo *info, Entry *entry); +void vfolder_info_remove_entry (VFolderInfo *info, Entry *entry); + +void vfolder_info_emit_change (VFolderInfo *info, + const char *path, + GnomeVFSMonitorEventType event_type); + +void vfolder_info_add_monitor (VFolderInfo *info, + GnomeVFSMonitorType type, + GnomeVFSURI *path, + GnomeVFSMethodHandle **handle); +void vfolder_info_cancel_monitor (GnomeVFSMethodHandle *handle); + +void vfolder_info_destroy_all (void); + +void vfolder_info_dump_entries (VFolderInfo *info, int offset); + +G_END_DECLS + +#endif /* VFOLDER_COMMON_H */ diff --git a/modules/vfolder/vfolder-common.h.vfolder-hacks b/modules/vfolder/vfolder-common.h.vfolder-hacks new file mode 100644 index 0000000..9acaba9 --- /dev/null +++ b/modules/vfolder/vfolder-common.h.vfolder-hacks @@ -0,0 +1,360 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* + * vfolder-common.h - Abstract Folder, Entry, Query, and VFolderInfo + * interfaces. + * + * Copyright (C) 2002 Ximian, Inc. + * + * The Gnome Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Gnome Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Alex Graveley + * Based on original code by George Lebl . + */ + +#ifndef VFOLDER_COMMON_H +#define VFOLDER_COMMON_H + +#include +#include +#include + +#include "vfolder-util.h" + +G_BEGIN_DECLS + +/* Turn this on to test the non-FAM monitoring code + */ +#undef VFOLDER_DEBUG_WITHOUT_MONITORING + +/* Turn this on to spew debugging info + */ +#undef VFOLDER_DEBUG + +#ifdef VFOLDER_DEBUG +#define D(x) x +#else +#define D(x) do {} while (0) +#endif + +typedef struct _VFolderInfo VFolderInfo; +typedef struct _Query Query; +typedef struct _Folder Folder; + +/* + * Entry API + */ +typedef struct { + gushort refcnt; + gushort allocs; + + /* + * Weight lets us determine if a monitor's file created (or changed) + * event should replace an existing visible entry. Higher weights + * are more valuable: + * 1000 - WriteDir entries + * 900 - folder parent entries + * 800 - GNOME2_PATH entries in order + * 700 - MergeDir/ItemDir entries in order + */ + gushort weight; + + VFolderInfo *info; + + char *displayname; + char *filename; + GnomeVFSURI *uri; + + GSList *keywords; /* GQuark */ + GSList *implicit_keywords; /* GQuark */ + + guint dirty : 1; + guint user_private : 1; +} Entry; + +Entry *entry_new (VFolderInfo *info, + const gchar *filename, + const gchar *displayname, + gboolean user_private, + gushort weight); + +void entry_ref (Entry *entry); +void entry_unref (Entry *entry); + +void entry_alloc (Entry *entry); +void entry_dealloc (Entry *entry); +gboolean entry_is_allocated (Entry *entry); + +gboolean entry_make_user_private (Entry *entry, Folder *folder); +gboolean entry_is_user_private (Entry *entry); + +gushort entry_get_weight (Entry *entry); +void entry_set_weight (Entry *entry, gushort weight); + +void entry_set_dirty (Entry *entry); + +void entry_set_filename (Entry *entry, const gchar *name); +const gchar *entry_get_filename (Entry *entry); + +void entry_set_displayname (Entry *entry, const gchar *name); +const gchar *entry_get_displayname (Entry *entry); + +GnomeVFSURI *entry_get_real_uri (Entry *entry); + +const GSList *entry_get_keywords (Entry *entry); +void entry_add_implicit_keyword (Entry *entry, GQuark keyword); + +void entry_quick_read_keys (Entry *entry, + const gchar *key1, + gchar **value1, + const gchar *key2, + gchar **value2); + +void entry_dump (Entry *entry, int indent); + + +/* + * Folder API + */ +struct _Folder { + gint refcnt; + + VFolderInfo *info; + + char *name; + + gchar *extend_uri; + VFolderMonitor *extend_monitor; + + Folder *parent; + + char *desktop_file; /* the .directory file */ + + Query *query; + + /* The following is for per file access */ + GHashTable *excludes; /* excluded by dirname/fileuri */ + GSList *includes; /* included by dirname/fileuri */ + + GSList *subfolders; + GHashTable *subfolders_ht; + + GSList *entries; + GHashTable *entries_ht; + + /* Some flags */ + guint read_only : 1; + guint dont_show_if_empty : 1; + guint only_unallocated : 1; /* include only unallocated */ + guint is_link : 1; + + guint has_user_private_subfolders : 1; + guint user_private : 1; + + /* lazily done, will run query only when it needs to */ + guint dirty : 1; + guint loading : 1; + guint sorted : 1; +}; + +typedef struct { + enum { + FOLDER = 1, + DESKTOP_FILE, + UNKNOWN_URI + } type; + + Folder *folder; + Entry *entry; + GnomeVFSURI *uri; +} FolderChild; + +Folder *folder_new (VFolderInfo *info, + const gchar *name, + gboolean user_private); + +void folder_ref (Folder *folder); +void folder_unref (Folder *folder); + +gboolean folder_make_user_private (Folder *folder); +gboolean folder_is_user_private (Folder *folder); + +void folder_set_dirty (Folder *folder); + +void folder_set_name (Folder *folder, const gchar *name); +const gchar *folder_get_name (Folder *folder); + +void folder_set_query (Folder *folder, Query *query); +Query *folder_get_query (Folder *folder); + +void folder_set_extend_uri (Folder *folder, const gchar *uri); +const gchar *folder_get_extend_uri (Folder *folder); + +void folder_set_desktop_file (Folder *folder, const gchar *filename); +const gchar *folder_get_desktop_file (Folder *folder); + +gboolean folder_get_child (Folder *folder, + const gchar *name, + FolderChild *child); +GSList *folder_list_children (Folder *folder); + +Entry *folder_get_entry (Folder *folder, const gchar *filename); +const GSList *folder_list_entries (Folder *folder); +void folder_remove_entry (Folder *folder, Entry *entry); +void folder_add_entry (Folder *folder, Entry *entry); + +void folder_add_include (Folder *folder, const gchar *file); +void folder_remove_include (Folder *folder, const gchar *file); + +void folder_add_exclude (Folder *folder, const gchar *file); +void folder_remove_exclude (Folder *folder, const gchar *file); + +Folder *folder_get_subfolder (Folder *folder, const gchar *name); +const GSList *folder_list_subfolders (Folder *folder); +void folder_remove_subfolder (Folder *folder, Folder *sub); +void folder_add_subfolder (Folder *folder, Folder *sub); + +gboolean folder_is_hidden (Folder *folder); + +void folder_dump_tree (Folder *folder, int indent); + +void folder_emit_changed (Folder *folder, + const gchar *child, + GnomeVFSMonitorEventType event_type); + + +/* + * Query API + */ +struct _Query { + enum { + QUERY_OR, + QUERY_AND, + QUERY_PARENT, + QUERY_KEYWORD, + QUERY_FILENAME + } type; + union { + GSList *queries; + GQuark keyword; + gchar *filename; + } val; + guint not : 1; +}; + +Query *query_new (int type); + +void query_free (Query *query); + +gboolean query_try_match (Query *query, + Folder *folder, + Entry *efile); + +/* + * VFolderInfo API + */ +/* NOTE: Exposed only so do_monitor_cancel can lock the VFolderInfo */ +typedef struct { + GnomeVFSURI *uri; + GnomeVFSMonitorType type; + VFolderInfo *info; +} MonitorHandle; + +struct _VFolderInfo { + GStaticRWLock rw_lock; + + char *scheme; + + char *filename; + VFolderMonitor *filename_monitor; + guint filename_reload_tag; + + /* dir where user changes to items are stored */ + char *write_dir; + VFolderMonitor *write_dir_monitor; + + /* deprecated */ + char *desktop_dir; /* directory with .directorys */ + VFolderMonitor *desktop_dir_monitor; + + /* Consider item dirs and mergedirs writeable?? */ + /* Monitoring on mergedirs?? */ + GSList *item_dirs; /* CONTAINS: ItemDir */ + + GSList *entries; /* CONTAINS: Entry */ + GHashTable *entries_ht; /* KEY: Entry->name, VALUE: Entry */ + + /* The root folder */ + Folder *root; + + /* some flags */ + guint read_only : 1; + guint dirty : 1; + guint loading : 1; + guint has_unallocated_folder : 1; + + GSList *requested_monitors; /* CONTAINS: MonitorHandle */ + + /* ctime for folders */ + time_t modification_time; +}; + +#define VFOLDER_INFO_READ_LOCK(vi) \ + g_static_rw_lock_reader_lock (&(vi->rw_lock)) +#define VFOLDER_INFO_READ_UNLOCK(vi) \ + g_static_rw_lock_reader_unlock (&(vi->rw_lock)) + +#define VFOLDER_INFO_WRITE_LOCK(vi) \ + g_static_rw_lock_writer_lock (&(vi->rw_lock)) +/* Writes out .vfolder-info file if there are changes */ +#define VFOLDER_INFO_WRITE_UNLOCK(vi) \ + vfolder_info_write_user (vi); \ + g_static_rw_lock_writer_unlock (&(vi->rw_lock)) + +VFolderInfo *vfolder_info_locate (const gchar *scheme); + +void vfolder_info_set_dirty (VFolderInfo *info); +void vfolder_info_write_user (VFolderInfo *info); + +Folder *vfolder_info_get_folder (VFolderInfo *info, + const gchar *path); +Folder *vfolder_info_get_parent (VFolderInfo *info, + const gchar *path); +Entry *vfolder_info_get_entry (VFolderInfo *info, + const gchar *path); + +const GSList *vfolder_info_list_all_entries (VFolderInfo *info); +Entry *vfolder_info_lookup_entry (VFolderInfo *info, + const gchar *name); +void vfolder_info_add_entry (VFolderInfo *info, Entry *entry); +void vfolder_info_remove_entry (VFolderInfo *info, Entry *entry); + +void vfolder_info_emit_change (VFolderInfo *info, + const char *path, + GnomeVFSMonitorEventType event_type); + +void vfolder_info_add_monitor (VFolderInfo *info, + GnomeVFSMonitorType type, + GnomeVFSURI *path, + GnomeVFSMethodHandle **handle); +void vfolder_info_cancel_monitor (GnomeVFSMethodHandle *handle); + +void vfolder_info_destroy_all (void); + +void vfolder_info_dump_entries (VFolderInfo *info, int offset); + +G_END_DECLS + +#endif /* VFOLDER_COMMON_H */ diff --git a/modules/vfolder/vfolder-info.c b/modules/vfolder/vfolder-info.c new file mode 100644 index 0000000..fc103d3 --- /dev/null +++ b/modules/vfolder/vfolder-info.c @@ -0,0 +1,2215 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* + * vfolder-info.c - Loading of .vfolder-info files. External interface + * defined in vfolder-common.h + * + * Copyright (C) 2002 Ximian, Inc. + * + * The Gnome Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Gnome Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Alex Graveley + * Based on original code by George Lebl . + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "vfolder-common.h" +#include "vfolder-util.h" + +#define DOT_GNOME ".gnome2" + +typedef enum { + ITEM_DIR = 1, + MERGE_DIR +} ItemDirType; + +typedef struct { + VFolderInfo *info; + gint weight; + gchar *uri; + GSList *monitors; + ItemDirType type; +} ItemDir; + +/* .vfolder-info format example: + * + * + * /etc/X11/applnk + * + * /usr/share/applications + * + * /etc/X11/gnome/vfolders + * + * + * Root + * + * important.desktop + * + * + * + * SomeFolder + * http:///mywebdav.com/homedir + * + * + * Test_Folder + * file:///a_readonly_path + * + * Test_Folder.directory + * + * + * + * Application + * Game + * + * Clock + * + * + * somefile.desktop + * someotherfile.desktop + * yetanother.desktop + * + * + * + */ + + +/* + * XML VFolder description writing + */ +static void +add_xml_tree_from_query (xmlNode *parent, Query *query) +{ + xmlNode *real_parent; + + if (query->not) + real_parent = xmlNewChild (parent /* parent */, + NULL /* ns */, + "Not" /* name */, + NULL /* content */); + else + real_parent = parent; + + if (query->type == QUERY_KEYWORD) { + const char *string = g_quark_to_string (query->val.keyword); + + xmlNewChild (real_parent /* parent */, + NULL /* ns */, + "Keyword" /* name */, + string /* content */); + } else if (query->type == QUERY_FILENAME) { + xmlNewChild (real_parent /* parent */, + NULL /* ns */, + "Filename" /* name */, + query->val.filename /* content */); + } else if (query->type == QUERY_PARENT) { + xmlNewChild (real_parent /* parent */, + NULL /* ns */, + "ParentQuery" /* name */, + NULL /* content */); + } else if (query->type == QUERY_OR || + query->type == QUERY_AND) { + xmlNode *node; + const char *name; + GSList *li; + + if (query->type == QUERY_OR) + name = "Or"; + else /* QUERY_AND */ + name = "And"; + + node = xmlNewChild (real_parent /* parent */, + NULL /* ns */, + name /* name */, + NULL /* content */); + + for (li = query->val.queries; li != NULL; li = li->next) { + Query *subquery = li->data; + add_xml_tree_from_query (node, subquery); + } + } else { + g_assert_not_reached (); + } +} + +static void +add_excludes_to_xml (gpointer key, gpointer value, gpointer user_data) +{ + const char *filename = key; + xmlNode *folder_node = user_data; + + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Exclude" /* name */, + filename /* content */); +} + +static void +add_xml_tree_from_folder (xmlNode *parent, Folder *folder) +{ + const GSList *li; + xmlNode *folder_node; + const gchar *extend_uri; + + /* + * return if this folder hasn't been modified by the user, + * and contains no modified subfolders. + */ + if (!folder->user_private && !folder->has_user_private_subfolders) + return; + + folder_node = xmlNewChild (parent /* parent */, + NULL /* ns */, + "Folder" /* name */, + NULL /* content */); + + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Name" /* name */, + folder_get_name (folder) /* content */); + + extend_uri = folder_get_extend_uri (folder); +#if 0 + /* this would confuse KDE, just use hardcoded value. */ + if (extend_uri) { + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + folder->is_link ? "ParentLink" : "Parent", + extend_uri /* content */); + } +#endif + + if (folder->user_private) { + const gchar *desktop_file; + + if (folder->read_only) + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "ReadOnly" /* name */, + NULL /* content */); + if (folder->dont_show_if_empty) + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "DontShowIfEmpty" /* name */, + NULL /* content */); + if (folder->only_unallocated) + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "OnlyUnallocated" /* name */, + NULL /* content */); + + if (folder->desktop_file != NULL) { + desktop_file = folder_get_desktop_file (folder); + if (desktop_file) + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Desktop" /* name */, + desktop_file); + } + + for (li = folder->includes; li != NULL; li = li->next) { + const char *include = li->data; + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Include" /* name */, + include /* content */); + } + + if (folder->excludes) { + g_hash_table_foreach (folder->excludes, + add_excludes_to_xml, + folder_node); + } + + if (folder->query) { + xmlNode *query_node; + query_node = xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Query" /* name */, + NULL /* content */); + add_xml_tree_from_query (query_node, + folder_get_query (folder)); + } + } + + for (li = folder_list_subfolders (folder); li != NULL; li = li->next) { + Folder *subfolder = li->data; + add_xml_tree_from_folder (folder_node, subfolder); + } +} + +static xmlDoc * +xml_tree_from_vfolder (VFolderInfo *info) +{ + xmlDoc *doc; + xmlNode *topnode; + GSList *li; + + doc = xmlNewDoc ("1.0"); + + topnode = xmlNewDocNode (doc /* doc */, + NULL /* ns */, + "VFolderInfo" /* name */, + NULL /* content */); + doc->xmlRootNode = topnode; + +#if 0 + /* Never write the WriteDir field, it will + * break KDE menus. Just use the hardcoded one. + */ + if (info->write_dir != NULL) { + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "WriteDir" /* name */, + info->write_dir /* content */); + } +#endif + + /* Deprecated */ + if (info->desktop_dir != NULL) { + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "DesktopDir" /* name */, + info->desktop_dir /* content */); + } + + for (li = info->item_dirs; li != NULL; li = li->next) { + ItemDir *item_dir = li->data; + + switch (item_dir->type) { + case MERGE_DIR: + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "MergeDir" /* name */, + item_dir->uri /* content */); + break; + case ITEM_DIR: + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "ItemDir" /* name */, + item_dir->uri /* content */); + break; + } + } + + if (info->root != NULL) + add_xml_tree_from_folder (topnode, info->root); + + return doc; +} + +/* FIXME: what to do about errors */ +void +vfolder_info_write_user (VFolderInfo *info) +{ + xmlDoc *doc; + GnomeVFSResult result; + gchar *tmpfile; + struct timeval tv; + + if (info->loading || !info->dirty) + return; + + if (!info->filename) + return; + + info->loading = TRUE; + + /* FIXME: errors, anyone? */ + result = vfolder_make_directory_and_parents (info->filename, + TRUE, + 0700); + if (result != GNOME_VFS_OK) { + g_warning ("Unable to create parent directory for " + "vfolder-info file: %s", + info->filename); + return; + } + + doc = xml_tree_from_vfolder (info); + if (!doc) + return; + + gettimeofday (&tv, NULL); + tmpfile = g_strdup_printf ("%s.tmp-%d", + info->filename, + (int) (tv.tv_sec ^ tv.tv_usec)); + + /* Write to temporary file */ + xmlSaveFormatFile (tmpfile, doc, TRUE /* format */); + + /* Avoid being notified of move, since we're performing it */ + if (info->filename_monitor) + vfolder_monitor_freeze (info->filename_monitor); + + /* Move temp file over to real filename */ + result = gnome_vfs_move (tmpfile, + info->filename, + TRUE /*force_replace*/); + if (result != GNOME_VFS_OK) { + g_warning ("Error writing vfolder configuration " + "file \"%s\": %s.", + info->filename, + gnome_vfs_result_to_string (result)); + } + + /* Start listening to changes again */ + if (info->filename_monitor) + vfolder_monitor_thaw (info->filename_monitor); + + xmlFreeDoc(doc); + g_free (tmpfile); + + info->modification_time = time (NULL); + info->dirty = FALSE; + info->loading = FALSE; +} + + +/* + * XML VFolder description reading + */ +static Query * +single_query_read (xmlNode *qnode) +{ + Query *query; + xmlNode *node; + + if (qnode->type != XML_ELEMENT_NODE || qnode->name == NULL) + return NULL; + + query = NULL; + + if (g_ascii_strcasecmp (qnode->name, "Not") == 0 && + qnode->xmlChildrenNode != NULL) { + xmlNode *iter; + + for (iter = qnode->xmlChildrenNode; + iter != NULL && query == NULL; + iter = iter->next) + query = single_query_read (iter); + if (query != NULL) { + query->not = ! query->not; + } + return query; + } + else if (g_ascii_strcasecmp (qnode->name, "Keyword") == 0) { + xmlChar *word = xmlNodeGetContent (qnode); + + if (word != NULL) { + query = query_new (QUERY_KEYWORD); + query->val.keyword = g_quark_from_string (word); + xmlFree (word); + } + return query; + } + else if (g_ascii_strcasecmp (qnode->name, "Filename") == 0) { + xmlChar *file = xmlNodeGetContent (qnode); + + if (file != NULL) { + query = query_new (QUERY_FILENAME); + query->val.filename = g_strdup (file); + xmlFree (file); + } + return query; + } + else if (g_ascii_strcasecmp (qnode->name, "ParentQuery") == 0) { + query = query_new (QUERY_PARENT); + } + else if (g_ascii_strcasecmp (qnode->name, "And") == 0) { + query = query_new (QUERY_AND); + } + else if (g_ascii_strcasecmp (qnode->name, "Or") == 0) { + query = query_new (QUERY_OR); + } + else { + /* We don't understand */ + return NULL; + } + + /* This must be OR or AND */ + g_assert (query != NULL); + + for (node = qnode->xmlChildrenNode; node; node = node->next) { + Query *new_query = single_query_read (node); + + if (new_query != NULL) + query->val.queries = + g_slist_prepend (query->val.queries, new_query); + } + + query->val.queries = g_slist_reverse (query->val.queries); + + return query; +} + +static void +add_or_set_query (Query **query, Query *new_query) +{ + if (*query == NULL) { + *query = new_query; + } else { + Query *old_query = *query; + *query = query_new (QUERY_OR); + (*query)->val.queries = + g_slist_append ((*query)->val.queries, old_query); + (*query)->val.queries = + g_slist_append ((*query)->val.queries, new_query); + } +} + +static Query * +query_read (xmlNode *qnode) +{ + Query *query; + xmlNode *node; + + query = NULL; + + for (node = qnode->xmlChildrenNode; node != NULL; node = node->next) { + if (node->type != XML_ELEMENT_NODE || + node->name == NULL) + continue; + + if (g_ascii_strcasecmp (node->name, "Not") == 0 && + node->xmlChildrenNode != NULL) { + xmlNode *iter; + Query *new_query = NULL; + + for (iter = node->xmlChildrenNode; + iter != NULL && new_query == NULL; + iter = iter->next) + new_query = single_query_read (iter); + if (new_query != NULL) { + new_query->not = ! new_query->not; + add_or_set_query (&query, new_query); + } + } else { + Query *new_query = single_query_read (node); + if (new_query != NULL) + add_or_set_query (&query, new_query); + } + } + + return query; +} + +static Folder * +folder_read (VFolderInfo *info, gboolean user_private, xmlNode *fnode) +{ + Folder *folder; + xmlNode *node; + + folder = folder_new (info, NULL, user_private); + + for (node = fnode->xmlChildrenNode; node != NULL; node = node->next) { + if (node->type != XML_ELEMENT_NODE || + node->name == NULL) + continue; + + if (g_ascii_strcasecmp (node->name, "Name") == 0) { + xmlChar *name = xmlNodeGetContent (node); + + if (name) { + g_free (folder->name); + folder_set_name (folder, name); + xmlFree (name); + } + } + else if (g_ascii_strcasecmp (node->name, "Parent") == 0) { + xmlChar *parent = xmlNodeGetContent (node); + + if (parent) { + gchar *esc_parent; + + esc_parent = vfolder_escape_home (parent); + if (*esc_parent != '\0') { + folder_set_extend_uri (folder, esc_parent); + folder->is_link = FALSE; + } + + xmlFree (parent); + g_free (esc_parent); + } + } + else if (g_ascii_strcasecmp (node->name, "ParentLink") == 0) { + xmlChar *parent = xmlNodeGetContent (node); + + if (parent) { + gchar *esc_parent; + + esc_parent = vfolder_escape_home (parent); + if (*esc_parent != '\0') { + folder_set_extend_uri (folder, esc_parent); + folder->is_link = TRUE; + } + + xmlFree (parent); + g_free (esc_parent); + } + } + else if (g_ascii_strcasecmp (node->name, "Desktop") == 0) { + xmlChar *desktop = xmlNodeGetContent (node); + + if (desktop) { + folder_set_desktop_file (folder, desktop); + xmlFree (desktop); + } + } + else if (g_ascii_strcasecmp (node->name, "Include") == 0) { + xmlChar *file = xmlNodeGetContent (node); + + if (file) { + gchar *esc_file; + + esc_file = vfolder_escape_home (file); + folder_add_include (folder, esc_file); + + xmlFree (file); + g_free (esc_file); + } + } + else if (g_ascii_strcasecmp (node->name, "Exclude") == 0) { + xmlChar *file = xmlNodeGetContent (node); + + if (file) { + gchar *esc_file; + + esc_file = vfolder_escape_home (file); + folder_add_exclude (folder, esc_file); + + xmlFree (file); + g_free (esc_file); + } + } + else if (g_ascii_strcasecmp (node->name, "Query") == 0) { + Query *query; + + query = query_read (node); + if (query) + folder_set_query (folder, query); + } + else if (g_ascii_strcasecmp (node->name, "Folder") == 0) { + Folder *new_folder = folder_read (info, + user_private, + node); + + if (new_folder != NULL) { + folder_add_subfolder (folder, new_folder); + folder_unref (new_folder); + } + } + else if (g_ascii_strcasecmp (node->name, + "OnlyUnallocated") == 0) { + folder->only_unallocated = TRUE; + info->has_unallocated_folder = TRUE; + } + else if (g_ascii_strcasecmp (node->name, "ReadOnly") == 0) { + folder->read_only = TRUE; + } + else if (g_ascii_strcasecmp (node->name, + "DontShowIfEmpty") == 0) { + folder->dont_show_if_empty = TRUE; + } + } + + /* Name is required */ + if (!folder_get_name (folder)) { + folder_unref (folder); + return NULL; + } + + return folder; +} + +static void itemdir_monitor_cb (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data); + +static void writedir_monitor_cb (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data); + +static void desktopdir_monitor_cb (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data); + + +static char * +remove_double_slashes (const char *uri) +{ + const char *src; + char *dest; + char *result; + gboolean slash; + + if (uri == NULL) { + return NULL; + } + + result = malloc (strlen (uri) + 1); + if (result == NULL) { + return NULL; + } + + src = uri; + dest = result; + slash = FALSE; + + while (*src != '\0') { + /* Don't do anything if current char is a / and slash is TRUE*/ + if ((*src == '/') && (slash != FALSE)) { + src++; + continue; + } + + if ((*src == '/') && (slash == FALSE)) { + slash = TRUE; + + } else { + slash = FALSE; + } + + *dest = *src; + dest++; + src++; + } + *dest = '\0'; + + return result; +} + +static ItemDir * +itemdir_new (VFolderInfo *info, + const gchar *uri, + ItemDirType type, + gint weight) +{ + ItemDir *ret; + gchar *tmp_uri; + + ret = g_new0 (ItemDir, 1); + ret->info = info; + ret->weight = weight; + tmp_uri = vfolder_escape_home (uri); + ret->uri = remove_double_slashes (tmp_uri); + g_free (tmp_uri); + ret->type = type; + + info->item_dirs = g_slist_append (info->item_dirs, ret); + + return ret; +} + +static void +itemdir_free (ItemDir *itemdir) +{ + GSList *iter; + + for (iter = itemdir->monitors; iter; iter = iter->next) { + VFolderMonitor *monitor = iter->data; + vfolder_monitor_cancel (monitor); + } + + g_slist_free (itemdir->monitors); + g_free (itemdir->uri); + g_free (itemdir); +} + +static void +set_hardcoded_extend_uri_recursive (Folder *parent, + const char *parent_uri) +{ + GSList *subfolders; + GSList *tmp; + + /* we set the extend URI unconditionally, + * ignoring anything in the file + */ + folder_set_extend_uri (parent, parent_uri); + + subfolders = (GSList*) folder_list_subfolders (parent); + tmp = subfolders; + while (tmp != NULL) { + Folder *sub = tmp->data; + char *child_uri; + + child_uri = g_strconcat (parent_uri, folder_get_name (sub), + "/", NULL); + + set_hardcoded_extend_uri_recursive (sub, child_uri); + + g_free (child_uri); + + tmp = tmp->next; + } +} + +static void +set_hardcoded_extend_uri (VFolderInfo *info) +{ + gchar *all_user_scheme; + + /* + * Set the extend uri for the root folder to the -all-users version of + * the scheme, in case the user doesn't have a private .vfolder-info + * file yet. + */ + if (!g_str_has_suffix (info->scheme, + "-all-users")) { + all_user_scheme = g_strconcat (info->scheme, "-all-users:///", NULL); + set_hardcoded_extend_uri_recursive (info->root, all_user_scheme); + g_free (all_user_scheme); + } +} + +static gboolean +read_vfolder_from_file (VFolderInfo *info, + const gchar *filename, + gboolean user_private, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + xmlDoc *doc; + xmlNode *node; + GnomeVFSResult my_result; + gint weight = 700; + + if (result == NULL) + result = &my_result; + + /* Fail silently if filename does not exist */ + if (access (filename, F_OK) != 0) + return TRUE; + + doc = xmlParseFile (filename); + if (doc == NULL + || doc->xmlRootNode == NULL + || doc->xmlRootNode->name == NULL + || g_ascii_strcasecmp (doc->xmlRootNode->name, + "VFolderInfo") != 0) { + *result = GNOME_VFS_ERROR_WRONG_FORMAT; + xmlFreeDoc(doc); + return FALSE; + } + + if (context != NULL && + gnome_vfs_context_check_cancellation (context)) { + xmlFreeDoc(doc); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + for (node = doc->xmlRootNode->xmlChildrenNode; + node != NULL; + node = node->next) { + if (node->type != XML_ELEMENT_NODE || + node->name == NULL) + continue; + + if (context != NULL && + gnome_vfs_context_check_cancellation (context)) { + xmlFreeDoc(doc); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + if (g_ascii_strcasecmp (node->name, "MergeDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + + if (dir != NULL) { + itemdir_new (info, dir, MERGE_DIR, weight--); + xmlFree (dir); + } + } + else if (g_ascii_strcasecmp (node->name, "ItemDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + + if (dir != NULL) { + itemdir_new (info, dir, ITEM_DIR, weight--); + xmlFree (dir); + } + } + else if (g_ascii_strcasecmp (node->name, "WriteDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + + if (dir != NULL) { + g_free (info->write_dir); + info->write_dir = vfolder_escape_home (dir); + xmlFree (dir); + } + } + else if (g_ascii_strcasecmp (node->name, "DesktopDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + + if (dir != NULL) { + g_free (info->desktop_dir); + info->desktop_dir = vfolder_escape_home (dir); + xmlFree (dir); + } + } + else if (g_ascii_strcasecmp (node->name, "Folder") == 0) { + Folder *folder = folder_read (info, + user_private, + node); + + if (folder != NULL) { + if (info->root != NULL) + folder_unref (info->root); + + info->root = folder; + set_hardcoded_extend_uri (info); + } + } + else if (g_ascii_strcasecmp (node->name, "ReadOnly") == 0) { + info->read_only = TRUE; + } + } + + xmlFreeDoc(doc); + + return TRUE; +} + + +/* + * MergeDir/ItemDir entry pool reading + */ +struct { + const gchar *dirname; + const gchar *keyword; +} mergedir_keywords[] = { + /*Parent Dir*/ /*Keyword to add*/ + + /* Gnome Menus */ + { "Development", "Development" }, + { "Editors", "TextEditor" }, + { "Games", "Game" }, + { "Graphics", "Graphics" }, + { "Internet", "Network" }, + { "Multimedia", "AudioVideo" }, + { "Office", "Office" }, + { "Settings", "Settings" }, + { "System", "System" }, + { "Utilities", "Utility" }, + + /* Ximian Menus */ + { "Addressbook", "Office" }, + { "Audio", "AudioVideo" }, + { "Calendar", "Office" }, + { "Finance", "Office" }, + + /* KDE Menus */ + { "WordProcessing", "Office" }, + { "Toys", "Utility" }, +}; + +static GQuark +get_mergedir_keyword (const gchar *dirname) +{ + gint i; + + for (i = 0; i < G_N_ELEMENTS (mergedir_keywords); i++) { + if (g_ascii_strcasecmp (mergedir_keywords [i].dirname, + dirname) == 0) { + return g_quark_from_static_string ( + mergedir_keywords [i].keyword); + } + } + + return 0; +} + +static Entry * +create_itemdir_entry (ItemDir *id, + const gchar *rel_path, + GnomeVFSFileInfo *file_info) +{ + Entry *new_entry = NULL; + gchar *file_uri; + + if (!vfolder_check_extension (file_info->name, ".desktop")) + return NULL; + + if (vfolder_info_lookup_entry (id->info, file_info->name)) { + D (g_print ("EXCLUDING DUPLICATE ENTRY: %s\n", + file_info->name)); + return NULL; + } + + file_uri = vfolder_build_uri (id->uri, rel_path, NULL); + + /* Ref belongs to the VFolderInfo */ + new_entry = entry_new (id->info, + file_uri /*filename*/, + file_info->name /*displayname*/, + FALSE /*user_private*/, + id->weight /*weight*/); + + g_free (file_uri); + + return new_entry; +} + +static void +add_keywords_from_relative_path (Entry *new_entry, const gchar *rel_path) +{ + gchar **pelems; + GQuark keyword; + gint i; + + pelems = g_strsplit (rel_path, "/", -1); + if (!pelems) + return; + + for (i = 0; pelems [i]; i++) { + keyword = get_mergedir_keyword (pelems [i]); + if (keyword) + entry_add_implicit_keyword (new_entry, keyword); + } + + g_strfreev (pelems); +} + +static void +set_mergedir_entry_keywords (Entry *new_entry, const gchar *rel_path) +{ + static GQuark merged = 0, application = 0, core_quark = 0; + + if (!merged) { + merged = g_quark_from_static_string ("Merged"); + application = g_quark_from_static_string("Application"); + core_quark = g_quark_from_static_string ("Core"); + } + + /* + * Mergedirs have the 'Merged' and 'Appliction' keywords added. + */ + entry_add_implicit_keyword (new_entry, merged); + entry_add_implicit_keyword (new_entry, application); + + if (!strcmp (rel_path, entry_get_displayname (new_entry))) + entry_add_implicit_keyword (new_entry, core_quark); + else + add_keywords_from_relative_path (new_entry, rel_path); +} + +static Entry * +create_mergedir_entry (ItemDir *id, + const gchar *rel_path, + GnomeVFSFileInfo *file_info) +{ + Entry *new_entry; + + new_entry = create_itemdir_entry (id, rel_path, file_info); + if (new_entry) + set_mergedir_entry_keywords (new_entry, rel_path); + + return new_entry; +} + +static Entry * +create_entry_or_add_dir_monitor (ItemDir *id, + const gchar *rel_path, + GnomeVFSFileInfo *file_info) +{ + VFolderMonitor *dir_monitor; + Entry *ret = NULL; + gchar *file_uri; + + if (file_info->type == GNOME_VFS_FILE_TYPE_DIRECTORY) { + /* Add monitor for subdirectory of this MergeDir/ItemDir */ + file_uri = vfolder_build_uri (id->uri, rel_path, NULL); + dir_monitor = vfolder_monitor_dir_new (file_uri, + itemdir_monitor_cb, + id); + if (dir_monitor) + id->monitors = g_slist_prepend (id->monitors, + dir_monitor); + g_free (file_uri); + } + else { + switch (id->type) { + case MERGE_DIR: + ret = create_mergedir_entry (id, rel_path, file_info); + break; + case ITEM_DIR: + ret = create_itemdir_entry (id, rel_path, file_info); + break; + } + } + + return ret; +} + +static gboolean +create_entry_directory_visit_cb (const gchar *rel_path, + GnomeVFSFileInfo *file_info, + gboolean recursing_will_loop, + gpointer user_data, + gboolean *recurse) +{ + ItemDir *id = user_data; + + create_entry_or_add_dir_monitor (id, rel_path, file_info); + + *recurse = !recursing_will_loop; + return TRUE; +} + +static gboolean +vfolder_info_read_info (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + gboolean ret = FALSE; + GSList *iter; + + if (!info->filename) + return FALSE; + + /* Don't let set_dirty write out the file */ + info->loading = TRUE; + + ret = read_vfolder_from_file (info, + info->filename, + TRUE, + result, + context); + if (ret) { + if (info->write_dir) + info->write_dir_monitor = + vfolder_monitor_dir_new (info->write_dir, + writedir_monitor_cb, + info); + + if (info->desktop_dir) + info->desktop_dir_monitor = + vfolder_monitor_dir_new (info->desktop_dir, + desktopdir_monitor_cb, + info); + + /* Load ItemDir/MergeDirs in order of appearance. */ + for (iter = info->item_dirs; iter; iter = iter->next) { + ItemDir *id = iter->data; + VFolderMonitor *dir_monitor; + + /* Add a monitor for the root directory */ + dir_monitor = + vfolder_monitor_dir_new (id->uri, + itemdir_monitor_cb, + id); + if (dir_monitor) + id->monitors = g_slist_prepend (id->monitors, + dir_monitor); + + gnome_vfs_directory_visit ( + id->uri, + GNOME_VFS_FILE_INFO_DEFAULT, + GNOME_VFS_DIRECTORY_VISIT_DEFAULT, + create_entry_directory_visit_cb, + id); + } + } + + /* Allow set_dirty to write config file again */ + info->loading = FALSE; + + return ret; +} + +static void +vfolder_info_reset (VFolderInfo *info) +{ + GSList *iter; + + info->loading = TRUE; + + if (info->filename_monitor) { + vfolder_monitor_cancel (info->filename_monitor); + info->filename_monitor = NULL; + } + + if (info->write_dir_monitor) { + vfolder_monitor_cancel (info->write_dir_monitor); + info->write_dir_monitor = NULL; + } + + for (iter = info->item_dirs; iter; iter = iter->next) { + ItemDir *dir = iter->data; + itemdir_free (dir); + } + g_slist_free (info->item_dirs); + info->item_dirs = NULL; + + g_free (info->filename); + g_free (info->write_dir); + g_free (info->desktop_dir); + + info->filename = NULL; + info->desktop_dir = NULL; + info->write_dir = NULL; + + folder_unref (info->root); + info->root = NULL; + + g_slist_foreach (info->entries, (GFunc) entry_unref, NULL); + g_slist_free (info->entries); + info->entries = NULL; + + if (info->entries_ht) { + g_hash_table_destroy (info->entries_ht); + info->entries_ht = NULL; + } + + /* Clear flags */ + info->read_only = + info->dirty = + info->loading = + info->has_unallocated_folder = FALSE; +} + + +/* + * VFolder ItemDir/MergeDir/WriteDir/DesktopDir directory monitoring + */ +static void +integrate_entry (Folder *folder, Entry *entry, gboolean do_add) +{ + const GSList *subs; + Entry *existing; + Query *query; + gboolean matches = FALSE; + + for (subs = folder_list_subfolders (folder); subs; subs = subs->next) { + Folder *asub = subs->data; + integrate_entry (asub, entry, do_add); + } + + if (folder->only_unallocated) + return; + + query = folder_get_query (folder); + if (query) + matches = query_try_match (query, folder, entry); + + existing = folder_get_entry (folder, entry_get_displayname (entry)); + if (existing) { + /* + * Do nothing if the existing entry has a higher weight than the + * one we wish to add. + */ + if (entry_get_weight (existing) > entry_get_weight (entry)) + return; + + folder_remove_entry (folder, existing); + + if (do_add && matches) { + folder_add_entry (folder, entry); + + folder_emit_changed (folder, + entry_get_displayname (entry), + GNOME_VFS_MONITOR_EVENT_CHANGED); + } else + folder_emit_changed (folder, + entry_get_displayname (entry), + GNOME_VFS_MONITOR_EVENT_DELETED); + } + else if (do_add && matches) { + folder_add_entry (folder, entry); + + folder_emit_changed (folder, + entry_get_displayname (entry), + GNOME_VFS_MONITOR_EVENT_CREATED); + } +} + +static void +integrate_itemdir_entry_createupdate (ItemDir *id, + GnomeVFSURI *full_uri, + const gchar *full_uristr, + const gchar *displayname, + GnomeVFSMonitorEventType event_type) +{ + Entry *entry; + GnomeVFSURI *real_uri; + const gchar *rel_path; + + rel_path = strstr (full_uristr, id->uri); + g_assert (rel_path != NULL); + rel_path += strlen (id->uri); + + /* Look for an existing entry with the same displayname */ + entry = vfolder_info_lookup_entry (id->info, displayname); + if (entry) { + real_uri = entry_get_real_uri (entry); + + if (gnome_vfs_uri_equal (full_uri, real_uri)) { + /* Refresh */ + entry_set_dirty (entry); + } + else if (entry_get_weight (entry) < id->weight) { + /* + * Existing entry is less important than the new + * one, so replace. + */ + entry_set_filename (entry, full_uristr); + entry_set_weight (entry, id->weight); + + if (id->type == MERGE_DIR) { + /* Add keywords from relative path */ + set_mergedir_entry_keywords (entry, rel_path); + } + } + + gnome_vfs_uri_unref (real_uri); + } + else if (event_type == GNOME_VFS_MONITOR_EVENT_CREATED) { + GnomeVFSFileInfo *file_info; + GnomeVFSResult result; + + file_info = gnome_vfs_file_info_new (); + + result = + gnome_vfs_get_file_info_uri ( + full_uri, + file_info, + GNOME_VFS_FILE_INFO_DEFAULT); + + if (result == GNOME_VFS_OK) + entry = create_entry_or_add_dir_monitor (id, + rel_path, + file_info); + + gnome_vfs_file_info_unref (file_info); + } + + if (entry) { + entry_ref (entry); + integrate_entry (id->info->root, + entry, + TRUE /* do_add */); + entry_unref (entry); + + id->info->modification_time = time (NULL); + } +} + +static gboolean +find_replacement_for_delete (ItemDir *id, Entry *entry) +{ + GSList *iter, *miter; + gint idx; + + idx = g_slist_index (id->info->item_dirs, id); + if (idx < 0) + return FALSE; + + iter = g_slist_nth (id->info->item_dirs, idx + 1); + + for (; iter; iter = iter->next) { + ItemDir *id_next = iter->data; + + for (miter = id_next->monitors; miter; miter = miter->next) { + VFolderMonitor *monitor = miter->data; + GnomeVFSURI *check_uri; + gchar *uristr, *rel_path; + gboolean exists; + + uristr = + vfolder_build_uri ( + monitor->uri, + entry_get_displayname (entry), + NULL); + + check_uri = gnome_vfs_uri_new (uristr); + exists = gnome_vfs_uri_exists (check_uri); + gnome_vfs_uri_unref (check_uri); + + if (!exists) { + g_free (uristr); + continue; + } + + entry_set_filename (entry, uristr); + entry_set_weight (entry, id_next->weight); + + if (id_next->type == MERGE_DIR) { + rel_path = strstr (uristr, id_next->uri); + rel_path += strlen (id_next->uri); + + /* Add keywords based on relative path */ + set_mergedir_entry_keywords (entry, rel_path); + } + + g_free (uristr); + return TRUE; + } + } + + return FALSE; +} + +static void +integrate_itemdir_entry_delete (ItemDir *id, + GnomeVFSURI *full_uri, + const gchar *displayname) +{ + Entry *entry; + GnomeVFSURI *real_uri; + gboolean replaced, equal; + + entry = vfolder_info_lookup_entry (id->info, displayname); + if (!entry) + return; + + real_uri = entry_get_real_uri (entry); + equal = gnome_vfs_uri_equal (full_uri, real_uri); + gnome_vfs_uri_unref (real_uri); + + /* Only care if its the currently visible entry being deleted */ + if (!equal) + return; + + replaced = find_replacement_for_delete (id, entry); + + entry_ref (entry); + integrate_entry (id->info->root, entry, replaced /* do_add */); + entry_unref (entry); + + id->info->modification_time = time (NULL); +} + +static void +itemdir_monitor_cb (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + ItemDir *id = user_data; + gchar *filename; + GnomeVFSURI *uri; + + D (g_print ("*** Itemdir '%s' monitor %s%s%s called! ***\n", + info_uri, + event_type == GNOME_VFS_MONITOR_EVENT_CREATED ? "CREATED":"", + event_type == GNOME_VFS_MONITOR_EVENT_DELETED ? "DELETED":"", + event_type == GNOME_VFS_MONITOR_EVENT_CHANGED ? "CHANGED":"")); + + /* Operating on the whole directory, ignore */ + if (!strcmp (monitor_uri, info_uri) || + !vfolder_check_extension (info_uri, ".desktop")) + return; + + uri = gnome_vfs_uri_new (info_uri); + filename = gnome_vfs_uri_extract_short_name (uri); + + switch (event_type) { + case GNOME_VFS_MONITOR_EVENT_CREATED: + case GNOME_VFS_MONITOR_EVENT_CHANGED: + VFOLDER_INFO_WRITE_LOCK (id->info); + integrate_itemdir_entry_createupdate (id, + uri, + info_uri, + filename, + event_type); + VFOLDER_INFO_WRITE_UNLOCK (id->info); + break; + case GNOME_VFS_MONITOR_EVENT_DELETED: + VFOLDER_INFO_WRITE_LOCK (id->info); + integrate_itemdir_entry_delete (id, uri, filename); + VFOLDER_INFO_WRITE_UNLOCK (id->info); + break; + default: + break; + } + + gnome_vfs_uri_unref (uri); + g_free (filename); +} + +static void +integrate_writedir_entry_changed (Folder *folder, + gchar *displayname, + GnomeVFSURI *changed_uri) +{ + Entry *entry; + GnomeVFSURI *real_uri; + const GSList *subs; + + entry = folder_get_entry (folder, displayname); + if (entry) { + real_uri = entry_get_real_uri (entry); + + if (gnome_vfs_uri_equal (real_uri, changed_uri)) { + entry_set_dirty (entry); + folder_emit_changed (folder, + displayname, + GNOME_VFS_MONITOR_EVENT_CHANGED); + } + + gnome_vfs_uri_unref (real_uri); + } + + for (subs = folder_list_subfolders (folder); subs; subs = subs->next) { + Folder *asub = subs->data; + integrate_writedir_entry_changed (asub, + displayname, + changed_uri); + } +} + +static void +writedir_monitor_cb (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + VFolderInfo *info = user_data; + GnomeVFSURI *uri; + gchar *filename, *filename_ts; + + /* Operating on the whole directory, ignore */ + if (!strcmp (monitor_uri, info_uri) || + (!vfolder_check_extension (info_uri, ".desktop") && + !vfolder_check_extension (info_uri, ".directory"))) + return; + + switch (event_type) { + case GNOME_VFS_MONITOR_EVENT_CHANGED: + uri = gnome_vfs_uri_new (info_uri); + filename_ts = gnome_vfs_uri_extract_short_name (uri); + filename = vfolder_untimestamp_file_name (filename_ts); + + VFOLDER_INFO_WRITE_LOCK (info); + integrate_writedir_entry_changed (info->root, filename, uri); + VFOLDER_INFO_WRITE_UNLOCK (info); + + gnome_vfs_uri_unref (uri); + g_free (filename_ts); + g_free (filename); + break; + case GNOME_VFS_MONITOR_EVENT_DELETED: + case GNOME_VFS_MONITOR_EVENT_CREATED: + default: + break; + } +} + +static void +desktopdir_monitor_cb (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + VFolderInfo *info = user_data; + GnomeVFSURI *uri; + + /* Operating on the whole directory, ignore */ + if (!strcmp (monitor_uri, info_uri) || + !vfolder_check_extension (info_uri, ".directory")) + return; + + switch (event_type) { + case GNOME_VFS_MONITOR_EVENT_CHANGED: + uri = gnome_vfs_uri_new (info_uri); + + VFOLDER_INFO_WRITE_LOCK (info); + integrate_writedir_entry_changed (info->root, + ".directory", + uri); + VFOLDER_INFO_WRITE_UNLOCK (info); + + gnome_vfs_uri_unref (uri); + break; + case GNOME_VFS_MONITOR_EVENT_DELETED: + case GNOME_VFS_MONITOR_EVENT_CREATED: + default: + break; + } +} + + +/* + * .vfolder-info monitoring + */ +static void +check_monitors_foreach (gpointer key, gpointer val, gpointer user_data) +{ + MonitorHandle *handle = key; + GSList *children = val; + GnomeVFSURI *uri, *curi; + const gchar *path; + + uri = handle->uri; + path = gnome_vfs_uri_get_path (handle->uri); + + if (handle->type == GNOME_VFS_MONITOR_DIRECTORY) { + Folder *folder; + GSList *new_children, *iter, *found; + + folder = vfolder_info_get_folder (handle->info, path); + if (!folder) { + gnome_vfs_monitor_callback ( + (GnomeVFSMethodHandle *) handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_DELETED); + return; + } + + /* + * FIXME: If someone has an folder which also + * has a , we won't receive change events for + * children matching the query... I think this is corner + * enough to ignore * though. + */ + if (folder->only_unallocated) + return; + + new_children = folder_list_children (folder); + + for (iter = children; iter; iter = iter->next) { + gchar *child_name = iter->data; + + /* Look for a child with the same name */ + found = g_slist_find_custom (new_children, + child_name, + (GCompareFunc) strcmp); + if (found) { + g_free (found->data); + new_children = + g_slist_delete_link (new_children, + found); + } else { + curi = + gnome_vfs_uri_append_file_name ( + handle->uri, + child_name); + + gnome_vfs_monitor_callback ( + (GnomeVFSMethodHandle *) handle, + curi, + GNOME_VFS_MONITOR_EVENT_DELETED); + + gnome_vfs_uri_unref (curi); + } + + g_free (child_name); + } + + /* Whatever is left is new, send created events */ + for (iter = new_children; iter; iter = iter->next) { + gchar *child_name = iter->data; + + curi = gnome_vfs_uri_append_file_name (handle->uri, + child_name); + + gnome_vfs_monitor_callback ( + (GnomeVFSMethodHandle *) handle, + curi, + GNOME_VFS_MONITOR_EVENT_CREATED); + + gnome_vfs_uri_unref (curi); + g_free (child_name); + } + + g_slist_free (new_children); + g_slist_free (children); + } + else { + gboolean found; + + found = vfolder_info_get_entry (handle->info, path) || + vfolder_info_get_folder (handle->info, path); + + gnome_vfs_monitor_callback ( + (GnomeVFSMethodHandle *) handle, + handle->uri, + found ? + GNOME_VFS_MONITOR_EVENT_CHANGED : + GNOME_VFS_MONITOR_EVENT_DELETED); + } +} + +static gboolean vfolder_info_init (VFolderInfo *info); + +static gboolean +filename_monitor_handle (gpointer user_data) +{ + VFolderInfo *info = user_data; + GHashTable *monitors; + GSList *iter; + + D (g_print ("*** PROCESSING .vfolder-info!!! ***\n")); + + monitors = g_hash_table_new (g_direct_hash, g_direct_equal); + + VFOLDER_INFO_WRITE_LOCK (info); + + /* Don't emit any events while we load */ + info->loading = TRUE; + + /* Compose a hash of all existing monitors and their children */ + for (iter = info->requested_monitors; iter; iter = iter->next) { + MonitorHandle *mhandle = iter->data; + GSList *monitored_paths = NULL; + Folder *folder; + + if (mhandle->type == GNOME_VFS_MONITOR_DIRECTORY) { + folder = + vfolder_info_get_folder ( + info, + gnome_vfs_uri_get_path (mhandle->uri)); + if (folder) + monitored_paths = folder_list_children (folder); + } + + g_hash_table_insert (monitors, mhandle, monitored_paths); + } + + vfolder_info_reset (info); + vfolder_info_init (info); + + /* Start sending events again */ + info->loading = FALSE; + + /* Traverse monitor hash and diff with newly read folder structure */ + g_hash_table_foreach (monitors, check_monitors_foreach, info); + + VFOLDER_INFO_WRITE_UNLOCK (info); + + g_hash_table_destroy (monitors); + + info->filename_reload_tag = 0; + return FALSE; +} + +static void +filename_monitor_cb (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + VFolderInfo *info = user_data; + + D (g_print ("*** Filename '%s' monitor %s%s%s called! ***\n", + info_uri, + event_type == GNOME_VFS_MONITOR_EVENT_CREATED ? "CREATED":"", + event_type == GNOME_VFS_MONITOR_EVENT_DELETED ? "DELETED":"", + event_type == GNOME_VFS_MONITOR_EVENT_CHANGED ? "CHANGED":"")); + + if (info->filename_reload_tag) { + g_source_remove (info->filename_reload_tag); + info->filename_reload_tag = 0; + } + + /* + * Don't process the .vfolder-info for 2 seconds after a delete event or + * .5 seconds after a create event. This allows files to be rewritten + * before we start reading it and possibly copying the system default + * file over top of it. + */ + switch (event_type) { + case GNOME_VFS_MONITOR_EVENT_DELETED: + info->filename_reload_tag = + g_timeout_add (2000, filename_monitor_handle, info); + break; + case GNOME_VFS_MONITOR_EVENT_CREATED: + info->filename_reload_tag = + g_timeout_add (500, filename_monitor_handle, info); + break; + case GNOME_VFS_MONITOR_EVENT_CHANGED: + default: + filename_monitor_handle (info); + break; + } +} + + +/* + * VFolderInfo Implementation + */ +static VFolderInfo * +vfolder_info_new (const char *scheme) +{ + VFolderInfo *info; + + info = g_new0 (VFolderInfo, 1); + info->scheme = g_strdup (scheme); + + g_static_rw_lock_init (&info->rw_lock); + + return info; +} + +static void +vfolder_info_find_filenames (VFolderInfo *info) +{ + gchar *scheme = info->scheme; + GnomeVFSURI *file_uri; + gboolean exists; + + /* Here we're finding the primary XML file + * that this URI will write changes to. + * It's the .menu file for -all-users, + * and the ~/.gnome2/vfolders/scheme.vfolder-info + * file otherwise. + */ + + if (g_str_has_suffix (info->scheme, + "-all-users")) { + /* The all-users scheme uses the + * .menu files + */ + const char *suffix; + char *single_scheme; + + suffix = g_strrstr (info->scheme, "-all-users"); + g_assert (suffix != NULL); + single_scheme = g_strndup (info->scheme, + suffix - info->scheme); + + info->filename = g_strconcat (SYSCONFDIR, + "/X11/desktop-menus/", + single_scheme, + ".menu", + NULL); + + g_free (single_scheme); + + file_uri = gnome_vfs_uri_new (info->filename); + + exists = gnome_vfs_uri_exists (file_uri); + gnome_vfs_uri_unref (file_uri); + +#if 0 + g_printerr ("all-users filename %s exists = %d\n", + info->filename, exists); +#endif + } else { + exists = FALSE; + } + + if (!exists) { + /* + * 2nd: Try user-private + * ~/.gnome2/vfolders/scheme.vfolder-info + */ + g_free (info->filename); + info->filename = g_strconcat (g_get_home_dir (), + "/" DOT_GNOME "/vfolders/", + scheme, ".vfolder-info", + NULL); + +#if 0 + g_printerr ("using filename %s\n", + info->filename); +#endif + } +} + +static gboolean +g_str_case_equal (gconstpointer v1, + gconstpointer v2) +{ + const gchar *string1 = v1; + const gchar *string2 = v2; + + return g_ascii_strcasecmp (string1, string2) == 0; +} + +/* 31 bit hash function */ +static guint +g_str_case_hash (gconstpointer key) +{ + const char *p = key; + guint h = g_ascii_toupper (*p); + + if (h) + for (p += 1; *p != '\0'; p++) + h = (h << 5) - h + g_ascii_toupper (*p); + + return h; +} + +static gboolean +vfolder_info_init (VFolderInfo *info) +{ + info->loading = TRUE; + info->entries_ht = g_hash_table_new (g_str_case_hash, g_str_case_equal); + info->root = folder_new (info, "Root", TRUE); + + set_hardcoded_extend_uri (info); + + /* + * Set the default writedir, in case there is no .vfolder-info + * for this scheme yet. Otherwise this will be overwritten + * when we read our source. + */ + info->write_dir = g_strconcat (g_get_home_dir (), + "/" DOT_GNOME "/vfolders/", + info->scheme, + NULL); + + /* Figure out which .vfolder-info to read */ + vfolder_info_find_filenames (info); + + info->filename_monitor = + vfolder_monitor_file_new (info->filename, + filename_monitor_cb, + info); + + info->modification_time = time (NULL); + info->loading = FALSE; + info->dirty = FALSE; + + /* Read from the user's .vfolder-info if it exists */ + return vfolder_info_read_info (info, NULL, NULL); +} + +static void +vfolder_info_destroy (VFolderInfo *info) +{ + if (info == NULL) + return; + + vfolder_info_reset (info); + + if (info->filename_reload_tag) + g_source_remove (info->filename_reload_tag); + + g_static_rw_lock_free (&info->rw_lock); + + g_free (info->scheme); + + while (info->requested_monitors) { + GnomeVFSMethodHandle *monitor = info->requested_monitors->data; + vfolder_info_cancel_monitor (monitor); + } + + g_free (info); +} + +/* + * Call to recursively list folder contents, causing them to allocate entries, + * so that we get OnlyUnallocated folder counts correctly. + */ +static void +load_folders (Folder *folder) +{ + const GSList *iter; + + for (iter = folder_list_subfolders (folder); iter; iter = iter->next) { + Folder *folder = iter->data; + load_folders (folder); + } +} + +static GHashTable *infos = NULL; +G_LOCK_DEFINE_STATIC (vfolder_lock); + +VFolderInfo * +vfolder_info_locate (const gchar *scheme) +{ + VFolderInfo *info = NULL; + + G_LOCK (vfolder_lock); + + if (!infos) { + infos = + g_hash_table_new_full ( + g_str_hash, + g_str_equal, + NULL, + (GDestroyNotify) vfolder_info_destroy); + } + + info = g_hash_table_lookup (infos, scheme); + if (info) { + G_UNLOCK (vfolder_lock); + return info; + } + else { + info = vfolder_info_new (scheme); + g_hash_table_insert (infos, info->scheme, info); + + VFOLDER_INFO_WRITE_LOCK (info); + G_UNLOCK (vfolder_lock); + + if (!vfolder_info_init (info)) { + D (g_print ("DESTROYING INFO FOR SCHEME: %s\n", + scheme)); + + G_LOCK (vfolder_lock); + g_hash_table_remove (infos, info); + G_UNLOCK (vfolder_lock); + + return NULL; + } + + if (info->has_unallocated_folder) { + info->loading = TRUE; + load_folders (info->root); + info->loading = FALSE; + } + + VFOLDER_INFO_WRITE_UNLOCK (info); + return info; + } +} + +void +vfolder_info_set_dirty (VFolderInfo *info) +{ + if (info->loading) + return; + + info->dirty = TRUE; +} + +static Folder * +get_folder_for_path_list_n (Folder *parent, + gchar **paths, + gint path_index, + gboolean skip_last) +{ + Folder *child; + gchar *subname, *subsubname; + + if (!parent || folder_is_hidden (parent)) + return NULL; + + subname = paths [path_index]; + if (!subname) + return parent; + + subsubname = paths [path_index + 1]; + if (!subsubname && skip_last) + return parent; + + if (*subname == '\0') + child = parent; + else + child = folder_get_subfolder (parent, subname); + + return get_folder_for_path_list_n (child, + paths, + path_index + 1, + skip_last); +} + +static Folder * +get_folder_for_path (Folder *root, const gchar *path, gboolean skip_last) +{ + gchar **paths; + Folder *folder; + + paths = g_strsplit (path, "/", -1); + if (!paths) + return NULL; + + folder = get_folder_for_path_list_n (root, paths, 0, skip_last); + + g_strfreev (paths); + + return folder; +} + +Folder * +vfolder_info_get_parent (VFolderInfo *info, const gchar *path) +{ + return get_folder_for_path (info->root, path, TRUE); +} + +Folder * +vfolder_info_get_folder (VFolderInfo *info, const gchar *path) +{ + return get_folder_for_path (info->root, path, FALSE); +} + +Entry * +vfolder_info_get_entry (VFolderInfo *info, const gchar *path) +{ + Folder *parent; + gchar *subname; + + parent = vfolder_info_get_parent (info, path); + if (!parent) + return NULL; + + subname = strrchr (path, '/'); + if (!subname) + return NULL; + else + subname++; + + return folder_get_entry (parent, subname); +} + +const GSList * +vfolder_info_list_all_entries (VFolderInfo *info) +{ + return info->entries; +} + +Entry * +vfolder_info_lookup_entry (VFolderInfo *info, const gchar *name) +{ + return g_hash_table_lookup (info->entries_ht, name); +} + +void +vfolder_info_add_entry (VFolderInfo *info, Entry *entry) +{ + info->entries = g_slist_prepend (info->entries, entry); + g_hash_table_insert (info->entries_ht, + (gchar *) entry_get_displayname (entry), + entry); +} + +void +vfolder_info_remove_entry (VFolderInfo *info, Entry *entry) +{ + info->entries = g_slist_remove (info->entries, entry); + g_hash_table_remove (info->entries_ht, + entry_get_displayname (entry)); +} + +#ifdef VFOLDER_DEBUG +#define DEBUG_CHANGE_EMIT(_change_uri, _handle_uri) \ + g_print ("EMITTING CHANGE: %s for %s, %s%s%s\n", \ + _change_uri, \ + _handle_uri, \ + event_type==GNOME_VFS_MONITOR_EVENT_CREATED?"CREATED":"", \ + event_type==GNOME_VFS_MONITOR_EVENT_DELETED?"DELETED":"", \ + event_type==GNOME_VFS_MONITOR_EVENT_CHANGED?"CHANGED":"") +#else +#define DEBUG_CHANGE_EMIT(_change_uri, _handle_uri) +#endif + +void +vfolder_info_emit_change (VFolderInfo *info, + const char *path, + GnomeVFSMonitorEventType event_type) +{ + GSList *iter; + GnomeVFSURI *uri; + gchar *escpath, *uristr; + + if (info->loading) + return; + + escpath = gnome_vfs_escape_path_string (path); + uristr = g_strconcat (info->scheme, "://", escpath, NULL); + uri = gnome_vfs_uri_new (uristr); + + for (iter = info->requested_monitors; iter; iter = iter->next) { + MonitorHandle *handle = iter->data; + + if (gnome_vfs_uri_equal (uri, handle->uri) || + (handle->type == GNOME_VFS_MONITOR_DIRECTORY && + gnome_vfs_uri_is_parent (handle->uri, + uri, + FALSE))) { + DEBUG_CHANGE_EMIT (uristr, handle->uri->text); + + gnome_vfs_monitor_callback ( + (GnomeVFSMethodHandle *) handle, + uri, + event_type); + } + } + + gnome_vfs_uri_unref (uri); + g_free (escpath); + g_free (uristr); +} + +void +vfolder_info_add_monitor (VFolderInfo *info, + GnomeVFSMonitorType type, + GnomeVFSURI *uri, + GnomeVFSMethodHandle **handle) +{ + MonitorHandle *monitor = g_new0 (MonitorHandle, 1); + monitor->info = info; + monitor->type = type; + + monitor->uri = uri; + gnome_vfs_uri_ref (uri); + + info->requested_monitors = g_slist_prepend (info->requested_monitors, + monitor); + + D (g_print ("EXTERNALLY WATCHING: %s\n", + gnome_vfs_uri_to_string (uri, 0))); + + *handle = (GnomeVFSMethodHandle *) monitor; +} + +void +vfolder_info_cancel_monitor (GnomeVFSMethodHandle *handle) +{ + MonitorHandle *monitor = (MonitorHandle *) handle; + + monitor->info->requested_monitors = + g_slist_remove (monitor->info->requested_monitors, monitor); + + gnome_vfs_uri_unref (monitor->uri); + g_free (monitor); +} + +void +vfolder_info_destroy_all (void) +{ + G_LOCK (vfolder_lock); + + if (infos) { + g_hash_table_destroy (infos); + infos = NULL; + } + + G_UNLOCK (vfolder_lock); +} + +void +vfolder_info_dump_entries (VFolderInfo *info, int offset) +{ + g_slist_foreach (info->entries, + (GFunc) entry_dump, + GINT_TO_POINTER (offset)); +} diff --git a/modules/vfolder/vfolder-info.c.vfolder-hacks b/modules/vfolder/vfolder-info.c.vfolder-hacks new file mode 100644 index 0000000..6a71242 --- /dev/null +++ b/modules/vfolder/vfolder-info.c.vfolder-hacks @@ -0,0 +1,2189 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* + * vfolder-info.c - Loading of .vfolder-info files. External interface + * defined in vfolder-common.h + * + * Copyright (C) 2002 Ximian, Inc. + * + * The Gnome Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Gnome Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Alex Graveley + * Based on original code by George Lebl . + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "vfolder-common.h" +#include "vfolder-util.h" + +#define DOT_GNOME ".gnome2" + +typedef enum { + ITEM_DIR = 1, + MERGE_DIR +} ItemDirType; + +typedef struct { + VFolderInfo *info; + gint weight; + gchar *uri; + GSList *monitors; + ItemDirType type; +} ItemDir; + +/* .vfolder-info format example: + * + * + * /etc/X11/applnk + * + * /usr/share/applications + * + * /etc/X11/gnome/vfolders + * + * + * Root + * + * important.desktop + * + * + * + * SomeFolder + * http:///mywebdav.com/homedir + * + * + * Test_Folder + * file:///a_readonly_path + * + * Test_Folder.directory + * + * + * + * Application + * Game + * + * Clock + * + * + * somefile.desktop + * someotherfile.desktop + * yetanother.desktop + * + * + * + */ + + +/* + * XML VFolder description writing + */ +static void +add_xml_tree_from_query (xmlNode *parent, Query *query) +{ + xmlNode *real_parent; + + if (query->not) + real_parent = xmlNewChild (parent /* parent */, + NULL /* ns */, + "Not" /* name */, + NULL /* content */); + else + real_parent = parent; + + if (query->type == QUERY_KEYWORD) { + const char *string = g_quark_to_string (query->val.keyword); + + xmlNewChild (real_parent /* parent */, + NULL /* ns */, + "Keyword" /* name */, + string /* content */); + } else if (query->type == QUERY_FILENAME) { + xmlNewChild (real_parent /* parent */, + NULL /* ns */, + "Filename" /* name */, + query->val.filename /* content */); + } else if (query->type == QUERY_PARENT) { + xmlNewChild (real_parent /* parent */, + NULL /* ns */, + "ParentQuery" /* name */, + NULL /* content */); + } else if (query->type == QUERY_OR || + query->type == QUERY_AND) { + xmlNode *node; + const char *name; + GSList *li; + + if (query->type == QUERY_OR) + name = "Or"; + else /* QUERY_AND */ + name = "And"; + + node = xmlNewChild (real_parent /* parent */, + NULL /* ns */, + name /* name */, + NULL /* content */); + + for (li = query->val.queries; li != NULL; li = li->next) { + Query *subquery = li->data; + add_xml_tree_from_query (node, subquery); + } + } else { + g_assert_not_reached (); + } +} + +static void +add_excludes_to_xml (gpointer key, gpointer value, gpointer user_data) +{ + const char *filename = key; + xmlNode *folder_node = user_data; + + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Exclude" /* name */, + filename /* content */); +} + +static void +add_xml_tree_from_folder (xmlNode *parent, Folder *folder) +{ + const GSList *li; + xmlNode *folder_node; + const gchar *extend_uri; + + /* + * return if this folder hasn't been modified by the user, + * and contains no modified subfolders. + */ + if (!folder->user_private && !folder->has_user_private_subfolders) + return; + + folder_node = xmlNewChild (parent /* parent */, + NULL /* ns */, + "Folder" /* name */, + NULL /* content */); + + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Name" /* name */, + folder_get_name (folder) /* content */); + + extend_uri = folder_get_extend_uri (folder); + if (extend_uri) { + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + folder->is_link ? "ParentLink" : "Parent", + extend_uri /* content */); + } + + if (folder->user_private) { + const gchar *desktop_file; + + if (folder->read_only) + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "ReadOnly" /* name */, + NULL /* content */); + if (folder->dont_show_if_empty) + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "DontShowIfEmpty" /* name */, + NULL /* content */); + if (folder->only_unallocated) + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "OnlyUnallocated" /* name */, + NULL /* content */); + + if (folder->desktop_file != NULL) { + desktop_file = folder_get_desktop_file (folder); + if (desktop_file) + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Desktop" /* name */, + desktop_file); + } + + for (li = folder->includes; li != NULL; li = li->next) { + const char *include = li->data; + xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Include" /* name */, + include /* content */); + } + + if (folder->excludes) { + g_hash_table_foreach (folder->excludes, + add_excludes_to_xml, + folder_node); + } + + if (folder->query) { + xmlNode *query_node; + query_node = xmlNewChild (folder_node /* parent */, + NULL /* ns */, + "Query" /* name */, + NULL /* content */); + add_xml_tree_from_query (query_node, + folder_get_query (folder)); + } + } + + for (li = folder_list_subfolders (folder); li != NULL; li = li->next) { + Folder *subfolder = li->data; + add_xml_tree_from_folder (folder_node, subfolder); + } +} + +static xmlDoc * +xml_tree_from_vfolder (VFolderInfo *info) +{ + xmlDoc *doc; + xmlNode *topnode; + GSList *li; + + doc = xmlNewDoc ("1.0"); + + topnode = xmlNewDocNode (doc /* doc */, + NULL /* ns */, + "VFolderInfo" /* name */, + NULL /* content */); + doc->xmlRootNode = topnode; + + if (info->write_dir != NULL) { + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "WriteDir" /* name */, + info->write_dir /* content */); + } + + /* Deprecated */ + if (info->desktop_dir != NULL) { + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "DesktopDir" /* name */, + info->desktop_dir /* content */); + } + + for (li = info->item_dirs; li != NULL; li = li->next) { + ItemDir *item_dir = li->data; + + switch (item_dir->type) { + case MERGE_DIR: + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "MergeDir" /* name */, + item_dir->uri /* content */); + break; + case ITEM_DIR: + xmlNewChild (topnode /* parent */, + NULL /* ns */, + "ItemDir" /* name */, + item_dir->uri /* content */); + break; + } + } + + if (info->root != NULL) + add_xml_tree_from_folder (topnode, info->root); + + return doc; +} + +/* FIXME: what to do about errors */ +void +vfolder_info_write_user (VFolderInfo *info) +{ + xmlDoc *doc; + GnomeVFSResult result; + gchar *tmpfile; + struct timeval tv; + + if (info->loading || !info->dirty) + return; + + if (!info->filename) + return; + + info->loading = TRUE; + + /* FIXME: errors, anyone? */ + result = vfolder_make_directory_and_parents (info->filename, + TRUE, + 0700); + if (result != GNOME_VFS_OK) { + g_warning ("Unable to create parent directory for " + "vfolder-info file: %s", + info->filename); + return; + } + + doc = xml_tree_from_vfolder (info); + if (!doc) + return; + + gettimeofday (&tv, NULL); + tmpfile = g_strdup_printf ("%s.tmp-%d", + info->filename, + (int) (tv.tv_sec ^ tv.tv_usec)); + + /* Write to temporary file */ + xmlSaveFormatFile (tmpfile, doc, TRUE /* format */); + + /* Avoid being notified of move, since we're performing it */ + if (info->filename_monitor) + vfolder_monitor_freeze (info->filename_monitor); + + /* Move temp file over to real filename */ + result = gnome_vfs_move (tmpfile, + info->filename, + TRUE /*force_replace*/); + if (result != GNOME_VFS_OK) { + g_warning ("Error writing vfolder configuration " + "file \"%s\": %s.", + info->filename, + gnome_vfs_result_to_string (result)); + } + + /* Start listening to changes again */ + if (info->filename_monitor) + vfolder_monitor_thaw (info->filename_monitor); + + xmlFreeDoc(doc); + g_free (tmpfile); + + info->modification_time = time (NULL); + info->dirty = FALSE; + info->loading = FALSE; +} + + +/* + * XML VFolder description reading + */ +static Query * +single_query_read (xmlNode *qnode) +{ + Query *query; + xmlNode *node; + + if (qnode->type != XML_ELEMENT_NODE || qnode->name == NULL) + return NULL; + + query = NULL; + + if (g_ascii_strcasecmp (qnode->name, "Not") == 0 && + qnode->xmlChildrenNode != NULL) { + xmlNode *iter; + + for (iter = qnode->xmlChildrenNode; + iter != NULL && query == NULL; + iter = iter->next) + query = single_query_read (iter); + if (query != NULL) { + query->not = ! query->not; + } + return query; + } + else if (g_ascii_strcasecmp (qnode->name, "Keyword") == 0) { + xmlChar *word = xmlNodeGetContent (qnode); + + if (word != NULL) { + query = query_new (QUERY_KEYWORD); + query->val.keyword = g_quark_from_string (word); + xmlFree (word); + } + return query; + } + else if (g_ascii_strcasecmp (qnode->name, "Filename") == 0) { + xmlChar *file = xmlNodeGetContent (qnode); + + if (file != NULL) { + query = query_new (QUERY_FILENAME); + query->val.filename = g_strdup (file); + xmlFree (file); + } + return query; + } + else if (g_ascii_strcasecmp (qnode->name, "ParentQuery") == 0) { + query = query_new (QUERY_PARENT); + } + else if (g_ascii_strcasecmp (qnode->name, "And") == 0) { + query = query_new (QUERY_AND); + } + else if (g_ascii_strcasecmp (qnode->name, "Or") == 0) { + query = query_new (QUERY_OR); + } + else { + /* We don't understand */ + return NULL; + } + + /* This must be OR or AND */ + g_assert (query != NULL); + + for (node = qnode->xmlChildrenNode; node; node = node->next) { + Query *new_query = single_query_read (node); + + if (new_query != NULL) + query->val.queries = + g_slist_prepend (query->val.queries, new_query); + } + + query->val.queries = g_slist_reverse (query->val.queries); + + return query; +} + +static void +add_or_set_query (Query **query, Query *new_query) +{ + if (*query == NULL) { + *query = new_query; + } else { + Query *old_query = *query; + *query = query_new (QUERY_OR); + (*query)->val.queries = + g_slist_append ((*query)->val.queries, old_query); + (*query)->val.queries = + g_slist_append ((*query)->val.queries, new_query); + } +} + +static Query * +query_read (xmlNode *qnode) +{ + Query *query; + xmlNode *node; + + query = NULL; + + for (node = qnode->xmlChildrenNode; node != NULL; node = node->next) { + if (node->type != XML_ELEMENT_NODE || + node->name == NULL) + continue; + + if (g_ascii_strcasecmp (node->name, "Not") == 0 && + node->xmlChildrenNode != NULL) { + xmlNode *iter; + Query *new_query = NULL; + + for (iter = node->xmlChildrenNode; + iter != NULL && new_query == NULL; + iter = iter->next) + new_query = single_query_read (iter); + if (new_query != NULL) { + new_query->not = ! new_query->not; + add_or_set_query (&query, new_query); + } + } else { + Query *new_query = single_query_read (node); + if (new_query != NULL) + add_or_set_query (&query, new_query); + } + } + + return query; +} + +static Folder * +folder_read (VFolderInfo *info, gboolean user_private, xmlNode *fnode) +{ + Folder *folder; + xmlNode *node; + + folder = folder_new (info, NULL, user_private); + + for (node = fnode->xmlChildrenNode; node != NULL; node = node->next) { + if (node->type != XML_ELEMENT_NODE || + node->name == NULL) + continue; + + if (g_ascii_strcasecmp (node->name, "Name") == 0) { + xmlChar *name = xmlNodeGetContent (node); + + if (name) { + g_free (folder->name); + folder_set_name (folder, name); + xmlFree (name); + } + } + else if (g_ascii_strcasecmp (node->name, "Parent") == 0) { + xmlChar *parent = xmlNodeGetContent (node); + + if (parent) { + gchar *esc_parent; + + esc_parent = vfolder_escape_home (parent); + folder_set_extend_uri (folder, esc_parent); + folder->is_link = FALSE; + + xmlFree (parent); + g_free (esc_parent); + } + } + else if (g_ascii_strcasecmp (node->name, "ParentLink") == 0) { + xmlChar *parent = xmlNodeGetContent (node); + + if (parent) { + gchar *esc_parent; + + esc_parent = vfolder_escape_home (parent); + folder_set_extend_uri (folder, esc_parent); + folder->is_link = TRUE; + + xmlFree (parent); + g_free (esc_parent); + } + } + else if (g_ascii_strcasecmp (node->name, "Desktop") == 0) { + xmlChar *desktop = xmlNodeGetContent (node); + + if (desktop) { + folder_set_desktop_file (folder, desktop); + xmlFree (desktop); + } + } + else if (g_ascii_strcasecmp (node->name, "Include") == 0) { + xmlChar *file = xmlNodeGetContent (node); + + if (file) { + gchar *esc_file; + + esc_file = vfolder_escape_home (file); + folder_add_include (folder, esc_file); + + xmlFree (file); + g_free (esc_file); + } + } + else if (g_ascii_strcasecmp (node->name, "Exclude") == 0) { + xmlChar *file = xmlNodeGetContent (node); + + if (file) { + gchar *esc_file; + + esc_file = vfolder_escape_home (file); + folder_add_exclude (folder, esc_file); + + xmlFree (file); + g_free (esc_file); + } + } + else if (g_ascii_strcasecmp (node->name, "Query") == 0) { + Query *query; + + query = query_read (node); + if (query) + folder_set_query (folder, query); + } + else if (g_ascii_strcasecmp (node->name, "Folder") == 0) { + Folder *new_folder = folder_read (info, + user_private, + node); + + if (new_folder != NULL) { + folder_add_subfolder (folder, new_folder); + folder_unref (new_folder); + } + } + else if (g_ascii_strcasecmp (node->name, + "OnlyUnallocated") == 0) { + folder->only_unallocated = TRUE; + info->has_unallocated_folder = TRUE; + } + else if (g_ascii_strcasecmp (node->name, "ReadOnly") == 0) { + folder->read_only = TRUE; + } + else if (g_ascii_strcasecmp (node->name, + "DontShowIfEmpty") == 0) { + folder->dont_show_if_empty = TRUE; + } + } + + /* Name is required */ + if (!folder_get_name (folder)) { + folder_unref (folder); + return NULL; + } + + return folder; +} + +static void itemdir_monitor_cb (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data); + +static void writedir_monitor_cb (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data); + +static void desktopdir_monitor_cb (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data); + + +static char * +remove_double_slashes (const char *uri) +{ + const char *src; + char *dest; + char *result; + gboolean slash; + + if (uri == NULL) { + return NULL; + } + + result = malloc (strlen (uri) + 1); + if (result == NULL) { + return NULL; + } + + src = uri; + dest = result; + slash = FALSE; + + while (*src != '\0') { + /* Don't do anything if current char is a / and slash is TRUE*/ + if ((*src == '/') && (slash != FALSE)) { + src++; + continue; + } + + if ((*src == '/') && (slash == FALSE)) { + slash = TRUE; + + } else { + slash = FALSE; + } + + *dest = *src; + dest++; + src++; + } + *dest = '\0'; + + return result; +} + +static ItemDir * +itemdir_new (VFolderInfo *info, + const gchar *uri, + ItemDirType type, + gint weight) +{ + ItemDir *ret; + gchar *tmp_uri; + + ret = g_new0 (ItemDir, 1); + ret->info = info; + ret->weight = weight; + tmp_uri = vfolder_escape_home (uri); + ret->uri = remove_double_slashes (tmp_uri); + g_free (tmp_uri); + ret->type = type; + + info->item_dirs = g_slist_append (info->item_dirs, ret); + + return ret; +} + +static void +itemdir_free (ItemDir *itemdir) +{ + GSList *iter; + + for (iter = itemdir->monitors; iter; iter = iter->next) { + VFolderMonitor *monitor = iter->data; + vfolder_monitor_cancel (monitor); + } + + g_slist_free (itemdir->monitors); + g_free (itemdir->uri); + g_free (itemdir); +} + +static gboolean +read_vfolder_from_file (VFolderInfo *info, + const gchar *filename, + gboolean user_private, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + xmlDoc *doc; + xmlNode *node; + GnomeVFSResult my_result; + gint weight = 700; + + if (result == NULL) + result = &my_result; + + /* Fail silently if filename does not exist */ + if (access (filename, F_OK) != 0) + return TRUE; + + doc = xmlParseFile (filename); + if (doc == NULL + || doc->xmlRootNode == NULL + || doc->xmlRootNode->name == NULL + || g_ascii_strcasecmp (doc->xmlRootNode->name, + "VFolderInfo") != 0) { + *result = GNOME_VFS_ERROR_WRONG_FORMAT; + xmlFreeDoc(doc); + return FALSE; + } + + if (context != NULL && + gnome_vfs_context_check_cancellation (context)) { + xmlFreeDoc(doc); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + for (node = doc->xmlRootNode->xmlChildrenNode; + node != NULL; + node = node->next) { + if (node->type != XML_ELEMENT_NODE || + node->name == NULL) + continue; + + if (context != NULL && + gnome_vfs_context_check_cancellation (context)) { + xmlFreeDoc(doc); + *result = GNOME_VFS_ERROR_CANCELLED; + return FALSE; + } + + if (g_ascii_strcasecmp (node->name, "MergeDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + + if (dir != NULL) { + itemdir_new (info, dir, MERGE_DIR, weight--); + xmlFree (dir); + } + } + else if (g_ascii_strcasecmp (node->name, "ItemDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + + if (dir != NULL) { + itemdir_new (info, dir, ITEM_DIR, weight--); + xmlFree (dir); + } + } + else if (g_ascii_strcasecmp (node->name, "WriteDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + + if (dir != NULL) { + g_free (info->write_dir); + info->write_dir = vfolder_escape_home (dir); + xmlFree (dir); + } + } + else if (g_ascii_strcasecmp (node->name, "DesktopDir") == 0) { + xmlChar *dir = xmlNodeGetContent (node); + + if (dir != NULL) { + g_free (info->desktop_dir); + info->desktop_dir = vfolder_escape_home (dir); + xmlFree (dir); + } + } + else if (g_ascii_strcasecmp (node->name, "Folder") == 0) { + Folder *folder = folder_read (info, + user_private, + node); + + if (folder != NULL) { + if (info->root != NULL) + folder_unref (info->root); + + info->root = folder; + } + } + else if (g_ascii_strcasecmp (node->name, "ReadOnly") == 0) { + info->read_only = TRUE; + } + } + + xmlFreeDoc(doc); + + return TRUE; +} + + +/* + * MergeDir/ItemDir entry pool reading + */ +struct { + const gchar *dirname; + const gchar *keyword; +} mergedir_keywords[] = { + /*Parent Dir*/ /*Keyword to add*/ + + /* Gnome Menus */ + { "Development", "Development" }, + { "Editors", "TextEditor" }, + { "Games", "Game" }, + { "Graphics", "Graphics" }, + { "Internet", "Network" }, + { "Multimedia", "AudioVideo" }, + { "Office", "Office" }, + { "Settings", "Settings" }, + { "System", "System" }, + { "Utilities", "Utility" }, + + /* Ximian Menus */ + { "Addressbook", "Office" }, + { "Audio", "AudioVideo" }, + { "Calendar", "Office" }, + { "Finance", "Office" }, + + /* KDE Menus */ + { "WordProcessing", "Office" }, + { "Toys", "Utility" }, +}; + +static GQuark +get_mergedir_keyword (const gchar *dirname) +{ + gint i; + + for (i = 0; i < G_N_ELEMENTS (mergedir_keywords); i++) { + if (g_ascii_strcasecmp (mergedir_keywords [i].dirname, + dirname) == 0) { + return g_quark_from_static_string ( + mergedir_keywords [i].keyword); + } + } + + return 0; +} + +static Entry * +create_itemdir_entry (ItemDir *id, + const gchar *rel_path, + GnomeVFSFileInfo *file_info) +{ + Entry *new_entry = NULL; + gchar *file_uri; + + if (!vfolder_check_extension (file_info->name, ".desktop")) + return NULL; + + if (vfolder_info_lookup_entry (id->info, file_info->name)) { + D (g_print ("EXCLUDING DUPLICATE ENTRY: %s\n", + file_info->name)); + return NULL; + } + + file_uri = vfolder_build_uri (id->uri, rel_path, NULL); + + /* Ref belongs to the VFolderInfo */ + new_entry = entry_new (id->info, + file_uri /*filename*/, + file_info->name /*displayname*/, + FALSE /*user_private*/, + id->weight /*weight*/); + + g_free (file_uri); + + return new_entry; +} + +static void +add_keywords_from_relative_path (Entry *new_entry, const gchar *rel_path) +{ + gchar **pelems; + GQuark keyword; + gint i; + + pelems = g_strsplit (rel_path, "/", -1); + if (!pelems) + return; + + for (i = 0; pelems [i]; i++) { + keyword = get_mergedir_keyword (pelems [i]); + if (keyword) + entry_add_implicit_keyword (new_entry, keyword); + } + + g_strfreev (pelems); +} + +static void +set_mergedir_entry_keywords (Entry *new_entry, const gchar *rel_path) +{ + static GQuark merged = 0, application = 0, core_quark = 0; + + if (!merged) { + merged = g_quark_from_static_string ("Merged"); + application = g_quark_from_static_string("Application"); + core_quark = g_quark_from_static_string ("Core"); + } + + /* + * Mergedirs have the 'Merged' and 'Appliction' keywords added. + */ + entry_add_implicit_keyword (new_entry, merged); + entry_add_implicit_keyword (new_entry, application); + + if (!strcmp (rel_path, entry_get_displayname (new_entry))) + entry_add_implicit_keyword (new_entry, core_quark); + else + add_keywords_from_relative_path (new_entry, rel_path); +} + +static Entry * +create_mergedir_entry (ItemDir *id, + const gchar *rel_path, + GnomeVFSFileInfo *file_info) +{ + Entry *new_entry; + + new_entry = create_itemdir_entry (id, rel_path, file_info); + if (new_entry) + set_mergedir_entry_keywords (new_entry, rel_path); + + return new_entry; +} + +static Entry * +create_entry_or_add_dir_monitor (ItemDir *id, + const gchar *rel_path, + GnomeVFSFileInfo *file_info) +{ + VFolderMonitor *dir_monitor; + Entry *ret = NULL; + gchar *file_uri; + + if (file_info->type == GNOME_VFS_FILE_TYPE_DIRECTORY) { + /* Add monitor for subdirectory of this MergeDir/ItemDir */ + file_uri = vfolder_build_uri (id->uri, rel_path, NULL); + dir_monitor = vfolder_monitor_dir_new (file_uri, + itemdir_monitor_cb, + id); + if (dir_monitor) + id->monitors = g_slist_prepend (id->monitors, + dir_monitor); + g_free (file_uri); + } + else { + switch (id->type) { + case MERGE_DIR: + ret = create_mergedir_entry (id, rel_path, file_info); + break; + case ITEM_DIR: + ret = create_itemdir_entry (id, rel_path, file_info); + break; + } + } + + return ret; +} + +static gboolean +create_entry_directory_visit_cb (const gchar *rel_path, + GnomeVFSFileInfo *file_info, + gboolean recursing_will_loop, + gpointer user_data, + gboolean *recurse) +{ + ItemDir *id = user_data; + + create_entry_or_add_dir_monitor (id, rel_path, file_info); + + *recurse = !recursing_will_loop; + return TRUE; +} + +static gboolean +vfolder_info_read_info (VFolderInfo *info, + GnomeVFSResult *result, + GnomeVFSContext *context) +{ + gboolean ret = FALSE; + GSList *iter; + + if (!info->filename) + return FALSE; + + /* Don't let set_dirty write out the file */ + info->loading = TRUE; + + ret = read_vfolder_from_file (info, + info->filename, + TRUE, + result, + context); + if (ret) { + if (info->write_dir) + info->write_dir_monitor = + vfolder_monitor_dir_new (info->write_dir, + writedir_monitor_cb, + info); + + if (info->desktop_dir) + info->desktop_dir_monitor = + vfolder_monitor_dir_new (info->desktop_dir, + desktopdir_monitor_cb, + info); + + /* Load ItemDir/MergeDirs in order of appearance. */ + for (iter = info->item_dirs; iter; iter = iter->next) { + ItemDir *id = iter->data; + VFolderMonitor *dir_monitor; + + /* Add a monitor for the root directory */ + dir_monitor = + vfolder_monitor_dir_new (id->uri, + itemdir_monitor_cb, + id); + if (dir_monitor) + id->monitors = g_slist_prepend (id->monitors, + dir_monitor); + + gnome_vfs_directory_visit ( + id->uri, + GNOME_VFS_FILE_INFO_DEFAULT, + GNOME_VFS_DIRECTORY_VISIT_DEFAULT, + create_entry_directory_visit_cb, + id); + } + } + + /* Allow set_dirty to write config file again */ + info->loading = FALSE; + + return ret; +} + +static void +vfolder_info_reset (VFolderInfo *info) +{ + GSList *iter; + + info->loading = TRUE; + + if (info->filename_monitor) { + vfolder_monitor_cancel (info->filename_monitor); + info->filename_monitor = NULL; + } + + if (info->write_dir_monitor) { + vfolder_monitor_cancel (info->write_dir_monitor); + info->write_dir_monitor = NULL; + } + + for (iter = info->item_dirs; iter; iter = iter->next) { + ItemDir *dir = iter->data; + itemdir_free (dir); + } + g_slist_free (info->item_dirs); + info->item_dirs = NULL; + + g_free (info->filename); + g_free (info->write_dir); + g_free (info->desktop_dir); + + info->filename = NULL; + info->desktop_dir = NULL; + info->write_dir = NULL; + + folder_unref (info->root); + info->root = NULL; + + g_slist_foreach (info->entries, (GFunc) entry_unref, NULL); + g_slist_free (info->entries); + info->entries = NULL; + + if (info->entries_ht) { + g_hash_table_destroy (info->entries_ht); + info->entries_ht = NULL; + } + + /* Clear flags */ + info->read_only = + info->dirty = + info->loading = + info->has_unallocated_folder = FALSE; +} + + +/* + * VFolder ItemDir/MergeDir/WriteDir/DesktopDir directory monitoring + */ +static void +integrate_entry (Folder *folder, Entry *entry, gboolean do_add) +{ + const GSList *subs; + Entry *existing; + Query *query; + gboolean matches = FALSE; + + for (subs = folder_list_subfolders (folder); subs; subs = subs->next) { + Folder *asub = subs->data; + integrate_entry (asub, entry, do_add); + } + + if (folder->only_unallocated) + return; + + query = folder_get_query (folder); + if (query) + matches = query_try_match (query, folder, entry); + + existing = folder_get_entry (folder, entry_get_displayname (entry)); + if (existing) { + /* + * Do nothing if the existing entry has a higher weight than the + * one we wish to add. + */ + if (entry_get_weight (existing) > entry_get_weight (entry)) + return; + + folder_remove_entry (folder, existing); + + if (do_add && matches) { + folder_add_entry (folder, entry); + + folder_emit_changed (folder, + entry_get_displayname (entry), + GNOME_VFS_MONITOR_EVENT_CHANGED); + } else + folder_emit_changed (folder, + entry_get_displayname (entry), + GNOME_VFS_MONITOR_EVENT_DELETED); + } + else if (do_add && matches) { + folder_add_entry (folder, entry); + + folder_emit_changed (folder, + entry_get_displayname (entry), + GNOME_VFS_MONITOR_EVENT_CREATED); + } +} + +static void +integrate_itemdir_entry_createupdate (ItemDir *id, + GnomeVFSURI *full_uri, + const gchar *full_uristr, + const gchar *displayname, + GnomeVFSMonitorEventType event_type) +{ + Entry *entry; + GnomeVFSURI *real_uri; + const gchar *rel_path; + + rel_path = strstr (full_uristr, id->uri); + g_assert (rel_path != NULL); + rel_path += strlen (id->uri); + + /* Look for an existing entry with the same displayname */ + entry = vfolder_info_lookup_entry (id->info, displayname); + if (entry) { + real_uri = entry_get_real_uri (entry); + + if (gnome_vfs_uri_equal (full_uri, real_uri)) { + /* Refresh */ + entry_set_dirty (entry); + } + else if (entry_get_weight (entry) < id->weight) { + /* + * Existing entry is less important than the new + * one, so replace. + */ + entry_set_filename (entry, full_uristr); + entry_set_weight (entry, id->weight); + + if (id->type == MERGE_DIR) { + /* Add keywords from relative path */ + set_mergedir_entry_keywords (entry, rel_path); + } + } + + gnome_vfs_uri_unref (real_uri); + } + else if (event_type == GNOME_VFS_MONITOR_EVENT_CREATED) { + GnomeVFSFileInfo *file_info; + GnomeVFSResult result; + + file_info = gnome_vfs_file_info_new (); + + result = + gnome_vfs_get_file_info_uri ( + full_uri, + file_info, + GNOME_VFS_FILE_INFO_DEFAULT); + + if (result == GNOME_VFS_OK) + entry = create_entry_or_add_dir_monitor (id, + rel_path, + file_info); + + gnome_vfs_file_info_unref (file_info); + } + + if (entry) { + entry_ref (entry); + integrate_entry (id->info->root, + entry, + TRUE /* do_add */); + entry_unref (entry); + + id->info->modification_time = time (NULL); + } +} + +static gboolean +find_replacement_for_delete (ItemDir *id, Entry *entry) +{ + GSList *iter, *miter; + gint idx; + + idx = g_slist_index (id->info->item_dirs, id); + if (idx < 0) + return FALSE; + + iter = g_slist_nth (id->info->item_dirs, idx + 1); + + for (; iter; iter = iter->next) { + ItemDir *id_next = iter->data; + + for (miter = id_next->monitors; miter; miter = miter->next) { + VFolderMonitor *monitor = miter->data; + GnomeVFSURI *check_uri; + gchar *uristr, *rel_path; + gboolean exists; + + uristr = + vfolder_build_uri ( + monitor->uri, + entry_get_displayname (entry), + NULL); + + check_uri = gnome_vfs_uri_new (uristr); + exists = gnome_vfs_uri_exists (check_uri); + gnome_vfs_uri_unref (check_uri); + + if (!exists) { + g_free (uristr); + continue; + } + + entry_set_filename (entry, uristr); + entry_set_weight (entry, id_next->weight); + + if (id_next->type == MERGE_DIR) { + rel_path = strstr (uristr, id_next->uri); + rel_path += strlen (id_next->uri); + + /* Add keywords based on relative path */ + set_mergedir_entry_keywords (entry, rel_path); + } + + g_free (uristr); + return TRUE; + } + } + + return FALSE; +} + +static void +integrate_itemdir_entry_delete (ItemDir *id, + GnomeVFSURI *full_uri, + const gchar *displayname) +{ + Entry *entry; + GnomeVFSURI *real_uri; + gboolean replaced, equal; + + entry = vfolder_info_lookup_entry (id->info, displayname); + if (!entry) + return; + + real_uri = entry_get_real_uri (entry); + equal = gnome_vfs_uri_equal (full_uri, real_uri); + gnome_vfs_uri_unref (real_uri); + + /* Only care if its the currently visible entry being deleted */ + if (!equal) + return; + + replaced = find_replacement_for_delete (id, entry); + + entry_ref (entry); + integrate_entry (id->info->root, entry, replaced /* do_add */); + entry_unref (entry); + + id->info->modification_time = time (NULL); +} + +static void +itemdir_monitor_cb (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + ItemDir *id = user_data; + gchar *filename; + GnomeVFSURI *uri; + + D (g_print ("*** Itemdir '%s' monitor %s%s%s called! ***\n", + info_uri, + event_type == GNOME_VFS_MONITOR_EVENT_CREATED ? "CREATED":"", + event_type == GNOME_VFS_MONITOR_EVENT_DELETED ? "DELETED":"", + event_type == GNOME_VFS_MONITOR_EVENT_CHANGED ? "CHANGED":"")); + + /* Operating on the whole directory, ignore */ + if (!strcmp (monitor_uri, info_uri) || + !vfolder_check_extension (info_uri, ".desktop")) + return; + + uri = gnome_vfs_uri_new (info_uri); + filename = gnome_vfs_uri_extract_short_name (uri); + + switch (event_type) { + case GNOME_VFS_MONITOR_EVENT_CREATED: + case GNOME_VFS_MONITOR_EVENT_CHANGED: + VFOLDER_INFO_WRITE_LOCK (id->info); + integrate_itemdir_entry_createupdate (id, + uri, + info_uri, + filename, + event_type); + VFOLDER_INFO_WRITE_UNLOCK (id->info); + break; + case GNOME_VFS_MONITOR_EVENT_DELETED: + VFOLDER_INFO_WRITE_LOCK (id->info); + integrate_itemdir_entry_delete (id, uri, filename); + VFOLDER_INFO_WRITE_UNLOCK (id->info); + break; + default: + break; + } + + gnome_vfs_uri_unref (uri); + g_free (filename); +} + +static void +integrate_writedir_entry_changed (Folder *folder, + gchar *displayname, + GnomeVFSURI *changed_uri) +{ + Entry *entry; + GnomeVFSURI *real_uri; + const GSList *subs; + + entry = folder_get_entry (folder, displayname); + if (entry) { + real_uri = entry_get_real_uri (entry); + + if (gnome_vfs_uri_equal (real_uri, changed_uri)) { + entry_set_dirty (entry); + folder_emit_changed (folder, + displayname, + GNOME_VFS_MONITOR_EVENT_CHANGED); + } + + gnome_vfs_uri_unref (real_uri); + } + + for (subs = folder_list_subfolders (folder); subs; subs = subs->next) { + Folder *asub = subs->data; + integrate_writedir_entry_changed (asub, + displayname, + changed_uri); + } +} + +static void +writedir_monitor_cb (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + VFolderInfo *info = user_data; + GnomeVFSURI *uri; + gchar *filename, *filename_ts; + + /* Operating on the whole directory, ignore */ + if (!strcmp (monitor_uri, info_uri) || + (!vfolder_check_extension (info_uri, ".desktop") && + !vfolder_check_extension (info_uri, ".directory"))) + return; + + switch (event_type) { + case GNOME_VFS_MONITOR_EVENT_CHANGED: + uri = gnome_vfs_uri_new (info_uri); + filename_ts = gnome_vfs_uri_extract_short_name (uri); + filename = vfolder_untimestamp_file_name (filename_ts); + + VFOLDER_INFO_WRITE_LOCK (info); + integrate_writedir_entry_changed (info->root, filename, uri); + VFOLDER_INFO_WRITE_UNLOCK (info); + + gnome_vfs_uri_unref (uri); + g_free (filename_ts); + g_free (filename); + break; + case GNOME_VFS_MONITOR_EVENT_DELETED: + case GNOME_VFS_MONITOR_EVENT_CREATED: + default: + break; + } +} + +static void +desktopdir_monitor_cb (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + VFolderInfo *info = user_data; + GnomeVFSURI *uri; + + /* Operating on the whole directory, ignore */ + if (!strcmp (monitor_uri, info_uri) || + !vfolder_check_extension (info_uri, ".directory")) + return; + + switch (event_type) { + case GNOME_VFS_MONITOR_EVENT_CHANGED: + uri = gnome_vfs_uri_new (info_uri); + + VFOLDER_INFO_WRITE_LOCK (info); + integrate_writedir_entry_changed (info->root, + ".directory", + uri); + VFOLDER_INFO_WRITE_UNLOCK (info); + + gnome_vfs_uri_unref (uri); + break; + case GNOME_VFS_MONITOR_EVENT_DELETED: + case GNOME_VFS_MONITOR_EVENT_CREATED: + default: + break; + } +} + + +/* + * .vfolder-info monitoring + */ +static void +check_monitors_foreach (gpointer key, gpointer val, gpointer user_data) +{ + MonitorHandle *handle = key; + GSList *children = val; + GnomeVFSURI *uri, *curi; + const gchar *path; + + uri = handle->uri; + path = gnome_vfs_uri_get_path (handle->uri); + + if (handle->type == GNOME_VFS_MONITOR_DIRECTORY) { + Folder *folder; + GSList *new_children, *iter, *found; + + folder = vfolder_info_get_folder (handle->info, path); + if (!folder) { + gnome_vfs_monitor_callback ( + (GnomeVFSMethodHandle *) handle, + handle->uri, + GNOME_VFS_MONITOR_EVENT_DELETED); + return; + } + + /* + * FIXME: If someone has an folder which also + * has a , we won't receive change events for + * children matching the query... I think this is corner + * enough to ignore * though. + */ + if (folder->only_unallocated) + return; + + new_children = folder_list_children (folder); + + for (iter = children; iter; iter = iter->next) { + gchar *child_name = iter->data; + + /* Look for a child with the same name */ + found = g_slist_find_custom (new_children, + child_name, + (GCompareFunc) strcmp); + if (found) { + g_free (found->data); + new_children = + g_slist_delete_link (new_children, + found); + } else { + curi = + gnome_vfs_uri_append_file_name ( + handle->uri, + child_name); + + gnome_vfs_monitor_callback ( + (GnomeVFSMethodHandle *) handle, + curi, + GNOME_VFS_MONITOR_EVENT_DELETED); + + gnome_vfs_uri_unref (curi); + } + + g_free (child_name); + } + + /* Whatever is left is new, send created events */ + for (iter = new_children; iter; iter = iter->next) { + gchar *child_name = iter->data; + + curi = gnome_vfs_uri_append_file_name (handle->uri, + child_name); + + gnome_vfs_monitor_callback ( + (GnomeVFSMethodHandle *) handle, + curi, + GNOME_VFS_MONITOR_EVENT_CREATED); + + gnome_vfs_uri_unref (curi); + g_free (child_name); + } + + g_slist_free (new_children); + g_slist_free (children); + } + else { + gboolean found; + + found = vfolder_info_get_entry (handle->info, path) || + vfolder_info_get_folder (handle->info, path); + + gnome_vfs_monitor_callback ( + (GnomeVFSMethodHandle *) handle, + handle->uri, + found ? + GNOME_VFS_MONITOR_EVENT_CHANGED : + GNOME_VFS_MONITOR_EVENT_DELETED); + } +} + +static gboolean vfolder_info_init (VFolderInfo *info); + +static gboolean +filename_monitor_handle (gpointer user_data) +{ + VFolderInfo *info = user_data; + GHashTable *monitors; + GSList *iter; + + D (g_print ("*** PROCESSING .vfolder-info!!! ***\n")); + + monitors = g_hash_table_new (g_direct_hash, g_direct_equal); + + VFOLDER_INFO_WRITE_LOCK (info); + + /* Don't emit any events while we load */ + info->loading = TRUE; + + /* Compose a hash of all existing monitors and their children */ + for (iter = info->requested_monitors; iter; iter = iter->next) { + MonitorHandle *mhandle = iter->data; + GSList *monitored_paths = NULL; + Folder *folder; + + if (mhandle->type == GNOME_VFS_MONITOR_DIRECTORY) { + folder = + vfolder_info_get_folder ( + info, + gnome_vfs_uri_get_path (mhandle->uri)); + if (folder) + monitored_paths = folder_list_children (folder); + } + + g_hash_table_insert (monitors, mhandle, monitored_paths); + } + + vfolder_info_reset (info); + vfolder_info_init (info); + + /* Start sending events again */ + info->loading = FALSE; + + /* Traverse monitor hash and diff with newly read folder structure */ + g_hash_table_foreach (monitors, check_monitors_foreach, info); + + VFOLDER_INFO_WRITE_UNLOCK (info); + + g_hash_table_destroy (monitors); + + info->filename_reload_tag = 0; + return FALSE; +} + +static void +filename_monitor_cb (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + VFolderInfo *info = user_data; + + D (g_print ("*** Filename '%s' monitor %s%s%s called! ***\n", + info_uri, + event_type == GNOME_VFS_MONITOR_EVENT_CREATED ? "CREATED":"", + event_type == GNOME_VFS_MONITOR_EVENT_DELETED ? "DELETED":"", + event_type == GNOME_VFS_MONITOR_EVENT_CHANGED ? "CHANGED":"")); + + if (info->filename_reload_tag) { + g_source_remove (info->filename_reload_tag); + info->filename_reload_tag = 0; + } + + /* + * Don't process the .vfolder-info for 2 seconds after a delete event or + * .5 seconds after a create event. This allows files to be rewritten + * before we start reading it and possibly copying the system default + * file over top of it. + */ + switch (event_type) { + case GNOME_VFS_MONITOR_EVENT_DELETED: + info->filename_reload_tag = + g_timeout_add (2000, filename_monitor_handle, info); + break; + case GNOME_VFS_MONITOR_EVENT_CREATED: + info->filename_reload_tag = + g_timeout_add (500, filename_monitor_handle, info); + break; + case GNOME_VFS_MONITOR_EVENT_CHANGED: + default: + filename_monitor_handle (info); + break; + } +} + + +/* + * VFolderInfo Implementation + */ +static VFolderInfo * +vfolder_info_new (const char *scheme) +{ + VFolderInfo *info; + + info = g_new0 (VFolderInfo, 1); + info->scheme = g_strdup (scheme); + + g_static_rw_lock_init (&info->rw_lock); + + return info; +} + +static void +vfolder_info_find_filenames (VFolderInfo *info) +{ + gchar *scheme = info->scheme; + GnomeVFSURI *file_uri; + gboolean exists; + + /* + * FIXME: load from gconf + */ + + /* + * 1st: Try mandatory system-global file located at + * /etc/gnome-vfs-2.0/vfolders/scheme.vfolder-info. Writability will + * depend on permissions of this file. + */ + info->filename = g_strconcat (SYSCONFDIR, + "/gnome-vfs-2.0/vfolders/", + scheme, ".vfolder-info", + NULL); + file_uri = gnome_vfs_uri_new (info->filename); + + exists = gnome_vfs_uri_exists (file_uri); + gnome_vfs_uri_unref (file_uri); + + if (!exists) { + /* + * 2nd: Try user-private ~/.gnome2/vfolders/scheme.vfolder-info + */ + g_free (info->filename); + info->filename = g_strconcat (g_get_home_dir (), + "/" DOT_GNOME "/vfolders/", + scheme, ".vfolder-info", + NULL); + } + + /* + * Special case for applications-all-users where we want to add any + * paths specified in $GNOME2_PATH, for people installing in strange + * places. + */ + if (strcmp (scheme, "applications-all-users")) { + int i; + const char *path; + char *dir, **ppath; + ItemDir *id; + int weight = 800; + + path = g_getenv ("GNOME2_PATH"); + if (path) { + ppath = g_strsplit (path, ":", -1); + + for (i = 0; ppath[i] != NULL; i++) { + dir = g_build_filename (ppath[i], + "/share/applications/", + NULL); + id = itemdir_new (info, + dir, + ITEM_DIR, + weight--); + g_free (dir); + } + + g_strfreev (ppath); + } + } +} + +static gboolean +g_str_case_equal (gconstpointer v1, + gconstpointer v2) +{ + const gchar *string1 = v1; + const gchar *string2 = v2; + + return g_ascii_strcasecmp (string1, string2) == 0; +} + +/* 31 bit hash function */ +static guint +g_str_case_hash (gconstpointer key) +{ + const char *p = key; + guint h = g_ascii_toupper (*p); + + if (h) + for (p += 1; *p != '\0'; p++) + h = (h << 5) - h + g_ascii_toupper (*p); + + return h; +} + +static gboolean +vfolder_info_init (VFolderInfo *info) +{ + gchar *all_user_scheme; + + info->loading = TRUE; + info->entries_ht = g_hash_table_new (g_str_case_hash, g_str_case_equal); + info->root = folder_new (info, "Root", TRUE); + + /* + * Set the extend uri for the root folder to the -all-users version of + * the scheme, in case the user doesn't have a private .vfolder-info + * file yet. + */ + all_user_scheme = g_strconcat (info->scheme, "-all-users:///", NULL); + folder_set_extend_uri (info->root, all_user_scheme); + g_free (all_user_scheme); + + /* + * Set the default writedir, in case there is no .vfolder-info for this + * scheme yet. Otherwise this will be overwritten when we read our + * source. + */ + info->write_dir = g_strconcat (g_get_home_dir (), + "/" DOT_GNOME "/vfolders/", + info->scheme, + NULL); + + /* Figure out which .vfolder-info to read */ + vfolder_info_find_filenames (info); + + if (g_getenv ("GNOME_VFS_VFOLDER_INFODIR")) { + gchar *filename = g_strconcat (info->scheme, + ".vfolder-info", + NULL); + + g_free (info->filename); + info->filename = + vfolder_build_uri ( + g_getenv ("GNOME_VFS_VFOLDER_INFODIR"), + filename, + NULL); + g_free (filename); + } + + if (g_getenv ("GNOME_VFS_VFOLDER_WRITEDIR")) { + g_free (info->write_dir); + info->write_dir = + vfolder_build_uri ( + g_getenv ("GNOME_VFS_VFOLDER_WRITEDIR"), + info->scheme, + NULL); + } + + info->filename_monitor = + vfolder_monitor_file_new (info->filename, + filename_monitor_cb, + info); + + info->modification_time = time (NULL); + info->loading = FALSE; + info->dirty = FALSE; + + /* Read from the user's .vfolder-info if it exists */ + return vfolder_info_read_info (info, NULL, NULL); +} + +static void +vfolder_info_destroy (VFolderInfo *info) +{ + if (info == NULL) + return; + + vfolder_info_reset (info); + + if (info->filename_reload_tag) + g_source_remove (info->filename_reload_tag); + + g_static_rw_lock_free (&info->rw_lock); + + g_free (info->scheme); + + while (info->requested_monitors) { + GnomeVFSMethodHandle *monitor = info->requested_monitors->data; + vfolder_info_cancel_monitor (monitor); + } + + g_free (info); +} + +/* + * Call to recursively list folder contents, causing them to allocate entries, + * so that we get OnlyUnallocated folder counts correctly. + */ +static void +load_folders (Folder *folder) +{ + const GSList *iter; + + for (iter = folder_list_subfolders (folder); iter; iter = iter->next) { + Folder *folder = iter->data; + load_folders (folder); + } +} + +static GHashTable *infos = NULL; +G_LOCK_DEFINE_STATIC (vfolder_lock); + +VFolderInfo * +vfolder_info_locate (const gchar *scheme) +{ + VFolderInfo *info = NULL; + + G_LOCK (vfolder_lock); + + if (!infos) { + infos = + g_hash_table_new_full ( + g_str_hash, + g_str_equal, + NULL, + (GDestroyNotify) vfolder_info_destroy); + } + + info = g_hash_table_lookup (infos, scheme); + if (info) { + G_UNLOCK (vfolder_lock); + return info; + } + else { + info = vfolder_info_new (scheme); + g_hash_table_insert (infos, info->scheme, info); + + VFOLDER_INFO_WRITE_LOCK (info); + G_UNLOCK (vfolder_lock); + + if (!vfolder_info_init (info)) { + D (g_print ("DESTROYING INFO FOR SCHEME: %s\n", + scheme)); + + G_LOCK (vfolder_lock); + g_hash_table_remove (infos, info); + G_UNLOCK (vfolder_lock); + + return NULL; + } + + if (info->has_unallocated_folder) { + info->loading = TRUE; + load_folders (info->root); + info->loading = FALSE; + } + + VFOLDER_INFO_WRITE_UNLOCK (info); + return info; + } +} + +void +vfolder_info_set_dirty (VFolderInfo *info) +{ + if (info->loading) + return; + + info->dirty = TRUE; +} + +static Folder * +get_folder_for_path_list_n (Folder *parent, + gchar **paths, + gint path_index, + gboolean skip_last) +{ + Folder *child; + gchar *subname, *subsubname; + + if (!parent || folder_is_hidden (parent)) + return NULL; + + subname = paths [path_index]; + if (!subname) + return parent; + + subsubname = paths [path_index + 1]; + if (!subsubname && skip_last) + return parent; + + if (*subname == '\0') + child = parent; + else + child = folder_get_subfolder (parent, subname); + + return get_folder_for_path_list_n (child, + paths, + path_index + 1, + skip_last); +} + +static Folder * +get_folder_for_path (Folder *root, const gchar *path, gboolean skip_last) +{ + gchar **paths; + Folder *folder; + + paths = g_strsplit (path, "/", -1); + if (!paths) + return NULL; + + folder = get_folder_for_path_list_n (root, paths, 0, skip_last); + + g_strfreev (paths); + + return folder; +} + +Folder * +vfolder_info_get_parent (VFolderInfo *info, const gchar *path) +{ + return get_folder_for_path (info->root, path, TRUE); +} + +Folder * +vfolder_info_get_folder (VFolderInfo *info, const gchar *path) +{ + return get_folder_for_path (info->root, path, FALSE); +} + +Entry * +vfolder_info_get_entry (VFolderInfo *info, const gchar *path) +{ + Folder *parent; + gchar *subname; + + parent = vfolder_info_get_parent (info, path); + if (!parent) + return NULL; + + subname = strrchr (path, '/'); + if (!subname) + return NULL; + else + subname++; + + return folder_get_entry (parent, subname); +} + +const GSList * +vfolder_info_list_all_entries (VFolderInfo *info) +{ + return info->entries; +} + +Entry * +vfolder_info_lookup_entry (VFolderInfo *info, const gchar *name) +{ + return g_hash_table_lookup (info->entries_ht, name); +} + +void +vfolder_info_add_entry (VFolderInfo *info, Entry *entry) +{ + info->entries = g_slist_prepend (info->entries, entry); + g_hash_table_insert (info->entries_ht, + (gchar *) entry_get_displayname (entry), + entry); +} + +void +vfolder_info_remove_entry (VFolderInfo *info, Entry *entry) +{ + info->entries = g_slist_remove (info->entries, entry); + g_hash_table_remove (info->entries_ht, + entry_get_displayname (entry)); +} + +#ifdef VFOLDER_DEBUG +#define DEBUG_CHANGE_EMIT(_change_uri, _handle_uri) \ + g_print ("EMITTING CHANGE: %s for %s, %s%s%s\n", \ + _change_uri, \ + _handle_uri, \ + event_type==GNOME_VFS_MONITOR_EVENT_CREATED?"CREATED":"", \ + event_type==GNOME_VFS_MONITOR_EVENT_DELETED?"DELETED":"", \ + event_type==GNOME_VFS_MONITOR_EVENT_CHANGED?"CHANGED":"") +#else +#define DEBUG_CHANGE_EMIT(_change_uri, _handle_uri) +#endif + +void +vfolder_info_emit_change (VFolderInfo *info, + const char *path, + GnomeVFSMonitorEventType event_type) +{ + GSList *iter; + GnomeVFSURI *uri; + gchar *escpath, *uristr; + + if (info->loading) + return; + + escpath = gnome_vfs_escape_path_string (path); + uristr = g_strconcat (info->scheme, "://", escpath, NULL); + uri = gnome_vfs_uri_new (uristr); + + for (iter = info->requested_monitors; iter; iter = iter->next) { + MonitorHandle *handle = iter->data; + + if (gnome_vfs_uri_equal (uri, handle->uri) || + (handle->type == GNOME_VFS_MONITOR_DIRECTORY && + gnome_vfs_uri_is_parent (handle->uri, + uri, + FALSE))) { + DEBUG_CHANGE_EMIT (uristr, handle->uri->text); + + gnome_vfs_monitor_callback ( + (GnomeVFSMethodHandle *) handle, + uri, + event_type); + } + } + + gnome_vfs_uri_unref (uri); + g_free (escpath); + g_free (uristr); +} + +void +vfolder_info_add_monitor (VFolderInfo *info, + GnomeVFSMonitorType type, + GnomeVFSURI *uri, + GnomeVFSMethodHandle **handle) +{ + MonitorHandle *monitor = g_new0 (MonitorHandle, 1); + monitor->info = info; + monitor->type = type; + + monitor->uri = uri; + gnome_vfs_uri_ref (uri); + + info->requested_monitors = g_slist_prepend (info->requested_monitors, + monitor); + + D (g_print ("EXTERNALLY WATCHING: %s\n", + gnome_vfs_uri_to_string (uri, 0))); + + *handle = (GnomeVFSMethodHandle *) monitor; +} + +void +vfolder_info_cancel_monitor (GnomeVFSMethodHandle *handle) +{ + MonitorHandle *monitor = (MonitorHandle *) handle; + + monitor->info->requested_monitors = + g_slist_remove (monitor->info->requested_monitors, monitor); + + gnome_vfs_uri_unref (monitor->uri); + g_free (monitor); +} + +void +vfolder_info_destroy_all (void) +{ + G_LOCK (vfolder_lock); + + if (infos) { + g_hash_table_destroy (infos); + infos = NULL; + } + + G_UNLOCK (vfolder_lock); +} + +void +vfolder_info_dump_entries (VFolderInfo *info, int offset) +{ + g_slist_foreach (info->entries, + (GFunc) entry_dump, + GINT_TO_POINTER (offset)); +} diff --git a/modules/vfolder/vfolder-method.c b/modules/vfolder/vfolder-method.c new file mode 100644 index 0000000..503216d --- /dev/null +++ b/modules/vfolder/vfolder-method.c @@ -0,0 +1,1734 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* + * vfolder-method.c - Gnome-VFS interface to manipulating vfolders. + * + * Copyright (C) 2002 Ximian, Inc. + * + * The Gnome Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Gnome Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Alex Graveley + * Based on original code by George Lebl . + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include +#include +#include +#include +#include + +#include "vfolder-common.h" +#include "vfolder-util.h" + + +typedef struct { + VFolderInfo *info; + GnomeVFSHandle *handle; + Entry *entry; + gboolean write; +} FileHandle; + +static FileHandle * +file_handle_new (GnomeVFSHandle *file_handle, + VFolderInfo *info, + Entry *entry, + gboolean write) +{ + if (file_handle != NULL) { + FileHandle *handle = g_new0 (FileHandle, 1); + + handle->handle = file_handle; + handle->info = info; + handle->write = write; + + handle->entry = entry; + entry_ref (entry); + + return handle; + } else + return NULL; +} + +static void +file_handle_free (FileHandle *handle) +{ + entry_unref (handle->entry); + g_free (handle); +} + +#define NICE_UNLOCK_INFO(info, write) \ + do { \ + if (write) { \ + VFOLDER_INFO_WRITE_UNLOCK (info); \ + } else { \ + VFOLDER_INFO_READ_UNLOCK (info); \ + } \ + } while (0) + + +/* + * GnomeVFS Callbacks + */ +static GnomeVFSResult +do_open (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result = GNOME_VFS_OK; + VFolderInfo *info; + Folder *parent; + FolderChild child; + GnomeVFSHandle *file_handle = NULL; + FileHandle *vfolder_handle; + VFolderURI vuri; + gboolean want_write = mode & GNOME_VFS_OPEN_WRITE; + + VFOLDER_URI_PARSE (uri, &vuri); + + /* These can't be very nice FILE names */ + if (!vuri.file || vuri.ends_in_slash) + return GNOME_VFS_ERROR_INVALID_URI; + + info = vfolder_info_locate (vuri.scheme); + if (!info) + return GNOME_VFS_ERROR_INVALID_URI; + + if (want_write && (info->read_only || vuri.is_all_scheme)) + return GNOME_VFS_ERROR_READ_ONLY; + + if (want_write) + VFOLDER_INFO_WRITE_LOCK (info); + else + VFOLDER_INFO_READ_LOCK (info); + + if (vuri.is_all_scheme) { + child.type = DESKTOP_FILE; + child.entry = vfolder_info_lookup_entry (info, vuri.file); + + if (!child.entry) { + NICE_UNLOCK_INFO (info, want_write); + return GNOME_VFS_ERROR_NOT_FOUND; + } + } else { + parent = vfolder_info_get_parent (info, vuri.path); + if (!parent) { + NICE_UNLOCK_INFO (info, want_write); + return GNOME_VFS_ERROR_NOT_FOUND; + } + + if (!folder_get_child (parent, vuri.file, &child)) { + NICE_UNLOCK_INFO (info, want_write); + return GNOME_VFS_ERROR_NOT_FOUND; + } + + if (child.type == FOLDER) { + NICE_UNLOCK_INFO (info, want_write); + return GNOME_VFS_ERROR_IS_DIRECTORY; + } + + if (want_write) { + if (!entry_make_user_private (child.entry, parent)) { + VFOLDER_INFO_WRITE_UNLOCK (info); + return GNOME_VFS_ERROR_READ_ONLY; + } + } + } + + file_uri = entry_get_real_uri (child.entry); + result = gnome_vfs_open_uri_cancellable (&file_handle, + file_uri, + mode, + context); + gnome_vfs_uri_unref (file_uri); + + if (result == GNOME_VFS_ERROR_CANCELLED) { + NICE_UNLOCK_INFO (info, want_write); + return result; + } + + vfolder_handle = file_handle_new (file_handle, + info, + child.entry, + want_write); + *method_handle = (GnomeVFSMethodHandle *) vfolder_handle; + + NICE_UNLOCK_INFO (info, want_write); + + return result; +} + + +static GnomeVFSResult +do_create (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + gboolean exclusive, + guint perm, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + GnomeVFSHandle *file_handle; + FileHandle *vfolder_handle; + GnomeVFSURI *file_uri; + VFolderURI vuri; + VFolderInfo *info; + Folder *parent; + FolderChild child; + Entry *new_entry; + const gchar *dirname; + gchar *filename, *basename; + + VFOLDER_URI_PARSE (uri, &vuri); + + /* These can't be very nice FILE names */ + if (vuri.file == NULL || vuri.ends_in_slash) + return GNOME_VFS_ERROR_INVALID_URI; + + if (!vfolder_check_extension (vuri.file, ".desktop") && + !vfolder_check_extension (vuri.file, ".directory")) { + return GNOME_VFS_ERROR_INVALID_URI; + } + + info = vfolder_info_locate (vuri.scheme); + if (!info) + return GNOME_VFS_ERROR_INVALID_URI; + + if (info->read_only || vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + VFOLDER_INFO_WRITE_LOCK (info); + + parent = vfolder_info_get_parent (info, vuri.path); + if (!parent) { + VFOLDER_INFO_WRITE_UNLOCK (info); + return GNOME_VFS_ERROR_NOT_FOUND; + } + + if (folder_get_child (parent, vuri.file, &child)) { + VFOLDER_INFO_WRITE_UNLOCK (info); + + if (child.type == FOLDER) + return GNOME_VFS_ERROR_IS_DIRECTORY; + else if (child.type == DESKTOP_FILE) + return GNOME_VFS_ERROR_FILE_EXISTS; + } + + /* + * make a user-local copy, so the folder will be written to the user's + * private .vfolder-info file + */ + if (!folder_make_user_private (parent)) { + VFOLDER_INFO_WRITE_UNLOCK (info); + return GNOME_VFS_ERROR_READ_ONLY; + } + + /* + * Create file in writedir unless writedir is not set or folder is + * a . Otherwise create in parent if exists. + */ + if (info->write_dir && !parent->is_link) { + /* Create uniquely named file in write_dir */ + dirname = info->write_dir; + basename = vfolder_timestamp_file_name (vuri.file); + filename = vfolder_build_uri (dirname, basename, NULL); + g_free (basename); + } else if (folder_get_extend_uri (parent)) { + /* No writedir, try modifying the parent */ + dirname = folder_get_extend_uri (parent); + filename = vfolder_build_uri (dirname, vuri.file, NULL); + } else { + /* Nowhere to create file, fail */ + VFOLDER_INFO_WRITE_UNLOCK (info); + return GNOME_VFS_ERROR_READ_ONLY; + } + + /* Make sure the destination directory exists */ + result = vfolder_make_directory_and_parents (dirname, FALSE, 0700); + if (result != GNOME_VFS_OK) { + VFOLDER_INFO_WRITE_UNLOCK (info); + g_free (filename); + return result; + } + + file_uri = gnome_vfs_uri_new (filename); + result = gnome_vfs_create_uri_cancellable (&file_handle, + file_uri, + mode, + exclusive, + perm, + context); + gnome_vfs_uri_unref (file_uri); + + if (result != GNOME_VFS_OK) { + VFOLDER_INFO_WRITE_UNLOCK (info); + g_free (filename); + return result; + } + + /* Create it */ + new_entry = entry_new (info, + filename, + vuri.file, + TRUE /*user_private*/, + 1000 /*weight*/); + g_free (filename); + + if (!new_entry) { + VFOLDER_INFO_WRITE_UNLOCK (info); + return GNOME_VFS_ERROR_READ_ONLY; + } + + if (!parent->is_link) + folder_add_include (parent, entry_get_filename (new_entry)); + + folder_add_entry (parent, new_entry); + + vfolder_handle = file_handle_new (file_handle, + info, + new_entry, + mode & GNOME_VFS_OPEN_WRITE); + *method_handle = (GnomeVFSMethodHandle *) vfolder_handle; + + VFOLDER_INFO_WRITE_UNLOCK (info); + + vfolder_info_emit_change (info, + uri->text, + GNOME_VFS_MONITOR_EVENT_CREATED); + + return result; +} + + +static GnomeVFSResult +do_close (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *) method_handle; + + if (method_handle == (GnomeVFSMethodHandle *) method) + return GNOME_VFS_OK; + + result = gnome_vfs_close_cancellable (handle->handle, context); + + if (handle->write) { + VFOLDER_INFO_WRITE_LOCK (handle->info); + entry_set_dirty (handle->entry); + VFOLDER_INFO_WRITE_UNLOCK (handle->info); + } + + file_handle_free (handle); + + return result; +} + + +static GnomeVFSResult +do_read (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + result = gnome_vfs_read_cancellable (handle->handle, + buffer, num_bytes, + bytes_read, + context); + + return result; +} + + +static GnomeVFSResult +do_write (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gconstpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_written, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + result = gnome_vfs_write_cancellable (handle->handle, + buffer, num_bytes, + bytes_written, + context); + + return result; +} + + +static GnomeVFSResult +do_seek (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSSeekPosition whence, + GnomeVFSFileOffset offset, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + result = gnome_vfs_seek_cancellable (handle->handle, + whence, offset, + context); + + return result; +} + + +static GnomeVFSResult +do_tell (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileOffset *offset_return) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + result = gnome_vfs_tell (handle->handle, offset_return); + + return result; +} + + +static GnomeVFSResult +do_truncate_handle (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileSize where, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *)method_handle; + + result = gnome_vfs_truncate_handle_cancellable (handle->handle, + where, + context); + + return result; +} + + +static GnomeVFSResult +do_truncate (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileSize where, + GnomeVFSContext *context) +{ + GnomeVFSURI *file_uri; + GnomeVFSResult result = GNOME_VFS_OK; + VFolderInfo *info; + Folder *parent; + FolderChild child; + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + /* These can't be very nice FILE names */ + if (vuri.file == NULL || vuri.ends_in_slash) + return GNOME_VFS_ERROR_INVALID_URI; + + info = vfolder_info_locate (vuri.scheme); + if (!info) + return GNOME_VFS_ERROR_INVALID_URI; + + if (info->read_only || vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + VFOLDER_INFO_WRITE_LOCK (info); + + parent = vfolder_info_get_parent (info, vuri.path); + if (!parent) { + VFOLDER_INFO_WRITE_UNLOCK (info); + return GNOME_VFS_ERROR_NOT_FOUND; + } + + if (!folder_get_child (parent, vuri.file, &child)) { + VFOLDER_INFO_WRITE_UNLOCK (info); + return GNOME_VFS_ERROR_NOT_FOUND; + } + + if (child.type == FOLDER) { + VFOLDER_INFO_WRITE_UNLOCK (info); + return GNOME_VFS_ERROR_IS_DIRECTORY; + } + + if (!entry_make_user_private (child.entry, parent)) { + VFOLDER_INFO_WRITE_UNLOCK (info); + return GNOME_VFS_ERROR_READ_ONLY; + } + + file_uri = entry_get_real_uri (child.entry); + + VFOLDER_INFO_WRITE_UNLOCK (info); + + result = gnome_vfs_truncate_uri_cancellable (file_uri, where, context); + gnome_vfs_uri_unref (file_uri); + + return result; +} + + +typedef struct { + VFolderInfo *info; + Folder *folder; + + GnomeVFSFileInfoOptions options; + + /* List of Entries */ + GSList *list; + GSList *current; +} DirHandle; + +static DirHandle * +dir_handle_new (VFolderInfo *info, + Folder *folder, + GnomeVFSFileInfoOptions options) +{ + DirHandle *ret = g_new0 (DirHandle, 1); + + ret->info = info; + ret->options = options; + ret->folder = folder; + folder_ref (folder); + + ret->list = ret->current = folder_list_children (folder); + + return ret; +} + +static DirHandle * +dir_handle_new_all (VFolderInfo *info, + GnomeVFSFileInfoOptions options) +{ + DirHandle *ret = g_new0 (DirHandle, 1); + const GSList *iter; + + iter = vfolder_info_list_all_entries (info); + for (; iter; iter = iter->next) { + Entry *entry = iter->data; + ret->list = + g_slist_prepend ( + ret->list, + g_strdup (entry_get_displayname (entry))); + } + ret->list = g_slist_reverse (ret->list); + + ret->info = info; + ret->options = options; + ret->current = ret->list; + + return ret; +} + +static void +dir_handle_free (DirHandle *handle) +{ + if (handle->folder) + folder_unref (handle->folder); + + g_slist_foreach (handle->list, (GFunc) g_free, NULL); + g_slist_free (handle->list); + g_free (handle); +} + + +static GnomeVFSResult +do_open_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + VFolderURI vuri; + DirHandle *dh = NULL; + Folder *folder; + VFolderInfo *info; + + VFOLDER_URI_PARSE (uri, &vuri); + + /* Read lock is kept until close_directory */ + info = vfolder_info_locate (vuri.scheme); + if (!info) + return GNOME_VFS_ERROR_INVALID_URI; + + VFOLDER_INFO_READ_LOCK (info); + + /* In the all- scheme just list all filenames */ + if (vuri.is_all_scheme) { + /* Don't allow dirnames for all-applications:/ */ + if (vuri.path && strrchr (vuri.path, '/') != vuri.path) { + VFOLDER_INFO_READ_UNLOCK (info); + return GNOME_VFS_ERROR_NOT_FOUND; + } + + dh = dir_handle_new_all (info, options); + } else { + folder = vfolder_info_get_folder (info, vuri.path); + if (!folder) { + VFOLDER_INFO_READ_UNLOCK (info); + return GNOME_VFS_ERROR_NOT_FOUND; + } + + dh = dir_handle_new (info, folder, options); + } + + VFOLDER_INFO_READ_UNLOCK (info); + + *method_handle = (GnomeVFSMethodHandle*) dh; + + return GNOME_VFS_OK; +} + + +static GnomeVFSResult +do_close_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + DirHandle *dh; + + dh = (DirHandle*) method_handle; + dir_handle_free (dh); + + return GNOME_VFS_OK; +} + + +static void +fill_file_info_for_directory (GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + const gchar *name, + time_t mtime, + gboolean read_only, + const gchar *link_ref) +{ + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_NONE; + + file_info->type = GNOME_VFS_FILE_TYPE_DIRECTORY; + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_TYPE; + + GNOME_VFS_FILE_INFO_SET_LOCAL (file_info, TRUE); + + file_info->mime_type = g_strdup ("x-directory/vfolder-desktop"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + file_info->ctime = mtime; + file_info->mtime = mtime; + file_info->valid_fields |= (GNOME_VFS_FILE_INFO_FIELDS_CTIME | + GNOME_VFS_FILE_INFO_FIELDS_MTIME); + + file_info->name = g_strdup (name); + + if (read_only) { + file_info->permissions = (GNOME_VFS_PERM_USER_READ | + GNOME_VFS_PERM_GROUP_READ | + GNOME_VFS_PERM_OTHER_READ); + file_info->valid_fields |= + GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS; + } + +#if 0 + /* + * FIXME: Idealy we'd be able to present links as actual symbolic links, + * but panel doesn't like symlinks in the menus, and nautilus seems to + * ignore it altogether. + */ + if (link_ref) { + if (options & GNOME_VFS_FILE_INFO_FOLLOW_LINKS) + file_info->type = GNOME_VFS_FILE_TYPE_DIRECTORY; + else + file_info->type = GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK; + + GNOME_VFS_FILE_INFO_SET_SYMLINK (file_info, TRUE); + + file_info->symlink_name = g_strdup (link_ref); + file_info->valid_fields |= + GNOME_VFS_FILE_INFO_FIELDS_SYMLINK_NAME; + } +#endif +} + +#define UNSUPPORTED_INFO_FIELDS (GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS | \ + GNOME_VFS_FILE_INFO_FIELDS_DEVICE | \ + GNOME_VFS_FILE_INFO_FIELDS_INODE | \ + GNOME_VFS_FILE_INFO_FIELDS_LINK_COUNT | \ + GNOME_VFS_FILE_INFO_FIELDS_ATIME) + +static GnomeVFSResult +get_file_info_internal (VFolderInfo *info, + FolderChild *child, + GnomeVFSFileInfoOptions options, + GnomeVFSFileInfo *file_info, + GnomeVFSContext *context) +{ + if (child->type == DESKTOP_FILE) { + GnomeVFSResult result; + GnomeVFSURI *file_uri; + gchar *displayname; + + /* we always get mime-type by forcing it below */ + if (options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE) + options &= ~GNOME_VFS_FILE_INFO_GET_MIME_TYPE; + + file_uri = entry_get_real_uri (child->entry); + displayname = g_strdup (entry_get_displayname (child->entry)); + + result = gnome_vfs_get_file_info_uri_cancellable (file_uri, + file_info, + options, + context); + gnome_vfs_uri_unref (file_uri); + + g_free (file_info->name); + file_info->name = displayname; + + g_free (file_info->mime_type); + file_info->mime_type = + g_strdup ("application/x-gnome-app-info"); + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; + + /* Now we wipe those fields we don't support */ + file_info->valid_fields &= ~(UNSUPPORTED_INFO_FIELDS); + + return result; + } + else if (child->type == FOLDER) { + if (child->folder) + fill_file_info_for_directory ( + file_info, + options, + folder_get_name (child->folder), + info->modification_time, + child->folder->read_only || info->read_only, + folder_get_extend_uri (child->folder)); + else + /* all-applications root dir */ + fill_file_info_for_directory (file_info, + options, + "/", + info->modification_time, + TRUE /*read-only*/, + NULL); + return GNOME_VFS_OK; + } + else + return GNOME_VFS_ERROR_GENERIC; +} + + +static GnomeVFSResult +do_read_directory (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + DirHandle *dh; + gchar *entry_name; + FolderChild child; + + dh = (DirHandle*) method_handle; + + VFOLDER_INFO_READ_LOCK (dh->info); + + READ_NEXT_ENTRY: + + if (!dh->current) { + VFOLDER_INFO_READ_UNLOCK (dh->info); + return GNOME_VFS_ERROR_EOF; + } + + entry_name = dh->current->data; + dh->current = dh->current->next; + + if (dh->folder) { + if (!folder_get_child (dh->folder, entry_name, &child)) + goto READ_NEXT_ENTRY; + } else { + /* all-scheme */ + child.type = DESKTOP_FILE; + child.entry = vfolder_info_lookup_entry (dh->info, entry_name); + + if (!child.entry) + goto READ_NEXT_ENTRY; + } + + if (child.type == FOLDER && folder_is_hidden (child.folder)) + goto READ_NEXT_ENTRY; + + result = get_file_info_internal (dh->info, + &child, + dh->options, + file_info, + context); + if (result != GNOME_VFS_OK) + goto READ_NEXT_ENTRY; + + VFOLDER_INFO_READ_UNLOCK (dh->info); + + return result; +} + + +static GnomeVFSResult +do_get_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + VFolderURI vuri; + VFolderInfo *info; + Folder *parent; + FolderChild child; + + VFOLDER_URI_PARSE (uri, &vuri); + + info = vfolder_info_locate (vuri.scheme); + if (!info) + return GNOME_VFS_ERROR_INVALID_URI; + + VFOLDER_INFO_READ_LOCK (info); + + if (vuri.is_all_scheme) { + if (vuri.file) { + /* all-scheme */ + child.type = DESKTOP_FILE; + child.entry = vfolder_info_lookup_entry (info, + vuri.file); + if (!child.entry) { + VFOLDER_INFO_READ_UNLOCK (info); + return GNOME_VFS_ERROR_NOT_FOUND; + } + } else { + /* all-scheme root folder */ + child.type = FOLDER; + child.folder = NULL; + } + } else { + parent = vfolder_info_get_parent (info, vuri.path); + if (!parent) { + VFOLDER_INFO_READ_UNLOCK (info); + return GNOME_VFS_ERROR_NOT_FOUND; + } + + if (!folder_get_child (parent, vuri.file, &child)) { + VFOLDER_INFO_READ_UNLOCK (info); + return GNOME_VFS_ERROR_NOT_FOUND; + } + } + + result = get_file_info_internal (info, + &child, + options, + file_info, + context); + + VFOLDER_INFO_READ_UNLOCK (info); + + return result; +} + + +static GnomeVFSResult +do_get_file_info_from_handle (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSResult result; + FileHandle *handle = (FileHandle *) method_handle; + FolderChild child; + + VFOLDER_INFO_READ_LOCK (handle->info); + + child.type = DESKTOP_FILE; + child.entry = handle->entry; + + result = get_file_info_internal (handle->info, + &child, + options, + file_info, + context); + + VFOLDER_INFO_READ_UNLOCK (handle->info); + + return result; +} + + +static gboolean +do_is_local (GnomeVFSMethod *method, + const GnomeVFSURI *uri) +{ + return TRUE; +} + + +static GnomeVFSResult +do_make_directory (GnomeVFSMethod *method, + GnomeVFSURI *uri, + guint perm, + GnomeVFSContext *context) +{ + VFolderInfo *info; + Folder *parent, *folder; + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + /* Root folder always exists */ + if (vuri.file == NULL) + return GNOME_VFS_ERROR_FILE_EXISTS; + + info = vfolder_info_locate (vuri.scheme); + if (!info) + return GNOME_VFS_ERROR_INVALID_URI; + + if (info->read_only || vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + VFOLDER_INFO_WRITE_LOCK (info); + + parent = vfolder_info_get_parent (info, vuri.path); + if (!parent) { + VFOLDER_INFO_WRITE_UNLOCK (info); + return GNOME_VFS_ERROR_NOT_FOUND; + } + + if (folder_get_entry (parent, vuri.file)) { + VFOLDER_INFO_WRITE_UNLOCK (info); + return GNOME_VFS_ERROR_FILE_EXISTS; + } + + folder = folder_get_subfolder (parent, vuri.file); + if (folder) { + if (!folder_is_hidden (folder)) { + VFOLDER_INFO_WRITE_UNLOCK (info); + return GNOME_VFS_ERROR_FILE_EXISTS; + } + + if (!folder_make_user_private (folder)) { + VFOLDER_INFO_WRITE_UNLOCK (info); + return GNOME_VFS_ERROR_READ_ONLY; + } + + if (folder->dont_show_if_empty) { + folder->dont_show_if_empty = FALSE; + vfolder_info_set_dirty (info); + } + + folder_ref (folder); + } else { + /* Create in the parent as well as in our .vfolder-info */ + if (parent->is_link) { + const gchar *extend_uri; + GnomeVFSURI *real_uri, *new_uri; + GnomeVFSResult result; + + extend_uri = folder_get_extend_uri (parent); + real_uri = gnome_vfs_uri_new (extend_uri); + new_uri = gnome_vfs_uri_append_file_name (real_uri, + vuri.file); + gnome_vfs_uri_unref (real_uri); + + result = + gnome_vfs_make_directory_for_uri_cancellable ( + new_uri, + perm, + context); + gnome_vfs_uri_unref (new_uri); + + if (result != GNOME_VFS_OK) { + VFOLDER_INFO_WRITE_UNLOCK (info); + return result; + } + } + + /* + * Don't write to .vfolder-info file if our parent is a link + * directory, since we just created a real child directory. + */ + folder = folder_new (info, vuri.file, parent->is_link == FALSE); + } + + folder_remove_exclude (parent, folder_get_name (folder)); + folder_add_subfolder (parent, folder); + folder_unref (folder); + + VFOLDER_INFO_WRITE_UNLOCK (info); + + vfolder_info_emit_change (info, + uri->text, + GNOME_VFS_MONITOR_EVENT_CREATED); + + return GNOME_VFS_OK; +} + + +static GnomeVFSResult +do_remove_directory_unlocked (VFolderInfo *info, + VFolderURI *vuri, + GnomeVFSContext *context) +{ + Folder *parent, *folder; + GnomeVFSResult result; + + parent = vfolder_info_get_parent (info, vuri->path); + if (!parent) + return GNOME_VFS_ERROR_NOT_FOUND; + + folder = folder_get_subfolder (parent, vuri->file); + if (!folder) + return GNOME_VFS_ERROR_NOT_FOUND; + + if (folder_list_subfolders (folder) || folder_list_entries (folder)) + return GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY; + + if (!folder_make_user_private (parent)) + return GNOME_VFS_ERROR_READ_ONLY; + + if (folder->is_link) { + gchar *uristr; + GnomeVFSURI *new_uri; + + uristr = vfolder_build_uri (folder_get_extend_uri (folder), + vuri->file, + NULL); + new_uri = gnome_vfs_uri_new (uristr); + g_free (uristr); + + /* Remove from the parent as well as in our .vfolder-info */ + result = + gnome_vfs_remove_directory_from_uri_cancellable ( + new_uri, + context); + gnome_vfs_uri_unref (new_uri); + + if (result != GNOME_VFS_OK) + return result; + } + + folder_add_exclude (parent, folder_get_name (folder)); + folder_remove_subfolder (parent, folder); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_remove_directory (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSContext *context) +{ + VFolderInfo *info; + VFolderURI vuri; + GnomeVFSResult result; + + VFOLDER_URI_PARSE (uri, &vuri); + + info = vfolder_info_locate (vuri.scheme); + if (!info) + return GNOME_VFS_ERROR_INVALID_URI; + + if (info->read_only || vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + VFOLDER_INFO_WRITE_LOCK (info); + result = do_remove_directory_unlocked (info, &vuri, context); + VFOLDER_INFO_WRITE_UNLOCK (info); + + if (result == GNOME_VFS_OK) + vfolder_info_emit_change (info, + uri->text, + GNOME_VFS_MONITOR_EVENT_DELETED); + + return result; +} + + +static GnomeVFSResult +do_unlink_unlocked (VFolderInfo *info, + VFolderURI *vuri, + GnomeVFSContext *context) +{ + Folder *parent; + Entry *entry; + + parent = vfolder_info_get_parent (info, vuri->path); + if (!parent) + return GNOME_VFS_ERROR_NOT_FOUND; + + entry = folder_get_entry (parent, vuri->file); + if (!entry) { + if (folder_get_subfolder (parent, vuri->file)) + return GNOME_VFS_ERROR_IS_DIRECTORY; + else + return GNOME_VFS_ERROR_NOT_FOUND; + } + + if (parent->is_link || entry_is_user_private (entry)) { + GnomeVFSURI *uri; + GnomeVFSResult result; + + /* Delete our local copy, or the linked source */ + uri = entry_get_real_uri (entry); + result = gnome_vfs_unlink_from_uri_cancellable (uri, context); + gnome_vfs_uri_unref (uri); + + /* + * We only care about the result if its a linked directory. + * Otherwise we can just modify the .vfolder-info. + */ + if (parent->is_link && result != GNOME_VFS_OK) + return result; + } + + if (!parent->is_link) { + if (!folder_make_user_private (parent)) + return GNOME_VFS_ERROR_READ_ONLY; + + /* Clear out the */ + if (entry_is_user_private (entry)) + folder_remove_include (parent, + entry_get_filename (entry)); + + folder_add_exclude (parent, entry_get_displayname (entry)); + } + + folder_remove_entry (parent, entry); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_unlink (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSContext *context) +{ + VFolderInfo *info; + VFolderURI vuri; + GnomeVFSResult result; + + VFOLDER_URI_PARSE (uri, &vuri); + + if (!vuri.file) + return GNOME_VFS_ERROR_INVALID_URI; + else if (vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + info = vfolder_info_locate (vuri.scheme); + if (!info) + return GNOME_VFS_ERROR_INVALID_URI; + + if (info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + VFOLDER_INFO_WRITE_LOCK (info); + result = do_unlink_unlocked (info, &vuri, context); + VFOLDER_INFO_WRITE_UNLOCK (info); + + if (result == GNOME_VFS_OK) + vfolder_info_emit_change (info, + uri->text, + GNOME_VFS_MONITOR_EVENT_DELETED); + + return result; +} + + +static void +set_desktop_file_key (GString *fullbuf, gchar *key, gchar *value) +{ + gchar *key_idx, *val_end; + + /* Remove the name if it already exists */ + key_idx = strstr (fullbuf->str, key); + if (key_idx && (key_idx == fullbuf->str || + key_idx [-1] == '\n' || + key_idx [-1] == '\r')) { + /* Look for the end of the value */ + val_end = strchr (key_idx, '\n'); + if (val_end < 0) + val_end = strchr (key_idx, '\r'); + if (val_end < 0) + val_end = &fullbuf->str [fullbuf->len - 1]; + + /* Erase the old name */ + g_string_erase (fullbuf, + key_idx - fullbuf->str, + val_end - key_idx); + } + + /* Mkae sure we don't bump into the last attribute */ + if (fullbuf->len > 0 && (fullbuf->str [fullbuf->len - 1] != '\n' && + fullbuf->str [fullbuf->len - 1] != '\r')) + g_string_append_c (fullbuf, '\n'); + + g_string_append_printf (fullbuf, "%s=%s\n", key, value); +} + +static void +set_desktop_file_locale_key (GString *fullbuf, gchar *key, gchar *value) +{ + GList *locale_list; + const gchar *locale; + gchar *locale_key; + + /* Get the list of applicable locales */ + locale_list = gnome_vfs_i18n_get_language_list ("LC_MESSAGES"); + + /* Get the localized keyname from the first locale */ + locale = locale_list ? locale_list->data : NULL; + if (!locale || !strcmp (locale, "C")) + locale_key = g_strdup (key); + else + locale_key = g_strdup_printf ("%s[%s]", key, locale); + + set_desktop_file_key (fullbuf, locale_key, value); + + g_list_free (locale_list); + g_free (locale_key); +} + +static void +set_dot_directory_locale_name (Folder *folder, gchar *val) +{ + Entry *dot_file; + GnomeVFSHandle *handle; + GnomeVFSFileSize readlen, writelen, offset = 0; + GString *fullbuf; + char buf[2048]; + guint mode, perm; + + dot_file = folder_get_entry (folder, ".directory"); + if (!dot_file) + return; + if (!entry_make_user_private (dot_file, folder)) + return; + + mode = (GNOME_VFS_OPEN_READ | + GNOME_VFS_OPEN_WRITE | + GNOME_VFS_OPEN_RANDOM); + + perm = (GNOME_VFS_PERM_USER_READ | + GNOME_VFS_PERM_USER_WRITE | + GNOME_VFS_PERM_GROUP_READ | + GNOME_VFS_PERM_OTHER_READ); + + if (gnome_vfs_open (&handle, + entry_get_filename (dot_file), + mode) != GNOME_VFS_OK && + gnome_vfs_create (&handle, + entry_get_filename (dot_file), + mode, + TRUE, + perm) != GNOME_VFS_OK) + return; + + /* read in the file contents to fullbuf */ + fullbuf = g_string_new (NULL); + while (gnome_vfs_read (handle, + buf, + sizeof (buf), + &readlen) == GNOME_VFS_OK) { + g_string_append_len (fullbuf, buf, readlen); + } + + /* set the key, replacing if necessary */ + set_desktop_file_locale_key (fullbuf, "Name", val); + + /* clear it */ + gnome_vfs_truncate_handle (handle, 0); + gnome_vfs_seek (handle, GNOME_VFS_SEEK_START, 0); + + /* write the changed contents */ + while (fullbuf->len - offset > 0 && + gnome_vfs_write (handle, + &fullbuf->str [offset], + fullbuf->len - offset, + &writelen) == GNOME_VFS_OK) { + offset += writelen; + } + + gnome_vfs_close (handle); + g_string_free (fullbuf, TRUE); +} + +static GnomeVFSResult +do_move (GnomeVFSMethod *method, + GnomeVFSURI *old_uri, + GnomeVFSURI *new_uri, + gboolean force_replace, + GnomeVFSContext *context) +{ + GnomeVFSResult result = GNOME_VFS_OK; + VFolderInfo *info; + Folder *old_parent, *new_parent; + VFolderURI old_vuri, new_vuri; + FolderChild old_child, existing_child; + + VFOLDER_URI_PARSE (old_uri, &old_vuri); + VFOLDER_URI_PARSE (new_uri, &new_vuri); + + if (!old_vuri.file) + return GNOME_VFS_ERROR_INVALID_URI; + + if (old_vuri.is_all_scheme || new_vuri.is_all_scheme) + return GNOME_VFS_ERROR_READ_ONLY; + + if (strcmp (old_vuri.scheme, new_vuri.scheme) != 0) + return GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM; + + info = vfolder_info_locate (old_vuri.scheme); + if (!info) + return GNOME_VFS_ERROR_INVALID_URI; + + if (info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + VFOLDER_INFO_WRITE_LOCK (info); + + old_parent = vfolder_info_get_parent (info, old_vuri.path); + if (!old_parent || + !folder_get_child (old_parent, old_vuri.file, &old_child)) { + VFOLDER_INFO_WRITE_UNLOCK (info); + return GNOME_VFS_ERROR_NOT_FOUND; + } + + if (!folder_make_user_private (old_parent)) { + VFOLDER_INFO_WRITE_UNLOCK (info); + return GNOME_VFS_ERROR_READ_ONLY; + } + + new_parent = vfolder_info_get_parent (info, new_vuri.path); + if (!new_parent) { + VFOLDER_INFO_WRITE_UNLOCK (info); + return GNOME_VFS_ERROR_NOT_A_DIRECTORY; + } + + if (!folder_make_user_private (new_parent)) { + VFOLDER_INFO_WRITE_UNLOCK (info); + return GNOME_VFS_ERROR_READ_ONLY; + } + + if (folder_get_child (new_parent, new_vuri.file, &existing_child)) { + if (!force_replace) { + VFOLDER_INFO_WRITE_UNLOCK (info); + return GNOME_VFS_ERROR_FILE_EXISTS; + } + } + + if (old_child.type == DESKTOP_FILE) { + if (!vfolder_check_extension (new_vuri.file, ".desktop") && + !vfolder_check_extension (new_vuri.file, ".directory")) { + VFOLDER_INFO_WRITE_UNLOCK (info); + return GNOME_VFS_ERROR_INVALID_URI; + } + + if (existing_child.type == FOLDER) { + VFOLDER_INFO_WRITE_UNLOCK (info); + return GNOME_VFS_ERROR_IS_DIRECTORY; + } + + /* ref in case old_parent is new_parent */ + entry_ref (old_child.entry); + + if (existing_child.type == DESKTOP_FILE) { + result = do_unlink_unlocked (info, + &new_vuri, + context); + if (result != GNOME_VFS_OK && + result != GNOME_VFS_ERROR_NOT_FOUND) { + entry_unref (old_child.entry); + VFOLDER_INFO_WRITE_UNLOCK (info); + return result; + } + } + + /* remove from old folder */ + folder_remove_entry (old_parent, old_child.entry); + folder_add_exclude (old_parent, + entry_get_filename (old_child.entry)); + + /* basenames different, have to make a local copy */ + if (strcmp (entry_get_displayname (old_child.entry), + new_vuri.file) != 0) { + entry_set_displayname (old_child.entry, new_vuri.file); + entry_make_user_private (old_child.entry, new_parent); + } + + /* add to new folder */ + folder_add_entry (new_parent, old_child.entry); + folder_add_include (new_parent, + entry_get_filename (old_child.entry)); + + entry_unref (old_child.entry); + + vfolder_info_emit_change (info, + old_uri->text, + GNOME_VFS_MONITOR_EVENT_DELETED); + + vfolder_info_emit_change (info, + new_uri->text, + GNOME_VFS_MONITOR_EVENT_CREATED); + } + else if (old_child.type == FOLDER) { + Folder *iter; + + if (existing_child.type && existing_child.type != FOLDER) { + VFOLDER_INFO_WRITE_UNLOCK (info); + return GNOME_VFS_ERROR_NOT_A_DIRECTORY; + } + + for (iter = new_parent->parent; iter; iter = iter->parent) { + if (iter == old_child.folder) { + VFOLDER_INFO_WRITE_UNLOCK (info); + return GNOME_VFS_ERROR_LOOP; + } + } + + /* ref in case old_parent is new_parent */ + folder_ref (old_child.folder); + + if (old_parent != new_parent) { + result = do_remove_directory_unlocked (info, + &new_vuri, + context); + if (result != GNOME_VFS_OK && + result != GNOME_VFS_ERROR_NOT_FOUND) { + folder_unref (old_child.folder); + VFOLDER_INFO_WRITE_UNLOCK (info); + return result; + } + } + + folder_remove_subfolder (old_parent, old_child.folder); + folder_add_exclude (old_parent, old_vuri.file); + + folder_make_user_private (old_child.folder); + folder_set_name (old_child.folder, new_vuri.file); + folder_add_subfolder (new_parent, old_child.folder); + + /* do the .directory name change */ + set_dot_directory_locale_name (old_child.folder, new_vuri.file); + + vfolder_info_emit_change (info, + old_uri->text, + GNOME_VFS_MONITOR_EVENT_DELETED); + + vfolder_info_emit_change (info, + new_uri->text, + GNOME_VFS_MONITOR_EVENT_CREATED); + + folder_unref (old_child.folder); + } + + VFOLDER_INFO_WRITE_UNLOCK (info); + + return GNOME_VFS_OK; +} + + +static GnomeVFSResult +do_check_same_fs (GnomeVFSMethod *method, + GnomeVFSURI *source_uri, + GnomeVFSURI *target_uri, + gboolean *same_fs_return, + GnomeVFSContext *context) +{ + VFolderURI source_vuri, target_vuri; + + *same_fs_return = FALSE; + + VFOLDER_URI_PARSE (source_uri, &source_vuri); + VFOLDER_URI_PARSE (target_uri, &target_vuri); + + if (strcmp (source_vuri.scheme, target_vuri.scheme) != 0 || + source_vuri.is_all_scheme != target_vuri.is_all_scheme) + *same_fs_return = FALSE; + else + *same_fs_return = TRUE; + + return GNOME_VFS_OK; +} + + +static GnomeVFSResult +do_set_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + const GnomeVFSFileInfo *info, + GnomeVFSSetFileInfoMask mask, + GnomeVFSContext *context) +{ + VFolderURI vuri; + + VFOLDER_URI_PARSE (uri, &vuri); + + if (!vuri.file) + return GNOME_VFS_ERROR_INVALID_URI; + + if (mask & GNOME_VFS_SET_FILE_INFO_NAME) { + GnomeVFSResult result = GNOME_VFS_OK; + GnomeVFSURI *parent_uri, *new_uri; + + parent_uri = gnome_vfs_uri_get_parent (uri); + new_uri = gnome_vfs_uri_append_file_name (parent_uri, + info->name); + gnome_vfs_uri_unref (parent_uri); + + if (!new_uri) + return GNOME_VFS_ERROR_INVALID_URI; + + result = do_move (method, + uri, + new_uri, + FALSE /* force_replace */, + context); + + gnome_vfs_uri_unref (new_uri); + return result; + } else { + /* + * We don't support setting any of this other permission, + * times and all that voodoo + */ + return GNOME_VFS_ERROR_NOT_SUPPORTED; + } +} + + +static GnomeVFSResult +do_create_symbolic_link (GnomeVFSMethod *method, + GnomeVFSURI *uri, + const char *target_reference, + GnomeVFSContext *context) +{ + VFolderURI vuri; + VFolderInfo *info; + Folder *parent; + FolderChild child; + GnomeVFSResult result; + + VFOLDER_URI_PARSE (uri, &vuri); + if (!vuri.file) + return GNOME_VFS_ERROR_INVALID_URI; + + info = vfolder_info_locate (vuri.scheme); + if (!info) + return GNOME_VFS_ERROR_INVALID_URI; + + if (info->read_only) + return GNOME_VFS_ERROR_READ_ONLY; + + VFOLDER_INFO_WRITE_LOCK (info); + + parent = vfolder_info_get_parent (info, vuri.path); + if (!parent) { + VFOLDER_INFO_WRITE_UNLOCK (info); + return GNOME_VFS_ERROR_NOT_FOUND; + } + + if (folder_get_child (parent, vuri.file, &child)) { + VFOLDER_INFO_WRITE_UNLOCK (info); + return GNOME_VFS_ERROR_FILE_EXISTS; + } + + if (parent->is_link) { + gchar *new_uristr; + GnomeVFSURI *new_uri; + + VFOLDER_INFO_WRITE_UNLOCK (info); + + new_uristr = vfolder_build_uri (folder_get_extend_uri (parent), + vuri.file, + NULL); + new_uri = gnome_vfs_uri_new (new_uristr); + + result = + gnome_vfs_create_symbolic_link_cancellable ( + new_uri, + target_reference, + context); + + gnome_vfs_uri_unref (new_uri); + + return result; + } else { + GnomeVFSFileInfo *file_info; + GnomeVFSURI *link_uri; + Folder *linkdir; + + if (!folder_make_user_private (parent)) { + VFOLDER_INFO_WRITE_UNLOCK (info); + return GNOME_VFS_ERROR_READ_ONLY; + } + + /* + * FIXME: need to unlock here to get the file info so we can + * check if the target file is a directory, avoiding a deadlock + * when target is on the same method (always?). + */ + VFOLDER_INFO_WRITE_UNLOCK (info); + + link_uri = gnome_vfs_uri_new (target_reference); + file_info = gnome_vfs_file_info_new (); + result = + gnome_vfs_get_file_info_uri_cancellable ( + link_uri, + file_info, + GNOME_VFS_FILE_INFO_FOLLOW_LINKS, + context); + gnome_vfs_uri_unref (link_uri); + + if (result != GNOME_VFS_OK) + return GNOME_VFS_ERROR_NOT_FOUND; + + /* We only support links to directories */ + if (file_info->type != GNOME_VFS_FILE_TYPE_DIRECTORY) + return GNOME_VFS_ERROR_NOT_A_DIRECTORY; + + VFOLDER_INFO_WRITE_LOCK (info); + + /* + * Reget parent, avoiding a race if it was removed while we were + * unlocked. + */ + parent = vfolder_info_get_parent (info, vuri.path); + if (!parent) { + VFOLDER_INFO_WRITE_UNLOCK (info); + return GNOME_VFS_ERROR_NOT_FOUND; + } + + linkdir = folder_new (info, vuri.file, TRUE); + folder_set_extend_uri (linkdir, target_reference); + linkdir->is_link = TRUE; + + folder_add_subfolder (parent, linkdir); + folder_unref (linkdir); + + VFOLDER_INFO_WRITE_UNLOCK (info); + + vfolder_info_emit_change (info, + uri->text, + GNOME_VFS_MONITOR_EVENT_CREATED); + + return GNOME_VFS_OK; + } +} + + +static GnomeVFSResult +do_monitor_add (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle_return, + GnomeVFSURI *uri, + GnomeVFSMonitorType monitor_type) +{ + VFolderInfo *info; + + info = vfolder_info_locate (gnome_vfs_uri_get_scheme (uri)); + if (!info) + return GNOME_VFS_ERROR_INVALID_URI; + + VFOLDER_INFO_READ_LOCK (info); + vfolder_info_add_monitor (info, + monitor_type, + uri, + method_handle_return); + VFOLDER_INFO_READ_UNLOCK (info); + + return GNOME_VFS_OK; +} + + +static GnomeVFSResult +do_monitor_cancel (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle) +{ + MonitorHandle *monitor = (MonitorHandle *) method_handle; + VFolderInfo *info; + + if (method_handle == NULL) + return GNOME_VFS_OK; + + info = monitor->info; + + VFOLDER_INFO_READ_LOCK (info); + vfolder_info_cancel_monitor (method_handle); + VFOLDER_INFO_READ_UNLOCK (info); + + return GNOME_VFS_OK; +} + + +/* + * GnomeVFS Registration + */ +static GnomeVFSMethod method = { + sizeof (GnomeVFSMethod), + do_open, + do_create, + do_close, + do_read, + do_write, + do_seek, + do_tell, + do_truncate_handle, + do_open_directory, + do_close_directory, + do_read_directory, + do_get_file_info, + do_get_file_info_from_handle, + do_is_local, + do_make_directory, + do_remove_directory, + do_move, + do_unlink, + do_check_same_fs, + do_set_file_info, + do_truncate, + NULL /* find_directory */, + do_create_symbolic_link, + do_monitor_add, + do_monitor_cancel +}; + +GnomeVFSMethod * +vfs_module_init (const char *method_name, const char *args) +{ + return &method; +} + +void +vfs_module_shutdown (GnomeVFSMethod *method) +{ + vfolder_info_destroy_all (); +} diff --git a/modules/vfolder/vfolder-util.c b/modules/vfolder/vfolder-util.c new file mode 100644 index 0000000..35a78b1 --- /dev/null +++ b/modules/vfolder/vfolder-util.c @@ -0,0 +1,493 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* + * vfolder-util.c - Utility functions for wrapping monitors and + * filename/uri parsing. + * + * Copyright (C) 2002 Ximian, Inc. + * + * The Gnome Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Gnome Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Alex Graveley + * Based on original code by George Lebl . + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#include "vfolder-util.h" +#include "vfolder-common.h" + +/* assumes vuri->path already set */ +gboolean +vfolder_uri_parse_internal (GnomeVFSURI *uri, VFolderURI *vuri) +{ + vuri->scheme = (gchar *) gnome_vfs_uri_get_scheme (uri); + + vuri->ends_in_slash = FALSE; + + if (strncmp (vuri->scheme, "all-", strlen ("all-")) == 0) { + vuri->scheme += strlen ("all-"); + vuri->is_all_scheme = TRUE; + } else + vuri->is_all_scheme = FALSE; + + if (vuri->path != NULL) { + int last_slash = strlen (vuri->path) - 1; + char *first; + + /* Note: This handling of paths is somewhat evil, may need a + * bit of a rework */ + + /* kill leading slashes, that is make sure there is + * only one */ + for (first = vuri->path; *first == '/'; first++) + ; + if (first != vuri->path) { + first--; + vuri->path = first; + } + + /* kill trailing slashes (leave first if all slashes) */ + while (last_slash > 0 && vuri->path [last_slash] == '/') { + vuri->path [last_slash--] = '\0'; + vuri->ends_in_slash = TRUE; + } + + /* get basename start */ + while (last_slash >= 0 && vuri->path [last_slash] != '/') + last_slash--; + + if (last_slash > -1) + vuri->file = vuri->path + last_slash + 1; + else + vuri->file = vuri->path; + + if (vuri->file[0] == '\0' && + strcmp (vuri->path, "/") == 0) { + vuri->file = NULL; + } + } else { + vuri->ends_in_slash = TRUE; + vuri->path = "/"; + vuri->file = NULL; + } + + vuri->uri = uri; + + return TRUE; +} + +static void +monitor_callback_internal (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + VFolderMonitor *monitor = (VFolderMonitor *) user_data; + + if (monitor->frozen) + return; + + D (g_print ( + "RECEIVED MONITOR: %s, %s, %s%s%s\n", + monitor_uri, + info_uri + strlen (monitor_uri), + event_type == GNOME_VFS_MONITOR_EVENT_CREATED ? "CREATED" : "", + event_type == GNOME_VFS_MONITOR_EVENT_DELETED ? "DELETED" : "", + event_type == GNOME_VFS_MONITOR_EVENT_CHANGED ? "CHANGED" : "")); + + (*monitor->callback) (handle, + monitor_uri, + info_uri, + event_type, + monitor->user_data); +} + +#define TIMEOUT_SECONDS 3 + +static GSList *stat_monitors = NULL; +G_LOCK_DEFINE_STATIC (stat_monitors); +static guint stat_timeout_tag = 0; + +static time_t +ctime_for_uri (const gchar *uri) +{ + GnomeVFSFileInfo *info; + GnomeVFSResult result; + time_t ctime = 0; + + info = gnome_vfs_file_info_new (); + + result = gnome_vfs_get_file_info (uri, + info, + GNOME_VFS_FILE_INFO_DEFAULT); + if (result == GNOME_VFS_OK) { + ctime = info->ctime; + } + + gnome_vfs_file_info_unref (info); + + return ctime; +} + +static gboolean +monitor_timeout_cb (gpointer user_data) +{ + GSList *iter; + GSList *copy; + + /* + * Copy the stat_monitors list in case the callback removes/adds + * monitors (which is likely). + */ + G_LOCK (stat_monitors); + copy = g_slist_copy (stat_monitors); + G_UNLOCK (stat_monitors); + + for (iter = copy; iter; iter = iter->next) { + VFolderMonitor *monitor = iter->data; + time_t ctime; + + G_LOCK (stat_monitors); + if (g_slist_position (stat_monitors, iter) < 0) { + G_UNLOCK (stat_monitors); + continue; + } + G_UNLOCK (stat_monitors); + + if (monitor->frozen) + continue; + + ctime = ctime_for_uri (monitor->uri); + if (ctime == monitor->ctime) + continue; + + (*monitor->callback) ((GnomeVFSMonitorHandle *) monitor, + monitor->uri, + monitor->uri, + ctime == 0 ? + GNOME_VFS_MONITOR_EVENT_DELETED : + GNOME_VFS_MONITOR_EVENT_CHANGED, + monitor->user_data); + + monitor->ctime = ctime; + } + + g_slist_free (copy); + + return TRUE; +} + +static VFolderMonitor * +monitor_start_internal (GnomeVFSMonitorType type, + const gchar *uri, + GnomeVFSMonitorCallback callback, + gpointer user_data) +{ + GnomeVFSResult result; + VFolderMonitor *monitor; +#if 0 + GnomeVFSFileInfo *info; + + /* Check the file exists so we don't get a bogus DELETED event */ + info = gnome_vfs_file_info_new (); + result = gnome_vfs_get_file_info (uri, + info, + GNOME_VFS_FILE_INFO_DEFAULT); + gnome_vfs_file_info_unref (info); + + if (result != GNOME_VFS_OK) + return NULL; +#endif + + monitor = g_new0 (VFolderMonitor, 1); + monitor->callback = callback; + monitor->user_data = user_data; + monitor->uri = g_strdup (uri); + +#ifndef VFOLDER_DEBUG_WITHOUT_MONITORING + result = gnome_vfs_monitor_add (&monitor->vfs_handle, + uri, + type, + monitor_callback_internal, + monitor); +#else + result = GNOME_VFS_ERROR_NOT_SUPPORTED; +#endif + + if (result == GNOME_VFS_ERROR_NOT_SUPPORTED) { + monitor->ctime = ctime_for_uri (uri); + + G_LOCK (stat_monitors); + if (stat_timeout_tag == 0) { + stat_timeout_tag = + g_timeout_add (TIMEOUT_SECONDS * 1000, + monitor_timeout_cb, + NULL); + } + + stat_monitors = g_slist_prepend (stat_monitors, monitor); + G_UNLOCK (stat_monitors); + } + + return monitor; +} + +VFolderMonitor * +vfolder_monitor_dir_new (const gchar *uri, + GnomeVFSMonitorCallback callback, + gpointer user_data) +{ + return monitor_start_internal (GNOME_VFS_MONITOR_DIRECTORY, + uri, + callback, + user_data); +} + +VFolderMonitor * +vfolder_monitor_file_new (const gchar *uri, + GnomeVFSMonitorCallback callback, + gpointer user_data) +{ + return monitor_start_internal (GNOME_VFS_MONITOR_FILE, + uri, + callback, + user_data); +} + +void +vfolder_monitor_freeze (VFolderMonitor *monitor) +{ + monitor->frozen = TRUE; + + if (monitor->vfs_handle) { + gnome_vfs_monitor_cancel (monitor->vfs_handle); + monitor->vfs_handle = NULL; + } +} + +void +vfolder_monitor_thaw (VFolderMonitor *monitor) +{ + if (!monitor->frozen) + return; + + monitor->frozen = FALSE; + + if (gnome_vfs_monitor_add (&monitor->vfs_handle, + monitor->uri, + monitor->type, + monitor_callback_internal, + monitor) != GNOME_VFS_OK) + monitor->vfs_handle = NULL; +} + +void +vfolder_monitor_cancel (VFolderMonitor *monitor) +{ + if (monitor->vfs_handle) + gnome_vfs_monitor_cancel (monitor->vfs_handle); + else { + G_LOCK (stat_monitors); + stat_monitors = g_slist_remove (stat_monitors, monitor); + + if (!stat_monitors) { + g_source_remove (stat_timeout_tag); + stat_timeout_tag = 0; + } + G_UNLOCK (stat_monitors); + } + + g_free (monitor->uri); + g_free (monitor); +} + +/* + * Stolen from eel_make_directory_and_parents from libeel + */ +static GnomeVFSResult +make_directory_and_parents_from_uri (GnomeVFSURI *uri, guint permissions) +{ + GnomeVFSResult result; + GnomeVFSURI *parent_uri; + + /* + * Make the directory, and return right away unless there's + * a possible problem with the parent. + */ + result = gnome_vfs_make_directory_for_uri (uri, permissions); + if (result != GNOME_VFS_ERROR_NOT_FOUND) + return result; + + /* If we can't get a parent, we are done. */ + parent_uri = gnome_vfs_uri_get_parent (uri); + if (!parent_uri) + return result; + + /* + * If we can get a parent, use a recursive call to create + * the parent and its parents. + */ + result = make_directory_and_parents_from_uri (parent_uri, permissions); + gnome_vfs_uri_unref (parent_uri); + if (result != GNOME_VFS_OK && result != GNOME_VFS_ERROR_FILE_EXISTS) + return result; + + /* + * A second try at making the directory after the parents + * have all been created. + */ + result = gnome_vfs_make_directory_for_uri (uri, permissions); + return result; +} + +GnomeVFSResult +vfolder_make_directory_and_parents (const gchar *uri, + gboolean skip_filename, + guint permissions) +{ + GnomeVFSURI *file_uri, *parent_uri; + GnomeVFSResult result; + + file_uri = gnome_vfs_uri_new (uri); + + if (skip_filename) { + parent_uri = gnome_vfs_uri_get_parent (file_uri); + gnome_vfs_uri_unref (file_uri); + file_uri = parent_uri; + } + + result = make_directory_and_parents_from_uri (file_uri, permissions); + gnome_vfs_uri_unref (file_uri); + + return result == GNOME_VFS_ERROR_FILE_EXISTS ? GNOME_VFS_OK : result; +} + + +gchar * +vfolder_timestamp_file_name (const gchar *file) +{ + struct timeval tv; + gchar *ret; + + gettimeofday (&tv, NULL); + + ret = g_strdup_printf ("%d-%s", + (int) (tv.tv_sec ^ tv.tv_usec), + file); + + return ret; +} + +gchar * +vfolder_untimestamp_file_name (const gchar *file) +{ + int n = 0; + + while (file [n] && g_ascii_isdigit (file [n])) + ++n; + n = (file [n] == '-') ? n + 1 : 0; + + return g_strdup (file [n] ? &file [n] : NULL); +} + +gboolean +vfolder_check_extension (const char *name, const char *ext_check) +{ + const char *ext; + + ext = strrchr (name, '.'); + if (ext && !strcmp (ext, ext_check)) + return TRUE; + else + return FALSE; +} + +gchar * +vfolder_escape_home (const gchar *file) +{ + if (file[0] == '~') + return g_strconcat (g_get_home_dir (), &file[1], NULL); + else + return g_strdup (file); +} + +/* Ripped from gfileutils.c:g_build_pathv() */ +gchar * +vfolder_build_uri (const gchar *first_element, + ...) +{ + GString *result; + gboolean is_first = TRUE; + const gchar *next_element; + va_list args; + + va_start (args, first_element); + + result = g_string_new (NULL); + next_element = first_element; + + while (TRUE) { + const gchar *element; + const gchar *start; + const gchar *end; + + if (next_element) { + element = next_element; + next_element = va_arg (args, gchar *); + } + else + break; + + start = element; + + if (!is_first) + start += strspn (start, "/"); + + end = start + strlen (start); + + if (next_element) { + while (end > start + 1 && end [-1] == '/') + end--; + + if (is_first) + if (end > start + 1 && + !strncmp (end - 1, "://", 3)) + end += 2; + } + + if (end > start) { + if (result->len > 0) + g_string_append_c (result, '/'); + + g_string_append_len (result, start, end - start); + } + + is_first = FALSE; + } + + va_end (args); + + return g_string_free (result, FALSE); +} diff --git a/modules/vfolder/vfolder-util.c.vfolder-hacks b/modules/vfolder/vfolder-util.c.vfolder-hacks new file mode 100644 index 0000000..bb326cd --- /dev/null +++ b/modules/vfolder/vfolder-util.c.vfolder-hacks @@ -0,0 +1,491 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* + * vfolder-util.c - Utility functions for wrapping monitors and + * filename/uri parsing. + * + * Copyright (C) 2002 Ximian, Inc. + * + * The Gnome Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Gnome Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Alex Graveley + * Based on original code by George Lebl . + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#include "vfolder-util.h" +#include "vfolder-common.h" + +/* assumes vuri->path already set */ +gboolean +vfolder_uri_parse_internal (GnomeVFSURI *uri, VFolderURI *vuri) +{ + vuri->scheme = (gchar *) gnome_vfs_uri_get_scheme (uri); + + vuri->ends_in_slash = FALSE; + + if (strncmp (vuri->scheme, "all-", strlen ("all-")) == 0) { + vuri->scheme += strlen ("all-"); + vuri->is_all_scheme = TRUE; + } else + vuri->is_all_scheme = FALSE; + + if (vuri->path != NULL) { + int last_slash = strlen (vuri->path) - 1; + char *first; + + /* Note: This handling of paths is somewhat evil, may need a + * bit of a rework */ + + /* kill leading slashes, that is make sure there is + * only one */ + for (first = vuri->path; *first == '/'; first++) + ; + if (first != vuri->path) { + first--; + vuri->path = first; + } + + /* kill trailing slashes (leave first if all slashes) */ + while (last_slash > 0 && vuri->path [last_slash] == '/') { + vuri->path [last_slash--] = '\0'; + vuri->ends_in_slash = TRUE; + } + + /* get basename start */ + while (last_slash >= 0 && vuri->path [last_slash] != '/') + last_slash--; + + if (last_slash > -1) + vuri->file = vuri->path + last_slash + 1; + else + vuri->file = vuri->path; + + if (vuri->file[0] == '\0' && + strcmp (vuri->path, "/") == 0) { + vuri->file = NULL; + } + } else { + vuri->ends_in_slash = TRUE; + vuri->path = "/"; + vuri->file = NULL; + } + + vuri->uri = uri; + + return TRUE; +} + +static void +monitor_callback_internal (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + VFolderMonitor *monitor = (VFolderMonitor *) user_data; + + if (monitor->frozen) + return; + + D (g_print ( + "RECEIVED MONITOR: %s, %s, %s%s%s\n", + monitor_uri, + info_uri + strlen (monitor_uri), + event_type == GNOME_VFS_MONITOR_EVENT_CREATED ? "CREATED" : "", + event_type == GNOME_VFS_MONITOR_EVENT_DELETED ? "DELETED" : "", + event_type == GNOME_VFS_MONITOR_EVENT_CHANGED ? "CHANGED" : "")); + + (*monitor->callback) (handle, + monitor_uri, + info_uri, + event_type, + monitor->user_data); +} + +#define TIMEOUT_SECONDS 3 + +static GSList *stat_monitors = NULL; +G_LOCK_DEFINE_STATIC (stat_monitors); +static guint stat_timeout_tag = 0; + +static time_t +ctime_for_uri (const gchar *uri) +{ + GnomeVFSFileInfo *info; + GnomeVFSResult result; + time_t ctime = 0; + + info = gnome_vfs_file_info_new (); + + result = gnome_vfs_get_file_info (uri, + info, + GNOME_VFS_FILE_INFO_DEFAULT); + if (result == GNOME_VFS_OK) { + ctime = info->ctime; + } + + gnome_vfs_file_info_unref (info); + + return ctime; +} + +static gboolean +monitor_timeout_cb (gpointer user_data) +{ + GSList *iter; + GSList *copy; + + /* + * Copy the stat_monitors list in case the callback removes/adds + * monitors (which is likely). + */ + G_LOCK (stat_monitors); + copy = g_slist_copy (stat_monitors); + G_UNLOCK (stat_monitors); + + for (iter = copy; iter; iter = iter->next) { + VFolderMonitor *monitor = iter->data; + time_t ctime; + + G_LOCK (stat_monitors); + if (g_slist_position (stat_monitors, iter) < 0) { + G_UNLOCK (stat_monitors); + continue; + } + G_UNLOCK (stat_monitors); + + if (monitor->frozen) + continue; + + ctime = ctime_for_uri (monitor->uri); + if (ctime == monitor->ctime) + continue; + + (*monitor->callback) ((GnomeVFSMonitorHandle *) monitor, + monitor->uri, + monitor->uri, + ctime == 0 ? + GNOME_VFS_MONITOR_EVENT_DELETED : + GNOME_VFS_MONITOR_EVENT_CHANGED, + monitor->user_data); + + monitor->ctime = ctime; + } + + g_slist_free (copy); + + return TRUE; +} + +static VFolderMonitor * +monitor_start_internal (GnomeVFSMonitorType type, + const gchar *uri, + GnomeVFSMonitorCallback callback, + gpointer user_data) +{ + GnomeVFSResult result; + VFolderMonitor *monitor; + GnomeVFSFileInfo *info; + + /* Check the file exists so we don't get a bogus DELETED event */ + info = gnome_vfs_file_info_new (); + result = gnome_vfs_get_file_info (uri, + info, + GNOME_VFS_FILE_INFO_DEFAULT); + gnome_vfs_file_info_unref (info); + + if (result != GNOME_VFS_OK) + return NULL; + + monitor = g_new0 (VFolderMonitor, 1); + monitor->callback = callback; + monitor->user_data = user_data; + monitor->uri = g_strdup (uri); + +#ifndef VFOLDER_DEBUG_WITHOUT_MONITORING + result = gnome_vfs_monitor_add (&monitor->vfs_handle, + uri, + type, + monitor_callback_internal, + monitor); +#else + result = GNOME_VFS_ERROR_NOT_SUPPORTED; +#endif + + if (result == GNOME_VFS_ERROR_NOT_SUPPORTED) { + monitor->ctime = ctime_for_uri (uri); + + G_LOCK (stat_monitors); + if (stat_timeout_tag == 0) { + stat_timeout_tag = + g_timeout_add (TIMEOUT_SECONDS * 1000, + monitor_timeout_cb, + NULL); + } + + stat_monitors = g_slist_prepend (stat_monitors, monitor); + G_UNLOCK (stat_monitors); + } + + return monitor; +} + +VFolderMonitor * +vfolder_monitor_dir_new (const gchar *uri, + GnomeVFSMonitorCallback callback, + gpointer user_data) +{ + return monitor_start_internal (GNOME_VFS_MONITOR_DIRECTORY, + uri, + callback, + user_data); +} + +VFolderMonitor * +vfolder_monitor_file_new (const gchar *uri, + GnomeVFSMonitorCallback callback, + gpointer user_data) +{ + return monitor_start_internal (GNOME_VFS_MONITOR_FILE, + uri, + callback, + user_data); +} + +void +vfolder_monitor_freeze (VFolderMonitor *monitor) +{ + monitor->frozen = TRUE; + + if (monitor->vfs_handle) { + gnome_vfs_monitor_cancel (monitor->vfs_handle); + monitor->vfs_handle = NULL; + } +} + +void +vfolder_monitor_thaw (VFolderMonitor *monitor) +{ + if (!monitor->frozen) + return; + + monitor->frozen = FALSE; + + if (gnome_vfs_monitor_add (&monitor->vfs_handle, + monitor->uri, + monitor->type, + monitor_callback_internal, + monitor) != GNOME_VFS_OK) + monitor->vfs_handle = NULL; +} + +void +vfolder_monitor_cancel (VFolderMonitor *monitor) +{ + if (monitor->vfs_handle) + gnome_vfs_monitor_cancel (monitor->vfs_handle); + else { + G_LOCK (stat_monitors); + stat_monitors = g_slist_remove (stat_monitors, monitor); + + if (!stat_monitors) { + g_source_remove (stat_timeout_tag); + stat_timeout_tag = 0; + } + G_UNLOCK (stat_monitors); + } + + g_free (monitor->uri); + g_free (monitor); +} + +/* + * Stolen from eel_make_directory_and_parents from libeel + */ +static GnomeVFSResult +make_directory_and_parents_from_uri (GnomeVFSURI *uri, guint permissions) +{ + GnomeVFSResult result; + GnomeVFSURI *parent_uri; + + /* + * Make the directory, and return right away unless there's + * a possible problem with the parent. + */ + result = gnome_vfs_make_directory_for_uri (uri, permissions); + if (result != GNOME_VFS_ERROR_NOT_FOUND) + return result; + + /* If we can't get a parent, we are done. */ + parent_uri = gnome_vfs_uri_get_parent (uri); + if (!parent_uri) + return result; + + /* + * If we can get a parent, use a recursive call to create + * the parent and its parents. + */ + result = make_directory_and_parents_from_uri (parent_uri, permissions); + gnome_vfs_uri_unref (parent_uri); + if (result != GNOME_VFS_OK && result != GNOME_VFS_ERROR_FILE_EXISTS) + return result; + + /* + * A second try at making the directory after the parents + * have all been created. + */ + result = gnome_vfs_make_directory_for_uri (uri, permissions); + return result; +} + +GnomeVFSResult +vfolder_make_directory_and_parents (const gchar *uri, + gboolean skip_filename, + guint permissions) +{ + GnomeVFSURI *file_uri, *parent_uri; + GnomeVFSResult result; + + file_uri = gnome_vfs_uri_new (uri); + + if (skip_filename) { + parent_uri = gnome_vfs_uri_get_parent (file_uri); + gnome_vfs_uri_unref (file_uri); + file_uri = parent_uri; + } + + result = make_directory_and_parents_from_uri (file_uri, permissions); + gnome_vfs_uri_unref (file_uri); + + return result == GNOME_VFS_ERROR_FILE_EXISTS ? GNOME_VFS_OK : result; +} + + +gchar * +vfolder_timestamp_file_name (const gchar *file) +{ + struct timeval tv; + gchar *ret; + + gettimeofday (&tv, NULL); + + ret = g_strdup_printf ("%d-%s", + (int) (tv.tv_sec ^ tv.tv_usec), + file); + + return ret; +} + +gchar * +vfolder_untimestamp_file_name (const gchar *file) +{ + int n = 0; + + while (file [n] && g_ascii_isdigit (file [n])) + ++n; + n = (file [n] == '-') ? n + 1 : 0; + + return g_strdup (file [n] ? &file [n] : NULL); +} + +gboolean +vfolder_check_extension (const char *name, const char *ext_check) +{ + const char *ext; + + ext = strrchr (name, '.'); + if (ext && !strcmp (ext, ext_check)) + return TRUE; + else + return FALSE; +} + +gchar * +vfolder_escape_home (const gchar *file) +{ + if (file[0] == '~') + return g_strconcat (g_get_home_dir (), &file[1], NULL); + else + return g_strdup (file); +} + +/* Ripped from gfileutils.c:g_build_pathv() */ +gchar * +vfolder_build_uri (const gchar *first_element, + ...) +{ + GString *result; + gboolean is_first = TRUE; + const gchar *next_element; + va_list args; + + va_start (args, first_element); + + result = g_string_new (NULL); + next_element = first_element; + + while (TRUE) { + const gchar *element; + const gchar *start; + const gchar *end; + + if (next_element) { + element = next_element; + next_element = va_arg (args, gchar *); + } + else + break; + + start = element; + + if (!is_first) + start += strspn (start, "/"); + + end = start + strlen (start); + + if (next_element) { + while (end > start + 1 && end [-1] == '/') + end--; + + if (is_first) + if (end > start + 1 && + !strncmp (end - 1, "://", 3)) + end += 2; + } + + if (end > start) { + if (result->len > 0) + g_string_append_c (result, '/'); + + g_string_append_len (result, start, end - start); + } + + is_first = FALSE; + } + + va_end (args); + + return g_string_free (result, FALSE); +} diff --git a/modules/vfolder/vfolder-util.h b/modules/vfolder/vfolder-util.h new file mode 100644 index 0000000..53f89b9 --- /dev/null +++ b/modules/vfolder/vfolder-util.h @@ -0,0 +1,111 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* + * vfolder-util.h - Utility functions for wrapping monitors and + * filename/uri parsing. + * + * Copyright (C) 2002 Ximian, Inc. + * + * The Gnome Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Gnome Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Alex Graveley + * Based on original code by George Lebl . + */ + +#ifndef VFOLDER_UTIL_H +#define VFOLDER_UTIL_H + +#include + +#include +#include +#include +#include + +G_BEGIN_DECLS + +typedef struct { + const gchar *scheme; + gboolean is_all_scheme; + gboolean ends_in_slash; + gchar *path; + gchar *file; + GnomeVFSURI *uri; +} VFolderURI; + +/* assumes vuri->path already set */ +gboolean vfolder_uri_parse_internal (GnomeVFSURI *uri, VFolderURI *vuri); + +#define VFOLDER_URI_PARSE(_uri, _vuri) { \ + gchar *path; \ + path = gnome_vfs_unescape_string ((_uri)->text, G_DIR_SEPARATOR_S); \ + if (path != NULL) { \ + (_vuri)->path = g_alloca (strlen (path) + 1); \ + strcpy ((_vuri)->path, path); \ + g_free (path); \ + } else { \ + (_vuri)->path = NULL; \ + } \ + vfolder_uri_parse_internal ((_uri), (_vuri)); \ + D (g_print ( "%s(): %s\n", G_GNUC_FUNCTION, (_vuri)->path)); \ +} + + +typedef struct { + GnomeVFSMonitorType type; + + GnomeVFSMonitorHandle *vfs_handle; + + time_t ctime; + gchar *uri; + + gboolean frozen; + + GnomeVFSMonitorCallback callback; + gpointer user_data; +} VFolderMonitor; + + +VFolderMonitor *vfolder_monitor_dir_new (const gchar *uri, + GnomeVFSMonitorCallback callback, + gpointer user_data); +VFolderMonitor *vfolder_monitor_file_new (const gchar *uri, + GnomeVFSMonitorCallback callback, + gpointer user_data); +void vfolder_monitor_emit (const gchar *uri, + GnomeVFSMonitorEventType event_type); +void vfolder_monitor_freeze (VFolderMonitor *monitor); +void vfolder_monitor_thaw (VFolderMonitor *monitor); +void vfolder_monitor_cancel (VFolderMonitor *monitor); + + +GnomeVFSResult vfolder_make_directory_and_parents (const gchar *uri, + gboolean skip_filename, + guint permissions); + + +gchar *vfolder_timestamp_file_name (const gchar *file); +gchar *vfolder_untimestamp_file_name (const gchar *file); +gboolean vfolder_check_extension (const char *name, + const char *ext_check); +gchar *vfolder_escape_home (const gchar *file); + +gchar *vfolder_build_uri (const char *first_element, + ...); + + +G_END_DECLS + +#endif /* VFOLDER_UTIL_H */ diff --git a/monikers/ChangeLog b/monikers/ChangeLog new file mode 100644 index 0000000..e9231c6 --- /dev/null +++ b/monikers/ChangeLog @@ -0,0 +1,218 @@ +2003-04-17 Michael Meeks + + * GNOME_VFS_Moniker_std.server.in.in: remove .so suffix. + +2003-02-04 Gustavo J. A. M. Carneiro + + * bonobo-storage-vfs.c (vfs_open_stream): Duplicate the + CORBA_Object reference being returned, otherwise the same + CORBA_Object is released twice when the client calls + bonobo_object_release_unref. This happens when client == server, + which is always the case currently. + (vfs_open_storage): Fix the same problem as in vfs_open_stream. + (vfs_open_storage): Set exception when gnome_vfs_make_directory fails. + +2003-02-03 Gustavo J. A. M. Carneiro + + * bonobo-storage-vfs.c (bonobo_storage_vfs_open): Raise exception + if the URI is *not* a directory, as opposed to raising one if it + is a directory. + + * bonobo-stream-vfs.c (bonobo_stream_vfs_storageinfo_from_file_info): + Look into fi->valid_fields instead of fi->flags to see if a field + is defined. + +2002-11-27 Jody Goldberg + + * Release 2.1.3.1 + +2002-04-22 Jody Goldberg + + * Release 1.9.12 + +2002-02-12 Peter Williams + + * Makefile.am (libmoniker_gnome_vfs_std_la_LIBADD): Fix + compile when $(srcdir) != $(builddir). + +2002-02-11 Johan Dahlin + + * Makefile.am: link libmoniker_gnome_vfs.so against + libgnome-vfs-2.so. Fixes #71018 + +2002-02-06 Michael Meeks + + * bonobo-storage-fs.c + (bonobo_storage_fs_finalize): chain to parent. + + * bonobo-storage-vfs.c + (bonobo_storage_vfs_finalize): ditto. + +2002-01-17 Darin Adler + + * bonobo-storage-fs.c: Added an include of , needed because + now gnome-vfs-mime.h doesn't include it. + +2002-01-02 Dave Camp + + * bonobo-storage-vfs.c (bonobo_storage_vfs_open): Removed the ununsed + mode parameter, changed the flags parameter to take a + Bonobo_Storage_OpenMode, and changed the name of the flags parameter + to mode. + + * bonobo-stream-vfs.c (bonobo_stream_vfs_open): Removed the unused + flags parameter, and changed the mode parameter to take a + Bonobo_Storage_OpenMode. + + * bonobo-moniker-vfs.c (bonobo_moniker_vfs_resolve): Reflect changes + in bonobo_{storage/stream}_vfs_open(). + +2001-10-17 Michael Meeks + + * bonobo-storage-fs.c: use the correct type constructor + to implement a CORBA interface. + + * bonobo-storage-vfs.c: ditto. + +2001-10-05 jacob berkman + + * Makefile.am: set LDFLAGS to -module -avoid-version + +2001-10-02 Darin Adler + + * Makefile.am: Change from xml-i18n-tools to intltool. + +2001-09-25 David Kaelbling + + * bonobo-storage-fs.c (fs_erase): don't do an + assignment instead of a comparison; sigh. + check for EEXIST as well as ENOTEMPTY. + +2001-08-22 Peter Williams + + * Makefile.am (INCLUDES): Typo fix. + +2001-08-14 Michael Meeks + + * Makefile.am: s/oaf/server/, install in + $(libdir)/bonobo/servers + +2001-08-03 Darin Adler + + reviewed by: + + * ChangeLog: + * Makefile.am: + * bonobo-storage-vfs.c: + * bonobo-stream-vfs.c: + * bonobo-stream-vfs.h: + +2001-08-03 Darin Adler + + reviewed by: + + * Makefile.am: + * bonobo-storage-vfs.c: + * bonobo-stream-vfs.c: + * bonobo-stream-vfs.h: + +2001-08-03 Darin Adler + + * Makefile.am: Use CFLAGS from gnome-vfs instead of hard-coding + things like -Wno-unused which are gcc-specific. + +2001-08-01 Darin Adler + + * .cvsignore: Add this. + +2001-08-02 Michael Meeks + + * bonobo-storage-vfs.c (concat_dir_and_file): impl. + (vfs_open_stream, vfs_list_contents, vfs_open_storage), + (vfs_erase): use it. + + * bonobo-storage-fs.c (concat_dir_and_file): impl. + (fs_get_info, fs_open_stream, fs_open_storage), + (fs_rename, fs_list_contents, fs_erase): use it. + +2001-07-30 Michael Meeks + + * GNOME_VFS_Moniker_std.oaf.in.in: in library gnome_vfs not + vfs_gnome, doh. + +2001-07-29 Seth Nickell + + * bonobo-storage-fs.c: + * bonobo-storage-vfs.c: + * bonobo-stream-fs.c: + * bonobo-stream-vfs.c: + + Make it actually compile ;-) Still had includes to parts + of libgnome. + +2001-07-29 Michael Meeks + + * Makefile.am: re-write. + +2001-07-27 Michael Meeks + + * Move into gnome-vfs. + + Reviewed by: Seth + +2001-07-27 Michael Meeks + + * gnome-moniker-std.c: fix the factory name so it is what it + says it is. + + * GNOME_Moniker_std.oaf.in.in: fix the shlib factory path. + + * Makefile.am (clean-local): actualy install the monikers. + use xml-i18n-tools. + +2001-07-11 Martin Baulig + + * bonobo-storage-fs.c, bonobo-moniker-extender-file: Use + gnome_vfs_mime_type_from_name(), not gnome_mime_type_from_file(). + +2001-07-10 Michael Meeks + + * bonobo-moniker-vfs.c: add. + + * bonobo-stream-vfs.c: port to GObject / BonoboObject. + + * bonobo-storage-vfs.c: ditto. + + * GNOME_Moniker_std.oaf.in.in: register the vfs moniker. + +2001-07-10 Michael Meeks + + * bonobo-storage-fs.c (fs_open_storage), + (fs_open_stream): CORBA_Object_duplicate the return + values. + +2001-07-10 Michael Meeks + + * bonobo-moniker-file.c (bonobo_moniker_file_resolve): + upd. to use it. + + * bonobo-storage-fs.c: port to BonoboObject / GObject. + +2001-07-10 Michael Meeks + + * bonobo-moniker-file.c (bonobo_moniker_file_resolve): + use bonobo-stream-fs directly, not via the storage plugin + architecture. + + * bonobo-stream-fs.c (bonobo_mode_to_fs): port to + BonoboObject / GObject. + +2001-07-09 Michael Meeks + + * gnome-moniker-std.[ch]: add. + + * bonobo-moniker-extender-file.c: add. + + * bonobo-moniker-file.c: add. + + * Makefile.am (INCLUDES): re-vamp, add file monikers. diff --git a/monikers/GNOME_VFS_Moniker_std.server.in.in b/monikers/GNOME_VFS_Moniker_std.server.in.in new file mode 100644 index 0000000..a5a8456 --- /dev/null +++ b/monikers/GNOME_VFS_Moniker_std.server.in.in @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/monikers/Makefile.am b/monikers/Makefile.am new file mode 100644 index 0000000..9f14b53 --- /dev/null +++ b/monikers/Makefile.am @@ -0,0 +1,49 @@ +INCLUDES = \ + -I$(top_srcdir) \ + -I$(top_builddir) \ + $(VFS_CFLAGS) \ + $(MONIKERS_CFLAGS) \ + -DG_DISABLE_DEPRECATED \ + -DG_LOG_DOMAIN=\"GnomeVFSMonikers\" + +EXTRA_DIST = \ + GNOME_VFS_Moniker_std.server.in.in + +moniker_LTLIBRARIES = libmoniker_gnome_vfs_std.la +monikerdir = $(libdir)/bonobo/monikers + +GNOME_VFS_Moniker_std.server.in: $(srcdir)/GNOME_VFS_Moniker_std.server.in.in + sed -e "s|\@MONIKER_LIBDIR\@|$(monikerdir)|" \ + $(srcdir)/GNOME_VFS_Moniker_std.server.in.in \ + > GNOME_VFS_Moniker_std.server.in + +CLEANFILES=GNOME_VFS_Moniker_std.server GNOME_VFS_Moniker_std.server.in + +serverdir = $(libdir)/bonobo/servers +server_DATA = GNOME_VFS_Moniker_std.server +@INTLTOOL_SERVER_RULE@ + +clean-local: + -rm -f $(server_DATA) + +libmoniker_gnome_vfs_std_la_SOURCES = \ + gnome-moniker-std.c \ + gnome-moniker-std.h \ + bonobo-stream-fs.h \ + bonobo-stream-fs.c \ + bonobo-storage-fs.h \ + bonobo-storage-fs.c \ + bonobo-moniker-extender-file.c \ + bonobo-moniker-file.c \ + bonobo-stream-vfs.h \ + bonobo-stream-vfs.c \ + bonobo-storage-vfs.h \ + bonobo-storage-vfs.c \ + bonobo-moniker-vfs.c + +libmoniker_gnome_vfs_std_la_LIBADD = \ + $(MONIKERS_LIBS) \ + $(top_builddir)/libgnomevfs/libgnomevfs-2.la + +libmoniker_gnome_vfs_std_la_LDFLAGS = \ + -module -avoid-version -no-undefined diff --git a/monikers/Makefile.in b/monikers/Makefile.in new file mode 100644 index 0000000..d8483f8 --- /dev/null +++ b/monikers/Makefile.in @@ -0,0 +1,537 @@ +# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ +AS = @AS@ +AWK = @AWK@ +BONOBO_ACTIVATION_REQUIRED = @BONOBO_ACTIVATION_REQUIRED@ +BONOBO_IDLDIR = @BONOBO_IDLDIR@ +BONOBO_REQUIRED = @BONOBO_REQUIRED@ +BZ2_LIBS = @BZ2_LIBS@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +DATADIRNAME = @DATADIRNAME@ +DB2HTML = @DB2HTML@ +DLLTOOL = @DLLTOOL@ +ECHO = @ECHO@ +ENABLE_PROFILER = @ENABLE_PROFILER@ +EXEEXT = @EXEEXT@ +FAM_LIBS = @FAM_LIBS@ +GCONFTOOL = @GCONFTOOL@ +GCONF_REQUIRED = @GCONF_REQUIRED@ +GCONF_SCHEMA_CONFIG_SOURCE = @GCONF_SCHEMA_CONFIG_SOURCE@ +GCONF_SCHEMA_FILE_DIR = @GCONF_SCHEMA_FILE_DIR@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GLIB_REQUIRED = @GLIB_REQUIRED@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GNOME_ACLOCAL_DIR = @GNOME_ACLOCAL_DIR@ +GNOME_ACLOCAL_FLAGS = @GNOME_ACLOCAL_FLAGS@ +GNOME_VFS_DIR = @GNOME_VFS_DIR@ +GTKDOC = @GTKDOC@ +HAVE_GTK_DOC = @HAVE_GTK_DOC@ +HTML_DIR = @HTML_DIR@ +INSTOBJEXT = @INSTOBJEXT@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_CAVES_RULE = @INTLTOOL_CAVES_RULE@ +INTLTOOL_DESKTOP_RULE = @INTLTOOL_DESKTOP_RULE@ +INTLTOOL_DIRECTORY_RULE = @INTLTOOL_DIRECTORY_RULE@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_KEYS_RULE = @INTLTOOL_KEYS_RULE@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_OAF_RULE = @INTLTOOL_OAF_RULE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_PONG_RULE = @INTLTOOL_PONG_RULE@ +INTLTOOL_PROP_RULE = @INTLTOOL_PROP_RULE@ +INTLTOOL_SCHEMAS_RULE = @INTLTOOL_SCHEMAS_RULE@ +INTLTOOL_SERVER_RULE = @INTLTOOL_SERVER_RULE@ +INTLTOOL_SHEET_RULE = @INTLTOOL_SHEET_RULE@ +INTLTOOL_SOUNDLIST_RULE = @INTLTOOL_SOUNDLIST_RULE@ +INTLTOOL_THEME_RULE = @INTLTOOL_THEME_RULE@ +INTLTOOL_UI_RULE = @INTLTOOL_UI_RULE@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTLTOOL_XML_RULE = @INTLTOOL_XML_RULE@ +LDFLAGS = @LDFLAGS@ +LIBEFS_CFLAGS = @LIBEFS_CFLAGS@ +LIBEFS_LIBS = @LIBEFS_LIBS@ +LIBGNOMEVFS_AGE = @LIBGNOMEVFS_AGE@ +LIBGNOMEVFS_CFLAGS = @LIBGNOMEVFS_CFLAGS@ +LIBGNOMEVFS_CURRENT = @LIBGNOMEVFS_CURRENT@ +LIBGNOMEVFS_LIBS = @LIBGNOMEVFS_LIBS@ +LIBGNOMEVFS_REVISION = @LIBGNOMEVFS_REVISION@ +LIBGNUTLS_CFLAGS = @LIBGNUTLS_CFLAGS@ +LIBGNUTLS_CONFIG = @LIBGNUTLS_CONFIG@ +LIBGNUTLS_LIBS = @LIBGNUTLS_LIBS@ +LIBIDL_REQUIRED = @LIBIDL_REQUIRED@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MODULES_CFLAGS = @MODULES_CFLAGS@ +MODULES_FILE_CFLAGS = @MODULES_FILE_CFLAGS@ +MODULES_FILE_LIBS = @MODULES_FILE_LIBS@ +MODULES_GCONF_CFLAGS = @MODULES_GCONF_CFLAGS@ +MODULES_GCONF_LIBS = @MODULES_GCONF_LIBS@ +MODULES_LIBS = @MODULES_LIBS@ +MODULES_XML_CFLAGS = @MODULES_XML_CFLAGS@ +MODULES_XML_GCONF_CFLAGS = @MODULES_XML_GCONF_CFLAGS@ +MODULES_XML_GCONF_LIBS = @MODULES_XML_GCONF_LIBS@ +MODULES_XML_LIBS = @MODULES_XML_LIBS@ +MONIKERS_CFLAGS = @MONIKERS_CFLAGS@ +MONIKERS_LIBS = @MONIKERS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ORBIT_IDL = @ORBIT_IDL@ +ORBIT_REQUIRED = @ORBIT_REQUIRED@ +PACKAGE = @PACKAGE@ +PKG_CONFIG = @PKG_CONFIG@ +POFILES = @POFILES@ +POPT_LIBS = @POPT_LIBS@ +POSUB = @POSUB@ +PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ +PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ +RANLIB = @RANLIB@ +STRIP = @STRIP@ +TEST_CFLAGS = @TEST_CFLAGS@ +TEST_LIBS = @TEST_LIBS@ +TOP_BUILDDIR = @TOP_BUILDDIR@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +VFS_CFLAGS = @VFS_CFLAGS@ +VFS_INCLUDEDIR = @VFS_INCLUDEDIR@ +VFS_LIBDIR = @VFS_LIBDIR@ +VFS_LIBS = @VFS_LIBS@ +VFS_OFFSET = @VFS_OFFSET@ +VFS_OFFSET_IS = @VFS_OFFSET_IS@ +VFS_OFFSET_PRINTF = @VFS_OFFSET_PRINTF@ +VFS_SIZE = @VFS_SIZE@ +VFS_SIZE_IS = @VFS_SIZE_IS@ +VFS_SIZE_PRINTF = @VFS_SIZE_PRINTF@ +WARN_CFLAGS = @WARN_CFLAGS@ +XML_REQUIRED = @XML_REQUIRED@ +cxxflags_set = @cxxflags_set@ + +INCLUDES = \ + -I$(top_srcdir) \ + -I$(top_builddir) \ + $(VFS_CFLAGS) \ + $(MONIKERS_CFLAGS) \ + -DG_DISABLE_DEPRECATED \ + -DG_LOG_DOMAIN=\"GnomeVFSMonikers\" + + +EXTRA_DIST = \ + GNOME_VFS_Moniker_std.server.in.in + + +moniker_LTLIBRARIES = libmoniker_gnome_vfs_std.la +monikerdir = $(libdir)/bonobo/monikers + +CLEANFILES = GNOME_VFS_Moniker_std.server GNOME_VFS_Moniker_std.server.in + +serverdir = $(libdir)/bonobo/servers +server_DATA = GNOME_VFS_Moniker_std.server + +libmoniker_gnome_vfs_std_la_SOURCES = \ + gnome-moniker-std.c \ + gnome-moniker-std.h \ + bonobo-stream-fs.h \ + bonobo-stream-fs.c \ + bonobo-storage-fs.h \ + bonobo-storage-fs.c \ + bonobo-moniker-extender-file.c \ + bonobo-moniker-file.c \ + bonobo-stream-vfs.h \ + bonobo-stream-vfs.c \ + bonobo-storage-vfs.h \ + bonobo-storage-vfs.c \ + bonobo-moniker-vfs.c + + +libmoniker_gnome_vfs_std_la_LIBADD = \ + $(MONIKERS_LIBS) \ + $(top_builddir)/libgnomevfs/libgnomevfs-2.la + + +libmoniker_gnome_vfs_std_la_LDFLAGS = \ + -module -avoid-version -no-undefined + +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../config.h +CONFIG_CLEAN_FILES = +LTLIBRARIES = $(moniker_LTLIBRARIES) + + +DEFS = @DEFS@ -I. -I$(srcdir) -I.. +LIBS = @LIBS@ +libmoniker_gnome_vfs_std_la_DEPENDENCIES = \ +$(top_builddir)/libgnomevfs/libgnomevfs-2.la +libmoniker_gnome_vfs_std_la_OBJECTS = gnome-moniker-std.lo \ +bonobo-stream-fs.lo bonobo-storage-fs.lo \ +bonobo-moniker-extender-file.lo bonobo-moniker-file.lo \ +bonobo-stream-vfs.lo bonobo-storage-vfs.lo bonobo-moniker-vfs.lo +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +DATA = $(server_DATA) + +DIST_COMMON = ChangeLog Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +SOURCES = $(libmoniker_gnome_vfs_std_la_SOURCES) +OBJECTS = $(libmoniker_gnome_vfs_std_la_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .lo .o .obj .s +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps monikers/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-monikerLTLIBRARIES: + +clean-monikerLTLIBRARIES: + -test -z "$(moniker_LTLIBRARIES)" || rm -f $(moniker_LTLIBRARIES) + +distclean-monikerLTLIBRARIES: + +maintainer-clean-monikerLTLIBRARIES: + +install-monikerLTLIBRARIES: $(moniker_LTLIBRARIES) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(monikerdir) + @list='$(moniker_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(monikerdir)/$$p"; \ + $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(monikerdir)/$$p; \ + else :; fi; \ + done + +uninstall-monikerLTLIBRARIES: + @$(NORMAL_UNINSTALL) + list='$(moniker_LTLIBRARIES)'; for p in $$list; do \ + $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(monikerdir)/$$p; \ + done + +.c.o: + $(COMPILE) -c $< + +# FIXME: We should only use cygpath when building on Windows, +# and only if it is available. +.c.obj: + $(COMPILE) -c `cygpath -w $<` + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + -rm -f *.$(OBJEXT) + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +.c.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.s.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.S.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + +maintainer-clean-libtool: + +libmoniker_gnome_vfs_std.la: $(libmoniker_gnome_vfs_std_la_OBJECTS) $(libmoniker_gnome_vfs_std_la_DEPENDENCIES) + $(LINK) -rpath $(monikerdir) $(libmoniker_gnome_vfs_std_la_LDFLAGS) $(libmoniker_gnome_vfs_std_la_OBJECTS) $(libmoniker_gnome_vfs_std_la_LIBADD) $(LIBS) + +install-serverDATA: $(server_DATA) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(serverdir) + @list='$(server_DATA)'; for p in $$list; do \ + if test -f $(srcdir)/$$p; then \ + echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(serverdir)/$$p"; \ + $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(serverdir)/$$p; \ + else if test -f $$p; then \ + echo " $(INSTALL_DATA) $$p $(DESTDIR)$(serverdir)/$$p"; \ + $(INSTALL_DATA) $$p $(DESTDIR)$(serverdir)/$$p; \ + fi; fi; \ + done + +uninstall-serverDATA: + @$(NORMAL_UNINSTALL) + list='$(server_DATA)'; for p in $$list; do \ + rm -f $(DESTDIR)$(serverdir)/$$p; \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = monikers + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +bonobo-moniker-extender-file.lo bonobo-moniker-extender-file.o : \ + bonobo-moniker-extender-file.c ../config.h \ + ../libgnomevfs/gnome-vfs-mime.h ../libgnomevfs/gnome-vfs-uri.h \ + gnome-moniker-std.h +bonobo-moniker-file.lo bonobo-moniker-file.o : bonobo-moniker-file.c \ + ../config.h gnome-moniker-std.h bonobo-stream-fs.h \ + bonobo-storage-fs.h +bonobo-moniker-vfs.lo bonobo-moniker-vfs.o : bonobo-moniker-vfs.c \ + ../config.h gnome-moniker-std.h bonobo-stream-vfs.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h bonobo-storage-vfs.h +bonobo-storage-fs.lo bonobo-storage-fs.o : bonobo-storage-fs.c \ + ../config.h bonobo-storage-fs.h ../libgnomevfs/gnome-vfs-mime.h \ + ../libgnomevfs/gnome-vfs-uri.h bonobo-stream-fs.h +bonobo-storage-vfs.lo bonobo-storage-vfs.o : bonobo-storage-vfs.c \ + ../config.h bonobo-storage-vfs.h bonobo-stream-vfs.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-directory.h \ + ../libgnomevfs/gnome-vfs-ops.h \ + ../libgnomevfs/gnome-vfs-monitor.h +bonobo-stream-fs.lo bonobo-stream-fs.o : bonobo-stream-fs.c ../config.h \ + bonobo-stream-fs.h ../libgnomevfs/gnome-vfs-mime.h \ + ../libgnomevfs/gnome-vfs-uri.h +bonobo-stream-vfs.lo bonobo-stream-vfs.o : bonobo-stream-vfs.c \ + ../config.h bonobo-stream-vfs.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-ops.h \ + ../libgnomevfs/gnome-vfs-monitor.h +gnome-moniker-std.lo gnome-moniker-std.o : gnome-moniker-std.c \ + ../config.h gnome-moniker-std.h + +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: +install-exec: install-exec-am + +install-data-am: install-monikerLTLIBRARIES install-serverDATA +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-monikerLTLIBRARIES uninstall-serverDATA +uninstall: uninstall-am +all-am: Makefile $(LTLIBRARIES) $(DATA) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(monikerdir) $(DESTDIR)$(serverdir) + + +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-monikerLTLIBRARIES mostlyclean-compile \ + mostlyclean-libtool mostlyclean-tags \ + mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-monikerLTLIBRARIES clean-compile clean-libtool \ + clean-tags clean-generic mostlyclean-am clean-local + +clean: clean-am + +distclean-am: distclean-monikerLTLIBRARIES distclean-compile \ + distclean-libtool distclean-tags distclean-generic \ + clean-am + -rm -f libtool + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-monikerLTLIBRARIES \ + maintainer-clean-compile maintainer-clean-libtool \ + maintainer-clean-tags maintainer-clean-generic \ + distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: mostlyclean-monikerLTLIBRARIES distclean-monikerLTLIBRARIES \ +clean-monikerLTLIBRARIES maintainer-clean-monikerLTLIBRARIES \ +uninstall-monikerLTLIBRARIES install-monikerLTLIBRARIES \ +mostlyclean-compile distclean-compile clean-compile \ +maintainer-clean-compile mostlyclean-libtool distclean-libtool \ +clean-libtool maintainer-clean-libtool uninstall-serverDATA \ +install-serverDATA tags mostlyclean-tags distclean-tags clean-tags \ +maintainer-clean-tags distdir info-am info dvi-am dvi check check-am \ +installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +GNOME_VFS_Moniker_std.server.in: $(srcdir)/GNOME_VFS_Moniker_std.server.in.in + sed -e "s|\@MONIKER_LIBDIR\@|$(monikerdir)|" \ + $(srcdir)/GNOME_VFS_Moniker_std.server.in.in \ + > GNOME_VFS_Moniker_std.server.in +@INTLTOOL_SERVER_RULE@ + +clean-local: + -rm -f $(server_DATA) + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/monikers/bonobo-moniker-extender-file.c b/monikers/bonobo-moniker-extender-file.c new file mode 100644 index 0000000..b38c83c --- /dev/null +++ b/monikers/bonobo-moniker-extender-file.c @@ -0,0 +1,97 @@ +/* + * bonobo-moniker-extender-file.c: + * + * Author: + * Dietmar Maurer (dietmar@helixcode.com) + * + * Copyright 2000, Helix Code, Inc. + */ +#include "config.h" +#include +#include +#include +#include +#include +#include +#include + +#include "gnome-moniker-std.h" + +Bonobo_Unknown +bonobo_file_extender_resolve (BonoboMonikerExtender *extender, + const Bonobo_Moniker m, + const Bonobo_ResolveOptions *options, + const CORBA_char *display_name, + const CORBA_char *requested_interface, + CORBA_Environment *ev) +{ + const char *mime_type; + char *oaf_requirements; + Bonobo_Unknown object; + Bonobo_Persist persist; + const char *fname; + Bonobo_ServerInfoList *result; + char *oafiid; + + if (strchr (display_name, ':')) + fname = strchr (display_name, ':') + 1; + else + fname = display_name; + + g_warning ("Filename : '%s'", fname); + + mime_type = gnome_vfs_mime_type_from_name (fname); + + oaf_requirements = g_strdup_printf ( + "bonobo:supported_mime_types.has ('%s') AND repo_ids.has ('%s') AND " + "repo_ids.has ('IDL:Bonobo/PersistFile:1.0')", + mime_type, requested_interface); + + result = bonobo_activation_query (oaf_requirements, NULL, ev); + if (BONOBO_EX (ev) || result == NULL || result->_buffer == NULL || + !result->_buffer[0].iid) + return CORBA_OBJECT_NIL; + + g_free (oaf_requirements); + + oafiid = g_strdup (result->_buffer[0].iid); + + CORBA_free (result); + + object = bonobo_url_lookup (oafiid, (gchar *) display_name, ev); + if (!BONOBO_EX (ev) && object != CORBA_OBJECT_NIL) { + g_free (oafiid); + Bonobo_Unknown_ref (object, ev); + if (!BONOBO_EX (ev)) + return bonobo_moniker_util_qi_return (object, + requested_interface, ev); + } + + CORBA_exception_init (ev); + + object = bonobo_activation_activate_from_id (oafiid, 0, NULL, ev); + + g_free (oafiid); + + if (BONOBO_EX (ev) || object == CORBA_OBJECT_NIL) + return CORBA_OBJECT_NIL; + + persist = Bonobo_Unknown_queryInterface ( + object, "IDL:Bonobo/PersistFile:1.0", ev); + + if (BONOBO_EX (ev) || persist == CORBA_OBJECT_NIL) { + bonobo_object_release_unref (object, ev); + return CORBA_OBJECT_NIL; + } + + if (persist != CORBA_OBJECT_NIL) { + Bonobo_PersistFile_load (persist, fname, ev); + + bonobo_object_release_unref (persist, ev); + + return bonobo_moniker_util_qi_return ( + object, requested_interface, ev); + } + + return CORBA_OBJECT_NIL; +} diff --git a/monikers/bonobo-moniker-file.c b/monikers/bonobo-moniker-file.c new file mode 100644 index 0000000..9910efa --- /dev/null +++ b/monikers/bonobo-moniker-file.c @@ -0,0 +1,80 @@ +/* + * bonobo-moniker-file.c: Sample file-system based Moniker implementation + * + * This is the file-system based Moniker implementation. + * + * Author: + * Michael Meeks (michael@helixcode.com) + * + * Copyright 2000, Helix Code, Inc. + */ +#include +#include +#include +#include +#include + +#include "gnome-moniker-std.h" +#include "bonobo-stream-fs.h" +#include "bonobo-storage-fs.h" + +Bonobo_Unknown +bonobo_moniker_file_resolve (BonoboMoniker *moniker, + const Bonobo_ResolveOptions *options, + const CORBA_char *requested_interface, + CORBA_Environment *ev) +{ + const char *fname = bonobo_moniker_get_name (moniker); + Bonobo_Unknown retval; + + if (!strcmp (requested_interface, "IDL:Bonobo/Stream:1.0")) { + BonoboObject *stream; + + stream = BONOBO_OBJECT (bonobo_stream_fs_open ( + fname, Bonobo_Storage_READ, 0664, ev)); + + if (BONOBO_EX (ev)) + return CORBA_OBJECT_NIL; + + if (!stream) { + g_warning ("Failed to open stream '%s'", fname); + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Moniker_InterfaceNotFound, NULL); + return CORBA_OBJECT_NIL; + } + + return CORBA_Object_duplicate (BONOBO_OBJREF (stream), ev); + + } else if (!strcmp (requested_interface, "IDL:Bonobo/Storage:1.0")) { + BonoboObject *storage; + + storage = BONOBO_OBJECT (bonobo_storage_fs_open ( + fname, Bonobo_Storage_READ, 0664, ev)); + + if (BONOBO_EX (ev)) + return CORBA_OBJECT_NIL; + + if (!storage) { + g_warning ("Failed to open storage '%s'", fname); + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Moniker_InterfaceNotFound, NULL); + return CORBA_OBJECT_NIL; + } + + return CORBA_Object_duplicate (BONOBO_OBJREF (storage), ev); + } + + retval = bonobo_moniker_use_extender ( + "OAFIID:Bonobo_MonikerExtender_file", + moniker, options, requested_interface, ev); + + if (BONOBO_EX (ev)) + return CORBA_OBJECT_NIL; + + if (retval == CORBA_OBJECT_NIL) + retval = bonobo_moniker_use_extender ( + "OAFIID:Bonobo_MonikerExtender_stream", + moniker, options, requested_interface, ev); + + return retval; +} diff --git a/monikers/bonobo-moniker-vfs.c b/monikers/bonobo-moniker-vfs.c new file mode 100644 index 0000000..a265445 --- /dev/null +++ b/monikers/bonobo-moniker-vfs.c @@ -0,0 +1,69 @@ +/* + * bonobo-moniker-file.c: Sample file-system based Moniker implementation + * + * This is the file-system based Moniker implementation. + * + * Author: + * Michael Meeks (michael@helixcode.com) + * + * Copyright 2000, Helix Code, Inc. + */ +#include +#include +#include +#include +#include + +#include "gnome-moniker-std.h" +#include "bonobo-stream-vfs.h" +#include "bonobo-storage-vfs.h" + +Bonobo_Unknown +bonobo_moniker_vfs_resolve (BonoboMoniker *moniker, + const Bonobo_ResolveOptions *options, + const CORBA_char *requested_interface, + CORBA_Environment *ev) +{ + const char *fname = bonobo_moniker_get_name (moniker); + + if (!strcmp (requested_interface, "IDL:Bonobo/Stream:1.0")) { + BonoboObject *stream; + + stream = BONOBO_OBJECT (bonobo_stream_vfs_open ( + fname, Bonobo_Storage_READ, ev)); + + if (BONOBO_EX (ev)) + return CORBA_OBJECT_NIL; + + if (!stream) { + g_warning ("Failed to open stream '%s'", fname); + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Moniker_InterfaceNotFound, NULL); + return CORBA_OBJECT_NIL; + } + return CORBA_Object_duplicate (BONOBO_OBJREF (stream), ev); + + } + else if (!strcmp (requested_interface, "IDL:Bonobo/Storage:1.0")) { + BonoboObject *storage; + + storage = BONOBO_OBJECT (bonobo_storage_vfs_open ( + fname, Bonobo_Storage_READ, ev)); + + if (BONOBO_EX (ev)) + return CORBA_OBJECT_NIL; + + if (!storage) { + g_warning ("Failed to open storage '%s'", fname); + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Moniker_InterfaceNotFound, NULL); + return CORBA_OBJECT_NIL; + } + + return CORBA_Object_duplicate (BONOBO_OBJREF (storage), ev); + } + else + return bonobo_moniker_use_extender ( + "OAFIID:Bonobo_MonikerExtender_stream", + moniker, options, requested_interface, ev); +} diff --git a/monikers/bonobo-storage-fs.c b/monikers/bonobo-storage-fs.c new file mode 100644 index 0000000..2c3af67 --- /dev/null +++ b/monikers/bonobo-storage-fs.c @@ -0,0 +1,505 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * bonobo-storage-fs.c: Sample file-system based Storage implementation + * + * This is just a sample file-system based Storage implementation. + * it is only used for debugging purposes + * + * Authors: + * Miguel de Icaza (miguel@gnu.org) + * Michael Meeks (michael@ximian.com) + * + * Copyright 2001, Ximian, Inc + */ + +#include +#include "bonobo-storage-fs.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "bonobo-stream-fs.h" + +static char * +concat_dir_and_file (const char *dir, const char *file) +{ + g_return_val_if_fail (dir != NULL, NULL); + g_return_val_if_fail (file != NULL, NULL); + + /* If the directory name doesn't have a / on the end, we need + to add one so we get a proper path to the file */ + if (dir[0] != '\0' && dir [strlen(dir) - 1] != '/') + return g_strconcat (dir, "/", file, NULL); + else + return g_strconcat (dir, file, NULL); +} + +static BonoboObjectClass *bonobo_storage_fs_parent_class; + +static void +bonobo_storage_fs_finalize (GObject *object) +{ + BonoboStorageFS *storage_fs = BONOBO_STORAGE_FS (object); + + g_free (storage_fs->path); + storage_fs->path = NULL; + + G_OBJECT_CLASS (bonobo_storage_fs_parent_class)->finalize (object); +} + +static Bonobo_StorageInfo* +fs_get_info (PortableServer_Servant storage, + const CORBA_char *path, + const Bonobo_StorageInfoFields mask, + CORBA_Environment *ev) +{ + BonoboStorageFS *storage_fs = BONOBO_STORAGE_FS ( + bonobo_object (storage)); + Bonobo_StorageInfo *si; + struct stat st; + char *full = NULL; + gboolean dangling = FALSE; + + if (mask & ~(Bonobo_FIELD_CONTENT_TYPE | Bonobo_FIELD_SIZE | + Bonobo_FIELD_TYPE)) { + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_NotSupported, NULL); + return CORBA_OBJECT_NIL; + } + + full = concat_dir_and_file (storage_fs->path, path); + if (stat (full, &st) == -1) { + if (lstat (full, &st) == -1) + goto get_info_except; + else + dangling = TRUE; + } + + si = Bonobo_StorageInfo__alloc (); + + si->size = st.st_size; + si->name = CORBA_string_dup (path); + + if (S_ISDIR (st.st_mode)) { + si->type = Bonobo_STORAGE_TYPE_DIRECTORY; + si->content_type = CORBA_string_dup ("x-directory/normal"); + } else { + si->type = Bonobo_STORAGE_TYPE_REGULAR; + if (dangling) + si->content_type = + CORBA_string_dup ("x-symlink/dangling"); + else + si->content_type = + CORBA_string_dup ( + gnome_vfs_mime_type_from_name (full)); + } + + g_free (full); + + return si; + + get_info_except: + + if (full) + g_free (full); + + if (errno == EACCES) + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_NoPermission, + NULL); + else if (errno == ENOENT) + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_NotFound, + NULL); + else + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_IOError, NULL); + + return CORBA_OBJECT_NIL; +} + +static void +fs_set_info (PortableServer_Servant storage, + const CORBA_char *path, + const Bonobo_StorageInfo *info, + const Bonobo_StorageInfoFields mask, + CORBA_Environment *ev) +{ + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_NotSupported, + NULL); +} + +static Bonobo_Stream +fs_open_stream (PortableServer_Servant storage, + const CORBA_char *path, + Bonobo_Storage_OpenMode mode, + CORBA_Environment *ev) +{ + BonoboStorageFS *storage_fs = BONOBO_STORAGE_FS ( + bonobo_object (storage)); + BonoboObject *stream; + char *full; + + full = concat_dir_and_file (storage_fs->path, path); + stream = BONOBO_OBJECT ( + bonobo_stream_fs_open (full, mode, 0644, ev)); + g_free (full); + + return CORBA_Object_duplicate ( + BONOBO_OBJREF (stream), ev); +} + +static Bonobo_Storage +fs_open_storage (PortableServer_Servant storage, + const CORBA_char *path, + Bonobo_Storage_OpenMode mode, + CORBA_Environment *ev) +{ + BonoboStorageFS *storage_fs = BONOBO_STORAGE_FS ( + bonobo_object (storage)); + BonoboObject *new_storage; + char *full; + + full = concat_dir_and_file (storage_fs->path, path); + new_storage = BONOBO_OBJECT ( + bonobo_storage_fs_open (full, mode, 0644, ev)); + g_free (full); + + return CORBA_Object_duplicate ( + BONOBO_OBJREF (new_storage), ev); +} + +static void +fs_copy_to (PortableServer_Servant storage, + Bonobo_Storage dest, + CORBA_Environment *ev) +{ + BonoboStorageFS *storage_fs = BONOBO_STORAGE_FS ( + bonobo_object (storage)); + + bonobo_storage_copy_to ( + BONOBO_OBJREF (storage_fs), dest, ev); +} + +static void +fs_rename (PortableServer_Servant storage, + const CORBA_char *path, + const CORBA_char *new_path, + CORBA_Environment *ev) +{ + BonoboStorageFS *storage_fs = BONOBO_STORAGE_FS ( + bonobo_object (storage)); + char *full_old, *full_new; + + full_old = concat_dir_and_file (storage_fs->path, path); + full_new = concat_dir_and_file (storage_fs->path, new_path); + + if (rename (full_old, full_new) == -1) { + + if ((errno == EACCES) || (errno == EPERM) || (errno == EROFS)) + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_NoPermission, + NULL); + else if (errno == ENOENT) + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_NotFound, + NULL); + else if ((errno == EEXIST) || (errno == ENOTEMPTY)) + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_NameExists, + NULL); + else + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_IOError, + NULL); + } + + g_free (full_old); + g_free (full_new); +} + +static void +fs_commit (PortableServer_Servant storage, + CORBA_Environment *ev) +{ + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Stream_NotSupported, NULL); +} + +static void +fs_revert (PortableServer_Servant storage, + CORBA_Environment *ev) +{ + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Stream_NotSupported, NULL); +} + +static Bonobo_Storage_DirectoryList * +fs_list_contents (PortableServer_Servant storage, + const CORBA_char *path, + Bonobo_StorageInfoFields mask, + CORBA_Environment *ev) +{ + BonoboStorageFS *storage_fs = BONOBO_STORAGE_FS ( + bonobo_object (storage)); + Bonobo_Storage_DirectoryList *list = NULL; + Bonobo_StorageInfo *buf; + struct dirent *de; + struct stat st; + DIR *dir = NULL; + gint i, max, v, num_entries = 0; + gchar *full = NULL; + + if (mask & ~(Bonobo_FIELD_CONTENT_TYPE | Bonobo_FIELD_SIZE | + Bonobo_FIELD_TYPE)) { + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_NotSupported, NULL); + return CORBA_OBJECT_NIL; + } + + if (!(dir = opendir (storage_fs->path))) + goto list_contents_except; + + for (max = 0; readdir (dir); max++) + /* do nothing */; + + rewinddir (dir); + + buf = CORBA_sequence_Bonobo_StorageInfo_allocbuf (max); + list = Bonobo_Storage_DirectoryList__alloc(); + list->_buffer = buf; + CORBA_sequence_set_release (list, TRUE); + + for (i = 0; (de = readdir (dir)) && (i < max); i++) { + + if ((de->d_name[0] == '.' && de->d_name[1] == '\0') || + (de->d_name[0] == '.' && de->d_name[1] == '.' + && de->d_name[2] == '\0')) { + i--; + continue; /* Ignore . and .. */ + } + + buf [i].name = CORBA_string_dup (de->d_name); + buf [i].size = 0; + buf [i].content_type = NULL; + + full = concat_dir_and_file (storage_fs->path, de->d_name); + v = stat (full, &st); + + if (v == -1) { + /* + * The stat failed -- two common cases are where + * the file was removed between the call to readdir + * and the iteration, and where the file is a dangling + * symlink. + */ + if (errno == ENOENT || errno == ELOOP) { + v = lstat (full, &st); + if (v == 0) { + /* FIXME - x-symlink/dangling is odd */ + buf [i].size = st.st_size; + buf [i].type = Bonobo_STORAGE_TYPE_REGULAR; + buf [i].content_type = + CORBA_string_dup ("x-symlink/dangling"); + g_free (full); + num_entries++; + continue; + } + } + + /* Unless it's something grave, just skip the file */ + if (errno != ENOMEM && errno != EFAULT && errno != ENOTDIR) { + i--; + g_free (full); + continue; + } + + goto list_contents_except; + } + + buf [i].size = st.st_size; + + if (S_ISDIR (st.st_mode)) { + buf [i].type = Bonobo_STORAGE_TYPE_DIRECTORY; + buf [i].content_type = + CORBA_string_dup ("x-directory/normal"); + } else { + buf [i].type = Bonobo_STORAGE_TYPE_REGULAR; + buf [i].content_type = + CORBA_string_dup ( + gnome_vfs_mime_type_from_name (full)); + } + + g_free (full); + + num_entries++; + } + + list->_length = num_entries; + + closedir (dir); + + return list; + + list_contents_except: + + if (dir) + closedir (dir); + + if (list) + CORBA_free (list); + + if (full) + g_free (full); + + if (errno == ENOENT) + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_NotFound, + NULL); + else if (errno == ENOTDIR) + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_NotStorage, + NULL); + else + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_IOError, NULL); + + return CORBA_OBJECT_NIL; +} + +static void +fs_erase (PortableServer_Servant storage, + const CORBA_char *path, + CORBA_Environment *ev) +{ + BonoboStorageFS *storage_fs = BONOBO_STORAGE_FS ( + bonobo_object (storage)); + char *full; + + full = concat_dir_and_file (storage_fs->path, path); + + if (remove (full) == -1) { + + if (errno == ENOENT) + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_NotFound, + NULL); + else if (errno == ENOTEMPTY || errno == EEXIST) + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_NotEmpty, + NULL); + else if (errno == EACCES || errno == EPERM) + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_NoPermission, + NULL); + else + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_IOError, NULL); + } + + g_free (full); +} + +static void +bonobo_storage_fs_class_init (BonoboStorageFSClass *klass) +{ + GObjectClass *object_class = (GObjectClass *) klass; + + POA_Bonobo_Storage__epv *epv = &klass->epv; + + bonobo_storage_fs_parent_class = + g_type_class_peek_parent (klass); + + epv->getInfo = fs_get_info; + epv->setInfo = fs_set_info; + epv->openStream = fs_open_stream; + epv->openStorage = fs_open_storage; + epv->copyTo = fs_copy_to; + epv->rename = fs_rename; + epv->commit = fs_commit; + epv->revert = fs_revert; + epv->listContents = fs_list_contents; + epv->erase = fs_erase; + + object_class->finalize = bonobo_storage_fs_finalize; +} + + +static void +bonobo_storage_fs_init (GObject *object) +{ + /* nothing to do */ +} + +BONOBO_TYPE_FUNC_FULL (BonoboStorageFS, + Bonobo_Storage, + bonobo_object_get_type (), + bonobo_storage_fs); + +/** + * bonobo_storage_fs_open: + * @path: path to existing directory that represents the storage + * @flags: open flags. + * @mode: mode used if @flags containst Bonobo_Storage_CREATE for the storage. + * + * Returns a BonoboStorage object that represents the storage at @path + */ +BonoboStorageFS * +bonobo_storage_fs_open (const char *path, gint flags, + gint mode, CORBA_Environment *ev) +{ + BonoboStorageFS *storage_fs; + struct stat st; + + g_return_val_if_fail (path != NULL, NULL); + g_return_val_if_fail (ev != NULL, NULL); + + /* Most storages are files */ + mode = mode | 0111; + + if ((flags & Bonobo_Storage_CREATE) && + (mkdir (path, mode) == -1) && (errno != EEXIST)) { + + if (errno == EACCES) + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_NoPermission, + NULL); + else + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_IOError, NULL); + return NULL; + } + + if (stat (path, &st) == -1) { + + if (errno == ENOENT) + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_NotFound, + NULL); + else + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_IOError, + NULL); + return NULL; + } + + if (!S_ISDIR (st.st_mode)) { + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_NotStorage, NULL); + return NULL; + } + + storage_fs = g_object_new (bonobo_storage_fs_get_type (), NULL); + storage_fs->path = g_strdup (path); + + return storage_fs; +} diff --git a/monikers/bonobo-storage-fs.h b/monikers/bonobo-storage-fs.h new file mode 100644 index 0000000..d869204 --- /dev/null +++ b/monikers/bonobo-storage-fs.h @@ -0,0 +1,34 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +#ifndef _BONOBO_STORAGE_FS_H_ +#define _BONOBO_STORAGE_FS_H_ + +#include + +G_BEGIN_DECLS + +#define BONOBO_STORAGE_FS_TYPE (bonobo_storage_fs_get_type ()) +#define BONOBO_STORAGE_FS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), BONOBO_STORAGE_FS_TYPE, BonoboStorageFS)) +#define BONOBO_STORAGE_FS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), BONOBO_STORAGE_FS_TYPE, BonoboStorageFSClass)) +#define BONOBO_IS_STORAGE_FS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), BONOBO_STORAGE_FS_TYPE)) +#define BONOBO_IS_STORAGE_FS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), BONOBO_STORAGE_FS_TYPE)) + +typedef struct { + BonoboObject parent; + char *path; +} BonoboStorageFS; + +typedef struct { + BonoboObjectClass parent_class; + + POA_Bonobo_Storage__epv epv; +} BonoboStorageFSClass; + +GType bonobo_storage_fs_get_type (void); +BonoboStorageFS *bonobo_storage_fs_open (const char *path, + gint flags, + gint mode, + CORBA_Environment *ev); + +G_END_DECLS + +#endif /* _BONOBO_STORAGE_FS_H_ */ diff --git a/monikers/bonobo-storage-vfs.c b/monikers/bonobo-storage-vfs.c new file mode 100644 index 0000000..2f01046 --- /dev/null +++ b/monikers/bonobo-storage-vfs.c @@ -0,0 +1,348 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * gnome-storage-vfs.c: Gnome VFS based storage implementation + * + * Author: + * Michael Meeks + */ +#include +#include "bonobo-storage-vfs.h" + +#include "bonobo-stream-vfs.h" +#include +#include +#include +#include +#include +#include + +static BonoboObjectClass *bonobo_storage_vfs_parent_class; + +static char * +concat_dir_and_file (const char *dir, const char *file) +{ + g_return_val_if_fail (dir != NULL, NULL); + g_return_val_if_fail (file != NULL, NULL); + + /* If the directory name doesn't have a / on the end, we need + to add one so we get a proper path to the file */ + if (dir[0] != '\0' && dir [strlen(dir) - 1] != '/') + return g_strconcat (dir, "/", file, NULL); + else + return g_strconcat (dir, file, NULL); +} + +static Bonobo_StorageInfo* +vfs_get_info (PortableServer_Servant storage, + const CORBA_char *path, + const Bonobo_StorageInfoFields mask, + CORBA_Environment *ev) +{ + g_warning ("FIXME: get_info not yet implemented"); + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_NotSupported, + NULL); + + return CORBA_OBJECT_NIL; +} + +static void +vfs_set_info (PortableServer_Servant storage, + const CORBA_char *path, + const Bonobo_StorageInfo *info, + const Bonobo_StorageInfoFields mask, + CORBA_Environment *ev) +{ + g_warning ("FIXME: set_info not yet implemented"); + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_NotSupported, + NULL); +} + +static Bonobo_Stream +vfs_open_stream (PortableServer_Servant storage, + const CORBA_char *path, + Bonobo_Storage_OpenMode mode, + CORBA_Environment *ev) +{ + BonoboStorageVfs *storage_vfs = BONOBO_STORAGE_VFS ( + bonobo_object (storage)); + BonoboStreamVfs *stream; + char *full; + + full = concat_dir_and_file (storage_vfs->path, path); + stream = bonobo_stream_vfs_open (full, mode, ev); + g_free (full); + if (stream) + return CORBA_Object_duplicate (BONOBO_OBJREF (stream), NULL); + else + return CORBA_OBJECT_NIL; +} + +/* + * Creates the Gtk object and the corba server bound to it + */ +static BonoboStorageVfs * +do_bonobo_storage_vfs_create (const char *path) +{ + BonoboStorageVfs *storage_vfs; + + storage_vfs = g_object_new (bonobo_storage_vfs_get_type (), NULL); + storage_vfs->path = g_strdup (path); + + return storage_vfs; +} + +static void +vfs_rename (PortableServer_Servant storage, + const CORBA_char *path, + const CORBA_char *new_path, + CORBA_Environment *ev) +{ + g_warning ("Not yet implemented"); + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Stream_IOError, NULL); +} + +static void +vfs_commit (PortableServer_Servant storage, + CORBA_Environment *ev) +{ + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Stream_NotSupported, NULL); +} + +static void +vfs_revert (PortableServer_Servant storage, + CORBA_Environment *ev) +{ + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Stream_NotSupported, NULL); +} + +static Bonobo_Storage_DirectoryList * +vfs_list_contents (PortableServer_Servant storage, + const CORBA_char *path, + Bonobo_StorageInfoFields mask, + CORBA_Environment *ev) +{ + BonoboStorageVfs *storage_vfs; + Bonobo_Storage_DirectoryList *list = NULL; + GnomeVFSResult result; + GList *dir_list, *info; + char *uri; + int len, i; + + storage_vfs = BONOBO_STORAGE_VFS (storage); + + uri = concat_dir_and_file (storage_vfs->path, path); + + result = gnome_vfs_directory_list_load ( + &dir_list, uri, + (mask & Bonobo_FIELD_CONTENT_TYPE) ? + GNOME_VFS_FILE_INFO_GET_MIME_TYPE : + GNOME_VFS_FILE_INFO_DEFAULT); + + if (result != GNOME_VFS_OK) { + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_NotFound, NULL); + g_free (uri); + return NULL; + } + + len = g_list_length (dir_list); + list = Bonobo_Storage_DirectoryList__alloc (); + list->_buffer = CORBA_sequence_Bonobo_StorageInfo_allocbuf (len); + list->_length = len; + CORBA_sequence_set_release (list, TRUE); + + i = 0; + for (info = dir_list; info; info = info->next) { + bonobo_stream_vfs_storageinfo_from_file_info ( + &list->_buffer [i++], info->data); + gnome_vfs_file_info_unref (info->data); + } + + g_list_free (dir_list); + g_free (uri); + + return list; +} + +/** + * bonobo_storage_vfs_open: + * @path: path to existing directory that represents the storage + * @mode: open mode. + * + * Returns a BonoboStorage object that represents the storage at @path + */ +BonoboStorageVfs * +bonobo_storage_vfs_open (const char *path, + Bonobo_Storage_OpenMode mode, + CORBA_Environment *ev) +{ + GnomeVFSResult result; + GnomeVFSFileInfo *info; + gboolean create = FALSE; + + g_return_val_if_fail (path != NULL, NULL); + + info = gnome_vfs_file_info_new (); + result = gnome_vfs_get_file_info ( + path, info, GNOME_VFS_FILE_INFO_DEFAULT); + + if (result == GNOME_VFS_ERROR_NOT_FOUND && + (mode & Bonobo_Storage_CREATE)) + create = TRUE; + + else if (mode & Bonobo_Storage_READ) { + if (result != GNOME_VFS_OK) { + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Stream_NoPermission, NULL); + return NULL; + } + + if ((info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_TYPE) && + (info->type != GNOME_VFS_FILE_TYPE_DIRECTORY)) { + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Stream_IOError, NULL); + return NULL; + } + + } else if (mode & (Bonobo_Storage_WRITE)) { + if (result == GNOME_VFS_ERROR_NOT_FOUND) + create = TRUE; + else + if ((info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_TYPE) && + (info->type != GNOME_VFS_FILE_TYPE_DIRECTORY)) { + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Stream_IOError, NULL); + return NULL; + } + } + gnome_vfs_file_info_unref (info); + + if (create) { + result = gnome_vfs_make_directory ( + path, GNOME_VFS_PERM_USER_ALL | + GNOME_VFS_PERM_GROUP_ALL); + + if (result != GNOME_VFS_OK) { + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Stream_NoPermission, NULL); + return NULL; + } + } + + return do_bonobo_storage_vfs_create (path); +} + +static Bonobo_Storage +vfs_open_storage (PortableServer_Servant storage, + const CORBA_char *path, + Bonobo_Storage_OpenMode mode, + CORBA_Environment *ev) +{ + BonoboStorageVfs *storage_vfs = BONOBO_STORAGE_VFS ( + bonobo_object (storage)); + BonoboStorageVfs *new_storage; + GnomeVFSResult result; + char *full; + + full = concat_dir_and_file (storage_vfs->path, path); + + result = gnome_vfs_make_directory (full, GNOME_VFS_PERM_USER_ALL); + if (result == GNOME_VFS_OK || + result == GNOME_VFS_ERROR_FILE_EXISTS) + new_storage = do_bonobo_storage_vfs_create (full); + else { + new_storage = NULL; + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_NoPermission, NULL); + } + + g_free (full); + + if (new_storage) + return CORBA_Object_duplicate (BONOBO_OBJREF (new_storage), NULL); + else + return CORBA_OBJECT_NIL; +} + +static void +vfs_erase (PortableServer_Servant storage, + const CORBA_char *path, + CORBA_Environment *ev) +{ + BonoboStorageVfs *storage_vfs = BONOBO_STORAGE_VFS ( + bonobo_object (storage)); + GnomeVFSResult result; + char *full; + + full = concat_dir_and_file (storage_vfs->path, path); + + result = gnome_vfs_unlink (full); + g_free (full); + + if (result != GNOME_VFS_OK) + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_NoPermission, + NULL); +} + +static void +vfs_copy_to (PortableServer_Servant storage, + Bonobo_Storage dest, + CORBA_Environment *ev) +{ + BonoboStorageVfs *storage_vfs = BONOBO_STORAGE_VFS ( + bonobo_object (storage)); + + bonobo_storage_copy_to ( + BONOBO_OBJREF (storage_vfs), dest, ev); +} + +static void +bonobo_storage_vfs_finalize (GObject *object) +{ + BonoboStorageVfs *storage_vfs = BONOBO_STORAGE_VFS (object); + + g_free (storage_vfs->path); + storage_vfs->path = NULL; + + G_OBJECT_CLASS (bonobo_storage_vfs_parent_class)->finalize (object); +} + +static void +bonobo_storage_vfs_class_init (BonoboStorageVfsClass *klass) +{ + GObjectClass *object_class = (GObjectClass *) klass; + POA_Bonobo_Storage__epv *epv = &klass->epv; + + bonobo_storage_vfs_parent_class = + g_type_class_peek_parent (klass); + + epv->getInfo = vfs_get_info; + epv->setInfo = vfs_set_info; + epv->openStream = vfs_open_stream; + epv->openStorage = vfs_open_storage; + epv->copyTo = vfs_copy_to; + epv->rename = vfs_rename; + epv->commit = vfs_commit; + epv->revert = vfs_revert; + epv->listContents = vfs_list_contents; + epv->erase = vfs_erase; + + object_class->finalize = bonobo_storage_vfs_finalize; +} + +static void +bonobo_storage_vfs_init (GObject *object) +{ + /* nothing to do */ +} + +BONOBO_TYPE_FUNC_FULL (BonoboStorageVfs, + Bonobo_Storage, + bonobo_object_get_type (), + bonobo_storage_vfs); diff --git a/monikers/bonobo-storage-vfs.h b/monikers/bonobo-storage-vfs.h new file mode 100644 index 0000000..36bf3d7 --- /dev/null +++ b/monikers/bonobo-storage-vfs.h @@ -0,0 +1,33 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +#ifndef _BONOBO_STORAGE_VFS_H_ +#define _BONOBO_STORAGE_VFS_H_ + +#include + +G_BEGIN_DECLS + +#define BONOBO_STORAGE_VFS_TYPE (bonobo_storage_vfs_get_type ()) +#define BONOBO_STORAGE_VFS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), BONOBO_STORAGE_VFS_TYPE, BonoboStorageVfs)) +#define BONOBO_STORAGE_VFS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), BONOBO_STORAGE_VFS_TYPE, BonoboStorageVfsClass)) +#define BONOBO_IS_STORAGE_VFS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), BONOBO_STORAGE_VFS_TYPE)) +#define BONOBO_IS_STORAGE_VFS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), BONOBO_STORAGE_VFS_TYPE)) + +typedef struct { + BonoboObject parent; + char *path; +} BonoboStorageVfs; + +typedef struct { + BonoboObjectClass parent_class; + + POA_Bonobo_Storage__epv epv; +} BonoboStorageVfsClass; + +GType bonobo_storage_vfs_get_type (void); +BonoboStorageVfs *bonobo_storage_vfs_open (const char *path, + Bonobo_Storage_OpenMode mode, + CORBA_Environment *ev); + +G_END_DECLS + +#endif /* _BONOBO_STORAGE_VFS_H_ */ diff --git a/monikers/bonobo-stream-fs.c b/monikers/bonobo-stream-fs.c new file mode 100644 index 0000000..d8aed37 --- /dev/null +++ b/monikers/bonobo-stream-fs.c @@ -0,0 +1,417 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/** + * bonobo-stream-fs.c: Sample file-system based Stream implementation + * + * This is just a sample file-system based Stream implementation. + * it is only used for debugging purposes + * + * Authors: + * Miguel de Icaza (miguel@gnu.org) + * Michael Meeks (michael@ximian.com) + * + * Copyright 2001, Ximian, Inc + */ +#include +#include "bonobo-stream-fs.h" +#include +#include +#include +#include +#include +#include + +struct _BonoboStreamFSPrivate { + gchar *mime_type; +}; + +static BonoboObjectClass *bonobo_stream_fs_parent_class; + +static gint +bonobo_mode_to_fs (Bonobo_Storage_OpenMode mode) +{ + gint fs_mode = 0; + + if (mode & Bonobo_Storage_READ) + fs_mode |= O_RDONLY; + if (mode & Bonobo_Storage_WRITE) + fs_mode |= O_RDWR; + if (mode & Bonobo_Storage_CREATE) + fs_mode |= O_CREAT | O_RDWR; + if (mode & Bonobo_Storage_FAILIFEXIST) + fs_mode |= O_EXCL; + + return fs_mode; +} + +static Bonobo_StorageInfo* +fs_get_info (PortableServer_Servant stream, + const Bonobo_StorageInfoFields mask, + CORBA_Environment *ev) +{ + BonoboStreamFS *stream_fs = BONOBO_STREAM_FS ( + bonobo_object (stream)); + Bonobo_StorageInfo *si; + struct stat st; + + if (mask & ~(Bonobo_FIELD_CONTENT_TYPE | Bonobo_FIELD_SIZE | + Bonobo_FIELD_TYPE)) { + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_NotSupported, NULL); + return CORBA_OBJECT_NIL; + } + + if (fstat (stream_fs->fd, &st) == -1) + goto get_info_except; + + si = Bonobo_StorageInfo__alloc (); + + si->size = st.st_size; + si->type = Bonobo_STORAGE_TYPE_REGULAR; + si->name = CORBA_string_dup (""); + si->content_type = CORBA_string_dup (stream_fs->priv->mime_type); + + return si; + + get_info_except: + + if (errno == EACCES) + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Stream_NoPermission, NULL); + else + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Stream_IOError, NULL); + + + return CORBA_OBJECT_NIL; +} + +static void +fs_set_info (PortableServer_Servant stream, + const Bonobo_StorageInfo *info, + const Bonobo_StorageInfoFields mask, + CORBA_Environment *ev) +{ + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Stream_NotSupported, NULL); +} + +static void +fs_write (PortableServer_Servant stream, + const Bonobo_Stream_iobuf *buffer, + CORBA_Environment *ev) +{ + BonoboStreamFS *stream_fs = BONOBO_STREAM_FS ( + bonobo_object (stream)); + + errno = EINTR; + while ((write (stream_fs->fd, buffer->_buffer, buffer->_length) == -1) + && (errno == EINTR)); + + if (errno == EINTR) return; + + if ((errno == EBADF) || (errno == EINVAL)) + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Stream_NoPermission, NULL); + else + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Stream_IOError, NULL); +} + +static void +fs_read (PortableServer_Servant stream, + CORBA_long count, + Bonobo_Stream_iobuf **buffer, + CORBA_Environment *ev) +{ + BonoboStreamFS *stream_fs = BONOBO_STREAM_FS ( + bonobo_object (stream)); + CORBA_octet *data; + int bytes_read; + + if (count < 0) { + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Stream_IOError, NULL); + return; + } + + *buffer = Bonobo_Stream_iobuf__alloc (); + CORBA_sequence_set_release (*buffer, TRUE); + data = CORBA_sequence_CORBA_octet_allocbuf (count); + (*buffer)->_buffer = data; + (*buffer)->_length = 0; + + do { + bytes_read = read (stream_fs->fd, data, count); + } while ((bytes_read == -1) && (errno == EINTR)); + + + if (bytes_read == -1) { + CORBA_free (*buffer); + *buffer = NULL; + + if (errno == EACCES) + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Stream_NoPermission, + NULL); + else + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Stream_IOError, NULL); + } else + (*buffer)->_length = bytes_read; +} + +static CORBA_long +fs_seek (PortableServer_Servant stream, + CORBA_long offset, + Bonobo_Stream_SeekType whence, + CORBA_Environment *ev) +{ + BonoboStreamFS *stream_fs = BONOBO_STREAM_FS ( + bonobo_object (stream)); + int fs_whence; + CORBA_long pos; + + if (whence == Bonobo_Stream_SeekCur) + fs_whence = SEEK_CUR; + else if (whence == Bonobo_Stream_SeekEnd) + fs_whence = SEEK_END; + else + fs_whence = SEEK_SET; + + if ((pos = lseek (stream_fs->fd, offset, fs_whence)) == -1) { + + if (errno == ESPIPE) + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Stream_NotSupported, + NULL); + else + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Stream_IOError, NULL); + return 0; + } + + return pos; +} + +static void +fs_truncate (PortableServer_Servant stream, + const CORBA_long new_size, + CORBA_Environment *ev) +{ + BonoboStreamFS *stream_fs = BONOBO_STREAM_FS ( + bonobo_object (stream)); + + if (ftruncate (stream_fs->fd, new_size) == 0) + return; + + if (errno == EACCES) + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Stream_NoPermission, NULL); + else + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Stream_IOError, NULL); +} + +static void +fs_commit (PortableServer_Servant stream, + CORBA_Environment *ev) +{ + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Stream_NotSupported, NULL); +} + +static void +fs_revert (PortableServer_Servant stream, + CORBA_Environment *ev) +{ + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Stream_NotSupported, NULL); +} + +static void +fs_destroy (BonoboObject *object) +{ + BonoboStreamFS *stream_fs = BONOBO_STREAM_FS (object); + + if (stream_fs->fd >= 0 && + close (stream_fs->fd)) + g_warning ("Close failed"); + stream_fs->fd = -1; + + if (stream_fs->path) + g_free (stream_fs->path); + stream_fs->path = NULL; + + if (stream_fs->priv->mime_type) + g_free (stream_fs->priv->mime_type); + stream_fs->priv->mime_type = NULL; + + bonobo_stream_fs_parent_class->destroy (object); +} + +static void +fs_finalize (GObject *object) +{ + BonoboStreamFS *stream_fs = BONOBO_STREAM_FS (object); + + if (stream_fs->priv) + g_free (stream_fs->priv); + stream_fs->priv = NULL; + + bonobo_stream_fs_parent_class->parent_class.finalize (object); +} + +static void +bonobo_stream_fs_class_init (BonoboStreamFSClass *klass) +{ + GObjectClass *oclass = (GObjectClass *) klass; + POA_Bonobo_Stream__epv *epv = &klass->epv; + + bonobo_stream_fs_parent_class = + g_type_class_peek_parent (klass); + + epv->getInfo = fs_get_info; + epv->setInfo = fs_set_info; + epv->write = fs_write; + epv->read = fs_read; + epv->seek = fs_seek; + epv->truncate = fs_truncate; + epv->commit = fs_commit; + epv->revert = fs_revert; + + oclass->finalize = fs_finalize; + ((BonoboObjectClass *)oclass)->destroy = fs_destroy; +} + +static void +bonobo_stream_fs_init (BonoboStreamFS *stream_fs) +{ + stream_fs->priv = g_new0 (BonoboStreamFSPrivate,1); + stream_fs->priv->mime_type = NULL; +} + +/** + * bonobo_stream_fs_get_type: + * + * Returns the GType for the BonoboStreamFS class. + */ +GType +bonobo_stream_fs_get_type (void) +{ + static GType type = 0; + + if (!type) { + GTypeInfo info = { + sizeof (BonoboStreamFSClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) bonobo_stream_fs_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (BonoboStreamFS), + 0, /* n_preallocs */ + (GInstanceInitFunc) bonobo_stream_fs_init + }; + + type = bonobo_type_unique ( + BONOBO_OBJECT_TYPE, + POA_Bonobo_Stream__init, NULL, + G_STRUCT_OFFSET (BonoboStreamFSClass, epv), + &info, "BonoboStreamFS"); + } + + return type; +} + +static BonoboStreamFS * +bonobo_stream_create (int fd, const char *path) +{ + BonoboStreamFS *stream_fs; + + if (!(stream_fs = g_object_new (bonobo_stream_fs_get_type (), NULL))) + return NULL; + + stream_fs->fd = fd; + stream_fs->priv->mime_type = g_strdup + (gnome_vfs_get_file_mime_type (path, NULL, FALSE)); + + return stream_fs; +} + + +/** + * bonobo_stream_fs_open: + * @path: The path to the file to be opened. + * @flags: The flags with which the file should be opened. + * + * Creates a new BonoboStream object for the filename specified by + * @path. + */ +BonoboStreamFS * +bonobo_stream_fs_open (const char *path, gint flags, gint mode, + CORBA_Environment *ev) +{ + BonoboStreamFS *stream; + struct stat st; + int v, fd; + gint fs_flags; + + if (!path || !ev) { + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_IOError, NULL); + return NULL; + } + + if (((v = stat (path, &st)) == -1) && + !(flags & Bonobo_Storage_CREATE)) { + + if ((errno == ENOENT) || (errno == ENOTDIR)) + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_NotFound, + NULL); + else if (errno == EACCES) + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_NoPermission, + NULL); + else + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_IOError, NULL); + return NULL; + } + + if ((v != -1) && S_ISDIR(st.st_mode)) { + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_NotStream, + NULL); + return NULL; + } + + + fs_flags = bonobo_mode_to_fs (flags); + + if ((fd = open (path, fs_flags, mode)) == -1) { + + if ((errno == ENOENT) || (errno == ENOTDIR)) + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_NotFound, + NULL); + else if (errno == EACCES) + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_NoPermission, + NULL); + else if (errno == EEXIST) + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_NameExists, + NULL); + else + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_IOError, NULL); + return NULL; + } + + if (!(stream = bonobo_stream_create (fd, path))) + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_IOError, NULL); + + return stream; +} diff --git a/monikers/bonobo-stream-fs.h b/monikers/bonobo-stream-fs.h new file mode 100644 index 0000000..6fef111 --- /dev/null +++ b/monikers/bonobo-stream-fs.h @@ -0,0 +1,48 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/** + * bonobo-stream-fs.c: Sample file-system based Stream implementation + * + * This is just a sample file-system based Stream implementation. + * it is only used for debugging purposes + * + * Author: + * Miguel de Icaza (miguel@gnu.org) + */ +#ifndef _BONOBO_STREAM_FS_H_ +#define _BONOBO_STREAM_FS_H_ + +#include + +G_BEGIN_DECLS + +#define BONOBO_STREAM_FS_TYPE (bonobo_stream_fs_get_type ()) +#define BONOBO_STREAM_FS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), BONOBO_STREAM_FS_TYPE, BonoboStreamFS)) +#define BONOBO_STREAM_FS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), BONOBO_STREAM_FS_TYPE, BonoboStreamFSClass)) +#define BONOBO_IS_STREAM_FS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), BONOBO_STREAM_FS_TYPE)) +#define BONOBO_IS_STREAM_FS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), BONOBO_STREAM_FS_TYPE)) + +typedef struct _BonoboStreamFS BonoboStreamFS; +typedef struct _BonoboStreamFSPrivate BonoboStreamFSPrivate; + +struct _BonoboStreamFS { + BonoboObject stream; + int fd; + char *path; + + BonoboStreamFSPrivate *priv; +}; + +typedef struct { + BonoboObjectClass parent_class; + + POA_Bonobo_Stream__epv epv; +} BonoboStreamFSClass; + +GType bonobo_stream_fs_get_type (void); +BonoboStreamFS *bonobo_stream_fs_open (const char *path, + gint flags, gint mode, + CORBA_Environment *ev); + +G_END_DECLS + +#endif /* _BONOBO_STREAM_FS_H_ */ diff --git a/monikers/bonobo-stream-vfs.c b/monikers/bonobo-stream-vfs.c new file mode 100644 index 0000000..6768c49 --- /dev/null +++ b/monikers/bonobo-stream-vfs.c @@ -0,0 +1,356 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/** + * gnome-stream-vfs.c: Gnome VFS based stream implementation + * + * Author: + * Michael Meeks + * + * Copyright 2001, Ximian, Inc. + */ + +#include +#include "bonobo-stream-vfs.h" + +#include +#include +#include +#include +#include + +static BonoboObjectClass *bonobo_stream_vfs_parent_class; + +void +bonobo_stream_vfs_storageinfo_from_file_info (Bonobo_StorageInfo *si, + GnomeVFSFileInfo *fi) +{ + g_return_if_fail (si != NULL); + g_return_if_fail (fi != NULL); + + si->name = CORBA_string_dup (fi->name); + + if (fi->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) + si->size = fi->size; + else + si->size = 0; + + if (fi->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_TYPE && + fi->type == GNOME_VFS_FILE_TYPE_DIRECTORY) + si->type = Bonobo_STORAGE_TYPE_DIRECTORY; + else + si->type = Bonobo_STORAGE_TYPE_REGULAR; + + if (fi->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE && + fi->mime_type) + si->content_type = CORBA_string_dup (fi->mime_type); + else + si->content_type = CORBA_string_dup (""); +} + +static Bonobo_StorageInfo * +vfs_get_info (PortableServer_Servant stream, + const Bonobo_StorageInfoFields mask, + CORBA_Environment *ev) +{ + BonoboStreamVfs *sfs = BONOBO_STREAM_VFS ( + bonobo_object (stream)); + Bonobo_StorageInfo *si; + GnomeVFSFileInfo *fi; + GnomeVFSResult result; + + if (mask & ~(Bonobo_FIELD_CONTENT_TYPE | Bonobo_FIELD_SIZE | + Bonobo_FIELD_TYPE)) { + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Storage_NotSupported, NULL); + return CORBA_OBJECT_NIL; + } + + fi = gnome_vfs_file_info_new (); + result = gnome_vfs_get_file_info_from_handle ( + sfs->handle, fi, + (mask & Bonobo_FIELD_CONTENT_TYPE) ? + GNOME_VFS_FILE_INFO_GET_MIME_TYPE : + GNOME_VFS_FILE_INFO_DEFAULT); + + if (result != GNOME_VFS_OK) { + if (result == GNOME_VFS_ERROR_ACCESS_DENIED) + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Stream_NoPermission, NULL); + else + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Stream_IOError, NULL); + return NULL; + } + + si = Bonobo_StorageInfo__alloc (); + + bonobo_stream_vfs_storageinfo_from_file_info (si, fi); + + gnome_vfs_file_info_unref (fi); + + return si; +} + +static void +vfs_set_info (PortableServer_Servant stream, + const Bonobo_StorageInfo *info, + const Bonobo_StorageInfoFields mask, + CORBA_Environment *ev) +{ + g_warning ("FIXME: set_info: a curious and not yet implemented API"); + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Stream_NotSupported, NULL); +} + +static void +vfs_write (PortableServer_Servant stream, + const Bonobo_Stream_iobuf *buffer, + CORBA_Environment *ev) +{ + BonoboStreamVfs *sfs = BONOBO_STREAM_VFS ( + bonobo_object (stream)); + GnomeVFSResult result; + GnomeVFSFileSize bytes_written; + + do { + result = gnome_vfs_write (sfs->handle, buffer->_buffer, + buffer->_length, &bytes_written); + } while (bytes_written < 1 && result == GNOME_VFS_ERROR_INTERRUPTED); + + if (result != GNOME_VFS_OK) + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Stream_IOError, NULL); +} + +static void +vfs_read (PortableServer_Servant stream, + CORBA_long count, + Bonobo_Stream_iobuf **buffer, + CORBA_Environment *ev) +{ + BonoboStreamVfs *sfs = BONOBO_STREAM_VFS ( + bonobo_object (stream)); + GnomeVFSResult result; + GnomeVFSFileSize bytes_read; + CORBA_octet *data; + + *buffer = Bonobo_Stream_iobuf__alloc (); + CORBA_sequence_set_release (*buffer, TRUE); + + data = CORBA_sequence_CORBA_octet_allocbuf (count); + + do { + result = gnome_vfs_read (sfs->handle, data, + count, &bytes_read); + } while (bytes_read < 1 && result == GNOME_VFS_ERROR_INTERRUPTED); + + if (result == GNOME_VFS_ERROR_EOF) { + (*buffer)->_length = 0; + (*buffer)->_buffer = NULL; + CORBA_free (data); + } else if (result != GNOME_VFS_OK) { + CORBA_free (data); + CORBA_free (*buffer); + *buffer = NULL; + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Stream_IOError, NULL); + } else { + (*buffer)->_buffer = data; + (*buffer)->_length = bytes_read; + } +} + +static CORBA_long +vfs_seek (PortableServer_Servant stream, + CORBA_long offset, + Bonobo_Stream_SeekType whence, + CORBA_Environment *ev) +{ + BonoboStreamVfs *sfs = BONOBO_STREAM_VFS ( + bonobo_object (stream)); + GnomeVFSSeekPosition pos; + GnomeVFSResult result; + GnomeVFSFileOffset where; + + switch (whence) { + case Bonobo_Stream_SeekCur: + pos = GNOME_VFS_SEEK_CURRENT; + break; + case Bonobo_Stream_SeekEnd: + pos = GNOME_VFS_SEEK_END; + break; + case Bonobo_Stream_SeekSet: + pos = GNOME_VFS_SEEK_START; + break; + default: + g_warning ("Seek whence %d unknown; fall back to SEEK_SET", + whence); + pos = GNOME_VFS_SEEK_START; + break; + } + + result = gnome_vfs_seek (sfs->handle, pos, offset); + + if (result != GNOME_VFS_OK) { + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Stream_IOError, NULL); + return -1; + } + + result = gnome_vfs_tell (sfs->handle, &where); + + if (result != GNOME_VFS_OK) { + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Stream_IOError, NULL); + return -1; + } + + return where; +} + +static void +vfs_truncate (PortableServer_Servant stream, + const CORBA_long new_size, + CORBA_Environment *ev) +{ + BonoboStreamVfs *sfs = BONOBO_STREAM_VFS ( + bonobo_object (stream)); + GnomeVFSResult result; + + result = gnome_vfs_truncate_handle (sfs->handle, new_size); + if (result == GNOME_VFS_OK) + return; + + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Stream_NoPermission, NULL); +} + +static void +vfs_commit (PortableServer_Servant stream, + CORBA_Environment *ev) +{ + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Stream_NotSupported, NULL); +} + +static void +vfs_revert (PortableServer_Servant stream, + CORBA_Environment *ev) +{ + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_Bonobo_Stream_NotSupported, NULL); +} + +static void +vfs_destroy (BonoboObject *object) +{ + BonoboStreamVfs *sfs = BONOBO_STREAM_VFS (object); + + if (sfs->handle) + if (gnome_vfs_close (sfs->handle) != GNOME_VFS_OK) + g_warning ("VFS Close failed"); + + sfs->handle = NULL; + + bonobo_stream_vfs_parent_class->destroy (object); +} + +static void +bonobo_stream_vfs_class_init (BonoboStreamVfsClass *klass) +{ + POA_Bonobo_Stream__epv *epv = &klass->epv; + + bonobo_stream_vfs_parent_class = + g_type_class_peek_parent (klass); + + epv->getInfo = vfs_get_info; + epv->setInfo = vfs_set_info; + epv->write = vfs_write; + epv->read = vfs_read; + epv->seek = vfs_seek; + epv->truncate = vfs_truncate; + epv->commit = vfs_commit; + epv->revert = vfs_revert; + + ((BonoboObjectClass *)klass)->destroy = vfs_destroy; +} + +/** + * bonobo_stream_vfs_get_type: + * + * Returns the GtkType for the BonoboStreamVfs class. + */ +GType +bonobo_stream_vfs_get_type (void) +{ + static GType type = 0; + + if (!type) { + GTypeInfo info = { + sizeof (BonoboStreamVfsClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) bonobo_stream_vfs_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (BonoboStreamVfs), + 0, /* n_preallocs */ + (GInstanceInitFunc) NULL + }; + + type = bonobo_type_unique ( + BONOBO_OBJECT_TYPE, + POA_Bonobo_Stream__init, NULL, + G_STRUCT_OFFSET (BonoboStreamVfsClass, epv), + &info, "BonoboStreamVFS"); + } + + return type; +} + +/** + * bonobo_stream_vfs_open: + * @path: The path to the file to be opened. + * @mode: The mode with which the file should be opened. + * + * Creates a new BonoboStream object for the filename specified by + * @path. + */ +BonoboStreamVfs * +bonobo_stream_vfs_open (const char *path, Bonobo_Storage_OpenMode mode, + CORBA_Environment *ev) +{ + GnomeVFSResult result; + GnomeVFSHandle *handle; + GnomeVFSOpenMode vfs_mode = GNOME_VFS_OPEN_NONE; + BonoboStreamVfs *stream_vfs; + + g_return_val_if_fail (path != NULL, NULL); + + if (mode == Bonobo_Storage_READ) + vfs_mode |= GNOME_VFS_OPEN_READ; + + else if (mode == Bonobo_Storage_WRITE) + vfs_mode |= GNOME_VFS_OPEN_WRITE; + + else { + g_warning ("Unhandled open mode %d", mode); + return NULL; + } + + result = gnome_vfs_open (&handle, path, vfs_mode); + if (vfs_mode & GNOME_VFS_OPEN_WRITE && + result == GNOME_VFS_ERROR_NOT_FOUND) + result = gnome_vfs_create (&handle, path, vfs_mode, + FALSE, S_IRUSR | S_IWUSR); + + if (result != GNOME_VFS_OK) + return NULL; + + stream_vfs = g_object_new (bonobo_stream_vfs_get_type (), NULL); + if (!stream_vfs) + return NULL; + + stream_vfs->handle = handle; + + return stream_vfs; +} diff --git a/monikers/bonobo-stream-vfs.h b/monikers/bonobo-stream-vfs.h new file mode 100644 index 0000000..87cc19e --- /dev/null +++ b/monikers/bonobo-stream-vfs.h @@ -0,0 +1,45 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ + +#ifndef BONOBO_STREAM_VFS_H +#define BONOBO_STREAM_VFS_H + +#include +#include +#include + +G_BEGIN_DECLS + +typedef struct _BonoboStreamVfs BonoboStreamVfs; + + +#define BONOBO_STREAM_VFS_TYPE (bonobo_stream_vfs_get_type ()) +#define BONOBO_STREAM_VFS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), BONOBO_STREAM_VFS_TYPE, BonoboStreamVfs)) +#define BONOBO_STREAM_VFS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), BONOBO_STREAM_VFS_TYPE, BonoboStreamVfsClass)) +#define BONOBO_IS_STREAM_VFS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), BONOBO_STREAM_VFS_TYPE)) +#define BONOBO_IS_STREAM_VFS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), BONOBO_STREAM_VFS_TYPE)) + +typedef struct _BonoboStreamVfsPrivate BonoboStreamVfsPrivate; + +struct _BonoboStreamVfs { + BonoboObject parent; + GnomeVFSHandle *handle; + + BonoboStreamVfsPrivate *priv; +}; + +typedef struct { + BonoboObjectClass parent_class; + + POA_Bonobo_Stream__epv epv; +} BonoboStreamVfsClass; + +GType bonobo_stream_vfs_get_type (void); +BonoboStreamVfs *bonobo_stream_vfs_open (const char *path, + Bonobo_Storage_OpenMode flags, + CORBA_Environment *ev); +void bonobo_stream_vfs_storageinfo_from_file_info (Bonobo_StorageInfo *si, + GnomeVFSFileInfo *fi); + +G_END_DECLS + +#endif /* BONOBO_STREAM_VFS_H */ diff --git a/monikers/gnome-moniker-std.c b/monikers/gnome-moniker-std.c new file mode 100644 index 0000000..9eff56c --- /dev/null +++ b/monikers/gnome-moniker-std.c @@ -0,0 +1,41 @@ +#include "config.h" +#include + +#include +#include "gnome-moniker-std.h" + +static BonoboObject * +bonobo_std_moniker_factory (BonoboGenericFactory *this, + const char *object_id, + void *data) +{ + g_return_val_if_fail (object_id != NULL, NULL); + + if (!strcmp (object_id, "OAFIID:GNOME_VFS_Moniker_File")) + + return BONOBO_OBJECT (bonobo_moniker_simple_new ( + "file:", bonobo_moniker_file_resolve)); + + else if (!strcmp (object_id, "OAFIID:GNOME_VFS_Moniker_VFS")) + + return BONOBO_OBJECT (bonobo_moniker_simple_new ( + "vfs:", bonobo_moniker_vfs_resolve)); + + else if (!strcmp (object_id, "OAFIID:GNOME_VFS_MonikerExtender_file")) + + return BONOBO_OBJECT (bonobo_moniker_extender_new ( + bonobo_file_extender_resolve, NULL)); + + else + g_warning ("Failing to manufacture a '%s'", object_id); + + return NULL; +} + + +BONOBO_OAF_SHLIB_FACTORY_MULTI ("OAFIID:GNOME_VFS_Moniker_std_Factory", + "bonobo standard moniker", + bonobo_std_moniker_factory, + NULL); + + diff --git a/monikers/gnome-moniker-std.h b/monikers/gnome-moniker-std.h new file mode 100644 index 0000000..23fd66f --- /dev/null +++ b/monikers/gnome-moniker-std.h @@ -0,0 +1,24 @@ +#ifndef _GNOME_MONIKER_STD_H_ +#define _GNOME_MONIKER_STD_H_ + +#include +#include + +Bonobo_Unknown bonobo_moniker_file_resolve (BonoboMoniker *moniker, + const Bonobo_ResolveOptions *options, + const CORBA_char *requested_interface, + CORBA_Environment *ev); + +Bonobo_Unknown bonobo_moniker_vfs_resolve (BonoboMoniker *moniker, + const Bonobo_ResolveOptions *options, + const CORBA_char *requested_interface, + CORBA_Environment *ev); + +Bonobo_Unknown bonobo_file_extender_resolve (BonoboMonikerExtender *extender, + const Bonobo_Moniker m, + const Bonobo_ResolveOptions *options, + const CORBA_char *display_name, + const CORBA_char *requested_interface, + CORBA_Environment *ev); + +#endif /* _GNOME_MONIKER_STD_H_ */ diff --git a/po/ChangeLog b/po/ChangeLog new file mode 100644 index 0000000..588382d --- /dev/null +++ b/po/ChangeLog @@ -0,0 +1,1953 @@ +2003-08-25 Guntupalli Karunakar + + * hi.po: Updated Hindi translation. + +2003-08-25 Takeshi AIHANA + + * ja.po: Updated Japanese translation. + +2003-08-24 Wang Jian + + * zh_CN.po: Updated Simplified Chinese translation by + Funda Wang . + +2003-08-23 Metin Amiroff + + * az.po: Updated Azerbaijani translation. + +2003-08-22 Stanislav Visnovsky + + * sk.po: Updated Slovak translation. + +2003-08-22 Changwoo Ryu + + * ko.po: Updated Korean translation. + +2003-08-21 Ole Laursen + + * da.po: Updated Danish translation. + +2003-08-21 Sanlig Badral + + * mn.po: Updated Mongolian translation. + +2003-08-20 Kjartan Maraas + + * no.po: Update Norwegian translation. + +2003-08-18 Metin Amiroff + + * az.po: Updated Azerbaijani translation. + +2003-08-15 Duarte Loreto + + * pt.po: Updated Portuguese translation. + +2003-08-14 Miloslav Trmac + + * cs.po: Updated Czech translation. + +2003-08-14 Dafydd Harries + + * cy.po: Updated Welsh translation. + +2003-08-14 Danilo Šegan + + * be.po: Updated Belarusian translation by Ales Nyakhaychyk + . + +2003-08-14 Artur Flinta + + * pl.po: Updated Polish translation. + +2003-08-14 Danilo Šegan + + * sr.po, sr@Latn.po: Updated Serbian translation. + +2003-08-11 Laurent Dhima + + * sq.po: Updated Albanian translation. + +2003-08-10 Changwoo Ryu + + * ko.po: Updated Korean translation. + +2003-08-09 Gil "Dolfin" Osher + + * he.po: Updated Hebrew translation. + +2003-08-09 Wang Jian + + * zh_CN.po: Updated Simplified Chinese translation by + Funda Wang . + +2003-08-09 Takeshi AIHANA + + * ja.po: Updated Japanese translation. + +2003-08-08 Vincent van Adrighem + + * nl.po: Dutch translation updated. + +2003-08-07 Miloslav Trmac + + * cs.po: Updated Czech translation. + +2003-08-07 Pablo Gonzalo del Campo + + * es.po: Updated Spanish translation by + Francisco Javier F. Serrador . + +2003-08-07 Guntupalli Karunakar + + * hi.po: Updated Hindi translation + +2003-08-07 Dmitry G. Mastrukov + + * be.po: Updated Belarusian translation + from Belarusian team . + +2003-08-05 Ole Laursen + + * da.po: Updated Danish translation. + +2003-08-04 Artur Flinta + + * pl.po: Updated Polish translation. + +2003-08-04 Duarte Loreto + + * pt.po: Updated Portuguese translation. + +=== gnome-vfs 2.3.7 === + +2003-08-04 Dafydd Harries + + * cy.po: Updated Welsh translation. + +2003-08-04 Danilo ? egan + + * sr.po, sr@Latn.po: Updated Serbian translation by Serbian + team (Prevod.org). + +2003-08-04 Christian Rose + + * sv.po: Updated Swedish translation. + +=== gnome-vfs 2.3.6 === + +2003-07-27 Alessio Frusciante + + * it.po: Updated Italian translation. + +2003-07-24 Pablo Saratxaga + + * vi.po: Updated Vietnamese file + +2003-07-22 Danilo ? egan + + * sr.po, sr@Latn.po: Updated Serbian translation by Serbian team + (Prevod.org). + +2003-07-12 Pablo Saratxaga + + * wa.po: Updated Walloon file + +2003-07-10 Joel Brich + + * eo.po: Added Esperanto translation + from Charles Voelger + +2003-07-05 Andras Timar + + * hu.po: Updated Hungarian translation. + +2003-07-03 Alessio Frusciante + + * it.po: Updated Italian translation by + Luca Ferretti . + +2003-07-01 Laurent Dhima + + * sq.po: Updated Albanian translation. + +2003-06-29 Pablo Saratxaga + + * wa.po: Updated Walloon file + +2003-06-27 Artur Flinta + + * pl.po: Updated Polish translation. + +=== gnome-vfs 2.3.5 === + +2003-06-22 Metin Amiroff + + * az.po: Updated Azerbaijani translation. + +2003-06-20 Sam?el J?n Gunnarsson + + * is.po: Updated Icelandic translation + +2003-06-18 Dmitry G. Mastrukov + + * ru.po: Updated Russian translation + from Russian team . + +2003-06-17 Pauli Virtanen + + * fi.po: Updated Finnish translation. + +2003-06-12 Guntupalli Karunakar + + * ml.po: Updated Malayalam translation. + +2003-06-12 Mohammad DAMT + + * id.po: Updated Indonesian translation + +==== gnome-vfs 2.3.4 ==== + +2003-06-05 Mathieu van Woerkom + + * li.po: Added Limburgish translation + +==== gnome-vfs 2.3.3 ==== + +2003-05-30 Vincent van Adrighem + + * nl.po: Dutch translation updated. + +2003-05-28 Gustavo Maciel Dias Vieira + + * pt_BR.po: Updated Brazilian Portuguese translation done by David + Barzilay . + +2003-05-27 Abel Cheung + + * zh_TW.po: Updated traditional Chinese translation. + +2003-05-19 Ole Laursen + + * da.po: Updated Danish translation. + +2003-05-19 Arafat Medini + + * ar.po: Updated Arabic translation + by Arabeyes + +2003-05-19 Telsa Gwymnne + + * cy.po: Updated Welsh translation from + Dafydd Harries + +==== gnome-vfs 2.3.2 ==== + +2003-05-17 Christophe Merlet + + * fr.po: Updated French translation. + +2003-05-15 Dmitry G. Mastrukov + + * be.po: Updated Belarusian translation + from Belarusian team . + +2003-05-10 Jordi Mallach + + * ca.po: Updated Catalan translation. + +2003-05-09 Telsa Gwynne + + * cy.po: Added Welsh translation from gnome-cy + and Kyfieithu + contributors. + +2003-05-08 Pablo Gonzalo del Campo + + * es.po: Updated Spanish translation by + Juan Manuel Garc?a Molina + +2003-05-08 Sam?el J?n Gunnarsson + + * is.po: Added Icelandic translation. + +2003-05-08 Dmitry G. Mastrukov + + * be.po: Updated Belarusian translation + from Belarusian team . + +2003-05-06 Danilo ? egan + + * sr.po, sr@Latn: Added Serbian translation by + http://Prevod.org/. + +2003-05-05 Duarte Loreto + + * pt.po: Updated Portuguese translation. + +2003-05-05 Christian Neumair + + * de.po: Updated German translation. + +==== gnome-vfs 2.3.1 ==== + +2003-05-04 Christophe Merlet + + * fr.po: Updated French translation. + +2003-05-04 Abel Cheung + + * zh_TW.po: Updated traditional Chinese translation. + +2003-05-01 Changwoo Ryu + + * ko.po: Updated Korean translation. + +2003-04-30 Takeshi AIHANA + + * ja.po: Updated Japanese translation. + +2003-04-29 Miloslav Trmac + + * cs.po: Updated Czech translation. + +2003-04-29 Gil "Dolfin" Osher + + * he.po: Updated Hebrew translation. + +2003-04-29 Christian Rose + + * sv.po: Updated Swedish translation. + +2003-04-24 Abel Cheung + + * zh_TW.po: Updated traditional Chinese translation. + +2003-04-17 HideToshi Tajima + + * POTFILES.in: Added cdemenu-desktop-method.c. + Fixes bug #103306. Translators, please translate these messages + exactly the same in CDE's sys.dtwmrc file of the locale. + +==== gnome-vfs 2.2.4 ==== + +2003-03-26 Christian Rose + + * yi.po: Added Yiddish translation by + Raphael Finkel . + +2003-03-20 Guntupalli Karunakar + + * ml.po: Added Malayalam translation by + FSF-India + +2003-03-14 Jo?=ABl Brich + + * eo.po: Added Esperanto translation + by Charles Voelger + +==== gnome-vfs 2.2.3 ==== + +2003-02-25 Taneem Ahmed + + * bn.po: Added Bangla/Bengali translation + by Sayamindu Dasgupta + +2003-02-21 Metin Amiroff + + * az.po: Updated Azerbaijani translation. + +2003-02-18 Roozbeh Pournader + + * fa.po: Added Persian translation. + +2003-02-14 Takeshi AIHANA + + * ja.po: Updated Japanese translation. + +2003-02-13 Dmitry G. Mastrukov + + * be.po: Updated Belarusian translation + from Belarusian team . + +==== gnome-vfs 2.2.2 ==== +==== gnome-vfs 2.2.1 ==== + +2003-02-06 Christian Rose + + * id.po: Added Indonesian translation by + Mohammad Damt . + +2003-02-01 Duarte Loreto + + * pt.po: Updated Portuguese translation. + +2003-01-27 Yuriy Syrota + + * uk.po: Updated Ukrainian translation. + +2003-01-25 Gustavo Noronha Silva + + * pt_BR.po: translation update. + +2003-01-24 Yanko Kaneti + + * bg.po: Updated Bulgarian translation by + Alexander Shopov . + +2003-01-22 Pablo Saratxaga + + * vi.po: Updated Vietnamese file + +2003-01-22 Christian Rose + + * mn.po: Added Mongolian translation by + Sanlig Badral . + +2003-01-21 Abel Cheung + + * zh_TW.po: Updated traditional Chinese translation. + +==== gnome-vfs 2.2.0 ==== + +2003-01-15 Fatih Demir + + * tr.po: Committed updated Turkish translation by Sinan. + +2003-01-14 Naba Kumar + + * hi.po: Updated Hindi translation from + Anurag Seetha + +==== gnome-vfs 2.1.91 ==== + +2003-01-10 Pablo Gonzalo del Campo + + * es.po: Fixed a couple of strings in Spanish translation. + +2003-01-09 Laurent Dhima + + * sq.po: Updated Albanian translation. + +2003-01-09 Dmitry G. Mastrukov + + * ru.po: updated Russian translation + from Russian team . + +2003-01-07 Daniel Yacob + + * am.po: Updated Amharic translation. + +2003-01-07 Kostas Papadimas + + * el.po: Updated Greek translation. + +2003-01-06 Vincent van Adrighem + + * nl.po: Dutch translation updated by Tino Meinen. + +==== gnome-vfs 2.1.6 ==== + +2003-01-05 Pauli Virtanen + + * fi.po: Updated Finnish translation. + +2003-01-04 Stanislav Visnovsky + + * sk.po: Updated Slovak translation. + +2003-01-04 Christian Neumair + + * de.po: Updated German translation. + +2003-01-03 Yanko Kaneti + + * bg.po: Updated Bulgarian translation by Alexander Shopov. + +2003-01-02 Zbigniew Chyla + + * pl.po: Updated Polish translation by + GNOME PL Team . + +2002-12-22 Artis Trops + + * lv.po: Updated Latvian translation. + +2002-12-20 Jordi Mallach + + * ca.po: Updated Catalan translation. + +2002-12-19 Christophe Merlet + + * fr.po: Updated French translation. + +2002-12-19 Andras Timar + + * hu.po: Updated Hungarian translation. + +2002-12-19 Christian Rose + + * sv.po: Updated Swedish translation. + +2002-12-17 German Poo Caaman~o + + * es.po: Updates Spanish translation + +2002-12-17 Christian Rose + + * sv.po: Updated Swedish translation. + +==== gnome-vfs 2.1.5 ==== + +2002-12-15 Hasbullah Bin Pit + + * ms.po: Updated Malay Translation. + +2002-12-15 Ole Laursen + + * da.po: Updated Danish translation. + +2002-12-14 Christophe Merlet + + * fr.po: Updated French translation. + +2002-12-14 Kjartan Maraas + + * no.po: Updated Norwegian translation. + +2002-12-13 Daniel Yacob + + * am.po: Added Amharic translation. + +2002-12-13 Miloslav Trmac + + * cs.po: Updated Czech translation. + +2002-12-11 Laurent Dhima + + * sq.po: Updated Albanian translation. + +2002-12-11 Pauli Virtanen + + * fi.po: Updated Finnish translation. + +==== gnome-vfs 2.1.4 ==== + +2002-12-07 Andras Timar + + * hu.po: Updated Hungarian translation. + +2002-11-30 Ole Laursen + + * da.po: Updated Danish translation. + +2002-11-27 Jody Goldberg + + * Release 2.1.3.1 + +2002-11-25 Vincent van Adrighem + + * nl.po: Massive copy-paste from stable branch. + +2002-11-15 Kjartan Maraas + + * no.po: Updated Norwegian translation. + +2002-11-12 Laurent Dhima + + * sq.po: Added Albanian translation. + +2002-11-04 Hasbullah Bin Pit + + * ms.po: Updated Malay Translation. + +2002-11-03 Dmitry G. Mastrukov + + * be.po: Added Belarusian translation + * from Belarusian team . + +2002-11-01 Christian Rose + + * sv.po: Updated Swedish translation. + +2002-07-28 Christophe Merlet + + * fr.po: Updated French translation from contribution of + Sun G11n . + +2002-07-25 Pablo Saratxaga + + * bs.po: Added Bosnian file + +2002-06-11 Abel Cheung + + * zh_TW.po: Updated traditional Chinese translation. + +2002-06-07 Jordi Mallach + + * ca.po: Updated Catalan translation. + +2002-06-05 Tivo Leedj=EF?=BDv + + * et.po: Updated Estonian translation. + +2002-06-05 Yanko Kaneti + + * bg.po (added): Bulgarian translation by + Borislav Aleksandrov . + +2002-06-02 Germ=EF?=BD Poo Caamao + + * es.po: Updated translation from + Juan Manuel Garc=EF?=BD Molina + +2002-06-01 Carlos Perell Mar=EF?=BD + + * es.po: Recoded as UTF-8 + +2002-06-01 Jesus Bravo Alvarez + + * gl.po: Updated Galician translation + +2002-05-29 Vincent van Adrighem + + * nl.po: Updated Dutch translation (by Tino Meinen). + +2002-05-19 Vlad Harchev + + * ru.po: updated russian translation from Dmitry G. Mastrukov + . + +2002-05-10 Valek Filippov + + * ru.po: updated russian translation from Dmitry Mastrukov. + +2002-05-10 Naba Kumar + + * hi.po: New Hindi translation added. + +2002-05-06 Seth Nickell + + reviewed by: + + * az.po: + * ca.po: + * da.po: + * de.po: + * el.po: + * es.po: + * et.po: + * fi.po: + * fr.po: + * ga.po: + * gl.po: + * hu.po: + * it.po: + * ja.po: + * ko.po: + * lt.po: + * ms.po: + * nl.po: + * nn.po: + * no.po: + * pl.po: + * pt.po: + * pt_BR.po: + * ro.po: + * ru.po: + * sk.po: + * sl.po: + * sv.po: + * tr.po: + * uk.po: + * wa.po: + * zh_CN.po: + * zh_TW.po: + +2002-05-05 Duarte Loreto + + * pt.po: Updated Portuguese translation and converted to UTF-8. + +2002-04-30 Pablo Saratxaga + + * vi.po: Added Vietnamese file + +2002-04-29 Pablo Saratxaga + + * eu.po: Added Basque file + * wa.po: Updated Walloon file + +2002-04-28 Christophe Merlet + + * fr.po: Updated French translation and converted to UTF-8. + +2002-04-24 Benedikt Roth + + * hu.po: Patch from andras@dns.net (Andras Salamon). + +2002-04-22 Jody Goldberg + + * Release 1.9.12 + +2002-04-09 Valek Filippov + + * ru.po: updated russian translation from Dmitry Mastrukov. + +2002-03-28 Kjartan Maraas + + * no.po: Updated Norwegian translation. + +2002-03-27 Seth Nickell + + reviewed by: + + * az.po: + * ca.po: + * da.po: + * de.po: + * el.po: + * es.po: + * et.po: + * fi.po: + * fr.po: + * ga.po: + * gl.po: + * hu.po: + * it.po: + * ja.po: + * ko.po: + * lt.po: + * ms.po: + * nl.po: + * nn.po: + * no.po: + * pl.po: + * pt.po: + * pt_BR.po: + * ro.po: + * ru.po: + * sk.po: + * sl.po: + * sv.po: + * tr.po: + * uk.po: + * wa.po: + * zh_CN.po: + * zh_TW.po: + +2002-03-15 Valek Filippov + + * ru.po: updated russian translation. + +2002-03-12 Changwoo Ryu + + * ko.po: Updated Korean translation and converted to UTF-8. + +2002-03-10 Christian Rose + + * POTFILES.skip: Created (containing modules/efs-method.c). + * POTFILES.in: Remove modules/efs-method.c. + +2002-03-09 Changwoo Ryu + + * ko.po: Updated Korean translation. + +2002-03-03 Christian Meyer + + * de.po: Updated German translation. + +2002-03-03 Kjartan Maraas + + * no.po: Updated Norwegian translation. + +2002-02-27 Christian Meyer + + * de.po: Updated German translation. + +2002-02-25 Christian Rose + + * sv.po: Updated Swedish translation. + +2002-02-23 Zbigniew Chyla + + * pl.po: Updated Polish translation by + GNOME PL Team . + +2002-02-23 Fatih Demir + + * tr.po: Committed updated Turkish translatio by Sinan. + +2002-02-17 Wang Jian + + * zh_CN.po: Updated Simplified Chinese translation by + Wang Jian. + +2002-02-14 Tivo Leedj=EF?=BDv + + * et.po: Added Estonian translation. + +2002-02-12 Kjartan Maraas + + * no.po: Updated Norwegian translation. + +2002-02-10 Kjartan Maraas + + * no.po: Updated Norwegian translation. + +2002-02-09 Pauli Virtanen + + * fi.po: Updated Finnish translation and converted it to UTF-8. + +2002-02-08 Duarte Loreto + + * pt.po: Updated Portuguese translation. + +2002-02-04 Seth Nickell + + reviewed by: + + * az.po: + * ca.po: + * da.po: + * de.po: + * el.po: + * es.po: + * fi.po: + * fr.po: + * ga.po: + * gl.po: + * hu.po: + * it.po: + * ja.po: + * ko.po: + * lt.po: + * nl.po: + * nn.po: + * no.po: + * pl.po: + * pt.po: + * pt_BR.po: + * ro.po: + * ru.po: + * sk.po: + * sl.po: + * sv.po: + * tr.po: + * uk.po: + * wa.po: + * zh_CN.po: + * zh_TW.po: + +2002-02-03 Hasbullah Bin Pit + + * ms.po: Updated Malay Translation. + +2002-01-30 Ole Laursen + + * da.po: Updated Danish translation and converted it to UTF-8. + +2002-01-30 Seth Nickell + + reviewed by: + + * az.po: + * ca.po: + * da.po: + * de.po: + * el.po: + * es.po: + * fi.po: + * fr.po: + * ga.po: + * gl.po: + * hu.po: + * it.po: + * ja.po: + * ko.po: + * lt.po: + * nl.po: + * nn.po: + * no.po: + * pl.po: + * pt.po: + * pt_BR.po: + * ro.po: + * ru.po: + * sk.po: + * sl.po: + * sv.po: + * tr.po: + * uk.po: + * wa.po: + * zh_CN.po: + * zh_TW.po: + +2002-01-30 Stanislav Visnovsky + + * sk.po: Updated Slovak translation. + +2002-01-30 Roy-Magne Mo + + * nn.po: Updated and converted to UTF-8 + +2002-01-29 Christophe Merlet + + * fr.po: Updated French translation. + +2002-01-28 jacob berkman + + * POTFILES.in: remove efs-method.c + +2002-01-28 Kjartan Maraas + + * no.po: Updated Norwegian translation. + +2002-01-27 Christian Rose + + * POTFILES.in: Sorted and added missing files. + * sv.po: Updated Swedish translation. + +2002-01-27 Christian Rose + + * sv.po: Converted to UTF-8. + +2002-01-19 Hasbullah Bin Pit + + * ms.po: Added Malay Translation by + Mohamad Afifi Omar (App) and me.. + +2001-12-16 Duarte Loreto + + * pt.po: Added Portuguese translation. + +2001-11-30 Roy-Magne Mo + + * nn.po: Updated Norwegian (nynorsk) translation. + +2001-11-21 Wang Jian + + * zh_CN.po: Added Simplified Chinese translation by + Lou Bingyong , UTF-8. + +2001-11-19 Pablo Saratxaga + + * az.po: Updated Azeri file + * wa.po: Updated Walloon file + +2001-11-08 Fatih Demir + + * tr.po: Committed updated Turkish translation by Sinan. + +2001-11-02 Maciej Stachowiak + + * az.po, ca.po, da.po, de.po, el.po, es.po, fi.po, fr.po, ga.po, + gl.po, hu.po, it.po, ja.po, ko.po, lt.po, nl.po, nn.po, no.po, + pl.po, pt_BR.po, ro.po, ru.po, sk.po, sl.po, sv.po, tr.po, uk.po, + wa.po, zh_TW.po: Updated by make distcheck. + +2001-11-02 Maciej Stachowiak + + * POTFILES.in: files from libgnomevfs-pthread have been moved + +2001-11-01 Seth Nickell + + * POTFILES.in, az.po, ca.po, da.po, de.po, el.po, + es.po, fi.po, fr.po, ga.po, gl.po, hu.po, it.po, + ja.po, ko.po, lt.po, nl.po, nn.po, no.po, pl.po, + pt_BR.po, ro.po, ru.po, sk.po, sl.po, sv.po, tr.po, + uk.po, wa.po, zh_TW.po: Lose the MIME translations. + +2001-10-29 Christian Rose + + * sv.po: Updated Swedish translation. + +2001-10-25 Christophe Merlet + + * fr.po: Updated French translation. + +2001-10-20 Pablo Saratxaga + + * az.po: Updated Azeri file + +2001-10-13 Valek Filippov + + * ru.po: updated russian translation. + +2001-10-13 Christophe Merlet + + * fr.po: Updated French translation. + +2001-09-25 Pablo Saratxaga + + * az.po: Updated Azeri file + +2001-09-24 Gediminas Paulauskas + + * lt.po: Updated Lithuanian translation. + +2001-09-09 Pablo Saratxaga + + * wa.po: Updated Walloon file + * ca.po: Updated Catalan file + +2001-09-08 Gustavo Maciel Dias Vieira + + * pt_BR.po: Updated Brazilian Portuguese translation. + +2001-09-07 Stanislav Visnovsky + + * sk.po: Small update. + +2001-08-27 Abel Cheung + + * zh_TW.Big5.po: Renamed to... + * zh_TW.po: this. Converted to UTF8 as well. + +2001-08-24 Andras Timar + + * hu.po: Updated Hungarian translation. + +2001-08-03 Seth Nickell + + reviewed by: + + * az.po: + * ca.po: + * da.po: + * de.po: + * el.po: + * es.po: + * fi.po: + * fr.po: + * ga.po: + * gl.po: + * hu.po: + * it.po: + * ja.po: + * ko.po: + * lt.po: + * nl.po: + * nn.po: + * no.po: + * pl.po: + * pt_BR.po: + * ro.po: + * ru.po: + * sk.po: + * sl.po: + * sv.po: + * tr.po: + * uk.po: + * wa.po: + +2001-07-29 Christian Meyer + + * de.po: Updated German translation. + +2001-07-17 Stanislav Visnovsky + + * sk.po: Updated Slovak translation. + +2001-07-15 Kjartan Maraas + + * nn.po: Updated Norwegian (nynorsk) translation. + +2001-07-13 Fatih Demir + + * tr.po: Updated Turkish translation. + +2001-07-08 Akira TAGOH + + * Updated Japanese translation. + +2001-07-02 Christopher R. Gabriel + + * it.po: Updated italian translation. + +2001-06-28 Kjartan Maraas + + * no.po: Updated Norwegian translation. + +2001-06-22 Christophe Merlet + + * fr.po: Updated French translation. + +2001-06-16 Wang Jian + + * zh_TW.Big5.po: Added by Joe Man + +2001-06-13 Carlos Perells Marmn + + * es.po: /s/vaciado de memoria/volcado de memoria + Thanks Eduardo Ferro + +2001-06-10 Ole Laursen + + * da.po: Updated Danish translation. + +2001-06-08 Fatih Demir + + * tr.po: Committed updated Turkish translation + by Sinan. + +2001-06-02 Christian Rose + + * sv.po: Updated Swedish translation. + +2001-05-24 Christian Meyer + + * de.po: Updated German translation. Kai when do you finally learn to + write Changelogs? + +2001-05-23 Robin * Slomkowski + + * az.po: + * ca.po: + * da.po: + * de.po: + * el.po: + * es.po: + * fi.po: + * fr.po: + * ga.po: + * gl.po: + * hu.po: + * it.po: + * ja.po: + * ko.po: + * lt.po: + * nl.po: + * nn.po: + * no.po: + * pl.po: + * pt_BR.po: + * ro.po: + * ru.po: + * sk.po: + * sl.po: + * sv.po: + * tr.po: + * uk.po: + * wa.po: + removed all refrences to the non-ascii mu in the + description and replaced it with ascii mu to make + gettext happy + +2001-04-28 Ole Laursen + + * da.po: Major overhaul. + +2001-04-27 Ole Laursen + + * da.po: Fixed a few strings. + +2001-04-25 Changwoo Ryu + + * ko.po: Updated Korean translation, by . + +2001-03-12 Gustavo Maciel Dias Vieira + + * pt_BR.po: Updated Brazilian Portuguese translation. + +2001-03-09 Jesus Bravo Alvarez + + * gl.po: From gnome-vfs-1-0 branch. + +2001-03-08 Mauricio Araya P. + + * es.po: Updated Spanish translation. + +2001-03-07 Ole Laursen + + * da.op: Updated Danish Translation. + +2001-03-07 Christian Rose + + * sv.po: Updated Swedish translation. + +2001-03-06 Darin Adler + + Merged all changes back here from the gnome-vfs-1 branch. + +=== start of changes from gnome-vfs-1 branch ==== + +2001-03-06 Stanislav Visnovsky + + * sk.po: Updated Slovak translation. + +2001-03-06 Pauli Virtanen + + * fi.po: Updated Finnish translation. + +2001-03-05 Szabolcs Ban + + * hu.po: Update by Andras Timar + +2001-03-04 Szabolcs Ban + + * hu.po: Update by Andras Timar + +2001-03-02 Stanislav Visnovsky + + * sk.po: Updated Slovak translation. + +2001-03-01 Simos Xenitellis + + * el.po: Update of Greek translation. + +2001-03-01 Christophe Merlet + + * fr.po: Updated French translation. + +2001-03-01 Kjartan Maraas + + * no.po: Updated Norwegian (bokmel) translation. + +2001-02-27 Simos Xenitellis + + * el.po: Update of Greek translation. + +2001-02-27 Darin Adler + + More attempt to clean up the carnage caused by + running xml-i18n-prepare. + + * POTFILES.in: Sort files. + + * de.po: + * fr.po: + * it.po: + * ko.po: + * pt_BR.po: + * sv.po: + * uk.po: + Removed duplicate entries. + +2001-02-27 Pablo Saratxaga + + * ca.po: Updated Catalan file + * wa.po: Added Walloon file + * da.po,el.po: removed duplicate entries + * nn.po,sl.po: fixed charset= value in header + +2001-02-26 Rebecca Schulman + + * POTFILES.in: + * da.po: + * de.po: + * el.po: + * fi.po: + * fr.po: + * it.po: + * ko.po: + * no.po: + * pt_BR.po: + * sk.po: + * sv.po: + * tr.po: + * uk.po: + Add translations that were formerly in + file-types-capplet.desktop to the + po files using xml-i18n-prepare + +2001-02-27 Jarkko Ranta + + * fi.po: Updated Finnish translation by Pauli Virtanen. + +2001-02-26 Kjartan Maraas + + * no.po: Updated Norwegian (bokmel) translation. + +2001-02-26 Pablo Saratxaga + + * az.po: Added Azeri file + * {ga,sl,tr,nl,no,pl,ro}.po: enabled/fixed headers + + +2001-02-26 Szabolcs Ban + + * hu.po: Update by Greg + +2001-02-26 Christophe Merlet + + * update.sh: Removed (Don't work with xml-i18n-tools >= 0.8.1) + * fr.po: Updated French translation. + +2001-02-25 Christian Rose + + * sv.po: Updated Swedish translation. + +2001-02-24 Marius Andreiana + + * ro.po: added + +2001-02-24 Stanislav Visnovsky + + * sk.po: Updated Slovak translation. + +2001-02-24 Kjartan Maraas + + * no.po: Updated Norwegian (bokmel) translation. + +2001-02-23 Christophe Merlet + + * fr.po: Updated French translation. + +2001-02-22 Simos Xenitellis + + * el.po: Updated Greek translation. + +2001-02-22 Kjartan Maraas + + * no.po: Updated Norwegian (bokmel) translation. + +2001-02-21 Gustavo Maciel Dias Vieira + + * pt_BR.po: Updated Brazilian Portuguese translation. + +2001-02-21 Kjartan Maraas + + * no.po: Updated Norwegian (bokmel) translation. + +2001-02-21 Fatih Demir + + * ko.po: Committed updated Korean translation. + +2001-02-21 Christian Rose + + * sv.po: Updated Swedish translation. + +2001-02-20 Matthias Warkus + + * de.po: Updated for beta and Nautilus release. + +2001-02-20 Christophe Merlet + + * fr.po: Updated French translation. + +2001-02-19 Stanislav Visnovsky + + * sk.po: Updated Slovak translation. + +2001-02-18 Simos Xenitellis + + * el.po: Updated Greek Translation. + +2001-02-18 Gustavo Maciel Dias Vieira + + * pt_BR.po: Updated Brazilian Portuguese translation. + +2001-02-16 Kjartan Maraas + + * no.po: Updated Norwegian (bokmel) translation. + +2001-02-15 Kjartan Maraas + + * nn.po: Added Norwegian (nynorsk) translation. + +2001-02-15 Christopher R. Gabriel + + * it.po: Updated italian translation + +2001-02-14 Kjartan Maraas + + * no.po: Updated Norwegian (bokmel) translation. + +2001-02-14 Stanislav Visnovsky + + * sk.po: Updated Slovak translation. + +2001-02-14 Martin Norbdck + + * sv.po: Updated Swedish translation. + +2001-02-14 Simos Xenitellis + + * el.po: Updated Greek translation. + +2001-02-13 Szabolcs Ban + + * hu.po: Update and fixes by Emese + +2001-02-13 Christophe Merlet + + * fr.po: Updated French translation. + +2001-02-11 Kjartan Maraas + + * no.po: Updated Norwegian (bokmel) translation. + +2001-02-09 Stanislav Visnovsky + + * sk.po: Updated Slovak translation. + +=== end of changes from gnome-vfs-1 branch === + +2001-02-28 Mauricio Araya P. + + * es.po: Updated Spanish translation. + +2001-02-26 Szabolcs Ban + + * hu.po: Update by Greg + +2001-02-24 Marius Andreiana + + * ro.po: added + +2001-02-19 Pablo Saratxaga + + * az.po: Added Azeri file + +2001-02-13 Pauli Virtanen + + * fi.po: Updated Finnish translation. + +2001-02-13 Christophe Merlet + + * fr.po: Updated French translation. + +2001-02-10 Simos Xenitellis + + * el.po: Added Greek translation. + +2001-02-09 Stanislav Visnovsky + + * sk.po: Updated Slovak translation. + +2001-02-05 Fatih Demir + + * tr.po: Committed updated Turkish translation + by Sinan Imamoglu. + +2001-02-05 Christophe Merlet + + * fr.po: Updated French translation. + * update.pl: Removed this script and replaced by... + * update.sh: Added this xml-i18n compatible script. + +2001-02-05 Mauricio Araya P. + + * es.po: Updated Spanish translation. + +2001-02-04 Fatih Demir + + * tr.po: Committed updated Turkish translation by + Gvrkem Cetin. + +2001-02-02 Kjartan Maraas + + * no.po: Updated Norwegian (bokmel) translation. + +2001-02-01 Stanislav Visnovsky + + * sk.po: Updated Slovak translation. + +2001-01-31 Szabolcs Ban + + * hu.po: Terminology fixes by Andras Timar + +2001-01-31 Szabolcs Ban + + * hu.po: Updated Hungarian translations + +2001-01-29 Kjartan Maraas + + * no.po: Updated Norwegian translation. + +2001-01-29 Martin Norbdck + + * sv.po: Updated Swedish translation. + +2001-01-27 Fatih Demir + + * ko.po: Committed updated Korean translation. + +2001-01-25 Szabolcs Ban + + * hu.po: Updated Hungarian translations + +2001-01-24 Kjartan Maraas + + * no.po: Updated Norwegian (bokmel) translation. + +2001-01-24 Szabolcs Ban + + * hu.po: Tons of fixes by Andras and Emese (spelling, + terminology, headers) + +2001-01-23 Martin Norbdck + + * sv.po: Updated Swedish translation. + +2001-01-23 Valek Filippov + + * ru.po: updated russian translation. + +2001-01-22 Christian Rose + + * sv.po: Updated Swedish translation. + +2001-01-22 Stanislav Visnovsky + + * sk.po: Updated Slovak translation. + +2001-01-20 Fatih Demir + + * ko.po: Committed updated Korean translation. + +2001-01-18 Martin Norbdck + + * sv.po: Updated Swedish translation. + +2001-01-18 Kenneth Christiansen + + * POTFILES.in: Updated + * da.po, fi.po, fr.po, no.po, sv.po: + All updated to include translations from + the gnome-vfs.keys file. All extracted with + a script of mine. + +2001-01-18 Kjartan Maraas + + * no.po: Updated Norwegian (bokmel) translation. + +2001-01-11 Stanislav Visnovsky + + * sk.po: Updated Slovak translation. + +2001-01-10 Christophe Merlet + + * fr.po: Updated French translation. + +2001-01-09 Valek Filippov + + * ru.po: updated russian translation. + +2001-01-03 Christian Rose + + * sv.po: Updated Swedish translation. + +2001-01-03 Stanislav Visnovsky + + * sk.po: Updated Slovak translation. + +2000-12-31 Kjartan Maraas + + * no.po: Updated Norwegian translation. + +2000-12-31 Pauli Virtanen + + * fi.po: Updated Finnish translation. + +2000-12-27 Kai Lahmann + + * de.po: Updated German translation + +2000-12-20 Stanislav Visnovsky + + * sk.po: Updated Slovak translation. + +2000-12-18 Christopher R. Gabriel + + * it.po: Updated italian translation + +2000-12-13 Valek Filippov + + * ru.po: updated russian translation. + +2000-12-13 Christian Rose + + * sv.po: Updated Swedish translation. + +2000-12-11 Kjartan Maraas + + * no.po: Updated Norwegian translation. + +2000-12-06 Fatih Demir + + * ko.po: Committed updated Korean + translation. + +2000-12-05 Kjartan Maraas + + * no.po: Updated Norwegian translation. + +2000-12-03 Kai Lahmann + + * de.po: Updated German translation + +2000-11-24 Kjartan Maraas + + * no.po: Updated Norwegian translation. + +2000-11-21 Valek Filippov + + * ru.po: updated russian translation. + +2000-11-20 Stanislav Visnovsky + + * sk.po: Updated Slovak translation. + +2000-11-20 Christian Rose + + * sv.po: Updated Swedish translation. + +2000-11-17 Christian Rose + + * sv.po: Updated Swedish translation. + +2000-11-16 Matthias Warkus + + * de.po: Update. + +2000-11-14 Valek Filippov + + * ru.po: updated russian translation. + +2000-11-14 Stanislav Visnovsky + + * sk.po: Updated Slovak translation. + +2000-11-14 Christopher R. Gabriel + + * it.po: Updated italian translation + +2000-11-13 Christian Rose + + * sv.po: Updated Swedish translation. + +2000-11-11 Kjartan Maraas + + * no.po: Updated Norwegian translation. + +2000-11-09 Szabolcs BAN + + * hu.po: Updated. + +2000-11-08 Yukihiro Nakai + + * sk.po: Update Slovak translation from Stanislav Visnovsky. + +2000-11-05 Yukihiro Nakai + + * sk.po: Intial Slovak translation from Stanislav Visnovsky. + +2000-11-03 Kai Lahmann + + * de.po: Updated German translation + +2000-11-03 Christian Rose + + * sv.po: Updated Swedish translation. + +2000-11-02 Valek Filippov + + * ru.po: updated russian translation. + +2000-10-21 Zbigniew Chyla + + * pl.po: Updated Polish translation. + +2000-10-17 Jarkko Ranta + + * fi.po: Updated Finnish Translation + +2000-10-12 Fatih Demir + + * tr.po: Updated the Turkish translation ( yes, + the update was done with gtranslator ). + +2000-09-28 Christophe Merlet + + * fr.po: Updated French translation. + +2000-09-14 Christian Rose + + * sv.po: Updated Swedish translation. + +2000-09-13 Christian Rose + + * sv.po: Updated Swedish translation. + +2000-09-12 Christian Rose + + * sv.po: Updated Swedish translation. + +2000-09-05 Martin Baulig + + * .cvsignore: Added Makefile.in.in. + +2000-08-30 Jesus Bravo Alvarez + + * gl.po: Updated Galician translation. + +2000-08-27 Alastair McKinstry + + * ga.po: Added Irish translation. + +2000-08-18 Takuo Kitame + + * ja.po: Updated Japanese translation + +2000-08-17 Christopher R. Gabriel + + * it.po: Updated Italian translation + +2000-08-16 Kjartan Maraas + + * no.po: Updated Norwegian translation. + +2000-08-14 Kai Lahmann + + * de.po: Updated German translation + +2000-08-13 Valek Filippov + + * ru.po: updated russian translation. + * POTFILES.in: added missing files. + +2000-08-08 Kai Lahmann + + * de.po: Updated German translation + +2000-07-26 Valek Filippov + + * ru.po: updated russian translation. + +2000-07-26 Matthias Warkus + + * de.po: Updated. + +2000-07-24 Fatih Demir + + * tr.po: Corrected some wrong translations. (->QA). + + * update.pl: I don't think that we're building a nautilus + translation in the gnome-vfs module ;) + + * .cvsignore: Added the "messages" file to the ignored ones. + +2000-07-24 Szabolcs BAN + + * hu.po: Updated Hungarian translations. + +2000-07-22 Yukihiro Nakai + + * ja.po: Updated from Akira TAGOH. + +2000-07-21 Christopher R. Gabriel + + * it.po: updated italian translation. + +2000-07-19 Kjartan Maraas + + * nl.po: Added Dutch translation from Mendel Mobach + . + +2000-07-12 Fatih Demir + + * tr.po: Updated the Turkish translation. + +2000-07-10 Kjartan Maraas + + * no.po: Updated Norwegian translation. + +2000-07-10 Fatih Demir + + * tr.po: Updated the Turkish translation. + +2000-07-05 Valek Filippov + + * ru.po: updated russian translation. + +2000-06-25 Jaka Mocnik + + * sl.po: fixed a bunch of typos and semantical errors ;) + +2000-06-24 Valek Filippov + + * ru.po: updated russian translation. + +2000-06-21 Kjartan Maraas + + * no.po: Updated Norwegian translation. + +2000-06-17 Valek Filippov + + * ru.po: updated russian translation. + +2000-06-17 Kjartan Maraas + + * POTFILES.in: Added missing files. + * no.po: Updated Norwegian translation. + +2000-04-26 Kjartan Maraas + + * no.po: Updated Norwegian translation. + +2000-06-10 Sung-Hyun Nam + + * ko.po: initial translation from Young-Ho,Cha + +2000-06-04 Valek Filippov + + * ru.po: Updated russian translation. + +2000-05-25 Fatih Demir + + * tr.po: Updated the Turkish translation. + +2000-05-25 Szabolcs BAN + + * hu.po: Added Hungarian translations. + +2000-04-27 Jesus Bravo Alvarez + + * gl.po: Updated Galician translation. + +2000-04-27 Andreas Hyden + + * sv.po: Updated Swedish translation. + +2000-04-26 Valek Filippov + + * ru.po: Updated russian translation. + +2000-04-26 Kjartan Maraas + + * no.po: Updated Norwegian translation. + * POTFILES.in: Added one missing file. + +2000-04-20 Pablo Saratxaga + + * lt.po: Updated Lithuanian file + +2000-04-19 Pablo Saratxaga + + * da.po: Updated Danish file + * ca.po: Added Catalan file + +2000-04-18 Vincent Renardias + + * fr.po: 100% complete. + +2000-04-17 Fatih Demir + + * tr.po : Updated it . + +2000-04-16 Valek Filippov + + * ru.po: Added russian translation. + +2000-04-16 Pablo Saratxaga + + * da.po: Updated Danish file + +2000-04-14 Yukihiro Nakai + + * ja.po: Japanese Update from Akira Tagoh. + +2000-04-10 Kjartan Maraas + + * no.po: Updated Norwegian translation. + +2000-04-08 Andreas Hyden + + * sv.po: Updated Swedish translation. + +2000-04-08 Jesus Bravo Alvarez + + * gl.po: Updated Galician translation. + +2000-04-05 Spiros Papadimitriou + + * el.po: Updated Greek translation. + +2000-03-30 Yuri Syrota + + * uk.po: Updated translation. + +2000-03-25 Zbigniew Chyla + + * pl.po: Updated translation. + +2000-03-25 Yukihiro Nakai + + * ja.po: Initial Japanese translation from Akira Tagoh + +2000-03-10 Kjartan Maraas + + * no.po: Updated Norwegian translation. + +2000-02-25 Andreas Hyden + + * sv.po: Updated Swedish translation. + +2000-02-23 Andreas Hyden + + * sv.po: Updated Swedish translation. + +2000-02-15 Vincent Renardias + + * fr.po : Updated (more work needed) + +2000-02-09 Simos Xenitellis + + * el.po: Updated Greek translation. + +2000-01-24 Spiros Papadimitiriou + + * el.po: Added Greek translation. + +2000-01-19 Kjartan Maraas + + * POTFILES.in: Added missing files. + * no.po: Updated accordingly. + +2000-01-04 Kjartan Maraas + + * update.sh: A little script that lets people + update the .pot file without makefiles etc. + +1999-12-29 Jesus Bravo Alvarez + + * gl.po: Added Galician translation. + +1999-12-28 Martin Norbdck + + * sv.po: Added Swedish translation. + +1999-12-28 Yuri Syrota + + * uk.po: Added Ukrainian translation. + +1999-12-27 Matthias Warkus + + * de.po: Added. + +1999-12-23 Fatih Demir + + * tr.po: Added tr.po for Turkish translation . + +1999-12-14 Kjartan Maraas + + * no.po: Updated Norwegian translation. + +1999-11-19 Kjartan Maraas + + * no.po: Added Norwegian translation. + +1999-09-29 Rodrigo Stulzer Lopes + + * pt_BR.po: Add pt_BR translations + +1999-09-25 Kjartan Maraas + + * da.po: Added Danish translation from Kenneth + Christiansen . + +1999-08-25 Vincent Renardias + + * fr.po: Initial translation: + 42 translated messages. diff --git a/po/Makefile.in.in b/po/Makefile.in.in new file mode 100644 index 0000000..6d2cd50 --- /dev/null +++ b/po/Makefile.in.in @@ -0,0 +1,254 @@ +# Makefile for program source directory in GNU NLS utilities package. +# Copyright (C) 1995, 1996, 1997 by Ulrich Drepper +# +# This file file be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU Public License +# but which still want to provide support for the GNU gettext functionality. +# Please note that the actual code is *not* freely available. +# +# - Modified by Owen Taylor to use GETTEXT_PACKAGE +# instead of PACKAGE and to look for po2tbl in ./ not in intl/ +# +# - Modified by jacob berkman to install +# Makefile.in.in and po2tbl.sed.in for use with glib-gettextize + +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +PACKAGE = @PACKAGE@ +VERSION = @VERSION@ + +SHELL = /bin/sh +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +top_builddir = .. +VPATH = @srcdir@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +datadir = @datadir@ +libdir = @libdir@ +localedir = $(libdir)/locale +gnulocaledir = $(datadir)/locale +gettextsrcdir = $(datadir)/glib-2.0/gettext/po +subdir = po + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +MKINSTALLDIRS = $(top_srcdir)/@MKINSTALLDIRS@ + +CC = @CC@ +GENCAT = @GENCAT@ +GMSGFMT = @GMSGFMT@ +MSGFMT = @MSGFMT@ +XGETTEXT = @XGETTEXT@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +MSGMERGE = INTLTOOL_EXTRACT=$(INTLTOOL_EXTRACT) $(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --dist +GENPOT = INTLTOOL_EXTRACT=$(INTLTOOL_EXTRACT) $(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --pot + +DEFS = @DEFS@ +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ + +INCLUDES = -I.. -I$(top_srcdir)/intl + +COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS) + +SOURCES = +POFILES = @POFILES@ +GMOFILES = @GMOFILES@ +DISTFILES = ChangeLog Makefile.in.in POTFILES.in $(GETTEXT_PACKAGE).pot \ +$(POFILES) $(GMOFILES) $(SOURCES) + +POTFILES = \ + +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +INSTOBJEXT = @INSTOBJEXT@ + +.SUFFIXES: +.SUFFIXES: .c .o .po .pox .gmo .mo .msg .cat + +.c.o: + $(COMPILE) $< + +.po.pox: + $(MAKE) $(GETTEXT_PACKAGE).pot + $(MSGMERGE) $< $(srcdir)/$(GETTEXT_PACKAGE).pot -o $*pox + +.po.mo: + $(MSGFMT) -o $@ $< + +.po.gmo: + file=$(srcdir)/`echo $* | sed 's,.*/,,'`.gmo \ + && rm -f $$file && $(GMSGFMT) -o $$file $< + +.po.cat: + sed -f ../intl/po2msg.sed < $< > $*.msg \ + && rm -f $@ && $(GENCAT) $@ $*.msg + + +all: all-@USE_NLS@ + +all-yes: $(CATALOGS) +all-no: + +$(srcdir)/$(GETTEXT_PACKAGE).pot: $(POTFILES) + $(GENPOT) + +install: install-exec install-data +install-exec: +install-data: install-data-@USE_NLS@ +install-data-no: all +install-data-yes: all + if test -r "$(MKINSTALLDIRS)"; then \ + $(MKINSTALLDIRS) $(DESTDIR)$(datadir); \ + else \ + $(SHELL) $(top_srcdir)/mkinstalldirs $(DESTDIR)$(datadir); \ + fi + @catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + case "$$cat" in \ + *.gmo) destdir=$(gnulocaledir);; \ + *) destdir=$(localedir);; \ + esac; \ + lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \ + dir=$(DESTDIR)$$destdir/$$lang/LC_MESSAGES; \ + if test -r "$(MKINSTALLDIRS)"; then \ + $(MKINSTALLDIRS) $$dir; \ + else \ + $(SHELL) $(top_srcdir)/mkinstalldirs $$dir; \ + fi; \ + if test -r $$cat; then \ + $(INSTALL_DATA) $$cat $$dir/$(GETTEXT_PACKAGE)$(INSTOBJEXT); \ + echo "installing $$cat as $$dir/$(GETTEXT_PACKAGE)$(INSTOBJEXT)"; \ + else \ + $(INSTALL_DATA) $(srcdir)/$$cat $$dir/$(GETTEXT_PACKAGE)$(INSTOBJEXT); \ + echo "installing $(srcdir)/$$cat as" \ + "$$dir/$(GETTEXT_PACKAGE)$(INSTOBJEXT)"; \ + fi; \ + if test -r $$cat.m; then \ + $(INSTALL_DATA) $$cat.m $$dir/$(GETTEXT_PACKAGE)$(INSTOBJEXT).m; \ + echo "installing $$cat.m as $$dir/$(GETTEXT_PACKAGE)$(INSTOBJEXT).m"; \ + else \ + if test -r $(srcdir)/$$cat.m ; then \ + $(INSTALL_DATA) $(srcdir)/$$cat.m \ + $$dir/$(GETTEXT_PACKAGE)$(INSTOBJEXT).m; \ + echo "installing $(srcdir)/$$cat as" \ + "$$dir/$(GETTEXT_PACKAGE)$(INSTOBJEXT).m"; \ + else \ + true; \ + fi; \ + fi; \ + done + if test "$(PACKAGE)" = "glib"; then \ + if test -r "$(MKINSTALLDIRS)"; then \ + $(MKINSTALLDIRS) $(DESTDIR)$(gettextsrcdir); \ + else \ + $(SHELL) $(top_srcdir)/mkinstalldirs $(DESTDIR)$(gettextsrcdir); \ + fi; \ + $(INSTALL_DATA) $(srcdir)/Makefile.in.in \ + $(DESTDIR)$(gettextsrcdir)/Makefile.in.in; \ + else \ + : ; \ + fi + +# Define this as empty until I found a useful application. +installcheck: + +uninstall: + catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \ + rm -f $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE)$(INSTOBJEXT); \ + rm -f $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE)$(INSTOBJEXT).m; \ + rm -f $(DESTDIR)$(gnulocaledir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE)$(INSTOBJEXT); \ + rm -f $(DESTDIR)$(gnulocaledir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE)$(INSTOBJEXT).m; \ + done + if test "$(PACKAGE)" = "glib"; then \ + rm -f $(DESTDIR)$(gettextsrcdir)/Makefile.in.in; \ + fi + +check: all + +dvi info tags TAGS ID: + +mostlyclean: + rm -f core core.* *.pox $(GETTEXT_PACKAGE).po *.old.po cat-id-tbl.tmp + rm -fr *.o + rm -f .intltool-merge-cache + +clean: mostlyclean + +distclean: clean + rm -f Makefile Makefile.in POTFILES *.mo *.msg *.cat *.cat.m + +maintainer-clean: distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + rm -f $(GMOFILES) + +distdir = ../$(GETTEXT_PACKAGE)-$(VERSION)/$(subdir) +dist distdir: update-po $(DISTFILES) + dists="$(DISTFILES)"; \ + for file in $$dists; do \ + ln $(srcdir)/$$file $(distdir) 2> /dev/null \ + || cp -p $(srcdir)/$$file $(distdir); \ + done + +update-po: Makefile + $(MAKE) $(GETTEXT_PACKAGE).pot + tmpdir=`pwd`; \ + cd $(srcdir); \ + catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \ + echo "$$lang:"; \ + if $$tmpdir/$(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --dist -o $$tmpdir/$$lang.new.po $$lang; then \ + if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ + rm -f $$tmpdir/$$lang.new.po; \ + else \ + if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ + :; \ + else \ + echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ + rm -f $$tmpdir/$$lang.new.po; \ + exit 1; \ + fi; \ + fi; \ + else \ + echo "msgmerge for $$cat failed!"; \ + rm -f $$tmpdir/$$lang.new.po; \ + fi; \ + done + +# POTFILES is created from POTFILES.in by stripping comments, empty lines +# and Intltool tags (enclosed in square brackets), and appending a full +# relative path to them +POTFILES: POTFILES.in + ( if test 'x$(srcdir)' != 'x.'; then \ + posrcprefix='$(top_srcdir)/'; \ + else \ + posrcprefix="../"; \ + fi; \ + rm -f $@-t $@ \ + && (sed -e '/^#/d' \ + -e "s/^\[.*\] +//" \ + -e '/^[ ]*$$/d' \ + -e "s@.*@ $$posrcprefix& \\\\@" < $(srcdir)/$@.in \ + | sed -e '$$s/\\$$//') > $@-t \ + && chmod a-w $@-t \ + && mv $@-t $@ ) + +Makefile: Makefile.in.in ../config.status POTFILES + cd .. \ + && CONFIG_FILES=$(subdir)/$@.in CONFIG_HEADERS= \ + $(SHELL) ./config.status + +# Tell versions [3.59,3.63) of GNU make not to export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/po/POTFILES.in b/po/POTFILES.in new file mode 100644 index 0000000..9ee5a30 --- /dev/null +++ b/po/POTFILES.in @@ -0,0 +1,15 @@ +# List of source files containing translatable strings. +# Please keep this file sorted alphabetically. +libgnomevfs/gnome-vfs-configuration.c +libgnomevfs/gnome-vfs-file-info.c +libgnomevfs/gnome-vfs-init.c +libgnomevfs/gnome-vfs-job.c +libgnomevfs/gnome-vfs-parse-ls.c +libgnomevfs/gnome-vfs-result.c +libgnomevfs/gnome-vfs-utils.c +modules/file-method.c +modules/ftp-method.c +modules/http-method.c +modules/test-method.c +modules/cdemenu-desktop-method.c +monikers/GNOME_VFS_Moniker_std.server.in.in diff --git a/po/am.gmo b/po/am.gmo new file mode 100644 index 0000000000000000000000000000000000000000..874bf792a620cbd79dea720240dc7af61bc75f94 GIT binary patch literal 1286 zcma))O=uHA6vszfzoPY{f*>dkf>Sg7(9bdh@VNCUG^HEwh{2)`Nlw zn{0w26e=S0QmC|*iq=c<=CLRBRuBfgh~7MS^*@`fO~8XgW`FzMypR8z?3dQ&X@b>? zeFS?E`zUtT7Cf+)L3Q>T+yQ<7w}Wee{R!L&dp+=f19!vz5%4#-7k1NDLR!F9a2H5H zG>Sk>!8a28u)*LhhhH$DcI6X z$Z;?Xs(G)2`#}z>xclHi@ENH3E`f)@)qo#CmG>QloQAb6uyEwhq~=u1pBoHe@4?0h zzDB_B4Qc+Y%2s!*mb#mbbpS7FMt{*ZlaCvDGebwXnYJ?Q6gd%&WNF`(8n4#S53@)| zCmm*!h)8ER!|*32`~iw9*BrtR3ZcWyZ}YZZBh^fAtanWjt#OORy8;KmzwnBYeK zuNkNqPLiZe4Vp0pOFNdBBm-6uGk~J?2P6Crx9;-bbVyjYk)b6s+6^Xb)8cWO<5q!b z<5@d2G?>!51v4D@wI0J^aoVZtQB99&oo8qy8jr-^lrw2z%+Q?yrD+%cJ;y=r*B8|}(lX(P|01zgwrvWH%xw>rcuRa&V{0r z)nc1*N@SJ^Ey3~snmiY$u~E|r5!xobm$Lj+mS0J4h04;hEIp8=Iq5!@ZuP&v1L@7n zswcfA>6WN;XJlnwy7;Yg_mE~!iz+F{BDy}TgAebmu zWmc9RN>}wj1JrorYhCfbrUr*9=v9@gGKYaM3XJ#Y>$h^B`zn{EyFf?qok{PVbl>`V hyeg?LL{%Zz^#yDM&8lP%$$@*pm-, 2002. +# +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-01-07 10:33+EDT\n" +"Last-Translator: Ge'ez Frontier Foundation \n" +"Language-Team: Amharic \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "" + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "" + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "" + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "" + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "ስህተት የለም" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "የፋይሉን አልተገኘም" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "አጠቃላይ ስህተት" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "የውስጥ ብልሽት" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "I/O ስህተት" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "የማይሰራ URI" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "የፋይሉ መጨረሻ" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "ዶሴ አይደለም" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "ፋይሉ በፊትም ነበር" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "ዶሴ ነው" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "ያልታወቀ ስህተት" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 byte" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u bytes" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (ዩኒኮድ ተቀብሏል)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +#, fuzzy +msgid "Files" +msgstr "ፋይሉ በፊትም ነበር" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "" diff --git a/po/ar.gmo b/po/ar.gmo new file mode 100644 index 0000000000000000000000000000000000000000..34f4795845a32de41eea3b9b78ddf113d438e858 GIT binary patch literal 5342 zcma);TWl298OH}o+SH|&B)ud}Lr&YcT#_|5I4N;}U?=&e>(c?#y;( z*5HSzGPZ&EjfXrWkt(IA*qDoPfKr2asFbIw>P5}Nj4D-m=tFu_RVfc`)k^(+XU^_= zDXKDX{GW6CF8}X;&g}0WUiF5;CtXF!C%<^ zZ^1S6e`oPu79V5LgN$zhWqm(?J`3&xKMx)OH-IH@J$Md$0=xr00%qXnz`ug)z<=9* zCqc-3FZda7pT%KN)*l7MPYA9CUjx4Y&e-v{LD_%N;$2Yo{RaFr_<`;J2^9PP1SS6m zNJiE@3X0ve;A3Df_!PJw6u&XZe`kU}Ujb)8$@fR#L*TpM=h1Z85 z3lq*0p!it_%KB}f_}8Flau(bS{uvZ~K1oudlda$m@D)(vdm9uT-UNlW_d$v4FQCM^ zk|N0dr$AZP4=V5|$bVsJ>44l4SOP^5!kFDUw&24&w5 zL9zEUa0N(u<`IrX55mEVG>KXA+)R_W3$*3WHagGIIOgV&97GR&dDr|E-YBQDbJj$ygKQgF_$K1#*COV3{ z?wt-oRn^I{&{Kh1)%Tqay?RAArt4~SJkhb!W6u6mQ&l%6F*O>6Ct@98r!iY|qgb0AFS&^eAyHJXB}Dm>?*(h^ zZdc``#yUy-pd9C(-Gq=jSQzPI5=P@{v>uNy>xy$-ttI2mZXyUvW|y-^GS?^lIEnN3 zX56i=q@MSZFjS*{+1V3DRs6|X6NDT-Oa`sA2avDh}si^q{e)j1#%t8z@1QN);)SJ4fM zx*|EX#>lf4g=ItV@=-Fhx@nCH&ls!viRh^{9w%X~#>l}aOu}N=;QWy0T!cYoye&i- zE!=1H`*lsp!_hdbP?K1pY9VATrwkoChx4w<%N?UK?kFeiaKedmBTo&5fq$IyP~yA` zNy89cb%XJ|YOQW41PNoYGZGvR!V{dxAgt;mdk!Dg`uM>x_RUG`^qTXzARDV+4M){+ zIe?w@=8CYUl5q~X8H($*S{Ol)ocEk~XCy`f)T>kUGv-HOP}PA5Kk_9F63w!VyHz zh0~`{X;l}-N^!@*1H*+~a$_-G;OgKG+0@;=xzN3(u<2RVv$?Nl%hTPAu&{6lt;+tk zb-jg6&&#^r=kj%f+)#z#$PMC(OHKMzf8>@p@6t=Y1NoX)#*v*k9q;j9yGU_KC-zk`@D3AH&oj9#1?05Ba z@HNV2va{J~+GKV%T~O)mY$jb)>Gf=inQ8lRN-r~dJDpAE(plc-^KVo(X>t1AS@Y#$ z@CtTkRJxc=WBlE8R%O%a&1@n&moBCk8{epGN+z0%XYoC)@H3U(V&_bD>SHX$!4%$3 zVY9B9QTDW6@tmDbmvXxc=~V)oa?*LiBDL&HGw+*NArwXWQ({ztWnH?IUX!R*`eV%8 zfQffhdY;!gEX=W5wLXIqI$I}<^()GJxpGr@|J$7zbyebUMh*=$L$=CxsE~w0A@7}%qE9!f;!utovPML*?7$$k zoc&o=o`Djq-DHXA$9TRVhgOI|f06>Urt>1!?2MQ@ZwNEzXSpErq)uUGff%?Oj9*I@ zl7vS#Qx$3=-dNu-Wc%hU=Q_L2P}A+f4}9 z_&bR#F_D+4WmF0!2CQvlJ0X=no&JBriMH};=Bh|~iumNJc?ZXAK9%0OcO~Y{rE}l4hJst-PSmrQO-ih-o61aI&9x%o zPay^)oCd9wQ9_&`2BT^@o-^5LBV7tLBQ-V2k~d~Wtj;neGkuA1Q}$eR#tAn!qjHyF zN=EYfHZp16D&*|k_g9!XUuOtxO7Vlt-W{z$C?W{HQnvUQhCR`z-BbS, 2002. +# Isam Bayazidi , 2002 +# Arafat Medini , 2003 +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-04-29 13:46+0200\n" +"Last-Translator: Arafat Medini \n" +"Language-Team: Arabic \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.0.1\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d يحوي رموزا مصفّرة." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d لا يحوي اسم الطريقة." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d لا يحوي اسم الملحق." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "ملف اﻹعدادات `%s' لم يتم العثور عليه: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "نوع عمليّة مجهول %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "تعذّر إنشاء أنبوب ل GIOChannelالمفتوح : %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "نوع عمليّة مجهول %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "اوقفت العمليّة" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "تعذّر اﻻعراب: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "سيتمّ تجاهل أخطاء اﻻعراب القادمة." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "لا اخطاء" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "لم اعثر على الملفّ" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "خطأ عامّ" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "خطأ داخلي" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "عوامل غير صحيحة" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "عمليّة غير مدعومة" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "خطأ I/O" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "البيانات معطوبة" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "التهيئة غير سليمة" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "توجيه غير صحيح للملفّ" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "الملفّ كبير جدّا" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "لا توجد مساحة كافية على الوحدة" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "نظام ملفّات للقراءة فقط" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "URI غير صحيح" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "الملف غير مفتوح" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "نظام فتح غير سليم" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr " منع الدخول" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "العديد من الملفّات مفتوحة " + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "نهاية الملفّ" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "ليس مجلّدا" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "العملية في تقدم" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "اعيقة العملية" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "الملف موجود" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "تمت مواجهة وصلات دائرية" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "العمليّة غير مسموح بها" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "مجلّد" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr " مساحة الذاكرة غير كافية" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "لم يتم العثور على المضيف" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "اسم المضيف غير سليم" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "ليس للمضيف عنوان" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "فشل الدخول" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "الغيت العملية" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "المجلّد مشغول" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "المجلّد غير فارغ" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "وصلات كثيرة جدا" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "نظام ملفات للقراءة فقط" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "ليس على نفس نظام الملفات" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "الاسم طويل جدا" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "الخدمة غير متوفرة" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "الطلب ترك بيانات الخدمة" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "خطا في البروتوكول" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "تعذّر إيجاد المتصفح الرئيسي" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "خطأ مجهول" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 بايت" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u بايت" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f ك" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f ميغابايت" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f جيغابايت" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (يونوكود غير سليم)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "GnomeVFSSeekPosition مجهول %d" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "لم أعثر على ملفّ إعدادات سليم عند %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "استخدم المتغيّر البيئي %s لتحديد موقع مختلف.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +#, fuzzy +msgid "Files" +msgstr "الملف موجود" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "معاين مونيكر القياسي" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "MonikerExtender لملف" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "مونيكر VFS عام لجنوم" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "مونيكر ملفّ عام" diff --git a/po/az.gmo b/po/az.gmo new file mode 100644 index 0000000000000000000000000000000000000000..a5314710fafc4e87be190d5eece215844dd63acf GIT binary patch literal 5441 zcmai%TWnlM8Gr|R0bJVBmX<jJb+XX-+#{Rt{Yl7 z%J|!v`Df;z|1vZA)Ag61S9~Waw^A;=SE&%*dj)^^{(PlU*TYxf`{3Up|I}Nqei@Co zQ@_e_uj4#?KkYRr@=bU(T!kNmUxC-cZ@|6q2T+#$4ZIuv7TyN`4R3(AGTAk7KimT! zarGLM{&Vmu_#FHQ{1*He{E2IS3Cj52LDAzcQ1o~c=3D(hvA-+fhiJbBirgLWa#(`0 z&ZOfZDD!Nz?DHuoc1+=Q@XPQPcpi$rn~pp1M(TfX{2P?VfyA8^I_Cb+**zpY1 z)X%#5bMR*B--jaqb13WdpzP~qcn5q9ivE|eN$I~1iXBFw%s&NZ;4z4c)z{#M;kTje z??Xt_X{g~B9iMjn>rmu3Apg{l`NNdz7f|f* z5 z|3{(78&^-Etov0cmMUPjZ_~V}tm#XWTROD}S+zZ7I_d}7N zgEIdYATCl>DEcH&=6x25A1}a3_(LdqzYJv`Z$O#<28<#0)=>6&5K8+~Q2bwm`Fv3P zdBO1o$Q0`LuK#r?=gyTFQRMG}(*Fp&6P|QTq0D<8ioQRC;+J1R+289>=J^Mdecebf z$@n{==zkDO|7j?8Xt??_@Cfw_5Z9|Wpy=@y6uFyOO!V0Y3B&xGaXjkClIjFS_AhH3 zpzQu0pdvcR_Zf=JdpAYwCf}o!Pf_lnj8hI#9;R><=ih_;{jB>fXM~&s^2zzOH~&SR zL5WBC_7_l(L9sod@wQLwvPjXCyD0JwZgI zOuFBD93^+=DH0>%uYHs;%0Y_QSw2jhfA=|_gwqs>zfZb0$yqrMAE7)%kvriSMPgn2 zEWVkd$R~c2*j}JaP$Vvt-eaQ`6If3#MYa-q{@rSHe4?rkKUVN)fkmq6^r)vRag-Sw zrTW;?g09p|Vk()Rq~n)%N3jn5tQLDZGNJ#D-LcmS{C;;!m)n`2s)?Lxrc&|KRC|78 zeNW9a8iB2t%*Iiw9y6Y>8TO4Rw%es^<3{cXQ20m^w1Spz4D3)V!K^0n0X-Qld}Ir`l+*Z$q_Uqk5_q;$<7@ zs$t_EmAD}`!4~yY`%wiaGnAf11k_@j5IfFp`EF8u&IW-l``Ru?^m^m!nCw6-6U5Q7 zIu;Y2RnrPGO%4#6+N5b*u|%OKorO*KQN(GIN9EF~1)WxEe&~xx+AtMg2Yxlv4EOvM zTak7q+_f30`%&Clu8~n8A(BfVpVfSwib{Dlq-}yTRL3RkL-Kf+scCb;UNKR{55ykB zHf+>L;^o{?yIZl2i{fFc_>0Lxo5?1J?P(S_8nm29;w-MjeXpJJ$<;Ut+HX@)T1)TH z+HCoRPFzmo0I#N+920|#aSV`E>U2@f_hnXankke0r!(T7wAPDpWb0&S6=#T%&fq6< zqFs1=SdGO%VzE@(f>bR<^(a2aSrNsd|M;QPr+vSEB2I1Y(ot{FU-+{xeKs!Zx*Q6l zt${?`&{><~CvQqyjYgbcCOL@;^Q)zl_`z$V5`il=iKEbuB$pB^n<2Ic3BO{i?K}di zRRWa$ATG|n@e%bomgMwNxy#*_=TL%+0AO~;SS&CHIQwUHCY&y)_z*-C$j(R`i49w2dCE zo5W{B;~Z@dk1UvIxn-99(iz``(|TsjPs+xgHIda1<|;pG)`-bMcyWGlZn&d~@%CDhji^1f?!|hT zcDL5_lPyded;jOUlv}da>m=2HKNfX8vua5X&Z_>M$ac9UjkmoSZEyDbGi)&skc;wN z1h_U$JCj>eu>I4DS?hIlJ6`o#i8|BkjD8 zMrfM4yVc$3ZbiBrCoSFPkVUn?a2*6FmEUqlO_I-fl1p@Foo=p$d|Eb;U!|F8494_2 zp3O(S_fD-Mtsp(5a)bZ6;RID->L1c^tExB@5``TkTMf#xMiosswzRrCTbhmV~ zm29uK`ifk-z=%2-uLP~84tt%Qbp!*kk!vf*JL??4ZLWetVxBaPT8fBF^a>Z8IIrI8 zM4|>KQQpozvc&4F*Qo`CM=z1e=Lx$PS1K(}R?6#_Dpj;%`0dT+?)AGH@v1I&FSff| zb+5Zsj21T*`pU1J@AW!$Rvv_8F4z5T*b1#v^hplJ?afdI?W~*ab?h~;Tt7&T3?jOj zOEvRIb3>Z{?WSU`rf49yb#9S#dsEFyVD}duPP)W}J*>GaI}ua4t%zxkb}uH4?pEG< z*d`WVlugAX#84>Fr`2rtVzk`rut1r8u((rW5p_gAk!#D6NWAe}iskqD zs*lC{SyLodcf$=6A{K5Et8H#5H?;7ibNW$BRx+_>K@a1Qcb-RX^@Zo!oE?Y| znY`dwFG9+VosqPaJHItdg(8#*RIwTP#wF70Y_G4#$rE^1LU_<484|N69rc9kaLMP)bejE`6+3t+_+z2r23j?dk@)RCBN<0<$#txb z;06wUj7-KzF1i#IP1WOu*Fhc_iM$DmL+V}M4?~IK^cdDxdYv^}#g-AV%lXB-Vc5xI zV%W@%WoLDXMb;xyBHfQu{zJ60-Xs8+q{$lsb=q8~euiLu5SE;oVRx%$F_(n#&N@@b veZ(&&Wve_cPS92%_}tcVuedh`5B, 2001 . +# Mətin Əmirov , 2003 +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs.HEAD.az\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-08-21 15:33+0200\n" +"Last-Translator: Mətin Əmirov \n" +"Language-Team: Azerbaijani \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d NUL hərflərini daxil edir." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d metod adını daxil etmir." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d modul adını daxil etmir." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Quraşdırma faylı `%s' tapıla bilmədi: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Namə'lum op növü %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "GIOChannel açmaq üçün boru yaradıla bilmir: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Namə'lum vəzifə növü %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Əməliyyat dayandırıldı" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Oxuna bilmədi: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Növbəti oxuma xətaları diqqətə alınmayacaq." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Xəta yoxdur" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Fayl tapıla bilmədi" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Ümumi xəta" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Daxili xəta" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Hökmsüz parametrlər" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Dəstəklənməyən gedişat" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "I/O xətası" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Mə'lumat xəsərlidir" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Şəkil hökmsüzdür" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Xəsərli fayl idarəsi" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "Fayl çox böyükdür" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Avadanlıqda yer yoxdur" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Yalınz oxuna bilən fayl sistemi" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "Hökmsüz URI" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Fayl açıq deyil" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Açma modu hökmlü deyil" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "İcazə yoxdur" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "Həddindən çox açıq fayl" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Fayl sonu" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Qovluq deyil" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Əməliyyat gedir" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Əməliyyat dayandırıldı" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Fayl mövcuddur" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Döngəli bağlar tapıldı" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Əməliyyata icazə verilmir" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "Qovluqdur" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Kifayət qədər yaddaş yoxdur" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Qovşaq tapıla bilmədi" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Hökmsüz qovşaq adı" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Qovşağın ünvanı yoxdur" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Giriş bacarılmadı " + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Əməliyyat ləğv edildi" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Qovluq məşğuldur" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Qovluq boş deyil" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "Çox bağ var" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Yalnız oxuna bilən fayl sistemi" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Eyni fayl sistemində deyil" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Ad çox uzundur" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Xidmət mövcud deyil" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Dəqiq xidmət datasını istə" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Protokol xətası" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "Əsas səyyah tapıla bilmədi" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "Əsas gedişat əlaqələndirilməyib" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "URL sxemi üçün idarəçi yoxdur" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "Əmr sətri təhlil edilərkən xəta" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "Əmr verilərkən xəta" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Namə'lum xəta" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 bayt" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u bayt" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr "(hökmsüz Yunikod)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "Namə'lum GnomeVFSSeekPosition %d" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "%s ünvanında hökmlü qurğu faylı tapıla bilmədi\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "Başqa mövqe tə'yin etmək üçün %s mühit dəyişənini işlədin.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "Tə'minatlar" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "Kartlar" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "Fayllar" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "Qovluqlar" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "Yardım" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "Qovşaqlar" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "Körpülər" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "Poçt" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "Vasitələr" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "Pəncərələr" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Sıravi Moniker e'malatxanası" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "fayl MonikerGenişlədicisi" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "adi Gnome VFS monikeri" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "adi fayl monikeri" diff --git a/po/be.gmo b/po/be.gmo new file mode 100644 index 0000000000000000000000000000000000000000..2e0b943ee7eda3b0dff8c4f1240b97bf8aa33871 GIT binary patch literal 6860 zcmb`KYiu0V6~~8$Kx+uEzIl`j#pD6&tP`Ndi4&Z+n)=3=FBu*j(RYgCb*|w_MioQgvzCQE={Zgr_`upFRU9S@( zzI5d4|J*z0o_ikub7uB;H(mLX!}T!ZR>rFzahxJ}?`-~Y{oyLdxe5Fucs2MhkU!@? z>3kN8pJRSaiVITg0YA$6ASn6A!8zbA@LF&$cs=+cxBz?w)RFIi^TA($w}Jl!KMvlC zvg^PsI1gN&&Ids~-w9p=j)I>CUj}amf0(ZS6x9A-g0kb!pzL@bw61iLbJ;?N38e+SqN zZURZMvmg8f_$^TWy_U{@0={#FuH+J#aqwKB)b-5w!K-a!_#`1r7KL zDF5C9WzTQGCE#qFR~))Q)k|-R6;S@Z2+F?KQv4A(m-(BZ;`t8{*PLrm@_F!Pa1po+ zG~nZ)_8$Q61`mVU_ZF!0{sb-rXAxv>oy8!oIBP)zJ__Ck4ujJ318^I722|YV;M7`h z5h#D30GERYzzp~^kPte~rxJf|03T$!08}3GpzJ;j%C9%TR`74&Jn(vy%H9r8@qH9j z+@DDCO;B;X7V>G|I#B)xp!&oyQ1QM9Do%e-=l=$!?=FIT54a}9GAMtKfZqUr4$ALs zkb*7F*FfcaCn&wgz$-vq-3i$I>sImH!VquNLl-leFWGHl13t*WWvd&P?DY`;WsB@< zW2|8;W6+B2wUqx~Oz+hr)CY87lC@3uvlw5{4Ocb+X9b8`HqYsj1;t|{!!VQ+U7H!J z8LJqIyK^iU|h|BhW1j7?oIEN59LCaa;Zz4=waN+fEt#2%KJ)&@}moC+3Wrk z9|k)avl-&BF4egBC$4odlF>1<%MGt_?^GtUopxCK9NdILWf z=Dqn&Yg>E2S-T>^^$Bcb8g;hjO)d;7t{+5ZQ||_o8+6NVuHu!Wwo4xep(%Qm!7y(E zx9H9IILucIUj1>^^bJ?M$Z5Cebmwwj6q&pi_+H-WE|m&?&aL=i5IHN{yy^GZIp_xY zg6FJsgCMM!T-kFgo+0{KiAK6EbDCC7!4EuVjY8(_@}o+W+&5gEnkr_=tP+N%&mXW8_#x?nR44n;rFcdi(!T~=p{VtB@nS>?9gjftk z#tU*JnXNq8h=8*(EW@2NZq}Q~?DPu-)8`p~AmC}f&DkUm6q!O83^rh zVRc}TiYh`8D}j7v&@+)tvegg`L(ZbJS+p-w$4#MTEhT%-4RT&V@t9g8Mx}B%U=!86 zN_0{dPpv9nC@cCEIXSf+Rl-tS ze(X|IEtSGDVNxeb!teA(@Q19mih(=)au^i7K($o%lAGQqW?}wl~FN8_& zYin`7#F2C#$EG}WdG)S}7f_$hKw6E~6N4)d!3L%A#BQrElB~yQI+>n)<`Ier26q~$ zUi30M`XjS$b@!^4Et|JzR;sb`Fhg&n$t}ue7iY2^nML=T_Qjp;9rt8eK`^rw`bxg&gxNIg4h_1)xxwKfvovt~9x9UFw!YzI z$Oi*ecfiYR_uOKqS>YAjay9bZz%2FKJA#Lb;SRSgEDtPe+1Rsj^^_m&ZP^z3Jb~dj za?)uk-mc2RQh|5Z68qkw4R`f!Uz6#Wl9O44JhPhakf&L6nvOod(z4Z4A~PGK0Y9Hv zQ5}df+rv)NvZcT)q>xchj5on&Sy_Mdlt=K((-7=w%jCk>sPpaUcqGB9&CG{ zg*SP8K0a03U32&RC_8uUmG>G7l1?Y+4w>{@geW_+DL5=`$yx+_#9hK#N+WP z`<{}$f zka0wu`IL3qTH8l(Fes&GSh+_iBC>ewd?@qdHiCxMZ|ZA9$i{pTLOJu>%O7W-6XaTGUIu5lN`Fgi0dsB}XUf z6)hTt@=3Sg*49|F+Pc1J(Mbf($;s&{tQ|p_?HdbGIBMCG5L)G8b277IhpkhWSqW2n z`P{TsKZ6q#d=ew8*|s`$0VjSj>3W7U)ru_(j@j~fDrq)K$}2Lj_KfUJ<0q~iN9hp? z0MhQCDqUMNRNW}L$Td2tA`U0UD!L}EN8#kYq$>6&b(Hpr>DjCuN+{Yy;^Sn1VA(DK zolaT~sO;4R?Qw02L?dHL-h@t4o4Y{h;XT!c`!f8J1|=E7i?fr`tF)emX5y|moGwjJ zqGOyT{+&u_3#XcCNEiG7{Ysu~P1csQvnBl(W1b$pYJo zBu1|kFB2juO8+-SFQXMFYI|&U6B^hI(Tr-(BwTOEA zK}^1?;-li0da&r9kWvLobzALYANT{w@^`wZ%xHdf9L9l$gvw0s{)yx*tJaW4O~0IY zUD3Mh2RF$o_RqsceSeISbIHz3M;%UYvi>xE%GQ~Fz!pIA$(B^UUL5+q+-qAx!h4mb zjq?kX6|o=VXuVvX6W8Dwzu~yk2ObHg$0wak%}Yy%fPE~|74>Fpq>rC)@d5Ol<@u;n g?+o=HuZ>@F+KJkxcX3nJQQ7!~=X{uC{Rm3@e;6h%djJ3c literal 0 HcmV?d00001 diff --git a/po/be.po b/po/be.po new file mode 100644 index 0000000..3164330 --- /dev/null +++ b/po/be.po @@ -0,0 +1,477 @@ +# translation of gnome-vfs.HEAD.be.po to Belarusian +# Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc. +# Vital Khilko , 2003 +# Ales Nyakhaychyk , 2003 +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs HEAD\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-08-14 10:10+0300\n" +"Last-Translator: Ales Nyakhaychyk \n" +"Language-Team: Belarusian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Report-Msgid-Bugs-To: \n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%" +"10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: KBabel 0.9.6\n" + +# libgnomevfs/gnome-vfs-configuration.c:223 +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d утрымлівае NUL знакі." + +# libgnomevfs/gnome-vfs-configuration.c:240 +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d ня ўтрымлівае назву мэтаду." + +# libgnomevfs/gnome-vfs-configuration.c:269 +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d ня утрымлівае назву модулу." + +# libgnomevfs/gnome-vfs-configuration.c:322 +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Файл наладак \"%s\" адсутнічае: %s" + +# libgnomevfs/gnome-vfs-job.c:714 +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Нывядомы від апэрацыі %u" + +# libgnomevfs/gnome-vfs-job.c:1005 libgnomevfs/gnome-vfs-job.c:1150 +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "Немагчыма стварыць канал для адчыненага GIOChannel: %s" + +# libgnomevfs/gnome-vfs-job.c:1596 +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Невядомы від заданьня %u" + +# libgnomevfs/gnome-vfs-job.c:1632 +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Дзеяньне спынена" + +# libgnomevfs/gnome-vfs-parse-ls.c:652 +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Немагчыма разабраць: %s" + +# libgnomevfs/gnome-vfs-parse-ls.c:654 +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Астатнія памылкі разбору будуць ігнараваныя." + +# libgnomevfs/gnome-vfs-result.c:35 +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Няма памылак" + +# libgnomevfs/gnome-vfs-result.c:36 +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Файл не адшуканы" + +# libgnomevfs/gnome-vfs-result.c:37 +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Агульная памылка" + +# libgnomevfs/gnome-vfs-result.c:38 +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Нутраная памылка" + +# libgnomevfs/gnome-vfs-result.c:39 +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Недапушчальныя парамэтры" + +# libgnomevfs/gnome-vfs-result.c:40 +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Дзеяньне не падтрымліваецца" + +# libgnomevfs/gnome-vfs-result.c:41 +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "Памылка ўводу/вываду" + +# libgnomevfs/gnome-vfs-result.c:42 +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Даньні пашкоджаны" + +# libgnomevfs/gnome-vfs-result.c:43 +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Нядапушчальны фармат" + +# libgnomevfs/gnome-vfs-result.c:44 +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Памылковы загаловак файла" + +# libgnomevfs/gnome-vfs-result.c:45 +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "Файл завялікі" + +# libgnomevfs/gnome-vfs-result.c:46 +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Нестае прасторы на дыску" + +# libgnomevfs/gnome-vfs-result.c:47 +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Файлавая сыстэма толькі дзеля чытаньня" + +# libgnomevfs/gnome-vfs-result.c:48 +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "Недапушчальны URI" + +# libgnomevfs/gnome-vfs-result.c:49 +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Файл не адчынены" + +# libgnomevfs/gnome-vfs-result.c:50 +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Недапушчальны рэжым адкрыцьця" + +# libgnomevfs/gnome-vfs-result.c:51 +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Доступ забаронены" + +# libgnomevfs/gnome-vfs-result.c:52 +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "Адчынена зашмат файлаў" + +# libgnomevfs/gnome-vfs-result.c:53 +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Канец файла" + +# libgnomevfs/gnome-vfs-result.c:54 +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Ня тэчка" + +# libgnomevfs/gnome-vfs-result.c:55 +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Дзеяньне выконваецца" + +# libgnomevfs/gnome-vfs-result.c:56 +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Дзеяньне перарванае" + +# libgnomevfs/gnome-vfs-result.c:57 +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Файл існуе" + +# libgnomevfs/gnome-vfs-result.c:58 +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Адшуканы цыклічныя спасылкі" + +# libgnomevfs/gnome-vfs-result.c:59 +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Дзеяньне не дазволена" + +# libgnomevfs/gnome-vfs-result.c:60 +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "Гэта тэчка" + +# libgnomevfs/gnome-vfs-result.c:61 +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Нестае памяці" + +# libgnomevfs/gnome-vfs-result.c:62 +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Вузел не адшуканы" + +# libgnomevfs/gnome-vfs-result.c:63 +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Недапушчальная назва вузла" + +# libgnomevfs/gnome-vfs-result.c:64 +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Вузел ня мае адраса" + +# libgnomevfs/gnome-vfs-result.c:65 +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Уваход ня адбыўся" + +# libgnomevfs/gnome-vfs-result.c:66 +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Дзеяньне адмененае" + +# libgnomevfs/gnome-vfs-result.c:67 +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Тэчка занята" + +# libgnomevfs/gnome-vfs-result.c:68 +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Тэчка не парожняя" + +# libgnomevfs/gnome-vfs-result.c:69 +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "Зашмат спасылак" + +# libgnomevfs/gnome-vfs-result.c:70 +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Файлавая сыстэма толькі дзеля чытаньня" + +# libgnomevfs/gnome-vfs-result.c:71 +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Ня ў той самай файлавай сыстэме" + +# libgnomevfs/gnome-vfs-result.c:72 +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Назва надта доўгаяы" + +# libgnomevfs/gnome-vfs-result.c:73 +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Паслуга недаступная" + +# libgnomevfs/gnome-vfs-result.c:74 +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Запыт састарэлых даньняў паслуг" + +# libgnomevfs/gnome-vfs-result.c:75 +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Памылка пратакола" + +# libgnomevfs/gnome-vfs-parse-ls.c:652 +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "Не магчыма адшукаць паслужнік прагляду" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "Адсутнічае дапомнае зьвязанае деяньне" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "Адсутнічае апрацоўнік для схемы URL" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "Памылка разбору загаднага радка" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "Памылка запуску загада" + +# libgnomevfs/gnome-vfs-result.c:137 +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Невядомая памылка" + +# libgnomevfs/gnome-vfs-utils.c:65 +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 байт" + +# libgnomevfs/gnome-vfs-utils.c:67 +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u байтаў" + +# libgnomevfs/gnome-vfs-utils.c:74 +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +# libgnomevfs/gnome-vfs-utils.c:78 +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +# libgnomevfs/gnome-vfs-utils.c:82 +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (нерэчаісны юнікод)" + +# modules/file-method.c:381 +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "Невядомая GnomeVFSSeekPosition %d" + +# modules/test-method.c:590 +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "Ня адшуканы правільны файл усталёвак у %s\n" + +# modules/test-method.c:592 +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "Выкарыстоўвайце пераменую асяродьдзя %s для указаньня іншага мейсца.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "Дастасаваньні" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "Карткі" + +# libgnomevfs/gnome-vfs-result.c:57 +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "Файлы" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "Тэчкі" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "Даведка" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "Вузлы" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "Спасылкі" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "Пошта" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "Прылады" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "Вокны" + +# monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Стандартнае мейсца мянушкі" + +# monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "файл MonikerExtender" + +# monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "агульная мянушка Gnome VFS" + +# monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "агульная мянушка файла" diff --git a/po/bg.gmo b/po/bg.gmo new file mode 100644 index 0000000000000000000000000000000000000000..6a583f59f69adb40a6017e1d8b416e450ded3e39 GIT binary patch literal 6077 zcmb7{Ym8iF8OKkRn+uAfAb5e7%32DY?JjMxEZ4TQWo5S|y%7DPoS8W@d+5wL<2h%x zT@$4jfzlX>ToQy(5Htqkhi$vdZoA#>7rtr88BI)x#t=WL3EzxCqtW00J!f|IGDtY> zng6`E=Y5|4^MBrV_D@$`^t{8fjrU8u8$aea-voy*;)7@6V#m1(JOy3~z6D+a{w8n# z4!oZBA9DOxj@L2iGWs`zn!kmQPl6ACSAq|Nw}2IJE%;;b%it{dS@0e3Q{a2x&EUWD zb}vq7d?R={_&|>PK+S&y)IK421^7Mi)8L7`|0PiC-^g(e)Vdb<3Gm&#{Wnnd{|PGo ziwQ>at_5Xx4R{^65xfc91!~_Iw;UrgW%`Dv!LR9J8%C59A4!({{f|!uR{hDIaQDpIbq%&18=7NeQ*H$MUL-);^}fe zFyUMW-U!|Vt^s#|RWJY_1b+|S3$7-ZTfrhIo%{&Y_^-gPg71R`@CL}f1{?upw+wy- zd?LqRg4*Y8P<;FYRNU7f5(BOSxwV=Z}2I&U>KpbTvu32P}Xa zz#8a*uY$ecC6KIr)`45Wt)TdO928Hlft$czgLi_fNRHOs4QjlUw|@w(r+pff?*0ra z&Pz$wW^iqeMNs>{1g-^FvH9KLt>7)7pSPa_*U|nhC_DcJ#p8{TsC{;WTK^dMH24N6 zeceIO8^Jx`Ch$pc6)0}>=uEhjSDYw+vY~x8@Jj#MWAP*3Zs(PT^eETjcTkP|`5H)? zEr0F4Hp8h8LKfL%X*zE%0iCrZ;xBg+axyHX}Fj!yq&A zNN>Ex9CTwN8z8aKseJie%@&Aoaf8F#khL0GY?oE?hX zJLJbnoPA&LyVF$YSt|)cQ}nCOjxegTpXORuoSk0aMSjV6Q4~hb17Vy%r${hvxg5cE z)~9qWT4m>THXK^NJ2x;CKu_S-7Mi(=_6#{gxuReSW0Hq66dTu++i^R?Vbv!aE|HaK zgbg?{H9t5I8!sr45*9Hs5=NvKzBO$9j?F>8Rx?G<_|<^Xa-XwH4lC+f7*w5IVeSxL z;)YxDOwFq#hTNCEF~8(7Az9*z+FlSgtD^|EPEza)<|m_`iDla=FCIq@b!WFER;NrB zQAA%ZuaX;-yqaR_^buzx3aggj#l1wB>!#Byo-tPU6X~hbA17g>LC-@`n1rRU&G{aW zx(I{X_!1Y@Tj{_l$UFe~bjkSFiLl=0{;r_W}t&@)ZX1 zKnz~VuZ-K=S1QPh@mg52=R#kPW0RZ*x&2V$1!ao9nwN}?zz_ndw=^t_*k$cb((@>V zT^K4C9!B&WID-b2*1f`5CGL4>_rAh5omli2I662(ZtL&gQ0U)WxNVae*f2P-`PP1V zm{{0@R<(Y~yn(_1^EM6k-=57I=7cKji`*ctx#VQfY^iyNNEcb!I~q2^F>{w&`*v)< z-Z$=!hGAbRtl!f!>;~1QTlEV2Jhwh*wl-^3@f4W5%6=)ik1}i?>icdOc*SbAU}R`y zdnclSzWyFgRVZS2vNC8A?@+S7QR7;;(_RT2dUx;Nx1+GRGf!SZdSN@&U8b4`&E}$? z^n9aWPo>QL2e-OKuV(uD?&!O{hl?pa(>k0^wT`D#>6~dDOXt#=^jtchPJYN0)jHBT zkxsTwu=>q(!d_IZBdk52o@VuII@7+5usCIw&9?KV3_}x!6;rLF+VLZ-U^c$avZ86y zQ|Ux{784WPYwd=UK9|n3>ruSCfR{&2I?c3GxH}<_(m5x6i5bTg^Evt$#l%!PYtnP9 zId57&klA$BNna)ayqr(Z$lXakY&g^U%0%oR)}S>_Fz{$C5}d4I*s#%2c$sJ&Zar=J zu#qpjMAH|sGRL+v*g7U_tta?SAOB`rPZLAiC$qXYUM>1?EThq~NFviYduev@+4^t} zvzU@YM_4|OQ`R=T*$t1S(@JT#n2E+lgiF)d5Rd1xyxfl_&74?03zgVAZLf54s*R_}5Q5>GWkvjAU+I;QCY1UQnARpt8B@v$ z$Vp$cjkB2=+YCGD&zM2_t#*{})>D{AP=tC+-Y=bjsV=$rfH|2O6oA#?;+?Q!w@_Wd zra^O56RJ6HnOsSmtels2o%AG0d`fJzOB!7}>CcsG)q!eYPL?!ff&yau))6Ot!DTr z&!8DAunQ_CqOgYt-w@jKlHH2LJLxl4XOaiuNH~&{&MKSDsf<0j0o$5!jIj%#oFmwi zEXm5|C`x3EnK~>~o98f{E1m-2*qD}Fo%E-+e^S{ZBQsb~CiB3oprt@`y|Si6xum9w zq>gtK31*#6bEU4GTVdfWtr<(QA%u)=@{mO%}-zag2ZL%a?)3! z{Y_{&pUYZF>2k)xBL6$;wdHowW)~WjLLIAGtbFKPIRPQ|RCs}0a&f?-Y9{vqWAjT_ ztLh|{4>Q+wmU6BC7qB{Q^N`7j{B)hKdsLp{koEBuwzbJXb-Hs`7E^w-bY)S-lm-&5 zJBr+>Iwa?*g>&npFMQ6*6M@Q>O$s+GJI!)xo{$r=&l3Fr&>1OFSPR51!tJp~AAf1A%hai^j_cfvtf3rq7*5Mf`()95ApYcuww~vh t&`yNP-ydz(+ka>+{0*`~5|*%MS%|ClZxZ}orVpq4q80P<$nu0c{{sT-KLh{( literal 0 HcmV?d00001 diff --git a/po/bg.po b/po/bg.po new file mode 100644 index 0000000..d47c92a --- /dev/null +++ b/po/bg.po @@ -0,0 +1,411 @@ +# Bulgarian translation for gnome-vfs. +# Copyright (C) 2002 Free Software Foundation, Inc. +# Borislav Aleksandrov , 2002. +# Alexander Shopov , 2003. +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-01-15 15:06+0200\n" +"Last-Translator: Alexander Shopov \n" +"Language-Team: Bulgarian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 0.9.6\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d съдържа NUL символи." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d не съдържа име на метод." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d не съдържа име на модул." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Конфигурационният файл \"%s\" не е намерен: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Неизвестен тип операция %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "Не мога да създам програмен канал за отваряне на GIOChannel: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Неизвестен вид задание %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Операцията е спряна" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Не мога да анализирам: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Следващите грешки при анализиране ще бъдат игнорирани." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Няма грешка" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Файлът не е намерен" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Обща грешка" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Вътрешна грешка" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Неправилни параметри" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Неподдържана операция" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "Вх./изх. грешка" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Повредени данни" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Невалиден формат" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Лош указател към файл" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "Файлът е твърде голям" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Няма свободно място на устройството" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Файлова система само за четене" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "Грешен URI" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Файлът не е отворен" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Режимът на отваряне не е валиден" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Достъпът забранен" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "Прекалено много отворени файлове" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Край на файл" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Не е директория" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Изпълнява се операция" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Операцията прекъсна" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Файлът съществува" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Открити са зациклени връзки" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Операцията не е позволена" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "Е директория" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Няма достатъчно памет" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Хостът не е намерен" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Името на хоста не е валидно" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Хостът няма адрес" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Влизането в системата е неуспешно" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Операцията прекъсна" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Директорията е заета" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Директорията не е празна" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "Прекалено много връзки" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Файлова система само за четене" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Не е в същата файлова система" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Името е твърде дълго" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Услугата не е достъпна" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Данните от услугата са остарели вследствие на заявката" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Протоколна грешка" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "Не мога да открия основния браузър" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Неизвестна грешка" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 байт" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u байта" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (грешен уникод)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "Неизвестно GnomeVFSSeekPosition %d" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "Не е намерен валиден файл с настройки в %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "" +"Ползвайте променливата на средата %s , за да зададете различно " +"местоположение.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +#, fuzzy +msgid "Files" +msgstr "Файлът съществува" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Фабрика за стандартни псевдоними" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "файл MonikerExtender" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "стандартен Гном VFS псевдоним" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "стандартен псевдоним на файл" diff --git a/po/bn.gmo b/po/bn.gmo new file mode 100644 index 0000000000000000000000000000000000000000..cf88a5ba1ef9d462dd981819a98d25451fb6c9c7 GIT binary patch literal 6695 zcmb`KTaXl28OPg5B3aRxXl`DTW6TN!X4zdJk_{oia@!Ji2@6#D5R2ZKp4o<(?y)lZgMg=Lj_@LJ{XJLk;K^s)r4 za*Ce+oO8bW_y0~Wzq@PBVTaEk&nJ17-QqZ305{L!i_fK79p^6ab?^h=+u&{BPwe^~ z@B!Apw)hW=_aiiy{S~0dui@)M;3n`6a3}Z(SOyn@-v&Pg{t)~q_)GA^;5Bdo_%FNe zCI~rS27VCSWN|wv^1DFs6N2-=uYex`U$FZ}LDB!d#UFv9_jB-eFth7FfnxvfpyYom z$%x#2pxB)c-VZJV9|ng(@f(Bua}MxzFZco|`JM#t1gF4HfNz5mM`rO|@NU*~2}1Az zQ1q99qPH0o|6jD{HH%*d75m?@>mPvkvHlq-@_z)y&)>iY!FgRK&c&eY4}g;2FerXq za1FQ*{22HqD0%+WuKxh8f1l(08|-F(kYb3w4@$khY}e0$i&-B9H-SF}p9JruNK%id zK;>;7IjO@YZ~^!r6F`2c8z=yyxD0O-sd%6Ft`HT zjqq0R6xa{G3qlLsQ$XJdjE?S^^j&HyewXqH|D`9LABp8r9>!dM7V#}{4Vb0={v6-X zz**a|*ZL{33J;)-1z)%G$n~ap?%LA>1eQx20^bpGH z9#CpMV=_;V^T_A3JhV*L;^QFKptGDuI3jZ)J($PyX&&jne3tP%qJJ6g2|tBn!bjSr z=l}hn@J&8ze-6d5FgT(cNSPk#k ztcv4q{l9* zoA_a1jO^-;=c|2gti(n+Yy>4M*{Bk&?D;`S)!dlG)L0bmi@gXtt<$<2#h%t!=O!)% ziK0e5AuN&XG0j(@F%i56lbFsc#&UJUKE9qvnh-d$|*%q zZmASeZL=rs>d?}1ZHGfkMy!FMfbs-xb$V%8v~9>4vW%iq7!!IpL$PvIsg<|0Ijs0} z!zHs4i?B|ORMijm#L5ebv;-wiwuBMwrQUL^?=KjOMu^iO?L?*)7bn`=y3Q%fqoatkRQM!D=bUe5MQ@JELZ)^K$pn8F!3H8%>xv zH!7(uVc_p!9?HzS6lpsJuerg5=~{akN`a(ev9lxC6NLMi$RMnFJ2#AudfuL`VeIQk z>@H288$!0EcZXwYj|^aUV_G7tt7L*9*IRL;UJoM*B=c?x@9c=70R8F~{_ORmFsONf z5I^!I4d?+GyrN&8(7i90p%>@Xu&D2ao-Ri>*(SMuf8qrthQ4A)MrWW%f!6CXOrL1A z)+X)Q&0rUXN`;+}o(pF{Z5$rivc9ml9CvLU*e7<|HR?{dHA>e| z>)g1)rR1uWjiBb1WN-CoSmr+FE)Kk870N-S;a0rDcF(O1sI^{D;VqyRj0FqTN=B>Z z6%uQjI989D^PsW6CyXkqy0#3F)pU}5J-uCAv{a3NXw-m8y#2|NdX+cDbmEQm&WwY7B^?bh#?vh>3AvAn;s^fbrV#M<{b`34@c=C`u+N|s(?`(TzH)%rPM zL~weR^H;U-rIr>yu4c{2EPczUW0hYQw0+5eKyF~@0!fInWHzPq75B5~H`pdU%wliS z$(qd>8|lfcc|ZbcrIu=QhfG`uzljHH+tEU#dr9jMI1!N3*Ypnir

t8)P8gQkIL_ z^F`}Hc1~mJTq~Zbf|zd$p4GoeYzj{=>#9v5i;8U&^?eqdLp-nK^~i2Y-l|zj)1($? z7;_g{bauej;#Ib3=5rEydR5EFFL8E6SD=-&QjRVU#U*eOKBB{?1o*sc`r6J&?cx%V zqKKPz5%VS`(D_)spi3u?;4H-v|Dq)|zg&bo{-;RN4XRE=waW>t9#$ zhvHb&;H4CWUlb2oNC%**Injmcw8{2+^TU}Tof`#06x%r&T>%M%dY{l0IiVLK2}On8 z6y_K@0F-YU(V4B$mL*y4wez|xuc2bd*wkwnD)-oVO-Y$jSOJ?%v4tLnwQV*WH&oEd z(8<==CXiFctO%Ia$Vz)w1hG_d#14x$GKKq@@}L0^uKdB#6(Ur zH`?%%fQ|f_Rs#7!FzuCknbc@HE~L)0-p?&Qh{7wHSGLjCjtR$@Y8sE%zyGPH1aY0F zVL|RiO9oUKGEgN6EthL9b~ArXM-vS8LOa}O0_neK&}3Na|2=<%-bmUqij+vfjH~5~xIsXATzv!3% literal 0 HcmV?d00001 diff --git a/po/bn.po b/po/bn.po new file mode 100644 index 0000000..cf3ed8f --- /dev/null +++ b/po/bn.po @@ -0,0 +1,411 @@ +# Bengali Translation of GNOME-vfs +# Copyright (C) 1999, 2000, 01, 02 Free Software Foundation, Inc. +# This file is distributed under the same license as the GNOME-vfs package. +# Sayamindu Dasgupta , 2003. +# +msgid "" +msgstr "" +"Project-Id-Version: GNOME-vfs\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-02-12 10:19+0530\n" +"Last-Translator: Sayamindu Dasgupta \n" +"Language-Team: Bengali (bn) \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%dতে নঞ-অক্ষর আছে" + +# msgstr "%s:%dতে নঞ-অক্ষর আছে" +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%dতে কোন প্রক্রিয়ার নাম নেই" + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%dতে কোন মডিউলের নাম নেই" + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "কনফিগারেশন ফাইল `%s পাওয়া গেল না: %s'" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "অজানা ধরনের অপপ্ %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "খোলা জি-আই-ও-চ্যানেল: %sএর জন্য কোন পাইপ তৈরি করা গেল না " + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "অজানা ধরনের কাজ %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "কাজ বন্ধ" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "%s-কে পড়ে কিছু বোঝা গেল না" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "এরপরের পড়ে বোঝার ভুলগুলোকে আমল দেবো না" + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "কোন ভুল নেই" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "ফাইল পাওয়া গেল না" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "সাধারন ভুল" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "অভ্যন্তরীন ভুল" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "বেঠিক প্যারামিটার" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "অসমর্থিত কাজ" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "আই-ও ভুল" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "তথ্য নষ্ট হয়ে গেছে" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "বৈধ বিন্যাসের অভাব" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "ত্রুটিপূর্ণ/সমস্যাযুক্ত ফাইল-হ্যান্ডল" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "ফাইলটা বড্ড বেশি বড়" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "ডিভাইসে আর জায়গা বাকি নেই" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "ফাইল-সিস্টেমে লেখা যাবে না" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "বেঠিক ইউ-আর-আই" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "ফাইল খোলা নেই" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "খোলা অবস্থা বেঠিক" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "ঢুকতে দেওয়া হল না" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "অনেক বেশি ফাইল খোলা আছে" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "ফাইলের শেষ" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "ডিরেক্টরি নয়" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "কাজ চলছে" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "কাজে বাধা দেওয়া হয়েছে" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "ফাইলটা আগে থেকেই আছে" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "আবর্তনকারি সংযোজক পাওয়া গেছে" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "কাজের জন্য অনুমতি নেই" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "একটা ডিরেক্টরি" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "যথেষ্ট মেমরী নেই" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "হোস্ট পাওয়া গেল না" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "হোস্ট নাম বেঠিক" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "হোস্টের কোন ঠিকানা নেই" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "লগ-ইন করা গেল না" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "কাজ বাতিল হয়ে গেছে" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "ডিরেক্টরি ব্যস্ত" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "ডিরেক্টরি ফঁাকা নয়" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "অনেক বেশি সংযোজক" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "ফাইল-সিস্টেমে লেখা যাবে না" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "একই ফাইল-সিস্টেমে নেই" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "বড্ড বড় নাম" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "সেবা পাওয়া যাবে না" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "আবেদন সেবার তথ্য বাতিল করবে" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "প্রটোকলে ভুল" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "মূল ব্রাওসার খঁুজে পাওয়া গেল না" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "অজানা ভুল" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "১ বাইট" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u বাইট" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f কে" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f এম-বি" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f জি-বি" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr "বেঠিক ইউনিকোড" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "অজানা GnomeVFSSeekPosition %d" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "%s-এ কোন সঠিক বিন্যাস ফাইল খঁুজে পাওয়া গেল না\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "" +"%s এনভায়রনমেন্ট ভ্যারিএবেল (Environment Variable) ব্যবহার করে অন্য একটা জায়গাকে " +"নির্দেশ করুন।\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +#, fuzzy +msgid "Files" +msgstr "ফাইলটা আগে থেকেই আছে" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "সাধারন ফাইল মনিকার কারখানা" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "ফাইল মনিকার প্রসায্য" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "সাধারন গ্নোম-ভি-এফ-এসস্ মনিকার" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "সাধারন ফাইল মনিকার" diff --git a/po/bs.gmo b/po/bs.gmo new file mode 100644 index 0000000000000000000000000000000000000000..5ba61ff23fcfc03986ef03dd9feba50c8a8889b3 GIT binary patch literal 4584 zcmaKuTZ|k>6^09vfY~@s2m}Hop>VQs5_{IWYn<2{$M;J%_S%kj9T^J{HPf}THPcho z^kwW_#N`R+#koj95Xlc%2oWi~a1#$8KkX(G0-g{;LPC)&A@K+=;UY_Xr@LonZ9-a8 z{m(gds_NY8oc_zbw|__R9AG@ac;tgheF5BdJ1?GB?ojH(;H%(=z}IW~``|;+Z`Am9 zjei9AAYF7Q6^Zt!9732+DaIQV7oW8jP6Ch!XQ82DyQ|Dm404&Dj>-5PI0 zDUrV$l>Hw9H-g*1d%)c_|2a_hKUZT6%DQiX9|2#k>DNKo{|)e7@aHxEZBX|8Bls!s zI`{~91C(<&W31Ra$?KEgZcyxe9{eb1z|VjgD0;kH;}5|5pnqB8??7399h7zd0Y%Td zP*UU`sBs$9(9hPi1Mi3aCMfdX1Ld3_fu99`1&W@3uK9lh#l9P$?0e5x75hiQk3%nk zV&~Uu`n%xa4=D9x5R=v4aS|a={{n>;=ZO3UQ1WMUjr%}MP+tT^-hyIR49dCR0H?s$ zYJ98a{}UAbH=*5tQ09LI%KpCrW!*b9{SQ#=+klhA zUk`%f?a zC3@}yKL?%$B_C2y;_y;Ee-#wFe+r5}-vVWycWVB-;AZGM*-UT(d>nip6g|HNie9gP z{M4Jg1C3W+w0lAGqdX#yGI%+RN9!yeC zmj9}k4;qeOQAhVhA zNVkH|jq{m4dG>^EEt%A`a+_uow@&+@dp2JRk@lu%-*Y-dMQjJtg>EkAHd9k2sspW- z%`zQX?`)(Fnn*7?gqMtuVyg}r??bLzsWrLPiA$_r45m$vbRvgUM-HBsqEi-K{s7n9Sv!Z^F+2(MIE!=rmm%Jnub(88?qdSiJ96&QHnn+o&;pws#0!r z;OzEO^#-$^$a)hG$;#lfXJ*x`um0mHHj@NUvl%Xl26n3xq3!Uu!LkS=I=Kg&asz&V|UJhZ~V=VvULAAG!glZwJ^ya)HI zg(c*nnT42`WTa*)4%xyzB9GO4MV6sAeIjF;+@<-PJ7v;H&js(gHYH|d=Bfo8-ZOr= zirR<_;vn%@rq24V4;Q#|KJ@GhN9X6Q?Vb*qEAQHPG@P#zavgHdK=tJ#Tt0)pHoVdP(mgcU`(aF4|4EG!fGFUKaRvVcNE_ zU`=mE9}Jmy#_K&v>N>U`BDbF_SX>n0iKf{*Ha9zWWMs+I#N-(D64!7l(U{S>y_j!L zVhaA#WwEE&J#%*9Xk*t%PPD_>jU(LZh+90PcQsu;cCJxYqe|`L2Tjw)dU9g-#Lltz z?=P8&(zR=@Y%gKOo9?i8c)6_Aq~p#~c0yzZjpf!!=`AvOOItZ_n&{ghf$>O|7YU_l z?J9LEUAx)^P&c<-N(gnLUFeYaLrOO5mbg!^7~xRz*g@aYXO0j045Ha+E2GP9<5@37 z!kg7stv6+FIf)H&NRpD{5vP>g(-@VvobHCS=p~M`9NG*dWrItOtY5okS1%OR7aYu zUZ#Hy(%Muli5!+x?@DH@XBCv$Zm~{=I8wX5k@IFL#}R!ph6Lsd!poPCr;~C=OiQ>$ zM%A=56`+o8giw*7@1P;#!cj|Xrjp91Q>ymbRlYd*kO}>DjQS3^rNJeUyicTn5xxJ{ z9!C;`j2&_Msl=V@7juy%WYuOmcS+S1r6kGBEsn=T>ZgS5IO&k(jt^vdru4}Ujgp#H z=B)KZI5H%pCMR%?Tvp0pK|zW`7cX@RdS-p&hn^Vr&5*2JC6)iTZPpXj!ZJ*Q-uYji CvCm@w literal 0 HcmV?d00001 diff --git a/po/bs.po b/po/bs.po new file mode 100644 index 0000000..77fa699 --- /dev/null +++ b/po/bs.po @@ -0,0 +1,410 @@ +# Bosnian translation of gnome-vfs. +# Copyright (C) 2002 +# This file is distributed under the same license as the gnome-vfs package. +# Samir Marić , 2002. +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2002-05-27 20:20GMT+1\n" +"Last-Translator: Samir Marić \n" +"Language-Team: Bosnian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 0.9.5\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d sadrži NUL oznake." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d ne sadrži ime metoda." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d ne sadrži ime modula." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Konfiguracijska datoteka `%s' nije pronađena: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Nepoznat tip operacije %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "Nemogu otvoriti cijev za otvaranje GIOChannel: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Nepoznata vrsta posla %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Operacija zaustavljena" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Ne mogu preraditi: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Sljedeće greÅ¡ke u preradi će biti ignorisane." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Bez greÅ¡ke" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Nema datoteke" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Neprecizirana greÅ¡ka" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Interna greÅ¡ka" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Nevažeći parametri" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Operacija nije podržana" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "I/O greÅ¡ka" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Podatci korumpirani" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Nevažeći format" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "LoÅ¡a drÅ¡ka datoteke" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "Datoteka je prevelika" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Nema mjesta na napravi" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Datotečni sistem samo za čitanje" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "Neispravan URI" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Datoteka nije otvorena" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Nevažeći način otvaranja" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Zabranjen pristup" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "PreviÅ¡e otvorenih datoteka" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Kraj datoteke" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Nije direktorij" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Operacija u toku" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Operacija prekinuta" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Datoteka postoji" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Pronađeni kružni linkovi" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Operacija nije dozvoljena" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "Je direktorij" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Premalo memorije" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Računar nije pronađen" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Nevažeće ime računara" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Računar nema adresu" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Prijava nije uspjela" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Operacija otkazana" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Direktorij zauzet" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Direktorij nije prazan" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "PreviÅ¡e linkova" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Datotečni sistem samo za čitanje" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Nije na istom datotečnom sistemu" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Ime je predugo" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Usluga nije dostupna" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Zahtijev ima prednost nad podacima usluge" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "GreÅ¡ka u protokolu" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +#, fuzzy +msgid "Could not find master browser" +msgstr "Ne mogu preraditi: %s" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Nepoznata greÅ¡ka" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 byte" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u bytes" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr "" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "Nepoznata GnomeVFSSeekPosition %d" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "Ne mogu pronaći važeću datoteku s podeÅ¡avanjima na %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "Koristite %s varijablu okruženja da bi ste naveli drugu lokaciju.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +#, fuzzy +msgid "Files" +msgstr "Datoteka postoji" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Standardna Moniker fabrika" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "datoteka MonikerExtender" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "opÅ¡ti Gnome VFS moniker" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "opÅ¡ti datotečni moniker" diff --git a/po/ca.gmo b/po/ca.gmo new file mode 100644 index 0000000000000000000000000000000000000000..785e3fdca7a5dad9731bccf78bbbd0f5d3189d7f GIT binary patch literal 5504 zcma);dyE}b9mkLIP!<6}R1}coW7!tC+igo>S)fq1yJcawE!|yAG$hQGw1nxp5I(@_Tz@<9?BJzC*N#L7hZP`FP@jrHRcldTlg0EcgWBDyQ!Z=DBx@EZ7Ks3m^_cfy~+E8&0OJKz;eb|IXAJK$|i zeHH5aNq9bd1il-72EG?Q+qAz3HU1Y+`}jT7KK=&7QO~Q-cP@N8?H5Azy9%BSTTtul zX*dft-$$Uvr;wlVP5V03ejbLB-=~}Qr=a?O6KehE;d|fwf+SowO%fV zY}HIc^*;c0&W}RLv4j`Hhv4P#aj5-%t>F*hJE{M&;a{M}pTj0K?nmyN8n}DzXa9)+feJg0Clck!>iycQ2RfNL+bm*P;wZBntu`=fQKO}Hjlzf;b)=F zce<(n2;TT6V}1oS&!sG?{yU)TYNDy%2xTv~!4Jaw;0NHxpyc)>RR7bEpZNwawrB=W zcJfoW5B>?NzeT7wz@1R@+z%z!haf-mMP4_;XQAxn4^VRaC)Bw|XuJkq1~tz#)cGHT z{LH6#(baqbYTQ?$&hrhw}f^P;z<^w%|+6_y5A3)GuN&jk^hs!D%RaU4zok zqfqNS*|dKLYM(DR?f-((|HX7xzcDDi?}sd578^RKc~3U{9Mt;Xhtl((q2kVY4A%a4 zK+QABOLAI(vV%pa^PYq{-@{P$`xU75zYCATpF^GNYBs0#38-}rLD`3cm|=Kiw|efb z5zehSByX*;w`m{ZX8vf8dTydY1ov?tqfL&cF3}Ka~ZFrAS74j!;=l6^&s-_>}z-roT5m7S2u04McKh^lv^p%$zh6Y zUH&VZnWX5Ee@ch*l-(5By|Fve{6v(ciCxaq*e7nM86Dr3I zQJRB%z4)l6i8b?*?^U~ZACAOV1ay816%$eyZ&wXX%!bO#{y|m|S+ZWdNTy77|9hs(E z?y@O6TGF*hc>BDacKSt_ub%4u(Q?e5j7qDS+Pz9|r_!=2>;D@^ z-K$V)%X;QcUsk9_qO?(x6sWOo zlO1ds8v1SSLDkaC?K;xTHJ2mmJjynzjgcOkGjol>a!jU_^_jWSMm8DB(9Ea#T50Be zC(Ug;;@}At-;+#`#ad}y9;0N2@@0VzX2BQOP9wK)n$n(3v&^nIn|5-(CgbL?P9Vu- zKJS>r9`kHR{j9S10H$f9vh;C^6(;&v%Y;9*ofg3=mygZcGG29Er!HkLik;0|yRr;V z+=(<+I}>g>jOs4;{mv>L)x|_Y5BgWD&X(Fz@P=|7`$}HB^aIWYCN{d$T{>2Kr$F1#x&(k%$vyCz&q$Tu( zPpsD(->iBGND?d6mX&5XU(5YTVnyz|?%vtOMd#Lz`Z5hF9ZfdA*ZLgxKJHiSnu5Y; zf1`)**=n8e6Pn6?ujdQIq)1eY-z=Bd4_X_Q1)fL?pLbm@Un)`^2HV0UT%5Mog9WtP z7%1N}U&p@j5%Xb|B>I@3^5)1hrz)4@pQh7zV>pTBC>TNz%Ep&4Y}kmhjuUiRb4lx7 zoCph^vY2|;wNA84yJvjw_{7N3BTKDmMOMDH2yR5VJrfgqTN9J5J^SqLy;HjbTaDi@H;G8hgm1+}=_ZQ4+R%d+FO1Qlfd>7oGhh3v&xIo5$MC zQ3(6UiN#UTl&##UYF95KmE9cD7*YAw<)zuy1Ijfn;aH=plyJujXVPg#r$(2*CMivJre^iBEiK>t<6$HolP&ZkZaUVFrwiD7@ zm)=DkC)K6rJAEP}IU%hcjIf;1(j1HuHa*O@Wr(R;rt8boUwc!v;&8)l={L1L?)MPd zFdwHVgp{0Chz`9B4`~*|jtZ_YgJ&ztIw3k}I(N#&{YnBH!<5v!Eai-esGPUk6c zzaF)rs^bVvNgK-@YL6Y&;@Z;SS6s2tfqP0B*$(#G^awYfUeMD<3b(ZcnkxgLWAHSY z+#ERGPnuXO9h5F7W<{K1@Kl6&gK>tytgq~(nI#10rm5N75ga*}A~B9|U76Xn*!)XF zayQGz=C(|6RPI4OClPJ7mS*tDQt}-p_mq1Opx9&$a?&B%FC=K?MarUwo z5>j8CvV9e_yLIkVZBm~qnc%l}3p6Z@48?F^{ zP`7c_2%W<1gG;1b&TW`xU2mk!8iga|tAojLxtD}+d*;ogsp|mE<>b(!-H16`zBc1GKK&0LMzI+H literal 0 HcmV?d00001 diff --git a/po/ca.po b/po/ca.po new file mode 100644 index 0000000..b420433 --- /dev/null +++ b/po/ca.po @@ -0,0 +1,1591 @@ +# gnome-vfs translation to Catalan. +# Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc. +# Softcatalà , 2000, 2001. +# Jordi Mallach , 2002, 2003. +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs 2.3.0\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-05-10 13:46+0200\n" +"Last-Translator: Jordi Mallach \n" +"Language-Team: Catalan \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d conté caràcters NULS." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d no conté cap nom de mètode." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d no conté cap nom de mòdul." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "El fitxer de configuració `%s' no ha estat trobat: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Tipus d'op %u desconegut" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "No es pot crear la connexió per obrir GIOChannel: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Tipus de feina %u desconegut" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Operació aturada" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "No s'ha pogut analitzar: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Els següent errors d'anàlisi seran ignorats" + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Cap error" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Fitxer no trobat" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Error genèric" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Error intern" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Paràmetres no vàlids" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Operació no suportada" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "Error E/S" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Dades corruptes" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Format no vàlid" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Fitxer associat incorrecte" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "Fitxer massa gran" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "No hi ha prou espai en el dispositiu" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Sistema de fitxers de només lectura" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "URI no vàlid" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Fitxer no obert" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Mode d'obertura no vàlid" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Accés denegat" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "Massa fitxers oberts" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Fi del fitxer" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "No és un directori" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Operació en progrés" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Operació interrompuda" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Fitxer ja existent" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Enllaços amb bucles trobats" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Operació no permesa" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "És un directori" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "No hi ha prou memòria" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Servidor no trobat" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Nom de servidor no vàlid" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Servidor sense adreça" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Entrada fallida" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Operació cancel·lada" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Directori ocupat" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Directori no buit" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "Massa enllaços" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Sistema de fitxers de només lectura" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "No és del mateix sistema de fitxers" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Nom massa llarg" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "El servei no està disponible" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Sol·licita les dades de serveis obsolets" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Error de protocol" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "No s'ha trobat el navegador mestre" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "No hi ha cap acció per defecte associada" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "No hi ha cap gestor per l'esquema d'URL" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "S'ha produït un error en analitzar la línia d'ordres" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "S'ha produït un error en executar l'ordre" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Error desconegut" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 byte" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u bytes" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (Unicode invàlid)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "Desconeguda GnomeVFSSeekPosition %d" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "No s'ha trobat un fitxer de configuració vàlid en %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "" +"Utilitzeu la variable d'entorn %s per a especificar una localització " +"diferent.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "Aplicacions" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "Targetes" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "Fitxers" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "Carpetes" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "Ajuda" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "Ordinadors" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "Enllaços" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "Correu" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "Eines" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "Finestres" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Factoria de Moniker estàndard" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "fitxer MonikerExtender" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "Moniker de Gnome VGS genèric" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "Moniker de fitxer genèric" + +#~ msgid "3D Studio image" +#~ msgstr "imatge 3D Studio" + +#~ msgid "AIFC audio" +#~ msgstr "àudio AIFC" + +#~ msgid "AIFF audio" +#~ msgstr "àudio AIFF" + +#~ msgid "ANIM animation" +#~ msgstr "animació ANIM" + +#~ msgid "AVI video" +#~ msgstr "vídeo AVI" + +#~ msgid "AbiWord document" +#~ msgstr "document AbiWord" + +#~ msgid "Adobe FrameMaker font" +#~ msgstr "font Adobe FrameMaker" + +#~ msgid "Adobe font metrics" +#~ msgstr "mètrica de font Adobe" + +#~ msgid "Andrew Toolkit inset" +#~ msgstr "sagnia Andrew Toolkit" + +#~ msgid "ApplixWare Graphics image" +#~ msgstr "imatge ApplixWare Graphics" + +#~ msgid "Applixware Words document" +#~ msgstr "document Applixware Words" + +#~ msgid "Applixware spreadsheet" +#~ msgstr "full de càlcul Applixware" + +#~ msgid "AutoCAD image" +#~ msgstr "imatge AutoCAD" + +#~ msgid "BCPIO document" +#~ msgstr "document BCPIO" + +#~ msgid "BDF font" +#~ msgstr "font BDF" + +#~ msgid "C shell script" +#~ msgstr "seqüència d'intèrpret d'ordres C" + +#~ msgid "C source code" +#~ msgstr "codi font C" + +#~ msgid "C source code header" +#~ msgstr "capçalera de codi font C" + +#~ msgid "C++ source code" +#~ msgstr "codi font C++" + +#~ msgid "CGI program" +#~ msgstr "programa CGI" + +#~ msgid "CGM image" +#~ msgstr "imatge CGM" + +#~ msgid "CMU raster image" +#~ msgstr "imatge CMU raster" + +#~ msgid "CPIO archive" +#~ msgstr "arxiu CPIO" + +#~ msgid "CPIO archive (gzip-compressed)" +#~ msgstr "arxiu CPIO (comprimit amb gzip)" + +#~ msgid "DCL script" +#~ msgstr "Seqüència DCL" + +#~ msgid "DOS font" +#~ msgstr "font DOS" + +#~ msgid "DOS/Windows program" +#~ msgstr "programa DOS/Windows" + +#~ msgid "DSSSL document" +#~ msgstr "document DSSSL" + +#~ msgid "DXF vector graphic" +#~ msgstr "gràfic vectorial DXF" + +#~ msgid "Debian package" +#~ msgstr "paquet Debian" + +#~ msgid "Dia diagram" +#~ msgstr "diagrama Dia" + +#~ msgid "Dolby Digital audio" +#~ msgstr "àudio Dolby Digital" + +#~ msgid "Emacs Lisp source code" +#~ msgstr "codi font Emacs Lisp" + +#~ msgid "Enlightenment theme" +#~ msgstr "tema Enlightenment" + +#~ msgid "FLC animation" +#~ msgstr "animació FLC" + +#~ msgid "FLI animation" +#~ msgstr "animació FLI" + +#~ msgid "FastTracker II audio" +#~ msgstr "àudio FastTracker II" + +#~ msgid "Fortran source code" +#~ msgstr "codi font Fortran" + +#~ msgid "FrameMaker interchange document" +#~ msgstr "document d'intercanvi FrameMaker" + +#~ msgid "G3 fax image" +#~ msgstr "imatge fax G3" + +#~ msgid "GIF image" +#~ msgstr "imatge GIF" + +#~ msgid "GIMP document" +#~ msgstr "document GIMP" + +#~ msgid "GMC link" +#~ msgstr "enllaç GMC" + +#~ msgid "GNOME application details" +#~ msgstr "Detalls de l'aplicació GNOME" + +#~ msgid "GNU Oleo Spreadsheet" +#~ msgstr "full de càlcul GNU Oleo" + +#~ msgid "GNU mail message" +#~ msgstr "missatge de correu GNU" + +#~ msgid "GTK configuration" +#~ msgstr "configuració GTK" + +#~ msgid "Glade project" +#~ msgstr "projecte Glade" + +#~ msgid "GnuCash Workbook" +#~ msgstr "llibre de treball GnuCash" + +#~ msgid "Gnumeric spreadsheet" +#~ msgstr "full de càlcul Gnumeric" + +#~ msgid "HDF document" +#~ msgstr "document HDF" + +#~ msgid "HTML page" +#~ msgstr "pàgina HTML" + +#~ msgid "IDL document" +#~ msgstr "document IDL" + +#~ msgid "IEF image" +#~ msgstr "imatge IEF" + +#~ msgid "IFF image" +#~ msgstr "imatge IFF" + +#~ msgid "ILBM image" +#~ msgstr "imatge ILBM" + +#~ msgid "ISI video" +#~ msgstr "vídeo ISI" + +#~ msgid "Impulse Tracker audio" +#~ msgstr "àudio Impulse Tracker" + +#~ msgid "JBuilder Project" +#~ msgstr "projecte JBuilder" + +#~ msgid "JPEG image" +#~ msgstr "imatge JPEG" + +#~ msgid "Java byte code" +#~ msgstr "codi de bytes Java" + +#~ msgid "Java source code" +#~ msgstr "codi font Java" + +#~ msgid "KDE application details" +#~ msgstr "Detalls de l'aplicació KDE" + +#~ msgid "KIllustrator document" +#~ msgstr "document KIllustrator" + +#~ msgid "KPresenter presentation" +#~ msgstr "presentació KPresenter" + +#~ msgid "KSpread spreadsheet" +#~ msgstr "full de càlcul KSpread" + +#~ msgid "KWord document" +#~ msgstr "document KWord" + +#~ msgid "Korn shell script" +#~ msgstr "seqüència d'intèrpret d'ordres Korn" + +#~ msgid "LHA archive" +#~ msgstr "arxiu LHA" + +#~ msgid "LHARC archive" +#~ msgstr "arxiu LHARC" + +#~ msgid "LIBGRX font" +#~ msgstr "font LIBGRX" + +#~ msgid "LightWave object" +#~ msgstr "objecte LightWave" + +#~ msgid "LightWave scene" +#~ msgstr "escena LightWave" + +#~ msgid "Linux PSF console font" +#~ msgstr "font de consola Linux PSF" + +#~ msgid "Lotus 1-2-3 spreadsheet" +#~ msgstr "full de càlcul Lotus 1-2-3" + +#~ msgid "M3 audio URL" +#~ msgstr "URL d'àudio M3" + +#~ msgid "MIDI audio" +#~ msgstr "àudio MIDI" + +#~ msgid "MOD audio" +#~ msgstr "àudio MOD" + +#~ msgid "MP3 audio" +#~ msgstr "àudio MP3" + +#~ msgid "MP3 audio playlist" +#~ msgstr "selecció de peces d'àudio MP3" + +#~ msgid "MPEG video" +#~ msgstr "vídeo MPEG" + +#~ msgid "MS ASF video" +#~ msgstr "vídeo MS ASF" + +#~ msgid "MS video" +#~ msgstr "vídeo MS" + +#~ msgid "Macintosh AppleDouble-encoded file" +#~ msgstr "fitxer codificat Macintosh AppleDouble" + +#~ msgid "Macintosh BinHex-encoded file" +#~ msgstr "fitxer codificat Macintosh BinHex" + +#~ msgid "Macintosh StuffIt archive" +#~ msgstr "arxiu Macintosh StuffIt" + +#~ msgid "Macromedia Flash file" +#~ msgstr "fitxer Macromedia Flash" + +#~ msgid "MathML document" +#~ msgstr "document MathML" + +#~ msgid "Microsoft Excel spreadsheet" +#~ msgstr "full de càlcul Microsoft Excel" + +#~ msgid "Microsoft PowerPoint document" +#~ msgstr "document Microsoft PowerPoint" + +#~ msgid "Microsoft Word document" +#~ msgstr "document Microsoft Word" + +#~ msgid "Microsoft video" +#~ msgstr "vídeo Microsoft" + +#~ msgid "Nautilus link" +#~ msgstr "enllaç Nautilus" + +#~ msgid "ODA document" +#~ msgstr "document ODA" + +#~ msgid "PBM image" +#~ msgstr "imatge PBM" + +#~ msgid "PCF font" +#~ msgstr "font PCF" + +#~ msgid "PDF document" +#~ msgstr "document PDF" + +#~ msgid "PEF program" +#~ msgstr "programa PEF" + +#~ msgid "PGM image" +#~ msgstr "imatge PGM" + +#~ msgid "PGN chess game" +#~ msgstr "joc d'escacs PGN" + +#~ msgid "PGP keys" +#~ msgstr "claus PGP" + +#~ msgid "PGP message" +#~ msgstr "missatge PGP" + +#~ msgid "PGP signature" +#~ msgstr "signatura PGP" + +#~ msgid "PGP-encrypted file" +#~ msgstr "fitxer codificat PGP" + +#~ msgid "PHP script" +#~ msgstr "seqüència PHP" + +#~ msgid "PN RealAudio document" +#~ msgstr "document PN RealAudio" + +#~ msgid "PNG image" +#~ msgstr "imatge PNG" + +#~ msgid "PNM image" +#~ msgstr "imatge PNM" + +#~ msgid "PPM image" +#~ msgstr "imatge PPM" + +#~ msgid "Palm OS database" +#~ msgstr "base de dades Palm OS" + +#~ msgid "Perl script" +#~ msgstr "Seqüència Perl" + +#~ msgid "Photoshop document" +#~ msgstr "document Photoshop" + +#~ msgid "PostScript Type 1 font" +#~ msgstr "font PostScript Tipus 1" + +#~ msgid "PostScript document" +#~ msgstr "document PostScript" + +#~ msgid "Python source code" +#~ msgstr "codi font Python" + +#~ msgid "QuickTime movie" +#~ msgstr "pel·lícula QuickTime" + +#~ msgid "Quicken document" +#~ msgstr "document Quicken" + +#~ msgid "Quicken for Windows document" +#~ msgstr "Quicken per a document Windows" + +#~ msgid "RAR archive" +#~ msgstr "arxiu RAR" + +#~ msgid "README document" +#~ msgstr "document README" + +#~ msgid "RGB image" +#~ msgstr "imatge RGB" + +#~ msgid "RIFF audio" +#~ msgstr "àudio RIFF" + +#~ msgid "RPM package" +#~ msgstr "paquet RPM" + +#~ msgid "RealAudio/Video document" +#~ msgstr "document RealAudio/Video" + +#~ msgid "RealVideo video" +#~ msgstr "vídeo RealVideo" + +#~ msgid "S/MIME file" +#~ msgstr "Fitxer S/MIME" + +#~ msgid "S/MIME signature" +#~ msgstr "signatura S/MIME" + +#~ msgid "SGI video" +#~ msgstr "vídeo SGI" + +#~ msgid "SGML document" +#~ msgstr "document SGML" + +#~ msgid "SMIL script" +#~ msgstr "seqüència SMIL" + +#~ msgid "SQL code" +#~ msgstr "codi SQL" + +#~ msgid "SV4 CPIO archive" +#~ msgstr "arxiu SV4 CPIO" + +#~ msgid "SV4 CPIP archive (with CRC)" +#~ msgstr "arxiu SV4 CPIP (amb CRC)" + +#~ msgid "SVG art" +#~ msgstr "art SVG" + +#~ msgid "Scheme source code" +#~ msgstr "codi font Scheme" + +#~ msgid "Scream Tracker 3 audio" +#~ msgstr "àudio Scream Tracker 3" + +#~ msgid "Scream Tracker audio" +#~ msgstr "àudio Scream Tracker" + +#~ msgid "Scream Tracker instrument" +#~ msgstr "instrument Scream Tracker" + +#~ msgid "Setext document" +#~ msgstr "document Setext" + +#~ msgid "Speech document" +#~ msgstr "document Speech" + +#~ msgid "Speedo font" +#~ msgstr "font Speedo" + +#~ msgid "Spreadsheet Interchange document" +#~ msgstr "document SpreadSheet Interchange" + +#~ msgid "Stampede package" +#~ msgstr "paquet Stampede" + +#~ msgid "StarOffice Writer document" +#~ msgstr "document StarOffice Writer" + +#~ msgid "StarOffice presentation" +#~ msgstr "presentació StarOffice" + +#~ msgid "StarOffice spreadsheet" +#~ msgstr "full de càlcul StarOffice" + +#~ msgid "Sun mu-law audio" +#~ msgstr "àudio Sun µ-law" + +#~ msgid "SunOS News font" +#~ msgstr "font SunOS News" + +#~ msgid "TIFF image" +#~ msgstr "imatge TIFF" + +#~ msgid "TarGA image" +#~ msgstr "imatge TarGA" + +#~ msgid "Tcl script" +#~ msgstr "seqüència Tcl" + +#~ msgid "TeX document" +#~ msgstr "document TeX" + +#~ msgid "TeX dvi document" +#~ msgstr "document TeX dvi" + +#~ msgid "TeX font" +#~ msgstr "font TeX" + +#~ msgid "TeX font metrics" +#~ msgstr "mètrica de font TeX" + +#~ msgid "TeXInfo document" +#~ msgstr "document TeXInfo" + +#~ msgid "ToutDoux document" +#~ msgstr "document ToutDoux" + +#~ msgid "TrueType font" +#~ msgstr "font TrueType" + +#~ msgid "USENET news message" +#~ msgstr "missatge USENET" + +#~ msgid "Unidata netCDF document" +#~ msgstr "document netCDF Unidata" + +#~ msgid "V font" +#~ msgstr "font V" + +#~ msgid "VOC audio" +#~ msgstr "àudio VOC" + +#~ msgid "VRML document" +#~ msgstr "document VRML" + +#~ msgid "Vivo video" +#~ msgstr "vídeo Vivo" + +#~ msgid "WAIS source code" +#~ msgstr "codi font WAIS" + +#~ msgid "Wavelet video" +#~ msgstr "vídeo Wavelet" + +#~ msgid "Windows bitmap image" +#~ msgstr "imatge de mapa de bits Windows" + +#~ msgid "Windows icon image" +#~ msgstr "imatge d'icona Windows" + +#~ msgid "Windows metafile graphics" +#~ msgstr "gràfics de metafitxer Windows" + +#~ msgid "WordPerfect document" +#~ msgstr "document WordPerfect" + +#~ msgid "X bitmap image" +#~ msgstr "imatge de mapa de bits X" + +#~ msgid "X window image" +#~ msgstr "imatge X Window" + +#~ msgid "XML document" +#~ msgstr "document XML" + +#~ msgid "XPM image" +#~ msgstr "imatge XPM" + +#~ msgid "Xbase database" +#~ msgstr "base de dades Xbase" + +#~ msgid "active server page" +#~ msgstr "pàgina del servidor actiu" + +#~ msgid "address card" +#~ msgstr "targeta d'adreces" + +#~ msgid "ar archive" +#~ msgstr "arxiu ar" + +#~ msgid "arj archive" +#~ msgstr "arxiu arj" + +#~ msgid "authors list" +#~ msgstr "llistat d'autors" + +#~ msgid "backup file" +#~ msgstr "còpia de seguretat" + +#~ msgid "basic audio" +#~ msgstr "àudio bàsic" + +#~ msgid "bibliography record" +#~ msgstr "registre bibliogràfic" + +#~ msgid "binary program" +#~ msgstr "programa binari" + +#~ msgid "block device" +#~ msgstr "dispositiu de bloqueig" + +#~ msgid "bzip-compressed file" +#~ msgstr "fitxer comprimit amb bzip" + +#~ msgid "calendar file" +#~ msgstr "fitxer calendari" + +#~ msgid "calendar or event document" +#~ msgstr "document calendari o esdeveniment" + +#~ msgid "character device" +#~ msgstr "dispositiu de caràcters" + +#~ msgid "comma-separated text document" +#~ msgstr "document separat per comes" + +#~ msgid "compound document" +#~ msgstr "document compost" + +#~ msgid "compress-compressed file" +#~ msgstr "fitxer comprimit amb compress" + +#~ msgid "compressed GIMP document" +#~ msgstr "document comprimit amb GIMP" + +#~ msgid "directory information file" +#~ msgstr "fitxer d'informació del directori" + +#~ msgid "document type definition" +#~ msgstr "definició del tipus de document" + +#~ msgid "email headers" +#~ msgstr "Capçaleres del correu electrònic" + +#~ msgid "email message" +#~ msgstr "missatge de correu electrònic" + +#~ msgid "encrypted message" +#~ msgstr "missatge encriptat" + +#~ msgid "enriched text document" +#~ msgstr "document de text enriquit" + +#~ msgid "gtar archive" +#~ msgstr "arxiu gtar" + +#~ msgid "gzip-compressed file" +#~ msgstr "fitxer comprimit amb gzip" + +#~ msgid "help page" +#~ msgstr "pàgina d'ajuda" + +#~ msgid "mail delivery report" +#~ msgstr "informe del lliurament del correu" + +#~ msgid "mail disposition report" +#~ msgstr "informe de la clasificació del correu" + +#~ msgid "mail system report" +#~ msgstr "informe de sistema de correu" + +#~ msgid "makefile" +#~ msgstr "makefile" + +#~ msgid "manual page" +#~ msgstr "pàgina manual" + +#~ msgid "manual page (compressed)" +#~ msgstr "pàgina manual (comprimida)" + +#~ msgid "memory dump" +#~ msgstr "paperera de memòria" + +#~ msgid "message digest" +#~ msgstr "resum del missatge" + +#~ msgid "message in several formats" +#~ msgstr "missatge en diferents formats" + +#~ msgid "multi-part message" +#~ msgstr "missatge multipart" + +#~ msgid "named pipe" +#~ msgstr "conducte designat" + +#~ msgid "object code" +#~ msgstr "codi objecte" + +#~ msgid "ogg audio" +#~ msgstr "àudio ogg" + +#~ msgid "partial email message" +#~ msgstr "missatge de correu parcial" + +#~ msgid "plain text document" +#~ msgstr "document de text" + +#~ msgid "profiler results" +#~ msgstr "resultats del perfilador" + +#~ msgid "reference to remote file" +#~ msgstr "refèrencia al fitxer remot" + +#~ msgid "rejected patch file" +#~ msgstr "fitxer pedaç rebutjat" + +#~ msgid "rich text document" +#~ msgstr "document de text enriquit" + +#~ msgid "search results" +#~ msgstr "resultats de la cerca" + +#~ msgid "shared library" +#~ msgstr "biblioteca compartida" + +#~ msgid "shell archive" +#~ msgstr "arxiu d'intèrpret d'ordres" + +#~ msgid "shell script" +#~ msgstr "Seqüència de l''intèrpret d'ordres" + +#~ msgid "signed message" +#~ msgstr "missatge signat" + +#~ msgid "socket" +#~ msgstr "sòcol" + +#~ msgid "software author credits" +#~ msgstr "crèdits d'autoria del programari" + +#~ msgid "software installation instructions" +#~ msgstr "instruccions d'instal·lació del programari" + +#~ msgid "software license terms" +#~ msgstr "condicions de la llicència del programari" + +#~ msgid "source code patch" +#~ msgstr "pedaç de codi font" + +#~ msgid "style sheet" +#~ msgstr "full d'estil" + +#~ msgid "symbolic link" +#~ msgstr "enllaç simbòlic" + +#~ msgid "tab-separated text document" +#~ msgstr "document de text separat per tabulació" + +#~ msgid "tar archive" +#~ msgstr "arxiu tar" + +#~ msgid "tar archive (bzip2-compressed)" +#~ msgstr "arxiu tar (comprimit amb bzip2)" + +#~ msgid "tar archive (gzip-compressed)" +#~ msgstr "arxiu tar (comprimit amb gzip)" + +#~ msgid "theme" +#~ msgstr "tema" + +#~ msgid "troff document" +#~ msgstr "document troff" + +#~ msgid "troff me input document" +#~ msgstr "document d'entrada troff me" + +#~ msgid "troff mm input document" +#~ msgstr "document d'entrada troff mm" + +#~ msgid "troff ms input document" +#~ msgstr "document d'entrada troff ms" + +#~ msgid "unknown type" +#~ msgstr "tipus desconegut" + +#~ msgid "ustar archive" +#~ msgstr "arxiu ustar" + +#~ msgid "wave audio" +#~ msgstr "àudio wave" + +#~ msgid "web folder" +#~ msgstr "carpeta web" + +#~ msgid "xfig vector graphic" +#~ msgstr "gràfic vectorial xfig" + +#~ msgid "zip archive" +#~ msgstr "arxiu zip" + +#~ msgid "zoo archive" +#~ msgstr "arxiu zoo" + +#~ msgid "GNOME VFS already initialized." +#~ msgstr "GNOME VFS ja està inicialitzat." + +#~ msgid "%s to retrieve" +#~ msgstr "%s per recuperar" + +#~ msgid "Closing connection to %s" +#~ msgstr "S'està tancant la connexió a %s" + +#~ msgid "%s of %s read" +#~ msgstr "%s de %s llegit" + +#~ msgid "%s read" +#~ msgstr "%s llegit" + +#~ msgid "Dying." +#~ msgstr "S'està morint." + +#~ msgid "Error reading: %s" +#~ msgstr "Error en llegir: %s" + +#~ msgid "Error writing: %s" +#~ msgstr "Error en escriure: %s" + +#~ msgid "Cannot write: %s" +#~ msgstr "No es pot escriure: %s" + +#~ msgid "Cannot create temporary file name `%s'" +#~ msgstr "No es pot crear el fitxer temporal de nom `%s'" + +#~ msgid "Cannot create socket: %s" +#~ msgstr "No es pot crear l'enllaç: %s" + +#~ msgid "Cannot bind `%s': %s" +#~ msgstr "No es pot vincular `%s': %s" + +#~ msgid "Cannot listen on `%s': %s" +#~ msgstr "No es pot atendre a `%s': %s" + +#~ msgid "Cannot accept connections on `%s': %s" +#~ msgstr "No es poden acceptar connexions en `%s': %s" + +#~ msgid "Cannot initialize CORBA." +#~ msgstr "No es pot inicialitzar CORBA." + +#~ msgid "Cannot resolve initial reference to RootPOA." +#~ msgstr "No es pot resoldre la referència inicial al RootPOA." + +#~ msgid "Cannot activate POA manager." +#~ msgstr "No es pot activar el gestor POA." + +#~ msgid "Usage: %s []\n" +#~ msgstr "Utilització: %s []\n" + +#~ msgid "Cannot open file descriptor %d." +#~ msgstr "No es pot obrir el descriptor de fitxers %d." + +#~ msgid "Notify interface for `%s' not found." +#~ msgstr "No s'ha trobat la interfície de notificació per a `%s'." + +#~ msgid "Cannot setup Request object." +#~ msgstr "No es pot configurar l'objecte demanat." + +#~ msgid "Cannot extract IOR." +#~ msgstr "No es pot extreure l'IOR." + +#~ msgid "Got weird string from the slave process: `%s'" +#~ msgstr "S'ha obtingut una cadena estranya del procés esclau: `%s' " + +#~ msgid "Cannot get object for `%s'" +#~ msgstr "No es pot obtenir l'objecte per a `%s'" + +#~ msgid "Cannot kill GNOME::VFS::Slave::Notify -- exception %s" +#~ msgstr "No es pot matar GNOME::VFS::Esclau::Notifica -- excepció %s" + +#~ msgid "Cannot connect socket `%s': %s" +#~ msgstr "No es pot connectar l'enllaç `%s': %s" + +#~ msgid "Cannot initialize GNOME::VFS:Slave::Notify" +#~ msgstr "No es pot inicialitzar GNOME::VFS:Esclau::Notifica" + +#~ msgid "Cannot reset GNOME::VFS::Slave %s -- exception %s" +#~ msgstr "No es pot reinicialitzar GNOME::VFS::Esclau %s -- excepció %s" + +#~ msgid "Cannot reset GNOME::VFS::Slave (IOR unknown) -- exception %s" +#~ msgstr "" +#~ "No es pot reinicialitzar GNOME::VFS::Esclau (IOR unknown) -- excepció %s" + +#~ msgid "Cannot kill GNOME::VFS::Slave %s -- exception %s" +#~ msgstr "No es pot matar GNOME::VFS::Esclau %s -- excepció %s" + +#~ msgid "Cannot kill GNOME::VFS::Slave (IOR unknown) -- exception %s" +#~ msgstr "No es pot matar GNOME::VFS::Esclau (IOR unknown) -- excepció %s" + +#~ msgid "Back" +#~ msgstr "Enrere" + +#~ msgid "Go to the previously visited directory" +#~ msgstr "Vés al directori visitat anteriorment" + +#~ msgid "Up" +#~ msgstr "Amunt" + +#~ msgid "Go to the parent directory" +#~ msgstr "Vés al directori pare" + +#~ msgid "Forward" +#~ msgstr "Endavant" + +#~ msgid "Go to the next visited directory" +#~ msgstr "Vés al directori visitat següent" + +#~ msgid "Rescan" +#~ msgstr "Torna a explorar" + +#~ msgid "Rescan the current directory" +#~ msgstr "Torna a explorar el directori actual" + +#~ msgid "Home" +#~ msgstr "Inici" + +#~ msgid "Go to the home directory" +#~ msgstr "Vés al directori arrel" + +#~ msgid "Name" +#~ msgstr "Nom" + +#~ msgid "Size" +#~ msgstr "Mida" + +#~ msgid "Date" +#~ msgstr "Data" + +#~ msgid "Enter name:" +#~ msgstr "Introduïu el nom:" + +#~ msgid "Show:" +#~ msgstr "Mostra:" + +#~ msgid "Show dotfiles" +#~ msgstr "Mostra els fiters de plantilla" + +#~ msgid "Edit Applications List" +#~ msgstr "Edita la llista d'aplicacions" + +#~ msgid "Select applications to appear in menu for MIME type \"%s\"" +#~ msgstr "" +#~ "Seleccioneu les aplicacions que han d'aparèixer al menú per al tipus de " +#~ "MIME \"%s\"" + +#~ msgid "Add Application..." +#~ msgstr "Afegeix una aplicació..." + +#~ msgid "Edit Application..." +#~ msgstr "Edita una aplicació..." + +#~ msgid "Delete Application" +#~ msgstr "Suprimeix una aplicació" + +#~ msgid "Edit Components List" +#~ msgstr "Edita la llista de components" + +#~ msgid "Select views to appear in menu for MIME type \"%s\"" +#~ msgstr "" +#~ "Seleccioneu les vistes que han d'aparèixer al menú per al tipus de MIME " +#~ "\"%s\"" + +#~ msgid "" +#~ "The MIME type entered contained upper case characters. Upper case " +#~ "characters were changed to lower case for you." +#~ msgstr "" +#~ "El tipus de MIME introduït contenia caràcters en majúscules; aquests " +#~ "caràcters s'han canviat a minúscules per a la vostra comoditat." + +#~ msgid "Add New MIME Type" +#~ msgstr "Afegeix un tipus nou de MIME" + +#~ msgid "Add MIME Type" +#~ msgstr "Afegeix un tipus de MIME" + +#~ msgid "New MIME type (e.g. image/x-thumper):" +#~ msgstr "Tipus nou de MIME (p.ex. image/x-thumper):" + +#~ msgid "Description (e.g. Thumper image):" +#~ msgstr "Descripció (p.ex. imatge Thumper):" + +#~ msgid "File Extensions " +#~ msgstr "Extensions de fitxer " + +#~ msgid "Add..." +#~ msgstr "Afegeix..." + +#~ msgid " Remove " +#~ msgstr " Elimina " + +#~ msgid "Add New Extension" +#~ msgstr "Afegeix una nova extensió" + +#~ msgid "" +#~ "Type in the extensions for this mime-type (without dot).\n" +#~ "You can enter several extensions seperated by a space,\n" +#~ "for example: html htm" +#~ msgstr "" +#~ "Escriviu les extensions per a aquest tipus de MIME (sense el punt).\n" +#~ "Podeu introduir diverses extensions separant-les amb un espai,\n" +#~ "per exemple: html htm" + +#~ msgid "Extension:" +#~ msgstr "Extensió:" + +#~ msgid "You must enter a name." +#~ msgstr "Heu d'introduir un nom." + +#~ msgid "You must enter a command." +#~ msgstr "Heu d'introduir una ordre." + +#~ msgid "" +#~ "\"%s\" does not exist or is not executable.\n" +#~ "Check your spelling and make sure you have\n" +#~ "the right permissions to execute this file." +#~ msgstr "" +#~ "\"%s\" no existeix o no és un executable.\n" +#~ "Comproveu que ho heu escrit correctament i que teniu\n" +#~ "els permisos necessaris per executar aquest fitxer." + +#~ msgid "" +#~ "The command \"%s\" cannot be found.\n" +#~ "You must use a command that can work from any command line." +#~ msgstr "" +#~ "No es pot trobar l'ordre \"%s\".\n" +#~ "Heu d'utilitzar una ordre que funcioni des de qualsevol línia d'ordres." + +#~ msgid "Bad Application Name" +#~ msgstr "Nom incorrecte de l'aplicació" + +#~ msgid "Bad Application Command" +#~ msgstr "Ordre incorrecta de l'aplicació" + +#~ msgid "Edit Application" +#~ msgstr "Edita una aplicació" + +#~ msgid "Application Name:" +#~ msgstr "Nom de l'aplicació:" + +#~ msgid "Application Command:" +#~ msgstr "Ordre de l'aplicació:" + +#~ msgid "Open Behavior" +#~ msgstr "Obre el comportament" + +#~ msgid "Can open multiple files" +#~ msgstr "Es poden obrir diversos fitxers" + +#~ msgid "Can open from URI" +#~ msgstr "Es pot obrir des de l'URI" + +#~ msgid "MIME Type" +#~ msgstr "Tipus de MIME" + +#~ msgid "Change Icon" +#~ msgstr "Canvia la icona" + +#~ msgid "Change File Extensions" +#~ msgstr "Canvia les extensions de fitxer" + +#~ msgid "Default Action:" +#~ msgstr "Acció per defecte:" + +#~ msgid "Use Viewer" +#~ msgstr "Utilitza el visualitzador" + +#~ msgid "Open With Application" +#~ msgstr "Obre amb l'aplicació" + +#~ msgid "Edit List" +#~ msgstr "Edita la llista" + +#~ msgid "Add New MIME Type..." +#~ msgstr "Afegeix un nou tipus de MIME..." + +#~ msgid "Delete This MIME Type" +#~ msgstr "Suprimeix aquest tipus de MIME" + +#~ msgid "Revert to System Defaults" +#~ msgstr "Torna als valors per defecte del sistema" + +#~ msgid "None" +#~ msgstr "Cap" + +#~ msgid "" +#~ "Reverting to system settings will lose any changes\n" +#~ "you have ever made to File Types and Programs.\n" +#~ "Revert anyway?" +#~ msgstr "" +#~ "Si torneu als paràmetres del sistema perdreu qualsevol canvi\n" +#~ "que mai hagueu fet als tipus de fitxer i als programes.\n" +#~ "Voleu tornar-hi igualment?" + +#~ msgid "none" +#~ msgstr "cap" + +#~ msgid "View as %s" +#~ msgstr "Visualitza com a %s" + +#~ msgid "Description" +#~ msgstr "Descripció" + +#~ msgid "Extension" +#~ msgstr "Extensió" + +#~ msgid "Default Action" +#~ msgstr "Acció per defecte" + +#~ msgid "Can't find an hbox, using a normal file selection" +#~ msgstr "" +#~ "No es pot trobar cap hbox, s'està utilitzant una selecció de fitxer normal" + +#~ msgid "Preview" +#~ msgstr "Previsualitza" + +#~ msgid "Select an icon" +#~ msgstr "Seleccioneu una icona" + +#~ msgid "Unknown sort rule %d" +#~ msgstr "Regla d'ordenació desconeguda %d" + +#~ msgid "Error writing to the wakeup GnomeVFSJob channel." +#~ msgstr "Error en escriure en el canal d'avís GnomeVFSJob" + +#~ msgid "" +#~ "Add a new Mime Type\n" +#~ "For example: image/tiff; text/x-scheme" +#~ msgstr "" +#~ "Afegiu un nou tipus de MIME\n" +#~ "Per exemple: image/tiff; text/x-scheme" + +#~ msgid "Mime Type:" +#~ msgstr "Tipus de MIME:" + +#~ msgid "Type in a description for this mime-type." +#~ msgstr "Escriviu una desripció per a aquest tipus de MIME." + +#~ msgid "Description:" +#~ msgstr "Descripció:" + +#~ msgid "New Application" +#~ msgstr "Nova aplicació" + +#~ msgid "Action" +#~ msgstr "Acció" + +#~ msgid "HTTP server returned an invalid PROPFIND response" +#~ msgstr "El servidor HTTP ha retornat una resposta PROPFIND no vàlida" + +#~ msgid "ftpfs: Invalid host name." +#~ msgstr "ftpfs: Nom de servidor no vàlid." + +#~ msgid "ftpfs: Invalid host address." +#~ msgstr "ftpfs: Adreça de servidor no vàlida." + +#~ msgid "ftpfs: making connection to %s" +#~ msgstr "ftpfs: connectant-se a %s" + +#~ msgid "ftpfs: connection interrupted by user" +#~ msgstr "ftpfs: connexió interrompuda per l'usuari" + +#~ msgid "ftpfs: connection to server failed: %s" +#~ msgstr "ftpfs: connexió al servidor fallida: %s" + +#~ msgid "Waiting to retry... %d (Control-C to cancel)" +#~ msgstr "" +#~ "S'està esperant per reintentar-ho... %d (Control-C per cancel·lar-ho)" + +#~ msgid " FTP: Password required for " +#~ msgstr " FTP: Contrasenya requerida per " + +#~ msgid "ftpfs: sending login name" +#~ msgstr "ftpfs: s'està enviant el nom d'entrada" + +#~ msgid "ftpfs: sending user password" +#~ msgstr "ftpfs: s'està enviant la contrasenya de l'usuari" + +#~ msgid "ftpfs: logged in" +#~ msgstr "ftpfs: connectat" + +#~ msgid "ftpfs: Login incorrect for user %s " +#~ msgstr "ftpfs: Entrada incorrecta per a l'usuari %s " + +#~ msgid "ftpfs: aborting transfer." +#~ msgstr "ftpfs: s'està avortant la transferència." + +#~ msgid "ftpfs: abort error: %s" +#~ msgstr "ftpfs: error en avortar: %s" + +#~ msgid "ftpfs: abort failed" +#~ msgstr "ftpfs: avortament fallit" + +#~ msgid "ftpfs: could not setup passive mode" +#~ msgstr "ftpfs: no s'ha pogut configurar el mode passiu" + +#~ msgid "ftpfs: storing file %d (%d)" +#~ msgstr "ftpfs: s'està emmagatzemant el fitxer %d (%d)" + +#~ msgid "ftpfs: CWD failed." +#~ msgstr "ftpfs: CWD fallit." + +#~ msgid "ftpfs: couldn't resolve symlink" +#~ msgstr "ftpfs: No s'ha pogut resoldre l'enllaç simbòlic" + +#~ msgid "Resolving symlink..." +#~ msgstr "S'està resolent l'enllaç simbòlic..." + +#~ msgid "ftpfs: Reading FTP directory %s... (don't use UNIX ls options)" +#~ msgstr "" +#~ "ftpfs: S'està llegint el directori FTP %s... (no utilitzeu les opcions ls " +#~ "de UNIX)" + +#~ msgid "ftpfs: Reading FTP directory %s..." +#~ msgstr "ftpfs: S'està llegint el directori FTP %s..." + +#~ msgid "ftpfs: reading FTP directory interrupted by user" +#~ msgstr "ftpfs: lectura del directori FTP interrompuda per l'usuari" + +#~ msgid "ftpfs: got listing" +#~ msgstr "ftpfs: llistat rebut" + +#~ msgid "ftpfs: failed; nowhere to fallback to" +#~ msgstr "ftpfs: fallit; enlloc per anar" + +#~ msgid "Starting linear transfer..." +#~ msgstr "S'està iniciant transferència lineal..." + +#~ msgid "Preparing reget..." +#~ msgstr "S'està preparant la recuperació..." diff --git a/po/cs.gmo b/po/cs.gmo new file mode 100644 index 0000000000000000000000000000000000000000..8d3eadadd8de3b67c8f795359ee59a409003d441 GIT binary patch literal 5586 zcma)Bq&udpGbp!kZd^dax@~8e;)Gwv+ zBh;@dcz3}m_#WD8P~;zj*T6IIYWPKX9sC-+8-5$gl&`{l@E7n__%HZAcngDF3kTs| zc(|z7pnN|KuYym)8{yaChv5rF`%j_t{}q&V{1M7J-h`Q|SLXU%0pCmewNT`4gO|Y) zlzD~=o`5pmC!zEYAb-jg?QJOQ`4SZSJyo=S7mECkpv?ag{1AK@$~>>bJK>+8%zsT^ z?w6Y(OI0IKZ?WlNq7_WH7N2gLYe1fD0=-C-UeTXvi?g^Qodgg#SZ;Y#vg%4;Vi_(>MQX5 z@EcI{TQBNAfzMx})NhLV6HF@d--HrZ&lUA`DE|H-)bQs8{|Ygsx&b4J{4G${a|dKd z^#BxoCg4H%C=@-;!F%AhpxE;jDE;1m5+DD7gYar9(tixfx=%sTy9sZHpM?YPSx6W4 zGsvI%JwIZHzd-TB6*xiW{RkBO?u6o(d-;*^#-YT=G?ab%NI?t5Zcjq#|16YopM$8b zUMjx70%iTL742_9k-rqDd=Op<#eN#fJO|-0JOV|(7|K5XGL$&{9@Ov$P}cKH$dKx9 zkUw=9lidYxgwk&uir$Yxk+YCL^*Me-|EG%f=b_l?0+fC5YQZ<5_~Ry&6+2Hr@yn;7 z^zXoa_*E!+{TS|r7od#y1{Ar!L(%6tj3j#Rg-79GD0csR(f$OKd7g#R??reClt<*{ zc{oR=$2{*6PhyJ$MSBktSF#3qK2DK&_fceAd5%!-qlkVID<>%96jE{a9OCz(;$3_r z_LoQeb$9lLAK?SV`(VLiP;?Nx?|g2jGDFdnJ1FwZQ6?!9lm{uYhvgC9ouqt>BK8sA z$|E+sH+#$NK3u$u&E+XkrYIk!U^=y*vWIe zsK%rHzOFc%c!7=e?DDj()V#>6BqoXnc7L``H%wAXTD*#}Tt89M%0XqLI(9v(;cFjk59bp+3_e@6o5dSj$LNms&rUcWHH@p~K zbvbgUV-qn>?`zYGVw3fl@DdLjMN!&JSolQX+dV~ZPv>@yO_Bt5CC+E|5*F5nU}P$Z zi`u%J#_b(dncOs*Nn1^_0$0s?smUlp#n4M_rN&sy*l1vlqFt7=qg982HR^R#W@uim|3FrnX+VRV{*aVMj=-PmxhUE4-lH#i(^*_h(cdJ<~HFakJBiN%H@S=9an0mVMHWudKIHX zQ%yA8ebWjm($0W8l##lzE?udyqZ))rCV_lXGdh+fWxFA66Pyh-Ct=@UAMY?VZAGwG zJXzu3=7{SX?xwKJVfnb7{Z7^*#4zPkPmr zbzPD|f4U{%nmTEdezK-GZ8lwmnIseC=2y!x@q^d;B?4PPhI66q|?$9@T_;!<1UpSf83)Se%-h?VF!lDjk>H%J&lKjXXCzIC!8mI8qwEUk@D^ z9U8f3kQM|>3q-JtvrBI1K0Q1f;?#sp&(N_(&KGxM*d(Z)R#{a$AF;fx$j9JSJfl zyfLa1b0*o}3^}z9W+xU2cx-v;L}_GOPF91lOOxaUpENP5N6JCcw_wDDrI~mo@Jq+i zmAJIzMs?qO$l(!|Bpb$~+BUOlJa*uq&R@rD|Ipyr*pR;KE-kNvw~q}C>BD+ZBTapL zY`FL7(Aa(Qx;GO$G&HCme?0Gk%-}xy4AE!!U?1nSHRzDo?uPz9PHN3j%}(-a>8jBk z>($$GU}wj$e6nWiqwTJBOiK=H=ePfxfE?E;0-V&|YO?u)9M!z2`OS0P^*BkJy5lvv z>xoU1w;$NYYwa?#=Ixzf9C2eVrN%KfX+T}#wl*;K@Q z_`U4q*MoU?@hlGTE}qp*j(lw5BjAapBp`ZLrI$oyb4%K&9X+?#n_nApE3_mC)BUaP zM)txzL9P&(E1$kMcrlx&m$^&y8qdq&FSiL!j)zRX9`PI}YJQm@%7a=+(^}@S*n~AN zbX*Ct0BdXK(Q%`F@hsD$mBd7G~`YkkPz0jS7*Lsrju!^Ha9S;n4LWyrZobH9mS=id%ht`Ppb(c zJLGhfZR^-0gr@|Qg!($OWFz)M7X!>1A5W3_>lmqV@tGtjgy_kgW7RTn5fKt@ymJ+S zsai0b7lOuC9I;Zek?lD-zdvvR>O_P#At={}a(BHZOP4bfrRH*qf18K+LaKrALH zLSygE3*|Nj#bBHf-Hk?|7PCeV#YL{p)sD^F!FT!fnT^6-e)m0QM;J7$V+&^iM%E<| zyX)CrEZTdia)V*0$(~u{74CZo)12377HN6vl8oQMawJfPt%5`{Hs&X;tjO{jCpg>3RPv8e k@4}O7*1P3xU3pxVVK#af9er|kZe~)hK5F-ue1KH_8{D@VMgRZ+ literal 0 HcmV?d00001 diff --git a/po/cs.po b/po/cs.po new file mode 100644 index 0000000..7835d61 --- /dev/null +++ b/po/cs.po @@ -0,0 +1,411 @@ +# GNOME-VFS cs.po - Czech translation +# Copyright (C) 2002 Free Software Foundation +# This file is distributed under the same license as the gnome-vfs package. +# Michal Bukovjan , 2002. +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs VERSION\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-08-14 22:57+0200\n" +"Last-Translator: Miloslav Trmac \n" +"Language-Team: Czech \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Report-Msgid-Bugs-To: \n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%" +"10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s: %d obsahuje znaky NUL." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s: %d neobsahuje název metody." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s: %d neobsahuje název modulu." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Soubor s nastavením `%s' nebyl nalezen: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Neznámý typ operace %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "Nelze vytvořit rouru pro otevření kanálu GIOChannel: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Neznámý typ úlohy %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Operace zastavena" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Nelze zpracovat: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Další chyby při zpracování budou ignorovány." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Bez chyb" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Soubor nenalezen" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Obecná chyba" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Interní chyba" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Neplatné parametry" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Nepodporovaná operace" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "Chyba vstupu/výstupu" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "PoÅ¡kozená data" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Neplatný formát" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Chybná úchytka souboru" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "PříliÅ¡ velký soubor" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "DoÅ¡lo místo na zařízení" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Souborový systém pouze pro čtení" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "Neplatná adresa URI" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Soubor nebyl otevřen" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Režim otevření je neplatný" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Přístup zamítnut" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "PříliÅ¡ mnoho otevřených souborů" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Konec souboru" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Není adresářem" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Probíhá operace" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Operace přeruÅ¡ena" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Soubor existuje" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Nalezeny odkazy ve smyčce" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Operace nebyla povolena" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "Je adresářem" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Nedostatek paměti" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Počítač nenalezen" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Neplatný název počítače" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Počítač postrádá adresu" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Přihlášení selhalo" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Operace zruÅ¡ena" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Adresář zaneprázdněn" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Adresář není prázdný" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "PříliÅ¡ mnoho odkazů" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Souborový systém pouze pro čtení" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Není na stejném souborovém systému" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "PříliÅ¡ dlouhý název" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Služba není k dispozici" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Požadavek činí data služby zastaralými" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Chyba protokolu" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "Nelze najít master browser" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "Neasociována implicitní akce" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "Žádná obsluha pro schéma URL" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "Chyba při zpracování příkazového řádku" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "Chyba při spouÅ¡tění příkazu" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Neznámá chyba" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 bajt" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u bajtů" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (neplatný Unicode)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "Neznámá pozice GnomeVFSSeekPosition %d" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "Nelze nalézt platný soubor s nastavením v %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "Jiné umístění lze zadat použitím proměnné prostředí %s\n" + +# Yes, I have checked. Solaris 8 +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "Applications" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "Cards" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "Files" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "Folders" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "Help" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "Hosts" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "Links" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "Mail" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "Tools" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "Windows" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Generátor Standard Moniker" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "soubor MonikerExtender" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "obecný moniker GNOME VFS" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "obecný moniker souboru" diff --git a/po/cy.gmo b/po/cy.gmo new file mode 100644 index 0000000000000000000000000000000000000000..2b1664299eedd1058ae27f75fb2d0e61477a10ce GIT binary patch literal 5409 zcmaKuTZ|<|8Gs7`FN0iFP%cs^<6hv*&g_DWvlkdc8A>^2>Kv(y6g05wolce zFMFn+F@}f_8YN2Ni%~-~F={X-8WSIgQGCE?l!PdFAsXY05`8cMjo;s0=ga^bI#ctV zs`~5p->P1^>Y^tU-+h$pDPMn^QUiGF#r)&@^ z4)veG?gdKy9?CxNWKog74~kzs80rr}S+@^wf{(!u!*7ND=b*?x4`n|uLR73?3H4Xu z0qU2dOqqWP?t%A0(Psr^+~=X3>l^SE_;l$1L*T2Bt*UEqA`NebyWldEa}NR^g;!I5 z60)@VE)@Iz1j@dC4w*{*8p?WqhO)1JLOI`mpv-qIN)dg{LQJaefiiv*%04~`F@?&Y z=zj|`R6Pzw{wt6_^%Va^e?NrchcCcs_!5-y7cp4Qdj*vF55W(?6)16*Lb2bcpzQle zDEs;*WD506=>IL`PyL;LqR;26)xLd`W)i&12Y zLdVvnHdc$nVU|XwOuZ}A-6qz(l#zYo;>@Zg0*~2nL^78&edc1t!2oT9cG=F3R-L8JsufY0-AaqHXn#+Rx?L5W zwYAcF-A$9Gg1paSj12Pu8Y@SBi%6`;wn+?@*UzC_eRH;oI=a{i=6F=B7 zw2|B1gH#K(y68{mj;^>WM)CoC(XeRS6Q71g^ z*)vsEYGMG_)TStWl;VZ4bhbL-N9(6~wJ~;iKqcC(nug*_N^{tOHDKsHO@IuC&ldt#PJSQ(-xdPGA^>2=wrJL9Sw7z zG=|#Qigtn*Z?}rQm~4=ia>(uWqV&TdEgQKnedNbhJ7tMg@3Q)JTa?z$d0HQ-EUx3b zh0m~Rp@}h3$S%?VQKe3|)#hC097Z!;qW^S>-xJn)-MjQG(b>ZoqNFp}iI}Kci*HxG zC`dF`NLyB@O?TG$5xK(ofxUm_^l59)ZulZ?OgbG;`dfRBr62ZPeO8jfbTyIiLtWOS zpQfp(hC`pDCdovt`qgHE|6sLg@xXIw?%lvTiKRT1!{A%EgpJZ(-FQH+hlA3e`8M~> zOsNN0lI)`zlZPWOZ&pDGE_*qlUj6da*Z%A}_mHg3dN50i8{t8wRkf(Q>@(75`* zcFy&Rsg09oI!lsMY44EM$Zz{+XAg8{=R5mv*K-FJ=H_pir3JyxDLhxkzd>&9Ha)k0 zVfKz&X6KMwBYSqvc~2h3yTHq zhE26Ny#JtXe;(fL^i7BL+@6C|YInF)HFr>&)x{ew*QLqjx^BcPor#OhSvB$;Km z>L_7Ir1Wf>jknJtn)H$8a@$tiwOwl3bbUU`Roj=4`Auw-s*zvI>Liy_G$IyRzQBe?)ESE%bhvg=`z{W{?o&cAu5wX-H?NB-4+?#A_sAsN&$8wA2&mDZ1<|D* zq1HYJuNZ~~qJE8HcM8O@?Q?l#DFP^xhe@U zo;RsYW_!Kzcgi0NBkMdYxxQ~P{OZ|}^O@Q_wK|z+qq*DT9D|KFy0p_uaXn(MMV)1m zpMqBmm?!Z)!X}khp=1~FiYUl6=8x(u>a!RbzEq2ZSr;iBIuRqX+QhTC=V*xfGtEgw zqy03;@B=w@Yh|4iEaF*&PJ-=Yq9Y|1nr&4!gRqIVPIqRT|d= zQB6JZSoHvAPj|7%_;i(ea8Tz>T0L2NjZeGJh;WrOhFroW2~;mq@k@*y0IC~Z?MDU ztx%Yr7tcFJNRVpK)SP7ULpcHFr2|2, 2003. +# Dafydd Harries , 2003. +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-08-14 12:07+0100\n" +"Last-Translator: Dafydd Harries >\n" +"Language-Team: Welsh \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8-bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "Mae %s:%d yn cynnwys nodau NUL." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "Nid yw %s:%d yn cynnwys enw modd." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "Nid yw %s:%d yn cynnwys enw modiwl." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Ni chanfodwyd y ffeil ffurfweddu `%s': %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Math op anhybys %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "Ni ellir creu pibell ar gyfer GIOChannel agored: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Math tasg anhysbys %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Atalwyd y gweithrediad" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Methu gramadegu: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Anwybyddir gwallau gramadegu pellach." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Dim gwall" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Ni chanfodwyd y ffeil" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Gwall generig" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Gwall fewnol" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Paramedrau annilys" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Gweithred anghynaledig" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "Gwall M/A" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Llygrwyd data" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Fformat annilys" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Dolen ffeil annilys" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "Ffeil rhy fawr" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Dim lle ar ôl ar y dyfais" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "System ffeil darllen-yn-unig" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "URI annilys" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Nid yw'r ffeil ar agor" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Modd agor annilys" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Gwrthodwyd mynediad" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "Gormod o ffeiliau ar agor" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Diwedd ffeil" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Nid yw'n gyfeiriadur" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Wrthi'n gweithredu" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Ymyrrwyd y weithred" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Mae'r ffeil yn bodoli" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Canfyddwyd cysylltiadau cylchol" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Ni chaniateir y weithred" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "Cyfeiriadur ydyw" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Dim digon o gof" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Ni chanfodwyd y gwesteiwr" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Enw gwesteiwr annilys" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Nid oes cyfeiriad gan y gwesteiwr" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Methu mewngofnodi" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Diddymwyd y weithred" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Mae'r cyfeiriadur yn brysur" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Nid yw'r cyfeiriadur yn wag" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "Gormod o gysylltiadau" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "System ffeil darllen-yn-unig" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Dim ar yr un system ffeil" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Enw rhy hir" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Nid yw'r gwasanaeth ar gael" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Mae'r cais yn anarferu data y gwasanaeth" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Gwall brotocol" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "Methu canfod y meistr-borwr" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "Dim gweithred rhagosodedig wedi ei gysylltu" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "Dim trimydd ar gyfer y cynllun LAU" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "Gwall wrth ddehongli'r llinell orchymyn" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "Gwall wrth weithredu'r gorchymyn" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Gwall anhysbys" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 beit" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u beit" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f C" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr "(Unicode annilys)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "GnomeVFSSeekPosition anhysbys %d" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "Ni chanfodwyd ffeil gosodiadau dilys at %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "Defnyddiwch y newidyn amgylcheddol %s er mwyn pennu lleoliad arall.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "Rhaglenni" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "Cardiau" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "Ffeiliau" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "Plygellau" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "Cymorth" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "Gwesteiwyr" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "Cysylltion" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "Post" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "Offer" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "Ffenestri" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Ffatri Moniker safonol" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "ffeil MonikerExtender" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "moniker Gnome VFS generig" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "moniker ffeil generig" diff --git a/po/da.gmo b/po/da.gmo new file mode 100644 index 0000000000000000000000000000000000000000..5f89d48ce3845c69f8170e3e1fb5a8db60d43e09 GIT binary patch literal 5373 zcmaKvU2I%O6@UlQ7H~%BX( zy>r*eKJbLZUnK-8Eq&+%sBI7r6+);eLOg&hR23n3;YSE4KLv>wK%xls0U^FKcWiG% z%9UroJ2Piy&YW{*&h<;zUGcc$d604w<(W4s)q{6k$q&!(uTttd_y_nV_)o~6`gg4F zpz(dwua3Mkavr{!_6`*JN8nC)9=;WR8omua2JeJVLs{}Ca1Z<$yczxnz60LGWY@s` za5ua^);m!8&%vwVqwwAEEAYMWo3Z^zP{#iPiXMN4qQ@&RZ1pYm{;q;=r~Miza<{-M zU<1lJQ;~B}=6eXr_#E=5Tx=gg(dV;J?Dyr^{>w-+{9J_uviiMJVgM4DWz{fwKP2 zvDz;;LR3}LP~;Co+2_Zh*wMpl;iuq@@Np>mek<~a@Lkk@75R54R*E*|6M5Sya;7qzlFEJm!astgH1~RwNUIZ4rTsnco?39xLAD= zz7swPWq;4b`U|l02Bm%jW&A9Qiu^~R#MQ&Gok3mG$H{f1)5sLl(1ZAK9f)YPt{K$E_5st%Y zDC0f>5m7yeiPR?{TT`EdV!tP#==l^Bxu;|Qw`2SFq4@0uDC_+W%KEQBvCEZIBu;ih zng9C8+o0HQBGwN>S$8S6KLl^5-h;CLFTp$E6HwOq0TjFb9E#muh2rNOOe+4m9g4pX zLAehWpzMDQO1yjqik-g-WxnSjQ>Yi=_3+oR{tqa6U4f9ydu`-i*q}ZO#m^qTAASMK z_~)Vc=f_a?{YNNz{4LgZvbd~w0~CGsLecLSoPh}x`#l92qMm``w~J8bc?lAR;gPtN zXQ4)rKh3-7Epr}-?VC8ri}+HW4^c$lJrwbyJP%OrrtGDJn1lCGxQfGbFTWp-@8TQr zuRLN0@sT_`C?5=O+>wz-pxBVmc+Df{Vu_+D;&XXUQD!N}C?_c5TX|&f$0;A6h<$KR zc*KTx#dopORD9nZDZZMgNX&>|_EC0Gj#A_t$b(74b5G=hP<$chKzu8YoP|3m_frm0 zr0mHI}IQ znekM&oUM}FdVO+rQMWotnY1cX`iV=stTthbf zbKaE9v)S8EN^io5V@Z`@qp}?ID-=JLr*>Byo#@)m-c(g?GheTqR46uvU};*FD~Gx{ z@WYX+EN*)JYN%$>z_r6DHCvW!u}B8C)nP7H?DeolY!`J#T6K|Iqvph9=6voeU%zi{ zb-OAyt80~Wx|wI8g1jqIoD9nz3d_i_7j@iNQ|2vgL?3m+6n%BV`3l#FDRq*jC2p+S zBo0P~2Dxn=r0UiDzEg3od5fuSQfyUYke-=W^D$uACR0lEsd=vxoo?DtE#|iC)uPLC ztJ?`1PpP=R*aTa2y*9RmlNn0S5&~+;mBdc8TiA`)=klV^O{4S7(wk1Gld=P`OyO*% zPCCM~oeYXfa|Q@aop|qBIZ>EOXKfQ+>NqV!RIZ*`)V|d*JtHE%pR|lFOuNzyPtAJX zl6EE>*^JbUb%U(KiRuv|K?3=zW3(5Q!fEhBg0rViN!a%|$0MeuEe3llu`N@GJ+|Ah zQNMIqaMWlk)`?NP-75ZKvR+=vCb!#t<@$YEPM5B7Ew|~lGlsM3Y%zR|iqhJ+OzR^9 zL+H4scLiScnlmN_*~K-$sZz^zHS8-{$7xBE)4yC1_Z(}z*`Bd-mdacw?2HjNHkN#rr;Q_n%r{otj2=5(kU)xt z+=zZg+kU9}LsJKJ{d#D()wdqflY0)1kz)thut@VvUy@^+b#m>-97{FiSbS_c;mVaP z+o()tHxuYcSI+(_NwOSvo2>sI5lOUBqE540SvJkEu3SvbL0ZY_&A3u~gwkrQu%xb{ zv+=A=t0YqkiPd?xYl!HQBxb_7>?U$cS9zf~o^Aeb%3Z*CYGE|vdI>_ScS*|a4#>^* zoRVP;rX)=-T+*sLZr!AtX?IHt)UI67trPFYlc_0^EGnhuxD~2;V%Cb*cYVKcp|bc^ zbkNKha_>^Y-DSD2*%#Y16)9n}C2Y5Hy-Fkoi_TZ6Kfk6NXln7E|ij$ON}1vH3@myY`b|~1iS=Elnoni*LsA}EJ${4gjwt4 zT(1x#MX!>X<9o=YlA24y7YSD#7cmCq`+!T&iz%2aWM{sqa$gLIDSRKD))|o^Czd1} z#bmRJ4+yaVb-pPw zF$>?3%pLPLvu=rq32W*45b&{soCG_Gyy3g1m#BF;5u6!zT_mXw@nLL-Y#4gBb{}dC z^;NlXfiY}AcLowMrtqc~me|7clGf|I9<%zUktHC|z=vt%gKs+p^OZXwvy1ZEjlphm z#z)$ccC(bzzAY7e&6KD=+FU2~a4l4>>x$s|E-<$oA-v5mA=U~($hW{*Zp;B% cvyaAQKLs%M)~7(@a)t^Y402WE#pSyH3+X(7`2YX_ literal 0 HcmV?d00001 diff --git a/po/da.po b/po/da.po new file mode 100644 index 0000000..00918e0 --- /dev/null +++ b/po/da.po @@ -0,0 +1,416 @@ +# Danish translation of gnome-vfs. +# Copyright (C) 1999, 2000, 01, 02, 03 Free Software Foundation, Inc. +# Kenneth Christiansen , 1999. +# Birger Langkjer , 2000. +# Keld Simonsen , 2000-2001. +# Ole Laursen , 2001, 02, 03. +# +# Konventioner: +# +# script -> program (sÃ¥fremt det er muligt, hvad det hidtil har været) +# video -> film +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs CVS\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-08-21 22:41+0200\n" +"Last-Translator: Ole Laursen \n" +"Language-Team: Danish \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Report-Msgid-Bugs-To: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d indeholder NUL-tegn." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d indeholder intet metodenavn." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d indeholder intet modulnavn." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Konfigurationsfilen '%s' kunne ikke findes: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Ukendt operationstype %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "Kan ikke oprette datakanal til Ã¥ben GIOChannel: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Ukendt jobtype %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Operation stoppet" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Kan ikke fortolke: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Yderligere tolkningsfejl bliver ignoreret." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Ingen fejl" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Fil ikke fundet" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Generel fejl" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Intern fejl" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Ugyldige parametre" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Ikke-understøttet operation" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "I/O-fejl" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Ødelagte data" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Ugyldigt format" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Ugyldigt filhÃ¥ndtag" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "For stor fil" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Ikke mere plads pÃ¥ enhed" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Skrivebeskyttet filsystem" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "Ugyldig URI" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "UÃ¥bnet fil" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Ugyldig Ã¥bningstilstand" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Adgang forbudt" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "For mange Ã¥bne filer" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Slutning pÃ¥ fil" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Ikke en mappe" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Operation er i gang" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Operation afbrudt" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Fil eksisterer" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Fandt henvisninger der peger i ring" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Operation ikke tilladt" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "Er en mappe" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Ikke tilstrækkelig hukommelse" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Vært ikke fundet" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Ugyldigt værtsnavn" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Vært har ingen adresse" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Logind mislykkedes" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Operation annulleret" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Mappen er optaget" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Mappen er ikke tomt" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "For mange henvisninger" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Skrivebeskyttet filsystem" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Ikke pÃ¥ det samme filsystem" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Navnet er for langt" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Tjeneste ikke tilgængelig" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Forespørgsel overflødiggør tjenestens data" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Protokolfejl" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "Kunne ikke finde hovedbrowser" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "Ingen forvalgt handling associeret" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "Ingen hÃ¥ndtering til URL-skema" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "Fejl ved fortolkning af kommandolinje" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "Fejl ved kørsel af kommando" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Ukendt fejl" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 byte" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u byte" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f k" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f Mb" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f Gb" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (ugyldig Unicode)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "Ukendt GnomeVFSSeekPosition %d" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "Fandt ikke en gyldig opsætningsfil ved %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "Brug miljøvariablen %s til at angive en anden placering.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "Programmer" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "Kort" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "Filer" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "Mapper" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "Hjælp" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "Værter" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "Henvisninger" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "Post" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "Værktøjer" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "Vinduer" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Fabrik for standardprotokolhÃ¥ndtering" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "fil-MonikerExtender" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "generel Gnome VFS-protokolhÃ¥ndtering" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "generel filprotokolhÃ¥ndtering" diff --git a/po/de.gmo b/po/de.gmo new file mode 100644 index 0000000000000000000000000000000000000000..7734a079629d00d1333d56a214f1a5947df4ea10 GIT binary patch literal 5536 zcmai%NsJvw8GtKf0VX6NVM!ocu}qxpjc1%~GKn3}I5YOdvp6%JSTYy-y{_)pdHt$i zy1HkRA`VDVq+AdXKp@0s2~ZRTE#m(zF~ z^{Z>%U2_q>gZ4HQ`DfrYa2vi0J_oOZpMiJ7Z$Me{HFy{NCA<~>8@>nL!erONNq8rG ztgg4A^l!nd;S2Ca_<8t2_)6XWb136qhoZ-uQ1tjG^jm#rwZE(2yJ^1`irnq+3fO?M z&ViZ>Q06-gWqbnpr?R?z2Z}z=L$Tjy>-KL#kv|J%{d4dG@Kq@5ya7K7{|sgQYsMoOKpB4}O3Jufq3mZr6uCn+ zPeM)o>AL;`yovhPpvZp@$~vz?+1Kyj?eGmK`d`i_rT=;;b{K~;|1_M1D-ai}Pr>)X zFF@Jf%XR&y@W5qC{T9BT_Ul+w^pQ!u43MCG|1x1fnAS$Z! zP~!eIxD5XaMebpY`Vc$}C*d}fIR7>jd;JVP3V#DduNw&(;RM8WY94+VuEINE4iQyf zg0jz-pxEIDkR{dYQ1xQ@*S_> z?RkRVVkepVzPi1SNBALolJ8-P>|1Om`pb8iazEuB$^>PBa)?4I_MgPr6ZLP&5t0Yw zll_WKAr8lqrhjAEob1>}HTAq291bD+|qCYJ6fU(nsei9gG;ioSO1f zv#pkKPKU-OCRDS%UYfLmBFU^%b3v%1gpuvQhN)3U0&BBEw{jB{M)#7Q(NUJ`tY@q~ zy104-F>BHpJ?;?AL;hwqO5!s2^Ho!QeBABRTY=LuQz(#pq_6ih#JPGZ-dUT*GJ3CVpiH%*ga!{by7=pQJ6Ng9W!Z99m`ySYs8c~2*VsV zR&5doBSXF1PzR|xwYYz^o@>!!Y8#}3Y8|9&i)yhBShmTO5`AjX=|G2l8>*$mcAQ$u z;>7AGVB;Z`tS2_X79FRJZQ*2w(zA?!TF!D}r?#8ljni96n(C&}No?s2C)A4UKrEAH zHdZSc;TZ*GT4>Gyp{WDsvQ|PAhSFKtgdbI$<~}Mn)|RwuwN2NEi0cI{qf-+Vn&F|@ zOj^>;gd>}gy0KXqw>eQ=Lc~iTU$l*OqLM!iZinFPs#OX5F6Vf})U?&X-U@8Xq+*X@ z8#e0YS?nD(+KP4RC?2+oznH9>6tc--yDPF@kCqd8R%ETL@3l3MPvZl*Yyy`S(OboJ*G{C7+>s8h7E7-(oL6g(JUJ&;jYrUM=q{HcqaE2J^B!1#d z>{K2fRx>e>SjePnq*ldejVY9AzYGHldn9hmJCElgu;h?|rXJ7j1tf@Pa6voSe zMAp;A4(Z1?xw6;Ga?B)|s4~CWaKsN@8@16 zBYtI;3*;VXOd|Kt%+zEhw?qzYoXi93(f~ir=p*f%oRkDsub8qMB)NXHB~6DbRYEh7 zmkM@Ns=}L5Yae02Yqp69>F)}_TVqLs5qYJZL?C+)A zVvqP6jD&n} z_TCxN1XpI`v`IMrwtpcG`Z|UrZS}IhGmVvG`M-ta=JXP3ywr2tn_Qb7r^`4`qDXI= ze9MTAg_^ZnL^GiX&~}G|`Kk?Eix1YE!AhQJ{vsvoW;MTmwo%VtUH`-NHb##fZ-8N4pXfgWcm;4%a-EHMM_kged*^z@ zmYjfDGHxoTL5sCxiHDS|V$~X_Tq-56PVxGM<4D&3X z)j?7{8@y-yy8&yb929k2?5Lk2sRd0Fbo?z7aq(40$anXRETa0Df8}zo$pPf~&{&t} zLr@8xAc^ksENJICC?n#iE17Zc40npj84)*wyplxGe#EMk`n+KmwjS#Bo=-}7-BHiv zOxh$ieOT3xi@nbgKeAIE7^Tzvs&e7TOCV^*h6l3bxRKU$?@SpLBMtuX_1|(;V32o$ zvNhk<0UnYH#!MPk6^+eWe%;x;}LLMkX!NH@=@m7(}DjK{)Tv1t2 z4}|3W$o+wm>!k9KGVb(77bi;`^j|Lb>ar_G4>7`3UM+f+r2|U}H$)LHmj!RlIvMsY YHF&y=rWn872K((xU66ph%?3UH0Xd(*fB*mh literal 0 HcmV?d00001 diff --git a/po/de.po b/po/de.po new file mode 100644 index 0000000..b4633ad --- /dev/null +++ b/po/de.po @@ -0,0 +1,413 @@ +# German gnome-vfs translation. +# Copyright (C) 1999-2003 Free Software Foundation, Inc. +# Matthias Warkus , 2000. +# Christian Meyer , 2002. +# Christian Neumair , 2002, 2003. +# +# TODO: Somebody who's familiar to CDE's terminology needs to sync the +# CDE-specific strings up with CDE +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs 2.4.x\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-05-05 17:10+0200\n" +"Last-Translator: Christian Neumair \n" +"Language-Team: German \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d enthält NUL-Zeichen." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d enthält keinen Methodennamen." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d enthält keinen Modulnamen" + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Die Konfigurationsdatei »%s« wurde nicht gefunden: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Unbekannter Operationstyp %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "" +"Es kann keine Weiterleitungen für den offenen GIOChannel angelegt werden: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Unbekannte Job-Art %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Operation angehalten" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Verarbeiten nicht möglich: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Weitere Verarbeitungsfehler werden ignoriert" + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Kein Fehler" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Datei nicht gefunden" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Allgemeiner Fehler" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Interner Fehler" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Ungültige Parameter" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Nicht unterstützte Operation" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "E/A-Fehler" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Daten beschädigt" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Format ungültig" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Fehlerhafter Dateideskriptor" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "Datei zu groß" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Kein Platz mehr auf dem Gerät verfügbar" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Schreibgeschütztes Dateisystem" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "Ungültiger URI" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Datei nicht geöffnet" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Öffnungsmodus ungültig" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Zugriff verweigert" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "Zu viele Dateien geöffnet" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Dateiende" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Kein Verzeichnis" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Operation läuft" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Operation unterbrochen" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Datei existiert" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Ringschluss bei Verknüpfungen entdeckt" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Operation nicht erlaubt" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "Ist ein Verzeichnis" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Nicht genügend Speicher" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Rechner nicht gefunden" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Rechnername ungültig" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Rechner hat keine Adresse" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Anmeldung fehlgeschlagen" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Operation abgebrochen" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Verzeichnis ist belegt" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Verzeichnis nicht leer" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "Zu viele Verknüpfungen" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Schreibgeschütztes Dateisystem" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Nicht auf demselben Dateisystem" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Name zu lang" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Dienst nicht erreichbar" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Anfrage lässt Daten des Dienstes veralten" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Protokollfehler" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "Bevorzugter Browser konnte nicht gefunden werden" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "Keine Vorgabeaktion festgelegt" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "Kein Handler für URL-Schema" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "Fehler beim Verarbeiten der Befehlszeile" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "Fehler beim Ausführen des Befehls" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Unbekannter Fehler" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 Byte" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u Byte" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f kB" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (ungültiger Unicode)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "Unbekannte GNOMEVFSSeekPosition %d" + +# CHECK +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "Es konnte keine gültige Einstellung bei %s gefunden werden\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "" +"Verwenden Sie die %s Umgebungsvariable, um einen anderen Ort anzugeben.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "Anwendungen" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "Karten" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "Dateien" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "Ordner" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "Hilfe" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "Rechner" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "Verknüpfungen" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "E-Mail" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "Werkzeuge" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "Fenster" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Standard-Moniker-Fabrik" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "Datei-MonikerExtender" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "Allgemeiner GNOME-VFS-Moniker" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "Allgemeiner Datei-Moniker" diff --git a/po/el.gmo b/po/el.gmo new file mode 100644 index 0000000000000000000000000000000000000000..2c67bfc18130c3fb8e4f2b913caf4c08e1c64634 GIT binary patch literal 6125 zcmb7{TaX-88OIw0!4*^x6}-UlvW5UN*$ug|TqFre*dn(go2U;`^v?9oHapWjPWL3) z2di>VK_yfLjg+8b0hXn;NlZ5D?j%{)2cFdG!ScmhSv)GGZ&qn6rTqO*_gwap2YdI- zf6h7IIp@3lzwh+?`Su%5J3Jd{pQf$4-f_MPZoPpIo}b?6IJbl6!JELh!1sf{&icOv z@23C94F8?sT?pOG_&QMX>-o49d=mUHxCgus908Yur@+sEm%)#MzXv}A{vEs*{7=^J zMG4KX0zU{onc)y9`Da0$6N0yZ-vB=XzL1T-3Tpk2Gn@sr?l<5Ez<09#yP)>J3d;T) zF-CHCg4%Z(co(<|`~tWg)VUGJzjKg}Pk=9gviEiHHt+)YDex^&dc2e2KfsUCzZoTj zcY|8L3e>u-pw53Lo3CVe7&MH3C+lAV@1*}WDEYsFI_F>DJ>V@psh$sj8Xo{<-*!;v zy5M?nA9x4Y0A**A_5T8Hyv}j{3yLr6aR#b8&wzx;DS^1m3Bc9hUhq+H0u;yI&F1qs zOY&<#>Gdd>2fqfE!4shLxC(9uAI6x6z!$(?@GWo$_%4_O2XOK#a1@lj-vbRe4NCrZ z;7ag4@N-~4q>#NspyZzeHGc%u{51G^@DJd<;CrC-Tt+ZB(%Axj7Tg1hxBEfq_ib4;P*lC=5L_Z-$pRDfGfb2;66}#{{+BRWT%&~ra+8ErtF z?2%pa{f5>+7s?jdbt_GL#7)lQG(EW3`oMPhAQc>yH$#ICHr|A*{U}bdz4ctr7sUw5 zTOZ>xn`7d`!!$keq5PuQeUf$~Z8fc*raIC`gZkE2$^$*CXo{hpM`+@kVy(Qw%{Kqv z2Z|?p*6YLE>j!(?vR^d21HTX!z2#1CzJJ7Q*^uH>DQu$~4fGaGAq-;I4AD#nkG;t0x9F@d6uc-hMKAEZqO-v* znh_u2Q8y@-J!hjE1Yv9nHP4MbQ}wH!83}79ta^djGPq+SVu4p4FujqpF$_lhQoZKJ zei)>iJlh*BGyB}gXpfPw9uzaldKqms<_ASnaU%>f!?kc<7d;{^pm!Xjq2g*C#9zcp?3j?6y4TsFg=@k;@-#k{j!3d`zp z7?hmtVWtpYqN-c)OxYWW4Y4nJd;NlkKs-+s^}QghmqsCMg`ijo2XII*_cDZ|rj5|!G z?TX1bw^lUU!oVLRA4bS`IcW%oSKMGcjasK0%0cp2AYQ%V&tAV4 z1{E(5@oT=!fF6*+EBGVhHufVU(2MzUSg>^=-{aUIXGU(?AA3QOq%UPDV=XY4KJtAXJi-eSHt+ z`qt%Et~UJ-4)m|PzmE|Fb5Fxq?J`fUKi9X`^sgOQy*8EGN}b9L)!ZN|yF_NdJVj=c z*E`*+TlA@7=8@`H6hB_7?9T^Y{8-OcHz?KJl9wCu+{%F2QX?$pk)Rws9@qEhN8xY1 zlrPmD>)AHAZBxgP{(N5##T3tQ9Kjecv9~{7Q7v;DJZx_QYTcu|hc@Tdb>yTLzRqnT zsf#4>fLS-}$30)k*dV=X!Bq)xA104URroH zC2t~?-cQW~$rOtk$(iQyWGZPG;5-B8+3iSjmTyzdL%O{3PS>jBBC@k)@!}K7Y%+&N z=M5iI$xQPEqI1oo|MzO?Fw;EPd{LXB$z1agmtuPBwJyEn7(%njbn|dBjV?%^;OhnC z8E77Il4C8GU_xph3mVPC*0MuJhT7qCQqf6HvDp+hHJV58m*p!q>{qa0g3=)!A=_EHCecAImO5M%;GHE+x5A-!xAkdm*(|9zcgyML_e0 zWzme~17YtRf#F>#&(_&4WE1gTKwG1%=*ZyUH#%y_W~F9UFjmn0d8^|jr6JNE<(&S(=fo3V+=Mv&`x)bsx*upIIo)dw!g9-+g9wxo?RRsZtD=-Vn zg_FG0ou}4*jF=Qj(~Z)MN|TS>*nmWreJVQ#VA~Y(RMy40H=)6H)KCKzW>P&SMSRqn z;S?$Y#rB8nrMgZ;*;A=IF`qFyg*hAlSF9;%-gckS%GvqcR-jaL4%p>3b<%V_-h7c0 z+YX}yVFV^pupkZ$%ql=vwk_fMQ<+zF0Z?$1dsi4b%O|{RlS=Wqga)c>N?gveMfaR# z>k`4rQuAEu?-pN3kxU1>fxS7>$j(8KN%=?nsu-Mtc9hq&)*D4i7X@?edqGmKE*?fV zr2>4m<)i^xOSmay0*<7tUSqqLmz?PoE*9&y;%=}3x4v+aYp=3ra!npcFA^u|&Om#G zD$C|Bb%B^f=J6qHLz^Z?q1SHY$91#-N()vrJ zc_Se06mgpYs#RUrj7GWo({enGUvwFAWh*oQzH`U+NyYypjA22I%#V zce5q=>m)xy?kvZ#I1QNO`Ffs;#bwSnWj@=cFQ*q0UFN#ZTkkRaa_N5C(tSlD+X`r3 z@e&B8%Axl(bWdN{j-jO}aYR<6Cn$jxuo;Fk>#z0eh5&SK(8WJ-=1q6SZm#_!=zqKW BNtFNq literal 0 HcmV?d00001 diff --git a/po/el.po b/po/el.po new file mode 100644 index 0000000..9c3f13c --- /dev/null +++ b/po/el.po @@ -0,0 +1,1531 @@ +# GNOME VFS Greek translation. +# Copyright (C) 2000-2003 Free Software Foundation, Inc. +# Spiros Papadimitriou , 2000. +# Simos Xenitellis , 2000-2001. +# Spiros did 90 messages. +# Simos added 34. (15/07/2000) +# simos: 384 messages, 14Feb2001, (sgpbea). +# simos: 384 messages, 18Feb2001, two fuzzies. +# simos: 405 messages, 27Feb2001, (rgmtsgpbea). +# simos: 406 messages, 01Mar2001, (rgmtsgpbea). +# kostas:66 messages, 07Jan2003,updated translation for Gnome2.1x +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs 0.6.2\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-01-07 17:57+0200\n" +"Last-Translator: Kostas Papadimas \n" +"Language-Team: Greek \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 0.9.6\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "Το %s:%d περιέχει χαρακτήρες NUL." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "Το %s:%d δεν περιέχει όνομα μεθόδου." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "Το %s:%d δεν περιέχει όνομα αρθρώματος." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Το αρχείο ρυθμίσεων `%s' δε βρέθηκε: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Άγνωστος κωδικός op %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "Ανεπιτυχής δημιουργία διασωλήνωσης για το ανοιχτό GIOChannel: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Άγνωστη είδος εργασίας %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Η λειτουργία διακόπηκε" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Αδύνατη η συντακτική ανάλυση: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Επιπλεόν συντακτικά σφάλματα θα αγνοηθούν." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Κανένα σφάλμα" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Το αρχείο δε βρέθηκε" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Γενικό σφάλμα" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Εσωτερικό σφάλμα" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Άκυρες παράμετροι" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Μη υποστηριζόμενη λειτουργία" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "Σφάλμα εισόδου/εξόδου" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Αλλοιωμένα δεδομένα" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Άκυρη μορφή" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Άκυρος χειριστής αρχείου" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "Πολύ μεγάλο αρχείο" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Δεν υπάρχει εναπομείνων χώρος στη συσκευή" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Σύσημα αρχείων μόνο ανάγνωσης" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "Άκυρο URI" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Το αρχείο δεν είναι ανοιχτό" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Άκυρη κατάσταση ανοίγματος" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Άρνηση πρόσβασης" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "Πάρα πολλά ανοιχτά αρχεία" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Τέλος αρχειού" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Δεν είναι κατάλογος" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Λειτουργία σε εξέλιξη" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Διακοπή λειτουργίας" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Το αρχείο υπάρχει" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Βρέθηκε βρόγχος συντομεύσεων" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Η λειτουργία δεν επιτρέπεται" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "Είναι κατάλογος" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Ανεπαρκής μνήμη" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Δε βρέθηκε ο κόμβος" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Άκυρο όνομα κόμβου" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Ο κόμβος δεν έχει διεύθυνση" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Είσοδος στο σύστημα ανεπιτυχής" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Ακύρωση λειτουργίας" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Απασχολημένος κατάλογος" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Ο κατάλογος δεν είναι άδειος" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "Πάρα πολλές συντομεύσεις" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Σύστημα αρχείων ανάγνωσης μόνο" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Δε βρίσκονται στο ίδιο σύστημα αρχείων" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Υπερβολικά μεγάλο όνομα" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Η υπηρεσία δεν είναι διαθέσιμη" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Η αίτηση απαρχαιώνει τα δεδομένα της υπηρεσίας" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Σφάλμα πρωτοκόλου" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "Αδύνατη η εύρεση πρωτεύοντος φυλλομετρητή" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Άγνωστο σφάλμα" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 byte" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u byte" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GΒ" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (μή έγκυρο Unicode)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "Άγνωστη GnomeVFSSeekPosition %d" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "Δεν βρέθηκε αρχείο έγκυρων ρυθμίσεων στο %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "" +"Χρήση της μεταβλητής περιβάλλοντος %s για τον καθορισμό μιας διαφορετικής " +"τοποθεσίας.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +#, fuzzy +msgid "Applications" +msgstr "Προσθήκη Εφαρμογής" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +#, fuzzy +msgid "Files" +msgstr "Το αρχείο υπάρχει" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +#, fuzzy +msgid "Folders" +msgstr "φάκελος" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Εργοστάσιο Standard Moniker" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "file MonikerExtender" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "γενικό Gnome VFS moniker" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "γενικό αρχείο moniker" + +#~ msgid "3D Studio image" +#~ msgstr "Εικόνα 3D Studio" + +#~ msgid "AIFC audio" +#~ msgstr "Ήχος AIFC" + +#~ msgid "AIFF audio" +#~ msgstr "Ήχος AIFF" + +#~ msgid "ANIM animation" +#~ msgstr "Κινούμενο σχέδιο ANIM" + +#~ msgid "AVI video" +#~ msgstr "Βίντεο AVI" + +#~ msgid "AbiWord document" +#~ msgstr "Έγγραφο AbiWord" + +#~ msgid "Adobe FrameMaker font" +#~ msgstr "Γραμματοσειρά Adobe FrameMaker" + +#~ msgid "Adobe font metrics" +#~ msgstr "Μετρικά γραμματοσειράς Adobe" + +#~ msgid "Andrew Toolkit inset" +#~ msgstr "Ένθεμα Andrew Toolkit" + +#~ msgid "ApplixWare Graphics image" +#~ msgstr "Εικόνα ApplixWare Graphics" + +#~ msgid "Applixware Words document" +#~ msgstr "Έγγραφο Applixware Words" + +#~ msgid "Applixware spreadsheet" +#~ msgstr "Λογιστικό φύλλο Applixware" + +#~ msgid "AutoCAD image" +#~ msgstr "Εικόνα AutoCAD" + +#~ msgid "BCPIO document" +#~ msgstr "Έγγραφο BCPIO" + +#~ msgid "BDF font" +#~ msgstr "Γραμματοσειρά BDF" + +#~ msgid "C shell script" +#~ msgstr "Πρόγραμμα εντολών φλοιού C" + +#~ msgid "C source code" +#~ msgstr "Πηγαίος κώδικας C" + +#, fuzzy +#~ msgid "C source code header" +#~ msgstr "Πηγαίος κώδικας C" + +#~ msgid "C++ source code" +#~ msgstr "Πηγαίος κώδικας C++" + +#~ msgid "CGI program" +#~ msgstr "Πρόγραμμα CGI" + +#~ msgid "CGM image" +#~ msgstr "Εικόνα CGM" + +#~ msgid "CMU raster image" +#~ msgstr "Εικόνα ράστερ CMU" + +#~ msgid "CPIO archive" +#~ msgstr "Αρχείο CPIO" + +#~ msgid "CPIO archive (gzip-compressed)" +#~ msgstr "Αρχείο CPIO (gzip-συμπιεσμένο)" + +#~ msgid "DCL script" +#~ msgstr "Πρόγραμμα εντολών DCL" + +#~ msgid "DOS font" +#~ msgstr "Γραμματοσειρά DOS" + +#~ msgid "DOS/Windows program" +#~ msgstr "Πρόγραμμα DOS/Windows" + +#~ msgid "DSSSL document" +#~ msgstr "Έγγραφο DSSSL" + +#~ msgid "DXF vector graphic" +#~ msgstr "Διανυσματικό γραφικό DXF" + +#~ msgid "Debian package" +#~ msgstr "Πακέτο Debian" + +#~ msgid "Dia diagram" +#~ msgstr "Διάγραμμα Dia" + +#~ msgid "Dolby Digital audio" +#~ msgstr "Ψηφιακός Ήχος Dolby" + +#~ msgid "Emacs Lisp source code" +#~ msgstr "Πηγαίος κώδικας Emacs Lisp" + +#~ msgid "Enlightenment theme" +#~ msgstr "Θέμα Enlightenment" + +#~ msgid "FLC animation" +#~ msgstr "Κινούμενο σχέδιο FLC" + +#~ msgid "FLI animation" +#~ msgstr "Κινούμενο σχέδιο FLI" + +#~ msgid "FastTracker II audio" +#~ msgstr "Ήχος FastTracker II" + +#~ msgid "Fortran source code" +#~ msgstr "Πηγαίος κώδικας Fortran" + +#~ msgid "FrameMaker interchange document" +#~ msgstr "Έγγραφο ανταλλαγής FrameMaker" + +#~ msgid "G3 fax image" +#~ msgstr "Εικόνα φαξ G3" + +#~ msgid "GIF image" +#~ msgstr "Εικόνα GIF" + +#~ msgid "GIMP document" +#~ msgstr "Έγγραφο GIMP" + +#~ msgid "GMC link" +#~ msgstr "Σύνδεσμος GMC" + +#~ msgid "GNOME application details" +#~ msgstr "Λεπτομέρειες εφαρμογής GNOME" + +#~ msgid "GNU Oleo Spreadsheet" +#~ msgstr "Λογιστικό φύλλο Oleo GNU" + +#~ msgid "GNU mail message" +#~ msgstr "Μήνυμα αλληλογραφίας GNU" + +#~ msgid "GTK configuration" +#~ msgstr "Ρυθμίσεις GTK" + +#~ msgid "Glade project" +#~ msgstr "Έργο Glade" + +#~ msgid "GnuCash Workbook" +#~ msgstr "Βιβλίο Εργασίας GnuCash" + +#~ msgid "Gnumeric spreadsheet" +#~ msgstr "Λογιστικό φύλλο Gnumeric" + +#~ msgid "HDF document" +#~ msgstr "Έγγραφο HDF" + +#~ msgid "HTML page" +#~ msgstr "Σελίδα HTML" + +#~ msgid "IDL document" +#~ msgstr "Έγγραφο IDL" + +#~ msgid "IEF image" +#~ msgstr "Εικόνα IEF" + +#~ msgid "IFF image" +#~ msgstr "Εικόνα IFF" + +#~ msgid "ILBM image" +#~ msgstr "Εικόνα ILBM" + +#~ msgid "ISI video" +#~ msgstr "Βίντεο ISI" + +#~ msgid "Impulse Tracker audio" +#~ msgstr "Ήχος Impulse Tracker" + +#~ msgid "JBuilder Project" +#~ msgstr "Έργο JBuilder" + +#~ msgid "JPEG image" +#~ msgstr "Εικόνα JPEG" + +#~ msgid "Java byte code" +#~ msgstr "Java byte code" + +#~ msgid "Java source code" +#~ msgstr "Πηγαίος κώδικας Java" + +#~ msgid "KDE application details" +#~ msgstr "Λεπτομέρειες εφαρμογής KDE" + +#~ msgid "KIllustrator document" +#~ msgstr "Έγγραφο KIllustrator" + +#~ msgid "KPresenter presentation" +#~ msgstr "Παρουσίαση KPresenter" + +#~ msgid "KSpread spreadsheet" +#~ msgstr "Λογιστικό φύλλο KSpread" + +#~ msgid "KWord document" +#~ msgstr "Έγγραφο KWord" + +#~ msgid "Korn shell script" +#~ msgstr "Πρόγραμμα εντολών φλοιού Korn" + +#~ msgid "LHA archive" +#~ msgstr "Αρχείο LHA" + +#~ msgid "LHARC archive" +#~ msgstr "Αρχείο LHARC" + +#~ msgid "LIBGRX font" +#~ msgstr "Γραμματοσειρά LIBGRX" + +#~ msgid "LightWave object" +#~ msgstr "Αντικείμενο LightWave" + +#~ msgid "LightWave scene" +#~ msgstr "Σκηνή LightWave" + +#~ msgid "Linux PSF console font" +#~ msgstr "Γραμματοσειρά κονσόλας PSF Linux" + +#~ msgid "Lotus 1-2-3 spreadsheet" +#~ msgstr "Λογιστικό φύλλο Lotus 1-2-3" + +#~ msgid "M3 audio URL" +#~ msgstr "URL ήχου M3" + +#~ msgid "MIDI audio" +#~ msgstr "Ήχος MIDI" + +#~ msgid "MOD audio" +#~ msgstr "Ήχος MOD" + +#~ msgid "MP3 audio" +#~ msgstr "Ήχος MP3" + +#~ msgid "MP3 audio playlist" +#~ msgstr "Λίστα τραγουδιών MP3" + +#~ msgid "MPEG video" +#~ msgstr "Βίντεο MPEG" + +#~ msgid "MS ASF video" +#~ msgstr "Βίντεο MS ASF" + +#~ msgid "MS video" +#~ msgstr "Βίντεο MS" + +#~ msgid "Macintosh AppleDouble-encoded file" +#~ msgstr "Αρχείο Macintosh κωδικοποίησης AppleDouble" + +#~ msgid "Macintosh BinHex-encoded file" +#~ msgstr "Αρχείο Macintosh κωδικοποίησης BinHex" + +#~ msgid "Macintosh StuffIt archive" +#~ msgstr "Αρχείο Macintosh StuffIt" + +#~ msgid "Macromedia Flash file" +#~ msgstr "Αρχείο Macromedia Flash" + +#~ msgid "MathML document" +#~ msgstr "Έγγραφο MathML" + +#~ msgid "Microsoft Excel spreadsheet" +#~ msgstr "Λογιστικό φύλλο Microsoft Excel" + +#~ msgid "Microsoft PowerPoint document" +#~ msgstr "Έγγραφο Microsoft PowerPoint" + +#~ msgid "Microsoft Word document" +#~ msgstr "Έγγραφο Microsoft Word" + +#~ msgid "Microsoft video" +#~ msgstr "Βίντεο Microsoft" + +#~ msgid "Nautilus link" +#~ msgstr "Σύνδεσμος Nautilus" + +#~ msgid "ODA document" +#~ msgstr "Έγγραφο ODA" + +#~ msgid "PBM image" +#~ msgstr "Εικόνα PBM" + +#~ msgid "PCF font" +#~ msgstr "Γραμματοσειρά PCF" + +#~ msgid "PDF document" +#~ msgstr "Έγγραφο PDF" + +#~ msgid "PEF program" +#~ msgstr "Πρόγραμμα PEF" + +#~ msgid "PGM image" +#~ msgstr "Εικόνα PGM" + +#~ msgid "PGN chess game" +#~ msgstr "Παρτίδα σκακιού PGN" + +#~ msgid "PGP keys" +#~ msgstr "Κλειδιά PGP" + +#~ msgid "PGP message" +#~ msgstr "Μήνυμα PGP" + +#~ msgid "PGP signature" +#~ msgstr "Υπογραφή PGP" + +#~ msgid "PGP-encrypted file" +#~ msgstr "Αρχείο κρυπτογραφημένο PGP" + +#~ msgid "PHP script" +#~ msgstr "Πρόγραμμα εντολών PHP" + +#~ msgid "PN RealAudio document" +#~ msgstr "Έγγραφο PN RealAudio" + +#~ msgid "PNG image" +#~ msgstr "Εικόνα PNG" + +#~ msgid "PNM image" +#~ msgstr "Εικόνα PNM" + +#~ msgid "PPM image" +#~ msgstr "Εικόνα PPM" + +#~ msgid "Palm OS database" +#~ msgstr "Βάση δεδομένων Palm OS" + +#~ msgid "Perl script" +#~ msgstr "Πρόγραμμα εντολών Perl" + +#~ msgid "Photoshop document" +#~ msgstr "Έγγραφο Photoshop" + +#~ msgid "PostScript Type 1 font" +#~ msgstr "Γραμματοσειρά Postscript Type 1" + +#~ msgid "PostScript document" +#~ msgstr "Έγγραφο PostScript" + +#~ msgid "Python source code" +#~ msgstr "Πηγαίος κώδικας Python" + +#~ msgid "QuickTime movie" +#~ msgstr "Ταινία QuickTime" + +#~ msgid "Quicken document" +#~ msgstr "Έγγραφο Quicken" + +#~ msgid "Quicken for Windows document" +#~ msgstr "Έγγραφο Quicken για Windows" + +#~ msgid "RAR archive" +#~ msgstr "Αρχείο RAR" + +#~ msgid "README document" +#~ msgstr "Έγγραφο README" + +#~ msgid "RGB image" +#~ msgstr "Εικόνα RGB" + +#~ msgid "RIFF audio" +#~ msgstr "Ήχος RIFF" + +#~ msgid "RPM package" +#~ msgstr "Πακέτο RPM" + +#~ msgid "RealAudio/Video document" +#~ msgstr "Έγγραφο RealAudio/Βίντεο" + +#~ msgid "RealVideo video" +#~ msgstr "Βίντεο RealVideo" + +#~ msgid "S/MIME file" +#~ msgstr "Αρχείο S/MIME" + +#~ msgid "S/MIME signature" +#~ msgstr "Υπογραφή S/MIME" + +#~ msgid "SGI video" +#~ msgstr "Βίντεο SGI" + +#~ msgid "SGML document" +#~ msgstr "Έγγραφο SGML" + +#~ msgid "SMIL script" +#~ msgstr "Πρόγραμμα εντολών SMIL" + +#~ msgid "SQL code" +#~ msgstr "Πηγαίος κώδικας SQL" + +#~ msgid "SV4 CPIO archive" +#~ msgstr "Αρχείο SV4 CPIO" + +#~ msgid "SV4 CPIP archive (with CRC)" +#~ msgstr "Αρχείο SV4 CPIP (με Κυκλικό Έλεγχο Αθροίσματος)" + +#~ msgid "SVG art" +#~ msgstr "Τέχνημα SVG" + +#~ msgid "Scheme source code" +#~ msgstr "Πηγαίος κώδικας Scheme" + +#~ msgid "Scream Tracker 3 audio" +#~ msgstr "Ήχος Scream Tracker 3" + +#~ msgid "Scream Tracker audio" +#~ msgstr "Ήχος Scream Tracker" + +#~ msgid "Scream Tracker instrument" +#~ msgstr "Μουσικό όργανο Scream Tracker" + +#~ msgid "Setext document" +#~ msgstr "Έγγραφο Setext" + +#~ msgid "Speech document" +#~ msgstr "Έγγραφο ομιλίας" + +#~ msgid "Speedo font" +#~ msgstr "Γραμματοσειρά Speedo" + +#~ msgid "Spreadsheet Interchange document" +#~ msgstr "Έγγραφο Ανταλλαγής Λογιστικού Φύλλου" + +#~ msgid "Stampede package" +#~ msgstr "Πακέτο Stampede" + +#~ msgid "StarOffice Writer document" +#~ msgstr "Έγγραφο StarOffice Writer" + +#~ msgid "StarOffice presentation" +#~ msgstr "Παρουσίαση StarOffice" + +#~ msgid "StarOffice spreadsheet" +#~ msgstr "Λογιστικό φύλλο StarOffice" + +#~ msgid "Sun mu-law audio" +#~ msgstr "Ήχος Sun ΅-law" + +#~ msgid "SunOS News font" +#~ msgstr "Γραμματοσειρά SunOS News" + +#~ msgid "TIFF image" +#~ msgstr "Εικόνα TIFF" + +#~ msgid "TarGA image" +#~ msgstr "Εικόνα TarGA" + +#~ msgid "Tcl script" +#~ msgstr "Πρόγραμμα εντολών Tcl" + +#~ msgid "TeX document" +#~ msgstr "Έγγραφο TeX" + +#~ msgid "TeX dvi document" +#~ msgstr "Έγγραφο TeX dvi" + +#~ msgid "TeX font" +#~ msgstr "Γραμματοσειρά TeX" + +#~ msgid "TeX font metrics" +#~ msgstr "Μετρικά γραμματοσειράς TeX" + +#~ msgid "TeXInfo document" +#~ msgstr "Έγγραφο TeXInfo" + +#~ msgid "ToutDoux document" +#~ msgstr "Έγγραφο ToutDoux" + +#~ msgid "TrueType font" +#~ msgstr "Γραμματοσειρά TrueType" + +#~ msgid "USENET news message" +#~ msgstr "Μήνυμα νέων USENET" + +#~ msgid "Unidata netCDF document" +#~ msgstr "Έγγραφο Unidata netCDF" + +#~ msgid "V font" +#~ msgstr "Γραμματοσειρά V" + +#~ msgid "VOC audio" +#~ msgstr "Ήχος VOC" + +#~ msgid "VRML document" +#~ msgstr "Έγγραφο VRML" + +#~ msgid "Vivo video" +#~ msgstr "Βίντεο Vivo" + +#~ msgid "WAIS source code" +#~ msgstr "Πηγαίος κώδικας WAIS" + +#~ msgid "Wavelet video" +#~ msgstr "Βίντεο Wavelet" + +#~ msgid "Windows bitmap image" +#~ msgstr "Εικόνα Windows bitmap" + +#~ msgid "Windows icon image" +#~ msgstr "Εικονίδιο Windows" + +#~ msgid "Windows metafile graphics" +#~ msgstr "Μετά-αρχείο γραφικών Windows" + +#~ msgid "WordPerfect document" +#~ msgstr "Έγγραφο WordPerfect" + +#~ msgid "X bitmap image" +#~ msgstr "Εικόνα X bitmap" + +#~ msgid "X window image" +#~ msgstr "Εικόνα περιβάλλοντος X " + +#~ msgid "XML document" +#~ msgstr "Έγγραφο XML" + +#~ msgid "XPM image" +#~ msgstr "Εικόνα XPM" + +#~ msgid "Xbase database" +#~ msgstr "Βάση δεδομένων Xbase" + +#~ msgid "active server page" +#~ msgstr "ενεργή σελίδα εξυπηρετητή" + +#~ msgid "address card" +#~ msgstr "κάρτα διεύθυνσης" + +#~ msgid "ar archive" +#~ msgstr "αρχείο ar" + +#~ msgid "arj archive" +#~ msgstr "αρχείο arj" + +#~ msgid "authors list" +#~ msgstr "λίστα συγγραφέων" + +#~ msgid "backup file" +#~ msgstr "αρχείο ασφαλείας" + +#~ msgid "basic audio" +#~ msgstr "βασικός ήχος" + +#~ msgid "bibliography record" +#~ msgstr "βιβλιογραφική εγγραφή" + +#~ msgid "binary program" +#~ msgstr "δυαδικό πρόγραμμα" + +#~ msgid "block device" +#~ msgstr "συσκευή μπλοκ" + +#~ msgid "bzip-compressed file" +#~ msgstr "αρχείο συμπιεσμένο με bzip" + +#~ msgid "calendar file" +#~ msgstr "αρχείο ημερολογίου" + +#~ msgid "calendar or event document" +#~ msgstr "έγγραφο ημερολογίου ή γεγονότος" + +#~ msgid "character device" +#~ msgstr "συσκευή χαρακτήρα" + +#~ msgid "comma-separated text document" +#~ msgstr "έγγραφο κειμένου διαχώρισης με κόμμα" + +#~ msgid "compound document" +#~ msgstr "σύνθετο έγγραφο" + +#~ msgid "compress-compressed file" +#~ msgstr "αρχείο συμπιεσμένο με compress" + +#~ msgid "compressed GIMP document" +#~ msgstr "συμπιεσμένο έγγραφο GIMP" + +#~ msgid "directory information file" +#~ msgstr "αρχείο πληροφοριών καταλόγου" + +#~ msgid "document type definition" +#~ msgstr "ορισμός τύπου εγγράφου" + +#~ msgid "email headers" +#~ msgstr "κεφαλίδα ηλεκ. μηνύματος" + +#~ msgid "email message" +#~ msgstr "ηλεκτρονικό μήνυμα" + +#~ msgid "encrypted message" +#~ msgstr "κρυπτογραφημένο μήνυμα" + +#~ msgid "enriched text document" +#~ msgstr "έγγραφο εμπλουτισμένου κειμένου" + +#~ msgid "gtar archive" +#~ msgstr "αρχείο gtar" + +#~ msgid "gzip-compressed file" +#~ msgstr "αρχείο συμπιεσμένο με gzip" + +#~ msgid "help page" +#~ msgstr "σελίδα βοηθείας" + +#~ msgid "mail delivery report" +#~ msgstr "αναφορά παράδοσης αλληλογραφίας" + +#~ msgid "mail disposition report" +#~ msgstr "αναφορά παράδοσης αλληλογραφίας" + +#~ msgid "mail system report" +#~ msgstr "αναφορά συστήματος αλληλογραφίας" + +#~ msgid "makefile" +#~ msgstr "makefile" + +#~ msgid "manual page" +#~ msgstr "σελίδα τεκμηρίωσης" + +#~ msgid "manual page (compressed)" +#~ msgstr "σελίδα τεκμηρίωσης (συμπιεσμένη)" + +#~ msgid "memory dump" +#~ msgstr "αποτύπωση μνήμης" + +#~ msgid "message digest" +#~ msgstr "επιτομή μηνύματος" + +#~ msgid "message in several formats" +#~ msgstr "μήνυμα πολλών μορφών" + +#~ msgid "multi-part message" +#~ msgstr "μήνυμα πολλών τμημάτων" + +#~ msgid "named pipe" +#~ msgstr "επώνυμη σωλήνωση" + +#~ msgid "object code" +#~ msgstr "ενδιάμεσος κώδικας" + +#~ msgid "ogg audio" +#~ msgstr "ήχος ogg" + +#~ msgid "partial email message" +#~ msgstr "μερικό μήνυμα ηλεκ. αλληλογραφίας" + +#~ msgid "plain text document" +#~ msgstr "έγγραφο απλού κειμένου" + +#~ msgid "profiler results" +#~ msgstr "αποτελέσματα προφίλ" + +#~ msgid "reference to remote file" +#~ msgstr "αναφορά σε απομακρυσμένο αρχείο" + +#~ msgid "rejected patch file" +#~ msgstr "αρχείο απόρριψης επιρράμματος" + +#~ msgid "rich text document" +#~ msgstr "έγγραφο εμπλουτισμένου κειμένου" + +#~ msgid "search results" +#~ msgstr "αποτελέσματα αναζήτησης" + +#~ msgid "shared library" +#~ msgstr "διαμοιραζόμενη βιβλιοθήκη" + +#~ msgid "shell archive" +#~ msgstr "αρχείο φλοιού" + +#~ msgid "shell script" +#~ msgstr "πρόγραμμα εντολών φλοιού" + +#~ msgid "signed message" +#~ msgstr "υπογεγραμένο μήνυμα" + +#~ msgid "socket" +#~ msgstr "υποδοχή" + +#~ msgid "software author credits" +#~ msgstr "μνεία συγγραφέων λογισμικού" + +#~ msgid "software installation instructions" +#~ msgstr "εντολές εγκατάστασης λογισμικού" + +#~ msgid "software license terms" +#~ msgstr "συνθήκες άδειας λογισμικού" + +#~ msgid "source code patch" +#~ msgstr "επίρραμμα πηγαίου κώδικα" + +#~ msgid "style sheet" +#~ msgstr "επίστρωμα ύφους" + +#~ msgid "symbolic link" +#~ msgstr "συμβολικός σύνδεσμος" + +#~ msgid "tab-separated text document" +#~ msgstr "έγγραφο κειμένου διαχώρισης με στηλοθέτες" + +#~ msgid "tar archive" +#~ msgstr "αρχείο tar" + +#~ msgid "tar archive (bzip2-compressed)" +#~ msgstr "αρχείο tar (συμπίεσης bzip2)" + +#~ msgid "tar archive (gzip-compressed)" +#~ msgstr "αρχείο tar (συμπίεσης gzip)" + +#~ msgid "theme" +#~ msgstr "θέμα" + +#~ msgid "troff document" +#~ msgstr "Έγγραφο troff" + +#~ msgid "troff me input document" +#~ msgstr "έγγραφο εισόδου troff me" + +#~ msgid "troff mm input document" +#~ msgstr "έγγραφο εισόδου troff mm" + +#~ msgid "troff ms input document" +#~ msgstr "έγγραφο εισόδου troff ms" + +#~ msgid "unknown type" +#~ msgstr "άγνωστος τύπος" + +#~ msgid "ustar archive" +#~ msgstr "αρχείο ustar" + +#~ msgid "wave audio" +#~ msgstr "ήχος κυμματομορφής" + +#~ msgid "web folder" +#~ msgstr "φάκελος web" + +#~ msgid "xfig vector graphic" +#~ msgstr "διανυσματικό γραφικό xfig" + +#~ msgid "zip archive" +#~ msgstr "αρχείο zip" + +#~ msgid "zoo archive" +#~ msgstr "αρχείο zoo" + +#~ msgid "GNOME VFS already initialized." +#~ msgstr "Το Ιδεατό Σύστημα Αρχείων GNOME έχει ήδη αρχικοποιηθεί." + +#~ msgid "Dying." +#~ msgstr "Τερματισμός." + +#~ msgid "Error reading: %s" +#~ msgstr "Σφάλμα ανάγνωσης: %s" + +#~ msgid "Error writing: %s" +#~ msgstr "Σφάλμα εγγραφής: %s" + +#~ msgid "Cannot write: %s" +#~ msgstr "Εγγραφή αδύνατη: %s" + +#~ msgid "Cannot create temporary file name `%s'" +#~ msgstr "Αδύνατη η δημιουργία προσωρινού αρχείου `%s'" + +#~ msgid "Cannot create socket: %s" +#~ msgstr "Αδυναμία δημιουργίας υποδοχέα: %s" + +#~ msgid "Cannot bind `%s': %s" +#~ msgstr "Αδυναμία δέσμευσης (bind) του `%s': %s" + +#~ msgid "Cannot listen on `%s': %s" +#~ msgstr "Αδυναμία ακρόασης (listen) στο `%s': %s" + +#~ msgid "Cannot accept connections on `%s': %s" +#~ msgstr "Λήψη συνδέσεων στο `%s' αδύνατη: %s" + +#~ msgid "Cannot initialize CORBA." +#~ msgstr "Αρχικοποίηση CORBA ανεπιτυχής." + +#~ msgid "Cannot resolve initial reference to RootPOA." +#~ msgstr "Αδυναμία επίλυσης αρχικής αναφοράς στο RootPOA." + +#~ msgid "Cannot activate POA manager." +#~ msgstr "Ενεργοποίηση διαχειριστή POA ανεπιτυχής." + +#~ msgid "Usage: %s []\n" +#~ msgstr "Χρήση: %s []\n" + +#~ msgid "Cannot open file descriptor %d." +#~ msgstr "Αδυναμία ανοίγματος περιγραφέα αρχείου %d." + +#~ msgid "Notify interface for `%s' not found." +#~ msgstr "Διεπιφάνεια ειδοποίησης για το `%s' δε βρέθηκε." + +#~ msgid "Cannot setup Request object." +#~ msgstr "Δημιουργία αντικειμένου Request (αίτησης) ανεπιτυχής." + +#~ msgid "Cannot extract IOR." +#~ msgstr "Εξαγωγή IOR αδύνατη." + +#~ msgid "Got weird string from the slave process: `%s'" +#~ msgstr "Λήψη παράξενης ακολουθίας από την διεργασία υπηρέτη: `%s'" + +#~ msgid "Cannot get object for `%s'" +#~ msgstr "Αδυναμία απόκτησης αντικειμένου για το `%s'" + +#~ msgid "Cannot kill GNOME::VFS::Slave::Notify -- exception %s" +#~ msgstr "Τερματισμός του GNOME::VFS::Slave::Notify αδύνατη -- εξαίρεση %s" + +#~ msgid "Cannot connect socket `%s': %s" +#~ msgstr "Αδυναμία σύνδεσης με τον υποδοχέα `%s': %s" + +#~ msgid "Cannot initialize GNOME::VFS:Slave::Notify" +#~ msgstr "Αρχικοποίηση του GNOME::VFS:Slave::Notify ανεπιτυχής" + +#~ msgid "Cannot reset GNOME::VFS::Slave %s -- exception %s" +#~ msgstr "Ανεπιτυχής επαναρχικοποίηση του GNOME::VFS::Slave %s -- εξαίρεση %s" + +#~ msgid "Cannot reset GNOME::VFS::Slave (IOR unknown) -- exception %s" +#~ msgstr "" +#~ "Ανεπιτυχής επαναρχικοποίηση του GNOME::VFS::Slave (άγνωστο IOR) -- " +#~ "εξαίρεση %s" + +#~ msgid "Cannot kill GNOME::VFS::Slave %s -- exception %s" +#~ msgstr "Ανεπιτυχής τερματισμός του GNOME::VFS::Slave %s -- εξαίρεση %s" + +#~ msgid "Cannot kill GNOME::VFS::Slave (IOR unknown) -- exception %s" +#~ msgstr "" +#~ "Ανεπιτυχής τερματισμός του GNOME::VFS::Slave (άγνωστο IOR) -- εξαίρεση %s" + +#~ msgid "File Types and Programs" +#~ msgstr "Είδη Αρχείων και Προγράμματα" + +#~ msgid "Specify which programs are used to open or view each file type" +#~ msgstr "" +#~ "Καθορισμός των προγραμμάτων που ανοίγουν ή εμφανίζουν κάθε είδος αρχείων" + +#~ msgid "MIME Type" +#~ msgstr "Είδος MIME" + +#~ msgid "Change Icon" +#~ msgstr "Αλλαγή Εικονιδίου" + +#~ msgid "Change File Extensions" +#~ msgstr "Αλλαγή Επέκτασης Αρχείου" + +#~ msgid "Default Action:" +#~ msgstr "Εξ' ορισμού Ενέργεια:" + +#~ msgid "Use Viewer" +#~ msgstr "Χρήση Θέασης" + +#~ msgid "Open With Application" +#~ msgstr "Άνοιγμα με Εφαρμογή" + +#~ msgid "Edit List" +#~ msgstr "Επεξεργασία Λίστας" + +#~ msgid "Add New MIME Type..." +#~ msgstr "Προσθήκη Νέου Είδους MIME..." + +#~ msgid "Delete This MIME Type" +#~ msgstr "Διαγραφή Αυτού Του Είδους MIME" + +#~ msgid "Revert to System Defaults" +#~ msgstr "Επαναφορά στα Εξ΄ Ορισμού Συστήματος" + +#~ msgid "None" +#~ msgstr "Τίποτα" + +#~ msgid "" +#~ "Reverting to system settings will lose any changes\n" +#~ "you have ever made to File Types and Programs.\n" +#~ "Revert anyway?" +#~ msgstr "" +#~ "Η επαναφορά στις ρυθμίσεις συστήματος θα διαγράψει\n" +#~ "ΌΛΕΣ τις αλλαγές που έχετε κάνει στα Είδη Αρχείων\n" +#~ "και Προγράμματα.\n" +#~ "Επαναφορά στις Ρυθμίσεις Συστήματος;" + +#~ msgid "none" +#~ msgstr "τίποτα" + +#~ msgid "View as %s" +#~ msgstr "Εμφάνιση ως %s" + +#~ msgid "Description" +#~ msgstr "Περιγραφή" + +#~ msgid "Extension" +#~ msgstr "Επέκταση" + +#~ msgid "Default Action" +#~ msgstr "Εξ' ορισμού ενέργεια" + +#~ msgid "Edit Applications List" +#~ msgstr "Επεξεργασία Λίστας Εφαρμογών" + +#~ msgid "Select applications to appear in menu for MIME type \"%s\"" +#~ msgstr "Επιλογή εφαρμογών για εμφάνιση στο μενού για το είδος MIME \"%s\"" + +#~ msgid "Add Application..." +#~ msgstr "Προσθήκη Εφαρμογής..." + +#~ msgid "Edit Application..." +#~ msgstr "Επεξεργασία Εφαρμογής..." + +#~ msgid "Delete Application" +#~ msgstr "Διαγραφή Εφαρμογής" + +#~ msgid "Edit Components List" +#~ msgstr "Επεξεργασία Λίστα Συστατικών" + +#~ msgid "Select views to appear in menu for MIME type \"%s\"" +#~ msgstr "Επιλογή όψεων για εμφάνιση στο μενού για το είδος MIME \"%s\"" + +#~ msgid "" +#~ "The MIME type entered contained upper case characters. Upper case " +#~ "characters were changed to lower case for you." +#~ msgstr "" +#~ "Το είδος MIME που εισάγατε περιέχει κεφαλαία γράμματα. Τα κεφαλαία " +#~ "γράμματα αλλάχτηκαν αυτόματα σε πεζά." + +#~ msgid "Add New MIME Type" +#~ msgstr "Προσθήκη Νέου Είδους Mime" + +#~ msgid "Add MIME Type" +#~ msgstr "Προσθήκη Είδους MIME" + +#~ msgid "New MIME type (e.g. image/x-thumper):" +#~ msgstr "Νέο είδος MIME (π.χ. image/x-thumper):" + +#~ msgid "Description (e.g. Thumper image):" +#~ msgstr "Περιγραφή (π.χ. Εικόνα μορφής thumper):" + +#~ msgid "File Extensions " +#~ msgstr "Επεκτάσεις Αρχείων" + +#~ msgid "Add..." +#~ msgstr "Προσθήκη..." + +#~ msgid " Remove " +#~ msgstr " Διαγραφή" + +#~ msgid "Add New Extension" +#~ msgstr "Προσθήκη Νέας Επέκτασης" + +#~ msgid "" +#~ "Type in the extensions for this mime-type (without dot).\n" +#~ "You can enter several extensions seperated by a space,\n" +#~ "for example: html htm" +#~ msgstr "" +#~ "Εισάγετε τις επεκτάσεις για αυτό το είδος-mime (χωρίς τελεία).\n" +#~ "Μπορείτε να εισάγετε πολλές επεκτάσεις διαχωρίζοντάς τες με διάστημα,\n" +#~ "για παράδειγμα: html htm" + +#~ msgid "Extension:" +#~ msgstr "Επέκταση:" + +#~ msgid "You must enter a name." +#~ msgstr "Πρέπει να εισάγετε ένα όνομα." + +#~ msgid "You must enter a command." +#~ msgstr "Πρέπει να εισάγετε μια εντολή." + +#~ msgid "" +#~ "\"%s\" does not exist or is not executable.\n" +#~ "Check your spelling and make sure you have\n" +#~ "the right permissions to execute this file." +#~ msgstr "" +#~ "Το \"%s\" δεν υπάρχει ή δεν είναι εκτελέσιμο.\n" +#~ "Ελέξτε την ορθογραφία σας και επιβεβαιώστε ότι\n" +#~ "ότι έχετε δικαίωμα εκτέλεσης του αρχείου." + +#~ msgid "" +#~ "The command \"%s\" cannot be found.\n" +#~ "You must use a command that can work from any command line." +#~ msgstr "" +#~ "Η εντολή \"%s\" δε βρέθηκε.\n" +#~ "Πρέπει να χρησιμοποιήσετε μια εντολή που να είναι προσβάσιμη από κάθε " +#~ "γραμμή εντολών." + +#~ msgid "Bad Application Name" +#~ msgstr "Κακό Όνομα Εφαρμογής" + +#~ msgid "Bad Application Command" +#~ msgstr "Κακή Εντολή Εφαρμογής" + +#~ msgid "Edit Application" +#~ msgstr "Επεξεργασία Εφαρμογής" + +#~ msgid "Application Name:" +#~ msgstr "Όνομα Εφαρμογής:" + +#~ msgid "Application Command:" +#~ msgstr "Εντολή Εφαρμογής:" + +#~ msgid "Open Behavior" +#~ msgstr "Συμπεριφορά Ανοίγματος" + +#~ msgid "Can open multiple files" +#~ msgstr "Μπορούν να ανοιχτούν πολλαπλά αρχεία" + +#~ msgid "Can open from URI" +#~ msgstr "Μπορεί να ανοιχτεί από URI" + +#~ msgid "Can't find an hbox, using a normal file selection" +#~ msgstr "Αδυναμία εύρεσης hbox, χρήση κανονικής επιλογής αρχείων" + +#~ msgid "Preview" +#~ msgstr "Επισκόπηση" + +#~ msgid "Select an icon" +#~ msgstr "Επιλέξτε εικονίδιο" + +#~ msgid "%s to retrieve" +#~ msgstr "%s προς λήψη" + +#~ msgid "Closing connection to %s" +#~ msgstr "Τερματισμός σύνδεσης με %s" + +#~ msgid "%s of %s read" +#~ msgstr "%s από %s αναγνώστηκαν" + +#~ msgid "%s read" +#~ msgstr "%s αναγνώστηκαν" + +#~ msgid "Back" +#~ msgstr "Πίσω" + +#~ msgid "Go to the previously visited directory" +#~ msgstr "Πήγαινε στον κατάλογο της προηγούμενης επίσκεψης" + +#~ msgid "Up" +#~ msgstr "Πάνω" + +#~ msgid "Go to the parent directory" +#~ msgstr "Πήγαινε στο γονικό κατάλογο" + +#~ msgid "Forward" +#~ msgstr "Εμπρός" + +#~ msgid "Go to the next visited directory" +#~ msgstr "Πήγαινε στο κατάλογο της επόμενης επίσκεψης" + +#~ msgid "Rescan" +#~ msgstr "Επανασάρωση" + +#~ msgid "Rescan the current directory" +#~ msgstr "Επανασάρωση του τρέχοντος καταλόγου" + +#~ msgid "Home" +#~ msgstr "Αρχή" + +#~ msgid "Go to the home directory" +#~ msgstr "Πήγαινε στον αρχικό κατάλογο χρήστη" + +#~ msgid "Name" +#~ msgstr "Όνομα" + +#~ msgid "Size" +#~ msgstr "Μέγεθος" + +#~ msgid "Date" +#~ msgstr "Ημερομηνία" + +#~ msgid "Enter name:" +#~ msgstr "Εισαγωγή ονόματος:" + +#~ msgid "Show:" +#~ msgstr "Εμφάνιση:" + +#~ msgid "Show dotfiles" +#~ msgstr "Εμφάνιση κρυφών αρχείων" + +#~ msgid "New Application" +#~ msgstr "Νέα Εφαρμογή" + +#~ msgid "Expects URIs as arguments" +#~ msgstr "Αναμένει URI ως ορίσματα" + +#~ msgid "" +#~ "Add a new MIME Type\n" +#~ "For example: image/tiff; text/x-scheme" +#~ msgstr "" +#~ "Προσθήκη νέου Είδους MIME\n" +#~ "Για παράδειγμα: image/tiff; text/x-scheme" + +#~ msgid "MIME Type:" +#~ msgstr "Είδος MIME:" + +#~ msgid "Type a description for this MIME type." +#~ msgstr "Εισάγετε μια περιγραφή για αυτό το είδος MIME." + +#~ msgid "Description:" +#~ msgstr "Περιγραφή:" + +#~ msgid "Add new MIME type..." +#~ msgstr "Προσθήκη νέου είδους MIME..." + +#~ msgid "No Description" +#~ msgstr "Χωρίς Περιγραφή" + +#~ msgid "Add Mime Type" +#~ msgstr "Προσθήκη Είδους Mime" + +#~ msgid "Mime Type" +#~ msgstr "Είδος Mime" diff --git a/po/eo.gmo b/po/eo.gmo new file mode 100644 index 0000000000000000000000000000000000000000..1ebb561ddd7ac055c4349a5b7dceecbc79a8794a GIT binary patch literal 5327 zcmai$U5H#)9l%fR_tsWhwbp(fwQD|_+3Y4wyKd98n`D!&$!^kQHwAsrGjq?(o|!xM zOz*jOH`^znAl9N3Owk8Z5etGSQt$&LFNG~qAABex2vxMD&^Iaipiso$|J*yXlUVUG z=ln~yXHm3^CabN%F7>8st@;E%ZukP*C}-y{42a3{sZz;@7MLKX}p*E zO*MDdT!c5!z6NFd)9_|^9)1{p4SocE8}5cbgtF!D;4b)kcn|zH{208O#cqMqa3_4M zuCGDq-+(v4=iw*eci^4yXLb8;q0IjSlykfTrTrEtubD|{B-1z&`6-dAeA20ualk2U`WW&X7sQs&(QMV`G-#vQ7; z0yXt+U4I_lLH!3%#{U}1KCeTO>re1L_%@XDUyYE`e=8I{OhQ?I7S6+Eh>6t;@Z<2i zP~`h*UH=W-bCptWLYaRfo67jRq4?GPb^QS-_TCT0kC&nNPY)uhdJdvebpgscFV*d@ zKsnDPI1S%`vhLL=bqAb)pN9LO=xGItf3)lV4Jdm2K9v1`1^KBrc-;=)f^t9p1!dkH zyk!4fP~LDAcrQ0Bb{QN4N}ivDll z&?4XMP{!?nvfezD^`3-so~NLU>q61fSE0!L4Jh+|0!6-8p{)NV6uI7oGVXd7iE{Ch za~*_YhZQL2eH!vp&-0RfUV^gj&!PD1>yV#%hnJl1pHRl#fb)nR?}fYI0Vw|TWnQvw zfQYKT3B}$oLAghlpoXtPOsd|3vfq1QfS-Zig0k)_@G2`ev^d!&Ylm{sfP^KuyD2FJ7;`kio{e}9! z$R>UwkDPON{D;57hwJ~-H4j74k?3dq5qm9BH084tc}`IlC`TzzP~;BFBQ`!xd59wS zPHZHP`0Sqek2?)Thw|*Kpc-(IB03a1?xo0mIzkb9$b(AbbD-vvaE>B=`MJ6+-f{jv zMtPJXwpgZ!uZthzerlE?kJwXec#<+h5&u_ur_0t&>Jq)0xt34tE;Ttd)7HliS3FT+ ziE5aeOmxdhNX%d01KYt7`QRoFaCUD=&^-M7V>PjqJb_5-_pQl@s;UFzm$VS}29 zRP(Kt4M8V1b2d@)gF)(Arf@zB>aa<4+c9&^WJzk(5tC)U(5>8>!s>w=Sl#xy_5+*g z??nIeF+xh&Cr6OdIm zbH5R6&N{>1fysl7Gme_Vprbr52L%T|>XK|nJ=^F?&%qXj%Q~Uj*%TaXf`Peh6+Yk8 z%`$9`Rb_MA9~7HvffM+4oTV1>91&AfX00{WV#j_TZPe{@oUvA&y3DF$qB48lg(6h{ zN1|?5MQ2s5@Lo4vCsr8m(*z^Kyw8DUW|T!8x0%gdOItaQdcvjy^@I-vrV&+YlO#E2 ztlGp6#-_$`+h>q!P>Xv{)oU$gs5&$0s9HPenMJi&J1kLN$r3re&rKxUO?K&B~$&^|a2}Cog z&pK+^#im3EI1~N)NSU=&KftWkBh_+j4#%#4sxV;8^R{e*;l8;?fcy0F;&x6JA2DyEt`ry zw%gFrAorbUsPR^`Q+x4ttJsUh`mPWmx7$PE2LoD8=f3bQKeXBz%U$(Zx_Q|VrM2+^ ztxuO0*YVBZQ>+>^cT5zrgD}9YQfI4bl*_DRG}GkvpDplvuC-qBnd@;o+ZaQXw1SgC$>zleKL1D5S zjqn3qY!ZHAQz!=mpQ9#;M3ws0YQTT6+N5~ky32jmx0&3f+=(#w7A|31uDuyOpxwqn z=}&zX`=%z;Q*24}QPJeJ$P4ESn{hu?r@oC*5{)Q0LR8AACr%qSVyrGfr?Hqc&T)zG z;5m(}_iban9rV7b{Zj`fPM=z79FfRMZ-d}Ql-oBwy}vO%+t_zN&+MO@nSEfI76vxX z;J>oUW#b-hOwZ_<2j>p(=K$kQ56{_)gJ`Mh&zVrg+{VOy4&sp$z~J<4H6>@ued zd%oB^NXcK1#N0(Fesp!^SYvj3oSY1`Hx`Hx2?1kH&o*5#p>}3AMj)e0RO%D|fAXZw z)^O68Cg*jK5Yinc!HhUu_Y%HX3Z458>hwvsB-B*Br9SKm-}7BkUw7D7mQmnY13zf5}X-{(1T08S|-kUIax2aPA6rrAe7*#vJ8UvoxUPzo-ldA zYV#eRCmdGR@_L6POc5j$F6bin>ueq~AnV&^I&6$N6P@bZb-1M*Ad?dqBD;Hran&3g ztL%H-^Ad1G3WmfrLzQQkZ^pOJbXP7BX)_+D>=JE5flR(v4rKmzdv!*-qLwm4M$05{ z*IMzUOoKd0*=Kvnp{dEXp8M}+PvUTTRpSbh$~eB)axzR2kc5BmCQ_hQ47&7mD^w^Qgesa zvnDOMyC@`-J-+l@P-pmXRo%-1MRfwjNVcDBEu9x#-;WWU}}0dZGf-x0g#Rx6q)2t&1+&t5$E! zwk;>$6KUZ(;^w0!+qN8h-ECdO6-TX3zHoB<0!5A*v415-6*DBWj{3G&j)}bIM?SV( z5~Mp<9`^E9?qVgwQ7acIniqYRT=fo$VJ-4F_guboVsiH}r$-GXE)0Ao0Rb~2K7;G* z)@Yk%PG-ku, 2003. +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs 2.3.5\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-07-01 14:57-0500\n" +"Last-Translator: Charles Voelger \n" +"Language-Team: Esperanto \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d enhavas NULA signoj." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d ne enhavas metodonomo." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d ne enhavas modjulonomo." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Agordodosiero '%s' ne estis trovita: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Nekonata op-tipo %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "Ne povas krei dukton por malfermi GIOChannel: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Nekonata tasktipo %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Operacio haltigita" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Ne analizebla: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Plu analizeraroj estos ignorataj." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Neniu eraro" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Dosiero ne trovita" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Ĝenerala eraro" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Interna eraro" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Nevalidaj parametroj" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Operacio ne estas subtenata" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "En/El eraro" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Datumo koruptita" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Formato nevalida" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Malbona dosier-tenilo" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "Dosiero estas tro granda" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Ne plu estas spaco sur la aparato" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Nurlega dosierosistemo" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "URI-o ne estas valida" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Dosiero ne estas malfermi" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Malferma reĝimo nevalida" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Aliro malpermesita" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "Tro multaj malfermaj dosieroj" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Fino de dosiero" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Ne estas dosierujo" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Operacio efektiviĝas" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Operacio interrompis" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Dosiero ekzistas" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Ripeta ligo renkontis" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Operacio ne estas permesata" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "Estas dosierujo" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Memoro ne estas sufiĉa" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Komputilo ne trovita" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Komputilonomo ne valida" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Komputilo ne havas adreso" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Saluto malsukcesis" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Operacio haltigita" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Dosierujo estas okupita" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Dosierujo ne estas malpena" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "Tro multaj ligoj" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Nurlega dosiersistemo" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Ne sur la sama dosiersistemo" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Nomo estas tro longa" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Servo ne disponebla" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Demando malaktualigas la datumon de servo" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Protokola eraro" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "Ne eblis trovi mastran rigardilon" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "Neniu apriora ago asociata" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "Neniu traktilo por URL-kombino" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "Eraro dum komandolinia analizo" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "Eraro dum komandlanĉo" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Nekonata eraro" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 Bitokoj" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u Bitokoj" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr "(nevalida unikodo)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "Nekonata GnomeVFSSeekPosition %d" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "Ne trovis validan agordodosieron je %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "Uzi la %s mediovariablo por doni malsaman situon.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "Aplikaĵoj" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "Kartoj" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "Dosieroj" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "Dosierujoj" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "Helpo" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "Komputiloj" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "Ligoj" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "Retpoŝto" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "Iloj" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "Fenestroj" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Normala Moniker-fabrikejo" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "MonikerExtender de dosiero" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "moniker-o de ĝenerala Gnome-VFS-o" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "monker-o de ĝenerala dosiero" diff --git a/po/es.gmo b/po/es.gmo new file mode 100644 index 0000000000000000000000000000000000000000..52a7986424127f4c26c1dc2c5549ecd06a3c2817 GIT binary patch literal 5893 zcma);v|ma)=n%tPWx77_s*`beRpPi z=UykSc&PY#f{K??@$nK-RVmO16jeas0o6rNgpgX^Pyq>wgj7ICAdvVHzcY8%YbUM5 zRmT6FnKK{fod2A2^6MM6J(=*$(Qc)E?aCxsk>79U58qGTkt8>OFN5y{UjzAhOyC0PGCqVusC*%0Tpxmbeirsu1{~RdtPl9s(SHWAr3!t3yBKQ&T z$Do}5M^OCnPmrr5Hx1SD3KTuZL9ydJcs8^qe~Cjy{+poi>SFA_04n+~g2UkNK(XW17)Rtr zK(W(a{;*Xt2?{^w!Ex|WQ0)6Ha4+~g_%ZMeQ1rbSQt&ew1LfWm;D^CagTm8iK#oja z0)=^lr$9OH8=%;|6##ZEs3?*(50g?Crs+>e68 zATCU1K+)@AQ1pKszhf|w@xJ1Fv3AuRXX4vN1fz!Tsj zpxFNcD0ccbDDp3ZqW>SjE5O4v*;q?|2QtKlk!m_}l-4W4J85y&3TSI3e5@-U{~!Re?i5;LJ35w{+xFJ2Jbf^DI@1 zHfy=m>`aD7#@cG?NR1EHFiY2u52vc-Y^gKr)yc&f)mqYpZk49+BbQEFr@E$Ga;dVq zYuL_B?S~XQs#&&vZatN znf6Mnv~R;?CbKI(nQ@)WsA{t3)*;fHp_F> zG%D*@X48@6q-Y?P$(`*aCmr-`>nbl5)Q6f%d+%BqEKFsxwh2FKo)&?Xi}N$ex0X!T zh=}j$mQlHBmx|@7SMZe)x=gA@HTX5i*-cIf?YlhR zO{QinlD(yE%j9B@!5B8`6|NH;wRsflL>3Q5#b0dJ%}P;nFz!p&>oGD{xYD&;-)r-R zx9V)Zw&jX4+IW-EM=Jw$T+_Q8uX@EB6N79g4DhOwg}NK`(yKU4H+lUFCA{ZZt668W z6<%i>XNZwb<0sz4TJ7;c*NK6|VqV5_pDfxH>&_A@tm~RH#}^iiS($S_3oac_H|A@9 z_NA9yQ>{o)7_K%XTu+s2gr6|vt6t9)m`Ng0ZT@7@!ymjhEDT)D3TL~<%3CTjQ3h^7 z3De5jYk>jnHUwopcXjL=8A=}FNTN>?Tpm@PJXada`%F6VH3m%-sz8Kbl#Q9NtUrje zmI*qI>9lc%M+Ae%6;$t<#%kM-oS2+AHZ*tYbmOQ5Rwf(7HiF#l(a}AP(S42Gd)3&U z@v(h(k1~Q_V;=g-CYQ*K-lsPI@=!)LYCsdFR79~zp`wo~bjX`D8?JFXUb+Gc)99ViQ(R^of(4;w!c zG#PP4=g`pX^z7t7#j%mmAyNP~<0iOkT$ScrxvQ6x&Gv^(Mua}Nc=~u_-#|`oj5ivS z1dfzAGOqSDvvO$Oh>shyzLTYmBUQ&YPP=h6bUZ6AQFB&T#L3L5i9)YwHRp1t4s_$- zVWS^2`3OP$(9pw;5L0X8Ja|Mmu?sgI85^3*Nm+SAVz3`qwimko;O_mZ{&{eRRR<5M zv7P&eNait#E0X&9d9u3uKhk*ye^e`Gavq?qa^ zatYXSGKx$7kd@(Zb53{RtK7I(WVV&{biU=9a-Zxm4coZ{uLyNwiQxKoS>on#PqxRz zZ+)NWPsvuA4Tq9Rl#Qtmf^o%xVy;#7#K2ocEDHE?{XBt(_vT3Ql6?9{#v%d}=Gt=W zU{XgYm3>0p!Bk%*WK_QXoHb-Dv0M=Ia$a8n*dD5mI^jvxwpml$6$Ll1*|=cz-sU-Y znHnmw482r`cbQTxMwUo{*9#u5D-{PjRkT;UJ27(oS)L-KTdPtnJ1`deY_B3;A$$uocf`E0BKFEDTT8mS&E@k@@T6RLsi7n!i0Q6g`!$n(W-KM z%dJe@Z-66O4}2C6xFqq~`VWwyuoWo**%>RgmpFh%-9j%`Rzj zTC09hJ*p|G+rq2Sluc4K;fn=$7_uxnVOm)NpJFiRzi#8H6S{$J6jLHcKZR6MOu_%! z3~AeW5v1VqJ-$Oi{zZCXoqsTt+9B zdi)al^vA`NTY^~drOl+;JHCFt$>R;~h-C~6l~^W4U~&S+Yy=0XvFi76$#CC~{oKI+ zPhcG}93Jpo-=Yp=V^7eBs+)}0A92a)tQQDDQfTUBM-8}X!C;ya@sgRXR0w`l-bq;@ zM3IV-5W7(!Vn1%_3gm`;odO`fl#E!V2+zD~hFluVp4Ank8A{HGauSVVtnAmz8^vQR ZCe=oO6klyrlKcm$F0UDk_8Ukh{{wR}LmB`8 literal 0 HcmV?d00001 diff --git a/po/es.po b/po/es.po new file mode 100644 index 0000000..e798085 --- /dev/null +++ b/po/es.po @@ -0,0 +1,414 @@ +# translation of gnome-vfs.HEAD.po to Spanish +# Spanish translation. +# Copyright (C) 2000,2003 Free Software Foundation, Inc. +# Manuel de Vega Barreiro , 2000. +# Mauricio Araya Polo , 2001. +# Juan Manuel García Molina , 2002,2003. +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs.HEAD\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-08-07 03:48+0200\n" +"Last-Translator: Juan Manuel García Molina \n" +"Language-Team: Spanish \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Report-Msgid-Bugs-To: \n" +"First-Translator: Mauricio Araya Polo \n" +"X-Generator: KBabel 1.0.1\n" +"Plural-Forms: nplurals=2; plural=(n == 1);\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d contiene caracteres nulos." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d contiene un método sin nombre." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d contiene un modulo sin nombre." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "No se encuentra el archivo de configuración `%s': %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Tipo de op %u desconocido" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "No se puede crear el pipe para el canal de E/S abierto: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Tipo de trabajo %u desconocido" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "La operación ha sido detenida" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "No se puede analizar: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "El resto de los errores de análisis serán ignorados." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Sin errores" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "No se ha encontrado el archivo" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Error genérico" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Error interno" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Parámetros no válidos" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "La operación no es soportada" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "Error de E/S" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Datos corruptos" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Formato no válido" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Manejador de archivos erróneo" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "El archivo es demasiado grande" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "No queda espacio en el dispositivo" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Sistema de archivos de sólo lectura" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "La URI no es válida" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "El archivo no está abierto" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "El modo de apertura no es válido" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Acceso denegado" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "Hay demasiados archivos abiertos" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Fin de archivo" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "No es un directorio" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "La operación está en progreso" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "La operación ha sido interrumpida" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "El archivo ya existe" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Se ha detectado una referencia circular de enlaces" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "La operación no está permitida" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "Es un directorio" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "No hay suficiente memoria" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "No se ha encontrado el host" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "El nombre del host no es válido" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "El host no tiene dirección" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Error en el acceso" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "La operación ha sido cancelada" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "El directorio se encuentra ocupado" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "El directorio no está vacío" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "Hay demasiados enlaces" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "El sistema de archivos sólo es de lectura" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "No en el mismo sistema de archivos" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "El nombre es demasiado largo" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "El servicio no se encuentra disponible" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Petición de datos de servicios obsoletos " + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Error de protocolo" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "No se pudo encontrar el examinador principal" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "No hay acción predeterminada asociada" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "No hay manejador para el esquema de URL" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "Error al analizar la línea de comandos" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "Error al lanzar el comando" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Error desconocido" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 byte" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, fuzzy, c-format +msgid "%u bytes" +msgstr "%u byte" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (Unicode inválido)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "GnomeVFSSeekPosition %d desconocida" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "No se ha encontrado un archivo de configuración válido para %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "" +"Use la variable de entorno %s para especificar una ubicación diferente\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "Aplicaciones" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "Tarjetas" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "Archivos" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "Carpetas" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "Ayuda" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "Máquinas" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "Enlaces" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "Correo" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "Herramientas" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "Ventanas" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Fábrica de monikers estándar" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "Archivo MonikerExtender" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "Moniker genérico de Gnome VFS" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "Moniker de archivo genérico" diff --git a/po/et.gmo b/po/et.gmo new file mode 100644 index 0000000000000000000000000000000000000000..1e37a78c7553fdfe338a8bf74b74e5f81cf8fab5 GIT binary patch literal 4488 zcmb`JO^h5z6~_zW5Lk#40wx4PD3Yx0#Gdu6*D?0S33lwYv$ogX*t-_FAZn&-W_zcn ztLf?}ezpuoX=2#KQw2NcBbRrk(}tr#w} zruskc)vK!aS+D=_z?N4P&k@GMjK|-r)QjNmExdTXdACycfUkh>125O~cfm)XU$61a z8vg>mAO774i~Lqz_k!EN`@qM*C&4-J3GfTxN5F4@Tfx`Bo!}2^`Zx9b4e*2T|5@W* zC?)dufwKQ2;D^B7;Qipintu|M{Xbu00?N9tfgb>0uIbC5?EgCW0QlpY|0XE={tkQy zya7HAz5~j+k7BIY+vN2icn}mjUjRQ08t{{#2StyUYy2L#4f-cF{t}e+H$YkUFHrQn z7bQjR;TrdX8v6N~j=_&Ze-#w@?|^d755P}@KLth4-`D)Vfnwh~pzM49R2BQ};76g? zK(X^HHT`XH=X;cT1H@$YTbx7))Z3uYe*!-N{vDKjxCdtmZU-?zEr23_29)zwL5WWf zd;)w4+zEak6#L%-#g4y%`@w&JqHhBuWc^`~qtpdZ>}-MJ?*S-sU$5~pDDrQBY@vQ$ z({F*|uRnvb?%$y3xs^lts~!X~RZWAkf3xNv1I5mB;A3DP+y%Y@%DF!S`Ke#=5Kkk^cDzN{}3qW?*ql&B~bLVHT`8!-@fa#i^{}qPM5m1QCP2L1F9qKw)I{| zHjQnho->i|#0amMG)k;GYSPpdx}957Se?b0)g6~>m)TUGSUh_avD7B>dfKa_F73qK zGB-u+(rS}0PWv7DqVZbx=(sYCYRNJ|TX>nty$!r$rZAYC=Vex)$FVp{cd#Z-BW?7+ zByps@Es8kp`f6`eaOf0*xosCN-_WhnZ%mM~z3pekhFV|`*9oiCak0%_ihbd$|0B)D zq!?FGg>$+Uchzy1_c>2wgDUETO>G{xwas&vtLL3BaG02>O%&z$v*JlWCRPQx@qvqb z&ej_&rbIS1$%w2BUOl&{7SrlKo?dNjKDcL6|K?3<=&1x@uhurcTzOa3DR+6aiqDdFQs}rbg(zZ>+rZEpY zv)pxqgD1IISm(`{D}H9Peq2aCjrqQCSq5i0cZF-aO`o5$WWGz2jayU{ZsT3JUn(sj zcP;M{V&X~7TpY54IwFtN`HBpoHv=MLTGZ0{f|@dUq?cS8_iRqgLguO!9NstSMisR& z>BK?eF|StBUg|DVbE)gw3&+o&x3;(Jd>m?RIvUMa3Arh~?pnGhB{W@*BwVJ84azvM ze3@k~$3arjmE+Z_Ck2StwB*kq&RyEKsU&_Liy5Q`$za=YXCuVE(;>Z>Ph2}x{>+pL zL9UHlxK!9QvbpNkB@-;rm_X=*8%8r>*(Q_ltW(&H#i((Cq~}VR*JNqmHU=F(wS0D^ zaa8Uk_zkWO?vTCB=3JwBpt1KUJv%o)dtg@+4uXwyaQn4pXxbB}0S3OtVGpj4d8wbX6 zq8qMmEKt)CH9W5mwBlmwzxNOydy_<_6?#Y?J9?uAVPjp-QmeLLPo2i&{xLc2q<@U2 z=^uu?ll}p!lVzDlHXB|UUh%qTE&eMbbs_GWlyWEcQGvT;f#ZzPNm&{)C@(d2fuJ5Y z5%N5Af>WbDLey|+*hBA-R)SKAjae21Wy`XR*l&1kcrCIR8u)UyC#9*jK821Li;Ny# zUn^`k);*ex?G?CK`{9*>`mNN|#+NbTgb zli}4Y3;$)odf74}(l@l3Fh5eglBsv7oG@CJ#HcPt;lHGC~0_Ery& z3oRy2bcPSgmNsVGctWh=+ty0=3B1aMO4?7@=X~sKf3#~IIq5x{j;wl*E%G>0iErS- z+Bb@&-X=7lu->-J@G9Q}z9_vqGQg7*C|Q>DOYW4uq!FwE7cEuPWwVoHWVcUsRvs>J z7`lj7W!;nLvW4k+vi1yTh-)h!WpS@3`jz9H;MO$+T<2xkuYz_Z_7Z&w)kx!Ip|Y5y zq^}m5nn+3&nDi%Fc$Klk>vSklM$7<2_uJfAb(D~zvU?A!L*`HN$Eh>Py_0ku>V({p z5}I6+an%K8=vqCOka2j)s8eyiUKXNak7D$e^tr`?|1Gdg4CIp_Br`U&xQuKn0juk0 zC6FWQDH%E**=7cJ?r5h&B4;L9FD2GJt0p, 2002. +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2002-06-05 14:39+0300\n" +"Last-Translator: Tõivo Leedjärv \n" +"Language-Team: Estonian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d sisaldab NUL märke." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d ei sisalda meetodi nime." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d ei sisalda mooduli nime." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Konfiguratsioonifaili '%s' ei leitud: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Tundmatu op tüüp: %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "Ei saa luua toru avatud GIOChannelile: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Tundmatu töö tüüp %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Operatsioon peatatud" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Ei suuda töödelda: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Järgmisi töötlemise vigu ignoreeritakse." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Vigu ei leitud" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Faili ei leitud" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Üldine viga" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Sisemine viga" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Vigased parameetrid" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Toetamata operatsioon" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "I/O viga" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Vigased andmed" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Formaat ei ole kehtiv" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Vigane failisang" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "Fail on liiga suur" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Seadme ruum on täis" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Kirjutamiskaitsega failisüsteem" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "Vigane URI" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Fail ei ole avatud" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Avamismood ei ole kehtiv" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Juurdepääs keelatud" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "Liiga palju avatud faile" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Faili lõpp" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Ei ole kataloog" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Operatsioon on töös" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Operatsioon katkestatud" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Fail on juba olemas" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Avastati silmuse moodustavad lingid" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Operatsioon ei ole lubatud" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "ls-i kataloog" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Pole piisavalt mälu" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Hosti ei leitud" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Hosti nimi ei ole kehtiv" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Hostil puudub aadress" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Sisselogimine ebaõnnestus" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Operatsioon katkestatud" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Kataloog on töös" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Kataloog ei ole tühi" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "Liiga palju linke" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Kirjutamiskaitsega failisüsteem" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Pole samas failisüsteemis" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Nimi on liiga pikk" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Teenus ei ole kättesaadav" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Päring tühistab teenuse andmed" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Protokolli viga" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +#, fuzzy +msgid "Could not find master browser" +msgstr "Ei suuda töödelda: %s" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Tundmatu viga" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 bait" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u baiti" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr "" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "Tundmatu GnomeVFSSeekPosition %d" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "Ei leia ühtegi korrektset sätete faili asukohast %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "Teise asukoha määramiseks kasuta keskkonnamuutujat %s.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +#, fuzzy +msgid "Files" +msgstr "Fail on juba olemas" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Standard Moniker factory" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "file MonikerExtender" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "generic Gnome VFS moniker" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "generic file moniker" diff --git a/po/eu.gmo b/po/eu.gmo new file mode 100644 index 0000000000000000000000000000000000000000..27f732826cece8bf09336f0a7d271eae7e6ed4fd GIT binary patch literal 4085 zcma);ON<;x8Gt(^1ZRPOLu>*BQjlyMC-izBENnJ{D7JUa5Zh~cy*?nzqGr0Lr`$bV zldf*tJAi-#D3=_NKnMYX0|+EIa6+IU4qQRx5Q$3^ONa}~1%W^uK#1?}u6Y=*5G|L# zsj9!L{&(-K2k!ZL#PbZ}VaDI?ilQC(+q?OX=g^y@=q>O*crQF0<`2OSFjs-k2401S zSpPf}`LDpY!3h1-D_!~Rt$=MLf9;Ai1G z;frDYn^4~WVc^S9&VL2o2XBS>pP-!o5BLDQ8)HT8D3o&-;d|gJd<>q2a_TtTV*MLo{&OgD zzk_oA>+liy7byB2#zPGHv<0!A7Xw#PCp8dLGjBc zpsZhpa*l)I*DpfR@7qx1UWQ`#tAT%j;-5c5Iq%S7Mk+~#~ z$UhEQicUj`=Pp#xL%HW`Q2g-&_#pfh{2+W4-UT0LtTHwjlvd*_iN_{`)M)Bl?jc-_ z{c?uHO&*D(JQ6p;5iK#qrZ+LZBj5#8jGoRddv6@RWV#2(4XCmA1O zD26;M4Dq!*%Zw)&;xl=~7xGAqCeKIt@nObshS*Lhnwl2>9%D!z%OiOzIVaCkEt>zO zwTUm~5#QrFek`r@)tQqmpKo!Fsoz{oRL>QawuM*c_s*)`K$p5#nbI%)_jcjb&{PAL zs6r3Tf!i*rb2HhlRd>HKK3ZuQJ=g0Q?^R+7Ym(@sPE_9_JkUjwo9L7-3RkIKX>?`O z$c~KayHdH4Db$(H&MCwSlW(d;ADwbV-==k`E9;8(kk2goW9o+XO3vuJx=4a#oue&l zBVBsatew`C#^kcBM-_UUwx#J+uH0AM+V9UzTHL6yEMekCwn$ZO zi_9xi^zbDwv2)Iq#059XcB8jfH*B7(u2D8E*iDwA^P;d=ox389&by!xKm17djLJ>F zQUonA*KN-rP~E1A%uV6ybU>yJ2}&b@d^Ir2%h^rJ_S6A;%~W(lgp^r%mYfbt0p?l*lFgI@HB}8=TqHi66u(R)S_(AHi z^{?1}jmn8TNqm{Cq7*k3X)rYL^}bgtOUp}Z3m0}S#iyjA*^MbYDsXjqc`aVvh*#Iu z%G&12##76zAQ)dHCFGQu+)BK>9^}^6Te-8^SMjA%7e3b%?WWo*@Q8FTlPsLoMOy3B z#Fva7ZmO-?XC(c?xz4$*nTja3Km(~v!9f_fsVZ}`Ix)&Qa9YOl zsMV~sDjGs&tFg%(8q-V=8C$27C-QaEI&XWkX}Q^?6(bqyon$c*_-u%Q!S# z5JX6gT4!p&ZmYd?<%|H!{kbkirm<;$ReYvXrv`Q9Z8m4F9%@UD&Q`SQY7xb7vG`6c z@7!oyF@J)5q%6*)Z*p?e&2eX=1E=TKjWH_Pl5TEP+BA1r*zuLlb!oA!jWMz4+Jx4h zP4}9J9&lEpEFXsUfQd(=-4h)G)YPxhd_~K`#FH8QzSSnx-DVTTqL_FtmZyce-% zR}(ruKH@Y&fIAh2k{oq(k{{zr$MhbxpoG zj%;pDOx;q{A-PpvkB#^;_zP$7MhJrBsVt<@W<)rp`_;M#+w#>4dC{(r0fin|NvY#6m@Dd!(R!sW)c!LrwgfNNfA-WgSqt}*u)IY z!}|jgm~VnE#gaMkl!~nn;Bt#HEtYggB0gDIr1iN<5{XI|9p*ONh#*NMri(MDH{NYZ5RJRq4hfcYzW)Gz CS0^(7 literal 0 HcmV?d00001 diff --git a/po/eu.po b/po/eu.po new file mode 100644 index 0000000..1a93c56 --- /dev/null +++ b/po/eu.po @@ -0,0 +1,1155 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2001 Free Software Foundation, Inc. +# Josu Waliño , 2002 +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs 1.0.3\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2001-05-25 13:35+0200\n" +"Last-Translator: Unmantained\n" +"Language-Team: Euskara\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=iso-8859-1\n" +"Content-Transfer-Encoding: 8bit\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d(e)k karaktere NULUAK ditu." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d(e)k ez du metodo-izenik." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d(e)k ez du modulu-izenik." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Ezin izan da `%s' konfigurazio-fitxategia aurkitu: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "%u op-mota ezezaguna" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "Ezin izan da GIOChannel irekitzeko kanalizazioa sortu: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "%u motako lana ezezaguna" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Eragiketa geldiarazita" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Ezin izan da ondokoa analizatu: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Gainerako analisi-erroreei ez zaie jaramonik egingo." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Errorerik ez" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Ez da fitxategia aurkitu" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Errore generikoa" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Barne-errorea" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Baliogabeko parametroa" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Eragiketa hori ez dago baimenduta" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "S/Iko errorea" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Datuak hondatuta" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Formatua ez da baliozkoa" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Fitxategi-heldulekua oker" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "Fitxategia handiegia da" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Ez da lekurik geratzen gailuan" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Irakurtzeko soilik fitxategi-sistema" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "URI baliogabea" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Ez da fitxategia ireki" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Irekitze-modua ez da baliozkoa" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Atzipena ukatuta" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "Fitxategi gehiegi daude irekita" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Fitxategi-amaiera" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Ez da direktorioa" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Eragiketa egiten ari da" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Eragiketa etenda" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Fitxategia badago" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Begizta-estekak aurkitu ditu" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Ez da eragiketa hori onartzen" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "Direktorioa da" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Ez dago nahikoa memoria" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Ez da ostalaria aurkitu" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Ostalari-izena ez da baliozkoa" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Ostalariak ez du helbiderik" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Saio-hasierak huts egin du" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Eragiketa etenda" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Direktorioa lanpetuta" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Direktorioa ez dago hutsik" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "Esteka gehiegi" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Irakurtzeko soilik fitxategi-sistema" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Ez dago fitxategi-sistema berean" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Izen luzeegia" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Zerbitzua ez dago erabilgarri" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Zerbitzu-datu zaharkituak eskatu dira" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Protokolo-errorea" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +#, fuzzy +msgid "Could not find master browser" +msgstr "Ezin izan da ondokoa analizatu: %s" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Errore ezezaguna" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 byte" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u byte" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr "" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "%d nomeVFSSeekPosition ezezaguna" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +#, fuzzy +msgid "Applications" +msgstr "KDE aplikazioaren xehetasunak" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +#, fuzzy +msgid "Files" +msgstr "Fitxategia badago" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +#, fuzzy +msgid "Folders" +msgstr "karpeta" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +#, fuzzy +msgid "generic file moniker" +msgstr "Errore generikoa" + +#~ msgid "GNOME VFS already initialized." +#~ msgstr "GNOME VFS dagoeneko hasieratuta dago." + +#~ msgid "3D Studio image" +#~ msgstr "3Dko estudio-irudia" + +#~ msgid "AIFC audio" +#~ msgstr "AIFC audioa" + +#~ msgid "AIFF audio" +#~ msgstr "AIFF audioa" + +#~ msgid "ANIM animation" +#~ msgstr "ANIM animazioa" + +#~ msgid "AVI video" +#~ msgstr "AVI bideoa" + +#~ msgid "AbiWord document" +#~ msgstr "AbiWord dokumentua" + +#~ msgid "Adobe FrameMaker font" +#~ msgstr "FrameMaker-en adobe letra-tipoa" + +#~ msgid "Adobe font metrics" +#~ msgstr "Adobe letra-tipoen neurriak" + +#~ msgid "Andrew Toolkit inset" +#~ msgstr "Andrew Toolkit-en txertatzea" + +#~ msgid "ApplixWare Graphics image" +#~ msgstr "ApplixWare Graphics-en irudia" + +#~ msgid "Applixware Words document" +#~ msgstr "Applixware Words-en dokumentua" + +#~ msgid "Applixware spreadsheet" +#~ msgstr "Applixware-ren kalkulu-orria" + +#~ msgid "AutoCAD image" +#~ msgstr "AutoCAD irudia" + +#~ msgid "BCPIO document" +#~ msgstr "BCPIO dokumentua" + +#~ msgid "BDF font" +#~ msgstr "BDF letra-tipoa" + +#~ msgid "C shell script" +#~ msgstr "C shell script-a" + +#~ msgid "C source code" +#~ msgstr "C iturburu-kodea" + +#~ msgid "C++ source code" +#~ msgstr "C++ iturburu-kodea" + +#~ msgid "CGI program" +#~ msgstr "CGI programa" + +#~ msgid "CGM image" +#~ msgstr "CGM irudia" + +#~ msgid "CMU raster image" +#~ msgstr "CMU bilbe-irudia" + +#~ msgid "CPIO archive" +#~ msgstr "CPIO artxiboa" + +#~ msgid "CPIO archive (gzip-compressed)" +#~ msgstr "CPIO artxiboa (gzip konprimitua)" + +#~ msgid "DCL script" +#~ msgstr "DCL script-a" + +#~ msgid "DOS font" +#~ msgstr "DOS letra-tipoa" + +#~ msgid "DOS/Windows program" +#~ msgstr "DOS/Windows programa" + +#~ msgid "DSSSL document" +#~ msgstr "DSSSL dokumentua" + +#~ msgid "DXF vector graphic" +#~ msgstr "DXF bektore-grafikoa" + +#~ msgid "Debian package" +#~ msgstr "Debian paketea" + +#~ msgid "Dia diagram" +#~ msgstr "Dia diagrama" + +#~ msgid "Dolby Digital audio" +#~ msgstr "Dolby Digital audioa" + +#~ msgid "Emacs Lisp source code" +#~ msgstr "Emacs-en Lisp iturburu-kodea" + +#~ msgid "Enlightenment theme" +#~ msgstr "Enlightenment gaia" + +#~ msgid "FLC animation" +#~ msgstr "FLC animazioa" + +#~ msgid "FLI animation" +#~ msgstr "FLI animazioa" + +#~ msgid "FastTracker II audio" +#~ msgstr "FastTracker II audioa" + +#~ msgid "Fortran source code" +#~ msgstr "Fortran iturburu-kodea" + +#~ msgid "FrameMaker interchange document" +#~ msgstr "FrameMaker-en trukatze-dokumentua" + +#~ msgid "G3 fax image" +#~ msgstr "G3 fax-irudia" + +#~ msgid "GIF image" +#~ msgstr "GIF irudia" + +#~ msgid "GIMP document" +#~ msgstr "GIMP dokumentua" + +#~ msgid "GMC link" +#~ msgstr "GMC esteka" + +#~ msgid "GNOME application details" +#~ msgstr "GNOME aplikazioaren xehetasunak" + +#~ msgid "GNU Oleo Spreadsheet" +#~ msgstr "GNU Oleo kalkulu-orria" + +#~ msgid "GNU mail message" +#~ msgstr "GNUren mezu elektronikoa" + +#~ msgid "GTK configuration" +#~ msgstr "GTKren konfigurazioa" + +#~ msgid "Glade project" +#~ msgstr "Glade proiektua" + +#~ msgid "GnuCash Workbook" +#~ msgstr "GnuCash laneko liburua" + +#~ msgid "Gnumeric spreadsheet" +#~ msgstr "Gnumeric kalkulu-orria" + +#~ msgid "HDF document" +#~ msgstr "HDF dokumentua" + +#~ msgid "HTML page" +#~ msgstr "HTML orria" + +#~ msgid "IDL document" +#~ msgstr "IDL dokumentua" + +#~ msgid "IEF image" +#~ msgstr "IEF irudia" + +#~ msgid "IFF image" +#~ msgstr "IFF irudia" + +#~ msgid "ILBM image" +#~ msgstr "ILBM irudia" + +#~ msgid "ISI video" +#~ msgstr "ISI bideoa" + +#~ msgid "Impulse Tracker audio" +#~ msgstr "Impulse Tracker audioa" + +#~ msgid "JBuilder Project" +#~ msgstr "JBuilder proiektua" + +#~ msgid "JPEG image" +#~ msgstr "JPEG irudia" + +#~ msgid "Java byte code" +#~ msgstr "Java byte-kodea" + +#~ msgid "Java source code" +#~ msgstr "Java iturburu-kodea" + +#~ msgid "KIllustrator document" +#~ msgstr "KIllustrator dokumentua" + +#~ msgid "KPresenter presentation" +#~ msgstr "KPresenter aurkezpena" + +#~ msgid "KSpread spreadsheet" +#~ msgstr "KSpread kalkulu-orria" + +#~ msgid "KWord document" +#~ msgstr "KWord dokumentua" + +#~ msgid "Korn shell script" +#~ msgstr "Korn shell script-a" + +#~ msgid "LHA archive" +#~ msgstr "LHA artxiboa" + +#~ msgid "LHARC archive" +#~ msgstr "LHARC artxiboa" + +#~ msgid "LIBGRX font" +#~ msgstr "LIBGRX letra-tipoa" + +#~ msgid "LightWave object" +#~ msgstr "LightWave objektua" + +#~ msgid "LightWave scene" +#~ msgstr "LightWave eszena" + +#~ msgid "Linux PSF console font" +#~ msgstr "Linux-en PSF kontsolarako letra-tipoak" + +#~ msgid "Lotus 1-2-3 spreadsheet" +#~ msgstr "Lotus 1-2-3 kalkulu-orria" + +#~ msgid "M3 audio URL" +#~ msgstr "M3 audioaren URLa" + +#~ msgid "MIDI audio" +#~ msgstr "MIDI audioa" + +#~ msgid "MOD audio" +#~ msgstr "MOD audioa" + +#~ msgid "MP3 audio" +#~ msgstr "MP3 audioa" + +#~ msgid "MP3 audio playlist" +#~ msgstr "MP3 audioaren erreprodukzio-zerrenda" + +#~ msgid "MPEG video" +#~ msgstr "MPEG bideoa" + +#~ msgid "MS ASF video" +#~ msgstr "MS ASF bideoa" + +#~ msgid "MS video" +#~ msgstr "MS bideoa" + +#~ msgid "Macintosh AppleDouble-encoded file" +#~ msgstr "Macintosh-en AppleDouble kodedun fitxategia" + +#~ msgid "Macintosh BinHex-encoded file" +#~ msgstr "Macintosh-en BinHex kodedun fitxategia" + +#~ msgid "Macintosh StuffIt archive" +#~ msgstr "Macintosh-en StuffIt artxiboa" + +#~ msgid "Macromedia Flash file" +#~ msgstr "Macromedia Flash fitxategia" + +#~ msgid "MathML document" +#~ msgstr "MathML dokumentua" + +#~ msgid "Microsoft Excel spreadsheet" +#~ msgstr "Microsoft Excel-en kalkulu-orria" + +#~ msgid "Microsoft PowerPoint document" +#~ msgstr "Microsoft PowerPoint-eko dokumentua" + +#~ msgid "Microsoft Word document" +#~ msgstr "Microsoft Word-eko dokumentua" + +#~ msgid "Microsoft video" +#~ msgstr "Microsoft bideoa" + +#~ msgid "Nautilus link" +#~ msgstr "Nautilus esteka" + +#~ msgid "ODA document" +#~ msgstr "ODA dokumentua" + +#~ msgid "PBM image" +#~ msgstr "PBM irudia" + +#~ msgid "PCF font" +#~ msgstr "PCF letra-tipoa" + +#~ msgid "PDF document" +#~ msgstr "PDF dokumentua" + +#~ msgid "PEF program" +#~ msgstr "PEF programa" + +#~ msgid "PGM image" +#~ msgstr "PGM irudia" + +#~ msgid "PGN chess game" +#~ msgstr "PGN xake-jokoa" + +#~ msgid "PGP keys" +#~ msgstr "PGP gakoak" + +#~ msgid "PGP message" +#~ msgstr "PGP mezua" + +#~ msgid "PGP signature" +#~ msgstr "PGP sinadura" + +#~ msgid "PGP-encrypted file" +#~ msgstr "PGPk enkriptatutako fitxategia" + +#~ msgid "PHP script" +#~ msgstr "PHP script-a" + +#~ msgid "PN RealAudio document" +#~ msgstr "PN RealAudio dokumentua" + +#~ msgid "PNG image" +#~ msgstr "PNG irudia" + +#~ msgid "PNM image" +#~ msgstr "PNM irudia" + +#~ msgid "PPM image" +#~ msgstr "PPM irudia" + +#~ msgid "Palm OS database" +#~ msgstr "Palm OS datu-basea" + +#~ msgid "Perl script" +#~ msgstr "Perl script-a" + +#~ msgid "Photoshop document" +#~ msgstr "Photoshop-eko dokumentua" + +#~ msgid "PostScript Type 1 font" +#~ msgstr "PostScript Type 1 letra-tipoa" + +#~ msgid "PostScript document" +#~ msgstr "PostScript-eko dokumentua" + +#~ msgid "Python source code" +#~ msgstr "Python iturburu-kodea" + +#~ msgid "QuickTime movie" +#~ msgstr "QuickTime filma" + +#~ msgid "Quicken document" +#~ msgstr "Quicken dokumentua" + +#~ msgid "Quicken for Windows document" +#~ msgstr "Windows-erako Quicken dokumentua" + +#~ msgid "RAR archive" +#~ msgstr "RAR artxiboa" + +#~ msgid "README document" +#~ msgstr "README dokumentua" + +#~ msgid "RGB image" +#~ msgstr "RGB irudia" + +#~ msgid "RIFF audio" +#~ msgstr "RIFF audioa" + +#~ msgid "RPM package" +#~ msgstr "RPM paketea" + +#~ msgid "RealAudio/Video document" +#~ msgstr "RealAudio/Video dokumentua" + +#~ msgid "RealVideo video" +#~ msgstr "RealVideo bideoa" + +#~ msgid "S/MIME file" +#~ msgstr "S/MIME fitxategia" + +#~ msgid "S/MIME signature" +#~ msgstr "S/MIME sinadura" + +#~ msgid "SGI video" +#~ msgstr "SGI bideoa" + +#~ msgid "SGML document" +#~ msgstr "SGML dokumentua" + +#~ msgid "SMIL script" +#~ msgstr "SMIL script-a" + +#~ msgid "SQL code" +#~ msgstr "SQL kodea" + +#~ msgid "SV4 CPIO archive" +#~ msgstr "SV4 CPIO artxiboa" + +#~ msgid "SV4 CPIP archive (with CRC)" +#~ msgstr "SV4 CPIP artxiboa (CRCrekin)" + +#~ msgid "SVG art" +#~ msgstr "SVG artea" + +#~ msgid "Scheme source code" +#~ msgstr "Scheme iturburu-kodea" + +#~ msgid "Scream Tracker 3 audio" +#~ msgstr "Scream Tracker 3 audioa" + +#~ msgid "Scream Tracker audio" +#~ msgstr "Scream Tracker audioa" + +#~ msgid "Scream Tracker instrument" +#~ msgstr "Scream Tracker instrumentua" + +#~ msgid "Setext document" +#~ msgstr "Setext dokumentua" + +#~ msgid "Speech document" +#~ msgstr "Speech dokumentua" + +#~ msgid "Speedo font" +#~ msgstr "Speedo letra-tipoa" + +#~ msgid "Spreadsheet Interchange document" +#~ msgstr "Kalkulu-orriaren trukatze-dokumentua" + +#~ msgid "Stampede package" +#~ msgstr "Stampede paketea" + +#~ msgid "StarOffice Writer document" +#~ msgstr "StarOffice Writer dokumentua" + +#~ msgid "StarOffice presentation" +#~ msgstr "StarOffice aurkezpena" + +#~ msgid "StarOffice spreadsheet" +#~ msgstr "StarOffice kalkulu-orria" + +#~ msgid "Sun mu-law audio" +#~ msgstr "Sun µ-law audioa" + +#~ msgid "SunOS News font" +#~ msgstr "SunOS News letra-tipoa" + +#~ msgid "TIFF image" +#~ msgstr "TIFF irudia" + +#~ msgid "TarGA image" +#~ msgstr "TarGA irudia" + +#~ msgid "Tcl script" +#~ msgstr "Tcl script-a" + +#~ msgid "TeX document" +#~ msgstr "TeX dokumentua" + +#~ msgid "TeX dvi document" +#~ msgstr "TeX dvi dokumentua" + +#~ msgid "TeX font" +#~ msgstr "TeX letra-tipoa" + +#~ msgid "TeX font metrics" +#~ msgstr "TeX letra-tipoen neurriak" + +#~ msgid "TeXInfo document" +#~ msgstr "TeXInfo dokumentua" + +#~ msgid "ToutDoux document" +#~ msgstr "ToutDoux dokumentua" + +#~ msgid "TrueType font" +#~ msgstr "TrueType letra-tipoak" + +#~ msgid "USENET news message" +#~ msgstr "USENET berrien mezua" + +#~ msgid "Unidata netCDF document" +#~ msgstr "Unidata netCDF dokumentua" + +#~ msgid "V font" +#~ msgstr "V letra-tipoa" + +#~ msgid "VOC audio" +#~ msgstr "VOC audioa" + +#~ msgid "VRML document" +#~ msgstr "VRML dokumentua" + +#~ msgid "Vivo video" +#~ msgstr "Vivo bideoa" + +#~ msgid "WAIS source code" +#~ msgstr "WAIS iturburu-kodea" + +#~ msgid "Wavelet video" +#~ msgstr "Wavelet bideoa" + +#~ msgid "Windows bitmap image" +#~ msgstr "Windows bit-maparen irudia" + +#~ msgid "Windows icon image" +#~ msgstr "Windows ikonoaren irudia" + +#~ msgid "Windows metafile graphics" +#~ msgstr "Windows metafitxategi grafikoak" + +#~ msgid "WordPerfect document" +#~ msgstr "WordPerfect dokumentua" + +#~ msgid "X bitmap image" +#~ msgstr "X bit-maparen irudia" + +#~ msgid "X window image" +#~ msgstr "X leihoaren irudia" + +#~ msgid "XML document" +#~ msgstr "XML dokumentua" + +#~ msgid "XPM image" +#~ msgstr "XPM irudia" + +#~ msgid "Xbase database" +#~ msgstr "Xbase datu-basea" + +#~ msgid "active server page" +#~ msgstr "zerbitzari aktiboaren orrialdea" + +#~ msgid "address card" +#~ msgstr "helbide-txartela" + +#~ msgid "ar archive" +#~ msgstr "ar artxiboa" + +#~ msgid "arj archive" +#~ msgstr "arj artxiboa" + +#~ msgid "authors list" +#~ msgstr "egileen zerrenda" + +#~ msgid "backup file" +#~ msgstr "babeskopia" + +#~ msgid "basic audio" +#~ msgstr "oinarrizko audioa" + +#~ msgid "bibliography record" +#~ msgstr "bibliografi erregistroa" + +#~ msgid "binary program" +#~ msgstr "programa bitarra" + +#~ msgid "block device" +#~ msgstr "bloke-gailua" + +#~ msgid "bzip-compressed file" +#~ msgstr "bzip- konprimitutako fitxategia" + +#~ msgid "calendar file" +#~ msgstr "egutegi-fitxategia" + +#~ msgid "calendar or event document" +#~ msgstr "egutegia edo gertaeren dokumentua" + +#~ msgid "character device" +#~ msgstr "karaktere-gailua" + +#~ msgid "comma-separated text document" +#~ msgstr "komaz bereizitako testua" + +#~ msgid "compound document" +#~ msgstr "dokumentu konposatua" + +#~ msgid "compress-compressed file" +#~ msgstr "compress- konprimitutako fitxategia" + +#~ msgid "compressed GIMP document" +#~ msgstr "GIMP dokumentu konprimitua" + +#~ msgid "directory information file" +#~ msgstr "direktorioen informazio-fitxategia" + +#~ msgid "document type definition" +#~ msgstr "dokumentu-motaren definizioa" + +#~ msgid "email headers" +#~ msgstr "postaren goiburukoak" + +#~ msgid "email message" +#~ msgstr "mezu elektronikoa" + +#~ msgid "encrypted message" +#~ msgstr "enkriptatutako mezua" + +#~ msgid "enriched text document" +#~ msgstr "testu aberastua" + +#~ msgid "gtar archive" +#~ msgstr "gtar artxiboa" + +#~ msgid "gzip-compressed file" +#~ msgstr "gzip- konprimitutako fitxategia" + +#~ msgid "help page" +#~ msgstr "laguntza-orrialdea" + +#~ msgid "mail delivery report" +#~ msgstr "posta-bidalketaren txostena" + +#~ msgid "mail disposition report" +#~ msgstr "posta-eskuratzearen txostena" + +#~ msgid "mail system report" +#~ msgstr "posta-sistemaren txostena" + +#~ msgid "makefile" +#~ msgstr "makefile" + +#~ msgid "manual page" +#~ msgstr "eskuliburuaren orrialdea" + +#~ msgid "manual page (compressed)" +#~ msgstr "eskuliburuaren orrialdea (konprimitua)" + +#~ msgid "memory dump" +#~ msgstr "memoria-irteera" + +#~ msgid "message digest" +#~ msgstr "mezuaren laburpena" + +#~ msgid "message in several formats" +#~ msgstr "mezua hainbat formatutan" + +#~ msgid "multi-part message" +#~ msgstr "zati anitzeko mezua" + +#~ msgid "named pipe" +#~ msgstr "izendun kanalizazioa" + +#~ msgid "object code" +#~ msgstr "objektu-kodea" + +#~ msgid "ogg audio" +#~ msgstr "ogg audioa" + +#~ msgid "partial email message" +#~ msgstr "mezu elektronikoaren zatia" + +#~ msgid "plain text document" +#~ msgstr "testu arrunta" + +#~ msgid "profiler results" +#~ msgstr "profilaren emaitzak" + +#~ msgid "reference to remote file" +#~ msgstr "urruneko fitxategiaren erreferentzia" + +#~ msgid "rejected patch file" +#~ msgstr "adabaki-fitxategia ezetsia" + +#~ msgid "rich text document" +#~ msgstr "testu aberastuko dokumentua" + +#~ msgid "search results" +#~ msgstr "bilaketaren emaitzak" + +#~ msgid "shared library" +#~ msgstr "liburutegi konpartitua" + +#~ msgid "shell archive" +#~ msgstr "shell artxiboa" + +#~ msgid "shell script" +#~ msgstr "shell script-a" + +#~ msgid "signed message" +#~ msgstr "sinatutako mezua" + +#~ msgid "socket" +#~ msgstr "socket-a" + +#~ msgid "software author credits" +#~ msgstr "Software-egileen kredituak" + +#~ msgid "software installation instructions" +#~ msgstr "softwarea instalatzeko jarraibideak" + +#~ msgid "software license terms" +#~ msgstr "softwarearen lizentzia" + +#~ msgid "source code patch" +#~ msgstr "iturburu-kodearen adabakia" + +#~ msgid "style sheet" +#~ msgstr "estilo-orria" + +#~ msgid "symbolic link" +#~ msgstr "esteka sinbolikoa" + +#~ msgid "tab-separated text document" +#~ msgstr "tabulazioz bereizitako testua" + +#~ msgid "tar archive" +#~ msgstr "tar artxiboa" + +#~ msgid "tar archive (bzip2-compressed)" +#~ msgstr "tar artxiboa (bzip2-konprimitua)" + +#~ msgid "tar archive (gzip-compressed)" +#~ msgstr "tar artxiboa (gzip-konprimitua)" + +#~ msgid "theme" +#~ msgstr "gaia" + +#~ msgid "troff document" +#~ msgstr "troff dokumentua" + +#~ msgid "troff me input document" +#~ msgstr "troff me sarrera-dokumentua" + +#~ msgid "troff mm input document" +#~ msgstr "troff mm sarrera-dokumentua" + +#~ msgid "troff ms input document" +#~ msgstr "troff ms sarrera-dokumentua" + +#~ msgid "unknown type" +#~ msgstr "mota ezezaguna" + +#~ msgid "ustar archive" +#~ msgstr "ustar artxiboa" + +#~ msgid "wave audio" +#~ msgstr "wave audioa" + +#~ msgid "web folder" +#~ msgstr "web karpeta" + +#~ msgid "xfig vector graphic" +#~ msgstr "xfig bektore-grafikoa" + +#~ msgid "zip archive" +#~ msgstr "zip artxiboa" + +#~ msgid "zoo archive" +#~ msgstr "zoo artxiboa" diff --git a/po/fa.gmo b/po/fa.gmo new file mode 100644 index 0000000000000000000000000000000000000000..26f7a9cadf809a45a8a14cd284b751edbbd984c1 GIT binary patch literal 5159 zcmbW3TWlOx8ONs(T4JsZ;aUoZf^pJx9Xm-I*GXy8-0J3L5~nXkg7NOGJ<0COGBfMM zsH&1Ejw8h?LZZ)k;Nrw2v2tsgO3f1>RN#$=S-V1Ngai*fAOr%Q;P*c>d$AKF#K^P% zJ?DJqeBbx~{@+>ue$|RM9G>TRzsS4d1CDbT{PPF-;2HRk<2(XB3qA~P&&MxRX;D?#N0?PhP@MGXR;3vRegHM8s;9Bruj6MbSfgcBVf@{FT`S{g*{XF;)<}c*< zvwZzFsPlgbeiZy2_(|~neEzSX&Q}t`)u8;W0at>X^YM02=MRIcz;EUAA*gd-13wR* z2fqgX1eD)*LFJo*p9S9smFK^}N5PdWJ_bGp%KzpZ_ky2h{Oug;p!S~!weLru;=Glw z|2)S9&@lg(eEcX$$gT&}`Okn~244ad-_d;j1gN}bK>57@ZU=9H{SP_LKR`lu)&ELV@;A(>W z0{BXf6QFqb0VummIsOWiKK}@IgDXf{<0nDoy$5^(dG;I1IiCiqA(7mG<|5THgYyPIXXmOoN-jAA?VU?}48KS7Njt zd;*leL!jcC0JZN8Q2Aa5p8?;^@ga&e#CQNyyr*-V1vfDM4cG_%8%rjn020VkY8yT>DgxspI_%y-Sv>NtwF(# zGCnuv-vx$O+(4=GG;bHLu9+3Qn|SpM@FESX39cgh^z$jsNx?qi>odG-vtjE~d{S1c zTXC;P9IfU>-mOPGiyQH#nyus2{inL9H^g`6gXFB{D2>&8uNJ#|`^#p}3mNXsU_Zln zu)Ac6VUW0f5Ss%>_L<_i8@a{Ai{jqp%Ry+WUNRn*OyE|%2QG)Ddc|ul*Uji;;>AwC zMQ3}l=*6)qd4cbhoEO}ZDf<|YyFsbqIXm1S2oqC`JU8)7&98Z;97ZOrd4bt8bZ`e| zfmazc-LbPH49fmkJ#rI246;MM(;fGi<8EwpMmekprQEV!AzJ2YZWMcVZl{~Lq#Q-{ zT0$H<{Zi1w9zQ4<*G#w-zhq)BN&H|e&dzodoOWRtdBr4*Ce3I)p6nRvc&}PZCY@cJ z5ti*PXSZ_mPWW*WXWv_qwTDVB8zo_AM*T5ocNkUiCtDkev&Rd($S)c%io(cwF^m%k zQ<}ytl_L1e=2Vc5UDmGcaA^I({D7f=$_8$wHOvw|a%jjI3bOAo#bFYFGZaHfshPL4 zFC6pX+aYN^*bpn#Qi zB@D)#17RKzU*eiu^i0JoCx+^lya~VPVUR2dMPn}r>to|cvPw~`1@_6fXJVagwG~gs ziC1+FN<`JL)JYL@xqympQ1mLwsXa%YwJ0331b5DoVXm9@ta#?Is-H+t?fEzfYc*zu zqc91JVUzPi9?B1c%H)y|HCuSV?04%PB@ajAutH5@q#22j9{LC!JBPEOExkKIW!zDE zX#`%YZZMe@r#%eCgNTWpBf+sCJWgu`Vbyzi_u<2ycWgL}ecMvqrPg|;yQcNgaMT=A zr*zj_7GcdKlXR<{itDvn7{P-YH{;hi5>si)(k+=x_)!>Cy+Hbod_{{2sJU14%agXm z)Tl9 z8z^je+VpQ6>>pUy#|(yrL&!<{+jbk8cAEw_Y+l#5X=7j4J~vJZBas`#6_5|Q zd!ydC84l|-PsxkS)+n3W7IR(thJCA;$}<8y)XiygC_A#BH-e^qUJ2|sBWAFcTKAlakrSrYca^va6 znT50LNoN~VrZJVyrSt4z{6FrvyEwzHS)9sUI=gIhcip5HHJi>ki`UxUIsQgEX9Fa% zi`q4X(>o@;na(?{)dhk{uQjGk<1TPcVKviAuaXd39b8W>&dB*(rnmPNjD!7MT(ghh0-AE(@s3 zA*|W-s`#7Y>)Xnm%td{B3BR+AGpfK@_G<~}s+g$kjAKbqhEOl_&da&g*3#u>DDrLD zS-MQ%vnof2%T|3&dX+R45mwjJYYX_uVs4yPsOiOy?Au3>$8B5n^bT4&Cs8>1;0T;4 z7sbIBn`%4irt~{4TjaKnUvkv_*|ogG37JSL>zUKn%LLL|wtlZFJEtQas6+(K&}hYG zamAY0)zq9i!Dh(LPMcPhn>6Jiz#sIdH;9(9(%hrK ze1fpcxnT49E>Y^Vy}odcU?mv%7TDVbcX*J9W*evNE=YuA#nP64OM>YY7Eh&bH7^*& z16|Cie%Zl|>FkJ3Qaf9ueFbKmJND2sVw@-te0JAJjI9#4C1!<-GO(n<&!}H>uBGVa z0?BcaD%dl&a_LQZ%@fb5T57*QChVcaryHkQ_3N}D8Yt{+$fdC$zHE1A?M3NnX;Vt# z6E(G^_CQunVSiiEX4O|E=*Ith8$@I$Nz^ouysUp;PX5Wp7VfmUc6YtoUtdcW&Vq`GNnhNq_d&fE!#r zlXVvV#kKB|, 2002 +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2002-08-25 14:27+0430\n" +"Last-Translator: Roozbeh Pournader \n" +"Language-Team: Persian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "‏‎%s:%d‎ نویسه‌ی NUL دارد." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "‏‎%s:%d‎ هیچ نام متدی ندارد." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "‏‎%s:%d‎ هیچ نام پیمانه‌ای ندارد." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "پرونده‌ی پیکربندی ‎`%s'‎ یافت نشد: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "نوع عملیات ناشناخته %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "نمی‌توان برای GIOChannel باز لوله ایجاد کرد: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "نوع کار ناشناخته %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "عملیات متوقف شد" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "نمی‌توان تجزیه کرد: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "خطاهای تجزیه‌ی بعدی نادیده گرفته خواهند شد." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "خطایی نیست" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "پرونده یافته نشد" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "خطای عمومی" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "خطای داخلی" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "پارامترهای نامعتبر" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "عملیات پشتیبانی‌نشده" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "خطای ورودی/خروجی" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "داده‌ها مخدوشند" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "قالب معتبر نیست" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "دست‌گیره پرونده‌ی خراب" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "پرونده خیلی بزرگ است" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "هیچ جایی روی دستگاه باقی نمانده" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "سیستم پرونده‌ای فقط‌خواندنی" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "نشانی جهانی نامعتبر" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "پرونده باز نیست" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "حالت باز کردن معتبر نیست" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "دست‌یابی منع شد" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "پرونده‌های باز خیلی زیادند" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "پایان پرونده" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "شاخه نیست" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "عملیات در حال پیش‌روی است" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "عملیات دچار وقفه شد" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "پرونده وجود دارد" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "به پیوندهای حلقه‌ای برخورده شد" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "عملیات مجاز نیست" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "شاخه است" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "حافظه‌ی ناکافی" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "میزبان یافته نشد" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "نام میزبان معتبر نیست" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "میزبان نشانی ندارد" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "ورود به سیستم شکست خورد" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "عملیات لغو شد" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "شاخه مشغول است" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "شاخه خالی نیست" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "پیوندها خیلی زیادند" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "سیستم پرونده‌ای فقط‌خواندنی" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "روی همان سیستم پرونده‌ای نیست" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "نام خیلی بلند است" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "خدمت در دست‌رس نیست" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "درخواست، داده‌های خدمت را قدیمی می‌کند" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "خطای قرارداد" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +#, fuzzy +msgid "Could not find master browser" +msgstr "نمی‌توان تجزیه کرد: %s" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "خطای ناشناخته" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "Û± بایت" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u بایت" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr "" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "‏GnomeVFSSeekPosition ناشناخته‌ی %d" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "پرونده‌ی تنظیمات معتبری در %s یافت نشد\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "از متغیر محیطی %s برای مشخص کردن یک مکان دیگر استفاده کنید.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +#, fuzzy +msgid "Files" +msgstr "پرونده وجود دارد" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "" diff --git a/po/fi.gmo b/po/fi.gmo new file mode 100644 index 0000000000000000000000000000000000000000..99a166beb892ec6aa7f3bdef379178cbb954122b GIT binary patch literal 5490 zcmai$TWnlM8Gxr(z`f9xJH1T{Zkn{~*y#n=Y125VlbG1Cn>ayjdFXg|);r#_XHL(| z*<@dMsVIoPAeE|!mkMDC@lYrd3KHT0$*M~G07BxbQUt0HeM15yctD8nKj-YOU0QME z@wYSc&+Wg>{NaYnpI3a3Qf{JbU8+pOf>-uFh-a`GV zn)_-l!uQkOfg=ADyarx?SHoxE2jO#YAN&@SC4UC@!e7Fh;eX(V;7v?+Eu4mT!iVd6 z2TK2WcolpWehj_x_tm;KVOETzpvHp--aT85z6{MhM$11L0RW5_-Xhyl=ZKfsO)kh zWUFcxiu^p3b3Oq@j{#l}pN2QW=b`NP`!!#IAEExcntz2d{t7lJ<8Fp>p8Zhd4%J+P zn)+s4e-?h6`ZuA-{|L%DuR%H2oA6fn7L@&8#v!HudMJ9BgfjmuoQJ0%CRSgCABJCt za=w@9`m1pM5~Y4$x8K5|B0meouMXGs<4{vyfw#j9ehNMZMQ=ZZBL5R8`*{_zMfC<0 zKluy1173nrd!_!1O5{v6K1UqPAwI*fNGoP;v|6qIpKKn=eDWt|tH z$iEElhOarX=2cL8O+FV_4n)YN|iMKAw?qPJ_AOy;|T zf08c_LOK6qQ1;h^vae^Ltn&htaW6x*q<#vIz&D`y)h$dea(6(n`@>M=ABUGf`Q|IA zlQr3jTBV3yB!}KZ+4&u$Qu+jZfFkzaOObiyJ50Hkau;Qaa*T3_aw$c=2PvN|e^ovp z{w$yDZ(sR~ID?<5e^1wxbBXTd{5!wfs4P=7MPfw070LqT5y}aQ#ISsl+mBPk*F`^~ zGx_^9N= zhba$H#Kxy65+f47xTl(>$R}|owqK&mP$X`YzSE_Blem^Xo4TfN*}ZCVYNoA^AE|h< z!ZOt`H`&rnpGM=-piiA$(#?*^O*7g&Oue%^^}1(c$G3E9diGtreXB_9u)EOfgJ^@A zDXHe0O&fx4+0@yVn$NPtHBEFr4eE$#>9%8J$E2;qs-q@Nebmj|nrLfEi<)!k+v#%UnCqr+FaVwJrg*q zUeEpcU~}df_GTszwjA+@i3T0zd67jn{)lU(d+O0fS9%UMMwf1cYGo7I*aU*PZAPCD z^m-8nJF2p{?PYPG7TAGrm!s4|o^!;+6lt@=T&&pZp^ds-wzH#ECoZ+>n5fKNa3O~3 z_vonOs_3k$Mep^x+bAo@`=o`DVcuiIGO|32I&M>&yQa3XA9cbenL6P^#5AHxZCb4y zGgfWl2RnwAa^pQnHK@h?EA?E9DXLCQGOE^2dU{bU)(*=tnNqw@Ee36LYp6rDXgSl+onjOCI)a#Z9?!(hZnY_v(gDaDnHFjuRMEtNrz^~_N<76%rvb|Y&&X( zw`|`vrJV_P97gIk^~FYqi0a`Yr3CV^V|9=%mC+CeIA>3-h}-vw;~lD|t#`CQI`9S(oj2F(N68f<5sa3ll5GbLyp@+^jSvBYVMa>bgW{8)Jx)*02*X zF{ms)u6j|BXe>xu64cqWoBH$Qiq!Y)xnpO}SleCo!IdVRY>oOWdk&>H{krZ-QkX18 z58`0LXl-YM@^E6D)p-oFjr|)~obGOK4PxBB=!uddN<8^K8!x)3L81QY7-E9R zl}k4EUDN3sHNHYghuk1e_r23e;af&$MeJHrUVJA}kc(=b*@`fn!RS45u`(vvzBq`3 zbP!A7RXKXFVhXOyo!zoi=8x>ZNV+aolb5$@-^f)*Uo6rhieNeE_7=11u1)&BG=m`x z@7_aZTo%IR3D z>+(%g!~(-{8k=oz`O*%BLnP@H-LB~w@{lPLe;HOx#(ja`DDrxA-1wbV=`1#K$?y=Q zJC+XDHAQ7kda&X4R)2eo*G%Di&U12}065Ip2$_q7m0IDxDuT&zTyeA7tNci>-2q_| zzzp zhG_DPD=awOE7*?{sqz>i$$LSZZxrLqm~V3J+N8(Q7);Ig(Lpqs`5zBjtD?or3xEt# zaDSHJ<43_DW(Q$B?AW6(&a0ni-k<(NyCuXy;&4grXoyB zP!uGhQJDN+!PUV41z+UmO*>o=hV@NCIxKjF@zzMyYE>1*2SZCAE0Hqm$A+t~&_=YK zmf@vYh9r$xUmloU9C}w{tkVd|2`5QYwmR6p*fj}>Y)u}bJgW)V_j-ct5UDjX9ut{J z+$eMM?${yev(mk)_66671*Rac)<#n&Mc?Rf&?AO&JZ1Z0uMoR#q7GgtIE1u|uM*wC v;!unwt)VLtYRYS5vD+o|jpgdSF?x{<>ZCJ%ku-*{k73tv?6Cd6YDdvZ literal 0 HcmV?d00001 diff --git a/po/fi.po b/po/fi.po new file mode 100644 index 0000000..844aec7 --- /dev/null +++ b/po/fi.po @@ -0,0 +1,409 @@ +# gnome-vfs Finnish translation +# Suomennos: http://gnome-fi.sourceforge.net/ +# +# Copyright (C) 2002 Free Software Foundation, Inc. +# Pauli Virtanen , 2000-2002. +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs 1.9.4\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-06-16 21:20+0200\n" +"Last-Translator: Pauli Virtanen \n" +"Language-Team: Finnish \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Report-Msgid-Bugs-To: \n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d sisältää NUL-merkkejä." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d ei sisällä metodin nimeä." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d ei sisällä moduulin nimeä." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Asetustiedostoa '%s' ei löytynyt: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Tuntematon op-tyyppi %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "GIOChannelille ei voi luoda putkea: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Tuntematon työtyyppi %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Toiminta pysäytetty" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Ei voitu tulkita: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Mahdolliset seuraavat tulkkausvirheet jäävät huomiotta." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Ei virhettä" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Tiedostoa ei löytynyt" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Yleinen virhe" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Sisäinen virhe" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Virheellisiä parametreja" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Ei-tuettu toiminto" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "I/O-virhe" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Data vahingoittunut" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Muoto on virheellinen" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Virheellinen tiedostokahva" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "Tiedosto on liian suuri" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Levyllä ei ole jäljellä tilaa" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Tiedostojärjestelmästä voi vain lukea" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "Virheellinen URI" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Tiedosto ei ole auki" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Avaustapa on virheellinen" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Ei käyttöoikeutta" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "Liian monta tiedostoa avoinna" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Tiedoston loppu" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Ei ole hakemisto" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Toiminto käynnissä" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Toiminto keskeytetty" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Tiedosto on olemassa" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Silmukkamaisia linkkejä havaittu" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Toiminto ei ole sallittu" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "On hakemisto" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Ei tarpeeksi muistia" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Konetta ei löytynyt" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Koneen nimi ei kelpaa" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Koneella ei ole osoitetta" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Sisäänkirjautuminen epäonnistui" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Toiminto peruttu" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Hakemistossa toimintaa" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Hakemisto ei ole tyhjä" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "Liian monta linkkiä" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Tiedostojärjestelmästä voi vain lukea" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Eivät ole samassa tiedostojärjestelmässä" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Nimi on liian pitkä" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Palvelu ei saatavilla" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Pyyntö vanhentaa palvelun datan" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Protokollavirhe" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "Pääselainta ei löytynyt" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "Oletusarvoista toimintoa ei ole kytketty" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "URL-tyypille ei ole käsittelintä" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "Komentorivin jäsennysvirhe" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "Komennon käynnistysvirhe" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Tuntematon virhe" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 tavu" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u tavua" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f Mt" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f Gt" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (virheellistä Unicodea)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "Tuntematon GnomeVFSSeekPosition %d" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "Ei löytänyt kelvollista asetustiedostoa paikasta %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "Käytä ympäristömuuttujaa %s määrittääksesi toisen paikan.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "Sovellukset" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "Kortit" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "Tiedostot" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "Hakemistot" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "Ohje" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "Isäntäkoneet" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "Linkit" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "Posti" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "Työkalut" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "Ikkunat" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Standardimoniker-tehdas" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "tiedosto-MonikerExtender" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "yleinen Gnome VFS -moniker" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "yleinen tiedostomoniker" diff --git a/po/fr.gmo b/po/fr.gmo new file mode 100644 index 0000000000000000000000000000000000000000..215359e630c534f71c87ce2c40973e0e8ca60eb9 GIT binary patch literal 5220 zcma)z$B4+szsRP?1t0SQzP4{?f+C>02his(UHBwpa5>Jt)Alt%;tAtc22&(66x3W!z4 z-A! zzW`<3pTKv)U%^M=AEB&&4~vLicSD-g6qIo@P|m#qMIRZw4}Jzd48H>9T(<&Wh7VBx zec^IJzX&hB0X;w&e?N<10yPmh6?hzefcDdH0vgzW&q72}KY}vv z=TOf18>r!Ha2oy-ei$C6b3ZJg*#DbQ^zvgk34aGgK2frqcQ>R-O~CiVX?PHR6p9|d z3}yT`pve9G(Ef|SS3~>jP~`p>d=Nf>Q_1`TQ2gNuDEnLtdUsW1|BF!8dku;le+#^qP34@A1RjB+ zkB>kZ_X#NTUEtTC?DI1y^ZpFQk7cl&XAhM9_d^ZOK~$j(6uneX)_*qCzXPvOe;JA% zcF`&KeIJzbUVylb*BPSw?{uK}5!?Iy4?s;}8Luy(j>sQAxp${1$0_oOedRkzIY<$| zc_T$WIoquNRqI)Pia#Bth#a?n@1sG^E1&3N%Kt*{K)KuUiR|(v zA8SR2`zYe$Cn$#~k5fKGIZK(N$S1xn@m1~wAyR#i!qrlbQT9^$pWGesf5P|R6Z?oS zie0(R>TZhY`Y`1TMLw~y*keX2^69;4z7b_Vl5fqaun+Q@F|7yK}2Mrd+p)&ZCaGW4BGJ%=Eh}y|!5zr=~pB={Ppd z>BQuzNz|Dr(XEuh>rtL$MxBlF+?F~nOjH`(O}j?7Y@uz}bVdByjn|iHsnVYju9ep6wY06~ zY|-I}GS;77oj18D(pVcgfx2K_i3LP&I!clP1J!L};gMN>+;GGBgO|es^En#Lqij$O zj<-Co=7SR=4U36Ksd=X(o%B_u7Hm7kfDw`@yfOrmGe7I;L^i9ff~ z*U~K0YeuK-oZe(oU6KQf)S1oO>XOCJT2Ymi8fO+aiJY@>if<*-Sxe84+WQLcYpcr( z+QsXpV`PZyMzPVEX_cDkiP=bFX=lL^38ZdvTea7@8Xe5XOypOw09IvA; zi!*n)kRzIwu*UJtdo`^!F}e&s4I2V%N1>4&}fZ2eWk>w zqax9ZHczi|^I8}~l(d4K@b}Hy*u$z71&PL-TFtNK_8NCTw;l83+?6ZFTwSs*^~M}e z2K}`q`=g(>Yx=5O_3>&j!gh7JNjULMuIhGefr2Em)QVTD4$r|}qKj zsfdAB;S45DTbthYtrlKMe`aGJfhNb4H*yei_IhdZgz(Z1H_c0+5dqVCH4J+Ew0AQV zdhfDH=Ir$eeUf|Dve!@5h*5zlCT-DvVr(JG+f~#y%@q@MX7u?>mltRC97>AUwKVCI zUXWICsw|?UitAa6^NX`XQKu#kjS<+<9S6c(GrBa_%Y)sF%yhzMCF1Vmt1ENO>ESpz zIM!&+5-k#f$Bdp{OUp4bV90zpWL^ipK@zkf2?j30K^9EKt_kiP`y|-A$;Feb*w1yj z@yXH;>k>8nP3{Ofy)DU%gRJ;JM*1Adij}tHS)%z={X-ID@21m*X;rSbrOp`_7b$6| zDrARNN~+)vrN~-HvQhJ$u5~UI7o|TgdRuf?#GZ=4*tJZv)kcvPdYC`8PjU;x)nwwf zbo$B*at~hlsm>b_LDy*n>uu?>U@hq9Z{OH=u`|cWqm8tUTe5X0>V2;)%(g=|A~MA$ zp`%{roXvC2j2itOMQTL^$!@izoQ;NdhG)58M5OoI`Fq)W-lyK>-WFH6w4@aj8CP9& zH`?Z1AWbBLN*wPiQgW>vG^)tML|%XA>CPno`)q9bY1$Uv)LH-hvI@g8l25Jr{`e8a z`b;f**0RVUf)2N}p;gX4XktiLw+o9B`iZ;mzy0&Jds}F&NQua5p|Re3iRV(^R!JlB zIb0GIZrSf0+yQl=9zJrIpoOF{d+=Prdk1ylyM(a>iD1?XDS@NPHb{#-!L?EwF4<`PB*Pm+3S zu1@#jBqV$!^y=~n|8x~s7$YQm9t+}BJOD`7KJm*2VNAVvUDLRh1k*ec@9}qrr0>&3 z(%?Oyma@v*o;W10fpm>w4zEE7{EX|l-nYf2hGa;&F}LYrvA5On&gr7E@{%qwC@j+H z-QtlT?}Oe=ehl5y@$8|NG-?m2*mtONvOC+>?_b`@=;Uj~4oVqUAR9+c#(VD*vqP+e?!-bcJT9FGyhj+I@EyPkM0g~(I)PH$p z_+X2E2U?Ke>+6!DWZkm&ZC;H1aq`Bfdm3y@gb(9yS9o}ZhsFiz8`- zhe%$BrEypLro-&KLnIC0Wc;^6ys{2lX{&`xkiYzMqz*dUUnGeNPYpd1LhARGyiRz; K)U)m|O8p0Gdy^^v literal 0 HcmV?d00001 diff --git a/po/fr.po b/po/fr.po new file mode 100644 index 0000000..5a83b57 --- /dev/null +++ b/po/fr.po @@ -0,0 +1,410 @@ +# French translation of gnome-vfs. +# Copyright (C) 1999-2003 Free Software Foundation, Inc. +# Vincent Renardias , 1999-2000. +# maintainer: Christophe Merlet (RedFox) , 2000-2003. +# Sun G11n , 2002. +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs 2.3.1\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-05-17 18:48+0200\n" +"Last-Translator: Christophe Merlet (RedFox) \n" +"Language-Team: GNOME French Team \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d contient des caractères NUL." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d ne contient pas de nom de méthode." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d ne contient pas de nom de module." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Le fichier de configuration « %s » n'a pas été trouvé : %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Type d'op %u inconnu" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "Impossible de créer un tube pour ouvrir GIOChannel : %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Type de tâche inconnu %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Opération arrêtée" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Impossible d'analyser : %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Les autres erreurs d'analyse seront ignorées." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Aucune erreur" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Fichier non trouvé" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Erreur générique" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Erreur interne" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Paramètres non valides" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Opération non supportée" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "Erreur d'E/S" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Données détériorées" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Format non valide" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Descripteur de fichier incorrect" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "Fichier trop gros" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Plus de place libre sur le périphérique" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Système de fichiers en lecture seule" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "URI non valide" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Fichier non ouvert" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Mode d'ouverture non valide" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Accès refusé" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "Trop de fichiers ouverts" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Fin de fichier" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "N'est pas un répertoire" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Opération en cours" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Opération interrompue" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Le fichier existe" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Boucle de liens rencontrée" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Opération non permise" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "Est un répertoire" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Mémoire saturée" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Hôte non trouvé" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Nom d'hôte non valide" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "L'hôte n'a pas d'adresse" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "La connexion a échoué" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Opération annulée" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Répertoire occupé" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Répertoire non vide" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "Trop de liens" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Système de fichiers en lecture seule" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Pas sur le même système de fichiers" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Nom trop long" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Service non disponible" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Données de demande de service obsolètes" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Erreur de protocole" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "Impossible de trouver le navigateur maître" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "Aucune action par défaut associée" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "Aucun gestionnaire pour ce type d'URL" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "Error lors de l'analyse de la ligne de commande" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "Erreur au lancement de la commande" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Erreur inconnue" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 octet" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u octets" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f Ko" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f Mo" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f Go" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (Unicode non valide)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "GnomeVFSSeekPosition %d inconnue" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "Fichier de réglages valide introuvable à %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "" +"Utilisez la variable d'environnement %s pour spécifier un emplacement " +"différent.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Fabrique de Moniker standard" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "fichier MonikerExtended" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "moniker générique Gnome VFS" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "fichier moniker générique" diff --git a/po/ga.gmo b/po/ga.gmo new file mode 100644 index 0000000000000000000000000000000000000000..d31fb66ad9ca9d49be4bc25846489cb4a3fbe9f9 GIT binary patch literal 1264 zcmaKqId2m|6vqb$mkDP$rAR!1pb49-69UErlqi>0Ax@O5X5t<14%wZtX2$`S6i84} zQ6d^Dz5$}4;Ts^)AVeA@iijc|LW2LSoj4MLCyjr8Gw=A%oBeXC>ji_I#OlR*jdc#| z+8+GCo`OB#Gq4+c37!DofQP|%;4$z6cm({|_P>HI{s(vz`~@BY3ws$m4)%bq=VkB= zINat8co9AaUEX8RNA7d*Ed2NTTKztO=iz??U7z2etJ~ex($xz(|0?M8-2h#^NzlbF zf~Udzpo?pO7r-ZNz5*}7e+#<%e+D6gK}H^b04!h~#B%kVxjt?-&fIJuDesBY-1fKW z=HzDK?!RLb(uk_nrb$X$5^3Ew*_2EKS*>YRMr=x(l-vAtohLG6!N42|W3*v`vcf2y z?6`RVEiVKt$cR(8U7Ow0kyKRUC>*j1Pg~^^ts+*@?eq%z@6K_)P`VMtl!_Dz*@EC9 zX_Yjo<`ibl%!)MM_5RvjR%=Q>R5Y!0DpsZz7ll}x*O|0ZE4mW0?eo@6=8b-UF?d1f ztq7ALrc9B`^ww(``TfPh{M?c^ZUlGv-UPRzOoP5Z_0naFrz-^Dom_f*mdm%~ofm$}FB_B(1Ks{*G34T5n+7 z{n|u#k*uNykA$}*cv_~w$SkIjh>s?+6)+pjPIj(R?Dq@f8n30$vRQ|AD<0W_dcvi; zP1Ts2OxQcY;+$714d3#LonWW0CX6?!sydV^DpP4y+5)R=CdBcgGD)o1z#pCPG-l&E zjqyfi%S+=elYcu~G9(3+u@}Y(<`?s7%qF=pT!t|P17jUWD!XX}3l@S_hWm 2000. +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs 0.1\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2000-08-27 14:00+0000\n" +"Last-Translator: Alastair McKinstry \n" +"Language-Team: Irish \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=ISO-8859-1\n" +"Content-Transfer-Encoding: 8bit\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "" + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "" + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "" + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, fuzzy, c-format +msgid "Unknown op type %u" +msgstr "Job ID gan aithne: %d" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, fuzzy, c-format +msgid "Unknown job kind %u" +msgstr "Job ID gan aithne: %d" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "" + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Gan earraidh" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Earraidh intíre" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "Earraidh I/A" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Formóid neamh-dhleathach" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "Comhad ró-mhór" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Corás chomad leámh-amhain" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "IRI neamh" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Níl aon filltéan ann" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "Is fillteán ann" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Cuimhne úsáidte" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Teip ar logann" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Níl an fillteán folamh" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Corás chomad leámh-amhain" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Ainm ró-fhada" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +#, fuzzy +msgid "Protocol error" +msgstr "Gan earraidh" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Earraidh gan aithne" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, fuzzy, c-format +msgid "%.1f K" +msgstr "%.1fK" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, fuzzy, c-format +msgid "%.1f MB" +msgstr "%.1fM" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, fuzzy, c-format +msgid "%.1f GB" +msgstr "%.1fG" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr "" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "GnomeVFSSeekPosition %d gan aithne" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "" + +#, fuzzy +#~ msgid "directory information file" +#~ msgstr "Níl an fillteán folamh" + +#, fuzzy +#~ msgid "unknown type" +#~ msgstr "Job ID gan aithne: %d" + +#~ msgid "Error reading: %s" +#~ msgstr "Earraidh ag leámh: %s" + +#~ msgid "Error writing: %s" +#~ msgstr "Earraidh ag scríobh: %s" + +#~ msgid "Cannot write: %s" +#~ msgstr "Teip ag scríobh: %s" + +#~ msgid "Usage: %s []\n" +#~ msgstr "Úsáid: %s < [ior_fd]\n" + +#, fuzzy +#~ msgid "Go to the parent directory" +#~ msgstr "Níl aon filltéan ann" + +#, fuzzy +#~ msgid "Go to the home directory" +#~ msgstr "Níl aon filltéan ann" + +#~ msgid "ftpfs: abort error: %s" +#~ msgstr "ftpfs: earraidh `abort: %s" + +#~ msgid "ftpfs: abort failed" +#~ msgstr "ftpfs: teip ar `abort'" + +#~ msgid "ftpfs: storing file %d (%d)" +#~ msgstr "ftpfs: ag sábháil comhad %d (%d)" + +#~ msgid "ftpfs: CWD failed." +#~ msgstr "ftpfs: Teip ar CWD." diff --git a/po/gl.gmo b/po/gl.gmo new file mode 100644 index 0000000000000000000000000000000000000000..659d251288a3e61237bd9ee0a0b2f09bca0330d9 GIT binary patch literal 4749 zcma);ON<;x8Gs9t5ZI6hAqfFOD3WZPhiAQOlf>RU*Y?`k#4l`b0vr%E-8Hji_f$=~ zde&YG1Sl7X1c3u00S;J55DN~m5(z0B5Sl|yIe{V}L@pKxM8t{50Y&ir)jf~3%wx3G z-&S=!{#X5fzjgiP-&XvVXt&Vrc(+oYfm<)FT?l2=bQeEQ1*WbUJqYw#$SiB@0;+$@B+L8 zz60gl+fY{Yo#*i(xC@G&pMoEN27VMqC~`dC@Q3h5`af&<29)&|psf2R6gjU(NSSv_ z!|hPhf4u2Ccr*PkL7D#olyiOzKMsEmMb6(g<9~vp-#bwDy>6!V{hjaz`fE`1{9@Dp z4xE3NQa^>LtbT`)aDnXaL&iO062i}0OgpWd0P$!_wk5KG#21?vK2Oojw;12jl zDDig-!ixU8-~;eUcoTfK;di0za~_Jkzijv>6utip#UB4^`Zr?~vCCE-;)e&Jobxo4 zc@;!-^>v5{>P5&>^`qwft5D+U4JdNF1vUH|oP#$ZjL5MJF{%126#epM{8=b|eF5GD zUxsr2Z<_aihqCWg93t~>gCf@=6gwPiXyNVjPc{4=l=FW9W&U5_$KaJL5_x8!oU;fe zUY~~isW0&O1pEfP4ZaLz{jcB?@a?Am06`*p9D%ZLfP_J^B}jXVUmv19Oxr>ezc0`v ze(t4B{~o0CNgC-P{qE*DOWRp@)AK%_V*AHZZ}X!?cPmYNByoqBDSklm&;9aG^OLx{ zj3)BSPt!2-_$PK2TTcHZHpG7ta}r156VZDYO@3lSxi|APv6rMriQ8?o8JhS);z;ho z5>0;FY2tJFEz-p9chWvW6CcU_Bi$xH0QIOmX6F_l|8J`zc?J?emN@t}tmDPRMx4IKb9s1Vm{VRv}FwNUyQO`!TC-{!*4oXwG;Ok93 zKO48`QzmNJqZ0-`Z)Oe(q-Csc%4pNrUQ-!VF3Ul`LXN#I_gh%we6EdNH-*b}v{mJN zH`aTbibH3ZSlX-#<%Vt#;>J{0wzs{0wV{^TBXrU#wNG@jr(LXK{r_09NmrDsdsPU! z?Ye4TD0`eIbCW1)zxB3snYLvaO7(b%6$TSEwaN1md)8y(kf~K^-sHfQZHJo;Ry>~d zrWki?g;$TRs1;xTkEPg50zj=qOp=fERtG}YVQ+(GIi1kQM!InRWYpGY7@bADIT%VD zh`r@?k~`{Ct|)ZdYS;C=&F9o15m>Y?g72zBp%I9GV&7y|7q(Mryqnu~msuuMn?#Ym z^9IxIod3;DE(7;6G3Gd{D0=rkEa&wd%Y$-vX2 zXxPNfWK`_TW<6I)JWa-975aTfj+CJaSs2;;s3r1)FE%!bD5I@Qj6O54xIDCDDDX)n zG)pna7VZ&otd7;)8{P@bGe{M!4CpSti zpRTOWZK=A=l}Q?CRKWGg4C6Ox*=P{=oZw=&R`S+U1U)HbQ4^&-+gk6$nIngfxAsU* zV!TD_Act(9pWo4%-`U!JpI+FpxUloyc}AGnI!dg{`pLZQt@-;~^9y?6{>6m{>UjrD ztXjuQ<6~jSCX4zB8;7q&y}LB)K@Y!DpuRn$ABuw*9;-?deVFsMdSvE+@!f&x+SYMv zdW(8LnJRO}>xT%`(~_As%|5ttaCxH7!rc4}SrY?sHa=O@l|5Z;>ldW`2UE%?|Z?VP*3sCTwqHS@n~$?%-lSyM#_SwASkxR`kEsMH&o_inoER;ki<} zFS$WVPpJofjq+f~k?xGi9MdG18Ex97EA>T{s9BC9`(dEN-!W_lVj%f;aO@Iy7^7z%26pK zYv@5t_Gq#>!(!jIDa0TYAxX94z189IzxuSP%a~wYgKb+@Q)69Xh;8}n z4bM6XVJdI+(T%)nnaZY5TR%KUoeOG7ram)p-XsADSv2BW+cV;=QJ_rC811v!7iPRo zeE=dXZ#!21?@|#AimIobAFV%P%HdfGUx@=m!Dc+F;nxU?aT#=>-URu~KrWQa>M&7D zSY&vXEJi>Tu4~Q^JNVL-*`VM~M~upoq=qb#J>^pf?~B`5fs2M`eO(~2D;K8Gwr8Sa zAQj3$!p9!6I0eR8=1jsOQrnS4#3qSXe1T0{sxEzXwAVG&+4B(<6HdLx5oi$_W>~2$baMHAWqG{p8kEn`^zN_B2w$(|1k%N*oi( zcx5GSSdC;&`EqWmwnRs-?YJ4KvZv(9mjPyIlB?A3Npj6yUDj, 1999-2002. +# +# Proxecto Trasno - Adaptación do software libre á lingua galega: Se desexas +# colaborar connosco, podes atopar máis información en http://www.trasno.net +# +# First Version: 1999-12-29 16:22+0100 +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2002-06-01 16:17+0200\n" +"Last-Translator: Jesús Bravo Álvarez \n" +"Language-Team: Galician \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d contén caracteres nulos." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d non contén ningún nome de método." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d non contén ningún nome de módulo." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Non se atopou o ficheiro de configuración `%s': %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Tipo de operación descoñecida %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "Non se pode crear unha canalización para abrir GIOChannel: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Clase de traballo %u descoñecida" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Operación parada" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Non foi posible analizar: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "O resto de erros de análise serán ignorados." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Sen erros" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Ficheiro non atopado" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Erro xenérico" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Erro interno" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Parámetros non válidos" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Operación non soportada" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "Erro de E/S" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Datos corrompidos" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Formato non válido" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Descritor de ficheiro erróneo" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "Ficheiro grande de máis" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Non hai espacio no dispositivo" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Sistema de ficheiros de só lectura" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "URI inválido" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Ficheiro non aberto" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Modo de apertura non válido" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Acceso denegado" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "Demasiados ficheiros abertos" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Fin de ficheiro" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Non é un directorio" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Operación en progreso" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Operación interrompida" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "O ficheiro xa existe" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Atopáronse ligazóns circulares" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Operación non permitida" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "É un directorio" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Non hai memoria dabondo" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Non se atopou a máquina" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Nome de máquina non válido" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "A máquina non ten enderezo" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Erro na autenticación" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Operación cancelada" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Directorio a ser usado" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Directorio non baleiro" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "Demasiadas ligazóns" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Sistema de ficheiros de só lectura" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Non están no mesmo sistema de ficheiros" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Nome demasiado longo" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Servicio non dispoñible" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "A petición fai obsoletos os datos do servicio" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Erro do protocolo" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +#, fuzzy +msgid "Could not find master browser" +msgstr "Non foi posible analizar: %s" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Erro descoñecido" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 byte" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u bytes" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr "" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "GnomeVFSSeekPosition %d descoñecido" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "Non se atopou un ficheiro de propiedades válido en %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "" +"Usar a variable de ambiente %s para indicar unha localización diferente.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +#, fuzzy +msgid "Files" +msgstr "O ficheiro xa existe" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Fábrica de Moniker estándar" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "ficheiro MonikerExtender" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "moniker xenérico de Gnome VFS" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "moniker xenérico de ficheiro" diff --git a/po/gnome-vfs-2.0.pot b/po/gnome-vfs-2.0.pot new file mode 100644 index 0000000..8cde76b --- /dev/null +++ b/po/gnome-vfs-2.0.pot @@ -0,0 +1,408 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "" + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "" + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "" + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "" + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr "" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "" diff --git a/po/he.gmo b/po/he.gmo new file mode 100644 index 0000000000000000000000000000000000000000..b3696a2c9db1624b2d3a9bc7f5c540175a290246 GIT binary patch literal 5868 zcmb7`TWlOx8OIMLKry}0aA`|vIg}bFZP&45T3k0RxjD8;oLJ7KMMA)Mcf6i>cV?NH zb?UbYA)czrj%`xcu1QTu97{YPgeZavsX|<&(uYcDB?MHWMF>$4f(In15WoMK+4Z{Q zg-MQobI$qB`L5^8{%+@vCBrjD`zUSoI%B5w{x1IT{QTXH?_*E$R??Kt|6DT`gh0^;PM1}bSd_VjPl-z&d4tT?RGd;KD z?1b9yA*l7kkpJd*KK?kAJ!Po4CHeT*pyZdJ^sm6%;RckRm*73{XHfdzgv!UiAf}jG zJ2H6-<>vrY9LM1;a01=|Q>eJi<-7zxME`}HuRyJT18Ut{Q2yM6(UQ9}XCJimNAmtz zcpLpEq2!mL^lU)+^&|K(_!5-;zt89Y1{H@LIIaC}g$G~(D((^dAUp>ZkEinfW%&7b z81qA@eQ!gl#VHz6=$=*P+(E1qr>moyE9l z?tzl)g|c@TD(_!_k}pG@i?2e-twXK*0o1-fh05z|Q2zZBTDX(o%Z@%MKZl^~KLb^7 zH7Gqx@Ikl+wg0bR4}24{mAR8mcEdgJlkjs;<4;1J_w!J8eg`UFuR!VfYtHLQvif&J z#c3aupI?Nk+d5R-=5xLXd+GlPYTr8$*7|;E;W(5%36%ZMLDj)!DF0uE((}i>-+@ya z?}VdpKUDmlhSI;1&wn3E&#RE~Gy7?hQ|$G~me07i?2qm^Jr87XdmrRoXF`u+)qL2} z+5T`oAiI@=NAkY>)gwC!pAI8i z_0y@SWJ9m&UvoMt)hm8J-D@XiQ{NmY7X2i#B|i-Ok~vVTRf3|I22q%pgI>u_1}vEJ z!cxUIhrBS1Qd^9DFZFFLsQGp>ifvT$LpwBb;t*n?Um38S38Ha{zfm|Dlow8imq&rBX~9voWQ=ZK;#nvO(R%jO;m)?==z< z>d>pSx_NDmkC>6XPH~ehRdi+~v7Rk8V`z>A;dEk-Mdcv0lOB$j=tMQegjh@`)(?v$ znWfB(B49?NnA*wX=DbPlxu8<96TS_~A+x1!b6g%MGLAsv#tUrCn-?oD^Yg$b$6J@ zP|59MT*`Bo2cJm&kn?HE`Dt{XSX`kHTu@pwZdr4XWS!;GDU6f~XE;Pu@PMV%tA1f- zGU*;3JaD*s%I_FEajI}gcPsM+t~c(vy*)jBg`WPx-Un=N-#~BweLajISQw{*wa+%W z2Mc?9ZEx>DPtScleaIc-7A>5Ly)dbGWNN?;1r^(MII3{RcG(lj6iM7ya^3xLt=t{O z?7mps#E+alb)?Y0B`33pdSQ?YqQreMVEZS6v}4>?E(@bcIVcql*2_uZ zR5V~a9xu2HFmvPRL2tsZSk!j+b{M;>vD{c{T;%T+xL_NrjXB%cq{rB9Gj!1E^JP8*_~djRn(KY@DZmwXtZia)B`>4SzJYgi$Cr;Oht?BFE+%-;&bvye^wenS9=C zd_$_28<&~buwa=T-RlY)FKhCWbMAtD+eaGDH*jIO@jMN6EiLFo&jPbcnB1jLc2nUR z3g+AgxH-}?K~qZ#{Q?TrFl+;V3Dp1Ed#SOGnHRF1*Jhqy~pi(D~g+FOCW;*4t#b-SZ7v?b~$^2BYMP-3Vk>xzT~D{u2I z?d-dW0x2PHDxY~`j2CXN{6K88eT6C24#Mly+J?+sW!)UF7gVduO5%zupLt2S%3s`) zXzh%k6y^)JdzBBf85TApN0hFh>zO@-3T#ba?|WQ_v9Mg=REoXD0j zTJ4lA5(w(2E&GaAcE;QyMRt?ZH_slbbri2);;I61(N!3Mo~KX5an2dNZMkxR)7d_% z6CHWP)>@9bZdOG)mxOhZ9p@y*t>6Nxs4X>~ZA+KYY zRSw#sq};1O*0VF%HY2kyN~3bMK?+=*wFz8g(Pd`Z4mv5#j`=gJQGkef%Nvz)egsv8 zS6JG*99Eg(zW@JZ=h@?`a-xqC)oh)Su0+|H+{p3^sM7824wdS`Ra)lUl2V}qL>lyI z*x(#Df49-m<%I+8p2%{p3m7$TI~>;%XgQi+PV9mOx=HkM&EIy+QDIWC#4XP+z1HC% z3GH)=xbEZgs=j$%xNNse=qFz;!jHghi``UP7W1;+Bo40P7SXB>ft?rVxGK=sK_6%C zdi`ERIR9+wQ|eBY0+}BQeZDvNdFZ0A+z@nSm-|v%D1zCiI*)c1koKR5Qs8b~T}7E} M{yR~h%Pceh1ym%HZU6uP literal 0 HcmV?d00001 diff --git a/po/he.po b/po/he.po new file mode 100644 index 0000000..7293eba --- /dev/null +++ b/po/he.po @@ -0,0 +1,411 @@ +# translation of gnome-vfs.HEAD.he.po to Hebrew +# translation of gnome-vfs.gnome-2-0.he.po to Hebrew +# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# Gil Osher , 2002 +# Gil 'Dolfin' Osher , 2003 +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs.HEAD.he\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-06-21 11:00+0300\n" +"Last-Translator: Gil 'Dolfin' Osher \n" +"Language-Team: Hebrew \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Report-Msgid-Bugs-To: \n" +"X-Generator: KBabel 1.0.1\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d מכיל תווים ריקים." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d לא מכיל שם שיטה." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s: %d לא מכיל שם מודול." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "קובץ ההגדרות '%s' לא נמצא: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "סוג op לא ידוע %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "לא ניתן ליצור צינור כדי לפתוח GIOChannel: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "סוג עבודה לא ידוע %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "פעולה נעצרה" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "לא ניתן לפענח: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "התעלמות משגיאות הפענוח הבאות." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "אין שגיאה" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "קובץ לא נמצא" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "שגיאה כללית" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "שגיאה פנימית" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "פרמטרים לא תקניים" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "פעולה לא נתמכת" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "שגיאת קלט/פלט" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "מידע פגום" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "מבנה לא תקני" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "מזהה קובץ שגוי" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "הקובץ גדול מידי" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "לא נותר מקום על ההתקן" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "מערכת קבצים לקריאה בלבד" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "כתובת לא תקנית" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "הקובץ לא פתוח" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "מצב פתיחה לא תקין" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "הגישה נדחית" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "יותר מידי קבצים פתוחים" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "סוף הקובץ" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "לא ספרייה" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "הפעולה בתהליך" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "הפעולה הופרעה" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "הקובץ קיים" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "נתקל בלולאת קישורים" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "הפעולה אינה מורשית" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "הוא ספרייה" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "אין מספיק זיכרון" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "מארח לא נמצא" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "שם המארח לא תקין" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "למארח אין כתובת" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "התחברות נכשלה" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "הפעולה התבטלה" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "הספרייה עסוקה" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "הספרייה לא ריקה" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "יותר מידי קישורים" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "מערכת קבצים לקריאה בלבד" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "לא באותה המערכת" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "שם ארוך מידי" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "שירות אינו זמין" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "מבקש נתוני שירותים מוחלטים" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "שגיאת פרוטוקול" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "לא ניתן למצוא דפדפן ראשי" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "לא שוייכה פעולה ברירת מחדל" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "אין מזהה לסכימת הכתובת" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "שגיאה בפרוק שורת הפקודה" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "שגיאה בהפעלת פקודה" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "שגיאה לא ידועה" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "בית אחד" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, fuzzy, c-format +msgid "%u bytes" +msgstr "בית אחד" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "KB %.1f" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "MB %.1f" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "GB %.1f" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (יוניקוד לא תקני)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "GnomeVFSSeekPosition לא ידוע %d" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "לא נמצא קובץ הגדרות תקני ב %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "השתמש במשתנה הסביבה %s כדי לציין מיקום אחר.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "יישומים" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "כרטיסים" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "קבצים" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "תיקיות" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "עזרה" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "מארחים" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "קישורים" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "דואר" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "כלים" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "חלונות" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "יצרן Moniker רגיל" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "מרחיב קובץ Moniker" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "Gnome VFS moniker כללי" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "קובץ moniker רגיל" diff --git a/po/hi.gmo b/po/hi.gmo new file mode 100644 index 0000000000000000000000000000000000000000..39522031571da58aa91134b1626f6a731e19b634 GIT binary patch literal 8315 zcmbW5TaX-88OIxesEeQ=-nhsST@x;|*-e0~3xr(AWzCh`6ttAynV#KFX1a&&nI!w5 zwZsBqA%#^Cuz)fKW(kInV5$O%Qt(76QpFR6rKQpoQf29bmipj>W%>J`)3YbD z=|8{6<>gWkQ@ue@>z9J^^BbVzn1UCA-vciN_kptaXF0wKev0vLbNm~q{pVt&_FWFj zpZTEHEzWTZXc%wL$M=JuWqbhC`k#Z+^BO3>{s3M9z6;9!vvE@IF9a2bUQqG}!KL7O zkQ94A1TO}E1j@hX^6@XhJJ0gG--C+F%_#jMIFjSNIUWL6F#iU)4ZN73d>h;WO5f`s zue^7_1pGVr1+Yl6zXjd{-VOc*z!Y2vJ_{nkdmB`I|B=t1hw;6PZvpi_03QH%gW5mm z)2?0?gSh04f!FIjsC`F3T=L!ouLa)&rSBq=uk|ZI*}DzA2HXikJ?}~IJK$mP2JmW( zS`PYPKR5|0-fw|-fR~Z91>i357Vr>wEBF`iI&eP4_*Jk3&IgZzTfn!$VemRgI|P0g z8~{&(()-sOucSFCAGd>F0e=eK2)+wS?iDl(Qeak>-Xs@L?iVwO-t<^2Pm}BD$OkI+vSnHDQq`>w# zLTj%j{3=F@e;@Zs?#0}+Vtd`huYA;{9-%&Qph(McOT&^sM+Q_qyge@Cu;vdL=hhwK<;) zibJYHT~OR!%7?DoxW$2Uxm6>&=5VX-#VO^Jbb9N#X}E;TAa>vhA7jMszI8?fjtEf#|`HKia5gOazjR;z?XzaGX> z>Miq2rW~?!%#TWyz+3J|QCv60B=GBjsfD$`l;gz2wIDL9hBqu{Srk-;OmE84q{MF= zmBZ0SV&yqeclM@p%`QJRl2ncxQOT{38xv1w}MjGjO$56_HYOOx* zt-yk~YI?V)1kM)f#0 zBjKnWus*JoNHUmIF<3jTFW#yk3X-sB0@>rO4k|Tob)42ojY4VsQYj&gZcaSt*lO3c zZO}0FhUag{WerD!I`S)1!hP~mOu(*jxvCkV$jc-b=7eDcBhn zHIKj!XEY9?xG_3LMOC4QUBUYLSYT3_WUC<^hn!V!gJ@r+jypolTu%0)9~Fa&;?bTX zMztg!wTbGSB|15a+q23S!m43iPPXUMdR(h9voVS5aWQUXZBsz4#!+Q_nu(e%beX-Y z5kQ@IB#kR%H8s?j0y392Kvj90-O&2w?<8sd2-Uy24(};zvo4Op9aLwTWGF~m$P+a& z?lRsU#tM)kmTIn&dRwC%QM`*@5yjPD+se(GgJ8$TI1Oz|drMRAT|Qf@x5p!9hnhlf zV`@cQGxc%WkDW>zwOX7ICUqhges60Ef5=*|7`QV`;;0%#s-+~9GjIz^1jVpCZW&N6 zLr~sVV%Pindc3cplJ4W#l;eCy|tI>L5a0MdRpiI57+gg((YdcM+FkC8Z zqljSekb&yeps=%?_H5j+rLbH*mH7f~jsCWvzkgw&f3UFNdNZ(aXkhS~er8x$*aUO6 zf5y80MP^{p(83$8>A!wqf6rRFXJJd?M`^_;LqlejS>q>-$lu{7<|cmJX2DY1VVEYzm#%gcY*#_3JccmB^7nIzBFzm#eg$lH0XEk2E^;&0DvuEDW~S$!xMwSV7|` z(MN{N;7C~SvEsj8ux-#ewPu+=5>$+oc=NL6Jz4X3Hn}%z9yD3=Xg0YgYd(`TU&)&L zvdR0i=7IdQ&6{6YO|tP+a#F)7 zRl*dvY>z#~tudJRyxodn=-kiHE&D;%e8SrOG~<)_;=$e-Qd;ipWyx`CkTz{019lg>7Kkq?a|npEVEJRFR%Xor<=hE(1rg zg*Q()IAIghWN;&shpdIqcS>LZX@8E;%oJz+wj_Bbo4kAWW}A>bUe{+RI{6>RAsE>7*PG3z5(HsqZ|iS#PXwm6=iwEQQBPcm@MKj^idoXu>-MwWa)%C!8) zXZ*)3r4O?RE?iSc7~_=;A_6({Y}zP8YeUQAtm(>ca&Kn44JJ94DHnJETW5sr)Di3P zXiZi<3SHFOZ9y!tT@70C+67cOw^qIHMwm#XoVZy`$whSJ)@H@|;dtM~wtKVY(>6vg zpw=Y>cFMh0UsEYK-m9+YqZ3`Wk*?ehY?_jkCzLT6z*ipgO zg4s+@xDME+t2d3>Gjc?sl1j_!>HWw0H_Zx89v1>~grf>I&5x|U|<(TdeUe6 z>)G~-5;!mZ&bOS0SagVd3e{Z#No6S6mbfaj?yEY!O1AO`)r`*+6zsJEzM1_C-8PJd)(n+3$Cf=&iLhQ5<6&W^g5L;184w;kJNvk|12}zH1LK1>sB~RV{jE=;VPE=xaor0FXig zT%Y046#3K;fTyh_T-Kbv0x-w3t8-4Ub*lE-mf$ntq^R@}!p_`$M?v|BBUt!sHc6tX zaaO9nc+Zogdae_@#G;upMB|x`F_o`&&RM1UE7S%A*%OY&d3m*sVIhejTv&zW@_UwA zXYg?w0T!QN4dI@CAh`;jv}=^+F5PjqfmZA3Xw_|tRNGi7O14gjn;L@aRs51*Rw!=W z_R9nJ77`+Wu|9tsZ}LXuf|WbjO~_P-7KNP313VqiCilY1Q)qT48!7IdYe-@FD;~(7 zDH>W=s30XiXVd9KJ!aj4SySKKttfR@EixdPV{C#?LY`b8wVN;!%$zhcK1|+Ms1jhS zYw~W%gtJW@zum%lI(Kp#*h!H}X7@1b8XX6T4xrD=ePm$c=?dECO>CS%ZC4d z8}7Qq;v-aZsecjWR2A&o&o2X}<(m5f%9~d{*Ws?g3>Zo{DMq9obeqqx)|_zc(Q#o1 z>dbuiOxP5wo@q+(*V*X)Dpet&H8;DJN12Qv>Sl<*42+S~cK>Gpjb{H9BDV z8$14fafLwR^6YWoy7Ti4Fo!dQ3i`1Puj+^Z;v~d4qW>(>|NAiM3VqUAZi&f%0d?Ko zg+N_&s6;HY(0ml}9fY8Lx6oOAF;QdVU{s&+_A+rDg literal 0 HcmV?d00001 diff --git a/po/hi.po b/po/hi.po new file mode 100644 index 0000000..999079d --- /dev/null +++ b/po/hi.po @@ -0,0 +1,478 @@ +# translation of gnome-vfs.hi.po to Hindi +# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# G Karunakar , 2003 +# +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-08-07 17:36+0530\n" +"Last-Translator: G Karunakar \n" +"Language-Team: Hindi \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"net>\n" +"X-Generator: KBabel 1.0\n" + +# libgnomevfs/gnome-vfs-configuration.c:223 +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s : %d में NUL कैरेक्टर मौजूद है" + +# libgnomevfs/gnome-vfs-configuration.c:240 +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s : %d में कोई विधि नाम मौजूद नहीं है" + +# libgnomevfs/gnome-vfs-configuration.c:269 +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s : %d में कोई माड्यूल नाम मौजूद नहीं है" + +# libgnomevfs/gnome-vfs-configuration.c:322 +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "कानफिगरेशन फाइल '%s' नहीं मिली : %s" + +# libgnomevfs/gnome-vfs-job.c:714 +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "अज्ञात कारक प्रकार %u" + +# libgnomevfs/gnome-vfs-job.c:1005 libgnomevfs/gnome-vfs-job.c:1150 +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "खुली GIO चैनल के लिए पाइप निर्मित नहीं किया जा सका : %s" + +# libgnomevfs/gnome-vfs-job.c:1596 +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "अज्ञात कार्य प्रकार %u" + +# libgnomevfs/gnome-vfs-job.c:1632 +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "प्रक्रिया रोक दी गई है" + +# libgnomevfs/gnome-vfs-parse-ls.c:652 +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "पार्सिंग नहीं किया जा सकता : %s" + +# libgnomevfs/gnome-vfs-parse-ls.c:654 +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "और अधिक पारसिंग त्रुटियों को अनदेखा कर दिया जाए" + +# libgnomevfs/gnome-vfs-result.c:35 +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "कोई त्रुटि नहीं है" + +# libgnomevfs/gnome-vfs-result.c:36 +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "फाइल नहीं मिली" + +# libgnomevfs/gnome-vfs-result.c:37 +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "साधारण त्रुटि" + +# libgnomevfs/gnome-vfs-result.c:38 +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "आंतरिक त्रुटि" + +# libgnomevfs/gnome-vfs-result.c:39 +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "अवैध पैरामीटर से" + +# libgnomevfs/gnome-vfs-result.c:40 +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "प्रक्रिया समर्थित नही" + +# "प्रक्रिया परिभाषित नहीं है"; प्रक्रिया करना संभव नहीं; यह प्रक्रिया नहीं की जा सकती" +# libgnomevfs/gnome-vfs-result.c:41 +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "इनपुट/आउटपुट त्रुटि" + +# libgnomevfs/gnome-vfs-result.c:42 +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "डाटा बेकार हो गया है" + +# libgnomevfs/gnome-vfs-result.c:43 +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "फार्मेट वैध नहीं है" + +# libgnomevfs/gnome-vfs-result.c:44 +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "फाइल प्रयोगकर्ता प्रोग्राम खराब है" + +# libgnomevfs/gnome-vfs-result.c:45 +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "फाइल अत्यंत बड़ी है" + +# libgnomevfs/gnome-vfs-result.c:46 +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "डिवाइस पर कोई स्थान उपलब्ध नहीं है" + +# libgnomevfs/gnome-vfs-result.c:47 +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "रीड ओनली फाइल सिस्टम" + +# libgnomevfs/gnome-vfs-result.c:48 +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "अवैध URI" + +# libgnomevfs/gnome-vfs-result.c:49 +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "फाइल नहीं खोली जा सकी" + +# libgnomevfs/gnome-vfs-result.c:50 +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "खोलो मोड वैध नहीं है" + +# libgnomevfs/gnome-vfs-result.c:51 +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "उपयोग नहीं किया जा सकता; प्रयोग संभव नहीं है" + +# libgnomevfs/gnome-vfs-result.c:52 +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "क्षमता से अधिक फाइलें खुली हैं" + +# libgnomevfs/gnome-vfs-result.c:53 +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "फाइल समाप्त" + +# libgnomevfs/gnome-vfs-result.c:54 +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "डायरेक्टरी नहीं है" + +# libgnomevfs/gnome-vfs-result.c:55 +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "प्रक्रिया चालू है" + +# libgnomevfs/gnome-vfs-result.c:56 +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "प्रक्रिया को बीच में रोका गया है" + +# libgnomevfs/gnome-vfs-result.c:57 +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "फाइल उपलब्ध है" + +# libgnomevfs/gnome-vfs-result.c:58 +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "लूप के जोड़ आए है" + +# libgnomevfs/gnome-vfs-result.c:59 +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "प्रक्रिया की अनुमति नहीं है" + +# libgnomevfs/gnome-vfs-result.c:60 +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "यह एक डायरेक्टरी है" + +# libgnomevfs/gnome-vfs-result.c:61 +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "पर्याप्त मेमोरी नहीं है" + +# libgnomevfs/gnome-vfs-result.c:62 +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "होस्ट नहीं मिला" + +# libgnomevfs/gnome-vfs-result.c:63 +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "होस्ट नाम वैध नहीं है" + +# libgnomevfs/gnome-vfs-result.c:64 +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "होस्ट का पता परिभाषित नहीं है; होस्ट का कोई पता नहीं है" + +# libgnomevfs/gnome-vfs-result.c:65 +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "लाॅगइन असफल" + +# libgnomevfs/gnome-vfs-result.c:66 +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "प्रक्रिया निरस्त कर दी गई है" + +# libgnomevfs/gnome-vfs-result.c:67 +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "डायरेक्टरी व्यस्त है" + +# libgnomevfs/gnome-vfs-result.c:68 +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "डायरेक्टरी रिक्त नहीं है" + +# libgnomevfs/gnome-vfs-result.c:69 +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "क्षमता से अधिक लिंक मौजूद है" + +# libgnomevfs/gnome-vfs-result.c:70 +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "रीड ओनली फाइल सिस्टम" + +# libgnomevfs/gnome-vfs-result.c:71 +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "इसी फाइल सिस्टम पर नहीं है" + +# libgnomevfs/gnome-vfs-result.c:72 +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "नाम अत्यधिक लम्बा है" + +# libgnomevfs/gnome-vfs-result.c:73 +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "सुविधा उपलब्ध नहीं है" + +# libgnomevfs/gnome-vfs-result.c:74 +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "निरपेक्ष डाटा की मांग की गई है " + +# libgnomevfs/gnome-vfs-result.c:75 +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "प्रोटोकाॅल त्रुटि" + +# libgnomevfs/gnome-vfs-parse-ls.c:652 +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "मास्टर ब्राउसर को नही ढूंढ पाए" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "कोइ डिफॉल्ट क्रिया नही है" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "URL सकीम का कोइ हेंडलर नही है" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "आदेश पंक्ति पार्स करने में त्रुटी" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "आदेश पालन में त्रुटी" + +# libgnomevfs/gnome-vfs-result.c:137 +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "अज्ञात त्रुटि" + +# libgnomevfs/gnome-vfs-utils.c:65 +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 बाइट" + +# libgnomevfs/gnome-vfs-utils.c:67 +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u बाइट्स" + +# libgnomevfs/gnome-vfs-utils.c:74 +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f किलोबाइट्स" + +# libgnomevfs/gnome-vfs-utils.c:78 +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f मेगाबाइट्स" + +# libgnomevfs/gnome-vfs-utils.c:82 +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f गीगाबाइट्स" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr "(अवैध यूनिकोड)" + +# modules/file-method.c:381 +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "अज्ञात गनोम VFSSeek स्थिति %d" + +# modules/test-method.c:590 +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "%s पर कोई वैध समायोजन फाइल नहीं मिली \n" + +# modules/test-method.c:592 +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "" +"किसी अन्य विशिष्ठ स्थान को बताने के लिए इनवाॅयरमेन्ट परिवर्तनांक %s का प्रयोग करें \n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "अनुप्रयोगें" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "कार्डस" + +# libgnomevfs/gnome-vfs-result.c:57 +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "फाइलें" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "फोल्डरें" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "सहायता" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "होस्ट" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "लिंकस" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "डाक" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "औजार" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "विंडोज" + +# monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "मानक माॅनीकर फैक्ट्री" + +# monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "फाइल माॅनीकर विस्तारक" + +# monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "सामान्य जीनोम VFS माॅनीकर " + +# monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "सामान्य फाइल माॅनीकर" diff --git a/po/hu.gmo b/po/hu.gmo new file mode 100644 index 0000000000000000000000000000000000000000..11ad25e460069705ac84f70442476b41ba7179c1 GIT binary patch literal 5532 zcma);Ym8h~9l(zQRg0jYsL1R1SlR-!-4?6cr4+X9w!5;sE$tQ(F_ANK&&=G;opXnK z?o2!5C&dtznAix>=%-bQ*=VDrkq-?a>PcUasq5ii;M?H8AwTt>vVH}Pw^F~l z^&%l1ALdAM*SI`qp; z5K+}Ml<~7r^n3)09X-4bJ`Qh!PeYOS*^(FG4b*>E@*hyZ|a*@EcI{ zJ6G0UgxlYu)E}Vidlj3?_*XQ&vj3Y<#(x{iI%`nm`xz9u zUWRk<5)?glVAP#(C#=BFK#9k%K#}wNP{#kHtZyM`-bei=i0W!LlziF`x4}msKlM0& zV)v(@tn&jX_Wvmqy?#~l_fYI`3G!2~@+b0N%V4qJ4N&^;gtG4(l>SdciIW->ITFZE zo#9XN;mZ)$t7o9-|05{tyioGDW&c0n4DGK%@!vE?nuLo`=6@DS-ai4wp3gu`r(S@f z*Dv5l;9sGP+rlCu=S0bUQ1mzfMXtDP{{j@bz6HhJYb9TVcT;}_ieGPJ6WMn!l<~)* ztp6w!`A$QLgU>@;q@IDY&yS(Zd%5J_;UVg8MHsRF5h!vU8|gFJgFBIgc@#DP5bQ$9wylOi@gOxaK2C=Sm){y$m1%NZg5 zl}GfsBfODk@Dt_xRLKKSd@J!Y{z#rIQ8Yz-B+pTb#Ix99o+37uM|^jL@^OmT2X}@? zY;srmJ^^=^@7qgO-~vT_Aokoz*+w}?kvNeD(}!nI$p@jtoaEo_Wt+sboQL;O?xl!N zmMP+6iEqMFO;hBNbB|+FEmC$-BrcTR9=o1N;z*x#aV?GP4mB~ktFDh681jK3mZbA|BX{4QL+t=+*qi$kH-CbSn=hmxTfoir^ zv)=2-y4Xf)w$n-Cn#tqTd3C@T_Hprqm{iGTb<9 zlQx}5S1s7FKSeOQJguc8uN}AKYU+~yCK08z@;a@L zbuFQjR(+b_RjN`riar^mFz!}6ZfRGUP@iuB0K9iLyWY7pU8>+ z(Bm7`R172*^U{`hb<(w5dYZGsrEUAr;S(pUZ5>N}99%jPt@jW8IU0Q`t?HH>3KQM+ z5ot%~eU6{d~5#kVX+EgY5M{>MW zEv-p$4q1lwFuGMdhwWQ-aPh2e+N5vE2)UhSrN{Mqs4T~LBQZ(7xlxoWp63izhl6d| zq+!*3Ts4?ZE-F{^n%tG`R=sJ-ZMmt_bDytkgbS@~IjC|U&z9~Ici2JPT5q__plUgm zO~f-j*)=G&J~%HfBz$W%`a=N;g(cJJ6suu5uJvLy@1nwZoU7t23{I#FC` z6z5s9QLJ^GZD|*_tQF_D&&t+ftrr|OS_+d4dtT$tBP@c8iT_0|Tked=CxoN9K z(l48#zQ~HL-BdOfuDpA%fMLl5@p{(mx~& z(s8awHtAVy5`%bUB=cpc+ZUe|0rJssvHQ@o#HCFzkQrz`BPv8WUSqk@NCH;+5JN%- zn}q1!h}?3VSfnAJ62*Cr(J-dl=o@DS@(D8x8xhYBIU;r% z35^lTq>__oqq&|YeZ!|?b+}lmqO9r%rez|@ru8+%Q}kHZun`s+?;2k|d~3AQBniQD zkfhRS(lb7sE}PX*Z{92EJv=vUVtRbgk)zxfejw+bAEZem#D-*UIATmJLS5D&Qj2Lb zPST5K-{iYQ5|Q8xk*8KhHA&kP_YbpnZsbGK!?*E6F89tGeW8pE3APxkx4W*zX?w2I z^&Dm0@zvyOWus#m@lmjyHaJ4Z!*JgCfkXcYTkzdNIAyLcmqe_4Vit1kJRhiyK7p}H wf@ui~@t=vP6X}M}mf32;na7zk{2m#7v6R{d>ym$R&b;>9WxO|7XY~E@Kf}iji2wiq literal 0 HcmV?d00001 diff --git a/po/hu.po b/po/hu.po new file mode 100644 index 0000000..3867ecb --- /dev/null +++ b/po/hu.po @@ -0,0 +1,408 @@ +# gnome-vfs Hungarian translations +# Copyright (C) 2000-2001 Free Software Foundation, Inc. +# Szabolcs BAN , 2000-2001. +# Gergely Nagy , 2001 +# Andras Timar , 2001 +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs CVS HEAD\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-08-09 12:59+0200\n" +"Last-Translator: Andras Timar \n" +"Language-Team: Hungarian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d NUL karaktereket tartalmaz." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d nem tartalmaz metódusnevet." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d nem tartalmaz modulnevet." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "'%s' konfigurációs fájlt nem található: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Ismeretlen op típus: %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "Nem lehet csővezetéket létrehozni a GIOChannel megnyitásához: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Ismeretlen munkatípus: %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "A művelet leállítva" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Nem sikerült értelmezni: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "A többi értelmezési hiba figyelmen kívül lesz hagyva." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Nincs hiba" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "A fájl nem található" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Általános hiba" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Belső hiba" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Érvénytelen paraméterek" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Nem támogatott művelet" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "I/O hiba" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Az adatok sérültek" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "A formátum érvénytelen" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Rossz fájl handle" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "A fájl túl nagy" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Nincs hely az eszközön" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Csak olvasható fájlrendszer" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "Érvénytelen URI" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Nincs nyitva a fájl" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "A megnyitás módja nem helyes" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Hozzáférés megtagadva" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "Túl sok nyitott fájl" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Fájl vége" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Nem könyvtár" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "A művelet folyamatban" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "A művelet megszakadt" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "A fájl létezik" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Ciklikus linket találtam" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "A művelet nem megengedett" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "Könyvtár" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Nincs elég memória" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "A gép nem található" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "A gépnév nem érvényes" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "A gépnek nincs címe" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "A belépés nem sikerült" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "A művelet leállítva" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "A könyvtár foglalt" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "A könyvtár nem üres" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "Túl sok link" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Csak olvasható fájlrendszer" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Nem ugyanazon a fájlrendszeren van" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "A név túl hosszú" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "A szolgáltatás nem elérhető" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "A kérés elavulttá teszi a szolgáltatás adatait" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Protokollhiba" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "Főtallózó (master browser) nem található" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "Nincs hozzárendelve alapértelmezett művelet" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "Nincs kezelő az URL-sémához" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "Hiba a parancssor értelmezése közben" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "Hiba a parancs indításakor" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Ismeretlen hiba" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 byte" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u byte" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (érvénytelen Unicode)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "Ismeretlen GnomeVFSSeekPosition %d" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "Nem található érvényes beállítófájl a következő helyen: %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "Használd a %s környezeti változót egy másik hely megadására.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "Alkalmazások" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "Cards" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "Fájlok" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "Mappák" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "Súgó" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "Gépek" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "Hivatkozások" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "Levelezés" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "Eszközök" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "Ablakok" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Standard Moniker factory" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "MonikerExtender fájl" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "általános Gnome VFS moniker" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "általános fájlmoniker" diff --git a/po/id.gmo b/po/id.gmo new file mode 100644 index 0000000000000000000000000000000000000000..ade4282b6ff4010061a3e0d6eb430233156b3d9d GIT binary patch literal 5387 zcmai%YlvM(9l%G^MBTn@t*^c^)~-p~-py|MTDNVQO|nV0*-g@9x4uxEd(Yf^C+FOA zZqJ;PWYuq?sD&bE)h`O-6GTKQf>QBQDeZ@XAc|0>QUpcB50?5x#NU6;+`D(TksfyL z@66-O%>Oa}|LmWxzv3yy^C;zJ%6H$a)BxVKlOLX!cPVu}{4;zDd=>Ji{uApvXuOsB zm63NuF2lFd-iI>&ad zdLK&vMR+BA0=^r59o`6k65C&Z^8N3i?Bg#`_VF(mM15N$-!Axe+OL5!Za2IFwxFzY zAo3WL`92Eedk6VbMQq=IvY#(N(cf2N`wyUu|2dTPpMmd%&qG<~6?i-RE0p!Go@(rJ z6J)Du9?JMdC~|%biXJ_@4t^Hi1fPPk-=9W43*Slo50U?b^8HRWDc{`!MV|do#vP1Y zgPQvJSbqY(hx)gnjQ=H+b)JVJ*B{|-_zIN$??6cDzYdBXrlHI~4;SGnh>6vg;SKN` zP~`h@tUm|$zDcQ_h_|5}N?}xKce*yQv7a=04*Wev+7n_&%IVkNPfg+FN z=Y8-qP}cocZ2uXQ{XZMqUxu=uS7ZNG43>TGhPS~PC~@FXC~>BM?}AT4`R;p=KlLkq zWdFZ`BL6?2*yZ1lKXnU21pk0y#}z1cx9|x3G!*^*8uF)}<464PrC5Ir;)dZ_j64}B z^Pi#Mq9KOf9ot8EfEUq?JRhXU{>8Us|MDE7+(WsOB04`tIY=QChvz|lABpc`Gx1w_ zL>{q$JUb}&hc|pR@-P$`aE&dG*kzTXDdOAmoTe;Mj#5rg#CPQpogb&%M-lyCrtpXk z?~3oD=L7M5Z)6KDQ^ba%=lvA%6VbKUR~}Rv9yxdNJW5%h?4*2vB9EMf+bIuI9-@dZ zoTA7X6Tig`)jUNWvA@`Ug)&DGzgK#%%P*MBC3-z~og%UO)bz|;S06vz@MMEks(xWQ z(VZf%jLW?~wZ5V|eN&oFWlKM^y*n@Tz*hYt(YYDe%XSw@o!L=$t=k)w^=d9qEp|HA zd!5+a*+eZ4hnee`$`!d+hfSipjxYNrPco~Hm^?2k-6^f9tRA|d)!m}h#n9&Z`10u^ z49jh{pr<`U%Y@$|@48-HhWVPQJ~{38=!?c{nWI?y-&E<(67>}&FT^1L; zEtzN3J2a)Y;ftfDGU%u*>tV&lkGdq^6TddP(X+QzRc0Byu}+0I0(&RlNQF;SVlB*bRBJFKk9_dhU!G&D@-G*)Fw$v%-FPv zA5452#%=CFs$MPcKON^<&QW!4vT-#!>Dgtq932)hnNqw@EqiTrGSZ=1ae3<1O3`z< z?ivJ7s1!rd3A#wVws{95^C>;63{a~@iSIBV?TZYndd(RVh3p{=aH`a~rW)ij7ciP>bNbI!_&vv3uNJvWIh|dMAxc`qPMnF2 z#^RgRLKGw#^U{`iwVtPWagkV&7X$m)v2*9FP0tkG1(QxE*25{QIkZXM*V8t<3Ct!T0HQAD~o(!b2&?;6JhWzT*7u-cO!T}w~K?) zpA}8)o0(D{Vo9Qp3MP*tFI}o^&iPcmcp8Hw8c}eBpp_-xdOvCb28TFXi6F%A(P zyr6OQfo)yrdVOMP@#xf<(`&6G5?JYM5!(oI2WDsQZq3fO4&1Bf?p~OizjKxr2DZ-P zzB0*{ard?64(Pdi7Y^KW=j{EATOowD)=HE6%wVPk%+@!=u0$VQTwT)-4iYn{4z-=n zoxfOG%DPtu`P|kFo|n3TWq&wW-=^py(vRe%)_HJ+{}g= z;*Of*pK?LMq9$*$ZZl}?ZU{pLmrQ1KUo!RPBq1Sh-=Q?d>B-IU4K;+^tk%yiPfT!T zl#eIc5IsW!-r{flkko?yLxzqCx@USO3k{83vzV#Jj-^6|UJ6&9;4G-5bZK2-x40Ch zCVx8IYv?lGL$0PXs&Hs9BPn|=c&Aw1qxpqq(BJ%Sl*^k#<5PYX>b#1K857M>eJGAFls#{evI0hITPnT#hqzl zn#A=9tHhc-`UBU8sz{4WotxMtn!-Fpa=FX2O~-Ix&qvpe(!6enS|u!U#zMm9$Ra6r z4f3`nvaQ6HW@ka?iDS+t<&UobzPS^qwb2QZt)$^1Fg{vx&c^=H4g=H~@-%4)x&F^x zAbMNEMT4tplzyb9rtJ~_WAR#U2L$V_U2F2M33r6ob!=C7Gt)V4IOrI!kvKMaU*P&M l3feiA2%eM`68odBY}qCXzR`8zb=L$viXfBM1U=H`{{Zc1XZ8R9 literal 0 HcmV?d00001 diff --git a/po/id.po b/po/id.po new file mode 100644 index 0000000..fbbfbb1 --- /dev/null +++ b/po/id.po @@ -0,0 +1,407 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs HEAD\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-06-12 15:24+0700\n" +"Last-Translator: Mohammad DAMT \n" +"Language-Team: Indonesia \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d berisi karakter NUL." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d tidak memiliki nama method" + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d tidak memiliki nama modul." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "File konfigurasi '%s' tidak ditemukan: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Tipe op %u tidak dikenal" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "Tidak dapat membuat pipe untuk membuka GIOChannel: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Jenis job %u tidak dikenal" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Operasi dihentikan" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Tidak dapat memparse: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Error parse berikutnya tidak akan ditampilkan." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Tidak ada error" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "File tidak ditemukan" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Error generik" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Error internal" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Parameter tidak sah" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Operasi tidak dikenal" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "Error I/O" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Data rusak" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Format tidak sah" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "File handle tidak sah" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "File terlalu besar" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Tidak ada sisa ruang kosong pada device" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "File sistem hanya bisa dibaca" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "URI tidak sah" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "File tidak dapat dibuka" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Mode open tidak sah" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Akses ditolak" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "File terbuka terlalu banyak" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Akhir file" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Bukan direktori" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Operasi sedang berlangsung" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Operasi diinterupsi" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "File sudah ada" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Link yang looping ditemukan" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Operasi tidak diizinkan" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "adalah sebuah direktori" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "tidak cukup memori" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Host tidak ditemukan" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Nama host tidak sah" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Host tidak memiliki alamat" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Login gagal" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Operasi dibatalkan" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Direktori sedang dipakai program lain" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Direktori masih ada isinya" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "Terlalu banyak link" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Sistem file hanya bisa dibaca saja" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Tidak dalam sistem file yang sama" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Nama terlalu panjang" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Layanan tidak tersedia" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Meminta data layanan yang basi" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Error protokol" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "Tidak dapat menemukan browser utama" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "Tidak ada aksi default yang dipasangkan" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "Tidak ada handler untuk skema URL tersebut" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "Error saat melakukan parsing perintah" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "Error saat menjalankan perintah" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Error tidak dikenal" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 byte" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u byte" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (unicode tidak sah)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "GnomeVFSSeekPosition %d tidak dikenal" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "Tidak dapat menemukan setting yang sah pada %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "Silakan pakai environment %s untuk menentukan lokasi yang berbeda.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "Aplikasi" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "Kartu" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "File" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "Folder" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "Bantuan" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "Host" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "Link" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "Mail" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "Peralatan" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "Windows" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Factory Moniker standar" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "file MonikerExtender" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "Gnome VFS moniker generik" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "file moniker standar" diff --git a/po/is.gmo b/po/is.gmo new file mode 100644 index 0000000000000000000000000000000000000000..d06361b0565a790ef107bccf3a90b66008ceee96 GIT binary patch literal 5345 zcma);TWlRi8Gr}U25>LX0_D<%4zwn{9mh_ZV%)2f+Og9(Nn<-fMMA94&N&{R-P!G4 zoSbJ=geVV4X$2Aj5d{T!hzLaZfug>wxU@nbp{f$1AW&7o8$uu<5JG(a?4IM(w3WK@ zoNwo{Gyi@3#~ZJDR`EPeyM^|hcPbUbd#>h(=TAG8x)J^vz6<^n@~8gW^mj1$G5Xgu zysP0Nd^h9kP}V;QuY+gcweXAZz3?o&3!aB^FA*rCxy|=ZzdH>u-k=SNAmieNgniAGY8rcn^FEirsz$<-6yg__u=c{Yy~f z`8~W3{vFD?J22`e;UpA&PC?oKG(;427EZx$L(%KEQ1pDQng2JGeA>xj;?LWloU;H$ zkIzBTH-#Ljo`NFJGf>X|29$lzLpg7&nXjPi`yv#1{sLv)4mOqVZ-Ru5+6Be_yCJSt z`yor!BT($|IFxgqfH%Q4DEsxB@n_*(^uGy3uV2F3;42W<`a>n}ujO#z-B8Xu3}wI1 zK#?U= zMgLzx4PS<`-@l;5)lQ5qcGvufJ@&&#;XD+3JPr9%XZex(^F1haYsLq-pBKWxKcD7T9X%n=0+Cwx-v40-m_i*zrHA4I+ zkH{rHl4l3)Q~r&ZZFm5R&Z6h&^Km*$G))tq%5#i1M-y8t&?M&N5#Ju7-A5Dq;2!^o z?IpkD8K>>_Z*^^!SINOen)poOeh+Oo?I2D3ArB_?&;Evw!x@^?5y?GyB&H>Q9;Q7= z6Q3NVNlZ%|itnds@ zcH88+4vn)WRI_Os*>+Ia#O3Nh5bBQQ%k{v8kx>T&=aNFVGZPd>r#3aZlVmzcjnjt~ zj~!&0GtrD5&smy<{3fnryJhD0tGD|6c)nYo4stC!b&}GB_4=fYP(a443w0di=&IMU z!c8&bcWH>$-V;a!?@H7z;DgE|RRT z*UG#<(v`zaoECjGhXhH-f2HQK3>BlGbnSKa;>0+{8qK(fGcu|p>x`NglbJI%FY@|* zsOolCY*zP*B++ZO>pQGZq7Wy;EJk4Y((9rQ8D}!v)<)z}3nog{LXsD_Mog)LFwAgc zJtlE5@~L09ErWD(wYcY4v)7`-)GmmI-6lv+EULvOU{RATCHmB2t^*woY^aV{*UQzB zq-&k-1SlTTNm8*1w&>;BxHeAaQ)ZS}pq7%1*lFzMwaN8q8%27}Xxnwnh7;>-7pYaayoO_AeL2J!!3%5@&m4X9s79kyh{% zInl2@zTHj4Kw`06#-d!Ux}Hl;Q!88&o0Id)%f|GMC%N@59S?`|wLb@|H##912@oz`O5I!O`{ z!84jrk4A;bncClKO|k9>)w8vd1ul;QJT#-1gSa%2K1?VdDxD+wa$X-Gq+|O?VYpn1 zB53y}T=@_myKWhDO>4yj@r+(1it#&@=K(MAmCKhFm*%#Wnwpp#qv&HL1i(Qvx-e&o zJ!!;6cE7*GsL2nmuFSWlx7UfF*uOPLsR*eYGkSW>7GqqP)#a`w>EGUcX`Qp{CJM{U z-T-`%WKfgYe5KRsVp=wWB`E_}+^oy# zMzs}%q$5QWL2#yQOl|R3Yll0S4bjs2Yx2rdxL(<_-?7ZHZ2L-(MgJE?FL<)^9urQuE8%Of5PpoDm>WV{P#8wL%)j96vlhyZe3=!5L z6xmzCjjSy=z01ulakt45N|B_Z*r$&3!H1(#%3f$Lw{?BSqH~+og{QblL;-tBZs*JhSig8`P3CfFcBz$#@KtA@=0&;X2&c$zJZZ|69#!~8dbvZB4d_FTh z2Zvwqux||pevWZ$j+=p7&k=oHMaIyS9Q;@@iK@$<8xc6wSJ&Ub&)rIax;3Cs4(40as zTqNNW#Ds92oow8(16z`QqUt~nwLq5pJH%UgsDzqrQd$hS$?kbnZjWK+t?JTdNjVs< z^WsH@EJUL1;gO|OYzg}!s10($7IJk-l^B)tErt&mR^sJ4uJ~uIPGP*aQC)T=9#z%1 zn%AJV6@DP*(Uf3&%ZvV4hlt9$?B~OTrOgOYETt-|r6W;I*6R?ZVo8#)*DK!g&L1wQ z6&>k1R}L&M_xx~%yWdyqdJtv8aN8C93&%&LF5`7Vvt#qM%=9H-QGd6DI9Np^#?xV3H_0~A9Zbv&8-^FHhzk?r~VHMH@30> literal 0 HcmV?d00001 diff --git a/po/is.po b/po/is.po new file mode 100644 index 0000000..f82306b --- /dev/null +++ b/po/is.po @@ -0,0 +1,409 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# Samúel Jón Gunnarsson , 2003 +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-06-21 12:15--100\n" +"Last-Translator: Samuel Jon Gunnarsson \n" +"Language-Team: Icelandic \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d inniheldur NUL tákn." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d inniheldur ekkert heiti fyrir aðgerð." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d inniheldur ekkert heiti fyrir einingu." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Stillingarskráin `%s' fannst ekki: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Óþekkt op gerð %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "Ekki tókst að stofna pípu fyrir opna GIOChannel: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Óþekkt vinnuaðgerð %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Aðgerð stöðvuð" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Ekki tókst að þátta: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Frekari þáttunarvillur verða hunsaðar." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Engin villa" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Skrá fannst ekki" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Almenn villa" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Innvær villa" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Ógild viðföng" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Óstudd aðgerð" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "I/O villa" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Skemmd gögn" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Ógilt skráarform" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Slæm skráaraðgerð" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "Skrá of stór" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Ekkert pláss eftir á einingu" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Ritvarið skráarkerfi" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "Ógilt URI" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Skráin er ekki opin" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Ógild opnunaraðgerð" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Aðgangi hafnað" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "Of margar opnar skrár" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Endi skráar" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Er ekki mappa" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Aðgerð í vinnslu" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Aðgerð stöðvuð" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Skráin er þegar til" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Hringrás í tenglum fannst" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Aðgerð ekki leyfileg" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "Er mappa" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Ekki nægjanlegt minni" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Vélin fannst ekki" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Heiti vélarinnar er ógilt" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Vélin hefur ekkert vistfang" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Innskráning mistókst" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Hætt var við aðgerð" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Mappan er upptekin" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Mappan er ekki tóm" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "Of margir tenglar" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Ritvarið skráarkerfi" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Er ekki á sama skráarkerfi" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Heitið er of langt" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Þjónusta ekki til staðar" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Beiðnin ógildir gögn þjónustu" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Samskiptavilla" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "Ekki tókst að finna yfirvafra" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "Engin sjálgefin aðgerð tilbundin" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "Engin aðgerð fyrir URL skemu" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "Villa við greiningu á skipanalínu" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "Villa við ræsingu skipunar" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Óþekkt villa" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 bæti" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u bæti" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (ógilt Unicode)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "Óþekkt GnomeVFSSeekPosition %d" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "Ekki tókst að finna gilda stillingaskrá í %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "Notaðu umhverfisbreytuna %s til að tilgreina aðra staðsetningu.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "Forrit" + +# Translate exactly the same in CDE's sys.dtwmrc file of the locale +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "Spjöld" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "Skrár" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "Möppur" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "Hjálp" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "Vélar" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "Tenglar" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "Póstur" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "Verkfæri" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "Gluggar" + +# Það þarf að finna eitthvað hentugt nafn á Moniker Factory, en eftir því sem mér skilts þá er moniker eitthvað form fyrir merkimiða. +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Standard Moniker factory" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "file MonikerExtender" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "almennur Gnome VFS merkimiði" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "almennur skráarmerkimiði" diff --git a/po/it.gmo b/po/it.gmo new file mode 100644 index 0000000000000000000000000000000000000000..9156c9f81e100e2c3e8c7fea96daf9ccedab706a GIT binary patch literal 5392 zcmai$O^jtl6@ZIz5N$yOMG$`|#HNRz*E2mZ%!#bWcxux*-}R-hQ{<>zcmr z*7erCJ=0@cxX_R&3xwH-3pX0n1U4pUNQ{Ce#*hevg~li*nh-Z86BkBY=y&SYd;NOA zc+>U1uBuai=bSpH{&elm3yN=%@(Ie*JCs_7S6wkcs zqW+i29SBMNX81mM2#S0MUIkCVE8%1CYPb$>hhK)b!SBOQ!dKyk;osp0;SMI-1+Rfp zZ$s(tzz@JL!0VxfH^Q&R_U}NEe-_I6FF;xUS5S`lI%Em;JNO~^XDD(P;ZFD;DC_Ke zf5RJ~%y%c0@%KUg)Zy6vFqHj#4vOA-v3(QDx{t$;!3$94e;$4Y{us)-zlUOnw;)Ta zofD1xRZz}11x0TU!fW6n{5VXY?DH#;Pr~b{e=qVyDC1v)GVX6s&hhWqKf$I&UPBG< ziS+dFe;fP%2<7}2q0GCJ!ykq>Lecl<;YVN!MIW27 z{uDfM8TNuQ?jnLfe{#edE~InURi$UOz+Jg-1G|C_P@A5ivj8P0PX)Q~CFLs0zbv-}{U&OjM| z9*W(cfMVZo#r9{Q$UO%|uRnvbk6%LB@0*Z6^)G&8`~*h)D7+fVdbdJ3-##dMJpx7k zQ7GqFi|rdw=KltqhEGEN)X(`5KYSgE{6C@G!^_#U=;anD^LC)v<+0daK~4SJvHwLV z`gs+K++U&i-P^H#EuFI7E+~H6j(h}untBPv-!4Eo_j3>zQon{wq27R84fPhh1zwEp z*ReU#*RIH;P{uz7Pr!3f^!*FSpZX0yBL60oeZCEGJM|z%&M#+|PwwKu@L%&IJ|*AX z4b(gozZRX!C%!oR#6FtRjt#QD==lCv-xDeOkUO-Savw$PyO$#NS)_yM8G@bn!($ZrW+@$t*n1y^P&4|(S4Ho4P#&hp9g|OdLhkt#MeHs< zA)nY@>^S=LE}L&8nN9UdZo4iux2ehLnVvp=q~XI27O496WU9L^uM(SkeR5@9ch{0K z=~kxn)0cMVP7h4A=2D#}1M{xkF0C^&?5_3dW@WsZ2~>x>UE{q@O>Rx94i`mcyGdnT z?$wbb)ji9|wIok7qmCwd?ke3aO;QOtZ;rCu%FS#L__8TJ-Q=}j1MEU6N-QU+Elab!1cl?HCvV( zE=%gXyT)9sI2fRZ*e=@{Yt@;}jhYi>nRC`xzWIN2)UB#$tEpAa=~deg735u(VqRDd z*szQYXHmyZZc5wLM)spln5|Ts>b#hdl zC)ubP-E*mF^R91m-Ag!fO2rkT4YaWCwaL4fmqGL_AfOgp ziN8dRg>!g))@GSrHQM%bdedojQuZ!7$z0x7Cmk-?OX{rB_&x5Z6YpKu;(4ibHrn8y z#y890i7QL<+IQE?z=()1lCII2=~bHHsoAhyX=lQ*V@TcPuI{gKiv~DHkU+j#Guq3R z!VU17xaB}CimMN}yJJeGExLI($-5>KeQdR%qoQ>EV50F>v=jYzt5qz;WCL5tA-CFn z<%)uqQ>Ck1*A4BpWVoL$&o;MhQCeH?()y*^;52U4y9|4J&FvC}OmX$OPwI424d+TW zFj}(8jXz!C@kyEL1((}(?qv^Sh?17E6SrZrvG`WiiGoC9UfMFRR`T`Soh3fxZeSjn zJAK-i^;6EU9YRll4f#6}s9aw^ckHLgA|t&N_aIJLOkIx2CL_7(w+$hLRS zp1WFm4z%{}(=&IqXAa!4hZY1|OL(q~-zK-ewRgXs+26i`-4~J;k@$g?<+;{@EjigFx^K-A zCQ_nCTOU}p)x?q!i?$Yg-=?i2b>Fv^U0Y8my({KRd^2xiqPrw@uE!L*Eq7Y%rMtv0 zZc}L`i_Q;|qf8{}HHg@ZiMi*g$t01w)ct=kNvI;$O6hqd!BqO_Sw=N_OZ6)bo?b^{cM{W(~kr|u(O8_R)P9+-~RuqPENYBJ7 zx4nC`Yx1}*ZC@h)NOGt@2NnOcHk4XW~TY6HOb&2x0YaSP2901`gLTV#uc+Ikw#@P!H?}v()n-!j@8MF zy4t;1S76v|Lxy*1WvRm&aiUXAPUlXHHfq(&j|Z=NXMWEz%Z`_W_t+5bnTeq33Pl{p zIxCsnFUNEthFei_a2Id&22Jv4Y_dGjjx;X^j9SdMTHj-;@hpfDH>IHcN z*kt?IAj)ZiW5kK@7~Uhz1&oh_1($M3s+YeTG$201`*%ynNt4l=Yk*Q@Kd3LH`KA%Q za;Lo8-X<>vuGuz8F&qmF*u%E=VDCnHR-TKzy5gH5i~if}RZPf3AmMdX$u1k;{vUly zmIpAJMo(B!4j0}I=k4${VVl>3=v+3IT3-<;WzBm+VnI5U3|1TO;>{sW*t{<|ZwRQk8!w&4wyEVV_=HD>L^EHNMup>E a`pSsU2YvkH;=*irWsG9Suq%ukwf+}xMTZsu literal 0 HcmV?d00001 diff --git a/po/it.po b/po/it.po new file mode 100644 index 0000000..710a27b --- /dev/null +++ b/po/it.po @@ -0,0 +1,409 @@ +# Italian localisation for gnome-vfs +# Copyright (C) 2000 Free Software Foundation, Inc. +# Christopher R. Gabriel +# Luca Ferretti , 2003. +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-07-27 17:45+0200\n" +"Last-Translator: Alessio Frusciante \n" +"Language-Team: Italian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Report-Msgid-Bugs-To: \n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d contiene caratteri NULL." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d non contiene il nome del metodo." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d non contiene il nome del modulo." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Il file di configurazione «%s» non è stato trovato: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Tipo di op %u sconosciuto." + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "Impossibile creare una pipe per aprire il GIOChannel: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Tipo di job %u sconosciuto" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Operazione interrotta" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Impossibile analizzare: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Ulteriori errori di analisi verranno ignorati." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Nessun errore" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "File non trovato" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Errore generico" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Errore interno" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Parametri non validi" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Operazione non supportata" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "Errore di Input/Output" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Dati corrotti" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Formato non valido" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Gestore file non corretto" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "File troppo grande" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Spazio insufficiente sulla periferica" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "File system in sola lettura" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "URI invalido" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "File non aperto" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Modalità di apertura non valida" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Accesso negato" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "Troppi file aperti" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Fine del file" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Non è una directory" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Operazione in corso" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Operazione interrotta" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Il file esiste" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Trovati link in loop" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Operazione non permessa" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "È una directory" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Memoria insufficiente" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Host non trovato" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Nome dell'host non valido" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "L'host non ha un indirizzo" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Login fallito" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Operazione annullata" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Directory occupata" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Directory non vuota" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "Troppi link" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "File system in sola lettura" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Non si trova sulla stesso file system" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Nome troppo lungo" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Servizio non disponibile" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Richiesta dati di servizi obsoleti" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Errore protocollo" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "Impossibile trovare un master browser" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "Nessuna azione predefinita associata" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "Nessun gestore per URL scheme" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "Errore nell'analizzare la riga di comando" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "Errore nell'avviare il comando" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Errore sconosciuto" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 byte" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u byte" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f kB" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (Unicode non valido)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "GnomeVFSSeekPosition %d sconosciuta" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "Impossibile trovare un file di impostazione valido a %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "" +"Usare la variabile d'ambiente %s per specificare una posizione diversa.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "Applicazioni" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "File" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "Cartelle" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "Aiuto" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "Host" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "Posta" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "Strumenti" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "Finestre" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Fabbrica Moniker standard" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "file MonikerExtender" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "moniker GNOME VFS generico" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "moniker file generico" diff --git a/po/ja.gmo b/po/ja.gmo new file mode 100644 index 0000000000000000000000000000000000000000..a0c38ad3dcf19356edc7021a151801275e1be340 GIT binary patch literal 6425 zcmbW4Yj9N69l)<|ja93)_Mz5O+Z23kAozm#zyJZF1P~JK)Gxi+y_;Ovy?5Qa3*gw2wG;^aXQ+WPCs-y(@w2+F1tzkq5aTyrgl0`fB$puZgwL~ zJH5likA^(hjhyBYK z{09ANL*5;-6<*DFH_U zg|owcH^6XU56XHQ^3QO?@g6Ah^g^-U%i;K8DD&Tja{jyUYw!ao=lJm3a16@%*VP4n zxfLR+F%!!CW+-|-3&oBeyb%`Qt#Ahvc~6FXAAXts??V0+%K9r1Qr6uLMW1O<<~p&%s&I=oDZPr^%1-S`cUM*3?=3LjZo}R4`u(Euo*6fxY*bVZ-%>} z=rHh%U4PS>5_)ExA<5P%8#+57<``!da zkB6YlTM8uyeh4wW@oRWL{5^aG-at^u{)?c*y9?$0i%`z{Ih+Fj0%hJU7e;$h99%hsVP4kD#poG<<(6#umNmq4pyb zyS76)*AB;fq3pL8%KAZgAN(*J{|r7z|7sS?ezV~m_+2RSyaFGEr=aNl4=DTG&Y|*t zHk9?xLeYC0lzFG1?DsL0dH)RG-+W8Zp9N)~4k+tahdd6&4@D??+)41tyk;o-M4|Zc zM^N+{hEw4wDCd0w>*1%c5#GU|?DG_ChAD`vjW?jw!Jk2?A0I=R_b+$}lt<>vBYu?! zQyEKX;y+m{cC3CLrXzdHGmC}_y2c@jejexl`)T*k8ff!rkI^or$s>9{p??K6Lh67# zBA>*bJeScP(!YZEke}i&$t6Ov<`KKK(G=}lGEt^+gW8M?3n6s?5G>F?lS5d8slogoPbXT zXrt>j)yGuSbuy;ycxrLSA{Fg6(`GbdrM-s9uN_w1<){U%OXf1ou@X(H-eYPy#{aGpx4W`wy6UV zWq_dD&FT zO=BjhM1lE@4v+Z3YxNR=tL(JvBrQjBDQ$}~#1zt+B|{BoPtZqzLt-6lA zS&??jOg5<}%#`U^nDUW8+Dy0|XV{w(@w#$pOyG^Q&+cdmI zm7nV?4Il7xyZqc1KbQCOoBZ5Q{oE^letY?b^$T15{D5ERt-WchhV_jr7j0?hhTorJv)#`PY8$W##t6->?`J>HQ7FFA7#kce9^X?fgPI~=0W2Il#3lnGXO-82 z<%PYXcK)2+1d(_8g(H6cke`41V(YXj+9+d(50v&IWQ|mn*Wvyfw7Jf)Tk*gqZBvZ9 zPAk!mw-Ik>Ja?qnyTQ*L{k#fV>zZJzGqj3Fw2jxYy4HU+vP_yfGJ52U7H^~~>Li+i zd1cS#j*q^T9~~M|Q(KnIzY77`v!4jSm3u>n=C_T#b*i{|N8q6GJ+Ejv2E}$bBiA?D ze`fUM*K|}&L{Qaw2@cFmpuCB*%XSoJ|8IL$2U>2VIJ~>~DglC1s%%>w37yVwWkyrY+spCllebWDfqwo)G%Lp7@C8@e%E5LAJhBda#Ma6U{NXB3}5 zSln=?xQX3rWh<_Ke!MU^d9-}aQPr`mwHz;%K}l8T&LQ8z!yMQWS;^DJuEC^Jfp9 zKTQEU9){qAx+BOxc4%i+9n|F+!xlG6Js#h2N`k)<4dXlakFUicx?mMZdP-rCqd5O~ zIY+~)d66WnI(>42%4eqb{IJ$}FX|OXutacNrOqC?$j%~=zMG`P59u;+flCFWSEQ!0 z;HL`|3Jgdj9>oM>Z{w+nThJ(O?IW&rA+NdzxG5xt*ZYOnFS2DGpKCwLWx?K3%{jUp zKssDX+h5>H5P|Yo;D8PiY6$lVM^)WZ<#~PMYu^~#hdjgj(0(I)!Oe1dxU`eesz@3e zJXzd=s=-!4N}=Go@@CZ%J5v%2W9B>pOiMP<*FMU;0Ep=-FBk5zfc_5SlV$y{&vtGJm+*! z5SE9|pTm#DB7Z1I((tY>|B+Pri=lM#MYd537B6XQ(SI;h9AyNr LCdXXakH&uhf&=i! literal 0 HcmV?d00001 diff --git a/po/ja.po b/po/ja.po new file mode 100644 index 0000000..78eb65d --- /dev/null +++ b/po/ja.po @@ -0,0 +1,408 @@ +# gnome-vfs ja.po +# Copyright (C) 2000 Free Software Foundation, Inc. +# Akira TAGOH , 2000. +# Takeshi AIHANA , 2003. +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs HEAD\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-08-25 11:58+0900\n" +"Last-Translator: Takeshi AIHANA \n" +"Language-Team: Japanese \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Report-Msgid-Bugs-To: \n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d NUL 文字があります。" + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d メソッド名がありません。" + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d モジュール名がありません。" + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "設定ファイル '%s' が見つかりません: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "オペレーションの種類 %u が不明です" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "GIOChannel を開くためのパイプを作成することができません: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "ジョブの種類 %u が不明です" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "操作を停止しました" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "解析できませんでした: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "これ以上の解析エラーは無視されます。" + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "エラーはありません" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "ファイルがありません" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "一般的なエラーです" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "内部エラーです" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "無効なパラメータです" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "サポート外の動作です" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "入出力エラーです" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "データが壊れています" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "フォーマットが無効です" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "おかしなファイル・ハンドルです" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "ファイルが大きすぎます" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "デバイスに空きがありません" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "読み取り専用のファイル・システムです" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "無効な URI です" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "ファイルが開けません" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "オープンモードは無効です" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "アクセスが拒否されました" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "開いているファイルが多すぎます" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "ファイルの終端 (EOF) です" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "フォルダではありません" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "操作が進行中です" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "操作を中断しました" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "ファイルは存在しています" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "ループしているリンクに遭遇しました" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "許可されていない操作です" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "これはフォルダ" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "メモリが足りません" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "ホストが見つかりません" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "ホスト名が無効です" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "ホストはアドレスを持っていません" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "ログインに失敗しました" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "操作はキャンセルされました" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "フォルダにアクセスできません" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "フォルダは空ではありません" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "リンクが多すぎます" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "読み取り専用のファイル・システムです" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "同一のファイルシステムではありません" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "名前が長すぎます" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "サービスがありません" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "廃止されたサービスのデータを要求しました" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "プロトコルのエラーです" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "マスター・ブラウザが見つかりませんでした" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "関連するデフォルトのアクションではありません" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "URL スキーマに対するハンドラではありません" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "コマンド・ラインを解析する際にエラーが発生しました" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "コマンドを起動する際にエラーが発生しました" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "不明なエラーです" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 バイト" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u バイト" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f Mバイト" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f Gバイト" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (Unicode が正しくありません)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "不明な GnomeVFSSeekPosition %d です" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "%s に適切な設定ファイルがありません\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "別の場所を示す環境変数 %s を使用して下さい。\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "アプリケーション" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "カード" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "ファイル" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "フォルダ" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "ヘルプ" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "ホスト" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "リンク" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "メール" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "ツール" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "ウィンドウ" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "標準モニカのファクトリ" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "ファイル MonikerExtender" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "汎用 GNOME VFS モニカ" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "汎用ファイル・モニカ" diff --git a/po/ko.gmo b/po/ko.gmo new file mode 100644 index 0000000000000000000000000000000000000000..c0d254f166d7730f9054f2eff873367db7fd63d0 GIT binary patch literal 5914 zcma);ZE##w8OM*jY7i6zQ2{xKu`RG^562=nXU6^ks|;FaKCL44T1 zb^lTfeir?!H1E*t06&cJK9J;}2CoM9gC7MCgC7GYz&pT`ARYM&a2@zd@D}ht;3vSF zvDr0XGq@IfK==DVnjZkK0!P3b!71=F;CJ-+&p=xLE0FZ~6G(de1yoo4NN~R^z>j16 z8j$2}1up|bAf3~yxgDhao&;&V3F5t;GL6ScU()ml^r@@OLo%0s> zdGOC5oqu&h;Fp^~sLI+vlHUx{J--5y9bNER@DO+tm<37SS2TYF-hlqEHQxbg{pC=S z*4+Zqeb$2{w@I@bP7p3;W8n2*4y60NtouI!pZO4DztQ85<4}@+8l<>N>;52kC;G$S9pD1E2K+sU zrR+)=2`aJcLDGwZq)!t_cGwKw2R;GPz7rtrcN}a1e+*Kb{{y7>xDj9XgKNRhfdb^< zFi88K2EPQJ12=&0fS&~Kgt3WRK-%vKknX)7q;sFsoCI%2{{@it`#y+}U_aO6Z-VR4 z{})L1YQ$w|{s9n2u?~>dJ*nBJ$M=C`|8IbFUO|r+LCTjidi)Kr3H>+q_!V$s3;MT# zwC`SU3uu58uSJmR$3+ky_BOu00R9ssf82&k(tIaK^Cn1oe;uSep8{#$GkX39Alc_l z&A)-9*SFf9toiCvm3uD&ghPJ>+uT6{|FoPP>f+q_Xdy_7K{`Xk;sT$Ok*nzKBM7hj362)quP7??$jy|6Z#Z0?DqF8!$avk4FC4iiVU_ z4_vCAdo>>g+tH|wkniXrUs8NMfVL5he6tg+0qrU@ggo^afz)zg;E z6T<7WBiu3);ytJBNGdKW(<$DY_Jqq?6xrr*Shy~a2+I@^wmF%Mn_4U9(IJ`37#~Qf=6wK+eu;Z9UZ&2Ld+8JcHZbh)QRBRwxVV%<*5CF zt-jXiuHgfQ%W0>mow6c{FRd8jdT}iiZr(fQ=j{ zmGq$aLuSNUqgNX|u(K;X&$ME0aI)b+u?7e_BJ9~tn)jyMbX}JY7m1{oX4{~F9aXE? zHpjsg<3`E~_hB!bm`K1HdYsg$8|87+5^Ot}OzbyZ&kcT8uUhMp&4Qk1+q~C|sSf1r zcmz%codgu7mFg~Rhp>cWhPfbp*ux^8WDnb}2iK4(xes z@6vm9STMC^#H(E$qol!?mv!1P)8bJB7muK0C&?zT zMZe316^4_s6f<2AU|qI@*wJ=Vw{iJ^8ISW`!OfV3*+>)HNjD(N#BD3acG?KfsF8|$ z965l{e1 zs4px#73)JrB@iM?0`gv;;4Z18vcXLwI1_9ag?$2fTxV*G>0l2VR#?Qz93ZIt|l%@U?Zm#mGuo}El$WVd5`cG#|XZI3{%+EzThLPZ)4y~pU&DS^~S24>cf=F^_92n_k@M~WHFtM>LwglK_DojRA$*s9P9`cK!&`(6IRZfs*}B$kTh_;0NPW*_vEC<%9+5e@rx4!rRo))zP)B zcDY_|>be_SHt^u*#^wzTc8`04Uw#y^o?KDX#k&#~G)%cG;Ru*A#RMQF`xZ)RD@K&yr2#gfct%Go?uf(zJ% z`?I5v#SE7t#q#K!dd14~3%C-KnWCJ@2Et36Uf@t~EsU~m#T|nsCzs^$N$xL>`UU(d z$(cd_)DoAa@2SIwb7aeU%P{|JMrI1->t$Kla;g+NuNJ}asxP1RYg zD*66F#qIS zIXmu;1%6XPDwPh-F)9g#C5Ad73!^x{oGEEH>%dT9GQS{4^8VQAN=1Q@b@|ZVSU!J1 z#~qT>e+?&RPspL1a>nc+@)CzvoH2__W{*^h4hx*2QlK!(=noOO;^2a+SfhjGECT4& z9HqiyNg4EiZa95Pp3kY}2j^sAkT1V>X1PRxRV#HXEU0#^PaassM*$474_1*UUSZ3n zW3-nJ-;q2iIh0p7tX~>bE>6oQ@@nI1h^#8i@ank#{4p-i%^}>#K=m;cOa=zbQ2rIi z^#V0k9QQ}&svfDEDNhaKRN77388)pPgaR@<$bxc=>LM>tc~Y4m3l~&Xoynlk=sO~M z^d*rtA3Qx#f>QcG3K)9JoX@~QDxFkCgW3k{zr^!?!2kdN literal 0 HcmV?d00001 diff --git a/po/ko.po b/po/ko.po new file mode 100644 index 0000000..250790b --- /dev/null +++ b/po/ko.po @@ -0,0 +1,407 @@ +# gnome-vfs ko.po +# Young-Ho Cha , 2000. +# Changwoo Ryu , 2002-2003. +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs-1\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-08-22 22:48+0900\n" +"Last-Translator: Changwoo Ryu \n" +"Language-Team: Korean \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Report-Msgid-Bugs-To: \n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d에 NUL 문자가 들어 있습니다." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d에 메서드 이름이 없습니다." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d에 모듈 이름이 없습니다." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "설정 파일 `%s'이(가) 없습니다: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "알 수 없는 op 형식 %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "GIOChannel을 열기위한 파이프 만들기 실패: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "알 수 없는 작업 종류 %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "작동 중지" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "분석할 수 없습니다: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "다음부터 분석 애러는 무시됩니다." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "오류 없음" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "파일이 없습니다" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "일반 오류" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "내부 오류" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "잘못된 인자" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "지원되지 않는 작동" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "입출력 오류" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "손상된 자료" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "형식이 잘못되어 있습니다" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "잘못된 파일 핸들" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "파일이 너무 큼" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "장치에 남은 공간 없습니다" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "읽기 전용 파일 시스템" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "잘못된 URI" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "파일을 열 수 없습니다" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "열기 모드가 잘못되어 있습니다" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "접근 거부" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "너무 많은 파일이 열었습니다" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "파일의 끝" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "디렉토리가 아닙니다" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "작동이 진행중" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "작동이 중단됩니다" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "파일이 있습니다" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "루핑되는 링크 만남" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "작동이 허가되지 않음" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "디렉토리입니다" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "메모리가 부족" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "호스트가 없습니다" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "호스트 이름이 잘못되었습니다" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "호스트의 주소가 없습니다" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "로그인 실패" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "작동 취소되었습니다" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "디렉토리가 사용중입니다" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "빈 디렉토리가 아닙니다" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "링크가 너무 많습니다" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "읽기 전용 파일 시스템" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "같은 파일시스템이 아닙니다" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "이름이 너무 깁니다" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "서비스가 가능하지 않습니다" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "쓰이지 않는 서비스의 자료 요청" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "프로토콜 오류" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "주요 브라우저를 찾을 수가 없습니다" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "기본 액션이 지정되어 있지 않습니다" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "URL 스킴에 대해 처리기가 지정되어 있지 않습니다" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "명령 행을 분석하는 데 애러가 발생했습니다" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "명령을 실행하는 데 애러가 발생했습니다" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "알 수 없는 애러가 발생했습니다" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 바이트" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u 바이트" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (잘못된 유니코드)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "알 수 없는 GnomeVFSSeekPosition %d" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "%s에서 올바른 설정 파일을 찾을 수 없습니다\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "다른 위치를 지정하려면 %s 환경 변수를 사용하십시오.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "응용프로그램" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "카드" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "파일" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "폴더" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "도움말" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "호스트" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "링크" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "메일" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "도구" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "ì°½" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "표준 모니커 팩토리" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "파일 모니커 익스텐더" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "일반 그놈 VFS 모니커" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "일반 파일 모니커" diff --git a/po/li.gmo b/po/li.gmo new file mode 100644 index 0000000000000000000000000000000000000000..4b1197ff1511451a0b522fad8d6bd9da1c0d96a2 GIT binary patch literal 5356 zcmaKvdx%_D8Ng3XTXk#I#z*bTo~qk4ZD$|pYu!FK$tGE|n@y8V3l`KfbI;tlGk4CJ z-p6h>B0?2W`iEjI74#3qT8ko5ibX`FxQN6*1VKcxz9@oVRZu~}BL2Q}?>rK#mp${F z^Ss~deBbP^cVGCp;<=x8HSNh)DbO`j^za zvE~YV4dWds>mP=f!qf0|@MG`|@G*EJ{1TK`{uu6sKZV!8f5SJyt2ylTa1P!8@2&eC zDDzwJ68I>*96kZBgx{#ge*|U!&!EWhdnj`J4F*+TTj_T(d?VwphqCTkcp+>+dC$I@ zhoGGIUMTw$$e;4{_%;-IJ`TlxpQ*>c0%iSkP~QI?cm+HQ38e?qwsC?zX)ahx1qe}EEK(d1+RrKLXm$LO3M6YQ0y=b<@^P>1dl;ntUd+b3_lA+ zzpvN*AHr)dQ0fIJ`(EZyS-+c?OI%$ErGFh1efC0$0_yUyuUxsr2ccGm7b13@!8RA;?Pl)Jh z7l#OULy`YFDDw*t7pVhKF(fc5jcx>0>k3jy^6MTr=UxlK_^AM5MFQLf$5|sP@ubNjNq3HEFC~|)jihMtT7eINI zDyXA1Ia(d3iJc_&ZlO&+chbTA;dwWoBIjP3$RW>tv|DL6(L~2Xw0mfz;_%$X=X>h! z5(6TqJR+CGtUSADcZ6@`$eR11=puHVe8ewnG))s5$+J#drX8dmp@~oBk(fA4yPX#9 z9h66GcXRm0ore4B?>E$JK(XsPXyWHtn#9uqn)p{9Od6isYTgeQX%hd}*JI*K$%psS z?xsmh9HU7LOZ*akYJnz?_)G4+xqbSibpG~ z(ajg9Bi-_@Fp10cu~VzM)iIfA6*kLf&YyN(_ifSfk#?qUUvb(;Won1hrEYE)Hdph3 zYN^$-d9EYt5*w+d!5~dqrbxWY)qWG{cEZk%aZzg30ppx6bStx_uzHXTtZw^E`+;@( z@XGoDmN}a)>gk-NS;VJz?IbRX;86bm!kDtxxB zn`OQ|(Uq6m{-D@a%ShncVV7FYGE_`W=~^Am;*I@2)~LrtoQYALCeEruVlsO=$&0-D zK2mku6`NJP!h79J;?QBePa~WRvpxdL&Y+7rY@N-LmbM~~I%3m-I^y#J*N7>#iJ}ZQ zR$~$e6I;W&u?*79)ynL8eb$P@)Xt=%ZXKj2R@6!zu&BwA5`AhV*G5M}8>-dB^>Vf9 ze#-OCHcU#tWIsa&}@(F zX3~;z4xCU%`qud}?r@{}gh*Jy`l4fXE+U27kZ%*5eYGxO-{&4rn3}OV*jvW6Y%2B` zk71)h=HuX~$x*CRNAY-6{KaAYq!1;?<9Xo+14fQ#zVIzS^x6r_UG*;AK1W0uZM?$h z!=)v3d^7hcUd=UkOboJzG{CJ=C#!DI%WUE_)8zJ_EQouqwO;cs>2W*TI75uIfuFb& z+m*-1T`vX_i{&zw=IWH|Ilo1&aK3LJICS!)wY}p$Pl8LQqtSfj&*AE>Z|a^Th3Rs% z!Vh$@P5KE#c{v#P3^Pe4s?4uW<-`wOo0bUNOfv8K*2!JU5>bZOA|z}pX>W%JXtxPa z=2KtgzL_cYAg?6*sNnKi<>k|bb=*%C*S9ffqEUrF2u2yrgl)q?oYf`iG*+U<16(2^ zc(F1O#ku*L=H^+qO7?7QWX9#G!9$CB%@m!)mZcXBbW(O%H>&{TF z$i8=<+Bno$7_SqNuykXYq!5uK7WG0iDW)imJI}hAcJhwX14b`z@Y$26# zwNY52aa0z=cx=hTQWd?AoH6}jQJkC%HL;#NuOx1G8ynZtn>K42JSUeeCIga6PIgn< z>QMcfHt))X=r-!&cy#A!r{%>IMmx~PxW4IG&L}f|UU58X4B@Jdiqh1_n4rxQJ33MC z2{qDFcbrAb*lx12Ta`UFNwLeXN#kA^@_61z{iJZzWl8qFgePcX6;yt<558 z3er|)*Zk1v7CTR;WbJrDl;OLX=Ppf=!UsCZrN^qw+um>_yfHO4Rw71-w2?yUkl~G# z^Mo{t)li!mHeXV56Y^b&aOA=S5%dF^v01;+zE>DL^sr9EE+;v+2FlPVH?Jqj|H-bsiBc3^!s-5t&au{nP%|hT+i^BZ~wYqEjraC7p%RV8#nQ;i2o}YE%q)glr zc8adYs+-|bHSrOcr zwnVq_Jv$!6txbb*\n" +"Language-Team: Limburgish\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +# hier wordt waarschijnlijk NULL bedoeld ipv NUL +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d haet NULL-teikes." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d haet geine metoodnaam." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d haet geine modulenaam." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Kóngfiggerasiebesjtandj '%s' woor neet gevónje: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Ónbekènd oper-tiep %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "Kèn gein piep aanmake veur GIOChannel: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Ónbekènd taaktiep %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Operasie gesjtop" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Kós neet verwirke: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Mie verwirkingsfaelers waere genegeerd." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Geine faeler" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Besjtandj neet gevónje" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Algemeine faeler" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Interne faeler" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Óngeljige paramaeters" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Neet-gesjtiepde operasie" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "I/O-faeler" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Data versjangeleerd" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Óngeljig formaat" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Sjlechte besjtandj-handle" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "Besjtandj te groet" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Gein ruumde vrie op 't apperaat" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Allein-laeze besjtandjsysteem" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "Óngeljige URI" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Besjtandj neet aope" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Óngeljige äöpeningsmodus" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Toegank verbaoje" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "Teväöl aope besjtenj" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "ènj van besjtandj" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Gein map" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Operasie is baezig" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Operasie óngerbraoke" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Besjtandj besjteit al" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Circulaere koppelinge gevónje" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Operasie neet toegesjtange" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "Is ein map" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Neet genóg ónthaud" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Mesjien neet gevónje" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Mesjiennaam is neet geljig" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Mesjien haet gein adres" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Inlogge neet gelök" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Operasie aafgebraoke" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Map is in gebroek" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Map is neet laeg" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "Teväöl koppelinge" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Allein-laeze besjtandjsysteem" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Neet op 'tzelfde besjtandjsysteem" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Naam te lank" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Deens is neet besjikbaar" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Verzeuk maak gegaeves van de deens achterhaold" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Protokolfaeler" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "Kós de huid-browser neet vènje" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "Gein sjtanderdaksie gedefinieerd" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "Gein aksie veur URL sjema" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "Faeler bie analysere opdrachregel" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "Faeler bie sjtarte opdrach" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Ónbekènde faeler" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 byte" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u bytes" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f Mb" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f Gb" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (óngeljige Unicode)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "Ónbekènde GnomeVFSSeekPosition %d" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "Gein geljig insjtèllingebesjtandj gevónje in %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "" +"Gebroek de %s omgaevingsvarrejabele veur ein angere lokasie op te gaeve.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "Programme" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "Kaarte" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "Besjtenj" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "Mappe" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "Hulp" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "Computers" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "Verwiezinge" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "E-mail" + +# Translate exactly the same in CDE's sys.dtwmrc file of the locale +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "Getuug" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "Vinsters" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Sjtanderd Monikerfebrik" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "Besjtandj MonikerExtender" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "Algemeine Gnome VFS moniker" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "Algemeine besjtandjmoniker" diff --git a/po/lt.gmo b/po/lt.gmo new file mode 100644 index 0000000000000000000000000000000000000000..25813fe42dde6fc405f80703369a1cbae1928e29 GIT binary patch literal 3570 zcmaKtOKep|7{^D!SAC=SevFSRDx6D8LF)w-fr1TfX-a8yVPx(-)6?laXXbcjPVo{< zjEQkcT(H-OF|IVm7}1ToFlv;gnn>6YHQl%{rin`Ye{<&cUQw8E`n&VZ%s1a_K2EP$ zeT-o|g6|G|-(JMn7T z4d4~v)-WFhN&gJE20R$#79_o|fVYB2!TZ5?LAv)ONPe9HZwAkR*Mfh8*MnChNVkJ` zgLMDazD)UY*?A(Ye-(H-$bSb(-zr>wH+VBh_B;xb{i7i1e+Jx% z+-VR;*avVLrm;^zntu+``LDryz+b_8!7B$Uzv_XHf;U3G9VGt`fH#4MLAvktuznmQ zyH0>)&vzij<0p{fxCByumV^8X1fBHW3evuMm_GsDg8BX+PeB}EM?lj18c1^ceF37!ET23O&7y0;EO#GVA{++Gm>Sd2ep_X{A^@2eo4KOW>?fOP(QknH^# zr1<_7=4)USt*-;APDTQ!gFFQ(zb}CtJO+}#AAzLj%fM40(#7t>7vZBp?+;>cC(`K0 z#z4|Z{tkyZp&ou;97ukU&D}xyqCs)E&Ht)wqM!8M@l^er93%k-)dLNx7xInjhhnq^ z-v)e?2dZ)Mg9gdD||UYNuOxL*nnLpk)M6lW;Ql%q1~$*nVa4#`wuoN1YE%%`P5mFTqd zFB3@`{YN^30A)gVswlISsUe5RL(2~6wl;?}-=j??XLs-4FJ*hmSmjH;7O$*V1=QVb za_&00MQj1*aek1ID{ z3ay0Z+uA0}pHJQPHhKZdQ@7NDvHsA+*u-ehIk+@{e&M8s2?$MtJNcs9n5XDkTYbl} z(mk%MiAF}YJQfWN_jZ%P&>fB95yU9^1|MlEH*n#G=*mK&QWrZ5()UEGvZhJZa<}Da z*}nr1(!_=@iXt}W*+Fel^|qif3gwomF@nM(qiShEWe8w-HZBlL67KaK@=tVQ3JZE@ zD)`$q`yofyK{AAIgp)E6>C%EI!>e|x>W?MLL3b>-Wg_6WQ*19OLeHc-(X~)y z8uzm)k$VSt8wres?~>IPio2lJX}qwC*g2=Ee|nMEfkuc18WhbcxVqGx`OqlX4DYRP zqkR&DCN$GRDE4e2c)J@P%7#@7rA~ZCw9HWnZNsJ!beNZ&Ra)_uqC2@RO@ZWF$!3@E z;`NeO3qMt6Dmy51rLCH4iDrZUR%cNu@PNXkQVPiA65UV1SVl(59J;CWv~1GCqC$aT zlk78b5=OO!ZVN6P9-&j{HrU|M7~t10@LE#AEOWd?bXiQ^3aK41G?*$~R7JGXF|JC!3y=)n|f Lqz1jJKNSA}Ip3ih literal 0 HcmV?d00001 diff --git a/po/lt.po b/po/lt.po new file mode 100644 index 0000000..aed2abd --- /dev/null +++ b/po/lt.po @@ -0,0 +1,900 @@ +# Lithuanian translation of gnome-vfs +# Copyright (C) 2000 Free Software Foundation, Inc. +# Gediminas Paulauskas , 2000 +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs 1.0.4\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2001-09-23 20:34+0200\n" +"Last-Translator: Gediminas Paulauskas \n" +"Language-Team: Lithuanian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=iso-8859-13\n" +"Content-Transfer-Encoding: 8bit\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d turi savyje NUL simboliø." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d neturi savyje metodo vardo." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d neturi savyje modulio vardo." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Konfigûracijos byla ¥%s´ nerasta: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Neþinomas op tipas %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, fuzzy, c-format +msgid "Unknown job kind %u" +msgstr "Neþinomas job'o ID %d" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Operacija sustabdyta" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Negalëjau parsinti: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Vëlesnës parsinimo klaidos bus ignoruotos." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Nëra klaidø" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Byla nerasta" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Paprasta klaida" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Vidinë klaida" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Negaliojantys parametrai" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Nepalaikoma operacija" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "I/O klaida" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Duomenys sugadinti" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Formatas neteisingas" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "Byla per didelë" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Kaupiklyje nebëra vietos" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Tik skaitoma bylø sistema" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "Negaliojantis URI" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Byla neatidaryta" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Atidarymo bûdas negaliojantis" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Priëjimas uþdraustas" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "Per daug atidarytø bylø" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Bylos pabaiga" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Ne katalogas" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Vyksta operacija" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Operacija pertraukta" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Byla egzistuoja" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Rasti amþini ciklai nuorodose" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Operacija neleidþiama" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "Yra katalogas" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Nepakanka atminties" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Hostas nerastas" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Hosto vardas neteisingas" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Hostas neturi adreso" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Prisijungimas nepavyko" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Operacija nutraukta" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Katalogas naudojamas" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Katalogas netuðèias" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "Per daug nuorodø" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Tik skaitoma bylø sistema" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Ne toje paèioje bylø sistemoje" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Vardas per ilgas" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Protokolo klaida" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +#, fuzzy +msgid "Could not find master browser" +msgstr "Negalëjau parsinti: %s" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Neþinoma klaida" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 baitas" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u baitø" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr "" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "Neþinoma GnomeVFSSeekPosition %d" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +#, fuzzy +msgid "Files" +msgstr "Byla egzistuoja" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +#, fuzzy +msgid "Folders" +msgstr "aplankas" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +#, fuzzy +msgid "generic file moniker" +msgstr "Paprasta klaida" + +#~ msgid "3D Studio image" +#~ msgstr "3D Studio paveikslëlis" + +#~ msgid "AIFC audio" +#~ msgstr "AIFC garsas" + +#~ msgid "AIFF audio" +#~ msgstr "AIFF garsas" + +#~ msgid "ANIM animation" +#~ msgstr "ANIM animacija" + +#~ msgid "AbiWord document" +#~ msgstr "AbiWord dokumentas" + +#~ msgid "Adobe FrameMaker font" +#~ msgstr "Adobe FrameMaker ðriftas" + +#~ msgid "ApplixWare Graphics image" +#~ msgstr "ApplixWare Graphics paveikslëlis" + +#~ msgid "Applixware Words document" +#~ msgstr "Applixware Words dokumentas" + +#~ msgid "Applixware spreadsheet" +#~ msgstr "Applixware spreadsheet" + +#~ msgid "AutoCAD image" +#~ msgstr "AutoCAD brëþinys" + +#~ msgid "BCPIO document" +#~ msgstr "BCPIO dokumentas" + +#~ msgid "BDF font" +#~ msgstr "BDF ðriftas" + +#~ msgid "CGI program" +#~ msgstr "CGI programa" + +#~ msgid "CGM image" +#~ msgstr "CGM paveikslëlis" + +#~ msgid "CPIO archive" +#~ msgstr "CPIO archyvas" + +#~ msgid "DOS font" +#~ msgstr "DOS ðriftas" + +#~ msgid "DOS/Windows program" +#~ msgstr "DOS/Windows programa" + +#~ msgid "DSSSL document" +#~ msgstr "DSSSL dokumentas" + +#~ msgid "Debian package" +#~ msgstr "Debian paketas" + +#~ msgid "Dia diagram" +#~ msgstr "Dia diagrama" + +#~ msgid "GIF image" +#~ msgstr "GIF paveikslëlis" + +#~ msgid "GIMP document" +#~ msgstr "GIMP dokumentas" + +#~ msgid "GMC link" +#~ msgstr "GMC nuoroda" + +#~ msgid "Glade project" +#~ msgstr "Glade projektas" + +#~ msgid "HDF document" +#~ msgstr "HDF dokumentas" + +#~ msgid "HTML page" +#~ msgstr "HTML puslapis" + +#~ msgid "IDL document" +#~ msgstr "IDL dokumentas" + +#~ msgid "IEF image" +#~ msgstr "IEF paveikslëlis" + +#~ msgid "IFF image" +#~ msgstr "IFF paveikslëlis" + +#~ msgid "ILBM image" +#~ msgstr "ILBM paveikslëlis" + +#~ msgid "JBuilder Project" +#~ msgstr "JBuilder Projektas" + +#~ msgid "JPEG image" +#~ msgstr "JPEG paveikslëlis" + +#~ msgid "KIllustrator document" +#~ msgstr "KIllustrator dokumentas" + +#~ msgid "KWord document" +#~ msgstr "KWord dokumentas" + +#~ msgid "LHA archive" +#~ msgstr "LHA archyvas" + +#~ msgid "LHARC archive" +#~ msgstr "LHARC archyvas" + +#~ msgid "LIBGRX font" +#~ msgstr "LIBGRX ðriftas" + +#~ msgid "LightWave object" +#~ msgstr "LightWave objektas" + +#~ msgid "LightWave scene" +#~ msgstr "LightWave scena" + +#~ msgid "MathML document" +#~ msgstr "MathML dokumentas" + +#~ msgid "Microsoft PowerPoint document" +#~ msgstr "Microsoft PowerPoint dokumentas" + +#~ msgid "Microsoft Word document" +#~ msgstr "Microsoft Word dokumentas" + +#~ msgid "Nautilus link" +#~ msgstr "Nautilus nuoroda" + +#~ msgid "ODA document" +#~ msgstr "ODA dokumentas" + +#~ msgid "PBM image" +#~ msgstr "PBM paveikslëlis" + +#~ msgid "PCF font" +#~ msgstr "PCF ðriftas" + +#~ msgid "PDF document" +#~ msgstr "PDF dokumentas" + +#~ msgid "PEF program" +#~ msgstr "PEF programa" + +#~ msgid "PGM image" +#~ msgstr "PGM paveikslëlis" + +#~ msgid "PN RealAudio document" +#~ msgstr "PN RealAudio dokumentas" + +#~ msgid "PNG image" +#~ msgstr "PNG paveikslëlis" + +#~ msgid "PNM image" +#~ msgstr "PNM paveikslëlis" + +#~ msgid "PPM image" +#~ msgstr "PPM paveikslëlis" + +#~ msgid "Photoshop document" +#~ msgstr "Photoshop dokumentas" + +#~ msgid "PostScript Type 1 font" +#~ msgstr "PostScript Type 1 ðriftas" + +#~ msgid "PostScript document" +#~ msgstr "PostScript dokumentas" + +#~ msgid "Quicken document" +#~ msgstr "Quicken dokumentas" + +#~ msgid "Quicken for Windows document" +#~ msgstr "Quicken for Windows dokumentas" + +#~ msgid "RAR archive" +#~ msgstr "RAR archyvas" + +#~ msgid "README document" +#~ msgstr "README dokumentas" + +#~ msgid "RGB image" +#~ msgstr "RGB paveikslëlis" + +#~ msgid "RPM package" +#~ msgstr "RPM paketas" + +#~ msgid "RealAudio/Video document" +#~ msgstr "RealAudio/Video dokumentas" + +#~ msgid "S/MIME file" +#~ msgstr "S/MIME byla" + +#~ msgid "S/MIME signature" +#~ msgstr "S/MIME paraðas" + +#~ msgid "SGML document" +#~ msgstr "SGML dokumentas" + +#~ msgid "SV4 CPIO archive" +#~ msgstr "SV4 CPIO archyvas" + +#~ msgid "Setext document" +#~ msgstr "Setext dokumentas" + +#~ msgid "Speech document" +#~ msgstr "Speech dokumentas" + +#~ msgid "Speedo font" +#~ msgstr "Speedo ðriftas" + +#~ msgid "Spreadsheet Interchange document" +#~ msgstr "Spreadsheet Interchange dokumentas" + +#~ msgid "Stampede package" +#~ msgstr "Stampede paketas" + +#~ msgid "StarOffice Writer document" +#~ msgstr "StarOffice Writer dokumentas" + +#~ msgid "SunOS News font" +#~ msgstr "SunOS News ðriftas" + +#~ msgid "TIFF image" +#~ msgstr "TIFF paveikslëlis" + +#~ msgid "TarGA image" +#~ msgstr "TarGA paveikslëlis" + +#~ msgid "TeX document" +#~ msgstr "TeX dokumentas" + +#~ msgid "TeX dvi document" +#~ msgstr "TeX dvi dokumentas" + +#~ msgid "TeX font" +#~ msgstr "TeX ðriftas" + +#~ msgid "TeXInfo document" +#~ msgstr "TeXInfo dokumentas" + +#~ msgid "ToutDoux document" +#~ msgstr "ToutDoux dokumentas" + +#~ msgid "TrueType font" +#~ msgstr "TrueType ðriftas" + +#~ msgid "Unidata netCDF document" +#~ msgstr "Unidata netCDF dokumentas" + +#~ msgid "V font" +#~ msgstr "V ðriftas" + +#~ msgid "VRML document" +#~ msgstr "VRML dokumentas" + +#~ msgid "WordPerfect document" +#~ msgstr "WordPerfect dokumentas" + +#~ msgid "X bitmap image" +#~ msgstr "X bitmap paveikslëlis" + +#~ msgid "X window image" +#~ msgstr "X window paveikslëlis" + +#~ msgid "XML document" +#~ msgstr "XML dokumentas" + +#~ msgid "XPM image" +#~ msgstr "XPM paveikslëlis" + +#~ msgid "address card" +#~ msgstr "adreso kortelë" + +#~ msgid "ar archive" +#~ msgstr "ar archyvas" + +#~ msgid "arj archive" +#~ msgstr "arj archyvas" + +#~ msgid "authors list" +#~ msgstr "autoriø sàraðas" + +#~ msgid "directory information file" +#~ msgstr "katalogo informacijos byla" + +#~ msgid "email headers" +#~ msgstr "el. paðto antraðtës" + +#~ msgid "email message" +#~ msgstr "el. paðto laiðkas" + +#~ msgid "encrypted message" +#~ msgstr "uþðifruotas laiðkas" + +#~ msgid "gtar archive" +#~ msgstr "gtar archyvas" + +#~ msgid "help page" +#~ msgstr "pagalbos puslapis" + +#~ msgid "multi-part message" +#~ msgstr "keliø daliø laiðkas" + +#~ msgid "search results" +#~ msgstr "paieðkos rezultatai" + +#~ msgid "signed message" +#~ msgstr "pasiraðytas laiðkas" + +#~ msgid "symbolic link" +#~ msgstr "simbolinë nuoroda" + +#~ msgid "tar archive" +#~ msgstr "tar archyvas" + +#~ msgid "theme" +#~ msgstr "tema" + +#~ msgid "troff document" +#~ msgstr "troff dokumentas" + +#~ msgid "unknown type" +#~ msgstr "neþinomas tipas" + +#~ msgid "zip archive" +#~ msgstr "zip archyvas" + +#~ msgid "zoo archive" +#~ msgstr "zoo archyvas" + +#~ msgid "GNOME VFS already initialized." +#~ msgstr "GNOME VFS jau inicializuota." + +#~ msgid "Dying." +#~ msgstr "Mirðtu." + +#~ msgid "Error reading: %s" +#~ msgstr "Klaida skaitant: %s" + +#~ msgid "Error writing: %s" +#~ msgstr "Klaida raðant: %s" + +#~ msgid "Cannot write: %s" +#~ msgstr "Negaliu raðyti: %s" + +#~ msgid "Cannot create temporary file name `%s'" +#~ msgstr "Negaliu sukurti laikinos bylos vardu ¥%s´" + +#~ msgid "Cannot create socket: %s" +#~ msgstr "Negaliu sukurti lizdo: %s" + +#~ msgid "Cannot bind `%s': %s" +#~ msgstr "Negaliu susieti ¥%s´: %s" + +#~ msgid "Cannot listen on `%s': %s" +#~ msgstr "Negaliu klausytis per ¥%s´: %s" + +#~ msgid "Cannot accept connections on `%s': %s" +#~ msgstr "Negaliu priimti prisijungimø per ¥%s´: %s" + +#~ msgid "Cannot initialize CORBA." +#~ msgstr "Negaliu inicializuoti CORBA." + +#~ msgid "Usage: %s []\n" +#~ msgstr "Vartojimas: %s []\n" + +#~ msgid "Got weird string from the slave process: `%s'" +#~ msgstr "Gauta keista eilutë ið vaikinio proceso: ¥%s´" + +#~ msgid "Cannot get object for `%s'" +#~ msgstr "Negaliu gauti objekto, skirto ¥%s´" + +#~ msgid "Cannot kill GNOME::VFS::Slave::Notify -- exception %s" +#~ msgstr "Negaliu nuþudyti GNOME::VFS::Slave::Notify -- iðimtis %s" + +#~ msgid "Cannot connect socket `%s': %s" +#~ msgstr "Negaliu prijungti lizdo ¥%s´: %s" + +#~ msgid "Cannot initialize GNOME::VFS:Slave::Notify" +#~ msgstr "Negaliu inicializuoti GNOME::VFS:Slave::Notify" + +#, fuzzy +#~ msgid "Can open multiple files" +#~ msgstr "Per daug atidarytø bylø" + +#~ msgid "%s to retrieve" +#~ msgstr "%s, kurá parsiøsti" + +#~ msgid "Closing connection to %s" +#~ msgstr "Uþdarau jungtá su %s" + +#~ msgid "%s of %s read" +#~ msgstr "%s ið %s perskaityti" + +#~ msgid "%s read" +#~ msgstr "%s perskaityti" + +#, fuzzy +#~ msgid "Go to the parent directory" +#~ msgstr "Ne katalogas" + +#, fuzzy +#~ msgid "Go to the home directory" +#~ msgstr "Ne katalogas" + +#, fuzzy +#~ msgid "Unknown sort rule %d" +#~ msgstr "Neþinomas job'o ID %d" + +#~ msgid "HTTP server returned an invalid PROPFIND response" +#~ msgstr "HTTP serveris gràþino negalimà PROPFIND atsakymà" + +#~ msgid "ftpfs: Invalid host name." +#~ msgstr "ftpfs: Negaliojantis hosto vardas." + +#~ msgid "ftpfs: Invalid host address." +#~ msgstr "ftpfs: Negaliojantis hosto adresas." + +#~ msgid "ftpfs: making connection to %s" +#~ msgstr "ftpfs: bandau prisijungti prie %s" + +#~ msgid "ftpfs: connection interrupted by user" +#~ msgstr "ftpfs: jungtis pertraukta vartotojo" + +#~ msgid "ftpfs: connection to server failed: %s" +#~ msgstr "ftpfs: prisijungimas prie serverio nepavyko: %s" + +#~ msgid "Waiting to retry... %d (Control-C to cancel)" +#~ msgstr "Laukiu kito bandymo... %d (Control-C atðaukti)" + +#~ msgid " FTP: Password required for " +#~ msgstr " FTP: Slaptaþodis reikalingas " + +#~ msgid "ftpfs: sending login name" +#~ msgstr "ftpfs: siunèiu prisijungimo vardà" + +#~ msgid "ftpfs: sending user password" +#~ msgstr "ftpfs: siunèiu vartotojo slaptaþodá" + +#~ msgid "ftpfs: logged in" +#~ msgstr "ftpfs: prisijungta" + +#~ msgid "ftpfs: Login incorrect for user %s " +#~ msgstr "ftpfs: neteisingas prisijungimas vartotojui %s" + +#~ msgid "ftpfs: aborting transfer." +#~ msgstr "ftpfs: nutraukiu siuntimà." + +#~ msgid "ftpfs: abort error: %s" +#~ msgstr "ftpfs: nutraukimo klaida: %s" + +#~ msgid "ftpfs: abort failed" +#~ msgstr "ftpfs: nutraukimas nepavyko" + +#~ msgid "ftpfs: could not setup passive mode" +#~ msgstr "ftpfs: negalëjau pereiti á pasyvø reþimà" + +#~ msgid "ftpfs: storing file %d (%d)" +#~ msgstr "ftpfs: áraðau bylà %d (%d)" + +#~ msgid "ftpfs: CWD failed." +#~ msgstr "ftpfs: CWD nepavyko." + +#~ msgid "ftpfs: couldn't resolve symlink" +#~ msgstr "ftpfs: negalëjau atsekti symlinko" + +#~ msgid "Resolving symlink..." +#~ msgstr "Atseku symlinkà..." + +#~ msgid "ftpfs: Reading FTP directory %s... (don't use UNIX ls options)" +#~ msgstr "ftpfs: Skaitau FTP katalogà %s... (nenaudok UNIX ls pasirinkèiø)" + +#~ msgid "ftpfs: Reading FTP directory %s..." +#~ msgstr "ftpfs: Skaitau FTP katalogà %s..." + +#~ msgid "ftpfs: reading FTP directory interrupt by user" +#~ msgstr "ftpfs: FTP katalogo skaitymas nutrauktas vartotojo" + +#~ msgid "ftpfs: got listing" +#~ msgstr "ftpfs: gavau sàraðà" + +#~ msgid "ftpfs: failed; nowhere to fallback to" +#~ msgstr "ftpfs: nepavyko; nëra kur besugráþti" + +#~ msgid "Starting linear transfer..." +#~ msgstr "Pradedu tiesiná siuntimà..." + +#~ msgid "Preparing reget..." +#~ msgstr "Paruoðiu gavimo pratæsimà..." diff --git a/po/lv.gmo b/po/lv.gmo new file mode 100644 index 0000000000000000000000000000000000000000..5dd0311fe232c614887977820c413f784d1b1289 GIT binary patch literal 4686 zcma);ON<;x8GwrrgIU5W5J*A@1!Vn5GV9&7P1c*Iz42q^_1d!6mU2O|zyUBwe1CV(%&rL% zt*QB@p8Y@TpWokk`%8*vfp#D5z->xB1D9^+i|2bgl)4jsAAS%H;0NHZ>i%!x{q%oV z^Pe^EVbM;;=b)@V%-2WY3HUL10X_)Za4-BO{2Y88eiFU|KMMZ>_rQPE{Yiw7`2+C7 z@I=iODC?hv@*WTGfX~B^!x!uE??BoA-I_mzvhQv9A$X(i{~5~p|A3G;w>|28J z{;$;YNzJc8&G^f8|223w{og=Y|0gK#`8)hPyknx0^I<6C^HB6#hVotm55r6FQ}8EH z^n9!CzYBN0PpN;`{Rc1xCQ^qWE>ef<{s}1YbOvge)cgiSRrM;AeLsd`x1T|g=Pfu3 z{{S2CE+)SS7ogaq4Vh9ez_w!KXeyQ%i z0{N)d_!9Yl3GanBpybm{DCggcaN>t4DC-uWocByU{u~tju0XN(x9a&HLeb;bQ1<^7 z%K1B3EPV|{zk~1#a2fJZJ-+1puR>Y(Z7Azrg-^m?K#^l7#t?hm52Zf`35(K}pwvP9 z`vgt)?WH|T+fNfaHE3I($LV~TCNU(>L$uwrdFj;8BT#I8WH_*e`}jRY6W>UDiS3@E z$s>N7D}PmAq=J&`P17)QX(!YgJ)+m-sHfCz{Fb|kkXMIjqOaIQ^662UJiBOOuUT4Y zXLyh{LzDQKriuT>)^gX%bAa|>`AezC;FoB7XyQkSW%0xNX%bKJ9F{M=$EAG}yGWl; zUCT#yubP~iY3t)hDxR!xif)*njC9MVxp8UG%jcJL>!Qg_E4Nvgx^+7BI@AQX9|f$)FZ|+IF2HGr99=b;z@mVYj|yf|fJdzDT2bWf3E-jJY(@ zi3upCo0-29Y{ogm*`CRQEq6R^a)Uv#tmx%P`Lv7D-SuvxE29RR=PvDp>dhucqzM*g zww3#AO*f0MwxugCw@EKwQ%8}&x657Xm}qVS5&Whx%ay1I_j9u65c0k zOHtHuo7&8^w9PV~sS`frm{W|PO%!EVyBZUBZP`_>8^3UI-|6~*#T4_TCLVR`C_1~S z7VC(@QXD4Xp%#NSIvVP&mVC$I4TEM89pA%7I(BI{Xq&ch37eQXckXS6J^JzErm&nM} zC-%azbLXt>p7FtznK&7Z=Bt1lu3q&`-IWBKEJiDQPv>hSc{vn{Ue9M3Nb{YbTLi5sf1l9@Eb2A|C9 z!&&ZvUdenf=*KSlEVcPlsp-3pOoyqs|HQg)MDMib*{z#ujmAm7gL@{C+iwC*l4*`u3R}U=&}sqBG)zS%y4EXt4jHT!PV8G9@QNa z_qm~TZ?KWYo7cOA8ZSw`T#tjR`LG~4-Sn%24OAL0s!o@S)VlRT7waJ(Y(#Dq8)U(FA=0lKC{%;1byv33 z%557d4MjOCErDQS@mLfyIW8*1=+rOtz$H`>5m*PAz6-fvb%r zk(65}#v(v?l_g-hAtCC~z@>v9`Bl$Lm-aPEmCeAP8SbP|RZae=mLXQ&9jICtP5vAXt7c|4-}HHEE2rX^$Q04Kcz*L* zArW2=jBb!p5=^>Iq=>}-tA>tO3^g5&NLkOChA5#LP&miqQcXvLCU2UU^tz6;Qco*) zs3m;wrJVMi+^GroJdw+PEUd`?t};-$=vt01$)I7FOJo&NPRqo;wVq0{aLrZPY^$fk K8QEt>RrWvqJPot} literal 0 HcmV?d00001 diff --git a/po/lv.po b/po/lv.po new file mode 100644 index 0000000..06af2f8 --- /dev/null +++ b/po/lv.po @@ -0,0 +1,407 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Free Software Foundation, Inc. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2002-12-20 19:07+0200\n" +"Last-Translator: Artis Trops \n" +"Language-Team: Latvian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d satur NUL rakstzÄ«mes." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d nesatur metodes nosaukumu." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d nesatur moduļa nosaukumu." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Konfigurācijas fails `%s' netika atrasts: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Nezināms op tips %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "Nevar izveidot kanālu lai atvērtu GIOChannel: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Nezināms darba tips %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Operācija apturēta" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Nevarēju noparsēt: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Pārējās parsēšanas kļūdas tiks ignorētas." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Nav kļūdas" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Fails nav atrasts" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Parastā kļūda" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Iekšējā kļūda" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Nepareizi parametri" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "NeatbalstÄ«ta operācija" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "I/O kļūda" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Dati bojāti" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Neatļauts formāts" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Slikts faila handle" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "Fails par lielu" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Nav vietas uz iekārtas" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Lasāmā failu sistēma" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "Nepareizs URI" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Fails nav atvērts" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Neatļauts atvērtais režīms" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Pieeja liegta" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "Par daudz atvērtu failu" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Faila Beigas (eof)" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Nav direktorija" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Operācija progresā" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Operācija pātraukta" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Fails eksistē" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "RinÄ·ojošās saites parādÄ«jušās" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Operācija nav atļauta" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "Ir direktorija" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Nepietiekami atmiņas" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Resursdators nav atrasts" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Resursdatora nosaukums nav pareizs" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Resursdatoram nav adreses" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "PieteikÅ¡anās neveiksmÄ«ga" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Operācija atsaukta" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Direktorija aizņemta" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Direktorija nav tukÅ¡a" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "Pārāk daudz saiÅ¡u" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Tikai lasāma failu sistēma" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Ne tā pati failu sistēma" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Nosaukums pārāk garÅ¡" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Serviss nav pieejams" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "PieprasÄ«jums atsauc servisa datus" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Protokola kļūda" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "Nevarēju atrast galveno pārlÅ«ku" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Nezināma kļūda" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 baits" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u baiti" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (nederÄ«gs Unicode)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "Nezināma GnomeVFSSeekPosition %d" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "Nevarēju atrast pareizu uzstādijumu failu %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "Lieto %s vides mainÄ«go lai norādÄ«tu citu atraÅ¡anās vietu.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +#, fuzzy +msgid "Files" +msgstr "Fails eksistē" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Standarta Moniker ražotne" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "fails MonikerExtender" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "parasts Gnome VFS moniker" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "parasts faila moniker" diff --git a/po/mk.gmo b/po/mk.gmo new file mode 100644 index 0000000000000000000000000000000000000000..b1510429afd30a0fd80defafb156fb366d4be641 GIT binary patch literal 6949 zcma)E1hYxih!z z{$bJw(nkJ43$dvPY0waj%9cLZ^s)WJ7z2rBHX%kLJ_u_3!$gDrV)`d^f5DG|*CFh3 zuot`;ygwh0fqK3Jyaap_yc+xt_-XK^eEv01`+p6}jz5F4&gUmU*|Q%Me^2N0FM?Ws0+jyK;5Fc@p!B>Aeh&OA zDE*gpxwu>lVyd?c)cO^m{Coryj|q4sxEH(@draBx^C~F6eh1zNz75L$3vg1;uLQ+IHz@hbz!l(n zkPv%MfgcACg7WVt`S=%Le4gjM2`V23QL6RZK;>0EA5Vab81DubgFnvkO;G+_3Q4%^ z-2i?TTnNgZL9iSAD!3W^2B>v!fU1cBRS1Q1dT<;_;WD{QNg4`PYy48PDsEo}_51};@_&|({{c$Q6*P&j zgGErhO@ZozuY!EMzwmVvcpgPX8rn;FtLp&=HorIWTY9xu@#wt78);;(yZFX+s~gws zwVdzUx#f>IS;KuFH?7!S;_(alZ}kZE0bR0hk^M!S!8`Ncy*VoXaMSvgPgzhNDklxM zeABgoTlple*Kvz8U5fo$?mM_ucZ#tt=(c?7x8f=8bt(3`lpEq-wV`}bZ7Ba%aVt-C zky`dzn&X3Dk^3TU<$x~LxbpLU?t8h_1J-jZcQ4_lth{C1x(Jc&!GoZ3>N0N6+#E*R z{YqFiTcfZPmxF~~cTeAlS-aBV0}h55CdKZuDaBFhhf!kIZyhwHF~9DY(x9I7oclP6 zO*Kfz;-oZfw#(!qBu3Bdf=ylsfD$`jKp;l*Mi8b9oVpnWl>Nmn(l<9^)laaG!l+B z>Qq%gDtoBnM zj_UPBEyeKFVL4im@Ai%3ISJAVhw?>o&JHsSR-0zmF?V&hxqco1qa5!oQ ztdA>Yf(+KH7_6Pv7jJD41@*9G0@>rO3o12lU7VzZMpPQVT&@#FH>W)4*lO3cZO}0B z1{QC~Wer479r=~kFi+A=1KvQMu(*jxWuG^Y7~hne9D0LcG@f{a@n{&C5g*6P4C0zN zfs66P1W}0~vy~@9EbxZnI=PecX1z(wj<8ZO!+{A$Bc7Ify!G-x%v9oN)LS2uo+Eyv zk{W7&)HHsQ#HEldEbF1;gdZ+X>ozO5ZW=U6X)LG)T9VZKQeY~HH7AC-cN_-N0;QLP@2 z+CX*A!cLyW?ODYOVbw5|lkNE=jcYY#HrC@bF2&8LZ3?K>II2v{GEuXId1fDL1f)(p zoWvEPniy(Kge;&9P*vV$H?)5F+X76PIZnD43V^jI8hT5F5>NB zEP}*XqPa@qZH>mGcn7^AimSmxYc_8Vg7J-U655b1Bq6 zg-v9zZpdXogDvi`WKeDx7F{+tZBZeDBsRYYNNS>trc`DD=}a%CwN8SvDM| zU7G@hw=k59hULP_#%NO55*JO^mkPEgI?oj5a%ic+bliA6cJ;>UXO*M~L=`gd_XH(f}=6En^^otz` z`@rj^cyD%!^$n99LG3{+;N@(J!@4=)WzWlqncX~_%+6-hGkc75vY91QxP8XUp5nnN z2D1GLaLUWR%gX)Pw3%h&F`i>1_i?TDvhVTZG_s)0AP_fBqU|{PpuiwYtg_N%ujorV zVObAn4mCYL=T#s(qy;R*h(m}zGxIn$9G%%~cVQhA%1+#|D*4ee$k^8fOLQ)M<{)O_ zV>W5u0_GZwG#3H4(quvuZ_oX+Ph*^W8c z4|~c3)Sg7cE<~P&e@mIPzPD%$fe#c|r{;Q(Py$Ab|2c zhzu0VJj;`pJ#B3v!j@Vkk1VuYD24SACzI^7*>lK7=3t)3b8_T>_#>Cl={8OoOYs@Z zwN5J)q$(ExDX5#oQ74Ktn@_|nq9tOU?c&PjiIN*?Ar5Iz+u2sqxD~1l)yT90FzGJB|_X%*|OWxJoBujrWsucFbGylBZXwgLFPK+b8Oy?YB-8=?n_6W;`sD?se8X& zUiO1lOw`l#3Q8YnC6kwZTbxppZi?UMJXd#`&C*uhQf&`#35-}MBr#Mqu5DXikqF7p zX|u5&!N^%9Fght%H6WhTB8k|X6sEZMvg9nvSx<3LJ|~_BE{4f%57aP~;hlTiMni);C^!;i!^yle?Q_S1UcHq$XtL$nv3fUJr^zha z(Xunn`MgkPcDahTC&O|4C5P?Sb3@kDttHqgFR|2~xTtj0*v7!ZyfMq)>6rs^(K_wU zPj?{LW_d6>Rj}l%XJEOPJ!_4$b@X0m9aQs?6|dxW*#1ee5@?8N^6CnARz2ywwPDaR zTi@+11fzYVsL@-KPR_qdWojdbLSV1)0uZl!EuqWj2~_fv^5WvJ2WKLawgN+ zW@Wl`YYFDe@Um|qTGY4BAUwrmOh<$)hA^8g3MxW*W3p-Q>Wf9xf_gvluslVNjNiq#lCJr`N#18in6~d{bOwH^R#cn37U?im5c94w z&vS9nK7_FL9E$Y*$2$+JY+F;g;5|8t6|&3y0keNwY{*23UeWSbA$GY=z>cYA3LE~P zxkfunQb#Atn?i>sy`|8%TpV!{uf-$M`QLV~FmZm?1?23k=g0EbanXrgO2S#iW#1~1 zo+lFWNf6h}m{q$|BNL~3(UW%kvVvTa+Jey^MK=wXHvH^W4-&hUnxmRm^U|wU-YGZLDwoyZj%*xRCk) literal 0 HcmV?d00001 diff --git a/po/mk.po b/po/mk.po new file mode 100644 index 0000000..51f01b5 --- /dev/null +++ b/po/mk.po @@ -0,0 +1,415 @@ +# translation of gnome-vfs.HEAD.mk.po to +# translation of gnome-vfs.HEAD.mk.po to Macedonian +# translation of gnome-vfs.HEAD.mk.po to +# translation of gnome-vfs.HEAD.po to Macedonian +# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# Maratonec , 2002,2003 +# Ivan Stojmirov , 2003 +# Vladislav Bidikov , 2003 +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs.HEAD.mk\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-06-15 21:47+0000\n" +"Last-Translator: Vladislav Bidikov \n" +"Language-Team: Macedonian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Report-Msgid-Bugs-To: \n" +"X-Generator: KBabel 1.0.1\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d содржи NUL карактери." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d не содржи име на метод." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d не содржи име на модул." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Конфигурациската датотека `%s' не е најдена: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Непознат оп тип %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "Неможе да креира цевка за отварање на GIOChannel: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Непознат вид на работа %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Операцијата е стопирана" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Неможе да се парсира: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Повеќе грешки при парсирањето ќе бидат игнорирани." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Нема грешка" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Датотеката не е најдена" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Општа грешка" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Внатрешна грешка" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Неправилни параметри" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Неподдржана операција" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "I/O грешка" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Податоците се корумпирани" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Невалиден формат" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Лошо име на датотека" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "Датотеката е преголема" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Нема слободен простор на уредот" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Системот на датотеки е само за читање" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "Невалиден URI" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Датотеката не е отворена" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Модот за отварање не е дозволен" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Пристапот е одбиен" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "Премногу отворени датотеки" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Крај на датотека" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Не е папка" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Операциите се во тек" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Операциите беа преќинати" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Датотеката постои" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Кружни линкови постојат" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Операцијата не е дозволена" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "Ова е папка" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Нема доволно меморија" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Домаќинот не беше пронајден" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Името на домаќинот не беше пронајдено" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Домаќинот нема адреса" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Логирањето не успеа" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Операцијата беше прекината" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Папката е зафатена" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Директориумот не е празен" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "Премногу линкови" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Само-читај фајл систем" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Не се наоѓа на истиот фајл-систем" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Името е предолго" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Сервисот не е присутен" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Барањето е непотребно за тие податоци од сервисот" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Грешка во протоколот" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "Неможе да се најде главниот прелистувач" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "Нема номинална акција поставено" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "Нема ракувач за URL шемата" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "Грешка при парсирање на командната линија" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "Грешка при лансирањето на командата" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Непозната грешка" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 бајт" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u бајтови" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (неважечки Unicode)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "Непозната Gnome VFS пребарувачка позиција %d" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "Неможе да се пронајде датотека со подесувања во %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "" +"Користете ја променливата за околина %s за да одреди друга локација. \n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "Апликации" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "Карти" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "Датотеки" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "Папки" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "Помош" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "Хостови" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "Врски" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "Пошта" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "Алатки" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "Прозорци" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Стандардна Moniker фабрика" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "фајлот MonikerExtender" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "општ Gnome VFS moniker" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "општ датотечен moniker" diff --git a/po/ml.gmo b/po/ml.gmo new file mode 100644 index 0000000000000000000000000000000000000000..2f0903d3585ead7b5eaf825a4a317c7042cc8a1b GIT binary patch literal 4203 zcma);?{6GO8OJBIB*lc57AP%H7z%-;$vNkks;)yy^ULI_xUNz=An^j$cjL=8d%LII zy(E5vk_bv^sEU9HHHs1-L9v=ZXuDSxUetd;geoB<-k}8~Bwiu`ulYPPvv;=R2v(l` z?#w*%Jm2R#&&>JH58QoT@$961iuRKYO6>(;5WfXzy!P(e8uBM@FVoEgC7K!J>K&3e*(qd-$C*BFYx`~23`_>6Dafd zflR4KK=J=5_yKUt_jiNh{~1vDANAuQ$e%jJOZgOcCRz-{co5;#u( z4-CrqMo4`Uychf^_!#&k_!aQ;;3BvKyae{ZTi_J97g5H*m%y#y?>znu+)jV<2-<-Y zpv->*`~vtLQ21R3h2OiN)W;t|(c_<>_}zfW4}#<17VsHx6zqZx@G>at{s9XAjfnm< z_$VlTn&1SOfx_bk_$}}~@N-}t(T;+%paHLgN5K0Lc@NkEh4(MOC%{|aQ{Y`V|1`J{ z6#oIZ3%me|{qMoAgZ}}A*UX2>1r)AQ`jY$mXphmv&)VlR37<-(u-O;PI5-$mhJ>u zZc;s;CMPqKsslkD=w_0py>5=D17T{Kd6F*b`ChiTqATl7r<*UTgE&bRYzQ?aam=YO z%QN?F!z8`9HS8u`6T4oXBzit<+Ya_g)G}$NzG`BVhD~kKG)dJV6Lr<0B+DIR>#DJH z#?LllxW_>>=z6)1G*rV&*A3F3V=&89Bh!IyRT-(nVSGGOhm&>~>xBU3Ej10OXR+79 zElT3HdN%RS`N+CK)9A=7oVV`)6~o6lE;6 z8>F*5>2`_zT$PLU7as>jT_2(-ENYy^BRwip!ymMC=Ma`0>w~kv}#9@lj53e z$4ST3PAp`jhYs#NF!J2YY;AvPY+f}g$xP~9_4;_NK2h8CxE>py9Glo)X9UCA5!4eO ztL&br)v>Ej?s{^2{qgbo$YF}JHk$@<76nw{q@H?ys@8~GVW7VpCCwl*Pq*XVXp*)^ z!}ux8<907-o7$`iI+J=jh=N60XIm;F~(o$Ru>QTAUdi#M34-tX|uVZVJ!Ng%Q7m;KY?viObl zeZda$COU(K9lT@*FO|hraaR_v+dd0m1(Tna#cOutwX%4NkH4P&0Y<;Jb8pLsBqT|& z;zC(0(Wm1AUnRgwkJqg667$4*(Jv96EF|?eanBqY{nmN4qtJMfQTSf5JTBX%LRQ>J zbcrc+D<60wD)KrJFeTrsgQx=u8GXId@(mx$ySzf0M8FOEakeZ7D%2z)OPf)`!^zT? z@ON18wq3qt&0&aKlBHufP|WSWBt{IX#8UT}orQxpWRg@}L`q#<`lu=2i!Acll{OMF{~bVx!pC6!@FtA~^bLj%>Yf`=cav|e^Waf$R~KnaPK zELpkjk~CVsX#>N}7l6oY1FuI{egUj=3Tv>%;+Vd($0O^gvY%*nHa9BCR<;= z;`AIpB$n;}XYTT=BIA~2?m(f7lr9jqS60h9FgsT*)WM6ZCAW~HTBG~XJK-mcr#uI$qMP418fn8NGP`~}e zNZBEm-)~OqudD!0xS{OVY`M6SbVu;27 literal 0 HcmV?d00001 diff --git a/po/ml.po b/po/ml.po new file mode 100644 index 0000000..4a40e17 --- /dev/null +++ b/po/ml.po @@ -0,0 +1,411 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FSF-India , 2003. +# +msgid "" +msgstr "" +"Project-Id-Version:gnome-vfs.HEAD\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-07-05 10:29+0530\n" +"Last-Translator: FSF-India \n" +"Language-Team: Malayalam \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "" + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "" + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "" + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "അറിയാത്ത op ഇനം %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "അറിയാത്ത തരം ജോലി %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "പ്രവ‌ര്‍ത്തനം അവസാനിപ്പിച്ചു" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, fuzzy, c-format +msgid "Could not parse: %s" +msgstr "%s തുറക്കാനാകുന്നില്ല" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "" + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "പ്രശ്നം ഇല്ല" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "രചന കണ്ടില്ല" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "പൊതു പിശക്" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "ആന്തരിക പിശക്" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "സാധുതയില്ലാത്ത ക്രിയാങ്കം" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "പിന്തുണയ്‌ക്കപ്പെടാത്ത സംക്രിയ" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "I/O തെറ്റ്" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "വസ്തുത തെറ്റുപറ്റിയതാണ‌്" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +#, fuzzy +msgid "Format not valid" +msgstr "തുറക്കുന്ന രീതി സാധുതയില്ലാത്തതാണ‌്" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "മോശമായ രചനാ വീതി" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "രചന വളരെ വലുത്" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "ഉപകരണത്തിന‌് ഇടതു വശത്ത് സ്ഥലമില്ല" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "സാധുതയില്ലാത്ത URI" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "രചന തുറന്നില്ല" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "തുറക്കുന്ന രീതി സാധുതയില്ലാത്തതാണ‌്" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "സ്വീകരിച്ചുകഴിഞ്ഞത്" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "ധാരാളം തുറന്ന രചനകള്‌‌" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "രചനയുടെ അവസാനം" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "ഒരു കൂട് അല്ല" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "രചന നിലവിലുണ്ട്" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "ഒരു കൂടാണോ" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "ഓര്മ്മയില്‌ ആവശ്യമായ സ്ഥലമില്ല" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "തലവനെ കാണുന്നില്ല" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +#, fuzzy +msgid "Host name not valid" +msgstr "തുറക്കുന്ന രീതി സാധുതയില്ലാത്തതാണ‌്" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "പ്രവേശനം പരാചയപ്പെട്ടു" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "കൂട് തിരക്കിലാണ‌്" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "കൂട് ശൂന്യമല്ല" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "ധാരാളം ബന്ധങ്ങള്‌‌‌" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "നാമം വളരെ നീണ്ടതാണ‌്" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "സേവനം ലഭ്യമല്ല" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "പെരുമാറ്റച്ചട്ട പിശക്" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "പ്രധാന തെരച്ചില് സഹായിയെ കണ്ടെത്താനായില്ല" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "അറിയാത്ത ഏതോ പ്രശ്നം" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 ബൈറ്റ്" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u ബൈറ്റ്സ്" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, fuzzy, c-format +msgid "%.1f K" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, fuzzy, c-format +msgid "%.1f GB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr "(അസാധുവായ യുണികോഡ്)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "പ്രയോഗങ്ങള്‌" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "രചനകള്" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "കൂടുകള്" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "സഹായം" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "ബന്ധങ്ങള്" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "തപാല്" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "ഉപകരണങ്ങള്" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "ജാലകങ്ങള്" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +#, fuzzy +msgid "Standard Moniker factory" +msgstr "സ്പന്ദന നിറ്മ്മാണശാല" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +#, fuzzy +msgid "generic file moniker" +msgstr "പൊതു പിശക്" diff --git a/po/mn.gmo b/po/mn.gmo new file mode 100644 index 0000000000000000000000000000000000000000..8bd69a79b0a88715117d0f768a2c00b9af41dc07 GIT binary patch literal 6634 zcmbW4Ym8iF8OLAbqAV5#?*j6AS<7v6d)S$CrgLW6 z?iaIdtu!fXA%$SPh6)8#>=n9YyCoqp24cvWVoZpaXo!hl)EE>$XpF!Ad(Q04ZWj|h z*?0cuy*=;q{GZEv_P1AF^r+#vhjumXiFX)N25-8UAD-V`V$7A`@4;D^A+z>k7Qvhi0y?f)exJ^lbnk2gVQ>ZPfDmw@kO{Blt1 zt_3dwbD+*yn&BEy^1c9Se*p4lqHKH|ls@}F@%KnJ{uHS7&x1Pu4EPc7Wl-n50e%Yn zBdGHib)IhW1<6}0phL5i>oL{&2cil;B}qxjzj>bwJ>=AQwj?-Zyw`4y=1M6&e0 z8blS-3Cg}(LGii){5Y5gIoj;a#vjYZe++(_@mE3l?eE|acp;m$e=|SgV-%G9!{D9Z zDXe(l%4m1TDJ}C2M=cWI(QHL zYcWc^ZUYyChrsK=SHSDRH$f;d*AS%gS2rkmUj}pFE^rxm1ndOg0Bhi-94@=Q3NmC4 zfEIi@!w23X^{QUJ=2zpc`O{%!%YJP%D%j8~`wLD- zg?hq3uZ;7QVQ~3Er`O{tn>=Uc zRI~Z2@6~);2`auFiK;fL_@P}pFtmzgpLm=&SP&L$*^9B&4p*Zcv0p__bGG7DW8dvq?bSRus#fcj8j7zD3gO~x zw`WtHW4~4l!eX4B?A1`LgN0Q;UyG{acDNpow{>;6U#`@~O+Ok$BW{=JuU0X!jKbRK zY%y#7(60u0>q{TA&M#HWx+t#U8c}JzLZONq(=o+C+g7)(rGvV$8CWuu$r=cuI`m4j z-7H8q4VZx}U@;Ssias+CThA7n9Gdk(I2N1rQ85VZh=<_?I#ETOz{OZ>{V_RJFbab)vU3Dyh@>s}iJTZuJ>Kd@B1nwI8Y{(SYd980 zJE#?5RQB&(vw5@ck8OjrZp}1bDL{(@~ zB}(ZxTVvt}uXQQ{w+GcIEc>BysT#-_VvCUQ^TEiti-3_40+jhul-9nk4s#zzQhkhb zd1i9|&YB;RpQe~)qqD?f3W4BAnVoUlnu9p&eu_?Rppd(lBqDcr#%xxlkC1n1(9^2F1x2!u| zx1JK3+fwzyxa8rcKD*fqOF_|6)T<=>?J3?RCzZpls9Id!vEB=db+72>w)kGTPkt^& zrN9gA?dhuASivucca>Dxy5gu_&HL2P{sCL4QgV;@SNkQ{sN z2(0g7C3K0j#@_SHb(eSYt>h>t?KUq>cg8RM$R>x9v#gy;Pe;uYj)SHa7FDN_w+qbt znTmOq4SVGw+t~ZsGf+SM+B4E~fej{k3>8m03TABMfDU0`T9irpS)BKLs%V0=_Z47;%xqM zls=o1A}gjE`%IE)ozl14v4KCpX_Fknwfi{FS$!01r#N`pIo~P31X?od!iG3$+mOcO z8AzVM;V!Sz{mndpfce{-45H*jx+jZI<;<+A3-Ho5rxco02xnZ+voqz4Bvl}wRqBl7 z%&Y`w9iiREb93kk>4n#ik{|QSg-IT5Ou*VqCUrh5yW}!Oj7gr951a@j9l&?<6MS|_ zdtRS^U{j8Z#yPP*E5Ib*Tap~iB@eY+^a!V`;!rx~xNbH^Gj+D|IoAr@rj9Qv4V@v> zt;WP0nyh$oM{}BTL}se?sZfvs6P&9=R|e7D&Fo||J56%f)mpM=ud^rHZxwQKmir}@ zp3Nl`7e_J?aTryO5-C~vRM|N{VN(`oqcl0e8O^+r4hVA|=rYN7HJ(o6V%0VZ?u0ae3 zNwCgQ(WO2~f9j7(4v|vSE+rQ6MnqXxY@|4vxvD2#t#~55TN~RVdN%vhqK{lZ85VXUf&yWYVLJraUf~uTS5IZNF zHOco8m?n=t3RDT*r9B&2ggHd;4dLQzvaw6ip`;hTTICE%>3w?!|4%86Ny4h-2jg;A z8K&Dj4O#bjqpMOCQr|YGt;|+)JS!Sqa*(vn40pB5Q0bqs*e(S7TwXi(o_8yrmpQrY zt2o#67H%MHQ59$}$&OuaZt*9gvtp1fOzXd<-S<*^v2TWDy3*Z@h;}THILK;Gtu#;9 zZWtQuU*La>w^{D|sE;IN;(`L1a~EBj8v58cu75k;W_7ceG)nUdx91Ud>nmeQ z9&&C=m2U2md$at^Zptj?DNHKz?dDQRh)YE*T, 2003. +# Sanlig Badral , 2003. +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs.HEAD\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-08-21 10:30+0200\n" +"Last-Translator: Sanlig Badral \n" +"Language-Team: Mongolian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Report-Msgid-Bugs-To: \n" +"X-Generator: KBabel 1.0.2\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d NUL тэмдэгт агуулж байна." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d методын нэр агуулаагүй байна." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d модулын нэр агуулаагүй байна." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "»%s« Тохируулгын файл олдсонгүй: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Тодорхойгүй үйлдийн төрөл %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "GIOChannel нээх шугам үүсгэгдэхгүй байна: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Тодорхойгүй ажилын хэв %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Үйлдэл зослоо" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Задлан ялгал боломжгүй: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Цаашдын задлан ялгалын алдааг хэрэгсэхгүй." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Алдаагүй" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Файл олдсонгүй" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Ерөнхий алдаа" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Дотоод алдаа" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Хүчингүй параметр" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Дэмжигдээгүй үйлдэл" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "О/Г-Алдаа" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Файл эвдэрчээ" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Формат хүчингүй" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Буруу файлын заагч" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "Файл хэтэрхий том" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Төхөөрөмж дээр үлдсэн зай алга" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Бичихээс хамгаалагдсан файлыэ систем" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "Хүчингүй URI" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Файл нээлттэй биш" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Нээх горим хүчингүй" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Хандалт нурлаа" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "Хэт олон нээлттэй файл" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Файлын төгсгөл" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Лавлах биш" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Үйлдэл явж байна" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Үйлдэл тасарлаа" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Файл оршин байна" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Цикл холбоос илэрлээ" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Үйлдэл зөвшөөрөгдөөгүй" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "Лавлах уу" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Хангалтгүй санах ой" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Хост олдсонгүй" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Хостын нэр хүчингүй" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Хост хаяггүй байна" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Бүртгэл бүтсэнгүй" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Үйлдэл буцаагдлаа" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Лавлах хэрэглэгдэж байна" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Лавлах хоосон биш" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "Хэтэрхий олон холбоос" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Бичихээс хамгаалагдсан файлын систем" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Өөрийнх нь файлын систем дээр биш" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Нэр хэт урт" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Үйлчилгээ хүрэх боломжгүй" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Хүсэлт үйлчилгээний өгөгдлийг хуучирууллаа" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Протоколлын алдаа" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "Эрхэм хөтлөгч олдсонгүй" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "Стандарт үйлдэл холбогдоогүй б/а." + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "URL схемийн хувьд тодорхойлогч алга" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "Тушаалын мөр шинжилж байхад алдаа" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "Тушаал ажиллуулахад алдаа" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Тодорхойгүй алдаа" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 байт" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u байт" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f кб" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f МБ" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f ГБ" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (хүчингүй юникод)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "Тодорхойгүй GNOMEVFSSeekPosition %d" + +# CHECK +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "Хүчинтэй тохируулгын файл %s -д олдсонгүй\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "Өөр байрлал тодорхойлохын тулд %s орчины хувьсагч хэрэглэнэ Ò¯Ò¯.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "Ð¥.програмууд" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "Карт" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "Файлууд" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "Лавлахууд" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "Тусламж" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "Хост" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "Холбоосууд" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "Э-захиа" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "Хэрэгэсэл" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "Цонхнууд" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Стандарт-Moniker-Үйлдвэр" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "Файл MonikerExtender" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "Ерөнхий GNOME-VFS-Moniker" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "Ерөнхий файл мoniker" diff --git a/po/ms.gmo b/po/ms.gmo new file mode 100644 index 0000000000000000000000000000000000000000..d7b9ba2f906c4db07a50da6d349103dca11d5f6a GIT binary patch literal 4757 zcmai$ON<;x8GtJxfn*8f!6ONTP!JZ|NoKukJ7n27j@OPKi@o+@??&N*T{B%X(>vW& zO;@)!gM<)@;1EtkLLwl9#0BLBxg@*}NI7soh{pj%2oxb9K_m_c4j}@G@9(aeSzDIU z+M2KH(N*=o_s@6T^i9QcoOU1W(2Yuc4xYVJGs4Kad!X#Q z2i^-0!B4<*P|gjIKlK%U?uO4nk@x%XPWTf1FnkrtJzkIeH~awoTeyVqekk7`g7V#2 zDCd7Z&gYTOLe2OKvHufz5B=XjS^sw^=e!9&3U8Zh@A)v4@f9fYor7|&fva!_z90S= zik!cW{lCHD2BrQN`wnHGBK0i9MC$9Y|2!0XejAE@UV#t5KgIbQP?oH}6^efDfO4LO zEASDx7Zy#V5z6`~lufd1m8&JN#8(}{P_dw|%fwJx#6ge+J(PMxj?^omew;)@n z7vYEC%W?j9k$;7#PQ3|b-HmK6-`@d6&ksPk_hHBq_1QRn8FuK8(9^w~AXiw1g z(d3+iG}%{lv-^3R&ZlVN6Y@Mn+d~sym^_d2BC;Nv4D8~5-WOViJEbyoL=rZm0EmSN%AY3FrrtD#S{Gr7I)v`^~H zPNr+!9alD}rG{#?*Rvt$#Jbcb>X=D%KV|XIxFoacxN*)`x>s6LSzV-s)qP)TUs$J4 zt(`y4GH0_DJs;F@@A~PWE=`qs*KTroKJ3vuCTQ8C?`xODm378#Wh`}x&P_lt-7Wo2 zuqFFUW(!jW+kEk)sSFA!%ettz<&$aR_QbD^Zj~BrRi$na+LKMimF8Gj+Fs?$vF_Gk zysImR+q|g8>I66N{pKrmQY5#}q@fD!`}E$ku87|DD(`hS9jKGO%sEfiHdj%ntg~g> z)3z*qsZRS)p-xePHc3*V?RHGewd<>9-R!`%{paHbYYz1|lTEwPi!Q9Gwdhf3ip|75 z)LPI+Clk5VSwBdzhC#A~jxW%W&QdoD+PWSl;Ui|&eTjL|w@f$p4tgieGTpU09XMu_ z1$9m?EK+CQ4b(XwFT_hIOwa1f_A8C;6MH4?Sr$}RT}ArV`Fb$KVRMYqtYCdLv^vP% zjpv0i?vShV;$k^rvP(sbMfd6%*Rz?(G#f+CqV$7C!MjJ1F#64GRP@Ydd0L4-&BjCJ zi-M7j(pSFcCpy1ii3{(t@l{up(av>7zffCD?z_Qf*d%DYS`@N}D8rA{#kSkXWv*Zu z(hBAw6eQztK8w05-N zL)t{*d@`MH9dfdI+jsRy0&u>buJDDf#sqmY6zZbzB?^*wZxye$0xp2P=EZ-mq@{Pc zb>jGCDq`RsID_q_{c&UaejoQ@KJ&dMFD%Td#>i2~6VFuEB?SE-hD;-YMg&aXs9`$O zd^Q=xJlh0zXD#VGh0~L8Ry1Ck+s>7K(5FwVJ~_8>ezS92(iW2)@&}3Jz~bV;&f;?C zz$1F;;L6hSLyL^CuyX;2l}%>r4s;fmI!lXsacSkiqYo`Ev+gWusBD(>Dfh$Vl98FCV>9%Aq381>?BNEr8Q9LIHTjA@X2=Uh zuiMOwYkhcNx+d*l)^VM8S$Q;*OtcVuUG^+#cVHKst&YsCudSb$$-T6&I7jY9kz5bk zt?0@=Q|&J@ipOJ3;UG0WzO{L>vpicTVqlui335O}%&+L>Zd%Pf-Dz@HE8m%8rfW03 zxUf7&@rp%DS7~BKgzNBa$`@`iz@uw7NVORS5|k9ONqK5_*}aBrXksCIyG2sYSko4= zX&oB{LJe6^`p7tS2FIe>nl}0A(g!nAo6Y4DQ;@GYyq6Z#mBOTjCK1*nJu7K?i~-oL zTaQdrf=&{sdNiqVA=OQBYvoAN?K)?hX5l94VefW?B$J_nP?wrWt4HcIiYSO@)7MpP z+{1cc2BdcCXl3vz>S$BzDqLbXx%5>VN-D>~6*9Q?lGp+n5;LuMBiu99LGIp^ytdz7 zb>xF2?+vUothc#ZQyWwxU3=&b!$}-y)fJ_?dQ22E`K-)LhBYi!o>as3G_IyD7~(~@ z0gn7WL>Hn46tx>0+#|#Gm6R8whtqlacD8z=;} z!JwXvL{I5jXUg46lXOU8Y9g|A1WI(}M?PzPC*HJcdPZ`J*`_@1y8P~O#7+s4riQj9 zHMGKwto-9g6ruSqHonm6w<)_pomp$_Hz}(dso629+KeV4&yI<&qOtb1qfM-}IY3>v zwl+zkRcAucuFSAbH3hd7^?I}FGyJ0+GzETpVu)Q|)^S?OaMb8@*O{`f+Bcv~T +# 2. Hasbullah Bin Pit (sebol) +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs HEAD\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2002-01-10 01:27+0800\n" +"Last-Translator: Mohamad Afifi Omar (App) \n" +"Language-Team: Bahasa Melayu \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 0.8\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d mengandungi aksara NUL." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d tidak mengandungi nama method." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d tidak mengandungi nama modul." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Fail konfigurasi `%s' tidak dijumpai: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Jenis op tidak diketahui %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "Tidak dapat mencipta paip untuk GIOChannel yang dibuka: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Jenis kerja tidak diketahui %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Operasi dihentikan" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Harap maaf tuan, gagal hantar: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Ralat penghantaran seterusnya akan diabaikan." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Tiada ralat" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Fail tidak dijumpai" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Ralat generik" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Ralat dalaman" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Parameter yang tidak sah" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Operasi yang tidak disokong" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "Ralat I/O" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Data telah rosak" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Format tidak sah" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Kendalian fail rosak" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "Fail terlalu besar" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Tiada lagi ruang simpanan" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Sistem fail baca sahaja" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "URI yang tidak sah" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Fail tidak dibuka" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Mod buka tidak sah" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Akses dinafikan" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "Terlalu banyak fail dibuka" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Penghujung fail" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Bukanlah satu direktori" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Operasi sedang dilaksanakan" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Operasi terganggu" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Fail telah wujud" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Pautan berulang dijumpai" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Operasi tidak dibenarkan" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "Ialah satu direktori" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Memori tidak mencukupi" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Hos tidak dijumpai" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Nama hos tidak sah" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Hos tidak mempunyai alamat" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Logmasuk gagal" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Operasi dibatalkan" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Direktori sibuk" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Direktori tidak kosong" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "Terlalu banyak pautan" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Fail sistem baca sahaja" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Bukan pada sistem fail yang sama" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Nama terlalu panjang" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Tiada servis" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Meminta data servis yang ketinggalan zaman" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Ralat protokol" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "Tak menjumpai pelungsur induk" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Ralat yang tidak diketahui" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 byte" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u byte" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (Unicode tidak sah)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "GnomeVFSSeekPosition yang tidak diketahui %d" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "Tak menjumpai fail tetapan yang sah pada %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "Guna pembolehubah oersekitaran %s untuk menyatakan lokasi lain.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +#, fuzzy +msgid "Files" +msgstr "Fail telah wujud" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "KIlang Moniker Piawai" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "MonikerExtender fail" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "Moniker Gnome VFS generik" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "Moniker fail generik" diff --git a/po/nl.gmo b/po/nl.gmo new file mode 100644 index 0000000000000000000000000000000000000000..3b5fb75b912b9e67012139ead7ebf7b0f3299f22 GIT binary patch literal 5270 zcmaKvX^b346@V)TIW{3cfCNYam1D7!Fymc^B+EKJ*7n-o*y}akwL#)YYPxG?+S5}t z>F$~JS|mb<{6xrzz#jzS5<*b~zX%8+MFOEnN%#dwC=!Q4g!lpCPXKX9e6PBDX1oMS zuKlL&SMR-gul?&AuY5{T)~L5qKYzJWJ$U^a_(S>rRZ86me*mwBFGBvQpI7ad;k#+S zQt@&oN&9yAMtA^T4^P53!H>XuU=PX>Ux0VRFTva3PvKkP@8J#b?{Fu)`kJym2W5Oe zybi9zo8cqyU2wDN{~VO{Uxp&bGf?FCA(V5Uhit8W2Hy;S31!|N;Fa(-DChj6;tki9 z``rO${XFEKda&wWf+Ei;DEj(n)$gIqe*((+pN8**7onWQyjvAN1K&>js}-Mxvi>C~>t2PTpTAY(S0TL2zZGh@ zyK1k)chF9t%>NXWb1p);*EivN;L}j#f1w)x6%;-E3Cg~5`6X}@6uo~Kz70MKMIXbe z{aLu@GNryzwSUW|GXFIwe)sRHeI>%keXfV%H+MnN+d(MzdjxW{dJM|E$KgHjDJc6r z2OIEtsNrAXP4H%vEBbBnXBXTDWj_bSPd-_-FG7*~>+p8?BPjR$O~u!sthJ$`z_&5}OM^OCv6Hxa3B9!&dK=F%bAu3YOL0SJ26n(x7F{%1X zHU7`4{~Cl5JKYB5{Jrpf@Gz8p9)lV_0p*;pKso>0RsT<*ock)2bN&qF-dA8`(eEr2 zzt{^IQXhmeFM@KP^AJ(gMJVTe4T`?q}7s@O>0&x2Iax0K})!S46-d$wu|#79xNx|e#Kx#Endv#QKa&A|Knk)ogRVt&biodA!6b&3th-){%FGNnEZ^o;jhT zuE|VP*eq{uA9h~%ZPE3ycBXG%ci6|n)K9y?GV$PO&9fS&eSaCuXpXFGt9z%_}Q;!ZzmfNu6uqg~W$+F>~K=8v! z>~>VEjV|??+oDKZCofMn1%k~mF|$$Ovn|~k=37%uIo$RK#gIR^(B~Y&uZKd|qH0QKdF{_e#T5+h_nRMK& zobvRFTB#hAYqF(yn_9`W(Q&Oqbs}-ST%GWp#Ob!-;xP?B5S^flUaqZ+FfvOSS!IG+ z^%=fX=`GwQ*PBV2>Xy|>$1xf=)k(R5XeRZpqfUC}qV zh!kE!zJ+u4)tb0{pLaW@YWgZ?kBp0KD*Bl8p`$_OJHb%Xy=bTM;z_UAi_Q8;A(x!= z=Y<~(=sA`7!biTg+G)#M^)B7IL`3OryiV_9LyPP9R_;@*nrq&eC}am=fLEo~%VxNj z8DTWj;`Of=_&v{BuX>mCc%5yGAxhf7PP~b&(&Ce*7X^vNa_LKRb;k9a-y~Kz-?wLv ztglpO16^zpenMA191MJhnj{jH>Q`rS{0FPe ziU*F8%)7pI@|LnhE`x935;jWOTfqa`Z5)*G)R(cZIio(rkwhOAOkQ1i`Fvp=?^AWE z*BEZ1xeAUDlrkO(%j!;yb&jCZScw~Fc|>^dVyT42sGZN8TH9zGl9)<=gRn+?+dVgT zUt?~evHN~Kf8XN#!o73!FtKqO&z1Gt=FKhW-Mbg(AGmjJo_QyTo{f#nxI8sjXi=X{ zaK>F_M{LuZ>KRv~8riHM zWx37)mp0+>eA8#0eKV^otILzC%{S*}2>s{^F)-7jF6{YY*B~W*?Fp%i$h`N=#*xOt zWS)qN6&lL~jF=M^^+GEtW|ZDZ2(W3KbgbT%C|j2%N}3^2w(N+|NtSFBwrAZqLzev= zE6+A0Nb8L0*9mfZG~~x}aKqaUs?Z&~X%Qg{FRw#5?3*3AT2F1%B^S1MPrQ!2QDw^G z#<7Bf2FbaBB+MT_jeqHpCzou?l*f(1cinWZwAFTcha}5{0H4@`{YD<=!*$57$3qm; zUGLj*qe_$Iv=M&Gb}}I>!(^K_Ll2Xz$@Y9dpwXDLf>@<`HQyEmAq(AGS4&VI${@$i z5W)u{5Uq}FWy7Rb_k^=jYddOL1mLB)S}P>8VL^^Nr%{sJm3JER_0laSBZdUDMHreI z%q()LgQaH6y)bKLEgu$j?BG-k_5!wCE7OW4!4mwpPYXU+ z5GKS^&D477@PlHUs)H7m_$IKfk=hGrb-S4VcMxk|@U};)H9he{o+iO9JTz`xrEorw zh(}r1m^2>e@j8NV9FE*;VX7*dPo?v=X=RD+sSUQZ>9o7lU81^LWb|~D*UDQYl89Ma z5^9m-f93YcjG%_PsZm+4PUYiHPRbf}uUNMcG*5Wq{|lI*vIioB7{vFSCeiyoDiPb3 zS>BT7eP7FCAv7awmEC2%_;1i3iT*5F3{SGMM*V#=PWGmb2>+e!$3wLx>x};&n, 2003. +# +msgid "" +msgstr "" +"Project-Id-Version: Gnome-vfs\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-08-08 22:16+0100\n" +"Last-Translator: Vincent van Adrighem \n" +"Language-Team: Dutch \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +# hier wordt waarschijnlijk NULL bedoeld ipv NUL +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d bevat NUL-tekens." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d bevat geen methodenaam." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d bevat geen modulenaam." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Configuratiebestand '%s' is niet gevonden: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Onbekend oper-type %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "Kan geen pijp creëren voor GIOChannel: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Onbekend taaktype %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Operatie gestopt" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Kon niet verwerken: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Volgende verwerkingsfouten worden genegeerd." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Geen fout" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Bestand niet gevonden" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Algemene fout" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Interne fout" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Ongeldige parameters" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Niet-ondersteunde operatie" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "I/O-fout" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Data beschadigd" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Ongeldig formaat" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Slechte bestands-handle" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "Bestand te groot" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Geen ruimte vrij op het apparaat" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Alleen-lezen bestandssysteem" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "Ongeldige URI" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Bestand niet open" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Ongeldige openingsmodus" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Toegang geweigerd" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "Teveel open bestanden" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Einde van bestand" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Geen map" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Operatie is bezig" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Operatie onderbroken" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Bestand bestaat reeds" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Circulaire koppelingen gevonden" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Operatie niet toegestaan" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "Is een map" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Onvoldoende geheugen" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Machine niet gevonden" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Machinenaam is niet geldig" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Machine heeft geen adres" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Inloggen niet gelukt" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Operatie afgebroken" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Map is in gebruik" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Map is niet leeg" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "Teveel koppelingen" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Alleen-lezen bestandssysteem" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Niet op hetzelfde bestandssysteem" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Naam te lang" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Service is niet beschikbaar" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Verzoek maakt gegevens van de service achterhaald" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Protocolfout" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "Kon de hoofd-browser niet vinden" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "Geen standaardactie gedefinieerd" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "Geen actie voor URL schema" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "Fout bij analyseren opdrachtregel" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "Fout bij starten opdracht" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Onbekende fout" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f Mb" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f Gb" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (ongeldige Unicode)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "Onbekende GnomeVFSSeekPosition %d" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "Geen geldig instellingenbestand gevonden in %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "Gebruik de %s omgevingsvariabele om een andere locatie op te geven.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "Programma's" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "Kaarten" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "Bestanden" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "Mappen" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "Hulp" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "Computers" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "Verwijzingen" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "E-mail" + +# Translate exactly the same in CDE's sys.dtwmrc file of the locale +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "Gereedschap" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "Vensters" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Standaard Monikerfabriek" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "bestand MonikerExtender" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "algemene Gnome VFS moniker" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "algemene bestandsmoniker" diff --git a/po/nn.gmo b/po/nn.gmo new file mode 100644 index 0000000000000000000000000000000000000000..c21d861b00fc751431e282c8a5207d3a1cf801ef GIT binary patch literal 4489 zcmaKuUu+yl9mj_@;g2D0DJ@VaW%|cW(&U`8ofgMULlVbMO=3I5cAyeM-MgJzuWxVW z*x7S(5~#ej4@jj#2rBvjLKTsUctRplgh2H}o_MPeq6i)Wl`44S0SQ!<&u@0`e6a$n zoBiI*{N^{m|G)k7y?ef|cup}MWIT3k54!F#}C)%uq};s4bNGf>Wb8~h0Pay5Sy6#iGid%<5;>o-8*`+M*K z@Fw^e_#P7e%iv9i#egPcgkmz$7{3Lh@6g@kj(0#L-e+Lx4KLW-7zW~K9zXAEF zKk$-xeFyvuxECgJUW1}X9Yh5+Q{fpM|DExj>t^XFpMCvW@5%4dd z`0)-d5qa(dg?=2=;2BW(7*Otc0Tlhe2a0@GL5YWLP~?9b6o0)7%DMMJvGW5k{~UM% z6n(!2%Dp{M_`L|qy|00y-*r&zbORK+KUVX9fOE{>2j!kQHbsu-K;ct>gh8+c5Nd_^ z^*G}hhWPLa#w0`JJH!}$o@R2CL3s$zLEhtxnQ|K5Px2OBPlnm8uNu?C48kJ#3vtv5 zhCGO@o(liUm&Dzj4AEO2&A?p4N9_9Oa8~}293>?}%!xlF*2J#I81jg%#cp+m*m)0Q znsJ07exG27eI@5kG31$I90>oEngt(bJkAiiicQ7Nl-m$5fcm1m#wR9Q`t0cv&y}#m z)X$E`y6J2YrPk}^_4B&95#>>{Fu9-Dy=|TDm}0}l+D097+ie&3GBeoj=|;aWUQGs6 zr&ubX!lUJSHm)dp8Pc-WjdE|o+L@?`P&va4LQPn+80xy#kF&KDR=)YMTN=h(Ac6NikP z3UoUcE*@E_7%W;mYoly9EfrqBxTqFw`5#NcOaeeHdQ1`z^j7Cxl49=&&0;35i;Z-a z+P2rmHZeMf*jaKp4#eKF9pv`pCFzcj+#M92YFI>0F%7xq&uIUCgzi5bjXS4n-BFbv* zHml$08C>of-evg26PmdgWIuUC9IMrG8eAW3;hCsGF0B^iRFubh$=S4Ra(osdSFK_2 zPGtL~*LJ2(3?vrwYTdT2yG+hm*D;qCR#%N_UvNGRxi%gT_sf7BP;a`1Zc7S{_l6X% ztBXEq9F}~q+jThxl8i15uhu;wfWO8iezwxw*^aRi_<1U75FP}BX{N1y@O`UAc(I?k zX2|@BF%_I#DLH?oFg7;1N~)9z8fa9&^}!6oop5Zhhld5O+Be6r)MW;4%JzKuy&D%6)rn;Q?>eJ zZMv@OM`w>db*MfG-TBBDwY5C5K8vU+v-+az*OsEh8hoaY=N)&__pBwd&4e|@2@cq# z7bT{)W}?olUUvCqlcbT=2bTM!ly4u@$E`h?r4uesPK+%rF3s<#gA!vDP3*&^xMWrr z=1Os-n^ErsQGUNHZZPDP5yPL)VNsM>UjYK>H7wN$Hc9krVE3M!B=C;z3NMB21Horgrr)dG!kAbgrt+k^9x_`@YJ z3Pp<}p$i#G?0~M6w(LgKO5HNBB3%e6`q6+2uSSEuWMtbH;<(*x9v+oxORTiGUJD${ z_Ed5Y?!-dUo2vf@%t0OHNl(gzn$Iz#)$P(yY5|G#7WD;-VmLZgqE^$q&G!iHC^MF@ z3$~1-BvLC}ODWZDM>(V~i2rQx0c=8dBI`tMu}MaBA)}?Rl%g%}#4v3G8ObERY{UhK z1e-{eB%=Zj59tmf^7&LQ$f20K22HDMS*DDI2D)$aDSd{eYRG3o@_OSL9at>$yVlud0dED^+mxRMOtG}u2gICWQZtF@v=j_?w- z(%h1vw?|e&o+BXbVVyvrQT@;UR&EFFDpHzTW7x^cZP%?0SA4O3t)LEt#wJ!*r}JK0 zx>_gAHn*>p{S4Wyb{!q}^cImyWAkY%B?kFQOf@+gl~Kgko=tAk+VYX!=G&$C(%fo; OJ{H, 2001. +# Roy-Magne Mo , 2001-2002. +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs 1.0.3\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2002-01-30 04:46+0100\n" +"Last-Translator: Roy-Magne Mo \n" +"Language-Team: Norwegian (Nynorsk) \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d inneheld NUL-teikn." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d innheld ikkje noke metodenamn." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d inneheld ikkje noke modulnamn." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Oppsettfil «%s» vart ikkje funnen: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Ukjend op-type %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "Kan ikkje opprette røyr for dem opne GIOChannel: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Ukjend jobbtype %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Operasjonen vart stoppa" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Kunne ikkje tolke %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Overser komande tolkningsfeil." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Ingen feil" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Fann ikkje fil" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Generell feil" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Intern feil" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Ugyldig(e) argument" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Ustøtta operasjon" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "IU-feil" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Data korrumpert" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Formatet er ikkje gyldig" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Ugyldeg filhandtak" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "Fila er for stor" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Ikkje noke ledig plass pÃ¥ eininga" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Ikkje skrivbart filsystem" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "Ugyldig URI" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Fila er ikkje open" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Modus for opning er ikkje gyldig" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Nekta tilgang" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "For mange opne filer" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Slutt pÃ¥ fila" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Ikkje ein katalog" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Operasjonen pÃ¥gÃ¥r" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Operasjonen avbroten" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Fila eksisterar" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Sirkulere lenkjer oppdaga" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Operasjonen ikkje tillaten" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "Er ein katalog" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Ikkje nok minne." + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Fann ikkje vert" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Verstnamn er ikkje gyldig!" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Verten har ikkje noka addresse" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Feil ved innlogging" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Operasjonen vart avbroten" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Katalog er oppteken" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Katalogen er ikkje tom" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "For mange lenkjer" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Kun lesbart filsystem" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Ikkje pÃ¥ det same filsystemet" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Namnet er for langt" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Tenesta er ikkje tilgjengeleg" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Spørjing forelda tenesten sine data" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Protokollfeil" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +#, fuzzy +msgid "Could not find master browser" +msgstr "Kunne ikkje tolke %s" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Ukjend feil" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 byte" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u bytes" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr "" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "Ukjend GnomeVFSSeekPosition %d" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "Klarte ikkje Ã¥ funne ei gyldig innstillingsfil pÃ¥ %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "Bruk %s miljøvariabelen om du vil spesifisere ei anna plassering.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +#, fuzzy +msgid "Applications" +msgstr "Detaljar for KDE-applikasjonar" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +#, fuzzy +msgid "Files" +msgstr "Fila eksisterar" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +#, fuzzy +msgid "Folders" +msgstr "mappe" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Standard Moniker-fabrikk" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "file MonikerExternder" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "generisk Gnome VFS-moniker" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "generell fil-moniker" + +#~ msgid "3D Studio image" +#~ msgstr "3D Studio bilete" + +#~ msgid "AIFC audio" +#~ msgstr "AIFC-lyd" + +#~ msgid "AIFF audio" +#~ msgstr "AIFF-lyd" + +#~ msgid "ANIM animation" +#~ msgstr "ANIM-animasjon" + +#~ msgid "AVI video" +#~ msgstr "AVI-video" + +#~ msgid "AbiWord document" +#~ msgstr "AbiWord-dokument" + +#~ msgid "Adobe FrameMaker font" +#~ msgstr "Adobe FrameMaker skrifttype" + +#~ msgid "Adobe font metrics" +#~ msgstr "Adobe skrifttypemetrikk" + +#~ msgid "Andrew Toolkit inset" +#~ msgstr "Andrew Toolkit innsats" + +#~ msgid "ApplixWare Graphics image" +#~ msgstr "Applixware grafikkobjekt" + +#~ msgid "Applixware Words document" +#~ msgstr "Applixware Words-dokument" + +#~ msgid "Applixware spreadsheet" +#~ msgstr "Applixware reikneark" + +#~ msgid "AutoCAD image" +#~ msgstr "AutoCAD-bilete" + +#~ msgid "BCPIO document" +#~ msgstr "BCPIO-dokument" + +#~ msgid "BDF font" +#~ msgstr "BDF-skrifttype" + +#~ msgid "C shell script" +#~ msgstr "C-skalskript" + +#~ msgid "C source code" +#~ msgstr "C-kjeldekode" + +#~ msgid "C source code header" +#~ msgstr "C-kjeldekode header" + +#~ msgid "C++ source code" +#~ msgstr "C++-kjeldekode" + +#~ msgid "CGI program" +#~ msgstr "CGI-program" + +#~ msgid "CGM image" +#~ msgstr "CGM-bilete" + +#~ msgid "CMU raster image" +#~ msgstr "CMU raster-bilete" + +#~ msgid "CPIO archive" +#~ msgstr "CPIO-arkiv" + +#~ msgid "CPIO archive (gzip-compressed)" +#~ msgstr "CPIO-arkiv (gzip-komprimering)" + +#~ msgid "DCL script" +#~ msgstr "DCL-skript" + +#~ msgid "DOS font" +#~ msgstr "DOS-skrifttype" + +#~ msgid "DOS/Windows program" +#~ msgstr "DOS/Windows program" + +#~ msgid "DSSSL document" +#~ msgstr "DSSSL-dokument" + +#~ msgid "DXF vector graphic" +#~ msgstr "DXF vektorgrafikk" + +#~ msgid "Debian package" +#~ msgstr "Debian pakke" + +#~ msgid "Dia diagram" +#~ msgstr "Dia diagram" + +#~ msgid "Dolby Digital audio" +#~ msgstr "Dolby Digital lyd" + +#~ msgid "Emacs Lisp source code" +#~ msgstr "Emacs Lisp kjeldekode" + +#~ msgid "Enlightenment theme" +#~ msgstr "Enlightenment-tema" + +#~ msgid "FLC animation" +#~ msgstr "FLC-animasjon" + +#~ msgid "FLI animation" +#~ msgstr "FLI-animasjon" + +#~ msgid "FastTracker II audio" +#~ msgstr "FastTracker II lyd" + +#~ msgid "Fortran source code" +#~ msgstr "Fortran-kjeldekode" + +#~ msgid "FrameMaker interchange document" +#~ msgstr "FrameMaker interchange dokument" + +#~ msgid "G3 fax image" +#~ msgstr "G3 faksbilete" + +#~ msgid "GIF image" +#~ msgstr "GIF-bilete" + +#~ msgid "GIMP document" +#~ msgstr "GIMP-dokument" + +#~ msgid "GMC link" +#~ msgstr "GMC-lenkje" + +#~ msgid "GNOME application details" +#~ msgstr "Detaljar for GNOME applikasjoner" + +#~ msgid "GNU Oleo Spreadsheet" +#~ msgstr "GNU Oleo-rekneark" + +#~ msgid "GNU mail message" +#~ msgstr "GNU e-post melding" + +#~ msgid "GTK configuration" +#~ msgstr "GTK-oppsett" + +#~ msgid "Glade project" +#~ msgstr "Glade prosjekt" + +#~ msgid "GnuCash Workbook" +#~ msgstr "GnuCash arbeidsbok" + +#~ msgid "Gnumeric spreadsheet" +#~ msgstr "Gnumeric reikneark" + +#~ msgid "HDF document" +#~ msgstr "HDF-dokument" + +#~ msgid "HTML page" +#~ msgstr "HTML-side" + +#~ msgid "IDL document" +#~ msgstr "IDL-dokument" + +#~ msgid "IEF image" +#~ msgstr "IEF-bilete" + +#~ msgid "IFF image" +#~ msgstr "IFF-bilete" + +#~ msgid "ILBM image" +#~ msgstr "ILMB-bilete" + +#~ msgid "ISI video" +#~ msgstr "ISI video" + +#~ msgid "Impulse Tracker audio" +#~ msgstr "Impulse Tracker lyd" + +#~ msgid "JBuilder Project" +#~ msgstr "JBuilder-prosjekt" + +#~ msgid "JPEG image" +#~ msgstr "JPEG-bilete" + +#~ msgid "Java byte code" +#~ msgstr "Jave byte-kode" + +#~ msgid "Java source code" +#~ msgstr "Java kjeldekode" + +#~ msgid "KIllustrator document" +#~ msgstr "KIllustrator-dokument" + +#~ msgid "KPresenter presentation" +#~ msgstr "Kpresenter-presentasjon" + +#~ msgid "KSpread spreadsheet" +#~ msgstr "KSpread-reikneark" + +#~ msgid "KWord document" +#~ msgstr "KWord-dokument" + +#~ msgid "Korn shell script" +#~ msgstr "Korn skalskript" + +#~ msgid "LHA archive" +#~ msgstr "LHA-arkiv" + +#~ msgid "LHARC archive" +#~ msgstr "LHARC-arkiv" + +#~ msgid "LIBGRX font" +#~ msgstr "LIBGRX skrifttype" + +#~ msgid "LightWave object" +#~ msgstr "LightWave-objekt" + +#~ msgid "LightWave scene" +#~ msgstr "LightWave-scene" + +#~ msgid "Linux PSF console font" +#~ msgstr "Linux PSF konsoll-skrifttype" + +#~ msgid "Lotus 1-2-3 spreadsheet" +#~ msgstr "Lotus 1-2-3 rekneark" + +#~ msgid "M3 audio URL" +#~ msgstr "M3 lyd-URL" + +#~ msgid "MIDI audio" +#~ msgstr "MIDI-lyd" + +#~ msgid "MOD audio" +#~ msgstr "MOD-lyd" + +#~ msgid "MP3 audio" +#~ msgstr "MP3-lyd" + +#~ msgid "MP3 audio playlist" +#~ msgstr "MP3-lyd spelelister" + +#~ msgid "MPEG video" +#~ msgstr "MPEG-video" + +#~ msgid "MS ASF video" +#~ msgstr "MS ASF-video" + +#~ msgid "MS video" +#~ msgstr "MS-video" + +#~ msgid "Macintosh AppleDouble-encoded file" +#~ msgstr "Macintosh AppleDouble-koda fil" + +#~ msgid "Macintosh BinHex-encoded file" +#~ msgstr "Macintosh BinHex-koda fil" + +#~ msgid "Macintosh StuffIt archive" +#~ msgstr "Macintosh StuffIt arkiv" + +#~ msgid "Macromedia Flash file" +#~ msgstr "Macromedia Flash fil" + +#~ msgid "MathML document" +#~ msgstr "MathML-dokument" + +#~ msgid "Microsoft Excel spreadsheet" +#~ msgstr "Microsoft Excel reikneark" + +#~ msgid "Microsoft PowerPoint document" +#~ msgstr "Microsoft PowerPoint-dokument" + +#~ msgid "Microsoft Word document" +#~ msgstr "Microsoft Word-dokument" + +#~ msgid "Microsoft video" +#~ msgstr "Microsoft video" + +#~ msgid "Nautilus link" +#~ msgstr "Nautilus lenke" + +#~ msgid "ODA document" +#~ msgstr "ODA-dokument" + +#~ msgid "PBM image" +#~ msgstr "PBM-bilete" + +#~ msgid "PCF font" +#~ msgstr "PCF-skrifttype" + +#~ msgid "PDF document" +#~ msgstr "PDF-dokument" + +#~ msgid "PEF program" +#~ msgstr "PEF-program" + +#~ msgid "PGM image" +#~ msgstr "PGM-bilete" + +#~ msgid "PGN chess game" +#~ msgstr "PGN-sjakkspel" + +#~ msgid "PGP keys" +#~ msgstr "PGP-nøkler" + +#~ msgid "PGP message" +#~ msgstr "PGP-melding" + +#~ msgid "PGP signature" +#~ msgstr "PGP-signatur" + +#~ msgid "PGP-encrypted file" +#~ msgstr "PGP-kryptert fil" + +#~ msgid "PHP script" +#~ msgstr "PHP-skript" + +#~ msgid "PN RealAudio document" +#~ msgstr "PN RealAudio- dokumentet" + +#~ msgid "PNG image" +#~ msgstr "PNG-bilete" + +#~ msgid "PNM image" +#~ msgstr "PNM-bilete" + +#~ msgid "PPM image" +#~ msgstr "PPM-bilete" + +#~ msgid "Palm OS database" +#~ msgstr "Palm OS database" + +#~ msgid "Perl script" +#~ msgstr "Perl skript" + +#~ msgid "Photoshop document" +#~ msgstr "Photoshop-dokument" + +#~ msgid "PostScript Type 1 font" +#~ msgstr "Postscript Type 1 skrifttype" + +#~ msgid "PostScript document" +#~ msgstr "PostScript-dokument" + +#~ msgid "Python source code" +#~ msgstr "Python kjeldekode" + +#~ msgid "QuickTime movie" +#~ msgstr "QuickTime-film" + +#~ msgid "Quicken document" +#~ msgstr "Quicken-dokument" + +#~ msgid "Quicken for Windows document" +#~ msgstr "Dokument for Quicken for Windows" + +#~ msgid "RAR archive" +#~ msgstr "RAR-arkiv" + +#~ msgid "README document" +#~ msgstr "README-dokument" + +#~ msgid "RGB image" +#~ msgstr "RGB-bilete" + +#~ msgid "RIFF audio" +#~ msgstr "RIFF-lyd" + +#~ msgid "RPM package" +#~ msgstr "RPM-pakke" + +#~ msgid "RealAudio/Video document" +#~ msgstr "RealAudio/Video-dokument" + +#~ msgid "RealVideo video" +#~ msgstr "RealVideo-film" + +#~ msgid "S/MIME file" +#~ msgstr "S/MIME-fil" + +#~ msgid "S/MIME signature" +#~ msgstr "S/MIME-signatur" + +#~ msgid "SGI video" +#~ msgstr "SGI-video" + +#~ msgid "SGML document" +#~ msgstr "SGML-dokument" + +#~ msgid "SMIL script" +#~ msgstr "SMIL-skript" + +#~ msgid "SQL code" +#~ msgstr "SQL-kode" + +#~ msgid "SV4 CPIO archive" +#~ msgstr "SV4 CPIO-arkiv" + +#~ msgid "SV4 CPIP archive (with CRC)" +#~ msgstr "SV4 CPIP arkiv (med SRS)" + +#~ msgid "SVG art" +#~ msgstr "SVG-bilete" + +#~ msgid "Scheme source code" +#~ msgstr "Scheme kjeldekode" + +#~ msgid "Scream Tracker 3 audio" +#~ msgstr "Sream Tracker 3 lyd" + +#~ msgid "Scream Tracker audio" +#~ msgstr "Scream Tracker lyd" + +#~ msgid "Scream Tracker instrument" +#~ msgstr "Scream Tracker instrument" + +#~ msgid "Setext document" +#~ msgstr "Setext-dokument" + +#~ msgid "Speech document" +#~ msgstr "Syntetisk tale" + +#~ msgid "Speedo font" +#~ msgstr "Speedo-skrifttype" + +#~ msgid "Spreadsheet Interchange document" +#~ msgstr "Spreadsheet interchange dokument" + +#~ msgid "Stampede package" +#~ msgstr "Stampede-pakke" + +#~ msgid "StarOffice Writer document" +#~ msgstr "StarOffice Writer-dokument" + +#~ msgid "StarOffice presentation" +#~ msgstr "StarOffice presentasjon" + +#~ msgid "StarOffice spreadsheet" +#~ msgstr "StarOffice-rekneark" + +#~ msgid "Sun mu-law audio" +#~ msgstr "Sun mu-law lyd" + +#~ msgid "SunOS News font" +#~ msgstr "SunOS NEWS-skrifttype" + +#~ msgid "TIFF image" +#~ msgstr "TIFF-bilete" + +#~ msgid "TarGA image" +#~ msgstr "TarGA-bilete" + +#~ msgid "Tcl script" +#~ msgstr "Tcl-skript" + +#~ msgid "TeX document" +#~ msgstr "TeX-dokument" + +#~ msgid "TeX dvi document" +#~ msgstr "TeX dvi-dokument" + +#~ msgid "TeX font" +#~ msgstr "TeX-skrifttype" + +#~ msgid "TeX font metrics" +#~ msgstr "TeX skrifttypemetrikk" + +#~ msgid "TeXInfo document" +#~ msgstr "TeXInfo-dokument" + +#~ msgid "ToutDoux document" +#~ msgstr "ToutDoux-dokument" + +#~ msgid "TrueType font" +#~ msgstr "TrueType-skrifttype" + +#~ msgid "USENET news message" +#~ msgstr "USENET diskusjonsmelding" + +#~ msgid "Unidata netCDF document" +#~ msgstr "Unidata netCDF-dokument" + +#~ msgid "V font" +#~ msgstr "V-skrifttype" + +#~ msgid "VOC audio" +#~ msgstr "VOC-lyd" + +#~ msgid "VRML document" +#~ msgstr "VRML-dokument" + +#~ msgid "Vivo video" +#~ msgstr "Vivo-film" + +#~ msgid "WAIS source code" +#~ msgstr "WAIS-kjeldekode" + +#~ msgid "Wavelet video" +#~ msgstr "Wavelet video" + +#~ msgid "Windows bitmap image" +#~ msgstr "Windows bitmap-bilete" + +#~ msgid "Windows icon image" +#~ msgstr "Windows ikonfil" + +#~ msgid "Windows metafile graphics" +#~ msgstr "Windows metafil grafikk" + +#~ msgid "WordPerfect document" +#~ msgstr "WordPerfect-dokument" + +#~ msgid "X bitmap image" +#~ msgstr "Bilete i X Bitmap-format" + +#~ msgid "X window image" +#~ msgstr "X window bilete" + +#~ msgid "XML document" +#~ msgstr "XML-dokument" + +#~ msgid "XPM image" +#~ msgstr "XPM-bilete" + +#~ msgid "Xbase database" +#~ msgstr "Xbase-database" + +#~ msgid "active server page" +#~ msgstr "active server side" + +#~ msgid "address card" +#~ msgstr "adressekort" + +#~ msgid "ar archive" +#~ msgstr "ar-arkiv" + +#~ msgid "arj archive" +#~ msgstr "arj-arkiv" + +#~ msgid "authors list" +#~ msgstr "forfattarliste" + +#~ msgid "backup file" +#~ msgstr "reservekopi" + +#~ msgid "basic audio" +#~ msgstr "enkel lyd" + +#~ msgid "bibliography record" +#~ msgstr "bibliografi oppføring" + +#~ msgid "binary program" +#~ msgstr "binærprogram" + +#~ msgid "block device" +#~ msgstr "blokkeining" + +#~ msgid "bzip-compressed file" +#~ msgstr "bzip-komprimert fil" + +#~ msgid "calendar file" +#~ msgstr "kalenderfil" + +#~ msgid "calendar or event document" +#~ msgstr "kalender eller hendingsfil" + +#~ msgid "character device" +#~ msgstr "teikneining" + +#~ msgid "comma-separated text document" +#~ msgstr "kommadelt tekstdokument" + +#~ msgid "compound document" +#~ msgstr "samansett dokument" + +#~ msgid "compress-compressed file" +#~ msgstr "compress-komprimert fil" + +#~ msgid "compressed GIMP document" +#~ msgstr "komprimert GIMP dokument" + +#~ msgid "directory information file" +#~ msgstr "katalog-informasjons fil" + +#~ msgid "document type definition" +#~ msgstr "dokumenttype definisjon" + +#~ msgid "email headers" +#~ msgstr "e-post hovud" + +#~ msgid "email message" +#~ msgstr "e-post melding" + +#~ msgid "encrypted message" +#~ msgstr "kryptert melding" + +#~ msgid "enriched text document" +#~ msgstr "riktekst tekstdokument" + +#~ msgid "gtar archive" +#~ msgstr "gtar arkiv" + +#~ msgid "gzip-compressed file" +#~ msgstr "gzip-komprimert fil" + +#~ msgid "help page" +#~ msgstr "hjelpeside" + +#~ msgid "mail delivery report" +#~ msgstr "e-post leveringsrapport" + +#~ msgid "mail disposition report" +#~ msgstr "e-post disposisjonsrapport" + +#~ msgid "mail system report" +#~ msgstr "e-postsystem rapport" + +#~ msgid "makefile" +#~ msgstr "makefil" + +#~ msgid "manual page" +#~ msgstr "manual-side" + +#~ msgid "manual page (compressed)" +#~ msgstr "manual-side (komprimert)" + +#~ msgid "memory dump" +#~ msgstr "minnedump" + +#~ msgid "message digest" +#~ msgstr "meldingsamandrag" + +#~ msgid "message in several formats" +#~ msgstr "meldinga i fleire format" + +#~ msgid "multi-part message" +#~ msgstr "melding med fleire delar" + +#~ msgid "named pipe" +#~ msgstr "namngitt røyr" + +#~ msgid "object code" +#~ msgstr "objektkode" + +#~ msgid "ogg audio" +#~ msgstr "ogg lyd" + +#~ msgid "partial email message" +#~ msgstr "del av e-post-melding" + +#~ msgid "plain text document" +#~ msgstr "rein tekst dokument" + +#~ msgid "profiler results" +#~ msgstr "resultat frÃ¥ profiler" + +#~ msgid "reference to remote file" +#~ msgstr "referanse til fil over nettverk." + +#~ msgid "rejected patch file" +#~ msgstr "fil avvist av patch" + +#~ msgid "rich text document" +#~ msgstr "rikt tekst dokument" + +#~ msgid "search results" +#~ msgstr "søkeresultat" + +#~ msgid "shared library" +#~ msgstr "delt bibliotek" + +#~ msgid "shell archive" +#~ msgstr "unix-skal arkiv" + +#~ msgid "shell script" +#~ msgstr "skalskript" + +#~ msgid "signed message" +#~ msgstr "signert melding" + +#~ msgid "socket" +#~ msgstr "sokkel" + +#~ msgid "software author credits" +#~ msgstr "forfattarliste for programvare" + +#~ msgid "software installation instructions" +#~ msgstr "instruksjonar for Ã¥ innstallere programvare" + +#~ msgid "software license terms" +#~ msgstr "lisensavtale for programvare" + +#~ msgid "source code patch" +#~ msgstr "patchfil for kjeldekode" + +#~ msgid "style sheet" +#~ msgstr "stilark" + +#~ msgid "symbolic link" +#~ msgstr "symbolsk lenkje" + +#~ msgid "tab-separated text document" +#~ msgstr "tabulatordelt tekstdokument" + +#~ msgid "tar archive" +#~ msgstr "tar-arkiv" + +#~ msgid "tar archive (bzip2-compressed)" +#~ msgstr "tar-arkiv (bzip2-komprimert)" + +#~ msgid "tar archive (gzip-compressed)" +#~ msgstr "tar-arkiv (gzip-komprimert)" + +#~ msgid "theme" +#~ msgstr "tema" + +#~ msgid "troff document" +#~ msgstr "troff-dokument" + +#~ msgid "troff me input document" +#~ msgstr "troff me inndata dokument" + +#~ msgid "troff mm input document" +#~ msgstr "troff mm inndata dokument" + +#~ msgid "troff ms input document" +#~ msgstr "troff ms inndata dokument" + +#~ msgid "unknown type" +#~ msgstr "ukjend type" + +#~ msgid "ustar archive" +#~ msgstr "ustar-arkiv" + +#~ msgid "wave audio" +#~ msgstr "lydbølge lyd" + +#~ msgid "web folder" +#~ msgstr "vevmappe" + +#~ msgid "xfig vector graphic" +#~ msgstr "xfig vektorgrafikk" + +#~ msgid "zip archive" +#~ msgstr "zip-arkiv" + +#~ msgid "zoo archive" +#~ msgstr "zoo-arkiv" + +#~ msgid "GNOME VFS already initialized." +#~ msgstr "GNOME VFS allereie initialisert." diff --git a/po/no.gmo b/po/no.gmo new file mode 100644 index 0000000000000000000000000000000000000000..67774c15eedfafd84a69e300e08007db6ba4c312 GIT binary patch literal 5246 zcma) z!OK*CxBgF^bLyNszq|9M=M~Qx%Dt3tyiKVNeE4R5cz(Y_sXO5x;4SbUkU#a`Sih0R z4^qD^a$n>eyp{HKDC5t=+u=p{4)}TaPWWZG4}KlWmcM{|;jiI+@OAiZcrT0Xf)j8L zd_30Iq4ZyXx5203UGOXLZunAce-+C7-$0S$&rsy}I}AsCdv(4Y@Lja;f->%YcoVEa z+2=syER^-0gfc&a{3#dP2T~ zyW9g2RZT$|e+ zuR=NBi?RMQxbFs~ehX#(Eo>^|?}p-655)RjDE6L&55NWZA?Tp!?MqO`e+`OUFGRis zMZTBee)vl$cDMnhJ`8t2@xy~qBeHY64UWTIgt5DAMFDP=~ zicliwT~PEk0cD+8DEfRd)-OUC_e`u`f{3Vo2*nRxjr%u9?{`R$|DrfkLW@k z(T&^>dB!LQ!dvAt@>-+JQRFU)UG`IUQ%+FCKjcBB;W-p}22NAt9(*LWiH}M=6dN6; zi0>>>#0SN$V#_ItJQDW^n`(hFNfAF+dQWEiNuH&8&1Makn!Rdle6p!e9)y0M-VNuxA{AHTNSI^8klx=Xc9I_A3FF74%J*xl3hL21023{=M& z4dcB|jm=D|j&-|v)=0|CS+9;KscvS>Tu*G88+9VF)|I+Zn4~nin{|zDx}*V$&)>J?$VYN^kR`Q7?L;QbUm9^<6ST30MeG(RCf~3S#`Z| z7rZH0XV}|K3U9)UCz3KjM@7-=mI(etmfGEMcA_gidsCK~ZTV{Fq(rct3@l8ebj3i| zdwwudmCa43TMpC=61ZlVrDlqPBj!oZHr82-9XlPg5!*$akyf2&)~H!gnYozx(pT?W zN8PT9&Z=7JoUUiBP+`2wQ;ZCY4g$-}a29paSW{#TZA2b*%H&;j%J~x0h$?lGrUhoK z+Qbh=riO9bGDy{{x&6y=tvQRTZIW+Qqm!PUQ*+T_IVMYr_o+Fr6P*rqs1`EY_G-bk zGOL>j2T!TEuIL0^w7oXAfsvU?&msfVqAT#7sJCz$uPyP$nz-E@o$@!h0hbZ(lZW_oJ+ zSwq@caO5yjH`eu9>)fagE)qsCzFarji%8)%_yNw@QOn}?9q#dns%eYP-bif2e?Y?x~E-j}ESGtB9TJ5ait~#3!-XNm1)~?ff zzGrY9SNAT*s$O%)L?OEg1KcXLQdPsbl0HUD>fHX762IqK>qTd?Hn+2hF+@qL*oiwa zs4Tu+b)q2An3uNPt2NuU?gFvGx{f(FyRu?T`?T{}FzHyj)nD0jIC{g?bz6eMSZ`~D z>*{hq_z6wE*X_CjHAy6@)UVb&{)5%V!~^?T;cUlPxl2VRhrzdS3Dd}$gWv(pCJst} z?yA@~zEgdYEr~uVm^>bN=3;3q_fxgvZ44*T90f-RO4;fO(}s;0YlEOun@elwxI}pH zw8qstrq*wIJu&{s_{8|c&eO}QwG$Fs>8}yqh;s)fCJxpnrfLTc>B)oBlT!~((89pl zSv*+Qxpv%yo;);t;E`(F0#UTKS|rxz36`4H^BYNl74;(bnYi&-yAxiH23f{k(K@no zA+fDq(lWJGlXRx_k}EElR>qvitUH=#)u6?>#hLAsOd>mx9@VfLR+-kNxmfP+=47u& zL*^n7A6{FXtxau@6RA*oZHD-e5-z6oR6Q$qk|lesL7rwU{r_djjFht;f~MrjT4`E# zm;y(-*g!6;DY>pT>A%GgNtJQLHHmUAtWjop3l&v~vYq%1M_g8GQD&^ZzIn-}Wztsj zC@pKZ4PMzT$V5gLo0qHDw0Y?|DRUklR`bJ*DGPgXBCA8n6sHZVHG7=63@LDH2Xdx0 z*Cx&FUKVzFyGonvBC)2r=(7nvA6DI#A1$St^*kpfgtxfpSxB7ogofOS9yw5%lnA@k zB7@|prR%7byjK#tHZO&{PnI)TuF3O^VWKZ_L7ntPw4YGHj-$Ouun{w*)u!!9 zs@&8r?7^7PD

%_vxcG8wRK0Fy6Tqk-v>`&}ip|1w!bJ|L^(|&pe$8DFk6#Jdm((eVrkYgwZzh?&bZwXCYNcIdeN#8S zJ>b^MH)$Sae)FDLzI%L^_}~qfrMiu+4T%>e{!g|x{38&O^J=We3r9Gjp=EMDA+OEQ zwPsQ;kYBzgB}2F53n+Nfc7v#|`mQO&VcX^A<$+pjvu63`dAjNjP92AaY)q!Ehm>6P zyKZfmq=QjCYX^mFX-^$5dSd9DlUAwONWdH8iyeu@=v^X0GvoV&FKR4`M_7_{6?aL} l=Sb2$ZiWQP;djYalI|xKt>}|W%ZoE_$kDNbNwr~y{vW{{Mvwpi literal 0 HcmV?d00001 diff --git a/po/no.po b/po/no.po new file mode 100644 index 0000000..b5b38a6 --- /dev/null +++ b/po/no.po @@ -0,0 +1,406 @@ +# Norwegian translation of gnome-vfs (bokmÃ¥l dialect). +# Copyright (C) 1999-2001 Free Software Foundation, Inc. +# Kjartan Maraas , 1999-2001. +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs 0.6.0.0\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-08-20 15:26+0200\n" +"Last-Translator: Kjartan Maraas \n" +"Language-Team: Norwegian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d inneholder NUL-tegn." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d inneholder ingen metodenavn." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d inneholder ingen modulnavn." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Konfigurasjonsfilen `%s' ble ikke funnet: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Ukjent op-type %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "Kan ikke opprette rør for Ã¥pen GIOChannel: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Ukjent type jobb %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Stoppet operasjonen" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Kan ikke fortolke: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Flere fortolkningsfeil vil bli ignorert." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Ingen feil" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Fil ikke funnet" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Ordinær feil" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Intern feil" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Ugyldige parametere" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Ikke støttet operasjon" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "I/U-feil" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Korrupt data" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Ugyldig format" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Ugyldig filhÃ¥ndtak" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "Filen er for stor" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Ikke mer plass pÃ¥ enheten" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Skrivebeskyttet filsystem" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "Ugyldig URI" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Filen er ikke Ã¥pen" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Ugyldig Ã¥pningsmodus" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Ingen tilgang" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "For mange Ã¥pne filer" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Slutt pÃ¥ filen" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Ikke en katalog" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Operasjonen er under fremgang" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Operasjonen avbrutt" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Filen eksisterer" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Lenker i løkke funnet" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Operasjonen ikke tillatt" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "Er en katalog" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Ikke nok minne" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Verten ikke funnet" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Ugyldig vertsnavn" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Verten har ingen adresse" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Innlogging feilet" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Operasjonen avbrutt" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Katalogen opptatt" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Katalogen er ikke tom" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "For mange lenker" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Skrivebeskyttet filsystem" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Ikke pÃ¥ samme filsystem" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Navnet er for langt" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Tjeneste ikke tilgjengelig" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Forespørsel ugyldiggjør tjenestens data" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Feil i protokoll" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "Kan ikke finne master browser" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "Ingen forvalgt handling asossiert" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "Ingen hÃ¥ndterer for URK-schema" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "Feil under lesing av kommandolinjen" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "Feil under oppstart av kommando" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Ukjent feil" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 byte" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u bytes" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (ugyldig Unicode)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "Ukjent GnomeVFSSeekPosition %d" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "Fant ikke gyldig fil med innstillinger i %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "Bruk miljøvariabelen %s for Ã¥ spesifisere en annen lokasjon.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "Applikasjoner" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "Kort" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "Filer" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "Mapper" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "Hjelp" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "Verter" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "Lenker" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "E-post" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "Verktøy" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "Vinduer" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Standard Moniker-fabrikk" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "file MonikerExtender" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "vanlig GNOME VFS moniker" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "vanlig fil-moniker" diff --git a/po/pl.gmo b/po/pl.gmo new file mode 100644 index 0000000000000000000000000000000000000000..505da4f3932a724dfa3b74f6501402616460cb2d GIT binary patch literal 5544 zcma)0^jjmBt*Au$H}jhzUZ@I^ynqD0e}s4@BhV`4&xzyG~=c85aL zo1Xp6dH-MMe@@@L_Tr}%-vg8zDc}2`QZ0DLCH&$0!=*}H3;zf&ga3s5Q*T%Gi)j25 z^(!jgR&fSiPWuX!@sGeO;c56`_!W3H{3g5&J`ZKf*Wph18+a3Z2YwXZ$YNK)I@|&G zSM?Pr{cU&!d=h>fej9!gzEHLQ63YBHpvdtjC~~|73spZ<>USyp2<=xv8Fw?h7}lWd zGgk31l=U8hGCzR)Q?6?7K#}LGQ0(`us{IF0#{Ue;{^#H);A>F!IS+4ve}=OEl|!Xp zZh(lY#-WTq2u05?K(S*AuYr%j8{pGWc4>B`G8WtgV)jCWm6gdbtrMQUe&(~#os@Kvi~bk!}AbT)x{V|#$OFZuInHs zR<}UWX9SMGBT)2MgS+6Pa4-BZlsNwj%6`v5+3&@QzlI{;TTuLb9fLI- zg);vHl>D^<#ouS)ZSW~5`@IY$-hTzf-{&j74G&S@#v*e5J`ZKwm!QbKR@I+^gkkX= zta!8{BB^I7L2*Lpjs4lu?Srq0&2oXw8IyuNR}hbH3fFhDS!1^^vKPM@!66 zO(%wZ?YSs3L6quai?iBWF^Taqo1`Nbc1KRPY_{Tj9hsJW-)`sUq3w6)da0AyRE-u? z2R+ZGsrGFYSYI8C<1p|{7Pu%?Q^wcJ0W()jwhX^|DK}i*2Nj z%p5<&u*ilJdN^fh;`7%<%RwVgiuKB+9v)7&>$XX?thDU%$S=pcJVXI$3nE{)Op300 zDRJ%8Calx%jZKo;V#d8DGuS9e@;F2Adjmh(Ud=YTv~y~+EQlIuxwFX-Y>0u0^)i=q z^irO72CA~TZN*tfO(TI@E@r9eBtgZ{v*-+OoXW;6K+09_K_*IWwWpbjV_N1DmpRY%y>`NKR$UZ!-X)^6 z*50S}k=znGZYgykUQIP;OboJ}G{C7+C(CM~ms!JUW{J~(G9&Ie)_TrGL6g(Dj5EYY z3;2mM(J4K?Rdr$@u~;f?VX79RX5`xBipaI>gNIL^w6;0#(x7nZu)o<~`m;ZJ)h+3! zB!%I8bA*d^)*<~AO=%v-F2PKaiAwXU#gzELYr_(OYeC|omW|{rC4neIY!MRH3zj=Y z1S~HTp!A2X%zYz6>J(d&eN^G{O6BR(nTRx_e@D{PsF646L0X za%KLz#@$^TyGPgS6Qg(4YNL#sC41Hu5)-AN!9x?J!S(#CUa+R6_hy@2>48FwkvQDP ztf-NjhONn<2|e$^AYIXW)JGF!6!>h=<%f>8#-adgSEM|5%{&Kyph%x+=L#Q54k(S znk2(?LPv2?O(%En(dEy{9ns|EsNS#Zn(pDz`o76Aee12o&%Kj(%Fi9rT;Drd*N;A0 zw9A{r`y5Aj{Zo4Db zv-3OurJwt`cP3{5ce7c|UU{)Cw==)gRAQRiCu47{$2qri7&MKyO6nSrIQLfC9kK;| zxpWYVy>pS#dDeDGx3lqtj>#3xT>GKX7u?fFO~QpIlbp{TV7tVYE0@yE{_X8`RwLVR zTJG-R?j6{qoYs4ZT^hYJNM4L2p|r(3gizKY>2+-*+&Jr-C@_N(N{3ZHf*vKD-_EF)pMY5&}M-0M^=Q`1%Wy|m^;Ib)#qMB}a1$Ns8-IE#(dL*gTxFY-!>T|01o?+ocV*jQJm zxN0}f#zF5)2S>*2$%BBvVARIhF0%}ZdtL6Vqu8G))l0Z=-S6nWcU+s(h$1H1IIFwG z14Fjsom`llt@1`?6cJrwwG#)a;S~6;)#*JOMs`)3rnefXDch~q&&z|!4Jz}4;$#(% z4U^@Xmq*#%A_P)TRwtCYL{^vh$+-**RV!}`QG|qKg)QTD zG-h4WPNImHkUALUp(y6cOVA_e%U6T9YIK|Xj@(eZBBU2-g&+w#tQwUc89qe$(Pzd70pAvO;y~qDB8qZ3PVHbD*^_Ue@te`YQ15#82yf zw@g!{b*xex)84ZrIQ~=ieoq(iiVWp{6h;2ns`Ex6Y>TufPnFGa(q6n(h^nfiA4=kt zeji?4>S)(YEMXWRK*0a6I3gU6-Z}aI+8sLYo$IXXE|Esps_s3TI5`|?6I-m32YJXG eZ(=OTDUPe?!iP+iKKe$hUJ5*D)P+6O3hF;uDAh^; literal 0 HcmV?d00001 diff --git a/po/pl.po b/po/pl.po new file mode 100644 index 0000000..e74fba2 --- /dev/null +++ b/po/pl.po @@ -0,0 +1,413 @@ +# Copyright (C) 2001-2003 Free Software Foundation, Inc. +# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +# Aktualną wersję tego pliku możesz odnaleźć w repozytorium cvs.gnome.pl +# (:pserver:anonymous@cvs.gnome.pl:/home/cvs, puste hasło) +# Jeśli masz jakiekolwiek uwagi odnoszące się do tłumaczenia lub chcesz +# pomóc w jego rozwijaniu i pielęgnowaniu, napisz do nas na adres: +# translators@gnome.pl +# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-06-27 00:15--100\n" +"Last-Translator: Gnome PL Team \n" +"Language-Team: Polish \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Report-Msgid-Bugs-To: \n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " +"|| n%100>=20) ? 1 : 2);\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d zawiera puste znaki." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d nie zawiera nazwy metody." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d nie zawiera nazwy modułu." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Nie odnaleziono pliku konfiguracyjnego `%s': %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Nieznany typ operacji %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "Nie można utworzyć potoku dla GIOChannel: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Nieznany typ zadania %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Zatrzymano operację" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Nie można przeanalizować: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Kolejne błędy składniowe zostaną zignorowane." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Bez błędu" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Nie odnaleziono pliku" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Błąd ogólny" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Błąd wewnętrzny" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Niepoprawne parametry" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Nieobsługiwana operacja" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "Błąd We/Wy" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Uszkodzone dane" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Niepoprawny format" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Niepoprawny uchwyt pliku" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "Zbyt wielki plik" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Brak miejsca na urządzeniu" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "System plików tylko do odczytu" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "Niepoprawny URI" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Nie otwarto pliku" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Niepoprawny tryb otwarcia" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Brak dostępu" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "Zbyt wiele otwartych plików" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Koniec pliku" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "To nie katalog" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Operacja w toku" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Operacja przerwana" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Plik istnieje" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Wystąpiły zapętlone dowiązania" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Niedozwolona operacja" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "Jest katalogiem" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Brak pamięci" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Nie odnaleziono komputera" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Niepoprawna nazwa komputera" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Komputer nie ma adresu" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Zalogowanie nie powiodło się" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Anulowano operację" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Katalog zajęty" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Katalog nie jest pusty" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "Zbyt wiele dowiązań" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "System plików tylko do odczytu" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "To nie ten sam system plików" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Zbyt długa nazwa" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Usługa nie jest dostępna" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Żądanie unieważnia dane usługi" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Błąd protokołu" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "Nie można odnaleźć głównego serwera listy przeglądania" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "Nie przypisano domyślnej akcji" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "Brak obsługi dla schematu URL" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "Błąd składni lini poleceń" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "Błąd podczas uruchamiania polecenia" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Nieznany błąd" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 bajt" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u bajtów" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (niepoprawny Unicode)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "Nieznana wartość %d GnomeVFSSeekPosition" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "Nie odnaleziono poprawnego pliku z ustawieniami pod %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "Aby określić inne położenie, użyj zmiennej środowiskowej %s.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "Aplikacje" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "Karty" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "Pliki" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "Foldery" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "Pomoc" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "Hosty" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "Łącza" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "Poczta" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "Narzędzia" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "Okna" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Generator standardowego monikera" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "plikowy MonikerExtender" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "ogólny moniker Gnome VFS" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "ogólny moniker plikowy" diff --git a/po/pt.gmo b/po/pt.gmo new file mode 100644 index 0000000000000000000000000000000000000000..e5c6e86effa1da979f61d01030b62db83c94886b GIT binary patch literal 5604 zcma)6@W`w#6dt%abYW$c82BkbPpg+v(C~zG<44lJ>3{IMyubg_uiek_txds zeLd6sHE{`$5QV@mlMxa!iQ^Jn5`+GEF$NQji9$3{BOyc*G5*kmKZN+5y7iVB$H-0B z`)<{(<Mrc-kDu248{if&Yg5skdVN92&2t zeqrQwkxTFb+Ivv?KLjs=$Km_nSKuY^oA5gL43s5*1Fwa@hgZS3;RoQAOm;Dxfji(` zvEGC7{TRFuJ_0`spMoEQ-;3?Pf-?SPC~~|8MUH>Lu+{fA`#T@LpZ1HP^t%S03tLdu z*%i46Wxmfr8J|M_l#A_KP~`a<6#YFB+nrmFeXj@~K zDO|4((lg5 zHK?f{iS^b}QR)966u&aD-h;Ak2|o!RkNhDNz5M}7|5qS?>UDmYQoRW^ zJQpS20;iz#|3a*H;57AbLGklnL($h8@K*RXl>N=&G?&9=NRw(q(UXT7J{sFk#rB^; z+3(9x_WO5;$<=vGE^=N1Wu43U5qWn&(eEu#?0W|k|9%k4IyJM#QxX$_ulv}F+%Js zkH~dhc;lQw@n3nwZu0D*$R0&Mlh4PgtWY#XbSlq5$^vB{=N zyKTMKi7ir_sNH3mrEOEEuJCG)NpvS=WX}{yX4PI(6t33o%9`5hGA*s{xJtXy7JC2E z!M$`VY&Nf_JYB1VUsrU}ZodliHB)_Q%5T@ljMp+#$MuV(>F@d(8<4iNNOW#Id(|72 zJLYZ0Jj1W0sk{v%_L~=;30xfoi%L*OTimULQsJE~iuaBi!rZ=oky9Hm9X>~w$AezZs z(NzZ=?%6T@tk#?XTvHqGT|31K6ZzQagqOxotKgOEtIOKAdp5Vy#h0dSb!I!YW_V&Z z)3&rT;lyU7ZVT7%_Bc^FE)sgszwTM>MWk>V{1(octApb9Ip=sn)wD%tZ=0fRGttMm z4IP!0>jpzjwxXTr#p7177n9{_Et?#-``VQyEr%*syS5uzZPjvCU6E~_CZe>q&eHl& z-{LxM!@CTtdd(RVg={AbaH`bdrW*ETHZhvn;PfA^@q3Q7UU5Zwl+)S47^0*#?8KSa zYAimkI#G~l%u8G5)p~KXaL0%hh0E;&i-!+ed-Ra=X)x(jGWy=wbJ+Wc+t5cPC`|Q7 zJzS~lEy7P|^8K=O6>5@5)Tm#rd;ABhO^F9?rj;vlTgX|eQrQf?g-h6W+Sv*o(COfy ze9v4H`=+<4&$1-ZM+K9|EiW9eZNd3e-FO=s$+}N6#YwfyO&)zscJ9qsIEp%+H;>9DtzsHTk?QYkfOsF}Koj%k&&x>-wc{Ih!OnyYqjg1gqegG+XBGS}^Ry>b}1ZVw(FUZcg}85eG1=_CpvcIbR?vUZ94KYgC( z(v?1Ey>Fc^Y}X`?3s>&j!E=KjaZC=08gW*MkA|Z|_>$UaGwOhdGdQVB=l$T+rp>h3 zsM4yri^HJtJv}^ZEQEGF?H*I0qrg=DZERu`)hI$QmxHimm+_w8Q8{sGr zkBdT7)^r$&8?Je|@}u}?2zkbb#vUJbsk`)E8Q3&9v_cWtsB=3cd3(j&(eLbcyy5n|Ac z++o7?B!jFfi|JOmuncPx&e^}Dt09LVSP^!J<+c(R4*7%l78yjd>!E%nk3bc+==F0$ z7SXso!A840I;Y$Xn1wZRGE4S9&qnHXioHHXgYNu=-_qzFz$jy=|V zlP)w{Z1NDpu0jscG>V+!^Px8RA(*!chw`)m!L6EfBt3m9j)+ViyhMx=(-Nl+pG9VE zNC`+->6qEHM(B6i?T}4~6EZLfvBNYui)cEgF{~(Qi?ncai&cscA=TpG1TnH5EH+GC zhPjN|H#~tpW-k*BBUQ&p%4x*;g2!<(|3?yoh@QCEBexigj@^a7x_l;D57L@pWvF3@t}%|b7?}d v!$7%waQ`H2av)3YbFbn5IQBTyz%b<-, 2001, 2002, 2003 +# +msgid "" +msgstr "" +"Project-Id-Version: 2.4\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-08-15 17:15+0100\n" +"Last-Translator: Duarte Loreto \n" +"Language-Team: pt \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Report-Msgid-Bugs-To: Duarte Loreto \n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d contém caracteres NULOS." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d não contém nome de método." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d não contém nome de módulo." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Ficheiro de configuração `%s' não foi encontrado: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Tipo op %u desconhecido" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "Não é possível abrir pipe para GIOChannel aberto: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Tipo de trabalho %u desconhecido" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Operação parada" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Não foi possível parsear: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Restantes erros de parseamento serão ignorados." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Nenhum erro" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Ficheiro não encontrado" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Erro genérico" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Erro interno" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Parâmetros inválidos" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Operação não suportada" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "Erro I/O" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Dados corrompidos" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Formato inválido" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Ponteiro para ficheiro inválido" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "Ficheiro demasiado grande" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Dispositivo sem espaço livre" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Sistema de ficheiros apenas de leitura" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "URI inválido" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Ficheiro não aberto" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Modo de abertura inválido" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Accesso negado" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "Demasiados ficheiros abertos" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Fim de ficheiro" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Não é um directório" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Operação em execução" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Operação interrompida" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Ficheiro existe" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Links em loop encontrados" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Operação não permitida" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "É um directório" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Memória não é suficiente" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Servidor não encontrado" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Nome de servidor inválido" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Servidor não tem endereço" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Registo falhou" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Operação cancelada" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Directório ocupado" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Directório não vazio" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "Demasiados links" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Sistema de ficheiros apenas de leitura" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Não está no mesmo sistema de ficheiros" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Nome demasiado longo" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Serviço indisponível" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Pedido de dados a serviço obsoleto" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Erro de protocolo" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "Não foi possível encontrar browser principal" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "Nenhuma acção por omissão associada" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "Nenhum gestor de esquema de URL" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "Erro ao parsear linha de comando" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "Erro ao executar comando" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Erro desconhecido" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 byte" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u bytes" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (Unicode inválido)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "GnomeVFSSeekPosition %d desconhecida" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "Ficheiro de configuração válido não encontrado em %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "" +"Utilize a variável de ambiente %s para especificar uma localização " +"diferente.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "Aplicações" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "Cartões" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "Ficheiros" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "Pastas" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "Ajuda" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "Servidores" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "Atalhos" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "Correio" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "Ferramentas" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "Janelas" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Fábrica de Moniker Standard" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "ficheiro MonikerExtender" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "moniker Gnome VFS genérico" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "ficheiro moniker genérico" + +#~ msgid "3D Studio image" +#~ msgstr "Imagem 3D Studio" + +#~ msgid "AIFC audio" +#~ msgstr "Audio AIFC" + +#~ msgid "AIFF audio" +#~ msgstr "Audio AIFF" + +#~ msgid "ANIM animation" +#~ msgstr "Animação ANIM" + +#~ msgid "AVI video" +#~ msgstr "Vídeo AVI" + +#~ msgid "AbiWord document" +#~ msgstr "Documento AbiWord" + +#~ msgid "Adobe FrameMaker font" +#~ msgstr "Fonte AdobeFrameMaker" + +#~ msgid "Adobe font metrics" +#~ msgstr "Métrica de Fontes Adobe" + +#~ msgid "Andrew Toolkit inset" +#~ msgstr "Inset do Andrew Toolkit" + +#~ msgid "ApplixWare Graphics image" +#~ msgstr "Imagem do ApplixWare Graphics" + +#~ msgid "Applixware Words document" +#~ msgstr "Documento do ApplixWare Words" + +#~ msgid "Applixware spreadsheet" +#~ msgstr "Folha de cálculo ApplixWare" + +#~ msgid "AutoCAD image" +#~ msgstr "Imagem AutoCAD" + +#~ msgid "BCPIO document" +#~ msgstr "Documento BCPIO" + +#~ msgid "BDF font" +#~ msgstr "Fonte BDF" + +#~ msgid "C shell script" +#~ msgstr "Script de Consola C" + +#~ msgid "C source code" +#~ msgstr "Código Fonte C" + +#~ msgid "C source code header" +#~ msgstr "Header de código fonte C" + +#~ msgid "C++ source code" +#~ msgstr "Código Fonte C++" + +#~ msgid "CGI program" +#~ msgstr "Aplicação CGI" + +#~ msgid "CGM image" +#~ msgstr "Imagem CGM" + +#~ msgid "CMU raster image" +#~ msgstr "Imagem rasterizada CMU" + +#~ msgid "CPIO archive" +#~ msgstr "Arquivo CPIO" + +#~ msgid "CPIO archive (gzip-compressed)" +#~ msgstr "Arquivo CPIO (comprimido com gzip)" + +#~ msgid "DCL script" +#~ msgstr "Script DCL" + +#~ msgid "DOS font" +#~ msgstr "Fonte DOS" + +#~ msgid "DOS/Windows program" +#~ msgstr "Aplicação DOS/Windows" + +#~ msgid "DSSSL document" +#~ msgstr "Documento DSSSL" + +#~ msgid "DXF vector graphic" +#~ msgstr "Gráfico de vectores DXF" + +#~ msgid "Debian package" +#~ msgstr "Pacote Debian" + +#~ msgid "Dia diagram" +#~ msgstr "Diagrama Dia" + +#~ msgid "Dolby Digital audio" +#~ msgstr "Audio Dolby Digital" + +#~ msgid "Emacs Lisp source code" +#~ msgstr "Código Fonte Emacs Lisp" + +#~ msgid "Enlightenment theme" +#~ msgstr "Tema para o Enlightenment" + +#~ msgid "FLC animation" +#~ msgstr "Animação FLC" + +#~ msgid "FLI animation" +#~ msgstr "Animação FLI" + +#~ msgid "FastTracker II audio" +#~ msgstr "Audio FastTracker II" + +#~ msgid "Fortran source code" +#~ msgstr "Código Fonte Fortran" + +#~ msgid "FrameMaker interchange document" +#~ msgstr "Documento de partilha FrameMaker" + +#~ msgid "G3 fax image" +#~ msgstr "Imagem de fax G3" + +#~ msgid "GIF image" +#~ msgstr "Imagem GIF" + +#~ msgid "GIMP document" +#~ msgstr "Documento GIMP" + +#~ msgid "GMC link" +#~ msgstr "Link GMC" + +#~ msgid "GNOME application details" +#~ msgstr "Detalhes de Aplicação GNOME" + +#~ msgid "GNU Oleo Spreadsheet" +#~ msgstr "Folha de Cálculo GNU Oleo" + +#~ msgid "GNU mail message" +#~ msgstr "Mensagem de mail GNU" + +#~ msgid "GTK configuration" +#~ msgstr "Configuração GTK" + +#~ msgid "Glade project" +#~ msgstr "Projecto Glade" + +#~ msgid "GnuCash Workbook" +#~ msgstr "Livro de Registo GnuCash" + +#~ msgid "Gnumeric spreadsheet" +#~ msgstr "Folha de cálculo Gnumeric" + +#~ msgid "HDF document" +#~ msgstr "Documento HDF" + +#~ msgid "HTML page" +#~ msgstr "Página HTML" + +#~ msgid "IDL document" +#~ msgstr "Documento IDL" + +#~ msgid "IEF image" +#~ msgstr "Imagem IEF" + +#~ msgid "IFF image" +#~ msgstr "Imagem IFF" + +#~ msgid "ILBM image" +#~ msgstr "Imagem ILBM" + +#~ msgid "ISI video" +#~ msgstr "Vídeo ISI" + +#~ msgid "Impulse Tracker audio" +#~ msgstr "Audio Impulse Tracker" + +#~ msgid "JBuilder Project" +#~ msgstr "Projecto JBuilder" + +#~ msgid "JPEG image" +#~ msgstr "Imagem JPEG" + +#~ msgid "Java byte code" +#~ msgstr "Byte-code de Java" + +#~ msgid "Java source code" +#~ msgstr "Código Fonte Java" + +#~ msgid "KIllustrator document" +#~ msgstr "Documento de KIllustrator" + +#~ msgid "KPresenter presentation" +#~ msgstr "Apresentação KPresenter" + +#~ msgid "KSpread spreadsheet" +#~ msgstr "Folha de Cálculo KSpread" + +#~ msgid "KWord document" +#~ msgstr "Documento KWord" + +#~ msgid "Korn shell script" +#~ msgstr "Script de consola Korn" + +#~ msgid "LHA archive" +#~ msgstr "Arquivo LHA" + +#~ msgid "LHARC archive" +#~ msgstr "Arquivo LHARC" + +#~ msgid "LIBGRX font" +#~ msgstr "Fonte LIBGRX" + +#~ msgid "LightWave object" +#~ msgstr "Objecto LightWave" + +#~ msgid "LightWave scene" +#~ msgstr "Cenário LightWave" + +#~ msgid "Linux PSF console font" +#~ msgstr "Fonte PSF de consola Linux" + +#~ msgid "Lotus 1-2-3 spreadsheet" +#~ msgstr "Folha de cálculo Lotus 1-2-3" + +#~ msgid "M3 audio URL" +#~ msgstr "Endereço de Audio M3" + +#~ msgid "MIDI audio" +#~ msgstr "Audio MIDI" + +#~ msgid "MOD audio" +#~ msgstr "Audio MOD" + +#~ msgid "MP3 audio" +#~ msgstr "Audio MP3" + +#~ msgid "MP3 audio playlist" +#~ msgstr "Lista de ficheiros audio MP3" + +#~ msgid "MPEG video" +#~ msgstr "Vídeo MPEG" + +#~ msgid "MS ASF video" +#~ msgstr "Vídeo MS ASF" + +#~ msgid "MS video" +#~ msgstr "Vídeo MS" + +#~ msgid "Macintosh AppleDouble-encoded file" +#~ msgstr "Ficheiro AppleDouble-enconded Macintosh" + +#~ msgid "Macintosh BinHex-encoded file" +#~ msgstr "Ficheiro BinHex-encoded Macintosh" + +#~ msgid "Macintosh StuffIt archive" +#~ msgstr "Ficheiro StuffIt Macintosh" + +#~ msgid "Macromedia Flash file" +#~ msgstr "Ficheiro Flash da Macromedia" + +#~ msgid "MathML document" +#~ msgstr "Documento MathML" + +#~ msgid "Microsoft Excel spreadsheet" +#~ msgstr "Folha de Cálculo Microsoft Excel" + +#~ msgid "Microsoft PowerPoint document" +#~ msgstr "Documento Microsoft PowerPoint" + +#~ msgid "Microsoft Word document" +#~ msgstr "Documento Miscrosoft Word" + +#~ msgid "Microsoft video" +#~ msgstr "Vídeo Microsoft" + +#~ msgid "Nautilus link" +#~ msgstr "Link Nautilus" + +#~ msgid "ODA document" +#~ msgstr "Documento ODA" + +#~ msgid "PBM image" +#~ msgstr "Imagem PBM" + +#~ msgid "PCF font" +#~ msgstr "Fonte PCF" + +#~ msgid "PDF document" +#~ msgstr "Documento PDF" + +#~ msgid "PEF program" +#~ msgstr "Aplicação PEF" + +#~ msgid "PGM image" +#~ msgstr "Imagem PGM" + +#~ msgid "PGN chess game" +#~ msgstr "Jogo de Xadrês PGN" + +#~ msgid "PGP keys" +#~ msgstr "Chaves PGP" + +#~ msgid "PGP message" +#~ msgstr "Mensagem PGP" + +#~ msgid "PGP signature" +#~ msgstr "Assinatura PGP" + +#~ msgid "PGP-encrypted file" +#~ msgstr "Ficheiro encriptado PGP" + +#~ msgid "PHP script" +#~ msgstr "Script PHP" + +#~ msgid "PN RealAudio document" +#~ msgstr "Documento PN RealAudio" + +#~ msgid "PNG image" +#~ msgstr "Imagem PNG" + +#~ msgid "PNM image" +#~ msgstr "Imagem PNM" + +#~ msgid "PPM image" +#~ msgstr "Imagem PPM" + +#~ msgid "Palm OS database" +#~ msgstr "Base de Dados SO Palm" + +#~ msgid "Perl script" +#~ msgstr "Script Perl" + +#~ msgid "Photoshop document" +#~ msgstr "Documento Photoshop" + +#~ msgid "PostScript Type 1 font" +#~ msgstr "Fonte Tipo 1 PostScript" + +#~ msgid "PostScript document" +#~ msgstr "Documento PostScript" + +#~ msgid "Python source code" +#~ msgstr "Código Fonte Python" + +#~ msgid "QuickTime movie" +#~ msgstr "Filme QuickTime" + +#~ msgid "Quicken document" +#~ msgstr "Documento Quicken" + +#~ msgid "Quicken for Windows document" +#~ msgstr "Documento Quicken para Windows" + +#~ msgid "RAR archive" +#~ msgstr "Ficheiro RAR" + +#~ msgid "README document" +#~ msgstr "Documento LEIA-ME" + +#~ msgid "RGB image" +#~ msgstr "Imagem RGB" + +#~ msgid "RIFF audio" +#~ msgstr "Audio RIFF" + +#~ msgid "RPM package" +#~ msgstr "Pacote RPM" + +#~ msgid "RealAudio/Video document" +#~ msgstr "Documento RealAudio/Video" + +#~ msgid "RealVideo video" +#~ msgstr "Vídeo RealVideo" + +#~ msgid "S/MIME file" +#~ msgstr "Ficheiro S/MIME" + +#~ msgid "S/MIME signature" +#~ msgstr "Assinatura S/MIME" + +#~ msgid "SGI video" +#~ msgstr "Vídeo SGI" + +#~ msgid "SGML document" +#~ msgstr "Documento SGML" + +#~ msgid "SMIL script" +#~ msgstr "Script SMIL" + +#~ msgid "SQL code" +#~ msgstr "Código SQL" + +#~ msgid "SV4 CPIO archive" +#~ msgstr "Ficheiro SV4 CPIO" + +#~ msgid "SV4 CPIP archive (with CRC)" +#~ msgstr "Ficheiro SV4 CPIO (com CRC)" + +#~ msgid "SVG art" +#~ msgstr "Arte SVG" + +#~ msgid "Scheme source code" +#~ msgstr "Código Fonte Scheme" + +#~ msgid "Scream Tracker 3 audio" +#~ msgstr "Audio Scream Tracker 3" + +#~ msgid "Scream Tracker audio" +#~ msgstr "Audio Scream Tracker" + +#~ msgid "Scream Tracker instrument" +#~ msgstr "Instrumento Scream Tracker" + +#~ msgid "Setext document" +#~ msgstr "Documento Setext" + +#~ msgid "Speech document" +#~ msgstr "Documento Speech" + +#~ msgid "Speedo font" +#~ msgstr "Fonte Speedo" + +#~ msgid "Spreadsheet Interchange document" +#~ msgstr "Documento de Folha de Cálculo Genérica" + +#~ msgid "Stampede package" +#~ msgstr "Pacote Stampede" + +#~ msgid "StarOffice Writer document" +#~ msgstr "Documento StarOffice Writer" + +#~ msgid "StarOffice presentation" +#~ msgstr "Apresentação StarOffice" + +#~ msgid "StarOffice spreadsheet" +#~ msgstr "Folha de Cálculo StarOffice" + +#~ msgid "Sun mu-law audio" +#~ msgstr "Audio Sun mu-law" + +#~ msgid "SunOS News font" +#~ msgstr "Fonte SunOS News" + +#~ msgid "TIFF image" +#~ msgstr "Imagem TIFF" + +#~ msgid "TarGA image" +#~ msgstr "Imagem TarGa" + +#~ msgid "Tcl script" +#~ msgstr "Script Tcl" + +#~ msgid "TeX document" +#~ msgstr "Documento TeX" + +#~ msgid "TeX dvi document" +#~ msgstr "Documento dvi TeX" + +#~ msgid "TeX font" +#~ msgstr "Fonte TeX" + +#~ msgid "TeX font metrics" +#~ msgstr "Métricas de Fonte TeX" + +#~ msgid "TeXInfo document" +#~ msgstr "Documento TeXInfo" + +#~ msgid "ToutDoux document" +#~ msgstr "Documento ToutDoux" + +#~ msgid "TrueType font" +#~ msgstr "Fonte trueType" + +#~ msgid "USENET news message" +#~ msgstr "Mensagem de News USENET" + +#~ msgid "Unidata netCDF document" +#~ msgstr "Documento Unidata netCDF" + +#~ msgid "V font" +#~ msgstr "Fonte V" + +#~ msgid "VOC audio" +#~ msgstr "Audio VOC" + +#~ msgid "VRML document" +#~ msgstr "Documento VRML" + +#~ msgid "Vivo video" +#~ msgstr "Vídeo Vivo" + +#~ msgid "WAIS source code" +#~ msgstr "Código Fonte WAIS" + +#~ msgid "Wavelet video" +#~ msgstr "Vídeo Wavelet" + +#~ msgid "Windows bitmap image" +#~ msgstr "Imagem Bitmap Windows" + +#~ msgid "Windows icon image" +#~ msgstr "Imagem de ícon Windows" + +#~ msgid "Windows metafile graphics" +#~ msgstr "Gráfico Metafile Windows" + +#~ msgid "WordPerfect document" +#~ msgstr "Documento WordPerfect" + +#~ msgid "X bitmap image" +#~ msgstr "Imagem Bitmap X" + +#~ msgid "X window image" +#~ msgstr "Imagem de Janela X" + +#~ msgid "XML document" +#~ msgstr "Documento XML" + +#~ msgid "XPM image" +#~ msgstr "Imagem XPM" + +#~ msgid "Xbase database" +#~ msgstr "Base de Dados XBase" + +#~ msgid "active server page" +#~ msgstr "página ASP" + +#~ msgid "address card" +#~ msgstr "cartão de endereço" + +#~ msgid "ar archive" +#~ msgstr "ficheiro ar" + +#~ msgid "arj archive" +#~ msgstr "ficheiro arj" + +#~ msgid "authors list" +#~ msgstr "lista de autores" + +#~ msgid "backup file" +#~ msgstr "ficheiro de salvaguarda" + +#~ msgid "basic audio" +#~ msgstr "audio basic" + +#~ msgid "bibliography record" +#~ msgstr "registo de bibliografia" + +#~ msgid "binary program" +#~ msgstr "aplicação binária" + +#~ msgid "block device" +#~ msgstr "dispositivo de armazenamento" + +#~ msgid "bzip-compressed file" +#~ msgstr "ficheiro comprimido bzip" + +#~ msgid "calendar file" +#~ msgstr "ficheiro de calendário" + +#~ msgid "calendar or event document" +#~ msgstr "documento de calendário ou evento" + +#~ msgid "character device" +#~ msgstr "dispositivo de escrita" + +#~ msgid "comma-separated text document" +#~ msgstr "documento separado por vírgulas (csv)" + +#~ msgid "compound document" +#~ msgstr "documento composto" + +#~ msgid "compress-compressed file" +#~ msgstr "ficheiro comprimido por compress" + +#~ msgid "compressed GIMP document" +#~ msgstr "documento GIMP comprimido" + +#~ msgid "directory information file" +#~ msgstr "ficheiro de informação de directório" + +#~ msgid "document type definition" +#~ msgstr "definição de tipo de documento" + +#~ msgid "email headers" +#~ msgstr "cabeçalho de E-Mail" + +#~ msgid "email message" +#~ msgstr "mensagem de E-Mail" + +#~ msgid "encrypted message" +#~ msgstr "mensagem encriptada" + +#~ msgid "enriched text document" +#~ msgstr "documento de texto rico" + +#~ msgid "gtar archive" +#~ msgstr "ficheiro gtar" + +#~ msgid "gzip-compressed file" +#~ msgstr "ficheiro comprimido gzip" + +#~ msgid "help page" +#~ msgstr "página de ajuda" + +#~ msgid "mail delivery report" +#~ msgstr "relatório de entrega de e-mail" + +#~ msgid "mail disposition report" +#~ msgstr "relatório de disposição de e-mail" + +#~ msgid "mail system report" +#~ msgstr "relatório de sistema de e-mail" + +#~ msgid "makefile" +#~ msgstr "makefile" + +#~ msgid "manual page" +#~ msgstr "página de manual" + +#~ msgid "manual page (compressed)" +#~ msgstr "página de manual (comprimida)" + +#~ msgid "memory dump" +#~ msgstr "dump de memória" + +#~ msgid "message digest" +#~ msgstr "conjunto de mensagens" + +#~ msgid "message in several formats" +#~ msgstr "mensagem em vários formatos" + +#~ msgid "multi-part message" +#~ msgstr "mensagem repartida" + +#~ msgid "named pipe" +#~ msgstr "pipe com nome" + +#~ msgid "object code" +#~ msgstr "código de objecto" + +#~ msgid "ogg audio" +#~ msgstr "audio ogg" + +#~ msgid "partial email message" +#~ msgstr "mensagem parcial de email" + +#~ msgid "plain text document" +#~ msgstr "documento de texto simples" + +#~ msgid "profiler results" +#~ msgstr "resultados do profiler" + +#~ msgid "reference to remote file" +#~ msgstr "referência a ficheiro remoto" + +#~ msgid "rejected patch file" +#~ msgstr "ficheiro patch rejeitado" + +#~ msgid "rich text document" +#~ msgstr "documento de texto rico" + +#~ msgid "search results" +#~ msgstr "resultados de busca" + +#~ msgid "shared library" +#~ msgstr "biblioteca partilhada" + +#~ msgid "shell archive" +#~ msgstr "ficheiro de consola" + +#~ msgid "shell script" +#~ msgstr "script de consola" + +#~ msgid "signed message" +#~ msgstr "mensagem assinada" + +#~ msgid "socket" +#~ msgstr "socket" + +#~ msgid "software author credits" +#~ msgstr "créditos de autor de aplicação" + +#~ msgid "software installation instructions" +#~ msgstr "instruções de instalação de aplicação" + +#~ msgid "software license terms" +#~ msgstr "termos de licença de aplicação" + +#~ msgid "source code patch" +#~ msgstr "patch de código fonte" + +#~ msgid "style sheet" +#~ msgstr "folha de estilo" + +#~ msgid "symbolic link" +#~ msgstr "link simbólico" + +#~ msgid "tab-separated text document" +#~ msgstr "documento separado por tabs" + +#~ msgid "tar archive" +#~ msgstr "ficheiro tar" + +#~ msgid "tar archive (bzip2-compressed)" +#~ msgstr "ficheiro tar (comprimido bzip2)" + +#~ msgid "tar archive (gzip-compressed)" +#~ msgstr "ficheiro tar (comprimido gzip)" + +#~ msgid "theme" +#~ msgstr "tema" + +#~ msgid "troff document" +#~ msgstr "documento troff" + +#~ msgid "troff me input document" +#~ msgstr "documento de entrada troff me" + +#~ msgid "troff mm input document" +#~ msgstr "documento de entrada troff mm" + +#~ msgid "troff ms input document" +#~ msgstr "documento de entrada troff ms" + +#~ msgid "unknown type" +#~ msgstr "tipo desconhecido" + +#~ msgid "ustar archive" +#~ msgstr "ficheiro ustar" + +#~ msgid "wave audio" +#~ msgstr "audio wave" + +#~ msgid "web folder" +#~ msgstr "pasta web" + +#~ msgid "xfig vector graphic" +#~ msgstr "gráfico de vector xfig" + +#~ msgid "zip archive" +#~ msgstr "ficheiro zip" + +#~ msgid "zoo archive" +#~ msgstr "ficheiro zoo" + +#~ msgid "GNOME VFS already initialized." +#~ msgstr "GNOME VFS já inicializado." diff --git a/po/pt_BR.gmo b/po/pt_BR.gmo new file mode 100644 index 0000000000000000000000000000000000000000..07f528b204a5ad839c32f5cd038bdfb49aff0df2 GIT binary patch literal 5641 zcmai%ZHygN8GsL#FBd^U!4E)=%G&aAx4T=b%L1j_?ryu#ZI^Zz4g8RE@0@$@v@>&t zIdiw&n#d0mKSDxG1kpbx1p-3S7(>v+XhL#B2nPLSNHkzHXhMv}82o|87@zmd+}|UnrfV)jS?^vb^JBP6AF`W&Q;SDf6y{qR&n! zBa{44i|9Aud+m zh9807gQDNr`u!#N)$^2kt$x3cO=WxzC9Y1@?+-$W-*3QA!zXLL1jTNDfinIrD02N9 zvZT5gi`tJ?u9I^awvK{2tNbA zU-$n4irrsABQ5x z>rnK6yXIvm_bJ}5hw^<9ik=3F{_8a#hGM6upv->(B8qwy%KmRcvESuPz7g(*GX8!j z{yq&w-p8P<`$H)5y#VDLy#i&ue?Selv5CaT^-$J10PlhZN?e_Vvd;5R{QWB^`}`H2 z2j!Wo5a!8GL{uv@vA2xfMce#HoDeSIxrM*thZ|_Jk34&6pQGJGo1iVy_RvVh;kk{! zchumy5gQz! z$=MM5;NI{^%-vl79*5KQZ}FKt4cZb-Y>nyEPTF?bewxIaJh&u0yKCMJC8i|KKU??7 zSr9+oLA#wMcfw(s#IE>Rd^3@HWhtH>JTwMbXPk1fP$iY99t*wD?M-`Mmjo7*%mH`D?WxOSMO7K#ED6VuCDUDjg9G{qWqzlgJ`S0{01)uNcp zo{D|xtKUOaN3UYD>aBE6H{(utVZ2KsoD7Q;fn{dUMIEr2E#j88B9A&~lUyBizQi?R zN^PR3z>QU(#KESiVcbXtdG%^(=aG7?r3_PNCKwnk*^Nr!`zy@NAo2Qfkfsp{b4ct`!r7k$kLd!jCFWix8D-M-OS=>e|%G5TBct z)roDFn(2{Uk6Y5uf}50)cbmChr^|^-36U^@@nzR)FCvB0;5P`)R2`A9PdUe%Oif=M z>@AbEY$Em;^0BTxD+Kv{l0X0PR~l=O4o7&uN}3VRhK0j zTSS!J#yNT)=vhL?HN8vls@I$`G01k(0H;bFt6qa%W*w)QCa3>cN!)X+^|H(26P(UA z&JZK5;wR3;M&#k}+-Uae&(GIx?(k-5~~vv};7wI^1bkAq9cqv7|;pM%lI zT~nWsq%htaj&QjyH%LFB%lGo!6_`mfQDuI$=7}G?HZBpk9v3c4Z6;@_h(#GZxt4xBbMyg}M2Oy!`UMqhl*aRvY^zy)vXhh9lKYPfqS?OwKf> zck8KLvr{uSP13`_#!-S;mfA9IcVl`+Pwk$azU8K=NyZ%_kv3KflljEptXVy8*13W9 znc_5V-O#r+>tB00cU@CXkl*$&E9>-3$2L~2NoVy6*6nqO8LMy0%e_fF;fl_lvE`-Z zg^@l}6O&`)dkn;e_-0m@_EfnuPq@Qw4fhx6`1ZBc#m3BNoCt>L8w+HKh@>&AXPR+2 zwy!XV7n^L$)=88%n#JCxIc*B$%&=&@ZbagVX0b<)eW?+WWTod_`%Kd&TBPFUt#4e- z4ctG&73}`c-J3h_d$DfSmo7(yOL%a#X8k9eu1AOyNhdn(KU2EMz4wskxQ1oOyKZ1I zx6_&Jn8pvt+oXgPv^{lXSaC7H-|Jq4bIV)sB+kv$9}U z&Xi=1s1i4FY5!~%yK@L>xNc%^2*+`BWNjaAa+l^z_SJ-XSsUwKI#B(cl42rVJCv(? zc)geX=Ze^A*XreBQMvK!uAtI7!R5Gb(@jPV_qjF>+s0fhq6=|F!gIqf1EEP6Ty0%0 z4l!FbW?;#1>)WAW!*&Dvh;M6yhkoL-C`Wy14?pV;Cn6dy;MEG}7f)5?fJj%XTS-M4 z>OVtOz$(Xkkx|S2GlWQHbl8APisVPSvi+y=!Z1?nF{8D%P8-TQTF+P8q42`aW7Y3C zR1Hq89bFnqWe~UMKTf4kY>rZ|`ri^KO4U&LfwG}92=PUebX^a7CsIVHdx)79$ApN8 z3w{`G%TPo}h)Hnlr{uFfcUjbbHp5j?RWO3GNQzi(GCAO6Dnd~rIg}JKk)lE@P??#` zWHXOZY}W0ioRTW+hgC*ZUSQE`Kv=#C%WnUSCSyrGM0qYdcI4_n5a}Q<$f2Vo@!YX2 z%y$YAZd6=B4T2-2T8m;7kb7@^bUL;gXxXL`#0J~?UYn3)aS9gEi214YDTj>;v)*Hn z8mO)!DV8|)1Q&((&^NBCAu2tq;>4g|C@iW@L>yEnTLuSD7vXGf86RS-DpBICD~Sz~ z__VCQfL}x&Ru1KgQ^(#dwf1-h{VL-nHWta>YhYtAX2nKi3~qA@*g-wR!IwHlk_w+f zMw0jsMNP237%_Mt3kggu_Ro+cTZZkU5HrYIU-(`v%dwO!Q-|fCV_@;h(!}NBFetn_ zXMq!u%U#x`=s+y0o!T^`PPH26!B|9kQ%(hj8-0~pXD}etIfIZL4ly!hlS6}pD2}+j z#T8N#$^VRsxPL}&3W<`m83Ienq!75os1!vQga7kT3yBxmNAheGS2dFL6i0U&{-Z}; fs;w|E*RVdS3m?u#ouI@O!(vID<1@lk$x;0e#L@|_ literal 0 HcmV?d00001 diff --git a/po/pt_BR.po b/po/pt_BR.po new file mode 100644 index 0000000..135803a --- /dev/null +++ b/po/pt_BR.po @@ -0,0 +1,1157 @@ +# translation of gnome-vfs.HEAD.pt_BR.po to Portuguese +# GNOME vfs translation for Brazilian Portuguese. +# Copyright (C) 1999-2001,2003 Free Software Foundation, Inc. +# Alexandre Hautequest , 1999. +# Gustavo Maciel Dias Vieira , 2000-2001. +# David Barzilay , 2003 +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs.HEAD.pt_BR\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-05-28 15:29+1000\n" +"Last-Translator: David Barzilay \n" +"Language-Team: Portuguese \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Brazilian Portuguese \n" +"X-Generator: KBabel 1.0\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d possui caracteres NUL." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d não possui nome de método." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d não possui nome de módulo." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Arquivo de configuração `%s' não foi achado: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Tipo de operação desconhecida %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "Não é possível criar pipe para abrir GIOChannel: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Tipo de trabalho desconhecido %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Operação paralizada" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Não é possível analisar: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Mais erros de análise serão ignorados." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Nenhum erro" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Arquivo não encontrado" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Erro genérico" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Erro interno" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Parâmetros inválidos" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Operação não suportada" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "Erro de E/S" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Dados corrompidos" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Formato inválido" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Descritor de arquivos inválido" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "Arquivo muito grande" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Sem espaço no dispositivo" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Sistema de arquivos somente-leitura" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "URI inválida" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Arquivo não aberto" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Modo de abertura inválido" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Acesso negado" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "Muitos arquivos abertos" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Fim de arquivo" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Não é um diretório" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Operação em progresso" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Operação interrompida" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Arquivo existe" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Vínculos circulares encontrados" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Operação não permitida" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "É um diretório" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Memória insuficiente" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Máquina não encontrada" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Nome de máquina inválido" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Máquina não tem endereço" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Falhou o login" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Operação cancelada" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Diretório ocupado" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Diretório não vazio" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "Muitos vínculos" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Sistema de arquivos somente para leitura" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Não no mesmo sistema de arquivos" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Nome muito extenso" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Serviço não disponível" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Pedido torna obsoleto os dados do serviço" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Erro de protocolo" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "Não foi possível encontrar o servidor de domínio" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "Nenhuma ação default associada" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "Não há ferramenta de gerenciamento para o esquema de URL" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "Erro ao analisar a linha de comando" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "Erro ao iniciar o comando" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Erro desconhecido" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 byte" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u bytes" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (Unicode inválido)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "GnomeVFSSeekPosition desconhecido %d" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "Não encontrei um arquivo de configurações válido em %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "" +"Use a variável de ambiente %s para especificar localizações diferentes.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "Aplicações" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "Placas" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "Arquivos" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "Pastas" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "Ajuda" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "Máquinas" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "Ligações" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "Correspondência" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "Ferramentas" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "Janelas" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Fábrica padrão de Monikers" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "arquivo MonikerExtender" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "moniker genérico do Gnome VFS" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "moniker genérico de arquivo" + +#~ msgid "3D Studio image" +#~ msgstr "imagem do 3D Studio" + +#~ msgid "AIFC audio" +#~ msgstr "áudio AIFC" + +#~ msgid "AIFF audio" +#~ msgstr "áudio AIFF" + +#~ msgid "ANIM animation" +#~ msgstr "animação ANIM" + +#~ msgid "AVI video" +#~ msgstr "vídeo AVI" + +#~ msgid "AbiWord document" +#~ msgstr "documento do AbiWord" + +#~ msgid "Adobe FrameMaker font" +#~ msgstr "fonte do Adobe FrameMaker" + +#~ msgid "Adobe font metrics" +#~ msgstr "métricas de fonte Adobe" + +#~ msgid "Andrew Toolkit inset" +#~ msgstr "inset do Andrew Toolkit" + +#~ msgid "ApplixWare Graphics image" +#~ msgstr "imagem do ApplixWare Graphics" + +#~ msgid "Applixware Words document" +#~ msgstr "documento do Applixware Words" + +#~ msgid "Applixware spreadsheet" +#~ msgstr "planilha do Applixware" + +#~ msgid "AutoCAD image" +#~ msgstr "imagem do AutoCAD" + +#~ msgid "BCPIO document" +#~ msgstr "documento BCPIO" + +#~ msgid "BDF font" +#~ msgstr "fonte BDF" + +#~ msgid "C shell script" +#~ msgstr "script de shell C" + +#~ msgid "C source code" +#~ msgstr "código fonte C" + +#, fuzzy +#~ msgid "C source code header" +#~ msgstr "código fonte C" + +#~ msgid "C++ source code" +#~ msgstr "código fonte C++" + +#~ msgid "CGI program" +#~ msgstr "programa CGI" + +#~ msgid "CGM image" +#~ msgstr "imagem CGM" + +#~ msgid "CMU raster image" +#~ msgstr "imagem raster CMU" + +#~ msgid "CPIO archive" +#~ msgstr "arquivo CPIO" + +#~ msgid "CPIO archive (gzip-compressed)" +#~ msgstr "arquivo CPIO (comprimido com gzip)" + +#~ msgid "DCL script" +#~ msgstr "script DCL" + +#~ msgid "DOS font" +#~ msgstr "fonte de DOS" + +#~ msgid "DOS/Windows program" +#~ msgstr "programa DOS/Windows" + +#~ msgid "DSSSL document" +#~ msgstr "documento DSSSL" + +#~ msgid "DXF vector graphic" +#~ msgstr "gráfico vetorial DXF" + +#~ msgid "Debian package" +#~ msgstr "pacote Debian" + +#~ msgid "Dia diagram" +#~ msgstr "diagrama do Dia" + +#~ msgid "Dolby Digital audio" +#~ msgstr "áudio Dolby Digital" + +#~ msgid "Emacs Lisp source code" +#~ msgstr "código fonte Emacs Lisp" + +#~ msgid "Enlightenment theme" +#~ msgstr "tema do Enlightenment" + +#~ msgid "FLC animation" +#~ msgstr "animação FLC" + +#~ msgid "FLI animation" +#~ msgstr "animação FLI" + +#~ msgid "FastTracker II audio" +#~ msgstr "áudio FastTracker II" + +#~ msgid "Fortran source code" +#~ msgstr "código fonte Fortran" + +#~ msgid "FrameMaker interchange document" +#~ msgstr "documento de intercâmbio do FrameMaker" + +#~ msgid "G3 fax image" +#~ msgstr "imagem de fax G3" + +#~ msgid "GIF image" +#~ msgstr "imagem GIF" + +#~ msgid "GIMP document" +#~ msgstr "documento do GIMP" + +#~ msgid "GMC link" +#~ msgstr "vínculo GMC" + +#~ msgid "GNOME application details" +#~ msgstr "detalhes de aplicativo Gnome" + +#~ msgid "GNU Oleo Spreadsheet" +#~ msgstr "planilha do GNU Oleo" + +#~ msgid "GNU mail message" +#~ msgstr "mensagem de correio GNU" + +#~ msgid "GTK configuration" +#~ msgstr "configuração do GTK" + +#~ msgid "Glade project" +#~ msgstr "projeto do Glade" + +#~ msgid "GnuCash Workbook" +#~ msgstr "livro de trabalho GnuCash" + +#~ msgid "Gnumeric spreadsheet" +#~ msgstr "planilha do Gnumeric" + +#~ msgid "HDF document" +#~ msgstr "documento HDF" + +#~ msgid "HTML page" +#~ msgstr "página HTML" + +#~ msgid "IDL document" +#~ msgstr "documento IDL" + +#~ msgid "IEF image" +#~ msgstr "imagem IEF" + +#~ msgid "IFF image" +#~ msgstr "imagem IFF" + +#~ msgid "ILBM image" +#~ msgstr "imagem ILBM" + +#~ msgid "ISI video" +#~ msgstr "vídeo ISI" + +#~ msgid "Impulse Tracker audio" +#~ msgstr "áudio Impulse Tracker" + +#~ msgid "JBuilder Project" +#~ msgstr "projeto do JBuilder" + +#~ msgid "JPEG image" +#~ msgstr "imagem JPEG" + +#~ msgid "Java byte code" +#~ msgstr "código compilado Java" + +#~ msgid "Java source code" +#~ msgstr "código fonte Java" + +#~ msgid "KIllustrator document" +#~ msgstr "documento do KIllustrator" + +#~ msgid "KPresenter presentation" +#~ msgstr "apresentação do KPresenter" + +#~ msgid "KSpread spreadsheet" +#~ msgstr "planilha do KSpread" + +#~ msgid "KWord document" +#~ msgstr "documento do KWord" + +#~ msgid "Korn shell script" +#~ msgstr "script de shell Korn" + +#~ msgid "LHA archive" +#~ msgstr "arquivo LHA" + +#~ msgid "LHARC archive" +#~ msgstr "arquivo LHARC" + +#~ msgid "LIBGRX font" +#~ msgstr "fonte LIBGRX" + +#~ msgid "LightWave object" +#~ msgstr "objeto LightWave" + +#~ msgid "LightWave scene" +#~ msgstr "cena LightWave" + +#~ msgid "Linux PSF console font" +#~ msgstr "fonte de console Linux PSF" + +#~ msgid "Lotus 1-2-3 spreadsheet" +#~ msgstr "planilha do Lotus 1-2-3" + +#~ msgid "M3 audio URL" +#~ msgstr "URL de áudio M3" + +#~ msgid "MIDI audio" +#~ msgstr "áudio MIDI" + +#~ msgid "MOD audio" +#~ msgstr "áudio MOD" + +#~ msgid "MP3 audio" +#~ msgstr "áudio MP3" + +#~ msgid "MP3 audio playlist" +#~ msgstr "lista de áudio MP3" + +#~ msgid "MPEG video" +#~ msgstr "vídeo MPEG" + +#~ msgid "MS ASF video" +#~ msgstr "vídeo MS ASF" + +#~ msgid "MS video" +#~ msgstr "vídeo MS" + +#~ msgid "Macintosh AppleDouble-encoded file" +#~ msgstr "arquivo Macintosh codificado com AppleDouble" + +#~ msgid "Macintosh BinHex-encoded file" +#~ msgstr "arquivo Macintosh codificado com BinHex" + +#~ msgid "Macintosh StuffIt archive" +#~ msgstr "arquivo Macintosh StuffIt" + +#~ msgid "Macromedia Flash file" +#~ msgstr "arquivo Macromedia Flash" + +#~ msgid "MathML document" +#~ msgstr "documento MathML" + +#~ msgid "Microsoft Excel spreadsheet" +#~ msgstr "planilha do Microsoft Excel" + +#~ msgid "Microsoft PowerPoint document" +#~ msgstr "documento do Microsoft PowerPoint" + +#~ msgid "Microsoft Word document" +#~ msgstr "documento do Microsoft Word" + +#~ msgid "Microsoft video" +#~ msgstr "vídeo Microsoft" + +#~ msgid "Nautilus link" +#~ msgstr "vínculo do Nautilus" + +#~ msgid "ODA document" +#~ msgstr "documento ODA" + +#~ msgid "PBM image" +#~ msgstr "imagem PBM" + +#~ msgid "PCF font" +#~ msgstr "fonte PCF" + +#~ msgid "PDF document" +#~ msgstr "documento PDF" + +#~ msgid "PEF program" +#~ msgstr "programa PEF" + +#~ msgid "PGM image" +#~ msgstr "imagem PGM" + +#~ msgid "PGN chess game" +#~ msgstr "jogo de xadrez PGN" + +#~ msgid "PGP keys" +#~ msgstr "chaves PGP" + +#~ msgid "PGP message" +#~ msgstr "mensagem PGP" + +#~ msgid "PGP signature" +#~ msgstr "assinatura PGP" + +#~ msgid "PGP-encrypted file" +#~ msgstr "arquivo cifrado com PGP" + +#~ msgid "PHP script" +#~ msgstr "script PHP" + +#~ msgid "PN RealAudio document" +#~ msgstr "documento RealAudio PN" + +#~ msgid "PNG image" +#~ msgstr "imagem PNG" + +#~ msgid "PNM image" +#~ msgstr "imagem PNM" + +#~ msgid "PPM image" +#~ msgstr "imagem PPM" + +#~ msgid "Palm OS database" +#~ msgstr "banco de dados Palm OS" + +#~ msgid "Perl script" +#~ msgstr "script Perl" + +#~ msgid "Photoshop document" +#~ msgstr "documento do Photoshop" + +#~ msgid "PostScript Type 1 font" +#~ msgstr "fonte PostScript Type 1" + +#~ msgid "PostScript document" +#~ msgstr "documento PostScript" + +#~ msgid "Python source code" +#~ msgstr "código fonte Python" + +#~ msgid "QuickTime movie" +#~ msgstr "filme QuickTime" + +#~ msgid "Quicken document" +#~ msgstr "documento do Quicken" + +#~ msgid "Quicken for Windows document" +#~ msgstr "documento do Quicken para Windows" + +#~ msgid "RAR archive" +#~ msgstr "arquivo RAR" + +#~ msgid "README document" +#~ msgstr "documento README" + +#~ msgid "RGB image" +#~ msgstr "imagem RGB" + +#~ msgid "RIFF audio" +#~ msgstr "áudio RIFF" + +#~ msgid "RPM package" +#~ msgstr "pacote RPM" + +#~ msgid "RealAudio/Video document" +#~ msgstr "documento RealAudio/Video" + +#~ msgid "RealVideo video" +#~ msgstr "vídeo RealVideo" + +#~ msgid "S/MIME file" +#~ msgstr "arquivo S/MIME" + +#~ msgid "S/MIME signature" +#~ msgstr "assinatura S/MIME" + +#~ msgid "SGI video" +#~ msgstr "vídeo SGI" + +#~ msgid "SGML document" +#~ msgstr "documento SGML" + +#~ msgid "SMIL script" +#~ msgstr "script SMIL" + +#~ msgid "SQL code" +#~ msgstr "código SQL" + +#~ msgid "SV4 CPIO archive" +#~ msgstr "arquivo SV4 CPIO" + +#~ msgid "SV4 CPIP archive (with CRC)" +#~ msgstr "arquivo SV4 CPIP (com CRC)" + +#~ msgid "SVG art" +#~ msgstr "arte SVG" + +#~ msgid "Scheme source code" +#~ msgstr "código fonte Scheme" + +#~ msgid "Scream Tracker 3 audio" +#~ msgstr "áudio Scream Tracker 3" + +#~ msgid "Scream Tracker audio" +#~ msgstr "áudio Scream Tracker" + +#~ msgid "Scream Tracker instrument" +#~ msgstr "instrumento Scream Tracker" + +#~ msgid "Setext document" +#~ msgstr "documento Setext" + +#~ msgid "Speech document" +#~ msgstr "documento Speech" + +#~ msgid "Speedo font" +#~ msgstr "fonte Speedo" + +#~ msgid "Spreadsheet Interchange document" +#~ msgstr "documento Spreadsheet Interchange" + +#~ msgid "Stampede package" +#~ msgstr "pacote Stampede" + +#~ msgid "StarOffice Writer document" +#~ msgstr "documento do StarOffice Writer" + +#~ msgid "StarOffice presentation" +#~ msgstr "apresentação do StarOffice" + +#~ msgid "StarOffice spreadsheet" +#~ msgstr "planilha do StarOffice" + +#~ msgid "Sun mu-law audio" +#~ msgstr "áudio Sun µ-law" + +#~ msgid "SunOS News font" +#~ msgstr "fonte SunOS News" + +#~ msgid "TIFF image" +#~ msgstr "imagem TIFF" + +#~ msgid "TarGA image" +#~ msgstr "imagem TarGA" + +#~ msgid "Tcl script" +#~ msgstr "script Tcl" + +#~ msgid "TeX document" +#~ msgstr "documento TeX" + +#~ msgid "TeX dvi document" +#~ msgstr "documento TeX dvi" + +#~ msgid "TeX font" +#~ msgstr "fonte TeX" + +#~ msgid "TeX font metrics" +#~ msgstr "métrica de fonte TeX" + +#~ msgid "TeXInfo document" +#~ msgstr "documento TeXInfo" + +#~ msgid "ToutDoux document" +#~ msgstr "documento do ToutDoux" + +#~ msgid "TrueType font" +#~ msgstr "fonte TrueType" + +#~ msgid "USENET news message" +#~ msgstr "mensagem de notícia USENET" + +#~ msgid "Unidata netCDF document" +#~ msgstr "documento Unidata netCDF" + +#~ msgid "V font" +#~ msgstr "fonte V" + +#~ msgid "VOC audio" +#~ msgstr "áudio VOC" + +#~ msgid "VRML document" +#~ msgstr "documento VRML" + +#~ msgid "Vivo video" +#~ msgstr "vídeo Vivo" + +#~ msgid "WAIS source code" +#~ msgstr "código fonte WAIS" + +#~ msgid "Wavelet video" +#~ msgstr "vídeo Wavelet" + +#~ msgid "Windows bitmap image" +#~ msgstr "imagem bitmap do Windows" + +#~ msgid "Windows icon image" +#~ msgstr "imagem de ícone do Windows" + +#~ msgid "Windows metafile graphics" +#~ msgstr "gráfico metafile do Windows" + +#~ msgid "WordPerfect document" +#~ msgstr "documento do WordPerfect" + +#~ msgid "X bitmap image" +#~ msgstr "imagem bitmap do X" + +#~ msgid "X window image" +#~ msgstr "imagem de janela do X" + +#~ msgid "XML document" +#~ msgstr "documento XML" + +#~ msgid "XPM image" +#~ msgstr "imagem XPM" + +#~ msgid "Xbase database" +#~ msgstr "banco de dados Xbase" + +#~ msgid "active server page" +#~ msgstr "active server page" + +#~ msgid "address card" +#~ msgstr "cartão de endereço" + +#~ msgid "ar archive" +#~ msgstr "arquivo ar" + +#~ msgid "arj archive" +#~ msgstr "arquivo arj" + +#~ msgid "authors list" +#~ msgstr "lista de autores" + +#~ msgid "backup file" +#~ msgstr "arquivo de backup" + +#~ msgid "basic audio" +#~ msgstr "áudio básico" + +#~ msgid "bibliography record" +#~ msgstr "registro bibliográfico" + +#~ msgid "binary program" +#~ msgstr "programa binário" + +#~ msgid "block device" +#~ msgstr "dispositivo de bloco" + +#~ msgid "bzip-compressed file" +#~ msgstr "arquivo comprimido com bzip" + +#~ msgid "calendar file" +#~ msgstr "arquivo de agenda" + +#~ msgid "calendar or event document" +#~ msgstr "documento de agenda ou evento" + +#~ msgid "character device" +#~ msgstr "dispositivo de caracter" + +#~ msgid "comma-separated text document" +#~ msgstr "documento texto separado por vírgulas" + +#~ msgid "compound document" +#~ msgstr "documento composto" + +#~ msgid "compress-compressed file" +#~ msgstr "arquivo comprimido com compress" + +#~ msgid "compressed GIMP document" +#~ msgstr "documento do GIMP comprimido" + +#~ msgid "directory information file" +#~ msgstr "arquivo de informação de diretório" + +#~ msgid "document type definition" +#~ msgstr "definição de tipo de documento" + +#~ msgid "email headers" +#~ msgstr "cabeçalhos de e-mail" + +#~ msgid "email message" +#~ msgstr "mensagem de e-mail" + +#~ msgid "encrypted message" +#~ msgstr "mensagem cifrada" + +#~ msgid "enriched text document" +#~ msgstr "documento de texto enriquecido" + +#~ msgid "gtar archive" +#~ msgstr "arquivo gtar" + +#~ msgid "gzip-compressed file" +#~ msgstr "arquivo comprimido com gzip" + +#~ msgid "help page" +#~ msgstr "página de ajuda" + +#~ msgid "mail delivery report" +#~ msgstr "relatório de entrega de correio" + +#~ msgid "mail disposition report" +#~ msgstr "relatório de disposição de correio" + +#~ msgid "mail system report" +#~ msgstr "relatório do sistema de correio" + +#~ msgid "makefile" +#~ msgstr "makefile" + +#~ msgid "manual page" +#~ msgstr "página de manual" + +#~ msgid "manual page (compressed)" +#~ msgstr "página de manual (comprimida)" + +#~ msgid "memory dump" +#~ msgstr "descarga de memória" + +#~ msgid "message digest" +#~ msgstr "resumo de mensagem" + +#~ msgid "message in several formats" +#~ msgstr "mensagem em vários formatos" + +#~ msgid "multi-part message" +#~ msgstr "mensagem multi-part" + +#~ msgid "named pipe" +#~ msgstr "named pipe" + +#~ msgid "object code" +#~ msgstr "código objeto" + +#~ msgid "ogg audio" +#~ msgstr "áudio ogg" + +#~ msgid "partial email message" +#~ msgstr "mensagem de e-mail parcial" + +#~ msgid "plain text document" +#~ msgstr "documento texto simples" + +#~ msgid "profiler results" +#~ msgstr "resultados de profiler" + +#~ msgid "reference to remote file" +#~ msgstr "referência à um arquivo remoto" + +#~ msgid "rejected patch file" +#~ msgstr "arquivo de patch rejeitado" + +#~ msgid "rich text document" +#~ msgstr "documento de texto rico" + +#~ msgid "search results" +#~ msgstr "resultados de busca" + +#~ msgid "shared library" +#~ msgstr "biblioteca compartilhada" + +#~ msgid "shell archive" +#~ msgstr "arquivo shell" + +#~ msgid "shell script" +#~ msgstr "script shell" + +#~ msgid "signed message" +#~ msgstr "mensagem assinada" + +#~ msgid "socket" +#~ msgstr "socket" + +#~ msgid "software author credits" +#~ msgstr "créditos de autor de software" + +#~ msgid "software installation instructions" +#~ msgstr "instruções de instalação de software" + +#~ msgid "software license terms" +#~ msgstr "termos da licença de software" + +#~ msgid "source code patch" +#~ msgstr "patch de código fonte" + +#~ msgid "style sheet" +#~ msgstr "style sheet" + +#~ msgid "symbolic link" +#~ msgstr "vínculo simbólico" + +#~ msgid "tab-separated text document" +#~ msgstr "documento texto separado por tabulações" + +#~ msgid "tar archive" +#~ msgstr "arquivo tar" + +#~ msgid "tar archive (bzip2-compressed)" +#~ msgstr "arquivo tar (comprimido com bzip2)" + +#~ msgid "tar archive (gzip-compressed)" +#~ msgstr "arquivo tar (comprimido com gzip)" + +#~ msgid "theme" +#~ msgstr "tema" + +#~ msgid "troff document" +#~ msgstr "documento troff" + +#~ msgid "troff me input document" +#~ msgstr "documento de entrada troff me" + +#~ msgid "troff mm input document" +#~ msgstr "documento de entrada troff mm" + +#~ msgid "troff ms input document" +#~ msgstr "documento de entrada troff ms" + +#~ msgid "unknown type" +#~ msgstr "tipo desconhecido" + +#~ msgid "ustar archive" +#~ msgstr "arquivo ustar" + +#~ msgid "wave audio" +#~ msgstr "áudio wave" + +#~ msgid "web folder" +#~ msgstr "pasta web" + +#~ msgid "xfig vector graphic" +#~ msgstr "gráfico vetorial do Xfig" + +#~ msgid "zip archive" +#~ msgstr "arquivo zip" + +#~ msgid "zoo archive" +#~ msgstr "arquivo zoo" diff --git a/po/ro.gmo b/po/ro.gmo new file mode 100644 index 0000000000000000000000000000000000000000..48cbdc517867d6603c8eb6fcd2a7a123391d3b4a GIT binary patch literal 3937 zcmai$O>7-U9l)2SEnuKPfI|7|wBUxOUB`A3a7`LDb)3{~YzNz^5Fdi^?!5P=*_~N- zcAdU(ffFD^)e8s2p;9Fz4pos5;t-)8xD>$w#DyLZLU~n1F9;++9FXDn-`(f;5)~L_ z{Co5D-~ar-CVx15>vtpCL-Y^RUwu;)ZNe80@rU-OTchaB@O5}Q{A)Mg z9Z$ozF#Sa+`+M*mFo*AiUxi2Ex8eQpr|>=SkMIuow~mK6Ec1uq+u(g27oqGs4Mpxc zd^`L+d>0&a^Ft`-ztQpgP|p1bz7@XIjeh|}{_o&nIO^vA0Y&a@T>dV27=9c+2<5w< zfpX6;!S}-fl>2=Rz8gLZKLnqLqQ^@ee+%Eo__dDzf^z;a!sOghDC?&>Zb8L((2c(Z zC_b`4HioUmV8L`g^ z$iL`u{wVlaDBl~x_rmW$vB&dJ;{BIU^nM-6zFYXX@J=Z6N1^Dw0wr#?q3E4MiT7_p z$+I6rIrnQQ_8-A};lH8ie=kDh`zN8;<8g=^qxUR)eWb~E#8z{3@#QUaX{2=1KGyMA#~8{Tq{$tniH_1FCopNWNS8R2I~}EelCJ2| z=IKqXXhvRpptgQb` zT)8akqC$_ewlqoQ%c0t>!*FUSr%YZ{!)Vo|%J-TNMdw6i^Rx|BXn!Aka55B~+fn7c z+O_@YoG)`-HHz%%%%;(K<4kE2Wy;c*(PKVT*g>>cI!#N=)Xs^Wr%pBdCLdfow%G|- zb2!ZD>|oe@MP1rji`HEG8v`Ir{2HwVrByn-s9Q?s8DZCD@Wf ztgQPIzhFjLZuAc7ip?^$Yn1IfR@1p?Lll-#h0{{AXA{GQ z>IPM0Y@DzA10pTQDa{V{R|BJh$ZkR=3`1q|Xj5V%_vy5WnCs#q(JnEW+-Wk$J&V%! z8v{?za>FhhCbME^gypu9FqzDU$`=JQTZRbsE*svUlg!3%F#DC-;A6iVe1;Q(3Z@hb z93dZw$7s79Hon$-xI*ue6FV3(*KXK)V>0w|aj`^*F1gFjUm-=D&&`wPwzrMBe9;Hn zq{eJ|u-*pRc(*T9H6+7kYc_ZWwowLTL*QQT{0!xzGLG+Ifn`;hr>kQ{M*aJAQ~QFc9$wqt zjF*;9J`^ubHj8pSQ^u>LL`n)QtEF9A&HUfWx^JCPNmo;il-RDUx>^cvv+QhQRqd3k ziEzT1JoV{lTwwp#Mya>#tCgo@S5(@TO{rCcIk_C7vnC{^Eif!WbIqDkk|0#kMy(2h zTuQE}(v-nEYilnNR+Tl%gk)e-3V>EORpE1uDE4!-EyvV{rVgX9rU(=7{SlGaRNakO z=c=fynxrZ{4}l&RW31zwnqX+d?ZYD>i zIFHn1;wE)&SZJiRmy~+mi74c{xh_ptxRE;ka$CMvOV6t6w^e);o!3`WEqi2EO93BY z-Q4h2^jR{tRok|;cxwBUnMP43m9jqmX`8w}iYVl2eE4Ep$V+PvrdGvT#Lu{aTy&m5-8On+3>rImQZ>^8}azB-E5wN-hYA;a(*S&6{TN9@{bqNc6zWI83j zy;ozo#!y);rCvf<%DosyA}dE|vxmaJZ;3P_+lInlr8MoyhGubE>2<02mdAvO)I%H* zC|0CYD&5OQB7r9))7PvDxY*>PXzP8$>qI6@h3icY+m1Eq;A*$eGo0zR((PN**7bd> zvC;Txn4YUjVyZxorvA%5oZMbro(9}}u;7c*vT?grt<_7Vm?KWOGDf*!1#3(#t&m{Y zdYp9fKcM!35GNa=T#V;beYJZi>{LWHR&{pQW>js7+s2b)S5MD%w(6`DO!QwK4Mi!a koexP}jRSEqGm3U>f&Hd7$urWKp{Ce5!;8X$qOrz*08>H_rT_o{ literal 0 HcmV?d00001 diff --git a/po/ro.po b/po/ro.po new file mode 100644 index 0000000..3801cd9 --- /dev/null +++ b/po/ro.po @@ -0,0 +1,1461 @@ +# gnome-vfs +# Copyright (C) YEAR Free Software Foundation, Inc. +# Marius Andreiana , 2001. +# +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2001-02-24 11:22+0200\n" +"Last-Translator: Marius Andreiana \n" +"Language-Team: Românã \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=ISO-8859-2\n" +"Content-Transfer-Encoding: 8bit\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d conþine caractere NUL" + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d nu conþine nici un nume de metodã." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d nu conþine nici un nume de modul." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Fiºierul configurare `%s' nu a fost gãsit: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Tip op necunoscut %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "Nu pot crea conectorul pipe pentru deschiderea GIOChannel: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, fuzzy, c-format +msgid "Unknown job kind %u" +msgstr "ID activitate necunoscut %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Operaþia opritã" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "N-am putut procesa: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Mai multe erori de procesare vor fi ignorate." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Nici o eroare" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Fiºierul nu a fost gãsit" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Eroare genericã" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Eroare internã" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Parametrii invalid" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Operaþiune nesuportatã" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "Eroare I/O" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Date corupte" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Formatul nu este valid" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Descriptor fiºier prost" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "Fiºierul prea mare" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Nu mai este spaþiu pe dispozitiv" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Sistem fiºiere doar-citire" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "URI invalid" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Fiºierul nu este deschis" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Modul deschidere nu este valid" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Acces respins" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "Prea multe fiºiere deschise" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Sfârºit fiºier" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Nu este un director" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Operaþia în progres" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Operaþia întreruptã" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Fiºierul existã " + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Am înâlnit legãturi care cicleazã" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Operaþia nu este permisã" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "Este un director" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Memorie insuficientã" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Gazda nu a fost gãsitã" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Numele gazdei este invalid" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Gazda nu are adresã" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Login eºuat" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "S-a renunþat la operaþie" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Directorul este ocupat" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Directorul nu este gol" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "Prea multe legãturi" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Sistem fiºier doar-citire" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Nu se aflã pe acelaºi sistem de fiºiere" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Numele este prea lung" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Serviciul nu este disponibil" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Cerere pentru date servicii ieºite din uz" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +#, fuzzy +msgid "Protocol error" +msgstr "Nici o eroare" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +#, fuzzy +msgid "Could not find master browser" +msgstr "N-am putut procesa: %s" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Eroare necunoscutã" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 octet" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u octet" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr "" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "GnomeVFSSeekPosition %d necunoscut" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +#, fuzzy +msgid "Applications" +msgstr "Aplicaþie nouã" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +#, fuzzy +msgid "Files" +msgstr "Fiºierul existã " + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +#, fuzzy +msgid "Folders" +msgstr "dosar" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +#, fuzzy +msgid "generic file moniker" +msgstr "Eroare genericã" + +#~ msgid "3D Studio image" +#~ msgstr "Imagine 3D Studio" + +#~ msgid "AIFC audio" +#~ msgstr "Audio AIFC" + +#~ msgid "AIFF audio" +#~ msgstr "Audio AIFF" + +#~ msgid "ANIM animation" +#~ msgstr "Animaþie ANIM" + +#~ msgid "AVI video" +#~ msgstr "Video AVI" + +#~ msgid "AbiWord document" +#~ msgstr "Document AbiWord" + +#~ msgid "Adobe FrameMaker font" +#~ msgstr "Font Adobe FrameMaker" + +#~ msgid "Adobe font metrics" +#~ msgstr "Dimensiuni font Adobe" + +#~ msgid "Andrew Toolkit inset" +#~ msgstr "Set Andrew Toolkit" + +#~ msgid "ApplixWare Graphics image" +#~ msgstr "Imagine ApplixWare Graphics" + +#~ msgid "Applixware Words document" +#~ msgstr "Document Applixware Words" + +#~ msgid "Applixware spreadsheet" +#~ msgstr "Spreadsheet Applixware" + +#~ msgid "AutoCAD image" +#~ msgstr "Imagine AutoCAD" + +#~ msgid "BCPIO document" +#~ msgstr "Document BCPIO" + +#~ msgid "BDF font" +#~ msgstr "Font BDF" + +#~ msgid "C shell script" +#~ msgstr "Script shell C" + +#~ msgid "C source code" +#~ msgstr "Cod sursã C" + +#, fuzzy +#~ msgid "C source code header" +#~ msgstr "Cod sursã C" + +#~ msgid "C++ source code" +#~ msgstr "Cod sursã C++" + +#~ msgid "CGI program" +#~ msgstr "Program CGI" + +#~ msgid "CGM image" +#~ msgstr "Imagine CGM" + +#~ msgid "CMU raster image" +#~ msgstr "Imagine raster CMU" + +#~ msgid "CPIO archive" +#~ msgstr "Arhivã CPIO" + +#~ msgid "CPIO archive (gzip-compressed)" +#~ msgstr "Arhivã CPIO (compresatã cu gzip)" + +#~ msgid "DCL script" +#~ msgstr "Script DCL" + +#~ msgid "DOS font" +#~ msgstr "Font DOS" + +#~ msgid "DOS/Windows program" +#~ msgstr "Program DOS/Windows" + +#~ msgid "DSSSL document" +#~ msgstr "Document DSSSL" + +#~ msgid "DXF vector graphic" +#~ msgstr "Graficã vectorialã DXF" + +#~ msgid "Debian package" +#~ msgstr "Pachet Debian" + +#~ msgid "Dia diagram" +#~ msgstr "Diagramã Dia" + +#~ msgid "Emacs Lisp source code" +#~ msgstr "Cod sursã Emacs Lisp" + +#~ msgid "Enlightenment theme" +#~ msgstr "Temã Enlightenment" + +#~ msgid "FLC animation" +#~ msgstr "Animaþie FLC" + +#~ msgid "FLI animation" +#~ msgstr "Animaþie FLI" + +#~ msgid "FastTracker II audio" +#~ msgstr "Audio FastTracker II" + +#~ msgid "Fortran source code" +#~ msgstr "Cod sursã Fortran" + +#~ msgid "FrameMaker interchange document" +#~ msgstr "Document FrameMaker interchange" + +#~ msgid "G3 fax image" +#~ msgstr "Imagine fax G3" + +#~ msgid "GIF image" +#~ msgstr "Imagine GIF" + +#~ msgid "GIMP document" +#~ msgstr "Document GIMP" + +#~ msgid "GMC link" +#~ msgstr "Legãturã GMC" + +#~ msgid "GNOME application details" +#~ msgstr "Detalii aplicaþie GNOME" + +#, fuzzy +#~ msgid "GNU Oleo Spreadsheet" +#~ msgstr "Spreadsheet Gnumeric" + +#~ msgid "GNU mail message" +#~ msgstr "Mesaj poºtã GNU" + +#~ msgid "GTK configuration" +#~ msgstr "Configuraþie GTK" + +#~ msgid "Gnumeric spreadsheet" +#~ msgstr "Spreadsheet Gnumeric" + +#~ msgid "HDF document" +#~ msgstr "Document HDF" + +#~ msgid "HTML page" +#~ msgstr "Paginã HTML" + +#~ msgid "IDL document" +#~ msgstr "Document IDL" + +#~ msgid "IEF image" +#~ msgstr "Imagine IEF" + +#~ msgid "IFF image" +#~ msgstr "Imagine IFF" + +#~ msgid "ILBM image" +#~ msgstr "Imagine ILBM" + +#~ msgid "ISI video" +#~ msgstr "Video ISI" + +#~ msgid "Impulse Tracker audio" +#~ msgstr "Audio Impulse Tracker" + +#~ msgid "JPEG image" +#~ msgstr "Imagine JPEG" + +#~ msgid "Java byte code" +#~ msgstr "Cod Java" + +#~ msgid "Java source code" +#~ msgstr "Cod sursã Java" + +#~ msgid "KDE application details" +#~ msgstr "Detalii aplicaþie KDE" + +#, fuzzy +#~ msgid "KIllustrator document" +#~ msgstr "Document PostScript" + +#, fuzzy +#~ msgid "KPresenter presentation" +#~ msgstr "Prezentare StarOffice" + +#, fuzzy +#~ msgid "KSpread spreadsheet" +#~ msgstr "Spreadsheet Applixware" + +#, fuzzy +#~ msgid "KWord document" +#~ msgstr "Document AbiWord" + +#~ msgid "Korn shell script" +#~ msgstr "Script shell Korn" + +#~ msgid "LHA archive" +#~ msgstr "Arhivã LHA" + +#~ msgid "LHARC archive" +#~ msgstr "Arhivã LHARC" + +#~ msgid "LIBGRX font" +#~ msgstr "Font LIBGRX" + +#~ msgid "LightWave object" +#~ msgstr "Obiect LightWave" + +#~ msgid "LightWave scene" +#~ msgstr "Scenã LightWave" + +#~ msgid "Linux PSF console font" +#~ msgstr "Font consolã Linux PSF" + +#, fuzzy +#~ msgid "Lotus 1-2-3 spreadsheet" +#~ msgstr "Spreadsheet Gnumeric" + +#~ msgid "M3 audio URL" +#~ msgstr "URL audio MP3" + +#~ msgid "MIDI audio" +#~ msgstr "Audio MIDI" + +#~ msgid "MOD audio" +#~ msgstr "Audio MOD" + +#~ msgid "MP3 audio" +#~ msgstr "Audio MP3" + +#~ msgid "MP3 audio playlist" +#~ msgstr "Listã audio MP3" + +#~ msgid "MPEG video" +#~ msgstr "Video MPEG" + +#, fuzzy +#~ msgid "MS ASF video" +#~ msgstr "Video MS" + +#~ msgid "MS video" +#~ msgstr "Video MS" + +#~ msgid "Macintosh AppleDouble-encoded file" +#~ msgstr "Fiºier codat Macintosh AppleDouble" + +#~ msgid "Macintosh BinHex-encoded file" +#~ msgstr "Fiºier codat Macintosh BinHex" + +#~ msgid "Macintosh StuffIt archive" +#~ msgstr "Arhivã Macintosh StuffIt" + +#~ msgid "MathML document" +#~ msgstr "Document MathML" + +#, fuzzy +#~ msgid "Microsoft Excel spreadsheet" +#~ msgstr "Document Microsoft Excel" + +#~ msgid "Microsoft PowerPoint document" +#~ msgstr "Document Microsoft PowerPoint" + +#~ msgid "Microsoft Word document" +#~ msgstr "Document Microsoft Word" + +#~ msgid "Microsoft video" +#~ msgstr "Video Microsoft" + +#~ msgid "Nautilus link" +#~ msgstr "Legãturã Nautilus" + +#~ msgid "ODA document" +#~ msgstr "Document ODA" + +#~ msgid "PBM image" +#~ msgstr "Imagine PBM" + +#~ msgid "PCF font" +#~ msgstr "Font PCF" + +#~ msgid "PDF document" +#~ msgstr "Document PDF" + +#~ msgid "PEF program" +#~ msgstr "Program PEF" + +#~ msgid "PGM image" +#~ msgstr "Imagine PGM" + +#~ msgid "PGN chess game" +#~ msgstr "Joc ºah PGN" + +#~ msgid "PGP keys" +#~ msgstr "Chei PGP" + +#~ msgid "PGP message" +#~ msgstr "Mesaj PGP" + +#~ msgid "PGP signature" +#~ msgstr "Semnãturã PGP" + +#~ msgid "PGP-encrypted file" +#~ msgstr "Fiºier criptat PGP" + +#~ msgid "PHP script" +#~ msgstr "Script PHP" + +#~ msgid "PN RealAudio document" +#~ msgstr "Document PN RealAudio " + +#~ msgid "PNG image" +#~ msgstr "Imagine PNG" + +#~ msgid "PNM image" +#~ msgstr "Imagine PNM" + +#~ msgid "PPM image" +#~ msgstr "Imagine PPM" + +#~ msgid "Palm OS database" +#~ msgstr "Bazã de date Palm OS" + +#~ msgid "Perl script" +#~ msgstr "Script Perl" + +#~ msgid "Photoshop document" +#~ msgstr "Document Photoshop" + +#~ msgid "PostScript Type 1 font" +#~ msgstr "Font PostScript Type 1" + +#~ msgid "PostScript document" +#~ msgstr "Document PostScript" + +#~ msgid "Python source code" +#~ msgstr "Cod sursã Python" + +#~ msgid "QuickTime movie" +#~ msgstr "Film QuickTIme" + +#, fuzzy +#~ msgid "Quicken document" +#~ msgstr "Document TeX" + +#, fuzzy +#~ msgid "Quicken for Windows document" +#~ msgstr "document calendar sau eveniment" + +#~ msgid "RAR archive" +#~ msgstr "Arhivã RAR" + +#~ msgid "README document" +#~ msgstr "Document README" + +#~ msgid "RGB image" +#~ msgstr "Imagine RGB" + +#~ msgid "RIFF audio" +#~ msgstr "Audio RIFF" + +#~ msgid "RPM package" +#~ msgstr "Pachet RPM" + +#~ msgid "RealAudio/Video document" +#~ msgstr "Document RealAudio/Video" + +#~ msgid "RealVideo video" +#~ msgstr "Video RealVideo" + +#~ msgid "S/MIME file" +#~ msgstr "Fiºier S/MIME" + +#~ msgid "S/MIME signature" +#~ msgstr "Semnãturã S/MIME" + +#~ msgid "SGI video" +#~ msgstr "Video SGI" + +#~ msgid "SGML document" +#~ msgstr "Document SGML" + +#~ msgid "SMIL script" +#~ msgstr "Script SMIL" + +#~ msgid "SQL code" +#~ msgstr "Cod SQL" + +#~ msgid "SV4 CPIO archive" +#~ msgstr "Arhivã SV4 CPIO" + +#~ msgid "SV4 CPIP archive (with CRC)" +#~ msgstr "Arhivã SV4 CPIO (cu CRC)" + +#~ msgid "SVG art" +#~ msgstr "Artã SVG" + +#~ msgid "Scheme source code" +#~ msgstr "Cod sursã Scheme" + +#~ msgid "Scream Tracker 3 audio" +#~ msgstr "Audio Scream Tracker 3" + +#~ msgid "Scream Tracker audio" +#~ msgstr "Audio Scream Tracker" + +#~ msgid "Scream Tracker instrument" +#~ msgstr "Instrument Scream Tracker" + +#~ msgid "Setext document" +#~ msgstr "Document Setext" + +#~ msgid "Speech document" +#~ msgstr "Document vocal" + +#~ msgid "Speedo font" +#~ msgstr "Font Speedo" + +#, fuzzy +#~ msgid "Spreadsheet Interchange document" +#~ msgstr "Document FrameMaker interchange" + +#, fuzzy +#~ msgid "Stampede package" +#~ msgstr "Pachet Debian" + +#~ msgid "StarOffice Writer document" +#~ msgstr "Document StarOffice Writer" + +#~ msgid "StarOffice presentation" +#~ msgstr "Prezentare StarOffice" + +#~ msgid "StarOffice spreadsheet" +#~ msgstr "Spreadsheet StarOffice" + +#~ msgid "Sun mu-law audio" +#~ msgstr "Audio Sun µ-law" + +#~ msgid "SunOS News font" +#~ msgstr "Font SunOS News" + +#~ msgid "TIFF image" +#~ msgstr "Imagine TIFF" + +#~ msgid "TarGA image" +#~ msgstr "Imagine TarGA" + +#~ msgid "Tcl script" +#~ msgstr "Script Tcl" + +#~ msgid "TeX document" +#~ msgstr "Document TeX" + +#~ msgid "TeX dvi document" +#~ msgstr "Document TeX dvi" + +#~ msgid "TeX font" +#~ msgstr "Font TeX" + +#~ msgid "TeX font metrics" +#~ msgstr "Dimensiuni font TeX" + +#~ msgid "TeXInfo document" +#~ msgstr "Document TexInfo" + +#~ msgid "ToutDoux document" +#~ msgstr "Document ToutDoux" + +#~ msgid "TrueType font" +#~ msgstr "Font TrueType" + +#~ msgid "USENET news message" +#~ msgstr "MEsaj ºtiri USENET" + +#~ msgid "Unidata netCDF document" +#~ msgstr "Document Unidata netCDF" + +#~ msgid "V font" +#~ msgstr "Font V" + +#~ msgid "VOC audio" +#~ msgstr "Audio VOC" + +#~ msgid "VRML document" +#~ msgstr "Document VRML" + +#~ msgid "Vivo video" +#~ msgstr "Video Vivo" + +#~ msgid "WAIS source code" +#~ msgstr "Cod sursã WAIS" + +#~ msgid "Wavelet video" +#~ msgstr "Video Wavelet" + +#~ msgid "Windows bitmap image" +#~ msgstr "Imagine bitmap Windows" + +#~ msgid "Windows icon image" +#~ msgstr "Imagine icon Windows" + +#~ msgid "WordPerfect document" +#~ msgstr "Document WordPerfect" + +#~ msgid "X bitmap image" +#~ msgstr "Imagine bitmap X" + +#~ msgid "X window image" +#~ msgstr "Imagine X window" + +#~ msgid "XML document" +#~ msgstr "Document XML" + +#~ msgid "XPM image" +#~ msgstr "Imagine XPM" + +#, fuzzy +#~ msgid "Xbase database" +#~ msgstr "Bazã de date Palm OS" + +#~ msgid "active server page" +#~ msgstr "paginã active server" + +#~ msgid "address card" +#~ msgstr "carte adresã" + +#~ msgid "ar archive" +#~ msgstr "Arhivã ar" + +#~ msgid "arj archive" +#~ msgstr "Arhivã arj" + +#~ msgid "authors list" +#~ msgstr "listã autori" + +#~ msgid "backup file" +#~ msgstr "fiºier backup" + +#~ msgid "basic audio" +#~ msgstr "audio standard" + +#~ msgid "bibliography record" +#~ msgstr "înregistare bibliograficã" + +#~ msgid "binary program" +#~ msgstr "program binar" + +#~ msgid "block device" +#~ msgstr "dispozitiv de tip block" + +#~ msgid "bzip-compressed file" +#~ msgstr "fiºier compresat bzip" + +#~ msgid "calendar file" +#~ msgstr "fiºier calendar" + +#~ msgid "calendar or event document" +#~ msgstr "document calendar sau eveniment" + +#~ msgid "character device" +#~ msgstr "dispozitiv de tip caracter" + +#~ msgid "comma-separated text document" +#~ msgstr "document text virgulã-separat" + +#~ msgid "compound document" +#~ msgstr "document compus" + +#~ msgid "compress-compressed file" +#~ msgstr "Fiºier compresat compress" + +#~ msgid "compressed GIMP document" +#~ msgstr "document compresat GIMP" + +#~ msgid "directory information file" +#~ msgstr "fiºier informaþie director" + +#~ msgid "document type definition" +#~ msgstr "definiþie tip document" + +#~ msgid "email headers" +#~ msgstr "headere email" + +#~ msgid "email message" +#~ msgstr "mesaj email" + +#~ msgid "encrypted message" +#~ msgstr "mesaj criptat" + +#~ msgid "enriched text document" +#~ msgstr "document text îmbogãþit" + +#~ msgid "gtar archive" +#~ msgstr "arhivã gtar" + +#~ msgid "gzip-compressed file" +#~ msgstr "fiºier compresat gzip" + +#~ msgid "help page" +#~ msgstr "paginã help" + +#~ msgid "mail delivery report" +#~ msgstr "report livrare mail" + +#~ msgid "mail disposition report" +#~ msgstr "report dispoziþie mail" + +#~ msgid "mail system report" +#~ msgstr "report sistem mail" + +#~ msgid "makefile" +#~ msgstr "makefile" + +#~ msgid "manual page" +#~ msgstr "paginã manual" + +#~ msgid "manual page (compressed)" +#~ msgstr "paginã manual (compresatã)" + +#~ msgid "memory dump" +#~ msgstr "dump memorie" + +#~ msgid "message digest" +#~ msgstr "digest mesaj" + +#~ msgid "message in several formats" +#~ msgstr "mesaj în câteva formate" + +#~ msgid "multi-part message" +#~ msgstr "mesaj multi-parte" + +#~ msgid "named pipe" +#~ msgstr "conector pipe cu nume" + +#~ msgid "object code" +#~ msgstr "cod obiect" + +#~ msgid "ogg audio" +#~ msgstr "audio ogg" + +#~ msgid "partial email message" +#~ msgstr "mesaj email parþial" + +#~ msgid "plain text document" +#~ msgstr "document text simplu" + +#~ msgid "profiler results" +#~ msgstr "rezultate profiler" + +#~ msgid "reference to remote file" +#~ msgstr "referinþã la fiºier la distanþã" + +#~ msgid "rejected patch file" +#~ msgstr "fiºier patch respins" + +#~ msgid "rich text document" +#~ msgstr "document rich text" + +#~ msgid "search results" +#~ msgstr "rezultate cãutare" + +#~ msgid "shared library" +#~ msgstr "bibliotecã comunã" + +#~ msgid "shell archive" +#~ msgstr "arhivã shell" + +#~ msgid "shell script" +#~ msgstr "script shell" + +#~ msgid "signed message" +#~ msgstr "mesaj semnat" + +#~ msgid "socket" +#~ msgstr "socket" + +#~ msgid "software author credits" +#~ msgstr "credite autor software" + +#~ msgid "software installation instructions" +#~ msgstr "intrucþiuni instalare software" + +#~ msgid "software license terms" +#~ msgstr "termeni licenþiere software" + +#~ msgid "source code patch" +#~ msgstr "patch cod sursã" + +#~ msgid "style sheet" +#~ msgstr "style sheet" + +#~ msgid "symbolic link" +#~ msgstr "legãturã simbolicã" + +#~ msgid "tab-separated text document" +#~ msgstr "document text tab-separat" + +#~ msgid "tar archive" +#~ msgstr "arhivã tar" + +#~ msgid "tar archive (bzip2-compressed)" +#~ msgstr "arhivã tar (compresatã bzip2)" + +#~ msgid "tar archive (gzip-compressed)" +#~ msgstr "arhivã tar (compresatã bzip2)" + +#~ msgid "theme" +#~ msgstr "temã" + +#, fuzzy +#~ msgid "troff document" +#~ msgstr "Document Troff" + +#~ msgid "troff me input document" +#~ msgstr "document intrare troff me" + +#~ msgid "troff mm input document" +#~ msgstr "document intrare troff mm" + +#~ msgid "troff ms input document" +#~ msgstr "document intrare troff ms" + +#~ msgid "unknown type" +#~ msgstr "tip necunoscut" + +#~ msgid "ustar archive" +#~ msgstr "arhivã ustar" + +#~ msgid "wave audio" +#~ msgstr "audio wave" + +#~ msgid "web folder" +#~ msgstr "dosar web" + +#~ msgid "xfig vector graphic" +#~ msgstr "graficã vectorialã xfig" + +#~ msgid "zip archive" +#~ msgstr "arhivã zip" + +#~ msgid "zoo archive" +#~ msgstr "arhivã zoo" + +#~ msgid "GNOME VFS already initialized." +#~ msgstr "GNOME VFS a fost deja iniþializat." + +#~ msgid "Dying." +#~ msgstr "Mor." + +#~ msgid "Error reading: %s" +#~ msgstr "Eroare citire: %s" + +#~ msgid "Error writing: %s" +#~ msgstr "Eroare scriere: %s" + +#~ msgid "Cannot write: %s" +#~ msgstr "Nu pot scrie: %s" + +#~ msgid "Cannot create temporary file name `%s'" +#~ msgstr "Nu pot crea fiºierul temporar `%s' " + +#~ msgid "Cannot create socket: %s" +#~ msgstr "Nu pot crea socketul: %s" + +#~ msgid "Cannot bind `%s': %s" +#~ msgstr "Nu pot lega `%s': %s" + +#~ msgid "Cannot listen on `%s': %s" +#~ msgstr "Nu pot asculta pe `%s': %s" + +#~ msgid "Cannot accept connections on `%s': %s" +#~ msgstr "Nu pot accepta conexiuni pe `%s': %s" + +#~ msgid "Cannot initialize CORBA." +#~ msgstr "Nu pot iniþializa CORBA" + +#~ msgid "Cannot resolve initial reference to RootPOA." +#~ msgstr "Nu pot rezolva referinþa iniþialã la RootPOA" + +#~ msgid "Cannot activate POA manager." +#~ msgstr "Nu pot activa managerul POA" + +#~ msgid "Usage: %s []\n" +#~ msgstr "Folosire: %s []\n" + +#~ msgid "Cannot open file descriptor %d." +#~ msgstr "Nu pot deschide descriptorul fiºier %d." + +#~ msgid "Notify interface for `%s' not found." +#~ msgstr "Interfaþa notificare pentru `%s' nu a fost gãsitã." + +#~ msgid "Cannot setup Request object." +#~ msgstr "Nu pot seta obiectul Cerere." + +#~ msgid "Cannot extract IOR." +#~ msgstr "Nu pot extrage IOR." + +#~ msgid "Got weird string from the slave process: `%s'" +#~ msgstr "Am obþinut ºir ciudat de la procesul dependent: `%s'" + +#~ msgid "Cannot get object for `%s'" +#~ msgstr "Nu pot obþine obiectul pentru `%s'" + +#~ msgid "Cannot kill GNOME::VFS::Slave::Notify -- exception %s" +#~ msgstr "Nu pot omorî GNOME::VFS::Slave::Notify -- excepþie %s" + +#~ msgid "Cannot connect socket `%s': %s" +#~ msgstr "Nu pot conecta socketul `%s': %s" + +#~ msgid "Cannot initialize GNOME::VFS:Slave::Notify" +#~ msgstr "Nu pot iniþializa GNOME::VFS:Slave::Notify" + +#~ msgid "Cannot reset GNOME::VFS::Slave %s -- exception %s" +#~ msgstr "Nu pot reseta GNOME::VFS:Slave %s - excepþie %s" + +#~ msgid "Cannot reset GNOME::VFS::Slave (IOR unknown) -- exception %s" +#~ msgstr "Nu pot reseta GNOME::VFS::Slave (IOR necunoscut) -- excepþie %s" + +#~ msgid "Cannot kill GNOME::VFS::Slave %s -- exception %s" +#~ msgstr "Nu pot omorî GNOME::VFS::Slave %s -- excepþie %s" + +#~ msgid "Cannot kill GNOME::VFS::Slave (IOR unknown) -- exception %s" +#~ msgstr "Nu pot omorî GNOME::VFS::Slave (IOR necunoscut) -- excepþie %s" + +#~ msgid "%s to retrieve" +#~ msgstr "%s pentru a fi primit" + +#~ msgid "Closing connection to %s" +#~ msgstr "Închid conexiunea la %s" + +#~ msgid "%s of %s read" +#~ msgstr "Am citit %s din %s" + +#~ msgid "%s read" +#~ msgstr "Am citit %s" + +#~ msgid "Back" +#~ msgstr "Înapoi" + +#~ msgid "Go to the previously visited directory" +#~ msgstr "Mergi la directorul precedent vizitat" + +#~ msgid "Up" +#~ msgstr "Sus" + +#~ msgid "Go to the parent directory" +#~ msgstr "Mergi la directorul pãrinte" + +#~ msgid "Forward" +#~ msgstr "Înainte" + +#~ msgid "Go to the next visited directory" +#~ msgstr "Mergi la directorul urmãtor visitat" + +#~ msgid "Rescan" +#~ msgstr "Rescaneazã" + +#~ msgid "Rescan the current directory" +#~ msgstr "Rescaneazã directorul curent" + +#~ msgid "Home" +#~ msgstr "Acasã" + +#~ msgid "Go to the home directory" +#~ msgstr "Mergi la directorul acasã" + +#~ msgid "Name" +#~ msgstr "Nume" + +#~ msgid "Size" +#~ msgstr "Mãrime" + +#~ msgid "Date" +#~ msgstr "Data" + +#~ msgid "Enter name:" +#~ msgstr "Introduceþi numele:" + +#~ msgid "Show:" +#~ msgstr "Aratã:" + +#~ msgid "Show dotfiles" +#~ msgstr "Aratã fiºierele care încep cu ." + +#~ msgid "Edit Applications List" +#~ msgstr "Editeazã lista aplicaþiilor" + +#~ msgid "Select applications to appear in menu for mime type \"%s\"" +#~ msgstr "" +#~ "Selecteazã aplicaþiile pentru a apãrea în meniu pentru tipul mine \"%s\"" + +#~ msgid "Add Application..." +#~ msgstr "Adaugã aplicaþie..." + +#~ msgid "Edit Application..." +#~ msgstr "Editeazã aplicaþie..." + +#~ msgid "Delete Application" +#~ msgstr "ªterge aplicaþie" + +#~ msgid "Edit Components List" +#~ msgstr "Editeazã lista componentelor" + +#~ msgid "Select views to appear in menu for mime type \"%s\"" +#~ msgstr "" +#~ "Selecteazã vizualizãrile pentru a apare în meniu pentru tipul mime \"%s\"" + +#~ msgid "" +#~ "The MIME type entered contained upper case characters. Upper case " +#~ "characters were changed to lower case for you." +#~ msgstr "" +#~ "Tipul MIME introdus conþine litere mari. Ele au fost schimbate în litere " +#~ "mici pentru dvs." + +#~ msgid "Add New MIME Type" +#~ msgstr "Adaugã tip MIME nou" + +#~ msgid "Add Mime Type" +#~ msgstr "Adaugã tip MIME" + +#~ msgid "" +#~ "Add a new Mime Type\n" +#~ "For example: image/tiff; text/x-scheme" +#~ msgstr "" +#~ "Adaugã un nou tip Mime Type\n" +#~ "De examplu: image/tiff; text/x-scheme" + +#~ msgid "Mime Type:" +#~ msgstr "Tip mime:" + +#~ msgid "Type in a description for this mime-type." +#~ msgstr "Introduceþi o descriere pentru acest tip mime." + +#~ msgid "Description:" +#~ msgstr "Descriere:" + +#~ msgid "File Extensions " +#~ msgstr "Extensii fiºier " + +#~ msgid "Add..." +#~ msgstr "Adaugã..." + +#~ msgid " Remove " +#~ msgstr " Elimina " + +#~ msgid "Add New Extension" +#~ msgstr "Adaugã extensie nouã" + +#~ msgid "" +#~ "Type in the extensions for this mime-type.\n" +#~ "For example: .html, .htm" +#~ msgstr "" +#~ "Introduceþi extensiile pentru acest tip mime.\n" +#~ "De examplu: .html, .htm" + +#~ msgid "Extension:" +#~ msgstr "Extensia:" + +#~ msgid "Application Name:" +#~ msgstr "Numele aplicaþiei:" + +#~ msgid "Application Command:" +#~ msgstr "Comandã aplicaþie:" + +#~ msgid "Open Behavior" +#~ msgstr "Purtare la deschidere" + +#~ msgid "Can open multiple files" +#~ msgstr "Nu pot deschide fiºiere multiple" + +#~ msgid "Expects URIs as arguments" +#~ msgstr "Aºteaptã URIuri ca argumente" + +#~ msgid "Edit Application" +#~ msgstr "Editeazã aplicaþie" + +#~ msgid "Can open from URI" +#~ msgstr "Nu pot deschide de la URI" + +#~ msgid "Mime Type" +#~ msgstr "Tip mime" + +#~ msgid "Change Icon" +#~ msgstr "Schimbã iconul" + +#~ msgid "Change File Extensions" +#~ msgstr "Schimbã extensiile fiºier" + +#~ msgid "Default Action:" +#~ msgstr "Acþiunea implicitã:" + +#~ msgid "Use Viewer" +#~ msgstr "Foloseºte vizualizator" + +#~ msgid "Open With Application" +#~ msgstr "Deschide cu aplicaþie" + +#~ msgid "Edit List" +#~ msgstr "Editeazã lista" + +#~ msgid "Add new Mime type..." +#~ msgstr "Adaugã tip mime nou..." + +#~ msgid "Delete this Mime type..." +#~ msgstr "ªterge acest tip mime..." + +#~ msgid "Revert to System Defaults" +#~ msgstr "Restaureazã setãrile implicite" + +#~ msgid "No Description" +#~ msgstr "Fãrã descriere" + +#~ msgid "None" +#~ msgstr "Nimic" + +#~ msgid "" +#~ "Reverting to system settings\n" +#~ "will lose all your personal \n" +#~ "Mime configuration.\n" +#~ "Revert to System Settings ?\n" +#~ msgstr "" +#~ "Restaurarea la setãrile implicite\n" +#~ "va pierde toate configuraþiile MIME\n" +#~ "personale.\n" +#~ "Restaureazã setãrile implicite ?\n" + +#~ msgid "none" +#~ msgstr "nimic" + +#~ msgid "View as %s" +#~ msgstr "Vizualizeazã ca %s" + +#~ msgid "Description" +#~ msgstr "Descriere" + +#~ msgid "Extension" +#~ msgstr "Extensie" + +#~ msgid "Default Action" +#~ msgstr "Acþiune implicitã" + +#~ msgid "Can't find an hbox, using a normal file selection" +#~ msgstr "Nu gãsesc hbox, folosesc un selector fiºiere normal" + +#~ msgid "Preview" +#~ msgstr "Previzualizare" diff --git a/po/ru.gmo b/po/ru.gmo new file mode 100644 index 0000000000000000000000000000000000000000..d5a9a5fce2acc8c8790f02033987403ef6fc6084 GIT binary patch literal 7068 zcmbuCdyE}b9mfX>sEf!;Pz2;yT-#FacDJQvSzaxDuI#p@?Lxp9oxOK?dYU1njJu`Rr?sh8} zCq4b%bI$La^Lu=MzjOBYm!0>F!*>tu8rrMpI!*<=@qGT{`@;o}a~b#^_zCbYApe|y zOL@0_wYSxHt^>8-1EALXApe{&A0Gjw&wfz;dpaL~4V3&*Q0JcnuL9o&bvj?gg&~p8=)s!5n`EUP1piIsO^c`twmz z>#hZ5&k|5_cjUMYH1xOU{Za7q^j`uce;m{~Z-cVyci?s42cYzyhmo4U6qFxYLG9lO zt^zlLgxL8m_*w8dQ1<;K@4p2uJI8T;3oc~*5)PI8EueU{D(`OqZ=}B&>;k`?;{=E* z&W9i-JO2j7s}`K5^A>_ycRSbzZU+_rpMq<^I(Qp+C4Bly$H2S6AA{2Oub}eh zQk*G0+rY1a_kr5?Wl-n-4HPf0#2La4a6Z@rO2072Z-F}J5%31^H4xREcfbPp9{3gT zVw|geR)FHiJ>bpY1K>^Ilc4l|3+x2{30@Dbz<6BhJOC~R2SLq01xk-!fcJyH2F1sY zE3gH;7u5RK!Oh@1;H}{GS7vs918k+gA6zCmupN9Kls%V2x&`2JQ2noi^4E9r@gIUq z>8IdIa2{k6t^sx4BcS~CF4zhF9h4uI5`^X8{U9nk2f*9GSHTtF`=I=G70y}$t_O9_ zFgOhU2$cWklRRwcECw~d29*87;5neaRTnAR?y2+p7fb4GmZlwc_>~{oj@^v>&v4SGj=ZgDk zns}^Fanh%_>AQ#4MN=J7O!ZwrlmG9eDW1xqjWlsoc}+T59ssuPQ8t|(S_kbSnqwCF z!A`gAmrP&a7sHab$Z2is7%=Pa%JA+Cdg;bpttC?ogT(cN*lg_UF~uP_a*K%<#ci{v zgV0pGWGF0|z^!<5PKTvh*=tPKO#evY#ZHGsXH~K2#jz=Qf$x=^Rn=~z2C;LO zTQUPaD~H^mRQ8L^BHDZBR?lP@0qEU(e!(hN4 ztVMReY^!g!#tY1_8yoF35Y~cHCLh+y7@#pfD4B{IW2@|{4Vu@(d)ub703gfSZv51N)*xoI8L zjh*f#oASN716&=r<*9B?(k5h$SN(~=6J$|qwc6!1=KQIF>hL`As zRrv&8?1+sQ6bUj*ndwEq=?x>ell#qD6PsbbTsHll@dpEDOKr|ZSs>4p!(hYMhlM3gWWU05i5awGUS<9D%os^M<8d#*(BOm$m1qgGnSLR=mtfvEPqUo;iGC4 z4%$F9kK&!2#nYpT7n@c5L`F`J$4OYNGO{@eldu>zqPE2&SHqw@GDAg;7Umdzu;xLX zus;sVL^U?#m>jZzGC)>2TeGgU%iT%P+r~~a_sa4JA!bSS`ma5@7{G=w|d@=&0*}@khYel=CgPCtW`~MGYi&v* zteRwm@?(eMTD2NRxJi{LbHCFU!yls7DhBTKqcEs=fpRJGWenVc5?;|C7_kf(7=WP6 zm&2^~wY50+aU|8pu_4b*Ub`#t0`k)t%(Ky2VlV|FSf@DV6|b;!Aa2>bX2lMttgEAQaXTXj7Pi1#t)C&c zqR`Q4I&SG&zHD*(P0007Jqz0+H;BtF5$ZB)pb-UceVgfJDyr=WcbeNuc5r3l)}k8e zG?27~(cm2{4hC!PpjX)Dxs@)ng*o31%x#&z#gS;G{gny#cK5EGHmReny@isGk2s$2 zbeY84l`N^2xyEj_R~Qxf_P%ZF3Z2t(QWNhN)>0@+)Qv9F+3zPUT$kyobUZzhPNt{p zd+QI?_oNf)$@*yerb%CCY9c+()RB+4MC%VpC>^iwPLHM&^*#17Wst4XLrk5Z9ctW} zI?$Z4g3+<`7}8@pwSK^`bR2E8@7Vvolx6k3>52LQmex#qkZs?r@8LF{`k6kRPRd@y zP8&`h!vVWF@-f_T%1K|OGhr1!ssX9wq|YLCxM2@?+|(b|&d7}!*@gacg5BYH+nr?V zlZYN=dNMQnm`vi}#|_Svxnt=G!x-8cblQ_1ukWspDiRFLy7ANRvvjxoQs2kw35S8n z^b~4Lq=yOMZl)jQH)D({j13LV{MLBBRZ{;+X#$p>vbTJSt_DY-mrTYj=w^kag~4VF z#I|h5^q@UvFP34fGv{LYl9(f4DP^<*`Gah}J3I1e1~MJTO?q0w$c*DBt5$t9+qYR& z`RGiVPT7~!SG($DMJGLEt!|N*@OWljdN>RBsrmsJF?&YjY@~vdzJSK~0gvxRGu)++ z$+zS6N2ffSj%9S2#P7#2aDPSz{g_}qG1iXI34I8OY(1eZXcHRLjwh`*j>v2=@1wVB zcBoWt+Jt>46?l;6m$ zti(13(&JMi)-E(S-B1P^$Yx4~^~9{e&g}$v_ZUlTl1#bQNnf(g6+Q8^lfEJ%A8UkQ zkF{6-@4@-jT7w=(I35=`>2nmj15GOwmRZWAlWZ!kD@)JxkETw1oVXpbq$I_bSQ?0- zbmlZwnYPzPPb3jhXB+)oo+c_1%6&|?MPavD*tey7(OJBD2A%7pnPgVBl-@QOAv{j9 z1z4rXN#8(s%9F@~D^Vsp&sGat5l<2aW=8S5rQ7r9vrjrvNub9#+nuUEl=+V^G!>dT zk_@eE5j$>awNH`KuIR=QO^3XwDyXz(55{eN*B`f43NxnjZ(>IIQ92%!4svmpnM$|A zcv`HSps9XH;n6nHYX-L|(+Cq3gg8W(B^SdB)-MX#45CfYeZD(dtsI_rj_ zgRGlW6vxOJ^{lfRDx>i83etg(!4?FSXm-bpy8Gk>T?H^trCFDowxfvaR4STEuxZqL z8>Fnx5i==8%oyzaNyOnU|T* zYD|M$;L=eF=lK0o&O3l-$bGPR~x=?~>A%xNBAcIB6pwQAn2+BYbPK zW{PX}p*N#!G_87=bM;~*jJkg)i%KIDwUkq}eU>9sKCQ#yhyDBK%)jKa(ycc~}`&`U*n0D2q)(G6@~+&JRkX9qztAkG3q-tUOm`qv zk1dq4N|XGG!8OF%zLlWjG2FxZJzFDbo9k?%d-4hCp*M5>MuW`<^4D(msAhuu%91Vr z+k*R_K|SU3m}jMJjK4^E^BtG}okpQ){3Sm1XDO@n5}8m%n!y$rF`Y?p*~U$Ow>tl2 KNrMh!&VK;LG7HuK literal 0 HcmV?d00001 diff --git a/po/ru.po b/po/ru.po new file mode 100644 index 0000000..440570a --- /dev/null +++ b/po/ru.po @@ -0,0 +1,472 @@ +# Copyright (C) 2000-2002 Free Software Foundation, Inc. +# Valek Filippov , 2000-2002. +# Dmitry G. Mastrukov , 2002-2003 +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-06-18 19:53+0400\n" +"Last-Translator: Dmitry G. Mastrukov \n" +"Language-Team: Russian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +# libgnomevfs/gnome-vfs-configuration.c:223 +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d содержит NUL символов." + +# libgnomevfs/gnome-vfs-configuration.c:240 +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d не содержит названия метода." + +# libgnomevfs/gnome-vfs-configuration.c:269 +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d не содержит названия модуля." + +# libgnomevfs/gnome-vfs-configuration.c:322 +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Конфигурационный файл \"%s\" не найден: %s" + +# libgnomevfs/gnome-vfs-job.c:714 +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Тип операции %u неизвестен" + +# libgnomevfs/gnome-vfs-job.c:1005 libgnomevfs/gnome-vfs-job.c:1150 +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "Невозможно создать канал для открытия GIOChannel: %s" + +# libgnomevfs/gnome-vfs-job.c:1596 +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Вид задания %u неизвестен" + +# libgnomevfs/gnome-vfs-job.c:1632 +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Действие остановлено" + +# libgnomevfs/gnome-vfs-parse-ls.c:652 +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Не удалось провести разбор: %s" + +# libgnomevfs/gnome-vfs-parse-ls.c:654 +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Остальные ошибки разбора будут проигнорированы." + +# libgnomevfs/gnome-vfs-result.c:35 +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Ошибки отсутствуют" + +# libgnomevfs/gnome-vfs-result.c:36 +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Файл не найден" + +# libgnomevfs/gnome-vfs-result.c:37 +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Произошла общая ошибка" + +# libgnomevfs/gnome-vfs-result.c:38 +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Произошла внутренняя ошибка" + +# libgnomevfs/gnome-vfs-result.c:39 +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Обнаружены неверные параметры" + +# libgnomevfs/gnome-vfs-result.c:40 +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Операция не поддерживается" + +# libgnomevfs/gnome-vfs-result.c:41 +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "Произошла ошибка ввода/вывода" + +# libgnomevfs/gnome-vfs-result.c:42 +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Данные повреждены" + +# libgnomevfs/gnome-vfs-result.c:43 +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Формат недопустим" + +# libgnomevfs/gnome-vfs-result.c:44 +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Заголовок файла неверен" + +# libgnomevfs/gnome-vfs-result.c:45 +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "Файл слишком велик" + +# libgnomevfs/gnome-vfs-result.c:46 +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Отсутствует место на устройстве" + +# libgnomevfs/gnome-vfs-result.c:47 +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Файловая система только для чтения" + +# libgnomevfs/gnome-vfs-result.c:48 +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "Идентификатор (URI) недопустим" + +# libgnomevfs/gnome-vfs-result.c:49 +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Файл не открыт" + +# libgnomevfs/gnome-vfs-result.c:50 +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Режим открытия недопустим" + +# libgnomevfs/gnome-vfs-result.c:51 +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Доступ запрещен" + +# libgnomevfs/gnome-vfs-result.c:52 +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "Открыто слишком много файлов" + +# libgnomevfs/gnome-vfs-result.c:53 +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Обнаружен конец файла" + +# libgnomevfs/gnome-vfs-result.c:54 +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Не является каталогом" + +# libgnomevfs/gnome-vfs-result.c:55 +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Действие выполняется" + +# libgnomevfs/gnome-vfs-result.c:56 +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Действие прервано" + +# libgnomevfs/gnome-vfs-result.c:57 +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Файл существует" + +# libgnomevfs/gnome-vfs-result.c:58 +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Обнаружены циклические ссылки" + +# libgnomevfs/gnome-vfs-result.c:59 +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Действие не разрешено" + +# libgnomevfs/gnome-vfs-result.c:60 +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "Является каталогом" + +# libgnomevfs/gnome-vfs-result.c:61 +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Недостаточно памяти" + +# libgnomevfs/gnome-vfs-result.c:62 +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Узел не найден" + +# libgnomevfs/gnome-vfs-result.c:63 +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Имя узла недопустимо" + +# libgnomevfs/gnome-vfs-result.c:64 +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "У узла отсутствует адрес" + +# libgnomevfs/gnome-vfs-result.c:65 +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Начать сеанс не удалось" + +# libgnomevfs/gnome-vfs-result.c:66 +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Действие отменено" + +# libgnomevfs/gnome-vfs-result.c:67 +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Каталог занят" + +# libgnomevfs/gnome-vfs-result.c:68 +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Каталог не пуст" + +# libgnomevfs/gnome-vfs-result.c:69 +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "Слишком много ссылок" + +# libgnomevfs/gnome-vfs-result.c:70 +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Файловая система только для чтения" + +# libgnomevfs/gnome-vfs-result.c:71 +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Не в той же файловой системе" + +# libgnomevfs/gnome-vfs-result.c:72 +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Слишком длинное имя" + +# libgnomevfs/gnome-vfs-result.c:73 +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Сервис не доступен" + +# libgnomevfs/gnome-vfs-result.c:74 +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Были запрошены устаревшие сервисные данные" + +# libgnomevfs/gnome-vfs-result.c:75 +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Произошла ошибка протокола" + +# libgnomevfs/gnome-vfs-parse-ls.c:652 +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "Не удалось найти главный браузер" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "Отсутствует исходное ассоциированное действие" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "Отсутствует обработчик для схемы ссылки (URL)" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "Произошла ошибка при разборе командной строки" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "Произошла ошибка при выполнении команды" + +# libgnomevfs/gnome-vfs-result.c:137 +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Произошла неизвестная ошибка" + +# libgnomevfs/gnome-vfs-utils.c:65 +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 байт" + +# libgnomevfs/gnome-vfs-utils.c:67 +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u байт" + +# libgnomevfs/gnome-vfs-utils.c:74 +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +# libgnomevfs/gnome-vfs-utils.c:78 +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +# libgnomevfs/gnome-vfs-utils.c:82 +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (недопустимый Юникод)" + +# modules/file-method.c:381 +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "Значение GnomeVFSSeekPosition %d неизвестно" + +# modules/test-method.c:590 +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "Не найден допустимый файл установок в \"%s\"\n" + +# modules/test-method.c:592 +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "Используйте переменную окружения \"%s\" для указания другого места.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "Приложения" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "Карточки" + +# libgnomevfs/gnome-vfs-result.c:57 +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "Файлы" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "Папки" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "Справка" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "Узлы" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "Ссылки" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "Почта" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "Инструмены" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "Окна" + +# monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Фабрика Стандартного моникера" + +# monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "файл MonikerExtender" + +# monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "общий моникер системы Gnome VFS" + +# monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "общий моникер файла" diff --git a/po/sk.gmo b/po/sk.gmo new file mode 100644 index 0000000000000000000000000000000000000000..66ef4975e85e757338d3d41aa52cbe749ea65d47 GIT binary patch literal 5519 zcmai%TZ|-C8Gw&+Q3p^!#S6FNW!&Y`voo^-!vG7jyR*B)&W+ufmB53Zt~%XaTh(=% zs_NeD2|j6%1TiK`)CV6rLde8SjM0#|x*J39#9)*ch(@DELyRUq@PND+Lj3-!>h9SM zgvy@z`rQB9`On$EU3=*>iti!H4U}i!uT&G>ei?uG{(iYq*TR3m55WII{;9Xh`Xw~p zME#1Ax0YOhAEdnjW&C6CDtH=R37>!;f!~3*!XH7|@@04nd==gZ--aKBH?Y`;;UwG* z?=R~ODE+7474Rwe3HUwuY50?}{kKr&{{e~||AZpP8!%V(Lxp~q!>eikFqCmO!%JZW z%0AO24?$V)5h(Km$Uo)E_AV58o`hn*@0RV)LmB@9l>L7NKLuZcvd?Sq^YGtL_P=VZ z@XPfOQPm8T@pDl0d=!cuQ+N&h8oVAp14Z7SmfVIPr~apsuS1!C8A8gu8=>g42g2W9*jDEqtwMX$fYo8fCve;TXIXCXk`( zhfwUWRr1$R{O}4Cz5WA5t~a3U^EMQDuBIY-Tn9y74MpF(pxE;vDD&!2#wAeXcpQo! zo`T|sAC&biDE9az6nne~#a@3b+uwwrq5c+>c{d^SZa58P{YRnnTPS*d12R-S5BaBl z!JjX{-$Ak48&KA{l0VX~p~$_r`4Pe8H5^H9dU0L5;7K->?z6U5@q)42JPKPM_D5T>2yO+NYmcJ!ONFI<+ z;!R>pzDp=~<-f?0CHF(ol@Pk%6TdA{G(~JC-wI`(a*%R_B0iN*&eCCu*hu12d?%mS z?)Ll_XBtkIza>WGt56mwpQT_rwTH5ca)2WKkPp-6-yJ0%g0mFygZNs$%PA5E_fzhp zh%c5Y66>UxJm%ya$|reGe7{JUqDb5;y*r3ICJKDL9tWQD?Ja72VydPO?=N_?z!KGT zcHGyVi!&3%sa{@R)Lz3R#>;GyPF&m_JKeNd!}&TkP5X}B&TmI{(B0P6Ze~+8l~c`m zo=sEj+c>bknrpS9z%yCk;#BQ7zODt#Y?#=OtU6%g*k#&FtjVly1ud&WGb6>WE7-TqCB`#`hE4 zShPtT?3kL58_6KmR4wdTDc4$vF?DRBVYLj>V+(4b3|Q1;Nr^tSkZPm-feqDS5QnK+ zboC(CHG|?l71t7*V2d!-Hui8bQ|Vb^fLd}1u~XVD*Cy4cf+*5etAlz>uRo!dMFX)+ zr(VN0tqe(9#BjMQ!H+Vut}s!53CBN(4GtWHIw{4}Ipg0rbsB05<0G$x(KhPnlmN_*+m-QRH@@dHP_2@aGI%d`j2PCJ;z!vxi|rSTCq`^9ZQb z2vGVXSLD8lG4&<3B>Sk`<)zB=r!yOKK2^OujkzWoRS1OKD8rt7+Mp3AgJY{JYn20%Sm~^g+emWLlaqTZlQWg+JM`4v*{PY^CTU?{ z_*wy#4Q1SDD(6bA0GO_OPn>zGjAn}(HOY9@YwW8FSIk%s%mmKK)gNBT@nOpcN7F%aA0 zn^~RN)7hR@#2t1|et(gU?^|CxRGAr#6Y(&8Wu7eIlQd@aOf|^Hj#+VNWht!(er12V zo>tb}tR8!~l4rp}oum6r)kb=1V!CQGvv-X9HMZ=Q#r?CoykT|N|C#?D*DR;NG}d^ZL|OL?Q^!NJKe0~l3@Eeo%GKnZIX!9PMYM- z))(EpM@_;Nc64y_o_|`FF4ok$OyjKg&dcQ787C;9O!O?s<6vuxL>ot+~!4U{oug0f|))iq!{xP%A$6?5aniZo}Ye zdKyu`mr8W1M-1l*(Xj1V?R7(5mm%@tiYXE@#L4+@nP|I*H)Vf$nECxP#bY3M%I1Vx z66M5mxjp@;(ceTcUIoO6_^qdjL*vIr%YykmC5T6QsRyUo&lOIS^SRy1s2%i~JTwDIo$WmCNG+nQ!%iGm(V9aPb1Zm4BCGWY4*BoQN+`im drqXwLrby~3pCW}`@?sghRCacXZHuMU{{c~!4buPs literal 0 HcmV?d00001 diff --git a/po/sk.po b/po/sk.po new file mode 100644 index 0000000..857c701 --- /dev/null +++ b/po/sk.po @@ -0,0 +1,411 @@ +# translation of gnome-vfs.HEAD.po to Slovak +# translation of sk.po to Slovak +# gnome-vfs sk.po +# Copyright (C) 2000-2001,2003 Free Software Foundation, Inc. +# Stanislav Visnovsky , 2000-2001,2003. +# Stanislav Visnovsky , 2003. +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs.HEAD\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-08-22 19:06+0200\n" +"Last-Translator: Stanislav Visnovsky \n" +"Language-Team: Slovak \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Report-Msgid-Bugs-To: \n" +"X-Generator: KBabel 1.2beta3\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d obsahuje znaky NUL." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d neobsahuje meno metódy." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d neobsahuje meno modulu." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Konfiguračný súbor '%s' nebol nájdený: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Neznámy typ operácie %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "Nemôžem vytvoriÅ¥ rúru pre otvorenie GIOChannel: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Neznáme typ úlohy %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Operácia zastavená" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Nemôžem rozložiÅ¥: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "ĎalÅ¡ie chyby budú ignorované." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Bez chyby" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Súbor nenájdený" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Chyba" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Interná chyba" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Neplatné parametre" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Nepodporovaná operácia" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "V/V chyba" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "PoÅ¡kodené dáta" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Neplatný formát" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Chybný handle súboru" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "PríliÅ¡ veľký súbor" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Nedostatok miesta na zariadení" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Súborový systém len pre čítanie" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "Neplatné URI" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Neotvorený súbor" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Mód otvorenia neplatný" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Prístup odmietnutý" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "PríliÅ¡ veľa otvorených súborov" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Koniec súboru" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Nie je priečinok" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Operácia prebieha" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Operácia preruÅ¡ená" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Súbor existuje" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Zaznamenaný cyklické odkazy" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Nedovolená operácia" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "Je priečinok" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Nedostatok pamäti" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Hostiteľ nenájdený" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Neplatné meno hostiteľa" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Hostiteľ nemá adresu" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Zlyhalo prihlásenie" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Operácia zruÅ¡ená" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Priečinok zaneprázdnený" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Priečinok nie je prázdny" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "PríliÅ¡ veľa odkazov" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Súborový systém len pre čítanie" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Nie je na rovnakom súborovom systéme" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Meno príliÅ¡ dlhé" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Služba nie je k dispozícii" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Požiadavka zneplatňuje dáta služby" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Chyba protokolu" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "Nemôžem nájsÅ¥ hostiteľa master browser" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "Nedefinovaná žiadna Å¡tandardná akcia" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "Pre URL nie je ovládací program" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "Chyba pri spracovaní príkazového riadku" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "Chyba pri spúšťaní príkazu" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Neznáma chyba" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 bajt" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u bajtov" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (neplatný Unicode kód)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "Neznáma GnomeVFSSeekPosition %d" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "Nepodarilo sa nájsÅ¥ platný súbor s nastavením v %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "Pre iné umiestnenie použite premennú prostredia %s\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "Aplikácie" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "Karty" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "Súbory" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "Priečinky" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "Pomocník" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "Hostitelia" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "Odkazy" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "PoÅ¡ta" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "Nástroje" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "Okná" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Vytváracie rozhranie pre Å¡tandardný moniker" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "súbor MonikerExtender" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "generický moniker Gnome VFS" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "generický moniker pre súbor" diff --git a/po/sl.gmo b/po/sl.gmo new file mode 100644 index 0000000000000000000000000000000000000000..443072bae1e275f9297bdffc8063a6a7483fd7df GIT binary patch literal 5404 zcma);Ta08y8GuXf4uXO=6c!3)SZ+N#v+Ke-z`|Z;mSN|{&I}~@Vojgwo|-;g)toxr zyEFRcB^ZR5DAD+02qxfzA;yFUB*ur`7)UfG5+jKcm6#BHFa{rdFvjn%bGm1CgVB?& z{!ZQhYt?z{+Do2QJdaRrpnU%#rMmF0OZnsZ!(~cc3;zf&hyQ^5)W7Qb#WdbX{mPnm z)SQD?(7pj>{1fmhcm{p|eieQYeiPmSpNF#LFX8R*4Y&vX8-5txz+zX!Nq8H4pssH~ z=|2sxgipbb!*9b+!k6my*P+b+4HP;43`LH2VN&(|m427O57B-#lyNt~OJD=aKKpCV zLRs%|DDxfUr$XJn1x21Gq1f+Rb^8lY#=i_@|5xEB;A>F!c^lpW-+{9KRb!Q3u7`-K z4nY}z1d5)YgJQ=BuYq5J*TZL_$or$3=io=FzghEdQ08BXkTP!%6n*wV8F#qmD%8|B z>-tmhI_l3s8UG5DeO`m2*YDv?@NFpaUyPE{e+?8nj6+%f5Ih1GAud+mfFFV1fui3J z>-x{(@%Jh9J1FyRW>Xn|50toipsvqCiI+tv@tD{3ry!>~k~1Yj_uwcw2yJT`2oRC~@#) z-Tz|UeikCKdJ~HLe}SU^K+{=r|D9>jpBFF6%kyoAvDW9R-Ns*YFr5vVk6sPAt{vWR2MMm+PJfg=P>5V*t z_tfu`HIG7xHL>^ZN9?#j(Ueb9G|#{wRH$^8=H+Os{#@44J)MjZaLq^ogStPgYo<8mGrI-3-1o&PTnt zHm{o-rZCOY7IEUjZXa~lmK!0{-gNDIc89E=+hKQKuWyw$s;NYEq}jAF>dbm)Gj*ib z%U#oyF8HX9noPGGGdGOSa;uIR??b7Zg*BzsJ=e3k6$%}C*6R~`2sXyR!ZyoLZ0YrW+}c%@&26_=ZmAh0 z2(2_r%@hSH=BDqP8?42S-7eOs+eMsRtvYw!s#!6aJ>y~-tM`$rJ5{k+RVzc#>#m(D zj1PH+lVQe5u&SPqC@=>)8(o=J4t`1n#WJ!rWH5awf+0ce+-uX^c^P%m$ZW$EMsDz%_1Y2~X zw!VpznM%(B1Jpt&h@IMQNt>uoyFAzHR=c*RH=9t4qJdZ@55BDy1L4^+{k+uV0HLW( zjG^g>!c00VoA6S_X_2CG?bN)E%?;bNG9>m))9T!|O3n1l4qQ{(S#Xy!Qnx!K7+-E!9Yv&+4RMR$?5ZUR`!0FB%ha^h!QM2!X>+m1P8&Ar6``FRwYwGT)KR?C zD*j@zt}8{!o%UFUUXPaLB9x&ShF&{m$<^TVt@A{b*2a6ZKGC;?PFRm2$E#73V`7lK z90O#PTB)i@FEhYtW}WO`DT#a1S}z3eI%H=HXNZwj@e?_*Re5};8pJ?iu_$eMRBOKD z!)eY6AG-F@*_9P*JIf)uy8`>$4_dC{a!B=m`P5e z%KU0A5d>8&v@o!7is+R!cE(LMChy^=C-+YuJW!3B z=LBu67RJZi;H7DO#Ak)s)~lg#`aV2KWr7Yj^1!a5)&S?~D0^xtj<@`|#Mp+``O`GE)c3|^OgEad8 zyFv%iuJ<>sUYtAo^_ls_8NKaIXLLn+tA_&|(P88oC7p*i==t6B$}MW>Io9!ZoAc7C#adpLCa*$i&pyp-5zao%6-zHm7PhPVv6Q$hoo?b; zeZft7(h%Alh_N&SSEBoHv5wK{GWCx8BR5>{n_S{1U5=x*X=L4YZU)}A4Hs(cn4C!6 zwLO7w_URlCmoCj+4hY+EItJYf9VA01ba4?;y*c-s&2{Al?>142sI7@Ww8I&U3w@uslO@4jd@0e|b9d!+*-L!*Izj&&M zr5x#`4t7qfAlRlEHgHHg%-zQJ@*#v#hCLY0>5%mb4!+TBr0x~sJ+V~XYPr99-0t}o5ZM|C$R=lUe5S`J-yQYVNER}!=A(G?Fxa>>-qxkZPd2|baZHfcC-jyP7N73+=G za_Z52bF_-FxS`YKJ**BRPBMi1dst=t`U)?cdYF4Q`35NmmZ-HvtRt`MZ9^~;B?U2!&?%Z(Lr1ymQF|V* zFN(2=G6Z1d0g1bziz(R{oi6^T$~E$=Zk^+z_v#NLp} zUV=w-W7~91H?gIt*O3ote_mq>&0V9gLrPs4?d0r0I?N&>NuHM#pW$1*wUxzA@NcvVPum$d0w?)3`2LH4FakEhp_8rODl8-(NgAFGnzq_S~GEfpaX&soms|Ne, 2000. +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs 0.1\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2000-07-07 02:53+0200\n" +"Last-Translator: Andraz Tori \n" +"Language-Team: Slovenian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Report-Msgid-Bugs-To: \n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d vsebuje NIČELNE znake." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d ne vsebuje imena metode." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d ne vsebuje imea modula." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Nastavitvena datoteka `%s' ni bila najdena: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Neznana vrsta operacije %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "Ne morem ustvariti cevi GIOChannel: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Neznana vrsta posla %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Operacija ustavljena" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Ne morem razčleniti: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Nadalnje napake pri razčlenitvi bodo ignorirane." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Brez napak" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Datoteke ni mogoče najti" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Generična napaka" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Interna napaka" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Neveljavni parametri" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Nepodprta operacija" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "V/I napaka" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Podatki so pokvarjeni" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Format ni veljaven" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Neveljavna datotečna ročica" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "Datoteka je prevelika" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Na napravi ni več prostora" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Datotečni sistem je le berljiv" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "Neveljaven URI" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Datoteka ni odprta" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Neveljaven način odpiranja" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Dostop zavrnjen" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "Preveč odprtih datotek" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Konec datoteke" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Ni imenik" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Operacija poteka" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Operacija je bila prekinjena" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Datoteka obstaja" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Najdene so bile krožne povezave" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Nedovoljena operacija" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "Je imenik" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Ni dovolj pomnilnika" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Gostitelj ni bil najden" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Gostitlejevo ime ni veljavno" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Gostitelj nima naslova" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Prijava ni uspela" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Operacija preklicana" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Imenik je zaseden" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Imenik ni prazen" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "Preveč povezav" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Datotečni sistem je le berljiv" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Ni na istem datotečnem sistemu" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Ime je predolgo" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Storitev ni na voljo" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Zahtevek zastara podatke storitve" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Napaka v protokolu" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "Ne morem najti glavnega brskalnika" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "S tem ni povezan nobeno privzeto dejanje" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "Ni obravnavalnika te sheme URLja" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "Napaka ob razčlenjevanju ukazne vrstice" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "Napaka ob zaganjanju ukaza" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Neznana napaka" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 bajt" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u bajtov" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (neveljaven Unicode)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "Neznan GnomeVFSSeekPosition %d" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "Nisem naÅ¡el veljavnih nastavitev v datoteki %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "Uporabite okolijsko spremenljivko %s za navedbo drugačne lokacije.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "Programi" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "Karte" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "Datoteke" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "Mape" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "Pomoč" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "Gostitelji" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "Povezave" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "PoÅ¡ta" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "Orodja" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "Okna" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Standardna tovarna vzdevkov" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "datoteka MonikerExtender" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "generični vzdevčnik VFS Gnome" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "generični vzdevčnik datotek" + +#~ msgid "3D Studio image" +#~ msgstr "Slika 3D Studia" + +#~ msgid "AIFC audio" +#~ msgstr "zvok AIFC" + +#~ msgid "AIFF audio" +#~ msgstr "zvok AIFF" + +#~ msgid "ANIM animation" +#~ msgstr "animacija ANIM" + +#~ msgid "AVI video" +#~ msgstr "video AVI" + +#~ msgid "AbiWord document" +#~ msgstr "dokument AbiWord-a" + +#~ msgid "Adobe FrameMaker font" +#~ msgstr "pisava Adobe FrameMaker" + +#~ msgid "Adobe font metrics" +#~ msgstr "metrika za pisavo Adobe" + +#~ msgid "Andrew Toolkit inset" +#~ msgstr "seznam Andrew Toolkit-a" + +#~ msgid "ApplixWare Graphics image" +#~ msgstr "slika Applixware Graphics" + +#~ msgid "Applixware Words document" +#~ msgstr "dokument Applixware Words" + +#~ msgid "Applixware spreadsheet" +#~ msgstr "preglednica Applixware-a" + +#~ msgid "AutoCAD image" +#~ msgstr "slika AutoCAD-a" + +#~ msgid "BCPIO document" +#~ msgstr "dokument BCPIO" + +#~ msgid "BDF font" +#~ msgstr "pisava BDF" + +#~ msgid "C shell script" +#~ msgstr "skripta za lupino C" + +#~ msgid "C source code" +#~ msgstr "izvorna koda C" + +#~ msgid "C++ source code" +#~ msgstr "izvorna koda C++" + +#~ msgid "CGI program" +#~ msgstr "program CGI" + +#~ msgid "CGM image" +#~ msgstr "slika CGM" + +#~ msgid "CMU raster image" +#~ msgstr "rastrska slika CMU" + +#~ msgid "CPIO archive" +#~ msgstr "arhiv CPIO" + +#~ msgid "CPIO archive (gzip-compressed)" +#~ msgstr "arhiv CPIO (komprimirana z gzip)" + +#~ msgid "DCL script" +#~ msgstr "skripta DCL" + +#~ msgid "DOS font" +#~ msgstr "pisava DOS" + +#~ msgid "DOS/Windows program" +#~ msgstr "program za DOS/Okena" + +#~ msgid "DSSSL document" +#~ msgstr "dokument DSSSL" + +#~ msgid "DXF vector graphic" +#~ msgstr "vektorska grafika DXF" + +#~ msgid "Debian package" +#~ msgstr "paket Debian" + +#~ msgid "Dia diagram" +#~ msgstr "diagram Dia" + +#~ msgid "Dolby Digital audio" +#~ msgstr "audio Dolby Digital" + +#~ msgid "Emacs Lisp source code" +#~ msgstr "izvorna koda Emacs Lisp" + +#~ msgid "Enlightenment theme" +#~ msgstr "tema Enlightment" + +#~ msgid "FLC animation" +#~ msgstr "animacija FLC" + +#~ msgid "FLI animation" +#~ msgstr "animacija FLI" + +#~ msgid "FastTracker II audio" +#~ msgstr "zvok FastTracker II" + +#~ msgid "Fortran source code" +#~ msgstr "izvorna koda Fortran" + +#~ msgid "FrameMaker interchange document" +#~ msgstr "izmenjalni dokument FrameMaker" + +#~ msgid "G3 fax image" +#~ msgstr "fax slika G3" + +#~ msgid "GIF image" +#~ msgstr "slika GIF" + +#~ msgid "GIMP document" +#~ msgstr "dokument GIMP" + +#~ msgid "GMC link" +#~ msgstr "povezava GMC" + +#~ msgid "GNOME application details" +#~ msgstr "podrobnosti GNOME programa" + +#~ msgid "GNU Oleo Spreadsheet" +#~ msgstr "preglednica GNU Oleo" + +#~ msgid "GNU mail message" +#~ msgstr "sporočilo GNU mail" + +#~ msgid "GTK configuration" +#~ msgstr "nastavitev GTK" + +#~ msgid "Glade project" +#~ msgstr "projekt Gladea" + +#~ msgid "GnuCash Workbook" +#~ msgstr "delovna knjiga GnuCash" + +#~ msgid "Gnumeric spreadsheet" +#~ msgstr "preglednica Gnumeric" + +#~ msgid "HDF document" +#~ msgstr "dokument HDF" + +#~ msgid "HTML page" +#~ msgstr "stran HTML" + +#~ msgid "IDL document" +#~ msgstr "dokument IDL" + +#~ msgid "IEF image" +#~ msgstr "slika IEF" + +#~ msgid "IFF image" +#~ msgstr "slika IFF" + +#~ msgid "ILBM image" +#~ msgstr "slika ILBM" + +#~ msgid "ISI video" +#~ msgstr "video ISI" + +#~ msgid "Impulse Tracker audio" +#~ msgstr "zvok Impulse trackerja" + +#~ msgid "JBuilder Project" +#~ msgstr "projekt JBuilderja" + +#~ msgid "JPEG image" +#~ msgstr "slika JPEG" + +#~ msgid "Java byte code" +#~ msgstr "bajtna koda Java" + +#~ msgid "Java source code" +#~ msgstr "java izvorna koda" + +#~ msgid "KDE application details" +#~ msgstr "podrobnosti KDE programa" + +#~ msgid "KIllustrator document" +#~ msgstr "dokument KIllustratoja" + +#~ msgid "KPresenter presentation" +#~ msgstr "predstavitev KPresenterja" + +#~ msgid "KSpread spreadsheet" +#~ msgstr "preglednica KSpreada" + +#~ msgid "KWord document" +#~ msgstr "dokument KWorda" + +#~ msgid "Korn shell script" +#~ msgstr "lupinska Å¡koljka Korn" + +#~ msgid "LHA archive" +#~ msgstr "arhiv LHA" + +#~ msgid "LHARC archive" +#~ msgstr "arhiv LHARC" + +#~ msgid "LIBGRX font" +#~ msgstr "pisava LIBGRX" + +#~ msgid "LightWave object" +#~ msgstr "predmet LightWavea" + +#~ msgid "LightWave scene" +#~ msgstr "scena LighteWavea" + +#~ msgid "Linux PSF console font" +#~ msgstr "konzolska pisava Linux PSF" + +#~ msgid "Lotus 1-2-3 spreadsheet" +#~ msgstr "preglednica Lotus-1-2-3" + +#~ msgid "M3 audio URL" +#~ msgstr "URL zvoka oblike M3" + +#~ msgid "MIDI audio" +#~ msgstr "zvok MIDI" + +#~ msgid "MOD audio" +#~ msgstr "zvok MOD" + +#~ msgid "MP3 audio" +#~ msgstr "zvok MP3" + +#~ msgid "MP3 audio playlist" +#~ msgstr "seznam predvajanja MP3 zvoka" + +#~ msgid "MPEG video" +#~ msgstr "video MPEG" + +#~ msgid "MS ASF video" +#~ msgstr "video MS ASF" + +#~ msgid "MS video" +#~ msgstr "MS video" + +#~ msgid "Macintosh AppleDouble-encoded file" +#~ msgstr "datoteka kodirana z Macintosh AppleDouble" + +#~ msgid "Macintosh BinHex-encoded file" +#~ msgstr "datoteka kodirana z Macintosh BinHex" + +#~ msgid "Macintosh StuffIt archive" +#~ msgstr "arhiv Macintosh StuffIt" + +#~ msgid "Macromedia Flash file" +#~ msgstr "datoteka Macromedia Flash" + +#~ msgid "MathML document" +#~ msgstr "dokument MathML" + +#~ msgid "Microsoft Excel spreadsheet" +#~ msgstr "preglednica Microsoft Excel" + +#~ msgid "Microsoft PowerPoint document" +#~ msgstr "dokument Microsoft PowerPoint" + +#~ msgid "Microsoft Word document" +#~ msgstr "dokument Micrsofot Word" + +#~ msgid "Microsoft video" +#~ msgstr "video Microsoft" + +#~ msgid "Nautilus link" +#~ msgstr "povezava Nautilusa" + +#~ msgid "ODA document" +#~ msgstr "dokument ODA" + +#~ msgid "PBM image" +#~ msgstr "slika PBM" + +#~ msgid "PCF font" +#~ msgstr "pisava PCF" + +#~ msgid "PDF document" +#~ msgstr "dokument PDF" + +#~ msgid "PEF program" +#~ msgstr "program PEF" + +#~ msgid "PGM image" +#~ msgstr "slika PGM" + +#~ msgid "PGN chess game" +#~ msgstr "igra Å¡aha PGN" + +#~ msgid "PGP keys" +#~ msgstr "ključi PGP" + +#~ msgid "PGP message" +#~ msgstr "sporočilo PGP" + +#~ msgid "PGP signature" +#~ msgstr "podpis PGP" + +#~ msgid "PGP-encrypted file" +#~ msgstr "datoteka zaÅ¡ifrirana s PGP" + +#~ msgid "PHP script" +#~ msgstr "skripta PHP" + +#~ msgid "PN RealAudio document" +#~ msgstr "dokument PN RealAudio" + +#~ msgid "PNG image" +#~ msgstr "slika PNG" + +#~ msgid "PNM image" +#~ msgstr "slika PNM" + +#~ msgid "PPM image" +#~ msgstr "slika PPM" + +#~ msgid "Palm OS database" +#~ msgstr "zbirka podatkov Palm OS" + +#~ msgid "Perl script" +#~ msgstr "skripta perl" + +#~ msgid "Photoshop document" +#~ msgstr "dokument Photoshopa" + +#~ msgid "PostScript Type 1 font" +#~ msgstr "pisava PostScript Type 1" + +#~ msgid "PostScript document" +#~ msgstr "dokument PostScript" + +#~ msgid "Python source code" +#~ msgstr "izvorna koda Python" + +#~ msgid "QuickTime movie" +#~ msgstr "film QuickTime" + +#~ msgid "Quicken document" +#~ msgstr "dokument Quicken" + +#~ msgid "Quicken for Windows document" +#~ msgstr "dokument Quicken za Okna" + +#~ msgid "RAR archive" +#~ msgstr "arhiv RAR" + +#~ msgid "README document" +#~ msgstr "dokument README" + +#~ msgid "RGB image" +#~ msgstr "slika RGB" + +#~ msgid "RIFF audio" +#~ msgstr "zvok RIFF" + +#~ msgid "RPM package" +#~ msgstr "paket RPM" + +#~ msgid "RealAudio/Video document" +#~ msgstr "dokument RealAudio/Video" + +#~ msgid "RealVideo video" +#~ msgstr "video RealVideo" + +#~ msgid "S/MIME file" +#~ msgstr "datoteka S/MIME" + +#~ msgid "S/MIME signature" +#~ msgstr "podpis S/MIME" + +#~ msgid "SGI video" +#~ msgstr "video SGI" + +#~ msgid "SGML document" +#~ msgstr "dokument SGML" + +#~ msgid "SMIL script" +#~ msgstr "skripta SMIL" + +#~ msgid "SQL code" +#~ msgstr "koda SQL" + +#~ msgid "SV4 CPIO archive" +#~ msgstr "arhiv SV4 CPIO" + +#~ msgid "SV4 CPIP archive (with CRC)" +#~ msgstr "arhiv SV4 CPIP (s CRCjem)" + +#~ msgid "SVG art" +#~ msgstr "delo SVG" + +#~ msgid "Scheme source code" +#~ msgstr "izvorna koda Scheme" + +#~ msgid "Scream Tracker 3 audio" +#~ msgstr "zvok Scream tracker 3" + +#~ msgid "Scream Tracker audio" +#~ msgstr "zvok Scream tracker" + +#~ msgid "Scream Tracker instrument" +#~ msgstr "inÅ¡trument Scream tracker" + +#~ msgid "Setext document" +#~ msgstr "dokument Setext" + +#~ msgid "Speech document" +#~ msgstr "dokument Speech" + +#~ msgid "Speedo font" +#~ msgstr "pisava Speedo" + +#~ msgid "Spreadsheet Interchange document" +#~ msgstr "izmenjalna preglednica Interexchange" + +#~ msgid "Stampede package" +#~ msgstr "paket Stampede" + +#~ msgid "StarOffice Writer document" +#~ msgstr "dokument StarOffice Writer-ja" + +#~ msgid "StarOffice presentation" +#~ msgstr "predstavitev StarOffice" + +#~ msgid "StarOffice spreadsheet" +#~ msgstr "preglednica StarOffice" + +#~ msgid "Sun mu-law audio" +#~ msgstr "zvok v obliki Sun mu-law" + +#~ msgid "SunOS News font" +#~ msgstr "pisava SunOS News" + +#~ msgid "TIFF image" +#~ msgstr "slika TIFF" + +#~ msgid "TarGA image" +#~ msgstr "slika TarGA" + +#~ msgid "Tcl script" +#~ msgstr "skripta TCL" + +#~ msgid "TeX document" +#~ msgstr "dokument TeX" + +#~ msgid "TeX dvi document" +#~ msgstr "dokument TeX dvi" + +#~ msgid "TeX font" +#~ msgstr "pisava TeX" + +#~ msgid "TeX font metrics" +#~ msgstr "metrika za pisavo TeX" + +#~ msgid "TeXInfo document" +#~ msgstr "dokument TeXInfo" + +#~ msgid "ToutDoux document" +#~ msgstr "dokument ToutDoux" + +#~ msgid "TrueType font" +#~ msgstr "pisava TrueType" + +#~ msgid "USENET news message" +#~ msgstr "sporočilo novičarskih skupin USENET" + +#~ msgid "Unidata netCDF document" +#~ msgstr "dokument Unidata netCDF" + +#~ msgid "V font" +#~ msgstr "pisava oblike V" + +#~ msgid "VOC audio" +#~ msgstr "zvok VOC" + +#~ msgid "VRML document" +#~ msgstr "dokument VRML" + +#~ msgid "Vivo video" +#~ msgstr "video Vivo" + +#~ msgid "WAIS source code" +#~ msgstr "izvorna koda WAIS" + +#~ msgid "Wavelet video" +#~ msgstr "video Wavelet" + +#~ msgid "Windows bitmap image" +#~ msgstr "bitna okenska slika" + +#~ msgid "Windows icon image" +#~ msgstr "ikona za Okna" + +#~ msgid "Windows metafile graphics" +#~ msgstr "metadatoteka okenske grafike" + +#~ msgid "WordPerfect document" +#~ msgstr "dokument WordPerfect" + +#~ msgid "X bitmap image" +#~ msgstr "bitna slika X" + +#~ msgid "X window image" +#~ msgstr "slika okna X" + +#~ msgid "XML document" +#~ msgstr "dokument XML" + +#~ msgid "XPM image" +#~ msgstr "slika XPM" + +#~ msgid "Xbase database" +#~ msgstr "zbirka podatkov Xbase" + +#~ msgid "active server page" +#~ msgstr "aktivna strežniÅ¡ka stran" + +#~ msgid "address card" +#~ msgstr "vizitka" + +#~ msgid "ar archive" +#~ msgstr "arhiv ar" + +#~ msgid "arj archive" +#~ msgstr "arhiv arj" + +#~ msgid "authors list" +#~ msgstr "seznam avtorjev" + +#~ msgid "backup file" +#~ msgstr "varnostna kopija" + +#~ msgid "basic audio" +#~ msgstr "osnovni zvok" + +#~ msgid "bibliography record" +#~ msgstr "bibliografski zapis" + +#~ msgid "binary program" +#~ msgstr "binarni program" + +#~ msgid "block device" +#~ msgstr "blokovna naprava" + +#~ msgid "bzip-compressed file" +#~ msgstr "datoteka komprimirana z bzip" + +#~ msgid "calendar file" +#~ msgstr "datoteka koledarja" + +#~ msgid "calendar or event document" +#~ msgstr "dokument koledarja ali dogodka" + +#~ msgid "character device" +#~ msgstr "znakovna naprava" + +#~ msgid "comma-separated text document" +#~ msgstr "dokument besedila ločenega z vejicami" + +#~ msgid "compound document" +#~ msgstr "združen dokument" + +#~ msgid "compress-compressed file" +#~ msgstr "datoteka komprimirana s compress" + +#~ msgid "compressed GIMP document" +#~ msgstr "komprimiran dokument GIMP" + +#~ msgid "directory information file" +#~ msgstr "datoteka s podatki o imeniku" + +#~ msgid "document type definition" +#~ msgstr "določitev vrste dokumenta" + +#~ msgid "email headers" +#~ msgstr "glave e-poÅ¡te" + +#~ msgid "email message" +#~ msgstr "sporočilo e-poÅ¡te" + +#~ msgid "encrypted message" +#~ msgstr "Å¡ifrirano sporočilo" + +#~ msgid "enriched text document" +#~ msgstr "dokument z obogatenim besedilom" + +#~ msgid "gtar archive" +#~ msgstr "arhiv gtar" + +#~ msgid "gzip-compressed file" +#~ msgstr "daoteka komprimirana z gzip" + +#~ msgid "help page" +#~ msgstr "stran pomoči" + +#~ msgid "mail delivery report" +#~ msgstr "poročilo o dostavi poÅ¡te" + +#~ msgid "mail disposition report" +#~ msgstr "poročilo o stanju poÅ¡te" + +#~ msgid "mail system report" +#~ msgstr "poročilo o poÅ¡tnem sistemu" + +#~ msgid "makefile" +#~ msgstr "makefile" + +#~ msgid "manual page" +#~ msgstr "stran priročnika" + +#~ msgid "manual page (compressed)" +#~ msgstr "stran priročnika (komprimirana)" + +#~ msgid "memory dump" +#~ msgstr "izpis pomnilnika" + +#~ msgid "message digest" +#~ msgstr "arhiv sporočil" + +#~ msgid "message in several formats" +#~ msgstr "sporočilo v več oblikah zapisa" + +#~ msgid "multi-part message" +#~ msgstr "več delno sporočilo" + +#~ msgid "named pipe" +#~ msgstr "poimenovana cev" + +#~ msgid "object code" +#~ msgstr "koda predmeta" + +#~ msgid "ogg audio" +#~ msgstr "zvok ogg" + +#~ msgid "partial email message" +#~ msgstr "del e-poÅ¡tnega sporočila" + +#~ msgid "plain text document" +#~ msgstr "dokument čistega besedila" + +#~ msgid "profiler results" +#~ msgstr "rezultati profiliranja" + +#~ msgid "reference to remote file" +#~ msgstr "navezava na oddaljeno datoteko" + +#~ msgid "rejected patch file" +#~ msgstr "datoteka z zavrnjenim popravkom" + +#~ msgid "rich text document" +#~ msgstr "dokument bogatega besedila" + +#~ msgid "search results" +#~ msgstr "zadetki iskanja" + +#~ msgid "shared library" +#~ msgstr "deljena knižnjica" + +#~ msgid "shell archive" +#~ msgstr "arhiv lupine" + +#~ msgid "shell script" +#~ msgstr "skripta lupine" + +#~ msgid "signed message" +#~ msgstr "podpisano sporočilo" + +#~ msgid "socket" +#~ msgstr "vtič" + +#~ msgid "software author credits" +#~ msgstr "zahvle avtorjem programja" + +#~ msgid "software installation instructions" +#~ msgstr "navodila za namestitev programja" + +#~ msgid "software license terms" +#~ msgstr "pogoji licence programja" + +#~ msgid "source code patch" +#~ msgstr "popravek izvorne kode" + +#~ msgid "style sheet" +#~ msgstr "slogovne predloge" + +#~ msgid "symbolic link" +#~ msgstr "simbolična povezava" + +#~ msgid "tab-separated text document" +#~ msgstr "datoteka z besedilom ločenim s tabulatorji" + +#~ msgid "tar archive" +#~ msgstr "arhiv tar" + +#~ msgid "tar archive (bzip2-compressed)" +#~ msgstr "arhiv tar (komprimiran z bzip2)" + +#~ msgid "tar archive (gzip-compressed)" +#~ msgstr "arhiv tar (komprimiran z gzip)" + +#~ msgid "theme" +#~ msgstr "tema" + +#~ msgid "troff document" +#~ msgstr "dokument troff" + +#~ msgid "troff me input document" +#~ msgstr "vhodni dokument troff me" + +#~ msgid "troff mm input document" +#~ msgstr "vhodni dokument troff mm" + +#~ msgid "troff ms input document" +#~ msgstr "vhodni dokument troff ms" + +#~ msgid "unknown type" +#~ msgstr "neznana vrsta" + +#~ msgid "ustar archive" +#~ msgstr "arhiv ustar" + +#~ msgid "wave audio" +#~ msgstr "zvok wave" + +#~ msgid "web folder" +#~ msgstr "spletna mapa" + +#~ msgid "xfig vector graphic" +#~ msgstr "vektorska grafika xfig" + +#~ msgid "zip archive" +#~ msgstr "arhiv zip" + +#~ msgid "zoo archive" +#~ msgstr "arhiv zoo" + +#~ msgid "GNOME VFS already initialized." +#~ msgstr "GNOME VFS je že inicializiran." + +#~ msgid "%s to retrieve" +#~ msgstr "%s za prenos sem" + +#~ msgid "Closing connection to %s" +#~ msgstr "Zapiram povezavo z %s" + +#~ msgid "%s of %s read" +#~ msgstr "%s od %s prebranih" + +#~ msgid "%s read" +#~ msgstr "%s prebran" + +#~ msgid "Dying." +#~ msgstr "Umira." + +#~ msgid "Error reading: %s" +#~ msgstr "Napaka pri branju: %s" + +#~ msgid "Error writing: %s" +#~ msgstr "Napaka pri pisanju v: %s" + +#~ msgid "Cannot write: %s" +#~ msgstr "Ne morem zapisati v: %s" + +#~ msgid "Cannot create temporary file name `%s'" +#~ msgstr "Ne morem ustvariti začasne datoteke `%s'" + +#~ msgid "Cannot create socket: %s" +#~ msgstr "Ne morem ustvariti vtiča %s" + +#~ msgid "Cannot bind `%s': %s" +#~ msgstr "Ne morem povezati `%s': %s" + +#~ msgid "Cannot listen on `%s': %s" +#~ msgstr "Ne morem posluÅ¡ati na `%s': %s" + +#~ msgid "Cannot accept connections on `%s': %s" +#~ msgstr "Ne morem sprejeti povezav na `%s': %s" + +#~ msgid "Cannot initialize CORBA." +#~ msgstr "Ne morem inicializirati CORBA-e." + +#~ msgid "Cannot resolve initial reference to RootPOA." +#~ msgstr "Ne morem razvozlati začetne reference na RootPOA." + +#~ msgid "Cannot activate POA manager." +#~ msgstr "Ne morem aktivirat upravljalca POA." + +#~ msgid "Usage: %s []\n" +#~ msgstr "Uporaba: %s []\n" + +#~ msgid "Cannot open file descriptor %d." +#~ msgstr "Ne morem odpreti datotečnega deskriptorja %d." + +#~ msgid "Notify interface for `%s' not found." +#~ msgstr "Vmesnik za obvestila za `%s' ni bil najden." + +#~ msgid "Cannot setup Request object." +#~ msgstr "Ne morem nastaviti predmeta za zahtevek." + +#~ msgid "Cannot extract IOR." +#~ msgstr "Ne morem izluščiti IORa." + +#~ msgid "Got weird string from the slave process: `%s'" +#~ msgstr "Dobil sem čudno sporočilo od suženjskega procesa: `%s'" + +#~ msgid "Cannot get object for `%s'" +#~ msgstr "Ne morem dobiti predmeta za `%s'" + +#~ msgid "Cannot kill GNOME::VFS::Slave::Notify -- exception %s" +#~ msgstr "Ne morem ubiti GNOME::VFS::Slave::Notify -- izjema %s" + +#~ msgid "Cannot connect socket `%s': %s" +#~ msgstr "Ne morem povezati vtiča `%s': %s" + +#~ msgid "Cannot initialize GNOME::VFS:Slave::Notify" +#~ msgstr "Ne morem inicializirati GNOME::VFS:Slave::Notify" + +#~ msgid "Cannot reset GNOME::VFS::Slave %s -- exception %s" +#~ msgstr "Ne morem ponastaviti GNOME::VFS::Slave %s -- izjema %s" + +#~ msgid "Cannot reset GNOME::VFS::Slave (IOR unknown) -- exception %s" +#~ msgstr "Ne morem ponastaviti GNOME::VFS::Slave (IOR neznan) -- izjema %s" + +#~ msgid "Cannot kill GNOME::VFS::Slave %s -- exception %s" +#~ msgstr "Ne morem ubiti GNOME::VFS::Slave %s -- izjema %s" + +#~ msgid "Cannot kill GNOME::VFS::Slave (IOR unknown) -- exception %s" +#~ msgstr "Ne morem ubiti GNOME::VFS::Slave (neznan IOR) -- izjema %s" + +#~ msgid "Back" +#~ msgstr "Nazaj" + +#~ msgid "Go to the previously visited directory" +#~ msgstr "Pojdi na prej obiskan imenik" + +#~ msgid "Up" +#~ msgstr "Gor" + +#~ msgid "Go to the parent directory" +#~ msgstr "Pojdi v starÅ¡evski imenik" + +#~ msgid "Forward" +#~ msgstr "Naprej" + +#~ msgid "Go to the next visited directory" +#~ msgstr "Pojdi na naslednji obiskan imenik" + +#~ msgid "Rescan" +#~ msgstr "Osveži" + +#~ msgid "Rescan the current directory" +#~ msgstr "Osveži trenutni imenik" + +#~ msgid "Home" +#~ msgstr "Dom" + +#~ msgid "Go to the home directory" +#~ msgstr "Pojdi v domači imenik" + +#~ msgid "Name" +#~ msgstr "Ime" + +#~ msgid "Size" +#~ msgstr "Velikost" + +#~ msgid "Date" +#~ msgstr "Datum" + +#~ msgid "Enter name:" +#~ msgstr "VpiÅ¡ite ime:" + +#~ msgid "Show:" +#~ msgstr "Kaži:" + +#~ msgid "Show dotfiles" +#~ msgstr "Kaži nastavitevene datoteke" + +#~ msgid "Edit Applications List" +#~ msgstr "Uredi seznam programov" + +#~ msgid "Select applications to appear in menu for mime type \"%s\"" +#~ msgstr "Izberi programe, ki naj se kažejo v menuju tipov mime \"%s\"" + +#~ msgid "Add Application..." +#~ msgstr "Dodaj program..." + +#~ msgid "Edit Application..." +#~ msgstr "Uredi program..." + +#~ msgid "Delete Application" +#~ msgstr "ZbriÅ¡i program" + +#~ msgid "Edit Components List" +#~ msgstr "Uredi seznam komponent" + +#~ msgid "Select views to appear in menu for mime type \"%s\"" +#~ msgstr "Izberi poglede, ki naj se kažejo v menuju tipov mime \"%s\"" + +#~ msgid "" +#~ "The MIME type entered contained upper case characters. Upper case " +#~ "characters were changed to lower case for you." +#~ msgstr "" +#~ "Vpisan tip MIME je vseboval velike črke. Samodejno so bile spremenjene v " +#~ "male." + +#~ msgid "Add New MIME Type" +#~ msgstr "Dodaj nov tip MIME" + +#~ msgid "Add Mime Type" +#~ msgstr "Dodaj tip Mime" + +#~ msgid "" +#~ "Add a new Mime Type\n" +#~ "For example: image/tiff; text/x-scheme" +#~ msgstr "" +#~ "Dodaj nov tip Mime\n" +#~ "Na primer: image/tiff; text/x-scheme" + +#~ msgid "Mime Type:" +#~ msgstr "Tip mime:" + +#~ msgid "Type in a description for this mime-type." +#~ msgstr "Vnesite opis tega tipa mime." + +#~ msgid "Description:" +#~ msgstr "Opis:" + +#~ msgid "File Extensions " +#~ msgstr "Pripone datotek " + +#~ msgid "Add..." +#~ msgstr "Dodaj..." + +#~ msgid " Remove " +#~ msgstr " Odstrani " + +#~ msgid "Add New Extension" +#~ msgstr "Dodaj novo pripono" + +#~ msgid "" +#~ "Type in the extensions for this mime-type.\n" +#~ "For example: .html, .htm" +#~ msgstr "" +#~ "Vnesite novo pripono za ta tip mime.\n" +#~ "Na primer: .html, .htm" + +#~ msgid "Extension:" +#~ msgstr "Pripona:" + +#~ msgid "New Application" +#~ msgstr "Nov program" + +#~ msgid "Application Name:" +#~ msgstr "Ime programa:" + +#~ msgid "Application Command:" +#~ msgstr "Ukaz programa:" + +#~ msgid "Open Behavior" +#~ msgstr "Odpri obnaÅ¡anje" + +#~ msgid "Can open multiple files" +#~ msgstr "Lahko odpre več datotek" + +#~ msgid "Expects URIs as arguments" +#~ msgstr "Kot argumente pričakuje URIje" + +#~ msgid "Edit Application" +#~ msgstr "Uredi program" + +#~ msgid "Can open from URI" +#~ msgstr "Lahko odpre iz URI-a" + +#~ msgid "Mime Type" +#~ msgstr "Tip Mime" + +#~ msgid "Change Icon" +#~ msgstr "Spremeni ikono" + +#~ msgid "Change File Extensions" +#~ msgstr "Spremeni pripone datotek" + +#~ msgid "Default Action:" +#~ msgstr "Privzeto dejanje:" + +#~ msgid "Use Viewer" +#~ msgstr "Uporabi pregledovalnik" + +#~ msgid "Open With Application" +#~ msgstr "Odpri s programom" + +#~ msgid "Edit List" +#~ msgstr "Uredi seznam" + +#~ msgid "Add new Mime type..." +#~ msgstr "Dodaj nov tip Mime..." + +#~ msgid "Delete this Mime type..." +#~ msgstr "ZbriÅ¡i ta tip Mime..." + +#~ msgid "Revert to System Defaults" +#~ msgstr "Vrni na privzete sistemske nastavitve" + +#~ msgid "No Description" +#~ msgstr "Ni opisa" + +#~ msgid "None" +#~ msgstr "Brez" + +#~ msgid "" +#~ "Reverting to system settings\n" +#~ "will lose all your personal \n" +#~ "Mime configuration.\n" +#~ "Revert to System Settings ?\n" +#~ msgstr "" +#~ "Vrnitev na privzete sistemske\n" +#~ "nastavitve bo povzročila izgubo vseh\n" +#~ "osebnih Mime nastavitev.\n" +#~ "Vrni na sistemske nastavitve ?\n" + +#~ msgid "none" +#~ msgstr "brez" + +#~ msgid "View as %s" +#~ msgstr "Poglej kot %s" + +#~ msgid "Description" +#~ msgstr "Opis" + +#~ msgid "Extension" +#~ msgstr "Pripona" + +#~ msgid "Default Action" +#~ msgstr "Privzeto Dejanje" + +#~ msgid "Can't find an hbox, using a normal file selection" +#~ msgstr "Ne najdem hbox, uporabljam običajno izbiranje datotek" + +#~ msgid "Preview" +#~ msgstr "Predogled" + +#~ msgid "Unknown sort rule %d" +#~ msgstr "Neznano pravilo urejanja %d" + +#~ msgid "Error writing to the wakeup GnomeVFSJob channel." +#~ msgstr "Napaka pri bujenju kanala GnomeVFSJob." + +#~ msgid "Add" +#~ msgstr "Dodaj" + +#~ msgid "Action" +#~ msgstr "Dejanje" + +#~ msgid "HTTP server returned an invalid PROPFIND response" +#~ msgstr "HTTP strežnik je vrnil napačen PROPFIND odgovor" + +#~ msgid "Application ID:" +#~ msgstr "ID programa:" + +#~ msgid "Default Application:" +#~ msgstr "Privzet Program:" + +#~ msgid "Default Viewer:" +#~ msgstr "Privzet Prikazovalnik:" + +#~ msgid "Select an icon..." +#~ msgstr "Izberi ikono..." + +#~ msgid "No Default" +#~ msgstr "Ni Privzeto" + +#~ msgid "Use None" +#~ msgstr "Brez" + +#~ msgid "ftpfs: Invalid host name." +#~ msgstr "ftpfs: Neveljavno ime gostitelja." + +#~ msgid "ftpfs: Invalid host address." +#~ msgstr "ftpfs: Neveljaven naslov gostitelja." + +#~ msgid "ftpfs: making connection to %s" +#~ msgstr "ftpfs: ustvarjam povezavo z %s" + +#~ msgid "ftpfs: connection interrupted by user" +#~ msgstr "ftpfs: uporabnik je prekinil povezavo" + +#~ msgid "ftpfs: connection to server failed: %s" +#~ msgstr "ftpfs: povezava do strežnika ni bila uspeÅ¡na: %s" + +#~ msgid "Waiting to retry... %d (Control-C to cancel)" +#~ msgstr "Čakam na nov poizkus... %d (Control-C za preklic)" + +#~ msgid " FTP: Password required for " +#~ msgstr " FTP: Potrebno je geslo za " + +#~ msgid "ftpfs: sending login name" +#~ msgstr "ftpfs: poÅ¡iljam ime za prijavo" + +#~ msgid "ftpfs: sending user password" +#~ msgstr "ftpfs: poÅ¡iljam uporabnikovo geslo" + +#~ msgid "ftpfs: logged in" +#~ msgstr "ftpfs: prijavljen sem" + +#~ msgid "ftpfs: Login incorrect for user %s " +#~ msgstr "ftpfs: Napačna prijava za uporabnika %s " + +#~ msgid "ftpfs: aborting transfer." +#~ msgstr "ftpfs: prekinjam prenos." + +#~ msgid "ftpfs: abort error: %s" +#~ msgstr "ftpfs: prekinitvena napaka: %s" + +#~ msgid "ftpfs: abort failed" +#~ msgstr "ftpfs: prekinitev ni uspela" + +#~ msgid "ftpfs: could not setup passive mode" +#~ msgstr "ftpfs: ne morem nastaviti pasivnega načina" + +#~ msgid "ftpfs: storing file %d (%d)" +#~ msgstr "ftpfs: shranjujem datoteko (%d) %D" + +#~ msgid "ftpfs: CWD failed." +#~ msgstr "ftpfs: CWD (sprememba delovnega direktorija) ni uspela." + +#~ msgid "ftpfs: couldn't resolve symlink" +#~ msgstr "ftpfs: ne morem razvozlati simbolične povezave" + +#~ msgid "Resolving symlink..." +#~ msgstr "Razvozljujem simbolno povezavo..." + +#~ msgid "ftpfs: Reading FTP directory %s... (don't use UNIX ls options)" +#~ msgstr "ftpfs: Berem FTP imenik %s... (ne uporabljam UNIX ls opcij)" + +#~ msgid "ftpfs: Reading FTP directory %s..." +#~ msgstr "ftpfs: Berem FTP imenik %s..." + +#~ msgid "ftpfs: reading FTP directory interrupt by user" +#~ msgstr "ftpfs: branje FTP imenika je prekinil uporabnik" + +#~ msgid "ftpfs: got listing" +#~ msgstr "ftpfs: seznam dobljen" + +#~ msgid "ftpfs: failed; nowhere to fallback to" +#~ msgstr "ftpfs: spodletel; ni več možnih reÅ¡itev" + +#~ msgid "Starting linear transfer..." +#~ msgstr "Začenjam linearen prenos..." + +#~ msgid "Preparing reget..." +#~ msgstr "Pripraljam ponvni prenos..." diff --git a/po/sq.gmo b/po/sq.gmo new file mode 100644 index 0000000000000000000000000000000000000000..3569361129657227ea36e8c68ffdbf2443ceaad8 GIT binary patch literal 5581 zcmai%Ta08y8GuUxFC!O01VzE}GVB8O>*U3NL$?QhVWbQ0m8^^q+$7 zfgN}?+=SP_uTDwcig#o)#3l6;=C}pp1VM%KqPkAB0ar+2=X<3HVbe`~Mw^KVE}~qOP8Z z<24jLXQ9~f1iT#9;fG)e#V%j1_-*)p>d#bs0m}TBq0D<7iawVjw2Zs9;(n;9FI4po z`~dZbpp1VE%05p*(d$R>Bk(yW^8cyoe+7yiE<|Zr|7v&$)}Ywk!z*;K~g3ni{TQ`H}U5^rrN_Int99DWzdxL-nk)UWx4DC#dz?DQ{q2fP#` ziu{Xk54;zC3=W~}`*_8t;Vsl(fTGU@1dG`3Du{?`FO>Zcz-jndD0X-RGDSTGMUJPS z%zp;TzQ2H?*Naf>@LPBl{AbmE5u1n{msGqS%6fN0nZF8Uy^V@($W-+?80-mUy(gg9 z<5?(vcpl2Szk?Egufl!s-&Ox!78QN(f}&pmWxa=>*ykHi^6XhC@$?&b1AGOFeXk)n zM4wxs#Kj_%aowu@i%{hFIuv=o4<+7z3?=_xg0lZ>a1!ogF=^j`K^`c2Jp{!LUxOmo zx1g-|6DaGy2>DTe<(KULI^2L)(kXWDK6V3=dO8Ci$+92){*MO}RbPVqQzk+*#FUDvDjjW}l`=jEaBuQ^Y@O6!F_$N{wEe8(wAD3TkJ5AuDKBD&r}xsh^+A~8AorupL-Mf`k}GE0%~E{gbeigE#E zl_H<`=iNBJb)D1d_>5bTlt%#ZTv}YVsiCK$`a)^ihL4F;-@_n zj;i1z5Mq7--Xs3n$#tFBXbR(*c;U3)J#(!I~=(fu}rm?olJDYXQgpjp;tDR zbfax@(YmZ{VQJN&M#C0`PHg6Eq7L=@scV?h z`K(ZfO`@BQ32l=lsZ~czmibaQa%)Pf`>t&d$zqQ_Z3-x_E)CNFH5anzIs z)8zS}Un2NXmt=dY*+xh67Pc&1)+*x8rbMs_2IjU=`h2MCgJQU&Dx2G0zZ|MLB=F5J zOU>muDyC+THQKDjj=dh%sMK(8 zHylxzNN2POf5bS=LsV{@SkgtKZF^RR6n)dMI%D5*?8#Usr4u?){A*r1riHP7?O{n*5ZL?WStgWusj>wrx zdyQj_^X=y8>HW3ogSDFv=$ZYqGY4;)riFpE6GX1ef5W($89j5$?15Y3xFt@{+InuX zA~kquRxg=BQ158l^^CrQ(@d)F9+TF|(!rUj%$9deESan|FfChKx289%52baJIg{x- zqNofG^%_R*mhGX%ardNh%1sr1kT)!MLCeOamKT=iwpE>(nx5b)z;=j*+h%oX&y@T6 zDYx3~;YQ=6zH?)JzIJeXoQRKCYI7VQ3FpbIK3I3<#0e|Dt}PcWm(&gqT19Q$&+3W$ zYvF*5>MkBOb(?Cootl~8x~;BR?KpQfIRlFJxwF0hbLsZaoy~hFth=0jT{*wx`du2` zs@b5c$3tu{C$+8IzCJm3c6>9Re~{e4uAEZU{kxKw)VD1s`7rMoF5uL435CsbXE`r3 zv(+Y7kvzmx$LlUPp6!-u0bP3Bo`YO>bJuY_$Dpip?rgl5MK)bhYnwhp&U-u0%RS{- zF<#OvQR;9#i`)a<>ew>ev~$~ANn6LDYIQSL7xhkQkU4c*EEeXjBSM0?GZUo2I=ym$ zMb*l9k0^D}&*`yyc8aAlR@r@bTfN1i*l7DY$2fIgwADOT5o5@T>X@m!9;z6zMT&38 z0MwLP*ULpt)9yiAb*w)cgRP5p`KAfMa<;og@cZf--?mx2)+N@0?Wukcc9pQ4QUhpKMAps(Bh#xp$u{}7C#of* z;;YAXCG_KUQJF%rOAN=;=V, 2002. +# Laurent Dhima , 2003 +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-08-11 14:56+0200\n" +"Last-Translator: Laurent Dhima \n" +"Language-Team: Albanian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Report-Msgid-Bugs-To: \n" +"X-Generator: KBabel 1.0.1\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d përmban karaktere NULL." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d nuk përmban emrin e metodës." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d nuk përmban emrin e modulit." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "File i konfigurimit `%s' nuk u gjet: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Tip op %u i panjohur" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "I pamundur krijimi i një pipe për të hapur GIOChannel: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Tip job %u i panjohur" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Operacioni u ndërpre" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "I pamundur analizimi: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Gabimet e tjera të analizës do të injorohen." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Asnjë gabim" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "File nuk u gjet" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Gabim i përgjithshëm" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Gabim i brendshëm" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Parametra të pavlefshëm" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Operacion i pasuportuar" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "Gabim Input/Output" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Të dhëna të dëmtuara" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Format i pavlefshëm" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Manazhues i file jo korrekt" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "File tepër i madh" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Nuk ka më hapsirë në periferike" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "File sistemi në vetëm-lexim" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "URI e pavlefshme" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "File i pahapur" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Menyrë hapje jo e vlefshme" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Ndalohet hyrja" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "Shumë files të hapur" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Fundi i file" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Nuk është një directory" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Oparacioni në kryerje e sipër" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Operacion i ndërprerë" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "File ekziston" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "U gjetën links në loop" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Operacion i palejuar" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "Është një directory" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Memorje e pamjaftueshme" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Host nuk u gjet" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Emër host i pavlefshëm" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Host nuk ka një adresë" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Identifikimi dështoi" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Operacioni u anullua" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Directory e zënë" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Directory jo bosh" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "Tepër links" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "File sistem në vetëm lexim" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Nuk gjendet në të njëjtin file sistemi" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Emër tepër i gjatë" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Shërbimi nuk është në dispozicion" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Kërkesë të dhënash nga shërbim tepër i vjetër" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Gabim protokolli" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "E pamundur gjetja e browser master" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "Nuk i është shoqëruar asnjë veprim i prezgjedhur" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "No handler for URL scheme" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "Gabim gjatë zbatimit të rreshtit të komandës" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "Gabim gjatë lëshimit të komandës" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Gabim i panjohur" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 byte" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, fuzzy, c-format +msgid "%u bytes" +msgstr "%u byte" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (Unicode i pavlefshëm)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "GnomeVFSSeekPosition %d e panjohur" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "Nuk u gjet një file i vlefshëm konfigurimi në %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "" +"Përdor të ndryshueshmen e ambientit %s për të specifikuar një pozicion " +"tjetër.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "Aplikativë" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "Cards" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "Files" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "Kartela" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "Ndihmë" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "Hosts" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "Lidhje" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "Mail" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "Vegla" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "Dritare" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Factory standart për Moniker" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "MonikerExtender file" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "Moniker Gnome VFS i përgjithshëm" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "moniker i përgjithshëm për file" diff --git a/po/sr.gmo b/po/sr.gmo new file mode 100644 index 0000000000000000000000000000000000000000..33ab00a99920a842925a2529a6eac9a52c78f58f GIT binary patch literal 6868 zcma)S96gofkPMOIu*JyW3Xlwp-|XSGs*KMh(WhGk14yJ9FqFE1z+Aw$N^-y>PkXl)$^M;vdhSu6CRoz_-Bu_#g1&;LU7y zE!Yjt1MkWDqoC$@gV%shfS(2rf;WOMW#hjDwf?uD^!PI zcPn@$m;-fAZ-#3@?e}$1>wSUk7#0JK*i$ zUqPKerz7>tO(3c|OF+r50A=SlK=BxX*Mk$_P2e-2^nE$Q*T7HG|9yu40JZ)ql+?Og zK-seZl-%+Rw}XcM&aD3g_!;`gK*^s4bKU@fp>!60~dm4LAG@M4k~W{3mWi7$djLzg3@anC?38E-UUv8 zvgajG>wgEb)cG5z^WMw)H$(1i^cR3%0JngOrz)uZz6)xfKMG`QTqb)r;#fO1yQ0;_ZG=^N)h!`6aLq z{B?$N2)cgy>p}T>AE|aF#n*Sh9QY$pes~ky4qgfA z*MeUI4LAylm&ZZr`D5@hP><}^b6*NJzBltuh}s&uFdJ`xcq6Rr^JV@+fwfh7>$#V< zh$j7H(^}ec+T}Do;_)l?Ev*sqn;ulMHtPKf+L!dg)188|62v?k7uk>n`AI%AG{u6R zO|&(%)wK0Aai&MUT1WdLO?ju-(gV$wKfQ||aj!=)q(>YN(Bw~>1?3&(B{w_GtUpk+@fDF zI|4r+7QFdRXIIa#S+_F9`%)OB8})S-Og;=^*AF7IamNOeA9X8kKK3e6SNn7jnvxff zh6NM2CGVosVWC>|8q-xXG#-1A(__(Dk+*yML;jmrh ztf^EmvFKKV{3v^IVyOfh*|^kc88t;e@SL@x%-iEfag@H#nA+@$v$Pk7p&9Z=YzO(U zSis3(rG&y-X>D=Vd4X5)^Tv}t&U&v{cGibcjB7-taSMeCZcN7%2Q5pjTvG>iBWGa2 zrfjc)0ICDGIMdC7bnAdKkOeGevZbQW8HkK)3JngO4SujIayEn`eqe@O3@^|L%i;ts zc16Yu@;I5L%nTyn42BhAC*#dp6Pew9v1o=o`85%Gi9Iu(IqekBY_UZ7m6_%eprA|$-LKRj+DV0f4SWxg1u zwXdtg`6@?JeH`oZ%;YtDVlN;+osldXttAFi2n0*Y%#2;u7{pmSDLT1alPH$3v=B|a=nX9&%(Z*C3kf*f?#ed(W^b$ zIZlT2Q2n6`E$~#IiM>7Xf^v}?ZK=J@D9-&mwy(`CY061k9Fbc?%_vYp`pl9cKknFE zR-6j@T9%|ptGmDzrV-aafi`s_ig<>J?0+MZTcjnq2>L(joD@W zi}X6rN-pc^HV-|Nu0p1JKFfMo*1NQWD?2%#OeRzHhm%+9dy`snf_B~{#~GeV&L-2z zssD3{v$B?)V(sZ<%3kEj8P?Y9+7roSW}E4r1n9C5v)%nuUO%# zNnTEB^+R?&nsehf2At$5I$;-cQ^~7F_S6sQyi=TY20N$g&tm!cRB$>uY0W>EOgYIB z<{p!}dpSuQuyy@#y0)gXXp>CT(7om)&!tvqiwT`mo1t<_hZ~kpCTBFq5@RQ)>-(_! zVU3;9n0Ay#d!-Re+P*cC!zi#HCGeCLm`e9OYPG6iEc?KzET|tz zZEW9Q_NnP1$$2qEU^FdeKv8sQixJRAP;!t}6R=BgX^Sb#?OD5#;^GjK=fvhkCtAWq zde!75h00-d>WA8Nl3NaFf9RiaF&4`yXYIHsJ1kp7y_|fCIK9NG7A7x{Z+E_qupvH8 zY!kT`%+Ex9litkp?QF<^;*p0rW;;P{g|HD#LIh2nE8KBDdQS|h%uRKZl%lmR$S)yZa?lN@3!s{u2z z5^6j1d@_BJ4YLB$Mx~Q{pHue}PpNY;=lFtz7@4Ig1+_j=e*{fx7(za`%~M30_L?1h znkp-^A*CL!R_LhaFw7h0K)Ut5wdkUO>?CqGSDr`cqQ7KGCw< zC9Btr9lF!f8;t|(m5O~SvoO%ImE|J670H%abqv0A*PWBXsRSgYdJx`;O{%mo*f>mM zxGirQxr!N>)gU~L0^&^JoSbNQipWvm&60#$gj6;m;KFH3oUUH9Q98+)7m;dc1>v*q z`b&u8TsFHvy93r8Vnx1bIL&Iuwy#LTmbz%^ +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs 2.4\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-08-14 00:54+0200\n" +"Last-Translator: DuÅ¡an Živojnov \n" +"Language-Team: Serbian (sr) \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " +"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d садржи NUL знакове." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d не садржи име метода." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d не садржи име модула." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Датотека са подешавањима `%s' није пронађена: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Непознат тип операције %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "Не могу направити везу ка процесу за отворени GIOChannel: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Непозната врста посла %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Операција заустављена" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Не могу обрадити: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Остале грешке у обради ће бити игнорисане." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Нема грешке" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Датотека није пронађена" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Општа грешка" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Унутрашња грешка" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Нетачни параметри" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Операција није подржана" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "У/И грешка" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Подаци оштећени" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Формат није тачан" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Лоше руковање датотекама" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "Датотека је превиише велика" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Није остало слободног простора на уређају" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Датотечни систем само за читање" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "Нетачан URI" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Датотека није отворена" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Начин отварања није тачан" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Пристип није дозвољен" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "Превише отворених датотека" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Крај датотеке" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Није директоријум" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Операција у току" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Операција прекинута" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Датотека постоји" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Пронађене кружне везе" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Операција није дозвољена" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "Јесте директоријум" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Нема довољно меморије" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Домаћин није пронађен" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Име домаћина није тачно" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Домаћин нема адресу" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Пријава није успела" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Операција обустављена" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Заузет директоријум" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Директоријум није празан" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "Превише веза" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Датотечки систем само за читање" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Није на истом датотечком систему" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Име је превише велико" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Сервис није доступан" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Захтев застарева податке сервиса" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Гречка у протоколу" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "Не могу пронаћи главни читач" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "Није додељена уобичајена акција" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "Нема руковаоца за врсту адресе (URL-а)" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "Грешка при обради наредбе" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "Грешка при покретању наредбе" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Непозната грешка" + +# bug: plural-forms +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 бајт" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u бајтова" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (неисправан Уникод)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "Непознато GnomeVFSSeekPosition %d" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "Не могу пронаћи тачну датотеку са подешавањима у %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "Користи %s променљиву да назначиш друго место.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "Програми" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "Карте" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "Датотеке" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "Директоријуми" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "Помоћ" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "Рачунари" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "Везе" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "Пошта" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "Алати" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "Прозори" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Производња обичног Moniker-а" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "датотека MonikerExtender" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "обичан Гном ВФС moniker" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "обичан moniker датотеке" diff --git a/po/sr@Latn.gmo b/po/sr@Latn.gmo new file mode 100644 index 0000000000000000000000000000000000000000..2b382adabf92a8321b730e5e841abb47d6d715cc GIT binary patch literal 5575 zcmai$Ym8h~9l#F)J{BntMMXdk>e4MR+ud!8>$Y21`dqr*mbP0JW8#^)XJ*gLopXl! zn07aOF(%XmNF+iuF@`j1j32}h5;Y=3lie6J;gc~TiVuj1@rxgP1QRv>{`cOQ9V*6~ zJ^P#U{=d%uoZno3#Z!v!0m{vkZ@f*ZF1+hX{_*|p?Mht_e-GaQ{|fn2|E%hl)A%9k zS5>^D;v#$}?W<76KLoFa=i$5IBk&sdC3pw?I+QJ6hCARd;4Sdq@ICNm7TX4=-~_y< zs;@%nKL@XZkHYuEFT)SQ?^f+UgEIe@P~`Xn6gmC^3sv7$>i2edE$!Q&jJp+H0c%k9 znW=af%6bn%neQNfDpc)jP~`an6#G3{wSNoB`0qj4|3~mf_!5+TUWXrre}uCC)nlb! zZi0xaW}%EKM^(wp-z79qH%TZGLuY+QTaVYE0!Uebtak2U$d@uY8 z6#c$a)qe`Vf04fs{a6rzkduRj(=704T!4h28<-*HGCi34#l4P zq0Bo1_rW?8J)VZU;5VV@^9mIC{sF~a+X#|bsG;chDJXX7LecvXDCgoyDC<85`BN|R zPsaTgiX3l1k@p%F6?yK0GJg*gdmVtNpw2>(-$IcihGM7BLGj~PAt9rlgP2~u01LlB zOs8IjvfiI6{tHUHT}z{ky8+5NJD}{d0PliFp~#uT+u&nR)_Vrt4xfj2z}Fy4s;gN{ z#@`BM{M}IW`()LgL$SkSkU#Y`{)ryXLYepTs{J+iVd{Uccq2+{>ieMR{~7*?eG@45 zdICz^KMloy&qLY&Cs5>i9g5xm24%l(1fkR?;0#=V5?5K({&2;oDn0`*qhG#-66#n* zL{uj!Vi(bM7iIL@ONFp0zK`=?^xQ!ad&_q(WjEzc$|U75Wj}>fTznFj_gBBgXA&p! zNnDBT<-45nvEmmwvf_PEbQOD#eqxv76ixXEMZOc1LzIJ*qZEmG`NYOYD0frDKDfE~ z#C8%N@{Lo(hVo66P&K$n5g%eYwUe@)a)2W7EFZ2YzC9HmfO8b_pTw4Y5{r@#@1e|7 zujH{3$El`s z=QUjm#$LHk1U=z zz%Xy)IX#{-G>P~heABh^q*$+9>a*kNc74vIT2^X?+(+g3kjE$>ZO%u!Yf^O8^(352 zZNfT(-kwQPTg*6UGJ}nhB=2Pie$YjJdo|nW($1;PGUr=qxwFX-Y>a`4ZDb)?)Ac-E z8>!0Xw%g0r)FC7Y&0>~1lq9Gao7^{6S&JRJU93^Hi#Q{#I(FWw!(uXf-lbVu{vN8j zRTZ0+wJZc(cdeqr_z*`p875r>mYIbv>WK9=aSd%n9(B~lJ#{ps8LkmiY7<2XZY3{b~ILhMv_E3`@VITy#eZnbN9dZS6TEEyq-kh4qA-%q(kA>U<1{Iva^=*LP8+MXYh_5$XlzNs4gK=j9`4WYIQ0i6{jIxBRIS2goJ&Ub39^d+Nxl07~in5*kh{= z8}*XVDjYT1igl_e-f9(pu~^q-qU2V4nuT7EmXk@yLL&^kcFJ;AgOAtVB%-v|-lFxP z+!8vWo`x8&rkXP*2H8#;;8dy8Wwp@D^l_T0bNWwb#68Da9}nJjIGs(LAx1ibpEwh1 zrN_6bK@21oOQkJN)r#-y9La@q9QU z^mMjH`YD>yyw?i}W|B-)nqRG?#1CE@mk8{;B>1lNa+VS&$`D(Ggl)LyS`h)wCIL!+ z9Ln4`Ii^0rmSi7QxV%#N(D}@I&ZlZsr?JpPqY8mg7-iT~OdB-ftTsufwiwmUa)^lF zIZdc{ZLQx-^~~h%v6Cmx)DB2qrLRV6Bgf55P3@{p&DLi2=;>W^)3bL@(ZaymDWX@_ zxMbY)Zap4W*^MdS763$7p9KJ@jzhKc*m-`f|PO?sQ{ zA6qiMm7A8Wow24nr-_5QW6ngH?9lrN5~-DP$7DBiujh37d@>}h{bR=$k0097ZhCTR zjO>rOkOEK5>CB$bcJ^X!w7tb`Msl8CIdix+yERUv#Syhb&87)NS+A)A}AgrRQXjH0__C8T9U(-z`5U zijn)Kr}V=Qm$Mi%wS#HXOqyDAE#3LZr>qdvHPYU)rHV{54J6vFF4(bO`i=m9(S49czh^U zs3#^us$$YfY}0TWWiq>Q0eObQhReugpAQtw-$JCkxbPn|`MS-DG~eMQxOUzxZv8=} zG$kfkH(nh}Onb1TRYwvuEbQY@x06^>U|S5xB~^cOcPag_YiOt*w{2*@jwqZd^AXCh;`8CL=OuZ&7C8PsFR@^HZG`xp=&lS za2k>RrP(7oyud*m3ysg<3J!#!4fo+W1UqHk~QyNu;T z9=*b=qO1@B)w6>6_j4by`-nE`tX;Pf?QJ5glqM%*$LKH!FRMFAzWE|Yhd5@e1dCB8 zNK7R7Qe&%gt~rS-O%(CYBIt`phD(j-WQxuM0}t&R)N*;aA}eRh=seUN(igu?r-4Z5 zfZ?h=%1U|UxIg3+^^-KqOT$_{!BeDWc9g3U4kqUEi9 +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs 2.4\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-08-14 00:54+0200\n" +"Last-Translator: DuÅ¡an Živojnov \n" +"Language-Team: Serbian (sr) \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " +"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d sadrži NUL znakove." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d ne sadrži ime metoda." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d ne sadrži ime modula." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Datoteka sa podeÅ¡avanjima `%s' nije pronađena: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Nepoznat tip operacije %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "Ne mogu napraviti vezu ka procesu za otvoreni GIOChannel: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Nepoznata vrsta posla %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Operacija zaustavljena" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Ne mogu obraditi: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Ostale greÅ¡ke u obradi će biti ignorisane." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Nema greÅ¡ke" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Datoteka nije pronađena" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "OpÅ¡ta greÅ¡ka" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "UnutraÅ¡nja greÅ¡ka" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Netačni parametri" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Operacija nije podržana" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "U/I greÅ¡ka" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Podaci oÅ¡tećeni" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Format nije tačan" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "LoÅ¡e rukovanje datotekama" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "Datoteka je previiÅ¡e velika" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Nije ostalo slobodnog prostora na uređaju" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Datotečni sistem samo za čitanje" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "Netačan URI" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Datoteka nije otvorena" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Način otvaranja nije tačan" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Pristip nije dozvoljen" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "PreviÅ¡e otvorenih datoteka" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Kraj datoteke" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Nije direktorijum" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Operacija u toku" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Operacija prekinuta" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Datoteka postoji" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Pronađene kružne veze" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Operacija nije dozvoljena" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "Jeste direktorijum" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Nema dovoljno memorije" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Domaćin nije pronađen" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Ime domaćina nije tačno" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Domaćin nema adresu" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Prijava nije uspela" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Operacija obustavljena" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Zauzet direktorijum" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Direktorijum nije prazan" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "PreviÅ¡e veza" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Datotečki sistem samo za čitanje" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Nije na istom datotečkom sistemu" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Ime je previÅ¡e veliko" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Servis nije dostupan" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Zahtev zastareva podatke servisa" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Grečka u protokolu" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "Ne mogu pronaći glavni čitač" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "Nije dodeljena uobičajena akcija" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "Nema rukovaoca za vrstu adrese (URL-a)" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "GreÅ¡ka pri obradi naredbe" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "GreÅ¡ka pri pokretanju naredbe" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Nepoznata greÅ¡ka" + +# bug: plural-forms +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 bajt" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u bajtova" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (neispravan Unikod)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "Nepoznato GnomeVFSSeekPosition %d" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "Ne mogu pronaći tačnu datoteku sa podeÅ¡avanjima u %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "Koristi %s promenljivu da naznačiÅ¡ drugo mesto.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "Programi" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "Karte" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "Datoteke" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "Direktorijumi" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "Pomoć" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "Računari" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "Veze" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "PoÅ¡ta" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "Alati" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "Prozori" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Proizvodnja običnog Moniker-a" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "datoteka MonikerExtender" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "običan Gnom VFS moniker" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "običan moniker datoteke" diff --git a/po/sv.gmo b/po/sv.gmo new file mode 100644 index 0000000000000000000000000000000000000000..562c4719dd4f39249c492cca2ea95168a189c084 GIT binary patch literal 5339 zcmaKvU2I%O6@aItKh&j#l%E#b(rJsyPrHttv|yYjsgv4?u^p$e-AW)8?(Uu4z1h1n z+dFriSiDg{RDA$MTM#b@H7PIr2q8sk#Y?pyS|s`eREU37MTiHGpf5-W@twJ|_9iV{ zdG@>Wf99Ms=Uo5(#w(vzJP%QBrJR48QeAk@Rs8V$@oJ@Rgnxq9z&9X&>ff=xgT@b1 zzb& z*4t3}&%*2Alkg_^HTVJe{n-99DD!^>MUK~@$nj4Yj(Tl%zN_K8XukoE0(ce?C{o7E+Uxc#%kKp^^%TV@t4Sopz1zl=*wvRK_2QoQqtB;xFs)PUs__iT%$*@xvD(f9j>!{wkDx{{Sc8 z8&K?U7fRg=cS8+Vp^PgbqNpce4L$?k2Y(#-8^{vsA5hM51J_ZxTd-WW5~I7LYX%OMc$LK{wNeb`3#ix zpMs*l??92`#aRC(l=$)2*nTaYa^BmZ?7J7r`m<2(#iLO6eH@DZo`w9W=lPNSeh%ea ze}=N|-yp88u4i*ZS2shEV=q4<*Ae(J_z0By^%ckz^$jTY`yNCz^%BGl!!sMX7%AgV zQABQ$^#En`IY>oxBaiGQ=h{P&{pERpaxdj>ium9>ws@X=vc&}4q zGn1;>UN6rYNtrq8)zKu?&5W7t#HP7X#}aE@sT+k!N~3#O&*-KrwCfqGk1wnoW0*Dh zj2`z4EmD4+ZDy^05!S1g`t-QprOzf_%Suhxw`n!r^>Yp&ZJAAVH}RZR*9&*nn}T(Q zy}hLHCd_y+DHC*56#ZU_;16c0-4$miy3(^ZWtrKQuXavK1RG;uVH%|?Hg&!4H%F?n zx#{-GO*MxEt{G;jxuW2RdD6FyHfynCw~IDnyNEN=s`JbmH7_bN=Q3aV>V4~|+f~t7 zRV$s-^{f>tjCXm8kzvtAV3`@tqK+GDimaiH$fHh}yr)h$Ut$_jrB2ecz>HO!_`%53 zFm780sd}}rZzZm^U{SSA@~vug($foSAv!F_WJ&QpwcvH4)1eO4Qf50|ExA@^bu;1M zDHYcfouG@3*Tyz5GE?bUW`J6D1-=vY7Ea^!*(}d>-RP`k=}jlpNjZUNCU>@_PCDGP zne_8ga|duuop|pW8D5x5XQdNfDnBiPSFWF4(!S9)T_Zz$FKHN^n`Wt*o|=uUA?++U zau}%_>-w!WH>!(^gb|D{+eUj4DclCXiF0<viNq@ ziGoC9UfOc6)@{eSv&0JPy5`~e)m39Ur<~7%NypQz{>q-i(Pvy;cO)o`_qRs4o-Q{D zKcUI@dp%d6CW%Cq`qjF}f3VuPc;H4>INLQ=?oyG-VelZZDO){Z+OQF0ogwJd7Sh_oTp~PpM&s&T zQ`>0zu~RE+wPO-fX|EC1h;RERClAynr)&G~(^Cg#rl#+nq=kXC(|E4Tziiy(y?SzT zX8&Y0Zi(nwTPqUl^8^dc=wt1IXp|*ZpLQtbe$hqS`3E8=2x^DNmJ-|QCoNN3Gf8(w zubwq&=G*#yzwtnxO}L_Ucx-uLd2agzQxlV8M0ixfZdhYRm*!l#ua}dx4u*_H06w(7 zHeZ|G9w$QaK}{~IDHH4do~ z>M)-UK3{fRm+NIsCkgkoMetPfCQmxZEGa6NI8`PswTMMB6sUbC=_R@tTr6}cv2bva zOa7*$x`>yn#nGJV#m%g~bKKvl+k}cF6KBvuPd&{1 zl)&izeGjfHjM_e-uuyld9u;BB@n! zHTG45&lN;J-KngimJqxnOId8x3X1Gz-shVQ9F-uwO2%#_I@36a3>4dx#o&CiiH_%L zJ-!>%yxgIo9k|GOuo7)aS;q8TBz&Wiz=wwon#~6nY^!8zQ4JOjnS|wAqPv*RiQQ=! zQE9gt%T?jPIBR7gvU)9K^(3xEv?;yr5ZHq&8QUhKSvqn0k+X-oTrJMi=;U$_yCjUR zT>fgXI3hW|n}|COQ~c2S;x574QBBKir(?16MxA@h7u8mdrjf;3gA2INFd@Z(eUWXn zamyP-HuP~>cgXft6e(TD<+-@PYNyCHd}mX9ZbVo-zY;q-nI9RZjvCQ4;YO@MD3trJ zOZ=CsZ1^7|, 2000, 2001. +# Christian Rose , 2000, 2001, 2002, 2003. +# +# $Id$ +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-08-04 00:20+0200\n" +"Last-Translator: Christian Rose \n" +"Language-Team: Swedish \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d innehÃ¥ller NUL-tecken." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d innehÃ¥ller inget metodnamn." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d innehÃ¥ller inget modulnamn." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Konfigurationsfilen \"%s\" hittades inte: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Okänd operandtyp %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "Kan inte skapa rör till öppen GIOChannel: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Okänd jobbtyp %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Operationen stoppad" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Kunde inte tolka: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Fler tolkningsfel kommer att ignoreras." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Inget fel" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Filen kunde inte hittas" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Allmänt fel" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Internt fel" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Ogiltiga parametrar" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Operationen stöds inte" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "I/O-fel" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Korrupt data" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Ogiltigt format" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Felaktigt filhandtag" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "Filen är för stor" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Ingen plats kvar pÃ¥ enheten" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Filsystemet är skrivskyddat" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "Ogiltig URI" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Filen är inte öppen" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Ogiltigt öppningsläge" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Åtkomst nekad" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "För mÃ¥nga öppna filer" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Slut pÃ¥ filen" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Inte en katalog" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Operationen pÃ¥gÃ¥r" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Operationen avbruten" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Filen finns" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Slinga i länkar pÃ¥träffad" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Operationen är inte tillÃ¥ten" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "Är en katalog" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Inte tillräckligt med minne" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Värddatorn kunde inte hittas" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Värddatornamnet är inte giltigt" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Värddatorn har ingen adress" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Inloggning misslyckades" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Operationen avbröts" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Katalogen är upptagen" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Katalogen är inte tom" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "För mÃ¥nga länkar" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Skrivskyddat filsystem" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Inte pÃ¥ samma filsystem" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Namnet är för lÃ¥ngt" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Tjänsten är inte tillgänglig" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Begäran förÃ¥ldrar tjänstens data" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Protokollfel" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "Kunde inte hitta huvudbläddrare" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "Ingen standardÃ¥tgärd associerad" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "Ingen hanterare för URL-schema" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "Fel vid tolkning av kommandorad" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "Fel vid start av kommando" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Okänt fel" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 byte" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u byte" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f kB" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (ogiltig Unicode)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "Okänd GnomeVFSSeekPosition %d" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "Hittade ingen giltig inställningsfil vid %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "Använd miljövariabeln %s för att ange en annan plats.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "Program" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "Kort" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "Filer" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "Mappar" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "Hjälp" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "Värdar" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "Länkar" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "E-post" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "Verktyg" + +# Osäker. Är det operativsystemet eller fönster? +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "Fönster" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Standardmonikerfabrik" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "MonikerExtender-fil" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "allmän Gnome VFS-moniker" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "Allmän filmoniker" + +#~ msgid "%u byte" +#~ msgid_plural "%u bytes" +#~ msgstr[0] "%u byte" +#~ msgstr[1] "%u byte" + +#~ msgid "Name" +#~ msgstr "Namn" + +#~ msgid "parse error" +#~ msgstr "tolkningsfel" + +#~ msgid "Parse error" +#~ msgstr "Tolkningsfel" + +#~ msgid "0 bytes" +#~ msgstr "0 byte" + +#~ msgid "Application" +#~ msgstr "Program" + +#~ msgid "Card" +#~ msgstr "Kort" + +#~ msgid "File" +#~ msgstr "Fil" + +#~ msgid "Folder" +#~ msgstr "Mapp" + +#~ msgid "Host" +#~ msgstr "Värd" + +#~ msgid "Link" +#~ msgstr "Länk" + +#~ msgid "Tool" +#~ msgstr "Verktyg" + +#~ msgid "Window" +#~ msgstr "Fönster" + +#~ msgid "%u size" +#~ msgstr "%u storlek" diff --git a/po/tr.gmo b/po/tr.gmo new file mode 100644 index 0000000000000000000000000000000000000000..45fb584e93042feb3c88f6150330266a24e595e3 GIT binary patch literal 4596 zcma);NsL@a8Gs8&Aen?M1d_29 z?f+Kwzn5;g?peiigz`Shfj2630WM$1AJ3KRmAVCP!neQ?d^7w-tiJ&7qW-(ce?;EF zpc`mE1ZDgpe{Y2+;oITk@Lt%3_rR~f_ro8;cfl9o+u&c|ZurkwpG64iKLBrnCnHy& zjDG^kJ|5l-pMvjz&&2kxL7D%}$R9zO_iK0~d^y(t1ZDldL(%_wl#y|_Ls@qhyaOJ9 zcf-?A_AMbl^*R1-gU>+G_v`ST@Z0cCID#U_%aO0bcT>LsA%u59nSTJvyk#i+e>(Q( zkzatC_UB^#2k>_4zk)LUk5Kmc8~gygd8U!`ekkn=Q1m+uWnTjq;YD~W{5}*te;Mnq zz=Lm4>R++GA7fx5brRwtbvD*N1;wAAff83w#rjuc|M#Gbe;&&IKZCN*Z{Z&JD!d=w zjZxnNKM6&j)yRub`o9GEsqgS7cKRtqH1z@$yT26M{|ZH4Swwg%l(^UpW&8tB^gRm2 z4i})vH6NdPMGJY8zh3(jX8OnOkLmBsbNLU0}K)4emE*_zLoFX<6 zf9#aDH0R%i0#B43sQ;C#~@}^hsO<5+{61EMRXNAi!UCf$Rm0l3UAGy z_))GmO%a_%f5hK;#ExRS@$*JrB$h**K(U9|NY2xP6nQ>E5r6HYyqCf?s18!*DRPhO zrHH>jNRhi%o&%J7!<$kM!4Fe*Q{=oz42WIdM3MVNo<;f7yHmGjvNX}>UE1-9y+_T? z&3E;Q!wo;t;1tzzVK&hn?<$kJQlCD*tUIfwFrCU4<=kt#o!7aoR(+zK$?fZQ`=rk7 zxVzTvVP#7-AE*{P9b1+bEfT4_sNqH|NCm~I#T zVrdK38TSrMQQ9!$sHqGFDT;bfA?49Dal7JdqZ^}^wyILsE1R87g-A0DENrLp#Zb5F zayV6$&22uYhUyp+_->e`j*I5@Qd(AJ^S&eZq$;X6waRvQS{i7T8a^crC3bD zLoJos=wz(7TK2sZZx}R7sQ3Xk(pl>IrM9kvOPEB@DPQ1T>@D3v?owY&vrMfr1JkiOv)xML`^2uL9m{~~8d0Qfov(YV1Z<8|!U)D!t5%n? zc8I)kNI2x`jD%RuF_|(EZ85w$#&v8aI!)Tpb5QtRFz|FM8pgPpw2GZsEKe(mr%8KR z`N4pevxTpG$B%9PnB`n}mkqBGQCeHC)B4%k;&R_EeTGj;O;n3Pc5%vxV|A{n2EEK0 zo-u7s+PR7oXNp9h@-FRj9=e=&G13YK&y5>4UYk_C7)UHus`IYz{6$Wr^SOQe__=e| z_Rsn<4JUCn+39Zray6`XoS^5zSl^?3tC;5xKYMZE=BclkD5O zcYkZ|q1L{GdVc@H{Gt2y(!#*jV??a1a?QB;*8D-eZ+_w61I@T)?y1&FVO*IRJhPzB zrOr4#x{{mRk2bPeKg97d?$Lb6wprU>n(O%dk(p)VdbR1<)`~Uxf?lbMep;^ThZ=z^ zs*i@(IbZZ1nK`v|>exi7`MJF_T&!4$t#QnPuI#01&mbc+JQ%V9_uj+jSB|$1O~#3c z*u8a(1D;8UCb3DHC8@e#TsGR=-q49JhelU*WjbcGG1^p% zTbD97taRii6gmzzaTOk#`- zHL1lMRak-vsW6V1gG{APq!I+g!}f+LMw=|R-mE7PM>A*3xZu|U#rme$CKxhC)0V5n z0`!BE@UiHX$tt?H_1$&uQ{E)5Y{&NJ)FNLu!8-MN?bJ#6st}bIhrQ8eMJ0HH`Ho$( z5E{`<(ZCl%j^+5YCHcri$NEj2mV7qYJk?uQ*NG8swdht+Hv}#!_R~Q+<%-dj?TyUl zIvpT%5R>p9HrZMcNNCY(4G! z(H9d3tK-2rjXj&tCQ|rX$?Z@+IR8s}n;H_rda5pQRRu#zN}KACM7Ps^lzeUbnT`7} z39s-iyuHyUCJ5DV#>MGrQRTKD?;H+40lLPQQwR@6^AYV*-LEr3Xte3bc8xBtNq4(& WLg|MkP7gXwC%mb?W^T-R(*7SgYxv{< literal 0 HcmV?d00001 diff --git a/po/tr.po b/po/tr.po new file mode 100644 index 0000000..085dee9 --- /dev/null +++ b/po/tr.po @@ -0,0 +1,469 @@ +# Turkish translation of GnomeVFS. +# Copyright (C) 2002 Free Software Foundation, Inc. +# Sinan Imamoglu , 2002. +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs 1.9.3\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-01-15 21:59+0200\n" +"Last-Translator: Sinan Ä°mamoğlu \n" +"Language-Team: Turkish \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +# libgnomevfs/gnome-vfs-configuration.c:224 +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d NUL harfleri içeriyor." + +# libgnomevfs/gnome-vfs-configuration.c:241 +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d metod adı içermiyor." + +# libgnomevfs/gnome-vfs-configuration.c:270 +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d modül adı içermiyor." + +# libgnomevfs/gnome-vfs-configuration.c:323 +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Yapılandırma dosyası `%s' bulunamadı: %s" + +# libgnomevfs-pthread/gnome-vfs-job.c:712 +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Bilinmeyen op türü %u" + +# libgnomevfs-pthread/gnome-vfs-job.c:1000 +# libgnomevfs-pthread/gnome-vfs-job.c:1145 +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "Açık GIOChannel %s için boru yaratılamıyor" + +# libgnomevfs-pthread/gnome-vfs-job.c:1603 +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Bilinmeyen iş türü %u" + +# libgnomevfs-pthread/gnome-vfs-job.c:1639 +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "İşlem durduruldu" + +# libgnomevfs/gnome-vfs-parse-ls.c:654 +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "%s taranamadı" + +# libgnomevfs/gnome-vfs-parse-ls.c:656 +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Artık tarama hataları gözardı edilecek." + +# libgnomevfs/gnome-vfs-result.c:39 +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Hata yok" + +# libgnomevfs/gnome-vfs-result.c:40 +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Dosya bulunamadı" + +# libgnomevfs/gnome-vfs-result.c:41 +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Genel hata" + +# libgnomevfs/gnome-vfs-result.c:42 +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "İç hata" + +# libgnomevfs/gnome-vfs-result.c:43 +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Geçersiz parametreler" + +# libgnomevfs/gnome-vfs-result.c:44 +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Desteklenmeyen işlem" + +# libgnomevfs/gnome-vfs-result.c:45 +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "G/Ç hatası" + +# libgnomevfs/gnome-vfs-result.c:46 +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Veri bozulmuş" + +# libgnomevfs/gnome-vfs-result.c:47 +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Biçim geçersiz" + +# libgnomevfs/gnome-vfs-result.c:48 +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Yanlış dosya tutacağı" + +# libgnomevfs/gnome-vfs-result.c:49 +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "Dosya fazla büyük" + +# libgnomevfs/gnome-vfs-result.c:50 +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Aygıtta boş alan kalmadı" + +# libgnomevfs/gnome-vfs-result.c:51 +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Salt okunur dosya sistemi" + +# libgnomevfs/gnome-vfs-result.c:52 +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "Geçersiz URI" + +# libgnomevfs/gnome-vfs-result.c:53 +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Dosya açık değil" + +# libgnomevfs/gnome-vfs-result.c:54 +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Açış kipi geçersiz" + +# libgnomevfs/gnome-vfs-result.c:55 +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Erişim reddedildi" + +# libgnomevfs/gnome-vfs-result.c:56 +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "Fazla dosya açık" + +# libgnomevfs/gnome-vfs-result.c:57 +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Dosya sonu" + +# libgnomevfs/gnome-vfs-result.c:58 +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Dizin değil" + +# libgnomevfs/gnome-vfs-result.c:59 +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "İşlem sürüyor" + +# libgnomevfs/gnome-vfs-result.c:60 +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "İşlem durduruldu" + +# libgnomevfs/gnome-vfs-result.c:61 +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Dosya zaten var" + +# libgnomevfs/gnome-vfs-result.c:62 +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "İç içe bağlantılarla karşılaştım" + +# libgnomevfs/gnome-vfs-result.c:63 +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "İşleme izin verilmiyor" + +# libgnomevfs/gnome-vfs-result.c:64 +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "Bir dizindir" + +# libgnomevfs/gnome-vfs-result.c:65 +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Yetersiz bellek" + +# libgnomevfs/gnome-vfs-result.c:66 +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Sunucu bulunamadı" + +# libgnomevfs/gnome-vfs-result.c:67 +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Sunucu adı geçersiz" + +# libgnomevfs/gnome-vfs-result.c:68 +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Sunucunun adresi yok" + +# libgnomevfs/gnome-vfs-result.c:69 +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Giriş başarısız" + +# libgnomevfs/gnome-vfs-result.c:70 +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "İşlem iptal edildi" + +# libgnomevfs/gnome-vfs-result.c:71 +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Dizin meşgul" + +# libgnomevfs/gnome-vfs-result.c:72 +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Dizin boş değil" + +# libgnomevfs/gnome-vfs-result.c:73 +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "Çok fazla bağlantı" + +# libgnomevfs/gnome-vfs-result.c:74 +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Salt okunur dosya sistemi" + +# libgnomevfs/gnome-vfs-result.c:75 +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Aynı dosya sistemi üzerinde değiller" + +# libgnomevfs/gnome-vfs-result.c:76 +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Ad fazla uzun" + +# libgnomevfs/gnome-vfs-result.c:77 +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Bu hizmet yok" + +# libgnomevfs/gnome-vfs-result.c:78 +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Ä°stem hizmet verisinin yerine geçer" + +# libgnomevfs/gnome-vfs-result.c:39 +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Protokol hatası" + +# libgnomevfs/gnome-vfs-parse-ls.c:654 +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "Ana gezgin bulunamadı" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "" + +# libgnomevfs/gnome-vfs-result.c:141 +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Bilinmeyen hata" + +# libgnomevfs/gnome-vfs-utils.c:68 +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 bayt" + +# libgnomevfs/gnome-vfs-utils.c:70 +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u bayt" + +# libgnomevfs/gnome-vfs-utils.c:77 +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +# libgnomevfs/gnome-vfs-utils.c:81 +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +# libgnomevfs/gnome-vfs-utils.c:85 +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (geçersiz Unicode)" + +# modules/file-method.c:380 +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "Bilinmeyen GnomeVFSSeekPosition %d" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "%s konumunda geçerli bir ayar dosyası yok\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "Başka bir konum belirtmek için %s çevre değişkenini kullanın.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "" + +# libgnomevfs/gnome-vfs-result.c:61 +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +#, fuzzy +msgid "Files" +msgstr "Dosya zaten var" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Standart Moniker fabrikası" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "dosya MonikerExtender'ı" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "soysal Gnome VFS moniker'ı" + +# libgnomevfs/gnome-vfs-result.c:41 +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "soysal dosya moniker'ı" diff --git a/po/uk.gmo b/po/uk.gmo new file mode 100644 index 0000000000000000000000000000000000000000..e6d3fc44c48e90a3d46ddf40ec20e1cdbf02ea36 GIT binary patch literal 5830 zcmb`KTZ|ob9mfX+#ZoWe4HWSYxVBu*cDHPyE>J0@EepLMZ85wMX3v?k9eU2pab`}- zc_1kiN`VGKsU^zAyV01K?Y5=6+wHCoyqFj=6MQiwhDR{*Ngu>u^z;4C|D3(BCO$an z?Dza{zsvV``A`3R*@fTtcsB7~$vgBh&wCKub|HUw#xL@`%fOT1C&4$tPk?`Lp3CfOl9sV8sBIAoOLU!OI!vp!UBHO3y#QuY)UBly=?-YJM1$e>*_w^}&tc z0q_gp6evI6a^v^FYcKG;e}QY6zZxki)&;YUUGA`(APQ7AQV0fGk9Kmx5P= zSAybk19%r$1@8fW1#SWV1`dJ4I3@mKa3}a2sJwXx)cFrU@pctT&VVcY>R@%u<1*^O>tBY$J&XXg>h60dAKiKWe)hM zk&JrWj%sdayMeWu3!|E8`YDc?(Ih^Q1_^Syt1UlC1AF2wKl33ZN!qOpEAI+x(JFV^ zHzlcQkY!;smX@0R43k!{F$t~sP~BIt?yMsMh{=>8FJ#AOsrAx!DvjikmmwXWaZwss2!YG4{c zJu}3<7VHnJ0UNSKrf3{QaeHhp3ELznb_e^jy@5$3+h$(cAsw3DPNi6rGFd#dgw+1>p} zJZko-0Q=g#9dXNK9g5serR`QLP9RA2UJ~!^Nl5|X)u;T~A0~0s3?e0d63PwIgJcM* zVZCExU$2v1tT*DS?F;=YJR4-^8jaWh1Nk2SvxRrQ)OU%W$ijMc+>FU`WptAVPoZf za#iOS?HjDDy~PX+4X?eqQd!5oZFH#0?!=GMhEGg}&4cYE?3i60vcxyHbr{`&o9ORP z;{8$F-}X0fC>m?~V?kwi;5UcOo_z`3JoF=TTYKLfjj%sX#x|_jKC*rDybFW<11o5w zaDqC*Fl@5m(QHkt!O2_g9YB}6y`9x7>*x2$ELg5=rkrb(@32`v8fGiJ)%p4SOg>i} z%*XSId@?^*9A#!QpECJbevIeSCjV`IzBrLj=d=0g;*h(K@|W_HIMNZ{&2v=&_G$;-t zbix#e?5$1SNwIY@KUD@0W{MY>MB9>8LTZp!#`g`I&{J$eAS@=Is{G14?TX~Q3{jDdo8qbRtdiM@ zfn%AljGroro?4S1TazF2@?(~yClsLKh+^;&^Ilu*kJ-a_iLD%Gk#c59ux0ZvWdr`r z2inVjj6=t5;kts5I%{kFD$3;Jd^r_|p=%ljPZUp=2b2(MP3PEmUUqx=Vc?zjE>~aa;FaNp}+ruvGr)^OXOD}&BR?aTuYBryC zg+ecZN|~l6g@;P1GWeuU*CauA!Gx-}hF;kk~s|aL6_3Nls zc)q(w$_S_UT)Iaz*chrUQkBR#Dt4CcLze4li0?I^kLa^Wqj0DW)DxFgiZJ!LITZKI zT2cjN66l^%$F{eED|m*s#1=3Gx2RHdNuTmIK*7_@=qf6$wW;`j5TUMt;p!+{a5h$x zwvEbwrxaWTKs898vr|~4RA<%8e=@)7D$J#irNcEQS$Ps6DlM|cCKm#9iyS1;oK#(q z3GhT&9j+vFLsJlCTU=C>s$-SWavPO|y_72baT(fGV0$Qg%1WO4ub;l%PUN0_$9dv;OEzif9ePRnjDo0D^7govG4oa@Id z*X7qmNjG0NWwS18huY|d)>b?QP8QD)9lpmgRo@>>5ia}HV;dh=of;oZ+3yNn^Ji_B zdBzq6p7BxMZ2;Z>ee^!etsDaA8kGHfToiG$b;r)_oAt@=Ewi^P7o{q1zC9Nm_WlDO CAG`Db literal 0 HcmV?d00001 diff --git a/po/uk.po b/po/uk.po new file mode 100644 index 0000000..1fe277b --- /dev/null +++ b/po/uk.po @@ -0,0 +1,407 @@ +# Ukrainian translation of gnome-vfs. +# Copyright (C) 1999 Free Software Foundation, Inc. +# Yuri Syrota , 1999. +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-01-27 04:26--500\n" +"Last-Translator: Yuriy Syrota \n" +"Language-Team: Ukrainian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d містить символи NUL." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d не містить назви методу." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d не містить назви модулю." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Не знайдено конфігураційного файлу \"%s\": %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Невідомий тип операції %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "Неможливо створити канал для GIOChannel: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Невідомий тип завдання %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Операцію зупинено" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Не вдалось проаналізувати: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Інші помилки аналізу буде проігноровано." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Без помилок" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Файл не знайдено" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Загальна помилка" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Внутрішня помилка" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Невірні параметри" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Операція не підтримується" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "Помилка В/В" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Дані зіпсовано" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Формат невірний" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "Поганий номер файлу" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "Файл надто великий" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Не лишилося вільно місця на пристрої" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Файлова система лише для зчитування" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "Невірний URI" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Файл не відкрито" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Невірний режим відкриття" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Доступ заборонено" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "Надто багато відкритих файлів" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Кінець файлу" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Не каталог" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Операція виконується" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Операцію перервано" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Файл існує" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Знайдено циклічне посилання" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Операцію не дозволено" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "Це каталог" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Недостатньо пам'яті" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Хосту не знайдено" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Невірна назва хосту" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Хост не має адреси" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Реєстрація не вдалась" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Операцію відмінено" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Каталог зайнято" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Каталог не порожній" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "Надто багато посилань" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Файлова система лише для зчитування" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Не на тій самій файловій системі" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Назва надто довга" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Сервіс не доступний" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Запит застирілих сервісних даних" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Помилка протоколу" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "Не вдалось знайти головний переглядач" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Невідома помилка" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 байт" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u байтів" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f Кб" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f Мб" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f Гб" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr "(неправильний знак Юнікоду)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "Невідомий GnomeVFSSeekPosition %d" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "Не знайдено правильно файлу параметрів у %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "Використайте змінну середовища %s для вказання іншого розміщення.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +#, fuzzy +msgid "Files" +msgstr "Файл існує" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Фабрика стандартних монікерів" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "файл MonikerExtender" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "загальний монікер GNOME VFS" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "загальний файловий монікер" diff --git a/po/vi.gmo b/po/vi.gmo new file mode 100644 index 0000000000000000000000000000000000000000..8f852c7f0210076b5fd273b89902558d5216f0eb GIT binary patch literal 5707 zcma);TZ|oL9l$^2qAY@fHx#g+%Gz={+uhdEbt#v2yKRr%OS|30+Y57M=A1L#IWwno z+3tx?qzOnG0}T*tkl1x?N`VbjQNkVwF{jqx123Y+M2$yc^aXv8s1L^Y`_FvmQmB{7 ze)~J${ePeN?KPJ?rg-+#uBUzXJxbN!t(WqT=XaMWbq#F8_rkX!f9jv6e=&ofq<@9s z&4xwzKE|t1)*pgb!X@~Act89Ad<5PMSD;+^I=l(K0dIi+f**p{bJ$gI7;b=fnSK?@ z{9$+nJPJPsABUfS&zbR`LfQWdD02J(iX4B1nW~rP`dtP;$oN%I)~$n=zyg$eHW}`M za^6>;YaBI%J45x_FsySvhM~c`fP-Z^IFI z2_4bnHYojVa1aJi?tc`D9%tY-cou#XUPRD{U9N=;sS&8*b}0E#f+F92P|o=l6n$SZ zd>!I)^(MqM>MbaC{0GF8>RN;r-Uwy?Fcd#eLGhypC4TOMa?bsbt?FSY_Fjgv{zZtY z>Ss{S`#lu7{tQLV%TZ4DZ-ATNCMfG&xEUr;&V355hc7{i*ESUWFT>d)&pJ2+x57`u zG8Df)2qmvqpvd(jD0=?V^#2YKMO}$;J_FYoj>9eVD^TQo63RULpKpQlN@NQ}z)^4v}P9PJjG*lZW=P8y{+dnC@jV1A2_r4Gm=e!DsQMV`T} z=J&AS4k)^azxtm~(Gi_BO>8XB3~hq8leUK@K9NUky_mvNfJlRUU8d$t(vhhwx$X`eM?lC$EcyJ&aNBzC50;wyaH$_kq+x_pm!H%##t7){+J$& zSsFR~4}-E-Nu%t%{HS{eB-E9HxPjuMbln1!T+%99^?wbk(IOJRG|b=X7T4 zRusG0j-6IwVWTKY>j{GI^qgS5*=_0E&as;$UQmhio2>-F23Q!mb`nMnT}tCdUso=7 zYxSg|CXgU3XS>uy6rrMTrGZ`LEN-mTu!b2Iar#EJ?**>fB_?y1yf}&T-(6LEU9nl- zOTti>yh_$#eds$l8Ade(mYta{YPTD>k!NdH-e1nhYympvxAD zJ9NUj*aTZF#M%vPoXl2crdXh+!id;0cFVMh^7ikc1y z&$5;Ji6#dKO>M<-XnRDVBa^vJ_>sqHlttzI?4*wEs#|kqNnE#VSNm=`(QJ3zMbDOT z4(wA#`fd=Wl`0ukBSf+ltWT=0jzy#_8{!7RSyM9-_BHaj&(w^WV7INnc73r&ZwwpN zqp*@Ws(%#gm?-XzioZCl<|U$JZ#+)IdYzGdQJ92w*zww|ORk22-#AZ187*93^ib*& zI$Qh%#YQ4un>fYsTDz3bMM)8;DGBc>;hYgK2j~ zSl3B|@{Ai^8Dh29isWC(008goJB*j`ckgvj>VZ(*yfv<_hCdTbVCV-l%h%hKDy7hDQsVw&;<~V{_s*M>B74^1E%0;i>Q_b#{fALTprjhMZ_$zL{cd9rw(bH>WXn26SkD<65 zAC2k6T}n3AecolaXYVn}@*VSYy9%Sdbs{4!C`?c-9E!)79xZvvz^p5dElkA~&nfIk zD{)~i9Mc25O3f=&FH~DEP;08~=1N`r?dAjj>!r%d)0SRny`qzL^NhS(J8w*Ll%20g zT2GU$)pO6ETju;k2JQc{k~+XEmIe9SwexZvZ?B!K=_E=UdMV|1qT0=;IL~P}Pg2-+ z^8U0e_A*bMv2|7CqR_X#$3YSoXp=AKQ{(*Uxvs^|9&4>|aPtw=#R)yXT*$tv zx6eicOH}xF-{7INwJZ`mfhwIF`jk>Txd9pT2zz%t8>#JTipq1SzM?B$Yt6jKd6X|AT=AfqljyC=_kmf#s7a8nllqjAm1?TB+%UKCabSLx?g+tK(I^738o5ahp2(@Yy419T2P%rV_J>I2>c|tG1T;uE`zf_x9*T zab|8hqA*a?vgW>2jEm#@{aPhy5o+xfiRz>B?;(9CwT5!LWFB!^C%S&EwAY>s^ddg; z$deP~i5T-Z^3~dFFG@Ia3Zp^mMA$K(m^{0S*S@ciy?FxIXpwp8 zaqOB|7d0f3Mbyq=bqum1!Q3^T*)5`+lBLJRcFiX`8xT$EjGSk;UP5vvAIO4A$_G)L z7XvlU!LR1(Wr2EOkA|fAvYi``gHG|Sj0rKlWoGgOm6+}3THmZ_q64vN(l=`2 z&l8NcIP7%2Z$8U93ga_4IZxG!C--s5X`5`nkUn|1XZn2O|6B9r*3+q!#8ash;cfx5 z(UMO=1h=aa2`5cd$?Z>iBx!HL=s|e>fFL7WDtyzP_eF$M6#LVG+Ap~ubi%Y3%I8mX zy@MXcHdzfB&t7dvcCzE;QXVP)>H8_Snoky~y`;tw6wQuUlw7jWXl+@(n9N+#^=4, 2002. +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs VERSION\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-07-03 20:15+0700\n" +"Last-Translator: pclouds \n" +"Language-Team: GnomeVI \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Report-Msgid-Bugs-To: \n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d chứa ký tá»± NUL." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d không chứa tên phÆ°Æ¡ng thức." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d không chứa tên module." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Không tìm thấy tập tin cấu hình `%s': %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Kiểu thao tác lạ %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "Không thể tạo ống dẫn cho GIOChannel: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Kiểu công việc lạ %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "Thao tác đã dừng" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Không thể phân tích: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Nhiều lỗi phân tích hÆ¡n sẽ bị bỏ qua." + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Không có lỗi" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "Không tìm thấy tập tin" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Lỗi chung" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Lỗi bên trong" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Tham số không hợp lệ" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "Thao tác không được hỗ trợ" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "Lỗi I/O" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Dữ liệu hỏng" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Dạng thức không hợp lệ" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "File handle sai" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "Tập tin quá lớn" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "Không còn chỗ trên thiết bị" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Hệ thống tập tin chỉ đọc" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "URI không hợp lệ" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Tập tin chÆ°a mở" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Chế độ mở không hợp lệ" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Cấm truy xuất" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "Quá nhiều tập tin được mở" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Hết tập tin" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Không phải thÆ° mục" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Thao tác đang thá»±c hiện" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "Thao tác bị ngắt" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Tập tin đã tồn tại" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Phát hiện liên kết vòng" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "Thao tác không được phép" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "là thÆ° mục" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "Không đủ bộ nhớ" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Không tìm thấy host" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Tên host không hợp lệ" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Host không có địa chỉ" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "Đăng nhập thất bại" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "Thao tác bị hủy bỏ" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "ThÆ° mục đang bận" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "ThÆ° mục không rỗng" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "Quá nhiều liên kết" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "Hệ thống tập tin chỉ đọc" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Không nàm trên cùng hệ thống tập tin" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Tên quá dài" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Dịch vụ không sẵn sàng" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Yêu cầu dữ liệu của dịch vụ lỗi thời" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Lỗi giao thức" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "Không thể tìm bộ duyệt chính" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "Không gắn với hành động mặc định nào" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "Không có bộ xá»­ lý cho URL scheme" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "Lỗi phân tích dòng lệnh" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "Lỗi thá»±c hiện dòng lệnh" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Lỗi lạ" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 byte" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u byte" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (Unicode không hợp lệ)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "Không biết GnomeVFSSeekPosition %d" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "Không thể tìm tập tin thông số hợp lệ tại %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "Hãy dùng biến môi trười %s để xác định một vị trí khác.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "Ứng dụng" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "Thẻ" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "Tập tin" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "ThÆ° mục" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "Trợ giúp" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "Máy" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "Liên kết" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "ThÆ° tín" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "Công cụ" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "Cá»­a sổ" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "Moniker factory chuẩn" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "MonikerExtender tập tin" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "moniker Gnome VFS chung" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "moniker tập tin chung" diff --git a/po/wa.gmo b/po/wa.gmo new file mode 100644 index 0000000000000000000000000000000000000000..ba368f5c3a25137bd2bbd93c18f63be928e1ab9c GIT binary patch literal 5254 zcmai$U5p)79l($Bp)Mc@@}YN~Nxc5&Q(KAV2j~Xnz}ik@j~3 zUkQ8*evXqm z3*r6W;Z^is#ilpIo1wIKLYemHxrvj5kh>}McT)hfIWIw<3wg<^v5LD~NYfoGwt z_Xd>t@4!#NcSHYsQ1<;R6ubQ+^k2;&8GkF3{cne#gX2*4IRfv5^HBCLq4?t&$P(%$ zD0=+_irsz#KLg)^x5D?K$oa3p>qeBik@lT|Q&8qFK$*7;MUT_r{quo8f|~wcg!Uhy zjQb0e_5TS)k84r#OYlZ0^6r81{s0ucPeR#$1x~|fpxF65ocfqjZ$pvi3MNbcZGoeK zEqE{ed*CQ+L$S|u5Ea$Wq0IXw{49JU^uG(muJ6Hp@B=9EcRxxz1ouH%=UY(5y$r?g zzk)LUw~#4n1S3oTEl}*egTHb302F&KL(%tHDEj^o-U81;@zJetamlSiJk9-Vz+51`hPvNZD>Ca`Kg!q z+X-I{d>@Mau49tO{|FTQPeR$hf}+QZP~`hD z!piI1f^tcmiVhNo2f4*Q;)B7pD?Ho|k8tbI{xY29zB{xDRexbppL;})-P{tF5?haO zi)<1%liXrQxkS#-bBmp)xJj*Ew*ycvv5#Draf?m&NP}xHx9D`aG`RLR@c$FxSz>i? zJaVW`N(^IC^&q#zpCQ;Kxk)?4|r8akJf0XD>%FN{`PcowpM0sv29hWAmj4sl`=#DM5EljQt&mKF# zu-s%*dekwrO!&8XC+*gyU$0r}$x%0^*CVH8rH-xhq#1AP3UP@o z4aVCn!IQA;A(hPZ0;|I&H)R@YBb%xtCM(nt>niLo_R>+3l=!OY6K8Lm>c?%#AWf%c zcODCC&F0uMkFsGiMB?#TH5;N5)3T(5n3{Du(#gP3YA(%Jotm@VG}oO7#S8th-EUHchyl#40fVAt2BX5 z{OQO!8>fU?A}<@8@ZgFlHaat%N;4=iYiVp4z_e{5OWWkO?k;mUdU)H9V0^V~w3Cf} zV7m?Ctf!7i1ot?S+YCxyh}$^IW0Q&2TYXrfC~eofV|y<)2m!g(D_&u-URsGNTm7!G zMM2L(X)7Dsfp3l*j-Ac3jf+H--qt00zgZgs#I~Ky@SW2f7cs~fCz=DI7MrHmD_X-f zQJaIjgwcuOjmCXjO)GW~!#L^7oH~)O=60Rao!g#y;?UxvF{=yKrQScI$?$#SoWbZ7 z+t#acj7RI?2wUiCgM{I`TwN5l#2S)28Y`<4j$pt!qY_SQX=(GG$>m^_smM&A;CU0L zoel5kPKRjYeP)|%H9n$FvL*RK?76}bZ_OsHCx~W3X-X4wJ=0q2I6XN&IkIqUsdYfI z81Gsn5;DrJiHY5KsC)zqf`YjP6$XYwX34GWbGg(`3! z`bx#YBl6-tyWw%VZwe_WzCYm5f2P zwp2q>++_10Wvu@*vZP2Yhs{*BmPqJIQgdp)zex-gB!t{-7!n0xUd7A(bL!wqs&fR0 zNDFJo)9Iff01egQv`o-RY1dMnF@ijRG9NB<{Y@#RbHfF_Hc^2`(#Rw$MxQ@B>dwC& z_VDt#s((&btlK}+l(Ha#i&EcBrv`B6dg;su7`5UAYvj*SCGD`ou%!yMfoJ} zzp{ZaTPpeOnw_@k{9zGsn0%K|&wPbEo+c5_v2k7WI9!U4akLt^5@4h`7<&gw^% zvsLS~B;edH<*jEW_|0}pneJ)or^rkIB`c8%K54wzh)v1#ero!>GlpG7f3p;W6*}v0 zV(P&Q7lf7%5d1w1<^JZHQPZVeWxo|)YFBBCwp0*2nAv2-GTcW)PC}*PN{06@B~GPO z4TnhHZLAWpJuAhGjMG|j^ixyl66*+`8 zPLh4lYE1j2pX<`Qik&yulqf`UBO*4D7wHZ$R8e%xb&7-9Z!l#Ch5F|ln)o>q7LBk@ z&Ge`b60>TKb&2<*Lsd7bz1E1%`!{cCfOIYoF+evtY#?w4o4ssIwvb>u8xYuStwXz zFwIXgnS21OQ!M0r!klgfQ!RBbrNU@O1p0@qlpxtcG9Wz?Z;jR$IYw%Df71((8!h33 z;L~g5ho7=4qOz-0wq}ek`C&NGvnsaQ-shJNIcxo*H^b2(XjA#<@ZSnXT}p7hid8TK zc@F28I`h(G{WGOei+adNY@p70(*`zT)vC6kWg@v8^FP|aJo^ftZ5rE;Wd80O6*mSY~8UetH zZCjIVC?A)4Pa?VaP5lu!Ia}DY^f^n-6r#sDKBD|rikwX!qQ*NX(gsFM;BzFQcI XZ;Zt7AWl+>aGLY&vQU?~iJbZm{mHA= literal 0 HcmV?d00001 diff --git a/po/wa.po b/po/wa.po new file mode 100644 index 0000000..e26d9f4 --- /dev/null +++ b/po/wa.po @@ -0,0 +1,408 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2001 Free Software Foundation, Inc. +# Pablo Saratxaga , 2001,2002,2003. +# Pablo Saratxaga , 2003. +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs 1.1\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-07-12 03:44+0200\n" +"Last-Translator: Pablo Saratxaga \n" +"Language-Team: Walon \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d a des caracteres vudes (NUL) Ã¥ dvins." + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d ni contént nou no d' metôde." + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d ni contént nou no d' module." + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "Li fitchî d' apontiaedje «%s» n' a nén stî trové: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "Sôre op %u nén cnoxhou" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "Dji n' a savou fé ene buze po drovi l' canÃ¥ GIOChannel: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "Sôre di bouye %u nén cnoxhowe" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "OperÃ¥cion djokêye" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "Dji n' sai analijhî: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "Les arokes d' analijhaedje ki shuront sront passêyes houte" + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "Nole aroke" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "fitchî nén trové" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "Aroke djenerike" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "Divintrinne aroke" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "Parametes nén valÃ¥ves" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "OperÃ¥cion nén sopoirtêye" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "Aroke d' I/R" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "Crombès dnêyes" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "Cogne nén valÃ¥ve" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "MÃ¥le pougneye di fitchî" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "Fitchî pÃ¥r trop lÃ¥dje" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "I gn a pupont d' plaece so l' éndjin" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "Sistinme di fitchîs k' on pout seulmint lére" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "HÃ¥rdêye nén valÃ¥ve" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "Fitchî nén drovi" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "Môde di drovaedje nén valÃ¥ve" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "Accès nén permetou" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "I gn a pÃ¥r trop di fitchîs di drovîs" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "Fén do fitchî" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "Nén on ridant" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "Avançmint del operÃ¥cion" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "OperÃ¥cion djokêye" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "Li fitchî egzistêye dedja" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "Betchfessîs loyéns di trovés" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "OperÃ¥cion nén permetowe" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "C' est on ridant" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "I gn a pont del memwere assez" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "Lodjoe nén trové" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "Li no do lodjoe n' est nén valÃ¥ve" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "Li lodjoe n' a nole adresse" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "L' elodjaedje a fwait berwete" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "OperÃ¥cion rinonceye" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "Ridant ocupé" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "Ridant nén vude" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "I gn a pÃ¥r trop d' loyéns" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "sistinme di fitchîs k' on pout seulmint lére" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "Nén sol minme sistinme di fitchîs" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "Li no est pÃ¥r trop long" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "Siervice nén disponibe" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "Li dmande rind obsolete les dnêyes do sierveu" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "Aroke di protocole" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "Dji n' sai trover on mwaisse foyteu" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "Nole prémetowe accion d' associeye" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "Åk n' a nén stî tot-z enondant l' comande" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "Aroke nén cnoxhowe" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 octet" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u octets" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f Ko" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f Mo" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f Go" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (unicôde nén valide)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "GnomeVFSSeekPosition %d nén cnoxhou" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "Dji n' a nén trové di fitchî d' apontiaedjes valide e %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "" +"Eployî li variÃ¥ve d' evironmint %s po specifyî on eplaeçmint diferin.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "Programes" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "CÃ¥tes" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "Fitchîs" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "Ridants" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "Aidance" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "Lodjoes" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "Loyéns" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "Emilaedje" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "Usteyes" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "Purneas" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "" diff --git a/po/yi.gmo b/po/yi.gmo new file mode 100644 index 0000000000000000000000000000000000000000..8a5e8ee7b0a27e14428ea87ccc46192a4fa0369e GIT binary patch literal 6110 zcmbW4TWlOx8ONukh2oZ5TWHIzhl@#X>&8tAse8+%NnW5ZB@PPUh-=es26UQyJ!vnaHP|K|qsE>$pkvyu9P#+KiB#=;f00fBN|IFF-+FnbD zk!SyV&iT&yzVH8C&ic34UNPhG?BV?+@Ak_*?+Nh06@2h4U+H<*g0Fz@1K$MS3;xWF ze+_<`@oyad)8S1BUB&zkQ1ZL@_yD*c{1EsUcpEqZ-U?2Dp8|gfUI)Gneh~aKcnkP1 zH}1sC_M>y4fqWBVemOOe-_mKiw=JbYTqxx_k-`a@t;7Q{|`|9 zUx_o4yAjm6Tfm#Z?cnFZL!k6#Ab;N1__zUl4wSzO;77nq;3vR0LD}(+!@q$aWqcJz z2tN&K|8`LO4uI1C6}Mh@_;t`QKkLRn0B>ac3sCZZ1f}Qi;LYGQJ*Ay@fSMlw<=-Jt zdVO#gcoMuG{5~i@f9}SA(D*XX`!{$S^EW`oXTaT{{0!VU2k&Kk8r%u~%Heg8B)vnR z;xYz)790n4&K&q8_&PWM-i#A_!7qb-;5_&_@GbBW@LjMMd=TY2Cj@owH$m|{3mWiy z;K#ug@MGX#!G7>6gq3##p!7Ws%I+yp`rZO>2mb>~?lyvls;GX-t~m%*Lj z@4&~wUdYw@v!L{z1$Tm%K-JB=4zGoj9gO?ITfwKm3OEhQ-=Dhi@4-75Ur%sk=Ppow zKLg$k&O2NIA7p$DLHz=F0F-iqAz`M1HXjAfko?*}zL3f>2P1C+j>fK~7>p!hgK za?1Z_9exMAj4?FXN4`-y-UGa{LppWNHeSU=zI8tLGx#DeWo{qo*utxrw4N{Vg>ZYj zTN529TNE$S#?~J+S)Ku#-{Q9QPzs*fo8cu5EPsTn{V3m+Q?2K6z9{yjymt>Tl-U|n zJ&992;uy-kyLgo!v_Tt>e(-8uaY_kTj`x6iw)3in^oVQ4`4(Q~3pCsMe-EhsqGy*r z%q>xT!mmYvITlCNBnWTydi(lE%)`4&e58bf46}jWz*Lhs_oFy7hmIXE)iFQyt9h7a zee0Lw#MHxlED22P*Tb&MNzkl?t>vZ}9?!$f>$m9bs#e1+GeH* zJS)Gq?Oq+q^>UOai5ZSYy?seqN1tS^Dc-|j9Hvp#glU?j-u@)Zp;IInKL}FTF6R`k zj$Kx6RpH>Bhur~#G4#ZKtvz&EbY##QbQuLx9H#W}1~cQEpyjuBAQ_E_hL2|fgQNjR zrWVD=GZV&DLc%6i4kjt#g>NleyEAh#s@2SJXrj@W)u7KiB!lI3Es00HLy0qpFImH{ zhNc#d;fbgkB9N~!MdL6|nxkVRY@MK33FPy!&}2H>W?nW|@i8)-6X3GST5Lzg$Jv*MY<>QSzITAk1Gq|spJ(KN}EYSQBTNJw2I zacz8!iJGl+nf+=rB;?6(mehzzX2@z0vV|%mkG-Si(E8<{ATs_im3B0z;`}r)2a`BD zPCblJ?;>dk!s~uKUPf(on1~=TmU+kG<8gA5ij0$b_}IRqN5k;=qe&LoO6(2V>t#Z= zq@PNL&2bfAZ?i3tG)z8Dk=v=P*=Qsw1gYLj;=N-TDL}k>l|LtPkBti(?vxj}l6 z3}H1I8Mm`PeefwWnt7W-oq_ZoGNCDbH!Y-P%IV~idjAviX~&G=k4&+%4@}xyM2mD zrY4J1E3dA+uFv9ZaRzzqe!jer*gwmdO>TUSwM}=}s|#JT#c5NVUHK8V%oTH{n73c7 zF{Zd!EFtjH${Xlknu`(>f0N*G+j?Jc9x90Q;PoQy8#>r>_(f#TgF=MWCh9SU!mXx~7?&XFTV%_DwRQ z_%JJ4q+GP%rt@}*MS`bEEh>%x>+(Uf+PhG^VAkEn*2nTa)HE=``Ea@E>2!nT6v!y?6f4jHKWBj_>jM}oOmaNvY8!72+C~Vuq8bzQKbNN-WURpel9r9eQm;6_X z&+z4}4M{5v=ahbsj4zAG+hkjtrW4jJ?Io%ru`Jn+%8&=MB)!aYtyfHmcV&R9K=^ZH z=!j*c(QU|F%dW9!OxjJ#Czr@N!^O^&2`Qg+_M|miC%98x5Zlw*NNul)t-6OSW!EXv z`bBZ#(oSWpEz|A#cd565;f`EU2~WxgT|r9x)$XzO{L|K5OHpZX*{OAJs%+`3UiUO8 z+o6(A6~={HEFj4jnI*!-#>*T-YiUg@N-{#cP&!+)2+Uz)}Snw4x4Ec7^yy`K2Vm+g*6w;hV^!Gc3h5X_3~CpUS3K|in>jI zrWQy9c{y8L#OGESPhfz(CiJU8ll+$IG;>1{m%lICl4X$GHQ&zA)n;2-F8XB_4sZHT zfJ@_z8&*SBw!(E1N?#GG8aV?6vPh)zFGBYtwV_KHK+3w!-K5&YE3Yr2aF!w>;l%5= z%C7K&{SC8vyDvKfXDyOIr2+G5OVr}B?PI5HYrzq97#Bj4qZGv*{xLyW`4dSSHw093 evdOjz&z`a74lQ}N|GI44-%Y-y4qi6s^ZpB5yp^{A literal 0 HcmV?d00001 diff --git a/po/yi.po b/po/yi.po new file mode 100644 index 0000000..1cbbe99 --- /dev/null +++ b/po/yi.po @@ -0,0 +1,407 @@ +# Yiddish version +# Copyright (C) 2003 Free Software Foundation, Inc. +# Raphael Finkel , 2003. +# +msgid "" +msgstr "" +"Project-Id-Version: 1.0\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-03-19\n" +"Last-Translator: Raphael Finkel \n" +"Language-Team: Yiddish \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d איז כּולל נוליקע שריפֿטצײכנס" + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d איז ניט כּולל קײן מעטאָד־נאָמען" + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d איז ניט כּולל קײן מאָדול־נאָמען" + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "צופּאַס־טעקע %s איז ניט בנימצה: %s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "אומבאַקאַנט אָפּעראַציע־סאָרט %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "ניט געקענט שאַפֿן קײן רער פֿאַר אַן אָפֿענעם GIOChannel: %s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "אומבאַקאַנט אַרבעטסאָרט %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "אָפּעראַציע האָט זיך אױפֿגעהערט" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "ניט געקענט אַנאַליזירן: %s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "איבעריקע אַנאַליזיר־טעותן װעלן זײַן איגנאָרירט" + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "קײן טעות ניט" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "טעקע ניט געפֿונען" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "אַלגעמײנער טעות" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "אינערלעכער טעות" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "אומלעקסיקע פּאַראַמעטערס" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "אָפּעראַציע ניט געשטיצט" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "אַרײַן־אַרױסשרײַב טעות" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "קאָרומפּירטע דאַטן" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "אומלעקסיקע פֿאָרמאַטירונג" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "שלעכטע טעקע־הענטל" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "טעקע צו גרױס" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "קײן אָרט ניט געבליבן אױף דער המצאָה" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "בלױז־לײענעװדיקע טעקע־סיסטעם" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "אומלעקסיקער URI" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "טעקע ניט אָפֿן" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "אומלעקסיקע עפֿן־מאָדע" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "צוטריט ניט דערלױבט" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "צופֿיל אָפֿענע טעקעס" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "סוף־טעקע" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "ניט קײן פּאַפּקע" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "אָפּעראַציע אַקטיװ" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "אָפּעראַציע איבערגעריסן" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "טעקע עקזיסטירט" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "קײַקלדיקע פֿאַרבינדונגען געפֿונען" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "אָפּעראַציע ניט דערלױבט" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "איז אַ פּאַפּקע" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "ניט גענוג זכּרון" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "קאָמפּיוטער ניט געפֿונען" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "אומלעקסיקער קאָמפּיוטער־נאָמען" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "קאָמפּיוטער האָט ניט קײן אַדרעס" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "אַרײַנלאָגירן דורכגעפֿאַלן" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "אָפּעראַציע אָפּגערופֿן" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "פּאַפּקע פֿאַרנומען" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "פּאַפּקע ניט לײדיק" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "צופֿיל פֿאַרבינדונגען" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "בלױז־לײענעװדיקע טעקע־סיסטעם" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "ניט אױף דער זעלבער טעקע־סיסטעם" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "נאָמען צו לאַנג" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "באַדינונג ניט בנימצה" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "בקשה פֿאַרעלטערט באַדינונגס דאַטן" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "פּראָטאָקאָל־טעות" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "ניט געקענט געפֿינינען הױפּט־בלעטערער" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "אומבאַקאַנטע טעות" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 אַכטעלע" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u אַכטעלעך" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f קילאָ" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f מעגאַ־אַכטעלעך" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f גיגאַ־אַכטעלעך" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (אומלעקסיקער אוניקאָד)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "אומבאַקאַנטע GnomeVFSSeekPosition %d" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "ניט געפֿונען קײן לעקסיקע מצבֿ־טעקע בײַ %s\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "ניץ דעם %s מצבֿ־װאַריאַבל אָנצוּװײַזן אַן אַנדער אָרט.\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +#, fuzzy +msgid "Files" +msgstr "טעקע עקזיסטירט" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "סטאַנדאַרדע צונעמעניש־פֿאַבריק" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "טעקע צונעמעניש־צוגעבער" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "אַלגעמײנע Gnome VFS צונעמעניש" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "אַלגעמײנע טעקע־צונעמעניש" diff --git a/po/zh_CN.gmo b/po/zh_CN.gmo new file mode 100644 index 0000000000000000000000000000000000000000..3ef92fd3a1707e7cd1a3eea20331c38f0ef6525e GIT binary patch literal 5143 zcmai#du$ZP9ml76(K=1qq>r>sNTzLEUO8h!(>Nw1JPl4T5U>-eRh6!9=gtdzyO-TP zz>(S-9Ajf+Ok<3J*f9pXI8JSpyf4zgTd%?ef^T2E0K&Hn>P=a3+s;~!vP>K8)$?f}0G`Q0Gt zJp|qcMnKwUnPN3a>-`X<`38s|vz5FFr1P|c~JzxuXKiCV>dCw{S8vGjie^mS!r1`hwkTh>T zNcJoRN$*L;I*_BkL-jksZ=gQ}lKvD(`@9X3UGIYrfggf&{##)rjo$;3A4)-5zY<&x zZUzxzb{PCBcnl=_##R3}p!Ye({;c}XVpGzOfs|L4>Zd@8_fJ6%9#gyw!jHukeKez~d9i;VtujKD5egu-epMW&K z1WAQg#udvISAn$NR*?4nF-Ys_YTQ!eKU3qKAg%j~;)vp;8h-~wXxY0Ut^2;>M&XjNO6Bj^?N|7&yyg{y9&~|-c$W7NcY0ORsR7D z(*Dap+HZ~OZvpXRFDSXA_;ZlfJ*apJq`aO4X`T0!dFvkL9|XiLz_(5lg%M8j1aJWt^NY4uKb1m!V3l<$j!H`E#Un0hZ) zTmw=qA>`LR%{R-I34eA>TX_yrHJSW$JyQ zVg#%~qZ*<(l8+altwlr01rPa^o<~Cj-=HeI(>?M%C8L;79zKP(5{+_hGaBVMu9%=E zD?xfFKd5##p;e&K{loY|!`h{phR*9PBWmkn5i2dLi17_;LOv6s7G1ZhROeCK@-)M8 z`R4jfJld!^TGSJcTXy5HW%Gpa8f~3hT0-1(*w#~~C=91~Lz5?5RuPb`jz)#+a$Q)4 z(Anx_(lnx)XV{j@)@VA98JO9qS-L6MTFtU-k4GJ$d4ea6q~I~z;dWA3d_&EawNSH! zS;b3Ts5(0SZ7XKPQ%kQpmpk`}4^s_5G&#>ZdxU=TrU?os=MAWmLCf<;8 zo91+BbCF1TO>8|*V8?=4Y`x>aL{m#y(MGI=9TN$7L&@nlbEMofEWxVDWnz!vdT#h$ zGvCFItd(@W(Kyf4Z;$R5#@r;!!`;t$u`=qhtQBKxu)w5 z!WhaZ59Uk_^k&aMU6<7?-J;g2vEXV;GmBl7q}ys(jY?RUi6trfSdGgyt`~gBHW}7V zmu<4+hQ(tV4A;@IljIZlVyDZ66-AIS6(hA!V70b`+);iDta15n!!&t=;6~iSs9wf4 zlLh1%)3)MlvyJqOX(`j=r~#xV*Id_*8puMO21B3VCCpPN$jbU{o46Zo6bV5pZc>X1 zZi<-4F;XGr_h{+9y!Qb6gFX zO7^H`MTJTJn3cgtNym-{fto9YcT^V7N-17gEMa(L|_#>t&Z*4QM(YeZ34Aw zTV~UBMJTT?L{k{?*{)3vB9FNwGhJ41?X>LOxGO9>A)c$=zFml&TW!|}LRzX9 z$HRCQw0GDId?#HBrKzHZo#b8nTSy5JHDXOc2E<}WP>h>)c=wf+u;;NQZXXteT$#Lnk0&hDCyT3U3@qU=1&I(i zr8p8yD+m#+9k_HNHG1SZ6cIAGiX+t%BC;#ymTcWp7gtd&(@~l|`*5G0BRjw77`W2`y2@Uut||?PmUjQBi3{Jhc?|#U$Jw zW!F!wt*Kof)5$)<(2hy)sf0sJ=y^=h^)tT zq2uPWrv=*%L4G|Nq7P_{s@r-;PFZ<>%KWyH|O5JeCe{0C^KM*ST zM=$&5d*$J-&r}#4k^_AOg%rnfxsHAK({{t5{05pA9vO-I>XZ|EuoYnRa=6l#$!c_vX%= z&bM_az238aSK99ylmp#NIii1*iVG`XH8>`8bS{0hxMvB=zM7WPz4F>|^_Cxa4X$P3 zk+PW{e_)X1&bGjK`HSh9%&=^mg857iznne1KNRJL4l1eg$ECOA_%Yd!QwIJiT2Scs zkA*H$eK|ZPhtH@^QFb}7F-Q&nIxTcIC9shSvkVhbzoZ_T%is!lO2>+y*#c4YTHzxOQjk4@k#Gm~SX^H{#;s()yN zWshgbmBZ(97e-iqZ`;gdhrBwLJw%zJRPy`MNEqh7dO;4KfH(|bxTie3KX>X4d2Kq| zJ3={&gCi5+oP6)KLO@&3=k^}SXO894!?I&^X1ZSus8biery5r-3Bsh(7J-+;IMsMK zhA`**F2E68H`)`9=PsU?!-F`a+~10Lk|JU%4<8I|R~d3Xlg$ib%~>afvGq}1h?(Eh zg;SDU-ADb4?aUuPjYUG~>>!=#=y)u>?l1eL>s8r(0&#n8gy*5Mc<&DKj;Z!9}Fg2B)HgcdalxmK8g72vGwnXc@)41G3>ilH+gm9KTu z0LARcgnw`^ogsA8%=9(XD3v=BPM&I!-N*86-TuIcf3QuaPsrAbGTkyWP1g;Q3w1x% eC%aFpYAaY<{C4J>Pta=r`{@h^LYEi6r~d`BM5itQ literal 0 HcmV?d00001 diff --git a/po/zh_CN.po b/po/zh_CN.po new file mode 100644 index 0000000..fda1a93 --- /dev/null +++ b/po/zh_CN.po @@ -0,0 +1,409 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Free Software Foundation, Inc. +# Lou Bingyong , 2001 +# Funda Wang , 2003 +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-08-17 08:59+0800\n" +"Last-Translator: Funda Wang \n" +"Language-Team: zh_CN \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Report-Msgid-Bugs-To: \n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:%d 包含空字符。" + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:%d 没有包含方法名。" + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:%d 没有包含模块名。" + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "配置文件“%s”找不到:%s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "未知的操作类型 %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "不能为打开 GIOChannel 建立管道:%s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "未知的工作种类 %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "操作停止" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "无法解释:%s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "更多的解释错误将被忽略。" + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "没有错误" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "文件找不到" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "一般错误" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "内部错误" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "无效的参数" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "不支持的操作" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "I/O 错误" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "数据损坏" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "无效的格式" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "错误的文件句柄" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "文件太大" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "设备中没有空间" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "只读的文件系统" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "无效的URI" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "文件未打开" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "无效的打开模式" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "访问拒绝" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "打开的文件太多" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "文件结束" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "不是一个目录" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "正在操作" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "操作被中断" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "文件已存在" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "遇上循环的链接" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "不允许的操作" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "是一个目录" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "没有足够的内存" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "无法找到主机" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "无效的主机名" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "主机没有地址" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "登录失败" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "操作被取消" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "目录忙" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "目录非空" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "太多链接" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "只读的文件系统" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "不在同一个文件系统中" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "名字太长" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "服务不存在" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "请求废弃的服务数据" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "协议错误" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "找不到主浏览器" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "没有关联默认动作" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "URL schema 没有处理程序" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "处理命令行出错" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "调用命令出错" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "未知的错误" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 字节" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u 字节" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (无效的 Unicode)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "未知的 GnomeVFSSeekPosition %d" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "没有在 %s 找到有效的设置文件\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "使用 %s 环境变量来指定其它位置。\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "应用程序" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "卡片" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "文件" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "文件夹" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "帮助" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "主机" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "链接" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "邮件" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "工具" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "窗口" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "标准 Moniker 工厂" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "文件 MonikerExtender" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "通用 Gnome VFS moniker" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "通用文件 moniker" diff --git a/po/zh_TW.gmo b/po/zh_TW.gmo new file mode 100644 index 0000000000000000000000000000000000000000..7306f44c2b3e062e5ffba4ae3ebb2e83b77a209c GIT binary patch literal 5268 zcmai#du$ZP9ml63NsDQoZTiTgnbJDEa>h2LaU4Pd#=s>u5U^7Qa^yf$}lnjGkg1iwV{Wrk}z-{1{!9CzZ;C^r+cnqX1KLi(mAAwJS{{g=OK8eL1 z1WUpB;7hXK2-5gga1Pi3ejPjjJ`PSu`L95l|2vTEa6z);ub}Vh?7+YK!G|G#5G1{) z!F$0FNc)sat_EqnH$a-Nf%s#llsAK9PdiBQ>yh%4An9KQY5%L>H^C1;+UGX-T`&XE z{tpxdd3geasjLDd{S_ej`6H0xXoHV{t>6=2FG%*DmwX?54E^6reg@L~`(Px^dkQ3f z7K5a>T(S=2=x>(&4)7c34}+vX1=2nrfaKR7!KcC7AlW|)PSW@zAjP2=r1dMn72rA$ zDQ4Z^SHXUe{2Q13o8a;Fx`bytFO!7xbv>LA5wH;6xW0RNr=Pl8ncAA%J3PeIb3jUuA{ zT*>7ihS(dDn?Z`lc987r1Zm$v5UFRwQhr);QjWh5(!5_wehkvOf05(&z)1XLvq4(- zaS*9y^JKpqr1f6{X}_?PZvZI{KbCSEq&nO##}9+#&l%bOCCJhLElB?VL&_h6ab(Y2 z@Y`THNcPs@AFUsgd`ogaNbx!a(!5`QWcP36_{Wle2g#l}C?@=5r68?W1(N;`L0TsY zl3zasOTj%Lt$Rg|-vqyg{w>-6Cs>aD!zezQR|V4eDC1{1;3+Rvy^gWM8>n}i~^GDyyXx~FygjRyK8f`fmu44aNhX1d~-*iXNJwPAb zZ&c&-%|d(5{}uR6KUbpBS)zI<{3tKAXdI2s41Md-s?k=Vtwp0VOdsWT4chn7=-g54 z>7!Ub>;J-;1}TR0%@4prU>J?g5anqx+B~!>G#oYmLrDE^spM;5B^uo$&qx{Ng!29p z+KXuPCagoFnx^xNvSSr!^ijU3wrkMJ(CGeQe7 zsA+LCAq>7IyuJ!*hR`c{u?TT0R*ITQLk;xJqz(s2 zrWq=aD>i)P4VJmp78cf-8BHjbE&Lg)6h}dfEGwCCVE8IcHRj3L3J>CJ3&+unm>uk_ zI54aTik65trq#?Fl6G@Jmo^vigwxEbVSyR-XR&I_f{VJ6G$M^y3p>W+h=!DtIR#R# zYldK}DP&@sW;=H9JLhV?OEC+2j%o4+E#`NiZ|W+N3|es*Of!97*cxF7ON($p_OP`= zPq4M7?I1N2O0KA?g){~-s)K^5zFyu2>e?*4c)eUJY#`KzqUXA@NH>OASQaeY#FA8f zENpXyt1~fVHJZ_6vl=s|89b`MaTOgiK`}urnrtqN2$GDc7^#HZeH`bwAk>h_Vvi_BMCcTcybLi)SZ2&mRG}2nkyV_RQogWQTyx0DyxexoL;{ix zmg$%gb0%vW1ooGP{{==y#sTaYxR z0jGbHgSyAD=C!7wHQ{tdkqin_9rA=T(Hvwv-!&;f6fv7*y3Oj1Cd1r{yTUNz;`P;= zHVM(R!L&6$rNwG)Jjmya_GYtzH_@d~oXlyM3GOuG`te0}GLbMXgo$pVApES}M*Sdb z#Z-Y?G|M#N!l1KcY2*xQ3nd{UTC~}(fM^s2igDcx?!J;D_5*B*+lTonmo8UtbA*BO z$zt*}`krvOfCJivx75l zDfV)^JJX}*|Bt>mI-I^#sG8)dYn|8!QarKw-|l$7+trsjdfMxFmw9b_(>8}s&F zPfd2Z?dM>Dx4Xj|>+y!$KWXVNwm)eZ2sCplpMPkBO*1Etd55|K)y%~48F zbdMck?$9V5Dhlh&J`_8d9Jyf;OCLO&-M7mdKL&mG#z6Y$zRW;xx_eKsoE&y{pG-}6 z(sbWOiqOy~!(K2xyQ3$N!bflDbo%rJgY#}jFVd8n9`Octx@}YGuIoYYSYYzq$K>i* zHrOC<(O$dGh@csnAiUfWYgZM z!@-K~&^h;KEm9Pel$@EfBT$zrEOT`dt}S+VAD4?FOxe~^*{RfX4P z?mg}ue9s*jgh~+5U{g8*f#rxuw)YB?u{zS78678GKeb-p W_m|xSflR0%EJA8=K zi=5M@+MnuT?k>s-mT`9u$aw8Nl^y9%pPI_{?MFyDy_{p2(SC2wMiJ@0l+(1r!8Np&jU9YfyuQRa5`;6j;6V$Ve8Y|H0tWbR$1nG-v_^E*`KjKNyTLZ*;($>dU>)?v>;2^buJPek~8u;R=G1 zv&0=4L&h<1+}-UvhXTgn-5=@sUiXlDt^>DP`r6qAxMG7O&;;qHpE2rVK?E9kcMo;Y zJDnTAE6vlRXQ?8jxM#xadXEe$jArWE4P1M4*Pv$Iqpg{2%*Y^bXwA*z8C(mt> nwxC3dSms1udhCEauQOrDz1hJ*^<7)HzP9>~S35s;$GiPsbu;$+ literal 0 HcmV?d00001 diff --git a/po/zh_TW.po b/po/zh_TW.po new file mode 100644 index 0000000..d5189f7 --- /dev/null +++ b/po/zh_TW.po @@ -0,0 +1,407 @@ +# traditional Chinese translation of gnome-vfs. +# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. +# Joe Man , 2001. +# Abel Cheung , 2002-2003. +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-vfs 2.3.2\n" +"POT-Creation-Date: 2003-08-25 13:18+0200\n" +"PO-Revision-Date: 2003-05-27 23:30+0800\n" +"Last-Translator: Abel Cheung \n" +"Language-Team: Chinese (traditional) \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: libgnomevfs/gnome-vfs-configuration.c:219 +#, c-format +msgid "%s:%d contains NUL characters." +msgstr "%s:第 %d 行中有 NUL 字元。" + +#: libgnomevfs/gnome-vfs-configuration.c:236 +#, c-format +msgid "%s:%d contains no method name." +msgstr "%s:第 %d 行沒有指定 method 的名稱。" + +#: libgnomevfs/gnome-vfs-configuration.c:265 +#, c-format +msgid "%s:%d contains no module name." +msgstr "%s:第 %d 行沒有指定模組名稱。" + +#: libgnomevfs/gnome-vfs-configuration.c:318 +#, c-format +msgid "Configuration file `%s' was not found: %s" +msgstr "找不到組態檔案‘%s’:%s" + +#: libgnomevfs/gnome-vfs-job.c:758 +#, c-format +msgid "Unknown op type %u" +msgstr "不明的 op 種類 %u" + +#: libgnomevfs/gnome-vfs-job.c:1048 libgnomevfs/gnome-vfs-job.c:1193 +#, c-format +msgid "Cannot create pipe for open GIOChannel: %s" +msgstr "無法建立用以開啟 GIOChannel 的 pipe:%s" + +#: libgnomevfs/gnome-vfs-job.c:1684 +#, c-format +msgid "Unknown job kind %u" +msgstr "不明的工作類型 %u" + +#: libgnomevfs/gnome-vfs-job.c:1717 +msgid "Operation stopped" +msgstr "操作已停止" + +#: libgnomevfs/gnome-vfs-parse-ls.c:652 +#, c-format +msgid "Could not parse: %s" +msgstr "無法解析:%s" + +#: libgnomevfs/gnome-vfs-parse-ls.c:654 +msgid "More parsing errors will be ignored." +msgstr "將會忽略更多的解析錯誤。" + +#. GNOME_VFS_OK +#: libgnomevfs/gnome-vfs-result.c:35 +msgid "No error" +msgstr "沒有錯誤" + +#. GNOME_VFS_ERROR_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:36 +msgid "File not found" +msgstr "找不到檔案" + +#. GNOME_VFS_ERROR_GENERIC +#: libgnomevfs/gnome-vfs-result.c:37 +msgid "Generic error" +msgstr "一般錯誤" + +#. GNOME_VFS_ERROR_INTERNAL +#: libgnomevfs/gnome-vfs-result.c:38 +msgid "Internal error" +msgstr "內部錯誤" + +#. GNOME_VFS_ERROR_BAD_PARAMETERS +#: libgnomevfs/gnome-vfs-result.c:39 +msgid "Invalid parameters" +msgstr "參數無效" + +#. GNOME_VFS_ERROR_NOT_SUPPORTED +#: libgnomevfs/gnome-vfs-result.c:40 +msgid "Unsupported operation" +msgstr "不支援的操作程序" + +#. GNOME_VFS_ERROR_IO +#: libgnomevfs/gnome-vfs-result.c:41 +msgid "I/O error" +msgstr "輸出/入錯誤" + +#. GNOME_VFS_ERROR_CORRUPTED_DATA +#: libgnomevfs/gnome-vfs-result.c:42 +msgid "Data corrupted" +msgstr "資料已損壞" + +#. GNOME_VFS_ERROR_WRONG_FORMAT +#: libgnomevfs/gnome-vfs-result.c:43 +msgid "Format not valid" +msgstr "格式無效" + +#. GNOME_VFS_ERROR_BAD_FILE +#: libgnomevfs/gnome-vfs-result.c:44 +msgid "Bad file handle" +msgstr "錯誤的 file handle" + +#. GNOME_VFS_ERROR_TOO_BIG +#: libgnomevfs/gnome-vfs-result.c:45 +msgid "File too big" +msgstr "檔案過大" + +#. GNOME_VFS_ERROR_NO_SPACE +#: libgnomevfs/gnome-vfs-result.c:46 +msgid "No space left on device" +msgstr "儲存設備沒有剩餘空間" + +#. GNOME_VFS_ERROR_READ_ONLY +#: libgnomevfs/gnome-vfs-result.c:47 +msgid "Read-only file system" +msgstr "唯讀的檔案系統" + +#. GNOME_VFS_ERROR_INVALID_URI +#: libgnomevfs/gnome-vfs-result.c:48 +msgid "Invalid URI" +msgstr "URI 無效" + +#. GNOME_VFS_ERROR_NOT_OPEN +#: libgnomevfs/gnome-vfs-result.c:49 +msgid "File not open" +msgstr "檔案沒有開啟" + +#. GNOME_VFS_ERROR_INVALID_OPEN_MODE +#: libgnomevfs/gnome-vfs-result.c:50 +msgid "Open mode not valid" +msgstr "開啟模式無效" + +#. GNOME_VFS_ERROR_ACCESS_DENIED +#: libgnomevfs/gnome-vfs-result.c:51 +msgid "Access denied" +msgstr "存取被拒" + +#. GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES +#: libgnomevfs/gnome-vfs-result.c:52 +msgid "Too many open files" +msgstr "已開啟的檔案太多" + +#. GNOME_VFS_ERROR_EOF +#: libgnomevfs/gnome-vfs-result.c:53 +msgid "End of file" +msgstr "已到達檔案的末端" + +#. GNOME_VFS_ERROR_NOT_A_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:54 +msgid "Not a directory" +msgstr "不是目錄" + +#. GNOME_VFS_ERROR_IN_PROGRESS +#: libgnomevfs/gnome-vfs-result.c:55 +msgid "Operation in progress" +msgstr "操作程序進行中" + +#. GNOME_VFS_ERROR_INTERRUPTED +#: libgnomevfs/gnome-vfs-result.c:56 +msgid "Operation interrupted" +msgstr "操作程序被中斷" + +#. GNOME_VFS_ERROR_FILE_EXISTS +#: libgnomevfs/gnome-vfs-result.c:57 +msgid "File exists" +msgstr "檔案已存在" + +#. GNOME_VFS_ERROR_LOOP +#: libgnomevfs/gnome-vfs-result.c:58 +msgid "Looping links encountered" +msgstr "遇上循環的鏈結" + +#. GNOME_VFS_ERROR_NOT_PERMITTED +#: libgnomevfs/gnome-vfs-result.c:59 +msgid "Operation not permitted" +msgstr "不許可的操作程序" + +#. GNOME_VFS_ERROR_IS_DIRECTORY +#: libgnomevfs/gnome-vfs-result.c:60 +msgid "Is a directory" +msgstr "是目錄" + +#. GNOME_VFS_ERROR_NO_MEMMORY +#: libgnomevfs/gnome-vfs-result.c:61 +msgid "Not enough memory" +msgstr "記憶體不足" + +#. GNOME_VFS_ERROR_HOST_NOT_FOUND +#: libgnomevfs/gnome-vfs-result.c:62 +msgid "Host not found" +msgstr "找不到主機" + +#. GNOME_VFS_ERROR_INVALID_HOST_NAME +#: libgnomevfs/gnome-vfs-result.c:63 +msgid "Host name not valid" +msgstr "主機名稱無效" + +#. GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS +#: libgnomevfs/gnome-vfs-result.c:64 +msgid "Host has no address" +msgstr "主機沒有地址" + +#. GNOME_VFS_ERROR_LOGIN_FAILED +#: libgnomevfs/gnome-vfs-result.c:65 +msgid "Login failed" +msgstr "登入失敗" + +#. GNOME_VFS_ERROR_CANCELLED +#: libgnomevfs/gnome-vfs-result.c:66 +msgid "Operation cancelled" +msgstr "操作程序被取消" + +#. GNOME_VFS_ERROR_DIRECTORY_BUSY +#: libgnomevfs/gnome-vfs-result.c:67 +msgid "Directory busy" +msgstr "目錄正在忙碌處理資料" + +#. GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY +#: libgnomevfs/gnome-vfs-result.c:68 +msgid "Directory not empty" +msgstr "目錄內仍有檔案存在" + +#. GNOME_VFS_ERROR_TOO_MANY_LINKS +#: libgnomevfs/gnome-vfs-result.c:69 +msgid "Too many links" +msgstr "鏈結過多" + +#. GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:70 +msgid "Read only file system" +msgstr "唯讀的檔案系統" + +#. GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM +#: libgnomevfs/gnome-vfs-result.c:71 +msgid "Not on the same file system" +msgstr "不是在相同的檔案系統內" + +#. GNOME_VFS_ERROR_NAME_TOO_LONG +#: libgnomevfs/gnome-vfs-result.c:72 +msgid "Name too long" +msgstr "名稱過長" + +#. GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE +#: libgnomevfs/gnome-vfs-result.c:73 +msgid "Service not available" +msgstr "無法提供服務" + +#. GNOME_VFS_ERROR_SERVICE_OBSOLETE +#: libgnomevfs/gnome-vfs-result.c:74 +msgid "Request obsoletes service's data" +msgstr "要求某些已過時服務的資料" + +#. GNOME_VFS_ERROR_PROTOCOL_ERROR +#: libgnomevfs/gnome-vfs-result.c:75 +msgid "Protocol error" +msgstr "協定錯誤" + +#. GNOME_VFS_ERROR_NO_MASTER_BROWSER +#: libgnomevfs/gnome-vfs-result.c:76 +msgid "Could not find master browser" +msgstr "找不到 master browser" + +#. GNOME_VFS_ERROR_NO_DEFAULT +#: libgnomevfs/gnome-vfs-result.c:77 +msgid "No default action associated" +msgstr "沒有預設的處理方式" + +#. GNOME_VFS_ERROR_NO_HANDLER +#: libgnomevfs/gnome-vfs-result.c:78 +msgid "No handler for URL scheme" +msgstr "沒有該類 URL 的處理程序" + +#. GNOME_VFS_ERROR_PARSE +#: libgnomevfs/gnome-vfs-result.c:79 +msgid "Error parsing command line" +msgstr "解析指令時出現錯誤" + +#. GNOME_VFS_ERROR_LAUNCH +#: libgnomevfs/gnome-vfs-result.c:80 +msgid "Error launching command" +msgstr "啟動指令時出現錯誤" + +#: libgnomevfs/gnome-vfs-result.c:174 +msgid "Unknown error" +msgstr "不明的錯誤" + +#: libgnomevfs/gnome-vfs-utils.c:84 +msgid "1 byte" +msgstr "1 位元組" + +#: libgnomevfs/gnome-vfs-utils.c:86 +#, c-format +msgid "%u bytes" +msgstr "%u 位元組" + +#: libgnomevfs/gnome-vfs-utils.c:93 +#, c-format +msgid "%.1f K" +msgstr "%.1f K" + +#: libgnomevfs/gnome-vfs-utils.c:97 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: libgnomevfs/gnome-vfs-utils.c:101 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: libgnomevfs/gnome-vfs-utils.c:1085 +msgid " (invalid Unicode)" +msgstr " (無效的統一碼)" + +#: modules/file-method.c:382 +#, c-format +msgid "Unknown GnomeVFSSeekPosition %d" +msgstr "不明的 GnomeVFSSeekPosition (搜尋位置) %d" + +#. FIXME: we probably shouldn't use printf to output the message +#: modules/test-method.c:590 +#, c-format +msgid "Didn't find a valid settings file at %s\n" +msgstr "在 %s 中找不到有效的組態檔\n" + +#: modules/test-method.c:592 +#, c-format +msgid "Use the %s environment variable to specify a different location.\n" +msgstr "使用 %s 環境變數來指定另一個位置。\n" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:175 +msgid "Applications" +msgstr "應用程式" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:178 +msgid "Cards" +msgstr "名片" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:181 +msgid "Files" +msgstr "檔案" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:184 +msgid "Folders" +msgstr "資料夾" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:187 +msgid "Help" +msgstr "說明" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:190 +msgid "Hosts" +msgstr "主機" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:193 +msgid "Links" +msgstr "鏈結" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:196 +msgid "Mail" +msgstr "郵件" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:199 +msgid "Tools" +msgstr "工具" + +#. Translate exactly the same in CDE's sys.dtwmrc file of the locale +#: modules/cdemenu-desktop-method.c:202 +msgid "Windows" +msgstr "視窗" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:1 +msgid "Standard Moniker factory" +msgstr "標準 Moniker 工廠" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:2 +msgid "file MonikerExtender" +msgstr "檔案 MonikerExtender" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:3 +msgid "generic Gnome VFS moniker" +msgstr "一般的 GNOME VFS moniker" + +#: monikers/GNOME_VFS_Moniker_std.server.in.in.h:4 +msgid "generic file moniker" +msgstr "一般的 file moniker" diff --git a/programs/Makefile.am b/programs/Makefile.am new file mode 100644 index 0000000..c2d4cbe --- /dev/null +++ b/programs/Makefile.am @@ -0,0 +1,38 @@ +NULL = + +INCLUDES = \ + -I$(top_srcdir) \ + -I$(top_builddir) \ + $(TEST_CFLAGS) \ + $(VFS_CFLAGS) \ + -DG_DISABLE_DEPRECATED + +libraries = \ + $(top_builddir)/libgnomevfs/libgnomevfs-2.la \ + $(TEST_LIBS) \ + $(POPT_LIBS) \ + $(LIBEFS_LIBS) + +bin_PROGRAMS = \ + gnomevfs-cat \ + gnomevfs-copy \ + gnomevfs-info \ + gnomevfs-ls \ + gnomevfs-mkdir \ + $(NULL) + +gnomevfs_cat_SOURCES = gnomevfs-cat.c +gnomevfs_cat_LDADD = $(libraries) + +gnomevfs_copy_SOURCES = gnomevfs-copy.c +gnomevfs_copy_LDADD = $(libraries) + +gnomevfs_info_SOURCES = gnomevfs-info.c +gnomevfs_info_LDADD = $(libraries) + +gnomevfs_ls_SOURCES = gnomevfs-ls.c +gnomevfs_ls_LDADD = $(libraries) + +gnomevfs_mkdir_SOURCES = gnomevfs-mkdir.c +gnomevfs_mkdir_LDADD = $(libraries) + diff --git a/programs/Makefile.in b/programs/Makefile.in new file mode 100644 index 0000000..0d118fa --- /dev/null +++ b/programs/Makefile.in @@ -0,0 +1,563 @@ +# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ +AS = @AS@ +AWK = @AWK@ +BONOBO_ACTIVATION_REQUIRED = @BONOBO_ACTIVATION_REQUIRED@ +BONOBO_IDLDIR = @BONOBO_IDLDIR@ +BONOBO_REQUIRED = @BONOBO_REQUIRED@ +BZ2_LIBS = @BZ2_LIBS@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +DATADIRNAME = @DATADIRNAME@ +DB2HTML = @DB2HTML@ +DLLTOOL = @DLLTOOL@ +ECHO = @ECHO@ +ENABLE_PROFILER = @ENABLE_PROFILER@ +EXEEXT = @EXEEXT@ +FAM_LIBS = @FAM_LIBS@ +GCONFTOOL = @GCONFTOOL@ +GCONF_REQUIRED = @GCONF_REQUIRED@ +GCONF_SCHEMA_CONFIG_SOURCE = @GCONF_SCHEMA_CONFIG_SOURCE@ +GCONF_SCHEMA_FILE_DIR = @GCONF_SCHEMA_FILE_DIR@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GLIB_REQUIRED = @GLIB_REQUIRED@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GNOME_ACLOCAL_DIR = @GNOME_ACLOCAL_DIR@ +GNOME_ACLOCAL_FLAGS = @GNOME_ACLOCAL_FLAGS@ +GNOME_VFS_DIR = @GNOME_VFS_DIR@ +GTKDOC = @GTKDOC@ +HAVE_GTK_DOC = @HAVE_GTK_DOC@ +HTML_DIR = @HTML_DIR@ +INSTOBJEXT = @INSTOBJEXT@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_CAVES_RULE = @INTLTOOL_CAVES_RULE@ +INTLTOOL_DESKTOP_RULE = @INTLTOOL_DESKTOP_RULE@ +INTLTOOL_DIRECTORY_RULE = @INTLTOOL_DIRECTORY_RULE@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_KEYS_RULE = @INTLTOOL_KEYS_RULE@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_OAF_RULE = @INTLTOOL_OAF_RULE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_PONG_RULE = @INTLTOOL_PONG_RULE@ +INTLTOOL_PROP_RULE = @INTLTOOL_PROP_RULE@ +INTLTOOL_SCHEMAS_RULE = @INTLTOOL_SCHEMAS_RULE@ +INTLTOOL_SERVER_RULE = @INTLTOOL_SERVER_RULE@ +INTLTOOL_SHEET_RULE = @INTLTOOL_SHEET_RULE@ +INTLTOOL_SOUNDLIST_RULE = @INTLTOOL_SOUNDLIST_RULE@ +INTLTOOL_THEME_RULE = @INTLTOOL_THEME_RULE@ +INTLTOOL_UI_RULE = @INTLTOOL_UI_RULE@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTLTOOL_XML_RULE = @INTLTOOL_XML_RULE@ +LDFLAGS = @LDFLAGS@ +LIBEFS_CFLAGS = @LIBEFS_CFLAGS@ +LIBEFS_LIBS = @LIBEFS_LIBS@ +LIBGNOMEVFS_AGE = @LIBGNOMEVFS_AGE@ +LIBGNOMEVFS_CFLAGS = @LIBGNOMEVFS_CFLAGS@ +LIBGNOMEVFS_CURRENT = @LIBGNOMEVFS_CURRENT@ +LIBGNOMEVFS_LIBS = @LIBGNOMEVFS_LIBS@ +LIBGNOMEVFS_REVISION = @LIBGNOMEVFS_REVISION@ +LIBGNUTLS_CFLAGS = @LIBGNUTLS_CFLAGS@ +LIBGNUTLS_CONFIG = @LIBGNUTLS_CONFIG@ +LIBGNUTLS_LIBS = @LIBGNUTLS_LIBS@ +LIBIDL_REQUIRED = @LIBIDL_REQUIRED@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MODULES_CFLAGS = @MODULES_CFLAGS@ +MODULES_FILE_CFLAGS = @MODULES_FILE_CFLAGS@ +MODULES_FILE_LIBS = @MODULES_FILE_LIBS@ +MODULES_GCONF_CFLAGS = @MODULES_GCONF_CFLAGS@ +MODULES_GCONF_LIBS = @MODULES_GCONF_LIBS@ +MODULES_LIBS = @MODULES_LIBS@ +MODULES_XML_CFLAGS = @MODULES_XML_CFLAGS@ +MODULES_XML_GCONF_CFLAGS = @MODULES_XML_GCONF_CFLAGS@ +MODULES_XML_GCONF_LIBS = @MODULES_XML_GCONF_LIBS@ +MODULES_XML_LIBS = @MODULES_XML_LIBS@ +MONIKERS_CFLAGS = @MONIKERS_CFLAGS@ +MONIKERS_LIBS = @MONIKERS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ORBIT_IDL = @ORBIT_IDL@ +ORBIT_REQUIRED = @ORBIT_REQUIRED@ +PACKAGE = @PACKAGE@ +PKG_CONFIG = @PKG_CONFIG@ +POFILES = @POFILES@ +POPT_LIBS = @POPT_LIBS@ +POSUB = @POSUB@ +PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ +PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ +RANLIB = @RANLIB@ +STRIP = @STRIP@ +TEST_CFLAGS = @TEST_CFLAGS@ +TEST_LIBS = @TEST_LIBS@ +TOP_BUILDDIR = @TOP_BUILDDIR@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +VFS_CFLAGS = @VFS_CFLAGS@ +VFS_INCLUDEDIR = @VFS_INCLUDEDIR@ +VFS_LIBDIR = @VFS_LIBDIR@ +VFS_LIBS = @VFS_LIBS@ +VFS_OFFSET = @VFS_OFFSET@ +VFS_OFFSET_IS = @VFS_OFFSET_IS@ +VFS_OFFSET_PRINTF = @VFS_OFFSET_PRINTF@ +VFS_SIZE = @VFS_SIZE@ +VFS_SIZE_IS = @VFS_SIZE_IS@ +VFS_SIZE_PRINTF = @VFS_SIZE_PRINTF@ +WARN_CFLAGS = @WARN_CFLAGS@ +XML_REQUIRED = @XML_REQUIRED@ +cxxflags_set = @cxxflags_set@ + +NULL = + +INCLUDES = \ + -I$(top_srcdir) \ + -I$(top_builddir) \ + $(TEST_CFLAGS) \ + $(VFS_CFLAGS) \ + -DG_DISABLE_DEPRECATED + + +libraries = \ + $(top_builddir)/libgnomevfs/libgnomevfs-2.la \ + $(TEST_LIBS) \ + $(POPT_LIBS) \ + $(LIBEFS_LIBS) + + +bin_PROGRAMS = \ + gnomevfs-cat \ + gnomevfs-copy \ + gnomevfs-info \ + gnomevfs-ls \ + gnomevfs-mkdir \ + $(NULL) + + +gnomevfs_cat_SOURCES = gnomevfs-cat.c +gnomevfs_cat_LDADD = $(libraries) + +gnomevfs_copy_SOURCES = gnomevfs-copy.c +gnomevfs_copy_LDADD = $(libraries) + +gnomevfs_info_SOURCES = gnomevfs-info.c +gnomevfs_info_LDADD = $(libraries) + +gnomevfs_ls_SOURCES = gnomevfs-ls.c +gnomevfs_ls_LDADD = $(libraries) + +gnomevfs_mkdir_SOURCES = gnomevfs-mkdir.c +gnomevfs_mkdir_LDADD = $(libraries) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../config.h +CONFIG_CLEAN_FILES = +bin_PROGRAMS = gnomevfs-cat$(EXEEXT) gnomevfs-copy$(EXEEXT) \ +gnomevfs-info$(EXEEXT) gnomevfs-ls$(EXEEXT) gnomevfs-mkdir$(EXEEXT) +PROGRAMS = $(bin_PROGRAMS) + + +DEFS = @DEFS@ -I. -I$(srcdir) -I.. +LIBS = @LIBS@ +gnomevfs_cat_OBJECTS = gnomevfs-cat.$(OBJEXT) +gnomevfs_cat_DEPENDENCIES = \ +$(top_builddir)/libgnomevfs/libgnomevfs-2.la +gnomevfs_cat_LDFLAGS = +gnomevfs_copy_OBJECTS = gnomevfs-copy.$(OBJEXT) +gnomevfs_copy_DEPENDENCIES = \ +$(top_builddir)/libgnomevfs/libgnomevfs-2.la +gnomevfs_copy_LDFLAGS = +gnomevfs_info_OBJECTS = gnomevfs-info.$(OBJEXT) +gnomevfs_info_DEPENDENCIES = \ +$(top_builddir)/libgnomevfs/libgnomevfs-2.la +gnomevfs_info_LDFLAGS = +gnomevfs_ls_OBJECTS = gnomevfs-ls.$(OBJEXT) +gnomevfs_ls_DEPENDENCIES = $(top_builddir)/libgnomevfs/libgnomevfs-2.la +gnomevfs_ls_LDFLAGS = +gnomevfs_mkdir_OBJECTS = gnomevfs-mkdir.$(OBJEXT) +gnomevfs_mkdir_DEPENDENCIES = \ +$(top_builddir)/libgnomevfs/libgnomevfs-2.la +gnomevfs_mkdir_LDFLAGS = +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +SOURCES = $(gnomevfs_cat_SOURCES) $(gnomevfs_copy_SOURCES) $(gnomevfs_info_SOURCES) $(gnomevfs_ls_SOURCES) $(gnomevfs_mkdir_SOURCES) +OBJECTS = $(gnomevfs_cat_OBJECTS) $(gnomevfs_copy_OBJECTS) $(gnomevfs_info_OBJECTS) $(gnomevfs_ls_OBJECTS) $(gnomevfs_mkdir_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .lo .o .obj .s +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps programs/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-binPROGRAMS: + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) + +distclean-binPROGRAMS: + +maintainer-clean-binPROGRAMS: + +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(bindir) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ + $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + else :; fi; \ + done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + list='$(bin_PROGRAMS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + done + +.c.o: + $(COMPILE) -c $< + +# FIXME: We should only use cygpath when building on Windows, +# and only if it is available. +.c.obj: + $(COMPILE) -c `cygpath -w $<` + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + -rm -f *.$(OBJEXT) + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +.c.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.s.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.S.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + +maintainer-clean-libtool: + +gnomevfs-cat$(EXEEXT): $(gnomevfs_cat_OBJECTS) $(gnomevfs_cat_DEPENDENCIES) + @rm -f gnomevfs-cat$(EXEEXT) + $(LINK) $(gnomevfs_cat_LDFLAGS) $(gnomevfs_cat_OBJECTS) $(gnomevfs_cat_LDADD) $(LIBS) + +gnomevfs-copy$(EXEEXT): $(gnomevfs_copy_OBJECTS) $(gnomevfs_copy_DEPENDENCIES) + @rm -f gnomevfs-copy$(EXEEXT) + $(LINK) $(gnomevfs_copy_LDFLAGS) $(gnomevfs_copy_OBJECTS) $(gnomevfs_copy_LDADD) $(LIBS) + +gnomevfs-info$(EXEEXT): $(gnomevfs_info_OBJECTS) $(gnomevfs_info_DEPENDENCIES) + @rm -f gnomevfs-info$(EXEEXT) + $(LINK) $(gnomevfs_info_LDFLAGS) $(gnomevfs_info_OBJECTS) $(gnomevfs_info_LDADD) $(LIBS) + +gnomevfs-ls$(EXEEXT): $(gnomevfs_ls_OBJECTS) $(gnomevfs_ls_DEPENDENCIES) + @rm -f gnomevfs-ls$(EXEEXT) + $(LINK) $(gnomevfs_ls_LDFLAGS) $(gnomevfs_ls_OBJECTS) $(gnomevfs_ls_LDADD) $(LIBS) + +gnomevfs-mkdir$(EXEEXT): $(gnomevfs_mkdir_OBJECTS) $(gnomevfs_mkdir_DEPENDENCIES) + @rm -f gnomevfs-mkdir$(EXEEXT) + $(LINK) $(gnomevfs_mkdir_LDFLAGS) $(gnomevfs_mkdir_OBJECTS) $(gnomevfs_mkdir_LDADD) $(LIBS) + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = programs + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +gnomevfs-cat.o: gnomevfs-cat.c ../libgnomevfs/gnome-vfs.h \ + ../libgnomevfs/gnome-vfs-async-ops.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-find-directory.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-xfer.h \ + ../libgnomevfs/gnome-vfs-directory.h \ + ../libgnomevfs/gnome-vfs-init.h \ + ../libgnomevfs/gnome-vfs-module-callback.h \ + ../libgnomevfs/gnome-vfs-monitor.h \ + ../libgnomevfs/gnome-vfs-ops.h ../libgnomevfs/gnome-vfs-utils.h +gnomevfs-copy.o: gnomevfs-copy.c ../libgnomevfs/gnome-vfs.h \ + ../libgnomevfs/gnome-vfs-async-ops.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-find-directory.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-xfer.h \ + ../libgnomevfs/gnome-vfs-directory.h \ + ../libgnomevfs/gnome-vfs-init.h \ + ../libgnomevfs/gnome-vfs-module-callback.h \ + ../libgnomevfs/gnome-vfs-monitor.h \ + ../libgnomevfs/gnome-vfs-ops.h ../libgnomevfs/gnome-vfs-utils.h +gnomevfs-info.o: gnomevfs-info.c ../libgnomevfs/gnome-vfs.h \ + ../libgnomevfs/gnome-vfs-async-ops.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-find-directory.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-xfer.h \ + ../libgnomevfs/gnome-vfs-directory.h \ + ../libgnomevfs/gnome-vfs-init.h \ + ../libgnomevfs/gnome-vfs-module-callback.h \ + ../libgnomevfs/gnome-vfs-monitor.h \ + ../libgnomevfs/gnome-vfs-ops.h ../libgnomevfs/gnome-vfs-utils.h +gnomevfs-ls.o: gnomevfs-ls.c ../libgnomevfs/gnome-vfs.h \ + ../libgnomevfs/gnome-vfs-async-ops.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-find-directory.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-xfer.h \ + ../libgnomevfs/gnome-vfs-directory.h \ + ../libgnomevfs/gnome-vfs-init.h \ + ../libgnomevfs/gnome-vfs-module-callback.h \ + ../libgnomevfs/gnome-vfs-monitor.h \ + ../libgnomevfs/gnome-vfs-ops.h ../libgnomevfs/gnome-vfs-utils.h +gnomevfs-mkdir.o: gnomevfs-mkdir.c ../libgnomevfs/gnome-vfs.h \ + ../libgnomevfs/gnome-vfs-async-ops.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-find-directory.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-xfer.h \ + ../libgnomevfs/gnome-vfs-directory.h \ + ../libgnomevfs/gnome-vfs-init.h \ + ../libgnomevfs/gnome-vfs-module-callback.h \ + ../libgnomevfs/gnome-vfs-monitor.h \ + ../libgnomevfs/gnome-vfs-ops.h ../libgnomevfs/gnome-vfs-utils.h + +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: install-binPROGRAMS +install-exec: install-exec-am + +install-data-am: +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-binPROGRAMS +uninstall: uninstall-am +all-am: Makefile $(PROGRAMS) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(bindir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-compile \ + mostlyclean-libtool mostlyclean-tags \ + mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-binPROGRAMS clean-compile clean-libtool clean-tags \ + clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-binPROGRAMS distclean-compile distclean-libtool \ + distclean-tags distclean-generic clean-am + -rm -f libtool + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-binPROGRAMS \ + maintainer-clean-compile maintainer-clean-libtool \ + maintainer-clean-tags maintainer-clean-generic \ + distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \ +maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \ +mostlyclean-compile distclean-compile clean-compile \ +maintainer-clean-compile mostlyclean-libtool distclean-libtool \ +clean-libtool maintainer-clean-libtool tags mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir info-am info \ +dvi-am dvi check check-am installcheck-am installcheck install-exec-am \ +install-exec install-data-am install-data install-am install \ +uninstall-am uninstall all-redirect all-am all installdirs \ +mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/programs/gnomevfs-cat.c b/programs/gnomevfs-cat.c new file mode 100644 index 0000000..0c10f52 --- /dev/null +++ b/programs/gnomevfs-cat.c @@ -0,0 +1,95 @@ +/* gnomevfs-cat.c - Test for open() and read() for gnome-vfs + + Copyright (C) 1999 Free Software Foundation + Copyright (C) 2003, Red Hat + + Example use: vfscat http://host:port | mpg123 - + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli + Bastien Nocera +*/ + +#include + +#include +#include +#include + +static void +show_result (GnomeVFSResult result, const gchar *what, const gchar *text_uri) +{ + if (result != GNOME_VFS_OK) { + fprintf (stderr, "%s `%s': %s\n", + what, text_uri, + gnome_vfs_result_to_string (result)); + exit (1); + } +} + +int +main (int argc, char **argv) +{ + GnomeVFSResult result; + GnomeVFSHandle *handle; + gchar buffer[1024]; + GnomeVFSFileSize bytes_read; + GnomeVFSURI *uri; + gchar *text_uri; + + if (argc != 2) { + fprintf (stderr, "Usage: %s \n", argv[0]); + return 1; + } + + if (! gnome_vfs_init ()) { + fprintf (stderr, "Cannot initialize gnome-vfs.\n"); + return 1; + } + + uri = gnome_vfs_uri_new (argv[1]); + if (uri == NULL) { + fprintf (stderr, "URI %s not valid.\n", argv[1]); + return 1; + } + + text_uri = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE); + + result = gnome_vfs_open_uri (&handle, uri, GNOME_VFS_OPEN_READ); + show_result (result, "open", text_uri); + + while (result == GNOME_VFS_OK) { + result = gnome_vfs_read (handle, buffer, + sizeof (buffer) - 1, + &bytes_read); + + /* show_result (result, "read", text_uri); */ + + buffer[bytes_read] = 0; + write (1, buffer, bytes_read); + if(bytes_read == 0) + break; + } + + result = gnome_vfs_close (handle); + show_result (result, "close", text_uri); + + g_free (text_uri); + + return 0; +} + diff --git a/programs/gnomevfs-copy.c b/programs/gnomevfs-copy.c new file mode 100644 index 0000000..bcde2ef --- /dev/null +++ b/programs/gnomevfs-copy.c @@ -0,0 +1,74 @@ +/* gnomevfs-copy.c - Test for open(), read() and write() for gnome-vfs + + Copyright (C) 2003, Red Hat + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Bastien Nocera +*/ + +#include + +#include +#include +#include + +/* Copied directly from eel */ +static GnomeVFSResult +copy_uri_simple ( const char *source_uri, const char *dest_uri) +{ + GnomeVFSResult result; + GnomeVFSURI *real_source_uri, *real_dest_uri; + real_source_uri = gnome_vfs_uri_new (source_uri); + real_dest_uri = gnome_vfs_uri_new (dest_uri); + + result = gnome_vfs_xfer_uri (real_source_uri, real_dest_uri, + GNOME_VFS_XFER_RECURSIVE, + GNOME_VFS_XFER_ERROR_MODE_ABORT, + GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE, + NULL, NULL); + + gnome_vfs_uri_unref (real_source_uri); + gnome_vfs_uri_unref (real_dest_uri); + + return result; +} + +int +main (int argc, char **argv) +{ + GnomeVFSResult res; + + if (argc != 3) { + printf ("Usage: %s \n", argv[0]); + return 1; + } + + if (!gnome_vfs_init ()) { + fprintf (stderr, "Cannot initialize gnome-vfs.\n"); + return 1; + } + + res = copy_uri_simple (argv[1], argv[2]); + + if (res != GNOME_VFS_OK) { + fprintf (stderr, "Failed to copy %s to %s\nReason: %s\n", + argv[1], argv[2], gnome_vfs_result_to_string (res)); + return 1; + } + + return 0; +} diff --git a/programs/gnomevfs-info.c b/programs/gnomevfs-info.c new file mode 100644 index 0000000..46f4806 --- /dev/null +++ b/programs/gnomevfs-info.c @@ -0,0 +1,149 @@ +/* gnomevfs-info.c - Test for get_file_info() for gnome-vfs + + Copyright (C) 2003, Red Hat + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Bastien Nocera +*/ + +#include + +#include +#include +#include +#include + +static const gchar * +type_to_string (GnomeVFSFileType type) +{ + switch (type) { + case GNOME_VFS_FILE_TYPE_UNKNOWN: + return "Unknown"; + case GNOME_VFS_FILE_TYPE_REGULAR: + return "Regular"; + case GNOME_VFS_FILE_TYPE_DIRECTORY: + return "Directory"; + case GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK: + return "Symbolic Link"; + case GNOME_VFS_FILE_TYPE_FIFO: + return "FIFO"; + case GNOME_VFS_FILE_TYPE_SOCKET: + return "Socket"; + case GNOME_VFS_FILE_TYPE_CHARACTER_DEVICE: + return "Character device"; + case GNOME_VFS_FILE_TYPE_BLOCK_DEVICE: + return "Block device"; + default: + return "???"; + } +} + +static void +show_file_info (GnomeVFSFileInfo *info) +{ +#define FLAG_STRING(info, which) \ + (GNOME_VFS_FILE_INFO_##which (info) ? "YES" : "NO") + + printf ("Name : %s\n", info->name); + + if(info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_TYPE) + printf ("Type : %s\n", type_to_string (info->type)); + + if(info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_SYMLINK_NAME && info->symlink_name != NULL) + printf ("Symlink to : %s\n", info->symlink_name); + + if(info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE) + printf ("MIME type : %s\n", info->mime_type); + + if(info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_SIZE) + printf ("Size : %" GNOME_VFS_SIZE_FORMAT_STR "\n", + info->size); + + if(info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_BLOCK_COUNT) + printf ("Blocks : %" GNOME_VFS_SIZE_FORMAT_STR "\n", + info->block_count); + + if(info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_IO_BLOCK_SIZE) + printf ("I/O block size : %d\n", info->io_block_size); + + if(info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_FLAGS) { + printf ("Local : %s\n", FLAG_STRING (info, LOCAL)); + printf ("SUID : %s\n", FLAG_STRING (info, SUID)); + printf ("SGID : %s\n", FLAG_STRING (info, SGID)); + printf ("Sticky : %s\n", FLAG_STRING (info, STICKY)); } + + if(info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS) + printf ("Permissions : %04o\n", info->permissions); + + + if(info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_LINK_COUNT) + printf ("Link count : %d\n", info->link_count); + + printf ("UID : %d\n", info->uid); + printf ("GID : %d\n", info->gid); + + if(info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_ATIME) + printf ("Access time : %s", ctime (&info->atime)); + + if(info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_MTIME) + printf ("Modification time : %s", ctime (&info->mtime)); + + if(info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_CTIME) + printf ("Change time : %s", ctime (&info->ctime)); + + if(info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_DEVICE) + printf ("Device # : %ld\n", (gulong) info->device); + + if(info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_INODE) + printf ("Inode # : %ld\n", (gulong) info->inode); + + if(info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_ACCESS) { + printf ("Readable : %s\n", + (info->permissions&GNOME_VFS_PERM_ACCESS_READABLE?"YES":"NO")); + printf ("Writable : %s\n", + (info->permissions&GNOME_VFS_PERM_ACCESS_WRITABLE?"YES":"NO")); + printf ("Executable : %s\n", + (info->permissions&GNOME_VFS_PERM_ACCESS_EXECUTABLE?"YES":"NO")); + } + +#undef FLAG_STRING +} + +int +main (int argc, char **argv) +{ + GnomeVFSFileInfo *info; + + if (argc != 2) { + fprintf (stderr, "Usage: %s \n", argv[0]); + return 1; + } + + if (! gnome_vfs_init ()) { + fprintf (stderr, "Cannot initialize gnome-vfs.\n"); + return 1; + } + + info = gnome_vfs_file_info_new (); + gnome_vfs_get_file_info (argv[1], info, + (GNOME_VFS_FILE_INFO_GET_MIME_TYPE + | GNOME_VFS_FILE_INFO_GET_ACCESS_RIGHTS + | GNOME_VFS_FILE_INFO_FOLLOW_LINKS)); + show_file_info (info); + + return 0; +} diff --git a/programs/gnomevfs-ls.c b/programs/gnomevfs-ls.c new file mode 100644 index 0000000..a0a9994 --- /dev/null +++ b/programs/gnomevfs-ls.c @@ -0,0 +1,125 @@ +/* gnomevfs-ls.c - Test for open_dir(), read_dir() and close_dir() for gnome-vfs + + Copyright (C) 2003, Red Hat + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Bastien Nocera +*/ + +#include + +char *directory; + +static void show_data (gpointer item, gpointer no_item); +static void list (void); + +static const gchar * +type_to_string (GnomeVFSFileType type) +{ + switch (type) { + case GNOME_VFS_FILE_TYPE_UNKNOWN: + return "Unknown"; + case GNOME_VFS_FILE_TYPE_REGULAR: + return "Regular"; + case GNOME_VFS_FILE_TYPE_DIRECTORY: + return "Directory"; + case GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK: + return "Symbolic Link"; + case GNOME_VFS_FILE_TYPE_FIFO: + return "FIFO"; + case GNOME_VFS_FILE_TYPE_SOCKET: + return "Socket"; + case GNOME_VFS_FILE_TYPE_CHARACTER_DEVICE: + return "Character device"; + case GNOME_VFS_FILE_TYPE_BLOCK_DEVICE: + return "Block device"; + default: + return "???"; + } +} + +static void +show_data (gpointer item, gpointer no_item) +{ + GnomeVFSFileInfo *info; + char *path; + + info = (GnomeVFSFileInfo *) item; + + path = g_strconcat (directory, "/", info->name, NULL); + + g_print ("%s\t%s%s%s\t(%s, %s)\tsize %ld\tmode %04o\n", + info->name, + GNOME_VFS_FILE_INFO_SYMLINK (info) ? " [link: " : "", + GNOME_VFS_FILE_INFO_SYMLINK (info) ? info->symlink_name + : "", + GNOME_VFS_FILE_INFO_SYMLINK (info) ? " ]" : "", + type_to_string (info->type), + info->mime_type, + (glong) info->size, + info->permissions); + + g_free (path); +} + +void +list (void) +{ + GnomeVFSResult result; + GnomeVFSFileInfo *info; + GnomeVFSDirectoryHandle *handle; + + result = gnome_vfs_directory_open (&handle, directory, + GNOME_VFS_FILE_INFO_GET_MIME_TYPE + | GNOME_VFS_FILE_INFO_FOLLOW_LINKS); + + if (result != GNOME_VFS_OK) + { + g_print("Error opening: %s\n", gnome_vfs_result_to_string + (result)); + return; + } + + info = gnome_vfs_file_info_new (); + while ((result = gnome_vfs_directory_read_next (handle, info)) == GNOME_VFS_OK) { + show_data ((gpointer) info, NULL); + } + + gnome_vfs_file_info_unref (info); + + if (result != GNOME_VFS_OK) { + g_print ("Error: %s\n", gnome_vfs_result_to_string (result)); + return; + } +} + +int +main (int argc, char *argv[]) +{ + gnome_vfs_init (); + + if (argc > 1) { + directory = argv[1]; + } else { + directory = g_get_current_dir (); + } + + list (); + + gnome_vfs_shutdown (); + return 0; +} diff --git a/programs/gnomevfs-mkdir.c b/programs/gnomevfs-mkdir.c new file mode 100644 index 0000000..cd77d0c --- /dev/null +++ b/programs/gnomevfs-mkdir.c @@ -0,0 +1,127 @@ +/* gnomevfs-mkdir.c - Test for mkdir() for gnome-vfs + + Copyright (C) 2003, Red Hat + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Bastien Nocera +*/ + +#include +#include +#include + +static GnomeVFSResult +make_directory_with_parents_for_uri (GnomeVFSURI * uri, + guint perm) +{ + GnomeVFSResult result; + GnomeVFSURI *parent, *work_uri; + GList *list = NULL; + + result = gnome_vfs_make_directory_for_uri (uri, perm); + if (result == GNOME_VFS_OK || result != GNOME_VFS_ERROR_NOT_FOUND) + return result; + + work_uri = uri; + + while (result == GNOME_VFS_ERROR_NOT_FOUND) { + parent = gnome_vfs_uri_get_parent (work_uri); + result = gnome_vfs_make_directory_for_uri (parent, perm); + + if (result == GNOME_VFS_ERROR_NOT_FOUND) + list = g_list_prepend (list, parent); + work_uri = parent; + } + + if (result != GNOME_VFS_OK) { + /* Clean up */ + while (list != NULL) { + gnome_vfs_uri_unref ((GnomeVFSURI *) list->data); + list = g_list_remove (list, list->data); + } + } + + while (result == GNOME_VFS_OK && list != NULL) { + result = gnome_vfs_make_directory_for_uri + ((GnomeVFSURI *) list->data, perm); + + gnome_vfs_uri_unref ((GnomeVFSURI *) list->data); + list = g_list_remove (list, list->data); + } + + result = gnome_vfs_make_directory_for_uri (uri, perm); + return result; +} + +static GnomeVFSResult +make_directory_with_parents (const gchar * text_uri, guint perm) +{ + GnomeVFSURI *uri; + GnomeVFSResult result; + + uri = gnome_vfs_uri_new (text_uri); + result = make_directory_with_parents_for_uri (uri, perm); + gnome_vfs_uri_unref (uri); + + return result; +} + +int +main (int argc, char *argv[]) +{ + gchar *directory; + GnomeVFSResult result; + gboolean with_parents; + + gnome_vfs_init (); + + if (argc > 1) { + if (strcmp (argv[1], "-p") == 0) { + directory = argv[2]; + with_parents = TRUE; + } else { + directory = argv[1]; + with_parents = FALSE; + } + } else { + fprintf (stderr, "Usage: %s [-p]

\n", argv[0]); + fprintf (stderr, " -p: Create parents of the directory if needed\n"); + return 0; + } + + if (with_parents) { + result = make_directory_with_parents (argv[1], + GNOME_VFS_PERM_USER_ALL + | GNOME_VFS_PERM_GROUP_ALL + | GNOME_VFS_PERM_OTHER_READ); + } else { + result = gnome_vfs_make_directory (argv[1], + GNOME_VFS_PERM_USER_ALL + | GNOME_VFS_PERM_GROUP_ALL + | GNOME_VFS_PERM_OTHER_READ); + } + + if (result != GNOME_VFS_OK) { + g_print ("Error making directory %s\nReason: %s\n", + directory, + gnome_vfs_result_to_string (result)); + return 0; + } + + gnome_vfs_shutdown (); + return 0; +} diff --git a/schemas/Makefile.am b/schemas/Makefile.am new file mode 100644 index 0000000..2999919 --- /dev/null +++ b/schemas/Makefile.am @@ -0,0 +1,18 @@ +schemadir = $(GCONF_SCHEMA_FILE_DIR) +schema_DATA = \ + system_http_proxy.schemas \ + desktop_default_applications.schemas + +# don't do this if we are building in eg. rpm +if GCONF_SCHEMAS_INSTALL +install-data-local: + if test -z "$(DESTDIR)" ; then \ + for p in $(schema_DATA) ; do \ + GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE) $(GCONFTOOL) --makefile-install-rule $(srcdir)/$$p; \ + done \ + fi +else +install-data-local: +endif + +EXTRA_DIST = $(schema_DATA) diff --git a/schemas/Makefile.in b/schemas/Makefile.in new file mode 100644 index 0000000..052e551 --- /dev/null +++ b/schemas/Makefile.in @@ -0,0 +1,319 @@ +# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ +AS = @AS@ +AWK = @AWK@ +BONOBO_ACTIVATION_REQUIRED = @BONOBO_ACTIVATION_REQUIRED@ +BONOBO_IDLDIR = @BONOBO_IDLDIR@ +BONOBO_REQUIRED = @BONOBO_REQUIRED@ +BZ2_LIBS = @BZ2_LIBS@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +DATADIRNAME = @DATADIRNAME@ +DB2HTML = @DB2HTML@ +DLLTOOL = @DLLTOOL@ +ECHO = @ECHO@ +ENABLE_PROFILER = @ENABLE_PROFILER@ +EXEEXT = @EXEEXT@ +FAM_LIBS = @FAM_LIBS@ +GCONFTOOL = @GCONFTOOL@ +GCONF_REQUIRED = @GCONF_REQUIRED@ +GCONF_SCHEMA_CONFIG_SOURCE = @GCONF_SCHEMA_CONFIG_SOURCE@ +GCONF_SCHEMA_FILE_DIR = @GCONF_SCHEMA_FILE_DIR@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GLIB_REQUIRED = @GLIB_REQUIRED@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GNOME_ACLOCAL_DIR = @GNOME_ACLOCAL_DIR@ +GNOME_ACLOCAL_FLAGS = @GNOME_ACLOCAL_FLAGS@ +GNOME_VFS_DIR = @GNOME_VFS_DIR@ +GTKDOC = @GTKDOC@ +HAVE_GTK_DOC = @HAVE_GTK_DOC@ +HTML_DIR = @HTML_DIR@ +INSTOBJEXT = @INSTOBJEXT@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_CAVES_RULE = @INTLTOOL_CAVES_RULE@ +INTLTOOL_DESKTOP_RULE = @INTLTOOL_DESKTOP_RULE@ +INTLTOOL_DIRECTORY_RULE = @INTLTOOL_DIRECTORY_RULE@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_KEYS_RULE = @INTLTOOL_KEYS_RULE@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_OAF_RULE = @INTLTOOL_OAF_RULE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_PONG_RULE = @INTLTOOL_PONG_RULE@ +INTLTOOL_PROP_RULE = @INTLTOOL_PROP_RULE@ +INTLTOOL_SCHEMAS_RULE = @INTLTOOL_SCHEMAS_RULE@ +INTLTOOL_SERVER_RULE = @INTLTOOL_SERVER_RULE@ +INTLTOOL_SHEET_RULE = @INTLTOOL_SHEET_RULE@ +INTLTOOL_SOUNDLIST_RULE = @INTLTOOL_SOUNDLIST_RULE@ +INTLTOOL_THEME_RULE = @INTLTOOL_THEME_RULE@ +INTLTOOL_UI_RULE = @INTLTOOL_UI_RULE@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTLTOOL_XML_RULE = @INTLTOOL_XML_RULE@ +LDFLAGS = @LDFLAGS@ +LIBEFS_CFLAGS = @LIBEFS_CFLAGS@ +LIBEFS_LIBS = @LIBEFS_LIBS@ +LIBGNOMEVFS_AGE = @LIBGNOMEVFS_AGE@ +LIBGNOMEVFS_CFLAGS = @LIBGNOMEVFS_CFLAGS@ +LIBGNOMEVFS_CURRENT = @LIBGNOMEVFS_CURRENT@ +LIBGNOMEVFS_LIBS = @LIBGNOMEVFS_LIBS@ +LIBGNOMEVFS_REVISION = @LIBGNOMEVFS_REVISION@ +LIBGNUTLS_CFLAGS = @LIBGNUTLS_CFLAGS@ +LIBGNUTLS_CONFIG = @LIBGNUTLS_CONFIG@ +LIBGNUTLS_LIBS = @LIBGNUTLS_LIBS@ +LIBIDL_REQUIRED = @LIBIDL_REQUIRED@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MODULES_CFLAGS = @MODULES_CFLAGS@ +MODULES_FILE_CFLAGS = @MODULES_FILE_CFLAGS@ +MODULES_FILE_LIBS = @MODULES_FILE_LIBS@ +MODULES_GCONF_CFLAGS = @MODULES_GCONF_CFLAGS@ +MODULES_GCONF_LIBS = @MODULES_GCONF_LIBS@ +MODULES_LIBS = @MODULES_LIBS@ +MODULES_XML_CFLAGS = @MODULES_XML_CFLAGS@ +MODULES_XML_GCONF_CFLAGS = @MODULES_XML_GCONF_CFLAGS@ +MODULES_XML_GCONF_LIBS = @MODULES_XML_GCONF_LIBS@ +MODULES_XML_LIBS = @MODULES_XML_LIBS@ +MONIKERS_CFLAGS = @MONIKERS_CFLAGS@ +MONIKERS_LIBS = @MONIKERS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ORBIT_IDL = @ORBIT_IDL@ +ORBIT_REQUIRED = @ORBIT_REQUIRED@ +PACKAGE = @PACKAGE@ +PKG_CONFIG = @PKG_CONFIG@ +POFILES = @POFILES@ +POPT_LIBS = @POPT_LIBS@ +POSUB = @POSUB@ +PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ +PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ +RANLIB = @RANLIB@ +STRIP = @STRIP@ +TEST_CFLAGS = @TEST_CFLAGS@ +TEST_LIBS = @TEST_LIBS@ +TOP_BUILDDIR = @TOP_BUILDDIR@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +VFS_CFLAGS = @VFS_CFLAGS@ +VFS_INCLUDEDIR = @VFS_INCLUDEDIR@ +VFS_LIBDIR = @VFS_LIBDIR@ +VFS_LIBS = @VFS_LIBS@ +VFS_OFFSET = @VFS_OFFSET@ +VFS_OFFSET_IS = @VFS_OFFSET_IS@ +VFS_OFFSET_PRINTF = @VFS_OFFSET_PRINTF@ +VFS_SIZE = @VFS_SIZE@ +VFS_SIZE_IS = @VFS_SIZE_IS@ +VFS_SIZE_PRINTF = @VFS_SIZE_PRINTF@ +WARN_CFLAGS = @WARN_CFLAGS@ +XML_REQUIRED = @XML_REQUIRED@ +cxxflags_set = @cxxflags_set@ + +schemadir = $(GCONF_SCHEMA_FILE_DIR) +schema_DATA = \ + system_http_proxy.schemas \ + desktop_default_applications.schemas + + +EXTRA_DIST = $(schema_DATA) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../config.h +CONFIG_CLEAN_FILES = +DATA = $(schema_DATA) + +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +all: all-redirect +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps schemas/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +install-schemaDATA: $(schema_DATA) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(schemadir) + @list='$(schema_DATA)'; for p in $$list; do \ + if test -f $(srcdir)/$$p; then \ + echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(schemadir)/$$p"; \ + $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(schemadir)/$$p; \ + else if test -f $$p; then \ + echo " $(INSTALL_DATA) $$p $(DESTDIR)$(schemadir)/$$p"; \ + $(INSTALL_DATA) $$p $(DESTDIR)$(schemadir)/$$p; \ + fi; fi; \ + done + +uninstall-schemaDATA: + @$(NORMAL_UNINSTALL) + list='$(schema_DATA)'; for p in $$list; do \ + rm -f $(DESTDIR)$(schemadir)/$$p; \ + done +tags: TAGS +TAGS: + + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = schemas + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: +install-exec: install-exec-am + +install-data-am: install-schemaDATA install-data-local +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-schemaDATA +uninstall: uninstall-am +all-am: Makefile $(DATA) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(schemadir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-generic clean-am + -rm -f libtool + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: uninstall-schemaDATA install-schemaDATA tags distdir info-am \ +info dvi-am dvi check check-am installcheck-am installcheck \ +install-exec-am install-exec install-data-local install-data-am \ +install-data install-am install uninstall-am uninstall all-redirect \ +all-am all installdirs mostlyclean-generic distclean-generic \ +clean-generic maintainer-clean-generic clean mostlyclean distclean \ +maintainer-clean + + +# don't do this if we are building in eg. rpm +@GCONF_SCHEMAS_INSTALL_TRUE@install-data-local: +@GCONF_SCHEMAS_INSTALL_TRUE@ if test -z "$(DESTDIR)" ; then \ +@GCONF_SCHEMAS_INSTALL_TRUE@ for p in $(schema_DATA) ; do \ +@GCONF_SCHEMAS_INSTALL_TRUE@ GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE) $(GCONFTOOL) --makefile-install-rule $(srcdir)/$$p; \ +@GCONF_SCHEMAS_INSTALL_TRUE@ done \ +@GCONF_SCHEMAS_INSTALL_TRUE@ fi +@GCONF_SCHEMAS_INSTALL_FALSE@install-data-local: + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/schemas/desktop_default_applications.schemas b/schemas/desktop_default_applications.schemas new file mode 100644 index 0000000..515aee0 --- /dev/null +++ b/schemas/desktop_default_applications.schemas @@ -0,0 +1,38 @@ + + + + + /schemas/desktop/gnome/applications/terminal/exec + /desktop/gnome/applications/terminal/exec + gnome-vfs + string + gnome-terminal + + Default terminal application + The default terminal application to use for applications that require a terminal. + + + + /schemas/desktop/gnome/applications/terminal/exec_arg + /desktop/gnome/applications/terminal/exec_arg + gnome-vfs + string + -x + + Exec argument for default terminal + The exec argument to use for the default terminal application. + + + + /schemas/desktop/gnome/applications/component_viewer/exec + /desktop/gnome/applications/component_viewer/exec + gnome-vfs + string + nautilus %s + + Default component viewer application + The application to use for viewing files that require a component to view them. The parameter %s will be replaced by the file's URIs, the parameter %c will be replaced by the component IID. + + + + diff --git a/schemas/system_http_proxy.schemas b/schemas/system_http_proxy.schemas new file mode 100644 index 0000000..19edb2c --- /dev/null +++ b/schemas/system_http_proxy.schemas @@ -0,0 +1,92 @@ + + + + + /schemas/system/http_proxy/use_http_proxy + /system/http_proxy/use_http_proxy + gnome-vfs + bool + false + + Use proxy settings when accessing http + Enables the proxy settings when accessing http over the + internet. + + + + /schemas/system/http_proxy/host + /system/http_proxy/host + gnome-vfs + string + + + Proxy host name + The machine name to proxy http through. + + + + /schemas/system/http_proxy/port + /system/http_proxy/port + gnome-vfs + int + 8080 + + Proxy port + The port on the machine defined by /system/http_proxy/host + that you proxy through + + + + /schemas/system/http_proxy/use_authentication + /system/http_proxy/use_authentication + gnome-vfs + bool + false + + Authenticate connections to the proxy server + If true, then connections to the proxy server require + authentication. The username/password combo defined by + /system/http_proxy/authentication_user and + /system/http_proxy/authentication_password. + + + + /schemas/system/http_proxy/authentication_user + /system/http_proxy/authentication_user + gnome-vfs + string + + + http proxy username + User name to pass as authentication when doing http proxying + + + + /schemas/system/http_proxy/authentication_password + /system/http_proxy/authentication_password + gnome-vfs + string + + + http proxy password + Password to pass as authentication when doing http proxying + + + + /schemas/system/http_proxy/ignore_hosts + /system/http_proxy/ignore_hosts + gnome-vfs + list + string + [localhost,127.0.0.0/8] + + Hosts are not contacted via the proxy + This key contains a list of hosts which are connected to + directly, rather than via the proxy (if it is active). The values can + be hostnames, domains (using an initial wildcard like *.foo.com), IP + host addresses (both IPv4 and IPv6) and network addresses with a + netmask (something like 192.168.0.0/24). + + + + diff --git a/stamp-h.in b/stamp-h.in new file mode 100644 index 0000000..9788f70 --- /dev/null +++ b/stamp-h.in @@ -0,0 +1 @@ +timestamp diff --git a/test/Makefile.am b/test/Makefile.am new file mode 100644 index 0000000..8787677 --- /dev/null +++ b/test/Makefile.am @@ -0,0 +1,160 @@ +NULL = + +INCLUDES = \ + -I$(top_srcdir) \ + -I$(top_builddir) \ + $(TEST_CFLAGS) \ + $(VFS_CFLAGS) \ + -DG_DISABLE_DEPRECATED \ + -DMODULES_PATH=\"$(libdir)/vfs/modules\" + +noinst_PROGRAMS = \ + test-async \ + test-async-cancel \ + test-async-directory \ + test-channel \ + test-directory \ + test-directory-visit \ + test-dirop \ + test-escape \ + test-find-directory \ + test-info \ + test-mime \ + test-mime-handlers \ + test-mime-handlers-set \ + test-mime-info \ + test-monitor \ + test-performance \ + test-seek \ + test-shell \ + test-symlinks \ + test-ssl \ + test-sync \ + test-sync-create \ + test-sync-write \ + test-unlink \ + test-uri \ + test-xfer \ + test-callback \ + test-module-selftest \ + test-queue \ + $(NULL) + +test_files= \ + test.input \ + test.cmds \ + test.output + +# Set up the environment so the tests can find the modules +TESTS_ENVIRONMENT = GNOME_VFS_MODULE_PATH=$(top_builddir)/modules/.libs \ + GNOME_VFS_MODULE_CONFIG_PATH=$(top_srcdir)/modules \ + GNOME_VFS_TEST_CONFIG_FILE=$(top_srcdir)/test/queue-test-config.xml \ + SRCDIR=$(srcdir) +TESTS = test-async-cancel test-escape test-uri test-queue $(srcdir)/auto-test + +libraries = \ + $(top_builddir)/libgnomevfs/libgnomevfs-2.la \ + $(TEST_LIBS) \ + $(POPT_LIBS) \ + $(LIBEFS_LIBS) + +test_async_SOURCES = test-async.c +test_async_LDADD = $(libraries) + +test_performance_SOURCES = test-performance.c +test_performance_LDADD = $(libraries) + +#test_resolv_SOURCES = test-resolv.c +#test_resolv_LDADD = $(libraries) + +#test_subdir_SOURCES = test-subdir.c +#test_subdir_LDADD = $(libraries) + +test_async_directory_SOURCES = test-async-directory.c +test_async_directory_LDADD = $(libraries) + +test_channel_SOURCES = test-channel.c +test_channel_LDADD = $(libraries) + +test_seek_SOURCES = test-seek.c +test_seek_LDADD = $(libraries) + +test_shell_SOURCES = test-shell.c +test_shell_LDADD = $(libraries) + +test_info_SOURCES = test-info.c +test_info_LDADD = $(libraries) + +test_mime_SOURCES = test-mime.c +test_mime_LDADD = $(libraries) + +test_mime_handlers_SOURCES = test-mime-handlers.c +test_mime_handlers_LDADD = $(libraries) + +test_mime_handlers_set_SOURCES = test-mime-handlers-set.c +test_mime_handlers_set_LDADD = $(libraries) + +test_xfer_SOURCES = test-xfer.c +test_xfer_LDADD = $(libraries) + +test_directory_SOURCES = test-directory.c +test_directory_LDADD = $(libraries) + +test_directory_visit_SOURCES = test-directory-visit.c +test_directory_visit_LDADD = $(libraries) + +test_symlinks_SOURCES = test-symlinks.c +test_symlinks_LDADD = $(libraries) + +test_ssl_SOURCES = test-ssl.c +test_ssl_LDADD = $(libraries) + +test_sync_SOURCES = test-sync.c +test_sync_LDADD = $(libraries) + +test_sync_write_SOURCES = test-sync-write.c +test_sync_write_LDADD = $(libraries) + +test_sync_create_SOURCES = test-sync-create.c +test_sync_create_LDADD = $(libraries) + +test_async_cancel_SOURCES = test-async-cancel.c +test_async_cancel_LDADD = $(libraries) + +test_escape_SOURCES = test-escape.c +test_escape_LDADD = $(libraries) + +test_uri_SOURCES = test-uri.c +test_uri_LDADD = $(libraries) + +test_unlink_SOURCES = test-unlink.c +test_unlink_LDADD = $(libraries) + +test_dirop_SOURCES = test-dirop.c +test_dirop_LDADD = $(libraries) + +test_find_directory_SOURCES = test-find-directory.c +test_find_directory_LDADD = $(libraries) + +test_mime_info_SOURCES = test-mime-info.c +test_mime_info_LDADD = $(libraries) + +test_monitor_SOURCES = test-monitor.c +test_monitor_LDADD = $(libraries) + +# test_metadata_SOURCES = test-metadata.c +# test_metadata_LDADD = $(libraries) + +test_callback_SOURCES = test-callback.c +test_callback_LDADD = $(libraries) + +test_module_selftest_SOURCES = test-module-selftest.c +test_module_selftest_LDADD = $(libraries) + +test_queue_SOURCES = test-queue.c +test_queue_LDADD = $(libraries) + +EXTRA_DIST = \ + $(test_files) \ + auto-test \ + vfs-run.in diff --git a/test/Makefile.in b/test/Makefile.in new file mode 100644 index 0000000..e0d35f3 --- /dev/null +++ b/test/Makefile.in @@ -0,0 +1,1152 @@ +# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ +AS = @AS@ +AWK = @AWK@ +BONOBO_ACTIVATION_REQUIRED = @BONOBO_ACTIVATION_REQUIRED@ +BONOBO_IDLDIR = @BONOBO_IDLDIR@ +BONOBO_REQUIRED = @BONOBO_REQUIRED@ +BZ2_LIBS = @BZ2_LIBS@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +DATADIRNAME = @DATADIRNAME@ +DB2HTML = @DB2HTML@ +DLLTOOL = @DLLTOOL@ +ECHO = @ECHO@ +ENABLE_PROFILER = @ENABLE_PROFILER@ +EXEEXT = @EXEEXT@ +FAM_LIBS = @FAM_LIBS@ +GCONFTOOL = @GCONFTOOL@ +GCONF_REQUIRED = @GCONF_REQUIRED@ +GCONF_SCHEMA_CONFIG_SOURCE = @GCONF_SCHEMA_CONFIG_SOURCE@ +GCONF_SCHEMA_FILE_DIR = @GCONF_SCHEMA_FILE_DIR@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GLIB_REQUIRED = @GLIB_REQUIRED@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GNOME_ACLOCAL_DIR = @GNOME_ACLOCAL_DIR@ +GNOME_ACLOCAL_FLAGS = @GNOME_ACLOCAL_FLAGS@ +GNOME_VFS_DIR = @GNOME_VFS_DIR@ +GTKDOC = @GTKDOC@ +HAVE_GTK_DOC = @HAVE_GTK_DOC@ +HTML_DIR = @HTML_DIR@ +INSTOBJEXT = @INSTOBJEXT@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_CAVES_RULE = @INTLTOOL_CAVES_RULE@ +INTLTOOL_DESKTOP_RULE = @INTLTOOL_DESKTOP_RULE@ +INTLTOOL_DIRECTORY_RULE = @INTLTOOL_DIRECTORY_RULE@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_KEYS_RULE = @INTLTOOL_KEYS_RULE@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_OAF_RULE = @INTLTOOL_OAF_RULE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_PONG_RULE = @INTLTOOL_PONG_RULE@ +INTLTOOL_PROP_RULE = @INTLTOOL_PROP_RULE@ +INTLTOOL_SCHEMAS_RULE = @INTLTOOL_SCHEMAS_RULE@ +INTLTOOL_SERVER_RULE = @INTLTOOL_SERVER_RULE@ +INTLTOOL_SHEET_RULE = @INTLTOOL_SHEET_RULE@ +INTLTOOL_SOUNDLIST_RULE = @INTLTOOL_SOUNDLIST_RULE@ +INTLTOOL_THEME_RULE = @INTLTOOL_THEME_RULE@ +INTLTOOL_UI_RULE = @INTLTOOL_UI_RULE@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTLTOOL_XML_RULE = @INTLTOOL_XML_RULE@ +LDFLAGS = @LDFLAGS@ +LIBEFS_CFLAGS = @LIBEFS_CFLAGS@ +LIBEFS_LIBS = @LIBEFS_LIBS@ +LIBGNOMEVFS_AGE = @LIBGNOMEVFS_AGE@ +LIBGNOMEVFS_CFLAGS = @LIBGNOMEVFS_CFLAGS@ +LIBGNOMEVFS_CURRENT = @LIBGNOMEVFS_CURRENT@ +LIBGNOMEVFS_LIBS = @LIBGNOMEVFS_LIBS@ +LIBGNOMEVFS_REVISION = @LIBGNOMEVFS_REVISION@ +LIBGNUTLS_CFLAGS = @LIBGNUTLS_CFLAGS@ +LIBGNUTLS_CONFIG = @LIBGNUTLS_CONFIG@ +LIBGNUTLS_LIBS = @LIBGNUTLS_LIBS@ +LIBIDL_REQUIRED = @LIBIDL_REQUIRED@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MODULES_CFLAGS = @MODULES_CFLAGS@ +MODULES_FILE_CFLAGS = @MODULES_FILE_CFLAGS@ +MODULES_FILE_LIBS = @MODULES_FILE_LIBS@ +MODULES_GCONF_CFLAGS = @MODULES_GCONF_CFLAGS@ +MODULES_GCONF_LIBS = @MODULES_GCONF_LIBS@ +MODULES_LIBS = @MODULES_LIBS@ +MODULES_XML_CFLAGS = @MODULES_XML_CFLAGS@ +MODULES_XML_GCONF_CFLAGS = @MODULES_XML_GCONF_CFLAGS@ +MODULES_XML_GCONF_LIBS = @MODULES_XML_GCONF_LIBS@ +MODULES_XML_LIBS = @MODULES_XML_LIBS@ +MONIKERS_CFLAGS = @MONIKERS_CFLAGS@ +MONIKERS_LIBS = @MONIKERS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ORBIT_IDL = @ORBIT_IDL@ +ORBIT_REQUIRED = @ORBIT_REQUIRED@ +PACKAGE = @PACKAGE@ +PKG_CONFIG = @PKG_CONFIG@ +POFILES = @POFILES@ +POPT_LIBS = @POPT_LIBS@ +POSUB = @POSUB@ +PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ +PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ +RANLIB = @RANLIB@ +STRIP = @STRIP@ +TEST_CFLAGS = @TEST_CFLAGS@ +TEST_LIBS = @TEST_LIBS@ +TOP_BUILDDIR = @TOP_BUILDDIR@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +VFS_CFLAGS = @VFS_CFLAGS@ +VFS_INCLUDEDIR = @VFS_INCLUDEDIR@ +VFS_LIBDIR = @VFS_LIBDIR@ +VFS_LIBS = @VFS_LIBS@ +VFS_OFFSET = @VFS_OFFSET@ +VFS_OFFSET_IS = @VFS_OFFSET_IS@ +VFS_OFFSET_PRINTF = @VFS_OFFSET_PRINTF@ +VFS_SIZE = @VFS_SIZE@ +VFS_SIZE_IS = @VFS_SIZE_IS@ +VFS_SIZE_PRINTF = @VFS_SIZE_PRINTF@ +WARN_CFLAGS = @WARN_CFLAGS@ +XML_REQUIRED = @XML_REQUIRED@ +cxxflags_set = @cxxflags_set@ + +NULL = + +INCLUDES = \ + -I$(top_srcdir) \ + -I$(top_builddir) \ + $(TEST_CFLAGS) \ + $(VFS_CFLAGS) \ + -DG_DISABLE_DEPRECATED \ + -DMODULES_PATH=\"$(libdir)/vfs/modules\" + + +noinst_PROGRAMS = \ + test-async \ + test-async-cancel \ + test-async-directory \ + test-channel \ + test-directory \ + test-directory-visit \ + test-dirop \ + test-escape \ + test-find-directory \ + test-info \ + test-mime \ + test-mime-handlers \ + test-mime-handlers-set \ + test-mime-info \ + test-monitor \ + test-performance \ + test-seek \ + test-shell \ + test-symlinks \ + test-ssl \ + test-sync \ + test-sync-create \ + test-sync-write \ + test-unlink \ + test-uri \ + test-xfer \ + test-callback \ + test-module-selftest \ + test-queue \ + $(NULL) + + +test_files = \ + test.input \ + test.cmds \ + test.output + + +# Set up the environment so the tests can find the modules +TESTS_ENVIRONMENT = GNOME_VFS_MODULE_PATH=$(top_builddir)/modules/.libs \ + GNOME_VFS_MODULE_CONFIG_PATH=$(top_srcdir)/modules \ + GNOME_VFS_TEST_CONFIG_FILE=$(top_srcdir)/test/queue-test-config.xml \ + SRCDIR=$(srcdir) + +TESTS = test-async-cancel test-escape test-uri test-queue $(srcdir)/auto-test + +libraries = \ + $(top_builddir)/libgnomevfs/libgnomevfs-2.la \ + $(TEST_LIBS) \ + $(POPT_LIBS) \ + $(LIBEFS_LIBS) + + +test_async_SOURCES = test-async.c +test_async_LDADD = $(libraries) + +test_performance_SOURCES = test-performance.c +test_performance_LDADD = $(libraries) + +#test_resolv_SOURCES = test-resolv.c +#test_resolv_LDADD = $(libraries) + +#test_subdir_SOURCES = test-subdir.c +#test_subdir_LDADD = $(libraries) + +test_async_directory_SOURCES = test-async-directory.c +test_async_directory_LDADD = $(libraries) + +test_channel_SOURCES = test-channel.c +test_channel_LDADD = $(libraries) + +test_seek_SOURCES = test-seek.c +test_seek_LDADD = $(libraries) + +test_shell_SOURCES = test-shell.c +test_shell_LDADD = $(libraries) + +test_info_SOURCES = test-info.c +test_info_LDADD = $(libraries) + +test_mime_SOURCES = test-mime.c +test_mime_LDADD = $(libraries) + +test_mime_handlers_SOURCES = test-mime-handlers.c +test_mime_handlers_LDADD = $(libraries) + +test_mime_handlers_set_SOURCES = test-mime-handlers-set.c +test_mime_handlers_set_LDADD = $(libraries) + +test_xfer_SOURCES = test-xfer.c +test_xfer_LDADD = $(libraries) + +test_directory_SOURCES = test-directory.c +test_directory_LDADD = $(libraries) + +test_directory_visit_SOURCES = test-directory-visit.c +test_directory_visit_LDADD = $(libraries) + +test_symlinks_SOURCES = test-symlinks.c +test_symlinks_LDADD = $(libraries) + +test_ssl_SOURCES = test-ssl.c +test_ssl_LDADD = $(libraries) + +test_sync_SOURCES = test-sync.c +test_sync_LDADD = $(libraries) + +test_sync_write_SOURCES = test-sync-write.c +test_sync_write_LDADD = $(libraries) + +test_sync_create_SOURCES = test-sync-create.c +test_sync_create_LDADD = $(libraries) + +test_async_cancel_SOURCES = test-async-cancel.c +test_async_cancel_LDADD = $(libraries) + +test_escape_SOURCES = test-escape.c +test_escape_LDADD = $(libraries) + +test_uri_SOURCES = test-uri.c +test_uri_LDADD = $(libraries) + +test_unlink_SOURCES = test-unlink.c +test_unlink_LDADD = $(libraries) + +test_dirop_SOURCES = test-dirop.c +test_dirop_LDADD = $(libraries) + +test_find_directory_SOURCES = test-find-directory.c +test_find_directory_LDADD = $(libraries) + +test_mime_info_SOURCES = test-mime-info.c +test_mime_info_LDADD = $(libraries) + +test_monitor_SOURCES = test-monitor.c +test_monitor_LDADD = $(libraries) + +# test_metadata_SOURCES = test-metadata.c +# test_metadata_LDADD = $(libraries) + +test_callback_SOURCES = test-callback.c +test_callback_LDADD = $(libraries) + +test_module_selftest_SOURCES = test-module-selftest.c +test_module_selftest_LDADD = $(libraries) + +test_queue_SOURCES = test-queue.c +test_queue_LDADD = $(libraries) + +EXTRA_DIST = \ + $(test_files) \ + auto-test \ + vfs-run.in + +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../config.h +CONFIG_CLEAN_FILES = vfs-run +noinst_PROGRAMS = test-async$(EXEEXT) test-async-cancel$(EXEEXT) \ +test-async-directory$(EXEEXT) test-channel$(EXEEXT) \ +test-directory$(EXEEXT) test-directory-visit$(EXEEXT) \ +test-dirop$(EXEEXT) test-escape$(EXEEXT) test-find-directory$(EXEEXT) \ +test-info$(EXEEXT) test-mime$(EXEEXT) test-mime-handlers$(EXEEXT) \ +test-mime-handlers-set$(EXEEXT) test-mime-info$(EXEEXT) \ +test-monitor$(EXEEXT) test-performance$(EXEEXT) test-seek$(EXEEXT) \ +test-shell$(EXEEXT) test-symlinks$(EXEEXT) test-ssl$(EXEEXT) \ +test-sync$(EXEEXT) test-sync-create$(EXEEXT) test-sync-write$(EXEEXT) \ +test-unlink$(EXEEXT) test-uri$(EXEEXT) test-xfer$(EXEEXT) \ +test-callback$(EXEEXT) test-module-selftest$(EXEEXT) \ +test-queue$(EXEEXT) +PROGRAMS = $(noinst_PROGRAMS) + + +DEFS = @DEFS@ -I. -I$(srcdir) -I.. +LIBS = @LIBS@ +test_async_OBJECTS = test-async.$(OBJEXT) +test_async_DEPENDENCIES = $(top_builddir)/libgnomevfs/libgnomevfs-2.la +test_async_LDFLAGS = +test_async_cancel_OBJECTS = test-async-cancel.$(OBJEXT) +test_async_cancel_DEPENDENCIES = \ +$(top_builddir)/libgnomevfs/libgnomevfs-2.la +test_async_cancel_LDFLAGS = +test_async_directory_OBJECTS = test-async-directory.$(OBJEXT) +test_async_directory_DEPENDENCIES = \ +$(top_builddir)/libgnomevfs/libgnomevfs-2.la +test_async_directory_LDFLAGS = +test_channel_OBJECTS = test-channel.$(OBJEXT) +test_channel_DEPENDENCIES = \ +$(top_builddir)/libgnomevfs/libgnomevfs-2.la +test_channel_LDFLAGS = +test_directory_OBJECTS = test-directory.$(OBJEXT) +test_directory_DEPENDENCIES = \ +$(top_builddir)/libgnomevfs/libgnomevfs-2.la +test_directory_LDFLAGS = +test_directory_visit_OBJECTS = test-directory-visit.$(OBJEXT) +test_directory_visit_DEPENDENCIES = \ +$(top_builddir)/libgnomevfs/libgnomevfs-2.la +test_directory_visit_LDFLAGS = +test_dirop_OBJECTS = test-dirop.$(OBJEXT) +test_dirop_DEPENDENCIES = $(top_builddir)/libgnomevfs/libgnomevfs-2.la +test_dirop_LDFLAGS = +test_escape_OBJECTS = test-escape.$(OBJEXT) +test_escape_DEPENDENCIES = $(top_builddir)/libgnomevfs/libgnomevfs-2.la +test_escape_LDFLAGS = +test_find_directory_OBJECTS = test-find-directory.$(OBJEXT) +test_find_directory_DEPENDENCIES = \ +$(top_builddir)/libgnomevfs/libgnomevfs-2.la +test_find_directory_LDFLAGS = +test_info_OBJECTS = test-info.$(OBJEXT) +test_info_DEPENDENCIES = $(top_builddir)/libgnomevfs/libgnomevfs-2.la +test_info_LDFLAGS = +test_mime_OBJECTS = test-mime.$(OBJEXT) +test_mime_DEPENDENCIES = $(top_builddir)/libgnomevfs/libgnomevfs-2.la +test_mime_LDFLAGS = +test_mime_handlers_OBJECTS = test-mime-handlers.$(OBJEXT) +test_mime_handlers_DEPENDENCIES = \ +$(top_builddir)/libgnomevfs/libgnomevfs-2.la +test_mime_handlers_LDFLAGS = +test_mime_handlers_set_OBJECTS = test-mime-handlers-set.$(OBJEXT) +test_mime_handlers_set_DEPENDENCIES = \ +$(top_builddir)/libgnomevfs/libgnomevfs-2.la +test_mime_handlers_set_LDFLAGS = +test_mime_info_OBJECTS = test-mime-info.$(OBJEXT) +test_mime_info_DEPENDENCIES = \ +$(top_builddir)/libgnomevfs/libgnomevfs-2.la +test_mime_info_LDFLAGS = +test_monitor_OBJECTS = test-monitor.$(OBJEXT) +test_monitor_DEPENDENCIES = \ +$(top_builddir)/libgnomevfs/libgnomevfs-2.la +test_monitor_LDFLAGS = +test_performance_OBJECTS = test-performance.$(OBJEXT) +test_performance_DEPENDENCIES = \ +$(top_builddir)/libgnomevfs/libgnomevfs-2.la +test_performance_LDFLAGS = +test_seek_OBJECTS = test-seek.$(OBJEXT) +test_seek_DEPENDENCIES = $(top_builddir)/libgnomevfs/libgnomevfs-2.la +test_seek_LDFLAGS = +test_shell_OBJECTS = test-shell.$(OBJEXT) +test_shell_DEPENDENCIES = $(top_builddir)/libgnomevfs/libgnomevfs-2.la +test_shell_LDFLAGS = +test_symlinks_OBJECTS = test-symlinks.$(OBJEXT) +test_symlinks_DEPENDENCIES = \ +$(top_builddir)/libgnomevfs/libgnomevfs-2.la +test_symlinks_LDFLAGS = +test_ssl_OBJECTS = test-ssl.$(OBJEXT) +test_ssl_DEPENDENCIES = $(top_builddir)/libgnomevfs/libgnomevfs-2.la +test_ssl_LDFLAGS = +test_sync_OBJECTS = test-sync.$(OBJEXT) +test_sync_DEPENDENCIES = $(top_builddir)/libgnomevfs/libgnomevfs-2.la +test_sync_LDFLAGS = +test_sync_create_OBJECTS = test-sync-create.$(OBJEXT) +test_sync_create_DEPENDENCIES = \ +$(top_builddir)/libgnomevfs/libgnomevfs-2.la +test_sync_create_LDFLAGS = +test_sync_write_OBJECTS = test-sync-write.$(OBJEXT) +test_sync_write_DEPENDENCIES = \ +$(top_builddir)/libgnomevfs/libgnomevfs-2.la +test_sync_write_LDFLAGS = +test_unlink_OBJECTS = test-unlink.$(OBJEXT) +test_unlink_DEPENDENCIES = $(top_builddir)/libgnomevfs/libgnomevfs-2.la +test_unlink_LDFLAGS = +test_uri_OBJECTS = test-uri.$(OBJEXT) +test_uri_DEPENDENCIES = $(top_builddir)/libgnomevfs/libgnomevfs-2.la +test_uri_LDFLAGS = +test_xfer_OBJECTS = test-xfer.$(OBJEXT) +test_xfer_DEPENDENCIES = $(top_builddir)/libgnomevfs/libgnomevfs-2.la +test_xfer_LDFLAGS = +test_callback_OBJECTS = test-callback.$(OBJEXT) +test_callback_DEPENDENCIES = \ +$(top_builddir)/libgnomevfs/libgnomevfs-2.la +test_callback_LDFLAGS = +test_module_selftest_OBJECTS = test-module-selftest.$(OBJEXT) +test_module_selftest_DEPENDENCIES = \ +$(top_builddir)/libgnomevfs/libgnomevfs-2.la +test_module_selftest_LDFLAGS = +test_queue_OBJECTS = test-queue.$(OBJEXT) +test_queue_DEPENDENCIES = $(top_builddir)/libgnomevfs/libgnomevfs-2.la +test_queue_LDFLAGS = +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +DIST_COMMON = Makefile.am Makefile.in vfs-run.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +SOURCES = $(test_async_SOURCES) $(test_async_cancel_SOURCES) $(test_async_directory_SOURCES) $(test_channel_SOURCES) $(test_directory_SOURCES) $(test_directory_visit_SOURCES) $(test_dirop_SOURCES) $(test_escape_SOURCES) $(test_find_directory_SOURCES) $(test_info_SOURCES) $(test_mime_SOURCES) $(test_mime_handlers_SOURCES) $(test_mime_handlers_set_SOURCES) $(test_mime_info_SOURCES) $(test_monitor_SOURCES) $(test_performance_SOURCES) $(test_seek_SOURCES) $(test_shell_SOURCES) $(test_symlinks_SOURCES) $(test_ssl_SOURCES) $(test_sync_SOURCES) $(test_sync_create_SOURCES) $(test_sync_write_SOURCES) $(test_unlink_SOURCES) $(test_uri_SOURCES) $(test_xfer_SOURCES) $(test_callback_SOURCES) $(test_module_selftest_SOURCES) $(test_queue_SOURCES) +OBJECTS = $(test_async_OBJECTS) $(test_async_cancel_OBJECTS) $(test_async_directory_OBJECTS) $(test_channel_OBJECTS) $(test_directory_OBJECTS) $(test_directory_visit_OBJECTS) $(test_dirop_OBJECTS) $(test_escape_OBJECTS) $(test_find_directory_OBJECTS) $(test_info_OBJECTS) $(test_mime_OBJECTS) $(test_mime_handlers_OBJECTS) $(test_mime_handlers_set_OBJECTS) $(test_mime_info_OBJECTS) $(test_monitor_OBJECTS) $(test_performance_OBJECTS) $(test_seek_OBJECTS) $(test_shell_OBJECTS) $(test_symlinks_OBJECTS) $(test_ssl_OBJECTS) $(test_sync_OBJECTS) $(test_sync_create_OBJECTS) $(test_sync_write_OBJECTS) $(test_unlink_OBJECTS) $(test_uri_OBJECTS) $(test_xfer_OBJECTS) $(test_callback_OBJECTS) $(test_module_selftest_OBJECTS) $(test_queue_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .lo .o .obj .s +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps test/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + +vfs-run: $(top_builddir)/config.status vfs-run.in + cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + +mostlyclean-noinstPROGRAMS: + +clean-noinstPROGRAMS: + -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) + +distclean-noinstPROGRAMS: + +maintainer-clean-noinstPROGRAMS: + +.c.o: + $(COMPILE) -c $< + +# FIXME: We should only use cygpath when building on Windows, +# and only if it is available. +.c.obj: + $(COMPILE) -c `cygpath -w $<` + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + -rm -f *.$(OBJEXT) + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +.c.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.s.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.S.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + +maintainer-clean-libtool: + +test-async$(EXEEXT): $(test_async_OBJECTS) $(test_async_DEPENDENCIES) + @rm -f test-async$(EXEEXT) + $(LINK) $(test_async_LDFLAGS) $(test_async_OBJECTS) $(test_async_LDADD) $(LIBS) + +test-async-cancel$(EXEEXT): $(test_async_cancel_OBJECTS) $(test_async_cancel_DEPENDENCIES) + @rm -f test-async-cancel$(EXEEXT) + $(LINK) $(test_async_cancel_LDFLAGS) $(test_async_cancel_OBJECTS) $(test_async_cancel_LDADD) $(LIBS) + +test-async-directory$(EXEEXT): $(test_async_directory_OBJECTS) $(test_async_directory_DEPENDENCIES) + @rm -f test-async-directory$(EXEEXT) + $(LINK) $(test_async_directory_LDFLAGS) $(test_async_directory_OBJECTS) $(test_async_directory_LDADD) $(LIBS) + +test-channel$(EXEEXT): $(test_channel_OBJECTS) $(test_channel_DEPENDENCIES) + @rm -f test-channel$(EXEEXT) + $(LINK) $(test_channel_LDFLAGS) $(test_channel_OBJECTS) $(test_channel_LDADD) $(LIBS) + +test-directory$(EXEEXT): $(test_directory_OBJECTS) $(test_directory_DEPENDENCIES) + @rm -f test-directory$(EXEEXT) + $(LINK) $(test_directory_LDFLAGS) $(test_directory_OBJECTS) $(test_directory_LDADD) $(LIBS) + +test-directory-visit$(EXEEXT): $(test_directory_visit_OBJECTS) $(test_directory_visit_DEPENDENCIES) + @rm -f test-directory-visit$(EXEEXT) + $(LINK) $(test_directory_visit_LDFLAGS) $(test_directory_visit_OBJECTS) $(test_directory_visit_LDADD) $(LIBS) + +test-dirop$(EXEEXT): $(test_dirop_OBJECTS) $(test_dirop_DEPENDENCIES) + @rm -f test-dirop$(EXEEXT) + $(LINK) $(test_dirop_LDFLAGS) $(test_dirop_OBJECTS) $(test_dirop_LDADD) $(LIBS) + +test-escape$(EXEEXT): $(test_escape_OBJECTS) $(test_escape_DEPENDENCIES) + @rm -f test-escape$(EXEEXT) + $(LINK) $(test_escape_LDFLAGS) $(test_escape_OBJECTS) $(test_escape_LDADD) $(LIBS) + +test-find-directory$(EXEEXT): $(test_find_directory_OBJECTS) $(test_find_directory_DEPENDENCIES) + @rm -f test-find-directory$(EXEEXT) + $(LINK) $(test_find_directory_LDFLAGS) $(test_find_directory_OBJECTS) $(test_find_directory_LDADD) $(LIBS) + +test-info$(EXEEXT): $(test_info_OBJECTS) $(test_info_DEPENDENCIES) + @rm -f test-info$(EXEEXT) + $(LINK) $(test_info_LDFLAGS) $(test_info_OBJECTS) $(test_info_LDADD) $(LIBS) + +test-mime$(EXEEXT): $(test_mime_OBJECTS) $(test_mime_DEPENDENCIES) + @rm -f test-mime$(EXEEXT) + $(LINK) $(test_mime_LDFLAGS) $(test_mime_OBJECTS) $(test_mime_LDADD) $(LIBS) + +test-mime-handlers$(EXEEXT): $(test_mime_handlers_OBJECTS) $(test_mime_handlers_DEPENDENCIES) + @rm -f test-mime-handlers$(EXEEXT) + $(LINK) $(test_mime_handlers_LDFLAGS) $(test_mime_handlers_OBJECTS) $(test_mime_handlers_LDADD) $(LIBS) + +test-mime-handlers-set$(EXEEXT): $(test_mime_handlers_set_OBJECTS) $(test_mime_handlers_set_DEPENDENCIES) + @rm -f test-mime-handlers-set$(EXEEXT) + $(LINK) $(test_mime_handlers_set_LDFLAGS) $(test_mime_handlers_set_OBJECTS) $(test_mime_handlers_set_LDADD) $(LIBS) + +test-mime-info$(EXEEXT): $(test_mime_info_OBJECTS) $(test_mime_info_DEPENDENCIES) + @rm -f test-mime-info$(EXEEXT) + $(LINK) $(test_mime_info_LDFLAGS) $(test_mime_info_OBJECTS) $(test_mime_info_LDADD) $(LIBS) + +test-monitor$(EXEEXT): $(test_monitor_OBJECTS) $(test_monitor_DEPENDENCIES) + @rm -f test-monitor$(EXEEXT) + $(LINK) $(test_monitor_LDFLAGS) $(test_monitor_OBJECTS) $(test_monitor_LDADD) $(LIBS) + +test-performance$(EXEEXT): $(test_performance_OBJECTS) $(test_performance_DEPENDENCIES) + @rm -f test-performance$(EXEEXT) + $(LINK) $(test_performance_LDFLAGS) $(test_performance_OBJECTS) $(test_performance_LDADD) $(LIBS) + +test-seek$(EXEEXT): $(test_seek_OBJECTS) $(test_seek_DEPENDENCIES) + @rm -f test-seek$(EXEEXT) + $(LINK) $(test_seek_LDFLAGS) $(test_seek_OBJECTS) $(test_seek_LDADD) $(LIBS) + +test-shell$(EXEEXT): $(test_shell_OBJECTS) $(test_shell_DEPENDENCIES) + @rm -f test-shell$(EXEEXT) + $(LINK) $(test_shell_LDFLAGS) $(test_shell_OBJECTS) $(test_shell_LDADD) $(LIBS) + +test-symlinks$(EXEEXT): $(test_symlinks_OBJECTS) $(test_symlinks_DEPENDENCIES) + @rm -f test-symlinks$(EXEEXT) + $(LINK) $(test_symlinks_LDFLAGS) $(test_symlinks_OBJECTS) $(test_symlinks_LDADD) $(LIBS) + +test-ssl$(EXEEXT): $(test_ssl_OBJECTS) $(test_ssl_DEPENDENCIES) + @rm -f test-ssl$(EXEEXT) + $(LINK) $(test_ssl_LDFLAGS) $(test_ssl_OBJECTS) $(test_ssl_LDADD) $(LIBS) + +test-sync$(EXEEXT): $(test_sync_OBJECTS) $(test_sync_DEPENDENCIES) + @rm -f test-sync$(EXEEXT) + $(LINK) $(test_sync_LDFLAGS) $(test_sync_OBJECTS) $(test_sync_LDADD) $(LIBS) + +test-sync-create$(EXEEXT): $(test_sync_create_OBJECTS) $(test_sync_create_DEPENDENCIES) + @rm -f test-sync-create$(EXEEXT) + $(LINK) $(test_sync_create_LDFLAGS) $(test_sync_create_OBJECTS) $(test_sync_create_LDADD) $(LIBS) + +test-sync-write$(EXEEXT): $(test_sync_write_OBJECTS) $(test_sync_write_DEPENDENCIES) + @rm -f test-sync-write$(EXEEXT) + $(LINK) $(test_sync_write_LDFLAGS) $(test_sync_write_OBJECTS) $(test_sync_write_LDADD) $(LIBS) + +test-unlink$(EXEEXT): $(test_unlink_OBJECTS) $(test_unlink_DEPENDENCIES) + @rm -f test-unlink$(EXEEXT) + $(LINK) $(test_unlink_LDFLAGS) $(test_unlink_OBJECTS) $(test_unlink_LDADD) $(LIBS) + +test-uri$(EXEEXT): $(test_uri_OBJECTS) $(test_uri_DEPENDENCIES) + @rm -f test-uri$(EXEEXT) + $(LINK) $(test_uri_LDFLAGS) $(test_uri_OBJECTS) $(test_uri_LDADD) $(LIBS) + +test-xfer$(EXEEXT): $(test_xfer_OBJECTS) $(test_xfer_DEPENDENCIES) + @rm -f test-xfer$(EXEEXT) + $(LINK) $(test_xfer_LDFLAGS) $(test_xfer_OBJECTS) $(test_xfer_LDADD) $(LIBS) + +test-callback$(EXEEXT): $(test_callback_OBJECTS) $(test_callback_DEPENDENCIES) + @rm -f test-callback$(EXEEXT) + $(LINK) $(test_callback_LDFLAGS) $(test_callback_OBJECTS) $(test_callback_LDADD) $(LIBS) + +test-module-selftest$(EXEEXT): $(test_module_selftest_OBJECTS) $(test_module_selftest_DEPENDENCIES) + @rm -f test-module-selftest$(EXEEXT) + $(LINK) $(test_module_selftest_LDFLAGS) $(test_module_selftest_OBJECTS) $(test_module_selftest_LDADD) $(LIBS) + +test-queue$(EXEEXT): $(test_queue_OBJECTS) $(test_queue_DEPENDENCIES) + @rm -f test-queue$(EXEEXT) + $(LINK) $(test_queue_LDFLAGS) $(test_queue_OBJECTS) $(test_queue_LDADD) $(LIBS) + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = test + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +test-async-cancel.o: test-async-cancel.c ../config.h \ + ../libgnomevfs/gnome-vfs-async-ops.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-find-directory.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-xfer.h ../libgnomevfs/gnome-vfs-init.h \ + ../libgnomevfs/gnome-vfs-job.h \ + ../libgnomevfs/gnome-vfs-module-callback.h \ + ../libgnomevfs/gnome-vfs-module-callback-private.h +test-async-directory.o: test-async-directory.c ../config.h \ + ../libgnomevfs/gnome-vfs-async-ops.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-find-directory.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-xfer.h ../libgnomevfs/gnome-vfs-init.h +test-async.o: test-async.c ../config.h \ + ../libgnomevfs/gnome-vfs-async-ops.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-find-directory.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-xfer.h ../libgnomevfs/gnome-vfs-init.h +test-callback.o: test-callback.c ../config.h \ + ../libgnomevfs/gnome-vfs-async-ops.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-find-directory.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-xfer.h ../libgnomevfs/gnome-vfs-init.h \ + ../libgnomevfs/gnome-vfs-ops.h \ + ../libgnomevfs/gnome-vfs-monitor.h \ + ../libgnomevfs/gnome-vfs-module-callback.h \ + ../libgnomevfs/gnome-vfs-standard-callbacks.h +test-channel.o: test-channel.c ../config.h \ + ../libgnomevfs/gnome-vfs-async-ops.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-find-directory.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-xfer.h ../libgnomevfs/gnome-vfs-init.h +test-directory-visit.o: test-directory-visit.c ../config.h \ + ../libgnomevfs/gnome-vfs-directory.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h ../libgnomevfs/gnome-vfs-init.h +test-directory.o: test-directory.c ../config.h \ + ../libgnomevfs/gnome-vfs-directory.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h ../libgnomevfs/gnome-vfs-init.h +test-dirop.o: test-dirop.c ../config.h ../libgnomevfs/gnome-vfs-init.h \ + ../libgnomevfs/gnome-vfs-ops.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-monitor.h +test-escape.o: test-escape.c ../config.h ../libgnomevfs/gnome-vfs-init.h \ + ../libgnomevfs/gnome-vfs-utils.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-file-info.h +test-find-directory.o: test-find-directory.c ../config.h \ + ../libgnomevfs/gnome-vfs-find-directory.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h ../libgnomevfs/gnome-vfs-init.h +test-info.o: test-info.c ../config.h ../libgnomevfs/gnome-vfs-init.h \ + ../libgnomevfs/gnome-vfs-ops.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-monitor.h +test-metadata.o: test-metadata.c ../libgnomevfs/gnome-vfs.h \ + ../libgnomevfs/gnome-vfs-async-ops.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-find-directory.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-xfer.h \ + ../libgnomevfs/gnome-vfs-directory.h \ + ../libgnomevfs/gnome-vfs-init.h \ + ../libgnomevfs/gnome-vfs-module-callback.h \ + ../libgnomevfs/gnome-vfs-monitor.h \ + ../libgnomevfs/gnome-vfs-ops.h ../libgnomevfs/gnome-vfs-utils.h \ + ../libgnomevfs/gnome-vfs-metadata.h +test-mime-handlers-set.o: test-mime-handlers-set.c ../config.h \ + ../libgnomevfs/gnome-vfs-application-registry.h \ + ../libgnomevfs/gnome-vfs-mime-handlers.h \ + ../libgnomevfs/gnome-vfs-mime-utils.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h ../libgnomevfs/gnome-vfs-init.h +test-mime-handlers.o: test-mime-handlers.c ../config.h \ + ../libgnomevfs/gnome-vfs-init.h \ + ../libgnomevfs/gnome-vfs-mime-handlers.h \ + ../libgnomevfs/gnome-vfs-mime-utils.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-mime-info.h +test-mime-info.o: test-mime-info.c ../config.h \ + ../libgnomevfs/gnome-vfs-init.h \ + ../libgnomevfs/gnome-vfs-mime-handlers.h \ + ../libgnomevfs/gnome-vfs-mime-utils.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-mime-info.h +test-mime.o: test-mime.c ../config.h ../libgnomevfs/gnome-vfs-init.h \ + ../libgnomevfs/gnome-vfs-mime-magic.h \ + ../libgnomevfs/gnome-vfs-mime-utils.h \ + ../libgnomevfs/gnome-vfs-mime-info.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-mime.h ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-utils.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-file-info.h +test-module-selftest.o: test-module-selftest.c ../config.h \ + ../libgnomevfs/gnome-vfs-init.h \ + ../libgnomevfs/gnome-vfs-private-utils.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-process.h +test-monitor.o: test-monitor.c ../libgnomevfs/gnome-vfs.h \ + ../libgnomevfs/gnome-vfs-async-ops.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-find-directory.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-xfer.h \ + ../libgnomevfs/gnome-vfs-directory.h \ + ../libgnomevfs/gnome-vfs-init.h \ + ../libgnomevfs/gnome-vfs-module-callback.h \ + ../libgnomevfs/gnome-vfs-monitor.h \ + ../libgnomevfs/gnome-vfs-ops.h ../libgnomevfs/gnome-vfs-utils.h +test-performance.o: test-performance.c ../config.h \ + ../libgnomevfs/gnome-vfs.h ../libgnomevfs/gnome-vfs-async-ops.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-find-directory.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-xfer.h \ + ../libgnomevfs/gnome-vfs-directory.h \ + ../libgnomevfs/gnome-vfs-init.h \ + ../libgnomevfs/gnome-vfs-module-callback.h \ + ../libgnomevfs/gnome-vfs-monitor.h \ + ../libgnomevfs/gnome-vfs-ops.h ../libgnomevfs/gnome-vfs-utils.h \ + ../libgnomevfs/gnome-vfs-mime-info.h +test-queue.o: test-queue.c ../config.h \ + ../libgnomevfs/gnome-vfs-async-ops.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-find-directory.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-xfer.h \ + ../libgnomevfs/gnome-vfs-job-limit.h \ + ../libgnomevfs/gnome-vfs-init.h ../libgnomevfs/gnome-vfs-job.h \ + ../libgnomevfs/gnome-vfs-module-callback.h \ + ../libgnomevfs/gnome-vfs-module-callback-private.h +test-resolv.o: test-resolv.c ../config.h ../libgnomevfs/gnome-vfs-init.h \ + ../libgnomevfs/gnome-vfs-ops.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-monitor.h \ + ../libgnomevfs/gnome-vfs-private-utils.h \ + ../libgnomevfs/gnome-vfs-process.h +test-seek.o: test-seek.c ../config.h ../libgnomevfs/gnome-vfs-init.h \ + ../libgnomevfs/gnome-vfs-ops.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-monitor.h +test-shell.o: test-shell.c ../config.h ../libgnomevfs/gnome-vfs-init.h \ + ../libgnomevfs/gnome-vfs-directory.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-find-directory.h \ + ../libgnomevfs/gnome-vfs-ops.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-monitor.h \ + ../libgnomevfs/gnome-vfs-ssl.h \ + ../libgnomevfs/gnome-vfs-socket.h \ + ../libgnomevfs/gnome-vfs-module-callback.h \ + ../libgnomevfs/gnome-vfs-standard-callbacks.h +test-ssl.o: test-ssl.c ../config.h ../libgnomevfs/gnome-vfs-init.h \ + ../libgnomevfs/gnome-vfs-socket-buffer.h \ + ../libgnomevfs/gnome-vfs-socket.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-ssl.h +test-subdir.o: test-subdir.c ../config.h ../libgnomevfs/gnome-vfs-init.h \ + ../libgnomevfs/gnome-vfs-ops.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-monitor.h \ + ../libgnomevfs/gnome-vfs-private-utils.h \ + ../libgnomevfs/gnome-vfs-process.h +test-symlinks.o: test-symlinks.c ../config.h \ + ../libgnomevfs/gnome-vfs-async-ops.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-find-directory.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-xfer.h ../libgnomevfs/gnome-vfs-init.h \ + ../libgnomevfs/gnome-vfs-ops.h \ + ../libgnomevfs/gnome-vfs-monitor.h +test-sync-create.o: test-sync-create.c ../config.h \ + ../libgnomevfs/gnome-vfs-init.h ../libgnomevfs/gnome-vfs-ops.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-monitor.h +test-sync-write.o: test-sync-write.c ../config.h \ + ../libgnomevfs/gnome-vfs-init.h ../libgnomevfs/gnome-vfs-ops.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-monitor.h +test-sync.o: test-sync.c ../config.h ../libgnomevfs/gnome-vfs-init.h \ + ../libgnomevfs/gnome-vfs-ops.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-monitor.h +test-unlink.o: test-unlink.c ../config.h ../libgnomevfs/gnome-vfs-init.h \ + ../libgnomevfs/gnome-vfs-ops.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-monitor.h +test-uri.o: test-uri.c ../config.h ../libgnomevfs/gnome-vfs-init.h \ + ../libgnomevfs/gnome-vfs-private-utils.h \ + ../libgnomevfs/gnome-vfs-cancellation.h \ + ../libgnomevfs/gnome-vfs-handle.h \ + ../libgnomevfs/gnome-vfs-context.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h \ + ../libgnomevfs/gnome-vfs-process.h \ + ../libgnomevfs/gnome-vfs-utils.h +test-xfer.o: test-xfer.c ../config.h ../libgnomevfs/gnome-vfs-init.h \ + ../libgnomevfs/gnome-vfs-xfer.h \ + ../libgnomevfs/gnome-vfs-file-info.h \ + ../libgnomevfs/gnome-vfs-file-size.h \ + ../libgnomevfs/gnome-vfs-result.h \ + ../libgnomevfs/gnome-vfs-uri.h + +check-TESTS: $(TESTS) + @failed=0; all=0; \ + srcdir=$(srcdir); export srcdir; \ + for tst in $(TESTS); do \ + if test -f $$tst; then dir=.; \ + else dir="$(srcdir)"; fi; \ + if $(TESTS_ENVIRONMENT) $$dir/$$tst; then \ + all=`expr $$all + 1`; \ + echo "PASS: $$tst"; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + failed=`expr $$failed + 1`; \ + echo "FAIL: $$tst"; \ + fi; \ + done; \ + if test "$$failed" -eq 0; then \ + banner="All $$all tests passed"; \ + else \ + banner="$$failed of $$all tests failed"; \ + fi; \ + dashes=`echo "$$banner" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + echo "$$dashes"; \ + test "$$failed" -eq 0 +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: +install-exec: install-exec-am + +install-data-am: +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: +uninstall: uninstall-am +all-am: Makefile $(PROGRAMS) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-noinstPROGRAMS mostlyclean-compile \ + mostlyclean-libtool mostlyclean-tags \ + mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-noinstPROGRAMS clean-compile clean-libtool clean-tags \ + clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-noinstPROGRAMS distclean-compile \ + distclean-libtool distclean-tags distclean-generic \ + clean-am + -rm -f libtool + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-noinstPROGRAMS \ + maintainer-clean-compile maintainer-clean-libtool \ + maintainer-clean-tags maintainer-clean-generic \ + distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \ +clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \ +mostlyclean-compile distclean-compile clean-compile \ +maintainer-clean-compile mostlyclean-libtool distclean-libtool \ +clean-libtool maintainer-clean-libtool tags mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir check-TESTS \ +info-am info dvi-am dvi check check-am installcheck-am installcheck \ +install-exec-am install-exec install-data-am install-data install-am \ +install uninstall-am uninstall all-redirect all-am all installdirs \ +mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/test/auto-test b/test/auto-test new file mode 100755 index 0000000..aba802f --- /dev/null +++ b/test/auto-test @@ -0,0 +1,13 @@ +#!/bin/sh + +# This is what we used to do, needs a little work +# to be save and avoid the libefs mess. +# +# ./test-shell < test.cmds | diff -a -u - test.output + +if ./test-async $SRCDIR/test.input; then + echo "Test passed" +else + echo "Test failed" + exit 1 +fi \ No newline at end of file diff --git a/test/test-async-cancel.c b/test/test-async-cancel.c new file mode 100644 index 0000000..4a5791a --- /dev/null +++ b/test/test-async-cancel.c @@ -0,0 +1,768 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* test-async-cancel.c - Test program for the GNOME Virtual File System. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Darin Adler +*/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TEST_ASSERT(expression, message) \ + G_STMT_START { if (!(expression)) test_failed message; } G_STMT_END + +static GnomeVFSAsyncHandle *test_handle; +static gpointer test_callback_data; +static gboolean test_done; + +#define MAX_THREAD_WAIT 500 +#define MAX_FD_CHECK 128 + +static void +stop_after_log (const char *domain, GLogLevelFlags level, + const char *message, gpointer data) +{ + void (* saved_handler)(int); + + g_log_default_handler(domain, level, message, data); + + saved_handler = signal (SIGINT, SIG_IGN); + raise(SIGINT); + signal(SIGINT, saved_handler); +} + +static void +make_asserts_break (const char *domain) +{ + g_log_set_handler (domain, + (GLogLevelFlags) (G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING), + stop_after_log, NULL); +} + +static int +get_free_file_descriptor_count (void) +{ + int count; + GList *list, *p; + int fd = -1; + + list = NULL; + for (count = 0; fd < MAX_FD_CHECK; count++) { + fd = open ("/dev/null", O_RDONLY); + if (fd == -1) { + break; + } + list = g_list_prepend (list, GINT_TO_POINTER (fd)); + } + + for (p = list; p != NULL; p = p->next) { + close (GPOINTER_TO_INT (p->data)); + } + g_list_free (list); + + return count; +} + +static int free_at_start; + +static int +get_used_file_descriptor_count (void) +{ + return free_at_start - get_free_file_descriptor_count (); +} + +static gboolean +wait_for_boolean (gboolean *wait_for_it) +{ + int i; + + if (*wait_for_it) { + return TRUE; + } + + for (i = 0; i < MAX_THREAD_WAIT; i++) { + g_thread_yield (); + g_main_context_iteration (NULL, FALSE); + if (*wait_for_it) { + return TRUE; + } + } + return FALSE; +} + +static gboolean +wait_until_vfs_jobs_gone (void) +{ + int i; + + if (gnome_vfs_job_get_count () == 0) { + return TRUE; + } + + for (i = 0; i < MAX_THREAD_WAIT; i++) { + g_thread_yield (); + g_main_context_iteration (NULL, FALSE); + if (gnome_vfs_job_get_count () == 0) { + return TRUE; + } + } + + return FALSE; +} + +static gboolean +wait_until_vfs_jobs_gone_no_main (void) +{ + int i; + + if (gnome_vfs_job_get_count () == 0) { + return TRUE; + } + + for (i = 0; i < MAX_THREAD_WAIT; i++) { + g_thread_yield (); + if (gnome_vfs_job_get_count () == 0) { + return TRUE; + } + } + return FALSE; +} + +static gboolean +wait_until_file_descriptors_gone (void) +{ + int i; + + if (get_used_file_descriptor_count () == 0) { + return TRUE; + } + + for (i = 0; i < MAX_THREAD_WAIT; i++) { + g_thread_yield (); + g_main_context_iteration (NULL, FALSE); + if (get_used_file_descriptor_count () == 0) { + return TRUE; + } + } + return FALSE; +} + +static gboolean at_least_one_test_failed = FALSE; + +static void +test_failed (const char *format, ...) +{ + va_list arguments; + char *message; + + va_start (arguments, format); + message = g_strdup_vprintf (format, arguments); + va_end (arguments); + + g_message ("test failed: %s", message); + at_least_one_test_failed = TRUE; +} + +static void +get_file_info_callback (GnomeVFSAsyncHandle *handle, + GList *results, + gpointer callback_data) +{ + TEST_ASSERT (handle == test_handle, ("get_file_info, bad handle")); + TEST_ASSERT (g_list_length (results) == 1, ("get_file_info, bad list length")); + TEST_ASSERT (callback_data == test_callback_data, ("get_file_info, bad handle")); + + test_handle = NULL; + g_free (callback_data); + + test_done = TRUE; +} + +static void +first_get_file_info (void) +{ + GList *uri_list; + + /* Start a get_file_info call. */ + test_done = FALSE; + test_callback_data = g_malloc (1); + uri_list = g_list_prepend (NULL, gnome_vfs_uri_new ("file:///dev/null")); + gnome_vfs_async_get_file_info (&test_handle, + uri_list, + GNOME_VFS_FILE_INFO_DEFAULT, + 0, + get_file_info_callback, + test_callback_data); + g_list_free (uri_list); + + /* Wait until it is done. */ + TEST_ASSERT (wait_for_boolean (&test_done), ("first_get_file_info: callback was not called")); + TEST_ASSERT (wait_until_vfs_jobs_gone (), ("first_get_file_info: job never went away")); + + /* For some reason, this consumes file descriptors. + * I don't know why. + */ +} + +static void +test_get_file_info (void) +{ + GList *uri_list; + + /* Start a get_file_info call. */ + test_done = FALSE; + test_callback_data = g_malloc (1); + uri_list = g_list_prepend (NULL, gnome_vfs_uri_new ("file:///dev/null")); + gnome_vfs_async_get_file_info (&test_handle, + uri_list, + GNOME_VFS_FILE_INFO_DEFAULT, + 0, + get_file_info_callback, + test_callback_data); + gnome_vfs_uri_list_free (uri_list); + + /* Wait until it is done. */ + TEST_ASSERT (wait_for_boolean (&test_done), ("get_file_info 1: callback was not called")); + TEST_ASSERT (wait_until_vfs_jobs_gone (), ("get_file_info 1: job never went away")); + TEST_ASSERT (get_used_file_descriptor_count () == 0, + ("get_file_info 1: %d file descriptors leaked", get_used_file_descriptor_count ())); + free_at_start = get_free_file_descriptor_count (); + + /* Cancel one right after starting it. */ + test_done = FALSE; + test_callback_data = g_malloc (1); + uri_list = g_list_prepend (NULL, gnome_vfs_uri_new ("file:///dev/null")); + gnome_vfs_async_get_file_info (&test_handle, + uri_list, + GNOME_VFS_FILE_INFO_DEFAULT, + 0, + get_file_info_callback, + test_callback_data); + gnome_vfs_uri_list_free (uri_list); + gnome_vfs_async_cancel (test_handle); + g_free (test_callback_data); + + /* Wait until it is done. */ + TEST_ASSERT (wait_until_vfs_jobs_gone (), ("get_file_info 2: job never went away")); + TEST_ASSERT (get_used_file_descriptor_count () == 0, + ("get_file_info 2: %d file descriptors leaked", get_used_file_descriptor_count ())); + TEST_ASSERT (test_done == FALSE, ("get_file_info 2: callback was called")); + free_at_start = get_free_file_descriptor_count (); +} + +static gboolean file_open_flag; + +static void +file_open_callback (GnomeVFSAsyncHandle *handle, + GnomeVFSResult result, + gpointer callback_data) +{ + TEST_ASSERT (handle == test_handle, ("open callback, bad handle")); + TEST_ASSERT (result == GNOME_VFS_OK, ("open callback, bad result")); + TEST_ASSERT (callback_data == test_callback_data, ("open callback, bad callback data")); + + file_open_flag = TRUE; +} + +static gboolean file_closed_flag; + +static void +file_close_callback (GnomeVFSAsyncHandle *handle, + GnomeVFSResult result, + gpointer callback_data) +{ + TEST_ASSERT (handle == test_handle, ("close callback, bad handle")); + TEST_ASSERT (result == GNOME_VFS_OK, ("close callback, bad result")); + TEST_ASSERT (callback_data == test_callback_data, ("close callback, bad callback data")); + + file_closed_flag = TRUE; +} + +static gboolean file_read_flag; +char read_buffer[1]; + +static void +file_read_callback (GnomeVFSAsyncHandle *handle, + GnomeVFSResult result, + gpointer buffer, + GnomeVFSFileSize bytes_requested, + GnomeVFSFileSize bytes_read, + gpointer callback_data) +{ + TEST_ASSERT (handle == test_handle, ("read callback, bad handle")); + TEST_ASSERT (result == GNOME_VFS_OK, ("read callback, bad result")); + TEST_ASSERT (buffer == read_buffer, ("read callback, bad buffer")); + TEST_ASSERT (bytes_requested == 1, ("read callback, bad bytes_requested")); + TEST_ASSERT (bytes_read == 1, ("read callback, bad bytes_read")); + TEST_ASSERT (callback_data == test_callback_data, ("read callback, bad callback data")); + + file_read_flag = TRUE; +} + +static gboolean directory_load_flag; + +static void +directory_load_callback (GnomeVFSAsyncHandle *handle, + GnomeVFSResult result, + GList *list, + guint entries_read, + gpointer callback_data) +{ + GList *element; + GnomeVFSFileInfo *info; + + for (element = list; element != NULL; element = element->next) { + info = element->data; + gnome_vfs_file_info_ref (info); + } + + for (element = list; element != NULL; element = element->next) { + info = element->data; + gnome_vfs_file_info_unref (info); + } + + directory_load_flag = TRUE; +} + +static gboolean directory_load_failed_flag; + +static void +directory_load_failed_callback (GnomeVFSAsyncHandle *handle, + GnomeVFSResult result, + GList *list, + guint entries_read, + gpointer callback_data) +{ + g_assert (result != GNOME_VFS_OK); + directory_load_failed_flag = TRUE; +} + +static void +test_open_read_close (void) +{ + file_open_flag = FALSE; + gnome_vfs_async_open (&test_handle, + "file:///etc/passwd", + GNOME_VFS_OPEN_READ, + 0, + file_open_callback, + test_callback_data); + TEST_ASSERT (wait_for_boolean (&file_open_flag), ("open: callback was not called")); + + file_read_flag = FALSE; + gnome_vfs_async_read (test_handle, + read_buffer, + 1, + file_read_callback, + test_callback_data); + + TEST_ASSERT (wait_for_boolean (&file_read_flag), ("open read close: read callback was not called")); + file_closed_flag = FALSE; + gnome_vfs_async_close (test_handle, + file_close_callback, + test_callback_data); + + TEST_ASSERT (wait_for_boolean (&file_closed_flag), ("open read close: close callback was not called")); + + TEST_ASSERT (wait_until_vfs_jobs_gone (), ("open read cancel close: job never went away")); + TEST_ASSERT (get_used_file_descriptor_count () == 0, + ("open read cancel close: %d file descriptors leaked", get_used_file_descriptor_count ())); + free_at_start = get_free_file_descriptor_count (); +} + +static void +test_open_read_cancel_close (void) +{ + file_open_flag = FALSE; + gnome_vfs_async_open (&test_handle, + "file:///etc/passwd", + GNOME_VFS_OPEN_READ, + 0, + file_open_callback, + test_callback_data); + TEST_ASSERT (wait_for_boolean (&file_open_flag), ("open: callback was not called")); + + file_read_flag = FALSE; + gnome_vfs_async_read (test_handle, + read_buffer, + 1, + file_read_callback, + test_callback_data); + gnome_vfs_async_cancel (test_handle); + + file_closed_flag = FALSE; + gnome_vfs_async_close (test_handle, + file_close_callback, + test_callback_data); + + TEST_ASSERT (wait_for_boolean (&file_closed_flag), ("open read cancel close: callback was not called")); + TEST_ASSERT (!file_read_flag, ("open read cancel close: read callback was called")); + + TEST_ASSERT (wait_until_vfs_jobs_gone (), ("open read cancel close: job never went away")); + TEST_ASSERT (get_used_file_descriptor_count () == 0, + ("open read cancel close: %d file descriptors leaked", get_used_file_descriptor_count ())); + free_at_start = get_free_file_descriptor_count (); +} + +static void +test_open_close (void) +{ + file_open_flag = FALSE; + gnome_vfs_async_open (&test_handle, + "file:///etc/passwd", + GNOME_VFS_OPEN_READ, + 0, + file_open_callback, + test_callback_data); + TEST_ASSERT (wait_for_boolean (&file_open_flag), ("open: open callback was not called")); + + file_closed_flag = FALSE; + gnome_vfs_async_close (test_handle, + file_close_callback, + test_callback_data); + + + TEST_ASSERT (wait_for_boolean (&file_closed_flag), ("open close: close callback was not called")); + + TEST_ASSERT (wait_until_vfs_jobs_gone (), ("open close 1: job never went away")); + TEST_ASSERT (get_used_file_descriptor_count () == 0, + ("open close 1: %d file descriptors leaked", get_used_file_descriptor_count ())); + free_at_start = get_free_file_descriptor_count (); +} + +static void +empty_close_callback (GnomeVFSAsyncHandle *handle, + GnomeVFSResult result, + gpointer callback_data) +{ +} + +static void +test_open_cancel (void) +{ + file_open_flag = FALSE; + gnome_vfs_async_open (&test_handle, + "file:///etc/passwd", + GNOME_VFS_OPEN_READ, + 0, + file_open_callback, + test_callback_data); + gnome_vfs_async_cancel (test_handle); + + TEST_ASSERT (wait_until_vfs_jobs_gone (), ("open cancel 1: job never went away")); + TEST_ASSERT (!file_open_flag, ("open cancel 1: open callback was called")); + TEST_ASSERT (get_used_file_descriptor_count () == 0, + ("open cancel 1: %d file descriptors leaked", get_used_file_descriptor_count ())); + free_at_start = get_free_file_descriptor_count (); + + file_open_flag = FALSE; + gnome_vfs_async_open (&test_handle, + "file:///etc/passwd", + GNOME_VFS_OPEN_READ, + 0, + file_open_callback, + test_callback_data); + wait_until_vfs_jobs_gone_no_main (); + gnome_vfs_async_cancel (test_handle); + if (file_open_flag) { /* too quick */ + gnome_vfs_async_close (test_handle, empty_close_callback, NULL); + } + TEST_ASSERT (wait_until_file_descriptors_gone (), + ("open cancel 2: %d file descriptors leaked", get_used_file_descriptor_count ())); + free_at_start = get_free_file_descriptor_count (); + TEST_ASSERT (wait_until_vfs_jobs_gone (), ("open cancel 2: later job never went away")); + TEST_ASSERT (!file_open_flag, ("open cancel 2: open callback was called")); +} + +static void +file_open_fail_callback (GnomeVFSAsyncHandle *handle, + GnomeVFSResult result, + gpointer callback_data) +{ + TEST_ASSERT (handle == test_handle, ("open callback, bad handle")); + TEST_ASSERT (result == GNOME_VFS_ERROR_NOT_FOUND, ("open callback, bad result")); + TEST_ASSERT (callback_data == test_callback_data, ("open callback, bad callback data")); + + file_open_flag = TRUE; +} + +static void +test_open_fail (void) +{ + file_open_flag = FALSE; + gnome_vfs_async_open (&test_handle, + "file:///etc/mugwump-xxx", + GNOME_VFS_OPEN_READ, + 0, + file_open_fail_callback, + test_callback_data); + TEST_ASSERT (wait_for_boolean (&file_open_flag), ("open fail 1: callback was not called")); + TEST_ASSERT (wait_until_vfs_jobs_gone (), ("open fail 1: job never went away")); + TEST_ASSERT (get_used_file_descriptor_count () == 0, + ("open fail 1: %d file descriptors leaked", get_used_file_descriptor_count ())); + free_at_start = get_free_file_descriptor_count (); +} + +static void +my_yield (int count) +{ + for (; count > 0; count--) { + usleep (1); + g_thread_yield (); + g_main_context_iteration (NULL, FALSE); + } +} + +static void +test_load_directory_cancel (int delay_till_cancel, int chunk_count) +{ + GnomeVFSAsyncHandle *handle; + guint num_entries; + + + gnome_vfs_async_load_directory (&handle, + "file:///etc", + GNOME_VFS_FILE_INFO_GET_MIME_TYPE + | GNOME_VFS_FILE_INFO_FORCE_FAST_MIME_TYPE + | GNOME_VFS_FILE_INFO_FOLLOW_LINKS, + chunk_count, + 0, + directory_load_callback, + &num_entries); + + usleep (delay_till_cancel * 100); + + directory_load_flag = FALSE; + gnome_vfs_async_cancel (handle); + TEST_ASSERT (wait_until_vfs_jobs_gone (), ("load directory cancel 1: job never went away delay %d", + delay_till_cancel)); + TEST_ASSERT (!directory_load_flag, ("load directory cancel 1: load callback was called")); + + gnome_vfs_async_load_directory (&handle, + "file:///etc", + GNOME_VFS_FILE_INFO_GET_MIME_TYPE + | GNOME_VFS_FILE_INFO_FORCE_FAST_MIME_TYPE + | GNOME_VFS_FILE_INFO_FOLLOW_LINKS, + chunk_count, + 0, + directory_load_callback, + &num_entries); + + my_yield (delay_till_cancel); + + directory_load_flag = FALSE; + gnome_vfs_async_cancel (handle); + TEST_ASSERT (wait_until_vfs_jobs_gone (), ("load directory cancel 2: job never went away delay %d", + delay_till_cancel)); + TEST_ASSERT (!directory_load_flag, ("load directory cancel 2: load callback was called")); +} + +static void +test_load_directory_fail (void) +{ + GnomeVFSAsyncHandle *handle; + guint num_entries; + + directory_load_failed_flag = FALSE; + gnome_vfs_async_load_directory (&handle, + "file:///strcprstskrzkrk", + GNOME_VFS_FILE_INFO_GET_MIME_TYPE + | GNOME_VFS_FILE_INFO_FORCE_FAST_MIME_TYPE + | GNOME_VFS_FILE_INFO_FOLLOW_LINKS, + 32, + 0, + directory_load_failed_callback, + &num_entries); + + TEST_ASSERT (wait_for_boolean (&directory_load_failed_flag), ("load directory 1: load callback was not called")); + TEST_ASSERT (wait_until_vfs_jobs_gone (), ("load directory 1: job never went away")); +} + +static gboolean find_directory_flag; + +static void +test_find_directory_callback (GnomeVFSAsyncHandle *handle, + GList *results, + gpointer callback_data) +{ + GList *element; + + find_directory_flag = TRUE; + + for (element = results; element != NULL; element = element->next) { + GnomeVFSFindDirectoryResult *result_item = (GnomeVFSFindDirectoryResult *)element->data; + + if (result_item->result == GNOME_VFS_OK) { + gnome_vfs_uri_ref (result_item->uri); + gnome_vfs_uri_unref (result_item->uri); + } + } + + g_assert (callback_data == &find_directory_flag); +} + +static void +test_find_directory (int delay_till_cancel) +{ + GnomeVFSAsyncHandle *handle; + GList *vfs_uri_as_list; + + + vfs_uri_as_list = g_list_append (NULL, gnome_vfs_uri_new ("file://~")); + vfs_uri_as_list = g_list_append (vfs_uri_as_list, gnome_vfs_uri_new ("file:///ace_of_spades")); + + find_directory_flag = FALSE; + + gnome_vfs_async_find_directory (&handle, vfs_uri_as_list, + GNOME_VFS_DIRECTORY_KIND_TRASH, FALSE, TRUE, 0777, 0, + test_find_directory_callback, &find_directory_flag); + + TEST_ASSERT (wait_for_boolean (&find_directory_flag), + ("find directory cancel 1: callback was not called %d", + delay_till_cancel)); + + find_directory_flag = FALSE; + + gnome_vfs_async_find_directory (&handle, vfs_uri_as_list, + GNOME_VFS_DIRECTORY_KIND_TRASH, FALSE, TRUE, 0777, 0, + test_find_directory_callback, &find_directory_flag); + + usleep (delay_till_cancel * 100); + + gnome_vfs_async_cancel (handle); + TEST_ASSERT (wait_until_vfs_jobs_gone (), ("find directory cancel 2: job never went away")); + TEST_ASSERT (!find_directory_flag, ("find directory cancel 2: callback was called")); + + + gnome_vfs_async_find_directory (&handle, vfs_uri_as_list, + GNOME_VFS_DIRECTORY_KIND_TRASH, FALSE, TRUE, 0777, 0, + test_find_directory_callback, &find_directory_flag); + + my_yield (delay_till_cancel); + + find_directory_flag = FALSE; + gnome_vfs_async_cancel (handle); + TEST_ASSERT (wait_until_vfs_jobs_gone (), ("open cancel 3: job never went away")); + TEST_ASSERT (!find_directory_flag, ("find directory cancel 3: callback was called")); + + gnome_vfs_uri_list_free (vfs_uri_as_list); +} + +int +main (int argc, char **argv) +{ + make_asserts_break("GnomeVFS"); + gnome_vfs_init (); + + /* Initialize our own stuff. */ + free_at_start = get_free_file_descriptor_count (); + + /* Do the basic tests of our own tools. */ + TEST_ASSERT (get_used_file_descriptor_count () == 0, ("file descriptor count")); + TEST_ASSERT (gnome_vfs_job_get_count () == 0, ("VFS job count")); + + /* Spend those first few file descriptors. */ + first_get_file_info (); + free_at_start = get_free_file_descriptor_count (); + + /* Test to see that a simple async. call works without leaking or anything. */ + fprintf (stderr, "Testing get file info...\n"); + test_get_file_info (); + test_get_file_info (); + fprintf (stderr, "Testing open, close...\n"); + test_open_close (); + test_open_close (); + fprintf (stderr, "Testing read, close...\n"); + test_open_read_close (); + test_open_read_close (); + fprintf (stderr, "Testing cancellation...\n"); + test_open_cancel (); + test_open_cancel (); + + fprintf (stderr, "Testing failed opens...\n"); + test_open_fail (); + test_open_fail (); + fprintf (stderr, "Testing read, cancel, closes...\n"); + test_open_read_cancel_close (); + test_open_read_cancel_close (); + + fprintf (stderr, "Testing directory loads"); + test_load_directory_fail (); + test_load_directory_cancel (0, 1); + test_load_directory_cancel (1, 1); + test_load_directory_cancel (10, 1); + test_load_directory_cancel (100, 1); + fprintf (stderr, "."); + test_load_directory_cancel (0, 1); + test_load_directory_cancel (1, 1); + test_load_directory_cancel (10, 1); + test_load_directory_cancel (100, 1); + fprintf (stderr, "."); + + test_load_directory_cancel (0, 32); + test_load_directory_cancel (1, 32); + test_load_directory_cancel (10, 32); + test_load_directory_cancel (100, 32); + fprintf (stderr, "."); + test_load_directory_cancel (0, 32); + test_load_directory_cancel (1, 32); + test_load_directory_cancel (10, 32); + test_load_directory_cancel (100, 32); + + fprintf (stderr, "\nTesting directory finds"); + test_find_directory (0); + test_find_directory (0); + fprintf (stderr, "."); + test_find_directory (1); + test_find_directory (1); + fprintf (stderr, "."); + test_find_directory (10); + test_find_directory (10); + fprintf (stderr, "."); + test_find_directory (100); + test_find_directory (100); + + fprintf (stderr, "\nTesting shutdown...\n"); + gnome_vfs_shutdown (); + + if (g_getenv ("_MEMPROF_SOCKET")) { + g_warning ("Waiting for memprof\n"); + g_main_context_iteration (NULL, TRUE); + } + + if (!at_least_one_test_failed) { + fprintf (stderr, "All tests passed successfully.\n"); + } + + /* Report to "make check" on whether it all worked or not. */ + return at_least_one_test_failed ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/test/test-async-directory.c b/test/test-async-directory.c new file mode 100644 index 0000000..a09f035 --- /dev/null +++ b/test/test-async-directory.c @@ -0,0 +1,339 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* test-async-directory.c - Test program for asynchronous directory + reading with the GNOME Virtual File System. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +static GMainLoop *main_loop; + +static int measure_speed = 0; +static int sort = 0; +static int items_per_notification = 1; +static int read_files = 0; + +static struct poptOption options[] = { + { + "chunk-size", + 'c', + POPT_ARG_INT, + &items_per_notification, + 0, + "Number of items to send for every notification", + "NUM_ITEMS" + }, + { + "measure-speed", + 'm', + POPT_ARG_NONE, + &measure_speed, + 0, + "Measure speed without displaying anything", + NULL + }, + { + "sort", + 's', + POPT_ARG_NONE, + &sort, + 0, + "Sort entries", + NULL + }, + { + "read-files", + 'r', + POPT_ARG_NONE, + &read_files, + 0, + "Test file reading", + NULL + }, + { + NULL, + 0, + 0, + NULL, + 0, + NULL, + NULL + } +}; + +static const gchar * +type_to_string (GnomeVFSFileType type) +{ + switch (type) { + case GNOME_VFS_FILE_TYPE_UNKNOWN: + return "Unknown"; + case GNOME_VFS_FILE_TYPE_REGULAR: + return "Regular"; + case GNOME_VFS_FILE_TYPE_DIRECTORY: + return "Directory"; + case GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK: + return "Symbolic Link"; + case GNOME_VFS_FILE_TYPE_FIFO: + return "FIFO"; + case GNOME_VFS_FILE_TYPE_SOCKET: + return "Socket"; + case GNOME_VFS_FILE_TYPE_CHARACTER_DEVICE: + return "Character device"; + case GNOME_VFS_FILE_TYPE_BLOCK_DEVICE: + return "Block device"; + default: + return "???"; + } +} + +static void +test_read_file_close_callback (GnomeVFSAsyncHandle *handle, + GnomeVFSResult result, + gpointer callback_data) +{ +} + + +static void +test_read_file_succeeded (GnomeVFSAsyncHandle *handle) +{ + gnome_vfs_async_close (handle, + test_read_file_close_callback, + NULL); +} + +static void +test_read_file_failed (GnomeVFSAsyncHandle *handle, GnomeVFSResult result) +{ + gnome_vfs_async_close (handle, + test_read_file_close_callback, + NULL); +} + +/* A read is complete, so we might or might not be done. */ +static void +test_read_file_read_callback (GnomeVFSAsyncHandle *handle, + GnomeVFSResult result, + gpointer buffer, + GnomeVFSFileSize bytes_requested, + GnomeVFSFileSize bytes_read, + gpointer callback_data) +{ + /* Check for a failure. */ + if (result != GNOME_VFS_OK && result != GNOME_VFS_ERROR_EOF) { + test_read_file_failed (handle, result); + return; + } + + /* If at the end of the file, we win! */ + test_read_file_succeeded (handle); +} + +char buffer[256]; + +/* Start reading a chunk. */ +static void +test_read_file_read_chunk (GnomeVFSAsyncHandle *handle) +{ + gnome_vfs_async_read (handle, + buffer, + 10, + test_read_file_read_callback, + handle); +} + +/* Once the open is finished, read a first chunk. */ +static void +test_read_file_open_callback (GnomeVFSAsyncHandle *handle, + GnomeVFSResult result, + gpointer callback_data) +{ + if (result != GNOME_VFS_OK) { + test_read_file_failed (handle, result); + return; + } + + test_read_file_read_chunk (handle); +} + +/* Set up the read handle and start reading. */ +static GnomeVFSAsyncHandle * +test_read_file_async (GnomeVFSURI *uri) +{ + GnomeVFSAsyncHandle *result; + + gnome_vfs_async_open_uri (&result, + uri, + GNOME_VFS_OPEN_READ, + 0, + test_read_file_open_callback, + NULL); + + return result; +} + +typedef struct { + const char *parent_uri; + int num_entries_read; +} CallbackData; + +volatile int async_task_counter; + +static void +directory_load_callback (GnomeVFSAsyncHandle *handle, + GnomeVFSResult result, + GList *list, + guint entries_read, + gpointer callback_data) +{ + CallbackData *data; + GnomeVFSFileInfo *info; + GnomeVFSURI *parent_uri; + GnomeVFSURI *uri; + GList *node; + guint i; + + data = (CallbackData *)callback_data; + + + if (!measure_speed) { + printf ("Directory load callback: %s, %d entries, callback_data `%s'\n", + gnome_vfs_result_to_string (result), + entries_read, + (gchar *) data->parent_uri); + } + + parent_uri = gnome_vfs_uri_new (data->parent_uri); + for (i = 0, node = list; i < entries_read && node != NULL; i++, node = node->next) { + info = node->data; + if (!measure_speed) { + printf (" File `%s'%s (%s, %s), " + "size %"GNOME_VFS_SIZE_FORMAT_STR", mode %04o\n", + info->name, + (info->flags & GNOME_VFS_FILE_FLAGS_SYMLINK) ? " [link]" : "", + type_to_string (info->type), + gnome_vfs_file_info_get_mime_type (info), + info->size, info->permissions); + fflush (stdout); + } + if (read_files) { + if ((info->type & GNOME_VFS_FILE_TYPE_REGULAR) != 0) { + uri = gnome_vfs_uri_append_file_name (parent_uri, info->name); + test_read_file_async (uri); + gnome_vfs_uri_unref (uri); + } + if (!measure_speed) { + printf ("reading a bit of %s\n", info->name); + } + } + } + + + data->num_entries_read += entries_read; + + gnome_vfs_uri_unref (parent_uri); + if (result != GNOME_VFS_OK) { + if (--async_task_counter == 0) { + g_main_loop_quit (main_loop); + } + } +} + +int +main (int argc, const char **argv) +{ + GnomeVFSAsyncHandle *handle; + poptContext popt_context; + const char **args; + gchar *text_uri; + GTimer *timer; + CallbackData callback_data; + + puts ("Initializing gnome-libs..."); + popt_context = poptGetContext ("test-vfs", argc, argv, + options, 0); + + args = poptGetArgs (popt_context); + if (args == NULL || args[1] != NULL) { + fprintf (stderr, "Usage: %s [] \n", argv[0]); + return 1; + } + + text_uri = g_strdup (args[0]); + poptFreeContext (popt_context); + + puts ("Initializing gnome-vfs..."); + gnome_vfs_init (); + + printf ("%d item(s) per notification\n", items_per_notification); + + if (measure_speed) { + timer = g_timer_new (); + g_timer_start (timer); + } else { + timer = NULL; + } + + callback_data.num_entries_read = 0; + callback_data.parent_uri = text_uri; + async_task_counter = 1; + gnome_vfs_async_load_directory + (&handle, + text_uri, + (GNOME_VFS_FILE_INFO_GET_MIME_TYPE | GNOME_VFS_FILE_INFO_FOLLOW_LINKS), + items_per_notification, + 0, + directory_load_callback, + &callback_data); + + if (!measure_speed) + puts ("main loop running."); + + main_loop = g_main_loop_new (NULL, TRUE); + g_main_loop_run (main_loop); + g_main_loop_unref (main_loop); + + if (measure_speed) { + gdouble elapsed_seconds; + + g_timer_stop (timer); + elapsed_seconds = g_timer_elapsed (timer, NULL); + printf ("%.5f seconds for %d entries, %.5f entries/sec.\n", + elapsed_seconds, callback_data.num_entries_read, + (double) callback_data.num_entries_read / elapsed_seconds); + } + + if (!measure_speed) + puts ("GTK+ main loop finished."); fflush (stdout); + + puts ("All done"); + + gnome_vfs_shutdown (); + + return 0; +} diff --git a/test/test-async.c b/test/test-async.c new file mode 100644 index 0000000..37e218c --- /dev/null +++ b/test/test-async.c @@ -0,0 +1,181 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* test-vfs.c - Test program for the GNOME Virtual File System. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli +*/ + +#include + +#include +#include +#include +#include + +#define QUEUE_LENGTH 4000 + +static GMainLoop *main_loop; + +/* Callbacks. */ +static void +close_callback (GnomeVFSAsyncHandle *handle, + GnomeVFSResult result, + gpointer callback_data) +{ + fprintf (stderr, "Close: %s.\n", gnome_vfs_result_to_string (result)); + g_main_loop_quit (main_loop); +} + +static void +file_control_callback (GnomeVFSAsyncHandle *handle, + GnomeVFSResult result, + gpointer operation_data, + gpointer callback_data) +{ + if (result != GNOME_VFS_OK) { + fprintf (stderr, "file_control failed: %s\n", + gnome_vfs_result_to_string (result)); + } else { + printf ("file_control result: %s\n", *(char **)operation_data); + } + + fprintf (stderr, "Now closing the file.\n"); + gnome_vfs_async_close (handle, close_callback, "close"); +} + +static void +read_callback (GnomeVFSAsyncHandle *handle, + GnomeVFSResult result, + gpointer buffer, + GnomeVFSFileSize bytes_requested, + GnomeVFSFileSize bytes_read, + gpointer callback_data) +{ + char **op_data; + + if (result != GNOME_VFS_OK) { + fprintf (stderr, "Read failed: %s\n", + gnome_vfs_result_to_string (result)); + } else { + printf ("%"GNOME_VFS_SIZE_FORMAT_STR"/" + "%"GNOME_VFS_SIZE_FORMAT_STR" " + "byte(s) read, callback data `%s'\n", + bytes_read, bytes_requested, + (gchar *) callback_data); + *((gchar *) buffer + bytes_read) = 0; + fprintf (stderr, "%s", (char *) buffer); + } + + fprintf (stderr, "Now testing file_control.\n"); + op_data = g_new (char *, 1); + gnome_vfs_async_file_control (handle, "file:test", op_data, g_free, file_control_callback, "file_control"); +} + +static void +open_callback (GnomeVFSAsyncHandle *handle, + GnomeVFSResult result, + gpointer callback_data) +{ + if (result != GNOME_VFS_OK) { + fprintf (stderr, "Open failed: %s.\n", + gnome_vfs_result_to_string (result)); + g_main_loop_quit (main_loop); + } else { + gchar *buffer; + const gulong buffer_size = 1024; + + fprintf (stderr, "File opened correctly, data `%s'.\n", + (gchar *) callback_data); + + buffer = g_malloc (buffer_size); + gnome_vfs_async_read (handle, + buffer, + buffer_size - 1, + read_callback, + "read_callback"); + } +} + +static void +dummy_close_callback (GnomeVFSAsyncHandle *handle, + GnomeVFSResult result, + gpointer callback_data) +{ +} + +static void +async_queue_callback (GnomeVFSAsyncHandle *handle, + GnomeVFSResult result, + gpointer callback_data) +{ + int *completed = callback_data; + + (*completed)++; + + if (result == GNOME_VFS_OK) + gnome_vfs_async_close (handle, dummy_close_callback, NULL); +} + +int +main (int argc, char **argv) +{ + int completed, i; + GnomeVFSAsyncHandle *handle; + + if (argc < 2) { + fprintf (stderr, "Usage: %s \n", argv[0]); + return 1; + } + + fprintf (stderr, "Initializing gnome-vfs...\n"); + gnome_vfs_init (); + + fprintf (stderr, "Creating async context...\n"); + + fprintf (stderr, "Starting open for `%s'...\n", argv[1]); + gnome_vfs_async_open (&handle, argv[1], GNOME_VFS_OPEN_READ, + GNOME_VFS_PRIORITY_MIN, + open_callback, "open_callback"); + + fprintf (stderr, "Main loop running.\n"); + main_loop = g_main_loop_new (NULL, TRUE); + g_main_loop_run (main_loop); + + fprintf (stderr, "Main loop finished.\n"); + + fprintf (stderr, "Test async queue efficiency ..."); + + for (completed = i = 0; i < QUEUE_LENGTH; i++) { + gnome_vfs_async_open (&handle, argv [1], GNOME_VFS_OPEN_READ, 0, + async_queue_callback, &completed); + } + + while (completed < QUEUE_LENGTH) + g_main_context_iteration (NULL, TRUE); + + fprintf (stderr, "Passed\n"); + + g_main_loop_unref (main_loop); + + fprintf (stderr, "All done\n"); + + gnome_vfs_shutdown (); + + return 0; +} diff --git a/test/test-callback.c b/test/test-callback.c new file mode 100644 index 0000000..760dcc0 --- /dev/null +++ b/test/test-callback.c @@ -0,0 +1,315 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static gboolean authentication_callback_called = FALSE; + +/* For this test case to function, these two URI's should + * require a username/password (set in authentication_username, authentication_password below) + * and AUTHENTICATION_URI_CHILD should be a child of AUTHENTICATION_URI + */ +#define AUTHENTICATION_URI_CHILD "http://localhost/~mikef/protected/index.html" +#define AUTHENTICATION_URI "http://localhost/~mikef/protected/" + +static const char *authentication_username = "foo"; +static const char *authentication_password = "foo"; + +static void /* GnomeVFSModuleCallback */ +authentication_callback (gconstpointer in, size_t in_size, gpointer out, size_t out_size, gpointer user_data) +{ + GnomeVFSModuleCallbackAuthenticationIn *in_real; + GnomeVFSModuleCallbackAuthenticationOut *out_real; + + /* printf ("in authentication_callback\n"); */ + + g_return_if_fail (sizeof (GnomeVFSModuleCallbackAuthenticationIn) == in_size + && sizeof (GnomeVFSModuleCallbackAuthenticationOut) == out_size); + + g_return_if_fail (in != NULL); + g_return_if_fail (out != NULL); + + in_real = (GnomeVFSModuleCallbackAuthenticationIn *)in; + out_real = (GnomeVFSModuleCallbackAuthenticationOut *)out; + + /* printf ("in uri: %s realm: %s\n", in_real->uri, in_real->realm); */ + + out_real->username = g_strdup (authentication_username); + out_real->password = g_strdup (authentication_password); + + authentication_callback_called = TRUE; +} + +static gboolean destroy_notify_occurred = FALSE; + +static void /*GDestroyNotify*/ +destroy_notify (gpointer user_data) +{ + destroy_notify_occurred = TRUE; +} + +static volatile gboolean open_callback_occurred = FALSE; + +static GnomeVFSResult open_callback_result_expected = GNOME_VFS_OK; + +static void /* GnomeVFSAsyncOpenCallback */ +open_callback (GnomeVFSAsyncHandle *handle, + GnomeVFSResult result, + gpointer callback_data) +{ + g_assert (result == open_callback_result_expected); + + open_callback_occurred = TRUE; +} + +static volatile gboolean close_callback_occurred = FALSE; + +static void /* GnomeVFSAsyncOpenCallback */ +close_callback (GnomeVFSAsyncHandle *handle, + GnomeVFSResult result, + gpointer callback_data) +{ + close_callback_occurred = TRUE; +} + +static void +stop_after_log (const char *domain, GLogLevelFlags level, + const char *message, gpointer data) +{ + void (* saved_handler) (int); + + g_log_default_handler (domain, level, message, data); + + saved_handler = signal (SIGINT, SIG_IGN); + raise (SIGINT); + signal (SIGINT, saved_handler); +} + +static void +make_asserts_break (const char *domain) +{ + g_log_set_handler + (domain, + (GLogLevelFlags) (G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING), + stop_after_log, NULL); +} + +static void (*flush_credentials_func)(void); + +int +main (int argc, char **argv) +{ + GnomeVFSHandle *handle; + GnomeVFSResult result; + GnomeVFSAsyncHandle *async_handle; + char *module_path; + char *authentication_uri, *authentication_uri_child; + GModule *module; + guint i; + + make_asserts_break ("GLib"); + make_asserts_break ("GnomeVFS"); + + if (argc == 2) { + authentication_uri = argv[1]; + authentication_uri_child = g_strdup_printf("%s/./", authentication_uri); + } else if (argc == 3) { + authentication_uri = argv[1]; + authentication_uri_child = argv[2]; + } else { + authentication_uri = AUTHENTICATION_URI; + authentication_uri_child = AUTHENTICATION_URI_CHILD; + } + + gnome_vfs_init (); + + /* Load http module so we can snag the test hook */ + module_path = g_module_build_path (MODULES_PATH, "http"); + module = g_module_open (module_path, G_MODULE_BIND_LAZY); + g_free (module_path); + module_path = NULL; + + if (module == NULL) { + fprintf (stderr, "Couldn't load http module \n"); + exit (-1); + } + + g_module_symbol (module, "http_authentication_test_flush_credentials", (gpointer *) &flush_credentials_func); + + if (flush_credentials_func == NULL) { + fprintf (stderr, "Couldn't find http_authentication_test_flush_credentials\n"); + exit (-1); + } + + /* Test 1: Attempt to access a URI requiring authentication w/o a callback registered */ + + result = gnome_vfs_open (&handle, authentication_uri, GNOME_VFS_OPEN_READ); + g_assert (result == GNOME_VFS_ERROR_ACCESS_DENIED); + handle = NULL; + + /* Test 2: Attempt an async open that requires http authentication */ + + gnome_vfs_module_callback_set_default (GNOME_VFS_MODULE_CALLBACK_AUTHENTICATION, + authentication_callback, + NULL, + NULL); + + authentication_callback_called = FALSE; + + open_callback_occurred = FALSE; + open_callback_result_expected = GNOME_VFS_OK; + + gnome_vfs_async_open ( + &async_handle, + authentication_uri, + GNOME_VFS_OPEN_READ, + 0, + open_callback, + NULL); + + while (!open_callback_occurred) { + g_main_context_iteration (NULL, TRUE); + } + + close_callback_occurred = FALSE; + gnome_vfs_async_close (async_handle, close_callback, NULL); + + while (!close_callback_occurred) { + g_main_context_iteration (NULL, TRUE); + } + + g_assert (authentication_callback_called); + + /* Test 3: Attempt a sync call to the same location; + * credentials should be stored so the authentication_callback function + * should not be called + */ + + authentication_callback_called = FALSE; + result = gnome_vfs_open (&handle, authentication_uri, GNOME_VFS_OPEN_READ); + g_assert (result == GNOME_VFS_OK); + gnome_vfs_close (handle); + handle = NULL; + /* The credentials should be in the cache, so we shouldn't have been called */ + g_assert (authentication_callback_called == FALSE); + + /* Test 4: Attempt a sync call to something deeper in the namespace. + * which should work without a callback too + */ + + authentication_callback_called = FALSE; + result = gnome_vfs_open (&handle, authentication_uri_child, GNOME_VFS_OPEN_READ); + g_assert (result == GNOME_VFS_OK); + gnome_vfs_close (handle); + handle = NULL; + /* The credentials should be in the cache, so we shouldn't have been called */ + g_assert (authentication_callback_called == FALSE); + + /* Test 5: clear the credential store and try again in reverse order */ + + flush_credentials_func(); + + authentication_callback_called = FALSE; + result = gnome_vfs_open (&handle, authentication_uri_child, GNOME_VFS_OPEN_READ); + g_assert (result == GNOME_VFS_OK); + gnome_vfs_close (handle); + handle = NULL; + g_assert (authentication_callback_called == TRUE); + + /* Test 6: Try something higher in the namespace, which should + * cause the callback to happen again + */ + + authentication_callback_called = FALSE; + result = gnome_vfs_open (&handle, authentication_uri, GNOME_VFS_OPEN_READ); + g_assert (result == GNOME_VFS_OK); + gnome_vfs_close (handle); + handle = NULL; + g_assert (authentication_callback_called == TRUE); + + /* Test 7: Try same URL as in test 4, make sure callback doesn't get called */ + + authentication_callback_called = FALSE; + result = gnome_vfs_open (&handle, authentication_uri_child, GNOME_VFS_OPEN_READ); + g_assert (result == GNOME_VFS_OK); + gnome_vfs_close (handle); + handle = NULL; + g_assert (authentication_callback_called == FALSE); + + /* Test 8: clear the credential store ensure that passing a username as NULL + * cancels the operation, resulting in a ACCESS_DENIED error */ + + flush_credentials_func(); + + authentication_username = NULL; + + authentication_callback_called = FALSE; + result = gnome_vfs_open (&handle, authentication_uri_child, GNOME_VFS_OPEN_READ); + g_assert (result == GNOME_VFS_ERROR_ACCESS_DENIED); + handle = NULL; + g_assert (authentication_callback_called == TRUE); + + + /* Test 9: exercise the "destroy notify" functionality */ + /* Note that job doesn't end until a "close" is called, so the inherited + * callback isn't released until then + */ + + flush_credentials_func(); + authentication_username = "foo"; + + gnome_vfs_module_callback_push (GNOME_VFS_MODULE_CALLBACK_AUTHENTICATION, + authentication_callback, + NULL, + destroy_notify); + + authentication_callback_called = FALSE; + + open_callback_occurred = FALSE; + open_callback_result_expected = GNOME_VFS_OK; + + destroy_notify_occurred = FALSE; + + gnome_vfs_async_open ( + &async_handle, + authentication_uri, + GNOME_VFS_OPEN_READ, + 0, + open_callback, + NULL); + + gnome_vfs_module_callback_pop (GNOME_VFS_MODULE_CALLBACK_AUTHENTICATION); + + g_assert (!destroy_notify_occurred); + + while (!open_callback_occurred) { + g_main_context_iteration (NULL, TRUE); + } + + close_callback_occurred = FALSE; + gnome_vfs_async_close (async_handle, close_callback, NULL); + + while (!close_callback_occurred) { + g_main_context_iteration (NULL, TRUE); + } + + for (i = 0 ; i<100 ; i++) { + g_main_context_iteration (NULL, FALSE); + usleep (10); + } + + g_assert (authentication_callback_called); + g_assert (destroy_notify_occurred); + + gnome_vfs_shutdown (); + + return 0; +} diff --git a/test/test-channel.c b/test/test-channel.c new file mode 100644 index 0000000..e5fa05b --- /dev/null +++ b/test/test-channel.c @@ -0,0 +1,128 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* test-channel.c - Test for the `open_as_channel' functionality of the GNOME + Virtual File System. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli */ + +#include + +#include /* workaround for bug in giochannel.h */ +#include +#include +#include +#include +#include +#include + +#define BUFFER_SIZE 4096 + +static GMainLoop *main_loop; + +static gboolean +io_channel_callback (GIOChannel *source, + GIOCondition condition, + gpointer data) +{ + gchar buffer[BUFFER_SIZE + 1]; + gsize bytes_read; + + printf ("\n\n************ IO Channel callback!\n"); + + if (condition & G_IO_IN) { + g_io_channel_read_chars (source, buffer, sizeof (buffer) - 1, &bytes_read, NULL); + buffer[bytes_read] = 0; + printf ("---> Read %lu byte(s):\n%s\n\n(***END***)\n", + (gulong)bytes_read, buffer); + fflush (stdout); + } + + if (condition & G_IO_NVAL) { + g_warning ("channel_callback got NVAL condition."); + return FALSE; + } + + if (condition & G_IO_HUP) { + printf ("\n----- EOF -----\n"); + fflush (stdout); + g_io_channel_shutdown (source, FALSE, NULL); + g_main_loop_quit (main_loop); + return FALSE; + } + + return TRUE; +} + +static void open_callback (GnomeVFSAsyncHandle *handle, + GIOChannel *channel, + GnomeVFSResult result, + gpointer data) +{ + if (result != GNOME_VFS_OK) { + printf ("Error opening: %s.\n", + gnome_vfs_result_to_string (result)); + return; + } + + printf ("Open successful, callback data `%s'.\n", (gchar *) data); + g_io_add_watch_full (channel, + G_PRIORITY_HIGH, + G_IO_IN | G_IO_NVAL | G_IO_HUP, + io_channel_callback, handle, + NULL); + + g_io_channel_unref (channel); +} + + +int +main (int argc, char **argv) +{ + GnomeVFSAsyncHandle *handle; + + if (argc < 2) { + fprintf (stderr, "Usage: %s \n", argv[0]); + return 1; + } + + puts ("Initializing gnome-vfs..."); + gnome_vfs_init (); + + printf ("Starting open for `%s'...\n", argv[1]); + gnome_vfs_async_open_as_channel (&handle, argv[1], + GNOME_VFS_OPEN_READ, + BUFFER_SIZE, + 0, + open_callback, + "open_callback"); + + puts ("GTK+ main loop running."); + main_loop = g_main_loop_new (NULL, TRUE); + g_main_loop_run (main_loop); + g_main_loop_unref (main_loop); + + puts ("GTK+ main loop finished."); + + puts ("All done"); + + while (1) + ; + + return 0; +} diff --git a/test/test-directory-visit.c b/test/test-directory-visit.c new file mode 100644 index 0000000..f621c21 --- /dev/null +++ b/test/test-directory-visit.c @@ -0,0 +1,111 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* test-directory-visit.c - Test program for the directory visiting functions + of the GNOME Virtual File System. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli */ + +#include + +#include +#include +#include +#include + +static const gchar * +type_to_string (GnomeVFSFileType type) +{ + switch (type) { + case GNOME_VFS_FILE_TYPE_UNKNOWN: + return "Unknown"; + case GNOME_VFS_FILE_TYPE_REGULAR: + return "Regular"; + case GNOME_VFS_FILE_TYPE_DIRECTORY: + return "Directory"; + case GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK: + return "Symbolic Link"; + case GNOME_VFS_FILE_TYPE_FIFO: + return "FIFO"; + case GNOME_VFS_FILE_TYPE_SOCKET: + return "Socket"; + case GNOME_VFS_FILE_TYPE_CHARACTER_DEVICE: + return "Character device"; + case GNOME_VFS_FILE_TYPE_BLOCK_DEVICE: + return "Block device"; + default: + return "???"; + } +} + +static gboolean +directory_visit_callback (const gchar *rel_path, + GnomeVFSFileInfo *info, + gboolean recursing_will_loop, + gpointer data, + gboolean *recurse) +{ + printf ("directory_visit_callback -- rel_path `%s' data `%s'\n", + rel_path, (gchar *) data); + + printf (" File `%s'%s (%s, %s), size %ld, mode %04o\n", + info->name, + GNOME_VFS_FILE_INFO_SYMLINK (info) ? " [link]" : "", + type_to_string (info->type), + gnome_vfs_file_info_get_mime_type (info), + (glong) info->size, info->permissions); + + if (info->name[0] != '.' + || (info->name[1] != '.' && info->name[1] != 0) + || info->name[2] != 0) { + if (recursing_will_loop) { + printf ("Loop detected\n"); + exit (1); + } + *recurse = TRUE; + } else { + *recurse = FALSE; + } + + return TRUE; +} + +int +main (int argc, char **argv) +{ + GnomeVFSResult result; + + if (argc != 2) { + fprintf (stderr, "Usage: %s \n", argv[0]); + return 1; + } + + gnome_vfs_init (); + + result = gnome_vfs_directory_visit + (argv[1], + (GNOME_VFS_FILE_INFO_FOLLOW_LINKS + | GNOME_VFS_FILE_INFO_FORCE_FAST_MIME_TYPE), + GNOME_VFS_DIRECTORY_VISIT_LOOPCHECK, + directory_visit_callback, + "stringa"); + + printf ("Result: %s\n", gnome_vfs_result_to_string (result)); + + return 0; +} diff --git a/test/test-directory.c b/test/test-directory.c new file mode 100644 index 0000000..183bcf3 --- /dev/null +++ b/test/test-directory.c @@ -0,0 +1,202 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* test-directory.c - Test program for directory reading in the GNOME + Virtual File System. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +static int measure_speed = 0; + +struct poptOption options[] = { + { + "measure-speed", + 'm', + POPT_ARG_NONE, + &measure_speed, + 0, + "Measure speed without displaying anything", + NULL + }, + { + NULL, + 0, + 0, + NULL, + 0, + NULL, + NULL + } +}; + + +static void +show_result (GnomeVFSResult result, const gchar *what, const gchar *text_uri) +{ + fprintf (stderr, "%s `%s': %s\n", + what, text_uri, gnome_vfs_result_to_string (result)); + if (result != GNOME_VFS_OK) + { + fprintf (stdout, "Error: %s\n", + gnome_vfs_result_to_string (result)); + exit (1); + } +} + +static const gchar * +type_to_string (GnomeVFSFileType type) +{ + switch (type) { + case GNOME_VFS_FILE_TYPE_UNKNOWN: + return "Unknown"; + case GNOME_VFS_FILE_TYPE_REGULAR: + return "Regular"; + case GNOME_VFS_FILE_TYPE_DIRECTORY: + return "Directory"; + case GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK: + return "Symbolic Link"; + case GNOME_VFS_FILE_TYPE_FIFO: + return "FIFO"; + case GNOME_VFS_FILE_TYPE_SOCKET: + return "Socket"; + case GNOME_VFS_FILE_TYPE_CHARACTER_DEVICE: + return "Character device"; + case GNOME_VFS_FILE_TYPE_BLOCK_DEVICE: + return "Block device"; + default: + return "???"; + } +} + +static void +print_list (GList *list) +{ + GnomeVFSFileInfo *info; + GList *node; + + if (list == NULL) { + printf (" (No files)\n"); + return; + } + + for (node = list; node != NULL; node = node->next) { + const gchar *mime_type; + + info = node->data; + + mime_type = gnome_vfs_file_info_get_mime_type (info); + if (mime_type == NULL) + mime_type = "(Unknown)"; + + printf (" File `%s'%s%s%s (%s, %s), size %ld, mode %04o\n", + info->name, + GNOME_VFS_FILE_INFO_SYMLINK (info) ? " [link: " : "", + GNOME_VFS_FILE_INFO_SYMLINK (info) ? info->symlink_name : "", + GNOME_VFS_FILE_INFO_SYMLINK (info) ? " ]" : "", + type_to_string (info->type), + mime_type, + (glong) info->size, + info->permissions); + } +} + +int +main (int argc, const char **argv) +{ + GList *list; + GnomeVFSResult result; + GTimer *timer; + const char **args; + gchar *text_uri; + poptContext popt_context; + + popt_context = poptGetContext ("test-directory", argc, + (const char **) argv, options, 0); + + while (poptGetNextOpt (popt_context) != -1) + ; + + args = poptGetArgs (popt_context); + if (args == NULL || args[1] != NULL) { + fprintf (stderr, "Usage: %s [] \n", argv[0]); + return 1; + } + + text_uri = g_strdup (args[0]); + + poptFreeContext (popt_context); + + gnome_vfs_init (); + + printf ("Loading directory..."); + fflush (stdout); + + if (measure_speed) { + timer = g_timer_new (); + g_timer_start (timer); + } else { + timer = NULL; + } + + /* Load with without requesting any metadata. */ + result = gnome_vfs_directory_list_load + (&list, text_uri, + (GNOME_VFS_FILE_INFO_GET_MIME_TYPE + | GNOME_VFS_FILE_INFO_FORCE_FAST_MIME_TYPE + | GNOME_VFS_FILE_INFO_FOLLOW_LINKS)); + + if (result == GNOME_VFS_OK && measure_speed) { + gdouble elapsed_seconds; + guint num_entries; + + g_timer_stop (timer); + elapsed_seconds = g_timer_elapsed (timer, NULL); + num_entries = g_list_length (list); + printf ("\n%.5f seconds for %d unsorted entries, %.5f entries/sec.\n", + elapsed_seconds, num_entries, + (double) num_entries / elapsed_seconds); + } + + if (!measure_speed) { + printf ("Ok\n"); + + show_result (result, "load_directory", text_uri); + + printf ("Listing for `%s':\n", text_uri); + print_list (list); + } + + printf ("Destroying.\n"); + gnome_vfs_file_info_list_free (list); + + printf ("Done.\n"); + + g_free (text_uri); + + return 0; +} diff --git a/test/test-dirop.c b/test/test-dirop.c new file mode 100644 index 0000000..594d936 --- /dev/null +++ b/test/test-dirop.c @@ -0,0 +1,89 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* test-unlink.c - Test program for unlink operation in the GNOME + Virtual File System. + + Copyright (C) 1999 Free Software Foundation + Copyright (C) 2000 Eazel Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: + Ettore Perazzoli + Ian McKellar + */ + +#include + +#include +#include +#include +#include +#include +#include + +static void +show_result (GnomeVFSResult result, const gchar *what, const gchar *text_uri) +{ + fprintf (stderr, "%s `%s': %s\n", + what, text_uri, gnome_vfs_result_to_string (result)); + if (result != GNOME_VFS_OK) + exit (1); +} + +int +main (int argc, char **argv) +{ + GnomeVFSResult result; + GnomeVFSURI *uri; + gchar *text_uri; + + if (argc != 3 && argc != 4) { + printf ("Usage: %s make [mode]\n %s remove) \n", argv[0], argv[0]); + return 1; + } + + if (! gnome_vfs_init ()) { + fprintf (stderr, "Cannot initialize gnome-vfs.\n"); + return 1; + } + + uri = gnome_vfs_uri_new (argv[2]); + if (uri == NULL) { + fprintf (stderr, "URI not valid.\n"); + return 1; + } + + text_uri = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE); + + if(!strcmp(argv[1], "make")) { + int mode = 0755; + + if (argc == 4) { + mode = strtol (argv[3], (char **)NULL, 8); + } + result = gnome_vfs_make_directory_for_uri (uri, mode); + show_result (result, "make_directory", text_uri); + } else if(!strcmp(argv[1], "remove")) { + result = gnome_vfs_remove_directory_from_uri (uri); + show_result (result, "remove_directory", text_uri); + } else { + fprintf (stderr, "Unknown directory operation `%s'\n", argv[1]); + } + + g_free (text_uri); + + return 0; +} diff --git a/test/test-escape.c b/test/test-escape.c new file mode 100644 index 0000000..ddc9c3c --- /dev/null +++ b/test/test-escape.c @@ -0,0 +1,313 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* test-async-cancel.c - Test program for the GNOME Virtual File System. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Darin Adler +*/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#define TEST_ASSERT(expression, message) \ + G_STMT_START { if (!(expression)) test_failed message; } G_STMT_END + +static void +stop_after_log (const char *domain, GLogLevelFlags level, + const char *message, gpointer data) +{ + void (* saved_handler) (int); + + g_log_default_handler (domain, level, message, data); + + saved_handler = signal (SIGINT, SIG_IGN); + raise (SIGINT); + signal (SIGINT, saved_handler); +} + +static void +make_asserts_break (const char *domain) +{ + g_log_set_handler + (domain, + (GLogLevelFlags) (G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING), + stop_after_log, NULL); +} + +static gboolean at_least_one_test_failed = FALSE; + +static void +test_failed (const char *format, ...) +{ + va_list arguments; + char *message; + + va_start (arguments, format); + message = g_strdup_vprintf (format, arguments); + va_end (arguments); + + g_message ("test failed: %s", message); + at_least_one_test_failed = TRUE; +} + +static void +test_escape (const char *input, const char *expected_output) +{ + char *output; + + output = gnome_vfs_escape_string (input); + + if (strcmp (output, expected_output) != 0) { + test_failed ("escaping %s resulted in %s instead of %s", + input, output, expected_output); + } + + g_free (output); +} + +static void +test_escape_path (const char *input, const char *expected_output) +{ + char *output; + + output = gnome_vfs_escape_path_string (input); + + if (strcmp (output, expected_output) != 0) { + test_failed ("escaping path %s resulted in %s instead of %s", + input, output, expected_output); + } + + g_free (output); +} + +static void +test_unescape (const char *input, const char *illegal, const char *expected_output) +{ + char *output; + + output = gnome_vfs_unescape_string (input, illegal); + if (expected_output == NULL) { + if (output != NULL) { + test_failed ("unescaping %s resulted in %s instead of NULL", + input, illegal, output); + } + } else { + if (output == NULL) { + test_failed ("unescaping %s resulted in NULL instead of %s", + input, illegal, expected_output); + } else if (strcmp (output, expected_output) != 0) { + test_failed ("unescaping %s with %s illegal resulted in %s instead of %s", + input, illegal, output, expected_output); + } + } + + g_free (output); +} + +static void +test_unescape_display (const char *input, const char *expected_output) +{ + char *output; + + output = gnome_vfs_unescape_string_for_display (input); + if (expected_output == NULL) { + if (output != NULL) { + test_failed ("unescaping %s for display resulted in %s instead of NULL", + input, output); + } + } else { + if (output == NULL) { + test_failed ("unescaping %s for display resulted in NULL instead of %s", + input, expected_output); + } else if (strcmp (output, expected_output) != 0) { + test_failed ("unescaping %s for display resulted in %s instead of %s", + input, output, expected_output); + } + } + + g_free (output); +} + +int +main (int argc, char **argv) +{ + make_asserts_break ("GnomeVFS"); + + gnome_vfs_init (); + + test_escape ("", ""); + + test_escape ("ABCDEFGHIJKLMNOPQRSTUVWXYZ", "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + test_escape ("abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz"); + test_escape ("0123456789", "0123456789"); + test_escape ("-_.!~*'()", "-_.!~*'()"); + + test_escape ("\x01\x02\x03\x04\x05\x06\x07", "%01%02%03%04%05%06%07"); + test_escape ("\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", "%08%09%0A%0B%0C%0D%0E%0F"); + test_escape (" \"#$%&+,/", "%20%22%23%24%25%26%2B%2C%2F"); + test_escape (":;<=>?@", "%3A%3B%3C%3D%3E%3F%40"); + test_escape ("[\\]^`", "%5B%5C%5D%5E%60"); + test_escape ("{|}\x7F", "%7B%7C%7D%7F"); + + test_escape ("\x80\x81\x82\x83\x84\x85\x86\x87", "%80%81%82%83%84%85%86%87"); + test_escape ("\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F", "%88%89%8A%8B%8C%8D%8E%8F"); + test_escape ("\x90\x91\x92\x93\x94\x95\x96\x97", "%90%91%92%93%94%95%96%97"); + test_escape ("\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F", "%98%99%9A%9B%9C%9D%9E%9F"); + test_escape ("\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7", "%A0%A1%A2%A3%A4%A5%A6%A7"); + test_escape ("\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF", "%A8%A9%AA%AB%AC%AD%AE%AF"); + test_escape ("\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7", "%B0%B1%B2%B3%B4%B5%B6%B7"); + test_escape ("\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF", "%B8%B9%BA%BB%BC%BD%BE%BF"); + test_escape ("\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7", "%C0%C1%C2%C3%C4%C5%C6%C7"); + test_escape ("\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF", "%C8%C9%CA%CB%CC%CD%CE%CF"); + test_escape ("\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7", "%D0%D1%D2%D3%D4%D5%D6%D7"); + test_escape ("\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF", "%D8%D9%DA%DB%DC%DD%DE%DF"); + test_escape ("\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7", "%E0%E1%E2%E3%E4%E5%E6%E7"); + test_escape ("\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF", "%E8%E9%EA%EB%EC%ED%EE%EF"); + test_escape ("\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7", "%F0%F1%F2%F3%F4%F5%F6%F7"); + test_escape ("\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF", "%F8%F9%FA%FB%FC%FD%FE%FF"); + + test_escape_path ("", ""); + + test_escape_path ("ABCDEFGHIJKLMNOPQRSTUVWXYZ", "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + test_escape_path ("abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz"); + test_escape_path ("0123456789", "0123456789"); + test_escape_path ("-_.!~*'()/", "-_.!~*'()/"); + + test_escape_path ("\x01\x02\x03\x04\x05\x06\x07", "%01%02%03%04%05%06%07"); + test_escape_path ("\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", "%08%09%0A%0B%0C%0D%0E%0F"); + test_escape_path (" \"#$%&+,", "%20%22%23%24%25&%2B%2C"); + test_escape_path (":;<=>?@", "%3A%3B%3C=%3E?%40"); + test_escape_path ("[\\]^`", "%5B%5C%5D%5E%60"); + test_escape_path ("{|}\x7F", "%7B%7C%7D%7F"); + + test_escape_path ("\x80\x81\x82\x83\x84\x85\x86\x87", "%80%81%82%83%84%85%86%87"); + test_escape_path ("\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F", "%88%89%8A%8B%8C%8D%8E%8F"); + test_escape_path ("\x90\x91\x92\x93\x94\x95\x96\x97", "%90%91%92%93%94%95%96%97"); + test_escape_path ("\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F", "%98%99%9A%9B%9C%9D%9E%9F"); + test_escape_path ("\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7", "%A0%A1%A2%A3%A4%A5%A6%A7"); + test_escape_path ("\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF", "%A8%A9%AA%AB%AC%AD%AE%AF"); + test_escape_path ("\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7", "%B0%B1%B2%B3%B4%B5%B6%B7"); + test_escape_path ("\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF", "%B8%B9%BA%BB%BC%BD%BE%BF"); + test_escape_path ("\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7", "%C0%C1%C2%C3%C4%C5%C6%C7"); + test_escape_path ("\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF", "%C8%C9%CA%CB%CC%CD%CE%CF"); + test_escape_path ("\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7", "%D0%D1%D2%D3%D4%D5%D6%D7"); + test_escape_path ("\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF", "%D8%D9%DA%DB%DC%DD%DE%DF"); + test_escape_path ("\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7", "%E0%E1%E2%E3%E4%E5%E6%E7"); + test_escape_path ("\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF", "%E8%E9%EA%EB%EC%ED%EE%EF"); + test_escape_path ("\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7", "%F0%F1%F2%F3%F4%F5%F6%F7"); + test_escape_path ("\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF", "%F8%F9%FA%FB%FC%FD%FE%FF"); + + test_unescape ("", NULL, ""); + test_unescape ("", "", ""); + test_unescape ("", "/", ""); + test_unescape ("", "/:", ""); + + test_unescape ("/", "/", "/"); + test_unescape ("%2f", NULL, "/"); + test_unescape ("%2F", NULL, "/"); + test_unescape ("%2F", "/", NULL); + test_unescape ("%", NULL, NULL); + test_unescape ("%1", NULL, NULL); + test_unescape ("%aa", NULL, "\xAA"); + test_unescape ("%ag", NULL, NULL); + test_unescape ("%g", NULL, NULL); + test_unescape ("%%", NULL, NULL); + test_unescape ("%1%1", NULL, NULL); + test_unescape ("ABCDEFGHIJKLMNOPQRSTUVWXYZ", NULL, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + test_unescape ("abcdefghijklmnopqrstuvwxyz", NULL, "abcdefghijklmnopqrstuvwxyz"); + test_unescape ("0123456789", NULL, "0123456789"); + test_unescape ("-_.!~*'()", NULL, "-_.!~*'()"); + + test_unescape ("%01%02%03%04%05%06%07", NULL, "\x01\x02\x03\x04\x05\x06\x07"); + test_unescape ("%08%09%0A%0B%0C%0D%0E%0F", NULL, "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"); + test_unescape ("%20%22%23%24%25%26%2B%2C%2F", NULL, " \"#$%&+,/"); + test_unescape ("%3A%3B%3C%3D%3E%3F%40", NULL, ":;<=>?@"); + test_unescape ("%5B%5C%5D%5E%60", NULL, "[\\]^`"); + test_unescape ("%7B%7C%7D%7F", NULL, "{|}\x7F"); + + test_unescape ("%80%81%82%83%84%85%86%87", NULL, "\x80\x81\x82\x83\x84\x85\x86\x87"); + test_unescape ("%88%89%8A%8B%8C%8D%8E%8F", NULL, "\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F"); + test_unescape ("%90%91%92%93%94%95%96%97", NULL, "\x90\x91\x92\x93\x94\x95\x96\x97"); + test_unescape ("%98%99%9A%9B%9C%9D%9E%9F", NULL, "\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F"); + test_unescape ("%A0%A1%A2%A3%A4%A5%A6%A7", NULL, "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7"); + test_unescape ("%A8%A9%AA%AB%AC%AD%AE%AF", NULL, "\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF"); + test_unescape ("%B0%B1%B2%B3%B4%B5%B6%B7", NULL, "\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7"); + test_unescape ("%B8%B9%BA%BB%BC%BD%BE%BF", NULL, "\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF"); + test_unescape ("%C0%C1%C2%C3%C4%C5%C6%C7", NULL, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7"); + test_unescape ("%C8%C9%CA%CB%CC%CD%CE%CF", NULL, "\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF"); + test_unescape ("%D0%D1%D2%D3%D4%D5%D6%D7", NULL, "\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7"); + test_unescape ("%D8%D9%DA%DB%DC%DD%DE%DF", NULL, "\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF"); + test_unescape ("%E0%E1%E2%E3%E4%E5%E6%E7", NULL, "\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7"); + test_unescape ("%E8%E9%EA%EB%EC%ED%EE%EF", NULL, "\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF"); + test_unescape ("%F0%F1%F2%F3%F4%F5%F6%F7", NULL, "\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7"); + test_unescape ("%F8%F9%FA%FB%FC%FD%FE%FF", NULL, "\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF"); + + test_unescape_display ("ABC%00DEF", "ABC%00DEF"); + test_unescape_display ("%20%22%23%24%25%26%2B%00%2C%2F", " \"#$%&+%00,/"); + test_unescape_display ("", ""); + test_unescape_display ("%1%1", "%1%1"); + test_unescape_display ("/", "/"); + test_unescape_display ("%2f", "/"); + test_unescape_display ("%2F", "/"); + test_unescape_display ("%", "%"); + test_unescape_display ("%1", "%1"); + test_unescape_display ("%aa", "\xAA"); + test_unescape_display ("%ag", "%ag"); + test_unescape_display ("%g", "%g"); + test_unescape_display ("%%", "%%"); + test_unescape_display ("%%20", "% "); + test_unescape_display ("ABCDEFGHIJKLMNOPQRSTUVWXYZ", "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + test_unescape_display ("abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz"); + test_unescape_display ("0123456789", "0123456789"); + test_unescape_display ("-_.!~*'()", "-_.!~*'()"); + + test_unescape_display ("%01%02%03%04%05%06%07", "\x01\x02\x03\x04\x05\x06\x07"); + test_unescape_display ("%08%09%0A%0B%0C%0D%0E%0F", "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"); + test_unescape_display ("%20%22%23%24%25%26%2B%2C%2F", " \"#$%&+,/"); + test_unescape_display ("%3A%3B%3C%3D%3E%3F%40", ":;<=>?@"); + test_unescape_display ("%5B%5C%5D%5E%60", "[\\]^`"); + test_unescape_display ("%7B%7C%7D%7F", "{|}\x7F"); + + test_unescape_display ("%80%81%82%83%84%85%86%87", "\x80\x81\x82\x83\x84\x85\x86\x87"); + test_unescape_display ("%88%89%8A%8B%8C%8D%8E%8F", "\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F"); + test_unescape_display ("%90%91%92%93%94%95%96%97", "\x90\x91\x92\x93\x94\x95\x96\x97"); + test_unescape_display ("%98%99%9A%9B%9C%9D%9E%9F", "\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F"); + test_unescape_display ("%A0%A1%A2%A3%A4%A5%A6%A7", "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7"); + test_unescape_display ("%A8%A9%AA%AB%AC%AD%AE%AF", "\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF"); + test_unescape_display ("%B0%B1%B2%B3%B4%B5%B6%B7", "\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7"); + test_unescape_display ("%B8%B9%BA%BB%BC%BD%BE%BF", "\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF"); + test_unescape_display ("%C0%C1%C2%C3%C4%C5%C6%C7", "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7"); + test_unescape_display ("%C8%C9%CA%CB%CC%CD%CE%CF", "\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF"); + test_unescape_display ("%D0%D1%D2%D3%D4%D5%D6%D7", "\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7"); + test_unescape_display ("%D8%D9%DA%DB%DC%DD%DE%DF", "\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF"); + test_unescape_display ("%E0%E1%E2%E3%E4%E5%E6%E7", "\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7"); + test_unescape_display ("%E8%E9%EA%EB%EC%ED%EE%EF", "\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF"); + test_unescape_display ("%F0%F1%F2%F3%F4%F5%F6%F7", "\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7"); + test_unescape_display ("%F8%F9%FA%FB%FC%FD%FE%FF", "\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF"); + + /* Report to "make check" on whether it all worked or not. */ + return at_least_one_test_failed ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/test/test-find-directory.c b/test/test-find-directory.c new file mode 100644 index 0000000..f15fed1 --- /dev/null +++ b/test/test-find-directory.c @@ -0,0 +1,85 @@ +/* test-mime.c - Test for the gnome_vfs_find_directory call + Virtual File System Library + + Copyright (C) 2000 Eazel + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Pavel Cisler +*/ + +#include + +#include +#include +#include +#include +#include +#include + +int +main (int argc, char **argv) +{ + GnomeVFSURI *uri; + GnomeVFSURI *result; + GnomeVFSResult error; + char *path; + gboolean create; + + create = FALSE; + + if (!gnome_vfs_init ()) { + fprintf (stderr, "Cannot initialize gnome-vfs.\n"); + return 1; + } + + if (argc == 1) { + fprintf (stderr, "Usage: %s [-create] near_uri \n", *argv); + return 1; + } + + + ++argv; + + if (strcmp (*argv, "-create") == 0) { + create = TRUE; + ++argv; + } + + uri = gnome_vfs_uri_new (*argv); + error = gnome_vfs_find_directory (uri, GNOME_VFS_DIRECTORY_KIND_TRASH, &result, create, + TRUE, 0777); + if (error == GNOME_VFS_OK) { + path = gnome_vfs_uri_to_string (result, GNOME_VFS_URI_HIDE_NONE); + g_print ("found trash at %s\n", path); + g_free (path); + error = gnome_vfs_find_directory (uri, GNOME_VFS_DIRECTORY_KIND_TRASH, + &result, FALSE, FALSE, 0777); + if (error == GNOME_VFS_OK) { + path = gnome_vfs_uri_to_string (result, GNOME_VFS_URI_HIDE_NONE); + g_print ("found it again in a cached entry at %s\n", path); + g_free (path); + } else { + g_print ("error %s finding cached trash entry near %s\n", gnome_vfs_result_to_string (error), + *argv); + } + } else { + g_print ("error %s finding trash near %s\n", gnome_vfs_result_to_string (error), + *argv); + } + + return 0; +} diff --git a/test/test-info.c b/test/test-info.c new file mode 100644 index 0000000..71268af --- /dev/null +++ b/test/test-info.c @@ -0,0 +1,188 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* test-info.c - Test program for the `get_file_info()' functionality of the + GNOME Virtual File System. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli */ + + +#include + +#include +#include +#include +#include +#include + +static const gchar * +type_to_string (GnomeVFSFileType type) +{ + switch (type) { + case GNOME_VFS_FILE_TYPE_UNKNOWN: + return "Unknown"; + case GNOME_VFS_FILE_TYPE_REGULAR: + return "Regular"; + case GNOME_VFS_FILE_TYPE_DIRECTORY: + return "Directory"; + case GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK: + return "Symbolic Link"; + case GNOME_VFS_FILE_TYPE_FIFO: + return "FIFO"; + case GNOME_VFS_FILE_TYPE_SOCKET: + return "Socket"; + case GNOME_VFS_FILE_TYPE_CHARACTER_DEVICE: + return "Character device"; + case GNOME_VFS_FILE_TYPE_BLOCK_DEVICE: + return "Block device"; + default: + return "???"; + } +} + + +static void +print_file_info (const GnomeVFSFileInfo *info) +{ +#define FLAG_STRING(info, which) \ + (GNOME_VFS_FILE_INFO_##which (info) ? "YES" : "NO") + + printf ("Name : %s\n", info->name); + + if(info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_TYPE) + printf ("Type : %s\n", type_to_string (info->type)); + + if(info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_SYMLINK_NAME && info->symlink_name != NULL) + printf ("Symlink to : %s\n", info->symlink_name); + + if(info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE) + printf ("MIME type : %s\n", info->mime_type); + + if(info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_SIZE) + printf ("Size : %" GNOME_VFS_SIZE_FORMAT_STR "\n", + info->size); + + if(info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_BLOCK_COUNT) + printf ("Blocks : %" GNOME_VFS_SIZE_FORMAT_STR "\n", + info->block_count); + + if(info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_IO_BLOCK_SIZE) + printf ("I/O block size : %d\n", info->io_block_size); + + if(info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_FLAGS) { + printf ("Local : %s\n", FLAG_STRING (info, LOCAL)); + printf ("SUID : %s\n", FLAG_STRING (info, SUID)); + printf ("SGID : %s\n", FLAG_STRING (info, SGID)); + printf ("Sticky : %s\n", FLAG_STRING (info, STICKY)); + } + + if(info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS) + printf ("Permissions : %04o\n", info->permissions); + + + if(info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_LINK_COUNT) + printf ("Link count : %d\n", info->link_count); + + printf ("UID : %d\n", info->uid); + printf ("GID : %d\n", info->gid); + + if(info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_ATIME) + printf ("Access time : %s", ctime (&info->atime)); + + if(info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_MTIME) + printf ("Modification time : %s", ctime (&info->mtime)); + + if(info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_CTIME) + printf ("Change time : %s", ctime (&info->ctime)); + + if(info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_DEVICE) + printf ("Device # : %ld\n", (gulong) info->device); + + if(info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_INODE) + printf ("Inode # : %ld\n", (gulong) info->inode); + + if(info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_ACCESS) { + printf ("Readable : %s\n", + (info->permissions&GNOME_VFS_PERM_ACCESS_READABLE?"YES":"NO")); + printf ("Writable : %s\n", + (info->permissions&GNOME_VFS_PERM_ACCESS_WRITABLE?"YES":"NO")); + printf ("Executable : %s\n", + (info->permissions&GNOME_VFS_PERM_ACCESS_EXECUTABLE?"YES":"NO")); + } + + +#undef FLAG_STRING +} + + int +main (int argc, + char **argv) +{ + GnomeVFSFileInfo *info; + GnomeVFSURI *vfs_uri; + GnomeVFSResult result; + gchar *uri; + int i=1; + + if (argc < 2) { + fprintf (stderr, "Usage: %s [...]\n", argv[0]); + return 1; + } + + if (!gnome_vfs_init ()) { + fprintf (stderr, "%s: Cannot initialize the GNOME Virtual File System.\n", + argv[0]); + return 1; + } + + while (i < argc) { + const char *path; + + uri = argv[i]; + + g_print("Getting info for \"%s\".\n", uri); + + info = gnome_vfs_file_info_new (); + result = gnome_vfs_get_file_info (uri, + info, + (GNOME_VFS_FILE_INFO_GET_MIME_TYPE + | GNOME_VFS_FILE_INFO_GET_ACCESS_RIGHTS + | GNOME_VFS_FILE_INFO_FOLLOW_LINKS)); + if (result != GNOME_VFS_OK) { + fprintf (stderr, "%s: %s: %s\n", + argv[0], uri, gnome_vfs_result_to_string (result)); + i++; + return result; + } + + print_file_info (info); + + gnome_vfs_file_info_unref (info); + + vfs_uri = gnome_vfs_uri_new (uri); + path = gnome_vfs_uri_get_path (vfs_uri); + printf ("Path: %s\n", path ? path : ""); + printf (gnome_vfs_uri_is_local (vfs_uri) + ? "File is local\n" : "File is not local\n"); + gnome_vfs_uri_unref (vfs_uri); + + i++; + } + + return 0; +} diff --git a/test/test-mime-handlers-set.c b/test/test-mime-handlers-set.c new file mode 100644 index 0000000..9584e06 --- /dev/null +++ b/test/test-mime-handlers-set.c @@ -0,0 +1,170 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* test-mime.c - Test for the mime handler detection features of the GNOME + Virtual File System Library + + Copyright (C) 2000 Eazel + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Maciej Stachowiak +*/ + +#include + +#include +#include +#include +#include +#include +#include + + +static void +usage (const char *name) +{ + fprintf (stderr, "Usage: %s mime_type field value\n", name); + fprintf (stderr, "Valid field values are: \n"); + fprintf (stderr, "\tdefault_action_type\n"); + fprintf (stderr, "\tdefault_application\n"); + fprintf (stderr, "\tdefault_component\n"); + fprintf (stderr, "\tshort_list_applicationss\n"); + fprintf (stderr, "\tshort_list_components\n"); + fprintf (stderr, "\tadd_to_all_applicationss\n"); + fprintf (stderr, "\tremove_from_all_applications\n"); + fprintf (stderr, "\tdefine_application\n"); + exit (1); +} + +static GnomeVFSMimeActionType +str_to_action_type (const char *str) +{ + if (g_ascii_strcasecmp (str, "component") == 0) { + return GNOME_VFS_MIME_ACTION_TYPE_COMPONENT; + } else if (g_ascii_strcasecmp (str, "application") == 0) { + return GNOME_VFS_MIME_ACTION_TYPE_APPLICATION; + } else { + return GNOME_VFS_MIME_ACTION_TYPE_NONE; + } +} + +static char ** +strsplit_handle_null (const char *str, const char *delim, int max) +{ + return g_strsplit ((str == NULL ? "" : str), delim, max); +} + + +static GList *gnome_vfs_strsplit_to_list (const char *str, const char *delim, int max) +{ + char **strv; + GList *retval; + int i; + + strv = strsplit_handle_null (str, delim, max); + + retval = NULL; + + for (i = 0; strv[i] != NULL; i++) { + retval = g_list_prepend (retval, strv[i]); + } + + retval = g_list_reverse (retval); + /* Don't strfreev, since we didn't copy the individual strings. */ + g_free (strv); + + return retval; +} + +static GList *comma_separated_str_to_str_list (const char *str) +{ + return gnome_vfs_strsplit_to_list (str, ",", 0); +} + + +static gboolean +str_to_bool (const char *str) +{ + return ((str != NULL) && + ((g_ascii_strcasecmp (str, "true") == 0) || + (g_ascii_strcasecmp (str, "yes") == 0))); +} + + +int +main (int argc, char **argv) +{ + const char *type; + const char *field; + const char *value; + + gnome_vfs_init (); + + if (argc < 3) { + usage (argv[0]); + } + + type = argv[1]; + field = argv[2]; + value = argv[3]; + + if (strcmp (field, "default_action_type") == 0) { + puts ("default_action_type"); + gnome_vfs_mime_set_default_action_type (type, str_to_action_type (value)); + } else if (strcmp (field, "default_application") == 0) { + puts ("default_application"); + gnome_vfs_mime_set_default_application (type, value); + } else if (strcmp (field, "default_component") == 0) { + puts ("default_component"); + gnome_vfs_mime_set_default_component (type, value); + } else if (strcmp (field, "short_list_applicationss") == 0) { + puts ("short_list_applications"); + gnome_vfs_mime_set_short_list_applications (type, + comma_separated_str_to_str_list (value)); + } else if (strcmp (field, "short_list_components") == 0) { + puts ("short_list_components"); + gnome_vfs_mime_set_short_list_components (type, + comma_separated_str_to_str_list (value)); + } else if (strcmp (field, "add_to_all_applicationss") == 0) { + puts ("add_to_all_applications"); + gnome_vfs_mime_extend_all_applications (type, + comma_separated_str_to_str_list (value)); + } else if (strcmp (field, "remove_from_all_applications") == 0) { + puts ("remove_from_all_applications"); + gnome_vfs_mime_remove_from_all_applications (type, + comma_separated_str_to_str_list (value)); + + } else if (strcmp (field, "define_application") == 0) { + GList *stuff; + GnomeVFSMimeApplication app; + + stuff = comma_separated_str_to_str_list (value); + + app.id = g_list_nth (stuff, 0)->data; + app.name = g_list_nth (stuff, 1)->data; + app.command = g_list_nth (stuff, 2)->data; + app.can_open_multiple_files = str_to_bool (g_list_nth (stuff, 3)->data); + app.expects_uris = str_to_bool (g_list_nth (stuff, 4)->data); + app.requires_terminal = str_to_bool (g_list_nth (stuff, 5)->data); + + gnome_vfs_application_registry_save_mime_application (&app); + gnome_vfs_application_registry_add_mime_type (app.id, type); + gnome_vfs_application_registry_sync (); + } else { + usage (argv[0]); + } + + return 0; +} diff --git a/test/test-mime-handlers.c b/test/test-mime-handlers.c new file mode 100644 index 0000000..7dc8f62 --- /dev/null +++ b/test/test-mime-handlers.c @@ -0,0 +1,233 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* test-mime.c - Test for the mime handler detection features of the GNOME + Virtual File System Library + + Copyright (C) 2000 Eazel + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Maciej Stachowiak +*/ + +#include + +#include +#include +#include +#include +#include +#include + +static void +append_comma_and_scheme (gpointer scheme, + gpointer user_data) +{ + char **string; + + string = (char **) user_data; + if (*string != NULL) { + char *tmp; + tmp = g_strconcat (*string, ", ", scheme, NULL); + g_free (*string); + *string = tmp; + } else { + *string = g_strdup (scheme); + } +} + + +static char * +format_supported_uri_schemes_for_display (GList *supported_uri_schemes) +{ + char *string; + + string = NULL; + g_list_foreach (supported_uri_schemes, + append_comma_and_scheme, + &string); + return string; +} + +static const char * +format_mime_application_argument_type_for_display (GnomeVFSMimeApplicationArgumentType argument_type) +{ + switch (argument_type) { + case GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_URIS: + return "Always"; + break; + case GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_PATHS: + return "No"; + case GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_URIS_FOR_NON_FILES: + return "For non-files"; + default: + g_assert_not_reached (); + } + return NULL; +} + +static void +print_application (GnomeVFSMimeApplication *application) +{ + if (application == NULL) { + puts ("(none)"); + } else { + gchar *uri_schemes; + + uri_schemes = format_supported_uri_schemes_for_display (application->supported_uri_schemes), + printf ("name: %s\ncommand: %s\ncan_open_multiple_files: %s\nexpects_uris: %s\nsupported_uri_schemes: %s\nrequires_terminal: %s\n", + application->name, application->command, + (application->can_open_multiple_files ? "TRUE" : "FALSE"), + format_mime_application_argument_type_for_display (application->expects_uris), + uri_schemes, + (application->requires_terminal ? "TRUE" : "FALSE")); + g_free (uri_schemes); + } +} + +static void +print_component (Bonobo_ServerInfo *component) +{ + if (component == NULL) { + puts ("(none)"); + } else { + printf ("iid: %s\n", component->iid); + } +} + +static void +print_action (GnomeVFSMimeAction *action) +{ + if (action == NULL) { + puts ("(none)"); + } else { + if (action->action_type == GNOME_VFS_MIME_ACTION_TYPE_APPLICATION) { + puts ("type: application"); + print_application (action->action.application); + } else { + puts ("type: component"); + print_component (action->action.component); + } + } +} + + +static void +print_component_list (GList *components) +{ + GList *p; + if (components == NULL) { + puts ("(none)"); + } else { + for (p = components; p != NULL; p = p->next) { + print_component (p->data); + puts ("------"); + } + + } +} + +static void +print_application_list (GList *applications) +{ + GList *p; + if (applications == NULL) { + puts ("(none)"); + } else { + for (p = applications; p != NULL; p = p->next) { + print_application (p->data); + puts ("------"); + } + + } +} + + +int +main (int argc, char **argv) +{ + char *type; + GnomeVFSMimeApplication *default_application; + Bonobo_ServerInfo *default_component; + GnomeVFSMimeAction *default_action; + const char *description; + GList *all_components; + GList *all_applications; + GList *short_list_components; + GList *short_list_applications; + + gnome_vfs_init (); + if (argc != 2) { + fprintf (stderr, "Usage: %s mime_type\n", *argv); + return 1; + } + + type = argv[1]; + + if (!gnome_vfs_mime_type_is_known (type)) { + fprintf (stderr, "Unknown mime type: %s\n", type); + return 1; + } + + description = gnome_vfs_mime_get_description (type); + printf ("Description: %s\n", description); + + default_action = gnome_vfs_mime_get_default_action (type); + puts ("Default Action"); + print_action (default_action); + puts (""); + gnome_vfs_mime_action_free (default_action); + + default_application = gnome_vfs_mime_get_default_application (type); + puts("Default Application"); + print_application (default_application); + puts (""); + gnome_vfs_mime_application_free (default_application); + + default_component = gnome_vfs_mime_get_default_component (type); + puts("Default Component"); + print_component (default_component); + puts (""); + CORBA_free (default_component); + + short_list_applications = gnome_vfs_mime_get_short_list_applications (type); + puts("Short List Applications"); + print_application_list (short_list_applications); + puts (""); + gnome_vfs_mime_application_list_free (short_list_applications); + + short_list_components = gnome_vfs_mime_get_short_list_components (type); + puts("Short List Components"); + print_component_list (short_list_components); + puts (""); + gnome_vfs_mime_component_list_free (short_list_components); + + all_applications = gnome_vfs_mime_get_all_applications (type); + puts("All Applications"); + print_application_list (all_applications); + puts (""); + gnome_vfs_mime_application_list_free (all_applications); + + all_components = gnome_vfs_mime_get_all_components (type); + puts("All Components"); + print_component_list (all_components); + puts (""); + gnome_vfs_mime_component_list_free (all_components); + + gnome_vfs_shutdown (); + return 0; +} + + diff --git a/test/test-mime-info.c b/test/test-mime-info.c new file mode 100644 index 0000000..70f1b95 --- /dev/null +++ b/test/test-mime-info.c @@ -0,0 +1,242 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* test-mime.c - Test for the mime handler detection features of the GNOME + Virtual File System Library + + Copyright (C) 2000 Eazel + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Maciej Stachowiak +*/ + +#include + +#include +#include +#include +#include +#include +#include + +int +main (int argc, char **argv) +{ + const char *value; + + gnome_vfs_init (); + + /* test reading of gnome-vfs.keys file */ + value = gnome_vfs_mime_get_value ("x-directory/normal", "description"); + if (value == NULL || strcmp (value, "folder") != 0) { + printf ("Error: get_value failed on \"description\".\n"); + exit (1); + } + value = gnome_vfs_mime_get_value ("x-directory/normal", "default_action_type"); + if (value == NULL || strcmp (value, "component") != 0) { + printf ("Error: get_value failed on \"default_action_type\".\n"); + exit (1); + } + /* default_component_iid doesn't appear anymore in gnome-vfs.keys */ +#if 0 + value = gnome_vfs_mime_get_value ("x-directory/normal", "default_component_iid"); + if (value == NULL || strcmp (value, "OAFIID:nautilus_file_manager_icon_view:42681b21-d5ca-4837-87d2-394d88ecc058") != 0) { + printf ("Error: get_value failed on \"default_component_iid\".\n"); + exit (1); + } +#endif + value = gnome_vfs_mime_get_value ("x-directory/normal", "short_list_component_iids_for_novice_user_level"); + if (value == NULL || strcmp (value, + "OAFIID:nautilus_file_manager_icon_view:42681b21-d5ca-4837-87d2-394d88ecc058," + "OAFIID:nautilus_file_manager_list_view:521e489d-0662-4ad7-ac3a-832deabe111c," + "OAFIID:nautilus_music_view:9456b5d2-60a8-407f-a56e-d561e1821391:OAFIID") != 0) { + printf ("Error: get_value failed on \"short_list_component_iids_for_novice_user_level\".\n"); + exit (1); + } + value = gnome_vfs_mime_get_value ("x-directory/normal", "short_list_component_iids_for_intermediate_user_level"); + if (value == NULL || strcmp (value, "OAFIID:nautilus_file_manager_icon_view:42681b21-d5ca-4837-87d2-394d88ecc058," + "OAFIID:nautilus_file_manager_list_view:521e489d-0662-4ad7-ac3a-832deabe111c," + "OAFIID:nautilus_music_view:9456b5d2-60a8-407f-a56e-d561e1821391") != 0) { + printf ("Error: get_value failed on \"short_list_component_iids_for_intermediate_user_level\".\n"); + exit (1); + } + value = gnome_vfs_mime_get_value ("x-directory/normal", "short_list_component_iids_for_advanced_user_level"); + if (value == NULL || strcmp (value, "OAFIID:nautilus_file_manager_icon_view:42681b21-d5ca-4837-87d2-394d88ecc058," + "OAFIID:nautilus_file_manager_list_view:521e489d-0662-4ad7-ac3a-832deabe111c," + "OAFIID:nautilus_music_view:9456b5d2-60a8-407f-a56e-d561e1821391") != 0) { + printf ("Error: get_value failed on \"short_list_component_iids_for_advanced_user_level\".\n"); + exit (1); + } + value = gnome_vfs_mime_get_description ("application/mime-type-test"); + if (value == NULL || strcmp (value, "mon test a moi") != 0) { + printf ("Error: description failed on \"application/mime-type-test\".\n"); + exit (1); + } + + + /* test reading of gnome-vfs.mime file */ + { + GList *list, *temp; + char *extensions[] = {"ps", "eps"}; + char **extension; + char *ext; + list = gnome_vfs_mime_get_extensions_list ("application/postscript"); + if (list == NULL) { + printf ("Error: get_extensions_list failed on \"application/postscript\" list NULL.\n"); + exit (1); + } + for (temp = list, extension = extensions; temp != NULL; temp = temp->next, extension++) { + if (strcmp (*extension, (char *)temp->data) != 0) { + printf ("Error: get_extensions_list failed on \"application/postscript\".\n"); + printf ("Wrong value received was %s instead of %s\n", (char *) temp->data, *extension); + exit (1); + } + } + gnome_vfs_mime_extensions_list_free (list); + + ext = gnome_vfs_mime_get_extensions_string ("application/postscript"); + if (ext == NULL || strcmp (ext, "eps ps") != 0) { + printf ("Error: get_extensions_string failed on \"application/postscript\".\n"); + exit (1); + } + ext = gnome_vfs_mime_get_extensions_pretty_string ("application/postscript"); + if (ext == NULL || strcmp (ext, ".ps, .eps") != 0) { + printf ("Error: get_extensions_pretty_string failed on \"application/postscript\".\n"); + exit (1); + } + } + + /* test writing the users' user.keys file. It should overide the system default */ + { + const char *value; + gnome_vfs_mime_set_value ("application/postscript", + "foo", + "bar"); + value = gnome_vfs_mime_get_value ("application/postscript", + "foo"); + if (value == NULL || strcmp (value, "bar") != 0) { + printf ("%s\n", value); + printf ("Error: set_value failed on \"application/postscript\" / \"foo\".\n"); + exit (1); + } + + /* test freeze/thaw for this stuff */ + gnome_vfs_mime_freeze (); + gnome_vfs_mime_set_value ("application/postscript", + "bar", + "foo"); + value = gnome_vfs_mime_get_value ("application/postscript", + "bar"); + if (value == NULL || strcmp (value, "foo") != 0) { + printf ("%s\n", value); + printf ("Error: set_value failed on \"application/postscript\" / \"bar\".\n"); + exit (1); + } + gnome_vfs_mime_thaw (); + value = gnome_vfs_mime_get_value ("application/postscript", + "bar"); + if (value == NULL || strcmp (value, "foo") != 0) { + printf ("%s\n", value); + printf ("Error: set_value failed on \"application/postscript\" / \"bar\".\n"); + exit (1); + } + + /* try to overide system settings.*/ + gnome_vfs_mime_set_value ("application/postscript", + "description", + "bar"); + value = gnome_vfs_mime_get_value ("application/postscript", + "description"); + if (value == NULL || strcmp (value, "bar") != 0) { + printf ("%s\n", value); + printf ("Error: set_value failed on \"application/postscript\" / \"description\".\n"); + exit (1); + } + + } + + + /* test to try to modify the user.mime file */ + { + char *value, *save; + + save = gnome_vfs_mime_get_extensions_string ("application/postscript"); + gnome_vfs_mime_set_registered_type_key ("application/postscript", "ext", "foo"); + + value = gnome_vfs_mime_get_extensions_string ("application/postscript"); + + if (strstr (value, "foo") == NULL) { + printf ("Error: cannot set mime type new extension.\n"); + exit (1); + } + if (strstr (value, "ps") != NULL) { + printf ("Error: didn't delete default mime type extension.\n"); + exit (1); + } + gnome_vfs_mime_set_registered_type_key ("application/postscript", "ext", save); + } + + { + GList *mime_types_list; + char *deleted_mime_type; + GList *temp; + gboolean found_mime_type; + + mime_types_list = gnome_vfs_get_registered_mime_types (); + + if (mime_types_list->data != NULL) { + /* try to delete a mime type */ + deleted_mime_type = mime_types_list->data; + gnome_vfs_mime_registered_mime_type_delete (deleted_mime_type); + gnome_vfs_mime_registered_mime_type_list_free (mime_types_list); + mime_types_list = gnome_vfs_get_registered_mime_types (); + for (temp = mime_types_list; temp != NULL; temp = temp->next) { + if (strcmp (deleted_mime_type, (char *)temp->data) == 0) { + printf ("Error: could not delete mime type.\n"); + exit (1); + } + } + gnome_vfs_mime_registered_mime_type_list_free (mime_types_list); + + /* reset to system defaults */ + gnome_vfs_mime_reset (); + + /* try to find the original mime type again */ + mime_types_list = gnome_vfs_get_registered_mime_types (); + found_mime_type = FALSE; + for (temp = mime_types_list; temp != NULL; temp = temp->next) { + if (strcmp (deleted_mime_type, (char *)temp->data) == 0) { + found_mime_type = TRUE; + break; + } + } + if (!found_mime_type) { + printf ("Error: lost a mime type.\n"); + exit (1); + } + + } + + } + + /* do hard stuff on the API */ + + printf ("all mime-info-related tests succeeded\n"); + + return 0; +} + + + diff --git a/test/test-mime.c b/test/test-mime.c new file mode 100644 index 0000000..5878fe8 --- /dev/null +++ b/test/test-mime.c @@ -0,0 +1,181 @@ +/* test-mime.c - Test for the mime type sniffing features of GNOME + Virtual File System Library + + Copyright (C) 2000 Eazel + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Pavel Cisler +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include + +static gboolean +is_good_scheme_char (char c) +{ + return g_ascii_isalnum (c) || c == '+' || c == '-' || c == '.'; +} + +static gboolean +is_uri (const char *str) +{ + const char *p; + + if (! g_ascii_isalpha (*str)) { + return FALSE; + } + + p = str + 1; + while (is_good_scheme_char (*p)) { + p++; + } + return *p == ':' && strchr (p, '/') != NULL; +} + +int +main (int argc, char **argv) +{ + GnomeVFSURI *uri; + gboolean magic_only; + gboolean suffix_only; + gboolean dump_table; + gboolean speed_test; + const char *result; + const char *table_path; + char *uri_string; + char *curdir; + char *path; + struct stat tmp; + GTimer *timer; + int i; + + table_path = NULL; + magic_only = FALSE; + dump_table = FALSE; + speed_test = FALSE; + suffix_only = FALSE; + + if (!gnome_vfs_init ()) { + fprintf (stderr, "Cannot initialize gnome-vfs.\n"); + return 1; + } + + if (argc == 1 || strcmp (argv[1], "--help") == 0) { + fprintf (stderr, "Usage: %s [--magicOnly | --suffixOnly] [--dumpTable] " + " [--loadTable ] fileToCheck1 [fileToCheck2 ...] \n", *argv); + return 1; + } + + + ++argv; + for (; *argv; argv++) { + if (strcmp (*argv, "--magicOnly") == 0) { + magic_only = TRUE; + } else if (strcmp (*argv, "--suffixOnly") == 0) { + suffix_only = TRUE; + } else if (strcmp (*argv, "--dumpTable") == 0) { + dump_table = TRUE; + } else if (strcmp (*argv, "--speedTest") == 0) { + speed_test = TRUE; + } else if (strcmp (*argv, "--loadTable") == 0) { + ++argv; + if (!*argv) { + fprintf (stderr, "Table path expected.\n"); + return 1; + } + table_path = *argv; + if (stat(table_path, &tmp) != 0) { + fprintf (stderr, "Table path %s not found.\n", table_path); + return 1; + } + } else { + break; + } + } + + + if (table_path != NULL) { + gnome_vfs_mime_test_get_magic_table (table_path); + } + + if (dump_table) { + gnome_vfs_mime_dump_magic_table (); + } + + if (speed_test) { + timer = g_timer_new (); + g_timer_start (timer); + for (i = 0; i < 100; i++) { + gnome_vfs_mime_info_reload (); + } + fprintf (stderr, "Mime reload took %g(ms)\n", + g_timer_elapsed (timer, NULL) * 10.0); + } + + for (; *argv != NULL; argv++) { + uri_string = g_strdup (*argv); + if (is_uri (uri_string)) { + uri = gnome_vfs_uri_new (*argv); + } else { + uri = NULL; + } + if (uri == NULL) { + if (uri_string[0] == '/') { + path = uri_string; + } else { + curdir = g_get_current_dir (); + path = g_strconcat (curdir, "/", uri_string, NULL); + g_free (uri_string); + g_free (curdir); + } + uri_string = gnome_vfs_get_uri_from_local_path (path); + g_free (path); + uri = gnome_vfs_uri_new (uri_string); + } + if (uri == NULL) { + printf ("%s is neither a full URI nor an absolute filename\n", *argv); + continue; + } + + if (magic_only) { + result = gnome_vfs_get_mime_type_from_file_data (uri); + } else if (suffix_only) { + result = gnome_vfs_get_mime_type_from_uri (uri); + } else { + result = gnome_vfs_get_mime_type (uri_string); + } + + printf ("looks like %s is %s\n", *argv, result); + gnome_vfs_uri_unref (uri); + } + + return bonobo_activation_debug_shutdown (); +} diff --git a/test/test-module-selftest.c b/test/test-module-selftest.c new file mode 100644 index 0000000..96a9feb --- /dev/null +++ b/test/test-module-selftest.c @@ -0,0 +1,134 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* test-module-selftest.c - Test program for the GNOME Virtual File System. + + Copyright (C) 1999 Free Software Foundation + Copyright (C) 2000, 2001 Eazel, Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: + Mike Fleming +*/ + + +/* + * This program executes module self-test code + */ + +#include + +#include +#include +#include +#include +#include +#include + +/* List of modules that have self-test code */ +static const char *self_test_modules[] = { + "http", + NULL +}; + +static void +stop_after_log (const char *domain, GLogLevelFlags level, + const char *message, gpointer data) +{ + void (* saved_handler) (int); + + g_log_default_handler (domain, level, message, data); + + saved_handler = signal (SIGINT, SIG_IGN); + raise (SIGINT); + signal (SIGINT, saved_handler); +} + +static void +make_asserts_break (const char *domain) +{ + g_log_set_handler + (domain, + (GLogLevelFlags) (G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING), + stop_after_log, NULL); +} + + +typedef gboolean (*TestFunc)(void); + +/* Note that, while this initialized gnome-vfs, it does + * not guarentee that gnome-vfs actually loads and initializes + * the modules in question + */ +int +main (int argc, char **argv) +{ + int i; + GModule *module; + TestFunc test_func; + gboolean result; + gboolean running_result; + + make_asserts_break ("GLib"); + make_asserts_break ("GnomeVFS"); + + /* Initialize the libraries we use. */ + gnome_vfs_init (); + + running_result = TRUE; + for (i=0 ; self_test_modules[i] != NULL ; i++) { + char *module_path; + char *dummy_uri_string; + GnomeVFSURI *uri; + + printf ("Module self-test: '%s'\n", self_test_modules[i]); + module_path = g_module_build_path (MODULES_PATH, self_test_modules[i]); + module = g_module_open (module_path, G_MODULE_BIND_LAZY); + g_free (module_path); + module_path = NULL; + + if (module == NULL) { + fprintf (stderr, "Couldn't load module '%s'\n", self_test_modules[i]); + continue; + } + + g_module_symbol (module, "vfs_module_self_test", (gpointer *) &test_func); + + if (test_func == NULL) { + fprintf (stderr, "Module had no self-test func '%s'\n", self_test_modules[i]); + continue; + } + + dummy_uri_string = g_strdup_printf ("%s:///", self_test_modules[i]); + + /* force normal initializing of the module by creating a URI + * for that scheme + */ + uri = gnome_vfs_uri_new (dummy_uri_string); + gnome_vfs_uri_unref (uri); + + g_free (dummy_uri_string); + + result = test_func(); + + fprintf (stderr, "%s: %s\n", self_test_modules[i], result ? "PASS" : "FAIL"); + + running_result = running_result && result; + } + + exit (running_result ? 0 : -1); +} + diff --git a/test/test-monitor.c b/test/test-monitor.c new file mode 100644 index 0000000..cd7766d --- /dev/null +++ b/test/test-monitor.c @@ -0,0 +1,138 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* test-monitor.c - Test program for file monitoringu in the GNOME Virtual + File System. + + Copyright (C) 2001 Ian McKellar + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: + Ian McKellar + */ + +#include + +#include +#include +#include +#include + +static GMainLoop *main_loop; + +static gboolean +timeout_cb (gpointer data) +{ + static int i = 0; + + if (i == 0) + { + unlink ("/tmp/test-monitor"); + g_spawn_command_line_sync ("touch /tmp/test-monitor", + NULL, NULL, NULL, NULL); + } + + if (i == 1) + { + unlink ("/tmp/test-monitor"); + } + + i++; + + return TRUE; +} + +static void +show_result (GnomeVFSResult result, const gchar *what, const gchar *text_uri) +{ + fprintf (stderr, "%s `%s': %s\n", + what, text_uri, gnome_vfs_result_to_string (result)); + if (result != GNOME_VFS_OK) + exit (1); +} + +static void +callback (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) { + static int i = 0; + + g_print ("Got a callback: "); + switch (event_type) { + case GNOME_VFS_MONITOR_EVENT_CHANGED: + g_print ("GNOME_VFS_MONITOR_EVENT_CHANGED"); + break; + case GNOME_VFS_MONITOR_EVENT_DELETED: + g_print ("GNOME_VFS_MONITOR_EVENT_DELETED"); + break; + case GNOME_VFS_MONITOR_EVENT_STARTEXECUTING: + g_print ("GNOME_VFS_MONITOR_EVENT_STARTEXECUTING"); + break; + case GNOME_VFS_MONITOR_EVENT_STOPEXECUTING: + g_print ("GNOME_VFS_MONITOR_EVENT_STOPEXECUTING"); + break; + case GNOME_VFS_MONITOR_EVENT_CREATED: + g_print ("GNOME_VFS_MONITOR_EVENT_CREATED"); + break; + case GNOME_VFS_MONITOR_EVENT_METADATA_CHANGED: + g_print ("GNOME_VFS_MONITOR_EVENT_METADATA_CHANGED"); + break; + default: + g_print ("Unknown monitor type, exiting..."); + exit (1); + } + + g_print (" (%s)", info_uri); + g_print ("\n"); + i++; + if (i >= 2) + exit (0); +} + +int +main (int argc, char **argv) +{ + GnomeVFSResult result; + gchar *text_uri = "/tmp/"; + GnomeVFSMonitorHandle *handle; + + if (! gnome_vfs_init ()) { + fprintf (stderr, "Cannot initialize gnome-vfs.\n"); + return 1; + } + + if (argc == 2) { + text_uri = argv[1]; + } + + result = gnome_vfs_monitor_add (&handle, text_uri, + GNOME_VFS_MONITOR_DIRECTORY, callback, "user data"); + printf ("handle is %p\n", handle); + show_result (result, "monitor_add", text_uri); + + g_timeout_add (1000, timeout_cb, NULL); + + if (result == GNOME_VFS_OK) { + main_loop = g_main_loop_new (NULL, TRUE); + g_main_loop_run (main_loop); + g_main_loop_unref (main_loop); + } + + g_free (text_uri); + + return 0; +} diff --git a/test/test-performance.c b/test/test-performance.c new file mode 100644 index 0000000..420f316 --- /dev/null +++ b/test/test-performance.c @@ -0,0 +1,27 @@ +#include + +#include +#include +#include +#include + +int +main (int argc, char **argv) +{ + int i; + GTimer *timer = g_timer_new (); + + g_type_init (); + gnome_vfs_init (); /* start threads */ + + g_timer_start (timer); + + for (i = 0; i < 10; i++) { + gnome_vfs_mime_info_reload (); + } + + fprintf (stderr, "mime parse took %g(ms)\n", + g_timer_elapsed (timer, NULL) * 100); + + return 0; +} diff --git a/test/test-queue.c b/test/test-queue.c new file mode 100644 index 0000000..afea23e --- /dev/null +++ b/test/test-queue.c @@ -0,0 +1,324 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* test-queue.c - Test program for the GNOME Virtual File System. + + Copyright (C) 2001 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: László Péter +*/ + +/* This is a simple test program for the job queue. + It tests some basic features but to see what's really going on on the + inside you should change + #undef QUEUE_DEBUG + to + #define QUEUE_DEBUG 1 + in libgnomevfs/gnome-vfs-job-queue.c and rebuild gnome-vfs. +*/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TEST_LIMIT 3 + +static GnomeVFSAsyncHandle *test_handle; +static gpointer test_callback_data; +static int jobs_started; +static int jobs_finished; +static int finished_7, finished_0; +static int test_no; +static gboolean verbose = FALSE; + +static gboolean at_least_one_test_failed = FALSE; + +static int prio_db[100]; + +static void +my_yield (int count) +{ + for (; count > 0; count--) { + if (!g_main_context_iteration (NULL, FALSE)) { + break; + } + usleep (10); + } +} + +static gboolean +wait_until_vfs_jobs_gone (void) +{ + int i; + + if (gnome_vfs_job_get_count () == 0) { + return TRUE; + } + + for (i = 0; i < 2000; i++) { + usleep (1000); + g_main_context_iteration (NULL, FALSE); + if (gnome_vfs_job_get_count () == 0) { + return TRUE; + } + } + return FALSE; +} + +static void +get_file_info_callback (GnomeVFSAsyncHandle *handle, + GList *results, + gpointer callback_data) +{ + int this_test_no = *(int *)callback_data; + jobs_finished ++; + if (prio_db[this_test_no] == 7) { + finished_7 = jobs_finished; + } + if (prio_db[this_test_no] == 0) { + finished_0 = jobs_finished; + } + if (verbose) { + printf ("finished test #%d: get_file_info, priority = %d\n", this_test_no, prio_db[this_test_no]); + } + g_free (callback_data); + jobs_started --; +} + +static gboolean +test_get_file_info (const char *uri, int priority) +{ + GList *uri_list; + + /* Start a get_file_info call. */ + test_callback_data = g_malloc (sizeof (int)); + *(int *)test_callback_data = ++test_no; + prio_db[test_no] = priority; + + uri_list = g_list_prepend (NULL, gnome_vfs_uri_new (uri)); + + jobs_started ++; + + if (verbose) { + printf ("starting test #%d: get_file_info, priority = %d\n", test_no, priority); + } + + test_handle = NULL; + gnome_vfs_async_get_file_info (&test_handle, + uri_list, + GNOME_VFS_FILE_INFO_DEFAULT, + priority, + get_file_info_callback, + test_callback_data); + if (test_handle == NULL) { + jobs_started --; + return FALSE; + } + + g_list_free (uri_list); + my_yield (20); + + return TRUE; +} + +static void +test_find_directory_callback (GnomeVFSAsyncHandle *handle, + GList *results, + gpointer callback_data) +{ + int this_test_no = *(int *)callback_data; + jobs_finished++; + if (verbose) { + printf ("finished test #%d: find_directory, priority = %d\n", this_test_no, prio_db[this_test_no]); + } + fflush (stdout); + g_free (callback_data); + jobs_started --; +} + +static void +test_find_directory (const char *uri, int priority) +{ + GnomeVFSAsyncHandle *handle; + GList *vfs_uri_as_list; + + test_callback_data = g_malloc (sizeof (int)); + *(int *)test_callback_data = ++test_no; + prio_db[test_no] = priority; + + vfs_uri_as_list = g_list_append (NULL, gnome_vfs_uri_new (uri)); + jobs_started++; + + if (verbose) { + printf ("starting test #%d: find_directory, priority = %d\n", test_no, priority); + } + + gnome_vfs_async_find_directory (&handle, vfs_uri_as_list, + GNOME_VFS_DIRECTORY_KIND_TRASH, FALSE, TRUE, 0777, priority, + test_find_directory_callback, test_callback_data); + my_yield (20); +} + + +static int usage (void) +{ + printf ("Usage: test-queue [-h|--help] [-v|--verbose]\n"); + printf ("\t-h, --help display usage information\n"); + printf ("\t-v, --verbose verbose mode\n\n"); + exit (1); +} + +int +main (int argc, char **argv) +{ + int limit; + int finished_before_7; + int finished_before_0; + int i; + + for (i = 1; i < argc; i++) { + if (!strcmp (argv[i], "-h") || + !strcmp (argv[i], "--help")) { + usage (); + continue; + } + if (!strcmp (argv[i], "-v") || + !strcmp (argv[i], "--verbose")) { + verbose = TRUE; + continue; + } + printf ("Unrecognized option: %s\n\n", argv[i]); + usage (); + } + + gnome_vfs_init (); + + limit = gnome_vfs_async_get_job_limit (); + if (verbose) { + printf ("Current job limit: %d\n", limit); + printf ("Trying to set the limit to 1; should result in a warning\n"); + } else { + printf ("You should see a warning and 2 critical errors below.\n"); + } + + gnome_vfs_async_set_job_limit (1); + if (limit != gnome_vfs_async_get_job_limit ()) { + at_least_one_test_failed = TRUE; + g_warning ("Current job limit changed to %d\n", + gnome_vfs_async_get_job_limit ()); + } + + printf ("Trying to start a job with priority = -11; should result in a critical error\n"); + if (test_get_file_info ("file:///dev/null", -11)) { + at_least_one_test_failed = TRUE; + } + + printf ("Trying to start a job with priority = 11; should result in a critical error\n"); + if (test_get_file_info ("file:///dev/null", 11)) { + at_least_one_test_failed = TRUE; + } + + if (!verbose) { + printf ("No warning or error messages are expected beyond this point\n"); + } + + if (verbose) { + printf ("Setting job limit to %d\n", TEST_LIMIT); + } + + gnome_vfs_async_set_job_limit (TEST_LIMIT); + limit = gnome_vfs_async_get_job_limit (); + if (limit != TEST_LIMIT) { + at_least_one_test_failed = TRUE; + g_warning ("Limit is %d, not %d as expected", limit, TEST_LIMIT); + } + + for (i = 0; i < 10; i++) { + test_find_directory ("test:///usr", 8); + } + + finished_before_7 = jobs_finished; + test_find_directory ("test:///usr", 7); + finished_before_0 = jobs_finished; + test_get_file_info ("test:///etc/passwd", 0); + + wait_until_vfs_jobs_gone (); + + /* Do some random tests with different priorities */ + test_find_directory ("file:///", 10); + test_find_directory ("file:///usr", 6); + test_find_directory ("file:///usr/local", -1); + test_find_directory ("file:///home", 2); + test_find_directory ("file:///etc", 5); + test_find_directory ("file:///tmp", 5); + test_find_directory ("file:///opt", 9); + test_find_directory ("file:///var", 10); + test_find_directory ("file:///", 10); + test_find_directory ("file:///home", 10); + test_get_file_info ("file:///dev/null", -1); + test_get_file_info ("file:///etc/passwd", -5); + test_find_directory ("file:///", -8); + test_find_directory ("file:///tmp", -10); + test_find_directory ("file:///etc", -5); + test_find_directory ("file:///usr", -1); + + wait_until_vfs_jobs_gone (); + + if (jobs_started != 0) { + printf ("%d jobs appear to be still running.\n", jobs_started - 2); + at_least_one_test_failed = TRUE; + } + + /* at most TEST_LIMIT low priority jobs + the 0 priority job may have + finished before this one */ + if ((finished_7 > 0) && (finished_7 - finished_before_7 > TEST_LIMIT + 1)) { + printf ("Scheduling error: %d lower priority jobs finished before " + "the 7 priority job when the job limit is %d\n", + finished_7 - finished_before_7, + TEST_LIMIT); + at_least_one_test_failed = TRUE; + } + + /* at most TEST_LIMIT low priority jobs may have finished before this one */ + if ((finished_0 > 0) && (finished_0 - finished_before_0 > TEST_LIMIT + 1)) { + printf ("Scheduling error: %d lower priority jobs finished before " + "the 0 priority job when the job limit is %d\n", + finished_0 - finished_before_0, + TEST_LIMIT); + at_least_one_test_failed = TRUE; + } + + if (verbose) { + printf ("Shutting down\n"); + } + + gnome_vfs_shutdown (); + + /* Report to "make check" on whether it all worked or not. */ + return at_least_one_test_failed ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/test/test-seek.c b/test/test-seek.c new file mode 100644 index 0000000..62465b1 --- /dev/null +++ b/test/test-seek.c @@ -0,0 +1,236 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* test-seek.c - Test for the seek emulation functionality of the GNOME Virtual + File System library. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Michael Meeks */ + +#include + +#include +#include +#include +#include +#include +#include + +static void +show_result (GnomeVFSResult result, const gchar *what, const gchar *text_uri) +{ + fprintf (stderr, "%s `%s': %s\n", + what, text_uri, gnome_vfs_result_to_string (result)); + if (result != GNOME_VFS_OK) + exit (1); +} + +static gboolean +show_if_error (GnomeVFSResult result, const gchar *what) +{ + if (result != GNOME_VFS_OK) { + fprintf (stderr, "%s: `%s'\n", + what, gnome_vfs_result_to_string (result)); + return TRUE; + } else + return FALSE; +} + +static const char * +translate_vfs_seek_pos (GnomeVFSSeekPosition whence, int *unix_whence) +{ + const char *txt; + int ref_whence; + + switch (whence) { + case GNOME_VFS_SEEK_START: + txt = "seek_start"; + ref_whence = SEEK_SET; + break; + case GNOME_VFS_SEEK_CURRENT: + txt = "seek_current"; + ref_whence = SEEK_CUR; + break; + case GNOME_VFS_SEEK_END: + txt = "seek_end"; + ref_whence = SEEK_END; + break; + default: + txt = "unknown seek type"; + ref_whence = SEEK_SET; + g_warning ("Unknown seek type"); + } + if (unix_whence) + *unix_whence = ref_whence; + + return txt; +} + +static gboolean +seek_test_chunk (GnomeVFSHandle *handle, + FILE *ref, + GnomeVFSFileOffset vfs_offset, + GnomeVFSSeekPosition whence, + GnomeVFSFileSize length) +{ + GnomeVFSResult result; + int ref_whence; + + translate_vfs_seek_pos (whence, &ref_whence); + + { /* Preliminary tell */ + GnomeVFSFileSize offset = 0; + long ref_off; + result = gnome_vfs_tell (handle, &offset); + if (show_if_error (result, "head gnome_vfs_tell")) + return FALSE; + + ref_off = ftell (ref); + if (ref_off < 0) { + g_warning ("Wierd ftell failure"); + return FALSE; + } + + if (ref_off != offset) { + g_warning ("Offset mismatch %d should be %d", (int)offset, (int)ref_off); + return FALSE; + } + } + + { /* seek */ + int fseekres; + result = gnome_vfs_seek (handle, whence, vfs_offset); + fseekres = fseek (ref, vfs_offset, ref_whence); + + if (fseekres == 0 && + result != GNOME_VFS_OK) { + g_warning ("seek success difference '%d - %d' - '%s'", + fseekres, errno, gnome_vfs_result_to_string (result)); + return FALSE; + } + } + + { /* read - leaks like a sieve on error =] */ + guint8 *data, *data_ref; + int bytes_read_ref; + GnomeVFSFileSize bytes_read; + + data = g_new (guint8, length); + data_ref = g_new (guint8, length); + + result = gnome_vfs_read (handle, data, length, &bytes_read); + bytes_read_ref = fread (data_ref, 1, length, ref); + + if (bytes_read_ref != bytes_read) { + g_warning ("read failure: vfs read %d and fread %d bytes ('%s')", + (int)bytes_read, bytes_read_ref, + gnome_vfs_result_to_string (result)); + return FALSE; + } + if (result != GNOME_VFS_OK) { + g_warning ("VFS read failed with '%s'", + gnome_vfs_result_to_string (result)); + return FALSE; + } + + { /* Compare the data */ + int i; + for (i = 0; i < bytes_read; i++) + if (data[i] != data_ref[i]) { + g_warning ("vfs read data mismatch at byte %d, '%d' != '%d'", + i, data[i], data_ref[i]); + return FALSE; + } + } + + g_free (data_ref); + g_free (data); + } + + { /* Tail tell */ + GnomeVFSFileSize offset; + long ref_off; + result = gnome_vfs_tell (handle, &offset); + if (show_if_error (result, "tail gnome_vfs_tell")) + return FALSE; + + ref_off = ftell (ref); + if (ref_off < 0) { + g_warning ("Wierd ftell failure"); + return FALSE; + } + + if (ref_off != offset) { + g_warning ("Offset mismatch %d should be %d", (int)offset, (int)ref_off); + return FALSE; + } + } + + return TRUE; +} + +int +main (int argc, char **argv) +{ + GnomeVFSResult result; + GnomeVFSHandle *handle; + FILE *ref; + int i, failures; + + if (! gnome_vfs_init ()) { + fprintf (stderr, "Cannot initialize gnome-vfs.\n"); + return 1; + } + + if (argc != 3) { + fprintf (stderr, "This is a program to test seek emulation on linear filesystems\n"); + fprintf (stderr, "Usage: %s \n", + argv[0]); + return 1; + } + + result = gnome_vfs_open (&handle, argv[1], GNOME_VFS_OPEN_READ|GNOME_VFS_OPEN_RANDOM); + show_result (result, "gnome_vfs_open", argv[1]); + + if (!(ref = fopen (argv[2], "r"))) { + fprintf (stderr, "Failed to open '%s' to compare seek history\n", argv[2]); + exit (1); + } + + failures = 0; + for (i = 0; i < 10; i++) { + GnomeVFSFileSize length = (1000.0 * rand () / (RAND_MAX + 1.0)); + GnomeVFSFileOffset seekpos = (1000.0 * rand () / (RAND_MAX + 1.0)); + GnomeVFSSeekPosition w = (int)(2.0 * rand () / (RAND_MAX + 1.0)); + + if (!seek_test_chunk (handle, ref, seekpos, w, length)) { + printf ("Failed: seek (offset %d, whence '%s'), read (length %d), tell = %ld\n", + (int)seekpos, translate_vfs_seek_pos (w, NULL), + (int)length, ftell (ref)); + failures++; + } + } + if (failures) + printf ("%d tests failed\n", failures); + else + printf ("All test successful\n"); + + result = gnome_vfs_close (handle); + show_result (result, "gnome_vfs_close", argv[1]); + + return 0; +} diff --git a/test/test-shell.c b/test/test-shell.c new file mode 100644 index 0000000..04de561 --- /dev/null +++ b/test/test-shell.c @@ -0,0 +1,1165 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* test-shell.c - A small program to allow testing of a wide variety of + gnome-vfs functionality + + Copyright (C) 2000 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Michael Meeks + + NB. This code leaks everywhere, don't loose hair. +*/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TEST_DEBUG 0 + +static char delim[]=" "; +static char **arg_data = NULL; +static int arg_cur = 0; + +static char *cur_dir = NULL; + +static GHashTable *files = NULL; + +FILE *vfserr = NULL; + + +static gboolean +show_if_error (GnomeVFSResult result, const char *what, const char *what2) +{ + if (result != GNOME_VFS_OK) { + fprintf (vfserr, "%s%s `%s'\n", + what, what2, gnome_vfs_result_to_string (result)); + return TRUE; + } else + return FALSE; +} + +static void +register_file (const char *str, GnomeVFSHandle *handle) +{ + if (!str) + fprintf (vfserr, "Need a valid name"); + else + g_hash_table_insert (files, g_strdup (str), handle); +} + +static GnomeVFSHandle * +lookup_file (const char *str) +{ + GnomeVFSHandle *handle; + + if (!str) { + fprintf (vfserr, "Invalid handle '%s'\n", str); + return NULL; + } + + handle = g_hash_table_lookup (files, str); + if (!handle) + fprintf (vfserr, "Can't find handle '%s'\n", str); + + return handle; +} + +static void +close_file (const char *str) +{ + GnomeVFSResult result; + gpointer hash_key, value; + + if (!str) + fprintf (vfserr, "Can't close NULL handles\n"); + + else if (g_hash_table_lookup_extended (files, str, &hash_key, &value)) { + g_hash_table_remove (files, str); + + result = gnome_vfs_close ((GnomeVFSHandle *)value); + show_if_error (result, "closing ", (char *)hash_key); + + g_free (hash_key); + } else + + fprintf (vfserr, "Unknown file handle '%s'\n", str); +} + +static gboolean +kill_file_cb (gpointer key, + gpointer value, + gpointer user_data) +{ + GnomeVFSResult result; + + result = gnome_vfs_close (value); + show_if_error (result, "closing ", key); + g_free (key); + + return TRUE; +} + +static void +close_files (void) +{ + g_hash_table_foreach_remove (files, kill_file_cb, NULL); + g_hash_table_destroy (files); +} + +static void +do_ls (void) +{ + GnomeVFSResult result; + GList *list, *node; + GnomeVFSFileInfo *info; + const char *path; + + if (!arg_data [arg_cur]) + path = cur_dir; + else + path = arg_data [arg_cur++]; + + result = gnome_vfs_directory_list_load + (&list, path, + GNOME_VFS_FILE_INFO_DEFAULT | + GNOME_VFS_FILE_INFO_GET_MIME_TYPE); + if (show_if_error (result, "open directory ", cur_dir)) + return; + + for (node = list; node != NULL; node = node->next) { + char prechar = '\0', postchar = '\0'; + info = node->data; + + if (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_TYPE) { + switch (info->type) { + case GNOME_VFS_FILE_TYPE_DIRECTORY: + prechar = '['; + postchar = ']'; + break; + case GNOME_VFS_FILE_TYPE_UNKNOWN: + prechar = '?'; + break; + case GNOME_VFS_FILE_TYPE_FIFO: + prechar = '|'; + break; + case GNOME_VFS_FILE_TYPE_SOCKET: + prechar = '-'; + break; + case GNOME_VFS_FILE_TYPE_CHARACTER_DEVICE: + case GNOME_VFS_FILE_TYPE_BLOCK_DEVICE: + prechar = '@'; + break; + case GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK: + prechar = '#'; + break; + default: + prechar = '\0'; + break; + } + if (!postchar) + postchar = prechar; + } + printf ("%c%s%c", prechar, info->name, postchar); + + if (strlen (info->name) < 40) { + int i, pad; + + pad = 40 - strlen (info->name) - + (prechar?1:0) - (postchar?1:0); + + for (i = 0; i < pad; i++) + printf (" "); + } + if (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) { + long i = info->size; + printf (" : %ld bytes", i); + } + + if (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE) { + printf (", type '%s'", info->mime_type); + } + + printf ("\n"); + } + + gnome_vfs_file_info_list_free (list); +} + +static void +list_commands (void) +{ + printf ("command can be one or all of:\n"); + printf ("Main operations:\n"); + printf (" * ls [opt_dir] list files\n"); + printf (" * cd [dir] enter storage\n"); + printf (" * mv move object\n"); + printf (" * rm remove stream\n"); + printf (" * mkdir make storage\n"); + printf (" * rmdir remove storage\n"); + printf (" * info,stat get information on object\n"); + printf (" * cat,type dump text file to console\n"); + printf (" * dump dump binary file to console\n"); + printf (" * sync: for sinkers\n"); + printf (" * ssl: displays ssl enabled state\n"); + printf (" * findtrash: locates a trash directory for a URI\n"); + printf (" * quit,exit,bye: exit\n"); + printf ("File operations:\n"); + printf (" * open : open a file\n"); + printf (" * create : create a file\n"); + printf (" * handleinfo : information from handle\n"); + printf (" * close : close a file\n"); + printf (" * read : read bytes from stream\n"); + printf (" * seek : seek set position\n"); +} + +static gboolean +simple_regexp (const char *regexp, const char *fname) +{ + int i, j; + gboolean ret = TRUE; + + g_return_val_if_fail (fname != NULL, FALSE); + g_return_val_if_fail (regexp != NULL, FALSE); + + for (i = j = 0; regexp [i] && fname [j]; j++, i++) { + if (regexp [i] == '\\' && + !(i > 0 && regexp [i - 1] == '\\')) { + j--; + continue; + } + + if (regexp [i] == '.' && + !(i > 0 && regexp [i - 1] == '\\')) + continue; + + if (g_ascii_tolower (regexp [i]) != g_ascii_tolower (fname [j])) { + ret = FALSE; + break; + } + } + + if (regexp [i] && regexp [i] == '*') + ret = TRUE; + + else if (!regexp [i] && fname [j]) + ret = FALSE; + + else if (!fname [j] && regexp [i]) + ret = FALSE; + +/* if (ret) + printf ("'%s' matched '%s'\n", regexp, fname);*/ + + return ret; +} + +static gboolean +validate_path (const char *path) +{ + GnomeVFSResult result; + GList *list; + + result = gnome_vfs_directory_list_load ( + &list, path, GNOME_VFS_FILE_INFO_DEFAULT); + + if (show_if_error (result, "open directory ", path)) { + return FALSE; + } + + gnome_vfs_file_info_list_free (list); + + return TRUE; +} + +static char * +get_regexp_name (const char *regexp, const char *path, gboolean dir) +{ + GnomeVFSResult result; + GList *list, *node; + GnomeVFSFileInfo *info; + char *res = NULL; + + result = gnome_vfs_directory_list_load ( + &list, path, GNOME_VFS_FILE_INFO_DEFAULT); + + if (show_if_error (result, "open directory ", path)) + return NULL; + + for (node = list; node != NULL; node = node->next) { + info = node->data; + + if (simple_regexp (regexp, info->name)) { + if (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_TYPE) { + if ((dir && info->type == GNOME_VFS_FILE_TYPE_DIRECTORY) || + (!dir && info->type != GNOME_VFS_FILE_TYPE_DIRECTORY)) { + res = g_strdup (info->name); + break; + } + } else { + fprintf (vfserr, "Can't cope with no type data"); + res = g_strdup (info->name); + break; + } + } + } + gnome_vfs_file_info_list_free (list); + + return res; +} + +static void +do_cd (void) +{ + char *p; + + p = arg_data [arg_cur++]; + + if (!p) { + fprintf (vfserr, "Takes a directory argument\n"); + return; + } + + if (!g_ascii_strcasecmp (p, "..")) { + guint lp; + char **tmp; + GString *newp = g_string_new (""); + + tmp = g_strsplit (cur_dir, "/", -1); + lp = 0; + if (!tmp [lp]) + return; + + while (tmp [lp + 1]) { + g_string_append_printf (newp, "%s/", tmp [lp]); + lp++; + } + g_free (cur_dir); + cur_dir = newp->str; + g_string_free (newp, FALSE); + } else if (!g_ascii_strcasecmp (p, ".")) { + } else { + char *newpath; + + if (strchr (p, ':') || + p [0] == '/') { + if (p [strlen (p) - 1] != '/') + newpath = g_strconcat (p, "/", NULL); + else + newpath = g_strdup (p); + } else { + char *ptr; + + ptr = get_regexp_name (p, cur_dir, TRUE); + if (!ptr) { + fprintf (vfserr, "Can't find '%s'\n", p); + return; + } + + newpath = g_strconcat (cur_dir, ptr, "/", NULL); + } + + if (validate_path (newpath)) { + g_free (cur_dir); + cur_dir = newpath; + } else + fprintf (vfserr, "Invalid path %s\n", newpath); + } +} + +static char * +get_fname (void) +{ + char *fname, *reg_name, *f; + + if (!arg_data [arg_cur]) + return NULL; + + reg_name = arg_data [arg_cur++]; + fname = get_regexp_name (reg_name, cur_dir, FALSE); + + if (!fname) + fname = reg_name; + + if (strchr (fname, ':') || + fname [0] == '/') + f = g_strdup (fname); + else if (cur_dir) + f = g_strconcat (cur_dir, fname, NULL); + else + f = g_strdup (fname); + + return f; +} + +static void +do_cat (void) +{ + char *from; + GnomeVFSHandle *from_handle; + GnomeVFSResult result; + + from = get_fname (); + + result = gnome_vfs_open (&from_handle, from, GNOME_VFS_OPEN_READ); + if (show_if_error (result, "open ", from)) + return; + + while (1) { + GnomeVFSFileSize bytes_read; + guint8 data [1025]; + + result = gnome_vfs_read (from_handle, data, 1024, &bytes_read); + if (show_if_error (result, "read ", from)) + return; + + if (bytes_read == 0) + break; + + if (bytes_read > 0 && + bytes_read <= 1024) + data [bytes_read] = '\0'; + else { + data [1024] = '\0'; + g_warning ("Wierd error from vfs_read"); + } + fprintf (stdout, "%s", data); + } + + result = gnome_vfs_close (from_handle); + if (show_if_error (result, "close ", from)) + return; + fprintf (stdout, "\n"); +} + +static void +do_rm (void) +{ + char *fname; + GnomeVFSResult result; + + fname = get_fname (); + + result = gnome_vfs_unlink (fname); + if (show_if_error (result, "unlink ", fname)) + return; +} + +static void +do_mkdir (void) +{ + char *fname; + GnomeVFSResult result; + + fname = get_fname (); + + result = gnome_vfs_make_directory (fname, GNOME_VFS_PERM_USER_ALL); + if (show_if_error (result, "mkdir ", fname)) + return; +} + +static void +do_rmdir (void) +{ + char *fname; + GnomeVFSResult result; + + fname = get_fname (); + + result = gnome_vfs_remove_directory (fname); + if (show_if_error (result, "rmdir ", fname)) + return; +} + +static void +do_mv (void) +{ + char *from, *to; + char *msg; + GnomeVFSResult result; + + from = get_fname (); + to = get_fname (); + if (!from || !to) { + fprintf (vfserr, "mv \n"); + return; + } + + result = gnome_vfs_move (from, to, FALSE); + + msg = g_strdup_printf ("%s to %s", from, to); + show_if_error (result, "move ", msg); + g_free (msg); +} + +static void +do_findtrash (void) +{ + char *from; + char *uri_as_string; + GnomeVFSResult result; + GnomeVFSURI *from_uri; + GnomeVFSURI *result_vfs_uri; + + from = get_fname (); + + from_uri = gnome_vfs_uri_new (from); + result = gnome_vfs_find_directory (from_uri, + GNOME_VFS_DIRECTORY_KIND_TRASH, + &result_vfs_uri, + TRUE, TRUE, 0777); + + if (result != GNOME_VFS_OK) { + fprintf (stdout, "couldn't find or create trash there, error code %d", result); + } else { + uri_as_string = gnome_vfs_uri_to_string (result_vfs_uri, GNOME_VFS_URI_HIDE_NONE); + fprintf (stdout, "trash found or created here: %s", uri_as_string); + g_free (uri_as_string); + } + + gnome_vfs_uri_unref (from_uri); + gnome_vfs_uri_unref (result_vfs_uri); +} + +static void +do_ssl (void) +{ + if (gnome_vfs_ssl_enabled ()) + fprintf (stdout, "SSL enabled\n"); + else + fprintf (stdout, "SSL disabled\n"); +} + +static void +print_info (GnomeVFSFileInfo *info) +{ + const char *mime_type; + struct tm *loctime; + + fprintf (stdout, "Name: '%s'\n", info->name); + if (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_TYPE) { + fprintf (stdout, "Type: "); + switch (info->type) { + case GNOME_VFS_FILE_TYPE_UNKNOWN: + fprintf (stdout, "unknown"); + break; + case GNOME_VFS_FILE_TYPE_REGULAR: + fprintf (stdout, "regular"); + break; + case GNOME_VFS_FILE_TYPE_DIRECTORY: + fprintf (stdout, "directory"); + break; + case GNOME_VFS_FILE_TYPE_FIFO: + fprintf (stdout, "fifo"); + break; + case GNOME_VFS_FILE_TYPE_SOCKET: + fprintf (stdout, "socket"); + break; + case GNOME_VFS_FILE_TYPE_CHARACTER_DEVICE: + fprintf (stdout, "char"); + break; + case GNOME_VFS_FILE_TYPE_BLOCK_DEVICE: + fprintf (stdout, "block"); + break; + case GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK: + fprintf (stdout, "symlink\n"); + fprintf (stdout, "symlink points to: %s", + info->symlink_name); + break; + default: + fprintf (stdout, "Error; invalid value"); + break; + } + } else + fprintf (stdout, "Type invalid"); + fprintf (stdout, "\n"); + + if (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) { + long i = info->size; + fprintf (stdout, "Size: %ld bytes", i); + } else { + fprintf (stdout, "Size invalid"); + } + fprintf (stdout, "\n"); + + mime_type = gnome_vfs_file_info_get_mime_type (info); + + fprintf (stdout, "Mime Type: %s \n", mime_type); + + loctime = localtime(&info->atime); + fprintf (stdout, "Last Accessed: %s", asctime(loctime)); + loctime = localtime(&info->mtime); + fprintf (stdout, "Last Modified: %s", asctime(loctime)); + loctime = localtime(&info->ctime); + fprintf (stdout, "Last Changed: %s", asctime(loctime)); + + fprintf (stdout, "uid: %d\n", info->uid); + + fprintf (stdout, "gid: %d\n", info->gid); + fprintf (stdout, "\n"); + /* FIXME bugzilla.eazel.com 2800: hack here; should dump them all */ +} + +static void +do_info (void) +{ + char *from; + GnomeVFSResult result; + GnomeVFSFileInfo *info; + + from = get_fname (); + + + info = gnome_vfs_file_info_new (); + result = gnome_vfs_get_file_info ( + from, info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE); + + if (show_if_error (result, "getting info on: ", from)) + return; + + print_info (info); + gnome_vfs_file_info_unref (info); +} + +static void +do_cp (void) +{ + char *from = NULL; + char *to = NULL; + GnomeVFSHandle *from_handle = NULL; + GnomeVFSHandle *to_handle = NULL; + GnomeVFSResult result; + + from = get_fname (); + + if (from) + to = get_fname (); + else { + fprintf (vfserr, "cp \n"); + goto out; + } + + result = gnome_vfs_open (&from_handle, from, GNOME_VFS_OPEN_READ); + if (show_if_error (result, "open ", from)) + goto out; + + result = gnome_vfs_open (&to_handle, to, GNOME_VFS_OPEN_WRITE); + if (result == GNOME_VFS_ERROR_NOT_FOUND) + result = gnome_vfs_create (&to_handle, to, GNOME_VFS_OPEN_WRITE, FALSE, + GNOME_VFS_PERM_USER_ALL); + if (show_if_error (result, "open ", to)) + goto out; + + while (1) { + GnomeVFSFileSize bytes_read; + GnomeVFSFileSize bytes_written; + guint8 data [1024]; + + result = gnome_vfs_read (from_handle, data, 1024, &bytes_read); + if (show_if_error (result, "read ", from)) + goto out; + + if (bytes_read == 0) + break; + + result = gnome_vfs_write (to_handle, data, bytes_read, &bytes_written); + if (show_if_error (result, "write ", to)) + goto out; + + if (bytes_read != bytes_written) + fprintf (vfserr, "Didn't write it all"); + } + + out: + g_free (from); + g_free (to); + + if (to_handle) { + result = gnome_vfs_close (to_handle); + if (show_if_error (result, "close ", to)) + /* Nothing */; + } + + if (from_handle) { + result = gnome_vfs_close (from_handle); + if (show_if_error (result, "close ", from)) + /* Nothing */; + } +} + +static void +ms_ole_dump (guint8 const *ptr, guint32 len, guint32 offset) +{ + guint32 lp,lp2; + guint32 off; + + for (lp = 0;lp<(len+15)/16;lp++) { + printf ("%8x | ", lp*16 + offset); + for (lp2=0;lp2<16;lp2++) { + off = lp2 + (lp<<4); + off'!'&&ptr[off]<127?ptr[off]:'.'):'*'); + } + printf ("\n"); + } +} + +static void +do_dump (void) +{ + char *from; + GnomeVFSHandle *from_handle; + GnomeVFSResult result; + guint32 offset; + + from = get_fname (); + + result = gnome_vfs_open (&from_handle, from, GNOME_VFS_OPEN_READ); + if (show_if_error (result, "open ", from)) + return; + + for (offset = 0; 1; ) { + GnomeVFSFileSize bytes_read; + guint8 data [1024]; + + result = gnome_vfs_read (from_handle, data, 1024, &bytes_read); + if (show_if_error (result, "read ", from)) + return; + + if (bytes_read == 0) + break; + + ms_ole_dump (data, bytes_read, offset); + + offset += bytes_read; + } + + result = gnome_vfs_close (from_handle); + if (show_if_error (result, "close ", from)) + return; +} + + +/* + * --------------------------------------------------------------------- + */ + +static char * +get_handle (void) +{ + if (!arg_data [arg_cur]) + return NULL; + + return arg_data [arg_cur++]; +} + +static int +get_int (void) +{ + if (!arg_data [arg_cur]) + return 0; + + return atoi (arg_data [arg_cur++]); +} + +static void +do_open (void) +{ + char *from, *handle; + GnomeVFSHandle *from_handle; + GnomeVFSResult result; + + handle = get_handle (); + from = get_fname (); + + if (!handle || !from) { + fprintf (vfserr, "open \n"); + return; + } + + result = gnome_vfs_open (&from_handle, from, GNOME_VFS_OPEN_READ); + if (show_if_error (result, "open ", from)) + return; + + register_file (handle, from_handle); +} + +static void +do_create (void) +{ + char *from, *handle; + GnomeVFSHandle *from_handle; + GnomeVFSResult result; + + handle = get_handle (); + from = get_fname (); + + if (!handle || !from) { + fprintf (vfserr, "create \n"); + return; + } + + result = gnome_vfs_create (&from_handle, from, GNOME_VFS_OPEN_READ, + FALSE, GNOME_VFS_PERM_USER_READ | + GNOME_VFS_PERM_USER_WRITE); + if (show_if_error (result, "create ", from)) + return; + + register_file (handle, from_handle); +} + +static void +do_read (void) +{ + char *handle; + int length; + GnomeVFSHandle *from_handle; + GnomeVFSResult result; + GnomeVFSFileSize bytes_read; + guint8 *data; + + handle = get_handle (); + length = get_int (); + + if (length < 0) { + fprintf (vfserr, "Can't read %d bytes\n", length); + return; + } + + from_handle = lookup_file (handle); + if (!from_handle) + return; + + data = g_malloc (length); + result = gnome_vfs_read (from_handle, data, length, &bytes_read); + if (show_if_error (result, "read ", handle)) + return; + + ms_ole_dump (data, bytes_read, 0); +} + +static void +do_seek (void) +{ + char *handle; + int offset; + GnomeVFSHandle *from_handle; + GnomeVFSResult result; + + handle = get_handle (); + offset = get_int (); + + if (offset < 0) { + fprintf (vfserr, "Can't seek to %d bytes offset\n", offset); + return; + } + + from_handle = lookup_file (handle); + if (!from_handle) + return; + + result = gnome_vfs_seek (from_handle, GNOME_VFS_SEEK_START, offset); + if (show_if_error (result, "seek ", handle)) + return; +} + +static void +do_close (void) +{ + close_file (get_handle ()); +} + +static void +do_handleinfo (void) +{ + const char *handlename = get_handle (); + GnomeVFSResult result; + GnomeVFSHandle *handle = lookup_file (handlename); + GnomeVFSFileInfo *info; + + if (!handle) + return; + + info = gnome_vfs_file_info_new (); + result = gnome_vfs_get_file_info_from_handle (handle, info, + GNOME_VFS_FILE_INFO_GET_MIME_TYPE); + + if (show_if_error (result, "getting info from handle: ", handlename)) + return; + + print_info (info); + gnome_vfs_file_info_unref (info); +} + +/* + * --------------------------------------------------------------------- + */ + +GMainLoop *main_loop = NULL; + +int interactive = 0; +const struct poptOption options [] = { + { "interactive", 'i', POPT_ARG_NONE, &interactive, 0, + "Allow interactive input", NULL }, + { NULL, '\0', 0, NULL, 0 } +}; + +static gboolean +callback (GIOChannel *source, + GIOCondition condition, + gpointer data) +{ + char *buffer = data; + char buf[1024]; + int len; + + len = read (0, buf, sizeof (buf) - 1); + + if (len + strlen (buffer) + 1 > 1024) + len = 1024 - strlen (buffer) - 1; + + buf[len] = '\0'; + strcat (buffer, buf); + + if (strchr (buf, '\n') != NULL && + main_loop != NULL) { + g_main_loop_quit (main_loop); + } + + return TRUE; +} + +static char * +get_input_string (const char *prompt) +{ + char buffer[512]; + + printf (prompt); + fgets (buffer, 511, stdin); + if (strchr (buffer, '\n')) + *strchr (buffer, '\n') = '\0'; + + return g_strndup (buffer, 512); +} + +static void +authentication_callback (gconstpointer in, size_t in_size, + gpointer out, size_t out_size, + gpointer user_data) +{ + GnomeVFSModuleCallbackAuthenticationIn *in_real; + GnomeVFSModuleCallbackAuthenticationOut *out_real; + + g_return_if_fail (sizeof (GnomeVFSModuleCallbackAuthenticationIn) == in_size + && sizeof (GnomeVFSModuleCallbackAuthenticationOut) == out_size); + + g_return_if_fail (in != NULL); + g_return_if_fail (out != NULL); + + in_real = (GnomeVFSModuleCallbackAuthenticationIn *)in; + out_real = (GnomeVFSModuleCallbackAuthenticationOut *)out; + + printf ("Authenticate for uri: %s realm: %s\n", in_real->uri, in_real->realm); + + out_real->username = get_input_string ("Username:\n"); + out_real->password = get_input_string ("Password:\n"); +} + +int +main (int argc, const char **argv) +{ + poptContext popt_context; + int exit = 0; + char *buffer = g_new (char, 1024) ; + const char **args; + FILE *instream; + + /* default to interactive on a terminal */ + interactive = isatty (0); + + files = g_hash_table_new (g_str_hash, g_str_equal); + + popt_context = poptGetContext ("test-vfs", argc, argv, + options, 0); + + if (interactive) + vfserr = stderr; + else + vfserr = stdout; + + if (!gnome_vfs_init ()) { + fprintf (vfserr, "Cannot initialize gnome-vfs.\n"); + return 1; + } + gnome_vfs_module_callback_push + (GNOME_VFS_MODULE_CALLBACK_AUTHENTICATION, + authentication_callback, NULL, NULL); + + instream = stdin; + args = poptGetArgs (popt_context); + if (!args) + cur_dir = g_get_current_dir (); + else + cur_dir = g_strdup (args [0]); + + if (cur_dir && cur_dir [strlen (cur_dir)] != '/') { + char *new_dir = g_strconcat (cur_dir, "/", NULL); + g_free (cur_dir); + cur_dir = new_dir; + } + + poptFreeContext (popt_context); + + while (!exit) { + char *ptr; + + if (interactive) { + GIOChannel *ioc; + guint watch_id; + strcpy (buffer, ""); + + main_loop = g_main_loop_new (NULL, TRUE); + + ioc = g_io_channel_unix_new (0 /* stdin */); + watch_id = g_io_add_watch (ioc, + G_IO_IN | G_IO_HUP | G_IO_ERR, + callback, buffer); + g_io_channel_unref (ioc); + + if (interactive) { + fprintf (stdout,"\n%s > ", cur_dir); + fflush (stdout); + } + + g_main_loop_run (main_loop); + + g_source_remove (watch_id); + + g_main_loop_unref (main_loop); + main_loop = NULL; + } else { + /* In non-interactive mode we just do this evil + * thingie */ + buffer[0] = '\0'; + fgets (buffer, 1023, instream); + if (!buffer [0]) { + exit = 1; + continue; + } + } + + if (!buffer || buffer [0] == '#') + continue; + + arg_data = g_strsplit (g_strchomp (buffer), delim, -1); + arg_cur = 0; + if ((!arg_data || !arg_data[0]) && interactive) continue; + if (!interactive) + printf ("Command : '%s'\n", arg_data [0]); + ptr = arg_data[arg_cur++]; + if (!ptr) + continue; + + if (g_ascii_strcasecmp (ptr, "ls") == 0) + do_ls (); + else if (g_ascii_strcasecmp (ptr, "cd") == 0) + do_cd (); + else if (g_ascii_strcasecmp (ptr, "dump") == 0) + do_dump (); + else if (g_ascii_strcasecmp (ptr, "type") == 0 || + g_ascii_strcasecmp (ptr, "cat") == 0) + do_cat (); + else if (g_ascii_strcasecmp (ptr, "cp") == 0) + do_cp (); + else if (g_ascii_strcasecmp (ptr, "rm") == 0) + do_rm (); + else if (g_ascii_strcasecmp (ptr, "mkdir") == 0) + do_mkdir (); + else if (g_ascii_strcasecmp (ptr, "rmdir") == 0) + do_rmdir (); + else if (g_ascii_strcasecmp (ptr, "mv") == 0) + do_mv (); + else if (g_ascii_strcasecmp (ptr, "info") == 0 || + g_ascii_strcasecmp (ptr, "stat") == 0) + do_info (); + else if (g_ascii_strcasecmp (ptr, "findtrash") == 0) + do_findtrash (); + else if (g_ascii_strcasecmp (ptr, "ssl") == 0) + do_ssl (); + else if (g_ascii_strcasecmp (ptr, "sync") == 0) + fprintf (vfserr, "a shell is like a boat, it lists or syncs (RMS)\n"); + else if (g_ascii_strcasecmp (ptr,"help") == 0 || + g_ascii_strcasecmp (ptr,"?") == 0 || + g_ascii_strcasecmp (ptr,"info") == 0 || + g_ascii_strcasecmp (ptr,"man") == 0) + list_commands (); + else if (g_ascii_strcasecmp (ptr,"exit") == 0 || + g_ascii_strcasecmp (ptr,"quit") == 0 || + g_ascii_strcasecmp (ptr,"q") == 0 || + g_ascii_strcasecmp (ptr,"bye") == 0) + exit = 1; + + /* File ops */ + else if (g_ascii_strcasecmp (ptr, "open") == 0) + do_open (); + else if (g_ascii_strcasecmp (ptr, "create") == 0) + do_create (); + else if (g_ascii_strcasecmp (ptr, "close") == 0) + do_close (); + else if (g_ascii_strcasecmp (ptr, "handleinfo") == 0) + do_handleinfo (); + else if (g_ascii_strcasecmp (ptr, "read") == 0) + do_read (); + else if (g_ascii_strcasecmp (ptr, "seek") == 0) + do_seek (); + + else + fprintf (vfserr, "Unknown command '%s'", ptr); + + g_strfreev (arg_data); + arg_data = NULL; + } + + g_free (buffer); + g_free (cur_dir); + + close_files (); + + return 0; +} + diff --git a/test/test-ssl.c b/test/test-ssl.c new file mode 100644 index 0000000..f6fb55a --- /dev/null +++ b/test/test-ssl.c @@ -0,0 +1,176 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* test-sync.c - Test program for synchronous operation of the GNOME + Virtual File System. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ian McKellar + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +enum { + SSL, SOCKET, SOCKETBUFFER +} abstraction = SOCKETBUFFER; + +static void +show_result (GnomeVFSResult result, + const gchar *what, + const gchar *host, + gint port) +{ + fprintf (stderr, "%s `%s:%d': %s\n", + what, host, port, gnome_vfs_result_to_string (result)); + if (result != GNOME_VFS_OK) + exit (1); +} + +#define HTTP_REQUEST "GET / HTTP/1.0\r\n\r\n" + +int +main (int argc, char **argv) +{ + GnomeVFSResult result = GNOME_VFS_OK; + gchar buffer[1024]; + gchar *host; + gint port; + GnomeVFSFileSize bytes_read; + GnomeVFSSSL *ssl = NULL; + GnomeVFSSocket *socket = NULL; + GnomeVFSSocketBuffer *socketbuffer = NULL; + + if (argc != 3) { + printf ("Usage: %s \n", argv[0]); + return 1; + } + + host = argv[1]; + port = atoi (argv[2]); + + if (port <= 0) { + printf ("Invalid port\n"); + return 1; + } + + if (! gnome_vfs_init ()) { + fprintf (stderr, "Cannot initialize gnome-vfs.\n"); + return 1; + } + + switch (abstraction) { + case SOCKETBUFFER: + g_print ("Testing GnomeVFSSocketBuffer"); + case SOCKET: + g_print (" and GnomeVFSSocket"); + case SSL: + g_print (" and GnomeVFSSSL"); + } + g_print (".\n"); + + result = gnome_vfs_ssl_create (&ssl, host, port); + + show_result (result, "ssl_create", host, port); + + if (ssl == NULL) { + fprintf (stderr, "couln't connect\n"); + return -1; + } + + if (abstraction >= SOCKET) { + socket = gnome_vfs_ssl_to_socket (ssl); + if (socket == NULL) { + fprintf (stderr, "couldn't create socket object\n"); + return -1; + } + + if (abstraction == SOCKETBUFFER) { + socketbuffer = gnome_vfs_socket_buffer_new (socket); + if (socketbuffer == NULL) { + fprintf (stderr, + "couldn't create socketbuffer object\n"); + return -1; + } + } + } + + switch (abstraction) { + case SSL: + result = gnome_vfs_ssl_write (ssl, HTTP_REQUEST, + strlen(HTTP_REQUEST), &bytes_read); + break; + case SOCKET: + result = gnome_vfs_socket_write (socket, HTTP_REQUEST, + strlen(HTTP_REQUEST), &bytes_read); + break; + case SOCKETBUFFER: + result = gnome_vfs_socket_buffer_write (socketbuffer, + HTTP_REQUEST, strlen(HTTP_REQUEST), + &bytes_read); + gnome_vfs_socket_buffer_flush (socketbuffer); + break; + } + + show_result (result, "write", host, port); + + while( result==GNOME_VFS_OK ) { + switch (abstraction) { + case SSL: + result = gnome_vfs_ssl_read (ssl, buffer, + sizeof buffer - 1, &bytes_read); + break; + case SOCKET: + result = gnome_vfs_socket_read (socket, buffer, + sizeof buffer - 1, &bytes_read); + break; + case SOCKETBUFFER: + result = gnome_vfs_socket_buffer_read ( + socketbuffer, buffer, + sizeof buffer - 1, &bytes_read); + break; + } + show_result (result, "read", host, port); + + buffer[bytes_read] = 0; + write (1,buffer,bytes_read); + if(!bytes_read) break; + } + + switch (abstraction) { + case SSL: + gnome_vfs_ssl_destroy (ssl); + break; + case SOCKET: + gnome_vfs_socket_close (socket); + break; + case SOCKETBUFFER: + gnome_vfs_socket_buffer_destroy (socketbuffer, TRUE); + break; + } + + return 0; +} diff --git a/test/test-symlinks.c b/test/test-symlinks.c new file mode 100644 index 0000000..c04dec1 --- /dev/null +++ b/test/test-symlinks.c @@ -0,0 +1,303 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* test-symlinks.c: verifies that symlinks are being created properly + Copyright (C) 2000 Eazel + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Seth Nickell */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +static GMainLoop *main_loop; + +typedef struct { + GnomeVFSResult expected_result; + const char *uri; + const char *target_uri; + const char *target_reference; +} CallbackData; + +static int measure_speed = 0; +static int sort = 0; +static int items_per_notification = 1; + +struct poptOption options[] = { + { + "chunk-size", + 'c', + POPT_ARG_INT, + &items_per_notification, + 0, + "Number of items to send for every notification", + "NUM_ITEMS" + }, + { + "measure-speed", + 'm', + POPT_ARG_NONE, + &measure_speed, + 0, + "Measure speed without displaying anything", + NULL + }, + { + "sort", + 's', + POPT_ARG_NONE, + &sort, + 0, + "Sort entries", + NULL + }, + { + NULL, + 0, + 0, + NULL, + 0, + NULL, + NULL + } +}; + +static int +deal_with_result (GnomeVFSResult result, GnomeVFSResult expected_result, + const char *uri, const char *target_uri, const char *target_reference, + gboolean unlink) +{ + char read_buffer[1024]; + const char *write_buffer = "this is test data...we should read the same thing"; + GnomeVFSHandle *handle; + GnomeVFSFileSize bytes_written, temp; + GnomeVFSFileInfo info_uri = {0,}; + GnomeVFSFileInfo info_target = {0,}; + int return_value = 1; + const gchar *result_string; + GnomeVFSResult error; + GnomeVFSURI *real_uri, *real_uri_target; + GnomeVFSFileInfo *info; + + real_uri = gnome_vfs_uri_new (uri); + real_uri_target = gnome_vfs_uri_new (target_uri); + + if (result != expected_result) { + result_string = gnome_vfs_result_to_string (result); + printf ("creating a link from %s to %s returned %s instead of %s.\n", uri, target_reference, + result_string, gnome_vfs_result_to_string (expected_result)); + return_value = 0; + } else if (result == GNOME_VFS_OK) { + info = gnome_vfs_file_info_new(); + error = gnome_vfs_get_file_info_uri (real_uri, info, GNOME_VFS_FILE_INFO_DEFAULT); + if ((error != GNOME_VFS_OK) || (info->type != GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK)) { + printf ("Symlink problem: gnome_vfs_file_info returns wrong for link %s\n", uri); + } else { + /* our link seems to have been created correctly - lets see if its real */ + error = gnome_vfs_open_uri (&handle, real_uri_target, GNOME_VFS_OPEN_WRITE); + if (error == GNOME_VFS_ERROR_NOT_FOUND) + error = gnome_vfs_create_uri (&handle, real_uri_target, GNOME_VFS_OPEN_WRITE, 0, GNOME_VFS_PERM_USER_ALL); + if (error == GNOME_VFS_OK) { + /* write stuff to our link location */ + error = gnome_vfs_write (handle, write_buffer, strlen (write_buffer) + 1, &bytes_written); + error = gnome_vfs_close (handle); + error = gnome_vfs_open_uri (&handle, real_uri, GNOME_VFS_OPEN_READ); + if (error == GNOME_VFS_OK) { + error = gnome_vfs_read (handle, read_buffer, bytes_written, &temp); + read_buffer[temp] = 0; + error = gnome_vfs_close (handle); + if (strcmp (read_buffer, write_buffer) != 0) { + printf ("Symlink problem: value written is not the same as the value read!\n"); + printf ("Written to %s: #%s# \nRead from link %s: #%s#\n", + target_uri, write_buffer, uri, read_buffer); + return_value = 0; + } + } + } + gnome_vfs_get_file_info_uri (real_uri, &info_uri, GNOME_VFS_FILE_INFO_FOLLOW_LINKS); + gnome_vfs_get_file_info_uri (real_uri_target, &info_target, GNOME_VFS_FILE_INFO_FOLLOW_LINKS); + if (info_uri.inode != info_target.inode) { + printf ("Symlink problem: link following is not working\n"); + printf ("File: %s Link: %s\n", target_uri, uri); + } + gnome_vfs_file_info_clear (&info_uri); + gnome_vfs_get_file_info_uri (real_uri, &info_uri, GNOME_VFS_FILE_INFO_DEFAULT); + gnome_vfs_file_info_clear (&info_target); + gnome_vfs_get_file_info_uri (real_uri_target, &info_target, GNOME_VFS_FILE_INFO_DEFAULT); + if (info_uri.inode == info_target.inode) { + printf ("Symlink problem: link following is happening when it shouldn't be.\n"); + printf ("File: %s Link: %s\n", target_uri, uri); + } + gnome_vfs_file_info_clear (&info_uri); + gnome_vfs_file_info_clear (&info_target); + } + gnome_vfs_file_info_unref (info); + if (unlink) { + gnome_vfs_unlink_from_uri (real_uri_target); + error = gnome_vfs_unlink_from_uri (real_uri); + if (error != GNOME_VFS_OK) { + printf ("Problem unlinking URI %s", uri); + } + } + } + + + gnome_vfs_uri_unref (real_uri); + gnome_vfs_uri_unref (real_uri_target); + + return return_value; +} + +static void +create_link_callback (GnomeVFSAsyncHandle *handle, + GnomeVFSResult result, + gpointer callback_data) +{ + const char *uri, *target_uri, *target_reference; + GnomeVFSResult expected_result; + CallbackData *info; + + info = (CallbackData*) callback_data; + + uri = info->uri; + target_uri = info->target_uri; + expected_result = info->expected_result; + target_reference = info->target_reference; + + deal_with_result (result, expected_result, uri, target_uri, target_reference, TRUE); + + g_free (callback_data); + g_main_loop_quit (main_loop); +} + + +static int +make_link (const char *uri, const char *target_reference, const char *target_uri, GnomeVFSResult expected_result, gboolean unlink) +{ + GnomeVFSURI *real_uri, *real_uri_target; + GnomeVFSResult result; + + int return_value = 1; + + real_uri = gnome_vfs_uri_new (uri); + real_uri_target = gnome_vfs_uri_new (target_uri); + + result = gnome_vfs_create_symbolic_link (real_uri, target_reference); + + return_value = deal_with_result(result, expected_result, uri, target_uri, target_reference, unlink); + + + + gnome_vfs_uri_unref (real_uri); + gnome_vfs_uri_unref (real_uri_target); + + return return_value; +} + +static void +make_link_async (const char *uri, const char *target_reference, const char *target_uri, GnomeVFSResult expected_result) +{ + CallbackData *info; + GnomeVFSAsyncHandle *handle; + + info = g_malloc (sizeof (CallbackData)); + info->uri = uri; + info->target_uri = target_uri; + info->expected_result = expected_result; + info->target_reference = target_reference; + + gnome_vfs_async_create_symbolic_link (&handle, gnome_vfs_uri_new(uri), target_reference, 0, create_link_callback, info); +} + +static void +check_broken_links (const char *uri) +{ + GnomeVFSHandle *handle; + GnomeVFSResult error; + GnomeVFSURI *real_uri, *real_uri_target; + + real_uri = gnome_vfs_uri_new (uri); + real_uri_target = gnome_vfs_uri_new ("file:///tmp/deadlink"); + + gnome_vfs_unlink_from_uri (real_uri_target); + gnome_vfs_create_symbolic_link (real_uri, "deadlink"); + + error = gnome_vfs_open_uri (&handle, real_uri, GNOME_VFS_OPEN_READ); + if (error != GNOME_VFS_ERROR_NOT_FOUND) { + printf ("GNOME_VFS_BROKEN_SYMLINK not returned open attempting to open a broken symlink.\n"); + printf ("Value returned: %d\n", error); + } + + gnome_vfs_unlink_from_uri (real_uri); + gnome_vfs_unlink_from_uri (real_uri_target); + + gnome_vfs_uri_unref (real_uri); + gnome_vfs_uri_unref (real_uri_target); +} + + +int +main (int argc, const char **argv) +{ + GnomeVFSURI *directory, *file_to_delete; + + poptContext popt_context; + + popt_context = poptGetContext ("test-vfs", argc, argv, + options, 0); + + if (argc != 2) { + fprintf (stderr, "Usage: %s \n", argv[0]); + return 1; + } + + gnome_vfs_init (); + directory = gnome_vfs_uri_new ("file:///tmp/tmp"); + + gnome_vfs_make_directory_for_uri (directory, GNOME_VFS_PERM_USER_ALL); + + make_link ("file:///tmp/link_to_ditz", "file:///tmp/ditz", "file:///tmp/ditz", GNOME_VFS_OK, TRUE); + make_link ("file:///tmp/link_to_ditz_relative", "ditz", "file:///tmp/ditz", GNOME_VFS_OK, TRUE); + make_link ("file:///tmp/tmp/link_to_ditz", "../ditz", "file:///tmp/ditz", GNOME_VFS_OK, FALSE); + make_link ("file:///tmp/link_to_link", "tmp/link_to_ditz", "file:///tmp/tmp/link_to_ditz", GNOME_VFS_OK, TRUE); + + gnome_vfs_remove_directory_from_uri (directory); + gnome_vfs_uri_unref (directory); + + file_to_delete = gnome_vfs_uri_new ("file:///tmp/ditz"); + gnome_vfs_unlink_from_uri (file_to_delete); + gnome_vfs_uri_unref (file_to_delete); + + check_broken_links("file:///tmp/link"); + + make_link ("file:///tmp/link_to_ditz_offfs", "http://www.a.com/ditz", "http://www.a.com/ditz", GNOME_VFS_ERROR_NOT_SUPPORTED, TRUE); + make_link ("http://www.eazel.com/link_to_ditz", "file:///tmp/ditz", "file:///tmp/ditz", GNOME_VFS_ERROR_NOT_SUPPORTED, TRUE); + make_link ("http://www.a.com/link_to_ditz_relative", "ditz", "http://www.a.com/ditz", GNOME_VFS_ERROR_NOT_SUPPORTED, TRUE); + + make_link_async ("file:///tmp/async_link", "file:///tmp/link", "file:///tmp/link", GNOME_VFS_OK); + + main_loop = g_main_loop_new (NULL, TRUE); + g_main_loop_run (main_loop); + g_main_loop_unref (main_loop); + + return 0; +} diff --git a/test/test-sync-create.c b/test/test-sync-create.c new file mode 100644 index 0000000..d8ac72b --- /dev/null +++ b/test/test-sync-create.c @@ -0,0 +1,94 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* test-sync.c - Test program for synchronous operation of the GNOME + Virtual File System. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli + Ian McKellar + + */ + +#include + +#include +#include +#include +#include + +#define BUFFER_SIZE 1024 + +static void +show_result (GnomeVFSResult result, const gchar *what, const gchar *text_uri) +{ + fprintf (stderr, "%s `%s': %s\n", + what, text_uri, gnome_vfs_result_to_string (result)); + if (result != GNOME_VFS_OK) + exit (1); +} + +int +main (int argc, char **argv) +{ + GnomeVFSResult result; + GnomeVFSHandle *handle; + gchar buffer[BUFFER_SIZE+1]; + GnomeVFSFileSize bytes_read; + GnomeVFSURI *uri; + gchar *text_uri; + + if (argc != 2) { + printf ("Usage: %s \n", argv[0]); + return 1; + } + + if (! gnome_vfs_init ()) { + fprintf (stderr, "Cannot initialize gnome-vfs.\n"); + return 1; + } + + uri = gnome_vfs_uri_new (argv[1]); + if (uri == NULL) { + fprintf (stderr, "URI not valid.\n"); + return 1; + } + + text_uri = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE); + + result = gnome_vfs_create_uri (&handle, uri, GNOME_VFS_OPEN_WRITE, FALSE, 0644); + show_result (result, "create", text_uri); + + while( result==GNOME_VFS_OK && !feof(stdin)) { + GnomeVFSFileSize temp; + + bytes_read = fread(buffer, 1, BUFFER_SIZE, stdin); + if(!bytes_read) break; + buffer[bytes_read] = 0; + result = gnome_vfs_write (handle, buffer, bytes_read, + &temp); + show_result (result, "write", text_uri); + + } + + result = gnome_vfs_close (handle); + show_result (result, "close", text_uri); + + g_free (text_uri); + + return 0; +} diff --git a/test/test-sync-write.c b/test/test-sync-write.c new file mode 100644 index 0000000..2febdd7 --- /dev/null +++ b/test/test-sync-write.c @@ -0,0 +1,92 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* test-sync.c - Test program for synchronous operation of the GNOME + Virtual File System. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli + Ian McKellar + + */ + +#include + +#include +#include +#include +#include + +static void +show_result (GnomeVFSResult result, const gchar *what, const gchar *text_uri) +{ + fprintf (stderr, "%s `%s': %s\n", + what, text_uri, gnome_vfs_result_to_string (result)); + if (result != GNOME_VFS_OK) + exit (1); +} + +int +main (int argc, char **argv) +{ + GnomeVFSResult result; + GnomeVFSHandle *handle; + gchar buffer[1024]; + GnomeVFSFileSize bytes_read; + GnomeVFSURI *uri; + gchar *text_uri; + + if (argc != 2) { + printf ("Usage: %s \n", argv[0]); + return 1; + } + + if (! gnome_vfs_init ()) { + fprintf (stderr, "Cannot initialize gnome-vfs.\n"); + return 1; + } + + uri = gnome_vfs_uri_new (argv[1]); + if (uri == NULL) { + fprintf (stderr, "URI not valid.\n"); + return 1; + } + + text_uri = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE); + + result = gnome_vfs_open_uri (&handle, uri, GNOME_VFS_OPEN_WRITE); + show_result (result, "open", text_uri); + + while( result==GNOME_VFS_OK && !feof(stdin)) { + GnomeVFSFileSize temp; + + bytes_read = fread(buffer, 1, sizeof buffer - 1, stdin); + if(!bytes_read) break; + buffer[bytes_read] = 0; + result = gnome_vfs_write (handle, buffer, bytes_read, + &temp); + show_result (result, "write", text_uri); + + } + + result = gnome_vfs_close (handle); + show_result (result, "close", text_uri); + + g_free (text_uri); + + return 0; +} diff --git a/test/test-sync.c b/test/test-sync.c new file mode 100644 index 0000000..0fc2113 --- /dev/null +++ b/test/test-sync.c @@ -0,0 +1,97 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* test-sync.c - Test program for synchronous operation of the GNOME + Virtual File System. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli */ + +#include + +#include +#include +#include +#include +#include + +static void +show_result (GnomeVFSResult result, const gchar *what, const gchar *text_uri) +{ + fprintf (stderr, "%s `%s': %s\n", + what, text_uri, gnome_vfs_result_to_string (result)); + if (result != GNOME_VFS_OK && result != GNOME_VFS_ERROR_EOF) + exit (1); +} + +int +main (int argc, char **argv) +{ + GnomeVFSResult result; + GnomeVFSHandle *handle; + gchar buffer[1024]; + GnomeVFSFileSize bytes_read; + GnomeVFSURI *uri; + gchar *text_uri; + gchar *out; + + if (argc != 2) { + printf ("Usage: %s \n", argv[0]); + return 1; + } + + if (! gnome_vfs_init ()) { + fprintf (stderr, "Cannot initialize gnome-vfs.\n"); + return 1; + } + + uri = gnome_vfs_uri_new (argv[1]); + if (uri == NULL) { + fprintf (stderr, "URI not valid.\n"); + return 1; + } + + text_uri = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE); + + result = gnome_vfs_open_uri (&handle, uri, GNOME_VFS_OPEN_READ); + show_result (result, "open", text_uri); + + while( result==GNOME_VFS_OK ) { + result = gnome_vfs_read (handle, buffer, sizeof buffer - 1, + &bytes_read); + show_result (result, "read", text_uri); + + buffer[bytes_read] = 0; + write (1,buffer,bytes_read); + if(!bytes_read) break; + } + + result = gnome_vfs_file_control (handle, "file:test", &out); + show_result (result, "file_control", text_uri); + if (result == GNOME_VFS_OK) { + g_print ("file_control file:test: %s\n", out); + } + + + + result = gnome_vfs_close (handle); + show_result (result, "close", text_uri); + + g_free (text_uri); + + return 0; +} diff --git a/test/test-unlink.c b/test/test-unlink.c new file mode 100644 index 0000000..680ca8c --- /dev/null +++ b/test/test-unlink.c @@ -0,0 +1,76 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* test-unlink.c - Test program for unlink operation in the GNOME + Virtual File System. + + Copyright (C) 1999 Free Software Foundation + Copyright (C) 2000 Eazel Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: + Ettore Perazzoli + Ian McKellar + */ + +#include + +#include +#include +#include +#include +#include + +static void +show_result (GnomeVFSResult result, const gchar *what, const gchar *text_uri) +{ + fprintf (stderr, "%s `%s': %s\n", + what, text_uri, gnome_vfs_result_to_string (result)); + if (result != GNOME_VFS_OK) + exit (1); +} + +int +main (int argc, char **argv) +{ + GnomeVFSResult result; + GnomeVFSURI *uri; + gchar *text_uri; + + if (argc != 2) { + printf ("Usage: %s \n", argv[0]); + return 1; + } + + if (! gnome_vfs_init ()) { + fprintf (stderr, "Cannot initialize gnome-vfs.\n"); + return 1; + } + + uri = gnome_vfs_uri_new (argv[1]); + if (uri == NULL) { + fprintf (stderr, "URI not valid.\n"); + return 1; + } + + text_uri = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE); + + result = gnome_vfs_unlink (text_uri); + show_result (result, "unlink", text_uri); + + g_free (text_uri); + + return 0; +} diff --git a/test/test-uri.c b/test/test-uri.c new file mode 100644 index 0000000..8e6b835 --- /dev/null +++ b/test/test-uri.c @@ -0,0 +1,727 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* test-mime.c - Test program for the GNOME Virtual File System. + + Copyright (C) 1999 Free Software Foundation + Copyright (C) 2000, 2001 Eazel, Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: + Darin Adler + Ian McKellar +*/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#define TEST_ASSERT(expression, message) \ + G_STMT_START { if (!(expression)) test_failed message; } G_STMT_END + +static void +stop_after_log (const char *domain, GLogLevelFlags level, + const char *message, gpointer data) +{ + void (* saved_handler) (int); + + g_log_default_handler (domain, level, message, data); + + saved_handler = signal (SIGINT, SIG_IGN); + raise (SIGINT); + signal (SIGINT, saved_handler); +} + +static void +make_asserts_break (const char *domain) +{ + g_log_set_handler + (domain, + (GLogLevelFlags) (G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING), + stop_after_log, NULL); +} + +static gboolean at_least_one_test_failed = FALSE; + +static void +test_failed (const char *format, ...) +{ + va_list arguments; + char *message; + + va_start (arguments, format); + message = g_strdup_vprintf (format, arguments); + va_end (arguments); + + g_message ("test failed: %s", message); + at_least_one_test_failed = TRUE; +} + +static void +test_make_canonical_path (const char *input, + const char *expected_output) +{ + char *output; + + output = gnome_vfs_make_path_name_canonical (input); + + if (strcmp (output, expected_output) != 0) { + test_failed ("test_make_canonical_path (%s) resulted in %s instead of %s", + input, output, expected_output); + } + + g_free (output); +} + +const char* test_uris[][2] = +{ + { "http://www.gnome.org/", "index.html" }, + { "http://www.gnome.org/", "/index.html"}, + { "http://www.gnome.org/", "/index.html"}, + { "http://www.gnome.org", "index.html"}, + { "http://www.gnome.org", "/index.html"}, + { "http://www.gnome.org", "./index.html"}, + {NULL, NULL} +}; + + +static void +test_make_full_from_relative (const gchar* base, const gchar* relative, + const gchar* expected_result) +{ + GnomeVFSURI *base_uri; + GnomeVFSURI *vfs_uri; + gchar *str = NULL; + + base_uri = gnome_vfs_uri_new (base); + vfs_uri = gnome_vfs_uri_resolve_relative (base_uri, relative); + str = gnome_vfs_uri_to_string (vfs_uri, GNOME_VFS_URI_HIDE_NONE); + if (expected_result != NULL) { + if (strcmp (expected_result, str) != 0) { + test_failed ("test_make_full_from_relative (%s, %s) resulted in %s instead of %s\n", base, relative, str, expected_result); + } + } + gnome_vfs_uri_unref (base_uri); + gnome_vfs_uri_unref (vfs_uri); + g_free (str); +} + + +static void +test_uri_to_string (const char *input, + const char *expected_output, + GnomeVFSURIHideOptions hide_options) +{ + GnomeVFSURI *uri; + char *output; + + uri = gnome_vfs_uri_new (input); + if (uri == NULL) { + output = g_strdup ("NULL"); + } else { + output = gnome_vfs_uri_to_string (uri, hide_options); + gnome_vfs_uri_unref (uri); + } + + if (strcmp (output, expected_output) != 0) { + test_failed ("gnome_vfs_uri_to_string (%s, %d) resulted in %s instead of %s", + input, hide_options, output, expected_output); + } + + g_free (output); +} + +static void +test_make_canonical (const char *input, + const char *expected_output) +{ + char *output; + + output = gnome_vfs_make_uri_canonical (input); + if (output == NULL) { + output = g_strdup ("NULL"); + } + + if (strcmp (output, expected_output) != 0) { + test_failed ("test_make_canonical (%s) resulted in %s instead of %s", + input, output, expected_output); + } + + g_free (output); +} + +static void +test_uri_match (const char *uri_string_1, const char *uri_string_2, gboolean expected_result) +{ + GnomeVFSURI *uri1; + GnomeVFSURI *uri2; + + uri1 = gnome_vfs_uri_new (uri_string_1); + uri2 = gnome_vfs_uri_new (uri_string_2); + + if (gnome_vfs_uri_equal (uri1, uri2) != expected_result) { + test_failed ("test_uri_match (%s, %s) resulted in a %s instead of %s", + uri_string_1, uri_string_2, + expected_result ? "mismatch" : "match", + expected_result ? "match" : "mismatch"); + } + + gnome_vfs_uri_unref (uri2); + gnome_vfs_uri_unref (uri1); +} + +static void +test_file_path_to_uri_string (const char *input, + const char *expected_output, + GnomeVFSURIHideOptions hide_options) +{ + GnomeVFSURI *uri, *resulting_uri; + char *output; + char *unescaped_output; + + uri = gnome_vfs_uri_new ("file:/"); + resulting_uri = gnome_vfs_uri_append_path (uri, input); + gnome_vfs_uri_unref (uri); + + output = gnome_vfs_uri_to_string (resulting_uri, hide_options); + gnome_vfs_uri_unref (resulting_uri); + + unescaped_output = gnome_vfs_unescape_string (output, "/"); + g_free (output); + + if (strcmp (unescaped_output, expected_output) != 0) { + test_failed ("gnome_vfs_uri_to_string (%s, %d) resulted in %s instead of %s", + input, hide_options, unescaped_output, expected_output); + } + + g_free (unescaped_output); +} + +static void +test_uri_has_fragment_id (const char *input, + const char *expected_output) +{ + GnomeVFSURI *uri; + char *output; + + uri = gnome_vfs_uri_new (input); + if (uri == NULL) { + output = g_strdup ("NULL"); + } else { + output = g_strdup (gnome_vfs_uri_get_fragment_identifier (uri)); + } + + if (strcmp (output, expected_output) != 0) { + test_failed ("test_uri_has_fragment_id (%s) resulted in %s instead of %s", + input, output, expected_output); + } + + g_free (output); + gnome_vfs_uri_unref (uri); +} + +static void +test_uri_extract_dirname (const char *input, + const char *expected_output) +{ + GnomeVFSURI *uri; + char *output; + + uri = gnome_vfs_uri_new (input); + if (uri == NULL) { + output = g_strdup ("NULL"); + } else { + output = gnome_vfs_uri_extract_dirname (uri); + } + + if (strcmp (output, expected_output) != 0) { + test_failed ("test_uri_extract_dirname (%s) resulted in %s instead of %s", + input, output, expected_output); + } + + g_free (output); + gnome_vfs_uri_unref (uri); +} + +static void +test_uri_parent (const char *input, + const char *expected_output) +{ + GnomeVFSURI *uri, *parent; + char *output; + + uri = gnome_vfs_uri_new (input); + if (uri == NULL) { + output = g_strdup ("URI NULL"); + } else { + parent = gnome_vfs_uri_get_parent (uri); + gnome_vfs_uri_unref (uri); + if (parent == NULL) { + output = g_strdup ("NULL"); + } else { + output = gnome_vfs_uri_to_string (parent, GNOME_VFS_URI_HIDE_NONE); + gnome_vfs_uri_unref (parent); + } + } + + if (strcmp (output, expected_output) != 0) { + test_failed ("gnome_vfs_uri_parent (%s) resulted in %s instead of %s", + input, output, expected_output); + } + + g_free (output); +} + +static void +test_uri_has_parent (const char *input, + const char *expected_output) +{ + GnomeVFSURI *uri; + const char *output; + gboolean has; + + uri = gnome_vfs_uri_new (input); + if (uri == NULL) { + output = "URI NULL"; + } else { + has = gnome_vfs_uri_has_parent (uri); + gnome_vfs_uri_unref (uri); + output = has ? "TRUE" : "FALSE"; + } + + if (strcmp (output, expected_output) != 0) { + test_failed ("gnome_vfs_uri_has_parent (%s) resulted in %s instead of %s", + input, output, expected_output); + } +} + +/* + * Ensure that gnome_vfs_uri_{get_host_name,get_scheme,get_user_name,get_password} + * return expected results + */ +static void +test_uri_part (const char *input, + const char *expected_output, + const char *(*func_gnome_vfs_uri)(const GnomeVFSURI *) + ) +{ + GnomeVFSURI *uri; + const char *output; + + uri = gnome_vfs_uri_new (input); + if (NULL == uri) { + output = "URI NULL"; + } else { + output = func_gnome_vfs_uri(uri); + if ( NULL == output ) { + output = "NULL"; + } + } + + if (strcmp (output, expected_output) != 0) { + test_failed ("gnome_vfs_uri_{?} (%s) resulted in %s instead of %s", + input, output, expected_output); + } + + if ( NULL != uri ) { + gnome_vfs_uri_unref (uri); + } + +} + +/* + * Ensure that gnome_vfs_uri_get_host_port + * return expected results + */ +static void +test_uri_host_port (const char *input, + guint expected_port) +{ + GnomeVFSURI *uri; + gboolean success = FALSE; + guint port; + + port = 0; + uri = gnome_vfs_uri_new (input); + if (NULL != uri) { + port = gnome_vfs_uri_get_host_port(uri); + if (expected_port == port) { + success = TRUE; + gnome_vfs_uri_unref (uri); + } + } + + if (!success) { + test_failed ("gnome_vfs_uri_get_host_port (%s) resulted in %u instead of %u", + input, port, expected_port); + } +} + +static void +test_uri_is_parent_common (const char *parent, const char *item, gboolean deep, gboolean expected_result) +{ + GnomeVFSURI *item_uri; + GnomeVFSURI *parent_uri; + gboolean result; + + item_uri = gnome_vfs_uri_new (item); + parent_uri = gnome_vfs_uri_new (parent); + + result = gnome_vfs_uri_is_parent (parent_uri, item_uri, deep); + + if (result != expected_result) { + test_failed ("gnome_vfs_uri_is_parent (%s, %s) resulted in \"%s\" instead of \"%s\"", + parent, item, result ? "TRUE" : "FALSE", expected_result ? "TRUE" : "FALSE"); + } + + gnome_vfs_uri_unref (item_uri); + gnome_vfs_uri_unref (parent_uri); +} + +static void +test_uri_is_parent_deep (const char *parent, const char *item, gboolean expected_result) +{ + test_uri_is_parent_common (parent, item, TRUE, expected_result); +} + +static void +test_uri_is_parent_shallow (const char *parent, const char *item, gboolean expected_result) +{ + test_uri_is_parent_common (parent, item, FALSE, expected_result); +} + +#define VERIFY_STRING_RESULT(function, expected) \ + G_STMT_START { \ + char *result = function; \ + if (!((result == NULL && expected == NULL) \ + || (result != NULL && expected != NULL && strcmp (result, (char *)expected) == 0))) { \ + test_failed ("%s: returned '%s' expected '%s'", #function, result, expected); \ + } \ + g_free (result); \ + } G_STMT_END + +int +main (int argc, char **argv) +{ + int i; + + make_asserts_break ("GLib"); + make_asserts_break ("GnomeVFS"); + + /* Initialize the libraries we use. */ + gnome_vfs_init (); + + /* Test the "make canonical" call for pathnames. */ + test_make_canonical_path ("", ""); + test_make_canonical_path ("/", "/"); + test_make_canonical_path ("/.", "/"); + test_make_canonical_path ("/./.", "/"); + test_make_canonical_path ("/.//.", "/"); + test_make_canonical_path ("/.///.", "/"); + test_make_canonical_path ("a", "a"); + test_make_canonical_path ("/a/b/..", "/a"); + test_make_canonical_path ("a///", "a/"); + test_make_canonical_path ("./a", "a"); + test_make_canonical_path ("../a", "../a"); + test_make_canonical_path ("..//a", "../a"); + test_make_canonical_path ("a/.", "a"); + test_make_canonical_path ("/a/.", "/a"); + test_make_canonical_path ("/a/..", "/"); + test_make_canonical_path ("a//.", "a"); + test_make_canonical_path ("./a/.", "a"); + test_make_canonical_path (".//a/.", "a"); + test_make_canonical_path ("./a//.", "a"); + test_make_canonical_path ("a/..", ""); + test_make_canonical_path ("a//..", ""); + test_make_canonical_path ("./a/..", ""); + test_make_canonical_path (".//a/..", ""); + test_make_canonical_path ("./a//..", ""); + test_make_canonical_path (".//a//..", ""); + test_make_canonical_path ("a/b/..", "a"); + test_make_canonical_path ("./a/b/..", "a"); + test_make_canonical_path ("/./a/b/..", "/a"); + test_make_canonical_path ("/a/./b/..", "/a"); + test_make_canonical_path ("/a/b/./..", "/a"); + test_make_canonical_path ("/a/b/../.", "/a"); + test_make_canonical_path ("a/b/../..", ""); + test_make_canonical_path ("./a/b/../..", ""); + test_make_canonical_path ("././a/b/../..", ""); + test_make_canonical_path ("a/b/c/../..", "a"); + test_make_canonical_path ("a/b/c/../../d", "a/d"); + test_make_canonical_path ("a/b/../../d", "d"); + test_make_canonical_path ("a/../../d", "../d"); + test_make_canonical_path ("a/b/.././.././c", "c"); + test_make_canonical_path ("a/.././.././b/c", "../b/c"); + test_make_canonical_path ("\\", "\\"); + + test_uri_to_string ("", "NULL", GNOME_VFS_URI_HIDE_NONE); + + test_uri_to_string ("http://www.eazel.com", "http://www.eazel.com", GNOME_VFS_URI_HIDE_NONE); + test_uri_to_string ("http://www.eazel.com/", "http://www.eazel.com/", GNOME_VFS_URI_HIDE_NONE); + test_uri_to_string ("http://www.eazel.com/dir", "http://www.eazel.com/dir", GNOME_VFS_URI_HIDE_NONE); + test_uri_to_string ("http://www.eazel.com/dir/", "http://www.eazel.com/dir/", GNOME_VFS_URI_HIDE_NONE); + test_uri_to_string ("http://yakk:womble@www.eazel.com:42/blah/", "http://yakk:womble@www.eazel.com:42/blah/", GNOME_VFS_URI_HIDE_NONE); + + test_uri_to_string ("http://yakk:womble@www.eazel.com:42/blah/", "http://:womble@www.eazel.com:42/blah/", GNOME_VFS_URI_HIDE_USER_NAME); + test_uri_to_string ("FILE://", "file:", GNOME_VFS_URI_HIDE_NONE); + + test_uri_to_string ("file:///trash", "file:///trash", GNOME_VFS_URI_HIDE_NONE); + test_uri_to_string ("file:///Users/mikef", "file:///Users/mikef", GNOME_VFS_URI_HIDE_NONE); + test_uri_to_string ("/trash", "file:///trash", GNOME_VFS_URI_HIDE_NONE); + + /* test URI parts */ + test_uri_part ("http://www.eazel.com:80/", "http", gnome_vfs_uri_get_scheme); + test_uri_part ("http://www.eazel.com:80/", "www.eazel.com", gnome_vfs_uri_get_host_name); + test_uri_part ("http://www.eazel.com:80/", "NULL", gnome_vfs_uri_get_user_name); + test_uri_part ("http://www.eazel.com:80/", "NULL", gnome_vfs_uri_get_password); + test_uri_part ("http://www.eazel.com:80/", "/", gnome_vfs_uri_get_path); + + test_uri_host_port ("http://www.eazel.com/", 0); + test_uri_host_port ("http://www.eazel.com:80/", 80); + + /* Now--same thing w/o trailing / */ + test_uri_part ("http://www.eazel.com:80", "http", gnome_vfs_uri_get_scheme); + test_uri_part ("http://www.eazel.com:80", "www.eazel.com", gnome_vfs_uri_get_host_name); + test_uri_part ("http://www.eazel.com:80", "NULL", gnome_vfs_uri_get_user_name); + test_uri_part ("http://www.eazel.com:80", "NULL", gnome_vfs_uri_get_password); + test_uri_part ("http://www.eazel.com:80", "/", gnome_vfs_uri_get_path); + + test_uri_host_port ("http://www.eazel.com", 0); + test_uri_host_port ("http://www.eazel.com:80", 80); + + /* now same thing with all the parts */ + test_uri_part ("http://yakk:womble@www.eazel.com:42/blah/", "http", gnome_vfs_uri_get_scheme ); + test_uri_part ("http://yakk:womble@www.eazel.com:42/blah/", "www.eazel.com", gnome_vfs_uri_get_host_name ); + test_uri_part ("http://yakk:womble@www.eazel.com:42/blah/", "yakk", gnome_vfs_uri_get_user_name ); + test_uri_part ("http://yakk:womble@www.eazel.com:42/blah/", "womble", gnome_vfs_uri_get_password ); + test_uri_host_port ("http://yakk:womble@www.eazel.com:42/blah/", 42); + test_uri_part ("http://yakk:womble@www.eazel.com:42/blah/", "/blah/", gnome_vfs_uri_get_path ); + + test_uri_part ("http://foo.com/query?email=user@host", "/query?email=user@host", gnome_vfs_uri_get_path); + test_uri_part ("http://user@host:42/query?email=user@host", "host", gnome_vfs_uri_get_host_name); + test_uri_part ("http://@:/path", "NULL", gnome_vfs_uri_get_host_name); + test_uri_part ("http://@::/path", "NULL", gnome_vfs_uri_get_host_name); + test_uri_part ("http://::/path", "NULL", gnome_vfs_uri_get_host_name); + test_uri_part ("http://@pass/path", "pass", gnome_vfs_uri_get_host_name); + + test_uri_parent ("", "URI NULL"); + test_uri_parent ("http://www.eazel.com", "NULL"); + test_uri_parent ("http://www.eazel.com/", "NULL"); + test_uri_parent ("http://www.eazel.com/dir", "http://www.eazel.com/"); + test_uri_parent ("http://www.eazel.com/dir/", "http://www.eazel.com/"); + test_uri_parent ("http://yakk:womble@www.eazel.com:42/blah/", "http://yakk:womble@www.eazel.com:42/"); + test_uri_parent ("file:", "NULL"); + test_uri_parent ("http:", "NULL"); + test_uri_parent ("file:/", "NULL"); + test_uri_parent ("FILE://", "NULL"); + test_uri_parent ("pipe:gnome-info2html2 as", "URI NULL"); + test_uri_parent ("file:///my/document.html#fragment", "file:///my"); + + test_uri_is_parent_shallow ("file:///path", "file:///path/child", TRUE); + test_uri_is_parent_shallow ("file:///bla", "file:///path/child", FALSE); + test_uri_is_parent_shallow ("file:///path1/path2", "file:///path1/path2/child", TRUE); + test_uri_is_parent_shallow ("ftp://foobar.com", "ftp://foobar.com/child", TRUE); + test_uri_is_parent_shallow ("ftp://foobar.com/", "ftp://foobar.com/child", TRUE); + test_uri_is_parent_shallow ("ftp://foobar.com/path", "ftp://foobar.com/path/child", TRUE); + test_uri_is_parent_shallow ("file:///path1/path2", "file:///path1/path2/path3/path4/path5/child", FALSE); + + test_uri_is_parent_deep ("file:///path", "file:///path/child", TRUE); + test_uri_is_parent_deep ("file:///path1/path2", "file:///path1/path2/child", TRUE); + test_uri_is_parent_deep ("ftp://foobar.com", "ftp://foobar.com/child", TRUE); + test_uri_is_parent_deep ("ftp://foobar.com/", "ftp://foobar.com/child", TRUE); + test_uri_is_parent_deep ("ftp://foobar.com/path", "ftp://foobar.com/path/child", TRUE); + + test_uri_is_parent_deep ("file:///path", "file:///path/path1/child", TRUE); + test_uri_is_parent_deep ("file:///path1/path2", "file:///path1/path2/path3/child", TRUE); + test_uri_is_parent_deep ("file:///path1/path2", "file:///path1/path2/path3/path4/path5/child", TRUE); + test_uri_is_parent_deep ("ftp://foobar.com", "ftp://foobar.com/path1/child", TRUE); + test_uri_is_parent_deep ("ftp://foobar.com/", "ftp://foobar.com/path1/child", TRUE); + test_uri_is_parent_deep ("ftp://foobar.com/path1", "ftp://foobar.com/path1/path2/child", TRUE); + + test_uri_has_parent ("", "URI NULL"); + test_uri_has_parent ("http://www.eazel.com", "FALSE"); + test_uri_has_parent ("http://www.eazel.com/", "FALSE"); + test_uri_has_parent ("http://www.eazel.com/dir", "TRUE"); + test_uri_has_parent ("http://www.eazel.com/dir/", "TRUE"); + test_uri_has_parent ("http://yakk:womble@www.eazel.com:42/blah/", "TRUE"); + test_uri_has_parent ("file:", "FALSE"); + test_uri_has_parent ("http:", "FALSE"); + test_uri_has_parent ("file:/", "FALSE"); + test_uri_has_parent ("FILE://", "FALSE"); + test_uri_has_parent ("pipe:gnome-info2html2 as", "URI NULL"); + + /* Test uri canonicalization */ + test_uri_to_string ("/////", "file:///", GNOME_VFS_URI_HIDE_NONE); + test_uri_to_string ("/.", "file:///", GNOME_VFS_URI_HIDE_NONE); + test_uri_to_string ("/./.", "file:///", GNOME_VFS_URI_HIDE_NONE); + test_uri_to_string ("/.///.", "file:///", GNOME_VFS_URI_HIDE_NONE); + test_uri_to_string ("/a/..", "file:///", GNOME_VFS_URI_HIDE_NONE); + test_uri_to_string ("/a/b/..", "file:///a", GNOME_VFS_URI_HIDE_NONE); + test_uri_to_string ("/a/b//..", "file:///a", GNOME_VFS_URI_HIDE_NONE); + test_uri_to_string ("/./a/b/..", "file:///a", GNOME_VFS_URI_HIDE_NONE); + test_uri_to_string ("/a/./b/..", "file:///a", GNOME_VFS_URI_HIDE_NONE); + test_uri_to_string ("/a/b/./..", "file:///a", GNOME_VFS_URI_HIDE_NONE); + test_uri_to_string ("/a///b//..", "file:///a", GNOME_VFS_URI_HIDE_NONE); + test_uri_to_string ("/a/b/../..", "file:///", GNOME_VFS_URI_HIDE_NONE); + test_uri_to_string ("/a/b/c/../..", "file:///a", GNOME_VFS_URI_HIDE_NONE); + test_uri_to_string ("/a/../b/..", "file:///", GNOME_VFS_URI_HIDE_NONE); + test_uri_to_string ("/a/../b/../c", "file:///c", GNOME_VFS_URI_HIDE_NONE); + test_uri_to_string ("/a/../b/../c", "file:///c", GNOME_VFS_URI_HIDE_NONE); + + test_make_canonical ("file:///%3F", "file:///%3F"); + test_make_canonical ("file:///%78", "file:///x"); + test_make_canonical ("file:///?", "file:///%3F"); + test_make_canonical ("file:///&", "file:///%26"); + test_make_canonical ("file:///x", "file:///x"); + test_make_canonical ("glorb:///%3F", "glorb:///%3F"); + test_make_canonical ("glorb:///%78", "glorb:///x"); + test_make_canonical ("glorb:///?", "glorb:///%3F"); + test_make_canonical ("glorb:///&", "glorb:///%26"); + test_make_canonical ("glorb:///x", "glorb:///x"); + test_make_canonical ("http:///%3F", "http:///%3F"); + test_make_canonical ("http:///%78", "http:///x"); + test_make_canonical ("http:///?", "http:///?"); + test_make_canonical ("http:///&", "http:///&"); + test_make_canonical ("http:///x", "http:///x"); + test_make_canonical ("pipe:foo", "pipe:foo"); + test_make_canonical ("eazel-services:///%3F", "eazel-services:///%3F"); + test_make_canonical ("eazel-services:///%78", "eazel-services:///x"); + test_make_canonical ("eazel-services:///?", "eazel-services:///?"); + test_make_canonical ("eazel-services:///&", "eazel-services:///&"); + test_make_canonical ("eazel-services:///x", "eazel-services:///x"); + + test_make_canonical ("eazel-install://anonymous@/product_name=gnucash", "eazel-install://anonymous@/product_name%3Dgnucash"); + test_make_canonical ("eazel-install://:password@/product_name=gnucash", "eazel-install://:password@/product_name%3Dgnucash"); + + test_make_canonical ("http://www.eazel.com/query?email=email@eazel.com", "http://www.eazel.com/query?email=email@eazel.com"); + + /* test proper case-sensitivity handling */ + test_make_canonical ("HTTP://WWW.ZOO.COM", "http://www.zoo.com"); + test_make_canonical ("HTTP://WWW.ZOO.COM/", "http://www.zoo.com/"); + test_make_canonical ("HTTP://WWW.ZOO.COM/ED", "http://www.zoo.com/ED"); + test_uri_match ("http://www.zoo.com/ed", "HTTP://WWW.ZOO.COM/ed", TRUE); + test_uri_match ("http://www.zoo.com/ed", "http://www.zoo.com/ED", FALSE); + + test_uri_match ("http://ed:ed@www.zoo.com/ed", "http://ed:ed@www.zoo.com/ed", TRUE); + test_uri_match ("http://ed:ed@www.zoo.com/ed", "HTTP://ed:ed@www.zoo.com/ed", TRUE); + test_uri_match ("http://ed:ed@www.zoo.com/ed", "http://ED:ed@www.zoo.com/ed", FALSE); + test_uri_match ("http://ed:ed@www.zoo.com/ed", "http://ed:ED@www.zoo.com/ed", FALSE); + test_uri_match ("http://ed:ed@www.zoo.com/ed", "http://ed:ed@WWW.zoo.com/ed", TRUE); + test_uri_match ("http://ed:ed@www.zoo.com/ed", "http://ed:ed@www.ZOO.com/ed", TRUE); + test_uri_match ("http://ed:ed@www.zoo.com/ed", "http://ed:ed@www.zoo.COM/ed", TRUE); + test_uri_match ("http://ed:ed@www.zoo.com/ed", "http://ed:ed@www.zoo.com/ED", FALSE); + + test_uri_match ("/tmp/foo", "/tmp/foo", TRUE); + test_uri_match ("file:/tmp/foo", "file:/TMP/foo", FALSE); + test_uri_match ("/tmp/foo", "/TMP/foo", FALSE); + + /* Test chained uris */ + test_uri_to_string ("/tmp/t.efs#http:///foobar/", "file:///tmp/t.efs#http:/foobar/", GNOME_VFS_URI_HIDE_NONE); + test_uri_parent ("/tmp/t.efs#http:/", "file:///tmp/t.efs"); + test_uri_to_string ("/tmp/t.efs#zip:/", "file:///tmp/t.efs#zip:/", GNOME_VFS_URI_HIDE_NONE); + test_uri_parent ("/tmp/t.efs#zip:/", "file:///tmp/t.efs"); + test_uri_to_string ("/tmp/t.efs#unknownmethod:/", "file:///tmp/t.efs", GNOME_VFS_URI_HIDE_NONE); + + /* Test fragment identifiers. */ + test_uri_to_string ("/tmp/#junk", "file:///tmp/#junk", GNOME_VFS_URI_HIDE_NONE); + test_uri_to_string ("/tmp/#junk", "file:///tmp/", GNOME_VFS_URI_HIDE_FRAGMENT_IDENTIFIER); + test_uri_to_string ("/tmp/#junk#", "file:///tmp/#junk#", GNOME_VFS_URI_HIDE_NONE); + test_uri_has_fragment_id ("/tmp/#junk", "junk"); + test_uri_has_fragment_id ("/tmp/#junk#", "junk#"); + + /* Test gnome_vfs_uri_extract_dirname (). */ + test_uri_extract_dirname ("/", "/"); + test_uri_extract_dirname ("/usr", "/"); + test_uri_extract_dirname ("/usr/bin", "/usr"); + + /* test a escaping->unescaping round trip for funny characters */ + test_file_path_to_uri_string ("/tmp/#backup_file#", "file:///tmp/#backup_file#", GNOME_VFS_URI_HIDE_NONE); + test_file_path_to_uri_string ("/tmp/percent%percent", "file:///tmp/percent%percent", GNOME_VFS_URI_HIDE_NONE); + + /* FIXME bugzilla.eazel.com 4101: Why append a slash in this case, but not in the http://www.eazel.com case? */ + test_uri_to_string ("http://www.eazel.com:80", "http://www.eazel.com:80/", GNOME_VFS_URI_HIDE_NONE); + + /* FIXME bugzilla.eazel.com 3829: illegal */ + test_uri_to_string ("foo", "file:foo", GNOME_VFS_URI_HIDE_NONE); + + /* FIXME bugzilla.eazel.com 4102: illegal? */ + test_uri_to_string ("file:foo", "file:foo", GNOME_VFS_URI_HIDE_NONE); + + /* FIXME bugzilla.eazel.com 3830: This turns a good path with + * a redundant "/" in it into a completely different one. + */ + test_uri_to_string ("//foo", "file://foo", GNOME_VFS_URI_HIDE_NONE); + + /* FIXME bugzilla.eazel.com 7774: Are any of these right? + * Perhaps they should all return NULL? + */ + test_uri_to_string (".", "file:", GNOME_VFS_URI_HIDE_NONE); + test_uri_to_string ("./a", "file:a", GNOME_VFS_URI_HIDE_NONE); + test_uri_to_string ("../a", "file:../a", GNOME_VFS_URI_HIDE_NONE); + test_uri_to_string ("../a", "file:../a", GNOME_VFS_URI_HIDE_NONE); + test_uri_to_string ("../../a", "file:a", GNOME_VFS_URI_HIDE_NONE); + + /* FIXME bugzilla.eazel.com 2801: Do we want GnomeVFSURI to + * just refuse to deal with URIs that we don't have a module + * for? + */ + test_uri_to_string ("glorp:", "NULL", GNOME_VFS_URI_HIDE_NONE); + test_uri_parent ("glorp:", "URI NULL"); + + test_uri_to_string ("file:", "file:///", GNOME_VFS_URI_HIDE_NONE); + test_uri_to_string ("http:", "http:///", GNOME_VFS_URI_HIDE_NONE); + test_uri_to_string ("file:/", "file:///", GNOME_VFS_URI_HIDE_NONE); + + /* FIXME bugzilla.eazel.com 6022: At least for http, we don't + * want to do canonicalizing after the ?. All these results + * are presumably wrong because of that. + */ + test_uri_to_string ("http://www.eazel.com?///xxx", "http://www.eazel.com?/xxx", GNOME_VFS_URI_HIDE_NONE); + test_uri_parent ("http://www.eazel.com?///xxx", "http://www.eazel.com?/"); + test_uri_parent ("http://www.eazel.com/dir?xxx/yyy", "http://www.eazel.com/dir?xxx"); + + VERIFY_STRING_RESULT (gnome_vfs_get_local_path_from_uri (""), NULL); + VERIFY_STRING_RESULT (gnome_vfs_get_local_path_from_uri ("/#"), NULL); + VERIFY_STRING_RESULT (gnome_vfs_get_local_path_from_uri ("file:/path"), "/path"); + VERIFY_STRING_RESULT (gnome_vfs_get_local_path_from_uri ("file://path"), NULL); + VERIFY_STRING_RESULT (gnome_vfs_get_local_path_from_uri ("file:///path"), "/path"); + VERIFY_STRING_RESULT (gnome_vfs_get_local_path_from_uri ("file:////path"), "//path"); + VERIFY_STRING_RESULT (gnome_vfs_get_local_path_from_uri ("file:///my/document.html"), "/my/document.html"); + VERIFY_STRING_RESULT (gnome_vfs_get_local_path_from_uri ("file:///my/document.html#fragment"), NULL); + VERIFY_STRING_RESULT (gnome_vfs_get_local_path_from_uri ("file:///my/docu%20ment%23/path"), "/my/docu ment#/path"); + VERIFY_STRING_RESULT (gnome_vfs_get_local_path_from_uri ("file:///my/docu%20ment%23/path/foo.html.gz#gunzip:///#fragment"), NULL); + VERIFY_STRING_RESULT (gnome_vfs_get_local_path_from_uri ("/my/document.html"), NULL); + VERIFY_STRING_RESULT (gnome_vfs_get_local_path_from_uri ("http://my/document.html"), NULL); + + /* Testing gnome_vfs_uri_make_full_from_relative */ + /* (not an extensive testing, but a regression test */ + i = 0; + while (test_uris[i][0] != NULL) { + test_make_full_from_relative (test_uris[i][0], test_uris[i][1], + "http://www.gnome.org/index.html"); + i++; + } + + + /* Report to "make check" on whether it all worked or not. */ + return at_least_one_test_failed ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/test/test-xfer.c b/test/test-xfer.c new file mode 100644 index 0000000..20dc0d3 --- /dev/null +++ b/test/test-xfer.c @@ -0,0 +1,256 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* test-xfer.c - Test program for the xfer functions in the GNOME Virtual File + System. + + Copyright (C) 1999 Free Software Foundation + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ettore Perazzoli */ + +#include + +#include +#include +#include +#include +#include + +static int recursive = 0; +static int replace = 0; +static int remove_source = 0; +static int follow_symlinks = 0; +static int follow_symlinks_recursive = 0; + +const struct poptOption options[] = { + POPT_AUTOHELP + { + "recursive", + 'r', + POPT_ARG_NONE, + &recursive, + 0, + "Copy directories recursively", + NULL + }, + { + "follow-symlinks", + 'L', + POPT_ARG_NONE, + &follow_symlinks, + 0, + "Follow symlinks", + NULL + }, + { + "recursive-symlinks", + 'Z', + POPT_ARG_NONE, + &follow_symlinks_recursive, + 0, + "Follow symlinks", + NULL + }, + { + "replace", + 'R', + POPT_ARG_NONE, + &replace, + 0, + "Replace files automatically", + NULL + }, + { + "delete-source", + 'd', + POPT_ARG_NONE, + &remove_source, + 0, + "Delete source files", + NULL + }, + { + NULL, + 0, + 0, + NULL, + 0, + NULL, + NULL + } +}; + +static void +show_result (GnomeVFSResult result, const gchar *what) +{ + fprintf (stderr, "%s: %s\n", what, gnome_vfs_result_to_string (result)); + if (result != GNOME_VFS_OK) + exit (1); +} + +static gint +xfer_progress_callback (GnomeVFSXferProgressInfo *info, + gpointer data) +{ + switch (info->status) { + case GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR: + printf ("VFS Error: %s\n", + gnome_vfs_result_to_string (info->vfs_status)); + exit (1); + break; + case GNOME_VFS_XFER_PROGRESS_STATUS_OVERWRITE: + printf ("Overwriting `%s' with `%s'\n", + info->target_name, info->source_name); + exit (1); + break; + case GNOME_VFS_XFER_PROGRESS_STATUS_OK: + printf ("Status: OK\n"); + switch (info->phase) { + case GNOME_VFS_XFER_PHASE_INITIAL: + printf ("Initial phase\n"); + return TRUE; + case GNOME_VFS_XFER_PHASE_COLLECTING: + printf ("Collecting file list\n"); + return TRUE; + case GNOME_VFS_XFER_PHASE_READYTOGO: + printf ("Ready to go!\n"); + return TRUE; + case GNOME_VFS_XFER_PHASE_OPENSOURCE: + printf ("Opening source\n"); + return TRUE; + case GNOME_VFS_XFER_PHASE_OPENTARGET: + printf ("Opening target\n"); + return TRUE; + case GNOME_VFS_XFER_PHASE_COPYING: + printf ("Transferring `%s' to `%s' (file %ld/%ld, byte %ld/%ld in file, " + "%" GNOME_VFS_SIZE_FORMAT_STR "/%" GNOME_VFS_SIZE_FORMAT_STR " total)\n", + info->source_name, + info->target_name, + info->file_index, + info->files_total, + (glong) info->bytes_copied, + (glong) info->file_size, + info->total_bytes_copied, + info->bytes_total); + return TRUE; + case GNOME_VFS_XFER_PHASE_CLOSESOURCE: + printf ("Closing source\n"); + return TRUE; + case GNOME_VFS_XFER_PHASE_CLOSETARGET: + printf ("Closing target\n"); + return TRUE; + case GNOME_VFS_XFER_PHASE_FILECOMPLETED: + printf ("Done with `%s' -> `%s', going next\n", + info->source_name, info->target_name); + return TRUE; + case GNOME_VFS_XFER_PHASE_COMPLETED: + printf ("All done.\n"); + return TRUE; + default: + printf ("Unexpected phase %d\n", info->phase); + return TRUE; /* keep going anyway */ + } + case GNOME_VFS_XFER_PROGRESS_STATUS_DUPLICATE: + break; + } + + printf ("Boh!\n"); + return FALSE; +} + +int +main (int argc, const char **argv) +{ + const char **args; + poptContext popt_context; + GnomeVFSURI *src_uri, *dest_uri; + GList *src_uri_list, *dest_uri_list; + GnomeVFSResult result; + GnomeVFSXferOptions xfer_options; + GnomeVFSXferOverwriteMode overwrite_mode; + + if (! gnome_vfs_init ()) { + fprintf (stderr, + "Cannot initialize the GNOME Virtual File System.\n"); + return 1; + } + + popt_context = poptGetContext ("test-directory", argc, argv, + options, 0); + + while (poptGetNextOpt (popt_context) != -1) + ; + + args = poptGetArgs (popt_context); + if (args == NULL || args[1] == NULL || args[2] != NULL) { + fprintf (stderr, "Usage: %s [] \n", + argv[0]); + return 1; + } + + src_uri = gnome_vfs_uri_new (args[0]); + if (src_uri == NULL) { + fprintf (stderr, "%s: invalid URI\n", args[0]); + return 1; + } + dest_uri = gnome_vfs_uri_new (args[1]); + if (dest_uri == NULL) { + fprintf (stderr, "%s: invalid URI\n", args[1]); + return 1; + } + + poptFreeContext (popt_context); + + + xfer_options = 0; + overwrite_mode = GNOME_VFS_XFER_OVERWRITE_MODE_QUERY; + if (recursive) { + fprintf (stderr, "Warning: Recursive xfer of directories.\n"); + xfer_options |= GNOME_VFS_XFER_RECURSIVE; + } + if (follow_symlinks) { + fprintf (stderr, "Warning: Following symlinks.\n"); + xfer_options |= GNOME_VFS_XFER_FOLLOW_LINKS; + } + if (follow_symlinks_recursive) { + fprintf (stderr, "Warning: Following symlinks recursively.\n"); + xfer_options |= GNOME_VFS_XFER_FOLLOW_LINKS_RECURSIVE; + } + if (replace) { + fprintf (stderr, "Warning: Using replace overwrite mode.\n"); + overwrite_mode = GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE; + } + if (remove_source) { + fprintf (stderr, "Warning: Removing source files.\n"); + xfer_options |= GNOME_VFS_XFER_REMOVESOURCE; + } + + src_uri_list = g_list_append (NULL, src_uri); + dest_uri_list = g_list_append (NULL, dest_uri); + result = gnome_vfs_xfer_uri_list (src_uri_list, dest_uri_list, + xfer_options, + GNOME_VFS_XFER_ERROR_MODE_QUERY, + overwrite_mode, + xfer_progress_callback, + NULL); + + show_result (result, "gnome_vfs_xfer"); + + gnome_vfs_uri_list_free (src_uri_list); + gnome_vfs_uri_list_free (dest_uri_list); + + return 0; +} diff --git a/test/test.cmds b/test/test.cmds new file mode 100644 index 0000000..e55c2c4 --- /dev/null +++ b/test/test.cmds @@ -0,0 +1,55 @@ +# setup the environment + +mkdir /tmp/test +cp test.input /tmp/test/test.input +cd /tmp/test + +# simple tests on the file filing system + +cp test.input t +mv t t2 +cp t2 t +open #1 t +read #1 16 +seek #1 0 +read #1 16 +open #2 t2 +read #2 16 +close #1 +close #2 +rm t +rm t2 + +# gzip as far as it goes ( no where ) + +# cd /tmp/test +# cp test.input /tmp/test/t.gz#gzip: +# open #1 /tmp/test/t.gz#gzip: +# read #1 16 +# close #1 +# rm t.gz + +# efs + +cd /tmp/test +mkdir /tmp/test/t.efs#efs:/ +cp test.input /tmp/test/t.efs#efs:/t +cp /tmp/test/test.input /tmp/test/t.efs#efs:/t2 +cd /tmp/test/t.efs#efs:/ +open #1 t +ls +open #2 t2 +read #1 16 +read #2 16 +ls +close #1 +close #2 +cd /tmp/test +rm t.efs + +# cleanup + +rm /tmp/test/test.input +rmdir /tmp/test +quit + diff --git a/test/test.input b/test/test.input new file mode 100644 index 0000000..d60c31a --- /dev/null +++ b/test/test.input @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/test/test.output b/test/test.output new file mode 100644 index 0000000000000000000000000000000000000000..1d240773caecce948143e160e9227712e3ba7103 GIT binary patch literal 1812 zcmc&#QE!4U5O!}Hzv7ZTpf3y73gnjGQpCO6q=>R@OrLMfXcOcdV>yvW`!IY(%9NxnquQwq3nY<7D`||1#t>;3c}1fMH1|9B2+iLA#I+rcyns=G zAw{0ugR&ZD7`jiah7u_Y*&@*Ao@!UW)M869fU4YFU%|AWqzDKt;EisGxKq56%GdYC zcNpdQY>9FO)8kQMk^}9hxh%Dc7T>2+8j}OOeibNZL3-}qM z^#Ar9w`U1|BxDJ<8cZi-Md&91lx4JbmsCg5ud{yCS(MIMXHqRF!}Z(keUlWj^aCF) Bzc>H@ literal 0 HcmV?d00001 diff --git a/test/vfs-run.in b/test/vfs-run.in new file mode 100755 index 0000000..257dc28 --- /dev/null +++ b/test/vfs-run.in @@ -0,0 +1,16 @@ +#! /bin/sh + +# Wrapper for VFS test programs. It makes sure the modules are loaded +# from the build directory instead of the system one. + +GNOME_VFS_MODULE_PATH=@TOP_BUILDDIR@/modules/.libs +export GNOME_VFS_MODULE_PATH + +echo "VFS modules will be loaded from $GNOME_VFS_MODULE_PATH" + +PATH=.:$PATH +export PATH + +exec $@ + +echo "$0: cannot exec "$@ -- 1.8.3.1