(* Tux Commander - UError - Error system functions Copyright (C) 2009 Tomas Bzatek Check for updates on tuxcmd.sourceforge.net 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 *) unit UError; interface uses lazglib2, gtk2, Classes, SysUtils, GTKForms; type TuxcmdErrorEnum = ( TUXCMD_ERROR_CANCELLED, TUXCMD_ERROR_EXCEPTION, TUXCMD_ERROR_NOT_SUPPORTED, // Basic IO TUXCMD_ERROR_CHDIR, TUXCMD_ERROR_OPENDIR, TUXCMD_ERROR_STAT, TUXCMD_ERROR_MKDIR, TUXCMD_ERROR_REMOVE, TUXCMD_ERROR_SYMLINK, TUXCMD_ERROR_CHMOD, TUXCMD_ERROR_CHOWN, TUXCMD_ERROR_RENAME, TUXCMD_ERROR_TIMESTAMPS, // File IO TUXCMD_ERROR_OPEN_FILE, TUXCMD_ERROR_READ_FILE, TUXCMD_ERROR_WRITE_FILE, TUXCMD_ERROR_CLOSE_FILE, TUXCMD_ERROR_SEEK, // File copy TUXCMD_ERROR_ALLOC_FAILED, TUXCMD_ERROR_SOURCE_OPEN, TUXCMD_ERROR_TARGET_OPEN, TUXCMD_ERROR_SOURCE_READ, TUXCMD_ERROR_TARGET_WRITE, TUXCMD_ERROR_SOURCE_CLOSE, TUXCMD_ERROR_TARGET_CLOSE ); // Ported from gioerror.h, glib-2.83.0 type GIOErrorEnum = ( G_IO_ERROR_FAILED, G_IO_ERROR_NOT_FOUND, G_IO_ERROR_EXISTS, G_IO_ERROR_IS_DIRECTORY, G_IO_ERROR_NOT_DIRECTORY, G_IO_ERROR_NOT_EMPTY, G_IO_ERROR_NOT_REGULAR_FILE, G_IO_ERROR_NOT_SYMBOLIC_LINK, G_IO_ERROR_NOT_MOUNTABLE_FILE, G_IO_ERROR_FILENAME_TOO_LONG, G_IO_ERROR_INVALID_FILENAME, G_IO_ERROR_TOO_MANY_LINKS, G_IO_ERROR_NO_SPACE, G_IO_ERROR_INVALID_ARGUMENT, G_IO_ERROR_PERMISSION_DENIED, G_IO_ERROR_NOT_SUPPORTED, G_IO_ERROR_NOT_MOUNTED, G_IO_ERROR_ALREADY_MOUNTED, G_IO_ERROR_CLOSED, G_IO_ERROR_CANCELLED, G_IO_ERROR_PENDING, G_IO_ERROR_READ_ONLY, G_IO_ERROR_CANT_CREATE_BACKUP, G_IO_ERROR_WRONG_ETAG, G_IO_ERROR_TIMED_OUT, G_IO_ERROR_WOULD_RECURSE, G_IO_ERROR_BUSY, G_IO_ERROR_WOULD_BLOCK, G_IO_ERROR_HOST_NOT_FOUND, G_IO_ERROR_WOULD_MERGE, G_IO_ERROR_FAILED_HANDLED, G_IO_ERROR_TOO_MANY_OPEN_FILES, G_IO_ERROR_NOT_INITIALIZED, G_IO_ERROR_ADDRESS_IN_USE, G_IO_ERROR_PARTIAL_INPUT, G_IO_ERROR_INVALID_DATA, G_IO_ERROR_DBUS_ERROR, G_IO_ERROR_HOST_UNREACHABLE, G_IO_ERROR_NETWORK_UNREACHABLE, G_IO_ERROR_CONNECTION_REFUSED, G_IO_ERROR_PROXY_FAILED, G_IO_ERROR_PROXY_AUTH_FAILED, G_IO_ERROR_PROXY_NEED_AUTH, G_IO_ERROR_PROXY_NOT_ALLOWED, G_IO_ERROR_BROKEN_PIPE, // G_IO_ERROR_CONNECTION_CLOSED = G_IO_ERROR_BROKEN_PIPE, G_IO_ERROR_NOT_CONNECTED, G_IO_ERROR_MESSAGE_TOO_LARGE, G_IO_ERROR_NO_SUCH_DEVICE, G_IO_ERROR_DESTINATION_UNSET ); const G_IO_ERROR_CONNECTION_CLOSED = G_IO_ERROR_BROKEN_PIPE; function tuxcmd_error_quark: TGQuark; function TUXCMD_ERROR: TGQuark; function g_io_error_quark: TGQuark; function G_IO_ERROR: TGQuark; function g_io_error_from_errno(err_no: gint): GIOErrorEnum; procedure tuxcmd_set_error_from_exception(Error: PPGError; E: Exception); procedure ShowError(Parent: TCustomGTKForm; const Text: string; Error: PGError); procedure PrefixTuxcmdError(Error: PPGError; const FileName: string); procedure VFSToTuxcmdError(Error: PPGError; Operation: TuxcmdErrorEnum); implementation uses UCoreUtils, UGnome; (********************************************************************************************************************************) function tuxcmd_error_quark: TGQuark; begin Result := g_quark_from_static_string('tuxcmd-error-quark'); end; function TUXCMD_ERROR: TGQuark; begin Result := tuxcmd_error_quark; end; function g_io_error_quark: TGQuark; begin Result := g_quark_from_static_string('g-io-error-quark'); end; function G_IO_ERROR: TGQuark; begin Result := g_io_error_quark; end; function g_io_error_from_errno(err_no: gint): GIOErrorEnum; begin // Prefer native library call Result := g_io_error_from_errno(err_no); (* case err_no of EEXIST: Result := G_IO_ERROR_EXISTS; EISDIR: Result := G_IO_ERROR_IS_DIRECTORY; EACCES: Result := G_IO_ERROR_PERMISSION_DENIED; ENAMETOOLONG: Result := G_IO_ERROR_FILENAME_TOO_LONG; ENOENT: Result := G_IO_ERROR_NOT_FOUND; ENOTDIR: Result := G_IO_ERROR_NOT_DIRECTORY; EROFS: Result := G_IO_ERROR_READ_ONLY; ELOOP: Result := G_IO_ERROR_TOO_MANY_LINKS; ENOSPC: Result := G_IO_ERROR_NO_SPACE; ENOMEM: Result := G_IO_ERROR_NO_SPACE; EINVAL: Result := G_IO_ERROR_INVALID_ARGUMENT; EPERM: Result := G_IO_ERROR_PERMISSION_DENIED; EMLINK: Result := G_IO_ERROR_TOO_MANY_LINKS; ENOMSG: Result := G_IO_ERROR_INVALID_DATA; ENODATA: Result := G_IO_ERROR_INVALID_DATA; EBADMSG: Result := G_IO_ERROR_INVALID_DATA; ECANCELED: Result := G_IO_ERROR_CANCELLED; ENOTEMPTY: Result := G_IO_ERROR_NOT_EMPTY; ENOTSUP: Result := G_IO_ERROR_NOT_SUPPORTED; EPROTONOSUPPORT: Result := G_IO_ERROR_NOT_SUPPORTED; ESOCKTNOSUPPORT: Result := G_IO_ERROR_NOT_SUPPORTED; EPFNOSUPPORT: Result := G_IO_ERROR_NOT_SUPPORTED; EAFNOSUPPORT: Result := G_IO_ERROR_NOT_SUPPORTED; ETIMEDOUT: Result := G_IO_ERROR_TIMED_OUT; EBUSY: Result := G_IO_ERROR_BUSY; EAGAIN: Result := G_IO_ERROR_WOULD_BLOCK; EMFILE: Result := G_IO_ERROR_TOO_MANY_OPEN_FILES; EADDRINUSE: Result := G_IO_ERROR_ADDRESS_IN_USE; EHOSTUNREACH: Result := G_IO_ERROR_HOST_UNREACHABLE; ENETUNREACH: Result := G_IO_ERROR_NETWORK_UNREACHABLE; ENETDOWN: Result := G_IO_ERROR_NETWORK_UNREACHABLE; ECONNREFUSED: Result := G_IO_ERROR_CONNECTION_REFUSED; EADDRNOTAVAIL: Result := G_IO_ERROR_CONNECTION_REFUSED; ECONNRESET: Result := G_IO_ERROR_CONNECTION_CLOSED; ENOTCONN: Result := G_IO_ERROR_NOT_CONNECTED; EDESTADDRREQ: Result := G_IO_ERROR_DESTINATION_UNSET; EMSGSIZE: Result := G_IO_ERROR_MESSAGE_TOO_LARGE; ENOTSOCK: Result := G_IO_ERROR_INVALID_ARGUMENT; else Result := G_IO_ERROR_FAILED; end; *) end; (********************************************************************************************************************************) procedure tuxcmd_set_error_from_exception(Error: PPGError; E: Exception); begin g_set_error(Error, TUXCMD_ERROR, integer(TUXCMD_ERROR_EXCEPTION), 'Exception raised: %s', [PChar(E.Message)]); end; (********************************************************************************************************************************) procedure ShowError(Parent: TCustomGTKForm; const Text: string; Error: PGError); var Dialog: PGtkWidget; error_str: PChar; begin if Error <> nil then error_str := Error^.message else error_str := ''; dialog := gtk_message_dialog_new_with_markup(PGtkWindow(Parent.FWidget), GTK_DIALOG_MODAL or GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, '%s'#10#10'%s', PChar(Text), error_str); gtk_window_set_title(PGtkWindow(dialog), ''); gtk_dialog_run(PGtkDialog(Dialog)); gtk_widget_destroy(PGtkWidget(Dialog)); end; procedure PrefixTuxcmdError(Error: PPGError; const FileName: string); begin if (Error = nil) or (Error^ = nil) then Exit; if ((Error^)^.domain <> TUXCMD_ERROR) then Exit; case TuxcmdErrorEnum((Error^)^.code) of TUXCMD_ERROR_CHDIR: g_prefix_error(Error, 'Error changing directory to ''%s'': ', [StrToUTF8(PChar(FileName))]); TUXCMD_ERROR_OPENDIR: g_prefix_error(Error, 'Error opening directory ''%s'': ', [StrToUTF8(PChar(FileName))]); TUXCMD_ERROR_STAT: g_prefix_error(Error, 'Error getting file info for ''%s'': ', [StrToUTF8(PChar(FileName))]); TUXCMD_ERROR_MKDIR: g_prefix_error(Error, 'Error creating directory ''%s'': ', [StrToUTF8(PChar(FileName))]); TUXCMD_ERROR_REMOVE: g_prefix_error(Error, 'Error deleting ''%s'': ', [StrToUTF8(PChar(FileName))]); TUXCMD_ERROR_SYMLINK: g_prefix_error(Error, 'Error creating symlink ''%s'': ', [StrToUTF8(PChar(FileName))]); TUXCMD_ERROR_CHMOD: g_prefix_error(Error, 'Error changing permissions of ''%s'': ', [StrToUTF8(PChar(FileName))]); TUXCMD_ERROR_CHOWN: g_prefix_error(Error, 'Error changing owner/group of ''%s'': ', [StrToUTF8(PChar(FileName))]); TUXCMD_ERROR_RENAME: g_prefix_error(Error, 'Error renaming file ''%s'': ', [StrToUTF8(PChar(FileName))]); TUXCMD_ERROR_TIMESTAMPS: g_prefix_error(Error, 'Error changing timestamps of ''%s'': ', [StrToUTF8(PChar(FileName))]); TUXCMD_ERROR_OPEN_FILE: g_prefix_error(Error, 'Error opening file ''%s'': ', [StrToUTF8(PChar(FileName))]); TUXCMD_ERROR_READ_FILE: g_prefix_error(Error, 'Error reading file ''%s'': ', [StrToUTF8(PChar(FileName))]); TUXCMD_ERROR_WRITE_FILE: g_prefix_error(Error, 'Error writing file ''%s'': ', [StrToUTF8(PChar(FileName))]); TUXCMD_ERROR_CLOSE_FILE: g_prefix_error(Error, 'Error closing file ''%s'': ', [StrToUTF8(PChar(FileName))]); TUXCMD_ERROR_SEEK: g_prefix_error(Error, 'Error seeking in file ''%s'': ', [StrToUTF8(PChar(FileName))]); end; end; procedure VFSToTuxcmdError(Error: PPGError; Operation: TuxcmdErrorEnum); var OldError: PGError; begin if (Error = nil) or (Error^ = nil) or ((Error^)^.domain <> G_IO_ERROR) then Exit; case GIOErrorEnum((Error^)^.code) of G_IO_ERROR_FAILED, G_IO_ERROR_NOT_FOUND, G_IO_ERROR_EXISTS, G_IO_ERROR_IS_DIRECTORY, G_IO_ERROR_NOT_DIRECTORY, G_IO_ERROR_NOT_EMPTY, G_IO_ERROR_NOT_REGULAR_FILE, G_IO_ERROR_NOT_SYMBOLIC_LINK, G_IO_ERROR_FILENAME_TOO_LONG, G_IO_ERROR_INVALID_FILENAME, G_IO_ERROR_TOO_MANY_LINKS, G_IO_ERROR_NO_SPACE, G_IO_ERROR_INVALID_ARGUMENT, G_IO_ERROR_PERMISSION_DENIED, G_IO_ERROR_NOT_SUPPORTED, // G_IO_ERROR_CLOSED, // G_IO_ERROR_CANCELLED, // G_IO_ERROR_PENDING, G_IO_ERROR_READ_ONLY, G_IO_ERROR_CANT_CREATE_BACKUP, G_IO_ERROR_WOULD_RECURSE, G_IO_ERROR_BUSY, G_IO_ERROR_WOULD_BLOCK, G_IO_ERROR_WOULD_MERGE, // G_IO_ERROR_FAILED_HANDLED, G_IO_ERROR_TOO_MANY_OPEN_FILES, G_IO_ERROR_NOT_INITIALIZED, G_IO_ERROR_PARTIAL_INPUT, G_IO_ERROR_INVALID_DATA, G_IO_ERROR_BROKEN_PIPE, G_IO_ERROR_NO_SUCH_DEVICE: begin OldError := Error^; Error^ := nil; g_set_error(Error, TUXCMD_ERROR, gint(Operation), '%s', [OldError^.message]); g_free (OldError); end; end; end; end.