~ubuntu-branches/ubuntu/raring/binkd/raring-proposed

« back to all changes in this revision

Viewing changes to srif.c

  • Committer: Bazaar Package Importer
  • Author(s): Marco d'Itri
  • Date: 2002-03-24 22:52:25 UTC
  • Revision ID: james.westby@ubuntu.com-20020324225225-7ru6itlapn03nl35
Tags: upstream-0.9.5a
ImportĀ upstreamĀ versionĀ 0.9.5a

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  srif.c -- Create flags or run external programs on mail events
 
3
 *
 
4
 *  srif.c is a part of binkd project
 
5
 *
 
6
 *  Copyright (C) 1996-1997  Dima Maloff, 5047/13
 
7
 *
 
8
 *  This program is free software; you can redistribute it and/or modify
 
9
 *  it under the terms of the GNU General Public License as published by
 
10
 *  the Free Software Foundation; either version 2 of the License, or
 
11
 *  (at your option) any later version. See COPYING.
 
12
 */
 
13
 
 
14
/*
 
15
 * $Id: srif.c,v 2.0 2001/01/10 12:12:39 gul Exp $
 
16
 *
 
17
 * $Log: srif.c,v $
 
18
 * Revision 2.0  2001/01/10 12:12:39  gul
 
19
 * Binkd is under CVS again
 
20
 *
 
21
 * Revision 1.4  1997/06/16  05:40:33  mff
 
22
 * Binkd will not complain about missing .rsp files when running
 
23
 * programms with "exec" statement without using of *S macro.
 
24
 *
 
25
 * Revision 1.3  1997/03/28  06:12:48  mff
 
26
 * Changes to support SRIF: + evt_run(), etc.
 
27
 *
 
28
 * Revision 1.2  1997/02/09  04:17:30  mff
 
29
 * Removed error msgs
 
30
 *
 
31
 * Revision 1.1  1997/01/08  03:57:54  mff
 
32
 * Initial revision
 
33
 *
 
34
 */
 
35
 
 
36
#include <string.h>
 
37
#include <stdlib.h>
 
38
#include <errno.h>
 
39
#include <ctype.h>
 
40
 
 
41
#include "Config.h"
 
42
#include "ftnaddr.h"
 
43
#include "ftnq.h"
 
44
#include "tools.h"
 
45
#include "srif.h"
 
46
#include "run.h"
 
47
#include "tools.h"
 
48
 
 
49
EVT_FLAG *evt_flags = 0;
 
50
 
 
51
/*
 
52
 * Tests if filename matches any of EVT_FLAG's patterns.
 
53
 */
 
54
int evt_test (char *filename0)
 
55
{
 
56
  EVT_FLAG *curr;
 
57
  char filename[MAXPATHLEN + 1];
 
58
  int rc=0;
 
59
 
 
60
  strnzcpy (filename, filename0, MAXPATHLEN);
 
61
  strlower (filename);
 
62
  for (curr = evt_flags; curr; curr = curr->next)
 
63
  {
 
64
    if (pmatch (curr->pattern, filename))
 
65
    {
 
66
      if (curr->path)
 
67
      {
 
68
        if (curr->imm)
 
69
        {
 
70
          Log (4, "got %s, creating %s", curr->pattern, curr->path);
 
71
          create_empty_sem_file (curr->path);
 
72
        }
 
73
        else
 
74
        {
 
75
          ++curr->flag;
 
76
          break;
 
77
        }
 
78
      }
 
79
      else if ((curr->command) && (curr->imm))
 
80
      {
 
81
        Log (4, "got %s, starting %s", curr->pattern, curr->command);
 
82
        rc=1;
 
83
      }
 
84
    }
 
85
  }
 
86
  return rc;
 
87
}
 
88
 
 
89
/*
 
90
 * Sets flags for all matched with evt_test events
 
91
 */
 
92
void evt_set (void)
 
93
{
 
94
  EVT_FLAG *curr;
 
95
 
 
96
  for (curr = evt_flags; curr; curr = curr->next)
 
97
  {
 
98
    if (curr->flag > 0)
 
99
    {
 
100
      Log (4, "got %s (%i), creating %s",
 
101
           curr->pattern, curr->flag, curr->path);
 
102
      curr->flag = 0;
 
103
      create_empty_sem_file (curr->path);
 
104
    }
 
105
  }
 
106
}
 
107
 
 
108
/* Makes SRIF request and SRIF response names from FTN address of a node */
 
109
static int mksrifpaths (FTN_ADDR *fa, char *srf, char *rsp)
 
110
{
 
111
  ftnaddress_to_filename (srf, fa);
 
112
  if (*srf)
 
113
  {
 
114
    strnzcpy (rsp, srf, MAXPATHLEN);
 
115
    strnzcat (srf, ".srf", MAXPATHLEN);
 
116
    strnzcat (rsp, ".rsp", MAXPATHLEN);
 
117
    return 1;
 
118
  }
 
119
  else
 
120
    return 0;
 
121
}
 
