File: attach.c

package info (click to toggle)
ifmail 2.14tx8.10-11
  • links: PTS
  • area: main
  • in suites: potato
  • size: 2,856 kB
  • ctags: 2,996
  • sloc: ansic: 30,319; perl: 4,955; yacc: 834; makefile: 730; sh: 425; cpp: 235; lex: 206; awk: 24
file content (131 lines) | stat: -rw-r--r-- 2,633 bytes parent folder | download | duplicates (12)
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
121
122
123
124
125
126
127
128
129
130
131
/* ### Modified by P.Saratxaga on We 10 Jan 1996 ###
 * - added all inbound's abel to file attachs if -DRELAXED
 */ 
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>
#include "ftn.h"
#include "lutil.h"
#include "config.h"

#ifndef PATH_MAX
#define PATH_MAX 512
#endif

/* increase this if you want to forward files from list/norm inbound */
#ifndef RELAXED
#define NUMDIRS 2
#else
#define NUMDIRS 5
#endif

extern FILE *openflo(faddr *,char);

void try_attach(fn,mode,addr,flavor)
char *fn;
int mode;
faddr *addr;
char flavor;
{
	FILE *flo;
	char pn[PATH_MAX],*p,*f;
	char *dirs[NUMDIRS];
	int i,j;

	debug(3,"Trying fileattach \"%s\" (mode %d) to %s (flavor %c)",
		S(fn),mode,ascfnode(addr,0x1f),flavor);

	if (fn == NULL) return;

	if (strstr(fn,"/../") ||
	    strstr(fn,"/..\\") ||
	    strstr(fn,"\\../") ||
	    strstr(fn,"\\..\\"))
	{
		loginf("attempt to attach file from outside restricted area \"%s\"",
			fn);
		return;
	}

	/*
	NOTE: you cannot attach a file from any point of the filesystem
	because that would be a security hole: anyone would be able to
	get any file from your system (readable for ifmail) sending a
	message to himself with an ATT flag.
	*/

	dirs[0]=pubdir;
	dirs[1]=protinbound;
#ifdef RELAXED
	dirs[2]=inbound;
	dirs[3]=norminbound;
	dirs[4]=listinbound;
#endif
	/* add more... */

	for (i=0;i<NUMDIRS;i++)
	for (j=0;j<2;j++)
	{
		if (j == 0)
		{
			strncpy(pn,dirs[i],sizeof(pn)-2);
			pn[strlen(dirs[i])]='/';
			for (f=fn;(*f) && (isspace(*f));f++);
			for (p=pn+strlen(dirs[i])+1;
				(*f) && (*f != '\n') && (!isspace(*f)) &&
				(p < pn+sizeof(pn)-1);
				p++,f++)
			{
				if (*f == '\\') *p='/';
				else *p=*f;
			}
			*p='\0';
		}
		else
		{
			for (p=pn+strlen(dirs[i])+1;*p;p++)
				*p=tolower(*p);
		}
	
		debug(3,"Checking \"%s\"",S(pn));

		if (access(pn,R_OK) == 0)
		{
			if ((flo=openflo(addr,flavor)) == NULL) return;

			if ((p=strrchr(pn,'/')))
			{
				f=fn;
				while (*(++p)) *(f++)=*p;
				*(f++)='\0';
			}

			debug(3,"attaching file \"%s\" to node %s",
				S(pn),ascfnode(addr,0x1f));

			fseek(flo,0L,SEEK_END);
			if (i == 1) /* transit files must be killed */
				fprintf(flo,"^");
			else if (i > 1) /* public files must not be killed */
			switch (mode)
			{
			case 0:	break;
			case 1: fprintf(flo,"#"); break;
			case 2: fprintf(flo,"^"); break;
			}
			fprintf(flo,"%s\n",pn);

			fclose(flo);
			loginf("Attached \"%s\" to %s",
				fn,ascfnode(addr,0x1f));
			return;
		}
	}
	loginf("fileattach \"%s\" to %s failed: no file",
		S(fn),ascfnode(addr,0x1f));
	return;
}