mirror of
https://github.com/MidnightCommander/mc
synced 2024-12-23 04:46:55 +03:00
38537ddd04
mhl/escape.h: add new function mhl_shell_is_char_escaped() src/command.c; src/complete.c; src/file.c; src/util.c: Changes for use MHL-functions. src/util.h: remove old escape-related declarations of functions
153 lines
3.0 KiB
C
153 lines
3.0 KiB
C
#ifndef __MHL_SHELL_ESCAPE_H
|
|
#define __MHL_SHELL_ESCAPE_H
|
|
|
|
/* Micro helper library: shell escaping functions */
|
|
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
#ifndef FALSE
|
|
# define FALSE 0
|
|
#endif
|
|
|
|
#ifndef TRUE
|
|
# define TRUE 1
|
|
#endif
|
|
|
|
#define mhl_shell_escape_toesc(x) \
|
|
(((x)==' ')||((x)=='!')||((x)=='#')||((x)=='$')||((x)=='%')|| \
|
|
((x)=='(')||((x)==')')||((x)=='\'')||((x)=='&')||((x)=='~')|| \
|
|
((x)=='{')||((x)=='}')||((x)=='[')||((x)==']')||((x)=='`')|| \
|
|
((x)=='?')||((x)=='|')||((x)=='<')||((x)=='>')||((x)==';')|| \
|
|
((x)=='*')||((x)=='\\')||((x)=='"'))
|
|
|
|
#define mhl_shell_escape_nottoesc(x) \
|
|
(((x)!=0) && (!mhl_shell_escape_toesc((x))))
|
|
|
|
/** To be compatible with the general posix command lines we have to escape
|
|
strings for the command line
|
|
|
|
/params const char * in
|
|
string for escaping
|
|
/returns
|
|
return escaped string (later need to free)
|
|
*/
|
|
static inline char* mhl_shell_escape_dup(const char* src)
|
|
{
|
|
if ((src==NULL)||(!(*src)))
|
|
return strdup("");
|
|
|
|
char* buffer = calloc(1, strlen(src)*2+2);
|
|
char* ptr = buffer;
|
|
|
|
/* look for the first char to escape */
|
|
while (1)
|
|
{
|
|
char c;
|
|
/* copy over all chars not to escape */
|
|
while ((c=(*src)) && mhl_shell_escape_nottoesc(c))
|
|
{
|
|
*ptr = c;
|
|
ptr++;
|
|
src++;
|
|
}
|
|
|
|
/* at this point we either have an \0 or an char to escape */
|
|
if (!c)
|
|
return buffer;
|
|
|
|
*ptr = '\\';
|
|
ptr++;
|
|
*ptr = c;
|
|
ptr++;
|
|
src++;
|
|
}
|
|
}
|
|
|
|
/** Unescape paths or other strings for e.g the internal cd
|
|
shell-unescape within a given buffer (writing to it!)
|
|
|
|
/params const char * in
|
|
string for unescaping
|
|
/returns
|
|
return unescaped string
|
|
*/
|
|
static inline char* mhl_shell_unescape_buf(char* text)
|
|
{
|
|
if (!text)
|
|
return NULL;
|
|
|
|
// look for the first \ - that's quick skipover if there's nothing to escape
|
|
char* readptr = text;
|
|
while ((*readptr) && ((*readptr)!='\\')) readptr++;
|
|
if (!(*readptr)) return text;
|
|
|
|
// if we're here, we're standing on the first '\'
|
|
char* writeptr = readptr;
|
|
char c;
|
|
while ((c = *readptr))
|
|
{
|
|
if (c=='\\')
|
|
{
|
|
readptr++;
|
|
switch ((c = *readptr))
|
|
{
|
|
case 'n': (*writeptr) = '\n'; writeptr++; break;
|
|
case 'r': (*writeptr) = '\r'; writeptr++; break;
|
|
case 't': (*writeptr) = '\t'; writeptr++; break;
|
|
|
|
case ' ':
|
|
case '\\':
|
|
case '#':
|
|
case '$':
|
|
case '%':
|
|
case '(':
|
|
case ')':
|
|
case '[':
|
|
case ']':
|
|
case '{':
|
|
case '}':
|
|
case '<':
|
|
case '>':
|
|
case '!':
|
|
case '*':
|
|
case '?':
|
|
case '~':
|
|
case '`':
|
|
case '"':
|
|
case ';':
|
|
default:
|
|
(*writeptr) = c; writeptr++; break;
|
|
}
|
|
}
|
|
else // got a normal character
|
|
{
|
|
(*writeptr) = *readptr;
|
|
writeptr++;
|
|
}
|
|
readptr++;
|
|
}
|
|
*writeptr = 0;
|
|
|
|
return text;
|
|
}
|
|
|
|
/** Check if char in pointer contain escape'd chars
|
|
|
|
/params const char * in
|
|
string for checking
|
|
/returns
|
|
return TRUE if string contain escaped chars
|
|
otherwise return FALSE
|
|
*/
|
|
static inline int
|
|
mhl_shell_is_char_escaped ( const char *in ) {
|
|
if (in == NULL || !*in || in[0] != '\\') return FALSE;
|
|
if (mhl_shell_escape_toesc(in[1])){
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
#endif
|