Commit f486f514 f486f514f72e3a2fd3be5ef85610e2faa483327b by Sergey Poznyakoff

New extension statement #searchpath controls the search path for dynamically loaded extensions.

1 parent 069b5683
...@@ -43,6 +43,7 @@ static void multiline_add __P ((void)); ...@@ -43,6 +43,7 @@ static void multiline_add __P ((void));
43 static void multiline_finish __P ((void)); 43 static void multiline_finish __P ((void));
44 static void ident __P((const char *text)); 44 static void ident __P((const char *text));
45 static void sieve_include __P((void)); 45 static void sieve_include __P((void));
46 static void sieve_searchpath __P((void));
46 47
47 #ifdef FLEX_SCANNER 48 #ifdef FLEX_SCANNER
48 #define xinput() (yyin ? getc(yyin) : EOF) 49 #define xinput() (yyin ? getc(yyin) : EOF)
...@@ -324,6 +325,7 @@ SIZESUF [kKmMgG] ...@@ -324,6 +325,7 @@ SIZESUF [kKmMgG]
324 <COMMENT>"*"+"/" BEGIN(INITIAL); 325 <COMMENT>"*"+"/" BEGIN(INITIAL);
325 /* Preprocessor directives (an extension) */ 326 /* Preprocessor directives (an extension) */
326 #[ \t]*include.*\n { sieve_include (); } 327 #[ \t]*include.*\n { sieve_include (); }
328 #[ \t]*searchpath.*\n { sieve_searchpath (); }
327 /* End-of-line comments */ 329 /* End-of-line comments */
328 #.*\n { sieve_line_num++; } 330 #.*\n { sieve_line_num++; }
329 #.* /* end-of-file comment */; 331 #.* /* end-of-file comment */;
...@@ -361,16 +363,14 @@ yywrap () ...@@ -361,16 +363,14 @@ yywrap ()
361 return pop_source(); 363 return pop_source();
362 } 364 }
363 365
364 void 366 static char *
365 sieve_include () 367 get_file_name (char *p, char *endp, int *usepath)
366 { 368 {
367 char *p, *startp, *endp = yytext + yyleng, exp, *name; 369 char exp, *name, *startp;
368 int n; 370 int n;
369 371
370 p = strstr (yytext, "include"); 372 if (usepath)
371 for (p += 7; p < endp && isspace (*p); p++) 373 *usepath = 0;
372 ;
373
374 switch (*p) 374 switch (*p)
375 { 375 {
376 case '"': 376 case '"':
...@@ -379,11 +379,13 @@ sieve_include () ...@@ -379,11 +379,13 @@ sieve_include ()
379 379
380 case '<': 380 case '<':
381 exp = '>'; 381 exp = '>';
382 if (usepath)
383 *usepath = 1;
382 break; 384 break;
383 385
384 default: 386 default:
385 yyerror ("include syntax"); 387 yyerror ("preprocessor syntax");
386 return; 388 return NULL;
387 } 389 }
388 390
389 for (startp = ++p; p < endp && *p != exp; p++) 391 for (startp = ++p; p < endp && *p != exp; p++)
...@@ -391,19 +393,88 @@ sieve_include () ...@@ -391,19 +393,88 @@ sieve_include ()
391 393
392 if (*p != exp) 394 if (*p != exp)
393 { 395 {
394 yyerror ("missing closing quote in include statement"); 396 yyerror ("missing closing quote in preprocessor statement");
395 return; 397 return NULL;
396 } 398 }
397 399
398 n = p - startp; 400 n = p - startp;
399 name = sieve_alloc (n + 1); 401 name = sieve_alloc (n + 1);
400 memcpy (name, startp, n); 402 memcpy (name, startp, n);
401 name[n] = 0; 403 name[n] = 0;
404 return name;
405 }
406
407 static int
408 _try_include (void *item, void *data)
409 {
410 char **dir = data;
411 char *name = malloc (strlen (item) + 1 + strlen (*dir) + 1);
412
413 if (!name)
414 return 0;
415 sprintf (name, "%s/%s", (char*) item, *dir);
416 if (access (name, R_OK) == 0)
417 {
418 *(char**) data = name;
419 return 1;
420 }
421 free (name);
422 return 0;
423 }
424
425 void
426 sieve_include ()
427 {
428 char *p, *endp = yytext + yyleng, *name;
429 int usepath;
430
431 p = strstr (yytext, "include");
432 for (p += 7; p < endp && isspace (*p); p++)
433 ;
434
435 name = get_file_name (p, endp, &usepath);
436 if (!name)
437 return;
438
439 if (usepath && name[0] != '/' && memcmp (name, "..", 2))
440 {
441 char *p = name;
442 if (list_do (sieve_include_path, _try_include, &p))
443 {
444 push_source (p);
445 free (name);
446 free (p);
447 return;
448 }
449 }
402 450
403 push_source (name); 451 push_source (name);
404 free (name); 452 free (name);
405 } 453 }
406 454
455 void
456 sieve_searchpath ()
457 {
458 int append = 0;
459 char *p, *endp = yytext + yyleng, *name;
460
461 p = strstr (yytext, "searchpath");
462 for (p += 10; p < endp && isspace (*p); p++)
463 ;
464 if (strcmp (p, "add") == 0)
465 {
466 append = 1;
467 for (p += 3; p < endp && isspace (*p); p++)
468 ;
469 }
470 name = get_file_name (p, endp, NULL);
471 if (name)
472 {
473 sieve_load_add_dir (sieve_machine, name);
474 free (name);
475 }
476 }
477
407 int 478 int
408 sieve_lex_begin (const char *name) 479 sieve_lex_begin (const char *name)
409 { 480 {
......