summaryrefslogtreecommitdiff
path: root/alpine/osdep/fltrname.c
blob: 7af381ebea6d13a53d98fa8051b1833f62febb94 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#if !defined(lint) && !defined(DOS)
static char rcsid[] = "$Id: fltrname.c 769 2007-10-24 00:15:40Z hubert@u.washington.edu $";
#endif

/*
 * ========================================================================
 * Copyright 2006-2007 University of Washington
 * Copyright 2013-2021 Eduardo Chappa
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * ========================================================================
 */

#include "../c-client/mail.h"	/* for MAILSTREAM */
#undef ERROR

#include <system.h>
#include <general.h>

#include "../../pith/osdep/writ_dir.h"
#include "../../pith/osdep/bldpath.h"

#include "fltrname.h"


/*----------------------------------------------------------------------
    Filter file names for strange characters

   Args:  file  -- the file name to check
 
 Result: Returns NULL if file name is OK
         Returns formatted error message if it is not
  ----*/
char *
filter_filename(char *file, int *fatal, int strict)
{
#define ERRORLEN 100
#define ALLOW_WEIRD 1
#ifdef ALLOW_WEIRD
    static char illegal[] = {'\177', '\0'};
#else
#ifdef	_WINDOWS
    static char illegal[] = {'"', '#', '$', '%', '&', /*'/',*/ '(', ')','*',
                          ',', ';', '<', '=', '>', '?', '[', ']',
                          '^', '|', '\177', '\0'};
#else	/* UNIX */
    static char illegal[] = {'"', '#', '$', '%', '&', '\'','(', ')','*',
                          ',', ':', ';', '<', '=', '>', '?', '[', ']',
                          '\\', '^', '|', '\177', '\0'};
#endif	/* UNIX */
#endif
    static char error[ERRORLEN];
    char ill_file[MAXPATH+1], *ill_char, *ptr, e2[20];
    int i;

    for(ptr = file; *ptr == ' '; ptr++) ; /* leading spaces gone */

    while(*ptr && (unsigned char)(*ptr) >= ' ' && strchr(illegal, *ptr) == 0)
      ptr++;

    *fatal = TRUE;
    if(*ptr != '\0') {
        if(*ptr == '\n') {
            ill_char = "<newline>";
        } else if(*ptr == '\r') {
            ill_char = "<carriage return>";
        } else if(*ptr == '\t') {
    	    ill_char = "<tab>";
	    *fatal = FALSE;		/* just whitespace */
        } else if(*ptr < ' ') {
            snprintf(e2, sizeof(e2), "control-%c", *ptr + '@');
            ill_char = e2;
        } else if (*ptr == '\177') {
    	    ill_char = "<del>";
        } else {
    	    e2[0] = *ptr;
    	    e2[1] = '\0';
    	    ill_char = e2;
	    *fatal = FALSE;		/* less offensive? */
        }
	if(!*fatal){
	    strncpy(error, ill_char, sizeof(error)-1);
	    error[sizeof(error)-1] = '\0';
	}
        else if(ptr != file) {
            strncpy(ill_file, file, MIN(ptr-file,sizeof(ill_file)-1));
            ill_file[MIN(ptr-file,sizeof(ill_file)-1)] = '\0';
	    snprintf(error, sizeof(error),
		    "Character \"%s\" after \"%.*s\" not allowed in file name",
		    ill_char, ERRORLEN-57, ill_file);
        } else {
            snprintf(error, sizeof(error),
                    "First character, \"%s\", not allowed in file name",
                    ill_char);
        }
            
        return(error);
    }

    if((i=is_writable_dir(file)) == 0 || i == 1){
	snprintf(error, sizeof(error), "\"%.*s\" is a directory", ERRORLEN-50, file);
        return(error);
    }

    if(strict){
	for(ptr = file; *ptr == ' '; ptr++) ;	/* leading spaces gone */

	if((ptr[0] == '.' && ptr[1] == '.') || filename_parent_ref(ptr)){
	    snprintf(error, sizeof(error), "\"..\" not allowed in filename");
	    return(error);
	}
    }

    return((char *)NULL);
}