122
 
 
123
static int srif_fill (char *path, FTN_ADDR *fa, int nfa,
 
124
                       char *req, char *rsp,
 
125
                       int prot, int listed, char *peer_name)
 
126
{
 
127
  FILE *out;
 
128
  int i;
 
129
 
 
130
  if ((out = fopen (path, "w")) != 0)
 
131
  {
 
132
    fprintf (out, "Sysop sysop\n");
 
133
    for (i = 0; i < nfa; ++i)
 
134
    {
 
135
      char adr[FTN_ADDR_SZ + 1];
 
136
 
 
137
      ftnaddress_to_str (adr, fa + i);
 
138
      fprintf (out, "AKA %s\n", adr);
 
139
    }
 
140
    fprintf (out, "Baud 115200\n");
 
141
    fprintf (out, "Time -1\n");
 
142
    fprintf (out, "RequestList %s\n", req);
 
143
    fprintf (out, "ResponseList %s\n", rsp);
 
144
    fprintf (out, "RemoteStatus %s\n", prot ? "PROTECTED" : "UNPROTECTED");
 
145
    fprintf (out, "SystemStatus %s\n", listed ? "LISTED" : "UNLISTED");
 
146
    fprintf (out, "CallerID %s\n", peer_name);
 
147
    fprintf (out, "SessionType OTHER\n");
 
148
    fclose (out);
 
149
    return 1;
 
150
  }
 
151
  return 0;
 
152
}
 
153
 
 
154
static FTNQ *parse_response (FTNQ *q, char *rsp, FTN_ADDR *fa)
 
155
{
 
156
  FILE *in = fopen (rsp, "r");
 
157
 
 
158
  if (in)
 
159
  {
 
160
    char buf[MAXPATHLEN + 1];
 
161
    int i;
 
162
 
 
163
    while (!feof (in))
 
164
    {
 
165
      if (!fgets (buf, MAXPATHLEN, in))
 
166
        break;
 
167
      for (i = 0; i < sizeof (buf) - 1 && !isspace (buf[i]); ++i);
 
168
      buf[i] = 0;
 
169
      switch (*buf)
 
170
        {
 
171
          case '=':
 
172
            q = q_add_file (q, buf + 1, fa, 'h', 'd', 0);
 
173
            break;
 
174
          case '+':
 
175
            q = q_add_file (q, buf + 1, fa, 'h', 0, 0);
 
176
            break;
 
177
          case '-':
 
178
            q = q_add_file (q, buf + 1, fa, 'h', 'a', 0);
 
179
            break;
 
180
          default:
 
181
            break;
 
182
        }
 
183
    }
 
184
    fclose (in);
 
185
  }
 
186
  else
 
187
    Log (1, "parse_response: %s: %s", rsp, strerror (errno));
 
188
  return q;
 
189
}
 
190
 
 
191
static char valid_filename_chars[]=".\\-_:/@";
 
192
static void run_args(char *cmd, char *filename0, FTN_ADDR *fa, 
 
193
                 int nfa, int prot, int listed, char *peer_name, STATE *st)
 
