1998-02-27 04:54:42 +00:00
|
|
|
/* Various utilities
|
2007-09-25 15:33:35 +00:00
|
|
|
Copyright (C) 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003,
|
|
|
|
2004, 2005, 2007 Free Software Foundation, Inc.
|
1998-02-27 04:54:42 +00:00
|
|
|
Written 1994, 1995, 1996 by:
|
|
|
|
Miguel de Icaza, Janne Kukonlehto, Dugan Porter,
|
|
|
|
Jakub Jelinek, Mauricio Plaza.
|
|
|
|
|
|
|
|
The file_date routine is mostly from GNU's fileutils package,
|
|
|
|
written by Richard Stallman and David MacKenzie.
|
|
|
|
|
|
|
|
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
|
2005-05-27 03:35:10 +00:00
|
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
1998-02-27 04:54:42 +00:00
|
|
|
|
|
|
|
#include <config.h>
|
2005-02-08 09:04:03 +00:00
|
|
|
|
|
|
|
#include <ctype.h>
|
|
|
|
#include <limits.h>
|
|
|
|
#include <stdarg.h>
|
1998-02-27 04:54:42 +00:00
|
|
|
#include <stdio.h>
|
2005-02-08 09:04:03 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
1998-02-27 04:54:42 +00:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
2005-02-08 09:04:03 +00:00
|
|
|
#include <unistd.h>
|
1998-02-27 04:54:42 +00:00
|
|
|
|
|
|
|
#include "global.h"
|
|
|
|
#include "profile.h"
|
2001-06-09 07:13:46 +00:00
|
|
|
#include "main.h" /* mc_home */
|
|
|
|
#include "cmd.h" /* guess_message_value */
|
2001-09-03 05:07:40 +00:00
|
|
|
#include "mountlist.h"
|
2002-09-22 07:40:56 +00:00
|
|
|
#include "win.h" /* xterm_flag */
|
2009-01-10 11:53:20 +01:00
|
|
|
#include "timefmt.h"
|
2008-12-29 00:56:59 +02:00
|
|
|
#include "strutil.h"
|
1998-02-27 04:54:42 +00:00
|
|
|
|
2001-06-05 22:49:15 +00:00
|
|
|
#ifdef HAVE_CHARSET
|
|
|
|
#include "charsets.h"
|
|
|
|
#endif
|
|
|
|
|
2002-07-29 23:12:31 +00:00
|
|
|
static const char app_text [] = "Midnight-Commander";
|
1998-02-27 04:54:42 +00:00
|
|
|
int easy_patterns = 1;
|
|
|
|
|
2004-08-19 11:26:48 +00:00
|
|
|
extern void str_replace(char *s, char from, char to)
|
|
|
|
{
|
|
|
|
for (; *s != '\0'; s++) {
|
|
|
|
if (*s == from)
|
|
|
|
*s = to;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-09-22 07:40:56 +00:00
|
|
|
static inline int
|
|
|
|
is_7bit_printable (unsigned char c)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
2002-09-22 07:40:56 +00:00
|
|
|
return (c > 31 && c < 127);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int
|
|
|
|
is_iso_printable (unsigned char c)
|
|
|
|
{
|
|
|
|
return ((c > 31 && c < 127) || c >= 160);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int
|
|
|
|
is_8bit_printable (unsigned char c)
|
|
|
|
{
|
|
|
|
/* "Full 8 bits output" doesn't work on xterm */
|
|
|
|
if (xterm_flag)
|
|
|
|
return is_iso_printable (c);
|
1998-02-27 04:54:42 +00:00
|
|
|
|
2002-09-22 07:40:56 +00:00
|
|
|
return (c > 31 && c != 127 && c != 155);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
is_printable (int c)
|
|
|
|
{
|
1998-02-27 04:54:42 +00:00
|
|
|
c &= 0xff;
|
2002-09-22 07:40:56 +00:00
|
|
|
|
2001-06-05 22:49:15 +00:00
|
|
|
#ifdef HAVE_CHARSET
|
2002-09-22 07:40:56 +00:00
|
|
|
/* "Display bits" is ignored, since the user controls the output
|
|
|
|
by setting the output codepage */
|
|
|
|
return is_8bit_printable (c);
|
2001-06-05 22:49:15 +00:00
|
|
|
#else
|
2002-09-22 07:40:56 +00:00
|
|
|
if (!eight_bit_clean)
|
|
|
|
return is_7bit_printable (c);
|
|
|
|
|
|
|
|
if (full_eight_bits) {
|
|
|
|
return is_8bit_printable (c);
|
1998-02-27 04:54:42 +00:00
|
|
|
} else
|
2002-09-22 07:40:56 +00:00
|
|
|
return is_iso_printable (c);
|
|
|
|
#endif /* !HAVE_CHARSET */
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
|
|
|
|
2005-02-05 13:03:11 +00:00
|
|
|
/* Calculates the message dimensions (lines and columns) */
|
2005-09-17 12:01:04 +00:00
|
|
|
void
|
|
|
|
msglen (const char *text, int *lines, int *columns)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
2005-02-05 13:03:11 +00:00
|
|
|
int nlines = 1; /* even the empty string takes one line */
|
|
|
|
int ncolumns = 0;
|
|
|
|
int colindex = 0;
|
|
|
|
|
|
|
|
for (; *text != '\0'; text++) {
|
|
|
|
if (*text == '\n') {
|
|
|
|
nlines++;
|
|
|
|
colindex = 0;
|
1998-02-27 04:54:42 +00:00
|
|
|
} else {
|
2005-02-05 13:03:11 +00:00
|
|
|
colindex++;
|
|
|
|
if (colindex > ncolumns)
|
|
|
|
ncolumns = colindex;
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
|
|
|
}
|
2005-02-05 13:03:11 +00:00
|
|
|
|
|
|
|
*lines = nlines;
|
|
|
|
*columns = ncolumns;
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
|
|
|
|
2002-09-10 19:58:33 +00:00
|
|
|
/*
|
|
|
|
* Copy from s to d, and trim the beginning if necessary, and prepend
|
|
|
|
* "..." in this case. The destination string can have at most len
|
|
|
|
* bytes, not counting trailing 0.
|
|
|
|
*/
|
|
|
|
char *
|
2004-08-29 16:42:40 +00:00
|
|
|
trim (const char *s, char *d, int len)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
2002-09-10 19:58:33 +00:00
|
|
|
int source_len;
|
|
|
|
|
2002-09-10 21:39:07 +00:00
|
|
|
/* Sanity check */
|
|
|
|
len = max (len, 0);
|
2002-09-10 19:58:33 +00:00
|
|
|
|
|
|
|
source_len = strlen (s);
|
|
|
|
if (source_len > len) {
|
2002-09-10 21:39:07 +00:00
|
|
|
/* Cannot fit the whole line */
|
|
|
|
if (len <= 3) {
|
|
|
|
/* We only have room for the dots */
|
|
|
|
memset (d, '.', len);
|
|
|
|
d[len] = 0;
|
|
|
|
return d;
|
|
|
|
} else {
|
|
|
|
/* Begin with ... and add the rest of the source string */
|
|
|
|
memset (d, '.', 3);
|
|
|
|
strcpy (d + 3, s + 3 + source_len - len);
|
|
|
|
}
|
1998-02-27 04:54:42 +00:00
|
|
|
} else
|
2002-09-10 21:39:07 +00:00
|
|
|
/* We can copy the whole line */
|
1998-02-27 04:54:42 +00:00
|
|
|
strcpy (d, s);
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
|
2003-01-28 22:52:04 +00:00
|
|
|
/*
|
|
|
|
* Quote the filename for the purpose of inserting it into the command
|
|
|
|
* line. If quote_percent is 1, replace "%" with "%%" - the percent is
|
|
|
|
* processed by the mc command line.
|
|
|
|
*/
|
1998-02-27 04:54:42 +00:00
|
|
|
char *
|
|
|
|
name_quote (const char *s, int quote_percent)
|
|
|
|
{
|
|
|
|
char *ret, *d;
|
2003-01-28 22:52:04 +00:00
|
|
|
|
|
|
|
d = ret = g_malloc (strlen (s) * 2 + 2 + 1);
|
1998-02-27 04:54:42 +00:00
|
|
|
if (*s == '-') {
|
2003-01-28 22:52:04 +00:00
|
|
|
*d++ = '.';
|
|
|
|
*d++ = '/';
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for (; *s; s++, d++) {
|
2003-01-28 22:52:04 +00:00
|
|
|
switch (*s) {
|
|
|
|
case '%':
|
|
|
|
if (quote_percent)
|
|
|
|
*d++ = '%';
|
|
|
|
break;
|
|
|
|
case '\'':
|
|
|
|
case '\\':
|
|
|
|
case '\r':
|
|
|
|
case '\n':
|
|
|
|
case '\t':
|
|
|
|
case '"':
|
|
|
|
case ';':
|
|
|
|
case ' ':
|
|
|
|
case '?':
|
|
|
|
case '|':
|
|
|
|
case '[':
|
|
|
|
case ']':
|
|
|
|
case '{':
|
|
|
|
case '}':
|
|
|
|
case '<':
|
|
|
|
case '>':
|
|
|
|
case '`':
|
|
|
|
case '!':
|
|
|
|
case '$':
|
|
|
|
case '&':
|
|
|
|
case '*':
|
|
|
|
case '(':
|
|
|
|
case ')':
|
|
|
|
*d++ = '\\';
|
|
|
|
break;
|
|
|
|
case '~':
|
|
|
|
case '#':
|
|
|
|
if (d == ret)
|
1998-02-27 04:54:42 +00:00
|
|
|
*d++ = '\\';
|
2003-01-28 22:52:04 +00:00
|
|
|
break;
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
|
|
|
*d = *s;
|
|
|
|
}
|
|
|
|
*d = '\0';
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *
|
|
|
|
fake_name_quote (const char *s, int quote_percent)
|
|
|
|
{
|
2005-02-08 22:33:52 +00:00
|
|
|
(void) quote_percent;
|
Glibing..... (2)
Wed Jan 27 03:17:44 1999 Timur Bakeyev <mc@bat.ru>
* Converted memory managment to Glib. Now we use g_new()/g_malloc()/
g_strdup()/g_free() routings. Also, copy_strings() replaced by
g_strconcat(), strcasecmp() -> g_strcasecmp(),and sprintf() by
g_snprintf().
* Some sequences of malloc()/sprintf() changed to g_strdup_printf().
* mad.[ch]: Modified, to work with new GLib's memory managment. Fixed
a missing #undef for tempnam, which caused dead loop. Add several new
functions to emulate GLib memory managment.
*main.c, mad.[ch]: Add a new switch "-M", which allows to redirect MAD
messages to the file.
* util.[ch], utilunix.c: Modified, deleted our variants of strcasecmp()
and strdup() - we have g_ equivalences. Remove get_full_name() - it is
similar to concat_dir_and_file(). Some other tricks with g_* functions.
* global.h: Modified, extended. Now it is main memory mangment include -
i.e. all inclusions of <stdlib.h>, <malloc.h>, <glib.h>, "fs.h", "mem.h",
"util.h" and "mad.h" done there. This elimanates problem with proper or-
der of #include's.
* All around the source - changed order of #include's, most of them gone
to global.h (see above), minor changes, like "0" -> NULL in string func-
tions.
1999-01-27 01:08:30 +00:00
|
|
|
return g_strdup (s);
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
|
|
|
|
2002-09-27 21:20:41 +00:00
|
|
|
/*
|
|
|
|
* Remove the middle part of the string to fit given length.
|
|
|
|
* Use "~" to show where the string was truncated.
|
|
|
|
* Return static buffer, no need to free() it.
|
1998-02-27 04:54:42 +00:00
|
|
|
*/
|
2004-08-29 16:42:40 +00:00
|
|
|
const char *
|
2002-09-27 21:20:41 +00:00
|
|
|
name_trunc (const char *txt, int trunc_len)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
patches by Rostislav Beneš: mc-28-fix
rest of fixes in files cmc.c, main.c (xterm title), panelize.c, subshell.c,
tree.c, tty.c, user.c, util.c, win.c
now, basic mc's function should work well, editor and view are still broken.
2008-12-29 01:53:08 +02:00
|
|
|
return str_trunc (txt, trunc_len);
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
|
|
|
|
2004-11-03 19:43:17 +00:00
|
|
|
/*
|
|
|
|
* path_trunc() is the same as name_trunc() above but
|
|
|
|
* it deletes possible password from path for security
|
|
|
|
* reasons.
|
|
|
|
*/
|
|
|
|
const char *
|
|
|
|
path_trunc (const char *path, int trunc_len) {
|
|
|
|
char *secure_path = strip_password (g_strdup (path), 1);
|
|
|
|
|
patches by Rostislav Beneš: mc-28-fix
rest of fixes in files cmc.c, main.c (xterm title), panelize.c, subshell.c,
tree.c, tty.c, user.c, util.c, win.c
now, basic mc's function should work well, editor and view are still broken.
2008-12-29 01:53:08 +02:00
|
|
|
const char *ret = str_trunc (secure_path, trunc_len);
|
2004-11-03 19:43:17 +00:00
|
|
|
g_free (secure_path);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2005-09-17 12:01:04 +00:00
|
|
|
const char *
|
|
|
|
size_trunc (double size)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
Glibing..... (2)
Wed Jan 27 03:17:44 1999 Timur Bakeyev <mc@bat.ru>
* Converted memory managment to Glib. Now we use g_new()/g_malloc()/
g_strdup()/g_free() routings. Also, copy_strings() replaced by
g_strconcat(), strcasecmp() -> g_strcasecmp(),and sprintf() by
g_snprintf().
* Some sequences of malloc()/sprintf() changed to g_strdup_printf().
* mad.[ch]: Modified, to work with new GLib's memory managment. Fixed
a missing #undef for tempnam, which caused dead loop. Add several new
functions to emulate GLib memory managment.
*main.c, mad.[ch]: Add a new switch "-M", which allows to redirect MAD
messages to the file.
* util.[ch], utilunix.c: Modified, deleted our variants of strcasecmp()
and strdup() - we have g_ equivalences. Remove get_full_name() - it is
similar to concat_dir_and_file(). Some other tricks with g_* functions.
* global.h: Modified, extended. Now it is main memory mangment include -
i.e. all inclusions of <stdlib.h>, <malloc.h>, <glib.h>, "fs.h", "mem.h",
"util.h" and "mad.h" done there. This elimanates problem with proper or-
der of #include's.
* All around the source - changed order of #include's, most of them gone
to global.h (see above), minor changes, like "0" -> NULL in string func-
tions.
1999-01-27 01:08:30 +00:00
|
|
|
static char x [BUF_TINY];
|
1998-02-27 04:54:42 +00:00
|
|
|
long int divisor = 1;
|
2004-08-29 16:42:40 +00:00
|
|
|
const char *xtra = "";
|
1998-02-27 04:54:42 +00:00
|
|
|
|
|
|
|
if (size > 999999999L){
|
|
|
|
divisor = 1024;
|
2003-01-22 07:07:05 +00:00
|
|
|
xtra = "K";
|
1998-02-27 04:54:42 +00:00
|
|
|
if (size/divisor > 999999999L){
|
|
|
|
divisor = 1024*1024;
|
2003-01-22 07:07:05 +00:00
|
|
|
xtra = "M";
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
|
|
|
}
|
2000-06-15 07:03:49 +00:00
|
|
|
g_snprintf (x, sizeof (x), "%.0f%s", (size/divisor), xtra);
|
1998-02-27 04:54:42 +00:00
|
|
|
return x;
|
|
|
|
}
|
|
|
|
|
2005-09-17 12:01:04 +00:00
|
|
|
const char *
|
|
|
|
size_trunc_sep (double size)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
|
|
|
static char x [60];
|
|
|
|
int count;
|
2004-08-29 23:20:01 +00:00
|
|
|
const char *p, *y;
|
|
|
|
char *d;
|
1998-02-27 04:54:42 +00:00
|
|
|
|
|
|
|
p = y = size_trunc (size);
|
|
|
|
p += strlen (p) - 1;
|
|
|
|
d = x + sizeof (x) - 1;
|
|
|
|
*d-- = 0;
|
2002-07-03 19:47:40 +00:00
|
|
|
while (p >= y && isalpha ((unsigned char) *p))
|
1998-02-27 04:54:42 +00:00
|
|
|
*d-- = *p--;
|
|
|
|
for (count = 0; p >= y; count++){
|
|
|
|
if (count == 3){
|
|
|
|
*d-- = ',';
|
|
|
|
count = 0;
|
|
|
|
}
|
|
|
|
*d-- = *p--;
|
|
|
|
}
|
|
|
|
d++;
|
|
|
|
if (*d == ',')
|
|
|
|
d++;
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
|
2001-06-28 04:17:28 +00:00
|
|
|
/*
|
|
|
|
* Print file SIZE to BUFFER, but don't exceed LEN characters,
|
|
|
|
* not including trailing 0. BUFFER should be at least LEN+1 long.
|
|
|
|
* This function is called for every file on panels, so avoid
|
|
|
|
* floating point by any means.
|
2001-08-30 16:41:08 +00:00
|
|
|
*
|
|
|
|
* Units: size units (filesystem sizes are 1K blocks)
|
|
|
|
* 0=bytes, 1=Kbytes, 2=Mbytes, etc.
|
2001-06-28 04:17:28 +00:00
|
|
|
*/
|
|
|
|
void
|
2001-08-30 16:41:08 +00:00
|
|
|
size_trunc_len (char *buffer, int len, off_t size, int units)
|
2001-06-28 04:17:28 +00:00
|
|
|
{
|
|
|
|
/* Avoid taking power for every file. */
|
|
|
|
static const off_t power10 [] =
|
|
|
|
{1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000,
|
|
|
|
1000000000};
|
2001-07-31 10:38:15 +00:00
|
|
|
static const char * const suffix [] =
|
2001-06-28 04:17:28 +00:00
|
|
|
{"", "K", "M", "G", "T", "P", "E", "Z", "Y", NULL};
|
|
|
|
int j = 0;
|
|
|
|
|
|
|
|
/* Don't print more than 9 digits - use suffix. */
|
|
|
|
if (len == 0 || len > 9)
|
|
|
|
len = 9;
|
|
|
|
|
2001-08-30 16:41:08 +00:00
|
|
|
for (j = units; suffix [j] != NULL; j++) {
|
2001-08-30 16:19:45 +00:00
|
|
|
if (size == 0) {
|
2001-08-30 16:41:08 +00:00
|
|
|
if (j == units) {
|
2001-08-30 16:19:45 +00:00
|
|
|
/* Empty files will print "0" even with minimal width. */
|
|
|
|
g_snprintf (buffer, len + 1, "0");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Use "~K" or just "K" if len is 1. Use "B" for bytes. */
|
|
|
|
g_snprintf (buffer, len + 1, (len > 1) ? "~%s" : "%s",
|
|
|
|
(j > 1) ? suffix[j - 1] : "B");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2001-06-28 04:17:28 +00:00
|
|
|
if (size < power10 [len - (j > 0)]) {
|
|
|
|
g_snprintf (buffer, len + 1, "%lu%s", (unsigned long) size, suffix[j]);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2001-08-30 16:19:45 +00:00
|
|
|
/* Powers of 1024, with rounding. */
|
|
|
|
size = (size + 512) >> 10;
|
2001-06-28 04:17:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-09-17 12:01:04 +00:00
|
|
|
int
|
|
|
|
is_exe (mode_t mode)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
|
|
|
if ((S_IXUSR & mode) || (S_IXGRP & mode) || (S_IXOTH & mode))
|
|
|
|
return 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define ismode(n,m) ((n & m) == m)
|
|
|
|
|
2004-08-29 23:20:01 +00:00
|
|
|
const char *
|
2002-09-06 19:23:45 +00:00
|
|
|
string_perm (mode_t mode_bits)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
2002-09-06 19:23:45 +00:00
|
|
|
static char mode[11];
|
1998-02-27 04:54:42 +00:00
|
|
|
|
|
|
|
strcpy (mode, "----------");
|
2002-09-06 19:23:45 +00:00
|
|
|
if (S_ISDIR (mode_bits))
|
|
|
|
mode[0] = 'd';
|
|
|
|
if (S_ISCHR (mode_bits))
|
|
|
|
mode[0] = 'c';
|
|
|
|
if (S_ISBLK (mode_bits))
|
|
|
|
mode[0] = 'b';
|
|
|
|
if (S_ISLNK (mode_bits))
|
|
|
|
mode[0] = 'l';
|
|
|
|
if (S_ISFIFO (mode_bits))
|
|
|
|
mode[0] = 'p';
|
2004-11-03 20:31:59 +00:00
|
|
|
if (S_ISNAM (mode_bits))
|
|
|
|
mode[0] = 'n';
|
2002-09-06 19:23:45 +00:00
|
|
|
if (S_ISSOCK (mode_bits))
|
|
|
|
mode[0] = 's';
|
|
|
|
if (S_ISDOOR (mode_bits))
|
|
|
|
mode[0] = 'D';
|
|
|
|
if (ismode (mode_bits, S_IXOTH))
|
|
|
|
mode[9] = 'x';
|
|
|
|
if (ismode (mode_bits, S_IWOTH))
|
|
|
|
mode[8] = 'w';
|
|
|
|
if (ismode (mode_bits, S_IROTH))
|
|
|
|
mode[7] = 'r';
|
|
|
|
if (ismode (mode_bits, S_IXGRP))
|
|
|
|
mode[6] = 'x';
|
|
|
|
if (ismode (mode_bits, S_IWGRP))
|
|
|
|
mode[5] = 'w';
|
|
|
|
if (ismode (mode_bits, S_IRGRP))
|
|
|
|
mode[4] = 'r';
|
|
|
|
if (ismode (mode_bits, S_IXUSR))
|
|
|
|
mode[3] = 'x';
|
|
|
|
if (ismode (mode_bits, S_IWUSR))
|
|
|
|
mode[2] = 'w';
|
|
|
|
if (ismode (mode_bits, S_IRUSR))
|
|
|
|
mode[1] = 'r';
|
|
|
|
#ifdef S_ISUID
|
|
|
|
if (ismode (mode_bits, S_ISUID))
|
|
|
|
mode[3] = (mode[3] == 'x') ? 's' : 'S';
|
|
|
|
#endif /* S_ISUID */
|
|
|
|
#ifdef S_ISGID
|
|
|
|
if (ismode (mode_bits, S_ISGID))
|
|
|
|
mode[6] = (mode[6] == 'x') ? 's' : 'S';
|
|
|
|
#endif /* S_ISGID */
|
|
|
|
#ifdef S_ISVTX
|
|
|
|
if (ismode (mode_bits, S_ISVTX))
|
|
|
|
mode[9] = (mode[9] == 'x') ? 't' : 'T';
|
|
|
|
#endif /* S_ISVTX */
|
1998-02-27 04:54:42 +00:00
|
|
|
return mode;
|
|
|
|
}
|
|
|
|
|
1999-02-03 23:19:40 +00:00
|
|
|
/* p: string which might contain an url with a password (this parameter is
|
|
|
|
modified in place).
|
|
|
|
has_prefix = 0: The first parameter is an url without a prefix
|
|
|
|
(user[:pass]@]machine[:port][remote-dir). Delete
|
|
|
|
the password.
|
|
|
|
has_prefix = 1: Search p for known url prefixes. If found delete
|
|
|
|
the password from the url.
|
2004-10-13 12:23:56 +00:00
|
|
|
Caveat: only the first url is found
|
1999-02-03 23:19:40 +00:00
|
|
|
*/
|
|
|
|
char *
|
|
|
|
strip_password (char *p, int has_prefix)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
2001-07-31 10:38:15 +00:00
|
|
|
static const struct {
|
2004-08-29 23:20:01 +00:00
|
|
|
const char *name;
|
1999-02-03 23:19:40 +00:00
|
|
|
size_t len;
|
|
|
|
} prefixes[] = { {"/#ftp:", 6},
|
1999-08-06 19:24:04 +00:00
|
|
|
{"ftp://", 6},
|
2005-02-12 14:30:48 +00:00
|
|
|
{"/#mc:", 5},
|
|
|
|
{"mc://", 5},
|
1999-08-06 19:24:04 +00:00
|
|
|
{"/#smb:", 6},
|
2005-02-12 14:30:48 +00:00
|
|
|
{"smb://", 6},
|
|
|
|
{"/#sh:", 5},
|
|
|
|
{"sh://", 5},
|
|
|
|
{"ssh://", 6}
|
1999-02-03 23:19:40 +00:00
|
|
|
};
|
1998-02-27 04:54:42 +00:00
|
|
|
char *at, *inner_colon, *dir;
|
2004-08-16 03:12:05 +00:00
|
|
|
size_t i;
|
1999-02-03 23:19:40 +00:00
|
|
|
char *result = p;
|
1998-02-27 04:54:42 +00:00
|
|
|
|
1999-02-03 23:19:40 +00:00
|
|
|
for (i = 0; i < sizeof (prefixes)/sizeof (prefixes[0]); i++) {
|
|
|
|
char *q;
|
|
|
|
|
|
|
|
if (has_prefix) {
|
|
|
|
if((q = strstr (p, prefixes[i].name)) == 0)
|
|
|
|
continue;
|
|
|
|
else
|
|
|
|
p = q + prefixes[i].len;
|
2004-11-09 12:30:29 +00:00
|
|
|
}
|
1999-02-03 23:19:40 +00:00
|
|
|
|
|
|
|
if ((dir = strchr (p, PATH_SEP)) != NULL)
|
|
|
|
*dir = '\0';
|
2004-11-09 12:30:29 +00:00
|
|
|
|
1999-02-03 23:19:40 +00:00
|
|
|
/* search for any possible user */
|
2004-10-05 14:25:28 +00:00
|
|
|
at = strrchr (p, '@');
|
1999-02-03 23:19:40 +00:00
|
|
|
|
2004-11-09 12:30:29 +00:00
|
|
|
if (dir)
|
|
|
|
*dir = PATH_SEP;
|
|
|
|
|
1999-02-03 23:19:40 +00:00
|
|
|
/* We have a username */
|
|
|
|
if (at) {
|
2004-11-09 12:30:29 +00:00
|
|
|
inner_colon = memchr (p, ':', at - p);
|
1999-02-03 23:19:40 +00:00
|
|
|
if (inner_colon)
|
2004-11-09 12:30:29 +00:00
|
|
|
memmove (inner_colon, at, strlen(at) + 1);
|
1999-02-03 23:19:40 +00:00
|
|
|
}
|
|
|
|
break;
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
1999-02-03 23:19:40 +00:00
|
|
|
return (result);
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
|
|
|
|
2005-09-17 12:01:04 +00:00
|
|
|
const char *
|
|
|
|
strip_home_and_password(const char *dir)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
1999-04-28 04:03:30 +00:00
|
|
|
size_t len;
|
1998-05-26 00:53:24 +00:00
|
|
|
static char newdir [MC_MAXPATHLEN];
|
1998-02-27 04:54:42 +00:00
|
|
|
|
1999-04-28 04:03:30 +00:00
|
|
|
if (home_dir && !strncmp (dir, home_dir, len = strlen (home_dir)) &&
|
|
|
|
(dir[len] == PATH_SEP || dir[len] == '\0')){
|
1998-02-27 04:54:42 +00:00
|
|
|
newdir [0] = '~';
|
2004-09-19 12:45:43 +00:00
|
|
|
g_strlcpy (&newdir [1], &dir [len], sizeof(newdir) - 1);
|
1998-02-27 04:54:42 +00:00
|
|
|
return newdir;
|
|
|
|
}
|
1998-05-26 00:53:24 +00:00
|
|
|
|
1999-02-03 23:19:40 +00:00
|
|
|
/* We do not strip homes in /#ftp tree, I do not like ~'s there
|
|
|
|
(see ftpfs.c why) */
|
2004-09-19 12:45:43 +00:00
|
|
|
g_strlcpy (newdir, dir, sizeof(newdir));
|
1999-02-03 23:19:40 +00:00
|
|
|
strip_password (newdir, 1);
|
|
|
|
return newdir;
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
|
|
|
|
2005-09-17 12:01:04 +00:00
|
|
|
static char *
|
|
|
|
maybe_start_group (char *d, int do_group, int *was_wildcard)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
|
|
|
if (!do_group)
|
|
|
|
return d;
|
|
|
|
if (*was_wildcard)
|
|
|
|
return d;
|
|
|
|
*was_wildcard = 1;
|
|
|
|
*d++ = '\\';
|
|
|
|
*d++ = '(';
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
|
2005-09-17 12:01:04 +00:00
|
|
|
static char *
|
|
|
|
maybe_end_group (char *d, int do_group, int *was_wildcard)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
|
|
|
if (!do_group)
|
|
|
|
return d;
|
|
|
|
if (!*was_wildcard)
|
|
|
|
return d;
|
|
|
|
*was_wildcard = 0;
|
|
|
|
*d++ = '\\';
|
|
|
|
*d++ = ')';
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If shell patterns are on converts a shell pattern to a regular
|
|
|
|
expression. Called by regexp_match and mask_rename. */
|
|
|
|
/* Shouldn't we support [a-fw] type wildcards as well ?? */
|
2005-09-17 12:01:04 +00:00
|
|
|
char *
|
|
|
|
convert_pattern (const char *pattern, int match_type, int do_group)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
2004-08-29 23:20:01 +00:00
|
|
|
char *d;
|
1998-03-17 00:24:52 +00:00
|
|
|
char *new_pattern;
|
1998-02-27 04:54:42 +00:00
|
|
|
int was_wildcard = 0;
|
2004-08-29 23:20:01 +00:00
|
|
|
const char *s;
|
1998-02-27 04:54:42 +00:00
|
|
|
|
2003-06-07 00:37:28 +00:00
|
|
|
if ((match_type != match_regex) && easy_patterns){
|
Glibing..... (2)
Wed Jan 27 03:17:44 1999 Timur Bakeyev <mc@bat.ru>
* Converted memory managment to Glib. Now we use g_new()/g_malloc()/
g_strdup()/g_free() routings. Also, copy_strings() replaced by
g_strconcat(), strcasecmp() -> g_strcasecmp(),and sprintf() by
g_snprintf().
* Some sequences of malloc()/sprintf() changed to g_strdup_printf().
* mad.[ch]: Modified, to work with new GLib's memory managment. Fixed
a missing #undef for tempnam, which caused dead loop. Add several new
functions to emulate GLib memory managment.
*main.c, mad.[ch]: Add a new switch "-M", which allows to redirect MAD
messages to the file.
* util.[ch], utilunix.c: Modified, deleted our variants of strcasecmp()
and strdup() - we have g_ equivalences. Remove get_full_name() - it is
similar to concat_dir_and_file(). Some other tricks with g_* functions.
* global.h: Modified, extended. Now it is main memory mangment include -
i.e. all inclusions of <stdlib.h>, <malloc.h>, <glib.h>, "fs.h", "mem.h",
"util.h" and "mad.h" done there. This elimanates problem with proper or-
der of #include's.
* All around the source - changed order of #include's, most of them gone
to global.h (see above), minor changes, like "0" -> NULL in string func-
tions.
1999-01-27 01:08:30 +00:00
|
|
|
new_pattern = g_malloc (MC_MAXPATHLEN);
|
1998-02-27 04:54:42 +00:00
|
|
|
d = new_pattern;
|
|
|
|
if (match_type == match_file)
|
|
|
|
*d++ = '^';
|
|
|
|
for (s = pattern; *s; s++, d++){
|
|
|
|
switch (*s){
|
|
|
|
case '*':
|
|
|
|
d = maybe_start_group (d, do_group, &was_wildcard);
|
|
|
|
*d++ = '.';
|
|
|
|
*d = '*';
|
|
|
|
break;
|
|
|
|
|
|
|
|
case '?':
|
|
|
|
d = maybe_start_group (d, do_group, &was_wildcard);
|
|
|
|
*d = '.';
|
|
|
|
break;
|
|
|
|
|
|
|
|
case '.':
|
|
|
|
d = maybe_end_group (d, do_group, &was_wildcard);
|
|
|
|
*d++ = '\\';
|
|
|
|
*d = '.';
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
d = maybe_end_group (d, do_group, &was_wildcard);
|
|
|
|
*d = *s;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
d = maybe_end_group (d, do_group, &was_wildcard);
|
|
|
|
if (match_type == match_file)
|
|
|
|
*d++ = '$';
|
|
|
|
*d = 0;
|
|
|
|
return new_pattern;
|
|
|
|
} else
|
Glibing..... (2)
Wed Jan 27 03:17:44 1999 Timur Bakeyev <mc@bat.ru>
* Converted memory managment to Glib. Now we use g_new()/g_malloc()/
g_strdup()/g_free() routings. Also, copy_strings() replaced by
g_strconcat(), strcasecmp() -> g_strcasecmp(),and sprintf() by
g_snprintf().
* Some sequences of malloc()/sprintf() changed to g_strdup_printf().
* mad.[ch]: Modified, to work with new GLib's memory managment. Fixed
a missing #undef for tempnam, which caused dead loop. Add several new
functions to emulate GLib memory managment.
*main.c, mad.[ch]: Add a new switch "-M", which allows to redirect MAD
messages to the file.
* util.[ch], utilunix.c: Modified, deleted our variants of strcasecmp()
and strdup() - we have g_ equivalences. Remove get_full_name() - it is
similar to concat_dir_and_file(). Some other tricks with g_* functions.
* global.h: Modified, extended. Now it is main memory mangment include -
i.e. all inclusions of <stdlib.h>, <malloc.h>, <glib.h>, "fs.h", "mem.h",
"util.h" and "mad.h" done there. This elimanates problem with proper or-
der of #include's.
* All around the source - changed order of #include's, most of them gone
to global.h (see above), minor changes, like "0" -> NULL in string func-
tions.
1999-01-27 01:08:30 +00:00
|
|
|
return g_strdup (pattern);
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
|
|
|
|
2005-09-17 12:01:04 +00:00
|
|
|
int
|
|
|
|
regexp_match (const char *pattern, const char *string, int match_type)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
|
|
|
static regex_t r;
|
|
|
|
static char *old_pattern = NULL;
|
|
|
|
static int old_type;
|
|
|
|
int rval;
|
2004-08-29 23:20:01 +00:00
|
|
|
char *my_pattern;
|
1998-02-27 04:54:42 +00:00
|
|
|
|
|
|
|
if (!old_pattern || STRCOMP (old_pattern, pattern) || old_type != match_type){
|
|
|
|
if (old_pattern){
|
|
|
|
regfree (&r);
|
Glibing..... (2)
Wed Jan 27 03:17:44 1999 Timur Bakeyev <mc@bat.ru>
* Converted memory managment to Glib. Now we use g_new()/g_malloc()/
g_strdup()/g_free() routings. Also, copy_strings() replaced by
g_strconcat(), strcasecmp() -> g_strcasecmp(),and sprintf() by
g_snprintf().
* Some sequences of malloc()/sprintf() changed to g_strdup_printf().
* mad.[ch]: Modified, to work with new GLib's memory managment. Fixed
a missing #undef for tempnam, which caused dead loop. Add several new
functions to emulate GLib memory managment.
*main.c, mad.[ch]: Add a new switch "-M", which allows to redirect MAD
messages to the file.
* util.[ch], utilunix.c: Modified, deleted our variants of strcasecmp()
and strdup() - we have g_ equivalences. Remove get_full_name() - it is
similar to concat_dir_and_file(). Some other tricks with g_* functions.
* global.h: Modified, extended. Now it is main memory mangment include -
i.e. all inclusions of <stdlib.h>, <malloc.h>, <glib.h>, "fs.h", "mem.h",
"util.h" and "mad.h" done there. This elimanates problem with proper or-
der of #include's.
* All around the source - changed order of #include's, most of them gone
to global.h (see above), minor changes, like "0" -> NULL in string func-
tions.
1999-01-27 01:08:30 +00:00
|
|
|
g_free (old_pattern);
|
2000-12-18 16:42:20 +00:00
|
|
|
old_pattern = NULL;
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
2004-08-29 23:20:01 +00:00
|
|
|
my_pattern = convert_pattern (pattern, match_type, 0);
|
|
|
|
if (regcomp (&r, my_pattern, REG_EXTENDED|REG_NOSUB|MC_ARCH_FLAGS)) {
|
|
|
|
g_free (my_pattern);
|
1998-02-27 04:54:42 +00:00
|
|
|
return -1;
|
1998-03-17 00:24:52 +00:00
|
|
|
}
|
2004-08-29 23:20:01 +00:00
|
|
|
old_pattern = my_pattern;
|
1998-02-27 04:54:42 +00:00
|
|
|
old_type = match_type;
|
|
|
|
}
|
|
|
|
rval = !regexec (&r, string, 0, NULL, 0);
|
|
|
|
return rval;
|
|
|
|
}
|
|
|
|
|
2005-09-17 12:01:04 +00:00
|
|
|
const char *
|
|
|
|
extension (const char *filename)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
2004-12-02 19:39:21 +00:00
|
|
|
const char *d = strrchr (filename, '.');
|
|
|
|
return (d != NULL) ? d + 1 : "";
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
|
|
|
|
2005-09-17 12:01:04 +00:00
|
|
|
int
|
|
|
|
get_int (const char *file, const char *key, int def)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
|
|
|
return GetPrivateProfileInt (app_text, key, def, file);
|
|
|
|
}
|
|
|
|
|
2005-09-17 12:01:04 +00:00
|
|
|
int
|
|
|
|
set_int (const char *file, const char *key, int value)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
Glibing..... (2)
Wed Jan 27 03:17:44 1999 Timur Bakeyev <mc@bat.ru>
* Converted memory managment to Glib. Now we use g_new()/g_malloc()/
g_strdup()/g_free() routings. Also, copy_strings() replaced by
g_strconcat(), strcasecmp() -> g_strcasecmp(),and sprintf() by
g_snprintf().
* Some sequences of malloc()/sprintf() changed to g_strdup_printf().
* mad.[ch]: Modified, to work with new GLib's memory managment. Fixed
a missing #undef for tempnam, which caused dead loop. Add several new
functions to emulate GLib memory managment.
*main.c, mad.[ch]: Add a new switch "-M", which allows to redirect MAD
messages to the file.
* util.[ch], utilunix.c: Modified, deleted our variants of strcasecmp()
and strdup() - we have g_ equivalences. Remove get_full_name() - it is
similar to concat_dir_and_file(). Some other tricks with g_* functions.
* global.h: Modified, extended. Now it is main memory mangment include -
i.e. all inclusions of <stdlib.h>, <malloc.h>, <glib.h>, "fs.h", "mem.h",
"util.h" and "mad.h" done there. This elimanates problem with proper or-
der of #include's.
* All around the source - changed order of #include's, most of them gone
to global.h (see above), minor changes, like "0" -> NULL in string func-
tions.
1999-01-27 01:08:30 +00:00
|
|
|
char buffer [BUF_TINY];
|
1998-02-27 04:54:42 +00:00
|
|
|
|
Glibing..... (2)
Wed Jan 27 03:17:44 1999 Timur Bakeyev <mc@bat.ru>
* Converted memory managment to Glib. Now we use g_new()/g_malloc()/
g_strdup()/g_free() routings. Also, copy_strings() replaced by
g_strconcat(), strcasecmp() -> g_strcasecmp(),and sprintf() by
g_snprintf().
* Some sequences of malloc()/sprintf() changed to g_strdup_printf().
* mad.[ch]: Modified, to work with new GLib's memory managment. Fixed
a missing #undef for tempnam, which caused dead loop. Add several new
functions to emulate GLib memory managment.
*main.c, mad.[ch]: Add a new switch "-M", which allows to redirect MAD
messages to the file.
* util.[ch], utilunix.c: Modified, deleted our variants of strcasecmp()
and strdup() - we have g_ equivalences. Remove get_full_name() - it is
similar to concat_dir_and_file(). Some other tricks with g_* functions.
* global.h: Modified, extended. Now it is main memory mangment include -
i.e. all inclusions of <stdlib.h>, <malloc.h>, <glib.h>, "fs.h", "mem.h",
"util.h" and "mad.h" done there. This elimanates problem with proper or-
der of #include's.
* All around the source - changed order of #include's, most of them gone
to global.h (see above), minor changes, like "0" -> NULL in string func-
tions.
1999-01-27 01:08:30 +00:00
|
|
|
g_snprintf (buffer, sizeof (buffer), "%d", value);
|
1998-02-27 04:54:42 +00:00
|
|
|
return WritePrivateProfileString (app_text, key, buffer, file);
|
|
|
|
}
|
|
|
|
|
2005-09-07 08:47:22 +00:00
|
|
|
extern char *
|
|
|
|
get_config_string (const char *file, const char *key, const char *defval)
|
|
|
|
{
|
|
|
|
char buffer[1024];
|
|
|
|
(void)GetPrivateProfileString (app_text, key, defval, buffer, sizeof(buffer), file);
|
|
|
|
return g_strdup (buffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
extern void
|
|
|
|
set_config_string (const char *file, const char *key, const char *val)
|
|
|
|
{
|
|
|
|
(void)WritePrivateProfileString (app_text, key, val, file);
|
|
|
|
}
|
|
|
|
|
2005-09-17 12:01:04 +00:00
|
|
|
int
|
|
|
|
exist_file (const char *name)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
|
|
|
return access (name, R_OK) == 0;
|
|
|
|
}
|
|
|
|
|
2005-09-17 12:01:04 +00:00
|
|
|
char *
|
|
|
|
load_file (const char *filename)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
|
|
|
FILE *data_file;
|
|
|
|
struct stat s;
|
|
|
|
char *data;
|
|
|
|
long read_size;
|
|
|
|
|
2001-07-31 10:38:15 +00:00
|
|
|
if ((data_file = fopen (filename, "r")) == NULL){
|
1998-02-27 04:54:42 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2001-07-31 10:38:15 +00:00
|
|
|
if (fstat (fileno (data_file), &s) != 0){
|
|
|
|
fclose (data_file);
|
1998-02-27 04:54:42 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2004-08-16 16:22:14 +00:00
|
|
|
data = g_malloc (s.st_size+1);
|
1998-02-27 04:54:42 +00:00
|
|
|
read_size = fread (data, 1, s.st_size, data_file);
|
|
|
|
data [read_size] = 0;
|
|
|
|
fclose (data_file);
|
|
|
|
|
|
|
|
if (read_size > 0)
|
|
|
|
return data;
|
|
|
|
else {
|
Glibing..... (2)
Wed Jan 27 03:17:44 1999 Timur Bakeyev <mc@bat.ru>
* Converted memory managment to Glib. Now we use g_new()/g_malloc()/
g_strdup()/g_free() routings. Also, copy_strings() replaced by
g_strconcat(), strcasecmp() -> g_strcasecmp(),and sprintf() by
g_snprintf().
* Some sequences of malloc()/sprintf() changed to g_strdup_printf().
* mad.[ch]: Modified, to work with new GLib's memory managment. Fixed
a missing #undef for tempnam, which caused dead loop. Add several new
functions to emulate GLib memory managment.
*main.c, mad.[ch]: Add a new switch "-M", which allows to redirect MAD
messages to the file.
* util.[ch], utilunix.c: Modified, deleted our variants of strcasecmp()
and strdup() - we have g_ equivalences. Remove get_full_name() - it is
similar to concat_dir_and_file(). Some other tricks with g_* functions.
* global.h: Modified, extended. Now it is main memory mangment include -
i.e. all inclusions of <stdlib.h>, <malloc.h>, <glib.h>, "fs.h", "mem.h",
"util.h" and "mad.h" done there. This elimanates problem with proper or-
der of #include's.
* All around the source - changed order of #include's, most of them gone
to global.h (see above), minor changes, like "0" -> NULL in string func-
tions.
1999-01-27 01:08:30 +00:00
|
|
|
g_free (data);
|
1998-02-27 04:54:42 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-11-20 18:38:29 +00:00
|
|
|
char *
|
|
|
|
load_mc_home_file (const char *filename, char **allocated_filename)
|
2001-06-09 07:13:46 +00:00
|
|
|
{
|
|
|
|
char *hintfile_base, *hintfile;
|
|
|
|
char *lang;
|
|
|
|
char *data;
|
|
|
|
|
|
|
|
hintfile_base = concat_dir_and_file (mc_home, filename);
|
2001-09-16 00:18:39 +00:00
|
|
|
lang = guess_message_value ();
|
2001-06-09 07:13:46 +00:00
|
|
|
|
2004-09-24 15:05:28 +00:00
|
|
|
hintfile = g_strconcat (hintfile_base, ".", lang, (char *) NULL);
|
2001-06-09 07:13:46 +00:00
|
|
|
data = load_file (hintfile);
|
|
|
|
|
|
|
|
if (!data) {
|
|
|
|
g_free (hintfile);
|
2003-11-20 18:38:29 +00:00
|
|
|
/* Fall back to the two-letter language code */
|
|
|
|
if (lang[0] && lang[1])
|
|
|
|
lang[2] = 0;
|
2004-09-24 15:05:28 +00:00
|
|
|
hintfile = g_strconcat (hintfile_base, ".", lang, (char *) NULL);
|
2001-06-09 07:13:46 +00:00
|
|
|
data = load_file (hintfile);
|
|
|
|
|
|
|
|
if (!data) {
|
|
|
|
g_free (hintfile);
|
|
|
|
hintfile = hintfile_base;
|
|
|
|
data = load_file (hintfile_base);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free (lang);
|
|
|
|
|
|
|
|
if (hintfile != hintfile_base)
|
|
|
|
g_free (hintfile_base);
|
|
|
|
|
|
|
|
if (allocated_filename)
|
|
|
|
*allocated_filename = hintfile;
|
|
|
|
else
|
|
|
|
g_free (hintfile);
|
|
|
|
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
1999-04-30 12:41:41 +00:00
|
|
|
/* Check strftime() results. Some systems (i.e. Solaris) have different
|
|
|
|
short-month-name sizes for different locales */
|
2005-09-17 12:01:04 +00:00
|
|
|
size_t
|
|
|
|
i18n_checktimelength (void)
|
1999-04-30 12:41:41 +00:00
|
|
|
{
|
2008-12-29 00:56:59 +02:00
|
|
|
size_t length, a, b;
|
|
|
|
char buf [MB_LEN_MAX * MAX_I18NTIMELENGTH + 1];
|
1999-04-30 12:41:41 +00:00
|
|
|
time_t testtime = time (NULL);
|
2008-12-29 00:56:59 +02:00
|
|
|
strftime (buf, sizeof(buf) - 1, _("%b %e %H:%M"), localtime(&testtime));
|
|
|
|
a = str_term_width1 (buf);
|
|
|
|
strftime (buf, sizeof(buf) - 1, _("%b %e %Y"), localtime(&testtime));
|
|
|
|
b = str_term_width1 (buf);
|
|
|
|
|
|
|
|
length = max (a, b);
|
|
|
|
length = max (str_term_width1 (_("(invalid)")), length);
|
|
|
|
|
1999-04-30 12:41:41 +00:00
|
|
|
/* Don't handle big differences. Use standard value (email bug, please) */
|
|
|
|
if ( length > MAX_I18NTIMELENGTH || length < MIN_I18NTIMELENGTH )
|
2009-01-10 11:53:20 +01:00
|
|
|
length = STD_I18NTIMELENGTH;
|
1999-04-30 12:41:41 +00:00
|
|
|
|
|
|
|
return length;
|
|
|
|
}
|
|
|
|
|
2005-09-17 12:01:04 +00:00
|
|
|
const char *
|
|
|
|
file_date (time_t when)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
2008-12-29 00:56:59 +02:00
|
|
|
static char timebuf [MB_LEN_MAX * MAX_I18NTIMELENGTH + 1];
|
1998-02-27 04:54:42 +00:00
|
|
|
time_t current_time = time ((time_t) 0);
|
2008-12-29 00:56:59 +02:00
|
|
|
static int i18n = 0;
|
2004-09-19 15:55:58 +00:00
|
|
|
static const char *fmtyear, *fmttime;
|
|
|
|
const char *fmt;
|
1999-04-30 12:41:41 +00:00
|
|
|
|
2008-12-29 00:56:59 +02:00
|
|
|
if (!i18n){
|
1999-04-30 12:41:41 +00:00
|
|
|
/* strftime() format string for old dates */
|
|
|
|
fmtyear = _("%b %e %Y");
|
|
|
|
/* strftime() format string for recent dates */
|
|
|
|
fmttime = _("%b %e %H:%M");
|
2008-12-29 00:56:59 +02:00
|
|
|
i18n = 1;
|
1999-04-30 12:41:41 +00:00
|
|
|
}
|
1998-02-27 04:54:42 +00:00
|
|
|
|
|
|
|
if (current_time > when + 6L * 30L * 24L * 60L * 60L /* Old. */
|
|
|
|
|| current_time < when - 60L * 60L) /* In the future. */
|
|
|
|
/* The file is fairly old or in the future.
|
|
|
|
POSIX says the cutoff is 6 months old;
|
|
|
|
approximate this by 6*30 days.
|
|
|
|
Allow a 1 hour slop factor for what is considered "the future",
|
|
|
|
to allow for NFS server/client clock disagreement.
|
|
|
|
Show the year instead of the time of day. */
|
1999-04-06 19:00:16 +00:00
|
|
|
|
1999-04-30 12:41:41 +00:00
|
|
|
fmt = fmtyear;
|
1999-04-06 19:00:16 +00:00
|
|
|
else
|
1999-04-30 12:41:41 +00:00
|
|
|
fmt = fmttime;
|
2009-04-03 12:19:09 +00:00
|
|
|
|
|
|
|
FMT_LOCALTIME(timebuf, sizeof (timebuf), fmt, when);
|
2009-01-10 11:53:20 +01:00
|
|
|
|
1999-04-30 12:41:41 +00:00
|
|
|
return timebuf;
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
|
|
|
|
2005-09-17 12:01:04 +00:00
|
|
|
const char *
|
|
|
|
extract_line (const char *s, const char *top)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
Glibing..... (2)
Wed Jan 27 03:17:44 1999 Timur Bakeyev <mc@bat.ru>
* Converted memory managment to Glib. Now we use g_new()/g_malloc()/
g_strdup()/g_free() routings. Also, copy_strings() replaced by
g_strconcat(), strcasecmp() -> g_strcasecmp(),and sprintf() by
g_snprintf().
* Some sequences of malloc()/sprintf() changed to g_strdup_printf().
* mad.[ch]: Modified, to work with new GLib's memory managment. Fixed
a missing #undef for tempnam, which caused dead loop. Add several new
functions to emulate GLib memory managment.
*main.c, mad.[ch]: Add a new switch "-M", which allows to redirect MAD
messages to the file.
* util.[ch], utilunix.c: Modified, deleted our variants of strcasecmp()
and strdup() - we have g_ equivalences. Remove get_full_name() - it is
similar to concat_dir_and_file(). Some other tricks with g_* functions.
* global.h: Modified, extended. Now it is main memory mangment include -
i.e. all inclusions of <stdlib.h>, <malloc.h>, <glib.h>, "fs.h", "mem.h",
"util.h" and "mad.h" done there. This elimanates problem with proper or-
der of #include's.
* All around the source - changed order of #include's, most of them gone
to global.h (see above), minor changes, like "0" -> NULL in string func-
tions.
1999-01-27 01:08:30 +00:00
|
|
|
static char tmp_line [BUF_MEDIUM];
|
1998-02-27 04:54:42 +00:00
|
|
|
char *t = tmp_line;
|
|
|
|
|
2004-08-16 03:12:05 +00:00
|
|
|
while (*s && *s != '\n' && (size_t) (t - tmp_line) < sizeof (tmp_line)-1 && s < top)
|
1998-02-27 04:54:42 +00:00
|
|
|
*t++ = *s++;
|
|
|
|
*t = 0;
|
|
|
|
return tmp_line;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* FIXME: I should write a faster version of this (Aho-Corasick stuff) */
|
2005-09-17 12:01:04 +00:00
|
|
|
const char *
|
|
|
|
_icase_search (const char *text, const char *data, int *lng)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
2004-08-29 23:20:01 +00:00
|
|
|
const char *d = text;
|
|
|
|
const char *e = data;
|
1998-02-27 04:54:42 +00:00
|
|
|
int dlng = 0;
|
|
|
|
|
|
|
|
if (lng)
|
|
|
|
*lng = 0;
|
|
|
|
for (;*e; e++) {
|
|
|
|
while (*(e+1) == '\b' && *(e+2)) {
|
|
|
|
e += 2;
|
|
|
|
dlng += 2;
|
|
|
|
}
|
patches by Rostislav Beneš: mc-28-fix
rest of fixes in files cmc.c, main.c (xterm title), panelize.c, subshell.c,
tree.c, tty.c, user.c, util.c, win.c
now, basic mc's function should work well, editor and view are still broken.
2008-12-29 01:53:08 +02:00
|
|
|
if (g_ascii_toupper((gchar) *d) == g_ascii_toupper((gchar) *e))
|
1998-02-27 04:54:42 +00:00
|
|
|
d++;
|
|
|
|
else {
|
|
|
|
e -= d - text;
|
|
|
|
d = text;
|
|
|
|
dlng = 0;
|
|
|
|
}
|
|
|
|
if (!*d) {
|
|
|
|
if (lng)
|
|
|
|
*lng = strlen (text) + dlng;
|
|
|
|
return e+1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The basename routine */
|
2005-09-17 12:01:04 +00:00
|
|
|
const char *
|
|
|
|
x_basename (const char *s)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
2004-08-16 18:19:37 +00:00
|
|
|
const char *where;
|
Glibing..... (2)
Wed Jan 27 03:17:44 1999 Timur Bakeyev <mc@bat.ru>
* Converted memory managment to Glib. Now we use g_new()/g_malloc()/
g_strdup()/g_free() routings. Also, copy_strings() replaced by
g_strconcat(), strcasecmp() -> g_strcasecmp(),and sprintf() by
g_snprintf().
* Some sequences of malloc()/sprintf() changed to g_strdup_printf().
* mad.[ch]: Modified, to work with new GLib's memory managment. Fixed
a missing #undef for tempnam, which caused dead loop. Add several new
functions to emulate GLib memory managment.
*main.c, mad.[ch]: Add a new switch "-M", which allows to redirect MAD
messages to the file.
* util.[ch], utilunix.c: Modified, deleted our variants of strcasecmp()
and strdup() - we have g_ equivalences. Remove get_full_name() - it is
similar to concat_dir_and_file(). Some other tricks with g_* functions.
* global.h: Modified, extended. Now it is main memory mangment include -
i.e. all inclusions of <stdlib.h>, <malloc.h>, <glib.h>, "fs.h", "mem.h",
"util.h" and "mad.h" done there. This elimanates problem with proper or-
der of #include's.
* All around the source - changed order of #include's, most of them gone
to global.h (see above), minor changes, like "0" -> NULL in string func-
tions.
1999-01-27 01:08:30 +00:00
|
|
|
return ((where = strrchr (s, PATH_SEP))) ? where + 1 : s;
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-09-17 12:01:04 +00:00
|
|
|
const char *
|
|
|
|
unix_error_string (int error_num)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
Glibing..... (2)
Wed Jan 27 03:17:44 1999 Timur Bakeyev <mc@bat.ru>
* Converted memory managment to Glib. Now we use g_new()/g_malloc()/
g_strdup()/g_free() routings. Also, copy_strings() replaced by
g_strconcat(), strcasecmp() -> g_strcasecmp(),and sprintf() by
g_snprintf().
* Some sequences of malloc()/sprintf() changed to g_strdup_printf().
* mad.[ch]: Modified, to work with new GLib's memory managment. Fixed
a missing #undef for tempnam, which caused dead loop. Add several new
functions to emulate GLib memory managment.
*main.c, mad.[ch]: Add a new switch "-M", which allows to redirect MAD
messages to the file.
* util.[ch], utilunix.c: Modified, deleted our variants of strcasecmp()
and strdup() - we have g_ equivalences. Remove get_full_name() - it is
similar to concat_dir_and_file(). Some other tricks with g_* functions.
* global.h: Modified, extended. Now it is main memory mangment include -
i.e. all inclusions of <stdlib.h>, <malloc.h>, <glib.h>, "fs.h", "mem.h",
"util.h" and "mad.h" done there. This elimanates problem with proper or-
der of #include's.
* All around the source - changed order of #include's, most of them gone
to global.h (see above), minor changes, like "0" -> NULL in string func-
tions.
1999-01-27 01:08:30 +00:00
|
|
|
static char buffer [BUF_LARGE];
|
2003-05-29 04:33:38 +00:00
|
|
|
#if GLIB_MAJOR_VERSION >= 2
|
|
|
|
gchar *strerror_currentlocale;
|
1998-02-27 04:54:42 +00:00
|
|
|
|
2003-05-29 04:33:38 +00:00
|
|
|
strerror_currentlocale = g_locale_from_utf8(g_strerror (error_num), -1, NULL, NULL, NULL);
|
|
|
|
g_snprintf (buffer, sizeof (buffer), "%s (%d)",
|
|
|
|
strerror_currentlocale, error_num);
|
|
|
|
g_free(strerror_currentlocale);
|
|
|
|
#else
|
Glibing..... (2)
Wed Jan 27 03:17:44 1999 Timur Bakeyev <mc@bat.ru>
* Converted memory managment to Glib. Now we use g_new()/g_malloc()/
g_strdup()/g_free() routings. Also, copy_strings() replaced by
g_strconcat(), strcasecmp() -> g_strcasecmp(),and sprintf() by
g_snprintf().
* Some sequences of malloc()/sprintf() changed to g_strdup_printf().
* mad.[ch]: Modified, to work with new GLib's memory managment. Fixed
a missing #undef for tempnam, which caused dead loop. Add several new
functions to emulate GLib memory managment.
*main.c, mad.[ch]: Add a new switch "-M", which allows to redirect MAD
messages to the file.
* util.[ch], utilunix.c: Modified, deleted our variants of strcasecmp()
and strdup() - we have g_ equivalences. Remove get_full_name() - it is
similar to concat_dir_and_file(). Some other tricks with g_* functions.
* global.h: Modified, extended. Now it is main memory mangment include -
i.e. all inclusions of <stdlib.h>, <malloc.h>, <glib.h>, "fs.h", "mem.h",
"util.h" and "mad.h" done there. This elimanates problem with proper or-
der of #include's.
* All around the source - changed order of #include's, most of them gone
to global.h (see above), minor changes, like "0" -> NULL in string func-
tions.
1999-01-27 01:08:30 +00:00
|
|
|
g_snprintf (buffer, sizeof (buffer), "%s (%d)",
|
|
|
|
g_strerror (error_num), error_num);
|
2003-05-29 04:33:38 +00:00
|
|
|
#endif
|
1998-02-27 04:54:42 +00:00
|
|
|
return buffer;
|
|
|
|
}
|
|
|
|
|
2005-09-17 12:01:04 +00:00
|
|
|
const char *
|
|
|
|
skip_separators (const char *s)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
patches by Rostislav Beneš: mc-28-fix
rest of fixes in files cmc.c, main.c (xterm title), panelize.c, subshell.c,
tree.c, tty.c, user.c, util.c, win.c
now, basic mc's function should work well, editor and view are still broken.
2008-12-29 01:53:08 +02:00
|
|
|
const char *su = s;
|
|
|
|
|
|
|
|
for (;*su; str_cnext_char (&su))
|
|
|
|
if (*su != ' ' && *su != '\t' && *su != ',') break;
|
|
|
|
|
|
|
|
return su;
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
|
|
|
|
2005-09-17 12:01:04 +00:00
|
|
|
const char *
|
|
|
|
skip_numbers (const char *s)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
patches by Rostislav Beneš: mc-28-fix
rest of fixes in files cmc.c, main.c (xterm title), panelize.c, subshell.c,
tree.c, tty.c, user.c, util.c, win.c
now, basic mc's function should work well, editor and view are still broken.
2008-12-29 01:53:08 +02:00
|
|
|
const char *su = s;
|
|
|
|
|
|
|
|
for (;*su; str_cnext_char (&su))
|
|
|
|
if (!str_isdigit (su)) break;
|
|
|
|
|
|
|
|
return su;
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Remove all control sequences from the argument string. We define
|
|
|
|
* "control sequence", in a sort of pidgin BNF, as follows:
|
|
|
|
*
|
|
|
|
* control-seq = Esc non-'['
|
|
|
|
* | Esc '[' (0 or more digits or ';' or '?') (any other char)
|
|
|
|
*
|
|
|
|
* This scheme works for all the terminals described in my termcap /
|
|
|
|
* terminfo databases, except the Hewlett-Packard 70092 and some Wyse
|
|
|
|
* terminals. If I hear from a single person who uses such a terminal
|
|
|
|
* with MC, I'll be glad to add support for it. (Dugan)
|
2001-08-16 03:52:51 +00:00
|
|
|
* Non-printable characters are also removed.
|
1998-02-27 04:54:42 +00:00
|
|
|
*/
|
|
|
|
|
2005-09-17 12:01:04 +00:00
|
|
|
char *
|
|
|
|
strip_ctrl_codes (char *s)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
2001-08-16 03:52:51 +00:00
|
|
|
char *w; /* Current position where the stripped data is written */
|
|
|
|
char *r; /* Current position where the original data is read */
|
patches by Rostislav Beneš: mc-28-fix
rest of fixes in files cmc.c, main.c (xterm title), panelize.c, subshell.c,
tree.c, tty.c, user.c, util.c, win.c
now, basic mc's function should work well, editor and view are still broken.
2008-12-29 01:53:08 +02:00
|
|
|
char *n;
|
1998-02-27 04:54:42 +00:00
|
|
|
|
|
|
|
if (!s)
|
|
|
|
return 0;
|
2001-08-16 03:52:51 +00:00
|
|
|
|
2002-08-15 06:53:44 +00:00
|
|
|
for (w = s, r = s; *r; ) {
|
|
|
|
if (*r == ESC_CHAR) {
|
|
|
|
/* Skip the control sequence's arguments */ ;
|
2001-08-16 03:52:51 +00:00
|
|
|
if (*(++r) == '[') {
|
2002-08-15 06:53:44 +00:00
|
|
|
/* strchr() matches trailing binary 0 */
|
|
|
|
while (*(++r) && strchr ("0123456789;?", *r));
|
2001-08-16 03:52:51 +00:00
|
|
|
}
|
2002-08-15 06:53:44 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Now we are at the last character of the sequence.
|
|
|
|
* Skip it unless it's binary 0.
|
|
|
|
*/
|
|
|
|
if (*r)
|
|
|
|
r++;
|
|
|
|
continue;
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
2002-08-15 06:53:44 +00:00
|
|
|
|
patches by Rostislav Beneš: mc-28-fix
rest of fixes in files cmc.c, main.c (xterm title), panelize.c, subshell.c,
tree.c, tty.c, user.c, util.c, win.c
now, basic mc's function should work well, editor and view are still broken.
2008-12-29 01:53:08 +02:00
|
|
|
n = str_get_next_char (r);
|
|
|
|
if (str_isprint (r)) {
|
|
|
|
memmove (w, r, n - r);
|
|
|
|
w+= n - r;
|
|
|
|
}
|
|
|
|
r = n;
|
2002-08-15 06:53:44 +00:00
|
|
|
}
|
2001-08-16 03:52:51 +00:00
|
|
|
*w = 0;
|
1998-02-27 04:54:42 +00:00
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-07-27 21:20:43 +00:00
|
|
|
#ifndef USE_VFS
|
2005-09-17 12:01:04 +00:00
|
|
|
char *
|
|
|
|
get_current_wd (char *buffer, int size)
|
2001-07-27 21:20:43 +00:00
|
|
|
{
|
|
|
|
char *p;
|
|
|
|
int len;
|
|
|
|
|
|
|
|
p = g_get_current_dir ();
|
|
|
|
len = strlen(p) + 1;
|
|
|
|
|
|
|
|
if (len > size) {
|
|
|
|
g_free (p);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2004-09-03 22:05:13 +00:00
|
|
|
memcpy (buffer, p, len);
|
2001-07-27 21:20:43 +00:00
|
|
|
g_free (p);
|
|
|
|
|
|
|
|
return buffer;
|
|
|
|
}
|
|
|
|
#endif /* !USE_VFS */
|
|
|
|
|
2005-07-14 06:31:29 +00:00
|
|
|
enum compression_type
|
|
|
|
get_compression_type (int fd)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
2002-07-02 21:25:49 +00:00
|
|
|
unsigned char magic[4];
|
|
|
|
|
1998-02-27 04:54:42 +00:00
|
|
|
/* Read the magic signature */
|
2003-01-27 18:19:34 +00:00
|
|
|
if (mc_read (fd, (char *) magic, 4) != 4)
|
2002-07-02 21:25:49 +00:00
|
|
|
return COMPRESSION_NONE;
|
|
|
|
|
1998-02-27 04:54:42 +00:00
|
|
|
/* GZIP_MAGIC and OLD_GZIP_MAGIC */
|
2002-07-02 21:25:49 +00:00
|
|
|
if (magic[0] == 037 && (magic[1] == 0213 || magic[1] == 0236)) {
|
2002-07-02 21:09:25 +00:00
|
|
|
return COMPRESSION_GZIP;
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* PKZIP_MAGIC */
|
2002-07-02 21:25:49 +00:00
|
|
|
if (magic[0] == 0120 && magic[1] == 0113 && magic[2] == 003
|
|
|
|
&& magic[3] == 004) {
|
1998-02-27 04:54:42 +00:00
|
|
|
/* Read compression type */
|
|
|
|
mc_lseek (fd, 8, SEEK_SET);
|
2003-01-27 18:19:34 +00:00
|
|
|
if (mc_read (fd, (char *) magic, 2) != 2)
|
2002-07-02 21:25:49 +00:00
|
|
|
return COMPRESSION_NONE;
|
|
|
|
|
1998-02-27 04:54:42 +00:00
|
|
|
/* Gzip can handle only deflated (8) or stored (0) files */
|
2002-07-02 21:25:49 +00:00
|
|
|
if ((magic[0] != 8 && magic[0] != 0) || magic[1] != 0)
|
|
|
|
return COMPRESSION_NONE;
|
2002-07-02 21:09:25 +00:00
|
|
|
|
|
|
|
/* Compatible with gzip */
|
|
|
|
return COMPRESSION_GZIP;
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* PACK_MAGIC and LZH_MAGIC and compress magic */
|
2002-07-02 21:25:49 +00:00
|
|
|
if (magic[0] == 037
|
|
|
|
&& (magic[1] == 036 || magic[1] == 0240 || magic[1] == 0235)) {
|
|
|
|
/* Compatible with gzip */
|
2002-07-02 21:09:25 +00:00
|
|
|
return COMPRESSION_GZIP;
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* BZIP and BZIP2 files */
|
|
|
|
if ((magic[0] == 'B') && (magic[1] == 'Z') &&
|
2002-07-02 21:25:49 +00:00
|
|
|
(magic[3] >= '1') && (magic[3] <= '9')) {
|
|
|
|
switch (magic[2]) {
|
|
|
|
case '0':
|
|
|
|
return COMPRESSION_BZIP;
|
|
|
|
case 'h':
|
|
|
|
return COMPRESSION_BZIP2;
|
|
|
|
}
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-11-12 11:20:08 +00:00
|
|
|
const char *
|
1998-09-22 11:20:32 +00:00
|
|
|
decompress_extension (int type)
|
|
|
|
{
|
|
|
|
switch (type){
|
2002-07-02 21:09:25 +00:00
|
|
|
case COMPRESSION_GZIP: return "#ugz";
|
|
|
|
case COMPRESSION_BZIP: return "#ubz";
|
|
|
|
case COMPRESSION_BZIP2: return "#ubz2";
|
1998-09-22 11:20:32 +00:00
|
|
|
}
|
|
|
|
/* Should never reach this place */
|
|
|
|
fprintf (stderr, "Fatal: decompress_extension called with an unknown argument\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
1998-02-27 04:54:42 +00:00
|
|
|
/* Hooks */
|
2005-09-17 12:01:04 +00:00
|
|
|
void
|
|
|
|
add_hook (Hook **hook_list, void (*hook_fn)(void *), void *data)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
Glibing..... (2)
Wed Jan 27 03:17:44 1999 Timur Bakeyev <mc@bat.ru>
* Converted memory managment to Glib. Now we use g_new()/g_malloc()/
g_strdup()/g_free() routings. Also, copy_strings() replaced by
g_strconcat(), strcasecmp() -> g_strcasecmp(),and sprintf() by
g_snprintf().
* Some sequences of malloc()/sprintf() changed to g_strdup_printf().
* mad.[ch]: Modified, to work with new GLib's memory managment. Fixed
a missing #undef for tempnam, which caused dead loop. Add several new
functions to emulate GLib memory managment.
*main.c, mad.[ch]: Add a new switch "-M", which allows to redirect MAD
messages to the file.
* util.[ch], utilunix.c: Modified, deleted our variants of strcasecmp()
and strdup() - we have g_ equivalences. Remove get_full_name() - it is
similar to concat_dir_and_file(). Some other tricks with g_* functions.
* global.h: Modified, extended. Now it is main memory mangment include -
i.e. all inclusions of <stdlib.h>, <malloc.h>, <glib.h>, "fs.h", "mem.h",
"util.h" and "mad.h" done there. This elimanates problem with proper or-
der of #include's.
* All around the source - changed order of #include's, most of them gone
to global.h (see above), minor changes, like "0" -> NULL in string func-
tions.
1999-01-27 01:08:30 +00:00
|
|
|
Hook *new_hook = g_new (Hook, 1);
|
1998-02-27 04:54:42 +00:00
|
|
|
|
|
|
|
new_hook->hook_fn = hook_fn;
|
|
|
|
new_hook->next = *hook_list;
|
|
|
|
new_hook->hook_data = data;
|
|
|
|
|
|
|
|
*hook_list = new_hook;
|
|
|
|
}
|
|
|
|
|
2005-09-17 12:01:04 +00:00
|
|
|
void
|
|
|
|
execute_hooks (Hook *hook_list)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
|
|
|
Hook *new_hook = 0;
|
|
|
|
Hook *p;
|
|
|
|
|
|
|
|
/* We copy the hook list first so tahat we let the hook
|
|
|
|
* function call delete_hook
|
|
|
|
*/
|
|
|
|
|
|
|
|
while (hook_list){
|
|
|
|
add_hook (&new_hook, hook_list->hook_fn, hook_list->hook_data);
|
|
|
|
hook_list = hook_list->next;
|
|
|
|
}
|
|
|
|
p = new_hook;
|
|
|
|
|
|
|
|
while (new_hook){
|
|
|
|
(*new_hook->hook_fn)(new_hook->hook_data);
|
|
|
|
new_hook = new_hook->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (hook_list = p; hook_list;){
|
|
|
|
p = hook_list;
|
|
|
|
hook_list = hook_list->next;
|
Glibing..... (2)
Wed Jan 27 03:17:44 1999 Timur Bakeyev <mc@bat.ru>
* Converted memory managment to Glib. Now we use g_new()/g_malloc()/
g_strdup()/g_free() routings. Also, copy_strings() replaced by
g_strconcat(), strcasecmp() -> g_strcasecmp(),and sprintf() by
g_snprintf().
* Some sequences of malloc()/sprintf() changed to g_strdup_printf().
* mad.[ch]: Modified, to work with new GLib's memory managment. Fixed
a missing #undef for tempnam, which caused dead loop. Add several new
functions to emulate GLib memory managment.
*main.c, mad.[ch]: Add a new switch "-M", which allows to redirect MAD
messages to the file.
* util.[ch], utilunix.c: Modified, deleted our variants of strcasecmp()
and strdup() - we have g_ equivalences. Remove get_full_name() - it is
similar to concat_dir_and_file(). Some other tricks with g_* functions.
* global.h: Modified, extended. Now it is main memory mangment include -
i.e. all inclusions of <stdlib.h>, <malloc.h>, <glib.h>, "fs.h", "mem.h",
"util.h" and "mad.h" done there. This elimanates problem with proper or-
der of #include's.
* All around the source - changed order of #include's, most of them gone
to global.h (see above), minor changes, like "0" -> NULL in string func-
tions.
1999-01-27 01:08:30 +00:00
|
|
|
g_free (p);
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-09-17 12:01:04 +00:00
|
|
|
void
|
|
|
|
delete_hook (Hook **hook_list, void (*hook_fn)(void *))
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
|
|
|
Hook *current, *new_list, *next;
|
|
|
|
|
|
|
|
new_list = 0;
|
|
|
|
|
|
|
|
for (current = *hook_list; current; current = next){
|
|
|
|
next = current->next;
|
|
|
|
if (current->hook_fn == hook_fn)
|
Glibing..... (2)
Wed Jan 27 03:17:44 1999 Timur Bakeyev <mc@bat.ru>
* Converted memory managment to Glib. Now we use g_new()/g_malloc()/
g_strdup()/g_free() routings. Also, copy_strings() replaced by
g_strconcat(), strcasecmp() -> g_strcasecmp(),and sprintf() by
g_snprintf().
* Some sequences of malloc()/sprintf() changed to g_strdup_printf().
* mad.[ch]: Modified, to work with new GLib's memory managment. Fixed
a missing #undef for tempnam, which caused dead loop. Add several new
functions to emulate GLib memory managment.
*main.c, mad.[ch]: Add a new switch "-M", which allows to redirect MAD
messages to the file.
* util.[ch], utilunix.c: Modified, deleted our variants of strcasecmp()
and strdup() - we have g_ equivalences. Remove get_full_name() - it is
similar to concat_dir_and_file(). Some other tricks with g_* functions.
* global.h: Modified, extended. Now it is main memory mangment include -
i.e. all inclusions of <stdlib.h>, <malloc.h>, <glib.h>, "fs.h", "mem.h",
"util.h" and "mad.h" done there. This elimanates problem with proper or-
der of #include's.
* All around the source - changed order of #include's, most of them gone
to global.h (see above), minor changes, like "0" -> NULL in string func-
tions.
1999-01-27 01:08:30 +00:00
|
|
|
g_free (current);
|
1998-02-27 04:54:42 +00:00
|
|
|
else
|
|
|
|
add_hook (&new_list, current->hook_fn, current->hook_data);
|
|
|
|
}
|
|
|
|
*hook_list = new_list;
|
|
|
|
}
|
|
|
|
|
2005-09-17 12:01:04 +00:00
|
|
|
int
|
|
|
|
hook_present (Hook *hook_list, void (*hook_fn)(void *))
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
|
|
|
Hook *p;
|
|
|
|
|
|
|
|
for (p = hook_list; p; p = p->next)
|
|
|
|
if (p->hook_fn == hook_fn)
|
|
|
|
return 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-09-17 12:01:04 +00:00
|
|
|
void
|
|
|
|
wipe_password (char *passwd)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
|
|
|
char *p = passwd;
|
|
|
|
|
1999-09-14 18:20:02 +00:00
|
|
|
if (!p)
|
|
|
|
return;
|
1998-02-27 04:54:42 +00:00
|
|
|
for (;*p ; p++)
|
|
|
|
*p = 0;
|
Glibing..... (2)
Wed Jan 27 03:17:44 1999 Timur Bakeyev <mc@bat.ru>
* Converted memory managment to Glib. Now we use g_new()/g_malloc()/
g_strdup()/g_free() routings. Also, copy_strings() replaced by
g_strconcat(), strcasecmp() -> g_strcasecmp(),and sprintf() by
g_snprintf().
* Some sequences of malloc()/sprintf() changed to g_strdup_printf().
* mad.[ch]: Modified, to work with new GLib's memory managment. Fixed
a missing #undef for tempnam, which caused dead loop. Add several new
functions to emulate GLib memory managment.
*main.c, mad.[ch]: Add a new switch "-M", which allows to redirect MAD
messages to the file.
* util.[ch], utilunix.c: Modified, deleted our variants of strcasecmp()
and strdup() - we have g_ equivalences. Remove get_full_name() - it is
similar to concat_dir_and_file(). Some other tricks with g_* functions.
* global.h: Modified, extended. Now it is main memory mangment include -
i.e. all inclusions of <stdlib.h>, <malloc.h>, <glib.h>, "fs.h", "mem.h",
"util.h" and "mad.h" done there. This elimanates problem with proper or-
der of #include's.
* All around the source - changed order of #include's, most of them gone
to global.h (see above), minor changes, like "0" -> NULL in string func-
tions.
1999-01-27 01:08:30 +00:00
|
|
|
g_free (passwd);
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Convert "\E" -> esc character and ^x to control-x key and ^^ to ^ key */
|
|
|
|
/* Returns a newly allocated string */
|
2005-09-17 12:01:04 +00:00
|
|
|
char *
|
|
|
|
convert_controls (const char *p)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
2004-09-28 09:28:57 +00:00
|
|
|
char *valcopy = g_strdup (p);
|
2004-09-27 11:26:53 +00:00
|
|
|
char *q;
|
1998-02-27 04:54:42 +00:00
|
|
|
|
|
|
|
/* Parse the escape special character */
|
2004-09-28 09:28:57 +00:00
|
|
|
for (q = valcopy; *p;){
|
1998-02-27 04:54:42 +00:00
|
|
|
if (*p == '\\'){
|
|
|
|
p++;
|
|
|
|
if ((*p == 'e') || (*p == 'E')){
|
|
|
|
p++;
|
|
|
|
*q++ = ESC_CHAR;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (*p == '^'){
|
|
|
|
p++;
|
|
|
|
if (*p == '^')
|
|
|
|
*q++ = *p++;
|
|
|
|
else {
|
2004-09-27 11:26:53 +00:00
|
|
|
char c = (*p | 0x20);
|
|
|
|
if (c >= 'a' && c <= 'z') {
|
|
|
|
*q++ = c - 'a' + 1;
|
|
|
|
p++;
|
2004-09-28 09:28:57 +00:00
|
|
|
} else if (*p)
|
1998-02-27 04:54:42 +00:00
|
|
|
p++;
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
*q++ = *p++;
|
|
|
|
}
|
|
|
|
}
|
2002-08-14 16:33:50 +00:00
|
|
|
*q = 0;
|
1998-02-27 04:54:42 +00:00
|
|
|
return valcopy;
|
|
|
|
}
|
|
|
|
|
2005-09-17 12:01:04 +00:00
|
|
|
static char *
|
|
|
|
resolve_symlinks (const char *path)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
2004-08-29 23:20:01 +00:00
|
|
|
char *buf, *buf2, *q, *r, c;
|
1998-02-27 04:54:42 +00:00
|
|
|
int len;
|
|
|
|
struct stat mybuf;
|
2004-08-29 23:20:01 +00:00
|
|
|
const char *p;
|
1998-02-27 04:54:42 +00:00
|
|
|
|
|
|
|
if (*path != PATH_SEP)
|
|
|
|
return NULL;
|
Glibing..... (2)
Wed Jan 27 03:17:44 1999 Timur Bakeyev <mc@bat.ru>
* Converted memory managment to Glib. Now we use g_new()/g_malloc()/
g_strdup()/g_free() routings. Also, copy_strings() replaced by
g_strconcat(), strcasecmp() -> g_strcasecmp(),and sprintf() by
g_snprintf().
* Some sequences of malloc()/sprintf() changed to g_strdup_printf().
* mad.[ch]: Modified, to work with new GLib's memory managment. Fixed
a missing #undef for tempnam, which caused dead loop. Add several new
functions to emulate GLib memory managment.
*main.c, mad.[ch]: Add a new switch "-M", which allows to redirect MAD
messages to the file.
* util.[ch], utilunix.c: Modified, deleted our variants of strcasecmp()
and strdup() - we have g_ equivalences. Remove get_full_name() - it is
similar to concat_dir_and_file(). Some other tricks with g_* functions.
* global.h: Modified, extended. Now it is main memory mangment include -
i.e. all inclusions of <stdlib.h>, <malloc.h>, <glib.h>, "fs.h", "mem.h",
"util.h" and "mad.h" done there. This elimanates problem with proper or-
der of #include's.
* All around the source - changed order of #include's, most of them gone
to global.h (see above), minor changes, like "0" -> NULL in string func-
tions.
1999-01-27 01:08:30 +00:00
|
|
|
r = buf = g_malloc (MC_MAXPATHLEN);
|
|
|
|
buf2 = g_malloc (MC_MAXPATHLEN);
|
1998-02-27 04:54:42 +00:00
|
|
|
*r++ = PATH_SEP;
|
|
|
|
*r = 0;
|
|
|
|
p = path;
|
|
|
|
for (;;) {
|
|
|
|
q = strchr (p + 1, PATH_SEP);
|
|
|
|
if (!q) {
|
|
|
|
q = strchr (p + 1, 0);
|
|
|
|
if (q == p + 1)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
c = *q;
|
|
|
|
*q = 0;
|
|
|
|
if (mc_lstat (path, &mybuf) < 0) {
|
Glibing..... (2)
Wed Jan 27 03:17:44 1999 Timur Bakeyev <mc@bat.ru>
* Converted memory managment to Glib. Now we use g_new()/g_malloc()/
g_strdup()/g_free() routings. Also, copy_strings() replaced by
g_strconcat(), strcasecmp() -> g_strcasecmp(),and sprintf() by
g_snprintf().
* Some sequences of malloc()/sprintf() changed to g_strdup_printf().
* mad.[ch]: Modified, to work with new GLib's memory managment. Fixed
a missing #undef for tempnam, which caused dead loop. Add several new
functions to emulate GLib memory managment.
*main.c, mad.[ch]: Add a new switch "-M", which allows to redirect MAD
messages to the file.
* util.[ch], utilunix.c: Modified, deleted our variants of strcasecmp()
and strdup() - we have g_ equivalences. Remove get_full_name() - it is
similar to concat_dir_and_file(). Some other tricks with g_* functions.
* global.h: Modified, extended. Now it is main memory mangment include -
i.e. all inclusions of <stdlib.h>, <malloc.h>, <glib.h>, "fs.h", "mem.h",
"util.h" and "mad.h" done there. This elimanates problem with proper or-
der of #include's.
* All around the source - changed order of #include's, most of them gone
to global.h (see above), minor changes, like "0" -> NULL in string func-
tions.
1999-01-27 01:08:30 +00:00
|
|
|
g_free (buf);
|
|
|
|
g_free (buf2);
|
1998-02-27 04:54:42 +00:00
|
|
|
*q = c;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
if (!S_ISLNK (mybuf.st_mode))
|
|
|
|
strcpy (r, p + 1);
|
|
|
|
else {
|
2003-08-29 22:45:04 +00:00
|
|
|
len = mc_readlink (path, buf2, MC_MAXPATHLEN - 1);
|
1998-02-27 04:54:42 +00:00
|
|
|
if (len < 0) {
|
2005-09-17 12:01:04 +00:00
|
|
|
g_free (buf);
|
|
|
|
g_free (buf2);
|
1998-02-27 04:54:42 +00:00
|
|
|
*q = c;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
buf2 [len] = 0;
|
|
|
|
if (*buf2 == PATH_SEP)
|
|
|
|
strcpy (buf, buf2);
|
|
|
|
else
|
|
|
|
strcpy (r, buf2);
|
|
|
|
}
|
|
|
|
canonicalize_pathname (buf);
|
|
|
|
r = strchr (buf, 0);
|
|
|
|
if (!*r || *(r - 1) != PATH_SEP) {
|
|
|
|
*r++ = PATH_SEP;
|
|
|
|
*r = 0;
|
|
|
|
}
|
|
|
|
*q = c;
|
|
|
|
p = q;
|
|
|
|
if (!c)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (!*buf)
|
|
|
|
strcpy (buf, PATH_SEP_STR);
|
|
|
|
else if (*(r - 1) == PATH_SEP && r != buf + 1)
|
|
|
|
*(r - 1) = 0;
|
Glibing..... (2)
Wed Jan 27 03:17:44 1999 Timur Bakeyev <mc@bat.ru>
* Converted memory managment to Glib. Now we use g_new()/g_malloc()/
g_strdup()/g_free() routings. Also, copy_strings() replaced by
g_strconcat(), strcasecmp() -> g_strcasecmp(),and sprintf() by
g_snprintf().
* Some sequences of malloc()/sprintf() changed to g_strdup_printf().
* mad.[ch]: Modified, to work with new GLib's memory managment. Fixed
a missing #undef for tempnam, which caused dead loop. Add several new
functions to emulate GLib memory managment.
*main.c, mad.[ch]: Add a new switch "-M", which allows to redirect MAD
messages to the file.
* util.[ch], utilunix.c: Modified, deleted our variants of strcasecmp()
and strdup() - we have g_ equivalences. Remove get_full_name() - it is
similar to concat_dir_and_file(). Some other tricks with g_* functions.
* global.h: Modified, extended. Now it is main memory mangment include -
i.e. all inclusions of <stdlib.h>, <malloc.h>, <glib.h>, "fs.h", "mem.h",
"util.h" and "mad.h" done there. This elimanates problem with proper or-
der of #include's.
* All around the source - changed order of #include's, most of them gone
to global.h (see above), minor changes, like "0" -> NULL in string func-
tions.
1999-01-27 01:08:30 +00:00
|
|
|
g_free (buf2);
|
1998-02-27 04:54:42 +00:00
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Finds out a relative path from first to second, i.e. goes as many ..
|
|
|
|
* as needed up in first and then goes down using second */
|
2005-09-17 12:01:04 +00:00
|
|
|
char *
|
|
|
|
diff_two_paths (const char *first, const char *second)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
2005-09-17 11:40:31 +00:00
|
|
|
char *p, *q, *r, *s, *buf = NULL;
|
1998-02-27 04:54:42 +00:00
|
|
|
int i, j, prevlen = -1, currlen;
|
2004-08-29 23:20:01 +00:00
|
|
|
char *my_first = NULL, *my_second = NULL;
|
1998-02-27 04:54:42 +00:00
|
|
|
|
2004-08-29 23:20:01 +00:00
|
|
|
my_first = resolve_symlinks (first);
|
|
|
|
if (my_first == NULL)
|
1998-02-27 04:54:42 +00:00
|
|
|
return NULL;
|
2005-09-17 11:40:31 +00:00
|
|
|
my_second = resolve_symlinks (second);
|
|
|
|
if (my_second == NULL) {
|
|
|
|
g_free (my_first);
|
|
|
|
return NULL;
|
|
|
|
}
|
1998-02-27 04:54:42 +00:00
|
|
|
for (j = 0; j < 2; j++) {
|
2004-08-29 23:20:01 +00:00
|
|
|
p = my_first;
|
|
|
|
q = my_second;
|
1998-02-27 04:54:42 +00:00
|
|
|
for (;;) {
|
|
|
|
r = strchr (p, PATH_SEP);
|
|
|
|
s = strchr (q, PATH_SEP);
|
|
|
|
if (!r || !s)
|
|
|
|
break;
|
|
|
|
*r = 0; *s = 0;
|
|
|
|
if (strcmp (p, q)) {
|
|
|
|
*r = PATH_SEP; *s = PATH_SEP;
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
*r = PATH_SEP; *s = PATH_SEP;
|
|
|
|
}
|
|
|
|
p = r + 1;
|
|
|
|
q = s + 1;
|
|
|
|
}
|
|
|
|
p--;
|
|
|
|
for (i = 0; (p = strchr (p + 1, PATH_SEP)) != NULL; i++);
|
|
|
|
currlen = (i + 1) * 3 + strlen (q) + 1;
|
|
|
|
if (j) {
|
|
|
|
if (currlen < prevlen)
|
Glibing..... (2)
Wed Jan 27 03:17:44 1999 Timur Bakeyev <mc@bat.ru>
* Converted memory managment to Glib. Now we use g_new()/g_malloc()/
g_strdup()/g_free() routings. Also, copy_strings() replaced by
g_strconcat(), strcasecmp() -> g_strcasecmp(),and sprintf() by
g_snprintf().
* Some sequences of malloc()/sprintf() changed to g_strdup_printf().
* mad.[ch]: Modified, to work with new GLib's memory managment. Fixed
a missing #undef for tempnam, which caused dead loop. Add several new
functions to emulate GLib memory managment.
*main.c, mad.[ch]: Add a new switch "-M", which allows to redirect MAD
messages to the file.
* util.[ch], utilunix.c: Modified, deleted our variants of strcasecmp()
and strdup() - we have g_ equivalences. Remove get_full_name() - it is
similar to concat_dir_and_file(). Some other tricks with g_* functions.
* global.h: Modified, extended. Now it is main memory mangment include -
i.e. all inclusions of <stdlib.h>, <malloc.h>, <glib.h>, "fs.h", "mem.h",
"util.h" and "mad.h" done there. This elimanates problem with proper or-
der of #include's.
* All around the source - changed order of #include's, most of them gone
to global.h (see above), minor changes, like "0" -> NULL in string func-
tions.
1999-01-27 01:08:30 +00:00
|
|
|
g_free (buf);
|
1998-02-27 04:54:42 +00:00
|
|
|
else {
|
2005-09-17 11:40:31 +00:00
|
|
|
g_free (my_first);
|
|
|
|
g_free (my_second);
|
1998-02-27 04:54:42 +00:00
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
}
|
Glibing..... (2)
Wed Jan 27 03:17:44 1999 Timur Bakeyev <mc@bat.ru>
* Converted memory managment to Glib. Now we use g_new()/g_malloc()/
g_strdup()/g_free() routings. Also, copy_strings() replaced by
g_strconcat(), strcasecmp() -> g_strcasecmp(),and sprintf() by
g_snprintf().
* Some sequences of malloc()/sprintf() changed to g_strdup_printf().
* mad.[ch]: Modified, to work with new GLib's memory managment. Fixed
a missing #undef for tempnam, which caused dead loop. Add several new
functions to emulate GLib memory managment.
*main.c, mad.[ch]: Add a new switch "-M", which allows to redirect MAD
messages to the file.
* util.[ch], utilunix.c: Modified, deleted our variants of strcasecmp()
and strdup() - we have g_ equivalences. Remove get_full_name() - it is
similar to concat_dir_and_file(). Some other tricks with g_* functions.
* global.h: Modified, extended. Now it is main memory mangment include -
i.e. all inclusions of <stdlib.h>, <malloc.h>, <glib.h>, "fs.h", "mem.h",
"util.h" and "mad.h" done there. This elimanates problem with proper or-
der of #include's.
* All around the source - changed order of #include's, most of them gone
to global.h (see above), minor changes, like "0" -> NULL in string func-
tions.
1999-01-27 01:08:30 +00:00
|
|
|
p = buf = g_malloc (currlen);
|
1998-02-27 04:54:42 +00:00
|
|
|
prevlen = currlen;
|
|
|
|
for (; i >= 0; i--, p += 3)
|
2005-09-17 11:40:31 +00:00
|
|
|
strcpy (p, "../");
|
1998-02-27 04:54:42 +00:00
|
|
|
strcpy (p, q);
|
|
|
|
}
|
2004-08-29 23:20:01 +00:00
|
|
|
g_free (my_first);
|
|
|
|
g_free (my_second);
|
1998-02-27 04:54:42 +00:00
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
|
Glibing..... (2)
Wed Jan 27 03:17:44 1999 Timur Bakeyev <mc@bat.ru>
* Converted memory managment to Glib. Now we use g_new()/g_malloc()/
g_strdup()/g_free() routings. Also, copy_strings() replaced by
g_strconcat(), strcasecmp() -> g_strcasecmp(),and sprintf() by
g_snprintf().
* Some sequences of malloc()/sprintf() changed to g_strdup_printf().
* mad.[ch]: Modified, to work with new GLib's memory managment. Fixed
a missing #undef for tempnam, which caused dead loop. Add several new
functions to emulate GLib memory managment.
*main.c, mad.[ch]: Add a new switch "-M", which allows to redirect MAD
messages to the file.
* util.[ch], utilunix.c: Modified, deleted our variants of strcasecmp()
and strdup() - we have g_ equivalences. Remove get_full_name() - it is
similar to concat_dir_and_file(). Some other tricks with g_* functions.
* global.h: Modified, extended. Now it is main memory mangment include -
i.e. all inclusions of <stdlib.h>, <malloc.h>, <glib.h>, "fs.h", "mem.h",
"util.h" and "mad.h" done there. This elimanates problem with proper or-
der of #include's.
* All around the source - changed order of #include's, most of them gone
to global.h (see above), minor changes, like "0" -> NULL in string func-
tions.
1999-01-27 01:08:30 +00:00
|
|
|
/* If filename is NULL, then we just append PATH_SEP to the dir */
|
1998-02-27 04:54:42 +00:00
|
|
|
char *
|
|
|
|
concat_dir_and_file (const char *dir, const char *file)
|
|
|
|
{
|
Glibing..... (2)
Wed Jan 27 03:17:44 1999 Timur Bakeyev <mc@bat.ru>
* Converted memory managment to Glib. Now we use g_new()/g_malloc()/
g_strdup()/g_free() routings. Also, copy_strings() replaced by
g_strconcat(), strcasecmp() -> g_strcasecmp(),and sprintf() by
g_snprintf().
* Some sequences of malloc()/sprintf() changed to g_strdup_printf().
* mad.[ch]: Modified, to work with new GLib's memory managment. Fixed
a missing #undef for tempnam, which caused dead loop. Add several new
functions to emulate GLib memory managment.
*main.c, mad.[ch]: Add a new switch "-M", which allows to redirect MAD
messages to the file.
* util.[ch], utilunix.c: Modified, deleted our variants of strcasecmp()
and strdup() - we have g_ equivalences. Remove get_full_name() - it is
similar to concat_dir_and_file(). Some other tricks with g_* functions.
* global.h: Modified, extended. Now it is main memory mangment include -
i.e. all inclusions of <stdlib.h>, <malloc.h>, <glib.h>, "fs.h", "mem.h",
"util.h" and "mad.h" done there. This elimanates problem with proper or-
der of #include's.
* All around the source - changed order of #include's, most of them gone
to global.h (see above), minor changes, like "0" -> NULL in string func-
tions.
1999-01-27 01:08:30 +00:00
|
|
|
int i = strlen (dir);
|
|
|
|
|
|
|
|
if (dir [i-1] == PATH_SEP)
|
2004-09-24 15:05:28 +00:00
|
|
|
return g_strconcat (dir, file, (char *) NULL);
|
1998-02-27 04:54:42 +00:00
|
|
|
else
|
2004-09-24 15:05:28 +00:00
|
|
|
return g_strconcat (dir, PATH_SEP_STR, file, (char *) NULL);
|
Glibing..... (2)
Wed Jan 27 03:17:44 1999 Timur Bakeyev <mc@bat.ru>
* Converted memory managment to Glib. Now we use g_new()/g_malloc()/
g_strdup()/g_free() routings. Also, copy_strings() replaced by
g_strconcat(), strcasecmp() -> g_strcasecmp(),and sprintf() by
g_snprintf().
* Some sequences of malloc()/sprintf() changed to g_strdup_printf().
* mad.[ch]: Modified, to work with new GLib's memory managment. Fixed
a missing #undef for tempnam, which caused dead loop. Add several new
functions to emulate GLib memory managment.
*main.c, mad.[ch]: Add a new switch "-M", which allows to redirect MAD
messages to the file.
* util.[ch], utilunix.c: Modified, deleted our variants of strcasecmp()
and strdup() - we have g_ equivalences. Remove get_full_name() - it is
similar to concat_dir_and_file(). Some other tricks with g_* functions.
* global.h: Modified, extended. Now it is main memory mangment include -
i.e. all inclusions of <stdlib.h>, <malloc.h>, <glib.h>, "fs.h", "mem.h",
"util.h" and "mad.h" done there. This elimanates problem with proper or-
der of #include's.
* All around the source - changed order of #include's, most of them gone
to global.h (see above), minor changes, like "0" -> NULL in string func-
tions.
1999-01-27 01:08:30 +00:00
|
|
|
}
|
|
|
|
|
2003-02-18 06:12:57 +00:00
|
|
|
/* Append text to GList, remove all entries with the same text */
|
|
|
|
GList *
|
|
|
|
list_append_unique (GList *list, char *text)
|
|
|
|
{
|
|
|
|
GList *link, *newlink;
|
|
|
|
|
2003-02-18 23:21:54 +00:00
|
|
|
/*
|
|
|
|
* Go to the last position and traverse the list backwards
|
|
|
|
* starting from the second last entry to make sure that we
|
|
|
|
* are not removing the current link.
|
|
|
|
*/
|
|
|
|
list = g_list_append (list, text);
|
|
|
|
list = g_list_last (list);
|
|
|
|
link = g_list_previous (list);
|
|
|
|
|
2003-02-18 06:12:57 +00:00
|
|
|
while (link) {
|
2003-02-18 23:21:54 +00:00
|
|
|
newlink = g_list_previous (link);
|
2003-02-19 00:42:04 +00:00
|
|
|
if (!strcmp ((char *) link->data, text)) {
|
2003-06-05 23:51:15 +00:00
|
|
|
g_free (link->data);
|
2003-02-18 23:21:54 +00:00
|
|
|
g_list_remove_link (list, link);
|
2003-02-19 00:42:04 +00:00
|
|
|
g_list_free_1 (link);
|
|
|
|
}
|
2003-02-18 06:12:57 +00:00
|
|
|
link = newlink;
|
|
|
|
}
|
|
|
|
|
2003-02-18 23:21:54 +00:00
|
|
|
return list;
|
2003-02-18 06:12:57 +00:00
|
|
|
}
|
|
|
|
|
2001-05-21 16:21:07 +00:00
|
|
|
/* Following code heavily borrows from libiberty, mkstemps.c */
|
|
|
|
|
|
|
|
/* Number of attempts to create a temporary file */
|
|
|
|
#ifndef TMP_MAX
|
|
|
|
#define TMP_MAX 16384
|
2001-07-26 05:01:26 +00:00
|
|
|
#endif /* !TMP_MAX */
|
2001-05-21 16:21:07 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Arguments:
|
2001-05-22 07:10:43 +00:00
|
|
|
* pname (output) - pointer to the name of the temp file (needs g_free).
|
|
|
|
* NULL if the function fails.
|
2001-07-27 19:27:09 +00:00
|
|
|
* prefix - part of the filename before the random part.
|
|
|
|
* Prepend $TMPDIR or /tmp if there are no path separators.
|
2001-05-22 07:10:43 +00:00
|
|
|
* suffix - if not NULL, part of the filename after the random part.
|
2001-05-21 16:21:07 +00:00
|
|
|
*
|
|
|
|
* Result:
|
|
|
|
* handle of the open file or -1 if couldn't open any.
|
|
|
|
*/
|
2002-11-01 20:24:07 +00:00
|
|
|
int
|
|
|
|
mc_mkstemps (char **pname, const char *prefix, const char *suffix)
|
2001-05-21 16:21:07 +00:00
|
|
|
{
|
|
|
|
static const char letters[]
|
|
|
|
= "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
2001-07-17 18:38:46 +00:00
|
|
|
static unsigned long value;
|
2001-05-21 16:21:07 +00:00
|
|
|
struct timeval tv;
|
|
|
|
char *tmpbase;
|
|
|
|
char *tmpname;
|
|
|
|
char *XXXXXX;
|
|
|
|
int count;
|
|
|
|
|
2002-11-01 20:24:07 +00:00
|
|
|
if (strchr (prefix, PATH_SEP) == NULL) {
|
2001-07-27 19:27:09 +00:00
|
|
|
/* Add prefix first to find the position of XXXXXX */
|
2002-09-11 04:58:24 +00:00
|
|
|
tmpbase = concat_dir_and_file (mc_tmpdir (), prefix);
|
2001-07-27 19:27:09 +00:00
|
|
|
} else {
|
|
|
|
tmpbase = g_strdup (prefix);
|
|
|
|
}
|
2001-05-21 16:21:07 +00:00
|
|
|
|
2004-09-24 15:05:28 +00:00
|
|
|
tmpname = g_strconcat (tmpbase, "XXXXXX", suffix, (char *) NULL);
|
2001-05-22 07:10:43 +00:00
|
|
|
*pname = tmpname;
|
2001-05-21 16:21:07 +00:00
|
|
|
XXXXXX = &tmpname[strlen (tmpbase)];
|
2002-11-01 20:24:07 +00:00
|
|
|
g_free (tmpbase);
|
2001-05-21 16:21:07 +00:00
|
|
|
|
|
|
|
/* Get some more or less random data. */
|
|
|
|
gettimeofday (&tv, NULL);
|
|
|
|
value += (tv.tv_usec << 16) ^ tv.tv_sec ^ getpid ();
|
|
|
|
|
|
|
|
for (count = 0; count < TMP_MAX; ++count) {
|
2001-07-17 18:38:46 +00:00
|
|
|
unsigned long v = value;
|
2001-05-21 16:21:07 +00:00
|
|
|
int fd;
|
|
|
|
|
|
|
|
/* Fill in the random bits. */
|
|
|
|
XXXXXX[0] = letters[v % 62];
|
|
|
|
v /= 62;
|
|
|
|
XXXXXX[1] = letters[v % 62];
|
|
|
|
v /= 62;
|
|
|
|
XXXXXX[2] = letters[v % 62];
|
|
|
|
v /= 62;
|
|
|
|
XXXXXX[3] = letters[v % 62];
|
|
|
|
v /= 62;
|
|
|
|
XXXXXX[4] = letters[v % 62];
|
|
|
|
v /= 62;
|
|
|
|
XXXXXX[5] = letters[v % 62];
|
|
|
|
|
2002-11-01 20:24:07 +00:00
|
|
|
fd = open (tmpname, O_RDWR | O_CREAT | O_TRUNC | O_EXCL,
|
|
|
|
S_IRUSR | S_IWUSR);
|
2001-05-21 16:21:07 +00:00
|
|
|
if (fd >= 0) {
|
|
|
|
/* Successfully created. */
|
|
|
|
return fd;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* This is a random value. It is only necessary that the next
|
2002-11-01 20:24:07 +00:00
|
|
|
TMP_MAX values generated by adding 7777 to VALUE are different
|
|
|
|
with (module 2^32). */
|
2001-05-21 16:21:07 +00:00
|
|
|
value += 7777;
|
|
|
|
}
|
|
|
|
|
2001-05-22 07:10:43 +00:00
|
|
|
/* Unsuccessful. Free the filename. */
|
|
|
|
g_free (tmpname);
|
2002-09-26 22:13:16 +00:00
|
|
|
*pname = NULL;
|
2001-05-21 16:21:07 +00:00
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
2002-12-08 06:51:22 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Read and restore position for the given filename.
|
|
|
|
* If there is no stored data, return line 1 and col 0.
|
|
|
|
*/
|
|
|
|
void
|
2004-08-29 23:20:01 +00:00
|
|
|
load_file_position (const char *filename, long *line, long *column)
|
2002-12-08 06:51:22 +00:00
|
|
|
{
|
|
|
|
char *fn;
|
|
|
|
FILE *f;
|
|
|
|
char buf[MC_MAXPATHLEN + 20];
|
|
|
|
int len;
|
|
|
|
|
|
|
|
/* defaults */
|
|
|
|
*line = 1;
|
|
|
|
*column = 0;
|
|
|
|
|
|
|
|
/* open file with positions */
|
|
|
|
fn = concat_dir_and_file (home_dir, MC_FILEPOS);
|
|
|
|
f = fopen (fn, "r");
|
|
|
|
g_free (fn);
|
2002-12-09 16:42:20 +00:00
|
|
|
if (!f)
|
2002-12-08 06:51:22 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
len = strlen (filename);
|
|
|
|
|
|
|
|
while (fgets (buf, sizeof (buf), f)) {
|
2004-09-24 16:43:08 +00:00
|
|
|
const char *p;
|
2002-12-08 06:51:22 +00:00
|
|
|
|
|
|
|
/* check if the filename matches the beginning of string */
|
|
|
|
if (strncmp (buf, filename, len) != 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* followed by single space */
|
|
|
|
if (buf[len] != ' ')
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* and string without spaces */
|
|
|
|
p = &buf[len + 1];
|
|
|
|
if (strchr (p, ' '))
|
|
|
|
continue;
|
|
|
|
|
2004-09-24 16:43:08 +00:00
|
|
|
*line = strtol(p, const_cast(char **, &p), 10);
|
|
|
|
if (*p == ';') {
|
2005-03-23 05:29:06 +00:00
|
|
|
*column = strtol(p+1, const_cast(char **, &p), 10);
|
2004-09-24 16:43:08 +00:00
|
|
|
if (*p != '\n')
|
|
|
|
*column = 0;
|
|
|
|
} else
|
|
|
|
*line = 1;
|
2002-12-08 06:51:22 +00:00
|
|
|
}
|
|
|
|
fclose (f);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Save position for the given file */
|
|
|
|
void
|
2004-08-29 23:20:01 +00:00
|
|
|
save_file_position (const char *filename, long line, long column)
|
2002-12-08 06:51:22 +00:00
|
|
|
{
|
|
|
|
char *tmp, *fn;
|
|
|
|
FILE *f, *t;
|
|
|
|
char buf[MC_MAXPATHLEN + 20];
|
|
|
|
int i = 1;
|
|
|
|
int len;
|
|
|
|
|
|
|
|
len = strlen (filename);
|
|
|
|
|
|
|
|
tmp = concat_dir_and_file (home_dir, MC_FILEPOS_TMP);
|
|
|
|
fn = concat_dir_and_file (home_dir, MC_FILEPOS);
|
|
|
|
|
|
|
|
/* open temporary file */
|
|
|
|
t = fopen (tmp, "w");
|
|
|
|
if (!t) {
|
|
|
|
g_free (tmp);
|
|
|
|
g_free (fn);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* put the new record */
|
2005-07-23 08:20:03 +00:00
|
|
|
if (line != 1 || column != 0) {
|
|
|
|
fprintf (t, "%s %ld;%ld\n", filename, line, column);
|
|
|
|
}
|
2002-12-08 06:51:22 +00:00
|
|
|
|
|
|
|
/* copy records from the old file */
|
|
|
|
f = fopen (fn, "r");
|
|
|
|
if (f) {
|
|
|
|
while (fgets (buf, sizeof (buf), f)) {
|
|
|
|
/* Skip entries for the current filename */
|
|
|
|
if (strncmp (buf, filename, len) == 0 && buf[len] == ' '
|
|
|
|
&& !strchr (&buf[len + 1], ' '))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
fprintf (t, "%s", buf);
|
|
|
|
if (++i > MC_FILEPOS_ENTRIES)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
fclose (f);
|
|
|
|
}
|
|
|
|
|
|
|
|
fclose (t);
|
|
|
|
rename (tmp, fn);
|
|
|
|
g_free (tmp);
|
|
|
|
g_free (fn);
|
|
|
|
}
|
2004-12-02 20:08:06 +00:00
|
|
|
|
|
|
|
extern const char *
|
|
|
|
cstrcasestr (const char *haystack, const char *needle)
|
|
|
|
{
|
patches by Rostislav Beneš: mc-28-fix
rest of fixes in files cmc.c, main.c (xterm title), panelize.c, subshell.c,
tree.c, tty.c, user.c, util.c, win.c
now, basic mc's function should work well, editor and view are still broken.
2008-12-29 01:53:08 +02:00
|
|
|
char *nee = str_create_search_needle (needle, 0);
|
|
|
|
const char *result = str_search_first (haystack, nee, 0);
|
|
|
|
str_release_search_needle (nee, 0);
|
|
|
|
return result;
|
2004-12-02 20:08:06 +00:00
|
|
|
}
|
2005-04-13 18:47:12 +00:00
|
|
|
|
2005-05-23 11:21:26 +00:00
|
|
|
const char *
|
|
|
|
cstrstr (const char *haystack, const char *needle)
|
|
|
|
{
|
|
|
|
return strstr(haystack, needle);
|
|
|
|
}
|
|
|
|
|
2005-04-13 18:47:12 +00:00
|
|
|
extern char *
|
|
|
|
str_unconst (const char *s)
|
|
|
|
{
|
2005-09-17 12:01:04 +00:00
|
|
|
return (char *) s;
|
2005-04-13 18:47:12 +00:00
|
|
|
}
|
2005-07-18 09:31:37 +00:00
|
|
|
|
|
|
|
#define ASCII_A (0x40 + 1)
|
|
|
|
#define ASCII_Z (0x40 + 26)
|
|
|
|
#define ASCII_a (0x60 + 1)
|
|
|
|
#define ASCII_z (0x60 + 26)
|
|
|
|
|
|
|
|
extern int
|
|
|
|
ascii_alpha_to_cntrl (int ch)
|
|
|
|
{
|
|
|
|
if ((ch >= ASCII_A && ch <= ASCII_Z)
|
|
|
|
|| (ch >= ASCII_a && ch <= ASCII_z)) {
|
|
|
|
ch &= 0x1f;
|
|
|
|
}
|
|
|
|
return ch;
|
|
|
|
}
|
2005-11-03 02:18:38 +00:00
|
|
|
|
|
|
|
const char *
|
|
|
|
Q_ (const char *s)
|
|
|
|
{
|
|
|
|
const char *result, *sep;
|
|
|
|
|
|
|
|
result = _(s);
|
|
|
|
sep = strchr(result, '|');
|
|
|
|
return (sep != NULL) ? sep + 1 : result;
|
|
|
|
}
|
|
|
|
|