New extension statement #searchpath controls the search path for dynamically loaded extensions.
Showing
1 changed file
with
82 additions
and
11 deletions
... | @@ -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 | { | ... | ... |
-
Please register or sign in to post a comment