194
{
 
195
  char *sp, *w;
 
196
  char *fn=filename0;
 
197
  char *pn=peer_name?peer_name:"";
 
198
  char ipaddr[16];
 
199
  char aka[4];
 
200
  char adr[FTN_ADDR_SZ + 2];
 
201
  int i;
 
202
  unsigned int l;
 
203
  unsigned int sw=1024;
 
204
  int use_fn=0;
 
205
 
 
206
  for(i=0;fn[i];i++)
 
207
  if((!isalnum(fn[i])) && (!strchr(valid_filename_chars, fn[i])))
 
208
  {
 
209
    fn="-";
 
210
    Log(4, "Invalid filename (%s) received!", filename0);
 
211
    break;
 
212
  }
 
213
  for(i=0;pn[i];i++)
 
214
  if((!isalnum(pn[i])) && (!strchr(valid_filename_chars, pn[i])))
 
215
  {
 
216
    i=0;
 
217
    break;
 
218
  }
 
219
  if(!i)
 
220
  {
 
221
    struct sockaddr_in sin;
 
222
    i=sizeof(struct sockaddr_in);
 
223
    if((!st) || (getpeername (st->s, (struct sockaddr *) &sin, &i) == -1))
 
224
      strcpy(ipaddr, "-");
 
225
    else  /* We don't like inet_ntoa ;-) */
 
226
    {
 
227
      sin.sin_addr.s_addr=htonl(sin.sin_addr.s_addr);
 
228
      sprintf(ipaddr, "%d.%d.%d.%d", 
 
229
                (int)(sin.sin_addr.s_addr>>24),
 
230
                (int)((sin.sin_addr.s_addr>>16)&0xFF),
 
231
                (int)((sin.sin_addr.s_addr>>8)&0xFF),
 
232
                (int)(sin.sin_addr.s_addr&0xFF));
 
233
    }
 
234
    pn=ipaddr;
 
235
  }
 
236
 
 
237
  if(sw<=strlen(cmd)) sw=strlen(cmd)+1;
 
238
  w=(char*)xalloc(sw);
 
239
  strcpy(w, cmd);
 
240
 
 
241
  strcpy(aka, "*A0");
 
242
 
 
243
  for(l=0;(l<strlen(w)) && ((sp=strchr(w+l, '*'))!=NULL); l++)
 
244
  {
 
245
    l=sp-w;
 
246
    switch(toupper(sp[1]))
 
247
    {
 
248
      case 'N': /* short filename for win32 */
 
249
#ifdef WIN32
 
250
        {
 
251
          char ts[MAXPATHLEN+1];
 
252
          i=GetShortPathName(filename0, ts, sizeof(ts));
 
253
          if((i<1) || (i>MAXPATHLEN))
 
254
          {
 
255
            Log(2, "GetShortPathName() fails %d", GetLastError());
 
256
            use_fn=1;
 
257
            strcpy(ts, fn);
 
258
          }
 
259
          w = ed (w, "*N", ts, &sw);
 
260
          break;
 
261
        }
 
262
#endif
 
263
        use_fn=1;
 
264
        w = ed (w, "*N", fn, &sw);
 
265
        break;
 
266
      case 'F': /* filename */
 
267
        use_fn=1;
 
268
        w = ed (w, "*F", fn, &sw);
 
269
        break;
 
270
      case 'A': /* AKA */
 
271
        i=isdigit(sp[2])?(sp[2]-'0'):0;
 
272
        if(i<nfa)
 
273
          ftnaddress_to_str (adr, fa+i);
 
274
        else
 
275
          strcpy(adr, "-");
 
276
        aka[2]=sp[2];
 
277
        if(!isdigit(sp[2]))  /* If you will remove it, *A *A1 may not work */
 
278
        {
 
279
          i=strlen(adr);
 
280
          adr[i++]=sp[2];
 
281
          adr[i]=0;
 
282
        }
 
283
        w = ed (w, aka, adr, &sw);
 
284
        break;
 
285
      case 'P': /* protected ? */
 
286
        w = ed (w, "*P", prot?"1":"0", &sw);
 
287
        break;
 
288
      case 'L': /* listed ? */
 
289
        w = ed (w, "*L", listed?"1":"0", &sw);
 
290
        break;
 
291
      case 'H': /* hostname or IP */
 
292
        w = ed (w, "*H", pn, &sw);
 
293
        break;
 
294
    }
 
295
  }
 
296
 
 
297
  if((fn!=filename0) && (use_fn))
 
298
    Log(1, "Security problem. Execution aborted...");
 
299
  else
 
300
    run(w);
 
301
  free(w);
 
302
}
 
303
 
 
304
/*
 
305
 * Runs external programs using S.R.I.F. interface
 
306
 * if the name matches one of our "exec"'s
 
307
 */
 
308
FTNQ *evt_run (FTNQ *q, char *filename0,
 
309
                FTN_ADDR *fa, int nfa,
 
310
                int prot, int listed, char *peer_name, STATE *st)
 
311
{
 
312
  EVT_FLAG *curr;
 
313
  char filename[MAXPATHLEN + 1];
 
314
 
 
315
  strnzcpy (filename, filename0, MAXPATHLEN);
 
316
  strlower (filename);
 
317
  for (curr = evt_flags; curr; curr = curr->next)
 
318
  {
 
319
    if (curr->command && pmatch (curr->pattern, filename) && 
 
320
        ((!st && !curr->imm) || (curr->imm && st)) )
 
321
    {
 
322
      char srf[MAXPATHLEN + 1], rsp[MAXPATHLEN + 1];
 
323
 
 
324
      if (strstr (curr->command, "*S") || strstr (curr->command, "*s"))
 
325
      {
 
326
        if (mksrifpaths (fa, srf, rsp))
 
327
        {
 
328
          char *w = ed (curr->command, "*S", srf, NULL);
 
329
 
 
330
          if (srif_fill (srf, fa, nfa, filename0, rsp, prot, listed, peer_name))
 
331
          {
 
332
            run_args (w, filename0, fa, nfa, prot, listed, peer_name, st);
 
333
          }
 
334
          else
 
335
            Log (1, "srif_fill: error");
 
336
          free (w);
 
337
          q = parse_response (q, rsp, fa);
 
338
          delete (srf);
 
339
          delete (rsp);
 
340
        }
 
341
        else
 
342
          Log (1, "mksrifpaths: error");
 
343
      }
 
344
      else
 
345
        run_args (curr->command, filename0, fa, nfa, prot, listed, peer_name, st);
 
346
    }
 
347
  }
 
348
  return q;
 
349
}