Home | History | Annotate | Line # | Download | only in global
      1 /*	$NetBSD: fold_addr.c,v 1.2 2017/02/14 01:16:45 christos Exp $	*/
      2 
      3 /*++
      4 /* NAME
      5 /*	fold_addr 3
      6 /* SUMMARY
      7 /*	address case folding
      8 /* SYNOPSIS
      9 /*	#include <fold_addr.h>
     10 /*
     11 /*	char	*fold_addr(result, addr, flags)
     12 /*	VSTRING *result;
     13 /*	const char *addr;
     14 /*	int	flags;
     15 /* DESCRIPTION
     16 /*	fold_addr() case folds an address according to the options
     17 /*	specified with \fIflags\fR. The result value is the output
     18 /*	address.
     19 /*
     20 /*	Arguments
     21 /* .IP result
     22 /*	Result buffer with the output address. Note: casefolding
     23 /*	may change the string length.
     24 /* .IP addr
     25 /*	Null-terminated read-only string with the input address.
     26 /* .IP flags
     27 /*	Zero or the bit-wise OR of:
     28 /* .RS
     29 /* .IP FOLD_ADDR_USER
     30 /*	Case fold the address local part.
     31 /* .IP FOLD_ADDR_HOST
     32 /*	Case fold the address domain part.
     33 /* .IP FOLD_ADDR_ALL
     34 /*	Alias for (FOLD_ADDR_USER | FOLD_ADDR_HOST).
     35 /* .RE
     36 /* SEE ALSO
     37 /*	msg(3) diagnostics interface
     38 /*	casefold(3) casefold text
     39 /* DIAGNOSTICS
     40 /*	Fatal errors: memory allocation problem.
     41 /* LICENSE
     42 /* .ad
     43 /* .fi
     44 /*	The Secure Mailer license must be distributed with this software.
     45 /* AUTHOR(S)
     46 /*	Wietse Venema
     47 /*	IBM T.J. Watson Research
     48 /*	P.O. Box 704
     49 /*	Yorktown Heights, NY 10598, USA
     50 /*--*/
     51 
     52 /* System library. */
     53 
     54 #include <sys_defs.h>
     55 #include <string.h>
     56 
     57 /* Utility library. */
     58 
     59 #include <stringops.h>
     60 
     61 /* Global library. */
     62 
     63 #include <fold_addr.h>
     64 
     65 #define STR(x)	vstring_str(x)
     66 
     67 /* fold_addr - case fold mail address */
     68 
     69 char   *fold_addr(VSTRING *result, const char *addr, int flags)
     70 {
     71     char   *cp;
     72 
     73     /*
     74      * Fold the address as appropriate.
     75      */
     76     switch (flags & FOLD_ADDR_ALL) {
     77     case FOLD_ADDR_HOST:
     78 	if ((cp = strrchr(addr, '@')) != 0) {
     79 	    cp += 1;
     80 	    vstring_strncpy(result, addr, cp - addr);
     81 	    casefold_append(result, cp);
     82 	    break;
     83 	}
     84 	/* FALLTHROUGH */
     85     case 0:
     86 	vstring_strcpy(result, addr);
     87 	break;
     88     case FOLD_ADDR_USER:
     89 	if ((cp = strrchr(addr, '@')) != 0) {
     90 	    casefold_len(result, addr, cp - addr);
     91 	    vstring_strcat(result, cp);
     92 	    break;
     93 	}
     94 	/* FALLTHROUGH */
     95     case FOLD_ADDR_USER | FOLD_ADDR_HOST:
     96 	casefold(result, addr);
     97 	break;
     98     }
     99     return (STR(result));
    100 }
    101 
    102 #ifdef TEST
    103 #include <stdlib.h>
    104 #include <vstream.h>
    105 #include <vstring_vstream.h>
    106 #include <msg_vstream.h>
    107 #include <argv.h>
    108 
    109 int     main(int argc, char **argv)
    110 {
    111     VSTRING *line_buffer = vstring_alloc(1);
    112     VSTRING *fold_buffer = vstring_alloc(1);
    113     ARGV   *cmd;
    114     char  **args;
    115 
    116     msg_vstream_init(argv[0], VSTREAM_ERR);
    117     util_utf8_enable = 1;
    118     while (vstring_fgets_nonl(line_buffer, VSTREAM_IN)) {
    119 	vstream_printf("> %s\n", STR(line_buffer));
    120 	cmd = argv_split(STR(line_buffer), CHARS_SPACE);
    121 	if (cmd->argc == 0 || cmd->argv[0][0] == '#') {
    122 	    argv_free(cmd);
    123 	    continue;
    124 	}
    125 	args = cmd->argv;
    126 
    127 	/*
    128 	 * Fold the host.
    129 	 */
    130 	if (strcmp(args[0], "host") == 0 && cmd->argc == 2) {
    131 	    vstream_printf("\"%s\" -> \"%s\"\n", args[1], fold_addr(fold_buffer,
    132 						  args[1], FOLD_ADDR_HOST));
    133 	}
    134 
    135 	/*
    136 	 * Fold the user.
    137 	 */
    138 	else if (strcmp(args[0], "user") == 0 && cmd->argc == 2) {
    139 	    vstream_printf("\"%s\" -> \"%s\"\n", args[1], fold_addr(fold_buffer,
    140 						  args[1], FOLD_ADDR_USER));
    141 	}
    142 
    143 	/*
    144 	 * Fold user and host.
    145 	 */
    146 	else if (strcmp(args[0], "all") == 0 && cmd->argc == 2) {
    147 	    vstream_printf("\"%s\" -> \"%s\"\n", args[1], fold_addr(fold_buffer,
    148 						   args[1], FOLD_ADDR_ALL));
    149 	}
    150 
    151 	/*
    152 	 * Fold none.
    153 	 */
    154 	else if (strcmp(args[0], "none") == 0 && cmd->argc == 2) {
    155 	    vstream_printf("\"%s\" -> \"%s\"\n", args[1], fold_addr(fold_buffer,
    156 							       args[1], 0));
    157 	}
    158 
    159 	/*
    160 	 * Usage.
    161 	 */
    162 	else {
    163 	    vstream_printf("Usage: %s host <addr> | user <addr> | all <addr>\n",
    164 			   argv[0]);
    165 	}
    166 	vstream_fflush(VSTREAM_OUT);
    167 	argv_free(cmd);
    168     }
    169     vstring_free(line_buffer);
    170     vstring_free(fold_buffer);
    171     exit(0);
    172 }
    173 
    174 #endif					/* TEST */
    175