diff --git a/lib/util.c b/lib/util.c index 2b7576198..2256ac2ae 100644 --- a/lib/util.c +++ b/lib/util.c @@ -1241,6 +1241,7 @@ mc_util_write_backup_content (const char *from_file_name, const char *to_file_na FILE *backup_fd; char *contents; gsize length; + gboolean ret1 = TRUE; if (!g_file_get_contents (from_file_name, &contents, &length, NULL)) return FALSE; @@ -1252,12 +1253,15 @@ mc_util_write_backup_content (const char *from_file_name, const char *to_file_na return FALSE; } - fwrite ((const void *) contents, length, 1, backup_fd); - - fflush (backup_fd); - fclose (backup_fd); + if (fwrite ((const void *) contents, length, 1, backup_fd) != length) + ret1 = FALSE; + { + int ret2; + ret2 = fflush (backup_fd); + ret2 = fclose (backup_fd); + } g_free (contents); - return TRUE; + return ret1; } /* Finds out a relative path from first to second, i.e. goes as many .. diff --git a/lib/utilunix.c b/lib/utilunix.c index 9b71718aa..3bc5de922 100644 --- a/lib/utilunix.c +++ b/lib/utilunix.c @@ -12,7 +12,7 @@ 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 @@ -50,153 +50,169 @@ #include "lib/global.h" #include "src/execute.h" -#include "src/wtools.h" /* message() */ +#include "src/wtools.h" /* message() */ struct sigaction startup_handler; #define UID_CACHE_SIZE 200 #define GID_CACHE_SIZE 30 -typedef struct { - int index; +typedef struct +{ + int index; char *string; } int_cache; -static int_cache uid_cache [UID_CACHE_SIZE]; -static int_cache gid_cache [GID_CACHE_SIZE]; +static int_cache uid_cache[UID_CACHE_SIZE]; +static int_cache gid_cache[GID_CACHE_SIZE]; -static char *i_cache_match (int id, int_cache *cache, int size) +static char * +i_cache_match (int id, int_cache * cache, int size) { int i; for (i = 0; i < size; i++) - if (cache [i].index == id) - return cache [i].string; + if (cache[i].index == id) + return cache[i].string; return 0; } -static void i_cache_add (int id, int_cache *cache, int size, char *text, - int *last) +static void +i_cache_add (int id, int_cache * cache, int size, char *text, int *last) { - g_free (cache [*last].string); - cache [*last].string = g_strdup (text); - cache [*last].index = id; - *last = ((*last)+1) % size; + g_free (cache[*last].string); + cache[*last].string = g_strdup (text); + cache[*last].index = id; + *last = ((*last) + 1) % size; } -char *get_owner (int uid) +char * +get_owner (int uid) { struct passwd *pwd; - static char ibuf [10]; - char *name; + static char ibuf[10]; + char *name; static int uid_last; - + if ((name = i_cache_match (uid, uid_cache, UID_CACHE_SIZE)) != NULL) - return name; - + return name; + pwd = getpwuid (uid); - if (pwd){ - i_cache_add (uid, uid_cache, UID_CACHE_SIZE, pwd->pw_name, &uid_last); - return pwd->pw_name; + if (pwd) + { + i_cache_add (uid, uid_cache, UID_CACHE_SIZE, pwd->pw_name, &uid_last); + return pwd->pw_name; } - else { - g_snprintf (ibuf, sizeof (ibuf), "%d", uid); - return ibuf; + else + { + g_snprintf (ibuf, sizeof (ibuf), "%d", uid); + return ibuf; } } -char *get_group (int gid) +char * +get_group (int gid) { struct group *grp; - static char gbuf [10]; + static char gbuf[10]; char *name; - static int gid_last; - + static int gid_last; + if ((name = i_cache_match (gid, gid_cache, GID_CACHE_SIZE)) != NULL) - return name; - + return name; + grp = getgrgid (gid); - if (grp){ - i_cache_add (gid, gid_cache, GID_CACHE_SIZE, grp->gr_name, &gid_last); - return grp->gr_name; - } else { - g_snprintf (gbuf, sizeof (gbuf), "%d", gid); - return gbuf; + if (grp) + { + i_cache_add (gid, gid_cache, GID_CACHE_SIZE, grp->gr_name, &gid_last); + return grp->gr_name; + } + else + { + g_snprintf (gbuf, sizeof (gbuf), "%d", gid); + return gbuf; } } /* Since ncurses uses a handler that automatically refreshes the */ /* screen after a SIGCONT, and we don't want this behavior when */ /* spawning a child, we save the original handler here */ -void save_stop_handler (void) +void +save_stop_handler (void) { sigaction (SIGTSTP, NULL, &startup_handler); } -int my_system (int flags, const char *shell, const char *command) +int +my_system (int flags, const char *shell, const char *command) { struct sigaction ignore, save_intr, save_quit, save_stop; pid_t pid; int status = 0; - + ignore.sa_handler = SIG_IGN; sigemptyset (&ignore.sa_mask); ignore.sa_flags = 0; - - sigaction (SIGINT, &ignore, &save_intr); + + sigaction (SIGINT, &ignore, &save_intr); sigaction (SIGQUIT, &ignore, &save_quit); /* Restore the original SIGTSTP handler, we don't want ncurses' */ /* handler messing the screen after the SIGCONT */ sigaction (SIGTSTP, &startup_handler, &save_stop); - if ((pid = fork ()) < 0){ - fprintf (stderr, "\n\nfork () = -1\n"); - return -1; + if ((pid = fork ()) < 0) + { + fprintf (stderr, "\n\nfork () = -1\n"); + return -1; } - if (pid == 0){ - signal (SIGINT, SIG_DFL); - signal (SIGQUIT, SIG_DFL); - signal (SIGTSTP, SIG_DFL); - signal (SIGCHLD, SIG_DFL); + if (pid == 0) + { + signal (SIGINT, SIG_DFL); + signal (SIGQUIT, SIG_DFL); + signal (SIGTSTP, SIG_DFL); + signal (SIGCHLD, SIG_DFL); - if (flags & EXECUTE_AS_SHELL) - execl (shell, shell, "-c", command, (char *) NULL); - else - { - gchar **shell_tokens; - const gchar *only_cmd; - shell_tokens = g_strsplit(shell," ", 2); + if (flags & EXECUTE_AS_SHELL) + execl (shell, shell, "-c", command, (char *) NULL); + else + { + gchar **shell_tokens; + const gchar *only_cmd; + shell_tokens = g_strsplit (shell, " ", 2); - if (shell_tokens == NULL) - only_cmd = shell; - else - only_cmd = (*shell_tokens) ? *shell_tokens: shell; + if (shell_tokens == NULL) + only_cmd = shell; + else + only_cmd = (*shell_tokens) ? *shell_tokens : shell; - execlp (only_cmd, shell, command, (char *) NULL); + execlp (only_cmd, shell, command, (char *) NULL); - /* - execlp will replace current process, - therefore no sence in call of g_strfreev(). - But this keeped for estetic reason :) - */ - g_strfreev(shell_tokens); + /* + execlp will replace current process, + therefore no sence in call of g_strfreev(). + But this keeped for estetic reason :) + */ + g_strfreev (shell_tokens); - } + } - _exit (127); /* Exec error */ - } else { - while (waitpid (pid, &status, 0) < 0) - if (errno != EINTR){ - status = -1; - break; - } + _exit (127); /* Exec error */ } - sigaction (SIGINT, &save_intr, NULL); + else + { + while (waitpid (pid, &status, 0) < 0) + if (errno != EINTR) + { + status = -1; + break; + } + } + sigaction (SIGINT, &save_intr, NULL); sigaction (SIGQUIT, &save_quit, NULL); sigaction (SIGTSTP, &save_stop, NULL); - return WEXITSTATUS(status); + return WEXITSTATUS (status); } @@ -212,29 +228,35 @@ tilde_expand (const char *directory) char *name; if (*directory != '~') - return g_strdup (directory); + return g_strdup (directory); p = directory + 1; /* d = "~" or d = "~/" */ - if (!(*p) || (*p == PATH_SEP)) { - passwd = getpwuid (geteuid ()); - q = (*p == PATH_SEP) ? p + 1 : ""; - } else { - q = strchr (p, PATH_SEP); - if (!q) { - passwd = getpwnam (p); - } else { - name = g_strndup (p, q - p); - passwd = getpwnam (name); - q++; - g_free (name); - } + if (!(*p) || (*p == PATH_SEP)) + { + passwd = getpwuid (geteuid ()); + q = (*p == PATH_SEP) ? p + 1 : ""; + } + else + { + q = strchr (p, PATH_SEP); + if (!q) + { + passwd = getpwnam (p); + } + else + { + name = g_strndup (p, q - p); + passwd = getpwnam (name); + q++; + g_free (name); + } } /* If we can't figure the user name, leave tilde unexpanded */ if (!passwd) - return g_strdup (directory); + return g_strdup (directory); return g_strconcat (passwd->pw_dir, PATH_SEP_STR, q, (char *) NULL); } @@ -258,84 +280,91 @@ mc_tmpdir (void) /* Check if already correctly initialized */ if (tmpdir && lstat (tmpdir, &st) == 0 && S_ISDIR (st.st_mode) && - st.st_uid == getuid () && (st.st_mode & 0777) == 0700) - return tmpdir; + st.st_uid == getuid () && (st.st_mode & 0777) == 0700) + return tmpdir; sys_tmp = getenv ("TMPDIR"); - if (!sys_tmp || sys_tmp[0] != '/') { - sys_tmp = TMPDIR_DEFAULT; + if (!sys_tmp || sys_tmp[0] != '/') + { + sys_tmp = TMPDIR_DEFAULT; } pwd = getpwuid (getuid ()); if (pwd) - g_snprintf (buffer, sizeof (buffer), "%s/mc-%s", sys_tmp, - pwd->pw_name); + g_snprintf (buffer, sizeof (buffer), "%s/mc-%s", sys_tmp, pwd->pw_name); else - g_snprintf (buffer, sizeof (buffer), "%s/mc-%lu", sys_tmp, - (unsigned long) getuid ()); + g_snprintf (buffer, sizeof (buffer), "%s/mc-%lu", sys_tmp, (unsigned long) getuid ()); canonicalize_pathname (buffer); - if (lstat (buffer, &st) == 0) { - /* Sanity check for existing directory */ - if (!S_ISDIR (st.st_mode)) - error = _("%s is not a directory\n"); - else if (st.st_uid != getuid ()) - error = _("Directory %s is not owned by you\n"); - else if (((st.st_mode & 0777) != 0700) - && (chmod (buffer, 0700) != 0)) - error = _("Cannot set correct permissions for directory %s\n"); - } else { - /* Need to create directory */ - if (mkdir (buffer, S_IRWXU) != 0) { - fprintf (stderr, - _("Cannot create temporary directory %s: %s\n"), - buffer, unix_error_string (errno)); - error = ""; - } + if (lstat (buffer, &st) == 0) + { + /* Sanity check for existing directory */ + if (!S_ISDIR (st.st_mode)) + error = _("%s is not a directory\n"); + else if (st.st_uid != getuid ()) + error = _("Directory %s is not owned by you\n"); + else if (((st.st_mode & 0777) != 0700) && (chmod (buffer, 0700) != 0)) + error = _("Cannot set correct permissions for directory %s\n"); + } + else + { + /* Need to create directory */ + if (mkdir (buffer, S_IRWXU) != 0) + { + fprintf (stderr, + _("Cannot create temporary directory %s: %s\n"), + buffer, unix_error_string (errno)); + error = ""; + } } - if (error != NULL) { - int test_fd; - char *test_fn, *fallback_prefix; - int fallback_ok = 0; + if (error != NULL) + { + int test_fd; + char *test_fn, *fallback_prefix; + int fallback_ok = 0; - if (*error) - fprintf (stderr, error, buffer); + if (*error) + fprintf (stderr, error, buffer); - /* Test if sys_tmp is suitable for temporary files */ - fallback_prefix = g_strdup_printf ("%s/mctest", sys_tmp); - test_fd = mc_mkstemps (&test_fn, fallback_prefix, NULL); - g_free (fallback_prefix); - if (test_fd != -1) { - close (test_fd); - test_fd = open (test_fn, O_RDONLY); - if (test_fd != -1) { - close (test_fd); - unlink (test_fn); - fallback_ok = 1; - } - } + /* Test if sys_tmp is suitable for temporary files */ + fallback_prefix = g_strdup_printf ("%s/mctest", sys_tmp); + test_fd = mc_mkstemps (&test_fn, fallback_prefix, NULL); + g_free (fallback_prefix); + if (test_fd != -1) + { + close (test_fd); + test_fd = open (test_fn, O_RDONLY); + if (test_fd != -1) + { + close (test_fd); + unlink (test_fn); + fallback_ok = 1; + } + } - if (fallback_ok) { - fprintf (stderr, _("Temporary files will be created in %s\n"), - sys_tmp); - g_snprintf (buffer, sizeof (buffer), "%s", sys_tmp); - error = NULL; - } else { - fprintf (stderr, _("Temporary files will not be created\n")); - g_snprintf (buffer, sizeof (buffer), "%s", "/dev/null/"); - } + if (fallback_ok) + { + fprintf (stderr, _("Temporary files will be created in %s\n"), sys_tmp); + g_snprintf (buffer, sizeof (buffer), "%s", sys_tmp); + error = NULL; + } + else + { + fprintf (stderr, _("Temporary files will not be created\n")); + g_snprintf (buffer, sizeof (buffer), "%s", "/dev/null/"); + } - fprintf (stderr, "%s\n", _("Press any key to continue...")); - getc (stdin); + fprintf (stderr, "%s\n", _("Press any key to continue...")); + getc (stdin); } tmpdir = buffer; if (!error) - g_setenv ("MC_TMPDIR", tmpdir, TRUE); + g_setenv ("MC_TMPDIR", tmpdir, TRUE); return tmpdir; } @@ -345,23 +374,26 @@ mc_tmpdir (void) /* More than that would be unportable */ #define MAX_PIPE_SIZE 4096 -static int error_pipe[2]; /* File descriptors of error pipe */ -static int old_error; /* File descriptor of old standard error */ +static int error_pipe[2]; /* File descriptors of error pipe */ +static int old_error; /* File descriptor of old standard error */ /* Creates a pipe to hold standard error for a later analysis. */ /* The pipe can hold 4096 bytes. Make sure no more is written */ /* or a deadlock might occur. */ -void open_error_pipe (void) +void +open_error_pipe (void) { - if (pipe (error_pipe) < 0){ - message (D_NORMAL, _("Warning"), _(" Pipe failed ")); + if (pipe (error_pipe) < 0) + { + message (D_NORMAL, _("Warning"), _(" Pipe failed ")); } old_error = dup (2); - if(old_error < 0 || close(2) || dup (error_pipe[1]) != 2){ - message (D_NORMAL, _("Warning"), _(" Dup failed ")); + if (old_error < 0 || close (2) || dup (error_pipe[1]) != 2) + { + message (D_NORMAL, _("Warning"), _(" Dup failed ")); - close (error_pipe[0]); - error_pipe[0] = -1; + close (error_pipe[0]); + error_pipe[0] = -1; } else { @@ -378,7 +410,7 @@ void open_error_pipe (void) if (fd_flags != -1) { fd_flags |= O_NONBLOCK; - if (fcntl(error_pipe[0], F_SETFL, fd_flags) == -1) + if (fcntl (error_pipe[0], F_SETFL, fd_flags) == -1) { /* TODO: handle it somehow */ } @@ -403,34 +435,41 @@ close_error_pipe (int error, const char *text) /* already closed */ if (error_pipe[0] == -1) - return 0; + return 0; if (error) - title = MSG_ERROR; + title = MSG_ERROR; else - title = _("Warning"); - if (old_error >= 0){ - close (2); - dup (old_error); - close (old_error); - len = read (error_pipe[0], msg, MAX_PIPE_SIZE - 1); + title = _("Warning"); + if (old_error >= 0) + { + if (dup2 (old_error, 2)) + { + message (error, MSG_ERROR, "%s", _("Error dup'ing old error pipe")); + return 1; + } + close (old_error); + len = read (error_pipe[0], msg, MAX_PIPE_SIZE - 1); - if (len >= 0) - msg[len] = 0; - close (error_pipe[0]); - error_pipe[0] = -1; + if (len >= 0) + msg[len] = 0; + close (error_pipe[0]); + error_pipe[0] = -1; } if (error < 0) - return 0; /* Just ignore error message */ - if (text == NULL){ - if (len <= 0) - return 0; /* Nothing to show */ + return 0; /* Just ignore error message */ + if (text == NULL) + { + if (len <= 0) + return 0; /* Nothing to show */ - /* Show message from pipe */ - message (error, title, "%s", msg); - } else { - /* Show given text and possible message from pipe */ - message (error, title, " %s \n %s ", text, msg); + /* Show message from pipe */ + message (error, title, "%s", msg); + } + else + { + /* Show given text and possible message from pipe */ + message (error, title, " %s \n %s ", text, msg); } return 1; } @@ -438,11 +477,11 @@ close_error_pipe (int error, const char *text) /* * Canonicalize path, and return a new path. Do everything in place. * The new path differs from path in: - * Multiple `/'s are collapsed to a single `/'. - * Leading `./'s and trailing `/.'s are removed. - * Trailing `/'s are removed. - * Non-leading `../'s and trailing `..'s are handled by removing - * portions of the path. + * Multiple `/'s are collapsed to a single `/'. + * Leading `./'s and trailing `/.'s are removed. + * Trailing `/'s are removed. + * Non-leading `../'s and trailing `..'s are handled by removing + * portions of the path. * Well formed UNC paths are modified only in the local part. */ void @@ -450,131 +489,160 @@ custom_canonicalize_pathname (char *path, CANON_PATH_FLAGS flags) { char *p, *s; int len; - char *lpath = path; /* path without leading UNC part */ + char *lpath = path; /* path without leading UNC part */ /* Detect and preserve UNC paths: //server/... */ - if ( ( flags & CANON_PATH_GUARDUNC ) && path[0] == PATH_SEP && path[1] == PATH_SEP) { - p = path + 2; - while (p[0] && p[0] != '/') - p++; - if (p[0] == '/' && p > path + 2) - lpath = p; + if ((flags & CANON_PATH_GUARDUNC) && path[0] == PATH_SEP && path[1] == PATH_SEP) + { + p = path + 2; + while (p[0] && p[0] != '/') + p++; + if (p[0] == '/' && p > path + 2) + lpath = p; } if (!lpath[0] || !lpath[1]) - return; + return; - if ( flags & CANON_PATH_JOINSLASHES ) { - /* Collapse multiple slashes */ - p = lpath; - while (*p) { - if (p[0] == PATH_SEP && p[1] == PATH_SEP) { - s = p + 1; - while (*(++s) == PATH_SEP); - str_move (p + 1, s); - } - p++; - } + if (flags & CANON_PATH_JOINSLASHES) + { + /* Collapse multiple slashes */ + p = lpath; + while (*p) + { + if (p[0] == PATH_SEP && p[1] == PATH_SEP) + { + s = p + 1; + while (*(++s) == PATH_SEP); + str_move (p + 1, s); + } + p++; + } } - if ( flags & CANON_PATH_JOINSLASHES ) { - /* Collapse "/./" -> "/" */ - p = lpath; - while (*p) { - if (p[0] == PATH_SEP && p[1] == '.' && p[2] == PATH_SEP) - str_move (p, p + 2); - else - p++; - } + if (flags & CANON_PATH_JOINSLASHES) + { + /* Collapse "/./" -> "/" */ + p = lpath; + while (*p) + { + if (p[0] == PATH_SEP && p[1] == '.' && p[2] == PATH_SEP) + str_move (p, p + 2); + else + p++; + } } - if ( flags & CANON_PATH_REMSLASHDOTS ) { - /* Remove trailing slashes */ - p = lpath + strlen (lpath) - 1; - while (p > lpath && *p == PATH_SEP) - *p-- = 0; + if (flags & CANON_PATH_REMSLASHDOTS) + { + /* Remove trailing slashes */ + p = lpath + strlen (lpath) - 1; + while (p > lpath && *p == PATH_SEP) + *p-- = 0; - /* Remove leading "./" */ - if (lpath[0] == '.' && lpath[1] == PATH_SEP) { - if (lpath[2] == 0) { - lpath[1] = 0; - return; - } else { - str_move (lpath, lpath + 2); - } - } + /* Remove leading "./" */ + if (lpath[0] == '.' && lpath[1] == PATH_SEP) + { + if (lpath[2] == 0) + { + lpath[1] = 0; + return; + } + else + { + str_move (lpath, lpath + 2); + } + } - /* Remove trailing "/" or "/." */ - len = strlen (lpath); - if (len < 2) - return; - if (lpath[len - 1] == PATH_SEP) { - lpath[len - 1] = 0; - } else { - if (lpath[len - 1] == '.' && lpath[len - 2] == PATH_SEP) { - if (len == 2) { - lpath[1] = 0; - return; - } else { - lpath[len - 2] = 0; - } - } - } + /* Remove trailing "/" or "/." */ + len = strlen (lpath); + if (len < 2) + return; + if (lpath[len - 1] == PATH_SEP) + { + lpath[len - 1] = 0; + } + else + { + if (lpath[len - 1] == '.' && lpath[len - 2] == PATH_SEP) + { + if (len == 2) + { + lpath[1] = 0; + return; + } + else + { + lpath[len - 2] = 0; + } + } + } } - if ( flags & CANON_PATH_REMDOUBLEDOTS ) { - /* Collapse "/.." with the previous part of path */ - p = lpath; - while (p[0] && p[1] && p[2]) { - if ((p[0] != PATH_SEP || p[1] != '.' || p[2] != '.') - || (p[3] != PATH_SEP && p[3] != 0)) { - p++; - continue; - } + if (flags & CANON_PATH_REMDOUBLEDOTS) + { + /* Collapse "/.." with the previous part of path */ + p = lpath; + while (p[0] && p[1] && p[2]) + { + if ((p[0] != PATH_SEP || p[1] != '.' || p[2] != '.') || (p[3] != PATH_SEP && p[3] != 0)) + { + p++; + continue; + } - /* search for the previous token */ - s = p - 1; - while (s >= lpath && *s != PATH_SEP) - s--; + /* search for the previous token */ + s = p - 1; + while (s >= lpath && *s != PATH_SEP) + s--; - s++; + s++; - /* If the previous token is "..", we cannot collapse it */ - if (s[0] == '.' && s[1] == '.' && s + 2 == p) { - p += 3; - continue; - } + /* If the previous token is "..", we cannot collapse it */ + if (s[0] == '.' && s[1] == '.' && s + 2 == p) + { + p += 3; + continue; + } - if (p[3] != 0) { - if (s == lpath && *s == PATH_SEP) { - /* "/../foo" -> "/foo" */ - str_move (s + 1, p + 4); - } else { - /* "token/../foo" -> "foo" */ - str_move (s, p + 4); - } - p = (s > lpath) ? s - 1 : s; - continue; - } + if (p[3] != 0) + { + if (s == lpath && *s == PATH_SEP) + { + /* "/../foo" -> "/foo" */ + str_move (s + 1, p + 4); + } + else + { + /* "token/../foo" -> "foo" */ + str_move (s, p + 4); + } + p = (s > lpath) ? s - 1 : s; + continue; + } - /* trailing ".." */ - if (s == lpath) { - /* "token/.." -> "." */ - if (lpath[0] != PATH_SEP) { - lpath[0] = '.'; - } - lpath[1] = 0; - } else { - /* "foo/token/.." -> "foo" */ - if (s == lpath + 1) - s[0] = 0; - else - s[-1] = 0; - break; - } + /* trailing ".." */ + if (s == lpath) + { + /* "token/.." -> "." */ + if (lpath[0] != PATH_SEP) + { + lpath[0] = '.'; + } + lpath[1] = 0; + } + else + { + /* "foo/token/.." -> "foo" */ + if (s == lpath + 1) + s[0] = 0; + else + s[-1] = 0; + break; + } - break; - } + break; + } } } @@ -587,9 +655,10 @@ canonicalize_pathname (char *path) #ifdef HAVE_GET_PROCESS_STATS # include -int gettimeofday (struct timeval *tp, void *tzp) +int +gettimeofday (struct timeval *tp, void *tzp) { - return get_process_stats(tp, PS_SELF, 0, 0); + return get_process_stats (tp, PS_SELF, 0, 0); } #endif /* HAVE_GET_PROCESS_STATS */ @@ -608,149 +677,178 @@ mc_realpath (const char *path, char resolved_path[]) int n; /* Make a copy of the source path since we may need to modify it. */ - if (strlen (path) >= PATH_MAX - 2) { - errno = ENAMETOOLONG; - return NULL; + if (strlen (path) >= PATH_MAX - 2) + { + errno = ENAMETOOLONG; + return NULL; } strcpy (copy_path, path); path = copy_path; max_path = copy_path + PATH_MAX - 2; /* If it's a relative pathname use getwd for starters. */ - if (*path != '/') { - /* Ohoo... */ -#ifdef HAVE_GETCWD - getcwd (new_path, PATH_MAX - 1); -#else - getwd (new_path); -#endif - new_path += strlen (new_path); - if (new_path[-1] != '/') - *new_path++ = '/'; - } else { - *new_path++ = '/'; - path++; + if (*path != '/') + { + + new_path = g_get_current_dir (); + if (new_path == NULL) + { + strcpy (got_path, ""); + } + else + { + g_snprintf (got_path, PATH_MAX, "%s", new_path); + g_free (new_path); + new_path = got_path; + } + + new_path += strlen (got_path); + if (new_path[-1] != '/') + *new_path++ = '/'; + } + else + { + *new_path++ = '/'; + path++; } /* Expand each slash-separated pathname component. */ - while (*path != '\0') { - /* Ignore stray "/". */ - if (*path == '/') { - path++; - continue; - } - if (*path == '.') { - /* Ignore ".". */ - if (path[1] == '\0' || path[1] == '/') { - path++; - continue; - } - if (path[1] == '.') { - if (path[2] == '\0' || path[2] == '/') { - path += 2; - /* Ignore ".." at root. */ - if (new_path == got_path + 1) - continue; - /* Handle ".." by backing up. */ - while ((--new_path)[-1] != '/'); - continue; - } - } - } - /* Safely copy the next pathname component. */ - while (*path != '\0' && *path != '/') { - if (path > max_path) { - errno = ENAMETOOLONG; - return NULL; - } - *new_path++ = *path++; - } + while (*path != '\0') + { + /* Ignore stray "/". */ + if (*path == '/') + { + path++; + continue; + } + if (*path == '.') + { + /* Ignore ".". */ + if (path[1] == '\0' || path[1] == '/') + { + path++; + continue; + } + if (path[1] == '.') + { + if (path[2] == '\0' || path[2] == '/') + { + path += 2; + /* Ignore ".." at root. */ + if (new_path == got_path + 1) + continue; + /* Handle ".." by backing up. */ + while ((--new_path)[-1] != '/'); + continue; + } + } + } + /* Safely copy the next pathname component. */ + while (*path != '\0' && *path != '/') + { + if (path > max_path) + { + errno = ENAMETOOLONG; + return NULL; + } + *new_path++ = *path++; + } #ifdef S_IFLNK - /* Protect against infinite loops. */ - if (readlinks++ > MAXSYMLINKS) { - errno = ELOOP; - return NULL; - } - /* See if latest pathname component is a symlink. */ - *new_path = '\0'; - n = readlink (got_path, link_path, PATH_MAX - 1); - if (n < 0) { - /* EINVAL means the file exists but isn't a symlink. */ - if (errno != EINVAL) { - /* Make sure it's null terminated. */ - *new_path = '\0'; - strcpy (resolved_path, got_path); - return NULL; - } - } else { - /* Note: readlink doesn't add the null byte. */ - link_path[n] = '\0'; - if (*link_path == '/') - /* Start over for an absolute symlink. */ - new_path = got_path; - else - /* Otherwise back up over this component. */ - while (*(--new_path) != '/'); - /* Safe sex check. */ - if (strlen (path) + n >= PATH_MAX - 2) { - errno = ENAMETOOLONG; - return NULL; - } - /* Insert symlink contents into path. */ - strcat (link_path, path); - strcpy (copy_path, link_path); - path = copy_path; - } -#endif /* S_IFLNK */ - *new_path++ = '/'; + /* Protect against infinite loops. */ + if (readlinks++ > MAXSYMLINKS) + { + errno = ELOOP; + return NULL; + } + /* See if latest pathname component is a symlink. */ + *new_path = '\0'; + n = readlink (got_path, link_path, PATH_MAX - 1); + if (n < 0) + { + /* EINVAL means the file exists but isn't a symlink. */ + if (errno != EINVAL) + { + /* Make sure it's null terminated. */ + *new_path = '\0'; + strcpy (resolved_path, got_path); + return NULL; + } + } + else + { + /* Note: readlink doesn't add the null byte. */ + link_path[n] = '\0'; + if (*link_path == '/') + /* Start over for an absolute symlink. */ + new_path = got_path; + else + /* Otherwise back up over this component. */ + while (*(--new_path) != '/'); + /* Safe sex check. */ + if (strlen (path) + n >= PATH_MAX - 2) + { + errno = ENAMETOOLONG; + return NULL; + } + /* Insert symlink contents into path. */ + strcat (link_path, path); + strcpy (copy_path, link_path); + path = copy_path; + } +#endif /* S_IFLNK */ + *new_path++ = '/'; } /* Delete trailing slash but don't whomp a lone slash. */ if (new_path != got_path + 1 && new_path[-1] == '/') - new_path--; + new_path--; /* Make sure it's null terminated. */ *new_path = '\0'; strcpy (resolved_path, got_path); return resolved_path; -#endif /* USE_SYSTEM_REALPATH */ +#endif /* USE_SYSTEM_REALPATH */ } /* Return the index of the permissions triplet */ int -get_user_permissions (struct stat *st) { +get_user_permissions (struct stat *st) +{ static gboolean initialized = FALSE; static gid_t *groups; static int ngroups; static uid_t uid; int i; - if (!initialized) { - uid = geteuid (); + if (!initialized) + { + uid = geteuid (); - ngroups = getgroups (0, NULL); - if (ngroups == -1) - ngroups = 0; /* ignore errors */ + ngroups = getgroups (0, NULL); + if (ngroups == -1) + ngroups = 0; /* ignore errors */ - /* allocate space for one element in addition to what - * will be filled by getgroups(). */ - groups = g_new (gid_t, ngroups + 1); + /* allocate space for one element in addition to what + * will be filled by getgroups(). */ + groups = g_new (gid_t, ngroups + 1); - if (ngroups != 0) { - ngroups = getgroups (ngroups, groups); - if (ngroups == -1) - ngroups = 0; /* ignore errors */ - } + if (ngroups != 0) + { + ngroups = getgroups (ngroups, groups); + if (ngroups == -1) + ngroups = 0; /* ignore errors */ + } - /* getgroups() may or may not return the effective group ID, - * so we always include it at the end of the list. */ - groups[ngroups++] = getegid (); + /* getgroups() may or may not return the effective group ID, + * so we always include it at the end of the list. */ + groups[ngroups++] = getegid (); - initialized = TRUE; + initialized = TRUE; } if (st->st_uid == uid || uid == 0) - return 0; + return 0; - for (i = 0; i < ngroups; i++) { - if (st->st_gid == groups[i]) - return 1; + for (i = 0; i < ngroups; i++) + { + if (st->st_gid == groups[i]) + return 1; } return 2; diff --git a/lib/vfs/mc-vfs/direntry.c b/lib/vfs/mc-vfs/direntry.c index 4e6a13340..7de3f7612 100644 --- a/lib/vfs/mc-vfs/direntry.c +++ b/lib/vfs/mc-vfs/direntry.c @@ -1261,8 +1261,10 @@ vfs_s_get_line (struct vfs_class *me, int sock, char *buf, int buf_len, char ter return 0; if (logfile) { - fwrite (buf, 1, 1, logfile); - fflush (logfile); + size_t ret1; + int ret2; + ret1 = fwrite (buf, 1, 1, logfile); + ret2 = fflush (logfile); } if (*buf == term) { @@ -1277,8 +1279,10 @@ vfs_s_get_line (struct vfs_class *me, int sock, char *buf, int buf_len, char ter { if (logfile) { - fwrite (&c, 1, 1, logfile); - fflush (logfile); + size_t ret1; + int ret2; + ret1 = fwrite (&c, 1, 1, logfile); + ret2 = fflush (logfile); } if (c == '\n') return 1; diff --git a/lib/vfs/mc-vfs/extfs.c b/lib/vfs/mc-vfs/extfs.c index ea8c9bc15..73a59ae2f 100644 --- a/lib/vfs/mc-vfs/extfs.c +++ b/lib/vfs/mc-vfs/extfs.c @@ -597,8 +597,7 @@ extfs_which (struct vfs_class *me, const char *path) info = &g_array_index (extfs_plugins, extfs_plugin_info_t, i); if ((strncmp (path, info->prefix, path_len) == 0) - && ((info->prefix[path_len] == '\0') - || (info->prefix[path_len] == '+'))) + && ((info->prefix[path_len] == '\0') || (info->prefix[path_len] == '+'))) return i; } return -1; @@ -706,7 +705,7 @@ extfs_resolve_symlinks_int (struct entry *entry, GSList * list) looping = g_slist_prepend (list, entry); pent = extfs_find_entry_int (entry->dir, entry->inode->linkname, looping, FALSE, FALSE); - g_slist_delete_link (looping, looping); + looping = g_slist_delete_link (looping, looping); if (pent == NULL) my_errno = ENOENT; diff --git a/lib/vfs/mc-vfs/fish.c b/lib/vfs/mc-vfs/fish.c index 966317f30..707e79820 100644 --- a/lib/vfs/mc-vfs/fish.c +++ b/lib/vfs/mc-vfs/fish.c @@ -159,8 +159,9 @@ fish_command (struct vfs_class *me, struct vfs_s_super *super, int wait_reply, c if (logfile) { - fwrite (str, strlen (str), 1, logfile); - fflush (logfile); + size_t ret; + ret = fwrite (str, strlen (str), 1, logfile); + ret = fflush (logfile); } tty_enable_interrupt_key (); @@ -217,15 +218,13 @@ fish_pipeopen (struct vfs_s_super *super, const char *path, const char *argv[]) } else { - close (0); - dup (fileset1[0]); + res = dup2 (fileset1[0], 0); close (fileset1[0]); close (fileset1[1]); - close (1); + res = dup2 (fileset2[1], 1); close (2); - dup (fileset2[1]); /* stderr to /dev/null */ - open ("/dev/null", O_WRONLY); + res = open ("/dev/null", O_WRONLY); close (fileset2[0]); close (fileset2[1]); execvp (path, const_cast (char **, argv)); @@ -294,7 +293,6 @@ fish_open_archive_int (struct vfs_class *me, struct vfs_s_super *super) print_vfs_message ("%s", answer); if (strstr (answer, "assword")) { - /* Currently, this does not work. ssh reads passwords from /dev/tty, not from stdin :-(. */ @@ -312,8 +310,16 @@ fish_open_archive_int (struct vfs_class *me, struct vfs_s_super *super) SUP.password = op; } print_vfs_message (_("fish: Sending password...")); - write (SUP.sockw, SUP.password, strlen (SUP.password)); - write (SUP.sockw, "\n", 1); + + { + size_t str_len; + str_len = strlen (SUP.password); + if ((write (SUP.sockw, SUP.password, str_len) != (ssize_t) str_len) + || (write (SUP.sockw, "\n", 1) != 1)) + { + ERRNOR (EIO, -1); + } + } } } @@ -757,6 +763,7 @@ fish_file_store (struct vfs_class *me, struct vfs_s_fh *fh, char *name, char *lo /* FIXME: File size is limited to ULONG_MAX */ if (!fh->u.fish.append) + { /* *INDENT-OFF* */ n = fish_command (me, super, WAIT_REPLY, "#STOR %lu /%s\n" @@ -781,7 +788,9 @@ fish_file_store (struct vfs_class *me, struct vfs_s_fh *fh, char *name, char *lo (unsigned long) s.st_size, quoted_name, quoted_name, (unsigned long) s.st_size, (unsigned long) s.st_size); /* *INDENT-ON* */ + } else + { /* *INDENT-OFF* */ n = fish_command (me, super, WAIT_REPLY, "#STOR %lu /%s\n" @@ -799,7 +808,7 @@ fish_file_store (struct vfs_class *me, struct vfs_s_fh *fh, char *name, char *lo (unsigned long) s.st_size, quoted_name, quoted_name, (unsigned long) s.st_size); /* *INDENT-ON* */ - + } if (n != PRELIM) { close (h); @@ -1024,8 +1033,8 @@ fish_send_command (struct vfs_class *me, struct vfs_s_super *super, const char * static int fish_chmod (struct vfs_class *me, const char *path, int mode) { - PREFIX /* *INDENT-OFF* */ + PREFIX g_snprintf (buf, sizeof (buf), "#CHMOD %4.4o /%s\n" "if chmod %4.4o /%s 2>/dev/null; then\n" @@ -1034,10 +1043,11 @@ fish_chmod (struct vfs_class *me, const char *path, int mode) "echo '### 500'\n" "fi\n", mode & 07777, rpath, mode & 07777, rpath); - /* *INDENT-ON* */ POSTFIX (OPT_FLUSH); + /* *INDENT-ON* */ } +/* *INDENT-OFF* */ #define FISH_OP(name, string) \ static int fish_##name (struct vfs_class *me, const char *path1, const char *path2) \ { \ @@ -1066,7 +1076,6 @@ static int fish_##name (struct vfs_class *me, const char *path1, const char *pat return fish_send_command(me, super2, buf, OPT_FLUSH); \ } -/* *INDENT-OFF* */ FISH_OP (rename, "#RENAME /%s /%s\n" "if mv /%s /%s 2>/dev/null; then\n" @@ -1119,8 +1128,8 @@ fish_chown (struct vfs_class *me, const char *path, int owner, int group) sowner = pw->pw_name; sgroup = gr->gr_name; { - PREFIX /* *INDENT-OFF* */ + PREFIX g_snprintf (buf, sizeof (buf), "#CHOWN %s:%s /%s\n" "if chown %s:%s /%s 2>/dev/null; then\n" @@ -1139,9 +1148,9 @@ fish_chown (struct vfs_class *me, const char *path, int owner, int group) static int fish_unlink (struct vfs_class *me, const char *path) { + /* *INDENT-OFF* */ PREFIX - /* *INDENT-OFF* */ g_snprintf (buf, sizeof (buf), "#DELE /%s\n" "if rm -f /%s 2>/dev/null; then\n" @@ -1158,9 +1167,9 @@ fish_unlink (struct vfs_class *me, const char *path) static int fish_exists (struct vfs_class *me, const char *path) { + /* *INDENT-OFF* */ PREFIX - /* *INDENT-OFF* */ g_snprintf (buf, sizeof (buf), "#ISEXISTS /%s\n" "ls -l /%s >/dev/null 2>/dev/null\n" @@ -1182,9 +1191,9 @@ fish_mkdir (struct vfs_class *me, const char *path, mode_t mode) { int ret_code; + /* *INDENT-OFF* */ PREFIX (void) mode; - /* *INDENT-OFF* */ g_snprintf (buf, sizeof (buf), "#MKD /%s\n" "if mkdir /%s 2>/dev/null; then\n" @@ -1211,8 +1220,8 @@ fish_mkdir (struct vfs_class *me, const char *path, mode_t mode) static int fish_rmdir (struct vfs_class *me, const char *path) { - PREFIX /* *INDENT-OFF* */ + PREFIX g_snprintf (buf, sizeof (buf), "#RMD /%s\n" "if rmdir /%s 2>/dev/null; then\n" diff --git a/lib/vfs/mc-vfs/ftpfs.c b/lib/vfs/mc-vfs/ftpfs.c index 93bfab624..1b355bfb4 100644 --- a/lib/vfs/mc-vfs/ftpfs.c +++ b/lib/vfs/mc-vfs/ftpfs.c @@ -1,18 +1,18 @@ /* Virtual File System: FTP file system. Copyright (C) 1995, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. - + Written by: 1995 Ching Hui - 1995 Jakub Jelinek - 1995, 1996, 1997 Miguel de Icaza - 1997 Norbert Warmuth - 1998 Pavel Machek + 1995 Jakub Jelinek + 1995, 1996, 1997 Miguel de Icaza + 1997 Norbert Warmuth + 1998 Pavel Machek This program 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 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 @@ -67,11 +67,11 @@ What to do with this? /* \todo Fix: Namespace pollution: horrible */ #include -#include /* atoi() */ +#include /* atoi() */ #include /* POSIX-required by sys/socket.h and netdb.h */ -#include /* struct hostent */ -#include /* AF_INET */ -#include /* struct in_addr */ +#include /* struct hostent */ +#include /* AF_INET */ +#include /* struct in_addr */ #ifdef HAVE_ARPA_INET_H #include #endif @@ -81,23 +81,23 @@ What to do with this? #include #include #include -#include /* gettimeofday() */ +#include /* gettimeofday() */ #include "lib/global.h" -#include "lib/tty/tty.h" /* enable/disable interrupt key */ +#include "lib/tty/tty.h" /* enable/disable interrupt key */ -#include "src/wtools.h" /* message() */ -#include "src/main.h" /* print_vfs_message */ +#include "src/wtools.h" /* message() */ +#include "src/main.h" /* print_vfs_message */ #include "src/history.h" -#include "src/setup.h" /* for load_anon_passwd */ +#include "src/setup.h" /* for load_anon_passwd */ #include "lib/mcconfig.h" #include "utilvfs.h" #include "xdirentry.h" #include "vfs.h" #include "vfs-impl.h" -#include "gc.h" /* vfs_stamp_create */ +#include "gc.h" /* vfs_stamp_create */ #include "netutil.h" #include "ftpfs.h" #ifndef MAXHOSTNAMELEN @@ -166,7 +166,7 @@ static struct linklist *connections_list; #define NONE 0x00 #define WAIT_REPLY 0x01 #define WANT_STRING 0x02 -static char reply_str [80]; +static char reply_str[80]; static struct vfs_class vfs_ftpfs_ops; @@ -176,7 +176,7 @@ static struct vfs_class vfs_ftpfs_ops; transfered to the remote server has to be mangled by this function right prior to sending it. Currently only Amiga ftp servers are handled in a special manner. - + When the remote server is an amiga: a) strip leading slash if necesarry b) replace first occurance of ":/" with ":" @@ -184,48 +184,52 @@ static struct vfs_class vfs_ftpfs_ops; */ static char *ftpfs_get_current_directory (struct vfs_class *me, struct vfs_s_super *super); -static int ftpfs_chdir_internal (struct vfs_class *me, struct vfs_s_super *super, const char *remote_path); -static int ftpfs_command (struct vfs_class *me, struct vfs_s_super *super, int wait_reply, const char *fmt, ...) - __attribute__ ((format (__printf__, 4, 5))); +static int ftpfs_chdir_internal (struct vfs_class *me, struct vfs_s_super *super, + const char *remote_path); +static int ftpfs_command (struct vfs_class *me, struct vfs_s_super *super, int wait_reply, + const char *fmt, ...) __attribute__ ((format (__printf__, 4, 5))); static int ftpfs_open_socket (struct vfs_class *me, struct vfs_s_super *super); -static int ftpfs_login_server (struct vfs_class *me, struct vfs_s_super *super, const char *netrcpass); +static int ftpfs_login_server (struct vfs_class *me, struct vfs_s_super *super, + const char *netrcpass); static int ftpfs_netrc_lookup (const char *host, char **login, char **pass); static char * ftpfs_translate_path (struct vfs_class *me, struct vfs_s_super *super, const char *remote_path) { if (!SUP.remote_is_amiga) - return g_strdup (remote_path); - else { - char *ret, *p; + return g_strdup (remote_path); + else + { + char *ret, *p; - if (MEDATA->logfile) { - fprintf (MEDATA->logfile, "MC -- ftpfs_translate_path: %s\n", remote_path); - fflush (MEDATA->logfile); - } + if (MEDATA->logfile) + { + fprintf (MEDATA->logfile, "MC -- ftpfs_translate_path: %s\n", remote_path); + fflush (MEDATA->logfile); + } - /* strip leading slash(es) */ - while (*remote_path == '/') - remote_path++; + /* strip leading slash(es) */ + while (*remote_path == '/') + remote_path++; - /* - * Don't change "/" into "", e.g. "CWD " would be - * invalid. - */ + /* + * Don't change "/" into "", e.g. "CWD " would be + * invalid. + */ if (*remote_path == '\0') - return g_strdup ("."); + return g_strdup ("."); - ret = g_strdup (remote_path); + ret = g_strdup (remote_path); - /* replace first occurance of ":/" with ":" */ - p = strchr (ret, ':'); - if ((p != NULL) && (*(p + 1) == '/')) - memmove (p + 1, p + 2, strlen (p + 2) + 1); + /* replace first occurance of ":/" with ":" */ + p = strchr (ret, ':'); + if ((p != NULL) && (*(p + 1) == '/')) + memmove (p + 1, p + 2, strlen (p + 2) + 1); - /* strip trailing "/." */ - if ((p = strrchr (ret, '/')) && *(p + 1) == '.' && *(p + 2) == '\0') - *p = '\0'; - return ret; + /* strip trailing "/." */ + if ((p = strrchr (ret, '/')) && *(p + 1) == '.' && *(p + 2) == '\0') + *p = '\0'; + return ret; } } @@ -245,34 +249,36 @@ ftpfs_translate_path (struct vfs_class *me, struct vfs_s_super *super, const cha #define FTP_COMMAND_PORT 21 static void -ftpfs_split_url(char *path, char **host, char **user, int *port, char **pass) +ftpfs_split_url (char *path, char **host, char **user, int *port, char **pass) { char *p; - p = vfs_split_url (path, host, user, port, pass, FTP_COMMAND_PORT, - URL_USE_ANONYMOUS); + p = vfs_split_url (path, host, user, port, pass, FTP_COMMAND_PORT, URL_USE_ANONYMOUS); - if (!*user) { - /* Look up user and password in netrc */ - if (use_netrc) - ftpfs_netrc_lookup (*host, user, pass); - if (!*user) - *user = g_strdup ("anonymous"); + if (!*user) + { + /* Look up user and password in netrc */ + if (use_netrc) + ftpfs_netrc_lookup (*host, user, pass); + if (!*user) + *user = g_strdup ("anonymous"); } /* Look up password in netrc for known user */ - if (use_netrc && *user && pass && !*pass) { - char *new_user; + if (use_netrc && *user && pass && !*pass) + { + char *new_user; - ftpfs_netrc_lookup (*host, &new_user, pass); + ftpfs_netrc_lookup (*host, &new_user, pass); - /* If user is different, remove password */ - if (new_user && strcmp (*user, new_user)) { - g_free (*pass); - *pass = NULL; - } + /* If user is different, remove password */ + if (new_user && strcmp (*user, new_user)) + { + g_free (*pass); + *pass = NULL; + } - g_free (new_user); + g_free (new_user); } g_free (p); @@ -284,38 +290,43 @@ ftpfs_get_reply (struct vfs_class *me, int sock, char *string_buf, int string_le { char answer[BUF_1K]; int i; - - for (;;) { - if (!vfs_s_get_line (me, sock, answer, sizeof (answer), '\n')){ - if (string_buf) - *string_buf = 0; - code = 421; - return 4; - } - switch (sscanf(answer, "%d", &code)){ - case 0: - if (string_buf) - g_strlcpy (string_buf, answer, string_len); - code = 500; - return 5; - case 1: - if (answer[3] == '-') { - while (1) { - if (!vfs_s_get_line (me, sock, answer, sizeof(answer), '\n')){ - if (string_buf) - *string_buf = 0; - code = 421; - return 4; - } - if ((sscanf (answer, "%d", &i) > 0) && - (code == i) && (answer[3] == ' ')) - break; - } - } - if (string_buf) - g_strlcpy (string_buf, answer, string_len); - return code / 100; - } + + for (;;) + { + if (!vfs_s_get_line (me, sock, answer, sizeof (answer), '\n')) + { + if (string_buf) + *string_buf = 0; + code = 421; + return 4; + } + switch (sscanf (answer, "%d", &code)) + { + case 0: + if (string_buf) + g_strlcpy (string_buf, answer, string_len); + code = 500; + return 5; + case 1: + if (answer[3] == '-') + { + while (1) + { + if (!vfs_s_get_line (me, sock, answer, sizeof (answer), '\n')) + { + if (string_buf) + *string_buf = 0; + code = 421; + return 4; + } + if ((sscanf (answer, "%d", &i) > 0) && (code == i) && (answer[3] == ' ')) + break; + } + } + if (string_buf) + g_strlcpy (string_buf, answer, string_len); + return code / 100; + } } } @@ -323,31 +334,34 @@ static int ftpfs_reconnect (struct vfs_class *me, struct vfs_s_super *super) { int sock = ftpfs_open_socket (me, super); - if (sock != -1){ - char *cwdir = SUP.cwdir; - close (SUP.sock); - SUP.sock = sock; - SUP.cwdir = NULL; - if (ftpfs_login_server (me, super, SUP.password)){ - if (!cwdir) - return 1; - sock = ftpfs_chdir_internal (me, super, cwdir); - g_free (cwdir); - return sock == COMPLETE; - } - SUP.cwdir = cwdir; + if (sock != -1) + { + char *cwdir = SUP.cwdir; + close (SUP.sock); + SUP.sock = sock; + SUP.cwdir = NULL; + if (ftpfs_login_server (me, super, SUP.password)) + { + if (!cwdir) + return 1; + sock = ftpfs_chdir_internal (me, super, cwdir); + g_free (cwdir); + return sock == COMPLETE; + } + SUP.cwdir = cwdir; } return 0; } static int -ftpfs_command (struct vfs_class *me, struct vfs_s_super *super, int wait_reply, const char *fmt, ...) +ftpfs_command (struct vfs_class *me, struct vfs_s_super *super, int wait_reply, const char *fmt, + ...) { va_list ap; char *cmdstr; int status, cmdlen; static int retry = 0; - static int level = 0; /* ftpfs_login_server() use ftpfs_command() */ + static int level = 0; /* ftpfs_login_server() use ftpfs_command() */ va_start (ap, fmt); cmdstr = g_strdup_vprintf (fmt, ap); @@ -358,37 +372,47 @@ ftpfs_command (struct vfs_class *me, struct vfs_s_super *super, int wait_reply, strcpy (cmdstr + cmdlen, "\r\n"); cmdlen += 2; - if (MEDATA->logfile) { - if (strncmp (cmdstr, "PASS ", 5) == 0) { - fputs ("PASS \r\n", MEDATA->logfile); - } else - fwrite (cmdstr, cmdlen, 1, MEDATA->logfile); + if (MEDATA->logfile) + { + if (strncmp (cmdstr, "PASS ", 5) == 0) + { + fputs ("PASS \r\n", MEDATA->logfile); + } + else + { + size_t ret; + ret = fwrite (cmdstr, cmdlen, 1, MEDATA->logfile); + } - fflush (MEDATA->logfile); + fflush (MEDATA->logfile); } got_sigpipe = 0; tty_enable_interrupt_key (); status = write (SUP.sock, cmdstr, cmdlen); - if (status < 0) { - code = 421; + if (status < 0) + { + code = 421; - if (errno == EPIPE) { /* Remote server has closed connection */ - if (level == 0) { - level = 1; - status = ftpfs_reconnect (me, super); - level = 0; - if (status && (write (SUP.sock, cmdstr, cmdlen) > 0)) { - goto ok; - } + if (errno == EPIPE) + { /* Remote server has closed connection */ + if (level == 0) + { + level = 1; + status = ftpfs_reconnect (me, super); + level = 0; + if (status && (write (SUP.sock, cmdstr, cmdlen) > 0)) + { + goto ok; + } - } - got_sigpipe = 1; - } - g_free (cmdstr); - tty_disable_interrupt_key (); - return TRANSIENT; + } + got_sigpipe = 1; + } + g_free (cmdstr); + tty_disable_interrupt_key (); + return TRANSIENT; } retry = 0; ok: @@ -396,34 +420,36 @@ ftpfs_command (struct vfs_class *me, struct vfs_s_super *super, int wait_reply, if (wait_reply) { - status = ftpfs_get_reply (me, SUP.sock, - (wait_reply & WANT_STRING) ? reply_str : NULL, - sizeof (reply_str) - 1); - if ((wait_reply & WANT_STRING) && !retry && !level && code == 421) - { - retry = 1; - level = 1; - status = ftpfs_reconnect (me, super); - level = 0; - if (status && (write (SUP.sock, cmdstr, cmdlen) > 0)) { - goto ok; - } - } - retry = 0; - g_free (cmdstr); - return status; + status = ftpfs_get_reply (me, SUP.sock, + (wait_reply & WANT_STRING) ? reply_str : NULL, + sizeof (reply_str) - 1); + if ((wait_reply & WANT_STRING) && !retry && !level && code == 421) + { + retry = 1; + level = 1; + status = ftpfs_reconnect (me, super); + level = 0; + if (status && (write (SUP.sock, cmdstr, cmdlen) > 0)) + { + goto ok; + } + } + retry = 0; + g_free (cmdstr); + return status; } - g_free (cmdstr); + g_free (cmdstr); return COMPLETE; } static void ftpfs_free_archive (struct vfs_class *me, struct vfs_s_super *super) { - if (SUP.sock != -1){ - print_vfs_message (_("ftpfs: Disconnecting from %s"), SUP.host); - ftpfs_command(me, super, NONE, "QUIT"); - close(SUP.sock); + if (SUP.sock != -1) + { + print_vfs_message (_("ftpfs: Disconnecting from %s"), SUP.host); + ftpfs_command (me, super, NONE, "QUIT"); + close (SUP.sock); } g_free (SUP.host); g_free (SUP.user); @@ -438,14 +464,15 @@ ftpfs_free_archive (struct vfs_class *me, struct vfs_s_super *super) /* This one is only used to initialize bucket->isbinary, don't use it as second parameter to ftpfs_changetype. */ -#define TYPE_UNKNOWN -1 +#define TYPE_UNKNOWN -1 static int ftpfs_changetype (struct vfs_class *me, struct vfs_s_super *super, int binary) { - if (binary != SUP.isbinary) { + if (binary != SUP.isbinary) + { if (ftpfs_command (me, super, WAIT_REPLY, "TYPE %c", binary ? 'I' : 'A') != COMPLETE) - ERRNOR (EIO, -1); + ERRNOR (EIO, -1); SUP.isbinary = binary; } return binary; @@ -453,158 +480,161 @@ ftpfs_changetype (struct vfs_class *me, struct vfs_s_super *super, int binary) /* This routine logs the user in */ static int -ftpfs_login_server (struct vfs_class *me, struct vfs_s_super *super, - const char *netrcpass) +ftpfs_login_server (struct vfs_class *me, struct vfs_s_super *super, const char *netrcpass) { char *pass; char *op; - char *name; /* login user name */ + char *name; /* login user name */ int anon = 0; char reply_string[BUF_MEDIUM]; SUP.isbinary = TYPE_UNKNOWN; - if (SUP.password) /* explicit password */ - op = g_strdup (SUP.password); - else if (netrcpass) /* password from netrc */ - op = g_strdup (netrcpass); - else if (!strcmp (SUP.user, "anonymous") || !strcmp (SUP.user, "ftp")) { - if (!ftpfs_anonymous_passwd) /* default anonymous password */ - ftpfs_init_passwd (); - op = g_strdup (ftpfs_anonymous_passwd); - anon = 1; - } else { /* ask user */ - char *p; + if (SUP.password) /* explicit password */ + op = g_strdup (SUP.password); + else if (netrcpass) /* password from netrc */ + op = g_strdup (netrcpass); + else if (!strcmp (SUP.user, "anonymous") || !strcmp (SUP.user, "ftp")) + { + if (!ftpfs_anonymous_passwd) /* default anonymous password */ + ftpfs_init_passwd (); + op = g_strdup (ftpfs_anonymous_passwd); + anon = 1; + } + else + { /* ask user */ + char *p; - p = g_strconcat (_(" FTP: Password required for "), - SUP.user, " ", (char *) NULL); - op = vfs_get_password (p); - g_free (p); - if (op == NULL) - ERRNOR (EPERM, 0); - SUP.password = g_strdup (op); + p = g_strconcat (_(" FTP: Password required for "), SUP.user, " ", (char *) NULL); + op = vfs_get_password (p); + g_free (p); + if (op == NULL) + ERRNOR (EPERM, 0); + SUP.password = g_strdup (op); } if (!anon || MEDATA->logfile) - pass = op; - else { - pass = g_strconcat ("-", op, (char *) NULL); - wipe_password (op); + pass = op; + else + { + pass = g_strconcat ("-", op, (char *) NULL); + wipe_password (op); } /* Proxy server accepts: username@host-we-want-to-connect */ - if (SUP.proxy) { - name = - g_strconcat (SUP.user, "@", - SUP.host[0] == '!' ? SUP.host + 1 : SUP.host, - (char *) NULL); - } else - name = g_strdup (SUP.user); - - if (ftpfs_get_reply - (me, SUP.sock, reply_string, - sizeof (reply_string) - 1) == COMPLETE) { - g_strup (reply_string); - SUP.remote_is_amiga = strstr (reply_string, "AMIGA") != 0; - if (MEDATA->logfile) { - fprintf (MEDATA->logfile, "MC -- remote_is_amiga = %d\n", - SUP.remote_is_amiga); - fflush (MEDATA->logfile); - } - - print_vfs_message (_("ftpfs: sending login name")); - - switch (ftpfs_command (me, super, WAIT_REPLY, "USER %s", name)) { - case CONTINUE: - print_vfs_message (_("ftpfs: sending user password")); - code = ftpfs_command (me, super, WAIT_REPLY, "PASS %s", pass); - if (code == CONTINUE) { - char *p; - - p = g_strdup_printf (_ - ("FTP: Account required for user %s"), - SUP.user); - op = input_dialog (p, _("Account:"), MC_HISTORY_FTPFS_ACCOUNT, ""); - g_free (p); - if (op == NULL) - ERRNOR (EPERM, 0); - print_vfs_message (_("ftpfs: sending user account")); - code = - ftpfs_command (me, super, WAIT_REPLY, "ACCT %s", op); - g_free (op); - } - if (code != COMPLETE) - break; - /* fall through */ - - case COMPLETE: - print_vfs_message (_("ftpfs: logged in")); - wipe_password (pass); - g_free (name); - return 1; - - default: - SUP.failed_on_login = 1; - if (SUP.password) - wipe_password (SUP.password); - SUP.password = 0; - - goto login_fail; - } + if (SUP.proxy) + { + name = + g_strconcat (SUP.user, "@", + SUP.host[0] == '!' ? SUP.host + 1 : SUP.host, (char *) NULL); } - message (D_ERROR, MSG_ERROR, _("ftpfs: Login incorrect for user %s "), - SUP.user); + else + name = g_strdup (SUP.user); + + if (ftpfs_get_reply (me, SUP.sock, reply_string, sizeof (reply_string) - 1) == COMPLETE) + { + g_strup (reply_string); + SUP.remote_is_amiga = strstr (reply_string, "AMIGA") != 0; + if (MEDATA->logfile) + { + fprintf (MEDATA->logfile, "MC -- remote_is_amiga = %d\n", SUP.remote_is_amiga); + fflush (MEDATA->logfile); + } + + print_vfs_message (_("ftpfs: sending login name")); + + switch (ftpfs_command (me, super, WAIT_REPLY, "USER %s", name)) + { + case CONTINUE: + print_vfs_message (_("ftpfs: sending user password")); + code = ftpfs_command (me, super, WAIT_REPLY, "PASS %s", pass); + if (code == CONTINUE) + { + char *p; + + p = g_strdup_printf (_("FTP: Account required for user %s"), SUP.user); + op = input_dialog (p, _("Account:"), MC_HISTORY_FTPFS_ACCOUNT, ""); + g_free (p); + if (op == NULL) + ERRNOR (EPERM, 0); + print_vfs_message (_("ftpfs: sending user account")); + code = ftpfs_command (me, super, WAIT_REPLY, "ACCT %s", op); + g_free (op); + } + if (code != COMPLETE) + break; + /* fall through */ + + case COMPLETE: + print_vfs_message (_("ftpfs: logged in")); + wipe_password (pass); + g_free (name); + return 1; + + default: + SUP.failed_on_login = 1; + if (SUP.password) + wipe_password (SUP.password); + SUP.password = 0; + + goto login_fail; + } + } + message (D_ERROR, MSG_ERROR, _("ftpfs: Login incorrect for user %s "), SUP.user); login_fail: wipe_password (pass); g_free (name); ERRNOR (EPERM, 0); } -static struct no_proxy_entry { - char *domain; - void *next; +static struct no_proxy_entry +{ + char *domain; + void *next; } *no_proxy; static void ftpfs_load_no_proxy_list (void) { /* FixMe: shouldn't be hardcoded!!! */ - char s[BUF_LARGE]; /* provide for BUF_LARGE characters */ + char s[BUF_LARGE]; /* provide for BUF_LARGE characters */ struct no_proxy_entry *np, *current = 0; - FILE *npf; - int c; - char *p; - static char *mc_file; + FILE *npf; + int c; + char *p; + static char *mc_file; if (mc_file) - return; + return; mc_file = concat_dir_and_file (mc_home, "mc.no_proxy"); - if (exist_file (mc_file) && - (npf = fopen (mc_file, "r"))) { - while (fgets (s, sizeof (s), npf)) { - if (!(p = strchr (s, '\n'))) { /* skip bogus entries */ - while ((c = fgetc (npf)) != EOF && c != '\n') - ; - continue; - } + if (exist_file (mc_file) && (npf = fopen (mc_file, "r"))) + { + while (fgets (s, sizeof (s), npf)) + { + if (!(p = strchr (s, '\n'))) + { /* skip bogus entries */ + while ((c = fgetc (npf)) != EOF && c != '\n') + ; + continue; + } - if (p == s) - continue; + if (p == s) + continue; - *p = '\0'; - - np = g_new (struct no_proxy_entry, 1); - np->domain = g_strdup (s); - np->next = NULL; - if (no_proxy) - current->next = np; - else - no_proxy = np; - current = np; - } + *p = '\0'; - fclose (npf); + np = g_new (struct no_proxy_entry, 1); + np->domain = g_strdup (s); + np->next = NULL; + if (no_proxy) + current->next = np; + else + no_proxy = np; + current = np; + } + + fclose (npf); } g_free (mc_file); } @@ -613,38 +643,41 @@ ftpfs_load_no_proxy_list (void) static int ftpfs_check_proxy (const char *host) { - struct no_proxy_entry *npe; + struct no_proxy_entry *npe; if (!ftpfs_proxy_host || !*ftpfs_proxy_host || !host || !*host) - return 0; /* sanity check */ + return 0; /* sanity check */ if (*host == '!') - return 1; - + return 1; + if (!ftpfs_always_use_proxy) - return 0; + return 0; if (!strchr (host, '.')) - return 0; + return 0; ftpfs_load_no_proxy_list (); - for (npe = no_proxy; npe; npe=npe->next) { - char *domain = npe->domain; + for (npe = no_proxy; npe; npe = npe->next) + { + char *domain = npe->domain; - if (domain[0] == '.') { - int ld = strlen (domain); - int lh = strlen (host); + if (domain[0] == '.') + { + int ld = strlen (domain); + int lh = strlen (host); - while (ld && lh && host[lh - 1] == domain[ld - 1]) { - ld--; - lh--; - } + while (ld && lh && host[lh - 1] == domain[ld - 1]) + { + ld--; + lh--; + } - if (!ld) - return 0; - } else - if (!g_strcasecmp (host, domain)) - return 0; + if (!ld) + return 0; + } + else if (!g_strcasecmp (host, domain)) + return 0; } return 1; @@ -655,9 +688,7 @@ ftpfs_get_proxy_host_and_port (const char *proxy, char **host, int *port) { char *user, *dir; - dir = - vfs_split_url (proxy, host, &user, port, 0, FTP_COMMAND_PORT, - URL_USE_ANONYMOUS); + dir = vfs_split_url (proxy, host, &user, port, 0, FTP_COMMAND_PORT, URL_USE_ANONYMOUS); g_free (user); g_free (dir); } @@ -666,39 +697,42 @@ static int ftpfs_open_socket (struct vfs_class *me, struct vfs_s_super *super) { struct addrinfo hints, *res, *curr_res; - int my_socket = 0; - char *host = NULL; - char *port = NULL; - int tmp_port; - int e; + int my_socket = 0; + char *host = NULL; + char *port = NULL; + int tmp_port; + int e; (void) me; - - /* Use a proxy host? */ - host = g_strdup(SUP.host); - if (!host || !*host){ - print_vfs_message (_("ftpfs: Invalid host name.")); + /* Use a proxy host? */ + host = g_strdup (SUP.host); + + if (!host || !*host) + { + print_vfs_message (_("ftpfs: Invalid host name.")); ftpfs_errno = EINVAL; g_free (host); - return -1; + return -1; } /* Hosts to connect to that start with a ! should use proxy */ tmp_port = SUP.port; - if (SUP.proxy){ - ftpfs_get_proxy_host_and_port (ftpfs_proxy_host, &host, &tmp_port); + if (SUP.proxy) + { + ftpfs_get_proxy_host_and_port (ftpfs_proxy_host, &host, &tmp_port); } - port = g_strdup_printf("%hu", (unsigned short) tmp_port); - if (port == NULL) { - g_free (host); - ftpfs_errno = errno; - return -1; + port = g_strdup_printf ("%hu", (unsigned short) tmp_port); + if (port == NULL) + { + g_free (host); + ftpfs_errno = errno; + return -1; } - tty_enable_interrupt_key(); /* clear the interrupt flag */ + tty_enable_interrupt_key (); /* clear the interrupt flag */ memset (&hints, 0, sizeof (struct addrinfo)); hints.ai_socktype = SOCK_STREAM; @@ -709,53 +743,61 @@ ftpfs_open_socket (struct vfs_class *me, struct vfs_s_super *super) g_free (port); port = NULL; - if ( e != 0 ) { - tty_disable_interrupt_key (); - print_vfs_message (_("ftpfs: %s"), gai_strerror (e)); - g_free (host); - ftpfs_errno = EINVAL; - return -1; + if (e != 0) + { + tty_disable_interrupt_key (); + print_vfs_message (_("ftpfs: %s"), gai_strerror (e)); + g_free (host); + ftpfs_errno = EINVAL; + return -1; } - for (curr_res = res; curr_res != NULL; curr_res = curr_res->ai_next) { + for (curr_res = res; curr_res != NULL; curr_res = curr_res->ai_next) + { - my_socket = socket (curr_res->ai_family, curr_res->ai_socktype, curr_res->ai_protocol); + my_socket = socket (curr_res->ai_family, curr_res->ai_socktype, curr_res->ai_protocol); - if (my_socket < 0) { + if (my_socket < 0) + { - if (curr_res->ai_next != NULL) - continue; + if (curr_res->ai_next != NULL) + continue; - tty_disable_interrupt_key(); - print_vfs_message (_("ftpfs: %s"), unix_error_string (errno)); - g_free (host); - freeaddrinfo (res); - ftpfs_errno = errno; - return -1; - } + tty_disable_interrupt_key (); + print_vfs_message (_("ftpfs: %s"), unix_error_string (errno)); + g_free (host); + freeaddrinfo (res); + ftpfs_errno = errno; + return -1; + } - print_vfs_message (_("ftpfs: making connection to %s"), host); - g_free (host); - host = NULL; + print_vfs_message (_("ftpfs: making connection to %s"), host); + g_free (host); + host = NULL; - if ( connect (my_socket, curr_res->ai_addr, curr_res->ai_addrlen) >= 0 ) - break; + if (connect (my_socket, curr_res->ai_addr, curr_res->ai_addrlen) >= 0) + break; - ftpfs_errno = errno; - close (my_socket); + ftpfs_errno = errno; + close (my_socket); - if (errno == EINTR && tty_got_interrupt ()) { - print_vfs_message (_("ftpfs: connection interrupted by user")); - } else if (res->ai_next == NULL) { - print_vfs_message (_("ftpfs: connection to server failed: %s"), - unix_error_string (errno)); - } else { - continue; - } + if (errno == EINTR && tty_got_interrupt ()) + { + print_vfs_message (_("ftpfs: connection interrupted by user")); + } + else if (res->ai_next == NULL) + { + print_vfs_message (_("ftpfs: connection to server failed: %s"), + unix_error_string (errno)); + } + else + { + continue; + } - freeaddrinfo (res); - tty_disable_interrupt_key (); - return -1; + freeaddrinfo (res); + tty_disable_interrupt_key (); + return -1; } freeaddrinfo (res); @@ -770,43 +812,55 @@ ftpfs_open_archive_int (struct vfs_class *me, struct vfs_s_super *super) /* We do not want to use the passive if we are using proxies */ if (SUP.proxy) - SUP.use_passive_connection = ftpfs_use_passive_connections_over_proxy; + SUP.use_passive_connection = ftpfs_use_passive_connections_over_proxy; retry_seconds = 0; - do { - SUP.failed_on_login = 0; + do + { + SUP.failed_on_login = 0; - SUP.sock = ftpfs_open_socket (me, super); - if (SUP.sock == -1) - return -1; + SUP.sock = ftpfs_open_socket (me, super); + if (SUP.sock == -1) + return -1; + + if (ftpfs_login_server (me, super, NULL)) + { + /* Logged in, no need to retry the connection */ + break; + } + else + { + if (SUP.failed_on_login) + { + /* Close only the socket descriptor */ + close (SUP.sock); + } + else + { + return -1; + } + if (ftpfs_retry_seconds) + { + retry_seconds = ftpfs_retry_seconds; + tty_enable_interrupt_key (); + for (count_down = retry_seconds; count_down; count_down--) + { + print_vfs_message (_("Waiting to retry... %d (Control-C to cancel)"), + count_down); + sleep (1); + if (tty_got_interrupt ()) + { + /* ftpfs_errno = E; */ + tty_disable_interrupt_key (); + return 0; + } + } + tty_disable_interrupt_key (); + } + } + } + while (retry_seconds); - if (ftpfs_login_server (me, super, NULL)) { - /* Logged in, no need to retry the connection */ - break; - } else { - if (SUP.failed_on_login){ - /* Close only the socket descriptor */ - close (SUP.sock); - } else { - return -1; - } - if (ftpfs_retry_seconds){ - retry_seconds = ftpfs_retry_seconds; - tty_enable_interrupt_key (); - for (count_down = retry_seconds; count_down; count_down--){ - print_vfs_message (_("Waiting to retry... %d (Control-C to cancel)"), count_down); - sleep (1); - if (tty_got_interrupt ()) { - /* ftpfs_errno = E; */ - tty_disable_interrupt_key (); - return 0; - } - } - tty_disable_interrupt_key (); - } - } - } while (retry_seconds); - SUP.cwdir = ftpfs_get_current_directory (me, super); if (!SUP.cwdir) SUP.cwdir = g_strdup (PATH_SEP_STR); @@ -815,7 +869,7 @@ ftpfs_open_archive_int (struct vfs_class *me, struct vfs_s_super *super) static int ftpfs_open_archive (struct vfs_class *me, struct vfs_s_super *super, - const char *archive_name, char *op) + const char *archive_name, char *op) { char *host, *user, *password; int port; @@ -830,23 +884,21 @@ ftpfs_open_archive (struct vfs_class *me, struct vfs_s_super *super, SUP.cwdir = NULL; SUP.proxy = 0; if (ftpfs_check_proxy (host)) - SUP.proxy = ftpfs_proxy_host; + SUP.proxy = ftpfs_proxy_host; SUP.password = password; SUP.use_passive_connection = ftpfs_use_passive_connections; SUP.strict = ftpfs_use_unix_list_options ? RFC_AUTODETECT : RFC_STRICT; SUP.isbinary = TYPE_UNKNOWN; SUP.remote_is_amiga = 0; super->name = g_strdup ("/"); - super->root = - vfs_s_new_inode (me, super, - vfs_s_default_stat (me, S_IFDIR | 0755)); + super->root = vfs_s_new_inode (me, super, vfs_s_default_stat (me, S_IFDIR | 0755)); return ftpfs_open_archive_int (me, super); } static int ftpfs_archive_same (struct vfs_class *me, struct vfs_s_super *super, - const char *archive_name, char *op, void *cookie) + const char *archive_name, char *op, void *cookie) { char *host, *user; int port; @@ -857,8 +909,7 @@ ftpfs_archive_same (struct vfs_class *me, struct vfs_s_super *super, ftpfs_split_url (strchr (op, ':') + 1, &host, &user, &port, 0); - port = ((strcmp (host, SUP.host) == 0) - && (strcmp (user, SUP.user) == 0) && (port == SUP.port)); + port = ((strcmp (host, SUP.host) == 0) && (strcmp (user, SUP.user) == 0) && (port == SUP.port)); g_free (host); g_free (user); @@ -873,104 +924,119 @@ ftpfs_get_current_directory (struct vfs_class *me, struct vfs_s_super *super) char buf[BUF_8K], *bufp, *bufq; if (ftpfs_command (me, super, NONE, "PWD") == COMPLETE && - ftpfs_get_reply(me, SUP.sock, buf, sizeof(buf)) == COMPLETE) { - bufp = NULL; - for (bufq = buf; *bufq; bufq++) - if (*bufq == '"') { - if (!bufp) { - bufp = bufq + 1; - } else { - *bufq = 0; - if (*bufp) { - if (*(bufq - 1) != '/') { - *bufq++ = '/'; - *bufq = 0; - } - if (*bufp == '/') - return g_strdup (bufp); - else { - /* If the remote server is an Amiga a leading slash - might be missing. MC needs it because it is used - as separator between hostname and path internally. */ - return g_strconcat( "/", bufp, (char *) NULL); - } - } else { - ftpfs_errno = EIO; - return NULL; - } - } - } + ftpfs_get_reply (me, SUP.sock, buf, sizeof (buf)) == COMPLETE) + { + bufp = NULL; + for (bufq = buf; *bufq; bufq++) + if (*bufq == '"') + { + if (!bufp) + { + bufp = bufq + 1; + } + else + { + *bufq = 0; + if (*bufp) + { + if (*(bufq - 1) != '/') + { + *bufq++ = '/'; + *bufq = 0; + } + if (*bufp == '/') + return g_strdup (bufp); + else + { + /* If the remote server is an Amiga a leading slash + might be missing. MC needs it because it is used + as separator between hostname and path internally. */ + return g_strconcat ("/", bufp, (char *) NULL); + } + } + else + { + ftpfs_errno = EIO; + return NULL; + } + } + } } ftpfs_errno = EIO; return NULL; } - + /* Setup Passive ftp connection, we use it for source routed connections */ static int ftpfs_setup_passive (struct vfs_class *me, struct vfs_s_super *super, - int my_socket, struct sockaddr_storage *sa, socklen_t *salen) + int my_socket, struct sockaddr_storage *sa, socklen_t * salen) { char *c; - if (ftpfs_command (me, super, WAIT_REPLY | WANT_STRING, "EPSV") == COMPLETE) { - int port; - /* (||||) */ - c = strchr (reply_str, '|'); - if (c == NULL) - return 0; - if(strlen(c) > 3) - c+=3; - else - return 0; + if (ftpfs_command (me, super, WAIT_REPLY | WANT_STRING, "EPSV") == COMPLETE) + { + int port; + /* (||||) */ + c = strchr (reply_str, '|'); + if (c == NULL) + return 0; + if (strlen (c) > 3) + c += 3; + else + return 0; - port = atoi (c); - if (port < 0 || port > 65535) - return 0; - port = htons (port); + port = atoi (c); + if (port < 0 || port > 65535) + return 0; + port = htons (port); - switch (sa->ss_family) { - case AF_INET: - ((struct sockaddr_in *)sa)->sin_port = port; - break; - case AF_INET6: - ((struct sockaddr_in6 *)sa)->sin6_port = port; - break; - default: - print_vfs_message (_("ftpfs: invalid address family")); - ERRNOR (EINVAL, -1); - } - } else if (sa->ss_family == AF_INET) { - int xa, xb, xc, xd, xe, xf; - char n [6]; + switch (sa->ss_family) + { + case AF_INET: + ((struct sockaddr_in *) sa)->sin_port = port; + break; + case AF_INET6: + ((struct sockaddr_in6 *) sa)->sin6_port = port; + break; + default: + print_vfs_message (_("ftpfs: invalid address family")); + ERRNOR (EINVAL, -1); + } + } + else if (sa->ss_family == AF_INET) + { + int xa, xb, xc, xd, xe, xf; + char n[6]; - if (ftpfs_command (me, super, WAIT_REPLY | WANT_STRING, "PASV") != COMPLETE) - return 0; + if (ftpfs_command (me, super, WAIT_REPLY | WANT_STRING, "PASV") != COMPLETE) + return 0; - /* Parse remote parameters */ - for (c = reply_str + 4; (*c) && (!isdigit ((unsigned char) *c)); c++); + /* Parse remote parameters */ + for (c = reply_str + 4; (*c) && (!isdigit ((unsigned char) *c)); c++); - if (!*c) - return 0; - if (!isdigit ((unsigned char) *c)) - return 0; - if (sscanf (c, "%d,%d,%d,%d,%d,%d", &xa, &xb, &xc, &xd, &xe, &xf) != 6) - return 0; + if (!*c) + return 0; + if (!isdigit ((unsigned char) *c)) + return 0; + if (sscanf (c, "%d,%d,%d,%d,%d,%d", &xa, &xb, &xc, &xd, &xe, &xf) != 6) + return 0; - n [0] = (unsigned char) xa; - n [1] = (unsigned char) xb; - n [2] = (unsigned char) xc; - n [3] = (unsigned char) xd; - n [4] = (unsigned char) xe; - n [5] = (unsigned char) xf; + n[0] = (unsigned char) xa; + n[1] = (unsigned char) xb; + n[2] = (unsigned char) xc; + n[3] = (unsigned char) xd; + n[4] = (unsigned char) xe; + n[5] = (unsigned char) xf; - memcpy (&(((struct sockaddr_in *)sa)->sin_addr.s_addr), (void *)n, 4); - memcpy (&(((struct sockaddr_in *)sa)->sin_port), (void *)&n[4], 2); - } else - return 0; + memcpy (&(((struct sockaddr_in *) sa)->sin_addr.s_addr), (void *) n, 4); + memcpy (&(((struct sockaddr_in *) sa)->sin_port), (void *) &n[4], 2); + } + else + return 0; - if (connect (my_socket, (struct sockaddr *) sa, *salen ) < 0) - return 0; + if (connect (my_socket, (struct sockaddr *) sa, *salen) < 0) + return 0; return 1; } @@ -982,103 +1048,115 @@ ftpfs_initconn (struct vfs_class *me, struct vfs_s_super *super) socklen_t data_addrlen; int data_sock, result; -again: + again: memset (&data_addr, 0, sizeof (struct sockaddr_storage)); data_addrlen = sizeof (struct sockaddr_storage); if (SUP.use_passive_connection) - result = getpeername (SUP.sock, (struct sockaddr *) &data_addr, &data_addrlen); + result = getpeername (SUP.sock, (struct sockaddr *) &data_addr, &data_addrlen); else - result = getsockname (SUP.sock, (struct sockaddr *) &data_addr, &data_addrlen); + result = getsockname (SUP.sock, (struct sockaddr *) &data_addr, &data_addrlen); - if (result == -1 ) - return -1; + if (result == -1) + return -1; - switch (data_addr.ss_family) { + switch (data_addr.ss_family) + { case AF_INET: - ((struct sockaddr_in *)&data_addr)->sin_port = 0; - break; + ((struct sockaddr_in *) &data_addr)->sin_port = 0; + break; case AF_INET6: - ((struct sockaddr_in6 *)&data_addr)->sin6_port = 0; - break; + ((struct sockaddr_in6 *) &data_addr)->sin6_port = 0; + break; default: - print_vfs_message (_("ftpfs: invalid address family")); - ERRNOR(EINVAL, -1); + print_vfs_message (_("ftpfs: invalid address family")); + ERRNOR (EINVAL, -1); } data_sock = socket (data_addr.ss_family, SOCK_STREAM, IPPROTO_TCP); - if (data_sock < 0) { - if (SUP.use_passive_connection) { - print_vfs_message (_("ftpfs: could not setup passive mode: %s"), unix_error_string (errno)); - SUP.use_passive_connection = 0; - goto again; - } + if (data_sock < 0) + { + if (SUP.use_passive_connection) + { + print_vfs_message (_("ftpfs: could not setup passive mode: %s"), + unix_error_string (errno)); + SUP.use_passive_connection = 0; + goto again; + } - print_vfs_message (_("ftpfs: could not create socket: %s"), unix_error_string (errno)); - return -1; + print_vfs_message (_("ftpfs: could not create socket: %s"), unix_error_string (errno)); + return -1; } - if (SUP.use_passive_connection) { + if (SUP.use_passive_connection) + { - if (ftpfs_setup_passive (me, super, data_sock, &data_addr, &data_addrlen)) - return data_sock; + if (ftpfs_setup_passive (me, super, data_sock, &data_addr, &data_addrlen)) + return data_sock; - SUP.use_passive_connection = 0; - print_vfs_message (_("ftpfs: could not setup passive mode")); + SUP.use_passive_connection = 0; + print_vfs_message (_("ftpfs: could not setup passive mode")); - close (data_sock); - goto again; + close (data_sock); + goto again; } /* If passive setup fails, fallback to active connections */ /* Active FTP connection */ - if ((bind (data_sock, (struct sockaddr *)&data_addr, data_addrlen) == 0) && - (getsockname (data_sock, (struct sockaddr *)&data_addr, &data_addrlen) == 0) && - (listen (data_sock, 1) == 0)) { - unsigned short int port; - char *addr; - unsigned int af; + if ((bind (data_sock, (struct sockaddr *) &data_addr, data_addrlen) == 0) && + (getsockname (data_sock, (struct sockaddr *) &data_addr, &data_addrlen) == 0) && + (listen (data_sock, 1) == 0)) + { + unsigned short int port; + char *addr; + unsigned int af; - switch (data_addr.ss_family) { - case AF_INET: - af = FTP_INET; - port = ((struct sockaddr_in *)&data_addr)->sin_port; - break; - case AF_INET6: - af = FTP_INET6; - port = ((struct sockaddr_in6 *)&data_addr)->sin6_port; - break; - default: - print_vfs_message (_("ftpfs: invalid address family")); - ERRNOR (EINVAL, -1); - } + switch (data_addr.ss_family) + { + case AF_INET: + af = FTP_INET; + port = ((struct sockaddr_in *) &data_addr)->sin_port; + break; + case AF_INET6: + af = FTP_INET6; + port = ((struct sockaddr_in6 *) &data_addr)->sin6_port; + break; + default: + print_vfs_message (_("ftpfs: invalid address family")); + ERRNOR (EINVAL, -1); + } - port = ntohs (port); + port = ntohs (port); - addr = g_try_malloc (NI_MAXHOST); - if (addr == NULL) - ERRNOR (ENOMEM, -1); + addr = g_try_malloc (NI_MAXHOST); + if (addr == NULL) + ERRNOR (ENOMEM, -1); - if (getnameinfo ((struct sockaddr *)&data_addr, data_addrlen, addr, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) != 0) { - g_free (addr); - ERRNOR (EIO, -1); - } + if (getnameinfo + ((struct sockaddr *) &data_addr, data_addrlen, addr, NI_MAXHOST, NULL, 0, + NI_NUMERICHOST) != 0) + { + g_free (addr); + ERRNOR (EIO, -1); + } - if (ftpfs_command (me, super, WAIT_REPLY, "EPRT |%u|%s|%hu|", af, addr, port) == COMPLETE) { - g_free (addr); - return data_sock; - } - g_free (addr); + if (ftpfs_command (me, super, WAIT_REPLY, "EPRT |%u|%s|%hu|", af, addr, port) == COMPLETE) + { + g_free (addr); + return data_sock; + } + g_free (addr); - if (FTP_INET == af) { - unsigned char *a = (unsigned char *)&((struct sockaddr_in *)&data_addr)->sin_addr; - unsigned char *p = (unsigned char *)&port; - - if (ftpfs_command (me, super, WAIT_REPLY, - "PORT %u,%u,%u,%u,%u,%u", a[0], a[1], a[2], a[3], - p[0], p[1]) == COMPLETE) - return data_sock; - } + if (FTP_INET == af) + { + unsigned char *a = (unsigned char *) &((struct sockaddr_in *) &data_addr)->sin_addr; + unsigned char *p = (unsigned char *) &port; + + if (ftpfs_command (me, super, WAIT_REPLY, + "PORT %u,%u,%u,%u,%u,%u", a[0], a[1], a[2], a[3], + p[0], p[1]) == COMPLETE) + return data_sock; + } } close (data_sock); ftpfs_errno = EIO; @@ -1087,42 +1165,47 @@ again: static int ftpfs_open_data_connection (struct vfs_class *me, struct vfs_s_super *super, const char *cmd, - const char *remote, int isbinary, int reget) + const char *remote, int isbinary, int reget) { struct sockaddr_storage from; int s, j, data; - socklen_t fromlen = sizeof(from); - + socklen_t fromlen = sizeof (from); + if ((s = ftpfs_initconn (me, super)) == -1) return -1; if (ftpfs_changetype (me, super, isbinary) == -1) return -1; - if (reget > 0){ - j = ftpfs_command (me, super, WAIT_REPLY, "REST %d", reget); - if (j != CONTINUE) - return -1; + if (reget > 0) + { + j = ftpfs_command (me, super, WAIT_REPLY, "REST %d", reget); + if (j != CONTINUE) + return -1; } - if (remote) { - char *remote_path = ftpfs_translate_path (me, super, remote); - j = ftpfs_command (me, super, WAIT_REPLY, "%s /%s", cmd, - /* WarFtpD can't STORE //filename */ - (*remote_path == '/') ? remote_path + 1 : remote_path); - g_free (remote_path); - } else - j = ftpfs_command (me, super, WAIT_REPLY, "%s", cmd); + if (remote) + { + char *remote_path = ftpfs_translate_path (me, super, remote); + j = ftpfs_command (me, super, WAIT_REPLY, "%s /%s", cmd, + /* WarFtpD can't STORE //filename */ + (*remote_path == '/') ? remote_path + 1 : remote_path); + g_free (remote_path); + } + else + j = ftpfs_command (me, super, WAIT_REPLY, "%s", cmd); if (j != PRELIM) - ERRNOR (EPERM, -1); + ERRNOR (EPERM, -1); tty_enable_interrupt_key (); if (SUP.use_passive_connection) - data = s; - else { - data = accept (s, (struct sockaddr *)&from, &fromlen); - if (data < 0) { - ftpfs_errno = errno; - close (s); - return -1; - } - close (s); + data = s; + else + { + data = accept (s, (struct sockaddr *) &from, &fromlen); + if (data < 0) + { + ftpfs_errno = errno; + close (s); + return -1; + } + close (s); } tty_disable_interrupt_key (); return data; @@ -1141,193 +1224,224 @@ ftpfs_linear_abort (struct vfs_class *me, struct vfs_s_fh *fh) SUP.ctl_connection_busy = 0; print_vfs_message (_("ftpfs: aborting transfer.")); - if (send (SUP.sock, ipbuf, sizeof (ipbuf), MSG_OOB) != sizeof (ipbuf)) { - print_vfs_message (_("ftpfs: abort error: %s"), - unix_error_string (errno)); - if (dsock != -1) - close (dsock); - return; + if (send (SUP.sock, ipbuf, sizeof (ipbuf), MSG_OOB) != sizeof (ipbuf)) + { + print_vfs_message (_("ftpfs: abort error: %s"), unix_error_string (errno)); + if (dsock != -1) + close (dsock); + return; } - if (ftpfs_command (me, super, NONE, "%cABOR", DM) != COMPLETE) { - print_vfs_message (_("ftpfs: abort failed")); - if (dsock != -1) - close (dsock); - return; + if (ftpfs_command (me, super, NONE, "%cABOR", DM) != COMPLETE) + { + print_vfs_message (_("ftpfs: abort failed")); + if (dsock != -1) + close (dsock); + return; } - if (dsock != -1) { - FD_ZERO (&mask); - FD_SET (dsock, &mask); - if (select (dsock + 1, &mask, NULL, NULL, NULL) > 0) { - struct timeval start_tim, tim; - gettimeofday (&start_tim, NULL); - /* flush the remaining data */ - while (read (dsock, buf, sizeof (buf)) > 0) { - gettimeofday (&tim, NULL); - if (tim.tv_sec > start_tim.tv_sec + ABORT_TIMEOUT) { - /* server keeps sending, drop the connection and ftpfs_reconnect */ - close (dsock); - ftpfs_reconnect (me, super); - return; - } - } - } - close (dsock); + if (dsock != -1) + { + FD_ZERO (&mask); + FD_SET (dsock, &mask); + if (select (dsock + 1, &mask, NULL, NULL, NULL) > 0) + { + struct timeval start_tim, tim; + gettimeofday (&start_tim, NULL); + /* flush the remaining data */ + while (read (dsock, buf, sizeof (buf)) > 0) + { + gettimeofday (&tim, NULL); + if (tim.tv_sec > start_tim.tv_sec + ABORT_TIMEOUT) + { + /* server keeps sending, drop the connection and ftpfs_reconnect */ + close (dsock); + ftpfs_reconnect (me, super); + return; + } + } + } + close (dsock); } if ((ftpfs_get_reply (me, SUP.sock, NULL, 0) == TRANSIENT) && (code == 426)) - ftpfs_get_reply (me, SUP.sock, NULL, 0); + ftpfs_get_reply (me, SUP.sock, NULL, 0); } #if 0 static void -resolve_symlink_without_ls_options(struct vfs_class *me, struct vfs_s_super *super, struct vfs_s_inode *dir) +resolve_symlink_without_ls_options (struct vfs_class *me, struct vfs_s_super *super, + struct vfs_s_inode *dir) { struct linklist *flist; struct direntry *fe, *fel; char tmp[MC_MAXPATHLEN]; int depth; - + dir->symlink_status = FTPFS_RESOLVING_SYMLINKS; - for (flist = dir->file_list->next; flist != dir->file_list; flist = flist->next) { + for (flist = dir->file_list->next; flist != dir->file_list; flist = flist->next) + { /* flist->data->l_stat is alread initialized with 0 */ fel = flist->data; - if (S_ISLNK(fel->s.st_mode) && fel->linkname) { - if (fel->linkname[0] == '/') { - if (strlen (fel->linkname) >= MC_MAXPATHLEN) - continue; - strcpy (tmp, fel->linkname); - } else { - if ((strlen (dir->remote_path) + strlen (fel->linkname)) >= MC_MAXPATHLEN) - continue; + if (S_ISLNK (fel->s.st_mode) && fel->linkname) + { + if (fel->linkname[0] == '/') + { + if (strlen (fel->linkname) >= MC_MAXPATHLEN) + continue; + strcpy (tmp, fel->linkname); + } + else + { + if ((strlen (dir->remote_path) + strlen (fel->linkname)) >= MC_MAXPATHLEN) + continue; strcpy (tmp, dir->remote_path); if (tmp[1] != '\0') - strcat (tmp, "/"); + strcat (tmp, "/"); strcat (tmp + 1, fel->linkname); - } - for ( depth = 0; depth < 100; depth++) { /* depth protects against recursive symbolic links */ - canonicalize_pathname (tmp); - fe = _get_file_entry(bucket, tmp, 0, 0); - if (fe) { - if (S_ISLNK (fe->s.st_mode) && fe->l_stat == 0) { - /* Symlink points to link which isn't resolved, yet. */ - if (fe->linkname[0] == '/') { - if (strlen (fe->linkname) >= MC_MAXPATHLEN) - break; - strcpy (tmp, fe->linkname); - } else { - /* at this point tmp looks always like this - /directory/filename, i.e. no need to check - strrchr's return value */ - *(strrchr (tmp, '/') + 1) = '\0'; /* dirname */ - if ((strlen (tmp) + strlen (fe->linkname)) >= MC_MAXPATHLEN) - break; - strcat (tmp, fe->linkname); - } - continue; - } else { - fel->l_stat = g_new (struct stat, 1); - if ( S_ISLNK (fe->s.st_mode)) - *fel->l_stat = *fe->l_stat; - else - *fel->l_stat = fe->s; + } + for (depth = 0; depth < 100; depth++) + { /* depth protects against recursive symbolic links */ + canonicalize_pathname (tmp); + fe = _get_file_entry (bucket, tmp, 0, 0); + if (fe) + { + if (S_ISLNK (fe->s.st_mode) && fe->l_stat == 0) + { + /* Symlink points to link which isn't resolved, yet. */ + if (fe->linkname[0] == '/') + { + if (strlen (fe->linkname) >= MC_MAXPATHLEN) + break; + strcpy (tmp, fe->linkname); + } + else + { + /* at this point tmp looks always like this + /directory/filename, i.e. no need to check + strrchr's return value */ + *(strrchr (tmp, '/') + 1) = '\0'; /* dirname */ + if ((strlen (tmp) + strlen (fe->linkname)) >= MC_MAXPATHLEN) + break; + strcat (tmp, fe->linkname); + } + continue; + } + else + { + fel->l_stat = g_new (struct stat, 1); + if (S_ISLNK (fe->s.st_mode)) + *fel->l_stat = *fe->l_stat; + else + *fel->l_stat = fe->s; (*fel->l_stat).st_ino = bucket->__inode_counter++; } - } + } break; - } + } } } dir->symlink_status = FTPFS_RESOLVED_SYMLINKS; } static void -resolve_symlink_with_ls_options(struct vfs_class *me, struct vfs_s_super *super, struct vfs_s_inode *dir) +resolve_symlink_with_ls_options (struct vfs_class *me, struct vfs_s_super *super, + struct vfs_s_inode *dir) { - char buffer[2048] = "", *filename; + char buffer[2048] = "", *filename; int sock; FILE *fp; struct stat s; struct linklist *flist; struct direntry *fe; int switch_method = 0; - + dir->symlink_status = FTPFS_RESOLVED_SYMLINKS; - if (strchr (dir->remote_path, ' ')) { - if (ftpfs_chdir_internal (bucket, dir->remote_path) != COMPLETE) { - print_vfs_message(_("ftpfs: CWD failed.")); - return; + if (strchr (dir->remote_path, ' ')) + { + if (ftpfs_chdir_internal (bucket, dir->remote_path) != COMPLETE) + { + print_vfs_message (_("ftpfs: CWD failed.")); + return; } sock = ftpfs_open_data_connection (bucket, "LIST -lLa", ".", TYPE_ASCII, 0); } else - sock = ftpfs_open_data_connection (bucket, "LIST -lLa", - dir->remote_path, TYPE_ASCII, 0); + sock = ftpfs_open_data_connection (bucket, "LIST -lLa", dir->remote_path, TYPE_ASCII, 0); - if (sock == -1) { - print_vfs_message(_("ftpfs: couldn't resolve symlink")); - return; + if (sock == -1) + { + print_vfs_message (_("ftpfs: couldn't resolve symlink")); + return; } - - fp = fdopen(sock, "r"); - if (fp == NULL) { - close(sock); - print_vfs_message(_("ftpfs: couldn't resolve symlink")); - return; + + fp = fdopen (sock, "r"); + if (fp == NULL) + { + close (sock); + print_vfs_message (_("ftpfs: couldn't resolve symlink")); + return; } tty_enable_interrupt_key (); flist = dir->file_list->next; - while (1) { - do { - if (flist == dir->file_list) - goto done; - fe = flist->data; - flist = flist->next; - } while (!S_ISLNK(fe->s.st_mode)); - while (1) { - if (fgets (buffer, sizeof (buffer), fp) == NULL) - goto done; - if (MEDATA->logfile){ - fputs (buffer, MEDATA->logfile); - fflush (MEDATA->logfile); - } - vfs_die("This code should be commented out\n"); - if (vfs_parse_ls_lga (buffer, &s, &filename, NULL)) { - int r = strcmp(fe->name, filename); - g_free(filename); - if (r == 0) { - if (S_ISLNK (s.st_mode)) { + while (1) + { + do + { + if (flist == dir->file_list) + goto done; + fe = flist->data; + flist = flist->next; + } + while (!S_ISLNK (fe->s.st_mode)); + while (1) + { + if (fgets (buffer, sizeof (buffer), fp) == NULL) + goto done; + if (MEDATA->logfile) + { + fputs (buffer, MEDATA->logfile); + fflush (MEDATA->logfile); + } + vfs_die ("This code should be commented out\n"); + if (vfs_parse_ls_lga (buffer, &s, &filename, NULL)) + { + int r = strcmp (fe->name, filename); + g_free (filename); + if (r == 0) + { + if (S_ISLNK (s.st_mode)) + { /* This server doesn't understand LIST -lLa */ switch_method = 1; goto done; } - fe->l_stat = g_new (struct stat, 1); - if (fe->l_stat == NULL) - goto done; - *fe->l_stat = s; + fe->l_stat = g_new (struct stat, 1); + if (fe->l_stat == NULL) + goto done; + *fe->l_stat = s; (*fe->l_stat).st_ino = bucket->__inode_counter++; - break; - } - if (r < 0) - break; - } - } + break; + } + if (r < 0) + break; + } + } } -done: - while (fgets(buffer, sizeof(buffer), fp) != NULL); + done: + while (fgets (buffer, sizeof (buffer), fp) != NULL); tty_disable_interrupt_key (); - fclose(fp); - ftpfs_get_reply(me, SUP.sock, NULL, 0); + fclose (fp); + ftpfs_get_reply (me, SUP.sock, NULL, 0); } static void -resolve_symlink(struct vfs_class *me, struct vfs_s_super *super, struct vfs_s_inode *dir) +resolve_symlink (struct vfs_class *me, struct vfs_s_super *super, struct vfs_s_inode *dir) { - print_vfs_message(_("Resolving symlink...")); + print_vfs_message (_("Resolving symlink...")); - if (SUP.strict_rfc959_list_cmd) - resolve_symlink_without_ls_options(me, super, dir); + if (SUP.strict_rfc959_list_cmd) + resolve_symlink_without_ls_options (me, super, dir); else - resolve_symlink_with_ls_options(me, super, dir); + resolve_symlink_with_ls_options (me, super, dir); } #endif @@ -1341,126 +1455,128 @@ ftpfs_dir_load (struct vfs_class *me, struct vfs_s_inode *dir, char *remote_path int cd_first; cd_first = ftpfs_first_cd_then_ls || (SUP.strict == RFC_STRICT) - || (strchr (remote_path, ' ') != NULL); + || (strchr (remote_path, ' ') != NULL); again: print_vfs_message (_("ftpfs: Reading FTP directory %s... %s%s"), - remote_path, - SUP.strict == - RFC_STRICT ? _("(strict rfc959)") : "", - cd_first ? _("(chdir first)") : ""); + remote_path, + SUP.strict == + RFC_STRICT ? _("(strict rfc959)") : "", cd_first ? _("(chdir first)") : ""); - if (cd_first) { - if (ftpfs_chdir_internal (me, super, remote_path) != COMPLETE) { - ftpfs_errno = ENOENT; - print_vfs_message (_("ftpfs: CWD failed.")); - return -1; - } + if (cd_first) + { + if (ftpfs_chdir_internal (me, super, remote_path) != COMPLETE) + { + ftpfs_errno = ENOENT; + print_vfs_message (_("ftpfs: CWD failed.")); + return -1; + } } gettimeofday (&dir->timestamp, NULL); dir->timestamp.tv_sec += ftpfs_directory_timeout; if (SUP.strict == RFC_STRICT) - sock = ftpfs_open_data_connection (me, super, "LIST", 0, TYPE_ASCII, 0); + sock = ftpfs_open_data_connection (me, super, "LIST", 0, TYPE_ASCII, 0); else if (cd_first) - /* Dirty hack to avoid autoprepending / to . */ - /* Wu-ftpd produces strange output for '/' if 'LIST -la .' used */ - sock = - ftpfs_open_data_connection (me, super, "LIST -la", 0, TYPE_ASCII, 0); - else { - /* Trailing "/." is necessary if remote_path is a symlink */ - char *path = concat_dir_and_file (remote_path, "."); - sock = - ftpfs_open_data_connection (me, super, "LIST -la", path, TYPE_ASCII, - 0); - g_free (path); + /* Dirty hack to avoid autoprepending / to . */ + /* Wu-ftpd produces strange output for '/' if 'LIST -la .' used */ + sock = ftpfs_open_data_connection (me, super, "LIST -la", 0, TYPE_ASCII, 0); + else + { + /* Trailing "/." is necessary if remote_path is a symlink */ + char *path = concat_dir_and_file (remote_path, "."); + sock = ftpfs_open_data_connection (me, super, "LIST -la", path, TYPE_ASCII, 0); + g_free (path); } if (sock == -1) - goto fallback; + goto fallback; /* Clear the interrupt flag */ tty_enable_interrupt_key (); - while (1) { - int i; - int res = - vfs_s_get_line_interruptible (me, buffer, sizeof (buffer), - sock); - if (!res) - break; + while (1) + { + int i; + int res = vfs_s_get_line_interruptible (me, buffer, sizeof (buffer), + sock); + if (!res) + break; - if (res == EINTR) { - me->verrno = ECONNRESET; - close (sock); - tty_disable_interrupt_key (); - ftpfs_get_reply (me, SUP.sock, NULL, 0); - print_vfs_message (_("%s: failure"), me->name); - return -1; - } + if (res == EINTR) + { + me->verrno = ECONNRESET; + close (sock); + tty_disable_interrupt_key (); + ftpfs_get_reply (me, SUP.sock, NULL, 0); + print_vfs_message (_("%s: failure"), me->name); + return -1; + } - if (MEDATA->logfile) { - fputs (buffer, MEDATA->logfile); - fputs ("\n", MEDATA->logfile); - fflush (MEDATA->logfile); - } + if (MEDATA->logfile) + { + fputs (buffer, MEDATA->logfile); + fputs ("\n", MEDATA->logfile); + fflush (MEDATA->logfile); + } - ent = vfs_s_generate_entry (me, NULL, dir, 0); - i = ent->ino->st.st_nlink; - if (!vfs_parse_ls_lga - (buffer, &ent->ino->st, &ent->name, &ent->ino->linkname)) { - vfs_s_free_entry (me, ent); - continue; - } - ent->ino->st.st_nlink = i; /* Ouch, we need to preserve our counts :-( */ - num_entries++; - vfs_s_insert_entry (me, dir, ent); + ent = vfs_s_generate_entry (me, NULL, dir, 0); + i = ent->ino->st.st_nlink; + if (!vfs_parse_ls_lga (buffer, &ent->ino->st, &ent->name, &ent->ino->linkname)) + { + vfs_s_free_entry (me, ent); + continue; + } + ent->ino->st.st_nlink = i; /* Ouch, we need to preserve our counts :-( */ + num_entries++; + vfs_s_insert_entry (me, dir, ent); } close (sock); me->verrno = E_REMOTE; if ((ftpfs_get_reply (me, SUP.sock, NULL, 0) != COMPLETE)) - goto fallback; + goto fallback; - if (num_entries == 0 && cd_first == 0) { - /* The LIST command may produce an empty output. In such scenario - it is not clear whether this is caused by `remote_path' being - a non-existent path or for some other reason (listing emtpy - directory without the -a option, non-readable directory, etc.). + if (num_entries == 0 && cd_first == 0) + { + /* The LIST command may produce an empty output. In such scenario + it is not clear whether this is caused by `remote_path' being + a non-existent path or for some other reason (listing emtpy + directory without the -a option, non-readable directory, etc.). - Since `dir_load' is a crucial method, when it comes to determine - whether a given path is a _directory_, the code must try its best - to determine the type of `remote_path'. The only reliable way to - achieve this is trough issuing a CWD command. */ + Since `dir_load' is a crucial method, when it comes to determine + whether a given path is a _directory_, the code must try its best + to determine the type of `remote_path'. The only reliable way to + achieve this is trough issuing a CWD command. */ - cd_first = 1; - goto again; + cd_first = 1; + goto again; } if (SUP.strict == RFC_AUTODETECT) - SUP.strict = RFC_DARING; + SUP.strict = RFC_DARING; print_vfs_message (_("%s: done."), me->name); return 0; fallback: - if (SUP.strict == RFC_AUTODETECT) { - /* It's our first attempt to get a directory listing from this - server (UNIX style LIST command) */ - SUP.strict = RFC_STRICT; - /* I hate goto, but recursive call needs another 8K on stack */ - /* return ftpfs_dir_load (me, dir, remote_path); */ - cd_first = 1; - goto again; + if (SUP.strict == RFC_AUTODETECT) + { + /* It's our first attempt to get a directory listing from this + server (UNIX style LIST command) */ + SUP.strict = RFC_STRICT; + /* I hate goto, but recursive call needs another 8K on stack */ + /* return ftpfs_dir_load (me, dir, remote_path); */ + cd_first = 1; + goto again; } print_vfs_message (_("ftpfs: failed; nowhere to fallback to")); ERRNOR (EACCES, -1); } static int -ftpfs_file_store (struct vfs_class *me, struct vfs_s_fh *fh, char *name, - char *localname) +ftpfs_file_store (struct vfs_class *me, struct vfs_s_fh *fh, char *name, char *localname) { int h, sock, n_read, n_written; off_t n_stored; @@ -1471,19 +1587,19 @@ ftpfs_file_store (struct vfs_class *me, struct vfs_s_fh *fh, char *name, #endif char buffer[8192]; struct stat s; - char *w_buf; + char *w_buf; struct vfs_s_super *super = FH_SUPER; h = open (localname, O_RDONLY); if (h == -1) - ERRNOR (EIO, -1); + ERRNOR (EIO, -1); sock = - ftpfs_open_data_connection (me, super, - fh->u.ftp.append ? "APPE" : "STOR", name, - TYPE_BINARY, 0); - if (sock < 0 || fstat (h, &s) == -1) { - close (h); - return -1; + ftpfs_open_data_connection (me, super, + fh->u.ftp.append ? "APPE" : "STOR", name, TYPE_BINARY, 0); + if (sock < 0 || fstat (h, &s) == -1) + { + close (h); + return -1; } #ifdef HAVE_STRUCT_LINGER_L_LINGER li.l_onoff = 1; @@ -1495,41 +1611,49 @@ ftpfs_file_store (struct vfs_class *me, struct vfs_s_fh *fh, char *name, n_stored = 0; tty_enable_interrupt_key (); - while (1) { - while ((n_read = read (h, buffer, sizeof (buffer))) == -1) { - if (errno == EINTR) { - if (tty_got_interrupt ()) { - ftpfs_errno = EINTR; - goto error_return; - } else - continue; - } - ftpfs_errno = errno; - goto error_return; - } - if (n_read == 0) - break; - n_stored += n_read; - w_buf = buffer; - while ((n_written = write (sock, w_buf, n_read)) != n_read) { - if (n_written == -1) { - if (errno == EINTR && !tty_got_interrupt ()) { - continue; - } - ftpfs_errno = errno; - goto error_return; - } - w_buf += n_written; - n_read -= n_written; - } - print_vfs_message (_("ftpfs: storing file %lu (%lu)"), - (unsigned long) n_stored, (unsigned long) s.st_size); + while (1) + { + while ((n_read = read (h, buffer, sizeof (buffer))) == -1) + { + if (errno == EINTR) + { + if (tty_got_interrupt ()) + { + ftpfs_errno = EINTR; + goto error_return; + } + else + continue; + } + ftpfs_errno = errno; + goto error_return; + } + if (n_read == 0) + break; + n_stored += n_read; + w_buf = buffer; + while ((n_written = write (sock, w_buf, n_read)) != n_read) + { + if (n_written == -1) + { + if (errno == EINTR && !tty_got_interrupt ()) + { + continue; + } + ftpfs_errno = errno; + goto error_return; + } + w_buf += n_written; + n_read -= n_written; + } + print_vfs_message (_("ftpfs: storing file %lu (%lu)"), + (unsigned long) n_stored, (unsigned long) s.st_size); } tty_disable_interrupt_key (); close (sock); close (h); if (ftpfs_get_reply (me, SUP.sock, NULL, 0) != COMPLETE) - ERRNOR (EIO, -1); + ERRNOR (EIO, -1); return 0; error_return: tty_disable_interrupt_key (); @@ -1539,17 +1663,17 @@ ftpfs_file_store (struct vfs_class *me, struct vfs_s_fh *fh, char *name, return -1; } -static int +static int ftpfs_linear_start (struct vfs_class *me, struct vfs_s_fh *fh, off_t offset) { char *name = vfs_s_fullpath (me, fh->ino); if (!name) - return 0; - FH_SOCK = ftpfs_open_data_connection(me, FH_SUPER, "RETR", name, TYPE_BINARY, offset); + return 0; + FH_SOCK = ftpfs_open_data_connection (me, FH_SUPER, "RETR", name, TYPE_BINARY, offset); g_free (name); if (FH_SOCK == -1) - ERRNOR (EACCES, 0); + ERRNOR (EACCES, 0); fh->linear = LS_LINEAR_OPEN; FH_SUPER->u.ftp.ctl_connection_busy = 1; fh->u.ftp.append = 0; @@ -1562,22 +1686,24 @@ ftpfs_linear_read (struct vfs_class *me, struct vfs_s_fh *fh, void *buf, int len int n; struct vfs_s_super *super = FH_SUPER; - while ((n = read (FH_SOCK, buf, len))<0) { + while ((n = read (FH_SOCK, buf, len)) < 0) + { if ((errno == EINTR) && !tty_got_interrupt ()) - continue; - break; + continue; + break; } - if (n<0) - ftpfs_linear_abort(me, fh); + if (n < 0) + ftpfs_linear_abort (me, fh); - if (!n) { - SUP.ctl_connection_busy = 0; - close (FH_SOCK); - FH_SOCK = -1; + if (!n) + { + SUP.ctl_connection_busy = 0; + close (FH_SOCK); + FH_SOCK = -1; if ((ftpfs_get_reply (me, SUP.sock, NULL, 0) != COMPLETE)) - ERRNOR (E_REMOTE, -1); - return 0; + ERRNOR (E_REMOTE, -1); + return 0; } ERRNOR (errno, n); } @@ -1586,70 +1712,74 @@ static void ftpfs_linear_close (struct vfs_class *me, struct vfs_s_fh *fh) { if (FH_SOCK != -1) - ftpfs_linear_abort(me, fh); + ftpfs_linear_abort (me, fh); } -static int ftpfs_ctl (void *fh, int ctlop, void *arg) +static int +ftpfs_ctl (void *fh, int ctlop, void *arg) { (void) arg; - switch (ctlop) { - case VFS_CTL_IS_NOTREADY: - { - int v; - - if (!FH->linear) - vfs_die ("You may not do this"); - if (FH->linear == LS_LINEAR_CLOSED || FH->linear == LS_LINEAR_PREOPEN) - return 0; + switch (ctlop) + { + case VFS_CTL_IS_NOTREADY: + { + int v; - v = vfs_s_select_on_two (FH->u.ftp.sock, 0); - if (((v < 0) && (errno == EINTR)) || v == 0) - return 1; - return 0; - } - default: - return 0; + if (!FH->linear) + vfs_die ("You may not do this"); + if (FH->linear == LS_LINEAR_CLOSED || FH->linear == LS_LINEAR_PREOPEN) + return 0; + + v = vfs_s_select_on_two (FH->u.ftp.sock, 0); + if (((v < 0) && (errno == EINTR)) || v == 0) + return 1; + return 0; + } + default: + return 0; } } static int -ftpfs_send_command(struct vfs_class *me, const char *filename, const char *cmd, int flags) +ftpfs_send_command (struct vfs_class *me, const char *filename, const char *cmd, int flags) { const char *rpath; - char *p, *mpath = g_strdup(filename); + char *p, *mpath = g_strdup (filename); struct vfs_s_super *super; int r; int flush_directory_cache = (flags & OPT_FLUSH); - if (!(rpath = vfs_s_get_path_mangle(me, mpath, &super, 0))) { - g_free(mpath); - return -1; + if (!(rpath = vfs_s_get_path_mangle (me, mpath, &super, 0))) + { + g_free (mpath); + return -1; } p = ftpfs_translate_path (me, super, rpath); r = ftpfs_command (me, super, WAIT_REPLY, cmd, p); g_free (p); vfs_stamp_create (&vfs_ftpfs_ops, super); if (flags & OPT_IGNORE_ERROR) - r = COMPLETE; - if (r != COMPLETE) { + r = COMPLETE; + if (r != COMPLETE) + { me->verrno = EPERM; g_free (mpath); return -1; } if (flush_directory_cache) - vfs_s_invalidate(me, super); - g_free(mpath); + vfs_s_invalidate (me, super); + g_free (mpath); return 0; } /* This routine is called as the last step in load_setup */ void -ftpfs_init_passwd(void) +ftpfs_init_passwd (void) { ftpfs_anonymous_passwd = load_anon_passwd (); if (ftpfs_anonymous_passwd) - return; + return; /* If there is no anonymous ftp password specified * then we'll just use anonymous@ @@ -1662,42 +1792,45 @@ ftpfs_init_passwd(void) ftpfs_anonymous_passwd = g_strdup ("anonymous@"); } -static int ftpfs_chmod (struct vfs_class *me, const char *path, int mode) +static int +ftpfs_chmod (struct vfs_class *me, const char *path, int mode) { char buf[BUF_SMALL]; int ret; - g_snprintf(buf, sizeof(buf), "SITE CHMOD %4.4o /%%s", mode & 07777); + g_snprintf (buf, sizeof (buf), "SITE CHMOD %4.4o /%%s", mode & 07777); - ret = ftpfs_send_command(me, path, buf, OPT_FLUSH); + ret = ftpfs_send_command (me, path, buf, OPT_FLUSH); - if ( mc_config_get_bool (mc_main_config, CONFIG_APP_SECTION, - "ignore_ftp_chattr_errors", TRUE)) { + if (mc_config_get_bool (mc_main_config, CONFIG_APP_SECTION, "ignore_ftp_chattr_errors", TRUE)) + { return 0; } return ret; } -static int ftpfs_chown (struct vfs_class *me, const char *path, int owner, int group) +static int +ftpfs_chown (struct vfs_class *me, const char *path, int owner, int group) { #if 0 ftpfs_errno = EPERM; return -1; #else -/* Everyone knows it is not possible to chown remotely, so why bother them. - If someone's root, then copy/move will always try to chown it... */ + /* Everyone knows it is not possible to chown remotely, so why bother them. + If someone's root, then copy/move will always try to chown it... */ (void) me; (void) path; (void) owner; (void) group; return 0; -#endif +#endif } -static int ftpfs_unlink (struct vfs_class *me, const char *path) +static int +ftpfs_unlink (struct vfs_class *me, const char *path) { - return ftpfs_send_command(me, path, "DELE /%s", OPT_FLUSH); + return ftpfs_send_command (me, path, "DELE /%s", OPT_FLUSH); } /* Return 1 if path is the same directory as the one we are in now */ @@ -1707,9 +1840,9 @@ ftpfs_is_same_dir (struct vfs_class *me, struct vfs_s_super *super, const char * (void) me; if (!SUP.cwdir) - return 0; + return 0; if (strcmp (path, SUP.cwdir) == 0) - return 1; + return 1; return 0; } @@ -1718,118 +1851,128 @@ ftpfs_chdir_internal (struct vfs_class *me, struct vfs_s_super *super, const cha { int r; char *p; - + if (!SUP.cwd_deferred && ftpfs_is_same_dir (me, super, remote_path)) - return COMPLETE; + return COMPLETE; p = ftpfs_translate_path (me, super, remote_path); r = ftpfs_command (me, super, WAIT_REPLY, "CWD /%s", p); g_free (p); - if (r != COMPLETE) { - ftpfs_errno = EIO; - } else { - g_free(SUP.cwdir); - SUP.cwdir = g_strdup (remote_path); - SUP.cwd_deferred = 0; + if (r != COMPLETE) + { + ftpfs_errno = EIO; + } + else + { + g_free (SUP.cwdir); + SUP.cwdir = g_strdup (remote_path); + SUP.cwd_deferred = 0; } return r; } -static int ftpfs_rename (struct vfs_class *me, const char *path1, const char *path2) +static int +ftpfs_rename (struct vfs_class *me, const char *path1, const char *path2) { - ftpfs_send_command(me, path1, "RNFR /%s", OPT_FLUSH); - return ftpfs_send_command(me, path2, "RNTO /%s", OPT_FLUSH); -} - -static int ftpfs_mkdir (struct vfs_class *me, const char *path, mode_t mode) -{ - (void) mode; /* FIXME: should be used */ - - return ftpfs_send_command(me, path, "MKD /%s", OPT_FLUSH); -} - -static int ftpfs_rmdir (struct vfs_class *me, const char *path) -{ - return ftpfs_send_command(me, path, "RMD /%s", OPT_FLUSH); + ftpfs_send_command (me, path1, "RNFR /%s", OPT_FLUSH); + return ftpfs_send_command (me, path2, "RNTO /%s", OPT_FLUSH); } static int -ftpfs_fh_open (struct vfs_class *me, struct vfs_s_fh *fh, int flags, - int mode) +ftpfs_mkdir (struct vfs_class *me, const char *path, mode_t mode) +{ + (void) mode; /* FIXME: should be used */ + + return ftpfs_send_command (me, path, "MKD /%s", OPT_FLUSH); +} + +static int +ftpfs_rmdir (struct vfs_class *me, const char *path) +{ + return ftpfs_send_command (me, path, "RMD /%s", OPT_FLUSH); +} + +static int +ftpfs_fh_open (struct vfs_class *me, struct vfs_s_fh *fh, int flags, int mode) { (void) mode; fh->u.ftp.append = 0; /* File will be written only, so no need to retrieve it from ftp server */ - if (((flags & O_WRONLY) == O_WRONLY) && !(flags & (O_RDONLY | O_RDWR))) { + if (((flags & O_WRONLY) == O_WRONLY) && !(flags & (O_RDONLY | O_RDWR))) + { #ifdef HAVE_STRUCT_LINGER_L_LINGER - struct linger li; + struct linger li; #else - int li = 1; + int li = 1; #endif - char *name; + char *name; - /* ftpfs_linear_start() called, so data will be written - * to local temporary file and stored to ftp server - * by vfs_s_close later - */ - if (FH_SUPER->u.ftp.ctl_connection_busy) { - if (!fh->ino->localname) { - int handle = vfs_mkstemps (&fh->ino->localname, me->name, - fh->ino->ent->name); - if (handle == -1) - return -1; - close (handle); - fh->u.ftp.append = flags & O_APPEND; - } - return 0; - } - name = vfs_s_fullpath (me, fh->ino); - if (!name) - return -1; - fh->handle = - ftpfs_open_data_connection (me, fh->ino->super, - (flags & O_APPEND) ? "APPE" : - "STOR", name, TYPE_BINARY, 0); - g_free (name); + /* ftpfs_linear_start() called, so data will be written + * to local temporary file and stored to ftp server + * by vfs_s_close later + */ + if (FH_SUPER->u.ftp.ctl_connection_busy) + { + if (!fh->ino->localname) + { + int handle = vfs_mkstemps (&fh->ino->localname, me->name, + fh->ino->ent->name); + if (handle == -1) + return -1; + close (handle); + fh->u.ftp.append = flags & O_APPEND; + } + return 0; + } + name = vfs_s_fullpath (me, fh->ino); + if (!name) + return -1; + fh->handle = + ftpfs_open_data_connection (me, fh->ino->super, + (flags & O_APPEND) ? "APPE" : "STOR", name, TYPE_BINARY, 0); + g_free (name); - if (fh->handle < 0) - return -1; + if (fh->handle < 0) + return -1; #ifdef HAVE_STRUCT_LINGER_L_LINGER - li.l_onoff = 1; - li.l_linger = 120; + li.l_onoff = 1; + li.l_linger = 120; #endif - setsockopt (fh->handle, SOL_SOCKET, SO_LINGER, &li, sizeof (li)); + setsockopt (fh->handle, SOL_SOCKET, SO_LINGER, &li, sizeof (li)); - if (fh->ino->localname) { - unlink (fh->ino->localname); - g_free (fh->ino->localname); - fh->ino->localname = NULL; - } - return 0; + if (fh->ino->localname) + { + unlink (fh->ino->localname); + g_free (fh->ino->localname); + fh->ino->localname = NULL; + } + return 0; } if (!fh->ino->localname) - if (vfs_s_retrieve_file (me, fh->ino) == -1) - return -1; + if (vfs_s_retrieve_file (me, fh->ino) == -1) + return -1; if (!fh->ino->localname) - vfs_die ("retrieve_file failed to fill in localname"); + vfs_die ("retrieve_file failed to fill in localname"); return 0; } -static int ftpfs_fh_close (struct vfs_class *me, struct vfs_s_fh *fh) +static int +ftpfs_fh_close (struct vfs_class *me, struct vfs_s_fh *fh) { - if (fh->handle != -1 && !fh->ino->localname){ - close (fh->handle); - fh->handle = -1; - /* File is stored to destination already, so - * we prevent MEDATA->ftpfs_file_store() call from vfs_s_close () - */ - fh->changed = 0; - if (ftpfs_get_reply (me, fh->ino->SUP.sock, NULL, 0) != COMPLETE) - ERRNOR (EIO, -1); - vfs_s_invalidate (me, FH_SUPER); + if (fh->handle != -1 && !fh->ino->localname) + { + close (fh->handle); + fh->handle = -1; + /* File is stored to destination already, so + * we prevent MEDATA->ftpfs_file_store() call from vfs_s_close () + */ + fh->changed = 0; + if (ftpfs_get_reply (me, fh->ino->SUP.sock, NULL, 0) != COMPLETE) + ERRNOR (EIO, -1); + vfs_s_invalidate (me, FH_SUPER); } return 0; } @@ -1841,11 +1984,12 @@ ftpfs_done (struct vfs_class *me) (void) me; - while (no_proxy) { - np = no_proxy->next; - g_free (no_proxy->domain); - g_free (no_proxy); - no_proxy = np; + while (no_proxy) + { + np = no_proxy->next; + g_free (no_proxy->domain); + g_free (no_proxy); + no_proxy = np; } g_free (ftpfs_anonymous_passwd); g_free (ftpfs_proxy_host); @@ -1856,12 +2000,13 @@ ftpfs_fill_names (struct vfs_class *me, fill_names_f func) { struct vfs_s_super *super = MEDATA->supers; char *name; - - while (super){ - name = g_strconcat ("/#ftp:", SUP.user, "@", SUP.host, "/", SUP.cwdir, (char *) NULL); - (*func)(name); - g_free (name); - super = super->next; + + while (super) + { + name = g_strconcat ("/#ftp:", SUP.user, "@", SUP.host, "/", SUP.cwdir, (char *) NULL); + (*func) (name); + g_free (name); + super = super->next; } } @@ -1870,7 +2015,8 @@ static char *netrc; static const char *netrcp; /* This should match the keywords[] array below */ -typedef enum { +typedef enum +{ NETRC_NONE = 0, NETRC_DEFAULT, NETRC_MACHINE, @@ -1882,66 +2028,76 @@ typedef enum { NETRC_UNKNOWN } keyword_t; -static keyword_t ftpfs_netrc_next (void) +static keyword_t +ftpfs_netrc_next (void) { char *p; keyword_t i; static const char *const keywords[] = { "default", "machine", - "login", "password", "passwd", "account", "macdef", NULL + "login", "password", "passwd", "account", "macdef", NULL }; - while (1) { - netrcp = skip_separators (netrcp); - if (*netrcp != '\n') - break; - netrcp++; + while (1) + { + netrcp = skip_separators (netrcp); + if (*netrcp != '\n') + break; + netrcp++; } if (!*netrcp) - return NETRC_NONE; + return NETRC_NONE; p = buffer; - if (*netrcp == '"') { - for (netrcp++; *netrcp != '"' && *netrcp; netrcp++) { - if (*netrcp == '\\') - netrcp++; - *p++ = *netrcp; - } - } else { - for (; *netrcp != '\n' && *netrcp != '\t' && *netrcp != ' ' && - *netrcp != ',' && *netrcp; netrcp++) { - if (*netrcp == '\\') - netrcp++; - *p++ = *netrcp; - } + if (*netrcp == '"') + { + for (netrcp++; *netrcp != '"' && *netrcp; netrcp++) + { + if (*netrcp == '\\') + netrcp++; + *p++ = *netrcp; + } + } + else + { + for (; *netrcp != '\n' && *netrcp != '\t' && *netrcp != ' ' && + *netrcp != ',' && *netrcp; netrcp++) + { + if (*netrcp == '\\') + netrcp++; + *p++ = *netrcp; + } } *p = 0; if (!*buffer) - return NETRC_NONE; + return NETRC_NONE; i = NETRC_DEFAULT; - while (keywords[i - 1]) { - if (!strcmp (keywords[i - 1], buffer)) - return i; + while (keywords[i - 1]) + { + if (!strcmp (keywords[i - 1], buffer)) + return i; - i++; + i++; } return NETRC_UNKNOWN; } -static int ftpfs_netrc_bad_mode (const char *netrcname) +static int +ftpfs_netrc_bad_mode (const char *netrcname) { static int be_angry = 1; struct stat mystat; - if (stat (netrcname, &mystat) >= 0 && (mystat.st_mode & 077)) { - if (be_angry) { - message (D_ERROR, MSG_ERROR, - _("~/.netrc file has incorrect mode.\n" - "Remove password or correct mode.")); - be_angry = 0; - } - return 1; + if (stat (netrcname, &mystat) >= 0 && (mystat.st_mode & 077)) + { + if (be_angry) + { + message (D_ERROR, MSG_ERROR, + _("~/.netrc file has incorrect mode.\n" "Remove password or correct mode.")); + be_angry = 0; + } + return 1; } return 0; } @@ -1950,52 +2106,60 @@ static int ftpfs_netrc_bad_mode (const char *netrcname) * domain is used for additional matching * No search is done after "default" in compliance with "man netrc" * Return 0 if found, -1 otherwise */ -static int ftpfs_find_machine (const char *host, const char *domain) +static int +ftpfs_find_machine (const char *host, const char *domain) { keyword_t keyword; - if (!host) host = ""; - if (!domain) domain = ""; + if (!host) + host = ""; + if (!domain) + domain = ""; - while ((keyword = ftpfs_netrc_next ()) != NETRC_NONE) { - if (keyword == NETRC_DEFAULT) - return 0; + while ((keyword = ftpfs_netrc_next ()) != NETRC_NONE) + { + if (keyword == NETRC_DEFAULT) + return 0; - if (keyword == NETRC_MACDEF) { - /* Scan for an empty line, which concludes "macdef" */ - do { - while (*netrcp && *netrcp != '\n') - netrcp++; - if (*netrcp != '\n') - break; - netrcp++; - } while (*netrcp && *netrcp != '\n'); - continue; - } + if (keyword == NETRC_MACDEF) + { + /* Scan for an empty line, which concludes "macdef" */ + do + { + while (*netrcp && *netrcp != '\n') + netrcp++; + if (*netrcp != '\n') + break; + netrcp++; + } + while (*netrcp && *netrcp != '\n'); + continue; + } - if (keyword != NETRC_MACHINE) - continue; + if (keyword != NETRC_MACHINE) + continue; - /* Take machine name */ - if (ftpfs_netrc_next () == NETRC_NONE) - break; + /* Take machine name */ + if (ftpfs_netrc_next () == NETRC_NONE) + break; - if (g_strcasecmp (host, buffer)) { - /* Try adding our domain to short names in .netrc */ - const char *host_domain = strchr (host, '.'); - if (!host_domain) - continue; + if (g_strcasecmp (host, buffer)) + { + /* Try adding our domain to short names in .netrc */ + const char *host_domain = strchr (host, '.'); + if (!host_domain) + continue; - /* Compare domain part */ - if (g_strcasecmp (host_domain, domain)) - continue; + /* Compare domain part */ + if (g_strcasecmp (host_domain, domain)) + continue; - /* Compare local part */ - if (g_strncasecmp (host, buffer, host_domain - host)) - continue; - } + /* Compare local part */ + if (g_strncasecmp (host, buffer, host_domain - host)) + continue; + } - return 0; + return 0; } /* end of .netrc */ @@ -2005,115 +2169,127 @@ static int ftpfs_find_machine (const char *host, const char *domain) /* Extract login and password from .netrc for the host. * pass may be NULL. * Returns 0 for success, -1 for error */ -static int ftpfs_netrc_lookup (const char *host, char **login, char **pass) +static int +ftpfs_netrc_lookup (const char *host, char **login, char **pass) { char *netrcname; char *tmp_pass = NULL; char hostname[MAXHOSTNAMELEN]; const char *domain; keyword_t keyword; - static struct rupcache { - struct rupcache *next; - char *host; - char *login; - char *pass; + static struct rupcache + { + struct rupcache *next; + char *host; + char *login; + char *pass; } *rup_cache = NULL, *rupp; /* Initialize *login and *pass */ if (!login) - return 0; + return 0; *login = NULL; if (pass) - *pass = NULL; + *pass = NULL; /* Look up in the cache first */ - for (rupp = rup_cache; rupp != NULL; rupp = rupp->next) { - if (!strcmp (host, rupp->host)) { - if (rupp->login) - *login = g_strdup (rupp->login); - if (pass && rupp->pass) - *pass = g_strdup (rupp->pass); - return 0; - } + for (rupp = rup_cache; rupp != NULL; rupp = rupp->next) + { + if (!strcmp (host, rupp->host)) + { + if (rupp->login) + *login = g_strdup (rupp->login); + if (pass && rupp->pass) + *pass = g_strdup (rupp->pass); + return 0; + } } /* Load current .netrc */ netrcname = concat_dir_and_file (home_dir, ".netrc"); netrcp = netrc = load_file (netrcname); - if (netrc == NULL) { - g_free (netrcname); - return 0; + if (netrc == NULL) + { + g_free (netrcname); + return 0; } /* Find our own domain name */ if (gethostname (hostname, sizeof (hostname)) < 0) - *hostname = 0; + *hostname = 0; if (!(domain = strchr (hostname, '.'))) - domain = ""; + domain = ""; /* Scan for "default" and matching "machine" keywords */ ftpfs_find_machine (host, domain); /* Scan for keywords following "default" and "machine" */ - while (1) { - int need_break = 0; - keyword = ftpfs_netrc_next (); + while (1) + { + int need_break = 0; + keyword = ftpfs_netrc_next (); - switch (keyword) { - case NETRC_LOGIN: - if (ftpfs_netrc_next () == NETRC_NONE) { - need_break = 1; - break; - } + switch (keyword) + { + case NETRC_LOGIN: + if (ftpfs_netrc_next () == NETRC_NONE) + { + need_break = 1; + break; + } - /* We have another name already - should not happen */ - if (*login) { - need_break = 1; - break; - } + /* We have another name already - should not happen */ + if (*login) + { + need_break = 1; + break; + } - /* We have login name now */ - *login = g_strdup (buffer); - break; + /* We have login name now */ + *login = g_strdup (buffer); + break; - case NETRC_PASSWORD: - case NETRC_PASSWD: - if (ftpfs_netrc_next () == NETRC_NONE) { - need_break = 1; - break; - } + case NETRC_PASSWORD: + case NETRC_PASSWD: + if (ftpfs_netrc_next () == NETRC_NONE) + { + need_break = 1; + break; + } - /* Ignore unsafe passwords */ - if (strcmp (*login, "anonymous") && strcmp (*login, "ftp") - && ftpfs_netrc_bad_mode (netrcname)) { - need_break = 1; - break; - } + /* Ignore unsafe passwords */ + if (strcmp (*login, "anonymous") && strcmp (*login, "ftp") + && ftpfs_netrc_bad_mode (netrcname)) + { + need_break = 1; + break; + } - /* Remember password. pass may be NULL, so use tmp_pass */ - if (tmp_pass == NULL) - tmp_pass = g_strdup (buffer); - break; + /* Remember password. pass may be NULL, so use tmp_pass */ + if (tmp_pass == NULL) + tmp_pass = g_strdup (buffer); + break; - case NETRC_ACCOUNT: - /* "account" is followed by a token which we ignore */ - if (ftpfs_netrc_next () == NETRC_NONE) { - need_break = 1; - break; - } + case NETRC_ACCOUNT: + /* "account" is followed by a token which we ignore */ + if (ftpfs_netrc_next () == NETRC_NONE) + { + need_break = 1; + break; + } - /* Ignore account, but warn user anyways */ - ftpfs_netrc_bad_mode (netrcname); - break; + /* Ignore account, but warn user anyways */ + ftpfs_netrc_bad_mode (netrcname); + break; - default: - /* Unexpected keyword or end of file */ - need_break = 1; - break; - } + default: + /* Unexpected keyword or end of file */ + need_break = 1; + break; + } - if (need_break) - break; + if (need_break) + break; } g_free (netrc); @@ -2123,16 +2299,17 @@ static int ftpfs_netrc_lookup (const char *host, char **login, char **pass) rupp->host = g_strdup (host); rupp->login = rupp->pass = 0; - if (*login != NULL) { - rupp->login = g_strdup (*login); + if (*login != NULL) + { + rupp->login = g_strdup (*login); } if (tmp_pass != NULL) - rupp->pass = g_strdup (tmp_pass); + rupp->pass = g_strdup (tmp_pass); rupp->next = rup_cache; rup_cache = rupp; if (pass) - *pass = tmp_pass; + *pass = tmp_pass; return 0; } @@ -2142,7 +2319,7 @@ init_ftpfs (void) { static struct vfs_s_subclass ftpfs_subclass; - tcp_init(); + tcp_init (); ftpfs_subclass.flags = VFS_S_REMOTE; ftpfs_subclass.archive_same = ftpfs_archive_same; diff --git a/lib/vfs/mc-vfs/mcfsutil.c b/lib/vfs/mc-vfs/mcfsutil.c index 28fd4f341..e3bf089ec 100644 --- a/lib/vfs/mc-vfs/mcfsutil.c +++ b/lib/vfs/mc-vfs/mcfsutil.c @@ -1,12 +1,12 @@ /* Low-level protocol for MCFS. - + Copyright (C) 1995, 1996 Miguel de Icaza - + This program 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 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 @@ -51,12 +51,12 @@ #include #include "lib/global.h" -#include "src/wtools.h" /* message() */ -#include "src/main.h" /* print_vfs_message */ +#include "src/wtools.h" /* message() */ +#include "src/main.h" /* print_vfs_message */ #include "utilvfs.h" #include "mcfsutil.h" #include "netutil.h" -#include "mcfs.h" /* tcp_invalidate_socket() */ +#include "mcfs.h" /* tcp_invalidate_socket() */ #define CHECK_SIG_PIPE(sock) if (got_sigpipe) \ { tcp_invalidate_socket (sock); return got_sigpipe = 0; } @@ -68,13 +68,15 @@ socket_read_block (int sock, char *dest, int len) { int nread, n; - for (nread = 0; nread < len;) { - n = read (sock, dest + nread, len - nread); - if (n <= 0) { - tcp_invalidate_socket (sock); - return 0; - } - nread += n; + for (nread = 0; nread < len;) + { + n = read (sock, dest + nread, len - nread); + if (n <= 0) + { + tcp_invalidate_socket (sock); + return 0; + } + nread += n; } return 1; } @@ -84,13 +86,14 @@ socket_write_block (int sock, const char *buffer, int len) { int left, status; - for (left = len; left > 0;) { - status = write (sock, buffer, left); - CHECK_SIG_PIPE (sock); - if (status < 0) - return 0; - left -= status; - buffer += status; + for (left = len; left > 0;) + { + status = write (sock, buffer, left); + CHECK_SIG_PIPE (sock); + if (status < 0) + return 0; + left -= status; + buffer += status; } return 1; } @@ -104,40 +107,58 @@ rpc_send (int sock, ...) va_start (ap, sock); - for (;;) { - cmd = va_arg (ap, int); - switch (cmd) { - case RPC_END: - va_end (ap); - return 1; + for (;;) + { + cmd = va_arg (ap, int); + switch (cmd) + { + case RPC_END: + va_end (ap); + return 1; - case RPC_INT: - tmp = htonl (va_arg (ap, int)); - write (sock, &tmp, sizeof (tmp)); - CHECK_SIG_PIPE (sock); - break; + case RPC_INT: + tmp = htonl (va_arg (ap, int)); + if (write (sock, &tmp, sizeof (tmp)) != sizeof (tmp)) + { + vfs_die ("RPC: write failed (RPC_INT)"); + break; + } + CHECK_SIG_PIPE (sock); + break; - case RPC_STRING: - text = va_arg (ap, char *); - len = strlen (text); - tmp = htonl (len); - write (sock, &tmp, sizeof (tmp)); - CHECK_SIG_PIPE (sock); - write (sock, text, len); - CHECK_SIG_PIPE (sock); - break; + case RPC_STRING: + text = va_arg (ap, char *); + len = strlen (text); + tmp = htonl (len); + if (write (sock, &tmp, sizeof (tmp)) != sizeof (tmp)) + { + vfs_die ("RPC: write failed (RPC_STRING)"); + break; + } + CHECK_SIG_PIPE (sock); + if (write (sock, text, len) != len) + { + vfs_die ("RPC: write failed (RPC_STRING)"); + break; + } + CHECK_SIG_PIPE (sock); + break; - case RPC_BLOCK: - len = va_arg (ap, int); - text = va_arg (ap, char *); - tmp = htonl (len); - write (sock, text, len); - CHECK_SIG_PIPE (sock); - break; + case RPC_BLOCK: + len = va_arg (ap, int); + text = va_arg (ap, char *); + tmp = htonl (len); + if (write (sock, text, len) != len) + { + vfs_die ("RPC: write failed (RPC_BLOCK)"); + break; + } + CHECK_SIG_PIPE (sock); + break; - default: - vfs_die ("Unknown rpc message\n"); - } + default: + vfs_die ("Unknown rpc message\n"); + } } } @@ -151,63 +172,70 @@ rpc_get (int sock, ...) va_start (ap, sock); - for (;;) { - cmd = va_arg (ap, int); - switch (cmd) { - case RPC_END: - va_end (ap); - return 1; + for (;;) + { + cmd = va_arg (ap, int); + switch (cmd) + { + case RPC_END: + va_end (ap); + return 1; - case RPC_INT: - if (socket_read_block (sock, (char *) &tmp, sizeof (tmp)) == 0) { - va_end (ap); - return 0; - } - dest = va_arg (ap, int *); - *dest = ntohl (tmp); - break; + case RPC_INT: + if (socket_read_block (sock, (char *) &tmp, sizeof (tmp)) == 0) + { + va_end (ap); + return 0; + } + dest = va_arg (ap, int *); + *dest = ntohl (tmp); + break; - /* returns an allocated string */ - case RPC_LIMITED_STRING: - case RPC_STRING: - if (socket_read_block (sock, (char *) &tmp, sizeof (tmp)) == 0) { - va_end (ap); - return 0; - } - len = ntohl (tmp); - if (cmd == RPC_LIMITED_STRING) - if (len > 16 * 1024) { - /* silently die */ - abort (); - } - if (len > 128 * 1024) - abort (); + /* returns an allocated string */ + case RPC_LIMITED_STRING: + case RPC_STRING: + if (socket_read_block (sock, (char *) &tmp, sizeof (tmp)) == 0) + { + va_end (ap); + return 0; + } + len = ntohl (tmp); + if (cmd == RPC_LIMITED_STRING) + if (len > 16 * 1024) + { + /* silently die */ + abort (); + } + if (len > 128 * 1024) + abort (); - /* Don't use glib functions here - this code is used by mcserv */ - text = malloc (len + 1); - if (socket_read_block (sock, text, len) == 0) { - free (text); - va_end (ap); - return 0; - } - text[len] = '\0'; + /* Don't use glib functions here - this code is used by mcserv */ + text = malloc (len + 1); + if (socket_read_block (sock, text, len) == 0) + { + free (text); + va_end (ap); + return 0; + } + text[len] = '\0'; - str_dest = va_arg (ap, char **); - *str_dest = text; - break; + str_dest = va_arg (ap, char **); + *str_dest = text; + break; - case RPC_BLOCK: - len = va_arg (ap, int); - text = va_arg (ap, char *); - if (socket_read_block (sock, text, len) == 0) { - va_end (ap); - return 0; - } - break; + case RPC_BLOCK: + len = va_arg (ap, int); + text = va_arg (ap, char *); + if (socket_read_block (sock, text, len) == 0) + { + va_end (ap); + return 0; + } + break; - default: - vfs_die ("Unknown rpc message\n"); - } + default: + vfs_die ("Unknown rpc message\n"); + } } } -#endif /* ENABLE_VFS_MCFS || ENABLE_MCSERVER */ +#endif /* ENABLE_VFS_MCFS || ENABLE_MCSERVER */ diff --git a/lib/vfs/mc-vfs/samba/lib/util.c b/lib/vfs/mc-vfs/samba/lib/util.c index 98df37ae8..272b9df3d 100644 --- a/lib/vfs/mc-vfs/samba/lib/util.c +++ b/lib/vfs/mc-vfs/samba/lib/util.c @@ -3,21 +3,21 @@ Version 1.9. Samba utility functions Copyright (C) Andrew Tridgell 1992-1998 - + 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ + */ #include "includes.h" @@ -53,10 +53,10 @@ #ifdef WITH_SSL #include -#undef Realloc /* SSLeay defines this and samba has a function of this name */ -extern SSL *ssl; -extern int sslFd; -#endif /* WITH_SSL */ +#undef Realloc /* SSLeay defines this and samba has a function of this name */ +extern SSL *ssl; +extern int sslFd; +#endif /* WITH_SSL */ extern int DEBUGLEVEL; #if 0 @@ -64,7 +64,7 @@ int Protocol = PROTOCOL_COREPLUS; #endif /*0 */ /* a default finfo structure to ensure all fields are sensible */ -file_info const def_finfo = {-1,0,0,0,0,0,0,""}; +file_info const def_finfo = { -1, 0, 0, 0, 0, 0, 0, "" }; /* the client file descriptor */ extern int Client; @@ -77,7 +77,7 @@ int trans_num = 0; /* case handling on filenames -*/ + */ const int case_default = CASE_LOWER; #if 0 @@ -97,11 +97,11 @@ static const char *remote_arch = "UNKNOWN"; static enum remote_arch_types ra_type = RA_UNKNOWN; #endif static const char *remote_proto = "UNKNOWN"; -pstring myhostname=""; -pstring user_socket_options=""; +pstring myhostname = ""; +pstring user_socket_options = ""; -pstring sesssetup_user=""; -static const char * const samlogon_user = ""; +pstring sesssetup_user = ""; +static const char *const samlogon_user = ""; const BOOL sam_logon_in_ssb = False; @@ -115,96 +115,103 @@ char **my_netbios_names; find a suitable temporary directory. The result should be copied immediately as it may be overwritten by a subsequent call ****************************************************************************/ -const char *tmpdir(void) +const char * +tmpdir (void) { - char *p; - if ((p = getenv("MC_TMPDIR")) || (p = getenv("TMPDIR"))) { - return p; - } - return "/tmp"; + char *p; + if ((p = getenv ("MC_TMPDIR")) || (p = getenv ("TMPDIR"))) + { + return p; + } + return "/tmp"; } /**************************************************************************** determine whether we are in the specified group ****************************************************************************/ #if 0 -BOOL in_group(gid_t group, gid_t current_gid, int ngroups, gid_t *groups) +BOOL +in_group (gid_t group, gid_t current_gid, int ngroups, gid_t * groups) { - int i; + int i; - if (group == current_gid) return(True); + if (group == current_gid) + return (True); - for (i=0;i= 0; i--) - { - if (netbios_name[i] == '.') - { - netbios_name[i] = 0; - break; - } - } + /* ok. this is because of a stupid microsoft-ism. if the called host + name contains a '.', microsoft clients expect you to truncate the + netbios name up to and including the '.' this even applies, by + mistake, to workgroup (domain) names, which is _really_ daft. + */ + for (i = 15; i >= 0; i--) + { + if (netbios_name[i] == '.') + { + netbios_name[i] = 0; + break; + } + } #endif /* TRUNCATE_NETBIOS_NAME */ - return netbios_name; + return netbios_name; } /**************************************************************************** interpret the weird netbios "name". Return the name type ****************************************************************************/ -static int name_interpret(char *in,char *out) +static int +name_interpret (char *in, char *out) { - int ret; - int len = (*in++) / 2; + int ret; + int len = (*in++) / 2; - *out=0; + *out = 0; - if (len > 30 || len<1) return(0); + if (len > 30 || len < 1) + return (0); - while (len--) + while (len--) { - if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') { - *out = 0; - return(0); - } - *out = ((in[0]-'A')<<4) + (in[1]-'A'); - in += 2; - out++; + if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') + { + *out = 0; + return (0); + } + *out = ((in[0] - 'A') << 4) + (in[1] - 'A'); + in += 2; + out++; } - *out = 0; - ret = out[-1]; + *out = 0; + ret = out[-1]; #ifdef NETBIOS_SCOPE - /* Handle any scope names */ - while(*in) + /* Handle any scope names */ + while (*in) { - *out++ = '.'; /* Scope names are separated by periods */ - len = *(unsigned char *)in++; - StrnCpy(out, in, len); - out += len; - *out=0; - in += len; + *out++ = '.'; /* Scope names are separated by periods */ + len = *(unsigned char *) in++; + StrnCpy (out, in, len); + out += len; + *out = 0; + in += len; } #endif - return(ret); + return (ret); } #endif /* 0 */ @@ -294,350 +305,378 @@ mangle a name into netbios format Note: must be (33 + strlen(scope) + 2) bytes long, at minimum. ****************************************************************************/ -int name_mangle( char *In, char *Out, char name_type ) - { - int i; - int c; - int len; - char buf[20]; - char *p = Out; - extern pstring global_scope; +int +name_mangle (char *In, char *Out, char name_type) +{ + int i; + int c; + int len; + char buf[20]; + char *p = Out; + extern pstring global_scope; - /* Safely copy the input string, In, into buf[]. */ - (void)memset( buf, 0, 20 ); - if (strcmp(In,"*") == 0) - buf[0] = '*'; - else - (void)slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type ); + /* Safely copy the input string, In, into buf[]. */ + (void) memset (buf, 0, 20); + if (strcmp (In, "*") == 0) + buf[0] = '*'; + else + (void) slprintf (buf, sizeof (buf) - 1, "%-15.15s%c", In, name_type); - /* Place the length of the first field into the output buffer. */ - p[0] = 32; - p++; + /* Place the length of the first field into the output buffer. */ + p[0] = 32; + p++; - /* Now convert the name to the rfc1001/1002 format. */ - for( i = 0; i < 16; i++ ) + /* Now convert the name to the rfc1001/1002 format. */ + for (i = 0; i < 16; i++) { - c = toupper( buf[i] ); - p[i*2] = ( (c >> 4) & 0x000F ) + 'A'; - p[(i*2)+1] = (c & 0x000F) + 'A'; + c = toupper (buf[i]); + p[i * 2] = ((c >> 4) & 0x000F) + 'A'; + p[(i * 2) + 1] = (c & 0x000F) + 'A'; } - p += 32; - p[0] = '\0'; + p += 32; + p[0] = '\0'; - /* Add the scope string. */ - for( i = 0, len = 0; NULL != global_scope; i++, len++ ) + /* Add the scope string. */ + for (i = 0, len = 0; NULL != global_scope; i++, len++) { - switch( global_scope[i] ) - { - case '\0': - p[0] = len; - if( len > 0 ) - p[len+1] = 0; - return( name_len(Out) ); - case '.': - p[0] = len; - p += (len + 1); - len = -1; - break; - default: - p[len+1] = global_scope[i]; - break; - } + switch (global_scope[i]) + { + case '\0': + p[0] = len; + if (len > 0) + p[len + 1] = 0; + return (name_len (Out)); + case '.': + p[0] = len; + p += (len + 1); + len = -1; + break; + default: + p[len + 1] = global_scope[i]; + break; + } } - return( name_len(Out) ); - } /* name_mangle */ + return (name_len (Out)); +} /* name_mangle */ /******************************************************************* check if a file exists ********************************************************************/ -BOOL file_exist(char *fname,SMB_STRUCT_STAT *sbuf) +BOOL +file_exist (char *fname, SMB_STRUCT_STAT * sbuf) { - SMB_STRUCT_STAT st; - if (!sbuf) sbuf = &st; - - if (sys_stat(fname,sbuf) != 0) - return(False); + SMB_STRUCT_STAT st; + if (!sbuf) + sbuf = &st; - return(S_ISREG(sbuf->st_mode)); + if (sys_stat (fname, sbuf) != 0) + return (False); + + return (S_ISREG (sbuf->st_mode)); } /******************************************************************* check a files mod time ********************************************************************/ -time_t file_modtime(char *fname) +time_t +file_modtime (char *fname) { - SMB_STRUCT_STAT st; - - if (sys_stat(fname,&st) != 0) - return(0); + SMB_STRUCT_STAT st; - return(st.st_mtime); + if (sys_stat (fname, &st) != 0) + return (0); + + return (st.st_mtime); } + #if 0 /******************************************************************* check if a directory exists ********************************************************************/ -BOOL directory_exist(char *dname,SMB_STRUCT_STAT *st) +BOOL +directory_exist (char *dname, SMB_STRUCT_STAT * st) { - SMB_STRUCT_STAT st2; - BOOL ret; + SMB_STRUCT_STAT st2; + BOOL ret; - if (!st) st = &st2; + if (!st) + st = &st2; - if (sys_stat(dname,st) != 0) - return(False); + if (sys_stat (dname, st) != 0) + return (False); - ret = S_ISDIR(st->st_mode); - if(!ret) - errno = ENOTDIR; - return ret; + ret = S_ISDIR (st->st_mode); + if (!ret) + errno = ENOTDIR; + return ret; } /******************************************************************* returns the size in bytes of the named file ********************************************************************/ -SMB_OFF_T file_size(char *file_name) +SMB_OFF_T +file_size (char *file_name) { - SMB_STRUCT_STAT buf; - buf.st_size = 0; - if(sys_stat(file_name,&buf) != 0) - return (SMB_OFF_T)-1; - return(buf.st_size); + SMB_STRUCT_STAT buf; + buf.st_size = 0; + if (sys_stat (file_name, &buf) != 0) + return (SMB_OFF_T) - 1; + return (buf.st_size); } -#endif /* 0 */ +#endif /* 0 */ /******************************************************************* return a string representing an attribute for a file ********************************************************************/ -char *attrib_string(uint16 mode) +char * +attrib_string (uint16 mode) { - static fstring attrstr; + static fstring attrstr; - attrstr[0] = 0; + attrstr[0] = 0; - if (mode & aVOLID) fstrcat(attrstr,"V"); - if (mode & aDIR) fstrcat(attrstr,"D"); - if (mode & aARCH) fstrcat(attrstr,"A"); - if (mode & aHIDDEN) fstrcat(attrstr,"H"); - if (mode & aSYSTEM) fstrcat(attrstr,"S"); - if (mode & aRONLY) fstrcat(attrstr,"R"); + if (mode & aVOLID) + fstrcat (attrstr, "V"); + if (mode & aDIR) + fstrcat (attrstr, "D"); + if (mode & aARCH) + fstrcat (attrstr, "A"); + if (mode & aHIDDEN) + fstrcat (attrstr, "H"); + if (mode & aSYSTEM) + fstrcat (attrstr, "S"); + if (mode & aRONLY) + fstrcat (attrstr, "R"); - return(attrstr); + return (attrstr); } #if 0 /**************************************************************************** make a file into unix format ****************************************************************************/ -void unix_format(char *fname) +void +unix_format (char *fname) { - string_replace(fname,'\\','/'); + string_replace (fname, '\\', '/'); } /**************************************************************************** make a file into dos format ****************************************************************************/ -void dos_format(char *fname) +void +dos_format (char *fname) { - string_replace(fname,'/','\\'); + string_replace (fname, '/', '\\'); } -#endif /* 0 */ +#endif /* 0 */ /******************************************************************* show a smb message structure ********************************************************************/ -void show_msg(char *buf) +void +show_msg (char *buf) { - int i; - int bcc=0; + int i; + int bcc = 0; - if (DEBUGLEVEL < 5) return; + if (DEBUGLEVEL < 5) + return; - DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n", - smb_len(buf), - (int)CVAL(buf,smb_com), - (int)CVAL(buf,smb_rcls), - (int)CVAL(buf,smb_reh), - (int)SVAL(buf,smb_err), - (int)CVAL(buf,smb_flg), - (int)SVAL(buf,smb_flg2))); - DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n", - (int)SVAL(buf,smb_tid), - (int)SVAL(buf,smb_pid), - (int)SVAL(buf,smb_uid), - (int)SVAL(buf,smb_mid), - (int)CVAL(buf,smb_wct))); + DEBUG (5, + ("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n", + smb_len (buf), (int) CVAL (buf, smb_com), (int) CVAL (buf, smb_rcls), (int) CVAL (buf, + smb_reh), + (int) SVAL (buf, smb_err), (int) CVAL (buf, smb_flg), (int) SVAL (buf, smb_flg2))); + DEBUG (5, + ("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n", + (int) SVAL (buf, smb_tid), (int) SVAL (buf, smb_pid), (int) SVAL (buf, smb_uid), + (int) SVAL (buf, smb_mid), (int) CVAL (buf, smb_wct))); - for (i=0;i<(int)CVAL(buf,smb_wct);i++) - { - DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i, - SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i))); - } + for (i = 0; i < (int) CVAL (buf, smb_wct); i++) + { + DEBUG (5, ("smb_vwv[%d]=%d (0x%X)\n", i, + SVAL (buf, smb_vwv + 2 * i), SVAL (buf, smb_vwv + 2 * i))); + } - bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct))); + bcc = (int) SVAL (buf, smb_vwv + 2 * (CVAL (buf, smb_wct))); - DEBUG(5,("smb_bcc=%d\n",bcc)); + DEBUG (5, ("smb_bcc=%d\n", bcc)); - if (DEBUGLEVEL < 10) return; + if (DEBUGLEVEL < 10) + return; - if (DEBUGLEVEL < 50) - { - bcc = MIN(bcc, 512); - } + if (DEBUGLEVEL < 50) + { + bcc = MIN (bcc, 512); + } - dump_data(10, smb_buf(buf), bcc); + dump_data (10, smb_buf (buf), bcc); } + /******************************************************************* return the length of an smb packet ********************************************************************/ -int smb_len(char *buf) +int +smb_len (char *buf) { - return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) ); + return (PVAL (buf, 3) | (PVAL (buf, 2) << 8) | ((PVAL (buf, 1) & 1) << 16)); } /******************************************************************* set the length of an smb packet ********************************************************************/ -void _smb_setlen(char *buf,int len) +void +_smb_setlen (char *buf, int len) { - buf[0] = 0; - buf[1] = (len&0x10000)>>16; - buf[2] = (len&0xFF00)>>8; - buf[3] = len&0xFF; + buf[0] = 0; + buf[1] = (len & 0x10000) >> 16; + buf[2] = (len & 0xFF00) >> 8; + buf[3] = len & 0xFF; } /******************************************************************* set the length and marker of an smb packet ********************************************************************/ -void smb_setlen(char *buf,int len) +void +smb_setlen (char *buf, int len) { - _smb_setlen(buf,len); + _smb_setlen (buf, len); - CVAL(buf,4) = 0xFF; - CVAL(buf,5) = 'S'; - CVAL(buf,6) = 'M'; - CVAL(buf,7) = 'B'; + CVAL (buf, 4) = 0xFF; + CVAL (buf, 5) = 'S'; + CVAL (buf, 6) = 'M'; + CVAL (buf, 7) = 'B'; } /******************************************************************* setup the word count and byte count for a smb message ********************************************************************/ -int set_message(char *buf,int num_words,int num_bytes,BOOL zero) +int +set_message (char *buf, int num_words, int num_bytes, BOOL zero) { - if (zero) - memset(buf + smb_size,'\0',num_words*2 + num_bytes); - CVAL(buf,smb_wct) = num_words; - SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes); - smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4); - return (smb_size + num_words*2 + num_bytes); + if (zero) + memset (buf + smb_size, '\0', num_words * 2 + num_bytes); + CVAL (buf, smb_wct) = num_words; + SSVAL (buf, smb_vwv + num_words * SIZEOFWORD, num_bytes); + smb_setlen (buf, smb_size + num_words * 2 + num_bytes - 4); + return (smb_size + num_words * 2 + num_bytes); } /******************************************************************* return the number of smb words ********************************************************************/ -static int smb_numwords(char *buf) +static int +smb_numwords (char *buf) { - return (CVAL(buf,smb_wct)); + return (CVAL (buf, smb_wct)); } /******************************************************************* return the size of the smb_buf region of a message ********************************************************************/ -int smb_buflen(char *buf) +int +smb_buflen (char *buf) { - return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2)); + return (SVAL (buf, smb_vwv0 + smb_numwords (buf) * 2)); } /******************************************************************* return a pointer to the smb_buf data area ********************************************************************/ -static int smb_buf_ofs(char *buf) +static int +smb_buf_ofs (char *buf) { - return (smb_size + CVAL(buf,smb_wct)*2); + return (smb_size + CVAL (buf, smb_wct) * 2); } /******************************************************************* return a pointer to the smb_buf data area ********************************************************************/ -char *smb_buf(char *buf) +char * +smb_buf (char *buf) { - return (buf + smb_buf_ofs(buf)); + return (buf + smb_buf_ofs (buf)); } /******************************************************************* return the SMB offset into an SMB buffer ********************************************************************/ -int smb_offset(char *p,char *buf) +int +smb_offset (char *p, char *buf) { - return(PTR_DIFF(p,buf+4) + chain_size); + return (PTR_DIFF (p, buf + 4) + chain_size); } #if 0 /******************************************************************* reduce a file name, removing .. elements. ********************************************************************/ -void dos_clean_name(char *s) +void +dos_clean_name (char *s) { - char *p=NULL; + char *p = NULL; - DEBUG(3,("dos_clean_name [%s]\n",s)); + DEBUG (3, ("dos_clean_name [%s]\n", s)); - /* remove any double slashes */ - string_sub(s, "\\\\", "\\"); + /* remove any double slashes */ + string_sub (s, "\\\\", "\\"); - while ((p = strstr(s,"\\..\\")) != NULL) + while ((p = strstr (s, "\\..\\")) != NULL) { - pstring s1; + pstring s1; - *p = 0; - pstrcpy(s1,p+3); + *p = 0; + pstrcpy (s1, p + 3); - if ((p=strrchr(s,'\\')) != NULL) - *p = 0; - else - *s = 0; - pstrcat(s,s1); - } + if ((p = strrchr (s, '\\')) != NULL) + *p = 0; + else + *s = 0; + pstrcat (s, s1); + } - trim_string(s,NULL,"\\.."); + trim_string (s, NULL, "\\.."); - string_sub(s, "\\.\\", "\\"); + string_sub (s, "\\.\\", "\\"); } /******************************************************************* reduce a file name, removing .. elements. ********************************************************************/ -void unix_clean_name(char *s) +void +unix_clean_name (char *s) { - char *p=NULL; + char *p = NULL; - DEBUG(3,("unix_clean_name [%s]\n",s)); + DEBUG (3, ("unix_clean_name [%s]\n", s)); - /* remove any double slashes */ - string_sub(s, "//","/"); + /* remove any double slashes */ + string_sub (s, "//", "/"); - /* Remove leading ./ characters */ - if(strncmp(s, "./", 2) == 0) { - trim_string(s, "./", NULL); - if(*s == 0) - pstrcpy(s,"./"); - } - - while ((p = strstr(s,"/../")) != NULL) + /* Remove leading ./ characters */ + if (strncmp (s, "./", 2) == 0) { - pstring s1; + trim_string (s, "./", NULL); + if (*s == 0) + pstrcpy (s, "./"); + } - *p = 0; - pstrcpy(s1,p+3); + while ((p = strstr (s, "/../")) != NULL) + { + pstring s1; - if ((p=strrchr(s,'/')) != NULL) - *p = 0; - else - *s = 0; - pstrcat(s,s1); - } + *p = 0; + pstrcpy (s1, p + 3); - trim_string(s,NULL,"/.."); + if ((p = strrchr (s, '/')) != NULL) + *p = 0; + else + *s = 0; + pstrcat (s, s1); + } + + trim_string (s, NULL, "/.."); } /******************************************************************* @@ -647,125 +686,128 @@ on the system that has the referenced file system. widelinks are allowed if widelinks is true ********************************************************************/ -BOOL reduce_name(char *s,char *dir,BOOL widelinks) +BOOL +reduce_name (char *s, char *dir, BOOL widelinks) { #ifndef REDUCE_PATHS - return True; + return True; #else - pstring dir2; - pstring wd; - pstring base_name; - pstring newname; - char *p=NULL; - BOOL relative = (*s != '/'); + pstring dir2; + pstring wd; + pstring base_name; + pstring newname; + char *p = NULL; + BOOL relative = (*s != '/'); - *dir2 = *wd = *base_name = *newname = 0; + *dir2 = *wd = *base_name = *newname = 0; - if (widelinks) - { - unix_clean_name(s); - /* can't have a leading .. */ - if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/')) + if (widelinks) { - DEBUG(3,("Illegal file name? (%s)\n",s)); - return(False); + unix_clean_name (s); + /* can't have a leading .. */ + if (strncmp (s, "..", 2) == 0 && (s[2] == 0 || s[2] == '/')) + { + DEBUG (3, ("Illegal file name? (%s)\n", s)); + return (False); + } + + if (strlen (s) == 0) + pstrcpy (s, "./"); + + return (True); } - if (strlen(s) == 0) - pstrcpy(s,"./"); + DEBUG (3, ("reduce_name [%s] [%s]\n", s, dir)); - return(True); - } - - DEBUG(3,("reduce_name [%s] [%s]\n",s,dir)); + /* remove any double slashes */ + string_sub (s, "//", "/"); - /* remove any double slashes */ - string_sub(s,"//","/"); + pstrcpy (base_name, s); + p = strrchr (base_name, '/'); - pstrcpy(base_name,s); - p = strrchr(base_name,'/'); + if (!p) + return (True); - if (!p) - return(True); - - if (!dos_GetWd(wd)) - { - DEBUG(0,("couldn't getwd for %s %s\n",s,dir)); - return(False); - } - - if (dos_ChDir(dir) != 0) - { - DEBUG(0,("couldn't chdir to %s\n",dir)); - return(False); - } - - if (!dos_GetWd(dir2)) - { - DEBUG(0,("couldn't getwd for %s\n",dir)); - dos_ChDir(wd); - return(False); - } - - if (p && (p != base_name)) - { - *p = 0; - if (strcmp(p+1,".")==0) - p[1]=0; - if (strcmp(p+1,"..")==0) - *p = '/'; - } - - if (dos_ChDir(base_name) != 0) - { - dos_ChDir(wd); - DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,base_name)); - return(False); - } - - if (!dos_GetWd(newname)) - { - dos_ChDir(wd); - DEBUG(2,("couldn't get wd for %s %s\n",s,dir2)); - return(False); - } - - if (p && (p != base_name)) - { - pstrcat(newname,"/"); - pstrcat(newname,p+1); - } - - { - size_t l = strlen(dir2); - if (dir2[l-1] == '/') - l--; - - if (strncmp(newname,dir2,l) != 0) + if (!dos_GetWd (wd)) { - dos_ChDir(wd); - DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,(int)l)); - return(False); + DEBUG (0, ("couldn't getwd for %s %s\n", s, dir)); + return (False); } - if (relative) + if (dos_ChDir (dir) != 0) { - if (newname[l] == '/') - pstrcpy(s,newname + l + 1); - else - pstrcpy(s,newname+l); + DEBUG (0, ("couldn't chdir to %s\n", dir)); + return (False); } - else - pstrcpy(s,newname); - } - dos_ChDir(wd); + if (!dos_GetWd (dir2)) + { + DEBUG (0, ("couldn't getwd for %s\n", dir)); + dos_ChDir (wd); + return (False); + } - if (strlen(s) == 0) - pstrcpy(s,"./"); + if (p && (p != base_name)) + { + *p = 0; + if (strcmp (p + 1, ".") == 0) + p[1] = 0; + if (strcmp (p + 1, "..") == 0) + *p = '/'; + } - DEBUG(3,("reduced to %s\n",s)); - return(True); + if (dos_ChDir (base_name) != 0) + { + dos_ChDir (wd); + DEBUG (3, ("couldn't chdir for %s %s basename=%s\n", s, dir, base_name)); + return (False); + } + + if (!dos_GetWd (newname)) + { + dos_ChDir (wd); + DEBUG (2, ("couldn't get wd for %s %s\n", s, dir2)); + return (False); + } + + if (p && (p != base_name)) + { + pstrcat (newname, "/"); + pstrcat (newname, p + 1); + } + + { + size_t l = strlen (dir2); + if (dir2[l - 1] == '/') + l--; + + if (strncmp (newname, dir2, l) != 0) + { + dos_ChDir (wd); + DEBUG (2, + ("Bad access attempt? s=%s dir=%s newname=%s l=%d\n", s, dir2, newname, + (int) l)); + return (False); + } + + if (relative) + { + if (newname[l] == '/') + pstrcpy (s, newname + l + 1); + else + pstrcpy (s, newname + l); + } + else + pstrcpy (s, newname); + } + + dos_ChDir (wd); + + if (strlen (s) == 0) + pstrcpy (s, "./"); + + DEBUG (3, ("reduced to %s\n", s)); + return (True); #endif } @@ -773,166 +815,179 @@ BOOL reduce_name(char *s,char *dir,BOOL widelinks) /**************************************************************************** expand some *s ****************************************************************************/ -static void expand_one(char *Mask,int len) +static void +expand_one (char *Mask, int len) { - char *p1; - while ((p1 = strchr(Mask,'*')) != NULL) + char *p1; + while ((p1 = strchr (Mask, '*')) != NULL) { - int lfill = (len+1) - strlen(Mask); - int l1= (p1 - Mask); - pstring tmp; - pstrcpy(tmp,Mask); - memset(tmp+l1,'?',lfill); - pstrcpy(tmp + l1 + lfill,Mask + l1 + 1); - pstrcpy(Mask,tmp); + int lfill = (len + 1) - strlen (Mask); + int l1 = (p1 - Mask); + pstring tmp; + pstrcpy (tmp, Mask); + memset (tmp + l1, '?', lfill); + pstrcpy (tmp + l1 + lfill, Mask + l1 + 1); + pstrcpy (Mask, tmp); } } /**************************************************************************** parse out a directory name from a path name. Assumes dos style filenames. ****************************************************************************/ -static void dirname_dos(char *path,char *buf) +static void +dirname_dos (char *path, char *buf) { - split_at_last_component(path, buf, '\\', NULL); + split_at_last_component (path, buf, '\\', NULL); } /**************************************************************************** parse out a filename from a path name. Assumes dos style filenames. ****************************************************************************/ -static char *filename_dos(char *path,char *buf) +static char * +filename_dos (char *path, char *buf) { - char *p = strrchr(path,'\\'); + char *p = strrchr (path, '\\'); - if (!p) - pstrcpy(buf,path); - else - pstrcpy(buf,p+1); + if (!p) + pstrcpy (buf, path); + else + pstrcpy (buf, p + 1); - return(buf); + return (buf); } /**************************************************************************** expand a wildcard expression, replacing *s with ?s ****************************************************************************/ -void expand_mask(char *Mask,BOOL doext) +void +expand_mask (char *Mask, BOOL doext) { - pstring mbeg,mext; - pstring dirpart; - pstring filepart; - BOOL hasdot = False; - char *p1; - BOOL absolute = (*Mask == '\\'); + pstring mbeg, mext; + pstring dirpart; + pstring filepart; + BOOL hasdot = False; + char *p1; + BOOL absolute = (*Mask == '\\'); - *mbeg = *mext = *dirpart = *filepart = 0; + *mbeg = *mext = *dirpart = *filepart = 0; - /* parse the directory and filename */ - if (strchr(Mask,'\\')) - dirname_dos(Mask,dirpart); + /* parse the directory and filename */ + if (strchr (Mask, '\\')) + dirname_dos (Mask, dirpart); - filename_dos(Mask,filepart); + filename_dos (Mask, filepart); - pstrcpy(mbeg,filepart); - if ((p1 = strchr(mbeg,'.')) != NULL) + pstrcpy (mbeg, filepart); + if ((p1 = strchr (mbeg, '.')) != NULL) { - hasdot = True; - *p1 = 0; - p1++; - pstrcpy(mext,p1); + hasdot = True; + *p1 = 0; + p1++; + pstrcpy (mext, p1); } - else + else { - pstrcpy(mext,""); - if (strlen(mbeg) > 8) - { - pstrcpy(mext,mbeg + 8); - mbeg[8] = 0; - } + pstrcpy (mext, ""); + if (strlen (mbeg) > 8) + { + pstrcpy (mext, mbeg + 8); + mbeg[8] = 0; + } } - if (*mbeg == 0) - pstrcpy(mbeg,"????????"); - if ((*mext == 0) && doext && !hasdot) - pstrcpy(mext,"???"); + if (*mbeg == 0) + pstrcpy (mbeg, "????????"); + if ((*mext == 0) && doext && !hasdot) + pstrcpy (mext, "???"); - if (strequal(mbeg,"*") && *mext==0) - pstrcpy(mext,"*"); + if (strequal (mbeg, "*") && *mext == 0) + pstrcpy (mext, "*"); - /* expand *'s */ - expand_one(mbeg,8); - if (*mext) - expand_one(mext,3); + /* expand *'s */ + expand_one (mbeg, 8); + if (*mext) + expand_one (mext, 3); - pstrcpy(Mask,dirpart); - if (*dirpart || absolute) pstrcat(Mask,"\\"); - pstrcat(Mask,mbeg); - pstrcat(Mask,"."); - pstrcat(Mask,mext); + pstrcpy (Mask, dirpart); + if (*dirpart || absolute) + pstrcat (Mask, "\\"); + pstrcat (Mask, mbeg); + pstrcat (Mask, "."); + pstrcat (Mask, mext); - DEBUG(6,("Mask expanded to [%s]\n",Mask)); -} + DEBUG (6, ("Mask expanded to [%s]\n", Mask)); +} /**************************************************************************** make a dir struct ****************************************************************************/ -void make_dir_struct(char *buf,char *mask,char *fname,SMB_OFF_T size,int mode,time_t date) -{ - char *p; - pstring mask2; +void +make_dir_struct (char *buf, char *mask, char *fname, SMB_OFF_T size, int mode, time_t date) +{ + char *p; + pstring mask2; - pstrcpy(mask2,mask); + pstrcpy (mask2, mask); - if ((mode & aDIR) != 0) - size = 0; + if ((mode & aDIR) != 0) + size = 0; - memset(buf+1,' ',11); - if ((p = strchr(mask2,'.')) != NULL) + memset (buf + 1, ' ', 11); + if ((p = strchr (mask2, '.')) != NULL) { - *p = 0; - memcpy(buf+1,mask2,MIN(strlen(mask2),8)); - memcpy(buf+9,p+1,MIN(strlen(p+1),3)); - *p = '.'; + *p = 0; + memcpy (buf + 1, mask2, MIN (strlen (mask2), 8)); + memcpy (buf + 9, p + 1, MIN (strlen (p + 1), 3)); + *p = '.'; } - else - memcpy(buf+1,mask2,MIN(strlen(mask2),11)); + else + memcpy (buf + 1, mask2, MIN (strlen (mask2), 11)); - memset(buf+21,'\0',DIR_STRUCT_SIZE-21); - CVAL(buf,21) = mode; - put_dos_date(buf,22,date); - SSVAL(buf,26,size & 0xFFFF); - SSVAL(buf,28,(size >> 16)&0xFFFF); - StrnCpy(buf+30,fname,12); - if (!case_sensitive) - strupper(buf+30); - DEBUG(8,("put name [%s] into dir struct\n",buf+30)); + memset (buf + 21, '\0', DIR_STRUCT_SIZE - 21); + CVAL (buf, 21) = mode; + put_dos_date (buf, 22, date); + SSVAL (buf, 26, size & 0xFFFF); + SSVAL (buf, 28, (size >> 16) & 0xFFFF); + StrnCpy (buf + 30, fname, 12); + if (!case_sensitive) + strupper (buf + 30); + DEBUG (8, ("put name [%s] into dir struct\n", buf + 30)); } /******************************************************************* close the low 3 fd's and open dev/null in their place ********************************************************************/ -void close_low_fds(void) +void +close_low_fds (void) { - int fd; - int i; - close(0); close(1); close(2); - /* try and use up these file descriptors, so silly - library routines writing to stdout etc won't cause havoc */ - for (i=0;i<3;i++) { - fd = sys_open("/dev/null",O_RDWR,0); - if (fd < 0) fd = sys_open("/dev/null",O_WRONLY,0); - if (fd < 0) { - DEBUG(0,("Cannot open /dev/null\n")); - return; + int fd; + int i; + close (0); + close (1); + close (2); + /* try and use up these file descriptors, so silly + library routines writing to stdout etc won't cause havoc */ + for (i = 0; i < 3; i++) + { + fd = sys_open ("/dev/null", O_RDWR, 0); + if (fd < 0) + fd = sys_open ("/dev/null", O_WRONLY, 0); + if (fd < 0) + { + DEBUG (0, ("Cannot open /dev/null\n")); + return; + } + if (fd != i) + { + DEBUG (0, ("Didn't get file descriptor %d\n", i)); + return; + } } - if (fd != i) { - DEBUG(0,("Didn't get file descriptor %d\n",i)); - return; - } - } } -#endif /* 0 */ +#endif /* 0 */ /**************************************************************************** Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available, @@ -940,9 +995,10 @@ else if SYSV use O_NDELAY if BSD use FNDELAY ****************************************************************************/ -int set_blocking(int fd, BOOL set) +int +set_blocking (int fd, BOOL set) { - int val; + int val; #ifdef O_NONBLOCK #define FLAG_TO_SET O_NONBLOCK #else @@ -953,13 +1009,13 @@ int set_blocking(int fd, BOOL set) #endif #endif - if((val = fcntl(fd, F_GETFL, 0)) == -1) - return -1; - if(set) /* Turn blocking on - ie. clear nonblock flag */ - val &= ~FLAG_TO_SET; - else - val |= FLAG_TO_SET; - return fcntl( fd, F_SETFL, val); + if ((val = fcntl (fd, F_GETFL, 0)) == -1) + return -1; + if (set) /* Turn blocking on - ie. clear nonblock flag */ + val &= ~FLAG_TO_SET; + else + val |= FLAG_TO_SET; + return fcntl (fd, F_SETFL, val); #undef FLAG_TO_SET } @@ -968,10 +1024,11 @@ int set_blocking(int fd, BOOL set) find the difference in milliseconds between two struct timeval values ********************************************************************/ -int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew) +int +TvalDiff (struct timeval *tvalold, struct timeval *tvalnew) { - return((tvalnew->tv_sec - tvalold->tv_sec)*1000 + - ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000); + return ((tvalnew->tv_sec - tvalold->tv_sec) * 1000 + + ((int) tvalnew->tv_usec - (int) tvalold->tv_usec) / 1000); } @@ -979,160 +1036,177 @@ int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew) /**************************************************************************** transfer some data between two fd's ****************************************************************************/ -SMB_OFF_T transfer_file(int infd,int outfd,SMB_OFF_T n,char *header,int headlen,int align) +SMB_OFF_T +transfer_file (int infd, int outfd, SMB_OFF_T n, char *header, int headlen, int align) { - static char *buf=NULL; - static int size=0; - char *buf1,*abuf; - SMB_OFF_T total = 0; + static char *buf = NULL; + static int size = 0; + char *buf1, *abuf; + SMB_OFF_T total = 0; - DEBUG(4,("transfer_file n=%.0f (head=%d) called\n",(double)n,headlen)); + DEBUG (4, ("transfer_file n=%.0f (head=%d) called\n", (double) n, headlen)); - if (size == 0) { - size = lp_readsize(); - size = MAX(size,1024); - } - - while (!buf && size>0) { - buf = (char *)Realloc(buf,size+8); - if (!buf) size /= 2; - } - - if (!buf) { - DEBUG(0,("Cannot allocate transfer buffer!\n")); - exit(1); - } - - abuf = buf + (align%8); - - if (header) - n += headlen; - - while (n > 0) - { - int s = (int)MIN(n,(SMB_OFF_T)size); - int ret,ret2=0; - - ret = 0; - - if (header && (headlen >= MIN(s,1024))) { - buf1 = header; - s = headlen; - ret = headlen; - headlen = 0; - header = NULL; - } else { - buf1 = abuf; - } - - if (header && headlen > 0) + if (size == 0) { - ret = MIN(headlen,size); - memcpy(buf1,header,ret); - headlen -= ret; - header += ret; - if (headlen <= 0) header = NULL; + size = lp_readsize (); + size = MAX (size, 1024); } - if (s > ret) - ret += read(infd,buf1+ret,s-ret); - - if (ret > 0) + while (!buf && size > 0) { - ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret); - if (ret2 > 0) total += ret2; - /* if we can't write then dump excess data */ - if (ret2 != ret) - transfer_file(infd,-1,n-(ret+headlen),NULL,0,0); + buf = (char *) Realloc (buf, size + 8); + if (!buf) + size /= 2; } - if (ret <= 0 || ret2 != ret) - return(total); - n -= ret; - } - return(total); + + if (!buf) + { + DEBUG (0, ("Cannot allocate transfer buffer!\n")); + exit (1); + } + + abuf = buf + (align % 8); + + if (header) + n += headlen; + + while (n > 0) + { + int s = (int) MIN (n, (SMB_OFF_T) size); + int ret, ret2 = 0; + + ret = 0; + + if (header && (headlen >= MIN (s, 1024))) + { + buf1 = header; + s = headlen; + ret = headlen; + headlen = 0; + header = NULL; + } + else + { + buf1 = abuf; + } + + if (header && headlen > 0) + { + ret = MIN (headlen, size); + memcpy (buf1, header, ret); + headlen -= ret; + header += ret; + if (headlen <= 0) + header = NULL; + } + + if (s > ret) + ret += read (infd, buf1 + ret, s - ret); + + if (ret > 0) + { + ret2 = (outfd >= 0 ? write_data (outfd, buf1, ret) : ret); + if (ret2 > 0) + total += ret2; + /* if we can't write then dump excess data */ + if (ret2 != ret) + transfer_file (infd, -1, n - (ret + headlen), NULL, 0, 0); + } + if (ret <= 0 || ret2 != ret) + return (total); + n -= ret; + } + return (total); } /**************************************************************************** find a pointer to a netbios name ****************************************************************************/ -static char *name_ptr(char *buf,int ofs) +static char * +name_ptr (char *buf, int ofs) { - unsigned char c = *(unsigned char *)(buf+ofs); + unsigned char c = *(unsigned char *) (buf + ofs); - if ((c & 0xC0) == 0xC0) + if ((c & 0xC0) == 0xC0) { - uint16 l; - char p[2]; - memcpy(p,buf+ofs,2); - p[0] &= ~0xC0; - l = RSVAL(p,0); - DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l)); - return(buf + l); + uint16 l; + char p[2]; + memcpy (p, buf + ofs, 2); + p[0] &= ~0xC0; + l = RSVAL (p, 0); + DEBUG (5, ("name ptr to pos %d from %d is %s\n", l, ofs, buf + l)); + return (buf + l); } - else - return(buf+ofs); -} + else + return (buf + ofs); +} /**************************************************************************** extract a netbios name from a buf ****************************************************************************/ -int name_extract(char *buf,int ofs,char *name) +int +name_extract (char *buf, int ofs, char *name) { - char *p = name_ptr(buf,ofs); - int d = PTR_DIFF(p,buf+ofs); - pstrcpy(name,""); - if (d < -50 || d > 50) return(0); - return(name_interpret(p,name)); + char *p = name_ptr (buf, ofs); + int d = PTR_DIFF (p, buf + ofs); + pstrcpy (name, ""); + if (d < -50 || d > 50) + return (0); + return (name_interpret (p, name)); } -#endif /* 0 */ - +#endif /* 0 */ + /**************************************************************************** return the total storage length of a mangled name ****************************************************************************/ -int name_len(char *s1) +int +name_len (char *s1) { - /* NOTE: this argument _must_ be unsigned */ - unsigned char *s = (unsigned char *)s1; - int len; + /* NOTE: this argument _must_ be unsigned */ + unsigned char *s = (unsigned char *) s1; + int len; - /* If the two high bits of the byte are set, return 2. */ - if (0xC0 == (*s & 0xC0)) - return(2); + /* If the two high bits of the byte are set, return 2. */ + if (0xC0 == (*s & 0xC0)) + return (2); - /* Add up the length bytes. */ - for (len = 1; (*s); s += (*s) + 1) { - len += *s + 1; - SMB_ASSERT(len < 80); - } + /* Add up the length bytes. */ + for (len = 1; (*s); s += (*s) + 1) + { + len += *s + 1; + SMB_ASSERT (len < 80); + } - return(len); -} /* name_len */ + return (len); +} /* name_len */ /******************************************************************* sleep for a specified number of milliseconds ********************************************************************/ -void msleep(int t) +void +msleep (int t) { - int tdiff=0; - struct timeval tval,t1,t2; - fd_set fds; + int tdiff = 0; + struct timeval tval, t1, t2; + fd_set fds; - GetTimeOfDay(&t1); - GetTimeOfDay(&t2); - - while (tdiff < t) { - tval.tv_sec = (t-tdiff)/1000; - tval.tv_usec = 1000*((t-tdiff)%1000); - - FD_ZERO(&fds); - errno = 0; - sys_select(0,&fds,&tval); + GetTimeOfDay (&t1); + GetTimeOfDay (&t2); - GetTimeOfDay(&t2); - tdiff = TvalDiff(&t1,&t2); - } + while (tdiff < t) + { + tval.tv_sec = (t - tdiff) / 1000; + tval.tv_usec = 1000 * ((t - tdiff) % 1000); + + FD_ZERO (&fds); + errno = 0; + sys_select (0, &fds, &tval); + + GetTimeOfDay (&t2); + tdiff = TvalDiff (&t1, &t2); + } } #if 0 @@ -1141,61 +1215,70 @@ void msleep(int t) * Does the actual matching. This is the 'original code' * used by the unix matcher. *********************************************************/ -static BOOL unix_do_match(char *str, char *regexp, int case_sig) +static BOOL +unix_do_match (char *str, char *regexp, int case_sig) { - char *p; + char *p; - for( p = regexp; *p && *str; ) { - switch(*p) { - case '?': - str++; p++; - break; - - case '*': - /* Look for a character matching - the one after the '*' */ - p++; - if(!*p) - return True; /* Automatic match */ - while(*str) { - while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str)))) - str++; - if(unix_do_match(str,p,case_sig)) - return True; - if(!*str) - return False; - else - str++; - } - return False; - - default: - if(case_sig) { - if(*str != *p) - return False; - } else { - if(toupper(*str) != toupper(*p)) - return False; - } - str++, p++; - break; - } - } - if(!*p && !*str) - return True; - - if (!*p && str[0] == '.' && str[1] == 0) - return(True); - - if (!*str && *p == '?') + for (p = regexp; *p && *str;) { - while (*p == '?') p++; - return(!*p); + switch (*p) + { + case '?': + str++; + p++; + break; + + case '*': + /* Look for a character matching + the one after the '*' */ + p++; + if (!*p) + return True; /* Automatic match */ + while (*str) + { + while (*str && (case_sig ? (*p != *str) : (toupper (*p) != toupper (*str)))) + str++; + if (unix_do_match (str, p, case_sig)) + return True; + if (!*str) + return False; + else + str++; + } + return False; + + default: + if (case_sig) + { + if (*str != *p) + return False; + } + else + { + if (toupper (*str) != toupper (*p)) + return False; + } + str++, p++; + break; + } + } + if (!*p && !*str) + return True; + + if (!*p && str[0] == '.' && str[1] == 0) + return (True); + + if (!*str && *p == '?') + { + while (*p == '?') + p++; + return (!*p); } - if(!*str && (*p == '*' && p[1] == '\0')) - return True; - return False; + if (!*str && (*p == '*' && p[1] == '\0')) + return True; + return False; } @@ -1206,60 +1289,72 @@ static BOOL unix_do_match(char *str, char *regexp, int case_sig) * This is the 'original code' used by the unix matcher. *********************************************************/ -static BOOL unix_mask_match(char *str, char *regexp, int case_sig,BOOL trans2) +static BOOL +unix_mask_match (char *str, char *regexp, int case_sig, BOOL trans2) { - char *p; - pstring p1, p2; - fstring ebase,eext,sbase,sext; + char *p; + pstring p1, p2; + fstring ebase, eext, sbase, sext; - BOOL matched; + BOOL matched; - /* Make local copies of str and regexp */ - StrnCpy(p1,regexp,sizeof(pstring)-1); - StrnCpy(p2,str,sizeof(pstring)-1); + /* Make local copies of str and regexp */ + StrnCpy (p1, regexp, sizeof (pstring) - 1); + StrnCpy (p2, str, sizeof (pstring) - 1); - if (!strchr(p2,'.')) { - pstrcat(p2,"."); - } - - /* Remove any *? and ** as they are meaningless */ - for(p = p1; *p; p++) - while( *p == '*' && (p[1] == '?' ||p[1] == '*')) - (void)pstrcpy( &p[1], &p[2]); - - if (strequal(p1,"*")) return(True); - - DEBUG(8,("unix_mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig)); - - if (trans2) { - fstrcpy(ebase,p1); - fstrcpy(sbase,p2); - } else { - if ((p=strrchr(p1,'.'))) { - *p = 0; - fstrcpy(ebase,p1); - fstrcpy(eext,p+1); - } else { - fstrcpy(ebase,p1); - eext[0] = 0; + if (!strchr (p2, '.')) + { + pstrcat (p2, "."); } - if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) { - *p = 0; - fstrcpy(sbase,p2); - fstrcpy(sext,p+1); - } else { - fstrcpy(sbase,p2); - fstrcpy(sext,""); - } - } + /* Remove any *? and ** as they are meaningless */ + for (p = p1; *p; p++) + while (*p == '*' && (p[1] == '?' || p[1] == '*')) + (void) pstrcpy (&p[1], &p[2]); - matched = unix_do_match(sbase,ebase,case_sig) && - (trans2 || unix_do_match(sext,eext,case_sig)); + if (strequal (p1, "*")) + return (True); - DEBUG(8,("unix_mask_match returning %d\n", matched)); + DEBUG (8, ("unix_mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig)); - return matched; + if (trans2) + { + fstrcpy (ebase, p1); + fstrcpy (sbase, p2); + } + else + { + if ((p = strrchr (p1, '.'))) + { + *p = 0; + fstrcpy (ebase, p1); + fstrcpy (eext, p + 1); + } + else + { + fstrcpy (ebase, p1); + eext[0] = 0; + } + + if (!strequal (p2, ".") && !strequal (p2, "..") && (p = strrchr (p2, '.'))) + { + *p = 0; + fstrcpy (sbase, p2); + fstrcpy (sext, p + 1); + } + else + { + fstrcpy (sbase, p2); + fstrcpy (sext, ""); + } + } + + matched = unix_do_match (sbase, ebase, case_sig) && + (trans2 || unix_do_match (sext, eext, case_sig)); + + DEBUG (8, ("unix_mask_match returning %d\n", matched)); + + return matched; } /********************************************************* @@ -1268,74 +1363,91 @@ static BOOL unix_mask_match(char *str, char *regexp, int case_sig,BOOL trans2) * False if failed. This is the 'new' NT style matcher. *********************************************************/ -BOOL do_match(char *str, char *regexp, int case_sig) +BOOL +do_match (char *str, char *regexp, int case_sig) { - char *p; + char *p; - for( p = regexp; *p && *str; ) { - switch(*p) { - case '?': - str++; p++; - break; + for (p = regexp; *p && *str;) + { + switch (*p) + { + case '?': + str++; + p++; + break; - case '*': - /* Look for a character matching - the one after the '*' */ - p++; - if(!*p) - return True; /* Automatic match */ - while(*str) { - while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str)))) - str++; - /* Now eat all characters that match, as - we want the *last* character to match. */ - while(*str && (case_sig ? (*p == *str) : (toupper(*p)==toupper(*str)))) - str++; - str--; /* We've eaten the match char after the '*' */ - if(do_match(str,p,case_sig)) { - return True; - } - if(!*str) { - return False; - } else { - str++; - } - } - return False; + case '*': + /* Look for a character matching + the one after the '*' */ + p++; + if (!*p) + return True; /* Automatic match */ + while (*str) + { + while (*str && (case_sig ? (*p != *str) : (toupper (*p) != toupper (*str)))) + str++; + /* Now eat all characters that match, as + we want the *last* character to match. */ + while (*str && (case_sig ? (*p == *str) : (toupper (*p) == toupper (*str)))) + str++; + str--; /* We've eaten the match char after the '*' */ + if (do_match (str, p, case_sig)) + { + return True; + } + if (!*str) + { + return False; + } + else + { + str++; + } + } + return False; - default: - if(case_sig) { - if(*str != *p) { - return False; + default: + if (case_sig) + { + if (*str != *p) + { + return False; + } + } + else + { + if (toupper (*str) != toupper (*p)) + { + return False; + } + } + str++, p++; + break; } - } else { - if(toupper(*str) != toupper(*p)) { - return False; - } - } - str++, p++; - break; } - } - if(!*p && !*str) - return True; + if (!*p && !*str) + return True; - if (!*p && str[0] == '.' && str[1] == 0) { - return(True); - } - - if (!*str && *p == '?') { - while (*p == '?') - p++; - return(!*p); - } + if (!*p && str[0] == '.' && str[1] == 0) + { + return (True); + } - if(!*str && (*p == '*' && p[1] == '\0')) { - return True; - } - - return False; + if (!*str && *p == '?') + { + while (*p == '?') + p++; + return (!*p); + } + + if (!*str && (*p == '*' && p[1] == '\0')) + { + return True; + } + + return False; } @@ -1347,227 +1459,259 @@ BOOL do_match(char *str, char *regexp, int case_sig) * This is the new 'NT style' matcher. *********************************************************/ -BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2) +BOOL +mask_match (char *str, char *regexp, int case_sig, BOOL trans2) { - char *p; - pstring t_pattern, t_filename, te_pattern, te_filename; - fstring ebase,eext,sbase,sext; + char *p; + pstring t_pattern, t_filename, te_pattern, te_filename; + fstring ebase, eext, sbase, sext; - BOOL matched = False; + BOOL matched = False; - /* Make local copies of str and regexp */ - pstrcpy(t_pattern,regexp); - pstrcpy(t_filename,str); + /* Make local copies of str and regexp */ + pstrcpy (t_pattern, regexp); + pstrcpy (t_filename, str); - if(trans2) { + if (trans2) + { - /* a special case for 16 bit apps */ - if (strequal(t_pattern,"????????.???")) - pstrcpy(t_pattern,"*"); + /* a special case for 16 bit apps */ + if (strequal (t_pattern, "????????.???")) + pstrcpy (t_pattern, "*"); #if 0 - /* - * Handle broken clients that send us old 8.3 format. - */ - string_sub(t_pattern,"????????","*"); - string_sub(t_pattern,".???",".*"); + /* + * Handle broken clients that send us old 8.3 format. + */ + string_sub (t_pattern, "????????", "*"); + string_sub (t_pattern, ".???", ".*"); #endif - } + } #if 0 - /* - * Not sure if this is a good idea. JRA. - */ - if(trans2 && is_8_3(t_pattern,False) && is_8_3(t_filename,False)) - trans2 = False; -#endif - -#if 0 - if (!strchr(t_filename,'.')) { - pstrcat(t_filename,"."); - } -#endif - - /* Remove any *? and ** as they are meaningless */ - string_sub(t_pattern, "*?", "*"); - string_sub(t_pattern, "**", "*"); - - if (strequal(t_pattern,"*")) - return(True); - - DEBUG(8,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", t_filename, t_pattern, case_sig)); - - if(trans2) { - /* - * Match each component of the regexp, split up by '.' - * characters. - */ - char *fp, *rp, *cp2, *cp1; - BOOL last_wcard_was_star = False; - int num_path_components, num_regexp_components; - - pstrcpy(te_pattern,t_pattern); - pstrcpy(te_filename,t_filename); - /* - * Remove multiple "*." patterns. - */ - string_sub(te_pattern, "*.*.", "*."); - num_regexp_components = count_chars(te_pattern, '.'); - num_path_components = count_chars(te_filename, '.'); - /* - * Check for special 'hack' case of "DIR a*z". - needs to match a.b.c...z + * Not sure if this is a good idea. JRA. */ - if(num_regexp_components == 0) - matched = do_match( te_filename, te_pattern, case_sig); - else { - for( cp1 = te_pattern, cp2 = te_filename; cp1;) { - fp = strchr(cp2, '.'); - if(fp) - *fp = '\0'; - rp = strchr(cp1, '.'); - if(rp) - *rp = '\0'; - - if(cp1[strlen(cp1)-1] == '*') - last_wcard_was_star = True; - else - last_wcard_was_star = False; - - if(!do_match(cp2, cp1, case_sig)) - break; - - cp1 = rp ? rp + 1 : NULL; - cp2 = fp ? fp + 1 : ""; - - if(last_wcard_was_star || ((cp1 != NULL) && (*cp1 == '*'))) { - /* Eat the extra path components. */ - int i; - - for(i = 0; i < num_path_components - num_regexp_components; i++) { - fp = strchr(cp2, '.'); - if(fp) - *fp = '\0'; - - if((cp1 != NULL) && do_match( cp2, cp1, case_sig)) { - cp2 = fp ? fp + 1 : ""; - break; - } - cp2 = fp ? fp + 1 : ""; - } - num_path_components -= i; - } - } - if(cp1 == NULL && ((*cp2 == '\0') || last_wcard_was_star)) - matched = True; - } - } else { - - /* ------------------------------------------------- - * Behaviour of Win95 - * for 8.3 filenames and 8.3 Wildcards - * ------------------------------------------------- - */ - if (strequal (t_filename, ".")) { - /* - * Patterns: *.* *. ?. ? ????????.??? are valid. - * - */ - if(strequal(t_pattern, "*.*") || strequal(t_pattern, "*.") || - strequal(t_pattern, "????????.???") || - strequal(t_pattern, "?.") || strequal(t_pattern, "?")) - matched = True; - } else if (strequal (t_filename, "..")) { - /* - * Patterns: *.* *. ?. ? *.? ????????.??? are valid. - * - */ - if(strequal(t_pattern, "*.*") || strequal(t_pattern, "*.") || - strequal(t_pattern, "?.") || strequal(t_pattern, "?") || - strequal(t_pattern, "????????.???") || - strequal(t_pattern, "*.?") || strequal(t_pattern, "?.*")) - matched = True; - } else { - - if ((p = strrchr (t_pattern, '.'))) { - /* - * Wildcard has a suffix. - */ - *p = 0; - fstrcpy (ebase, t_pattern); - if (p[1]) { - fstrcpy (eext, p + 1); - } else { - /* pattern ends in DOT: treat as if there is no DOT */ - *eext = 0; - if (strequal (ebase, "*")) - return (True); - } - } else { - /* - * No suffix for wildcard. - */ - fstrcpy (ebase, t_pattern); - eext[0] = 0; - } - - p = strrchr (t_filename, '.'); - if (p && (p[1] == 0) ) { - /* - * Filename has an extension of '.' only. - */ - *p = 0; /* nuke dot at end of string */ - p = 0; /* and treat it as if there is no extension */ - } - - if (p) { - /* - * Filename has an extension. - */ - *p = 0; - fstrcpy (sbase, t_filename); - fstrcpy (sext, p + 1); - if (*eext) { - matched = do_match(sbase, ebase, case_sig) - && do_match(sext, eext, case_sig); - } else { - /* pattern has no extension */ - /* Really: match complete filename with pattern ??? means exactly 3 chars */ - matched = do_match(str, ebase, case_sig); - } - } else { - /* - * Filename has no extension. - */ - fstrcpy (sbase, t_filename); - fstrcpy (sext, ""); - if (*eext) { - /* pattern has extension */ - matched = do_match(sbase, ebase, case_sig) - && do_match(sext, eext, case_sig); - } else { - matched = do_match(sbase, ebase, case_sig); -#ifdef EMULATE_WEIRD_W95_MATCHING - /* - * Even Microsoft has some problems - * Behaviour Win95 -> local disk - * is different from Win95 -> smb drive from Nt 4.0 - * This branch would reflect the Win95 local disk behaviour - */ - if (!matched) { - /* a? matches aa and a in w95 */ - fstrcat (sbase, "."); - matched = do_match(sbase, ebase, case_sig); - } + if (trans2 && is_8_3 (t_pattern, False) && is_8_3 (t_filename, False)) + trans2 = False; #endif - } - } + +#if 0 + if (!strchr (t_filename, '.')) + { + pstrcat (t_filename, "."); } - } +#endif - DEBUG(8,("mask_match returning %d\n", matched)); + /* Remove any *? and ** as they are meaningless */ + string_sub (t_pattern, "*?", "*"); + string_sub (t_pattern, "**", "*"); - return matched; + if (strequal (t_pattern, "*")) + return (True); + + DEBUG (8, + ("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", t_filename, t_pattern, case_sig)); + + if (trans2) + { + /* + * Match each component of the regexp, split up by '.' + * characters. + */ + char *fp, *rp, *cp2, *cp1; + BOOL last_wcard_was_star = False; + int num_path_components, num_regexp_components; + + pstrcpy (te_pattern, t_pattern); + pstrcpy (te_filename, t_filename); + /* + * Remove multiple "*." patterns. + */ + string_sub (te_pattern, "*.*.", "*."); + num_regexp_components = count_chars (te_pattern, '.'); + num_path_components = count_chars (te_filename, '.'); + + /* + * Check for special 'hack' case of "DIR a*z". - needs to match a.b.c...z + */ + if (num_regexp_components == 0) + matched = do_match (te_filename, te_pattern, case_sig); + else + { + for (cp1 = te_pattern, cp2 = te_filename; cp1;) + { + fp = strchr (cp2, '.'); + if (fp) + *fp = '\0'; + rp = strchr (cp1, '.'); + if (rp) + *rp = '\0'; + + if (cp1[strlen (cp1) - 1] == '*') + last_wcard_was_star = True; + else + last_wcard_was_star = False; + + if (!do_match (cp2, cp1, case_sig)) + break; + + cp1 = rp ? rp + 1 : NULL; + cp2 = fp ? fp + 1 : ""; + + if (last_wcard_was_star || ((cp1 != NULL) && (*cp1 == '*'))) + { + /* Eat the extra path components. */ + int i; + + for (i = 0; i < num_path_components - num_regexp_components; i++) + { + fp = strchr (cp2, '.'); + if (fp) + *fp = '\0'; + + if ((cp1 != NULL) && do_match (cp2, cp1, case_sig)) + { + cp2 = fp ? fp + 1 : ""; + break; + } + cp2 = fp ? fp + 1 : ""; + } + num_path_components -= i; + } + } + if (cp1 == NULL && ((*cp2 == '\0') || last_wcard_was_star)) + matched = True; + } + } + else + { + + /* ------------------------------------------------- + * Behaviour of Win95 + * for 8.3 filenames and 8.3 Wildcards + * ------------------------------------------------- + */ + if (strequal (t_filename, ".")) + { + /* + * Patterns: *.* *. ?. ? ????????.??? are valid. + * + */ + if (strequal (t_pattern, "*.*") || strequal (t_pattern, "*.") || + strequal (t_pattern, "????????.???") || + strequal (t_pattern, "?.") || strequal (t_pattern, "?")) + matched = True; + } + else if (strequal (t_filename, "..")) + { + /* + * Patterns: *.* *. ?. ? *.? ????????.??? are valid. + * + */ + if (strequal (t_pattern, "*.*") || strequal (t_pattern, "*.") || + strequal (t_pattern, "?.") || strequal (t_pattern, "?") || + strequal (t_pattern, "????????.???") || + strequal (t_pattern, "*.?") || strequal (t_pattern, "?.*")) + matched = True; + } + else + { + + if ((p = strrchr (t_pattern, '.'))) + { + /* + * Wildcard has a suffix. + */ + *p = 0; + fstrcpy (ebase, t_pattern); + if (p[1]) + { + fstrcpy (eext, p + 1); + } + else + { + /* pattern ends in DOT: treat as if there is no DOT */ + *eext = 0; + if (strequal (ebase, "*")) + return (True); + } + } + else + { + /* + * No suffix for wildcard. + */ + fstrcpy (ebase, t_pattern); + eext[0] = 0; + } + + p = strrchr (t_filename, '.'); + if (p && (p[1] == 0)) + { + /* + * Filename has an extension of '.' only. + */ + *p = 0; /* nuke dot at end of string */ + p = 0; /* and treat it as if there is no extension */ + } + + if (p) + { + /* + * Filename has an extension. + */ + *p = 0; + fstrcpy (sbase, t_filename); + fstrcpy (sext, p + 1); + if (*eext) + { + matched = do_match (sbase, ebase, case_sig) && do_match (sext, eext, case_sig); + } + else + { + /* pattern has no extension */ + /* Really: match complete filename with pattern ??? means exactly 3 chars */ + matched = do_match (str, ebase, case_sig); + } + } + else + { + /* + * Filename has no extension. + */ + fstrcpy (sbase, t_filename); + fstrcpy (sext, ""); + if (*eext) + { + /* pattern has extension */ + matched = do_match (sbase, ebase, case_sig) && do_match (sext, eext, case_sig); + } + else + { + matched = do_match (sbase, ebase, case_sig); +#ifdef EMULATE_WEIRD_W95_MATCHING + /* + * Even Microsoft has some problems + * Behaviour Win95 -> local disk + * is different from Win95 -> smb drive from Nt 4.0 + * This branch would reflect the Win95 local disk behaviour + */ + if (!matched) + { + /* a? matches aa and a in w95 */ + fstrcat (sbase, "."); + matched = do_match (sbase, ebase, case_sig); + } +#endif + } + } + } + } + + DEBUG (8, ("mask_match returning %d\n", matched)); + + return matched; } #endif /* 0 */ @@ -1577,46 +1721,47 @@ set the length of a file from a filedescriptor. Returns 0 on success, -1 on failure. ****************************************************************************/ -int set_filelen(int fd, SMB_OFF_T len) +int +set_filelen (int fd, SMB_OFF_T len) { -/* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot - extend a file with ftruncate. Provide alternate implementation - for this */ + /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot + extend a file with ftruncate. Provide alternate implementation + for this */ #ifdef HAVE_FTRUNCATE_EXTEND - return sys_ftruncate(fd, len); + return sys_ftruncate (fd, len); #else - SMB_STRUCT_STAT st; - char c = 0; - SMB_OFF_T currpos = sys_lseek(fd, (SMB_OFF_T)0, SEEK_CUR); + SMB_STRUCT_STAT st; + char c = 0; + SMB_OFF_T currpos = sys_lseek (fd, (SMB_OFF_T) 0, SEEK_CUR); - if(currpos == -1) - return -1; - /* Do an fstat to see if the file is longer than - the requested size (call ftruncate), - or shorter, in which case seek to len - 1 and write 1 - byte of zero */ - if(sys_fstat(fd, &st)<0) - return -1; + if (currpos == -1) + return -1; + /* Do an fstat to see if the file is longer than + the requested size (call ftruncate), + or shorter, in which case seek to len - 1 and write 1 + byte of zero */ + if (sys_fstat (fd, &st) < 0) + return -1; #ifdef S_ISFIFO - if (S_ISFIFO(st.st_mode)) - return 0; + if (S_ISFIFO (st.st_mode)) + return 0; #endif - if(st.st_size == len) - return 0; - if(st.st_size > len) - return sys_ftruncate(fd, len); + if (st.st_size == len) + return 0; + if (st.st_size > len) + return sys_ftruncate (fd, len); - if(sys_lseek(fd, len-1, SEEK_SET) != len -1) - return -1; - if(write(fd, &c, 1)!=1) - return -1; - /* Seek to where we were */ - if(sys_lseek(fd, currpos, SEEK_SET) != currpos) - return -1; - return 0; + if (sys_lseek (fd, len - 1, SEEK_SET) != len - 1) + return -1; + if (write (fd, &c, 1) != 1) + return -1; + /* Seek to where we were */ + if (sys_lseek (fd, currpos, SEEK_SET) != currpos) + return -1; + return 0; #endif } @@ -1625,9 +1770,10 @@ int set_filelen(int fd, SMB_OFF_T len) /**************************************************************************** this is a version of setbuffer() for those machines that only have setvbuf ****************************************************************************/ - void setbuffer(FILE *f,char *buf,int bufsize) +void +setbuffer (FILE * f, char *buf, int bufsize) { - setvbuf(f,buf,_IOFBF,bufsize); + setvbuf (f, buf, _IOFBF, bufsize); } #endif #endif /* 0 */ @@ -1637,218 +1783,237 @@ this is a version of setbuffer() for those machines that only have setvbuf /**************************************************************************** expand a pointer to be a particular size ****************************************************************************/ -void *Realloc(void *p,size_t size) +void * +Realloc (void *p, size_t size) { - void *ret=NULL; + void *ret = NULL; - if (size == 0) { - if (p) free(p); - DEBUG(5,("Realloc asked for 0 bytes\n")); - return NULL; - } + if (size == 0) + { + if (p) + free (p); + DEBUG (5, ("Realloc asked for 0 bytes\n")); + return NULL; + } - if (!p) - ret = (void *)malloc(size); - else - ret = (void *)realloc(p,size); + if (!p) + ret = (void *) malloc (size); + else + ret = (void *) realloc (p, size); #ifdef MEM_MAN - { - extern FILE *dbf; - smb_mem_write_info(ret, dbf); - } + { + extern FILE *dbf; + smb_mem_write_info (ret, dbf); + } #endif - if (!ret) - DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",(int)size)); + if (!ret) + DEBUG (0, ("Memory allocation error: failed to expand to %d bytes\n", (int) size)); - return(ret); + return (ret); } /**************************************************************************** get my own name and IP ****************************************************************************/ -BOOL get_myname(char *my_name,struct in_addr *ip) +BOOL +get_myname (char *my_name, struct in_addr * ip) { - struct hostent *hp; - pstring hostname; + struct hostent *hp; + pstring hostname; - *hostname = 0; + *hostname = 0; - /* get my host name */ - if (gethostname(hostname, sizeof(hostname)) == -1) + /* get my host name */ + if (gethostname (hostname, sizeof (hostname)) == -1) { - DEBUG(0,("gethostname failed\n")); - return False; - } - - /* Ensure null termination. */ - hostname[sizeof(hostname)-1] = '\0'; - - /* get host info */ - if ((hp = Get_Hostbyname(hostname)) == 0) - { - DEBUG(0,( "Get_Hostbyname: Unknown host %s\n",hostname)); - return False; + DEBUG (0, ("gethostname failed\n")); + return False; } - if (my_name) - { - /* split off any parts after an initial . */ - char *p = strchr(hostname,'.'); - if (p) *p = 0; + /* Ensure null termination. */ + hostname[sizeof (hostname) - 1] = '\0'; - fstrcpy(my_name,hostname); + /* get host info */ + if ((hp = Get_Hostbyname (hostname)) == 0) + { + DEBUG (0, ("Get_Hostbyname: Unknown host %s\n", hostname)); + return False; } - if (ip) - putip((char *)ip,(char *)hp->h_addr); + if (my_name) + { + /* split off any parts after an initial . */ + char *p = strchr (hostname, '.'); + if (p) + *p = 0; - return(True); + fstrcpy (my_name, hostname); + } + + if (ip) + putip ((char *) ip, (char *) hp->h_addr); + + return (True); } /**************************************************************************** true if two IP addresses are equal ****************************************************************************/ -BOOL ip_equal(struct in_addr ip1,struct in_addr ip2) +BOOL +ip_equal (struct in_addr ip1, struct in_addr ip2) { - uint32 a1,a2; - a1 = ntohl(ip1.s_addr); - a2 = ntohl(ip2.s_addr); - return(a1 == a2); + uint32 a1, a2; + a1 = ntohl (ip1.s_addr); + a2 = ntohl (ip2.s_addr); + return (a1 == a2); } -#if 0 /* May be useful one day */ +#if 0 /* May be useful one day */ /**************************************************************************** interpret a protocol description string, with a default ****************************************************************************/ -int interpret_protocol(char *str,int def) +int +interpret_protocol (char *str, int def) { - if (strequal(str,"NT1")) - return(PROTOCOL_NT1); - if (strequal(str,"LANMAN2")) - return(PROTOCOL_LANMAN2); - if (strequal(str,"LANMAN1")) - return(PROTOCOL_LANMAN1); - if (strequal(str,"CORE")) - return(PROTOCOL_CORE); - if (strequal(str,"COREPLUS")) - return(PROTOCOL_COREPLUS); - if (strequal(str,"CORE+")) - return(PROTOCOL_COREPLUS); - - DEBUG(0,("Unrecognised protocol level %s\n",str)); - - return(def); + if (strequal (str, "NT1")) + return (PROTOCOL_NT1); + if (strequal (str, "LANMAN2")) + return (PROTOCOL_LANMAN2); + if (strequal (str, "LANMAN1")) + return (PROTOCOL_LANMAN1); + if (strequal (str, "CORE")) + return (PROTOCOL_CORE); + if (strequal (str, "COREPLUS")) + return (PROTOCOL_COREPLUS); + if (strequal (str, "CORE+")) + return (PROTOCOL_COREPLUS); + + DEBUG (0, ("Unrecognised protocol level %s\n", str)); + + return (def); } -#endif /* 0 */ +#endif /* 0 */ /**************************************************************************** interpret an internet address or name into an IP address in 4 byte form ****************************************************************************/ -uint32 interpret_addr(const char *str) +uint32 +interpret_addr (const char *str) { - struct hostent *hp; - uint32 res; - int i; - BOOL pure_address = True; + struct hostent *hp; + uint32 res; + int i; + BOOL pure_address = True; - if (strcmp(str,"0.0.0.0") == 0) return(0); - if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF); + if (strcmp (str, "0.0.0.0") == 0) + return (0); + if (strcmp (str, "255.255.255.255") == 0) + return (0xFFFFFFFF); - for (i=0; pure_address && str[i]; i++) - if (!(isdigit((int)str[i]) || str[i] == '.')) - pure_address = False; + for (i = 0; pure_address && str[i]; i++) + if (!(isdigit ((int) str[i]) || str[i] == '.')) + pure_address = False; - /* if it's in the form of an IP address then get the lib to interpret it */ - if (pure_address) { - res = inet_addr(str); - } else { - /* otherwise assume it's a network name of some sort and use - Get_Hostbyname */ - if ((hp = Get_Hostbyname(str)) == 0) { - DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str)); - return 0; + /* if it's in the form of an IP address then get the lib to interpret it */ + if (pure_address) + { + res = inet_addr (str); } - if(hp->h_addr == NULL) { - DEBUG(3,("Get_Hostbyname: host address is invalid for host %s\n",str)); - return 0; + else + { + /* otherwise assume it's a network name of some sort and use + Get_Hostbyname */ + if ((hp = Get_Hostbyname (str)) == 0) + { + DEBUG (3, ("Get_Hostbyname: Unknown host. %s\n", str)); + return 0; + } + if (hp->h_addr == NULL) + { + DEBUG (3, ("Get_Hostbyname: host address is invalid for host %s\n", str)); + return 0; + } + putip ((char *) &res, (char *) hp->h_addr); } - putip((char *)&res,(char *)hp->h_addr); - } - if (res == (uint32)-1) return(0); + if (res == (uint32) - 1) + return (0); - return(res); + return (res); } /******************************************************************* a convenient addition to interpret_addr() ******************************************************************/ -struct in_addr *interpret_addr2(const char *str) +struct in_addr * +interpret_addr2 (const char *str) { - static struct in_addr ret; - uint32 a = interpret_addr(str); - ret.s_addr = a; - return(&ret); + static struct in_addr ret; + uint32 a = interpret_addr (str); + ret.s_addr = a; + return (&ret); } /******************************************************************* check if an IP is the 0.0.0.0 ******************************************************************/ -BOOL zero_ip(struct in_addr ip) +BOOL +zero_ip (struct in_addr ip) { - uint32 a; - putip((char *)&a,(char *)&ip); - return(a == 0); + uint32 a; + putip ((char *) &a, (char *) &ip); + return (a == 0); } /******************************************************************* matchname - determine if host name matches IP address ******************************************************************/ -BOOL matchname(char *remotehost,struct in_addr addr) +BOOL +matchname (char *remotehost, struct in_addr addr) { - struct hostent *hp; - int i; - - if ((hp = Get_Hostbyname(remotehost)) == 0) { - DEBUG(0,("Get_Hostbyname(%s): lookup failure.\n", remotehost)); - return False; - } + struct hostent *hp; + int i; - /* - * Make sure that gethostbyname() returns the "correct" host name. - * Unfortunately, gethostbyname("localhost") sometimes yields - * "localhost.domain". Since the latter host name comes from the - * local DNS, we just have to trust it (all bets are off if the local - * DNS is perverted). We always check the address list, though. - */ - - if (strcasecmp(remotehost, hp->h_name) - && strcasecmp(remotehost, "localhost")) { - DEBUG(0,("host name/name mismatch: %s != %s\n", - remotehost, hp->h_name)); - return False; - } - - /* Look up the host address in the address list we just got. */ - for (i = 0; hp->h_addr_list[i]; i++) { - if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0) - return True; - } + if ((hp = Get_Hostbyname (remotehost)) == 0) + { + DEBUG (0, ("Get_Hostbyname(%s): lookup failure.\n", remotehost)); + return False; + } - /* - * The host name does not map to the original host address. Perhaps - * someone has compromised a name server. More likely someone botched - * it, but that could be dangerous, too. - */ - - DEBUG(0,("host name/address mismatch: %s != %s\n", - inet_ntoa(addr), hp->h_name)); - return False; + /* + * Make sure that gethostbyname() returns the "correct" host name. + * Unfortunately, gethostbyname("localhost") sometimes yields + * "localhost.domain". Since the latter host name comes from the + * local DNS, we just have to trust it (all bets are off if the local + * DNS is perverted). We always check the address list, though. + */ + + if (strcasecmp (remotehost, hp->h_name) && strcasecmp (remotehost, "localhost")) + { + DEBUG (0, ("host name/name mismatch: %s != %s\n", remotehost, hp->h_name)); + return False; + } + + /* Look up the host address in the address list we just got. */ + for (i = 0; hp->h_addr_list[i]; i++) + { + if (memcmp (hp->h_addr_list[i], (caddr_t) & addr, sizeof (addr)) == 0) + return True; + } + + /* + * The host name does not map to the original host address. Perhaps + * someone has compromised a name server. More likely someone botched + * it, but that could be dangerous, too. + */ + + DEBUG (0, ("host name/address mismatch: %s != %s\n", inet_ntoa (addr), hp->h_name)); + return False; } @@ -1858,22 +2023,24 @@ BOOL matchname(char *remotehost,struct in_addr addr) Based on a fix from . *******************************************************************/ -static void strip_mount_options( pstring *str) +static void +strip_mount_options (pstring * str) { - if (**str == '-') - { - char *p = *str; - while(*p && !isspace(*p)) - p++; - while(*p && isspace(*p)) - p++; - if(*p) { - pstring tmp_str; + if (**str == '-') + { + char *p = *str; + while (*p && !isspace (*p)) + p++; + while (*p && isspace (*p)) + p++; + if (*p) + { + pstring tmp_str; - pstrcpy(tmp_str, p); - pstrcpy(*str, tmp_str); + pstrcpy (tmp_str, p); + pstrcpy (*str, tmp_str); + } } - } } /******************************************************************* @@ -1884,104 +2051,109 @@ static void strip_mount_options( pstring *str) *******************************************************************/ #ifdef WITH_NISPLUS_HOME -static char *automount_lookup(char *user_name) +static char * +automount_lookup (char *user_name) { - static fstring last_key = ""; - static pstring last_value = ""; - - char *nis_map = (char *)lp_nis_home_map_name(); - - char buffer[NIS_MAXATTRVAL + 1]; - nis_result *result; - nis_object *object; - entry_obj *entry; - - DEBUG(5, ("NIS+ Domain: %s\n", (char *)nis_local_directory())); - - if (strcmp(user_name, last_key)) - { - slprintf(buffer, sizeof(buffer)-1, "[%s=%s]%s.%s", "key", user_name, nis_map, - (char *)nis_local_directory()); - DEBUG(5, ("NIS+ querystring: %s\n", buffer)); - - if (result = nis_list(buffer, RETURN_RESULT, NULL, NULL)) + static fstring last_key = ""; + static pstring last_value = ""; + + char *nis_map = (char *) lp_nis_home_map_name (); + + char buffer[NIS_MAXATTRVAL + 1]; + nis_result *result; + nis_object *object; + entry_obj *entry; + + DEBUG (5, ("NIS+ Domain: %s\n", (char *) nis_local_directory ())); + + if (strcmp (user_name, last_key)) { - if (result->status != NIS_SUCCESS) - { - DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status))); - fstrcpy(last_key, ""); pstrcpy(last_value, ""); - } - else - { - object = result->objects.objects_val; - if (object->zo_data.zo_type == ENTRY_OBJ) + slprintf (buffer, sizeof (buffer) - 1, "[%s=%s]%s.%s", "key", user_name, nis_map, + (char *) nis_local_directory ()); + DEBUG (5, ("NIS+ querystring: %s\n", buffer)); + + if (result = nis_list (buffer, RETURN_RESULT, NULL, NULL)) { - entry = &object->zo_data.objdata_u.en_data; - DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type)); - DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val)); - - pstrcpy(last_value, entry->en_cols.en_cols_val[1].ec_value.ec_value_val); - string_sub(last_value, "&", user_name); - fstrcpy(last_key, user_name); + if (result->status != NIS_SUCCESS) + { + DEBUG (3, ("NIS+ query failed: %s\n", nis_sperrno (result->status))); + fstrcpy (last_key, ""); + pstrcpy (last_value, ""); + } + else + { + object = result->objects.objects_val; + if (object->zo_data.zo_type == ENTRY_OBJ) + { + entry = &object->zo_data.objdata_u.en_data; + DEBUG (5, ("NIS+ entry type: %s\n", entry->en_type)); + DEBUG (3, + ("NIS+ result: %s\n", + entry->en_cols.en_cols_val[1].ec_value.ec_value_val)); + + pstrcpy (last_value, entry->en_cols.en_cols_val[1].ec_value.ec_value_val); + string_sub (last_value, "&", user_name); + fstrcpy (last_key, user_name); + } + } } - } + nis_freeresult (result); } - nis_freeresult(result); - } - strip_mount_options(&last_value); + strip_mount_options (&last_value); - DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n", user_name, last_value)); - return last_value; + DEBUG (4, ("NIS+ Lookup: %s resulted in %s\n", user_name, last_value)); + return last_value; } #else /* WITH_NISPLUS_HOME */ -static char *automount_lookup(char *user_name) +static char * +automount_lookup (char *user_name) { - static fstring last_key = ""; - static pstring last_value = ""; + static fstring last_key = ""; + static pstring last_value = ""; - int nis_error; /* returned by yp all functions */ - char *nis_result; /* yp_match inits this */ - int nis_result_len; /* and set this */ - char *nis_domain; /* yp_get_default_domain inits this */ - char *nis_map = (char *)lp_nis_home_map_name(); + int nis_error; /* returned by yp all functions */ + char *nis_result; /* yp_match inits this */ + int nis_result_len; /* and set this */ + char *nis_domain; /* yp_get_default_domain inits this */ + char *nis_map = (char *) lp_nis_home_map_name (); - if ((nis_error = yp_get_default_domain(&nis_domain)) != 0) - { - DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error))); + if ((nis_error = yp_get_default_domain (&nis_domain)) != 0) + { + DEBUG (3, ("YP Error: %s\n", yperr_string (nis_error))); + return last_value; + } + + DEBUG (5, ("NIS Domain: %s\n", nis_domain)); + + if (!strcmp (user_name, last_key)) + { + nis_result = last_value; + nis_result_len = strlen (last_value); + nis_error = 0; + } + else + { + if ((nis_error = yp_match (nis_domain, nis_map, + user_name, strlen (user_name), + &nis_result, &nis_result_len)) != 0) + { + DEBUG (3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n", + yperr_string (nis_error), user_name, nis_map)); + } + if (!nis_error && nis_result_len >= sizeof (pstring)) + { + nis_result_len = sizeof (pstring) - 1; + } + fstrcpy (last_key, user_name); + strncpy (last_value, nis_result, nis_result_len); + last_value[nis_result_len] = '\0'; + } + + strip_mount_options (&last_value); + + DEBUG (4, ("YP Lookup: %s resulted in %s\n", user_name, last_value)); return last_value; - } - - DEBUG(5, ("NIS Domain: %s\n", nis_domain)); - - if (!strcmp(user_name, last_key)) - { - nis_result = last_value; - nis_result_len = strlen(last_value); - nis_error = 0; - } - else - { - if ((nis_error = yp_match(nis_domain, nis_map, - user_name, strlen(user_name), - &nis_result, &nis_result_len)) != 0) - { - DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n", - yperr_string(nis_error), user_name, nis_map)); - } - if (!nis_error && nis_result_len >= sizeof(pstring)) - { - nis_result_len = sizeof(pstring)-1; - } - fstrcpy(last_key, user_name); - strncpy(last_value, nis_result, nis_result_len); - last_value[nis_result_len] = '\0'; - } - - strip_mount_options(&last_value); - - DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, last_value)); - return last_value; } #endif /* WITH_NISPLUS_HOME */ #endif @@ -1991,69 +2163,71 @@ static char *automount_lookup(char *user_name) This is Luke's original function with the NIS lookup code moved out to a separate function. *******************************************************************/ -static char *automount_server(const char *user_name) +static char * +automount_server (const char *user_name) { - static pstring server_name; - (void) user_name; + static pstring server_name; + (void) user_name; - /* use the local machine name as the default */ - /* this will be the default if WITH_AUTOMOUNT is not used or fails */ - pstrcpy(server_name, local_machine); + /* use the local machine name as the default */ + /* this will be the default if WITH_AUTOMOUNT is not used or fails */ + pstrcpy (server_name, local_machine); #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT)) - if (lp_nis_home_map()) - { - int home_server_len; - char *automount_value = automount_lookup(user_name); - home_server_len = strcspn(automount_value,":"); - DEBUG(5, ("NIS lookup succeeded. Home server length: %d\n",home_server_len)); - if (home_server_len > sizeof(pstring)) - { - home_server_len = sizeof(pstring); - } - strncpy(server_name, automount_value, home_server_len); - server_name[home_server_len] = '\0'; - } + if (lp_nis_home_map ()) + { + int home_server_len; + char *automount_value = automount_lookup (user_name); + home_server_len = strcspn (automount_value, ":"); + DEBUG (5, ("NIS lookup succeeded. Home server length: %d\n", home_server_len)); + if (home_server_len > sizeof (pstring)) + { + home_server_len = sizeof (pstring); + } + strncpy (server_name, automount_value, home_server_len); + server_name[home_server_len] = '\0'; + } #endif - DEBUG(4,("Home server: %s\n", server_name)); + DEBUG (4, ("Home server: %s\n", server_name)); - return server_name; + return server_name; } /******************************************************************* Patch from jkf@soton.ac.uk Added this to implement %p (NIS auto-map version of %H) *******************************************************************/ -static char *automount_path(char *user_name) +static char * +automount_path (char *user_name) { - static pstring server_path; + static pstring server_path; - /* use the passwd entry as the default */ - /* this will be the default if WITH_AUTOMOUNT is not used or fails */ - /* pstrcpy() copes with get_home_dir() returning NULL */ - pstrcpy(server_path, get_home_dir(user_name)); + /* use the passwd entry as the default */ + /* this will be the default if WITH_AUTOMOUNT is not used or fails */ + /* pstrcpy() copes with get_home_dir() returning NULL */ + pstrcpy (server_path, get_home_dir (user_name)); #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT)) - if (lp_nis_home_map()) - { - char *home_path_start; - char *automount_value = automount_lookup(user_name); - home_path_start = strchr(automount_value,':'); - if (home_path_start != NULL) - { - DEBUG(5, ("NIS lookup succeeded. Home path is: %s\n", - home_path_start?(home_path_start+1):"")); - pstrcpy(server_path, home_path_start+1); - } - } + if (lp_nis_home_map ()) + { + char *home_path_start; + char *automount_value = automount_lookup (user_name); + home_path_start = strchr (automount_value, ':'); + if (home_path_start != NULL) + { + DEBUG (5, ("NIS lookup succeeded. Home path is: %s\n", + home_path_start ? (home_path_start + 1) : "")); + pstrcpy (server_path, home_path_start + 1); + } + } #endif - DEBUG(4,("Home server path: %s\n", server_path)); + DEBUG (4, ("Home server path: %s\n", server_path)); - return server_path; + return server_path; } @@ -2062,151 +2236,181 @@ sub strings with useful parameters Rewritten by Stefaan A Eeckels and Paul Rippin ********************************************************************/ -void standard_sub_basic(char *str) +void +standard_sub_basic (char *str) { - char *s, *p; - char pidstr[10]; - struct passwd *pass; - const char *username = sam_logon_in_ssb ? samlogon_user : sesssetup_user; + char *s, *p; + char pidstr[10]; + struct passwd *pass; + const char *username = sam_logon_in_ssb ? samlogon_user : sesssetup_user; - for (s = str ; s && *s && (p = strchr(s,'%')); s = p ) - { - switch (*(p+1)) - { - case 'G' : - { - if ((pass = Get_Pwnam(username))!=NULL) - { - string_sub(p,"%G",gidtoname(pass->pw_gid)); - } - else - { - p += 2; - } - break; - } - case 'N' : string_sub(p,"%N", automount_server(username)); break; - case 'I' : string_sub(p,"%I", client_addr(Client)); break; - case 'L' : string_sub(p,"%L", local_machine); break; - case 'M' : string_sub(p,"%M", client_name(Client)); break; - case 'R' : string_sub(p,"%R", remote_proto); break; - case 'T' : string_sub(p,"%T", timestring()); break; - case 'U' : string_sub(p,"%U", username); break; - case 'a' : string_sub(p,"%a", remote_arch); break; - case 'd' : - { - slprintf(pidstr,sizeof(pidstr) - 1, "%d",(int)getpid()); - string_sub(p,"%d", pidstr); - break; - } - case 'h' : string_sub(p,"%h", myhostname); break; - case 'm' : string_sub(p,"%m", remote_machine); break; - case 'v' : string_sub(p,"%v", VERSION); break; - case '$' : /* Expand environment variables */ - { - /* Contributed by Branko Cibej */ - fstring envname; - char *envval; - char *q, *r; - int copylen; + for (s = str; s && *s && (p = strchr (s, '%')); s = p) + { + switch (*(p + 1)) + { + case 'G': + { + if ((pass = Get_Pwnam (username)) != NULL) + { + string_sub (p, "%G", gidtoname (pass->pw_gid)); + } + else + { + p += 2; + } + break; + } + case 'N': + string_sub (p, "%N", automount_server (username)); + break; + case 'I': + string_sub (p, "%I", client_addr (Client)); + break; + case 'L': + string_sub (p, "%L", local_machine); + break; + case 'M': + string_sub (p, "%M", client_name (Client)); + break; + case 'R': + string_sub (p, "%R", remote_proto); + break; + case 'T': + string_sub (p, "%T", timestring ()); + break; + case 'U': + string_sub (p, "%U", username); + break; + case 'a': + string_sub (p, "%a", remote_arch); + break; + case 'd': + { + slprintf (pidstr, sizeof (pidstr) - 1, "%d", (int) getpid ()); + string_sub (p, "%d", pidstr); + break; + } + case 'h': + string_sub (p, "%h", myhostname); + break; + case 'm': + string_sub (p, "%m", remote_machine); + break; + case 'v': + string_sub (p, "%v", VERSION); + break; + case '$': /* Expand environment variables */ + { + /* Contributed by Branko Cibej */ + fstring envname; + char *envval; + char *q, *r; + int copylen; - if (*(p+2) != '(') - { - p+=2; - break; - } - if ((q = strchr(p,')')) == NULL) - { - DEBUG(0,("standard_sub_basic: Unterminated environment \ + if (*(p + 2) != '(') + { + p += 2; + break; + } + if ((q = strchr (p, ')')) == NULL) + { + DEBUG (0, ("standard_sub_basic: Unterminated environment \ variable [%s]\n", p)); - p+=2; - break; - } + p += 2; + break; + } - r = p+3; - copylen = MIN((size_t)(q-r),(size_t)(sizeof(envname)-1)); - strncpy(envname,r,copylen); - envname[copylen] = '\0'; + r = p + 3; + copylen = MIN ((size_t) (q - r), (size_t) (sizeof (envname) - 1)); + strncpy (envname, r, copylen); + envname[copylen] = '\0'; - if ((envval = getenv(envname)) == NULL) - { - DEBUG(0,("standard_sub_basic: Environment variable [%s] not set\n", - envname)); - p+=2; - break; - } + if ((envval = getenv (envname)) == NULL) + { + DEBUG (0, ("standard_sub_basic: Environment variable [%s] not set\n", envname)); + p += 2; + break; + } - copylen = MIN((size_t)(q+1-p),(size_t)(sizeof(envname)-1)); - strncpy(envname,p,copylen); - envname[copylen] = '\0'; - string_sub(p,envname,envval); - break; - } - case '\0': p++; break; /* don't run off end if last character is % */ - default : p+=2; break; - } - } - return; + copylen = MIN ((size_t) (q + 1 - p), (size_t) (sizeof (envname) - 1)); + strncpy (envname, p, copylen); + envname[copylen] = '\0'; + string_sub (p, envname, envval); + break; + } + case '\0': + p++; + break; /* don't run off end if last character is % */ + default: + p += 2; + break; + } + } + return; } /**************************************************************************** do some standard substitutions in a string ****************************************************************************/ -void standard_sub(connection_struct *conn,char *str) +void +standard_sub (connection_struct * conn, char *str) { - char *p, *s; - const char *home; + char *p, *s; + const char *home; - for (s=str; (p=strchr(s, '%'));s=p) { - switch (*(p+1)) { - case 'H': - if ((home = get_home_dir(conn->user))) { - string_sub(p,"%H",home); - } else { - p += 2; - } - break; - - case 'P': - string_sub(p,"%P",conn->connectpath); - break; - - case 'S': - string_sub(p,"%S", - lp_servicename(SNUM(conn))); - break; - - case 'g': - string_sub(p,"%g", - gidtoname(conn->gid)); - break; - case 'u': - string_sub(p,"%u",conn->user); - break; - - /* Patch from jkf@soton.ac.uk Left the %N (NIS - * server name) in standard_sub_basic as it is - * a feature for logon servers, hence uses the - * username. The %p (NIS server path) code is - * here as it is used instead of the default - * "path =" string in [homes] and so needs the - * service name, not the username. */ - case 'p': - string_sub(p,"%p", - automount_path(lp_servicename(SNUM(conn)))); - break; - case '\0': - p++; - break; /* don't run off the end of the string - */ - - default: p+=2; - break; - } - } - - standard_sub_basic(str); + for (s = str; (p = strchr (s, '%')); s = p) + { + switch (*(p + 1)) + { + case 'H': + if ((home = get_home_dir (conn->user))) + { + string_sub (p, "%H", home); + } + else + { + p += 2; + } + break; + + case 'P': + string_sub (p, "%P", conn->connectpath); + break; + + case 'S': + string_sub (p, "%S", lp_servicename (SNUM (conn))); + break; + + case 'g': + string_sub (p, "%g", gidtoname (conn->gid)); + break; + case 'u': + string_sub (p, "%u", conn->user); + break; + + /* Patch from jkf@soton.ac.uk Left the %N (NIS + * server name) in standard_sub_basic as it is + * a feature for logon servers, hence uses the + * username. The %p (NIS server path) code is + * here as it is used instead of the default + * "path =" string in [homes] and so needs the + * service name, not the username. */ + case 'p': + string_sub (p, "%p", automount_path (lp_servicename (SNUM (conn)))); + break; + case '\0': + p++; + break; /* don't run off the end of the string + */ + + default: + p += 2; + break; + } + } + + standard_sub_basic (str); } @@ -2214,15 +2418,16 @@ void standard_sub(connection_struct *conn,char *str) /******************************************************************* are two IPs on the same subnet? ********************************************************************/ -BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask) +BOOL +same_net (struct in_addr ip1, struct in_addr ip2, struct in_addr mask) { - uint32 net1,net2,nmask; + uint32 net1, net2, nmask; - nmask = ntohl(mask.s_addr); - net1 = ntohl(ip1.s_addr); - net2 = ntohl(ip2.s_addr); - - return((net1 & nmask) == (net2 & nmask)); + nmask = ntohl (mask.s_addr); + net1 = ntohl (ip1.s_addr); + net2 = ntohl (ip2.s_addr); + + return ((net1 & nmask) == (net2 & nmask)); } @@ -2230,73 +2435,76 @@ BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask) a wrapper for gethostbyname() that tries with all lower and all upper case if the initial name fails ****************************************************************************/ -struct hostent *Get_Hostbyname(const char *name) +struct hostent * +Get_Hostbyname (const char *name) { - char *name2 = strdup(name); - struct hostent *ret; + char *name2 = strdup (name); + struct hostent *ret; - if (!name2) + if (!name2) { - DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n")); - exit(0); + DEBUG (0, ("Memory allocation error in Get_Hostbyname! panic\n")); + exit (0); } - - /* - * This next test is redundent and causes some systems (with - * broken isalnum() calls) problems. - * JRA. - */ + + /* + * This next test is redundent and causes some systems (with + * broken isalnum() calls) problems. + * JRA. + */ #if 0 - if (!isalnum(*name2)) + if (!isalnum (*name2)) { - free(name2); - return(NULL); + free (name2); + return (NULL); } #endif /* 0 */ - ret = sys_gethostbyname(name2); - if (ret != NULL) + ret = sys_gethostbyname (name2); + if (ret != NULL) { - free(name2); - return(ret); + free (name2); + return (ret); } - /* try with all lowercase */ - strlower(name2); - ret = sys_gethostbyname(name2); - if (ret != NULL) + /* try with all lowercase */ + strlower (name2); + ret = sys_gethostbyname (name2); + if (ret != NULL) { - free(name2); - return(ret); + free (name2); + return (ret); } - /* try with all uppercase */ - strupper(name2); - ret = sys_gethostbyname(name2); - if (ret != NULL) + /* try with all uppercase */ + strupper (name2); + ret = sys_gethostbyname (name2); + if (ret != NULL) { - free(name2); - return(ret); + free (name2); + return (ret); } - - /* nothing works :-( */ - free(name2); - return(NULL); + + /* nothing works :-( */ + free (name2); + return (NULL); } /******************************************************************* turn a uid into a user name ********************************************************************/ -char *uidtoname(uid_t uid) +char * +uidtoname (uid_t uid) { - static char name[40]; - struct passwd *pass = getpwuid(uid); - if (pass) return(pass->pw_name); - slprintf(name, sizeof(name) - 1, "%d",(int)uid); - return(name); + static char name[40]; + struct passwd *pass = getpwuid (uid); + if (pass) + return (pass->pw_name); + slprintf (name, sizeof (name) - 1, "%d", (int) uid); + return (name); } @@ -2304,71 +2512,84 @@ char *uidtoname(uid_t uid) turn a gid into a group name ********************************************************************/ -char *gidtoname(gid_t gid) +char * +gidtoname (gid_t gid) { - static char name[40]; - struct group *grp = getgrgid(gid); - if (grp) return(grp->gr_name); - slprintf(name,sizeof(name) - 1, "%d",(int)gid); - return(name); + static char name[40]; + struct group *grp = getgrgid (gid); + if (grp) + return (grp->gr_name); + slprintf (name, sizeof (name) - 1, "%d", (int) gid); + return (name); } /******************************************************************* turn a user name into a uid ********************************************************************/ -uid_t nametouid(const char *name) +uid_t +nametouid (const char *name) { - struct passwd *pass = getpwnam(name); - if (pass) return(pass->pw_uid); - return (uid_t)-1; + struct passwd *pass = getpwnam (name); + if (pass) + return (pass->pw_uid); + return (uid_t) - 1; } /******************************************************************* something really nasty happened - panic! ********************************************************************/ -void smb_panic(const char *why) +void +smb_panic (const char *why) { - const char *cmd = lp_panic_action(); - if (cmd && *cmd) { - system(cmd); - } - DEBUG(0,("PANIC: %s\n", why)); - dbgflush(); - abort(); + const char *cmd = lp_panic_action (); + if (cmd && *cmd) + { + if (system (cmd)) + { + DEBUG (0, ("PANIC: cannot run panic handler command \"%s\"\n", cmd)); + } + } + DEBUG (0, ("PANIC: %s\n", why)); + dbgflush (); + abort (); } #if 0 /******************************************************************* a readdir wrapper which just returns the file name ********************************************************************/ -char *readdirname(DIR *p) +char * +readdirname (DIR * p) { - SMB_STRUCT_DIRENT *ptr; - char *dname; + SMB_STRUCT_DIRENT *ptr; + char *dname; - if (!p) return(NULL); - - ptr = (SMB_STRUCT_DIRENT *)sys_readdir(p); - if (!ptr) return(NULL); + if (!p) + return (NULL); - dname = ptr->d_name; + ptr = (SMB_STRUCT_DIRENT *) sys_readdir (p); + if (!ptr) + return (NULL); + + dname = ptr->d_name; #ifdef NEXT2 - if (telldir(p) < 0) return(NULL); + if (telldir (p) < 0) + return (NULL); #endif #ifdef HAVE_BROKEN_READDIR - /* using /usr/ucb/cc is BAD */ - dname = dname - 2; + /* using /usr/ucb/cc is BAD */ + dname = dname - 2; #endif - { - static pstring buf; - memcpy(buf, dname, NAMLEN(ptr)+1); - dname = buf; - } + { + static pstring buf; + memcpy (buf, dname, NAMLEN (ptr) + 1); + dname = buf; + } - return(dname); + return (dname); } /******************************************************************* @@ -2376,53 +2597,54 @@ char *readdirname(DIR *p) of a path matches a (possibly wildcarded) entry in a namelist. ********************************************************************/ -BOOL is_in_path(char *name, name_compare_entry *namelist) +BOOL +is_in_path (char *name, name_compare_entry * namelist) { - pstring last_component; - char *p; + pstring last_component; + char *p; - DEBUG(8, ("is_in_path: %s\n", name)); + DEBUG (8, ("is_in_path: %s\n", name)); - /* if we have no list it's obviously not in the path */ - if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) - { - DEBUG(8,("is_in_path: no name list.\n")); - return False; - } - - /* Get the last component of the unix name. */ - p = strrchr(name, '/'); - strncpy(last_component, p ? ++p : name, sizeof(last_component)-1); - last_component[sizeof(last_component)-1] = '\0'; - - for(; namelist->name != NULL; namelist++) - { - if(namelist->is_wild) + /* if we have no list it's obviously not in the path */ + if ((namelist == NULL) || ((namelist != NULL) && (namelist[0].name == NULL))) { - /* - * Look for a wildcard match. Use the old - * 'unix style' mask match, rather than the - * new NT one. - */ - if (unix_mask_match(last_component, namelist->name, case_sensitive, False)) - { - DEBUG(8,("is_in_path: mask match succeeded\n")); - return True; - } + DEBUG (8, ("is_in_path: no name list.\n")); + return False; } - else + + /* Get the last component of the unix name. */ + p = strrchr (name, '/'); + strncpy (last_component, p ? ++p : name, sizeof (last_component) - 1); + last_component[sizeof (last_component) - 1] = '\0'; + + for (; namelist->name != NULL; namelist++) { - if((case_sensitive && (strcmp(last_component, namelist->name) == 0))|| - (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0))) + if (namelist->is_wild) { - DEBUG(8,("is_in_path: match succeeded\n")); - return True; + /* + * Look for a wildcard match. Use the old + * 'unix style' mask match, rather than the + * new NT one. + */ + if (unix_mask_match (last_component, namelist->name, case_sensitive, False)) + { + DEBUG (8, ("is_in_path: mask match succeeded\n")); + return True; + } + } + else + { + if ((case_sensitive && (strcmp (last_component, namelist->name) == 0)) || + (!case_sensitive && (StrCaseCmp (last_component, namelist->name) == 0))) + { + DEBUG (8, ("is_in_path: match succeeded\n")); + return True; + } } } - } - DEBUG(8,("is_in_path: match not found\n")); - - return False; + DEBUG (8, ("is_in_path: match not found\n")); + + return False; } /******************************************************************* @@ -2437,216 +2659,223 @@ BOOL is_in_path(char *name, name_compare_entry *namelist) remove a potentially expensive call to mask_match if possible. ********************************************************************/ - -void set_namearray(name_compare_entry **ppname_array, char *namelist) + +void +set_namearray (name_compare_entry ** ppname_array, char *namelist) { - char *name_end; - char *nameptr = namelist; - int num_entries = 0; - int i; + char *name_end; + char *nameptr = namelist; + int num_entries = 0; + int i; - (*ppname_array) = NULL; + (*ppname_array) = NULL; - if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0'))) - return; - - /* We need to make two passes over the string. The - first to count the number of elements, the second - to split it. - */ - while(*nameptr) - { - if ( *nameptr == '/' ) - { - /* cope with multiple (useless) /s) */ - nameptr++; - continue; - } - /* find the next / */ - name_end = strchr(nameptr, '/'); - - /* oops - the last check for a / didn't find one. */ - if (name_end == NULL) - break; - - /* next segment please */ - nameptr = name_end + 1; - num_entries++; - } - - if(num_entries == 0) - return; - - if(( (*ppname_array) = (name_compare_entry *)malloc( - (num_entries + 1) * sizeof(name_compare_entry))) == NULL) - { - DEBUG(0,("set_namearray: malloc fail\n")); - return; - } - - /* Now copy out the names */ - nameptr = namelist; - i = 0; - while(*nameptr) - { - if ( *nameptr == '/' ) - { - /* cope with multiple (useless) /s) */ - nameptr++; - continue; - } - /* find the next / */ - if ((name_end = strchr(nameptr, '/')) != NULL) - { - *name_end = 0; - } - - /* oops - the last check for a / didn't find one. */ - if(name_end == NULL) - break; - - (*ppname_array)[i].is_wild = ((strchr( nameptr, '?')!=NULL) || - (strchr( nameptr, '*')!=NULL)); - if(((*ppname_array)[i].name = strdup(nameptr)) == NULL) - { - DEBUG(0,("set_namearray: malloc fail (1)\n")); + if ((nameptr == NULL) || ((nameptr != NULL) && (*nameptr == '\0'))) return; - } - /* next segment please */ - nameptr = name_end + 1; - i++; + /* We need to make two passes over the string. The + first to count the number of elements, the second + to split it. + */ + while (*nameptr) + { + if (*nameptr == '/') + { + /* cope with multiple (useless) /s) */ + nameptr++; + continue; + } + /* find the next / */ + name_end = strchr (nameptr, '/'); + + /* oops - the last check for a / didn't find one. */ + if (name_end == NULL) + break; + + /* next segment please */ + nameptr = name_end + 1; + num_entries++; } - - (*ppname_array)[i].name = NULL; - return; + if (num_entries == 0) + return; + + if (((*ppname_array) = (name_compare_entry *) malloc ((num_entries + + 1) * sizeof (name_compare_entry))) == + NULL) + { + DEBUG (0, ("set_namearray: malloc fail\n")); + return; + } + + /* Now copy out the names */ + nameptr = namelist; + i = 0; + while (*nameptr) + { + if (*nameptr == '/') + { + /* cope with multiple (useless) /s) */ + nameptr++; + continue; + } + /* find the next / */ + if ((name_end = strchr (nameptr, '/')) != NULL) + { + *name_end = 0; + } + + /* oops - the last check for a / didn't find one. */ + if (name_end == NULL) + break; + + (*ppname_array)[i].is_wild = ((strchr (nameptr, '?') != NULL) || + (strchr (nameptr, '*') != NULL)); + if (((*ppname_array)[i].name = strdup (nameptr)) == NULL) + { + DEBUG (0, ("set_namearray: malloc fail (1)\n")); + return; + } + + /* next segment please */ + nameptr = name_end + 1; + i++; + } + + (*ppname_array)[i].name = NULL; + + return; } /**************************************************************************** routine to free a namearray. ****************************************************************************/ -void free_namearray(name_compare_entry *name_array) +void +free_namearray (name_compare_entry * name_array) { - if(name_array == 0) - return; + if (name_array == 0) + return; - if(name_array->name != NULL) - free(name_array->name); + if (name_array->name != NULL) + free (name_array->name); - free((char *)name_array); + free ((char *) name_array); } /**************************************************************************** routine to do file locking ****************************************************************************/ -BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type) +BOOL +fcntl_lock (int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type) { #ifdef HAVE_FCNTL_LOCK - SMB_STRUCT_FLOCK lock; - int ret; + SMB_STRUCT_FLOCK lock; + int ret; - if(lp_ole_locking_compat()) { - SMB_OFF_T mask2= ((SMB_OFF_T)0x3) << (SMB_OFF_T_BITS-4); - SMB_OFF_T mask = (mask2<<2); - - /* make sure the count is reasonable, we might kill the lockd otherwise */ - count &= ~mask; - - /* the offset is often strange - remove 2 of its bits if either of - the top two bits are set. Shift the top ones by two bits. This - still allows OLE2 apps to operate, but should stop lockd from - dieing */ - if ((offset & mask) != 0) - offset = (offset & ~mask) | (((offset & mask) >> 2) & mask2); - } else { - SMB_OFF_T mask2 = ((SMB_OFF_T)0x4) << (SMB_OFF_T_BITS-4); - SMB_OFF_T mask = (mask2<<1); - SMB_OFF_T neg_mask = ~mask; - - /* interpret negative counts as large numbers */ - if (count < 0) - count &= ~mask; - - /* no negative offsets */ - if(offset < 0) - offset &= ~mask; - - /* count + offset must be in range */ - while ((offset < 0 || (offset + count < 0)) && mask) + if (lp_ole_locking_compat ()) { - offset &= ~mask; - mask = ((mask >> 1) & neg_mask); + SMB_OFF_T mask2 = ((SMB_OFF_T) 0x3) << (SMB_OFF_T_BITS - 4); + SMB_OFF_T mask = (mask2 << 2); + + /* make sure the count is reasonable, we might kill the lockd otherwise */ + count &= ~mask; + + /* the offset is often strange - remove 2 of its bits if either of + the top two bits are set. Shift the top ones by two bits. This + still allows OLE2 apps to operate, but should stop lockd from + dieing */ + if ((offset & mask) != 0) + offset = (offset & ~mask) | (((offset & mask) >> 2) & mask2); } - } - - DEBUG(8,("fcntl_lock %d %d %.0f %.0f %d\n",fd,op,(double)offset,(double)count,type)); - - lock.l_type = type; - lock.l_whence = SEEK_SET; - lock.l_start = offset; - lock.l_len = count; - lock.l_pid = 0; - - errno = 0; - - ret = fcntl(fd,op,&lock); - if (errno == EFBIG) - { - if( DEBUGLVL( 0 )) + else { - dbgtext("fcntl_lock: WARNING: lock request at offset %.0f, length %.0f returned\n", (double)offset,(double)count); - dbgtext("a 'file too large' error. This can happen when using 64 bit lock offsets\n"); - dbgtext("on 32 bit NFS mounted file systems. Retrying with 32 bit truncated length.\n"); + SMB_OFF_T mask2 = ((SMB_OFF_T) 0x4) << (SMB_OFF_T_BITS - 4); + SMB_OFF_T mask = (mask2 << 1); + SMB_OFF_T neg_mask = ~mask; + + /* interpret negative counts as large numbers */ + if (count < 0) + count &= ~mask; + + /* no negative offsets */ + if (offset < 0) + offset &= ~mask; + + /* count + offset must be in range */ + while ((offset < 0 || (offset + count < 0)) && mask) + { + offset &= ~mask; + mask = ((mask >> 1) & neg_mask); + } } - /* 32 bit NFS file system, retry with smaller offset */ + + DEBUG (8, ("fcntl_lock %d %d %.0f %.0f %d\n", fd, op, (double) offset, (double) count, type)); + + lock.l_type = type; + lock.l_whence = SEEK_SET; + lock.l_start = offset; + lock.l_len = count; + lock.l_pid = 0; + errno = 0; - lock.l_len = count & 0xffffffff; - ret = fcntl(fd,op,&lock); - } - if (errno != 0) - DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno, unix_error_string(errno))); - - /* a lock query */ - if (op == SMB_F_GETLK) - { - if ((ret != -1) && - (lock.l_type != F_UNLCK) && - (lock.l_pid != 0) && - (lock.l_pid != getpid())) + ret = fcntl (fd, op, &lock); + if (errno == EFBIG) { - DEBUG(3,("fd %d is locked by pid %d\n",fd,(int)lock.l_pid)); - return(True); + if (DEBUGLVL (0)) + { + dbgtext ("fcntl_lock: WARNING: lock request at offset %.0f, length %.0f returned\n", + (double) offset, (double) count); + dbgtext ("a 'file too large' error. This can happen when using 64 bit lock offsets\n"); + dbgtext + ("on 32 bit NFS mounted file systems. Retrying with 32 bit truncated length.\n"); + } + /* 32 bit NFS file system, retry with smaller offset */ + errno = 0; + lock.l_len = count & 0xffffffff; + ret = fcntl (fd, op, &lock); } - /* it must be not locked or locked by me */ - return(False); - } + if (errno != 0) + DEBUG (3, ("fcntl lock gave errno %d (%s)\n", errno, unix_error_string (errno))); - /* a lock set or unset */ - if (ret == -1) - { - DEBUG(3,("lock failed at offset %.0f count %.0f op %d type %d (%s)\n", - (double)offset,(double)count,op,type, unix_error_string (errno))); - - /* perhaps it doesn't support this sort of locking?? */ - if (errno == EINVAL) + /* a lock query */ + if (op == SMB_F_GETLK) { - DEBUG(3,("locking not supported? returning True\n")); - return(True); + if ((ret != -1) && + (lock.l_type != F_UNLCK) && (lock.l_pid != 0) && (lock.l_pid != getpid ())) + { + DEBUG (3, ("fd %d is locked by pid %d\n", fd, (int) lock.l_pid)); + return (True); + } + + /* it must be not locked or locked by me */ + return (False); } - return(False); - } + /* a lock set or unset */ + if (ret == -1) + { + DEBUG (3, ("lock failed at offset %.0f count %.0f op %d type %d (%s)\n", + (double) offset, (double) count, op, type, unix_error_string (errno))); - /* everything went OK */ - DEBUG(8,("Lock call successful\n")); + /* perhaps it doesn't support this sort of locking?? */ + if (errno == EINVAL) + { + DEBUG (3, ("locking not supported? returning True\n")); + return (True); + } - return(True); + return (False); + } + + /* everything went OK */ + DEBUG (8, ("Lock call successful\n")); + + return (True); #else - return(False); + return (False); #endif } @@ -2654,160 +2883,188 @@ BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type) is the name specified one of my netbios names returns true is it is equal, false otherwise ********************************************************************/ -BOOL is_myname(char *s) +BOOL +is_myname (char *s) { - int n; - BOOL ret = False; + int n; + BOOL ret = False; - for (n=0; my_netbios_names[n]; n++) { - if (strequal(my_netbios_names[n], s)) - ret=True; - } - DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret)); - return(ret); + for (n = 0; my_netbios_names[n]; n++) + { + if (strequal (my_netbios_names[n], s)) + ret = True; + } + DEBUG (8, ("is_myname(\"%s\") returns %d\n", s, ret)); + return (ret); } -#endif /* 0 */ -#if 0 /* Can be useful one day */ +#endif /* 0 */ +#if 0 /* Can be useful one day */ /******************************************************************* set the horrid remote_arch string based on an enum. ********************************************************************/ -void set_remote_arch(enum remote_arch_types type) +void +set_remote_arch (enum remote_arch_types type) { - ra_type = type; - switch( type ) - { - case RA_WFWG: - remote_arch = "WfWg"; - return; - case RA_OS2: - remote_arch = "OS2"; - return; - case RA_WIN95: - remote_arch = "Win95"; - return; - case RA_WINNT: - remote_arch = "WinNT"; - return; - case RA_SAMBA: - remote_arch = "Samba"; - return; - default: - ra_type = RA_UNKNOWN; - remote_arch = "UNKNOWN"; - break; - } + ra_type = type; + switch (type) + { + case RA_WFWG: + remote_arch = "WfWg"; + return; + case RA_OS2: + remote_arch = "OS2"; + return; + case RA_WIN95: + remote_arch = "Win95"; + return; + case RA_WINNT: + remote_arch = "WinNT"; + return; + case RA_SAMBA: + remote_arch = "Samba"; + return; + default: + ra_type = RA_UNKNOWN; + remote_arch = "UNKNOWN"; + break; + } } /******************************************************************* Get the remote_arch type. ********************************************************************/ -enum remote_arch_types get_remote_arch(void) +enum remote_arch_types +get_remote_arch (void) { - return ra_type; + return ra_type; } #endif /* 0 */ #if 0 /******************************************************************* align a pointer to a multiple of 2 bytes ********************************************************************/ -char *align2(char *q, char *base) +char * +align2 (char *q, char *base) { - if ((q - base) & 1) - { - q++; - } - return q; + if ((q - base) & 1) + { + q++; + } + return q; } -void out_ascii(FILE *f, unsigned char *buf,int len) +void +out_ascii (FILE * f, unsigned char *buf, int len) { - int i; - for (i=0;i(per_line/2)) fprintf(f, " "); - while (n--) - { - fprintf(f, " "); - } - n = MIN(per_line/2,i%per_line); - out_ascii(f,&buf[i-(i%per_line)],n); fprintf(f, " "); - n = (i%per_line) - n; - if (n>0) out_ascii(f,&buf[i-n],n); - fprintf(f, "\n"); - } + n = per_line - (i % per_line); + fprintf (f, " "); + if (n > (per_line / 2)) + fprintf (f, " "); + while (n--) + { + fprintf (f, " "); + } + n = MIN (per_line / 2, i % per_line); + out_ascii (f, &buf[i - (i % per_line)], n); + fprintf (f, " "); + n = (i % per_line) - n; + if (n > 0) + out_ascii (f, &buf[i - n], n); + fprintf (f, "\n"); + } } #endif /* 0 */ -void print_asc(int level, unsigned char *buf,int len) +void +print_asc (int level, unsigned char *buf, int len) { - int i; - for (i=0;i8) DEBUG(level,(" ")); - while (n--) DEBUG(level,(" ")); + n = 16 - (i % 16); + DEBUG (level, (" ")); + if (n > 8) + DEBUG (level, (" ")); + while (n--) + DEBUG (level, (" ")); - n = MIN(8,i%16); - print_asc(level,&buf[i-(i%16)],n); DEBUG(level,(" ")); - n = (i%16) - n; - if (n>0) print_asc(level,&buf[i-n],n); - DEBUG(level,("\n")); - } + n = MIN (8, i % 16); + print_asc (level, &buf[i - (i % 16)], n); + DEBUG (level, (" ")); + n = (i % 16) - n; + if (n > 0) + print_asc (level, &buf[i - n], n); + DEBUG (level, ("\n")); + } } /***************************************************************************** @@ -2820,89 +3077,96 @@ void dump_data(int level,char *buf1,int len) * * **************************************************************************** */ -int str_checksum(const char *s) +int +str_checksum (const char *s) { - int res = 0; - int c; - int i=0; - - while(*s) { - c = *s; - res ^= (c << (i % 15)) ^ (c >> (15-(i%15))); - s++; - i++; - } - return(res); -} /* str_checksum */ + int res = 0; + int c; + int i = 0; + + while (*s) + { + c = *s; + res ^= (c << (i % 15)) ^ (c >> (15 - (i % 15))); + s++; + i++; + } + return (res); +} /* str_checksum */ #if 0 /***************************************************************** zero a memory area then free it. Used to catch bugs faster -*****************************************************************/ -void zero_free(void *p, size_t size) +*****************************************************************/ +void +zero_free (void *p, size_t size) { - memset(p, 0, size); - free(p); + memset (p, 0, size); + free (p); } /***************************************************************** set our open file limit to a requested max and return the limit -*****************************************************************/ -int set_maxfiles(int requested_max) +*****************************************************************/ +int +set_maxfiles (int requested_max) { #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)) - struct rlimit rlp; - int saved_current_limit; + struct rlimit rlp; + int saved_current_limit; - if(getrlimit(RLIMIT_NOFILE, &rlp)) { - DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n", - unix_error_string (errno) )); - /* just guess... */ - return requested_max; - } + if (getrlimit (RLIMIT_NOFILE, &rlp)) + { + DEBUG (0, ("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n", + unix_error_string (errno))); + /* just guess... */ + return requested_max; + } - /* + /* * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to - * account for the extra fd we need - * as well as the log files and standard - * handles etc. Save the limit we want to set in case - * we are running on an OS that doesn't support this limit (AIX) - * which always returns RLIM_INFINITY for rlp.rlim_max. - */ + * account for the extra fd we need + * as well as the log files and standard + * handles etc. Save the limit we want to set in case + * we are running on an OS that doesn't support this limit (AIX) + * which always returns RLIM_INFINITY for rlp.rlim_max. + */ - saved_current_limit = rlp.rlim_cur = MIN(requested_max,rlp.rlim_max); + saved_current_limit = rlp.rlim_cur = MIN (requested_max, rlp.rlim_max); - if(setrlimit(RLIMIT_NOFILE, &rlp)) { - DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n", - (int)rlp.rlim_cur, unix_error_string (errno) )); - /* just guess... */ - return saved_current_limit; - } + if (setrlimit (RLIMIT_NOFILE, &rlp)) + { + DEBUG (0, ("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n", + (int) rlp.rlim_cur, unix_error_string (errno))); + /* just guess... */ + return saved_current_limit; + } - if(getrlimit(RLIMIT_NOFILE, &rlp)) { - DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n", - unix_error_string (errno) )); - /* just guess... */ - return saved_current_limit; + if (getrlimit (RLIMIT_NOFILE, &rlp)) + { + DEBUG (0, ("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n", + unix_error_string (errno))); + /* just guess... */ + return saved_current_limit; } #if defined(RLIM_INFINITY) - if(rlp.rlim_cur == RLIM_INFINITY) - return saved_current_limit; + if (rlp.rlim_cur == RLIM_INFINITY) + return saved_current_limit; #endif - if((int)rlp.rlim_cur > saved_current_limit) - return saved_current_limit; + if ((int) rlp.rlim_cur > saved_current_limit) + return saved_current_limit; - return rlp.rlim_cur; + return rlp.rlim_cur; #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */ - /* - * No way to know - just guess... - */ - return requested_max; + /* + * No way to know - just guess... + */ + return requested_max; #endif } -#endif /* 0 */ +#endif /* 0 */ diff --git a/src/background.c b/src/background.c index 18fa11bfd..afddd12b0 100644 --- a/src/background.c +++ b/src/background.c @@ -3,14 +3,14 @@ /* Background support. Copyright (C) 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc. - + Written by: 1996 Miguel de Icaza 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 @@ -39,18 +39,19 @@ #include #include -#include /* waitpid() */ +#include /* waitpid() */ #include #include #include "lib/global.h" #include "background.h" #include "wtools.h" -#include "layout.h" /* repaint_screen() */ -#include "fileopctx.h" /* FileOpContext */ -#include "lib/tty/key.h" /* add_select_channel(), delete_select_channel() */ +#include "layout.h" /* repaint_screen() */ +#include "fileopctx.h" /* FileOpContext */ +#include "lib/tty/key.h" /* add_select_channel(), delete_select_channel() */ -enum ReturnType { +enum ReturnType +{ Return_String, Return_Integer }; @@ -64,26 +65,25 @@ static int parent_fd; /* File descriptor for messages from our parent */ static int from_parent_fd; -#define MAXCALLARGS 4 /* Number of arguments supported */ +#define MAXCALLARGS 4 /* Number of arguments supported */ struct TaskList *task_list = NULL; static int background_attention (int fd, void *closure); - + static void -register_task_running (FileOpContext *ctx, pid_t pid, int fd, int to_child, - char *info) +register_task_running (FileOpContext * ctx, pid_t pid, int fd, int to_child, char *info) { TaskList *new; new = g_new (TaskList, 1); - new->pid = pid; - new->info = info; + new->pid = pid; + new->info = info; new->state = Task_Running; - new->next = task_list; - new->fd = fd; + new->next = task_list; + new->fd = fd; new->to_child_fd = to_child; - task_list = new; + task_list = new; add_select_channel (fd, background_attention, ctx); } @@ -94,18 +94,20 @@ destroy_task_and_return_fd (pid_t pid) TaskList *p = task_list; TaskList *prev = 0; - while (p){ - if (p->pid == pid){ - if (prev) - prev->next = p->next; - else - task_list = p->next; - g_free (p->info); - g_free (p); - return p->fd; - } - prev = p; - p = p->next; + while (p) + { + if (p->pid == pid) + { + if (prev) + prev->next = p->next; + else + task_list = p->next; + g_free (p->info); + g_free (p); + return p->fd; + } + prev = p; + p = p->next; } /* pid not found */ @@ -115,16 +117,16 @@ destroy_task_and_return_fd (pid_t pid) void unregister_task_running (pid_t pid, int fd) { - destroy_task_and_return_fd(pid); + destroy_task_and_return_fd (pid); delete_select_channel (fd); } void unregister_task_with_pid (pid_t pid) { - int fd = destroy_task_and_return_fd(pid); + int fd = destroy_task_and_return_fd (pid); if (fd != -1) - delete_select_channel (fd); + delete_select_channel (fd); } /* @@ -138,51 +140,56 @@ unregister_task_with_pid (pid_t pid) int do_background (struct FileOpContext *ctx, char *info) { - int comm[2]; /* control connection stream */ - int back_comm[2]; /* back connection */ + int comm[2]; /* control connection stream */ + int back_comm[2]; /* back connection */ pid_t pid; if (pipe (comm) == -1) - return -1; + return -1; if (pipe (back_comm) == -1) - return -1; + return -1; - if ((pid = fork ()) == -1) { - int saved_errno = errno; - (void) close (comm[0]); - (void) close (comm[1]); - (void) close (back_comm[0]); - (void) close (back_comm[1]); - errno = saved_errno; - return -1; + if ((pid = fork ()) == -1) + { + int saved_errno = errno; + (void) close (comm[0]); + (void) close (comm[1]); + (void) close (back_comm[0]); + (void) close (back_comm[1]); + errno = saved_errno; + return -1; } - if (pid == 0) { - int nullfd; + if (pid == 0) + { + int nullfd; - parent_fd = comm[1]; - from_parent_fd = back_comm[0]; + parent_fd = comm[1]; + from_parent_fd = back_comm[0]; - we_are_background = 1; - current_dlg = NULL; + we_are_background = 1; + current_dlg = NULL; - /* Make stdin/stdout/stderr point somewhere */ - close (0); - close (1); - close (2); + /* Make stdin/stdout/stderr point somewhere */ + close (0); + close (1); + close (2); - if ((nullfd = open ("/dev/null", O_RDWR)) != -1) { - while (dup2 (nullfd, 0) == -1 && errno == EINTR); - while (dup2 (nullfd, 1) == -1 && errno == EINTR); - while (dup2 (nullfd, 2) == -1 && errno == EINTR); - } + if ((nullfd = open ("/dev/null", O_RDWR)) != -1) + { + while (dup2 (nullfd, 0) == -1 && errno == EINTR); + while (dup2 (nullfd, 1) == -1 && errno == EINTR); + while (dup2 (nullfd, 2) == -1 && errno == EINTR); + } - return 0; - } else { - ctx->pid = pid; - register_task_running (ctx, pid, comm[0], back_comm[1], info); - return 1; + return 0; + } + else + { + ctx->pid = pid; + register_task_running (ctx, pid, comm[0], back_comm[1], info); + return 1; } } @@ -231,174 +238,211 @@ background_attention (int fd, void *closure) { FileOpContext *ctx; int have_ctx; - union + union { - int (*have_ctx0)(int); - int (*have_ctx1)(int, char *); - int (*have_ctx2)(int, char *, char *); - int (*have_ctx3)(int, char *, char *, char *); - int (*have_ctx4)(int, char *, char *, char *, char *); + int (*have_ctx0) (int); + int (*have_ctx1) (int, char *); + int (*have_ctx2) (int, char *, char *); + int (*have_ctx3) (int, char *, char *, char *); + int (*have_ctx4) (int, char *, char *, char *, char *); - int (*non_have_ctx0)(FileOpContext *, int); - int (*non_have_ctx1)(FileOpContext *, int, char *); - int (*non_have_ctx2)(FileOpContext *, int, char *, char *); - int (*non_have_ctx3)(FileOpContext *, int, char *, char *, char *); - int (*non_have_ctx4)(FileOpContext *, int, char *, char *, char *, char *); + int (*non_have_ctx0) (FileOpContext *, int); + int (*non_have_ctx1) (FileOpContext *, int, char *); + int (*non_have_ctx2) (FileOpContext *, int, char *, char *); + int (*non_have_ctx3) (FileOpContext *, int, char *, char *, char *); + int (*non_have_ctx4) (FileOpContext *, int, char *, char *, char *, char *); - char * (*ret_str0)(); - char * (*ret_str1)(char *); - char * (*ret_str2)(char *, char *); - char * (*ret_str3)(char *, char *, char *); - char * (*ret_str4)(char *, char *, char *, char *); + char *(*ret_str0) (); + char *(*ret_str1) (char *); + char *(*ret_str2) (char *, char *); + char *(*ret_str3) (char *, char *, char *); + char *(*ret_str4) (char *, char *, char *, char *); - void *pointer; + void *pointer; } routine; -/* void *routine;*/ - int argc, i, result, status; - char *data [MAXCALLARGS]; - ssize_t bytes; - struct TaskList *p; - int to_child_fd = -1; + /* void *routine; */ + int argc, i, result, status; + char *data[MAXCALLARGS]; + ssize_t bytes, ret; + struct TaskList *p; + int to_child_fd = -1; enum ReturnType type; ctx = closure; bytes = read (fd, &routine.pointer, sizeof (routine)); - if (bytes == -1 || (size_t) bytes < (sizeof (routine))) { - const char *background_process_error = _(" Background process error "); + if (bytes == -1 || (size_t) bytes < (sizeof (routine))) + { + const char *background_process_error = _(" Background process error "); - unregister_task_running (ctx->pid, fd); - if (!waitpid (ctx->pid, &status, WNOHANG)) { - /* the process is still running, but it misbehaves - kill it */ - kill (ctx->pid, SIGTERM); - message (D_ERROR, background_process_error, _(" Unknown error in child ")); - return 0; - } + unregister_task_running (ctx->pid, fd); + if (!waitpid (ctx->pid, &status, WNOHANG)) + { + /* the process is still running, but it misbehaves - kill it */ + kill (ctx->pid, SIGTERM); + message (D_ERROR, background_process_error, _(" Unknown error in child ")); + return 0; + } - /* 0 means happy end */ - if (WIFEXITED (status) && (WEXITSTATUS (status) == 0)) - return 0; + /* 0 means happy end */ + if (WIFEXITED (status) && (WEXITSTATUS (status) == 0)) + return 0; - message (D_ERROR, background_process_error, _(" Child died unexpectedly ")); + message (D_ERROR, background_process_error, _(" Child died unexpectedly ")); - return 0; + return 0; } - read (fd, &argc, sizeof (argc)); - if (argc > MAXCALLARGS){ - message (D_ERROR, _(" Background protocol error "), - _(" Background process sent us a request for more arguments \n" - " than we can handle. \n")); + if ((read (fd, &argc, sizeof (argc)) != sizeof (argc)) || + (read (fd, &type, sizeof (type)) != sizeof (type)) || + (read (fd, &have_ctx, sizeof (have_ctx)) != sizeof (have_ctx))) + { + message (D_ERROR, _(" Background protocol error "), _("Reading failed")); + return 0; } - read (fd, &type, sizeof (type)); - read (fd, &have_ctx, sizeof (have_ctx)); + + if (argc > MAXCALLARGS) + { + message (D_ERROR, _(" Background protocol error "), + _(" Background process sent us a request for more arguments \n" + " than we can handle. \n")); + } + if (have_ctx) - read (fd, ctx, sizeof (FileOpContext)); - - for (i = 0; i < argc; i++){ - int size; - - read (fd, &size, sizeof (size)); - data [i] = g_malloc (size+1); - read (fd, data [i], size); - - data [i][size] = 0; /* NULL terminate the blocks (they could be strings) */ + { + if (read (fd, ctx, sizeof (FileOpContext)) != sizeof (FileOpContext)) + { + message (D_ERROR, _(" Background protocol error "), _("Reading failed")); + return 0; + } } - /* Find child task info by descriptor */ - /* Find before call, because process can destroy self after */ - for (p = task_list; p; p = p->next) { - if (p->fd == fd) - break; - } + for (i = 0; i < argc; i++) + { + int size; - if (p) to_child_fd = p->to_child_fd; + if (read (fd, &size, sizeof (size)) != sizeof (size)) + { + message (D_ERROR, _(" Background protocol error "), _("Reading failed")); + return 0; + } + data[i] = g_malloc (size + 1); + if (read (fd, data[i], size) != size) + { + message (D_ERROR, _(" Background protocol error "), _("Reading failed")); + return 0; + } + data[i][size] = 0; /* NULL terminate the blocks (they could be strings) */ + } + + /* Find child task info by descriptor */ + /* Find before call, because process can destroy self after */ + for (p = task_list; p; p = p->next) + { + if (p->fd == fd) + break; + } + + if (p) + to_child_fd = p->to_child_fd; if (to_child_fd == -1) - message (D_ERROR, _(" Background process error "), _(" Unknown error in child ")); + message (D_ERROR, _(" Background process error "), _(" Unknown error in child ")); /* Handle the call */ - if (type == Return_Integer){ - if (!have_ctx) - switch (argc){ - case 0: - result = routine.have_ctx0 (Background); - break; - case 1: - result = routine.have_ctx1 (Background, data [0]); - break; - case 2: - result = routine.have_ctx2 (Background, data [0], data [1]); - break; - case 3: - result = routine.have_ctx3 (Background, data [0], data [1], data [2]); - break; - case 4: - result = routine.have_ctx4 (Background, data [0], data [1], data [2], data [3]); - break; - } - else - switch (argc){ - case 0: - result = routine.non_have_ctx0 (ctx, Background); - break; - case 1: - result = routine.non_have_ctx1 (ctx, Background, data [0]); - break; - case 2: - result = routine.non_have_ctx2 (ctx, Background, data [0], data [1]); - break; - case 3: - result = routine.non_have_ctx3 (ctx, Background, data [0], data [1], data [2]); - break; - case 4: - result = routine.non_have_ctx4 (ctx, Background, data [0], data [1], data [2], data [3]); - break; - } + if (type == Return_Integer) + { + if (!have_ctx) + switch (argc) + { + case 0: + result = routine.have_ctx0 (Background); + break; + case 1: + result = routine.have_ctx1 (Background, data[0]); + break; + case 2: + result = routine.have_ctx2 (Background, data[0], data[1]); + break; + case 3: + result = routine.have_ctx3 (Background, data[0], data[1], data[2]); + break; + case 4: + result = routine.have_ctx4 (Background, data[0], data[1], data[2], data[3]); + break; + } + else + switch (argc) + { + case 0: + result = routine.non_have_ctx0 (ctx, Background); + break; + case 1: + result = routine.non_have_ctx1 (ctx, Background, data[0]); + break; + case 2: + result = routine.non_have_ctx2 (ctx, Background, data[0], data[1]); + break; + case 3: + result = routine.non_have_ctx3 (ctx, Background, data[0], data[1], data[2]); + break; + case 4: + result = + routine.non_have_ctx4 (ctx, Background, data[0], data[1], data[2], data[3]); + break; + } - /* Send the result code and the value for shared variables */ - write (to_child_fd, &result, sizeof (int)); - if (have_ctx && to_child_fd != -1) - write (to_child_fd, ctx, sizeof (FileOpContext)); - } else if (type == Return_String) { - int len; - char *resstr = NULL; + /* Send the result code and the value for shared variables */ + ret = write (to_child_fd, &result, sizeof (int)); + if (have_ctx && to_child_fd != -1) + ret = write (to_child_fd, ctx, sizeof (FileOpContext)); + } + else if (type == Return_String) + { + int len; + char *resstr = NULL; - /* FIXME: string routines should also use the Foreground/Background - * parameter. Currently, this is not used here - */ - switch (argc){ - case 0: - resstr = routine.ret_str0 (); - break; - case 1: - resstr = routine.ret_str1 (data [0]); - break; - case 2: - resstr = routine.ret_str2 (data [0], data [1]); - break; - case 3: - resstr = routine.ret_str3 (data [0], data [1], data [2]); - break; - case 4: - resstr = routine.ret_str4 (data [0], data [1], data [2], data [3]); - break; - default: g_assert_not_reached(); - } - if (resstr){ - len = strlen (resstr); - write (to_child_fd, &len, sizeof (len)); - if (len){ - write (to_child_fd, resstr, len); - g_free (resstr); - } - } else { - len = 0; - write (to_child_fd, &len, sizeof (len)); - } + /* FIXME: string routines should also use the Foreground/Background + * parameter. Currently, this is not used here + */ + switch (argc) + { + case 0: + resstr = routine.ret_str0 (); + break; + case 1: + resstr = routine.ret_str1 (data[0]); + break; + case 2: + resstr = routine.ret_str2 (data[0], data[1]); + break; + case 3: + resstr = routine.ret_str3 (data[0], data[1], data[2]); + break; + case 4: + resstr = routine.ret_str4 (data[0], data[1], data[2], data[3]); + break; + default: + g_assert_not_reached (); + } + if (resstr) + { + len = strlen (resstr); + ret = write (to_child_fd, &len, sizeof (len)); + if (len) + { + write (to_child_fd, resstr, len); + } + g_free (resstr); + } + else + { + len = 0; + ret = write (to_child_fd, &len, sizeof (len)); + } } for (i = 0; i < argc; i++) - g_free (data [i]); + g_free (data[i]); repaint_screen (); return 0; @@ -414,19 +458,20 @@ background_attention (int fd, void *closure) * the call be a file operation context. */ static void -parent_call_header (void *routine, int argc, enum ReturnType type, FileOpContext *ctx) +parent_call_header (void *routine, int argc, enum ReturnType type, FileOpContext * ctx) { int have_ctx; + ssize_t ret; have_ctx = (ctx != NULL); - write (parent_fd, &routine, sizeof (routine)); - write (parent_fd, &argc, sizeof (int)); - write (parent_fd, &type, sizeof (type)); - write (parent_fd, &have_ctx, sizeof (have_ctx)); + ret = write (parent_fd, &routine, sizeof (routine)); + ret = write (parent_fd, &argc, sizeof (int)); + ret = write (parent_fd, &type, sizeof (type)); + ret = write (parent_fd, &have_ctx, sizeof (have_ctx)); if (have_ctx) - write (parent_fd, ctx, sizeof (FileOpContext)); + ret = write (parent_fd, ctx, sizeof (FileOpContext)); } int @@ -434,22 +479,24 @@ parent_call (void *routine, struct FileOpContext *ctx, int argc, ...) { va_list ap; int i; + ssize_t ret; va_start (ap, argc); parent_call_header (routine, argc, Return_Integer, ctx); - for (i = 0; i < argc; i++) { - int len; - void *value; + for (i = 0; i < argc; i++) + { + int len; + void *value; - len = va_arg (ap, int); - value = va_arg (ap, void *); - write (parent_fd, &len, sizeof (int)); - write (parent_fd, value, len); + len = va_arg (ap, int); + value = va_arg (ap, void *); + ret = write (parent_fd, &len, sizeof (int)); + ret = write (parent_fd, value, len); } - read (from_parent_fd, &i, sizeof (int)); + ret = read (from_parent_fd, &i, sizeof (int)); if (ctx) - read (from_parent_fd, ctx, sizeof (FileOpContext)); + ret = read (from_parent_fd, ctx, sizeof (FileOpContext)); return i; } @@ -460,25 +507,32 @@ parent_call_string (void *routine, int argc, ...) va_list ap; char *str; int i; - + va_start (ap, argc); parent_call_header (routine, argc, Return_String, NULL); - for (i = 0; i < argc; i++){ - int len; - void *value; + for (i = 0; i < argc; i++) + { + int len; + void *value; - len = va_arg (ap, int); - value = va_arg (ap, void *); - write (parent_fd, &len, sizeof (int)); - write (parent_fd, value, len); + len = va_arg (ap, int); + value = va_arg (ap, void *); + if ((write (parent_fd, &len, sizeof (int)) != sizeof (int)) || + (write (parent_fd, value, len) != len)) + return NULL; } - read (from_parent_fd, &i, sizeof (int)); + if (read (from_parent_fd, &i, sizeof (int)) != sizeof (int)) + return NULL; if (!i) - return NULL; + return NULL; str = g_malloc (i + 1); - read (from_parent_fd, str, i); - str [i] = 0; + if (read (from_parent_fd, str, i) != i) + { + g_free (str); + return NULL; + } + str[i] = 0; return str; } -#endif /* WITH_BACKGROUND */ +#endif /* WITH_BACKGROUND */ diff --git a/src/cons.handler.c b/src/cons.handler.c index bb4674b6b..cee2503d4 100644 --- a/src/cons.handler.c +++ b/src/cons.handler.c @@ -1,12 +1,12 @@ /* Client interface for General purpose Linux console save/restore server Copyright (C) 1994, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 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 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 @@ -37,7 +37,7 @@ #include "lib/global.h" #include "lib/tty/tty.h" -#include "lib/skin.h" /* tty_set_normal_attrs */ +#include "lib/skin.h" /* tty_set_normal_attrs */ #include "lib/tty/win.h" #include "consaver/cons.saver.h" @@ -54,47 +54,49 @@ static int pipefd1[2] = { -1, -1 }; static int pipefd2[2] = { -1, -1 }; static void -show_console_contents_linux (int starty, unsigned char begin_line, - unsigned char end_line) +show_console_contents_linux (int starty, unsigned char begin_line, unsigned char end_line) { unsigned char message = 0; unsigned short bytes = 0; int i; + ssize_t ret; /* Is tty console? */ if (!console_flag) - return; + return; /* Paranoid: Is the cons.saver still running? */ - if (cons_saver_pid < 1 || kill (cons_saver_pid, SIGCONT)) { - cons_saver_pid = 0; - console_flag = 0; - return; + if (cons_saver_pid < 1 || kill (cons_saver_pid, SIGCONT)) + { + cons_saver_pid = 0; + console_flag = 0; + return; } /* Send command to the console handler */ message = CONSOLE_CONTENTS; - write (pipefd1[1], &message, 1); + ret = write (pipefd1[1], &message, 1); /* Check for outdated cons.saver */ - read (pipefd2[0], &message, 1); + ret = read (pipefd2[0], &message, 1); if (message != CONSOLE_CONTENTS) - return; + return; /* Send the range of lines that we want */ - write (pipefd1[1], &begin_line, 1); - write (pipefd1[1], &end_line, 1); + ret = write (pipefd1[1], &begin_line, 1); + ret = write (pipefd1[1], &end_line, 1); /* Read the corresponding number of bytes */ - read (pipefd2[0], &bytes, 2); + ret = read (pipefd2[0], &bytes, 2); /* Read the bytes and output them */ - for (i = 0; i < bytes; i++) { - if ((i % COLS) == 0) - tty_gotoyx (starty + (i / COLS), 0); - read (pipefd2[0], &message, 1); - tty_print_char (message); + for (i = 0; i < bytes; i++) + { + if ((i % COLS) == 0) + tty_gotoyx (starty + (i / COLS), 0); + ret = read (pipefd2[0], &message, 1); + tty_print_char (message); } /* Read the value of the console_flag */ - read (pipefd2[0], &message, 1); + ret = read (pipefd2[0], &message, 1); } static void @@ -104,91 +106,114 @@ handle_console_linux (unsigned char action) char *mc_conssaver; int status; - switch (action) { + switch (action) + { case CONSOLE_INIT: - /* Close old pipe ends in case it is the 2nd time we run cons.saver */ - close (pipefd1[1]); - close (pipefd2[0]); - /* Create two pipes for communication */ - pipe (pipefd1); - pipe (pipefd2); - /* Get the console saver running */ - cons_saver_pid = fork (); - if (cons_saver_pid < 0) { - /* Cannot fork */ - /* Delete pipes */ - close (pipefd1[1]); - close (pipefd1[0]); - close (pipefd2[1]); - close (pipefd2[0]); - console_flag = 0; - } else if (cons_saver_pid > 0) { - /* Parent */ - /* Close the extra pipe ends */ - close (pipefd1[0]); - close (pipefd2[1]); - /* Was the child successful? */ - read (pipefd2[0], &console_flag, 1); - if (!console_flag) { - close (pipefd1[1]); - close (pipefd2[0]); - waitpid (cons_saver_pid, &status, 0); - } - } else { - /* Child */ - /* Close the extra pipe ends */ - close (pipefd1[1]); - close (pipefd2[0]); - tty_name = ttyname (0); - /* Bind the pipe 0 to the standard input */ - close (0); - dup (pipefd1[0]); - close (pipefd1[0]); - /* Bind the pipe 1 to the standard output */ - close (1); - dup (pipefd2[1]); - close (pipefd2[1]); - /* Bind standard error to /dev/null */ - close (2); - open ("/dev/null", O_WRONLY); - if (tty_name) { - /* Exec the console save/restore handler */ - mc_conssaver = concat_dir_and_file (SAVERDIR, "cons.saver"); - execl (mc_conssaver, "cons.saver", tty_name, (char *) NULL); - } - /* Console is not a tty or execl() failed */ - console_flag = 0; - write (1, &console_flag, 1); - _exit (3); - } /* if (cons_saver_pid ...) */ - break; + /* Close old pipe ends in case it is the 2nd time we run cons.saver */ + status = close (pipefd1[1]); + status = close (pipefd2[0]); + /* Create two pipes for communication */ + if (!((pipe (pipefd1) == 0) && ((pipe (pipefd2)) == 0))) + { + console_flag = 0; + break; + } + /* Get the console saver running */ + cons_saver_pid = fork (); + if (cons_saver_pid < 0) + { + /* Cannot fork */ + /* Delete pipes */ + status = close (pipefd1[1]); + status = close (pipefd1[0]); + status = close (pipefd2[1]); + status = close (pipefd2[0]); + console_flag = 0; + } + else if (cons_saver_pid > 0) + { + /* Parent */ + /* Close the extra pipe ends */ + status = close (pipefd1[0]); + status = close (pipefd2[1]); + /* Was the child successful? */ + status = read (pipefd2[0], &console_flag, 1); + if (!console_flag) + { + pid_t ret; + status = close (pipefd1[1]); + status = close (pipefd2[0]); + ret = waitpid (cons_saver_pid, &status, 0); + } + } + else + { + /* Child */ + /* Close the extra pipe ends */ + status = close (pipefd1[1]); + status = close (pipefd2[0]); + tty_name = ttyname (0); + /* Bind the pipe 0 to the standard input */ + do + { + if (dup2 (pipefd1[0], 0) == -1) + break; + status = close (pipefd1[0]); + /* Bind the pipe 1 to the standard output */ + if (dup2 (pipefd2[1], 1) == -1) + break; + + status = close (pipefd2[1]); + /* Bind standard error to /dev/null */ + status = open ("/dev/null", O_WRONLY); + if (dup2 (status, 2) == -1) + break; + status = close (status); + if (tty_name) + { + /* Exec the console save/restore handler */ + mc_conssaver = concat_dir_and_file (SAVERDIR, "cons.saver"); + execl (mc_conssaver, "cons.saver", tty_name, (char *) NULL); + } + /* Console is not a tty or execl() failed */ + } + while (0); + console_flag = 0; + status = write (1, &console_flag, 1); + _exit (3); + } /* if (cons_saver_pid ...) */ + break; case CONSOLE_DONE: case CONSOLE_SAVE: case CONSOLE_RESTORE: - /* Is tty console? */ - if (!console_flag) - return; - /* Paranoid: Is the cons.saver still running? */ - if (cons_saver_pid < 1 || kill (cons_saver_pid, SIGCONT)) { - cons_saver_pid = 0; - console_flag = 0; - return; - } - /* Send command to the console handler */ - write (pipefd1[1], &action, 1); - if (action != CONSOLE_DONE) { - /* Wait the console handler to do its job */ - read (pipefd2[0], &console_flag, 1); - } - if (action == CONSOLE_DONE || !console_flag) { - /* We are done -> Let's clean up */ - close (pipefd1[1]); - close (pipefd2[0]); - waitpid (cons_saver_pid, &status, 0); - console_flag = 0; - } - break; + /* Is tty console? */ + if (!console_flag) + return; + /* Paranoid: Is the cons.saver still running? */ + if (cons_saver_pid < 1 || kill (cons_saver_pid, SIGCONT)) + { + cons_saver_pid = 0; + console_flag = 0; + return; + } + /* Send command to the console handler */ + status = write (pipefd1[1], &action, 1); + if (action != CONSOLE_DONE) + { + /* Wait the console handler to do its job */ + status = read (pipefd2[0], &console_flag, 1); + } + if (action == CONSOLE_DONE || !console_flag) + { + /* We are done -> Let's clean up */ + pid_t ret; + close (pipefd1[1]); + close (pipefd2[0]); + ret = waitpid (cons_saver_pid, &status, 0); + console_flag = 0; + } + break; } } @@ -208,18 +233,18 @@ static void console_init (void) { if (console_flag) - return; + return; screen_info.size = sizeof (screen_info); if (ioctl (FD_OUT, CONS_GETINFO, &screen_info) == -1) - return; + return; memset (&screen_shot, 0, sizeof (screen_shot)); screen_shot.xsize = screen_info.mv_csz; screen_shot.ysize = screen_info.mv_rsz; screen_shot.buf = g_try_malloc (screen_info.mv_csz * screen_info.mv_rsz * 2); if (screen_shot.buf != NULL) - console_flag = 1; + console_flag = 1; } static void @@ -236,7 +261,7 @@ set_attr (unsigned attr) bc = (attr >> 4) & 0xF; printf ("\x1B[%d;%d;3%d;4%dm", (bc & 8) ? 5 : 25, (tc & 8) ? 1 : 22, - color_map[tc & 7], color_map[bc & 7]); + color_map[tc & 7], color_map[bc & 7]); } #define cursor_to(x, y) do { \ @@ -250,15 +275,16 @@ console_restore (void) int i, last; if (!console_flag) - return; + return; cursor_to (0, 0); /* restoring all content up to cursor position */ last = screen_info.mv_row * screen_info.mv_csz + screen_info.mv_col; - for (i = 0; i < last; ++i) { - set_attr ((screen_shot.buf[i] >> 8) & 0xFF); - putc (screen_shot.buf[i] & 0xFF, stdout); + for (i = 0; i < last; ++i) + { + set_attr ((screen_shot.buf[i] >> 8) & 0xFF); + putc (screen_shot.buf[i] & 0xFF, stdout); } /* restoring cursor color */ @@ -271,7 +297,7 @@ static void console_shutdown (void) { if (!console_flag) - return; + return; g_free (screen_shot.buf); @@ -286,94 +312,101 @@ console_save (void) scrmap_t revmap; if (!console_flag) - return; + return; /* screen_info.size is already set in console_init() */ - if (ioctl (FD_OUT, CONS_GETINFO, &screen_info) == -1) { - console_shutdown (); - return; + if (ioctl (FD_OUT, CONS_GETINFO, &screen_info) == -1) + { + console_shutdown (); + return; } /* handle console resize */ - if (screen_info.mv_csz != screen_shot.xsize - || screen_info.mv_rsz != screen_shot.ysize) { - console_shutdown (); - console_init (); + if (screen_info.mv_csz != screen_shot.xsize || screen_info.mv_rsz != screen_shot.ysize) + { + console_shutdown (); + console_init (); } - if (ioctl (FD_OUT, CONS_SCRSHOT, &screen_shot) == -1) { - console_shutdown (); - return; + if (ioctl (FD_OUT, CONS_SCRSHOT, &screen_shot) == -1) + { + console_shutdown (); + return; } - if (ioctl (FD_OUT, GIO_SCRNMAP, &map) == -1) { - console_shutdown (); - return; + if (ioctl (FD_OUT, GIO_SCRNMAP, &map) == -1) + { + console_shutdown (); + return; } - for (i = 0; i < 256; i++) { - char *p = memchr (map.scrmap, i, 256); - revmap.scrmap[i] = p ? p - map.scrmap : i; + for (i = 0; i < 256; i++) + { + char *p = memchr (map.scrmap, i, 256); + revmap.scrmap[i] = p ? p - map.scrmap : i; } - for (i = 0; i < screen_shot.xsize * screen_shot.ysize; i++) { - screen_shot.buf[i] = - (screen_shot.buf[i] & 0xff00) | (unsigned char) revmap. - scrmap[screen_shot.buf[i] & 0xff]; + for (i = 0; i < screen_shot.xsize * screen_shot.ysize; i++) + { + screen_shot.buf[i] = + (screen_shot.buf[i] & 0xff00) | (unsigned char) revmap. + scrmap[screen_shot.buf[i] & 0xff]; } } static void -show_console_contents_freebsd (int starty, unsigned char begin_line, - unsigned char end_line) +show_console_contents_freebsd (int starty, unsigned char begin_line, unsigned char end_line) { int col, line; char c; if (!console_flag) - return; + return; - for (line = begin_line; line <= end_line; line++) { - tty_gotoyx (starty + line - begin_line, 0); - for (col = 0; col < min (COLS, screen_info.mv_csz); col++) { - c = screen_shot.buf[line * screen_info.mv_csz + col] & 0xFF; - tty_print_char (c); - } + for (line = begin_line; line <= end_line; line++) + { + tty_gotoyx (starty + line - begin_line, 0); + for (col = 0; col < min (COLS, screen_info.mv_csz); col++) + { + c = screen_shot.buf[line * screen_info.mv_csz + col] & 0xFF; + tty_print_char (c); + } } } static void handle_console_freebsd (unsigned char action) { - switch (action) { + switch (action) + { case CONSOLE_INIT: - console_init (); - break; + console_init (); + break; case CONSOLE_DONE: - console_shutdown (); - break; + console_shutdown (); + break; case CONSOLE_SAVE: - console_save (); - break; + console_save (); + break; case CONSOLE_RESTORE: - console_restore (); - break; + console_restore (); + break; } } -#endif /* __FreeBSD__ */ +#endif /* __FreeBSD__ */ void -show_console_contents (int starty, unsigned char begin_line, - unsigned char end_line) +show_console_contents (int starty, unsigned char begin_line, unsigned char end_line) { tty_set_normal_attrs (); - if (look_for_rxvt_extensions ()) { - show_rxvt_contents (starty, begin_line, end_line); - return; + if (look_for_rxvt_extensions ()) + { + show_rxvt_contents (starty, begin_line, end_line); + return; } #ifdef __linux__ show_console_contents_linux (starty, begin_line, end_line); @@ -390,7 +423,7 @@ handle_console (unsigned char action) (void) action; if (look_for_rxvt_extensions ()) - return; + return; #ifdef __linux__ handle_console_linux (action); diff --git a/src/consaver/cons.saver.c b/src/consaver/cons.saver.c index c80ba57d6..745c46778 100644 --- a/src/consaver/cons.saver.c +++ b/src/consaver/cons.saver.c @@ -9,12 +9,12 @@ This code requires root privileges. You may want to make the cons.saver setuid root. The code should be safe even if it is setuid but who knows? - + 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 @@ -67,175 +67,184 @@ static void send_contents (char *buffer, unsigned int columns, unsigned int rows) { - unsigned char begin_line = 0, end_line = 0; - unsigned int lastline, lc_index, x; - unsigned char message, outbuf[1024], *p; - unsigned short bytes; + unsigned char begin_line = 0, end_line = 0; + unsigned int lastline, lc_index, x; + unsigned char message, outbuf[1024], *p; + unsigned short bytes; - lc_index = 2 * rows * columns; - for (lastline = rows; lastline > 0; lastline--) - for (x = 0; x < columns; x++) - { - lc_index -= 2; - if (buffer [lc_index] != ' ') - goto out; - } -out: + lc_index = 2 * rows * columns; + for (lastline = rows; lastline > 0; lastline--) + for (x = 0; x < columns; x++) + { + lc_index -= 2; + if (buffer[lc_index] != ' ') + goto out; + } + out: - message = CONSOLE_CONTENTS; - write (1, &message, 1); + message = CONSOLE_CONTENTS; + if (write (1, &message, 1) != 1) + return; + if (read (0, &begin_line, 1) != 1) + return; + if (read (0, &end_line, 1) != 1) + return; + if (begin_line > lastline) + begin_line = lastline; + if (end_line > lastline) + end_line = lastline; - read (0, &begin_line, 1); - read (0, &end_line, 1); - if (begin_line > lastline) - begin_line = lastline; - if (end_line > lastline) - end_line = lastline; + lc_index = (end_line - begin_line) * columns; - lc_index = (end_line - begin_line) * columns; - bytes = lc_index; - if (lc_index != bytes) - bytes = 0; - write (1, &bytes, 2); - if (! bytes) - return; + if (write (1, &bytes, 2) != 2) + return; + if (!bytes) + return; - p = outbuf; - for (lc_index = 2 * begin_line * columns; - lc_index < 2 * end_line * columns; - lc_index += 2) + p = outbuf; + for (lc_index = 2 * begin_line * columns; lc_index < 2 * end_line * columns; lc_index += 2) { - *p++ = buffer [lc_index]; - if (p == outbuf + sizeof (outbuf)) - { - write (1, outbuf, sizeof (outbuf)); - p = outbuf; - } + *p++ = buffer[lc_index]; + if (p == outbuf + sizeof (outbuf)) + { + if (write (1, outbuf, sizeof (outbuf)) != sizeof (outbuf)) + return; + p = outbuf; + } } - if (p != outbuf) - write (1, outbuf, p - outbuf); + if (p != outbuf) + if (write (1, outbuf, p - outbuf) < (p - outbuf)) + return; } -static void __attribute__ ((noreturn)) -die (void) +static void __attribute__ ((noreturn)) die (void) { - unsigned char zero = 0; - write (1, &zero, 1); - exit (3); + unsigned char zero = 0; + ssize_t ret; + ret = write (1, &zero, 1); + exit (3); } int main (int argc, char **argv) { - unsigned char action = 0, console_flag = 3; - int console_fd, vcsa_fd, console_minor, buffer_size; - struct stat st; - uid_t uid, euid; - char *buffer, *tty_name, console_name [16], vcsa_name [16]; - const char *p, *q; - struct winsize winsz; + unsigned char action = 0, console_flag = 3; + int console_fd, vcsa_fd, console_minor, buffer_size; + struct stat st; + uid_t uid, euid; + char *buffer, *tty_name, console_name[16], vcsa_name[16]; + const char *p, *q; + struct winsize winsz; - close (2); + close (2); - if (argc != 2) - die (); + if (argc != 2) + die (); - tty_name = argv [1]; - if (strnlen (tty_name, 15) == 15 - || strncmp (tty_name, "/dev/", 5)) - die (); + tty_name = argv[1]; + if (strnlen (tty_name, 15) == 15 || strncmp (tty_name, "/dev/", 5)) + die (); - setsid (); - uid = getuid (); - euid = geteuid (); + setsid (); + uid = getuid (); + euid = geteuid (); - if (seteuid (uid) < 0) - die (); - console_fd = open (tty_name, O_RDONLY); - if (console_fd < 0) - die (); - if (fstat (console_fd, &st) < 0 || ! S_ISCHR (st.st_mode)) - die (); - if ((st.st_rdev & 0xff00) != 0x0400) - die (); - console_minor = (int) (st.st_rdev & 0x00ff); - if (console_minor < 1 || console_minor > 63) - die (); - if (st.st_uid != uid) - die (); + if (seteuid (uid) < 0) + die (); + console_fd = open (tty_name, O_RDONLY); + if (console_fd < 0) + die (); + if (fstat (console_fd, &st) < 0 || !S_ISCHR (st.st_mode)) + die (); + if ((st.st_rdev & 0xff00) != 0x0400) + die (); + console_minor = (int) (st.st_rdev & 0x00ff); + if (console_minor < 1 || console_minor > 63) + die (); + if (st.st_uid != uid) + die (); - switch (tty_name [5]) + switch (tty_name[5]) { - /* devfs */ - case 'v': p = "/dev/vc/%d"; q = "/dev/vcc/a%d"; break; - /* /dev/ttyN */ - case 't': p = "/dev/tty%d"; q = "/dev/vcsa%d"; break; - default: die (); break; + /* devfs */ + case 'v': + p = "/dev/vc/%d"; + q = "/dev/vcc/a%d"; + break; + /* /dev/ttyN */ + case 't': + p = "/dev/tty%d"; + q = "/dev/vcsa%d"; + break; + default: + die (); + break; } - snprintf (console_name, sizeof (console_name), p, console_minor); - if (strncmp (console_name, tty_name, sizeof (console_name)) != 0) - die (); + snprintf (console_name, sizeof (console_name), p, console_minor); + if (strncmp (console_name, tty_name, sizeof (console_name)) != 0) + die (); - if (seteuid (euid) < 0) - die (); + if (seteuid (euid) < 0) + die (); - snprintf (vcsa_name, sizeof (vcsa_name), q, console_minor); - vcsa_fd = open (vcsa_name, O_RDWR); - if (vcsa_fd < 0) - die (); - if (fstat (vcsa_fd, &st) < 0 || ! S_ISCHR (st.st_mode)) - die (); + snprintf (vcsa_name, sizeof (vcsa_name), q, console_minor); + vcsa_fd = open (vcsa_name, O_RDWR); + if (vcsa_fd < 0) + die (); + if (fstat (vcsa_fd, &st) < 0 || !S_ISCHR (st.st_mode)) + die (); - if (seteuid (uid) < 0) - die (); + if (seteuid (uid) < 0) + die (); - winsz.ws_col = winsz.ws_row = 0; - if (ioctl (console_fd, TIOCGWINSZ, &winsz) < 0 - || winsz.ws_col <= 0 || winsz.ws_row <= 0 - || winsz.ws_col >= 256 || winsz.ws_row >= 256) - die (); + winsz.ws_col = winsz.ws_row = 0; + if (ioctl (console_fd, TIOCGWINSZ, &winsz) < 0 + || winsz.ws_col <= 0 || winsz.ws_row <= 0 || winsz.ws_col >= 256 || winsz.ws_row >= 256) + die (); - buffer_size = 4 + 2 * winsz.ws_col * winsz.ws_row; - buffer = calloc (buffer_size, 1); - if (buffer == NULL) - die (); + buffer_size = 4 + 2 * winsz.ws_col * winsz.ws_row; + buffer = calloc (buffer_size, 1); + if (buffer == NULL) + die (); - write (1, &console_flag, 1); + if (write (1, &console_flag, 1) != 1) + die (); - while (console_flag && read (0, &action, 1) == 1) + while (console_flag && read (0, &action, 1) == 1) { - switch (action) - { - case CONSOLE_DONE: - console_flag = 0; - continue; - case CONSOLE_SAVE: - if (seteuid (euid) < 0 - || lseek (vcsa_fd, 0, 0) != 0 - || fstat (console_fd, &st) < 0 || st.st_uid != uid - || read (vcsa_fd, buffer, buffer_size) != buffer_size - || fstat (console_fd, &st) < 0 || st.st_uid != uid) - memset (buffer, 0, buffer_size); - if (seteuid (uid) < 0) - die (); - break; - case CONSOLE_RESTORE: - if (seteuid (euid) >= 0 - && lseek (vcsa_fd, 0, 0) == 0 - && fstat (console_fd, &st) >= 0 && st.st_uid == uid) - write (vcsa_fd, buffer, buffer_size); - if (seteuid (uid) < 0) - die (); - break; - case CONSOLE_CONTENTS: - send_contents (buffer + 4, winsz.ws_col, winsz.ws_row); - break; - } + switch (action) + { + case CONSOLE_DONE: + console_flag = 0; + continue; + case CONSOLE_SAVE: + if (seteuid (euid) < 0 + || lseek (vcsa_fd, 0, 0) != 0 + || fstat (console_fd, &st) < 0 || st.st_uid != uid + || read (vcsa_fd, buffer, buffer_size) != buffer_size + || fstat (console_fd, &st) < 0 || st.st_uid != uid) + memset (buffer, 0, buffer_size); + if (seteuid (uid) < 0) + die (); + break; + case CONSOLE_RESTORE: + if (seteuid (euid) >= 0 + && lseek (vcsa_fd, 0, 0) == 0 && fstat (console_fd, &st) >= 0 && st.st_uid == uid) + if (write (vcsa_fd, buffer, buffer_size) != buffer_size) + die (); + if (seteuid (uid) < 0) + die (); + break; + case CONSOLE_CONTENTS: + send_contents (buffer + 4, winsz.ws_col, winsz.ws_row); + break; + } - write (1, &console_flag, 1); + if (write (1, &console_flag, 1) != 1) + die (); } - exit (0); + exit (0); } diff --git a/src/editor/edit.c b/src/editor/edit.c index d3e90e4f7..2d12d81c9 100644 --- a/src/editor/edit.c +++ b/src/editor/edit.c @@ -328,6 +328,7 @@ edit_load_file_fast (WEdit * edit, const char *filename) { long buf, buf2; int file = -1; + int ret = 1; edit->curs2 = edit->last_byte; buf2 = edit->curs2 >> S_EDIT_BUF_SIZE; edit->utf8 = 0; @@ -343,20 +344,32 @@ edit_load_file_fast (WEdit * edit, const char *filename) if (!edit->buffers2[buf2]) edit->buffers2[buf2] = g_malloc0 (EDIT_BUF_SIZE); - mc_read (file, - (char *) edit->buffers2[buf2] + EDIT_BUF_SIZE - - (edit->curs2 & M_EDIT_BUF_SIZE), edit->curs2 & M_EDIT_BUF_SIZE); - - for (buf = buf2 - 1; buf >= 0; buf--) + do { - /* edit->buffers2[0] is already allocated */ - if (!edit->buffers2[buf]) - edit->buffers2[buf] = g_malloc0 (EDIT_BUF_SIZE); - mc_read (file, (char *) edit->buffers2[buf], EDIT_BUF_SIZE); - } + if (mc_read (file, + (char *) edit->buffers2[buf2] + EDIT_BUF_SIZE - + (edit->curs2 & M_EDIT_BUF_SIZE), edit->curs2 & M_EDIT_BUF_SIZE) < 0) + break; + for (buf = buf2 - 1; buf >= 0; buf--) + { + /* edit->buffers2[0] is already allocated */ + if (!edit->buffers2[buf]) + edit->buffers2[buf] = g_malloc0 (EDIT_BUF_SIZE); + if (mc_read (file, (char *) edit->buffers2[buf], EDIT_BUF_SIZE) < 0) + break; + } + ret = 0; + } + while (0); + if (ret) + { + char *err_str = g_strdup_printf (_(" Error reading %s "), filename); + edit_error_dialog (_("Error"), err_str); + g_free (err_str); + } mc_close (file); - return 0; + return ret; } /* detecting an error on save is easy: just check if every byte has been written. */ diff --git a/src/editor/editcmd.c b/src/editor/editcmd.c index 60ee3a33c..367ce849a 100644 --- a/src/editor/editcmd.c +++ b/src/editor/editcmd.c @@ -273,9 +273,11 @@ edit_save_file (WEdit * edit, const char *filename) } else savename = g_strdup (real_filename); - - mc_chown (savename, edit->stat1.st_uid, edit->stat1.st_gid); - mc_chmod (savename, edit->stat1.st_mode); + { + int ret; + ret = mc_chown (savename, edit->stat1.st_uid, edit->stat1.st_gid); + ret = mc_chmod (savename, edit->stat1.st_mode); + } if ((fd = mc_open (savename, O_CREAT | O_WRONLY | O_TRUNC | O_BINARY, edit->stat1.st_mode)) == -1) @@ -757,7 +759,10 @@ edit_delete_macro (WEdit * edit, int k) n = 0; while (fscanf (f, "%lu %d, ", ¯o[n].command, ¯o[n].ch)) n++; - fscanf (f, ";\n"); + { + int ret; + ret = fscanf (f, ";\n"); + } if (s != k) { fprintf (g, ("key '%d 0': "), s); @@ -866,7 +871,10 @@ edit_load_macro_cmd (WEdit * edit, struct macro macro[], int *n, int k) { while (2 == fscanf (f, "%lu %d, ", &dummy.command, &dummy.ch)); } - fscanf (f, ";\n"); + { + int ret; + ret = fscanf (f, ";\n"); + } if (s == k) found = 1; } @@ -2503,8 +2511,6 @@ edit_block_process_cmd (WEdit * edit, const char *shell_cmd, int block) */ tmp = g_strconcat (" ", home_dir, PATH_SEP_STR EDIT_DIR, shell_cmd, " ", quoted_name, " ", home_dir, PATH_SEP_STR EDIT_BLOCK_FILE " /dev/null", (char *) NULL); - system (tmp); - g_free (tmp); } else { @@ -2515,23 +2521,31 @@ edit_block_process_cmd (WEdit * edit, const char *shell_cmd, int block) */ tmp = g_strconcat (" ", home_dir, PATH_SEP_STR EDIT_DIR, shell_cmd, " ", quoted_name, (char *) NULL); - system (tmp); - g_free (tmp); } - g_free (quoted_name); - close_error_pipe (D_NORMAL, NULL); - edit_refresh_cmd (edit); - edit->force |= REDRAW_COMPLETELY; - - /* insert result block */ - if (block && !edit_block_delete_cmd (edit)) + if (system (tmp) == -1) { - edit_insert_file (edit, b); - block_file = fopen (b, "w"); - if (block_file != NULL) - fclose (block_file); + edit_error_dialog (_("Process block"), _("Error calling program")); } + else + { + + g_free (quoted_name); + close_error_pipe (D_NORMAL, NULL); + + edit_refresh_cmd (edit); + edit->force |= REDRAW_COMPLETELY; + + /* insert result block */ + if (block && !edit_block_delete_cmd (edit)) + { + edit_insert_file (edit, b); + block_file = fopen (b, "w"); + if (block_file != NULL) + fclose (block_file); + } + } + g_free (tmp); edit_block_process_cmd__EXIT: g_free (b); diff --git a/src/file.c b/src/file.c index 2c0902d28..58769294c 100644 --- a/src/file.c +++ b/src/file.c @@ -416,8 +416,8 @@ warn_same_file (const char *fmt, const char *a, const char *b) union { void *p; - FileProgressStatus (*f) (enum OperationMode, const char *fmt, - const char *a, const char *b); + FileProgressStatus (*f) (enum OperationMode, const char *fmt, + const char *a, const char *b); } pntr; pntr.f = real_warn_same_file; @@ -1991,7 +1991,7 @@ panel_operate (void *source_panel, FileOperation operation, gboolean force_singl { WPanel *panel = (WPanel *) source_panel; const gboolean single_entry = force_single || (panel->marked <= 1) - || (get_current_type () == view_tree); + || (get_current_type () == view_tree); char *source = NULL; #ifdef WITH_FULL_PATHS @@ -2003,6 +2003,7 @@ panel_operate (void *source_panel, FileOperation operation, gboolean force_singl char *temp = NULL; char *save_cwd = NULL, *save_dest = NULL; struct stat src_stat; + gboolean ret_val = TRUE; int i; FileProgressStatus value; FileOpContext *ctx; @@ -2197,8 +2198,12 @@ panel_operate (void *source_panel, FileOperation operation, gboolean force_singl /* We now have ETA in all cases */ /* One file: FIXME mc_chdir will take user out of any vfs */ - if (operation != OP_COPY && get_current_type () == view_tree) - mc_chdir (PATH_SEP_STR); + if ((operation != OP_COPY) && (get_current_type () == view_tree) && + (mc_chdir (PATH_SEP_STR) < 0)) + { + ret_val = FALSE; + goto clean_up; + } /* The source and src_stat variables have been initialized before */ #ifdef WITH_FULL_PATHS @@ -2417,7 +2422,9 @@ panel_operate (void *source_panel, FileOperation operation, gboolean force_singl #endif /* WITH_BACKGROUND */ file_op_context_destroy (ctx); - return TRUE; + file_op_total_context_destroy (tctx); + + return ret_val; } /* }}} */ @@ -2557,8 +2564,8 @@ query_replace (FileOpContext * ctx, const char *destname, struct stat *_s_stat, union { void *p; - FileProgressStatus (*f) (FileOpContext *, enum OperationMode, const char *, - struct stat *, struct stat *); + FileProgressStatus (*f) (FileOpContext *, enum OperationMode, const char *, + struct stat *, struct stat *); } pntr; pntr.f = file_progress_real_query_replace; diff --git a/src/find.c b/src/find.c index 883cb0781..1643f538e 100644 --- a/src/find.c +++ b/src/find.c @@ -4,12 +4,12 @@ Written 1995 by Miguel de Icaza Complete rewrote. - + 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 @@ -42,17 +42,17 @@ #include "lib/vfs/mc-vfs/vfs.h" #include "lib/strutil.h" -#include "setup.h" /* verbose */ +#include "setup.h" /* verbose */ #include "dialog.h" #include "widget.h" #include "dir.h" -#include "panel.h" /* current_panel */ -#include "main.h" /* do_cd, try_to_select */ +#include "panel.h" /* current_panel */ +#include "main.h" /* do_cd, try_to_select */ #include "wtools.h" -#include "cmd.h" /* view_file_at_line */ +#include "cmd.h" /* view_file_at_line */ #include "boxes.h" -#include "history.h" /* MC_HISTORY_SHARED_SEARCH */ -#include "layout.h" /* mc_refresh() */ +#include "history.h" /* MC_HISTORY_SHARED_SEARCH */ +#include "layout.h" /* mc_refresh() */ #include "find.h" @@ -71,7 +71,8 @@ static int FIND2_X = 64; #define FIND2_X_USE (FIND2_X - 20) /* A couple of extra messages we need */ -enum { +enum +{ B_STOP = B_USER + 1, B_AGAIN, B_PANELIZE, @@ -79,7 +80,8 @@ enum { B_VIEW }; -typedef enum { +typedef enum +{ FIND_CONT = 0, FIND_SUSPEND, FIND_ABORT @@ -89,29 +91,29 @@ typedef enum { char *find_ignore_dirs = NULL; /* static variables to remember find parameters */ -static WInput *in_start; /* Start path */ -static WInput *in_name; /* Filename */ -static WInput *in_with; /* Text inside filename */ -static WCheck *file_case_sens_cbox; /* "case sensitive" checkbox */ -static WCheck *file_pattern_cbox; /* File name is glob or regexp */ +static WInput *in_start; /* Start path */ +static WInput *in_name; /* Filename */ +static WInput *in_with; /* Text inside filename */ +static WCheck *file_case_sens_cbox; /* "case sensitive" checkbox */ +static WCheck *file_pattern_cbox; /* File name is glob or regexp */ static WCheck *recursively_cbox; static WCheck *skip_hidden_cbox; -static WCheck *content_case_sens_cbox; /* "case sensitive" checkbox */ -static WCheck *content_regexp_cbox; /* "find regular expression" checkbox */ -static WCheck *content_first_hit_cbox; /* "First hit" checkbox" */ -static WCheck *content_whole_words_cbox; /* "whole words" checkbox */ +static WCheck *content_case_sens_cbox; /* "case sensitive" checkbox */ +static WCheck *content_regexp_cbox; /* "find regular expression" checkbox */ +static WCheck *content_first_hit_cbox; /* "First hit" checkbox" */ +static WCheck *content_whole_words_cbox; /* "whole words" checkbox */ #ifdef HAVE_CHARSET static WCheck *file_all_charsets_cbox; static WCheck *content_all_charsets_cbox; #endif -static gboolean running = FALSE; /* nice flag */ -static char *find_pattern = NULL; /* Pattern to search */ -static char *content_pattern = NULL; /* pattern to search inside files; if - content_regexp_flag is true, it contains the - regex pattern, else the search string. */ -static unsigned long matches; /* Number of matches */ -static gboolean is_start = FALSE; /* Status of the start/stop toggle button */ +static gboolean running = FALSE; /* nice flag */ +static char *find_pattern = NULL; /* Pattern to search */ +static char *content_pattern = NULL; /* pattern to search inside files; if + content_regexp_flag is true, it contains the + regex pattern, else the search string. */ +static unsigned long matches; /* Number of matches */ +static gboolean is_start = FALSE; /* Status of the start/stop toggle button */ static char *old_dir = NULL; /* Where did we stop */ @@ -119,38 +121,43 @@ static int resuming; static int last_line; static int last_pos; -static Dlg_head *find_dlg; /* The dialog */ -static WButton *stop_button; /* pointer to the stop button */ -static WLabel *status_label; /* Finished, Searching etc. */ -static WLabel *found_num_label; /* Number of found items */ -static WListbox *find_list; /* Listbox with the file list */ +static Dlg_head *find_dlg; /* The dialog */ +static WButton *stop_button; /* pointer to the stop button */ +static WLabel *status_label; /* Finished, Searching etc. */ +static WLabel *found_num_label; /* Number of found items */ +static WListbox *find_list; /* Listbox with the file list */ /* This keeps track of the directory stack */ #if GLIB_CHECK_VERSION (2, 14, 0) static GQueue dir_queue = G_QUEUE_INIT; #else -typedef struct dir_stack { +typedef struct dir_stack +{ char *name; struct dir_stack *prev; } dir_stack; static dir_stack *dir_stack_base = 0; -#endif /* GLIB_CHECK_VERSION */ +#endif /* GLIB_CHECK_VERSION */ -static struct { - const char* text; - int len; /* length including space and brackets */ - int x; -} fbuts [] = { - { N_("&Suspend"), 11, 29 }, - { N_("Con&tinue"), 12, 29 }, - { N_("&Chdir"), 11, 3 }, - { N_("&Again"), 9, 17 }, - { N_("&Quit"), 8, 43 }, - { N_("Pane&lize"), 12, 3 }, - { N_("&View - F3"), 13, 20 }, - { N_("&Edit - F4"), 13, 38 } +/* *INDENT-OFF* */ +static struct +{ + const char *text; + int len; /* length including space and brackets */ + int x; +} fbuts[] = +{ + {N_("&Suspend"), 11, 29}, + {N_("Con&tinue"), 12, 29}, + {N_("&Chdir"), 11, 3}, + {N_("&Again"), 9, 17}, + {N_("&Quit"), 8, 43}, + {N_("Pane&lize"), 12, 3}, + {N_("&View - F3"), 13, 20}, + {N_("&Edit - F4"), 13, 38} }; +/* *INDENT-ON* */ /* find file options */ typedef struct @@ -170,8 +177,7 @@ typedef struct gboolean content_all_charsets; } find_file_options_t; -static find_file_options_t options = -{ +static find_file_options_t options = { TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE }; @@ -188,37 +194,48 @@ find_load_options (void) char *ignore_dirs; if (loaded) - return; + return; loaded = TRUE; /* Back compatibility: try load old parameter at first */ ignore_dirs = mc_config_get_string (mc_main_config, "Misc", "find_ignore_dirs", ""); - if (ignore_dirs [0] != '\0') { - find_ignore_dirs = g_strconcat (":", ignore_dirs, ":", (char *) NULL); - mc_config_set_string (mc_main_config, "FindFile", "ignore_dirs", ignore_dirs); + if (ignore_dirs[0] != '\0') + { + find_ignore_dirs = g_strconcat (":", ignore_dirs, ":", (char *) NULL); + mc_config_set_string (mc_main_config, "FindFile", "ignore_dirs", ignore_dirs); } g_free (ignore_dirs); mc_config_del_param (mc_main_config, "Misc", "find_ignore_dirs"); /* Then load new parameters */ ignore_dirs = mc_config_get_string (mc_main_config, "FindFile", "ignore_dirs", ""); - if (ignore_dirs [0] != '\0') { - g_free (find_ignore_dirs); - find_ignore_dirs = g_strconcat (":", ignore_dirs, ":", (char *) NULL); + if (ignore_dirs[0] != '\0') + { + g_free (find_ignore_dirs); + find_ignore_dirs = g_strconcat (":", ignore_dirs, ":", (char *) NULL); } g_free (ignore_dirs); - options.file_case_sens = mc_config_get_bool (mc_main_config, "FindFile", "file_case_sens", TRUE); - options.file_pattern = mc_config_get_bool (mc_main_config, "FindFile", "file_shell_pattern", TRUE); + options.file_case_sens = + mc_config_get_bool (mc_main_config, "FindFile", "file_case_sens", TRUE); + options.file_pattern = + mc_config_get_bool (mc_main_config, "FindFile", "file_shell_pattern", TRUE); options.find_recurs = mc_config_get_bool (mc_main_config, "FindFile", "file_find_recurs", TRUE); - options.skip_hidden = mc_config_get_bool (mc_main_config, "FindFile", "file_skip_hidden", FALSE); - options.file_all_charsets = mc_config_get_bool (mc_main_config, "FindFile", "file_all_charsets", FALSE); - options.content_case_sens = mc_config_get_bool (mc_main_config, "FindFile", "content_case_sens", TRUE); - options.content_regexp = mc_config_get_bool (mc_main_config, "FindFile", "content_regexp", FALSE); - options.content_first_hit = mc_config_get_bool (mc_main_config, "FindFile", "content_first_hit", FALSE); - options.content_whole_words = mc_config_get_bool (mc_main_config, "FindFile", "content_whole_words", FALSE); - options.content_all_charsets = mc_config_get_bool (mc_main_config, "FindFile", "content_all_charsets", FALSE); + options.skip_hidden = + mc_config_get_bool (mc_main_config, "FindFile", "file_skip_hidden", FALSE); + options.file_all_charsets = + mc_config_get_bool (mc_main_config, "FindFile", "file_all_charsets", FALSE); + options.content_case_sens = + mc_config_get_bool (mc_main_config, "FindFile", "content_case_sens", TRUE); + options.content_regexp = + mc_config_get_bool (mc_main_config, "FindFile", "content_regexp", FALSE); + options.content_first_hit = + mc_config_get_bool (mc_main_config, "FindFile", "content_first_hit", FALSE); + options.content_whole_words = + mc_config_get_bool (mc_main_config, "FindFile", "content_whole_words", FALSE); + options.content_all_charsets = + mc_config_get_bool (mc_main_config, "FindFile", "content_all_charsets", FALSE); } static void @@ -232,8 +249,10 @@ find_save_options (void) mc_config_set_bool (mc_main_config, "FindFile", "content_case_sens", options.content_case_sens); mc_config_set_bool (mc_main_config, "FindFile", "content_regexp", options.content_regexp); mc_config_set_bool (mc_main_config, "FindFile", "content_first_hit", options.content_first_hit); - mc_config_set_bool (mc_main_config, "FindFile", "content_whole_words", options.content_whole_words); - mc_config_set_bool (mc_main_config, "FindFile", "content_all_charsets", options.content_all_charsets); + mc_config_set_bool (mc_main_config, "FindFile", "content_whole_words", + options.content_whole_words); + mc_config_set_bool (mc_main_config, "FindFile", "content_all_charsets", + options.content_all_charsets); } static inline char * @@ -257,7 +276,7 @@ status_update (const char *text) static void found_num_update (void) { - char buffer [BUF_TINY]; + char buffer[BUF_TINY]; g_snprintf (buffer, sizeof (buffer), _("Found: %ld"), matches); label_set_text (found_num_label, buffer); } @@ -277,10 +296,11 @@ find_check_regexp (const char *r) search = mc_search_new (r, -1); - if (search != NULL) { - search->search_type = MC_SEARCH_T_REGEX; - regexp_ok = mc_search_prepare (search); - mc_search_free (search); + if (search != NULL) + { + search->search_type = MC_SEARCH_T_REGEX; + regexp_ok = mc_search_prepare (search); + mc_search_free (search); } return regexp_ok; @@ -291,38 +311,38 @@ find_check_regexp (const char *r) * Validate regex, prevent closing the dialog if it's invalid. */ static cb_ret_t -find_parm_callback (Dlg_head *h, Widget *sender, - dlg_msg_t msg, int parm, void *data) +find_parm_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, void *data) { - switch (msg) { + switch (msg) + { case DLG_VALIDATE: - if (h->ret_value != B_ENTER) - return MSG_HANDLED; + if (h->ret_value != B_ENTER) + return MSG_HANDLED; - /* check filename regexp */ - if (!(file_pattern_cbox->state & C_BOOL) - && (in_name->buffer[0] != '\0') - && !find_check_regexp (in_name->buffer)) { - message (D_ERROR, MSG_ERROR, _(" Malformed regular expression ")); - dlg_select_widget (in_name); - h->running = 1; /* Don't stop the dialog */ - return MSG_HANDLED; - } + /* check filename regexp */ + if (!(file_pattern_cbox->state & C_BOOL) + && (in_name->buffer[0] != '\0') && !find_check_regexp (in_name->buffer)) + { + message (D_ERROR, MSG_ERROR, _(" Malformed regular expression ")); + dlg_select_widget (in_name); + h->running = 1; /* Don't stop the dialog */ + return MSG_HANDLED; + } - /* check content regexp */ - if ((content_regexp_cbox->state & C_BOOL) - && (in_with->buffer[0] != '\0') - && !find_check_regexp (in_with->buffer)) { - message (D_ERROR, MSG_ERROR, _(" Malformed regular expression ")); - dlg_select_widget (in_with); - h->running = 1; /* Don't stop the dialog */ - return MSG_HANDLED; - } + /* check content regexp */ + if ((content_regexp_cbox->state & C_BOOL) + && (in_with->buffer[0] != '\0') && !find_check_regexp (in_with->buffer)) + { + message (D_ERROR, MSG_ERROR, _(" Malformed regular expression ")); + dlg_select_widget (in_with); + h->running = 1; /* Don't stop the dialog */ + return MSG_HANDLED; + } - return MSG_HANDLED; + return MSG_HANDLED; default: - return default_dlg_callback (h, sender, msg, parm, data); + return default_dlg_callback (h, sender, msg, parm, data); } } @@ -368,24 +388,24 @@ find_parameters (char **start_dir, char **pattern, char **content) #ifdef ENABLE_NLS { - int i = sizeof (buts) / sizeof (buts[0]); - while (i-- != 0) - buts[i] = _(buts[i]); + int i = sizeof (buts) / sizeof (buts[0]); + while (i-- != 0) + buts[i] = _(buts[i]); - file_case_label = _(file_case_label); - file_pattern_label = _(file_pattern_label); - file_recurs_label = _(file_recurs_label); - file_skip_hidden_label = _(file_skip_hidden_label); + file_case_label = _(file_case_label); + file_pattern_label = _(file_pattern_label); + file_recurs_label = _(file_recurs_label); + file_skip_hidden_label = _(file_skip_hidden_label); #ifdef HAVE_CHARSET - file_all_charsets_label = _(file_all_charsets_label); - content_all_charsets_label = _(content_all_charsets_label); + file_all_charsets_label = _(file_all_charsets_label); + content_all_charsets_label = _(content_all_charsets_label); #endif - content_case_label = _(content_case_label); - content_regexp_label = _(content_regexp_label); - content_first_hit_label = _(content_first_hit_label); - content_whole_words_label = _(content_whole_words_label); + content_case_label = _(content_case_label); + content_regexp_label = _(content_regexp_label); + content_first_hit_label = _(content_first_hit_label); + content_whole_words_label = _(content_whole_words_label); } -#endif /* ENABLE_NLS */ +#endif /* ENABLE_NLS */ b0 = str_term_width1 (buts[0]) + 6; /* default button */ b1 = str_term_width1 (buts[1]) + 4; @@ -394,40 +414,44 @@ find_parameters (char **start_dir, char **pattern, char **content) find_load_options (); if (in_start_dir == NULL) - in_start_dir = g_strdup ("."); + in_start_dir = g_strdup ("."); -find_par_start: + find_par_start: find_dlg = - create_dlg (0, 0, FIND_Y, FIND_X, dialog_colors, - find_parm_callback, "[Find File]", _("Find File"), - DLG_CENTER | DLG_REVERSE); + create_dlg (0, 0, FIND_Y, FIND_X, dialog_colors, + find_parm_callback, "[Find File]", _("Find File"), DLG_CENTER | DLG_REVERSE); add_widget (find_dlg, - button_new (FIND_Y - 3, FIND_X * 3/4 - b1/2, B_CANCEL, NORMAL_BUTTON, buts[1], 0)); + button_new (FIND_Y - 3, FIND_X * 3 / 4 - b1 / 2, B_CANCEL, NORMAL_BUTTON, buts[1], + 0)); add_widget (find_dlg, - button_new (FIND_Y - 3, FIND_X/4 - b0/2, B_ENTER, DEFPUSH_BUTTON, buts[0], 0)); + button_new (FIND_Y - 3, FIND_X / 4 - b0 / 2, B_ENTER, DEFPUSH_BUTTON, buts[0], 0)); #ifdef HAVE_CHARSET content_all_charsets_cbox = check_new (11, FIND_X / 2 + 1, - options.content_all_charsets, content_all_charsets_label); + options.content_all_charsets, + content_all_charsets_label); add_widget (find_dlg, content_all_charsets_cbox); #endif - content_whole_words_cbox = check_new (10, FIND_X / 2 + 1, options.content_whole_words, content_whole_words_label); + content_whole_words_cbox = + check_new (10, FIND_X / 2 + 1, options.content_whole_words, content_whole_words_label); add_widget (find_dlg, content_whole_words_cbox); - content_first_hit_cbox = check_new (9, FIND_X / 2 + 1, options.content_first_hit, content_first_hit_label); + content_first_hit_cbox = + check_new (9, FIND_X / 2 + 1, options.content_first_hit, content_first_hit_label); add_widget (find_dlg, content_first_hit_cbox); - content_regexp_cbox = check_new (8, FIND_X / 2 + 1, options.content_regexp, content_regexp_label); + content_regexp_cbox = + check_new (8, FIND_X / 2 + 1, options.content_regexp, content_regexp_label); add_widget (find_dlg, content_regexp_cbox); - content_case_sens_cbox = check_new (7, FIND_X / 2 + 1, options.content_case_sens, content_case_label); + content_case_sens_cbox = + check_new (7, FIND_X / 2 + 1, options.content_case_sens, content_case_label); add_widget (find_dlg, content_case_sens_cbox); #ifdef HAVE_CHARSET - file_all_charsets_cbox = check_new (11, 3, - options.file_all_charsets, file_all_charsets_label); + file_all_charsets_cbox = check_new (11, 3, options.file_all_charsets, file_all_charsets_label); add_widget (find_dlg, file_all_charsets_cbox); #endif @@ -453,8 +477,7 @@ find_par_start: add_widget (find_dlg, in_name); add_widget (find_dlg, label_new (5, 3, _("File name:"))); - add_widget (find_dlg, - button_new (3, FIND_X - b2 - 2, B_TREE, NORMAL_BUTTON, buts[2], 0)); + add_widget (find_dlg, button_new (3, FIND_X - b2 - 2, B_TREE, NORMAL_BUTTON, buts[2], 0)); in_start = input_new (3, 3, INPUT_COLOR, FIND_X - b2 - 6, in_start_dir, "start", INPUT_COMPLETE_DEFAULT); @@ -463,68 +486,68 @@ find_par_start: dlg_select_widget (in_name); - switch (run_dlg (find_dlg)) { + switch (run_dlg (find_dlg)) + { case B_CANCEL: - return_value = FALSE; - break; + return_value = FALSE; + break; case B_TREE: - { - char temp_dir[MC_MAXPATHLEN]; + { + char temp_dir[MC_MAXPATHLEN]; - g_strlcpy (temp_dir, in_start->buffer, sizeof (temp_dir)); + g_strlcpy (temp_dir, in_start->buffer, sizeof (temp_dir)); #ifdef HAVE_CHARSET - options.file_all_charsets = file_all_charsets_cbox->state & C_BOOL; - options.content_all_charsets = content_all_charsets_cbox->state & C_BOOL; + options.file_all_charsets = file_all_charsets_cbox->state & C_BOOL; + options.content_all_charsets = content_all_charsets_cbox->state & C_BOOL; #endif - options.content_case_sens = content_case_sens_cbox->state & C_BOOL; - options.content_regexp = content_regexp_cbox->state & C_BOOL; - options.content_first_hit = content_first_hit_cbox->state & C_BOOL; - options.content_whole_words = content_whole_words_cbox->state & C_BOOL; - options.file_pattern = file_pattern_cbox->state & C_BOOL; - options.file_case_sens = file_case_sens_cbox->state & C_BOOL; - options.find_recurs = recursively_cbox->state & C_BOOL; - options.skip_hidden = skip_hidden_cbox->state & C_BOOL; - destroy_dlg (find_dlg); + options.content_case_sens = content_case_sens_cbox->state & C_BOOL; + options.content_regexp = content_regexp_cbox->state & C_BOOL; + options.content_first_hit = content_first_hit_cbox->state & C_BOOL; + options.content_whole_words = content_whole_words_cbox->state & C_BOOL; + options.file_pattern = file_pattern_cbox->state & C_BOOL; + options.file_case_sens = file_case_sens_cbox->state & C_BOOL; + options.find_recurs = recursively_cbox->state & C_BOOL; + options.skip_hidden = skip_hidden_cbox->state & C_BOOL; + destroy_dlg (find_dlg); - if ((temp_dir[0] == '\0') - || ((temp_dir[0] == '.') && (temp_dir[1] == '\0'))) - g_strlcpy (temp_dir, current_panel->cwd, sizeof (temp_dir)); + if ((temp_dir[0] == '\0') || ((temp_dir[0] == '.') && (temp_dir[1] == '\0'))) + g_strlcpy (temp_dir, current_panel->cwd, sizeof (temp_dir)); - if (in_start_dir != INPUT_LAST_TEXT) - g_free (in_start_dir); - in_start_dir = tree_box (temp_dir); - if (in_start_dir == NULL) - in_start_dir = g_strdup (temp_dir); - /* Warning: Dreadful goto */ - goto find_par_start; - break; - } + if (in_start_dir != INPUT_LAST_TEXT) + g_free (in_start_dir); + in_start_dir = tree_box (temp_dir); + if (in_start_dir == NULL) + in_start_dir = g_strdup (temp_dir); + /* Warning: Dreadful goto */ + goto find_par_start; + break; + } default: #ifdef HAVE_CHARSET - options.file_all_charsets = file_all_charsets_cbox->state & C_BOOL; - options.content_all_charsets = content_all_charsets_cbox->state & C_BOOL; + options.file_all_charsets = file_all_charsets_cbox->state & C_BOOL; + options.content_all_charsets = content_all_charsets_cbox->state & C_BOOL; #endif - options.content_case_sens = content_case_sens_cbox->state & C_BOOL; - options.content_regexp = content_regexp_cbox->state & C_BOOL; - options.content_first_hit = content_first_hit_cbox->state & C_BOOL; - options.content_whole_words = content_whole_words_cbox->state & C_BOOL; - options.find_recurs = recursively_cbox->state & C_BOOL; - options.file_pattern = file_pattern_cbox->state & C_BOOL; - options.file_case_sens = file_case_sens_cbox->state & C_BOOL; - options.skip_hidden = skip_hidden_cbox->state & C_BOOL; + options.content_case_sens = content_case_sens_cbox->state & C_BOOL; + options.content_regexp = content_regexp_cbox->state & C_BOOL; + options.content_first_hit = content_first_hit_cbox->state & C_BOOL; + options.content_whole_words = content_whole_words_cbox->state & C_BOOL; + options.find_recurs = recursively_cbox->state & C_BOOL; + options.file_pattern = file_pattern_cbox->state & C_BOOL; + options.file_case_sens = file_case_sens_cbox->state & C_BOOL; + options.skip_hidden = skip_hidden_cbox->state & C_BOOL; - *content = (in_with->buffer[0] != '\0') ? g_strdup (in_with->buffer) : NULL; - *start_dir = g_strdup ((in_start->buffer[0] != '\0') ? in_start->buffer : "."); - *pattern = g_strdup (in_name->buffer); - if (in_start_dir != INPUT_LAST_TEXT) - g_free (in_start_dir); - in_start_dir = g_strdup (*start_dir); + *content = (in_with->buffer[0] != '\0') ? g_strdup (in_with->buffer) : NULL; + *start_dir = g_strdup ((in_start->buffer[0] != '\0') ? in_start->buffer : "."); + *pattern = g_strdup (in_name->buffer); + if (in_start_dir != INPUT_LAST_TEXT) + g_free (in_start_dir); + in_start_dir = g_strdup (*start_dir); - find_save_options (); + find_save_options (); - return_value = TRUE; + return_value = TRUE; } destroy_dlg (find_dlg); @@ -554,7 +577,7 @@ clear_stack (void) g_queue_clear (&dir_queue); } -#else /* GLIB_CHAECK_VERSION */ +#else /* GLIB_CHAECK_VERSION */ static void push_directory (const char *dir) @@ -572,12 +595,13 @@ pop_directory (void) { char *name = NULL; - if (dir_stack_base != NULL) { - dir_stack *next; - name = dir_stack_base->name; - next = dir_stack_base->prev; - g_free (dir_stack_base); - dir_stack_base = next; + if (dir_stack_base != NULL) + { + dir_stack *next; + name = dir_stack_base->name; + next = dir_stack_base->prev; + g_free (dir_stack_base); + dir_stack_base = next; } return name; @@ -589,10 +613,10 @@ clear_stack (void) { char *dir = NULL; while ((dir = pop_directory ()) != NULL) - g_free (dir); + g_free (dir); } -#endif /* GLIB_CHAECK_VERSION */ +#endif /* GLIB_CHAECK_VERSION */ static void insert_file (const char *dir, const char *file) @@ -600,18 +624,22 @@ insert_file (const char *dir, const char *file) char *tmp_name = NULL; static char *dirname = NULL; - while (dir [0] == PATH_SEP && dir [1] == PATH_SEP) - dir++; + while (dir[0] == PATH_SEP && dir[1] == PATH_SEP) + dir++; - if (old_dir){ - if (strcmp (old_dir, dir)){ - g_free (old_dir); - old_dir = g_strdup (dir); - dirname = add_to_list (dir, NULL); - } - } else { - old_dir = g_strdup (dir); - dirname = add_to_list (dir, NULL); + if (old_dir) + { + if (strcmp (old_dir, dir)) + { + g_free (old_dir); + old_dir = g_strdup (dir); + dirname = add_to_list (dir, NULL); + } + } + else + { + old_dir = g_strdup (dir); + dirname = add_to_list (dir, NULL); } tmp_name = g_strdup_printf (" %s", file); @@ -626,7 +654,7 @@ find_add_match (const char *dir, const char *file) /* Don't scroll */ if (matches == 0) - listbox_select_first (find_list); + listbox_select_first (find_list); send_message (&find_list->widget, WIDGET_DRAW, 0); matches++; @@ -643,70 +671,74 @@ find_add_match (const char *dir, const char *file) * has_newline - is there newline ? */ static char * -get_line_at (int file_fd, char *buf, int buf_size, int *pos, int *n_read, - gboolean *has_newline) +get_line_at (int file_fd, char *buf, int buf_size, int *pos, int *n_read, gboolean * has_newline) { char *buffer = NULL; int buffer_size = 0; char ch = 0; int i = 0; - for (;;) { - if (*pos >= *n_read) { - *pos = 0; - *n_read = mc_read (file_fd, buf, buf_size); - if (*n_read <= 0) - break; - } + for (;;) + { + if (*pos >= *n_read) + { + *pos = 0; + *n_read = mc_read (file_fd, buf, buf_size); + if (*n_read <= 0) + break; + } - ch = buf[(*pos)++]; - if (ch == '\0') { - /* skip possible leading zero(s) */ - if (i == 0) - continue; - else - break; - } + ch = buf[(*pos)++]; + if (ch == '\0') + { + /* skip possible leading zero(s) */ + if (i == 0) + continue; + else + break; + } - if (i >= buffer_size - 1) { - buffer = g_realloc (buffer, buffer_size += 80); - } - /* Strip newline */ - if (ch == '\n') - break; + if (i >= buffer_size - 1) + { + buffer = g_realloc (buffer, buffer_size += 80); + } + /* Strip newline */ + if (ch == '\n') + break; - buffer[i++] = ch; + buffer[i++] = ch; } *has_newline = (ch != '\0'); if (buffer != NULL) - buffer[i] = '\0'; + buffer[i] = '\0'; return buffer; } static FindProgressStatus -check_find_events(Dlg_head *h) +check_find_events (Dlg_head * h) { Gpm_Event event; int c; event.x = -1; c = tty_get_event (&event, h->mouse_status == MOU_REPEAT, FALSE); - if (c != EV_NONE) { - dlg_process_event (h, c, &event); - if (h->ret_value == B_ENTER - || h->ret_value == B_CANCEL - || h->ret_value == B_AGAIN - || h->ret_value == B_PANELIZE) { - /* dialog terminated */ - return FIND_ABORT; - } - if (!(h->flags & DLG_WANT_IDLE)) { - /* searching suspended */ - return FIND_SUSPEND; - } + if (c != EV_NONE) + { + dlg_process_event (h, c, &event); + if (h->ret_value == B_ENTER + || h->ret_value == B_CANCEL || h->ret_value == B_AGAIN || h->ret_value == B_PANELIZE) + { + /* dialog terminated */ + return FIND_ABORT; + } + if (!(h->flags & DLG_WANT_IDLE)) + { + /* searching suspended */ + return FIND_SUSPEND; + } } return FIND_CONT; @@ -722,26 +754,27 @@ check_find_events(Dlg_head *h) * TRUE if do_search should exit and proceed to the event handler */ static gboolean -search_content (Dlg_head *h, const char *directory, const char *filename) +search_content (Dlg_head * h, const char *directory, const char *filename) { struct stat s; - char buffer [BUF_4K]; + char buffer[BUF_4K]; char *fname = NULL; int file_fd; gboolean ret_val = FALSE; fname = concat_dir_and_file (directory, filename); - if (mc_stat (fname, &s) != 0 || !S_ISREG (s.st_mode)){ - g_free (fname); - return 0; + if (mc_stat (fname, &s) != 0 || !S_ISREG (s.st_mode)) + { + g_free (fname); + return 0; } file_fd = mc_open (fname, O_RDONLY); g_free (fname); if (file_fd == -1) - return 0; + return 0; g_snprintf (buffer, sizeof (buffer), _("Grepping in %s"), str_trunc (filename, FIND2_X_USE)); @@ -752,61 +785,67 @@ search_content (Dlg_head *h, const char *directory, const char *filename) tty_got_interrupt (); { - int line = 1; - int pos = 0; - int n_read = 0; - gboolean has_newline; - char *p = NULL; - gboolean found = FALSE; - gsize found_len; - char result [BUF_MEDIUM]; + int line = 1; + int pos = 0; + int n_read = 0; + gboolean has_newline; + char *p = NULL; + gboolean found = FALSE; + gsize found_len; + char result[BUF_MEDIUM]; - if (resuming) { - /* We've been previously suspended, start from the previous position */ - resuming = 0; - line = last_line; - pos = last_pos; - } - while (!ret_val - && (p = get_line_at (file_fd, buffer, sizeof (buffer), - &pos, &n_read, &has_newline)) != NULL) { - if (!found /* Search in binary line once */ - && mc_search_run (search_content_handle, - (const void *) p, 0, strlen (p), &found_len)) { - g_snprintf (result, sizeof (result), "%d:%s", line, filename); - find_add_match (directory, result); - found = TRUE; - } - g_free (p); + if (resuming) + { + /* We've been previously suspended, start from the previous position */ + resuming = 0; + line = last_line; + pos = last_pos; + } + while (!ret_val + && (p = get_line_at (file_fd, buffer, sizeof (buffer), + &pos, &n_read, &has_newline)) != NULL) + { + if (!found /* Search in binary line once */ + && mc_search_run (search_content_handle, + (const void *) p, 0, strlen (p), &found_len)) + { + g_snprintf (result, sizeof (result), "%d:%s", line, filename); + find_add_match (directory, result); + found = TRUE; + } + g_free (p); - if (found && options.content_first_hit) - break; + if (found && options.content_first_hit) + break; - if (has_newline) { - found = FALSE; - line++; - } + if (has_newline) + { + found = FALSE; + line++; + } - if ((line & 0xff) == 0) { - FindProgressStatus res; - res = check_find_events(h); - switch (res) { - case FIND_ABORT: - stop_idle (h); - ret_val = TRUE; - break; - case FIND_SUSPEND: - resuming = 1; - last_line = line; - last_pos = pos; - ret_val = TRUE; - break; - default: - break; - } - } + if ((line & 0xff) == 0) + { + FindProgressStatus res; + res = check_find_events (h); + switch (res) + { + case FIND_ABORT: + stop_idle (h); + ret_val = TRUE; + break; + case FIND_SUSPEND: + resuming = 1; + last_line = line; + last_pos = pos; + ret_val = TRUE; + break; + default: + break; + } + } - } + } } tty_disable_interrupt_key (); mc_close (file_fd); @@ -817,145 +856,158 @@ static int do_search (struct Dlg_head *h) { static struct dirent *dp = NULL; - static DIR *dirp = NULL; + static DIR *dirp = NULL; static char *directory = NULL; struct stat tmp_stat; static int pos = 0; static int subdirs_left = 0; gsize bytes_found; - unsigned long count; /* Number of files displayed */ + unsigned long count; /* Number of files displayed */ - if (!h) { /* someone forces me to close dirp */ - if (dirp) { - mc_closedir (dirp); - dirp = NULL; - } - g_free (directory); - directory = NULL; + if (!h) + { /* someone forces me to close dirp */ + if (dirp) + { + mc_closedir (dirp); + dirp = NULL; + } + g_free (directory); + directory = NULL; dp = NULL; - return 1; + return 1; } - search_content_handle = mc_search_new(content_pattern, -1); - if (search_content_handle) { - search_content_handle->search_type = options.content_regexp ? MC_SEARCH_T_REGEX : MC_SEARCH_T_NORMAL; + search_content_handle = mc_search_new (content_pattern, -1); + if (search_content_handle) + { + search_content_handle->search_type = + options.content_regexp ? MC_SEARCH_T_REGEX : MC_SEARCH_T_NORMAL; search_content_handle->is_case_sentitive = options.content_case_sens; search_content_handle->whole_words = options.content_whole_words; search_content_handle->is_all_charsets = options.content_all_charsets; } - search_file_handle = mc_search_new(find_pattern, -1); - search_file_handle->search_type = options.file_pattern ? MC_SEARCH_T_GLOB : MC_SEARCH_T_REGEX; + search_file_handle = mc_search_new (find_pattern, -1); + search_file_handle->search_type = options.file_pattern ? MC_SEARCH_T_GLOB : MC_SEARCH_T_REGEX; search_file_handle->is_case_sentitive = options.file_case_sens; search_file_handle->is_all_charsets = options.file_all_charsets; search_file_handle->is_entire_line = options.file_pattern; count = 0; - do_search_begin: - while (!dp){ - if (dirp){ - mc_closedir (dirp); - dirp = 0; - } - - while (!dirp){ - char *tmp = NULL; + do_search_begin: + while (!dp) + { + if (dirp) + { + mc_closedir (dirp); + dirp = 0; + } - tty_setcolor (REVERSE_COLOR); - while (1) { - char *temp_dir = NULL; - gboolean found; + while (!dirp) + { + char *tmp = NULL; - tmp = pop_directory (); - if (tmp == NULL) { - running = FALSE; - status_update (_("Finished")); - stop_idle (h); - mc_search_free (search_file_handle); - search_file_handle = NULL; - mc_search_free (search_content_handle); - search_content_handle = NULL; - return 0; - } + tty_setcolor (REVERSE_COLOR); + while (1) + { + char *temp_dir = NULL; + gboolean found; - if ((find_ignore_dirs == NULL) || (find_ignore_dirs[0] == '\0')) - break; + tmp = pop_directory (); + if (tmp == NULL) + { + running = FALSE; + status_update (_("Finished")); + stop_idle (h); + mc_search_free (search_file_handle); + search_file_handle = NULL; + mc_search_free (search_content_handle); + search_content_handle = NULL; + return 0; + } - temp_dir = g_strdup_printf (":%s:", tmp); - found = strstr (find_ignore_dirs, temp_dir) != 0; - g_free (temp_dir); - - if (!found) - break; + if ((find_ignore_dirs == NULL) || (find_ignore_dirs[0] == '\0')) + break; - g_free (tmp); - } + temp_dir = g_strdup_printf (":%s:", tmp); + found = strstr (find_ignore_dirs, temp_dir) != 0; + g_free (temp_dir); - g_free (directory); - directory = tmp; + if (!found) + break; - if (verbose){ - char buffer [BUF_SMALL]; + g_free (tmp); + } - g_snprintf (buffer, sizeof (buffer), _("Searching %s"), - str_trunc (directory, FIND2_X_USE)); - status_update (buffer); - } - /* mc_stat should not be called after mc_opendir - because vfs_s_opendir modifies the st_nlink - */ - if (!mc_stat (directory, &tmp_stat)) - subdirs_left = tmp_stat.st_nlink - 2; - else - subdirs_left = 0; + g_free (directory); + directory = tmp; - dirp = mc_opendir (directory); - } /* while (!dirp) */ + if (verbose) + { + char buffer[BUF_SMALL]; + + g_snprintf (buffer, sizeof (buffer), _("Searching %s"), + str_trunc (directory, FIND2_X_USE)); + status_update (buffer); + } + /* mc_stat should not be called after mc_opendir + because vfs_s_opendir modifies the st_nlink + */ + if (!mc_stat (directory, &tmp_stat)) + subdirs_left = tmp_stat.st_nlink - 2; + else + subdirs_left = 0; + + dirp = mc_opendir (directory); + } /* while (!dirp) */ /* skip invalid filenames */ - while ((dp = mc_readdir (dirp)) != NULL - && !str_is_valid_string (dp->d_name)) + while ((dp = mc_readdir (dirp)) != NULL && !str_is_valid_string (dp->d_name)) ; - } /* while (!dp) */ + } /* while (!dp) */ - if (strcmp (dp->d_name, ".") == 0 || - strcmp (dp->d_name, "..") == 0){ - dp = mc_readdir (dirp); + if (strcmp (dp->d_name, ".") == 0 || strcmp (dp->d_name, "..") == 0) + { + dp = mc_readdir (dirp); /* skip invalid filenames */ while (dp != NULL && !str_is_valid_string (dp->d_name)) dp = mc_readdir (dirp); - mc_search_free(search_file_handle); - search_file_handle = NULL; - mc_search_free(search_content_handle); - search_content_handle = NULL; - return 1; + mc_search_free (search_file_handle); + search_file_handle = NULL; + mc_search_free (search_content_handle); + search_content_handle = NULL; + return 1; } - if (!(options.skip_hidden && (dp->d_name[0] == '.'))) { - gboolean search_ok; + if (!(options.skip_hidden && (dp->d_name[0] == '.'))) + { + gboolean search_ok; - if ((subdirs_left != 0) && options.find_recurs - && (directory != NULL)) { /* Can directory be NULL ? */ + if ((subdirs_left != 0) && options.find_recurs && (directory != NULL)) + { /* Can directory be NULL ? */ char *tmp_name = concat_dir_and_file (directory, dp->d_name); - if (!mc_lstat (tmp_name, &tmp_stat) - && S_ISDIR (tmp_stat.st_mode)) { + if (!mc_lstat (tmp_name, &tmp_stat) && S_ISDIR (tmp_stat.st_mode)) + { push_directory (tmp_name); subdirs_left--; - } else + } + else g_free (tmp_name); } - search_ok = mc_search_run (search_file_handle, dp->d_name, - 0, strlen (dp->d_name), &bytes_found); + search_ok = mc_search_run (search_file_handle, dp->d_name, + 0, strlen (dp->d_name), &bytes_found); - if (search_ok) { + if (search_ok) + { if (content_pattern == NULL) find_add_match (directory, dp->d_name); - else if (search_content (h, directory, dp->d_name)) { - mc_search_free(search_file_handle); + else if (search_content (h, directory, dp->d_name)) + { + mc_search_free (search_file_handle); search_file_handle = NULL; - mc_search_free(search_content_handle); + mc_search_free (search_content_handle); search_content_handle = NULL; return 1; } @@ -963,25 +1015,27 @@ do_search (struct Dlg_head *h) } /* skip invalid filenames */ - while ((dp = mc_readdir (dirp)) != NULL - && !str_is_valid_string (dp->d_name)) + while ((dp = mc_readdir (dirp)) != NULL && !str_is_valid_string (dp->d_name)) ; /* Displays the nice dot */ count++; - if (!(count & 31)){ - /* For nice updating */ - const char rotating_dash[] = "|/-\\"; + if (!(count & 31)) + { + /* For nice updating */ + const char rotating_dash[] = "|/-\\"; - if (verbose){ - pos = (pos + 1) % 4; - tty_setcolor (DLG_NORMALC (h)); - dlg_move (h, FIND2_Y - 7, FIND2_X - 4); - tty_print_char (rotating_dash [pos]); - mc_refresh (); - } - } else - goto do_search_begin; + if (verbose) + { + pos = (pos + 1) % 4; + tty_setcolor (DLG_NORMALC (h)); + dlg_move (h, FIND2_Y - 7, FIND2_X - 4); + tty_print_char (rotating_dash[pos]); + mc_refresh (); + } + } + else + goto do_search_begin; mc_search_free (search_file_handle); search_file_handle = NULL; @@ -1005,10 +1059,10 @@ static char * make_fullname (const char *dirname, const char *filename) { - if (strcmp(dirname, ".") == 0 || strcmp(dirname, "."PATH_SEP_STR) == 0) - return g_strdup (filename); - if (strncmp(dirname, "."PATH_SEP_STR, 2) == 0) - return concat_dir_and_file (dirname + 2, filename); + if (strcmp (dirname, ".") == 0 || strcmp (dirname, "." PATH_SEP_STR) == 0) + return g_strdup (filename); + if (strncmp (dirname, "." PATH_SEP_STR, 2) == 0) + return concat_dir_and_file (dirname + 2, filename); return concat_dir_and_file (dirname, filename); } @@ -1019,17 +1073,20 @@ find_do_view_edit (int unparsed_view, int edit, char *dir, char *file) const char *filename = NULL; int line; - if (content_pattern != NULL) { - filename = strchr (file + 4, ':') + 1; - line = atoi (file + 4); - } else { - filename = file + 4; - line = 0; + if (content_pattern != NULL) + { + filename = strchr (file + 4, ':') + 1; + line = atoi (file + 4); + } + else + { + filename = file + 4; + line = 0; } fullname = make_fullname (dir, filename); if (edit) - do_edit_at_line (fullname, line); + do_edit_at_line (fullname, line); else view_file_at_line (fullname, unparsed_view, use_internal_view, line); g_free (fullname); @@ -1044,33 +1101,35 @@ view_edit_currently_selected_file (int unparsed_view, int edit) listbox_get_current (find_list, &text, (void **) &dir); if ((text == NULL) || (dir == NULL)) - return MSG_NOT_HANDLED; + return MSG_NOT_HANDLED; find_do_view_edit (unparsed_view, edit, dir, text); return MSG_HANDLED; } static cb_ret_t -find_callback (struct Dlg_head *h, Widget *sender, - dlg_msg_t msg, int parm, void *data) +find_callback (struct Dlg_head *h, Widget * sender, dlg_msg_t msg, int parm, void *data) { - switch (msg) { + switch (msg) + { case DLG_KEY: - if (parm == KEY_F (3) || parm == KEY_F (13)) { - int unparsed_view = (parm == KEY_F (13)); - return view_edit_currently_selected_file (unparsed_view, 0); - } - if (parm == KEY_F (4)) { - return view_edit_currently_selected_file (0, 1); - } - return MSG_NOT_HANDLED; + if (parm == KEY_F (3) || parm == KEY_F (13)) + { + int unparsed_view = (parm == KEY_F (13)); + return view_edit_currently_selected_file (unparsed_view, 0); + } + if (parm == KEY_F (4)) + { + return view_edit_currently_selected_file (0, 1); + } + return MSG_NOT_HANDLED; case DLG_IDLE: - do_search (h); - return MSG_HANDLED; + do_search (h); + return MSG_HANDLED; default: - return default_dlg_callback (h, sender, msg, parm, data); + return default_dlg_callback (h, sender, msg, parm, data); } } @@ -1085,7 +1144,7 @@ start_stop (int button) is_start = !is_start; status_update (is_start ? _("Stopped") : _("Searching")); - button_set_text (stop_button, fbuts [is_start ? 1 : 0].text); + button_set_text (stop_button, fbuts[is_start ? 1 : 0].text); return 0; } @@ -1116,74 +1175,71 @@ setup_gui (void) #ifdef ENABLE_NLS static gboolean i18n_flag = FALSE; - if (!i18n_flag) { - int i = sizeof (fbuts) / sizeof (fbuts[0]); - while (i-- != 0) { + if (!i18n_flag) + { + int i = sizeof (fbuts) / sizeof (fbuts[0]); + while (i-- != 0) + { fbuts[i].text = _(fbuts[i].text); fbuts[i].len = str_term_width1 (fbuts[i].text) + 3; - } + } - fbuts[2].len += 2; /* DEFPUSH_BUTTON */ - i18n_flag = TRUE; + fbuts[2].len += 2; /* DEFPUSH_BUTTON */ + i18n_flag = TRUE; } -#endif /* ENABLE_NLS */ +#endif /* ENABLE_NLS */ /* * Dynamically place buttons centered within current window size */ { - int l0 = max (fbuts[0].len, fbuts[1].len); - int l1 = fbuts[2].len + fbuts[3].len + l0 + fbuts[4].len; - int l2 = fbuts[5].len + fbuts[6].len + fbuts[7].len; - int r1, r2; + int l0 = max (fbuts[0].len, fbuts[1].len); + int l1 = fbuts[2].len + fbuts[3].len + l0 + fbuts[4].len; + int l2 = fbuts[5].len + fbuts[6].len + fbuts[7].len; + int r1, r2; - /* Check, if both button rows fit within FIND2_X */ - FIND2_X = max (l1 + 9, COLS - 16); - FIND2_X = max (l2 + 8, FIND2_X); + /* Check, if both button rows fit within FIND2_X */ + FIND2_X = max (l1 + 9, COLS - 16); + FIND2_X = max (l2 + 8, FIND2_X); - /* compute amount of space between buttons for each row */ - r1 = (FIND2_X - 4 - l1) % 5; - l1 = (FIND2_X - 4 - l1) / 5; - r2 = (FIND2_X - 4 - l2) % 4; - l2 = (FIND2_X - 4 - l2) / 4; + /* compute amount of space between buttons for each row */ + r1 = (FIND2_X - 4 - l1) % 5; + l1 = (FIND2_X - 4 - l1) / 5; + r2 = (FIND2_X - 4 - l2) % 4; + l2 = (FIND2_X - 4 - l2) / 4; - /* ...and finally, place buttons */ - fbuts[2].x = 2 + r1 / 2 + l1; - fbuts[3].x = fbuts[2].x + fbuts[2].len + l1; - fbuts[0].x = fbuts[3].x + fbuts[3].len + l1; - fbuts[4].x = fbuts[0].x + l0 + l1; - fbuts[5].x = 2 + r2 / 2 + l2; - fbuts[6].x = fbuts[5].x + fbuts[5].len + l2; - fbuts[7].x = fbuts[6].x + fbuts[6].len + l2; + /* ...and finally, place buttons */ + fbuts[2].x = 2 + r1 / 2 + l1; + fbuts[3].x = fbuts[2].x + fbuts[2].len + l1; + fbuts[0].x = fbuts[3].x + fbuts[3].len + l1; + fbuts[4].x = fbuts[0].x + l0 + l1; + fbuts[5].x = 2 + r2 / 2 + l2; + fbuts[6].x = fbuts[5].x + fbuts[5].len + l2; + fbuts[7].x = fbuts[6].x + fbuts[6].len + l2; } find_dlg = - create_dlg (0, 0, FIND2_Y, FIND2_X, dialog_colors, find_callback, - "[Find File]", _("Find File"), DLG_CENTER | DLG_REVERSE); + create_dlg (0, 0, FIND2_Y, FIND2_X, dialog_colors, find_callback, + "[Find File]", _("Find File"), DLG_CENTER | DLG_REVERSE); add_widget (find_dlg, - button_new (FIND2_Y - 3, fbuts[7].x, B_VIEW, NORMAL_BUTTON, - fbuts[7].text, find_do_edit_file)); + button_new (FIND2_Y - 3, fbuts[7].x, B_VIEW, NORMAL_BUTTON, + fbuts[7].text, find_do_edit_file)); add_widget (find_dlg, - button_new (FIND2_Y - 3, fbuts[6].x, B_VIEW, NORMAL_BUTTON, - fbuts[6].text, find_do_view_file)); + button_new (FIND2_Y - 3, fbuts[6].x, B_VIEW, NORMAL_BUTTON, + fbuts[6].text, find_do_view_file)); add_widget (find_dlg, - button_new (FIND2_Y - 3, fbuts[5].x, B_PANELIZE, - NORMAL_BUTTON, fbuts[5].text, 0)); + button_new (FIND2_Y - 3, fbuts[5].x, B_PANELIZE, NORMAL_BUTTON, fbuts[5].text, 0)); add_widget (find_dlg, - button_new (FIND2_Y - 4, fbuts[4].x, B_CANCEL, - NORMAL_BUTTON, fbuts[4].text, 0)); + button_new (FIND2_Y - 4, fbuts[4].x, B_CANCEL, NORMAL_BUTTON, fbuts[4].text, 0)); stop_button = - button_new (FIND2_Y - 4, fbuts[0].x, B_STOP, NORMAL_BUTTON, - fbuts[0].text, start_stop); + button_new (FIND2_Y - 4, fbuts[0].x, B_STOP, NORMAL_BUTTON, fbuts[0].text, start_stop); add_widget (find_dlg, stop_button); add_widget (find_dlg, - button_new (FIND2_Y - 4, fbuts[3].x, B_AGAIN, - NORMAL_BUTTON, fbuts[3].text, 0)); + button_new (FIND2_Y - 4, fbuts[3].x, B_AGAIN, NORMAL_BUTTON, fbuts[3].text, 0)); add_widget (find_dlg, - button_new (FIND2_Y - 4, fbuts[2].x, B_ENTER, - DEFPUSH_BUTTON, fbuts[2].text, 0)); + button_new (FIND2_Y - 4, fbuts[2].x, B_ENTER, DEFPUSH_BUTTON, fbuts[2].text, 0)); status_label = label_new (FIND2_Y - 7, 4, _("Searching")); add_widget (find_dlg, status_label); @@ -1191,8 +1247,7 @@ setup_gui (void) found_num_label = label_new (FIND2_Y - 6, 4, ""); add_widget (find_dlg, found_num_label); - find_list = - listbox_new (2, 2, FIND2_Y - 10, FIND2_X - 4, FALSE, NULL); + find_list = listbox_new (2, 2, FIND2_Y - 10, FIND2_X - 4, FALSE, NULL); add_widget (find_dlg, find_list); } @@ -1213,7 +1268,7 @@ kill_gui (void) static int find_file (const char *start_dir, const char *pattern, const char *content, - char **dirname, char **filename) + char **dirname, char **filename) { int return_value = 0; char *dir_tmp = NULL, *file_tmp = NULL; @@ -1222,9 +1277,8 @@ find_file (const char *start_dir, const char *pattern, const char *content, /* FIXME: Need to cleanup this, this ought to be passed non-globaly */ find_pattern = str_unconst (pattern); - content_pattern = (content != NULL && str_is_valid_string (content)) - ? g_strdup(content) - : NULL; + content_pattern = (content != NULL && str_is_valid_string (content)) + ? g_strdup (content) : NULL; init_find_vars (); push_directory (start_dir); @@ -1237,82 +1291,87 @@ find_file (const char *start_dir, const char *pattern, const char *content, get_list_info (&file_tmp, &dir_tmp); if (dir_tmp) - *dirname = g_strdup (dir_tmp); + *dirname = g_strdup (dir_tmp); if (file_tmp) - *filename = g_strdup (file_tmp); + *filename = g_strdup (file_tmp); - if (return_value == B_PANELIZE && *filename) { - int status, link_to_dir, stale_link; - int next_free = 0; - int i; - struct stat st; - GList *entry; - dir_list *list = ¤t_panel->dir; - char *name = NULL; + if (return_value == B_PANELIZE && *filename) + { + int status, link_to_dir, stale_link; + int next_free = 0; + int i; + struct stat st; + GList *entry; + dir_list *list = ¤t_panel->dir; + char *name = NULL; - for (i = 0, entry = find_list->list; entry != NULL; - i++, entry = g_list_next (entry)) { - const char *lc_filename = NULL; - WLEntry *le = (WLEntry *) entry->data; + for (i = 0, entry = find_list->list; entry != NULL; i++, entry = g_list_next (entry)) + { + const char *lc_filename = NULL; + WLEntry *le = (WLEntry *) entry->data; - if ((le->text == NULL) || (le->data == NULL)) - continue; + if ((le->text == NULL) || (le->data == NULL)) + continue; - if (content_pattern != NULL) - lc_filename = strchr (le->text + 4, ':') + 1; - else - lc_filename = le->text + 4; + if (content_pattern != NULL) + lc_filename = strchr (le->text + 4, ':') + 1; + else + lc_filename = le->text + 4; - name = make_fullname (le->data, lc_filename); - status = - handle_path (list, name, &st, next_free, &link_to_dir, - &stale_link); - if (status == 0) { - g_free (name); - continue; - } - if (status == -1) { - g_free (name); - break; - } + name = make_fullname (le->data, lc_filename); + status = handle_path (list, name, &st, next_free, &link_to_dir, &stale_link); + if (status == 0) + { + g_free (name); + continue; + } + if (status == -1) + { + g_free (name); + break; + } - /* don't add files more than once to the panel */ - if (content_pattern != NULL && next_free > 0 - && strcmp (list->list[next_free - 1].fname, name) == 0) { - g_free (name); - continue; - } + /* don't add files more than once to the panel */ + if (content_pattern != NULL && next_free > 0 + && strcmp (list->list[next_free - 1].fname, name) == 0) + { + g_free (name); + continue; + } - if (!next_free) /* first turn i.e clean old list */ - panel_clean_dir (current_panel); - list->list[next_free].fnamelen = strlen (name); - list->list[next_free].fname = name; - list->list[next_free].f.marked = 0; - list->list[next_free].f.link_to_dir = link_to_dir; - list->list[next_free].f.stale_link = stale_link; - list->list[next_free].f.dir_size_computed = 0; - list->list[next_free].st = st; + if (!next_free) /* first turn i.e clean old list */ + panel_clean_dir (current_panel); + list->list[next_free].fnamelen = strlen (name); + list->list[next_free].fname = name; + list->list[next_free].f.marked = 0; + list->list[next_free].f.link_to_dir = link_to_dir; + list->list[next_free].f.stale_link = stale_link; + list->list[next_free].f.dir_size_computed = 0; + list->list[next_free].st = st; list->list[next_free].sort_key = NULL; list->list[next_free].second_sort_key = NULL; - next_free++; - if (!(next_free & 15)) - rotate_dash (); - } + next_free++; + if (!(next_free & 15)) + rotate_dash (); + } - if (next_free) { - current_panel->count = next_free; - current_panel->is_panelized = 1; + if (next_free) + { + current_panel->count = next_free; + current_panel->is_panelized = 1; - if (start_dir[0] == PATH_SEP) { - strcpy (current_panel->cwd, PATH_SEP_STR); - chdir (PATH_SEP_STR); - } - } + if (start_dir[0] == PATH_SEP) + { + int ret; + strcpy (current_panel->cwd, PATH_SEP_STR); + ret = chdir (PATH_SEP_STR); + } + } } g_free (content_pattern); kill_gui (); - do_search (NULL); /* force do_search to release resources */ + do_search (NULL); /* force do_search to release resources */ g_free (old_dir); old_dir = NULL; @@ -1324,49 +1383,57 @@ do_find (void) { char *start_dir = NULL, *pattern = NULL, *content = NULL; char *filename = NULL, *dirname = NULL; - int v; + int v; gboolean dir_and_file_set; - while (find_parameters (&start_dir, &pattern, &content)){ - if (pattern [0] == '\0') - break; /* nothing search*/ + while (find_parameters (&start_dir, &pattern, &content)) + { + if (pattern[0] == '\0') + break; /* nothing search */ - dirname = filename = NULL; - is_start = FALSE; - v = find_file (start_dir, pattern, content, &dirname, &filename); - g_free (pattern); + dirname = filename = NULL; + is_start = FALSE; + v = find_file (start_dir, pattern, content, &dirname, &filename); + g_free (pattern); - if (v == B_ENTER){ - if (dirname || filename){ - if (dirname){ - do_cd (dirname, cd_exact); - if (filename) - try_to_select (current_panel, filename + (content ? - (strchr (filename + 4, ':') - filename + 1) : 4) ); - } else if (filename) - do_cd (filename, cd_exact); - select_item (current_panel); - } - g_free (dirname); - g_free (filename); - break; - } + if (v == B_ENTER) + { + if (dirname || filename) + { + if (dirname) + { + do_cd (dirname, cd_exact); + if (filename) + try_to_select (current_panel, filename + (content ? + (strchr (filename + 4, ':') - + filename + 1) : 4)); + } + else if (filename) + do_cd (filename, cd_exact); + select_item (current_panel); + } + g_free (dirname); + g_free (filename); + break; + } - g_free (content); - dir_and_file_set = dirname && filename; - g_free (dirname); - g_free (filename); + g_free (content); + dir_and_file_set = dirname && filename; + g_free (dirname); + g_free (filename); - if (v == B_CANCEL) - break; - - if (v == B_PANELIZE){ - if (dir_and_file_set){ - try_to_select (current_panel, NULL); - panel_re_sort (current_panel); - try_to_select (current_panel, NULL); - } - break; - } + if (v == B_CANCEL) + break; + + if (v == B_PANELIZE) + { + if (dir_and_file_set) + { + try_to_select (current_panel, NULL); + panel_re_sort (current_panel); + try_to_select (current_panel, NULL); + } + break; + } } } diff --git a/src/main.c b/src/main.c index afeb6e778..7059b4cb9 100644 --- a/src/main.c +++ b/src/main.c @@ -3,8 +3,8 @@ 2003, 2004, 2005, 2006, 2007, 2009 Free Software Foundation, Inc. Written by: 1994, 1995, 1996, 1997 Miguel de Icaza - 1994, 1995 Janne Kukonlehto - 1997 Norbert Warmuth + 1994, 1995 Janne Kukonlehto + 1997 Norbert Warmuth 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 @@ -37,25 +37,25 @@ #include #include #include -#include /* for username in xterm title */ +#include /* for username in xterm title */ #include "lib/global.h" #include "lib/tty/tty.h" #include "lib/tty/mouse.h" -#include "lib/tty/key.h" /* For init_key() */ -#include "lib/tty/win.h" /* xterm_flag */ +#include "lib/tty/key.h" /* For init_key() */ +#include "lib/tty/win.h" /* xterm_flag */ #include "lib/skin.h" #include "lib/mcconfig.h" #include "lib/filehighlight.h" -#include "lib/fileloc.h" /* MC_USERCONF_DIR */ +#include "lib/fileloc.h" /* MC_USERCONF_DIR */ -#include "lib/vfs/mc-vfs/vfs.h" /* vfs_translate_url() */ +#include "lib/vfs/mc-vfs/vfs.h" /* vfs_translate_url() */ #ifdef ENABLE_VFS_SMB -#include "lib/vfs/mc-vfs/smbfs.h" /* smbfs_set_debug() */ +#include "lib/vfs/mc-vfs/smbfs.h" /* smbfs_set_debug() */ #endif /* ENABLE_VFS_SMB */ #ifdef ENABLE_VFS @@ -75,21 +75,21 @@ #include "treestore.h" #include "consaver/cons.saver.h" #include "subshell.h" -#include "setup.h" /* save_setup() */ -#include "boxes.h" /* sort_box() */ +#include "setup.h" /* save_setup() */ +#include "boxes.h" /* sort_box() */ #include "layout.h" -#include "cmd.h" /* Normal commands */ +#include "cmd.h" /* Normal commands */ #include "hotlist.h" #include "panelize.h" -#include "learn.h" /* learn_keys() */ +#include "learn.h" /* learn_keys() */ #include "listmode.h" #include "execute.h" -#include "ext.h" /* For flush_extension_file() */ +#include "ext.h" /* For flush_extension_file() */ #include "widget.h" #include "command.h" #include "wtools.h" -#include "cmddef.h" /* CK_ cmd name const */ -#include "user.h" /* user_file_menu_cmd() */ +#include "cmddef.h" /* CK_ cmd name const */ +#include "user.h" /* user_file_menu_cmd() */ #include "chmod.h" #include "chown.h" @@ -110,7 +110,7 @@ #endif -#include "keybind.h" /* type global_keymap_t */ +#include "keybind.h" /* type global_keymap_t */ /* When the modes are active, left_panel, right_panel and tree_panel */ /* Point to a proper data structure. You should check with the functions */ @@ -171,7 +171,7 @@ int auto_save_setup = 1; */ #define full_eight_bits (1) #define eight_bit_clean (1) -#else /* HAVE_CHARSET */ +#else /* HAVE_CHARSET */ /* If true, allow characters in the range 160-255 */ int eight_bit_clean = 1; /* @@ -179,13 +179,13 @@ int eight_bit_clean = 1; * This is reported to break on many terminals (xterm, qansi-m). */ int full_eight_bits = 0; -#endif /* !HAVE_CHARSET */ +#endif /* !HAVE_CHARSET */ /* * If utf-8 terminal utf8_display = 1 * Display bits set UTF-8 * -*/ + */ int utf8_display = 0; /* If true use the internal viewer */ @@ -297,7 +297,7 @@ char *mc_home_alt = NULL; GQuark mc_main_error_quark (void) { - return g_quark_from_static_string (PACKAGE); + return g_quark_from_static_string (PACKAGE); } #ifdef USE_INTERNAL_EDIT @@ -323,10 +323,11 @@ const global_keymap_t *main_x_map; void save_cwds_stat (void) { - if (fast_reload) { - mc_stat (current_panel->cwd, &(current_panel->dir_stat)); - if (get_other_type () == view_listing) - mc_stat (other_panel->cwd, &(other_panel->dir_stat)); + if (fast_reload) + { + mc_stat (current_panel->cwd, &(current_panel->dir_stat)); + if (get_other_type () == view_listing) + mc_stat (other_panel->cwd, &(other_panel->dir_stat)); } } @@ -334,13 +335,14 @@ save_cwds_stat (void) void do_update_prompt (void) { - if (update_prompt) { - printf ("\r\n%s", subshell_prompt); - fflush (stdout); - update_prompt = 0; + if (update_prompt) + { + printf ("\r\n%s", subshell_prompt); + fflush (stdout); + update_prompt = 0; } } -#endif /* HAVE_SUBSHELL_SUPPORT */ +#endif /* HAVE_SUBSHELL_SUPPORT */ void change_panel (void) @@ -355,8 +357,9 @@ static void stop_dialogs (void) { midnight_dlg->running = 0; - if (current_dlg) { - current_dlg->running = 0; + if (current_dlg) + { + current_dlg->running = 0; } } @@ -365,25 +368,29 @@ quit_cmd_internal (int quiet) { int q = quit; - if (quiet || !confirm_exit) { - q = 1; - } else { - if (query_dialog - (_(" The Midnight Commander "), - _(" Do you really want to quit the Midnight Commander? "), D_NORMAL, - 2, _("&Yes"), _("&No")) == 0) - q = 1; + if (quiet || !confirm_exit) + { + q = 1; } - if (q) { -#ifdef HAVE_SUBSHELL_SUPPORT - if (!use_subshell) - stop_dialogs (); - else if ((q = exit_subshell ())) -#endif - stop_dialogs (); + else + { + if (query_dialog + (_(" The Midnight Commander "), + _(" Do you really want to quit the Midnight Commander? "), D_NORMAL, + 2, _("&Yes"), _("&No")) == 0) + q = 1; } if (q) - quit |= 1; + { +#ifdef HAVE_SUBSHELL_SUPPORT + if (!use_subshell) + stop_dialogs (); + else if ((q = exit_subshell ())) +#endif + stop_dialogs (); + } + if (q) + quit |= 1; return quit; } @@ -405,11 +412,12 @@ void subshell_chdir (const char *directory) { #ifdef HAVE_SUBSHELL_SUPPORT - if (use_subshell) { - if (vfs_current_is_local ()) - do_subshell_chdir (directory, 0, 1); + if (use_subshell) + { + if (vfs_current_is_local ()) + do_subshell_chdir (directory, 0, 1); } -#endif /* HAVE_SUBSHELL_SUPPORT */ +#endif /* HAVE_SUBSHELL_SUPPORT */ } void @@ -434,11 +442,12 @@ get_parent_dir_name (const char *cwd, const char *lwd) { const char *p; if (strlen (lwd) > strlen (cwd)) - if ((p = strrchr (lwd, PATH_SEP)) && !strncmp (cwd, lwd, p - lwd) && - ((gsize)strlen (cwd) == (gsize) p - (gsize) lwd || (p == lwd && cwd[0] == PATH_SEP && - cwd[1] == '\0'))) { - return (p + 1); - } + if ((p = strrchr (lwd, PATH_SEP)) && !strncmp (cwd, lwd, p - lwd) && + ((gsize) strlen (cwd) == (gsize) p - (gsize) lwd || (p == lwd && cwd[0] == PATH_SEP && + cwd[1] == '\0'))) + { + return (p + 1); + } return NULL; } @@ -447,16 +456,17 @@ get_parent_dir_name (const char *cwd, const char *lwd) * Don't record change in the directory history. */ static int -_do_panel_cd (WPanel *panel, const char *new_dir, enum cd_enum cd_type) +_do_panel_cd (WPanel * panel, const char *new_dir, enum cd_enum cd_type) { const char *directory; char *olddir; char temp[MC_MAXPATHLEN]; char *translated_url; - if (cd_type == cd_parse_command) { - while (*new_dir == ' ') - new_dir++; + if (cd_type == cd_parse_command) + { + while (*new_dir == ' ') + new_dir++; } olddir = g_strdup (panel->cwd); @@ -464,19 +474,22 @@ _do_panel_cd (WPanel *panel, const char *new_dir, enum cd_enum cd_type) /* Convert *new_path to a suitable pathname, handle ~user */ - if (cd_type == cd_parse_command) { - if (!strcmp (new_dir, "-")) { - strcpy (temp, panel->lwd); - new_dir = temp; - } + if (cd_type == cd_parse_command) + { + if (!strcmp (new_dir, "-")) + { + strcpy (temp, panel->lwd); + new_dir = temp; + } } directory = *new_dir ? new_dir : home_dir; - if (mc_chdir (directory) == -1) { - strcpy (panel->cwd, olddir); - g_free (olddir); - g_free (translated_url); - return 0; + if (mc_chdir (directory) == -1) + { + strcpy (panel->cwd, olddir); + g_free (olddir); + g_free (translated_url); + return 0; } g_free (translated_url); @@ -493,9 +506,8 @@ _do_panel_cd (WPanel *panel, const char *new_dir, enum cd_enum cd_type) /* Reload current panel */ panel_clean_dir (panel); panel->count = - do_load_dir (panel->cwd, &panel->dir, panel->current_sort_field->sort_routine, - panel->reverse, panel->case_sensitive, - panel->exec_first, panel->filter); + do_load_dir (panel->cwd, &panel->dir, panel->current_sort_field->sort_routine, + panel->reverse, panel->case_sensitive, panel->exec_first, panel->filter); try_to_select (panel, get_parent_dir_name (panel->cwd, olddir)); load_hint (0); panel->dirty = 1; @@ -517,7 +529,7 @@ do_panel_cd (struct WPanel *panel, const char *new_dir, enum cd_enum cd_type) r = _do_panel_cd (panel, new_dir, cd_type); if (r) - directory_history_add (panel, panel->cwd); + directory_history_add (panel, panel->cwd); return r; } @@ -528,46 +540,47 @@ do_cd (const char *new_dir, enum cd_enum exact) } void -directory_history_next (WPanel *panel) +directory_history_next (WPanel * panel) { GList *nextdir; nextdir = g_list_next (panel->dir_history); if (!nextdir) - return; + return; if (_do_panel_cd (panel, (char *) nextdir->data, cd_exact)) - panel->dir_history = nextdir; + panel->dir_history = nextdir; } void -directory_history_prev (WPanel *panel) +directory_history_prev (WPanel * panel) { GList *prevdir; prevdir = g_list_previous (panel->dir_history); if (!prevdir) - return; + return; if (_do_panel_cd (panel, (char *) prevdir->data, cd_exact)) - panel->dir_history = prevdir; + panel->dir_history = prevdir; } void -directory_history_list (WPanel *panel) +directory_history_list (WPanel * panel) { char *s; s = show_hist (&panel->dir_history, &panel->widget); - if (s != NULL) { - if (_do_panel_cd (panel, s, cd_exact)) - directory_history_add (panel, panel->cwd); - else - message (D_ERROR, MSG_ERROR, _("Cannot change directory")); - g_free (s); + if (s != NULL) + { + if (_do_panel_cd (panel, s, cd_exact)) + directory_history_add (panel, panel->cwd); + else + message (D_ERROR, MSG_ERROR, _("Cannot change directory")); + g_free (s); } } @@ -579,37 +592,38 @@ load_prompt (int fd, void *unused) (void) unused; if (!read_subshell_prompt ()) - return 0; + return 0; /* Don't actually change the prompt if it's invisible */ - if (current_dlg == midnight_dlg && command_prompt) { - char *tmp_prompt; - int prompt_len; + if (current_dlg == midnight_dlg && command_prompt) + { + char *tmp_prompt; + int prompt_len; - tmp_prompt = strip_ctrl_codes (subshell_prompt); - prompt_len = str_term_width1 (tmp_prompt); + tmp_prompt = strip_ctrl_codes (subshell_prompt); + prompt_len = str_term_width1 (tmp_prompt); - /* Check for prompts too big */ - if (COLS > 8 && prompt_len > COLS - 8) { - tmp_prompt[COLS - 8] = '\0'; - prompt_len = COLS - 8; - } - mc_prompt = tmp_prompt; - label_set_text (the_prompt, mc_prompt); - winput_set_origin ((WInput *) cmdline, prompt_len, - COLS - prompt_len); + /* Check for prompts too big */ + if (COLS > 8 && prompt_len > COLS - 8) + { + tmp_prompt[COLS - 8] = '\0'; + prompt_len = COLS - 8; + } + mc_prompt = tmp_prompt; + label_set_text (the_prompt, mc_prompt); + winput_set_origin ((WInput *) cmdline, prompt_len, COLS - prompt_len); - /* since the prompt has changed, and we are called from one of the - * tty_get_event channels, the prompt updating does not take place - * automatically: force a cursor update and a screen refresh - */ - update_cursor (midnight_dlg); - mc_refresh (); + /* since the prompt has changed, and we are called from one of the + * tty_get_event channels, the prompt updating does not take place + * automatically: force a cursor update and a screen refresh + */ + update_cursor (midnight_dlg); + mc_refresh (); } update_prompt = 1; return 0; } -#endif /* HAVE_SUBSHELL_SUPPORT */ +#endif /* HAVE_SUBSHELL_SUPPORT */ void sort_cmd (void) @@ -618,12 +632,10 @@ sort_cmd (void) const panel_field_t *sort_order; if (!SELECTED_IS_PANEL) - return; + return; p = MENU_PANEL; - sort_order = sort_box (p->current_sort_field, &p->reverse, - &p->case_sensitive, - &p->exec_first); + sort_order = sort_box (p->current_sort_field, &p->reverse, &p->case_sensitive, &p->exec_first); panel_set_sort_order (p, sort_order); @@ -635,9 +647,10 @@ treebox_cmd (void) char *sel_dir; sel_dir = tree_box (selection (current_panel)->fname); - if (sel_dir) { - do_cd (sel_dir, cd_exact); - g_free (sel_dir); + if (sel_dir) + { + do_cd (sel_dir, cd_exact); + g_free (sel_dir); } } @@ -648,11 +661,11 @@ listmode_cmd (void) char *newmode; if (get_current_type () != view_listing) - return; + return; newmode = listmode_edit (current_panel->user_format); if (!newmode) - return; + return; g_free (current_panel->user_format); current_panel->list_type = list_user; @@ -661,7 +674,7 @@ listmode_cmd (void) do_refresh (); } -#endif /* LISTMODE_EDITOR */ +#endif /* LISTMODE_EDITOR */ /* NOTICE: hotkeys specified here are overriden in menubar_paint_idx (alex) */ static GList * @@ -670,30 +683,31 @@ create_panel_menu (void) GList *entries = NULL; entries = g_list_append (entries, menu_entry_create (_("&Listing mode..."), CK_ListingCmd)); - entries = g_list_append (entries, menu_entry_create (_("&Quick view"), CK_QuickViewCmd)); - entries = g_list_append (entries, menu_entry_create (_("&Info" ), CK_InfoCmd)); - entries = g_list_append (entries, menu_entry_create (_("&Tree"), CK_TreeCmd)); + entries = g_list_append (entries, menu_entry_create (_("&Quick view"), CK_QuickViewCmd)); + entries = g_list_append (entries, menu_entry_create (_("&Info"), CK_InfoCmd)); + entries = g_list_append (entries, menu_entry_create (_("&Tree"), CK_TreeCmd)); entries = g_list_append (entries, menu_separator_create ()); - entries = g_list_append (entries, menu_entry_create (_("&Sort order..."), CK_Sort)); + entries = g_list_append (entries, menu_entry_create (_("&Sort order..."), CK_Sort)); entries = g_list_append (entries, menu_separator_create ()); - entries = g_list_append (entries, menu_entry_create (_("&Filter..."), CK_FilterCmd)); + entries = g_list_append (entries, menu_entry_create (_("&Filter..."), CK_FilterCmd)); #ifdef HAVE_CHARSET entries = g_list_append (entries, menu_separator_create ()); - entries = g_list_append (entries, menu_entry_create (_("&Encoding..."), CK_PanelSetPanelEncoding)); + entries = + g_list_append (entries, menu_entry_create (_("&Encoding..."), CK_PanelSetPanelEncoding)); #endif #ifdef USE_NETCODE entries = g_list_append (entries, menu_separator_create ()); #ifdef ENABLE_VFS_MCFS entries = g_list_append (entries, menu_entry_create (_("&Network link..."), CK_NetlinkCmd)); #endif - entries = g_list_append (entries, menu_entry_create (_("FT&P link..."), CK_FtplinkCmd)); - entries = g_list_append (entries, menu_entry_create (_("S&hell link..."), CK_FishlinkCmd)); + entries = g_list_append (entries, menu_entry_create (_("FT&P link..."), CK_FtplinkCmd)); + entries = g_list_append (entries, menu_entry_create (_("S&hell link..."), CK_FishlinkCmd)); #ifdef ENABLE_VFS_SMB - entries = g_list_append (entries, menu_entry_create (_("SM&B link..."), CK_SmblinkCmd)); + entries = g_list_append (entries, menu_entry_create (_("SM&B link..."), CK_SmblinkCmd)); #endif /* ENABLE_VFS_SMB */ #endif entries = g_list_append (entries, menu_separator_create ()); - entries = g_list_append (entries, menu_entry_create (_("&Rescan"), CK_RereadCmd)); + entries = g_list_append (entries, menu_entry_create (_("&Rescan"), CK_RereadCmd)); return entries; } @@ -703,27 +717,30 @@ create_file_menu (void) { GList *entries = NULL; - entries = g_list_append (entries, menu_entry_create (_("&View"), CK_ViewCmd)); - entries = g_list_append (entries, menu_entry_create (_("Vie&w file..."), CK_ViewFileCmd)); - entries = g_list_append (entries, menu_entry_create (_("&Filtered view"), CK_FilteredViewCmd)); - entries = g_list_append (entries, menu_entry_create (_("&Edit"), CK_EditCmd)); - entries = g_list_append (entries, menu_entry_create (_("&Copy"), CK_CopyCmd)); - entries = g_list_append (entries, menu_entry_create (_("C&hmod"), CK_ChmodCmd)); - entries = g_list_append (entries, menu_entry_create (_("&Link"), CK_LinkCmd)); - entries = g_list_append (entries, menu_entry_create (_("&SymLink"), CK_SymlinkCmd)); - entries = g_list_append (entries, menu_entry_create (_("Edit s&ymlink"), CK_EditSymlinkCmd)); - entries = g_list_append (entries, menu_entry_create (_("Ch&own"), CK_ChownCmd)); - entries = g_list_append (entries, menu_entry_create (_("&Advanced chown"), CK_ChownAdvancedCmd)); - entries = g_list_append (entries, menu_entry_create (_("&Rename/Move"), CK_RenameCmd)); - entries = g_list_append (entries, menu_entry_create (_("&Mkdir"), CK_MkdirCmd)); - entries = g_list_append (entries, menu_entry_create (_("&Delete"), CK_DeleteCmd)); - entries = g_list_append (entries, menu_entry_create (_("&Quick cd"), CK_QuickCdCmd)); + entries = g_list_append (entries, menu_entry_create (_("&View"), CK_ViewCmd)); + entries = g_list_append (entries, menu_entry_create (_("Vie&w file..."), CK_ViewFileCmd)); + entries = g_list_append (entries, menu_entry_create (_("&Filtered view"), CK_FilteredViewCmd)); + entries = g_list_append (entries, menu_entry_create (_("&Edit"), CK_EditCmd)); + entries = g_list_append (entries, menu_entry_create (_("&Copy"), CK_CopyCmd)); + entries = g_list_append (entries, menu_entry_create (_("C&hmod"), CK_ChmodCmd)); + entries = g_list_append (entries, menu_entry_create (_("&Link"), CK_LinkCmd)); + entries = g_list_append (entries, menu_entry_create (_("&SymLink"), CK_SymlinkCmd)); + entries = g_list_append (entries, menu_entry_create (_("Edit s&ymlink"), CK_EditSymlinkCmd)); + entries = g_list_append (entries, menu_entry_create (_("Ch&own"), CK_ChownCmd)); + entries = + g_list_append (entries, menu_entry_create (_("&Advanced chown"), CK_ChownAdvancedCmd)); + entries = g_list_append (entries, menu_entry_create (_("&Rename/Move"), CK_RenameCmd)); + entries = g_list_append (entries, menu_entry_create (_("&Mkdir"), CK_MkdirCmd)); + entries = g_list_append (entries, menu_entry_create (_("&Delete"), CK_DeleteCmd)); + entries = g_list_append (entries, menu_entry_create (_("&Quick cd"), CK_QuickCdCmd)); entries = g_list_append (entries, menu_separator_create ()); - entries = g_list_append (entries, menu_entry_create (_("Select &group"), CK_SelectCmd)); - entries = g_list_append (entries, menu_entry_create (_("U&nselect group"), CK_UnselectCmd)); - entries = g_list_append (entries, menu_entry_create (_("Reverse selec&tion"), CK_ReverseSelectionCmd)); + entries = g_list_append (entries, menu_entry_create (_("Select &group"), CK_SelectCmd)); + entries = g_list_append (entries, menu_entry_create (_("U&nselect group"), CK_UnselectCmd)); + entries = + g_list_append (entries, + menu_entry_create (_("Reverse selec&tion"), CK_ReverseSelectionCmd)); entries = g_list_append (entries, menu_separator_create ()); - entries = g_list_append (entries, menu_entry_create (_("E&xit"), CK_QuitCmd)); + entries = g_list_append (entries, menu_entry_create (_("E&xit"), CK_QuitCmd)); return entries; } @@ -737,39 +754,51 @@ create_command_menu (void) */ GList *entries = NULL; - entries = g_list_append (entries, menu_entry_create (_("&User menu"), CK_UserMenuCmd)); - entries = g_list_append (entries, menu_entry_create (_("&Directory tree"), CK_TreeBoxCmd)); - entries = g_list_append (entries, menu_entry_create (_("&Find file"), CK_FindCmd)); - entries = g_list_append (entries, menu_entry_create (_("S&wap panels"), CK_SwapCmd)); - entries = g_list_append (entries, menu_entry_create (_("Switch &panels on/off"), CK_ShowCommandLine)); - entries = g_list_append (entries, menu_entry_create (_("&Compare directories"), CK_CompareDirsCmd)); + entries = g_list_append (entries, menu_entry_create (_("&User menu"), CK_UserMenuCmd)); + entries = g_list_append (entries, menu_entry_create (_("&Directory tree"), CK_TreeBoxCmd)); + entries = g_list_append (entries, menu_entry_create (_("&Find file"), CK_FindCmd)); + entries = g_list_append (entries, menu_entry_create (_("S&wap panels"), CK_SwapCmd)); + entries = + g_list_append (entries, menu_entry_create (_("Switch &panels on/off"), CK_ShowCommandLine)); + entries = + g_list_append (entries, menu_entry_create (_("&Compare directories"), CK_CompareDirsCmd)); #ifdef USE_DIFF_VIEW - entries = g_list_append (entries, menu_entry_create (_("&View diff files"), CK_DiffViewCmd)); + entries = g_list_append (entries, menu_entry_create (_("&View diff files"), CK_DiffViewCmd)); #endif - entries = g_list_append (entries, menu_entry_create (_("E&xternal panelize"), CK_ExternalPanelize)); - entries = g_list_append (entries, menu_entry_create (_("Show directory s&izes"), CK_SingleDirsizeCmd)); + entries = + g_list_append (entries, menu_entry_create (_("E&xternal panelize"), CK_ExternalPanelize)); + entries = + g_list_append (entries, + menu_entry_create (_("Show directory s&izes"), CK_SingleDirsizeCmd)); entries = g_list_append (entries, menu_separator_create ()); - entries = g_list_append (entries, menu_entry_create (_("Command &history"), CK_HistoryCmd)); - entries = g_list_append (entries, menu_entry_create (_("Di&rectory hotlist"), CK_QuickChdirCmd)); + entries = g_list_append (entries, menu_entry_create (_("Command &history"), CK_HistoryCmd)); + entries = + g_list_append (entries, menu_entry_create (_("Di&rectory hotlist"), CK_QuickChdirCmd)); #ifdef ENABLE_VFS - entries = g_list_append (entries, menu_entry_create (_("&Active VFS list"), CK_ReselectVfs)); + entries = g_list_append (entries, menu_entry_create (_("&Active VFS list"), CK_ReselectVfs)); #endif #ifdef WITH_BACKGROUND - entries = g_list_append (entries, menu_entry_create (_("&Background jobs"), CK_JobsCmd)); + entries = g_list_append (entries, menu_entry_create (_("&Background jobs"), CK_JobsCmd)); #endif entries = g_list_append (entries, menu_separator_create ()); #ifdef USE_EXT2FSLIB - entries = g_list_append (entries, menu_entry_create (_("&Undelete files (ext2fs only)"), CK_UndeleteCmd)); + entries = + g_list_append (entries, + menu_entry_create (_("&Undelete files (ext2fs only)"), CK_UndeleteCmd)); #endif #ifdef LISTMODE_EDITOR - entries = g_list_append (entries, menu_entry_create (_("&Listing format edit"), CK_ListmodeCmd)); + entries = + g_list_append (entries, menu_entry_create (_("&Listing format edit"), CK_ListmodeCmd)); #endif #if defined (USE_EXT2FSLIB) || defined (LISTMODE_EDITOR) entries = g_list_append (entries, menu_separator_create ()); #endif - entries = g_list_append (entries, menu_entry_create (_("Edit &extension file"), CK_EditExtFileCmd)); - entries = g_list_append (entries, menu_entry_create (_("Edit &menu file"), CK_EditMcMenuCmd)); - entries = g_list_append (entries, menu_entry_create (_("Edit hi&ghlighting group file"), CK_EditFhlFileCmd)); + entries = + g_list_append (entries, menu_entry_create (_("Edit &extension file"), CK_EditExtFileCmd)); + entries = g_list_append (entries, menu_entry_create (_("Edit &menu file"), CK_EditMcMenuCmd)); + entries = + g_list_append (entries, + menu_entry_create (_("Edit hi&ghlighting group file"), CK_EditFhlFileCmd)); return entries; } @@ -780,15 +809,15 @@ create_options_menu (void) GList *entries = NULL; entries = g_list_append (entries, menu_entry_create (_("&Configuration..."), CK_ConfigureBox)); - entries = g_list_append (entries, menu_entry_create (_("&Layout..."), CK_LayoutCmd)); - entries = g_list_append (entries, menu_entry_create (_("C&onfirmation..."), CK_ConfirmBox)); - entries = g_list_append (entries, menu_entry_create (_("&Display bits..."), CK_DisplayBitsBox)); - entries = g_list_append (entries, menu_entry_create (_("Learn &keys..."), CK_LearnKeys)); + entries = g_list_append (entries, menu_entry_create (_("&Layout..."), CK_LayoutCmd)); + entries = g_list_append (entries, menu_entry_create (_("C&onfirmation..."), CK_ConfirmBox)); + entries = g_list_append (entries, menu_entry_create (_("&Display bits..."), CK_DisplayBitsBox)); + entries = g_list_append (entries, menu_entry_create (_("Learn &keys..."), CK_LearnKeys)); #ifdef ENABLE_VFS - entries = g_list_append (entries, menu_entry_create (_("&Virtual FS..."), CK_ConfigureVfs)); + entries = g_list_append (entries, menu_entry_create (_("&Virtual FS..."), CK_ConfigureVfs)); #endif entries = g_list_append (entries, menu_separator_create ()); - entries = g_list_append (entries, menu_entry_create (_("&Save setup"), CK_SaveSetupCmd)); + entries = g_list_append (entries, menu_entry_create (_("&Save setup"), CK_SaveSetupCmd)); return entries; } @@ -797,17 +826,16 @@ void init_menu (void) { menubar_add_menu (the_menubar, - create_menu (horizontal_split ? _("&Above") : _("&Left"), - create_panel_menu (), "[Left and Right Menus]")); + create_menu (horizontal_split ? _("&Above") : _("&Left"), + create_panel_menu (), "[Left and Right Menus]")); + menubar_add_menu (the_menubar, create_menu (_("&File"), create_file_menu (), "[File Menu]")); menubar_add_menu (the_menubar, - create_menu (_("&File"), create_file_menu (), "[File Menu]")); + create_menu (_("&Command"), create_command_menu (), "[Command Menu]")); menubar_add_menu (the_menubar, - create_menu (_("&Command"), create_command_menu (), "[Command Menu]")); + create_menu (_("&Options"), create_options_menu (), "[Options Menu]")); menubar_add_menu (the_menubar, - create_menu (_("&Options"), create_options_menu (), "[Options Menu]")); - menubar_add_menu (the_menubar, - create_menu (horizontal_split ? _("&Below") : _("&Right"), - create_panel_menu (), "[Left and Right Menus]")); + create_menu (horizontal_split ? _("&Below") : _("&Right"), + create_panel_menu (), "[Left and Right Menus]")); } void @@ -829,12 +857,12 @@ static void menu_cmd (void) { if (the_menubar->is_active) - return; + return; if ((get_current_index () == 0) == (current_panel->active != 0)) - the_menubar->selected = 0; + the_menubar->selected = 0; else - the_menubar->selected = g_list_length (the_menubar->menu) - 1; + the_menubar->selected = g_list_length (the_menubar->menu) - 1; menu_last_selected_cmd (); } @@ -846,17 +874,17 @@ midnight_get_shortcut (unsigned long command) shortcut = lookup_keymap_shortcut (main_map, command); if (shortcut != NULL) - return g_strdup (shortcut); + return g_strdup (shortcut); shortcut = lookup_keymap_shortcut (panel_map, command); if (shortcut != NULL) - return g_strdup (shortcut); + return g_strdup (shortcut); ext_map = lookup_keymap_shortcut (main_map, CK_StartExtMap1); if (ext_map != NULL) - shortcut = lookup_keymap_shortcut (main_x_map, command); + shortcut = lookup_keymap_shortcut (main_x_map, command); if (shortcut != NULL) - return g_strdup_printf ("%s %s", ext_map, shortcut); + return g_strdup_printf ("%s %s", ext_map, shortcut); return NULL; } @@ -866,14 +894,15 @@ void toggle_fast_reload (void) { fast_reload = !fast_reload; - if (fast_reload_w == 0 && fast_reload) { - message (D_NORMAL, _(" Information "), - _ - (" Using the fast reload option may not reflect the exact \n" - " directory contents. In this case you'll need to do a \n" - " manual reload of the directory. See the man page for \n" - " the details. ")); - fast_reload_w = 1; + if (fast_reload_w == 0 && fast_reload) + { + message (D_NORMAL, _(" Information "), + _ + (" Using the fast reload option may not reflect the exact \n" + " directory contents. In this case you'll need to do a \n" + " manual reload of the directory. See the man page for \n" + " the details. ")); + fast_reload_w = 1; } } @@ -903,7 +932,7 @@ toggle_panels_split (void) { horizontal_split = !horizontal_split; layout_change (); - do_refresh(); + do_refresh (); } void @@ -921,9 +950,10 @@ static void translated_mc_chdir (char *dir) { char *newdir; + int ret; newdir = vfs_translate_url (dir); - mc_chdir (newdir); + ret = mc_chdir (newdir); g_free (newdir); } @@ -935,45 +965,54 @@ create_panels (void) panel_view_mode_t current_mode, other_mode; char original_dir[BUF_1K] = "\0"; - if (boot_current_is_left) { - current_index = 0; - other_index = 1; - current_mode = startup_left_mode; - other_mode = startup_right_mode; - } else { - current_index = 1; - other_index = 0; - current_mode = startup_right_mode; - other_mode = startup_left_mode; + if (boot_current_is_left) + { + current_index = 0; + other_index = 1; + current_mode = startup_left_mode; + other_mode = startup_right_mode; + } + else + { + current_index = 1; + other_index = 0; + current_mode = startup_right_mode; + other_mode = startup_left_mode; } /* Creates the left panel */ - if (mc_run_param0 != NULL) { - if (mc_run_param1 != NULL) { - /* Ok, user has specified two dirs, save the original one, - * since we may not be able to chdir to the proper - * second directory later - */ - mc_get_current_wd (original_dir, sizeof (original_dir) - 2); - } - translated_mc_chdir (mc_run_param0); + if (mc_run_param0 != NULL) + { + if (mc_run_param1 != NULL) + { + /* Ok, user has specified two dirs, save the original one, + * since we may not be able to chdir to the proper + * second directory later + */ + mc_get_current_wd (original_dir, sizeof (original_dir) - 2); + } + translated_mc_chdir (mc_run_param0); } set_display_type (current_index, current_mode); /* The other panel */ - if (mc_run_param1 != NULL) { - if (original_dir[0] != '\0') - translated_mc_chdir (original_dir); - translated_mc_chdir (mc_run_param1); + if (mc_run_param1 != NULL) + { + if (original_dir[0] != '\0') + translated_mc_chdir (original_dir); + translated_mc_chdir (mc_run_param1); } set_display_type (other_index, other_mode); - if (startup_left_mode == view_listing) { - current_panel = left_panel; - } else { - if (right_panel) - current_panel = right_panel; - else - current_panel = left_panel; + if (startup_left_mode == view_listing) + { + current_panel = left_panel; + } + else + { + if (right_panel) + current_panel = right_panel; + else + current_panel = left_panel; } /* Create the nice widgets */ @@ -995,13 +1034,13 @@ copy_current_pathname (void) { char *cwd_path; if (!command_prompt) - return; + return; cwd_path = remove_encoding_from_path (current_panel->cwd); command_insert (cmdline, cwd_path, 0); - if (cwd_path [strlen (cwd_path ) - 1] != PATH_SEP) - command_insert (cmdline, PATH_SEP_STR, 0); + if (cwd_path[strlen (cwd_path) - 1] != PATH_SEP) + command_insert (cmdline, PATH_SEP_STR, 0); g_free (cwd_path); } @@ -1011,36 +1050,37 @@ copy_other_pathname (void) char *cwd_path; if (get_other_type () != view_listing) - return; + return; if (!command_prompt) - return; + return; cwd_path = remove_encoding_from_path (other_panel->cwd); command_insert (cmdline, cwd_path, 0); - if (cwd_path [strlen (cwd_path ) - 1] != PATH_SEP) - command_insert (cmdline, PATH_SEP_STR, 0); + if (cwd_path[strlen (cwd_path) - 1] != PATH_SEP) + command_insert (cmdline, PATH_SEP_STR, 0); g_free (cwd_path); } static void -copy_readlink (WPanel *panel) +copy_readlink (WPanel * panel) { if (!command_prompt) - return; - if (S_ISLNK (selection (panel)->st.st_mode)) { - char buffer[MC_MAXPATHLEN]; - char *p = - concat_dir_and_file (panel->cwd, selection (panel)->fname); - int i; + return; + if (S_ISLNK (selection (panel)->st.st_mode)) + { + char buffer[MC_MAXPATHLEN]; + char *p = concat_dir_and_file (panel->cwd, selection (panel)->fname); + int i; - i = mc_readlink (p, buffer, MC_MAXPATHLEN - 1); - g_free (p); - if (i > 0) { - buffer[i] = 0; - command_insert (cmdline, buffer, 1); - } + i = mc_readlink (p, buffer, MC_MAXPATHLEN - 1); + g_free (p); + if (i > 0) + { + buffer[i] = 0; + command_insert (cmdline, buffer, 1); + } } } @@ -1054,7 +1094,7 @@ static void copy_other_readlink (void) { if (get_other_type () == view_listing) - copy_readlink (other_panel); + copy_readlink (other_panel); } /* Insert the selected file name into the input line */ @@ -1063,33 +1103,38 @@ copy_prog_name (void) { char *tmp; if (!command_prompt) - return; + return; - if (get_current_type () == view_tree) { - WTree *tree = (WTree *) get_panel_widget (get_current_index ()); - tmp = tree_selected_name (tree); - } else - tmp = selection (current_panel)->fname; + if (get_current_type () == view_tree) + { + WTree *tree = (WTree *) get_panel_widget (get_current_index ()); + tmp = tree_selected_name (tree); + } + else + tmp = selection (current_panel)->fname; command_insert (cmdline, tmp, 1); } static void -copy_tagged (WPanel *panel) +copy_tagged (WPanel * panel) { int i; if (!command_prompt) - return; + return; input_disable_update (cmdline); - if (panel->marked) { - for (i = 0; i < panel->count; i++) { - if (panel->dir.list[i].f.marked) - command_insert (cmdline, panel->dir.list[i].fname, 1); - } - } else { - command_insert (cmdline, panel->dir.list[panel->selected].fname, - 1); + if (panel->marked) + { + for (i = 0; i < panel->count; i++) + { + if (panel->dir.list[i].f.marked) + command_insert (cmdline, panel->dir.list[i].fname, 1); + } + } + else + { + command_insert (cmdline, panel->dir.list[panel->selected].fname, 1); } input_enable_update (cmdline); } @@ -1104,22 +1149,22 @@ static void copy_other_tagged (void) { if (get_other_type () == view_listing) - copy_tagged (other_panel); + copy_tagged (other_panel); } void -midnight_set_buttonbar (WButtonBar *b) +midnight_set_buttonbar (WButtonBar * b) { - buttonbar_set_label (b, 1, Q_("ButtonBar|Help"), main_map, NULL); - buttonbar_set_label (b, 2, Q_("ButtonBar|Menu"), main_map, NULL); - buttonbar_set_label (b, 3, Q_("ButtonBar|View"), main_map, NULL); - buttonbar_set_label (b, 4, Q_("ButtonBar|Edit"), main_map, NULL); - buttonbar_set_label (b, 5, Q_("ButtonBar|Copy"), main_map, NULL); - buttonbar_set_label (b, 6, Q_("ButtonBar|RenMov"), main_map, NULL); - buttonbar_set_label (b, 7, Q_("ButtonBar|Mkdir"), main_map, NULL); - buttonbar_set_label (b, 8, Q_("ButtonBar|Delete"), main_map, NULL); - buttonbar_set_label (b, 9, Q_("ButtonBar|PullDn"), main_map, NULL); - buttonbar_set_label (b, 10, Q_("ButtonBar|Quit"), main_map, NULL); + buttonbar_set_label (b, 1, Q_ ("ButtonBar|Help"), main_map, NULL); + buttonbar_set_label (b, 2, Q_ ("ButtonBar|Menu"), main_map, NULL); + buttonbar_set_label (b, 3, Q_ ("ButtonBar|View"), main_map, NULL); + buttonbar_set_label (b, 4, Q_ ("ButtonBar|Edit"), main_map, NULL); + buttonbar_set_label (b, 5, Q_ ("ButtonBar|Copy"), main_map, NULL); + buttonbar_set_label (b, 6, Q_ ("ButtonBar|RenMov"), main_map, NULL); + buttonbar_set_label (b, 7, Q_ ("ButtonBar|Mkdir"), main_map, NULL); + buttonbar_set_label (b, 8, Q_ ("ButtonBar|Delete"), main_map, NULL); + buttonbar_set_label (b, 9, Q_ ("ButtonBar|PullDn"), main_map, NULL); + buttonbar_set_label (b, 10, Q_ ("ButtonBar|Quit"), main_map, NULL); } static gboolean ctl_x_map_enabled = FALSE; @@ -1131,13 +1176,14 @@ ctl_x_cmd (void) } static cb_ret_t -midnight_execute_cmd (Widget *sender, unsigned long command) +midnight_execute_cmd (Widget * sender, unsigned long command) { cb_ret_t res = MSG_HANDLED; (void) sender; - switch (command) { + switch (command) + { case CK_AddHotlist: add2hotlist_cmd (); break; @@ -1239,7 +1285,7 @@ midnight_execute_cmd (Widget *sender, unsigned long command) break; case CK_InfoCmd: if (sender == (Widget *) the_menubar) - info_cmd (); /* mwnu */ + info_cmd (); /* mwnu */ else info_cmd_no_menu (); /* shortcut or buttonbar */ break; @@ -1292,7 +1338,7 @@ midnight_execute_cmd (Widget *sender, unsigned long command) break; case CK_QuickViewCmd: if (sender == (Widget *) the_menubar) - quick_view_cmd (); /* menu */ + quick_view_cmd (); /* menu */ else quick_cmd_no_menu (); /* shortcut or buttonabr */ break; @@ -1393,42 +1439,49 @@ init_xterm_support (void) const char *termvalue; termvalue = getenv ("TERM"); - if (!termvalue || !(*termvalue)) { - fputs (_("The TERM environment variable is unset!\n"), stderr); - exit (1); + if (!termvalue || !(*termvalue)) + { + fputs (_("The TERM environment variable is unset!\n"), stderr); + exit (1); } /* Check mouse capabilities */ xmouse_seq = tty_tgetstr ("Km"); - if (strcmp (termvalue, "cygwin") == 0) { - mc_args__force_xterm = 1; - use_mouse_p = MOUSE_DISABLED; + if (strcmp (termvalue, "cygwin") == 0) + { + mc_args__force_xterm = 1; + use_mouse_p = MOUSE_DISABLED; } if (mc_args__force_xterm || strncmp (termvalue, "xterm", 5) == 0 - || strncmp (termvalue, "konsole", 7) == 0 - || strncmp (termvalue, "rxvt", 4) == 0 - || strcmp (termvalue, "Eterm") == 0 - || strcmp (termvalue, "dtterm") == 0) { - xterm_flag = 1; + || strncmp (termvalue, "konsole", 7) == 0 + || strncmp (termvalue, "rxvt", 4) == 0 + || strcmp (termvalue, "Eterm") == 0 || strcmp (termvalue, "dtterm") == 0) + { + xterm_flag = 1; - /* Default to the standard xterm sequence */ - if (!xmouse_seq) { - xmouse_seq = ESC_STR "[M"; - } + /* Default to the standard xterm sequence */ + if (!xmouse_seq) + { + xmouse_seq = ESC_STR "[M"; + } - /* Enable mouse unless explicitly disabled by --nomouse */ - if (use_mouse_p != MOUSE_DISABLED) { - const char *color_term = getenv ("COLORTERM"); - if (strncmp (termvalue, "rxvt", 4) == 0 || - (color_term != NULL && strncmp (color_term, "rxvt", 4) == 0) || - strcmp (termvalue, "Eterm") == 0) { - use_mouse_p = MOUSE_XTERM_NORMAL_TRACKING; - } else { - use_mouse_p = MOUSE_XTERM_BUTTON_EVENT_TRACKING; - } - } + /* Enable mouse unless explicitly disabled by --nomouse */ + if (use_mouse_p != MOUSE_DISABLED) + { + const char *color_term = getenv ("COLORTERM"); + if (strncmp (termvalue, "rxvt", 4) == 0 || + (color_term != NULL && strncmp (color_term, "rxvt", 4) == 0) || + strcmp (termvalue, "Eterm") == 0) + { + use_mouse_p = MOUSE_XTERM_NORMAL_TRACKING; + } + else + { + use_mouse_p = MOUSE_XTERM_BUTTON_EVENT_TRACKING; + } + } } } @@ -1443,13 +1496,13 @@ setup_mc (void) #ifdef HAVE_SUBSHELL_SUPPORT if (use_subshell) - add_select_channel (subshell_pty, load_prompt, 0); -#endif /* !HAVE_SUBSHELL_SUPPORT */ + add_select_channel (subshell_pty, load_prompt, 0); +#endif /* !HAVE_SUBSHELL_SUPPORT */ tty_setup_sigwinch (sigwinch_handler); if ((tty_baudrate () < 9600) || tty_is_slow ()) - verbose = 0; + verbose = 0; init_xterm_support (); init_mouse (); @@ -1459,35 +1512,39 @@ static void setup_dummy_mc (void) { char d[MC_MAXPATHLEN]; + int ret; mc_get_current_wd (d, MC_MAXPATHLEN); setup_mc (); - mc_chdir (d); + ret = mc_chdir (d); } -static void check_codeset() +static void +check_codeset () { const char *current_system_codepage = NULL; - current_system_codepage = str_detect_termencoding(); + current_system_codepage = str_detect_termencoding (); #ifdef HAVE_CHARSET { - const char *_display_codepage; + const char *_display_codepage; - _display_codepage = get_codepage_id (display_codepage); + _display_codepage = get_codepage_id (display_codepage); - if (! strcmp(_display_codepage, current_system_codepage)) { - utf8_display = str_isutf8 (current_system_codepage); - return; - } + if (!strcmp (_display_codepage, current_system_codepage)) + { + utf8_display = str_isutf8 (current_system_codepage); + return; + } - display_codepage = get_codepage_index (current_system_codepage); - if (display_codepage == -1) { - display_codepage = 0; - } + display_codepage = get_codepage_index (current_system_codepage); + if (display_codepage == -1) + { + display_codepage = 0; + } - mc_config_set_string(mc_main_config, "Misc", "display_codepage", cp_display); + mc_config_set_string (mc_main_config, "Misc", "display_codepage", cp_display); } #endif utf8_display = str_isutf8 (current_system_codepage); @@ -1497,7 +1554,7 @@ static void done_screen (void) { if (!(quit & SUBSHELL_EXIT)) - clr_scr (); + clr_scr (); tty_reset_shell_mode (); tty_noraw_mode (); tty_keypad (FALSE); @@ -1516,10 +1573,11 @@ done_mc (void) */ if (auto_save_setup) - save_setup (); /* does also call save_hotlist */ - else { - save_hotlist (); - save_panel_types (); + save_setup (); /* does also call save_hotlist */ + else + { + save_hotlist (); + save_panel_types (); } done_screen (); vfs_add_current_stamps (); @@ -1535,176 +1593,193 @@ done_mc_profile (void) } static cb_ret_t -midnight_callback (Dlg_head *h, Widget *sender, - dlg_msg_t msg, int parm, void *data) +midnight_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, void *data) { unsigned long command; - switch (msg) { + switch (msg) + { case DLG_INIT: - setup_panels (); - return MSG_HANDLED; + setup_panels (); + return MSG_HANDLED; case DLG_DRAW: - load_hint (1); - /* We handle the special case of the output lines */ - if (console_flag && output_lines) - show_console_contents (output_start_y, - LINES - output_lines - keybar_visible - - 1, LINES - keybar_visible - 1); - return MSG_HANDLED; + load_hint (1); + /* We handle the special case of the output lines */ + if (console_flag && output_lines) + show_console_contents (output_start_y, + LINES - output_lines - keybar_visible - + 1, LINES - keybar_visible - 1); + return MSG_HANDLED; case DLG_RESIZE: - setup_panels (); - menubar_arrange (the_menubar); - return MSG_HANDLED; + setup_panels (); + menubar_arrange (the_menubar); + return MSG_HANDLED; case DLG_IDLE: - /* We only need the first idle event to show user menu after start */ - set_idle_proc (h, 0); + /* We only need the first idle event to show user menu after start */ + set_idle_proc (h, 0); - if (boot_current_is_left) - dlg_select_widget (get_panel_widget (0)); - else - dlg_select_widget (get_panel_widget (1)); + if (boot_current_is_left) + dlg_select_widget (get_panel_widget (0)); + else + dlg_select_widget (get_panel_widget (1)); - if (auto_menu) - midnight_execute_cmd (NULL, CK_UserMenuCmd); - return MSG_HANDLED; + if (auto_menu) + midnight_execute_cmd (NULL, CK_UserMenuCmd); + return MSG_HANDLED; case DLG_KEY: - if (ctl_x_map_enabled) { - ctl_x_map_enabled = FALSE; - command = lookup_keymap_command (main_x_map, parm); - if (command != CK_Ignore_Key) - return midnight_execute_cmd (NULL, command); - } + if (ctl_x_map_enabled) + { + ctl_x_map_enabled = FALSE; + command = lookup_keymap_command (main_x_map, parm); + if (command != CK_Ignore_Key) + return midnight_execute_cmd (NULL, command); + } - /* FIXME: should handle all menu shortcuts before this point */ - if (the_menubar->is_active) - return MSG_NOT_HANDLED; + /* FIXME: should handle all menu shortcuts before this point */ + if (the_menubar->is_active) + return MSG_NOT_HANDLED; - if (parm == '\t') - free_completions (cmdline); + if (parm == '\t') + free_completions (cmdline); - if (parm == '\n') { - size_t i; + if (parm == '\n') + { + size_t i; - for (i = 0; cmdline->buffer[i] && (cmdline->buffer[i] == ' ' || - cmdline->buffer[i] == '\t'); i++) - ; - if (cmdline->buffer[i]) { - send_message ((Widget *) cmdline, WIDGET_KEY, parm); - return MSG_HANDLED; - } - stuff (cmdline, "", 0); - cmdline->point = 0; - } + for (i = 0; cmdline->buffer[i] && (cmdline->buffer[i] == ' ' || + cmdline->buffer[i] == '\t'); i++) + ; + if (cmdline->buffer[i]) + { + send_message ((Widget *) cmdline, WIDGET_KEY, parm); + return MSG_HANDLED; + } + stuff (cmdline, "", 0); + cmdline->point = 0; + } - /* Ctrl-Enter and Alt-Enter */ - if (((parm & ~(KEY_M_CTRL | KEY_M_ALT)) == '\n') - && (parm & (KEY_M_CTRL | KEY_M_ALT))) { - copy_prog_name (); - return MSG_HANDLED; - } + /* Ctrl-Enter and Alt-Enter */ + if (((parm & ~(KEY_M_CTRL | KEY_M_ALT)) == '\n') && (parm & (KEY_M_CTRL | KEY_M_ALT))) + { + copy_prog_name (); + return MSG_HANDLED; + } - /* Ctrl-Shift-Enter */ - if (parm == (KEY_M_CTRL | KEY_M_SHIFT | '\n')) { - copy_current_pathname (); - copy_prog_name (); - return MSG_HANDLED; - } + /* Ctrl-Shift-Enter */ + if (parm == (KEY_M_CTRL | KEY_M_SHIFT | '\n')) + { + copy_current_pathname (); + copy_prog_name (); + return MSG_HANDLED; + } - if ((!alternate_plus_minus || !(console_flag || xterm_flag)) - && !quote && !current_panel->searching) { - if (!only_leading_plus_minus) { - /* Special treatement, since the input line will eat them */ - if (parm == '+') { - select_cmd (); - return MSG_HANDLED; - } + if ((!alternate_plus_minus || !(console_flag || xterm_flag)) + && !quote && !current_panel->searching) + { + if (!only_leading_plus_minus) + { + /* Special treatement, since the input line will eat them */ + if (parm == '+') + { + select_cmd (); + return MSG_HANDLED; + } - if (parm == '\\' || parm == '-') { - unselect_cmd (); - return MSG_HANDLED; - } + if (parm == '\\' || parm == '-') + { + unselect_cmd (); + return MSG_HANDLED; + } - if (parm == '*') { - reverse_selection_cmd (); - return MSG_HANDLED; - } - } else if (!command_prompt || !cmdline->buffer[0]) { - /* Special treatement '+', '-', '\', '*' only when this is - * first char on input line - */ + if (parm == '*') + { + reverse_selection_cmd (); + return MSG_HANDLED; + } + } + else if (!command_prompt || !cmdline->buffer[0]) + { + /* Special treatement '+', '-', '\', '*' only when this is + * first char on input line + */ - if (parm == '+') { - select_cmd (); - return MSG_HANDLED; - } + if (parm == '+') + { + select_cmd (); + return MSG_HANDLED; + } - if (parm == '\\' || parm == '-') { - unselect_cmd (); - return MSG_HANDLED; - } + if (parm == '\\' || parm == '-') + { + unselect_cmd (); + return MSG_HANDLED; + } - if (parm == '*') { - reverse_selection_cmd (); - return MSG_HANDLED; - } - } - } - return MSG_NOT_HANDLED; + if (parm == '*') + { + reverse_selection_cmd (); + return MSG_HANDLED; + } + } + } + return MSG_NOT_HANDLED; case DLG_HOTKEY_HANDLED: - if ((get_current_type () == view_listing) && current_panel->searching) { - current_panel->searching = 0; - current_panel->dirty = 1; - } - return MSG_HANDLED; + if ((get_current_type () == view_listing) && current_panel->searching) + { + current_panel->searching = 0; + current_panel->dirty = 1; + } + return MSG_HANDLED; case DLG_UNHANDLED_KEY: - if (command_prompt) { - cb_ret_t v; + if (command_prompt) + { + cb_ret_t v; - v = send_message ((Widget *) cmdline, WIDGET_KEY, parm); - if (v == MSG_HANDLED) - return MSG_HANDLED; - } + v = send_message ((Widget *) cmdline, WIDGET_KEY, parm); + if (v == MSG_HANDLED) + return MSG_HANDLED; + } - if (ctl_x_map_enabled) { - ctl_x_map_enabled = FALSE; - command = lookup_keymap_command (main_x_map, parm); - } else - command = lookup_keymap_command (main_map, parm); + if (ctl_x_map_enabled) + { + ctl_x_map_enabled = FALSE; + command = lookup_keymap_command (main_x_map, parm); + } + else + command = lookup_keymap_command (main_map, parm); - return (command == CK_Ignore_Key) - ? MSG_NOT_HANDLED - : midnight_execute_cmd (NULL, command); + return (command == CK_Ignore_Key) ? MSG_NOT_HANDLED : midnight_execute_cmd (NULL, command); case DLG_POST_KEY: - if (!the_menubar->is_active) - update_dirty_panels (); - return MSG_HANDLED; + if (!the_menubar->is_active) + update_dirty_panels (); + return MSG_HANDLED; case DLG_ACTION: - /* shortcut */ - if (sender == NULL) - midnight_execute_cmd (NULL, parm); - /* message from menu */ - else if (sender == (Widget *) the_menubar) - midnight_execute_cmd (sender, parm); - /* message from buttonbar */ - else if (sender == (Widget *) the_bar) { - if (data == NULL) - midnight_execute_cmd (sender, parm); - else - send_message ((Widget *) data, WIDGET_COMMAND, parm); - } - return MSG_HANDLED; + /* shortcut */ + if (sender == NULL) + midnight_execute_cmd (NULL, parm); + /* message from menu */ + else if (sender == (Widget *) the_menubar) + midnight_execute_cmd (sender, parm); + /* message from buttonbar */ + else if (sender == (Widget *) the_bar) + { + if (data == NULL) + midnight_execute_cmd (sender, parm); + else + send_message ((Widget *) data, WIDGET_COMMAND, parm); + } + return MSG_HANDLED; default: - return default_dlg_callback (h, sender, msg, parm, data); + return default_dlg_callback (h, sender, msg, parm, data); } } @@ -1718,27 +1793,34 @@ update_xterm_title_path (void) struct passwd *pw = NULL; char *login = NULL; int res = 0; - if (xterm_flag && xterm_title) { - path = strip_home_and_password (current_panel->cwd); - res = gethostname(host, sizeof (host)); - if ( res ) { /* On success, res = 0 */ - host[0] = '\0'; - } else { - host[sizeof (host) - 1] = '\0'; - } - pw = getpwuid(getuid()); - if ( pw ) { - login = g_strdup_printf ("%s@%s", pw->pw_name, host); - } else { - login = g_strdup (host); - } - p = g_strdup_printf ("mc [%s]:%s", login, path); - fprintf (stdout, "\33]0;%s\7", str_term_form (p)); - g_free (login); - g_free (p); - if (!alternate_plus_minus) - numeric_keypad_mode (); - fflush (stdout); + if (xterm_flag && xterm_title) + { + path = strip_home_and_password (current_panel->cwd); + res = gethostname (host, sizeof (host)); + if (res) + { /* On success, res = 0 */ + host[0] = '\0'; + } + else + { + host[sizeof (host) - 1] = '\0'; + } + pw = getpwuid (getuid ()); + if (pw) + { + login = g_strdup_printf ("%s@%s", pw->pw_name, host); + } + else + { + login = g_strdup (host); + } + p = g_strdup_printf ("mc [%s]:%s", login, path); + fprintf (stdout, "\33]0;%s\7", str_term_form (p)); + g_free (login); + g_free (p); + if (!alternate_plus_minus) + numeric_keypad_mode (); + fflush (stdout); } } @@ -1752,25 +1834,28 @@ load_hint (int force) char *hint; if (!the_hint->widget.parent) - return; + return; - if (!message_visible) { - label_set_text (the_hint, NULL); - return; + if (!message_visible) + { + label_set_text (the_hint, NULL); + return; } hint = get_random_hint (force); - if (hint != NULL) { - if (*hint) - set_hintbar (hint); - g_free (hint); - } else { - char text[BUF_SMALL]; + if (hint != NULL) + { + if (*hint) + set_hintbar (hint); + g_free (hint); + } + else + { + char text[BUF_SMALL]; - g_snprintf (text, sizeof (text), _("GNU Midnight Commander %s\n"), - VERSION); - set_hintbar (text); + g_snprintf (text, sizeof (text), _("GNU Midnight Commander %s\n"), VERSION); + set_hintbar (text); } } @@ -1805,9 +1890,8 @@ prepend_cwd_on_local (const char *filename) char *d; size_t l; - if (!vfs_file_is_local (filename) - || g_path_is_absolute (filename)) - return g_strdup (filename); + if (!vfs_file_is_local (filename) || g_path_is_absolute (filename)) + return g_strdup (filename); d = g_malloc (MC_MAXPATHLEN + strlen (filename) + 2); mc_get_current_wd (d, MC_MAXPATHLEN); @@ -1824,27 +1908,28 @@ prepend_cwd_on_local (const char *filename) static void mc_maybe_editor_or_viewer (void) { - switch (mc_run_mode) { + switch (mc_run_mode) + { #ifdef USE_INTERNAL_EDIT case MC_RUN_EDITOR: - edit_file (mc_run_param0, edit_one_file_start_line); - break; -#endif /* USE_INTERNAL_EDIT */ + edit_file (mc_run_param0, edit_one_file_start_line); + break; +#endif /* USE_INTERNAL_EDIT */ case MC_RUN_VIEWER: - { - char *path; - path = prepend_cwd_on_local (mc_run_param0); - view_file (path, 0, 1); - g_free (path); - break; - } + { + char *path; + path = prepend_cwd_on_local (mc_run_param0); + view_file (path, 0, 1); + g_free (path); + break; + } #ifdef USE_DIFF_VIEW case MC_RUN_DIFFVIEWER: - diff_view (mc_run_param0, mc_run_param1, mc_run_param0, mc_run_param1); - break; -#endif /* USE_DIFF_VIEW */ + diff_view (mc_run_param0, mc_run_param1, mc_run_param0, mc_run_param1); + break; +#endif /* USE_DIFF_VIEW */ default: - break; + break; } midnight_shutdown = 1; done_mc (); @@ -1855,20 +1940,20 @@ static void do_nc (void) { int midnight_colors[DLG_COLOR_NUM]; - midnight_colors[0] = mc_skin_color_get("dialog", "_default_"); - midnight_colors[1] = mc_skin_color_get("dialog", "focus"); - midnight_colors[2] = mc_skin_color_get("dialog", "hotnormal"); - midnight_colors[3] = mc_skin_color_get("dialog", "hotfocus"); + midnight_colors[0] = mc_skin_color_get ("dialog", "_default_"); + midnight_colors[1] = mc_skin_color_get ("dialog", "focus"); + midnight_colors[2] = mc_skin_color_get ("dialog", "hotnormal"); + midnight_colors[3] = mc_skin_color_get ("dialog", "hotfocus"); panel_init (); midnight_dlg = create_dlg (0, 0, LINES, COLS, midnight_colors, midnight_callback, - "[main]", NULL, DLG_WANT_IDLE); + "[main]", NULL, DLG_WANT_IDLE); if (mc_run_mode == MC_RUN_FULL) - setup_mc (); + setup_mc (); else - setup_dummy_mc (); + setup_dummy_mc (); /* start check display_codepage and source_codepage */ check_codeset (); @@ -1905,18 +1990,19 @@ do_nc (void) /* Check if we were invoked as an editor or file viewer */ if (mc_run_mode != MC_RUN_FULL) - mc_maybe_editor_or_viewer (); - else { - create_panels_and_run_mc (); + mc_maybe_editor_or_viewer (); + else + { + create_panels_and_run_mc (); - /* Program end */ - midnight_shutdown = 1; + /* Program end */ + midnight_shutdown = 1; - /* destroy_dlg destroys even current_panel->cwd, so we have to save a copy :) */ - if (mc_args__last_wd_file && vfs_current_is_local ()) - last_wd_string = g_strdup (current_panel->cwd); + /* destroy_dlg destroys even current_panel->cwd, so we have to save a copy :) */ + if (mc_args__last_wd_file && vfs_current_is_local ()) + last_wd_string = g_strdup (current_panel->cwd); - done_mc (); + done_mc (); } destroy_dlg (midnight_dlg); @@ -1932,35 +2018,41 @@ OS_Setup (void) const char *shell_env = getenv ("SHELL"); const char *mc_libdir; - if ((shell_env == NULL) || (shell_env[0] == '\0')) { + if ((shell_env == NULL) || (shell_env[0] == '\0')) + { struct passwd *pwd; pwd = getpwuid (geteuid ()); if (pwd != NULL) - shell = g_strdup (pwd->pw_shell); - } else - shell = g_strdup (shell_env); + shell = g_strdup (pwd->pw_shell); + } + else + shell = g_strdup (shell_env); - if ((shell == NULL) || (shell[0] == '\0')) { - g_free (shell); - shell = g_strdup ("/bin/sh"); + if ((shell == NULL) || (shell[0] == '\0')) + { + g_free (shell); + shell = g_strdup ("/bin/sh"); } /* This is the directory, where MC was installed, on Unix this is DATADIR */ /* and can be overriden by the MC_DATADIR environment variable */ mc_libdir = getenv ("MC_DATADIR"); - if (mc_libdir != NULL) { - mc_home = g_strdup (mc_libdir); - mc_home_alt = g_strdup (SYSCONFDIR); - } else { - mc_home = g_strdup (SYSCONFDIR); - mc_home_alt = g_strdup (DATADIR); + if (mc_libdir != NULL) + { + mc_home = g_strdup (mc_libdir); + mc_home_alt = g_strdup (SYSCONFDIR); + } + else + { + mc_home = g_strdup (SYSCONFDIR); + mc_home_alt = g_strdup (DATADIR); } /* This variable is used by the subshell */ home_dir = getenv ("HOME"); if (!home_dir) - home_dir = mc_home; + home_dir = mc_home; } static void @@ -1970,7 +2062,7 @@ sigchld_handler_no_subshell (int sig) int pid, status; if (!console_flag) - return; + return; /* COMMENT: if it were true that after the call to handle_console(..INIT) the value of console_flag never changed, we could simply not install @@ -1981,19 +2073,23 @@ sigchld_handler_no_subshell (int sig) pid = waitpid (cons_saver_pid, &status, WUNTRACED | WNOHANG); - if (pid == cons_saver_pid) { + if (pid == cons_saver_pid) + { - if (WIFSTOPPED (status)) { - /* Someone has stopped cons.saver - restart it */ - kill (pid, SIGCONT); - } else { - /* cons.saver has died - disable console saving */ - handle_console (CONSOLE_DONE); - console_flag = 0; - } + if (WIFSTOPPED (status)) + { + /* Someone has stopped cons.saver - restart it */ + kill (pid, SIGCONT); + } + else + { + /* cons.saver has died - disable console saving */ + handle_console (CONSOLE_DONE); + console_flag = 0; + } } /* If we got here, some other child exited; ignore it */ -#endif /* __linux__ */ +#endif /* __linux__ */ (void) sig; } @@ -2005,9 +2101,9 @@ init_sigchld (void) sigchld_action.sa_handler = #ifdef HAVE_SUBSHELL_SUPPORT - use_subshell ? sigchld_handler : -#endif /* HAVE_SUBSHELL_SUPPORT */ - sigchld_handler_no_subshell; + use_subshell ? sigchld_handler : +#endif /* HAVE_SUBSHELL_SUPPORT */ + sigchld_handler_no_subshell; sigemptyset (&sigchld_action.sa_mask); @@ -2015,16 +2111,17 @@ init_sigchld (void) sigchld_action.sa_flags = SA_RESTART; #else sigchld_action.sa_flags = 0; -#endif /* !SA_RESTART */ +#endif /* !SA_RESTART */ - if (sigaction (SIGCHLD, &sigchld_action, NULL) == -1) { + if (sigaction (SIGCHLD, &sigchld_action, NULL) == -1) + { #ifdef HAVE_SUBSHELL_SUPPORT - /* - * This may happen on QNX Neutrino 6, where SA_RESTART - * is defined but not implemented. Fallback to no subshell. - */ - use_subshell = 0; -#endif /* HAVE_SUBSHELL_SUPPORT */ + /* + * This may happen on QNX Neutrino 6, where SA_RESTART + * is defined but not implemented. Fallback to no subshell. + */ + use_subshell = 0; +#endif /* HAVE_SUBSHELL_SUPPORT */ } } @@ -2035,99 +2132,122 @@ mc_main__setup_by_args (int argc, char *argv[]) char *tmp; if (mc_args__nomouse) - use_mouse_p = MOUSE_DISABLED; + use_mouse_p = MOUSE_DISABLED; #ifdef USE_NETCODE - if (mc_args__netfs_logfile != NULL) { - mc_setctl ("/#ftp:", VFS_SETCTL_LOGFILE, (void *) mc_args__netfs_logfile); + if (mc_args__netfs_logfile != NULL) + { + mc_setctl ("/#ftp:", VFS_SETCTL_LOGFILE, (void *) mc_args__netfs_logfile); #ifdef ENABLE_VFS_SMB - smbfs_set_debugf (mc_args__netfs_logfile); -#endif /* ENABLE_VFS_SMB */ + smbfs_set_debugf (mc_args__netfs_logfile); +#endif /* ENABLE_VFS_SMB */ } #ifdef ENABLE_VFS_SMB if (mc_args__debug_level != 0) - smbfs_set_debug (mc_args__debug_level); -#endif /* ENABLE_VFS_SMB */ -#endif /* USE_NETCODE */ + smbfs_set_debug (mc_args__debug_level); +#endif /* ENABLE_VFS_SMB */ +#endif /* USE_NETCODE */ base = x_basename (argv[0]); tmp = (argc > 0) ? argv[1] : NULL; - if (!STRNCOMP (base, "mce", 3) || !STRCOMP (base, "vi")) { - mc_run_param0 = g_strdup (""); - if (tmp != NULL) { - /* - * Check for filename:lineno, followed by an optional colon. - * This format is used by many programs (especially compilers) - * in error messages and warnings. It is supported so that - * users can quickly copy and paste file locations. - */ - char *end = tmp + strlen (tmp), *p = end; - if (p > tmp && p[-1] == ':') - p--; - while (p > tmp && g_ascii_isdigit ((gchar) p[-1])) - p--; - if (tmp < p && p < end && p[-1] == ':') { - struct stat st; - gchar *fname = g_strndup (tmp, p - 1 - tmp); - /* - * Check that the file before the colon actually exists. - * If it doesn't exist, revert to the old behavior. - */ - if (mc_stat (tmp, &st) == -1 && mc_stat (fname, &st) != -1) { - mc_run_param0 = fname; - edit_one_file_start_line = atoi (p); - } else { - g_free (fname); - goto try_plus_filename; - } - } else { - try_plus_filename: - if (*tmp == '+' && g_ascii_isdigit ((gchar) tmp[1])) { - int start_line = atoi (tmp); - if (start_line > 0) { - char *file = (argc > 1) ? argv[2] : NULL; - if (file) { - tmp = file; - edit_one_file_start_line = start_line; - } - } - } - mc_run_param0 = g_strdup (tmp); - } - } - mc_run_mode = MC_RUN_EDITOR; - } else if (!STRNCOMP (base, "mcv", 3) || !STRCOMP (base, "view")) { - if (tmp != NULL) - mc_run_param0 = g_strdup (tmp); - else { - fputs ("No arguments given to the viewer\n", stderr); - exit (1); - } - mc_run_mode = MC_RUN_VIEWER; + if (!STRNCOMP (base, "mce", 3) || !STRCOMP (base, "vi")) + { + mc_run_param0 = g_strdup (""); + if (tmp != NULL) + { + /* + * Check for filename:lineno, followed by an optional colon. + * This format is used by many programs (especially compilers) + * in error messages and warnings. It is supported so that + * users can quickly copy and paste file locations. + */ + char *end = tmp + strlen (tmp), *p = end; + if (p > tmp && p[-1] == ':') + p--; + while (p > tmp && g_ascii_isdigit ((gchar) p[-1])) + p--; + if (tmp < p && p < end && p[-1] == ':') + { + struct stat st; + gchar *fname = g_strndup (tmp, p - 1 - tmp); + /* + * Check that the file before the colon actually exists. + * If it doesn't exist, revert to the old behavior. + */ + if (mc_stat (tmp, &st) == -1 && mc_stat (fname, &st) != -1) + { + mc_run_param0 = fname; + edit_one_file_start_line = atoi (p); + } + else + { + g_free (fname); + goto try_plus_filename; + } + } + else + { + try_plus_filename: + if (*tmp == '+' && g_ascii_isdigit ((gchar) tmp[1])) + { + int start_line = atoi (tmp); + if (start_line > 0) + { + char *file = (argc > 1) ? argv[2] : NULL; + if (file) + { + tmp = file; + edit_one_file_start_line = start_line; + } + } + } + mc_run_param0 = g_strdup (tmp); + } + } + mc_run_mode = MC_RUN_EDITOR; + } + else if (!STRNCOMP (base, "mcv", 3) || !STRCOMP (base, "view")) + { + if (tmp != NULL) + mc_run_param0 = g_strdup (tmp); + else + { + fputs ("No arguments given to the viewer\n", stderr); + exit (1); + } + mc_run_mode = MC_RUN_VIEWER; #ifdef USE_DIFF_VIEW - } else if (!STRNCOMP (base, "mcd", 3) || !STRCOMP (base, "diff")) { - if (argc < 3) { - fputs ("There 2 files are required to diffviewer\n", stderr); - exit (1); - } else if (tmp != NULL) { - mc_run_param0 = g_strdup (tmp); - tmp = (argc > 1) ? argv[2] : NULL; - if (tmp != NULL) - mc_run_param1 = g_strdup (tmp); - mc_run_mode = MC_RUN_DIFFVIEWER; - } -#endif /* USE_DIFF_VIEW */ - } else { - /* sets the current dir and the other dir */ - if (tmp != NULL) { - mc_run_param0 = g_strdup (tmp); - tmp = (argc > 1) ? argv[2] : NULL; - if (tmp != NULL) - mc_run_param1 = g_strdup (tmp); - } - mc_run_mode = MC_RUN_FULL; + } + else if (!STRNCOMP (base, "mcd", 3) || !STRCOMP (base, "diff")) + { + if (argc < 3) + { + fputs ("There 2 files are required to diffviewer\n", stderr); + exit (1); + } + else if (tmp != NULL) + { + mc_run_param0 = g_strdup (tmp); + tmp = (argc > 1) ? argv[2] : NULL; + if (tmp != NULL) + mc_run_param1 = g_strdup (tmp); + mc_run_mode = MC_RUN_DIFFVIEWER; + } +#endif /* USE_DIFF_VIEW */ + } + else + { + /* sets the current dir and the other dir */ + if (tmp != NULL) + { + mc_run_param0 = g_strdup (tmp); + tmp = (argc > 1) ? argv[2] : NULL; + if (tmp != NULL) + mc_run_param1 = g_strdup (tmp); + } + mc_run_mode = MC_RUN_FULL; } } @@ -2161,10 +2281,10 @@ main (int argc, char *argv[]) SLtt_Ignore_Beep = 1; #endif - if ( !mc_args_handle (&argc, &argv, "mc")) - return 1; + if (!mc_args_handle (&argc, &argv, "mc")) + return 1; - mc_main__setup_by_args (argc,argv); + mc_main__setup_by_args (argc, argv); /* NOTE: This has to be called before tty_init or whatever routine calls any define_sequence */ @@ -2176,11 +2296,11 @@ main (int argc, char *argv[]) #ifdef HAVE_SUBSHELL_SUPPORT /* Don't use subshell when invoked as viewer or editor */ if (mc_run_mode != MC_RUN_FULL) - use_subshell = 0; + use_subshell = 0; if (use_subshell) - subshell_get_console_attributes (); -#endif /* HAVE_SUBSHELL_SUPPORT */ + subshell_get_console_attributes (); +#endif /* HAVE_SUBSHELL_SUPPORT */ /* Install the SIGCHLD handler; must be done before init_subshell() */ init_sigchld (); @@ -2196,15 +2316,16 @@ main (int argc, char *argv[]) tty_init_colors (mc_args__disable_colors, mc_args__force_colors); - isInitialized = mc_skin_init(&error); + isInitialized = mc_skin_init (&error); mc_filehighlight = mc_fhl_new (TRUE); dlg_set_default_colors (); - if ( ! isInitialized ) { + if (!isInitialized) + { message (D_ERROR, _("Warning"), "%s", error->message); - g_error_free(error); + g_error_free (error); error = NULL; } @@ -2212,19 +2333,17 @@ main (int argc, char *argv[]) /* do it after the screen library initialization to show the error message */ mc_dir = concat_dir_and_file (home_dir, MC_USERCONF_DIR); canonicalize_pathname (mc_dir); - if ((stat (mc_dir, &s) != 0) && (errno == ENOENT) - && mkdir (mc_dir, 0700) != 0) - message (D_ERROR, _("Warning"), - _("Cannot create %s directory"), mc_dir); + if ((stat (mc_dir, &s) != 0) && (errno == ENOENT) && mkdir (mc_dir, 0700) != 0) + message (D_ERROR, _("Warning"), _("Cannot create %s directory"), mc_dir); g_free (mc_dir); #ifdef HAVE_SUBSHELL_SUPPORT /* Done here to ensure that the subshell doesn't */ /* inherit the file descriptors opened below, etc */ if (use_subshell) - init_subshell (); + init_subshell (); -#endif /* HAVE_SUBSHELL_SUPPORT */ +#endif /* HAVE_SUBSHELL_SUPPORT */ /* Removing this from the X code let's us type C-c */ load_key_defs (); @@ -2233,23 +2352,25 @@ main (int argc, char *argv[]) /* Also done after init_subshell, to save any shell init file messages */ if (console_flag) - handle_console (CONSOLE_SAVE); + handle_console (CONSOLE_SAVE); if (alternate_plus_minus) - application_keypad_mode (); + application_keypad_mode (); #ifdef HAVE_SUBSHELL_SUPPORT - if (use_subshell) { - mc_prompt = strip_ctrl_codes (subshell_prompt); - if (mc_prompt == NULL) - mc_prompt = (geteuid () == 0) ? "# " : "$ "; - } else -#endif /* HAVE_SUBSHELL_SUPPORT */ - mc_prompt = (geteuid () == 0) ? "# " : "$ "; + if (use_subshell) + { + mc_prompt = strip_ctrl_codes (subshell_prompt); + if (mc_prompt == NULL) + mc_prompt = (geteuid () == 0) ? "# " : "$ "; + } + else +#endif /* HAVE_SUBSHELL_SUPPORT */ + mc_prompt = (geteuid () == 0) ? "# " : "$ "; /* Program main loop */ if (!midnight_shutdown) - do_nc (); + do_nc (); /* Save the tree store */ tree_store_save (); @@ -2259,7 +2380,7 @@ main (int argc, char *argv[]) /* Virtual File System shutdown */ vfs_shut (); - flush_extension_file (); /* does only free memory */ + flush_extension_file (); /* does only free memory */ mc_fhl_free (&mc_filehighlight); mc_skin_deinit (); @@ -2267,26 +2388,28 @@ main (int argc, char *argv[]) tty_shutdown (); if (console_flag && !(quit & SUBSHELL_EXIT)) - handle_console (CONSOLE_RESTORE); + handle_console (CONSOLE_RESTORE); if (alternate_plus_minus) - numeric_keypad_mode (); + numeric_keypad_mode (); - signal (SIGCHLD, SIG_DFL); /* Disable the SIGCHLD handler */ + signal (SIGCHLD, SIG_DFL); /* Disable the SIGCHLD handler */ if (console_flag) - handle_console (CONSOLE_DONE); - putchar ('\n'); /* Hack to make shell's prompt start at left of screen */ + handle_console (CONSOLE_DONE); + putchar ('\n'); /* Hack to make shell's prompt start at left of screen */ - if (mc_run_mode == MC_RUN_FULL && mc_args__last_wd_file && last_wd_string - && !print_last_revert) { - int last_wd_fd = - open (mc_args__last_wd_file, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, - S_IRUSR | S_IWUSR); + if (mc_run_mode == MC_RUN_FULL && mc_args__last_wd_file && last_wd_string && !print_last_revert) + { + int last_wd_fd = open (mc_args__last_wd_file, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, + S_IRUSR | S_IWUSR); - if (last_wd_fd != -1) { - write (last_wd_fd, last_wd_string, strlen (last_wd_string)); - close (last_wd_fd); - } + if (last_wd_fd != -1) + { + ssize_t ret1; + int ret2; + ret1 = write (last_wd_fd, last_wd_string, strlen (last_wd_string)); + ret2 = close (last_wd_fd); + } } g_free (last_wd_string); diff --git a/src/panelize.c b/src/panelize.c index 1c6620f1b..c24bef3ca 100644 --- a/src/panelize.c +++ b/src/panelize.c @@ -480,8 +480,9 @@ do_external_panelize (char *command) current_panel->count = next_free; if (list->list[0].fname[0] == PATH_SEP) { + int ret; strcpy (current_panel->cwd, PATH_SEP_STR); - chdir (PATH_SEP_STR); + ret = chdir (PATH_SEP_STR); } } else diff --git a/src/screen.c b/src/screen.c index 06ee01281..6c52f8eda 100644 --- a/src/screen.c +++ b/src/screen.c @@ -1404,7 +1404,10 @@ panel_new_with_dir (const char *panel_name, const char *wpath) /* Because do_load_dir lists files in current directory */ if (wpath) - mc_chdir (wpath); + { + int ret; + ret = mc_chdir (wpath); + } /* Load the default format */ panel->count = @@ -1413,7 +1416,10 @@ panel_new_with_dir (const char *panel_name, const char *wpath) /* Restore old right path */ if (wpath) - mc_chdir (curdir); + { + int ret; + ret = mc_chdir (curdir); + } return panel; } @@ -3467,7 +3473,10 @@ reload_panelized (WPanel * panel) dir_list *list = &panel->dir; if (panel != current_panel) - mc_chdir (panel->cwd); + { + int ret; + ret = mc_chdir (panel->cwd); + } for (i = 0, j = 0; i < panel->count; i++) { @@ -3498,7 +3507,10 @@ reload_panelized (WPanel * panel) panel->count = j; if (panel != current_panel) - mc_chdir (current_panel->cwd); + { + int ret; + ret = mc_chdir (current_panel->cwd); + } } static void @@ -3560,6 +3572,7 @@ update_panels (int force_update, const char *current_file) { int reload_other = !(force_update & UP_ONLY_CURRENT); WPanel *panel; + int ret; update_one_panel (get_current_index (), force_update, current_file); if (reload_other) @@ -3570,7 +3583,7 @@ update_panels (int force_update, const char *current_file) else panel = (WPanel *) get_panel_widget (get_other_index ()); - mc_chdir (panel->cwd); + ret = mc_chdir (panel->cwd); } gsize diff --git a/src/subshell.c b/src/subshell.c index 1b4ff8ce1..167f21a03 100644 --- a/src/subshell.c +++ b/src/subshell.c @@ -44,20 +44,20 @@ #include #ifdef HAVE_STROPTS_H -# include /* For I_PUSH */ +# include /* For I_PUSH */ #endif /* HAVE_STROPTS_H */ #include "lib/global.h" -#include "lib/tty/tty.h" /* LINES */ -#include "lib/tty/key.h" /* XCTRL */ +#include "lib/tty/tty.h" /* LINES */ +#include "lib/tty/key.h" /* XCTRL */ #include "lib/vfs/mc-vfs/vfs.h" #include "lib/strutil.h" #include "lib/fileloc.h" -#include "panel.h" /* current_panel */ -#include "wtools.h" /* query_dialog() */ -#include "main.h" /* do_update_prompt() */ -#include "consaver/cons.saver.h" /* handle_console() */ +#include "panel.h" /* current_panel */ +#include "wtools.h" /* query_dialog() */ +#include "main.h" /* do_update_prompt() */ +#include "consaver/cons.saver.h" /* handle_console() */ #include "subshell.h" #ifndef WEXITSTATUS @@ -94,9 +94,9 @@ static int resize_tty (int fd); /* If using a subshell for evaluating commands this is true */ int use_subshell = #ifdef SUBSHELL_OPTIONAL -FALSE; + FALSE; #else -TRUE; + TRUE; #endif /* File descriptors of the pseudoterminal used by the subshell */ @@ -104,83 +104,104 @@ int subshell_pty = 0; static int subshell_pty_slave = -1; /* The key for switching back to MC from the subshell */ -static const char subshell_switch_key = XCTRL('o') & 255; +static const char subshell_switch_key = XCTRL ('o') & 255; /* State of the subshell: * INACTIVE: the default state; awaiting a command * ACTIVE: remain in the shell until the user hits `subshell_switch_key' * RUNNING_COMMAND: return to MC when the current command finishes */ -enum subshell_state_enum subshell_state; + enum subshell_state_enum + subshell_state; /* Holds the latest prompt captured from the subshell */ -char *subshell_prompt = NULL; + char * + subshell_prompt = NULL; /* Initial length of the buffer for the subshell's prompt */ #define INITIAL_PROMPT_SIZE 10 /* Used by the child process to indicate failure to start the subshell */ -#define FORK_FAILURE 69 /* Arbitrary */ +#define FORK_FAILURE 69 /* Arbitrary */ /* Length of the buffer for all I/O with the subshell */ -#define PTY_BUFFER_SIZE BUF_SMALL /* Arbitrary; but keep it >= 80 */ +#define PTY_BUFFER_SIZE BUF_SMALL /* Arbitrary; but keep it >= 80 */ /* For pipes */ -enum {READ=0, WRITE=1}; + enum + { + READ = 0, WRITE = 1 }; -static char pty_buffer[PTY_BUFFER_SIZE] = "\0"; /* For reading/writing on the subshell's pty */ -static int subshell_pipe[2]; /* To pass CWD info from the subshell to MC */ -static pid_t subshell_pid = 1; /* The subshell's process ID */ -static char subshell_cwd[MC_MAXPATHLEN+1]; /* One extra char for final '\n' */ + static char + pty_buffer[PTY_BUFFER_SIZE] = "\0"; /* For reading/writing on the subshell's pty */ + static int + subshell_pipe[2]; /* To pass CWD info from the subshell to MC */ + static pid_t + subshell_pid = 1; /* The subshell's process ID */ + static char + subshell_cwd[MC_MAXPATHLEN + 1]; /* One extra char for final '\n' */ /* Subshell type (gleaned from the SHELL environment variable, if available) */ -static enum { - BASH, - TCSH, - ZSH, - FISH -} subshell_type; + static enum + { + BASH, + TCSH, + ZSH, + FISH + } subshell_type; /* Flag to indicate whether the subshell is ready for next command */ -static int subshell_ready; + static int + subshell_ready; /* The following two flags can be changed by the SIGCHLD handler. This is */ /* OK, because the `int' type is updated atomically on all known machines */ -static volatile int subshell_alive, subshell_stopped; + static volatile int + subshell_alive, + subshell_stopped; /* We store the terminal's initial mode here so that we can configure the pty similarly, and also so we can restore the real terminal to sanity if we have to exit abruptly */ -static struct termios shell_mode; + static struct termios + shell_mode; /* This is a transparent mode for the terminal where MC is running on */ /* It is used when the shell is active, so that the control signals */ /* are delivered to the shell pty */ -static struct termios raw_mode; + static struct termios + raw_mode; /* This counter indicates how many characters of prompt we have read */ /* FIXME: try to figure out why this had to become global */ -static int prompt_pos; + static int + prompt_pos; /* * Write all data, even if the write() call is interrupted. */ -static ssize_t -write_all (int fd, const void *buf, size_t count) + static + ssize_t + write_all (int fd, const void *buf, size_t count) { ssize_t ret; ssize_t written = 0; - while (count > 0) { - ret = write (fd, (const unsigned char *) buf + written, count); - if (ret < 0) { - if (errno == EINTR) { - continue; - } else { - return written > 0 ? written : ret; - } - } - count -= ret; - written += ret; + while (count > 0) + { + ret = write (fd, (const unsigned char *) buf + written, count); + if (ret < 0) + { + if (errno == EINTR) + { + continue; + } + else + { + return written > 0 ? written : ret; + } + } + count -= ret; + written += ret; } return written; } @@ -189,7 +210,7 @@ write_all (int fd, const void *buf, size_t count) * Prepare child process to running the shell and run it. * * Modifies the global variables (in the child process only): - * shell_mode + * shell_mode * * Returns: never. */ @@ -200,7 +221,7 @@ init_subshell_child (const char *pty_name) pid_t mc_sid; (void) pty_name; - setsid (); /* Get a fresh terminal session */ + setsid (); /* Get a fresh terminal session */ /* Make sure that it has become our controlling terminal */ @@ -213,10 +234,10 @@ init_subshell_child (const char *pty_name) /* Configure its terminal modes and window size */ /* Set up the pty with the same termios flags as our own tty */ - if (tcsetattr (subshell_pty_slave, TCSANOW, &shell_mode)) { - fprintf (stderr, "Cannot set pty terminal modes: %s\r\n", - unix_error_string (errno)); - _exit (FORK_FAILURE); + if (tcsetattr (subshell_pty_slave, TCSANOW, &shell_mode)) + { + fprintf (stderr, "Cannot set pty terminal modes: %s\r\n", unix_error_string (errno)); + _exit (FORK_FAILURE); } /* Set the pty's size (80x25 by default on Linux) according to the */ @@ -227,42 +248,45 @@ init_subshell_child (const char *pty_name) /* It simplifies things to change to our home directory here, */ /* and the user's startup file may do a `cd' command anyway */ - chdir (home_dir); /* FIXME? What about when we re-run the subshell? */ + { + int ret; + ret = chdir (home_dir); /* FIXME? What about when we re-run the subshell? */ + } /* Set MC_SID to prevent running one mc from another */ mc_sid = getsid (0); - if (mc_sid != -1) { - char sid_str[BUF_SMALL]; - g_snprintf (sid_str, sizeof (sid_str), "MC_SID=%ld", - (long) mc_sid); - putenv (g_strdup (sid_str)); + if (mc_sid != -1) + { + char sid_str[BUF_SMALL]; + g_snprintf (sid_str, sizeof (sid_str), "MC_SID=%ld", (long) mc_sid); + putenv (g_strdup (sid_str)); } - switch (subshell_type) { + switch (subshell_type) + { case BASH: - init_file = MC_USERCONF_DIR PATH_SEP_STR "bashrc"; - if (access (init_file, R_OK) == -1) - init_file = ".bashrc"; + init_file = MC_USERCONF_DIR PATH_SEP_STR "bashrc"; + if (access (init_file, R_OK) == -1) + init_file = ".bashrc"; - /* Make MC's special commands not show up in bash's history */ - putenv ((char*)"HISTCONTROL=ignorespace"); + /* Make MC's special commands not show up in bash's history */ + putenv ((char *) "HISTCONTROL=ignorespace"); - /* Allow alternative readline settings for MC */ - if (access (MC_USERCONF_DIR PATH_SEP_STR "inputrc", R_OK) == 0) - putenv ((char*)"INPUTRC=" MC_USERCONF_DIR PATH_SEP_STR "/inputrc"); + /* Allow alternative readline settings for MC */ + if (access (MC_USERCONF_DIR PATH_SEP_STR "inputrc", R_OK) == 0) + putenv ((char *) "INPUTRC=" MC_USERCONF_DIR PATH_SEP_STR "/inputrc"); - break; + break; - /* TODO: Find a way to pass initfile to TCSH and ZSH */ + /* TODO: Find a way to pass initfile to TCSH and ZSH */ case TCSH: case ZSH: case FISH: - break; + break; default: - fprintf (stderr, __FILE__ ": unimplemented subshell type %d\r\n", - subshell_type); - _exit (FORK_FAILURE); + fprintf (stderr, __FILE__ ": unimplemented subshell type %d\r\n", subshell_type); + _exit (FORK_FAILURE); } /* Attach all our standard file descriptors to the pty */ @@ -276,7 +300,7 @@ init_subshell_child (const char *pty_name) dup2 (subshell_pty_slave, STDERR_FILENO); close (subshell_pipe[READ]); - close (subshell_pty_slave); /* These may be FD_CLOEXEC, but just in case... */ + close (subshell_pty_slave); /* These may be FD_CLOEXEC, but just in case... */ /* Close master side of pty. This is important; apart from */ /* freeing up the descriptor for use in the subshell, it also */ /* means that when MC exits, the subshell will get a SIGHUP and */ @@ -286,24 +310,25 @@ init_subshell_child (const char *pty_name) /* Execute the subshell at last */ - switch (subshell_type) { + switch (subshell_type) + { case BASH: - execl (shell, "bash", "-rcfile", init_file, (char *) NULL); - break; + execl (shell, "bash", "-rcfile", init_file, (char *) NULL); + break; case TCSH: - execl (shell, "tcsh", (char *) NULL); - break; + execl (shell, "tcsh", (char *) NULL); + break; case ZSH: - /* Use -g to exclude cmds beginning with space from history - * and -Z to use the line editor on non-interactive term */ - execl (shell, "zsh", "-Z", "-g", (char *) NULL); + /* Use -g to exclude cmds beginning with space from history + * and -Z to use the line editor on non-interactive term */ + execl (shell, "zsh", "-Z", "-g", (char *) NULL); - break; + break; case FISH: - execl (shell, "fish", (char *) NULL); + execl (shell, "fish", (char *) NULL); break; } @@ -328,27 +353,27 @@ check_sid (void) sid_str = getenv ("MC_SID"); if (!sid_str) - return 0; + return 0; old_sid = (pid_t) strtol (sid_str, NULL, 0); if (!old_sid) - return 0; + return 0; my_sid = getsid (0); if (my_sid == -1) - return 0; + return 0; /* The parent mc is in a different session, it's OK */ if (old_sid != my_sid) - return 0; + return 0; r = query_dialog (_("Warning"), - _("GNU Midnight Commander is already\n" - "running on this terminal.\n" - "Subshell support will be disabled."), D_ERROR, 2, - _("&OK"), _("&Quit")); - if (r != 0) { - return 2; + _("GNU Midnight Commander is already\n" + "running on this terminal.\n" + "Subshell support will be disabled."), D_ERROR, 2, _("&OK"), _("&Quit")); + if (r != 0) + { + return 2; } return 1; @@ -359,9 +384,9 @@ check_sid (void) * Fork the subshell, and set up many, many things. * * Possibly modifies the global variables: - * subshell_type, subshell_alive, subshell_stopped, subshell_pid - * use_subshell - Is set to FALSE if we can't run the subshell - * quit - Can be set to SUBSHELL_EXIT by the SIGCHLD handler + * subshell_type, subshell_alive, subshell_stopped, subshell_pid + * use_subshell - Is set to FALSE if we can't run the subshell + * quit - Can be set to SUBSHELL_EXIT by the SIGCHLD handler */ void @@ -371,84 +396,91 @@ init_subshell (void) static char pty_name[BUF_SMALL]; char precmd[BUF_SMALL]; - switch (check_sid ()) { + switch (check_sid ()) + { case 1: - use_subshell = FALSE; - return; + use_subshell = FALSE; + return; case 2: - use_subshell = FALSE; - midnight_shutdown = 1; - return; + use_subshell = FALSE; + midnight_shutdown = 1; + return; } /* Take the current (hopefully pristine) tty mode and make */ /* a raw mode based on it now, before we do anything else with it */ init_raw_mode (); - if (subshell_pty == 0) { /* First time through */ - /* Find out what type of shell we have */ + if (subshell_pty == 0) + { /* First time through */ + /* Find out what type of shell we have */ - if (strstr (shell, "/zsh") || getenv ("ZSH_VERSION")) - subshell_type = ZSH; - else if (strstr (shell, "/tcsh")) - subshell_type = TCSH; - else if (strstr (shell, "/csh")) - subshell_type = TCSH; - else if (strstr (shell, "/bash") || getenv ("BASH")) - subshell_type = BASH; - else if (strstr (shell, "/fish")) - subshell_type = FISH; - else { - use_subshell = FALSE; - return; - } + if (strstr (shell, "/zsh") || getenv ("ZSH_VERSION")) + subshell_type = ZSH; + else if (strstr (shell, "/tcsh")) + subshell_type = TCSH; + else if (strstr (shell, "/csh")) + subshell_type = TCSH; + else if (strstr (shell, "/bash") || getenv ("BASH")) + subshell_type = BASH; + else if (strstr (shell, "/fish")) + subshell_type = FISH; + else + { + use_subshell = FALSE; + return; + } - /* Open a pty for talking to the subshell */ + /* Open a pty for talking to the subshell */ - /* FIXME: We may need to open a fresh pty each time on SVR4 */ + /* FIXME: We may need to open a fresh pty each time on SVR4 */ - subshell_pty = pty_open_master (pty_name); - if (subshell_pty == -1) { - fprintf (stderr, "Cannot open master side of pty: %s\r\n", - unix_error_string (errno)); - use_subshell = FALSE; - return; - } - subshell_pty_slave = pty_open_slave (pty_name); - if (subshell_pty_slave == -1) { - fprintf (stderr, "Cannot open slave side of pty %s: %s\r\n", - pty_name, unix_error_string (errno)); - use_subshell = FALSE; - return; - } + subshell_pty = pty_open_master (pty_name); + if (subshell_pty == -1) + { + fprintf (stderr, "Cannot open master side of pty: %s\r\n", unix_error_string (errno)); + use_subshell = FALSE; + return; + } + subshell_pty_slave = pty_open_slave (pty_name); + if (subshell_pty_slave == -1) + { + fprintf (stderr, "Cannot open slave side of pty %s: %s\r\n", + pty_name, unix_error_string (errno)); + use_subshell = FALSE; + return; + } - /* Create a pipe for receiving the subshell's CWD */ + /* Create a pipe for receiving the subshell's CWD */ - if (subshell_type == TCSH) { - g_snprintf (tcsh_fifo, sizeof (tcsh_fifo), "%s/mc.pipe.%d", - mc_tmpdir (), (int) getpid ()); - if (mkfifo (tcsh_fifo, 0600) == -1) { - fprintf (stderr, "mkfifo(%s) failed: %s\r\n", tcsh_fifo, - unix_error_string (errno)); - use_subshell = FALSE; - return; - } + if (subshell_type == TCSH) + { + g_snprintf (tcsh_fifo, sizeof (tcsh_fifo), "%s/mc.pipe.%d", + mc_tmpdir (), (int) getpid ()); + if (mkfifo (tcsh_fifo, 0600) == -1) + { + fprintf (stderr, "mkfifo(%s) failed: %s\r\n", tcsh_fifo, unix_error_string (errno)); + use_subshell = FALSE; + return; + } - /* Opening the FIFO as O_RDONLY or O_WRONLY causes deadlock */ + /* Opening the FIFO as O_RDONLY or O_WRONLY causes deadlock */ - if ((subshell_pipe[READ] = open (tcsh_fifo, O_RDWR)) == -1 - || (subshell_pipe[WRITE] = - open (tcsh_fifo, O_RDWR)) == -1) { - fprintf (stderr, _("Cannot open named pipe %s\n"), tcsh_fifo); - perror (__FILE__": open"); - use_subshell = FALSE; - return; - } - } else /* subshell_type is BASH or ZSH */ if (pipe (subshell_pipe)) { - perror (__FILE__": couldn't create pipe"); - use_subshell = FALSE; - return; - } + if ((subshell_pipe[READ] = open (tcsh_fifo, O_RDWR)) == -1 + || (subshell_pipe[WRITE] = open (tcsh_fifo, O_RDWR)) == -1) + { + fprintf (stderr, _("Cannot open named pipe %s\n"), tcsh_fifo); + perror (__FILE__ ": open"); + use_subshell = FALSE; + return; + } + } + else /* subshell_type is BASH or ZSH */ if (pipe (subshell_pipe)) + { + perror (__FILE__ ": couldn't create pipe"); + use_subshell = FALSE; + return; + } } /* Fork the subshell */ @@ -457,44 +489,43 @@ init_subshell (void) subshell_stopped = FALSE; subshell_pid = fork (); - if (subshell_pid == -1) { - fprintf (stderr, "Cannot spawn the subshell process: %s\r\n", - unix_error_string (errno)); - /* We exit here because, if the process table is full, the */ - /* other method of running user commands won't work either */ - exit (1); + if (subshell_pid == -1) + { + fprintf (stderr, "Cannot spawn the subshell process: %s\r\n", unix_error_string (errno)); + /* We exit here because, if the process table is full, the */ + /* other method of running user commands won't work either */ + exit (1); } - if (subshell_pid == 0) { /* We are in the child process */ - init_subshell_child (pty_name); + if (subshell_pid == 0) + { /* We are in the child process */ + init_subshell_child (pty_name); } /* Set up `precmd' or equivalent for reading the subshell's CWD */ - switch (subshell_type) { + switch (subshell_type) + { case BASH: - g_snprintf (precmd, sizeof (precmd), - " PROMPT_COMMAND='pwd>&%d;kill -STOP $$'\n", - subshell_pipe[WRITE]); - break; + g_snprintf (precmd, sizeof (precmd), + " PROMPT_COMMAND='pwd>&%d;kill -STOP $$'\n", subshell_pipe[WRITE]); + break; case ZSH: - g_snprintf (precmd, sizeof (precmd), - " precmd(){ pwd>&%d;kill -STOP $$ }\n", - subshell_pipe[WRITE]); - break; + g_snprintf (precmd, sizeof (precmd), + " precmd(){ pwd>&%d;kill -STOP $$ }\n", subshell_pipe[WRITE]); + break; case TCSH: - g_snprintf (precmd, sizeof (precmd), - "set echo_style=both;" - "alias precmd 'echo $cwd:q >>%s;kill -STOP $$'\n", - tcsh_fifo); - break; + g_snprintf (precmd, sizeof (precmd), + "set echo_style=both;" + "alias precmd 'echo $cwd:q >>%s;kill -STOP $$'\n", tcsh_fifo); + break; case FISH: - g_snprintf (precmd, sizeof (precmd), - "function fish_prompt ; pwd>&%d;kill -STOP %%self; end\n", - subshell_pipe[WRITE]); - break; + g_snprintf (precmd, sizeof (precmd), + "function fish_prompt ; pwd>&%d;kill -STOP %%self; end\n", + subshell_pipe[WRITE]); + break; } write_all (subshell_pty, precmd, strlen (precmd)); @@ -503,16 +534,18 @@ init_subshell (void) subshell_state = RUNNING_COMMAND; tty_enable_interrupt_key (); - if (!feed_subshell (QUIETLY, TRUE)) { - use_subshell = FALSE; + if (!feed_subshell (QUIETLY, TRUE)) + { + use_subshell = FALSE; } tty_disable_interrupt_key (); if (!subshell_alive) - use_subshell = FALSE; /* Subshell died instantly, so don't use it */ + use_subshell = FALSE; /* Subshell died instantly, so don't use it */ } -static void init_raw_mode () +static void +init_raw_mode () { static int initialized = 0; @@ -522,65 +555,66 @@ static void init_raw_mode () /* pty. So, instead of changing the code for execute(), pre_exec(), */ /* etc, we just set up the modes we need here, before each command. */ - if (initialized == 0) /* First time: initialise `raw_mode' */ + if (initialized == 0) /* First time: initialise `raw_mode' */ { - tcgetattr (STDOUT_FILENO, &raw_mode); - raw_mode.c_lflag &= ~ICANON; /* Disable line-editing chars, etc. */ - raw_mode.c_lflag &= ~ISIG; /* Disable intr, quit & suspend chars */ - raw_mode.c_lflag &= ~ECHO; /* Disable input echoing */ - raw_mode.c_iflag &= ~IXON; /* Pass ^S/^Q to subshell undisturbed */ - raw_mode.c_iflag &= ~ICRNL; /* Don't translate CRs into LFs */ - raw_mode.c_oflag &= ~OPOST; /* Don't postprocess output */ - raw_mode.c_cc[VTIME] = 0; /* IE: wait forever, and return as */ - raw_mode.c_cc[VMIN] = 1; /* soon as a character is available */ - initialized = 1; + tcgetattr (STDOUT_FILENO, &raw_mode); + raw_mode.c_lflag &= ~ICANON; /* Disable line-editing chars, etc. */ + raw_mode.c_lflag &= ~ISIG; /* Disable intr, quit & suspend chars */ + raw_mode.c_lflag &= ~ECHO; /* Disable input echoing */ + raw_mode.c_iflag &= ~IXON; /* Pass ^S/^Q to subshell undisturbed */ + raw_mode.c_iflag &= ~ICRNL; /* Don't translate CRs into LFs */ + raw_mode.c_oflag &= ~OPOST; /* Don't postprocess output */ + raw_mode.c_cc[VTIME] = 0; /* IE: wait forever, and return as */ + raw_mode.c_cc[VMIN] = 1; /* soon as a character is available */ + initialized = 1; } } -int invoke_subshell (const char *command, int how, char **new_dir) +int +invoke_subshell (const char *command, int how, char **new_dir) { char *pcwd; - + /* Make the MC terminal transparent */ tcsetattr (STDOUT_FILENO, TCSANOW, &raw_mode); - + /* Make the subshell change to MC's working directory */ if (new_dir) - do_subshell_chdir (current_panel->cwd, TRUE, 1); - - if (command == NULL) /* The user has done "C-o" from MC */ + do_subshell_chdir (current_panel->cwd, TRUE, 1); + + if (command == NULL) /* The user has done "C-o" from MC */ { - if (subshell_state == INACTIVE) - { - subshell_state = ACTIVE; - /* FIXME: possibly take out this hack; the user can - re-play it by hitting C-hyphen a few times! */ - if (subshell_ready) - write_all (subshell_pty, " \b", 2); /* Hack to make prompt reappear */ - } + if (subshell_state == INACTIVE) + { + subshell_state = ACTIVE; + /* FIXME: possibly take out this hack; the user can + re-play it by hitting C-hyphen a few times! */ + if (subshell_ready) + write_all (subshell_pty, " \b", 2); /* Hack to make prompt reappear */ + } } - else /* MC has passed us a user command */ + else /* MC has passed us a user command */ { - if (how == QUIETLY) - write_all (subshell_pty, " ", 1); - /* FIXME: if command is long (>8KB ?) we go comma */ - write_all (subshell_pty, command, strlen (command)); - write_all (subshell_pty, "\n", 1); - subshell_state = RUNNING_COMMAND; - subshell_ready = FALSE; + if (how == QUIETLY) + write_all (subshell_pty, " ", 1); + /* FIXME: if command is long (>8KB ?) we go comma */ + write_all (subshell_pty, command, strlen (command)); + write_all (subshell_pty, "\n", 1); + subshell_state = RUNNING_COMMAND; + subshell_ready = FALSE; } feed_subshell (how, FALSE); pcwd = vfs_translate_path_n (current_panel->cwd); if (new_dir && subshell_alive && strcmp (subshell_cwd, pcwd)) - *new_dir = subshell_cwd; /* Make MC change to the subshell's CWD */ + *new_dir = subshell_cwd; /* Make MC change to the subshell's CWD */ g_free (pcwd); /* Restart the subshell if it has died by SIGHUP, SIGQUIT, etc. */ while (!subshell_alive && !quit && use_subshell) - init_subshell (); + init_subshell (); prompt_pos = 0; @@ -599,52 +633,56 @@ read_subshell_prompt (void) FD_ZERO (&tmp); FD_SET (subshell_pty, &tmp); - if (subshell_prompt == NULL) { /* First time through */ - subshell_prompt = g_malloc (prompt_size); - *subshell_prompt = '\0'; - prompt_pos = 0; + if (subshell_prompt == NULL) + { /* First time through */ + subshell_prompt = g_malloc (prompt_size); + *subshell_prompt = '\0'; + prompt_pos = 0; } - while (subshell_alive - && (rc = - select (subshell_pty + 1, &tmp, NULL, NULL, &timeleft))) { - /* Check for `select' errors */ - if (rc == -1) { - if (errno == EINTR) - continue; - else { - fprintf (stderr, "select (FD_SETSIZE, &tmp...): %s\r\n", - unix_error_string (errno)); - exit (1); - } - } + while (subshell_alive && (rc = select (subshell_pty + 1, &tmp, NULL, NULL, &timeleft))) + { + /* Check for `select' errors */ + if (rc == -1) + { + if (errno == EINTR) + continue; + else + { + fprintf (stderr, "select (FD_SETSIZE, &tmp...): %s\r\n", unix_error_string (errno)); + exit (1); + } + } - bytes = read (subshell_pty, pty_buffer, sizeof (pty_buffer)); + bytes = read (subshell_pty, pty_buffer, sizeof (pty_buffer)); - /* Extract the prompt from the shell output */ + /* Extract the prompt from the shell output */ - for (i = 0; i < bytes; ++i) - if (pty_buffer[i] == '\n' || pty_buffer[i] == '\r') { - prompt_pos = 0; - } else { - if (!pty_buffer[i]) - continue; + for (i = 0; i < bytes; ++i) + if (pty_buffer[i] == '\n' || pty_buffer[i] == '\r') + { + prompt_pos = 0; + } + else + { + if (!pty_buffer[i]) + continue; - subshell_prompt[prompt_pos++] = pty_buffer[i]; - if (prompt_pos == prompt_size) - subshell_prompt = - g_realloc (subshell_prompt, prompt_size *= 2); - } + subshell_prompt[prompt_pos++] = pty_buffer[i]; + if (prompt_pos == prompt_size) + subshell_prompt = g_realloc (subshell_prompt, prompt_size *= 2); + } - subshell_prompt[prompt_pos] = '\0'; + subshell_prompt[prompt_pos] = '\0'; } if (rc == 0 && bytes == 0) - return FALSE; + return FALSE; return TRUE; } /* Resize given terminal using TIOCSWINSZ, return ioctl() result */ -static int resize_tty (int fd) +static int +resize_tty (int fd) { #if defined TIOCSWINSZ struct winsize tty_size; @@ -660,10 +698,11 @@ static int resize_tty (int fd) } /* Resize subshell_pty */ -void resize_subshell (void) +void +resize_subshell (void) { if (use_subshell == 0) - return; + return; resize_tty (subshell_pty); } @@ -674,21 +713,23 @@ exit_subshell (void) int subshell_quit = TRUE; if (subshell_state != INACTIVE && subshell_alive) - subshell_quit = - !query_dialog (_("Warning"), - _(" The shell is still active. Quit anyway? "), - D_NORMAL, 2, _("&Yes"), _("&No")); + subshell_quit = + !query_dialog (_("Warning"), + _(" The shell is still active. Quit anyway? "), + D_NORMAL, 2, _("&Yes"), _("&No")); - if (subshell_quit) { - if (subshell_type == TCSH) { - if (unlink (tcsh_fifo) == -1) - fprintf (stderr, "Cannot remove named pipe %s: %s\r\n", - tcsh_fifo, unix_error_string (errno)); - } + if (subshell_quit) + { + if (subshell_type == TCSH) + { + if (unlink (tcsh_fifo) == -1) + fprintf (stderr, "Cannot remove named pipe %s: %s\r\n", + tcsh_fifo, unix_error_string (errno)); + } - g_free (subshell_prompt); - subshell_prompt = NULL; - pty_buffer[0] = '\0'; + g_free (subshell_prompt); + subshell_prompt = NULL; + pty_buffer[0] = '\0'; } return subshell_quit; @@ -719,29 +760,33 @@ subshell_name_quote (const char *s) const char *quote_cmd_start, *quote_cmd_end; int c; - if (subshell_type == FISH) { - quote_cmd_start = "(printf \"%b\" '"; - quote_cmd_end = "')"; - } else { - quote_cmd_start = "\"`printf \"%b\" '"; - quote_cmd_end = "'`\""; + if (subshell_type == FISH) + { + quote_cmd_start = "(printf \"%b\" '"; + quote_cmd_end = "')"; + } + else + { + quote_cmd_start = "\"`printf \"%b\" '"; + quote_cmd_end = "'`\""; } /* Factor 5 because we need \, 0 and 3 other digits per character. */ - d = ret = g_try_malloc (1 + (5 * strlen (s)) + (strlen(quote_cmd_start)) - + (strlen(quote_cmd_end))); + d = ret = g_try_malloc (1 + (5 * strlen (s)) + (strlen (quote_cmd_start)) + + (strlen (quote_cmd_end))); if (d == NULL) - return NULL; + return NULL; /* Prevent interpreting leading `-' as a switch for `cd' */ - if (*s == '-') { - *d++ = '.'; - *d++ = '/'; + if (*s == '-') + { + *d++ = '.'; + *d++ = '/'; } /* Copy the beginning of the command to the buffer */ strcpy (d, quote_cmd_start); - d += strlen(quote_cmd_start); + d += strlen (quote_cmd_start); /* * Print every character except digits and letters as a backslash-escape @@ -749,18 +794,23 @@ subshell_name_quote (const char *s) * character converted to octal number. */ su = s; - for (; su[0] != '\0'; ) { - n = str_cget_next_char_safe (su); - if (str_isalnum (su)) { - memcpy (d, su, n - su); - d+= n - su; - } else { - for (c = 0; c < n - su; c++) { - sprintf (d, "\\0%03o", (unsigned char) su[c]); - d += 5; - } - } - su = n; + for (; su[0] != '\0';) + { + n = str_cget_next_char_safe (su); + if (str_isalnum (su)) + { + memcpy (d, su, n - su); + d += n - su; + } + else + { + for (c = 0; c < n - su; c++) + { + sprintf (d, "\\0%03o", (unsigned char) su[c]); + d += 5; + } + } + su = n; } strcpy (d, quote_cmd_end); @@ -776,79 +826,88 @@ do_subshell_chdir (const char *directory, int do_update, int reset_prompt) char *pcwd; char *temp; char *translate; - + pcwd = vfs_translate_path_n (current_panel->cwd); - - if (! - (subshell_state == INACTIVE - && strcmp (subshell_cwd, pcwd))) { - /* We have to repaint the subshell prompt if we read it from - * the main program. Please note that in the code after this - * if, the cd command that is sent will make the subshell - * repaint the prompt, so we don't have to paint it. */ - if (do_update) - do_update_prompt (); + + if (!(subshell_state == INACTIVE && strcmp (subshell_cwd, pcwd))) + { + /* We have to repaint the subshell prompt if we read it from + * the main program. Please note that in the code after this + * if, the cd command that is sent will make the subshell + * repaint the prompt, so we don't have to paint it. */ + if (do_update) + do_update_prompt (); g_free (pcwd); - return; + return; } /* The initial space keeps this out of the command history (in bash because we set "HISTCONTROL=ignorespace") */ write_all (subshell_pty, " cd ", 4); - if (*directory) { + if (*directory) + { translate = vfs_translate_path_n (directory); - if (translate) { + if (translate) + { temp = subshell_name_quote (translate); - if (temp) { - write_all (subshell_pty, temp, strlen (temp)); - g_free (temp); - } else { - /* Should not happen unless the directory name is so long - that we don't have memory to quote it. */ - write_all (subshell_pty, ".", 1); - } + if (temp) + { + write_all (subshell_pty, temp, strlen (temp)); + g_free (temp); + } + else + { + /* Should not happen unless the directory name is so long + that we don't have memory to quote it. */ + write_all (subshell_pty, ".", 1); + } g_free (translate); - } else { + } + else + { write_all (subshell_pty, ".", 1); } - } else { - write_all (subshell_pty, "/", 1); + } + else + { + write_all (subshell_pty, "/", 1); } write_all (subshell_pty, "\n", 1); subshell_state = RUNNING_COMMAND; feed_subshell (QUIETLY, FALSE); - if (subshell_alive) { + if (subshell_alive) + { int bPathNotEq = strcmp (subshell_cwd, pcwd); - if (bPathNotEq && subshell_type == TCSH) { - char rp_subshell_cwd[PATH_MAX]; - char rp_current_panel_cwd[PATH_MAX]; + if (bPathNotEq && subshell_type == TCSH) + { + char rp_subshell_cwd[PATH_MAX]; + char rp_current_panel_cwd[PATH_MAX]; - char *p_subshell_cwd = - mc_realpath (subshell_cwd, rp_subshell_cwd); - char *p_current_panel_cwd = - mc_realpath (pcwd, rp_current_panel_cwd); + char *p_subshell_cwd = mc_realpath (subshell_cwd, rp_subshell_cwd); + char *p_current_panel_cwd = mc_realpath (pcwd, rp_current_panel_cwd); - if (p_subshell_cwd == NULL) - p_subshell_cwd = subshell_cwd; - if (p_current_panel_cwd == NULL) + if (p_subshell_cwd == NULL) + p_subshell_cwd = subshell_cwd; + if (p_current_panel_cwd == NULL) p_current_panel_cwd = pcwd; - bPathNotEq = strcmp (p_subshell_cwd, p_current_panel_cwd); - } + bPathNotEq = strcmp (p_subshell_cwd, p_current_panel_cwd); + } - if (bPathNotEq && strcmp (pcwd, ".")) { + if (bPathNotEq && strcmp (pcwd, ".")) + { char *cwd = strip_password (g_strdup (pcwd), 1); - fprintf (stderr, _("Warning: Cannot change to %s.\n"), cwd); - g_free (cwd); - } + fprintf (stderr, _("Warning: Cannot change to %s.\n"), cwd); + g_free (cwd); + } } if (reset_prompt) - prompt_pos = 0; + prompt_pos = 0; update_prompt = FALSE; - + g_free (pcwd); /* Make sure that MC never stores the CWD in a silly format */ /* like /usr////lib/../bin, or the strcmp() above will fail */ @@ -860,11 +919,11 @@ subshell_get_console_attributes (void) { /* Get our current terminal modes */ - if (tcgetattr (STDOUT_FILENO, &shell_mode)) { - fprintf (stderr, "Cannot get terminal settings: %s\r\n", - unix_error_string (errno)); - use_subshell = FALSE; - return; + if (tcgetattr (STDOUT_FILENO, &shell_mode)) + { + fprintf (stderr, "Cannot get terminal settings: %s\r\n", unix_error_string (errno)); + use_subshell = FALSE; + return; } } @@ -881,41 +940,50 @@ sigchld_handler (int sig) pid = waitpid (subshell_pid, &status, WUNTRACED | WNOHANG); - if (pid == subshell_pid) { - /* Figure out what has happened to the subshell */ + if (pid == subshell_pid) + { + /* Figure out what has happened to the subshell */ - if (WIFSTOPPED (status)) { - if (WSTOPSIG (status) == SIGSTOP) { - /* The subshell has received a SIGSTOP signal */ - subshell_stopped = TRUE; - } else { - /* The user has suspended the subshell. Revive it */ - kill (subshell_pid, SIGCONT); - } - } else { - /* The subshell has either exited normally or been killed */ - subshell_alive = FALSE; - delete_select_channel (subshell_pty); - if (WIFEXITED (status) && WEXITSTATUS (status) != FORK_FAILURE) - quit |= SUBSHELL_EXIT; /* Exited normally */ - } + if (WIFSTOPPED (status)) + { + if (WSTOPSIG (status) == SIGSTOP) + { + /* The subshell has received a SIGSTOP signal */ + subshell_stopped = TRUE; + } + else + { + /* The user has suspended the subshell. Revive it */ + kill (subshell_pid, SIGCONT); + } + } + else + { + /* The subshell has either exited normally or been killed */ + subshell_alive = FALSE; + delete_select_channel (subshell_pty); + if (WIFEXITED (status) && WEXITSTATUS (status) != FORK_FAILURE) + quit |= SUBSHELL_EXIT; /* Exited normally */ + } } #ifdef __linux__ pid = waitpid (cons_saver_pid, &status, WUNTRACED | WNOHANG); - if (pid == cons_saver_pid) { + if (pid == cons_saver_pid) + { - if (WIFSTOPPED (status)) - /* Someone has stopped cons.saver - restart it */ - kill (pid, SIGCONT); - else { - /* cons.saver has died - disable confole saving */ - handle_console (CONSOLE_DONE); - console_flag = 0; - } + if (WIFSTOPPED (status)) + /* Someone has stopped cons.saver - restart it */ + kill (pid, SIGCONT); + else + { + /* cons.saver has died - disable confole saving */ + handle_console (CONSOLE_DONE); + console_flag = 0; + } } -#endif /* __linux__ */ +#endif /* __linux__ */ /* If we got here, some other child exited; ignore it */ } @@ -925,12 +993,12 @@ sigchld_handler (int sig) static int feed_subshell (int how, int fail_on_error) { - fd_set read_set; /* For `select' */ + fd_set read_set; /* For `select' */ int maxfdp; - int bytes; /* For the return value from `read' */ - int i; /* Loop counter */ + int bytes; /* For the return value from `read' */ + int i; /* Loop counter */ - struct timeval wtime; /* Maximum time we wait for the subshell */ + struct timeval wtime; /* Maximum time we wait for the subshell */ struct timeval *wptr; /* we wait up to 10 seconds if fail_on_error, forever otherwise */ @@ -938,116 +1006,123 @@ feed_subshell (int how, int fail_on_error) wtime.tv_usec = 0; wptr = fail_on_error ? &wtime : NULL; - while (1) { - if (!subshell_alive) - return FALSE; + while (1) + { + if (!subshell_alive) + return FALSE; - /* Prepare the file-descriptor set and call `select' */ + /* Prepare the file-descriptor set and call `select' */ - FD_ZERO (&read_set); - FD_SET (subshell_pty, &read_set); - FD_SET (subshell_pipe[READ], &read_set); - maxfdp = max (subshell_pty, subshell_pipe[READ]); - if (how == VISIBLY) { - FD_SET (STDIN_FILENO, &read_set); - maxfdp = max (maxfdp, STDIN_FILENO); - } + FD_ZERO (&read_set); + FD_SET (subshell_pty, &read_set); + FD_SET (subshell_pipe[READ], &read_set); + maxfdp = max (subshell_pty, subshell_pipe[READ]); + if (how == VISIBLY) + { + FD_SET (STDIN_FILENO, &read_set); + maxfdp = max (maxfdp, STDIN_FILENO); + } - if (select (maxfdp + 1, &read_set, NULL, NULL, wptr) == -1) { + if (select (maxfdp + 1, &read_set, NULL, NULL, wptr) == -1) + { - /* Despite using SA_RESTART, we still have to check for this */ - if (errno == EINTR) - continue; /* try all over again */ - tcsetattr (STDOUT_FILENO, TCSANOW, &shell_mode); - fprintf (stderr, "select (FD_SETSIZE, &read_set...): %s\r\n", - unix_error_string (errno)); - exit (1); - } + /* Despite using SA_RESTART, we still have to check for this */ + if (errno == EINTR) + continue; /* try all over again */ + tcsetattr (STDOUT_FILENO, TCSANOW, &shell_mode); + fprintf (stderr, "select (FD_SETSIZE, &read_set...): %s\r\n", + unix_error_string (errno)); + exit (1); + } - if (FD_ISSET (subshell_pty, &read_set)) - /* Read from the subshell, write to stdout */ + if (FD_ISSET (subshell_pty, &read_set)) + /* Read from the subshell, write to stdout */ - /* This loop improves performance by reducing context switches - by a factor of 20 or so... unfortunately, it also hangs MC - randomly, because of an apparent Linux bug. Investigate. */ - /* for (i=0; i<5; ++i) * FIXME -- experimental */ - { - bytes = read (subshell_pty, pty_buffer, sizeof (pty_buffer)); + /* This loop improves performance by reducing context switches + by a factor of 20 or so... unfortunately, it also hangs MC + randomly, because of an apparent Linux bug. Investigate. */ + /* for (i=0; i<5; ++i) * FIXME -- experimental */ + { + bytes = read (subshell_pty, pty_buffer, sizeof (pty_buffer)); - /* The subshell has died */ - if (bytes == -1 && errno == EIO && !subshell_alive) - return FALSE; + /* The subshell has died */ + if (bytes == -1 && errno == EIO && !subshell_alive) + return FALSE; - if (bytes <= 0) { - tcsetattr (STDOUT_FILENO, TCSANOW, &shell_mode); - fprintf (stderr, "read (subshell_pty...): %s\r\n", - unix_error_string (errno)); - exit (1); - } + if (bytes <= 0) + { + tcsetattr (STDOUT_FILENO, TCSANOW, &shell_mode); + fprintf (stderr, "read (subshell_pty...): %s\r\n", unix_error_string (errno)); + exit (1); + } - if (how == VISIBLY) - write_all (STDOUT_FILENO, pty_buffer, bytes); - } + if (how == VISIBLY) + write_all (STDOUT_FILENO, pty_buffer, bytes); + } - else if (FD_ISSET (subshell_pipe[READ], &read_set)) - /* Read the subshell's CWD and capture its prompt */ + else if (FD_ISSET (subshell_pipe[READ], &read_set)) + /* Read the subshell's CWD and capture its prompt */ - { - bytes = - read (subshell_pipe[READ], subshell_cwd, - MC_MAXPATHLEN + 1); - if (bytes <= 0) { - tcsetattr (STDOUT_FILENO, TCSANOW, &shell_mode); - fprintf (stderr, "read (subshell_pipe[READ]...): %s\r\n", - unix_error_string (errno)); - exit (1); - } + { + bytes = read (subshell_pipe[READ], subshell_cwd, MC_MAXPATHLEN + 1); + if (bytes <= 0) + { + tcsetattr (STDOUT_FILENO, TCSANOW, &shell_mode); + fprintf (stderr, "read (subshell_pipe[READ]...): %s\r\n", + unix_error_string (errno)); + exit (1); + } - subshell_cwd[bytes - 1] = 0; /* Squash the final '\n' */ + subshell_cwd[bytes - 1] = 0; /* Squash the final '\n' */ - synchronize (); + synchronize (); - subshell_ready = TRUE; - if (subshell_state == RUNNING_COMMAND) { - subshell_state = INACTIVE; - return 1; - } - } + subshell_ready = TRUE; + if (subshell_state == RUNNING_COMMAND) + { + subshell_state = INACTIVE; + return 1; + } + } - else if (FD_ISSET (STDIN_FILENO, &read_set)) - /* Read from stdin, write to the subshell */ - { - bytes = read (STDIN_FILENO, pty_buffer, sizeof (pty_buffer)); - if (bytes <= 0) { - tcsetattr (STDOUT_FILENO, TCSANOW, &shell_mode); - fprintf (stderr, - "read (STDIN_FILENO, pty_buffer...): %s\r\n", - unix_error_string (errno)); - exit (1); - } + else if (FD_ISSET (STDIN_FILENO, &read_set)) + /* Read from stdin, write to the subshell */ + { + bytes = read (STDIN_FILENO, pty_buffer, sizeof (pty_buffer)); + if (bytes <= 0) + { + tcsetattr (STDOUT_FILENO, TCSANOW, &shell_mode); + fprintf (stderr, + "read (STDIN_FILENO, pty_buffer...): %s\r\n", unix_error_string (errno)); + exit (1); + } - for (i = 0; i < bytes; ++i) - if (pty_buffer[i] == subshell_switch_key) { - write_all (subshell_pty, pty_buffer, i); - if (subshell_ready) - subshell_state = INACTIVE; - return TRUE; - } + for (i = 0; i < bytes; ++i) + if (pty_buffer[i] == subshell_switch_key) + { + write_all (subshell_pty, pty_buffer, i); + if (subshell_ready) + subshell_state = INACTIVE; + return TRUE; + } - write_all (subshell_pty, pty_buffer, bytes); + write_all (subshell_pty, pty_buffer, bytes); - if (pty_buffer[bytes-1] == '\n' || pty_buffer[bytes-1] == '\r') - subshell_ready = FALSE; - } else { - return FALSE; - } + if (pty_buffer[bytes - 1] == '\n' || pty_buffer[bytes - 1] == '\r') + subshell_ready = FALSE; + } + else + { + return FALSE; + } } } /* Wait until the subshell dies or stops. If it stops, make it resume. */ /* Possibly modifies the globals `subshell_alive' and `subshell_stopped' */ -static void synchronize (void) +static void +synchronize (void) { sigset_t sigchld_mask, old_mask; @@ -1063,11 +1138,12 @@ static void synchronize (void) /* Wait until the subshell has stopped */ while (subshell_alive && !subshell_stopped) - sigsuspend (&old_mask); + sigsuspend (&old_mask); - if (subshell_state != ACTIVE) { - /* Discard all remaining data from stdin to the subshell */ - tcflush (subshell_pty_slave, TCIFLUSH); + if (subshell_state != ACTIVE) + { + /* Discard all remaining data from stdin to the subshell */ + tcflush (subshell_pty_slave, TCIFLUSH); } subshell_stopped = FALSE; @@ -1083,13 +1159,14 @@ static void synchronize (void) /* System V version of pty_open_master */ -static int pty_open_master (char *pty_name) +static int +pty_open_master (char *pty_name) { char *slave_name; int pty_master; #ifdef HAVE_POSIX_OPENPT - pty_master = posix_openpt(O_RDWR); + pty_master = posix_openpt (O_RDWR); #elif HAVE_GETPT /* getpt () is a GNU extension (glibc 2.1.x) */ pty_master = getpt (); @@ -1099,17 +1176,17 @@ static int pty_open_master (char *pty_name) #else strcpy (pty_name, "/dev/ptmx"); pty_master = open (pty_name, O_RDWR); -#endif +#endif if (pty_master == -1) - return -1; + return -1; - if (grantpt (pty_master) == -1 /* Grant access to slave */ - || unlockpt (pty_master) == -1 /* Clear slave's lock flag */ - || !(slave_name = ptsname (pty_master))) /* Get slave's name */ + if (grantpt (pty_master) == -1 /* Grant access to slave */ + || unlockpt (pty_master) == -1 /* Clear slave's lock flag */ + || !(slave_name = ptsname (pty_master))) /* Get slave's name */ { - close (pty_master); - return -1; + close (pty_master); + return -1; } strcpy (pty_name, slave_name); return pty_master; @@ -1121,50 +1198,54 @@ pty_open_slave (const char *pty_name) { int pty_slave = open (pty_name, O_RDWR); - if (pty_slave == -1) { - fprintf (stderr, "open (%s, O_RDWR): %s\r\n", pty_name, - unix_error_string (errno)); - return -1; + if (pty_slave == -1) + { + fprintf (stderr, "open (%s, O_RDWR): %s\r\n", pty_name, unix_error_string (errno)); + return -1; } #if !defined(__osf__) && !defined(__linux__) #if defined (I_FIND) && defined (I_PUSH) if (!ioctl (pty_slave, I_FIND, "ptem")) - if (ioctl (pty_slave, I_PUSH, "ptem") == -1) { - fprintf (stderr, "ioctl (%d, I_PUSH, \"ptem\") failed: %s\r\n", - pty_slave, unix_error_string (errno)); - close (pty_slave); - return -1; - } + if (ioctl (pty_slave, I_PUSH, "ptem") == -1) + { + fprintf (stderr, "ioctl (%d, I_PUSH, \"ptem\") failed: %s\r\n", + pty_slave, unix_error_string (errno)); + close (pty_slave); + return -1; + } if (!ioctl (pty_slave, I_FIND, "ldterm")) - if (ioctl (pty_slave, I_PUSH, "ldterm") == -1) { - fprintf (stderr, - "ioctl (%d, I_PUSH, \"ldterm\") failed: %s\r\n", - pty_slave, unix_error_string (errno)); - close (pty_slave); - return -1; - } + if (ioctl (pty_slave, I_PUSH, "ldterm") == -1) + { + fprintf (stderr, + "ioctl (%d, I_PUSH, \"ldterm\") failed: %s\r\n", + pty_slave, unix_error_string (errno)); + close (pty_slave); + return -1; + } #if !defined(sgi) && !defined(__sgi) if (!ioctl (pty_slave, I_FIND, "ttcompat")) - if (ioctl (pty_slave, I_PUSH, "ttcompat") == -1) { - fprintf (stderr, - "ioctl (%d, I_PUSH, \"ttcompat\") failed: %s\r\n", - pty_slave, unix_error_string (errno)); - close (pty_slave); - return -1; - } -#endif /* sgi || __sgi */ -#endif /* I_FIND && I_PUSH */ -#endif /* __osf__ || __linux__ */ + if (ioctl (pty_slave, I_PUSH, "ttcompat") == -1) + { + fprintf (stderr, + "ioctl (%d, I_PUSH, \"ttcompat\") failed: %s\r\n", + pty_slave, unix_error_string (errno)); + close (pty_slave); + return -1; + } +#endif /* sgi || __sgi */ +#endif /* I_FIND && I_PUSH */ +#endif /* __osf__ || __linux__ */ - fcntl(pty_slave, F_SETFD, FD_CLOEXEC); + fcntl (pty_slave, F_SETFD, FD_CLOEXEC); return pty_slave; } #else /* !HAVE_GRANTPT */ /* BSD version of pty_open_master */ -static int pty_open_master (char *pty_name) +static int +pty_open_master (char *pty_name) { int pty_master; const char *ptr1, *ptr2; @@ -1172,28 +1253,30 @@ static int pty_open_master (char *pty_name) strcpy (pty_name, "/dev/ptyXX"); for (ptr1 = "pqrstuvwxyzPQRST"; *ptr1; ++ptr1) { - pty_name [8] = *ptr1; - for (ptr2 = "0123456789abcdef"; *ptr2; ++ptr2) - { - pty_name [9] = *ptr2; + pty_name[8] = *ptr1; + for (ptr2 = "0123456789abcdef"; *ptr2; ++ptr2) + { + pty_name[9] = *ptr2; - /* Try to open master */ - if ((pty_master = open (pty_name, O_RDWR)) == -1) { - if (errno == ENOENT) /* Different from EIO */ - return -1; /* Out of pty devices */ - else - continue; /* Try next pty device */ - } - pty_name [5] = 't'; /* Change "pty" to "tty" */ - if (access (pty_name, 6)){ - close (pty_master); - pty_name [5] = 'p'; - continue; - } - return pty_master; - } + /* Try to open master */ + if ((pty_master = open (pty_name, O_RDWR)) == -1) + { + if (errno == ENOENT) /* Different from EIO */ + return -1; /* Out of pty devices */ + else + continue; /* Try next pty device */ + } + pty_name[5] = 't'; /* Change "pty" to "tty" */ + if (access (pty_name, 6)) + { + close (pty_master); + pty_name[5] = 'p'; + continue; + } + return pty_master; + } } - return -1; /* Ran out of pty devices */ + return -1; /* Ran out of pty devices */ } /* BSD version of pty_open_slave */ @@ -1203,15 +1286,16 @@ pty_open_slave (const char *pty_name) int pty_slave; struct group *group_info = getgrnam ("tty"); - if (group_info != NULL) { - /* The following two calls will only succeed if we are root */ - /* [Commented out while permissions problem is investigated] */ - /* chown (pty_name, getuid (), group_info->gr_gid); FIXME */ - /* chmod (pty_name, S_IRUSR | S_IWUSR | S_IWGRP); FIXME */ + if (group_info != NULL) + { + /* The following two calls will only succeed if we are root */ + /* [Commented out while permissions problem is investigated] */ + /* chown (pty_name, getuid (), group_info->gr_gid); FIXME */ + /* chmod (pty_name, S_IRUSR | S_IWUSR | S_IWGRP); FIXME */ } if ((pty_slave = open (pty_name, O_RDWR)) == -1) - fprintf (stderr, "open (pty_name, O_RDWR): %s\r\n", pty_name); - fcntl(pty_slave, F_SETFD, FD_CLOEXEC); + fprintf (stderr, "open (pty_name, O_RDWR): %s\r\n", pty_name); + fcntl (pty_slave, F_SETFD, FD_CLOEXEC); return pty_slave; } diff --git a/src/tree.c b/src/tree.c index 30d0b0249..7df35eacb 100644 --- a/src/tree.c +++ b/src/tree.c @@ -663,13 +663,14 @@ tree_rescan (void *data) { char old_dir[MC_MAXPATHLEN]; WTree *tree = data; + int ret; if (!tree->selected_ptr || !mc_get_current_wd (old_dir, MC_MAXPATHLEN) || mc_chdir (tree->selected_ptr->name)) return; tree_store_rescan (tree->selected_ptr->name); - mc_chdir (old_dir); + ret = mc_chdir (old_dir); } static void diff --git a/src/treestore.c b/src/treestore.c index 2d2c4d6f2..2ef065d49 100644 --- a/src/treestore.c +++ b/src/treestore.c @@ -3,33 +3,33 @@ * * Contains a storage of the file system tree representation * - Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2009 - Free Software Foundation, Inc. + Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2009 + Free Software Foundation, Inc. - Written: 1994, 1996 Janne Kukonlehto - 1997 Norbert Warmuth - 1996, 1999 Miguel de Icaza - - 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. + Written: 1994, 1996 Janne Kukonlehto + 1997 Norbert Warmuth + 1996, 1999 Miguel de Icaza - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + 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 module has been converted to be a widget. + 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. - The program load and saves the tree each time the tree widget is - created and destroyed. This is required for the future vfs layer, - it will be possible to have tree views over virtual file systems. -*/ + 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + This module has been converted to be a widget. + + The program load and saves the tree each time the tree widget is + created and destroyed. This is required for the future vfs layer, + it will be possible to have tree views over virtual file systems. + */ /** \file treestore.c * \brief Source: tree store @@ -59,113 +59,117 @@ static struct TreeStore ts; -static tree_entry *tree_store_add_entry(const char *name); +static tree_entry *tree_store_add_entry (const char *name); static void -tree_store_dirty(int state) +tree_store_dirty (int state) { ts.dirty = state; } /* Returns the number of common bytes in the strings. */ static size_t -str_common(const char *s1, const char *s2) +str_common (const char *s1, const char *s2) { size_t result = 0; while (*s1 != '\0' && *s2 != '\0' && *s1++ == *s2++) - result++; + result++; return result; } /* The directory names are arranged in a single linked list in the same order as they are displayed. When the tree is displayed the expected order is like this: - / - /bin - /etc - /etc/X11 - /etc/rc.d - /etc.old/X11 - /etc.old/rc.d - /usr + / + /bin + /etc + /etc/X11 + /etc/rc.d + /etc.old/X11 + /etc.old/rc.d + /usr i.e. the required collating sequence when comparing two directory names is - '\0' < PATH_SEP < all-other-characters-in-encoding-order + '\0' < PATH_SEP < all-other-characters-in-encoding-order - Since strcmp doesn't fulfil this requirement we use pathcmp when - inserting directory names into the list. The meaning of the return value - of pathcmp and strcmp are the same (an integer less than, equal to, or - greater than zero if p1 is found to be less than, to match, or be greater - than p2. + Since strcmp doesn't fulfil this requirement we use pathcmp when + inserting directory names into the list. The meaning of the return value + of pathcmp and strcmp are the same (an integer less than, equal to, or + greater than zero if p1 is found to be less than, to match, or be greater + than p2. */ static int -pathcmp(const char *p1, const char *p2) +pathcmp (const char *p1, const char *p2) { for (; *p1 == *p2; p1++, p2++) - if (*p1 == '\0') - return 0; + if (*p1 == '\0') + return 0; if (*p1 == '\0') - return -1; + return -1; if (*p2 == '\0') - return 1; + return 1; if (*p1 == PATH_SEP) - return -1; + return -1; if (*p2 == PATH_SEP) - return 1; + return 1; return (*p1 - *p2); } /* Searches for specified directory */ tree_entry * -tree_store_whereis(const char *name) +tree_store_whereis (const char *name) { tree_entry *current = ts.tree_first; int flag = -1; - while (current && (flag = pathcmp(current->name, name)) < 0) - current = current->next; + while (current && (flag = pathcmp (current->name, name)) < 0) + current = current->next; if (flag == 0) - return current; + return current; else - return NULL; + return NULL; } struct TreeStore * -tree_store_get(void) +tree_store_get (void) { return &ts; } static char * -decode(char *buffer) +decode (char *buffer) { - char *res = g_strdup(buffer); + char *res = g_strdup (buffer); char *p, *q; - for (p = q = res; *p; p++, q++) { - if (*p == '\n') { - *q = 0; - return res; - } + for (p = q = res; *p; p++, q++) + { + if (*p == '\n') + { + *q = 0; + return res; + } - if (*p != '\\') { - *q = *p; - continue; - } + if (*p != '\\') + { + *q = *p; + continue; + } - p++; + p++; - switch (*p) { - case 'n': - *q = '\n'; - break; - case '\\': - *q = '\\'; - break; - } + switch (*p) + { + case 'n': + *q = '\n'; + break; + case '\\': + *q = '\\'; + break; + } } *q = *p; @@ -174,7 +178,7 @@ decode(char *buffer) /* Loads the tree store from the specified filename */ static int -tree_store_load_from(char *name) +tree_store_load_from (char *name) { FILE *file; char buffer[MC_MAXPATHLEN + 20], oldname[MC_MAXPATHLEN]; @@ -182,78 +186,95 @@ tree_store_load_from(char *name) int len, common; int do_load; - g_return_val_if_fail(name != NULL, FALSE); + g_return_val_if_fail (name != NULL, FALSE); if (ts.loaded) - return TRUE; + return TRUE; - file = fopen(name, "r"); + file = fopen (name, "r"); - if (file) { - fgets(buffer, sizeof(buffer), file); + if (file) + { + if (fgets (buffer, sizeof (buffer), file) != NULL) + { + if (strncmp (buffer, TREE_SIGNATURE, strlen (TREE_SIGNATURE)) != 0) + { + fclose (file); + do_load = FALSE; + } + else + do_load = TRUE; + } + else + do_load = FALSE; + } + else + do_load = FALSE; - if (strncmp(buffer, TREE_SIGNATURE, strlen(TREE_SIGNATURE)) != 0) { - fclose(file); - do_load = FALSE; - } else - do_load = TRUE; - } else - do_load = FALSE; + if (do_load) + { + ts.loaded = TRUE; - if (do_load) { - ts.loaded = TRUE; + /* File open -> read contents */ + oldname[0] = 0; + while (fgets (buffer, MC_MAXPATHLEN, file)) + { + tree_entry *e; + int scanned; + char *lc_name; - /* File open -> read contents */ - oldname[0] = 0; - while (fgets(buffer, MC_MAXPATHLEN, file)) { - tree_entry *e; - int scanned; - char *lc_name; + /* Skip invalid records */ + if ((buffer[0] != '0' && buffer[0] != '1')) + continue; - /* Skip invalid records */ - if ((buffer[0] != '0' && buffer[0] != '1')) - continue; + if (buffer[1] != ':') + continue; - if (buffer[1] != ':') - continue; + scanned = buffer[0] == '1'; - scanned = buffer[0] == '1'; + lc_name = decode (buffer + 2); - lc_name = decode(buffer + 2); + len = strlen (lc_name); + if (lc_name[0] != PATH_SEP) + { + /* Clear-text decompression */ + char *s = strtok (lc_name, " "); - len = strlen(lc_name); - if (lc_name[0] != PATH_SEP) { - /* Clear-text decompression */ - char *s = strtok(lc_name, " "); - - if (s) { - common = atoi(s); - different = strtok(NULL, ""); - if (different) { - strcpy(oldname + common, different); - if (vfs_file_is_local(oldname)) { - e = tree_store_add_entry(oldname); - e->scanned = scanned; - } - } - } - } else { - if (vfs_file_is_local(lc_name)) { - e = tree_store_add_entry(lc_name); - e->scanned = scanned; - } - strcpy(oldname, lc_name); - } - g_free(lc_name); - } - fclose(file); + if (s) + { + common = atoi (s); + different = strtok (NULL, ""); + if (different) + { + strcpy (oldname + common, different); + if (vfs_file_is_local (oldname)) + { + e = tree_store_add_entry (oldname); + e->scanned = scanned; + } + } + } + } + else + { + if (vfs_file_is_local (lc_name)) + { + e = tree_store_add_entry (lc_name); + e->scanned = scanned; + } + strcpy (oldname, lc_name); + } + g_free (lc_name); + } + fclose (file); } /* Nothing loaded, we add some standard directories */ - if (!ts.tree_first) { - tree_store_add_entry(PATH_SEP_STR); - tree_store_rescan(PATH_SEP_STR); - ts.loaded = TRUE; + if (!ts.tree_first) + { + tree_store_add_entry (PATH_SEP_STR); + tree_store_rescan (PATH_SEP_STR); + ts.loaded = TRUE; } return TRUE; @@ -265,49 +286,53 @@ tree_store_load_from(char *name) * \return 1 if success (true), 0 otherwise (false) */ int -tree_store_load(void) +tree_store_load (void) { char *name; int retval; - name = g_build_filename (home_dir, MC_USERCONF_DIR, MC_TREESTORE_FILE, NULL); - retval = tree_store_load_from(name); - g_free(name); + name = g_build_filename (home_dir, MC_USERCONF_DIR, MC_TREESTORE_FILE, NULL); + retval = tree_store_load_from (name); + g_free (name); return retval; } static char * -encode(const char *string) +encode (const char *string) { int special_chars; const char *p; char *q; char *res; - for (special_chars = 0, p = string; *p; p++) { - if (*p == '\n' || *p == '\\') - special_chars++; + for (special_chars = 0, p = string; *p; p++) + { + if (*p == '\n' || *p == '\\') + special_chars++; } - res = g_malloc(p - string + special_chars + 1); - for (p = string, q = res; *p; p++, q++) { - if (*p != '\n' && *p != '\\') { - *q = *p; - continue; - } + res = g_malloc (p - string + special_chars + 1); + for (p = string, q = res; *p; p++, q++) + { + if (*p != '\n' && *p != '\\') + { + *q = *p; + continue; + } - *q++ = '\\'; + *q++ = '\\'; - switch (*p) { - case '\n': - *q = 'n'; - break; + switch (*p) + { + case '\n': + *q = 'n'; + break; - case '\\': - *q = '\\'; - break; - } + case '\\': + *q = '\\'; + break; + } } *q = 0; return res; @@ -315,48 +340,51 @@ encode(const char *string) /* Saves the tree to the specified filename */ static int -tree_store_save_to(char *name) +tree_store_save_to (char *name) { tree_entry *current; FILE *file; - file = fopen(name, "w"); + file = fopen (name, "w"); if (!file) - return errno; + return errno; - fprintf(file, "%s\n", TREE_SIGNATURE); + fprintf (file, "%s\n", TREE_SIGNATURE); current = ts.tree_first; - while (current) { - int i, common; + while (current) + { + int i, common; - if (vfs_file_is_local(current->name)) { - /* Clear-text compression */ - if (current->prev - && (common = - str_common(current->prev->name, current->name)) > 2) { - char *encoded = encode(current->name + common); + if (vfs_file_is_local (current->name)) + { + /* Clear-text compression */ + if (current->prev && (common = str_common (current->prev->name, current->name)) > 2) + { + char *encoded = encode (current->name + common); - i = fprintf(file, "%d:%d %s\n", current->scanned, common, - encoded); - g_free(encoded); - } else { - char *encoded = encode(current->name); + i = fprintf (file, "%d:%d %s\n", current->scanned, common, encoded); + g_free (encoded); + } + else + { + char *encoded = encode (current->name); - i = fprintf(file, "%d:%s\n", current->scanned, encoded); - g_free(encoded); - } + i = fprintf (file, "%d:%s\n", current->scanned, encoded); + g_free (encoded); + } - if (i == EOF) { - fprintf(stderr, _("Cannot write to the %s file:\n%s\n"), - name, unix_error_string(errno)); - break; - } - } - current = current->next; + if (i == EOF) + { + fprintf (stderr, _("Cannot write to the %s file:\n%s\n"), + name, unix_error_string (errno)); + break; + } + } + current = current->next; } - tree_store_dirty(FALSE); - fclose(file); + tree_store_dirty (FALSE); + fclose (file); return 0; } @@ -367,7 +395,7 @@ tree_store_save_to(char *name) * \return 0 if success, errno on error */ int -tree_store_save(void) +tree_store_save (void) { char *name; int retval; @@ -375,19 +403,20 @@ tree_store_save(void) name = g_build_filename (home_dir, MC_USERCONF_DIR, MC_TREESTORE_FILE, NULL); mc_util_make_backup_if_possible (name, ".tmp"); - if ((retval = tree_store_save_to(name)) != 0) { - mc_util_restore_from_backup_if_possible (name, ".tmp"); - g_free(name); - return retval; + if ((retval = tree_store_save_to (name)) != 0) + { + mc_util_restore_from_backup_if_possible (name, ".tmp"); + g_free (name); + return retval; } mc_util_unlink_backup_if_possible (name, ".tmp"); - g_free(name); + g_free (name); return 0; } static tree_entry * -tree_store_add_entry(const char *name) +tree_store_add_entry (const char *name) { int flag = -1; tree_entry *current = ts.tree_first; @@ -397,59 +426,70 @@ tree_store_add_entry(const char *name) int submask = 0; if (ts.tree_last && ts.tree_last->next) - abort(); + abort (); /* Search for the correct place */ - while (current && (flag = pathcmp(current->name, name)) < 0) { - old = current; - current = current->next; + while (current && (flag = pathcmp (current->name, name)) < 0) + { + old = current; + current = current->next; } if (flag == 0) - return current; /* Already in the list */ + return current; /* Already in the list */ /* Not in the list -> add it */ - new = g_new0(tree_entry, 1); - if (!current) { - /* Append to the end of the list */ - if (!ts.tree_first) { - /* Empty list */ - ts.tree_first = new; - new->prev = NULL; - } else { - old->next = new; - new->prev = old; - } - new->next = NULL; - ts.tree_last = new; - } else { - /* Insert in to the middle of the list */ - new->prev = old; - if (old) { - /* Yes, in the middle */ - new->next = old->next; - old->next = new; - } else { - /* Nope, in the beginning of the list */ - new->next = ts.tree_first; - ts.tree_first = new; - } - new->next->prev = new; + new = g_new0 (tree_entry, 1); + if (!current) + { + /* Append to the end of the list */ + if (!ts.tree_first) + { + /* Empty list */ + ts.tree_first = new; + new->prev = NULL; + } + else + { + old->next = new; + new->prev = old; + } + new->next = NULL; + ts.tree_last = new; + } + else + { + /* Insert in to the middle of the list */ + new->prev = old; + if (old) + { + /* Yes, in the middle */ + new->next = old->next; + old->next = new; + } + else + { + /* Nope, in the beginning of the list */ + new->next = ts.tree_first; + ts.tree_first = new; + } + new->next->prev = new; } /* Calculate attributes */ - new->name = g_strdup(name); - len = strlen(new->name); + new->name = g_strdup (name); + len = strlen (new->name); new->sublevel = 0; for (i = 0; i < len; i++) - if (new->name[i] == PATH_SEP) { - new->sublevel++; - new->subname = new->name + i + 1; - } + if (new->name[i] == PATH_SEP) + { + new->sublevel++; + new->subname = new->name + i + 1; + } if (new->next) - submask = new->next->submask; + submask = new->next->submask; else - submask = 0; + submask = 0; submask |= 1 << new->sublevel; submask &= (2 << new->sublevel) - 1; new->submask = submask; @@ -457,223 +497,231 @@ tree_store_add_entry(const char *name) /* Correct the submasks of the previous entries */ current = new->prev; - while (current && current->sublevel > new->sublevel) { - current->submask |= 1 << new->sublevel; - current = current->prev; + while (current && current->sublevel > new->sublevel) + { + current->submask |= 1 << new->sublevel; + current = current->prev; } /* The entry has now been added */ - if (new->sublevel > 1) { - /* Let's check if the parent directory is in the tree */ - char *parent = g_strdup(new->name); + if (new->sublevel > 1) + { + /* Let's check if the parent directory is in the tree */ + char *parent = g_strdup (new->name); - for (i = strlen(parent) - 1; i > 1; i--) { - if (parent[i] == PATH_SEP) { - parent[i] = 0; - tree_store_add_entry(parent); - break; - } - } - g_free(parent); + for (i = strlen (parent) - 1; i > 1; i--) + { + if (parent[i] == PATH_SEP) + { + parent[i] = 0; + tree_store_add_entry (parent); + break; + } + } + g_free (parent); } - tree_store_dirty(TRUE); + tree_store_dirty (TRUE); return new; } static Hook *remove_entry_hooks; void -tree_store_add_entry_remove_hook(tree_store_remove_fn callback, void *data) +tree_store_add_entry_remove_hook (tree_store_remove_fn callback, void *data) { - add_hook(&remove_entry_hooks, (void (*)(void *)) callback, data); + add_hook (&remove_entry_hooks, (void (*)(void *)) callback, data); } void -tree_store_remove_entry_remove_hook(tree_store_remove_fn callback) +tree_store_remove_entry_remove_hook (tree_store_remove_fn callback) { - delete_hook(&remove_entry_hooks, (void (*)(void *)) callback); + delete_hook (&remove_entry_hooks, (void (*)(void *)) callback); } static void -tree_store_notify_remove(tree_entry * entry) +tree_store_notify_remove (tree_entry * entry) { Hook *p = remove_entry_hooks; tree_store_remove_fn r; - while (p) { - r = (tree_store_remove_fn) p->hook_fn; - r(entry, p->hook_data); - p = p->next; + while (p) + { + r = (tree_store_remove_fn) p->hook_fn; + r (entry, p->hook_data); + p = p->next; } } static tree_entry * -remove_entry(tree_entry * entry) +remove_entry (tree_entry * entry) { tree_entry *current = entry->prev; long submask = 0; tree_entry *ret = NULL; - tree_store_notify_remove(entry); + tree_store_notify_remove (entry); /* Correct the submasks of the previous entries */ if (entry->next) - submask = entry->next->submask; - while (current && current->sublevel > entry->sublevel) { - submask |= 1 << current->sublevel; - submask &= (2 << current->sublevel) - 1; - current->submask = submask; - current = current->prev; + submask = entry->next->submask; + while (current && current->sublevel > entry->sublevel) + { + submask |= 1 << current->sublevel; + submask &= (2 << current->sublevel) - 1; + current->submask = submask; + current = current->prev; } /* Unlink the entry from the list */ if (entry->prev) - entry->prev->next = entry->next; + entry->prev->next = entry->next; else - ts.tree_first = entry->next; + ts.tree_first = entry->next; if (entry->next) - entry->next->prev = entry->prev; + entry->next->prev = entry->prev; else - ts.tree_last = entry->prev; + ts.tree_last = entry->prev; /* Free the memory used by the entry */ - g_free(entry->name); - g_free(entry); + g_free (entry->name); + g_free (entry); return ret; } void -tree_store_remove_entry(const char *name) +tree_store_remove_entry (const char *name) { tree_entry *current, *base, *old; int len; - g_return_if_fail(name != NULL); + g_return_if_fail (name != NULL); /* Miguel Ugly hack */ if (name[0] == PATH_SEP && name[1] == 0) - return; + return; /* Miguel Ugly hack end */ - base = tree_store_whereis(name); + base = tree_store_whereis (name); if (!base) - return; /* Doesn't exist */ + return; /* Doesn't exist */ - len = strlen(base->name); + len = strlen (base->name); current = base->next; while (current - && strncmp(current->name, base->name, len) == 0 - && (current->name[len] == '\0' - || current->name[len] == PATH_SEP)) { - old = current; - current = current->next; - remove_entry(old); + && strncmp (current->name, base->name, len) == 0 + && (current->name[len] == '\0' || current->name[len] == PATH_SEP)) + { + old = current; + current = current->next; + remove_entry (old); } - remove_entry(base); - tree_store_dirty(TRUE); + remove_entry (base); + tree_store_dirty (TRUE); return; } /* This subdirectory exists -> clear deletion mark */ void -tree_store_mark_checked(const char *subname) +tree_store_mark_checked (const char *subname) { char *name; tree_entry *current, *base; int flag = 1, len; if (!ts.loaded) - return; + return; if (ts.check_name == NULL) - return; + return; /* Calculate the full name of the subdirectory */ - if (subname[0] == '.' && - (subname[1] == 0 || (subname[1] == '.' && subname[2] == 0))) - return; + if (subname[0] == '.' && (subname[1] == 0 || (subname[1] == '.' && subname[2] == 0))) + return; if (ts.check_name[0] == PATH_SEP && ts.check_name[1] == 0) - name = g_strconcat(PATH_SEP_STR, subname, (char *) NULL); + name = g_strconcat (PATH_SEP_STR, subname, (char *) NULL); else - name = concat_dir_and_file(ts.check_name, subname); + name = concat_dir_and_file (ts.check_name, subname); /* Search for the subdirectory */ current = ts.check_start; - while (current && (flag = pathcmp(current->name, name)) < 0) - current = current->next; + while (current && (flag = pathcmp (current->name, name)) < 0) + current = current->next; - if (flag != 0) { - /* Doesn't exist -> add it */ - current = tree_store_add_entry(name); - ts.add_queue = g_list_prepend(ts.add_queue, g_strdup(name)); + if (flag != 0) + { + /* Doesn't exist -> add it */ + current = tree_store_add_entry (name); + ts.add_queue = g_list_prepend (ts.add_queue, g_strdup (name)); } - g_free(name); + g_free (name); /* Clear the deletion mark from the subdirectory and its children */ base = current; - if (base) { - len = strlen(base->name); - base->mark = 0; - current = base->next; - while (current - && strncmp(current->name, base->name, len) == 0 - && (current->name[len] == '\0' - || current->name[len] == PATH_SEP || len == 1)) { - current->mark = 0; - current = current->next; - } + if (base) + { + len = strlen (base->name); + base->mark = 0; + current = base->next; + while (current + && strncmp (current->name, base->name, len) == 0 + && (current->name[len] == '\0' || current->name[len] == PATH_SEP || len == 1)) + { + current->mark = 0; + current = current->next; + } } } /* Mark the subdirectories of the current directory for delete */ tree_entry * -tree_store_start_check(const char *path) +tree_store_start_check (const char *path) { tree_entry *current, *retval; int len; if (!ts.loaded) - return NULL; + return NULL; - g_return_val_if_fail(ts.check_name == NULL, NULL); + g_return_val_if_fail (ts.check_name == NULL, NULL); ts.check_start = NULL; /* Search for the start of subdirectories */ - current = tree_store_whereis(path); - if (!current) { - struct stat s; + current = tree_store_whereis (path); + if (!current) + { + struct stat s; - if (mc_stat(path, &s) == -1) - return NULL; + if (mc_stat (path, &s) == -1) + return NULL; - if (!S_ISDIR(s.st_mode)) - return NULL; + if (!S_ISDIR (s.st_mode)) + return NULL; - current = tree_store_add_entry(path); - ts.check_name = g_strdup(path); + current = tree_store_add_entry (path); + ts.check_name = g_strdup (path); - return current; + return current; } - ts.check_name = g_strdup(path); + ts.check_name = g_strdup (path); retval = current; /* Mark old subdirectories for delete */ ts.check_start = current->next; - len = strlen(ts.check_name); + len = strlen (ts.check_name); current = ts.check_start; while (current - && strncmp(current->name, ts.check_name, len) == 0 - && (current->name[len] == '\0' || current->name[len] == PATH_SEP - || len == 1)) { - current->mark = 1; - current = current->next; + && strncmp (current->name, ts.check_name, len) == 0 + && (current->name[len] == '\0' || current->name[len] == PATH_SEP || len == 1)) + { + current->mark = 1; + current = current->next; } return retval; @@ -681,132 +729,141 @@ tree_store_start_check(const char *path) /* Delete subdirectories which still have the deletion mark */ void -tree_store_end_check(void) +tree_store_end_check (void) { tree_entry *current, *old; int len; GList *the_queue, *l; if (!ts.loaded) - return; + return; - g_return_if_fail(ts.check_name != NULL); + g_return_if_fail (ts.check_name != NULL); /* Check delete marks and delete if found */ - len = strlen(ts.check_name); + len = strlen (ts.check_name); current = ts.check_start; while (current - && strncmp(current->name, ts.check_name, len) == 0 - && (current->name[len] == '\0' || current->name[len] == PATH_SEP - || len == 1)) { - old = current; - current = current->next; - if (old->mark) - remove_entry(old); + && strncmp (current->name, ts.check_name, len) == 0 + && (current->name[len] == '\0' || current->name[len] == PATH_SEP || len == 1)) + { + old = current; + current = current->next; + if (old->mark) + remove_entry (old); } /* get the stuff in the scan order */ - ts.add_queue = g_list_reverse(ts.add_queue); + ts.add_queue = g_list_reverse (ts.add_queue); the_queue = ts.add_queue; ts.add_queue = NULL; - g_free(ts.check_name); + g_free (ts.check_name); ts.check_name = NULL; - for (l = the_queue; l; l = l->next) { - g_free(l->data); + for (l = the_queue; l; l = l->next) + { + g_free (l->data); } - g_list_free(the_queue); + g_list_free (the_queue); } static void -process_special_dirs(GList ** special_dirs, char *file) +process_special_dirs (GList ** special_dirs, char *file) { gchar **buffers, **start_buff; mc_config_t *cfg; gsize buffers_len; - cfg = mc_config_init(file); + cfg = mc_config_init (file); if (cfg == NULL) - return; + return; - start_buff = buffers = mc_config_get_string_list(cfg, "Special dirs", "list", &buffers_len); - if (buffers == NULL){ - mc_config_deinit(cfg); + start_buff = buffers = mc_config_get_string_list (cfg, "Special dirs", "list", &buffers_len); + if (buffers == NULL) + { + mc_config_deinit (cfg); return; } - while(*buffers) { - *special_dirs = g_list_prepend(*special_dirs, g_strdup(*buffers)); + while (*buffers) + { + *special_dirs = g_list_prepend (*special_dirs, g_strdup (*buffers)); buffers++; } - g_strfreev(start_buff); - mc_config_deinit(cfg); + g_strfreev (start_buff); + mc_config_deinit (cfg); } static gboolean -should_skip_directory(const char *dir) +should_skip_directory (const char *dir) { static GList *special_dirs; GList *l; static int loaded; - if (loaded == 0) { - loaded = 1; - setup_init(); - process_special_dirs(&special_dirs, profile_name); - process_special_dirs(&special_dirs, global_profile_name); + if (loaded == 0) + { + loaded = 1; + setup_init (); + process_special_dirs (&special_dirs, profile_name); + process_special_dirs (&special_dirs, global_profile_name); } - for (l = special_dirs; l; l = l->next) { - if (strncmp(dir, l->data, strlen(l->data)) == 0) - return TRUE; + for (l = special_dirs; l; l = l->next) + { + if (strncmp (dir, l->data, strlen (l->data)) == 0) + return TRUE; } return FALSE; } tree_entry * -tree_store_rescan(const char *dir) +tree_store_rescan (const char *dir) { DIR *dirp; struct dirent *dp; struct stat buf; tree_entry *entry; - if (should_skip_directory(dir)) { - entry = tree_store_add_entry(dir); - entry->scanned = 1; + if (should_skip_directory (dir)) + { + entry = tree_store_add_entry (dir); + entry->scanned = 1; - return entry; + return entry; } - entry = tree_store_start_check(dir); + entry = tree_store_start_check (dir); if (!entry) - return NULL; + return NULL; - dirp = mc_opendir(dir); - if (dirp) { - for (dp = mc_readdir(dirp); dp; dp = mc_readdir(dirp)) { - char *full_name; + dirp = mc_opendir (dir); + if (dirp) + { + for (dp = mc_readdir (dirp); dp; dp = mc_readdir (dirp)) + { + char *full_name; - if (dp->d_name[0] == '.') { - if (dp->d_name[1] == 0 - || (dp->d_name[1] == '.' && dp->d_name[2] == 0)) - continue; - } + if (dp->d_name[0] == '.') + { + if (dp->d_name[1] == 0 || (dp->d_name[1] == '.' && dp->d_name[2] == 0)) + continue; + } - full_name = concat_dir_and_file(dir, dp->d_name); - if (mc_lstat(full_name, &buf) != -1) { - if (S_ISDIR(buf.st_mode)) - tree_store_mark_checked(dp->d_name); - } - g_free(full_name); - } - mc_closedir(dirp); + full_name = concat_dir_and_file (dir, dp->d_name); + if (mc_lstat (full_name, &buf) != -1) + { + if (S_ISDIR (buf.st_mode)) + tree_store_mark_checked (dp->d_name); + } + g_free (full_name); + } + mc_closedir (dirp); } - tree_store_end_check(); + tree_store_end_check (); entry->scanned = 1; return entry; diff --git a/src/widget.c b/src/widget.c index 90dd5215c..fb47afd0b 100644 --- a/src/widget.c +++ b/src/widget.c @@ -4,11 +4,11 @@ 2004, 2005, 2006, 2007, 2009 Free Software Foundation, Inc. Authors: 1994, 1995 Radek Doulik - 1994, 1995 Miguel de Icaza - 1995 Jakub Jelinek - 1996 Andrej Borsenkow - 1997 Norbert Warmuth - 2009, 2010 Andrew Borodin + 1994, 1995 Miguel de Icaza + 1995 Jakub Jelinek + 1996 Andrej Borsenkow + 1997 Norbert Warmuth + 2009, 2010 Andrew Borodin 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 @@ -71,10 +71,7 @@ widget_selectcolor (Widget * w, gboolean focused, gboolean hotkey) tty_setcolor (hotkey ? (focused ? DLG_HOT_FOCUSC (h) - : DLG_HOT_NORMALC (h)) - : (focused - ? DLG_FOCUSC (h) - : DLG_NORMALC (h))); + : DLG_HOT_NORMALC (h)) : (focused ? DLG_FOCUSC (h) : DLG_NORMALC (h))); } struct hotkey_t @@ -615,6 +612,8 @@ save_text_to_clip_file (const char *text) { int file; char *fname = NULL; + ssize_t ret; + size_t str_len; fname = g_build_filename (home_dir, EDIT_CLIP_FILE, NULL); file = mc_open (fname, O_CREAT | O_WRONLY | O_TRUNC, @@ -624,9 +623,10 @@ save_text_to_clip_file (const char *text) if (file == -1) return FALSE; - mc_write (file, (char *) text, strlen (text)); + str_len = strlen (text); + ret = mc_write (file, (char *) text, str_len); mc_close (file); - return TRUE; + return ret == (ssize_t) str_len; } static gboolean