fred.c

来自「ftam等标准协议服务器和客户端的源代码。」· C语言 代码 · 共 2,257 行 · 第 1/4 页

C
2,257
字号
/* fred.c - DiSH support for FrED */#ifndef	lintstatic char *rcsid = "$Header: /xtel/isode/isode/quipu/dish/RCS/fred.c,v 9.0 1992/06/16 12:35:39 isode Rel $";#endif/* * $Header: /xtel/isode/isode/quipu/dish/RCS/fred.c,v 9.0 1992/06/16 12:35:39 isode Rel $ * * * $Log: fred.c,v $ * Revision 9.0  1992/06/16  12:35:39  isode * Release 8.0 * *//* *				  NOTICE * *    Acquisition, use, and distribution of this module and related *    materials are subject to the restrictions of a license agreement. *    Consult the Preface in the User's Manual for the full terms of *    this agreement. * */#include <ctype.h>#include <stdio.h>#include "manifest.h"#include "sys.file.h"#include <sys/stat.h>#include "quipu/ufn.h"#include "quipu/list.h"#include "quipu/read.h"#include "tailor.h"#include "quipu/ds_search.h"#ifndef	X_OK#define	X_OK	1#endif#define	OPT	(!frompipe || rps -> ps_byteno == 0 ? opt : rps)#define	RPS	(!frompipe || opt -> ps_byteno == 0 ? rps : opt)extern	char	frompipe;extern	PS	opt, rps;extern int errno;extern	char	dad_flag;#ifndef	NO_STATSextern	LLog   *dad_log;#endifextern	Attr_Sequence    		ufnas;char		fred_flag;char		fred_expand;char		fred_list;char		fred_long;char		fred_mailbox;char		fred_phone;char		fred_photo;char		fred_sequence;char		fred_subdisplay;static short	s_dn;static short	s_photo;static AttributeType t_alias;static AttributeType t_author;static AttributeType t_authorCN;static AttributeType t_authorSN;static AttributeType t_domain;static AttributeType t_master;static AttributeType t_mbox;static AttributeType t_modtime;static AttributeType t_modwhom;static AttributeType t_object;static AttributeType t_othermbox;static AttributeType t_phone;static AttributeType t_photo;static AttributeType t_postal;static AttributeType t_slave;static AttributeType t_surname;static AttributeType t_title;Entry	fredentry ();Attr_Sequence fred_as (), fred_full ();static struct dn_seq *interact ();static	do_dm_match ();static	fred_children ();static	done_match ();static  int dns_sort ();static	do_ufn_match ();static	build_ufnrc ();static	do_expand ();static	fred_init ();static  showfredattr ();Filter	joinfilter (), ocfilter (), strfilter ();PE	grab_pe ();sntx_table *get_syntax_table ();struct dn_seq *dn_seq_push ();/*    FRED BACK-END */int	call_fred (argc, argv)int	argc;char  **argv;{    static int did_ufnas = 0;    if (argc < 2)	goto usage;    fred_init ();    if (!did_ufnas) {	if (ufn_init () == FALSE) {	    ps_printf (OPT, "UFN initialization fails.\n");	    return;	}	ufnas = as_merge (ufnas, as_cpy (fred_as ()));	did_ufnas = 1;    }    if (test_arg (argv[1], "-display", 7)) {	if (argc != 3)	    goto usage;	(void) setenv ("DISPLAY", argv[2]);	if (s_photo)	    set_av_pe_print (s_photo,			     strdup (isodefile ("g3fax/Xphoto", 1)));	return;    }    if (test_arg (argv[1], "-dm2dn", 5)) {	if (argc < 3)	    goto usage;	do_dm_match (argc - 2, argv + 2);	return;    }    if (test_arg (argv[1], "-expand", 5)) {	if (argc < 3)	    goto usage;	do_expand (argc - 2, argv + 2);	return;    }    if (test_arg (argv[1], "-ufnrc", 5)) {	build_ufnrc (argc - 2, argv + 2);	return;    }    if (test_arg (argv[1], "-ufn", 3)) {	if (argc < 3)	    goto usage;	do_ufn_match (argc - 2, argv + 2);	return;    }usage: ;    Usage (argv[0]);}/*    DM2DN SUPPORT */static	int	dlevel = 0;static	int	dsa_status;struct dn_seq *dm2dn_seq ();struct dn_seq *dm2dn_seq_aux ();#define	make_filter(cp,at) \    	strfilter ((at), (cp), index ((cp), '*') ? FILTERITEM_SUBSTRINGS \						 : FILTERITEM_EQUALITY)/*  */static	do_dm_match (n, vec)int	n;char  **vec;{    int	    seqno;    char   *cp,	    mbox[BUFSIZ];    register struct dn_seq *dlist,			   *dp;    if (n > 0 && strcmp (*vec, "-list") == 0) {	n--, vec++;	fred_list = dad_flag;    }    else	fred_list = FALSE;    if (n > 0 && strcmp (vec[0], "-phone") == 0) {	n--, vec++;	fred_phone = TRUE;    }    else	fred_phone = FALSE;    if (n > 0 && strcmp (vec[0], "-photo") == 0) {	n--, vec++;	fred_photo = dad_flag;    }    else	fred_photo = FALSE;    if (n != 1) {	Usage ("fred");	return;    }    if ((cp = index (vec[0], '@')) && cp != vec[0]) {	(void) strcpy (mbox, vec[0]);	*cp++ = NULL;	if (*cp == NULL) {	    ps_printf (OPT, "Must specify domain in mailbox specification.\n");	    return;	}    }    else {	mbox[0] = NULL;	cp = cp ? ++cp : vec[0];    }    if ((dlist = dm2dn_seq (cp)) == NULLDNSEQ) {	if (dsa_status == OK)	    ps_printf (OPT, "Unable to resolve domain.\n");	return;    }    if (mbox[0] == NULL) {	if (fred_list) {	    done_match (dlist, NULLCP);	    return;	}	for (dp = dlist; dp; dp = dp -> dns_next) {	    if (seqno = add_sequence (dp -> dns_dn))		ps_printf (RPS, "%-3d ", seqno);	    dn_print (RPS, dp -> dns_dn, RDNOUT);	    ps_printf (RPS, "\n");	}	dn_seq_free (dlist);	return;    }    if ((dlist = interact (dlist, NULLDN, cp)) == NULL) {	ps_printf (OPT, "Unable to resolve mailbox.\n");	return;    }    {	char	buffer[BUFSIZ];	struct ds_search_arg search_arg;	register struct ds_search_arg *sa = &search_arg;	struct ds_search_result search_result;	register struct ds_search_result *sr = &search_result;	struct DSError error;	register struct DSError *se = &error;	Filter	fi;	EntryInfo *ptr;	register struct dn_seq *result = NULL;	PS	nps;	bzero ((char *) sa, sizeof *sa);	sa -> sra_common.ca_servicecontrol.svc_options = SVC_OPT_PREFERCHAIN;	sa -> sra_common.ca_servicecontrol.svc_timelimit = SVC_NOTIMELIMIT;	sa -> sra_common.ca_servicecontrol.svc_sizelimit = SVC_NOSIZELIMIT;	sa -> sra_subset = SRA_WHOLESUBTREE;	sa -> sra_searchaliases = FALSE;	sa -> sra_eis.eis_allattributes = FALSE;	sa -> sra_eis.eis_select = fred_as ();	sa -> sra_eis.eis_infotypes = EIS_ATTRIBUTESANDVALUES;	if (t_mbox == NULL || t_othermbox == NULL)	    fatal (-100, "rfc822Mailbox/otherMailbox: invalid attribute type");		fi = make_filter (mbox, t_mbox);	if (!index (mbox, '*')) {	    (void) sprintf (buffer, "internet$%s", mbox);	    fi -> flt_next = make_filter (buffer, t_othermbox);	    sa -> sra_filter = filter_alloc ();	    bzero ((char *) sa -> sra_filter, sizeof *sa -> sra_filter);	    sa -> sra_filter -> flt_type = FILTER_OR;	    sa -> sra_filter -> FUFILT = fi;	}	else	    sa -> sra_filter = fi;	if ((nps = ps_alloc (str_open))	        && str_setup (nps, NULLCP, 0, 0) == NOTOK) {	    ps_free (nps);	    nps = NULLPS;	}	for (dp = dlist; dp; dp = dp -> dns_next) {	    if (!dp -> dns_dn -> dn_parent) {		ps_printf (nps, "Unable to resolve domain %s beyond ", cp);		ufn_dn_print_aux (nps, dp -> dns_dn, NULLDN, 0);		ps_print (nps, "\n");		continue;	    }	    sa -> sra_baseobject = dp -> dns_dn;	    if (rebind () != OK)		break;	    while (ds_search (sa, se, sr) != DS_OK) {		if (dish_error (nps, se) == 0) {		    dsa_status = NOTOK;		    goto free_filter;		}		sa -> sra_baseobject =		    	    se -> ERR_REFERRAL.DSE_ref_candidates -> cr_name;	    }	    if (sr -> srr_correlated != TRUE)		correlate_search_results (sr);	    for (ptr = sr -> CSR_entries; ptr; ptr = ptr -> ent_next) {		cache_entry (ptr, sa -> sra_eis.eis_allattributes,			     sa -> sra_eis.eis_infotypes);		result = dn_seq_push (ptr -> ent_dn, result);	    }	    dn_free (sr -> CSR_object);	    entryinfo_free (sr -> CSR_entries, 0);	    crefs_free (sr -> CSR_cr);	}free_filter: ;	filter_free (sa -> sra_filter);	dn_seq_free (dlist);	if (result == NULL && nps && nps -> ps_byteno) {	    ps_print (nps, " ");	    *--nps -> ps_ptr = NULL, nps -> ps_cnt++;	    ps_print (OPT, nps -> ps_base);	    nps -> ps_ptr = nps -> ps_base, nps -> ps_cnt = nps -> ps_bufsiz;	}	else	    done_match (result, NULLCP);	if (nps)	    ps_free (nps);    }}/*  */static struct dn_seq *dm2dn_seq (dm)char   *dm;{    register char *dp;    for (dp = dm; *dp; dp++)	if (isupper (*dp))	    *dp = tolower (*dp);    dlevel = 0;    dsa_status = OK;    return dm2dn_seq_aux (dm, NULLDN, NULLDNSEQ);}/*  */static struct dn_seq *dm2dn_seq_aux (dm, dn, dlist)char   *dm;DN	dn;struct dn_seq *dlist;{    register char   *dp;    struct ds_search_arg search_arg;    register struct ds_search_arg *sa = &search_arg;    struct ds_search_result search_result;    register struct ds_search_result *sr = &search_result;    struct DSError error;    register struct DSError *se = &error;    bzero ((char *) sa, sizeof *sa);    sa -> sra_common.ca_servicecontrol.svc_options = SVC_OPT_PREFERCHAIN;    sa -> sra_common.ca_servicecontrol.svc_timelimit = SVC_NOTIMELIMIT;    sa -> sra_common.ca_servicecontrol.svc_sizelimit = SVC_NOSIZELIMIT;    sa -> sra_baseobject = dn;    sa -> sra_subset = SRA_ONELEVEL;    sa -> sra_searchaliases = FALSE;    sa -> sra_eis.eis_allattributes = FALSE;    sa -> sra_eis.eis_select = fred_as ();    sa -> sra_eis.eis_infotypes = EIS_ATTRIBUTESANDVALUES;    dp = dm;    for (;;) {	int	    i;	EntryInfo  *ptr;	register s_filter *fi;	if ((dsa_status = rebind ()) != OK)	    return dlist;	if ((i = strlen (dp)) < dlevel)	    break;	sa -> sra_filter = fi = filter_alloc ();	bzero ((char *) fi, sizeof *fi);	fi -> flt_type = FILTER_ITEM;	fi -> FUITEM.fi_type = FILTERITEM_EQUALITY;	if ((fi -> FUITEM.UNAVA.ava_type = t_domain) == NULL)	    fatal (-100, "associatedDomain: invalid attribute type");	fi -> FUITEM.UNAVA.ava_value = str2AttrV (dp, t_domain -> oa_syntax);	while (ds_search (sa, se, sr) != DS_OK) {	    if (dish_error (OPT, se) == 0) {		dsa_status = NOTOK;		goto free_filter;	    }	    sa -> sra_baseobject =			    se -> ERR_REFERRAL.DSE_ref_candidates -> cr_name;	}	if (sr -> srr_correlated != TRUE)	    correlate_search_results (sr);	if (sr -> CSR_entries == NULLENTRYINFO) {	    filter_free (sa -> sra_filter);	    if (dp = index (dp, '.'))		dp++;	    if (dp == NULL)		break;	    continue;	}	for (ptr = sr -> CSR_entries; ptr; ptr = ptr -> ent_next)	    cache_entry (ptr, sa -> sra_eis.eis_allattributes,			 sa -> sra_eis.eis_infotypes);	if (i > dlevel) {	    dlevel = i;	    if (dlist)		dn_seq_free (dlist), dlist = NULLDNSEQ;	}	if (i == dlevel)	    for (ptr = sr -> CSR_entries; ptr; ptr = ptr -> ent_next) {		struct dn_seq *dprev = dlist;		dlist = dm2dn_seq_aux (dm, ptr -> ent_dn, dlist);		if (dprev == dlist)		    dlist = dn_seq_push (ptr -> ent_dn, dlist);		else		    if (i < dlevel)			break;	    }	dn_free (sr -> CSR_object);	entryinfo_free (sr -> CSR_entries, 0);	crefs_free (sr -> CSR_cr);free_filter: ;	filter_free (sa -> sra_filter);	break;    }    return dlist;}/*    EXPAND SUPPORT */struct dn_seq	*expand_full (),    		*expand_partial ();/*  */static	do_expand (n, vec)int	n;char  **vec;{    int	    complete;    DN	    dn;    struct dn_seq *result;    if (n > 0 && strcmp (*vec, "-full") == 0) {	n--, vec++;	fred_long = TRUE;    }    else	fred_long = FALSE;    if (n != 1) {	Usage ("fred");	return;    }    dn = NULLDN;    if (strcmp (*vec, "@") && (dn = str2dn (*vec)) == NULLDN) {	ps_printf (OPT, "Bad DN: %s", *vec);	return;    }    result = fred_long ? expand_full (dn, &complete)		       : expand_partial (dn, &complete);        dn_free (dn);    if (result == NULL)	return;    fred_list = TRUE;    done_match (result, complete ? "5" : "3");}/*  */static struct dn_seq *expand_full (dn, complete)DN	dn;int    *complete;{    struct ds_list_arg list_arg;    register struct ds_list_arg *la = &list_arg;    struct ds_list_result list_result;    register struct ds_list_result *lr = &list_result;    struct DSError list_error;    register struct DSError *le = &list_error;    register struct subordinate *sub;    register struct list_cache *ptr;    DN	    adn,	    newdn;    struct dn_seq *result = NULLDNSEQ;    bzero ((char *) la, sizeof *la);    bzero ((char *) lr, sizeof *lr);    bzero ((char *) le, sizeof *le);    la -> lsa_common.ca_servicecontrol.svc_options			= SVC_OPT_PREFERCHAIN | SVC_OPT_DONTDEREFERENCEALIAS;    la -> lsa_common.ca_servicecontrol.svc_timelimit = SVC_NOTIMELIMIT;    la -> lsa_common.ca_servicecontrol.svc_sizelimit = SVC_NOSIZELIMIT;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?