diff options
| author | Sam Varshavchik | 2013-08-19 16:39:41 -0400 | 
|---|---|---|
| committer | Sam Varshavchik | 2013-08-25 14:43:51 -0400 | 
| commit | 9c45d9ad13fdf439d44d7443ae75da15ea0223ed (patch) | |
| tree | 7a81a04cb51efb078ee350859a64be2ebc6b8813 /sqwebmail/addressbook.c | |
| parent | a9520698b770168d1f33d6301463bb70a19655ec (diff) | |
| download | courier-libs-9c45d9ad13fdf439d44d7443ae75da15ea0223ed.tar.bz2 | |
Initial checkin
Imported from subversion report, converted to git. Updated all paths in
scripts and makefiles, reflecting the new directory hierarchy.
Diffstat (limited to 'sqwebmail/addressbook.c')
| -rw-r--r-- | sqwebmail/addressbook.c | 1050 | 
1 files changed, 1050 insertions, 0 deletions
| diff --git a/sqwebmail/addressbook.c b/sqwebmail/addressbook.c new file mode 100644 index 0000000..75c1aa8 --- /dev/null +++ b/sqwebmail/addressbook.c @@ -0,0 +1,1050 @@ +#include "config.h" +/* +** Copyright 2000-2011 Double Precision, Inc.  See COPYING for +** distribution information. +*/ + +/* +*/ + +#include	"sqwebmail.h" +#include	"addressbook.h" +#include	"maildir.h" +#include	"cgi/cgi.h" +#include	"rfc822/rfc822.h" +#include	"maildir/maildirmisc.h" +#include	"numlib/numlib.h" +#include	<stdio.h> +#include	<string.h> +#include	<ctype.h> + +#define	ADDRESSBOOK	"sqwebmail-addressbook" + +#define TOUTF8(what)	\ +	libmail_u_convert_toutf8((what), sqwebmail_content_charset, NULL) + +extern const char *sqwebmail_content_charset; + +extern void output_attrencoded(const char *); +extern void output_attrencoded_fp(const char *, FILE *); +extern void output_urlencoded(const char *); +extern void print_safe(const char *); +extern void call_print_safe_to_stdout(const char *p, size_t cnt); + +static char *q_escape(const char *name) +{ +	char *names; +	const char *cp; +	size_t namelen; +	char *p; + +	namelen=1; + +	for (cp=name; *cp; ++cp, ++namelen) +		if (*cp == '"' || *cp == '\\') +			++namelen; + +	names=malloc(namelen); +	if (!names) +	{ +		enomem(); +	} + +	for (p=names, cp=name; *cp; ++cp) +	{ +		if (iscntrl((int)(unsigned char)*cp))	continue; + +		if (*cp == '"' || *cp == '\\') +			*p++='\\'; +		*p++= *cp; +	} +	*p=0; + +	return names; +} + +/* +** When adding a new name/address pair into the address book delete +** bad characters from both. +*/ + +static void fix_nameaddr(const char *name, const char *addr, +	char **nameret, char **addrret) +{ +	char *names, *addresss; +	char	*p, *q; + +	names=q_escape(name); + +	if ((addresss=strdup(addr)) == 0) +	{ +		free(names); +		enomem(); +	} + +	for (p=q=addresss; *p; p++) +	{ +		if (isspace((int)(unsigned char)*p))	continue; +		if (iscntrl((int)(unsigned char)*p))	continue; +		if (*p == '<' || *p == '>' || *p == '(' || *p == ')' || +			*p == '\\') +			continue; +		*q++=*p; +	} +	*q=0; + +	*nameret=names; +	*addrret=addresss; +} + +static void ab_add_int(const char *name, const char *address, const char *nick) +{ +	char	*nicks, *names, *addresss, *p, *q; +	FILE	*fp; +	char	*header, *value; + +	int	new_fd; +	char	*new_name; +	FILE	*new_fp; +	int	written; + +	/* Delete bad characters from nickname, name, address */ + +	if ((nicks=strdup(nick)) == 0)	enomem(); + +	for (p=q=nicks; *p; p++) +	{ +		if (isspace((int)(unsigned char)*p))	continue; +		if (iscntrl((int)(unsigned char)*p))	continue; +		if (strchr(":;,<>@\\", *p))	continue; +		*q++=*p; +	} +	*q=0; + +	if (*nicks == 0) +	{ +		free(nicks); +		return; +	} + +	/* Remove quotes from name */ + +	fix_nameaddr(name, address, &names, &addresss); + +	if (*addresss == 0) +	{ +		free(addresss); +		free(nicks); +		free(names); +		return; +	} + +	fp=fopen(ADDRESSBOOK, "r"); + +	new_fd=maildir_createmsg(INBOX, "addressbook", &new_name); +	p=malloc(sizeof("tmp/")+strlen(new_name)); +	if (!p) +	{ +		close(new_fd); +		free(new_name); +		enomem(); +	} +	strcat(strcpy(p, "tmp/"), new_name); +	free(new_name); +	new_name=p; + +	if (new_fd < 0 || (new_fp=fdopen(new_fd, "w")) == 0) +	{ +		if (new_fd >= 0)	close(new_fd); +		free(addresss); +		free(nicks); +		free(names); +		enomem(); +		return; +	} + +	written=0; +	while (fp && (header=maildir_readheader_nolc(fp, &value)) != 0) +	{ +		if (strcmp(header, nicks) == 0) +		{ +			fprintf(new_fp, "%s: %s,\n    ", +				nicks, value); +			written=1; +			break; +		} +		fprintf(new_fp, "%s: %s\n", header, value); +	} +	if (!written) +		fprintf(new_fp, "%s: ", nicks); +	if (*names) +		fprintf(new_fp, "\"%s\" <%s>\n", +			names, addresss); +	else +		fprintf(new_fp, "<%s>\n", addresss); +	free(names); +	free(addresss); +	free(nicks); + +	while (fp && (header=maildir_readheader_nolc(fp, &value)) != 0) +		fprintf(new_fp, "%s: %s\n", header, value); + +	if (fp) fclose(fp); + +	if (fflush(new_fp) || ferror(new_fp)) +	{ +		fclose(new_fp); +		close(new_fd); +		unlink(new_name); +		free(new_name); +		error("Unable to write out new address book -- write error, or out of disk space."); +		return; +	} +	fclose(new_fp); + +	rename(new_name, ADDRESSBOOK); +	free(new_name); +} + +void ab_add(const char *name, const char *address, const char *nick) +{ +	char *nick_utf8, *name_utf8, *addr_utf8; + +	if (*nick == 0 || *address == 0) +		return; + +	nick_utf8=TOUTF8(nick); +	name_utf8=TOUTF8(name ? name:""); +	addr_utf8=TOUTF8(address); + +	if (nick_utf8 && name_utf8 && addr_utf8) +		ab_add_int(name_utf8, addr_utf8, nick_utf8); + +	if (nick_utf8) +		free(nick_utf8); +	if (name_utf8) +		free(name_utf8); +	if (addr_utf8) +		free(addr_utf8); +} + +/* note: we're always passing utf-8 to dodel() */ + +static void dodel(const char *nick, struct rfc822a *a, int n, +	const char *replace_name, const char *replace_addr) +{ +char	*p; +FILE	*fp, *new_fp; +char	*new_name; +int	new_fd; +char	*header, *value; + +char	*namebuf=0, *addrbuf=0; +struct	rfc822token namet, addresst; + +	if (replace_name && replace_addr && n < a->naddrs) +	{ +		fix_nameaddr(replace_name, replace_addr, &namebuf, &addrbuf); +		namet.token='"'; +		namet.ptr=namebuf; +		namet.len=strlen(namebuf); +		namet.next=0; +		a->addrs[n].name= &namet; + +		addresst.token=0; +		addresst.ptr=addrbuf; +		addresst.len=strlen(addrbuf); +		addresst.next=0; +		a->addrs[n].tokens= &addresst; +	} +	else +	{ +		while (++n < a->naddrs) +			a->addrs[n-1]=a->addrs[n]; +		--a->naddrs;		/* It's that simple... */ +	} + +	fp=fopen(ADDRESSBOOK, "r"); + +	new_fd=maildir_createmsg(INBOX, "addressbook", &new_name); +	if (new_fd < 0 || (new_fp=fdopen(new_fd, "w")) == 0) +	{ +		if (new_fd >= 0)	close(new_fd); +		fclose(fp); +		enomem(); +		return; +	} +	p=malloc(sizeof("tmp/")+strlen(new_name)); +	if (!p) +	{ +		unlink(new_name); +		fclose(fp); +		fclose(new_fp); +		free(new_name); +		enomem(); +	} +	strcat(strcpy(p, "tmp/"), new_name); +	free(new_name); +	new_name=p; + +	while (fp && (header=maildir_readheader_nolc(fp, &value)) != 0) +	{ +		if (strcmp(header, nick) == 0) +		{ +		char	*s, *t; + +			if (a->naddrs == 0) +				continue; +			s=rfc822_getaddrs_wrap(a, 70); + +			if (!s) +			{ +				fclose(new_fp); +				close(new_fd); +				fclose(fp); +				unlink(new_name); +				enomem(); +			} +			fprintf(new_fp, "%s: ", header); +				for (t=s; *t; t++) +				{ +					putc(*t, new_fp); +					if (*t == '\n') +						fprintf(new_fp, "    "); +				} +			fprintf(new_fp, "\n"); +			free(s); +			continue; +		} +		fprintf(new_fp, "%s: %s\n", header, value); +	} +	if (fp) fclose(fp); + +	if (namebuf)	free(namebuf); +	if (addrbuf)	free(addrbuf); + +	if (fflush(new_fp) || ferror(new_fp)) +	{ +		fclose(new_fp); +		unlink(new_name); +		free(new_name); +		error("Unable to write out new address book -- write error, or out of disk space."); +		return; +	} + +	fclose(new_fp); +	rename(new_name, ADDRESSBOOK); +	free(new_name); +} + +static void dodelall(const char *nick) +{ +FILE	*fp, *new_fp; +int	new_fd; +char	*new_name, *p; +char	*header, *value; + +	fp=fopen(ADDRESSBOOK, "r"); + +	new_fd=maildir_createmsg(INBOX, "addressbook", &new_name); +	if (new_fd < 0 || (new_fp=fdopen(new_fd, "w")) == 0) +	{ +		if (new_fd >= 0)	close(new_fd); +		fclose(fp); +		enomem(); +		return; +	} +	p=malloc(sizeof("tmp/")+strlen(new_name)); +	if (!p) +	{ +		unlink(new_name); +		fclose(fp); +		fclose(new_fp); +		free(new_name); +		enomem(); +	} +	strcat(strcpy(p, "tmp/"), new_name); +	free(new_name); +	new_name=p; + +	while (fp && (header=maildir_readheader_nolc(fp, &value)) != 0) +	{ +		if (strcmp(header, nick) == 0)	continue; +		fprintf(new_fp, "%s: %s\n", header, value); +	} +	if (fp) fclose(fp); + +	if (fflush(new_fp) || ferror(new_fp)) +	{ +		fclose(new_fp); +		unlink(new_name); +		free(new_name); +		error("Unable to write out new address book -- write error, or out of disk space."); +		return; +	} + +	fclose(new_fp); +	rename(new_name, ADDRESSBOOK); +	free(new_name); +} + +void ab_listselect() +{ +	ab_listselect_fp(stdout); +} + +struct abooklist { +	struct abooklist *next; +	char *name; +	} ; + +static void abl_free(struct abooklist *a) +{ +struct abooklist *b; + +	while (a) +	{ +		b=a->next; +		free(a->name); +		free(a); +		a=b; +	} +} + +static int sortabook(const void *a, const void *b) +{ +	return ( strcmp( (*(struct abooklist * const *)a)->name, +			(*(struct abooklist * const *)b)->name)); +} + +void ab_listselect_fp(FILE *w) +{ +	FILE	*fp; +	char *header, *value; +	struct	abooklist *a=0, *b, **aa; +	size_t	acnt=0, i; + +	if ((fp=fopen(ADDRESSBOOK, "r")) != 0) +	{ +		while ((header=maildir_readheader_nolc(fp, &value)) != NULL) +		{ +			if ((b=malloc(sizeof(struct abooklist))) == 0 || +				(b->name=strdup(header)) == 0) +			{ +				if (b)	free(b); +				abl_free(a); +				enomem(); +			} +			b->next=a; +			a=b; +			acnt++; +		} +		fclose(fp); + +		if ((aa=malloc(sizeof(struct abooklist *)*(acnt+1))) == 0) +		{ +			abl_free(a); +			enomem(); +		} + +		for (acnt=0, b=a; b; b=b->next) +			aa[acnt++]=b; +		qsort(aa, acnt, sizeof(*aa), sortabook); + +		for (i=0; i<acnt; i++) +		{ +			char *p=libmail_u_convert_fromutf8(aa[i]->name, +							   sqwebmail_content_charset, +							   NULL); + +			fprintf(w, "<option value=\""); +			output_attrencoded_fp(p ? p:aa[i]->name, w); +			fprintf(w, "\">"); + +			output_attrencoded_fp(p ? p:aa[i]->name, w); +			if (p) +				free(p); +			fprintf(w, "</option>\n"); +		} +		free(aa); +		abl_free(a); +	} +} + +/* +** Extract all name/address entries from the address book, for external +** processing (mostly calendaring). +*/ + +int ab_get_nameaddr( int (*callback_func)(const char *, const char *, +					  void *), +		     void *callback_arg) +{ +	FILE	*fp; +	char *header, *value; +	int rc=0; + +	if ((fp=fopen(ADDRESSBOOK, "r")) != 0) +	{ +		while ((header=maildir_readheader_nolc(fp, &value)) != NULL) +		{ +			struct rfc822t *t; +			struct rfc822a *a; + +			if (!value) +				continue; + +			t=rfc822t_alloc_new(value, NULL, NULL); +			a=t ? rfc822a_alloc(t):0; + +			if (a) +			{ +				int i; + +				for (i=0; i<a->naddrs; i++) +				{ +					char *addr; +					char *name; + +					if (a->addrs[i].tokens == NULL) +						continue; + +					addr=rfc822_display_addr_tobuf(a, i, +								       NULL); +					if (!addr) +						continue; + +					name=a->addrs[i].name ? +						rfc822_display_name_tobuf(a, i, +									  NULL): +						NULL; + +					rc=(*callback_func)(addr, name, +							    callback_arg); +					if (name) +						free(name); +					free(addr); +					if (rc) +						break; +				} +			} + +			if (a) rfc822a_free(a); +			if (t) rfc822t_free(t); +			if (rc) +				break; +		} +		fclose(fp); +	} +	return (rc); +} + +struct ab_addrselect_s { +	struct ab_addrselect_s *next; +	char *name; +	char *addr; +} ; + +static int ab_addrselect_cb(const char *a, const char *n, void *vp) +{ +	struct ab_addrselect_s **p=(struct ab_addrselect_s **)vp, *q; + +	if (!n || !a) +		return (0); + +	while ( (*p) && strcasecmp((*p)->name, n) < 0) +		p= &(*p)->next; + +	if ((q=malloc(sizeof(struct ab_addrselect_s))) == NULL) +		return (-1); + +	if ((q->name=strdup(n)) == NULL) +	{ +		free(q); +		return(-1); +	} + +	if ((q->addr=strdup(a)) == NULL) +	{ +		free(q->name); +		free(q); +		return(-1); +	} + +	q->next= *p; +	*p=q; +	return (0); +} + +static void ab_show_utf8(const char *p) +{ +	int err; +	char *p_s=libmail_u_convert_fromutf8(p, sqwebmail_content_charset, +					     &err); + +	if (!p_s) +		return; + +	if (err) +	{ +		free(p_s); +		return; +	} + +	p=p_s; + +	while (*p) +	{ +		size_t i; + +		for (i=0; p[i]; ++i) +		{ +			if (*p == '"' || *p == '\\') +				break; +		} + +		if (i) +			call_print_safe_to_stdout(p, i); + +		p += i; + +		if (*p) +		{ +			putchar('\\'); +			putchar(*p); +			++p; +		} +	} +	free(p_s); +	return; +} + + +void ab_nameaddr_show(const char *name, const char *addr) +{ +	if (name) +	{ +		printf("\""); +		ab_show_utf8(name); +		printf("\" "); +	} +	printf("<"); + +	if (addr) +		ab_show_utf8(addr); + +	printf(">"); +} + +void ab_addrselect() +{ +	struct ab_addrselect_s *list=NULL, *p; + +	printf("<select name=\"addressbookname\"><option value=\"\"></option>\n"); + +	if (ab_get_nameaddr(ab_addrselect_cb, &list) == 0) +	{ +		for (p=list; p; p=p->next) +		{ +			printf("<option value=\""); +			output_attrencoded(p->addr); +			printf("\">"); +			ab_nameaddr_show(p->name, p->addr); +			printf("</option>\n"); +		} +	} +	printf("</select>\n"); + +	while ((p=list) != NULL) +	{ +		list=p->next; +		free(p->name); +		free(p->addr); +		free(p); +	} +} + +const char *ab_find(const char *nick) +{ +FILE	*fp; +char *header, *value; + +	if ((fp=fopen(ADDRESSBOOK, "r")) != 0) +	{ +		while ((header=maildir_readheader_nolc(fp, &value)) != NULL) +		{ +			if (strcmp(header, nick) == 0) +			{ +				fclose(fp); +				return (value); +			} +		} +		fclose(fp); +	} +	return (0); +} +	 +void addressbook() +{ +FILE	*fp; +char    *header, *value; +const char	*nick_prompt=getarg("PROMPT"); +const char	*nick_submit=getarg("SUBMIT"); +const char	*nick_title1=getarg("TITLE1"); +const char	*nick_title2=getarg("TITLE2"); +const char	*nick_delete=getarg("DELETE"); +const char	*nick_name=getarg("NAME"); +const char	*nick_address=getarg("ADDRESS"); +const char	*nick_add=getarg("ADD"); +const char	*nick_edit=getarg("EDIT"); +const char	*nick_select1=getarg("SELECT1"); +const char	*nick_select2=getarg("SELECT2"); +const char *nick1; +int	do_edit; +char	*s, *q, *r; + +char	*edit_name=0; +char	*edit_addr=0; +int	replace_index=0; + +#if 0 +	fp=fopen("/tmp/pid", "w"); +	fprintf(fp, "%d", getpid()); +	fclose(fp); +	sleep(10); +#endif + +	nick1=cgi("nick"); +	do_edit=0; +	if (*cgi("nick.edit")) +		do_edit=1; +	else if (*cgi("nick.edit2")) +	{ +		do_edit=1; +		nick1=cgi("nick2"); +	} +	else if (*cgi("editnick")) +	{ +		do_edit=1; +		nick1=cgi("editnick"); +	} + +	if (*cgi("ADDYCNT"))	/* Import from LDAP */ +	{ +	unsigned counter=atoi(cgi("ADDYCNT")); +	char	numbuf[NUMBUFSIZE]; +	char	numbuf2[NUMBUFSIZE+10]; +	unsigned	i; + +		if (counter < 1 || counter > 1000) +			counter=1000; +		nick1=cgi("nick2"); +		if (!*nick1) +			nick1=cgi("nick1"); + +		if (*nick1) +		{ +			do_edit=1; +			for (i=0; i<counter; i++) +			{ +			const char *addy=cgi(strcat(strcpy(numbuf2, "ADDY"), +                                        libmail_str_size_t(i, numbuf))); +			char	*addycpy; +			char	*name; + +				if (*addy == 0)	continue; + +				addycpy=strdup(addy); +				if (!addycpy)	enomem(); + +				name=strchr(addycpy, '>'); +				if (!name) +				{ +					free(addycpy); +					continue; +				} +				*name++=0; +				while (*name == ' ')	++name; +				addy=addycpy; +				if (*addy == '<')	++addy; +				ab_add(name, addy, nick1); +			} +		} +	} + +	if (*cgi("nick.delete")) +	{ +		char *p=TOUTF8(cgi("nick")); + +		do_edit=0; + +		if (p) +		{ +			dodelall(p); +			free(p); +		} +	} +	else if (*cgi("add")) +	{ +	const char *newname=cgi("newname"); +	const char *newaddr=cgi("newaddress"); +	const char *editnick=cgi("editnick"); +	const char *replacenum=cgi("replacenick"); + +		if (*replacenum) +		{ +			if ((fp=fopen(ADDRESSBOOK, "r")) != 0) +			{ +				char *editnick_utf8=TOUTF8(editnick); + +				while ((header=maildir_readheader_nolc(fp, +					&value)) != NULL) +					if (editnick_utf8 && +					    strcmp(header, editnick_utf8) == 0) +						break; + +				if (header && editnick_utf8) +				{ +				struct rfc822t *t; +				struct rfc822a *a; + +					t=rfc822t_alloc_new(value, NULL, NULL); +					a=t ? rfc822a_alloc(t):0; + +					if (a) +					{ +						char *newname_utf8= +							TOUTF8(newname); + +						char *newaddr_utf8= +							TOUTF8(newaddr); + +						dodel(editnick_utf8, a, +						      atoi(replacenum), +						      newname_utf8 && newaddr_utf8 ? +						      newname_utf8:NULL, +						      newname_utf8 && newaddr_utf8 ? +						      newaddr_utf8:NULL); +						rfc822a_free(a); +						if (newname_utf8) +							free(newname_utf8); +						if (newaddr_utf8) +							free(newaddr_utf8); +					} +					if (t)	rfc822t_free(t); +				} +				if (editnick_utf8) +					free(editnick_utf8); + +				fclose(fp); +			} +		} +		else +			ab_add(newname, newaddr, editnick); +		do_edit=1; +		nick1=editnick; +	} + +	printf("%s", nick_prompt); +	printf("%s\n", nick_select1); + +	ab_listselect(); + +	printf("%s\n", nick_select2); +	printf("%s", nick_submit); + +	s=strdup(nick1); +	if (!s)	enomem(); +	for (q=r=s; *q; q++) +	{ +		if (isspace((int)(unsigned char)*q) || +			strchr(",;:()\"%@<>'!", *q)) +			continue; +		*r++=*q; +	} +	*r=0; + +	if (do_edit && *s) +	{ +		printf("<input type=\"hidden\" name=\"editnick\" value=\""); +		output_attrencoded(s); +		printf("\" />\n"); + +		printf("<table border=\"0\" class=\"nickedit-box\">\n"); +		printf("<tr><td colspan=\"3\">\n"); + +		printf("%s%s%s", nick_title1, s, nick_title2); +		printf("</td></tr>\n"); + +		if ((fp=fopen(ADDRESSBOOK, "r")) != 0) +		{ +			char *s_utf8=TOUTF8(s); + +			while ((header=maildir_readheader_nolc(fp, &value)) +				!= NULL) +				if (s_utf8 && strcmp(header, s_utf8) == 0) +					break; + +			if (s_utf8) +				free(s_utf8); + +			if (header) +			{ +			struct rfc822t *t; +			struct rfc822a *a; +			char	*save_value=strdup(value); + +				if (!save_value) +				{ +					fclose(fp); +					free(s); +					enomem(); +				} +				strcpy(save_value, value); +					/* Need copy 'cause dodel also +					** calls maildir_readheader */ + + +				t=rfc822t_alloc_new(save_value, NULL, NULL); +				a=t ? rfc822a_alloc(t):0; + +				if (a) +				{ +				int	i; + +					for (i=0; i<a->naddrs; i++) +					{ +					char buf[100]; + +						sprintf(buf, "del%d", i); +						if (*cgi(buf)) +						{ +							dodel(s, a, i, 0, 0); +							break; +						} +						sprintf(buf, "startedit%d", i); +						if (*cgi(buf)) +						{ +							if (edit_name) +								free(edit_name); +							edit_name= +								rfc822_display_name_tobuf(a, i, NULL); +							if (edit_addr) +								free(edit_addr); +							edit_addr= +								rfc822_display_addr_tobuf(a, i, NULL); +							replace_index=i; +							break; +						} +					} + +					for (i=0; i<a->naddrs; i++) +					{ +						char *s; + +						if (a->addrs[i].tokens == 0) +							continue; +						printf("<tr><td align=\"right\"" +						       " class=\"nickname\">"); + +						if (a->addrs[i].name) +							/* getname defaults it +							** here. +							*/ +						{ +							char *n=rfc822_display_name_tobuf(a, i, NULL); + +							if (n) +							{ +								printf("\""); +								ab_show_utf8(n); +								printf("\""); +								free(n); +							} + +						} + +						printf("</td><td align=\"left\"" +						       " class=\"nickaddr\">" +						       "<"); +						s=rfc822_display_addr_tobuf(a, i, NULL); + +						if (s) +						{ +							ab_show_utf8(s); +							free(s); +						} +						printf("></td><td><input type=\"submit\" name=\"startedit%d\" value=\"%s\" /> <input type=\"submit\" name=\"del%d\" value=\"%s\" /></td></tr>\n", +							i, nick_edit, +							i, nick_delete); +					} +					rfc822a_free(a); +				} +				if (t)	rfc822t_free(t); +				free(save_value); +			} +			fclose(fp); +		} +		printf("<tr><td colspan=\"3\"><hr width=\"90%%\" /></td></tr>\n"); +		printf("<tr><td align=\"right\">%s</td><td colspan=\"2\"><input type=\"text\" name=\"newname\" class=\"nicknewname\"", nick_name); + +		if (edit_name) +		{ +			int err; +			char *edit_name_native= +				libmail_u_convert_fromutf8(edit_name, +							   sqwebmail_content_charset, +							   &err); + +			if (edit_name_native) +			{ +				if (err == 0) +				{ +					printf(" value=\""); +					output_attrencoded(edit_name_native); +					printf("\""); +				} +				free(edit_name_native); +			} +		} +		printf(" /></td></tr>\n"); + +		printf("<tr><td align=\"right\">%s</td><td><input type=\"text\" name=\"newaddress\" class=\"nicknewaddr\"", nick_address); +		if (edit_addr) +		{ +			int err; +			char *edit_addr_native= +				libmail_u_convert_fromutf8(edit_addr, +							   sqwebmail_content_charset, +							   &err); + +			if (edit_addr_native) +			{ +				if (err == 0) +				{ +					printf(" value=\""); +					output_attrencoded(edit_addr_native); +					printf("\""); +				} +				free(edit_addr_native); +			} +		} + +		printf(" /></td><td>"); + +		if (edit_name || edit_addr) +			printf("<input type=\"hidden\" name=\"replacenick\" value=\"%d\" />", +				replace_index); + +		printf("<input type=\"submit\" name=\"add\" value=\"%s\" /></td></tr>\n", +			edit_name || edit_addr ? nick_edit:nick_add); + +		printf("</table>\n"); +	} +	free(s); + +	if (edit_name) +		free(edit_name); +	if (edit_addr) +		free(edit_addr); +} | 
