|
|
1.1 root 1: /* fred.c - DiSH support for FrED */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/quipu/dish/RCS/fred.c,v 7.6 90/07/09 14:47:11 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/quipu/dish/RCS/fred.c,v 7.6 90/07/09 14:47:11 mrose Exp $
9: *
10: *
11: * $Log: fred.c,v $
12: * Revision 7.6 90/07/09 14:47:11 mrose
13: * sync
14: *
15: * Revision 7.5 90/04/18 08:49:40 mrose
16: * 6.2
17: *
18: * Revision 7.4 90/03/15 11:18:27 mrose
19: * quipu-sync
20: *
21: * Revision 7.3 90/01/11 18:37:38 mrose
22: * real-sync
23: *
24: * Revision 7.2 89/12/19 16:21:03 mrose
25: * sync
26: *
27: * Revision 7.1 89/11/26 14:25:47 mrose
28: * sync
29: *
30: * Revision 7.0 89/11/23 22:20:08 mrose
31: * Release 6.0
32: *
33: */
34:
35: /*
36: * NOTICE
37: *
38: * Acquisition, use, and distribution of this module and related
39: * materials are subject to the restrictions of a license agreement.
40: * Consult the Preface in the User's Manual for the full terms of
41: * this agreement.
42: *
43: */
44:
45:
46: #include <ctype.h>
47: #include <stdio.h>
48: #include "quipu/ds_search.h"
49: #include "quipu/entry.h"
50:
51:
52: #define OPT (!frompipe || rps -> ps_byteno == 0 ? opt : rps)
53: #define RPS (!frompipe || opt -> ps_byteno == 0 ? rps : opt)
54: extern char frompipe;
55: extern PS opt, rps;
56:
57:
58: char fred_flag;
59: char fred_expand;
60: char fred_long;
61: char fred_phone;
62: char fred_sequence;
63: char fred_subdisplay;
64:
65:
66: static int dsa_status;
67:
68: struct dn_seq *dm2dn_seq ();
69:
70: Entry fredentry ();
71:
72:
73: struct dn_seq *dn_seq_push ();
74:
75: /* FRED BACK-END */
76:
77: int call_fred (argc, argv)
78: int argc;
79: char **argv;
80: {
81: if (argc < 2)
82: goto usage;
83:
84: if (test_arg (argv[1], "-dm2dn", 5)) {
85: int seqno;
86: register struct dn_seq *dlist,
87: *dp;
88:
89: if (argc != 3)
90: goto usage;
91:
92: if ((dlist = dm2dn_seq (argv[2])) == NULLDNSEQ) {
93: if (dsa_status == OK)
94: ps_printf (OPT, "Unable to resolve domain.\n");
95: return;
96: }
97:
98: for (dp = dlist; dp; dp = dp -> dns_next) {
99: if (seqno = add_sequence (dp -> dns_dn))
100: ps_printf (RPS, "%-3d ", seqno);
101: dn_print (RPS, dp -> dns_dn, RDNOUT);
102: ps_printf (RPS, "\n");
103: }
104:
105: dn_seq_free (dlist);
106: return;
107: }
108:
109: if (test_arg (argv[1], "-ufn", 3)) {
110: if (argc < 3)
111: goto usage;
112:
113: do_ufn_match (argc - 2, argv + 2);
114: return;
115: }
116:
117: usage: ;
118: Usage (argv[0]);
119: }
120:
121: /* */
122:
123: #define ADOMAIN "associatedDomain"
124:
125: static int dlevel = 0;
126:
127: struct dn_seq *dm2dn_seq_aux ();
128:
129:
130: static struct dn_seq *dm2dn_seq (dm)
131: char *dm;
132: {
133: register char *dp;
134:
135: for (dp = dm; *dp; dp++)
136: if (isupper (*dp))
137: *dp = tolower (*dp);
138:
139: dlevel = 0;
140: dsa_status = OK;
141:
142: return dm2dn_seq_aux (dm, NULLDN, NULLDNSEQ);
143: }
144:
145: /* */
146:
147: static struct dn_seq *dm2dn_seq_aux (dm, dn, dlist)
148: char *dm;
149: DN dn;
150: struct dn_seq *dlist;
151: {
152: register char *dp;
153: register CommonArgs *ca;
154: struct ds_search_arg search_arg;
155: register struct ds_search_arg *sa = &search_arg;
156: struct ds_search_result search_result;
157: register struct ds_search_result *sr = &search_result;
158: struct DSError error;
159: register struct DSError *se = &error;
160:
161: bzero ((char *) sa, sizeof *sa);
162:
163: /* perhaps later initialize this from user, etc. */
164: ca = &sa -> sra_common;
165: ca -> ca_servicecontrol.svc_options = SVC_OPT_PREFERCHAIN;
166: ca -> ca_servicecontrol.svc_prio = SVC_PRIO_LOW;
167: ca -> ca_servicecontrol.svc_timelimit = SVC_NOTIMELIMIT;
168: ca -> ca_servicecontrol.svc_sizelimit = SVC_NOSIZELIMIT;
169: ca -> ca_servicecontrol.svc_scopeofreferral = SVC_REFSCOPE_NONE;
170:
171: sa -> sra_baseobject = dn;
172: sa -> sra_subset = SRA_ONELEVEL;
173: sa -> sra_searchaliases = FALSE;
174:
175: dp = dm;
176: for (;;) {
177: int i;
178: EntryInfo *ptr;
179: register filter *fi;
180: register AttributeType at;
181:
182: if ((dsa_status = rebind ()) != OK)
183: return dlist;
184:
185: if ((i = strlen (dp)) < dlevel)
186: break;
187:
188: sa -> sra_filter = fi = filter_alloc ();
189:
190: bzero ((char *) fi, sizeof *fi);
191: fi -> flt_type = FILTER_ITEM;
192: fi -> FUITEM.fi_type = FILTERITEM_EQUALITY;
193: if ((fi -> FUITEM.UNAVA.ava_type = at = AttrT_new (ADOMAIN)) == NULL)
194: fatal (-100, "associatedDomain: invalid attribute type");
195: fi -> FUITEM.UNAVA.ava_value =
196: str2AttrV (dp, at -> oa_syntax);
197:
198: while (ds_search (sa, se, sr) != DS_OK) {
199: if (dish_error (OPT, se) == 0) {
200: dsa_status = NOTOK;
201: goto free_filter;
202: }
203:
204: sa -> sra_baseobject =
205: se -> ERR_REFERRAL.DSE_ref_candidates -> cr_name;
206: }
207:
208: if (sr -> srr_correlated != TRUE)
209: correlate_search_results (sr);
210:
211: if (sr -> CSR_entries == NULLENTRYINFO) {
212: filter_free (sa -> sra_filter);
213: if (dp = index (dp, '.'))
214: dp++;
215: if (dp == NULL)
216: break;
217: continue;
218: }
219:
220: if (i > dlevel) {
221: dlevel = i;
222: if (dlist)
223: dn_seq_free (dlist), dlist = NULLDNSEQ;
224: }
225:
226: if (i == dlevel)
227: for (ptr = sr -> CSR_entries; ptr; ptr = ptr -> ent_next) {
228: struct dn_seq *dprev = dlist;
229:
230: dlist = dm2dn_seq_aux (dm, ptr -> ent_dn, dlist);
231:
232: if (dprev == dlist)
233: dlist = dn_seq_push (ptr -> ent_dn, dlist);
234: else
235: if (i < dlevel)
236: break;
237: }
238:
239: entryinfo_free (sr -> CSR_entries, 0);
240: free_filter: ;
241: filter_free (sa -> sra_filter);
242: break;
243: }
244:
245: return dlist;
246: }
247:
248: /* UFN SUPPORT */
249:
250: extern char ufn_notify;
251:
252:
253: static struct dn_seq *interact (dns, dn, s)
254: struct dn_seq *dns;
255: DN dn;
256: char *s;
257: {
258: int i,
259: j;
260: char *bp,
261: buffer[BUFSIZ];
262: struct dn_seq *result = NULL,
263: *ptr;
264: static PS nps = NULL;
265:
266: if (dns == NULL)
267: return NULL;
268: if (nps == NULLPS
269: && ((nps = ps_alloc (str_open)) == NULLPS
270: || str_setup (nps, NULLCP, 0, 0) == NOTOK)) {
271: if (nps)
272: ps_free (nps);
273: return dns;
274: }
275:
276: i = 0;
277: for (ptr = dns; ptr; ptr = ptr -> dns_next)
278: i++;
279:
280: if (i == 1)
281: return dns;
282:
283: bp = buffer;
284: if (i > 10) {
285: (void) sprintf (bp,
286: "%d imprecise matches for '%s', select from them [y/n] ? ",
287: i, s);
288: if (!yesno (buffer)) {
289: dn_seq_free (dns);
290: return NULLDNSEQ;
291: }
292:
293: *bp = NULL;
294: }
295: else
296: (void) sprintf (bp,
297: "Please select from the following %d match%s for '%s':\n",
298: i, i != 1 ? "es" : "", s);
299:
300: dns_sort (&dns, i);
301:
302: j = 1;
303: for (bp += strlen (buffer); dns; bp = buffer) {
304: ps_print (nps, " ");
305: ufn_dn_print_aux (nps, dns -> dns_dn, dn, 0);
306: ps_print (nps, " [y/n] ? ");
307: ps_print (nps, " ");
308: *--nps -> ps_ptr = NULL, nps -> ps_cnt++;
309:
310: (void) strcpy (bp, nps -> ps_base);
311:
312: nps -> ps_ptr = nps -> ps_base, nps -> ps_cnt = nps -> ps_bufsiz;
313:
314: if (yesno (buffer)) {
315: struct dn_seq *newdns = dn_seq_alloc ();
316:
317: newdns -> dns_next = result;
318: newdns -> dns_dn = dn_cpy (dns -> dns_dn);
319: result = newdns;
320: dns = dns -> dns_next;
321: }
322: else {
323: struct dn_seq *tmp = dns;
324:
325: dns = dns -> dns_next;
326: tmp -> dns_next = NULL;
327: dn_seq_free (tmp);
328: }
329:
330: if ((j++ % 10) == 0 && dns) {
331: (void) sprintf (buffer, "Continue (%d more) [y/n] ? ", i - j + 1);
332: if (!yesno (buffer))
333: break;
334: }
335: }
336:
337: return result;
338: }
339:
340: /* */
341:
342: static int dns_compar (a, b)
343: struct dn_seq **a,
344: **b;
345: {
346: int i;
347: DN adn,
348: bdn;
349:
350: for (adn = (*a) -> dns_dn; adn -> dn_parent; adn = adn -> dn_parent)
351: continue;
352: for (bdn = (*b) -> dns_dn; bdn -> dn_parent; bdn = bdn -> dn_parent)
353: continue;
354:
355: i = rdn_cmp (adn -> dn_rdn, bdn -> dn_rdn);
356: return (i == (-1) || i == 1 ? i : 0);
357: }
358:
359:
360: static int dns_sort (dns, i)
361: struct dn_seq **dns;
362: int i;
363: {
364: register struct dn_seq *ptr;
365:
366: if (i == 0)
367: for (ptr = *dns; ptr; ptr = ptr -> dns_next)
368: i++;
369:
370: if (i > 1) {
371: struct dn_seq **base,
372: **bp,
373: **ep;
374:
375: if (base = (struct dn_seq **) malloc ((unsigned) (i * sizeof *base))) {
376: ep = base;
377: for (ptr = *dns; ptr; ptr = ptr -> dns_next)
378: *ep++ = ptr;
379:
380: qsort ((char *) base, i, sizeof *base, dns_compar);
381:
382: bp = base;
383: ptr = *dns = *bp++;
384: while (bp < ep) {
385: ptr -> dns_next = *bp;
386: ptr = *bp++;
387: }
388: ptr -> dns_next = NULL;
389:
390: free ((char *) base);
391: }
392: }
393: }
394:
395: /* */
396:
397: static do_ufn_match (n, vec)
398: int n;
399: char **vec;
400: {
401: int i;
402: struct dn_seq *dns = NULL;
403: register struct dn_seq *ptr;
404:
405: if (ufn_init () == FALSE) {
406: ps_printf (OPT, "UFN initialization fails.\n");
407: return;
408: }
409:
410: if (rebind () != OK)
411: return;
412:
413: ufn_notify = !frompipe;
414: if (!ufn_match (n, vec, interact, &dns, (struct _envlist *) 0)) {
415: ps_printf (OPT, "Unable to resolve name.\n");
416: return;
417: }
418:
419: if (dns == NULL) {
420: ps_printf (OPT, "Search failed to find anything.\n");
421: return;
422: }
423:
424: i = 0;
425: for (ptr = dns; ptr; ptr = ptr -> dns_next)
426: i++;
427:
428: fred_long = i == 1;
429: fred_expand = fred_subdisplay = FALSE;
430: fred_sequence = TRUE;
431:
432: if (i > 1) {
433: ps_printf (RPS, "%d matches found.\n", i);
434: (void) ps_flush (RPS);
435:
436: dns_sort (&dns, i);
437: }
438:
439: for (ptr = dns; ptr; ptr = ptr -> dns_next) {
440: normalize_dn (&ptr -> dns_dn);
441: (void) add_sequence (ptr -> dns_dn);
442: }
443: for (i = 0, ptr = dns; ptr; ptr = ptr -> dns_next, i++) {
444: if (i > 0)
445: (void) ps_flush (RPS);
446:
447: (void) showfred (ptr -> dns_dn, fred_long, fred_subdisplay);
448: }
449:
450: dn_seq_free (dns);
451: }
452:
453: /* */
454:
455: normalize_dn (ptr)
456: DN *ptr;
457: {
458: register DN dn,
459: dn2,
460: *dp;
461: register Entry wp;
462:
463: for (dn = *ptr, dp = &dn -> dn_parent; *dp; dp = &((*dp) -> dn_parent)) {
464: dn2 = *dp, *dp = NULLDN;
465: if ((wp = fredentry (dn, TRUE)) == NULLENTRY)
466: break;
467: *dp = dn2;
468:
469: if (wp -> e_alias) {
470: *dp = NULLDN;
471: dn_append (dn = dn_cpy (wp -> e_alias), dn2);
472: dn_free (*ptr), *ptr = dn;
473: dp = &dn -> dn_parent;
474: }
475: }
476: }
477:
478: /* SHOWENTRY SUPPORT */
479:
480: #include "quipu/list.h"
481: #include "quipu/read.h"
482:
483: /* */
484:
485: static AttributeType t_mbox = NULLAttrT;
486: static AttributeType t_phone = NULLAttrT;
487: static AttributeType t_modtime = NULLAttrT;
488: static AttributeType t_modwhom = NULLAttrT;
489: static AttributeType t_postal = NULLAttrT;
490: static AttributeType t_title = NULLAttrT;
491: static AttributeType t_photo = NULLAttrT;
492:
493: extern int postal_indent;
494: extern int ufn_indent;
495:
496: static struct template {
497: char *t_name;
498: char *t_prefix;
499:
500: int t_level;
501:
502: AttributeType t_at;
503: } default_template[] = {
504: "title", NULL,
505: 0, NULL,
506: "documentTitle", NULL,
507: 0, NULL,
508: #define LEVEL_POSTAL 0
509: "organizationName", NULL,
510: 0, NULL,
511: "organizationalUnitName", NULL,
512: 0, NULL,
513: "roomNumber", " Room ",
514: 0, NULL,
515: "streetAddress", " ",
516: 0, NULL,
517: "postOfficeBox", " POB ",
518: 0, NULL,
519: "physicalDeliveryOfficeName", " ",
520: 0, NULL,
521: "stateOrProvinceName", " ",
522: 0, NULL,
523: "postalCode", " ",
524: 0, NULL,
525:
526: "postalAddress", NULL,
527: 1, NULL,
528: "documentAuthor", "Author: ",
529: 1, NULL,
530:
531: "registeredAddress", "Registered Address: ",
532: 2, NULL,
533: "documentVersion", "Version of: ",
534: 2, NULL,
535:
536: "telephoneNumber", "Telephone: ",
537: 3, NULL,
538: "mobileTelephoneNumber", "Mobile: ",
539: 3, NULL,
540: "pagerTelephoneNumber", "Pager: ",
541: 3, NULL,
542: "facsimileTelephoneNumber", "FAX: ",
543: 3, NULL,
544: "telexNumber", "Telex: ",
545: 3, NULL,
546: "teletexTerminalIdentifier", "Teletex: ",
547: 3, NULL,
548: "x121Address", "X.121: ",
549: 3, NULL,
550: "internationaliSDNNumber", "ISDN: ",
551: 3, NULL,
552: "presentationAddress", "OSI: ",
553: 3, NULL,
554:
555: #define LEVEL_MBOX 4
556: "rfc822Mailbox", " Mailbox: ",
557: 4, NULL,
558: "otherMailbox", " ",
559: 4, NULL,
560: "textEncodedORaddress", " ",
561: 4, NULL,
562:
563: "destinationIndicator", "Destination Indicator: ",
564: 5, NULL,
565: "preferredDeliveryMethod", "Preferred Delivery Method: ",
566: 5, NULL,
567: "supportedApplicationContext", "Supports: ",
568: 5, NULL,
569:
570: "description", NULL,
571: 6, NULL,
572:
573: "info", "Information: ",
574: 7, NULL,
575: "businessCategory", "Business: ",
576: 7, NULL,
577: "userClass", "User Class: ",
578: 7, NULL,
579: "localityName", "Locality: ",
580: 7, NULL,
581: "documentLocation", "Location: ",
582: 7, NULL,
583:
584: "aliasedObjectName", "Alias to: ",
585: 8, NULL,
586: "roleOccupant", "Occupant: ",
587: 8, NULL,
588: "seeAlso", "See Also: ",
589: 8, NULL,
590: "secretary", "Secretary: ",
591: 8, NULL,
592: "manager", "Manager: ",
593: 8, NULL,
594:
595: "homePostalAddress", "Home Address: ",
596: 9, NULL,
597: "homePhone", "Home Phone: ",
598: 9, NULL,
599: "favouriteDrink", "Drinks: ",
600: 9, NULL,
601: "photo", "Picture: ",
602: 9, NULL,
603:
604: NULL
605: };
606:
607:
608: /* */
609:
610: showfred (mydn, islong, subdisplay)
611: DN mydn;
612: char islong,
613: subdisplay;
614: {
615: int didtime,
616: haspost,
617: level,
618: nchild,
619: pos,
620: seqno;
621: register struct template *t;
622: register Attr_Sequence eptr;
623: register AV_Sequence avs,
624: avp;
625: AttributeType rdn_at,
626: inf_at;
627: AttributeValue rdn_av;
628: Entry myentry = fredentry (mydn = dn_cpy (mydn), islong);
629: PS ps = NULLPS;
630: RDN myrdn;
631: static int once_only = 0;
632:
633: if (once_only == 0) {
634: once_only++;
635:
636: t_mbox = AttrT_new ("rfc822Mailbox");
637: t_phone = AttrT_new ("telephoneNumber");
638: t_modtime = AttrT_new ("lastModifiedTime");
639: t_modwhom = AttrT_new ("lastModifiedBy");
640: t_postal = AttrT_new ("postalAddress");
641: t_title = AttrT_new ("title");
642: t_photo = AttrT_new ("photo");
643:
644: for (t = default_template; t -> t_name; t++)
645: t -> t_at = AttrT_new (t -> t_name);
646: }
647:
648: pos = RPS -> ps_byteno;
649:
650: seqno = fred_sequence ? add_sequence (mydn) : 0;
651: if (islong == FALSE) {
652: if (seqno)
653: ps_printf (RPS, "%3d. ", seqno);
654: else
655: ps_printf (RPS, " ");
656: }
657:
658: if (mydn) {
659: register DN adn;
660: register RDN rdn;
661:
662:
663: if (islong == FALSE) {
664: ufn_dn_print_aux (RPS, mydn, NULLDN, 0);
665: goto ufn_short;
666: }
667: for (adn = mydn; adn -> dn_parent; adn = adn -> dn_parent)
668: continue;
669: myrdn = adn -> dn_rdn;
670: rdn_at = myrdn -> rdn_at, rdn_av = &myrdn -> rdn_av;
671: AttrV_print (RPS, rdn_av, EDBOUT);
672: for (rdn = myrdn -> rdn_next; rdn; rdn = rdn -> rdn_next) {
673: ps_print (RPS, " + ");
674: AttrV_print (RPS, &rdn -> rdn_av, EDBOUT);
675: }
676: }
677: else {
678: myrdn = NULLRDN, rdn_at = NULLAttrT, rdn_av = NULLAttrV;
679: ps_print (RPS, "@");
680: }
681:
682: if (islong == TRUE && seqno)
683: ps_printf (RPS, " (%d)", seqno);
684:
685: if ((pos += 52 - RPS -> ps_byteno) <= 0)
686: pos = 1;
687:
688: inf_at = NULLAttrT;
689: if (myentry) {
690: for (eptr = myentry -> e_attributes; eptr; eptr = eptr -> attr_link)
691: if (!fred_phone && AttrT_cmp (eptr -> attr_type, t_mbox) == 0) {
692: inf_at = t_mbox;
693:
694: if (avs = eptr -> attr_value) {
695: ps_printf (RPS, "%*s", pos, "");
696: showfredattr (&avs -> avseq_av);
697: }
698: break;
699: }
700: else
701: if (AttrT_cmp (eptr -> attr_type, t_phone) == 0) {
702: inf_at = t_phone;
703: avp = eptr -> attr_value;
704: }
705:
706: if (inf_at == t_phone && avp) {
707: ps_printf (RPS, "%*s", pos, "");
708: showfredattr (&avp -> avseq_av);
709: }
710: }
711:
712: ufn_short: ;
713: ps_print (RPS, "\n");
714:
715: if (myentry == NULLENTRY)
716: goto out;
717: if (islong == FALSE)
718: goto children;
719:
720: for (eptr = myentry -> e_attributes; eptr; eptr = eptr -> attr_link)
721: if (AttrT_cmp (eptr -> attr_type, t_photo) == 0) {
722: if (eptr -> attr_value) {
723: if (rdn_av
724: && (ps = ps_alloc (str_open)) != NULLPS
725: && str_setup (ps, NULLCP, 0, 0) != NOTOK) {
726: register RDN rdn;
727:
728: AttrV_print (ps, rdn_av, EDBOUT);
729: for (rdn = myrdn -> rdn_next; rdn; rdn = rdn -> rdn_next) {
730: ps_print (ps, "/");
731: AttrV_print (ps, &rdn -> rdn_av, EDBOUT);
732: }
733: ps_print (ps, " ");
734: *--ps -> ps_ptr = NULL, ps -> ps_cnt++;
735: (void) setenv ("RDN", ps -> ps_base);
736: }
737: else
738: (void) setenv ("RDN", "Photo");
739: }
740: break;
741: }
742:
743: level = 0;
744: for (eptr = myentry -> e_attributes; eptr; eptr = eptr -> attr_link)
745: if (AttrT_cmp (eptr -> attr_type, rdn_at) == 0) {
746: for (avp = eptr -> attr_value; avp; avp = avp -> avseq_next)
747: if (AttrV_cmp (&avp -> avseq_av, rdn_av)) {
748: ps_print (RPS, " aka: ");
749: showfredattr (&avp -> avseq_av);
750: ps_print (RPS, "\n");
751: level++;
752: }
753:
754: break;
755: }
756:
757: haspost = 0;
758: for (eptr = myentry -> e_attributes; eptr; eptr = eptr -> attr_link)
759: if (AttrT_cmp (eptr -> attr_type, t_postal) == 0) {
760: if (eptr -> attr_value)
761: haspost = 1;
762: }
763: ps_print (RPS, "\n");
764:
765: level = -1;
766: for (t = default_template; t -> t_name; t++) {
767: if (AttrT_cmp (t -> t_at, rdn_at) == 0)
768: continue;
769:
770: for (eptr = myentry -> e_attributes;
771: eptr;
772: eptr = eptr -> attr_link)
773: if (AttrT_cmp (eptr -> attr_type, t -> t_at) == 0) {
774: int i;
775:
776: if (AttrT_cmp (eptr -> attr_type, inf_at) == 0
777: && (avs = eptr -> attr_value)
778: && !avs -> avseq_next)
779: continue;
780:
781: if (haspost
782: && t -> t_level == LEVEL_POSTAL
783: && AttrT_cmp (eptr -> attr_type, t_title)) {
784: level = t -> t_level + 1;
785: continue;
786: }
787:
788: if (t -> t_level != level) {
789: if (level >= 0)
790: ps_print (RPS, "\n");
791: if ((level = t -> t_level) == LEVEL_MBOX)
792: ps_print (RPS, "Mailbox information:\n");
793: }
794:
795: if (t -> t_prefix) {
796: i = strlen (t -> t_prefix);
797: ps_printf (RPS, "%s", t -> t_prefix);
798: }
799: else
800: i = 0;
801:
802: if (avs = eptr -> attr_value) {
803: postal_indent = i;
804: ufn_indent = postal_indent + 2;
805: showfredattr (&avs -> avseq_av);
806: ps_print (RPS, "\n");
807: for (avp = avs -> avseq_next;
808: avp;
809: avp = avp -> avseq_next) {
810: if (t -> t_prefix)
811: ps_printf (RPS, "%*s", i, "");
812: else
813: ps_print (RPS, "\n");
814:
815: showfredattr (&avp -> avseq_av);
816:
817: ps_print (RPS, "\n");
818: }
819: }
820: else
821: ps_print (RPS, "no value?!?\n");
822:
823: break;
824: }
825: }
826:
827: ufn_indent = (sizeof "Modified: " - 1) + 2;
828: if (mydn) {
829: ps_print (RPS, "\nName: ");
830: ufn_dn_print_aux (RPS, mydn, NULLDN, 1);
831: if (seqno)
832: ps_printf (RPS, " (%d)", seqno);
833: }
834:
835: ps_print (RPS, "\n");
836:
837: didtime = 0;
838: for (eptr = myentry -> e_attributes; eptr; eptr = eptr -> attr_link)
839: if (AttrT_cmp (eptr -> attr_type, t_modtime) == 0) {
840: if (avs = eptr -> attr_value) {
841: ps_print (RPS, "Modified: ");
842: showfredattr (&avs -> avseq_av);
843: ps_print (RPS, "\n");
844:
845: didtime = 1;
846: }
847: break;
848: }
849: if (didtime)
850: for (eptr = myentry -> e_attributes; eptr; eptr = eptr -> attr_link)
851: if (AttrT_cmp (eptr -> attr_type, t_modwhom) == 0) {
852: if ((avs = eptr -> attr_value)
853: && dn_cmp ((DN) avs -> avseq_av.av_struct, mydn)) {
854: ps_print (RPS, " by: ");
855: showfredattr (&avs -> avseq_av);
856: ps_print (RPS, "\n");
857: }
858: break;
859: }
860:
861: children: ;
862: nchild = 0;
863: if (subdisplay) {
864: struct ds_list_arg list_arg;
865: struct ds_list_result list_result;
866: struct DSError list_error;
867: struct list_cache *ptr;
868:
869: (void) ps_flush (RPS);
870:
871: (void) service_control (OPT, 0, NULLVP, &list_arg.lsa_common);
872: list_arg.lsa_common.ca_servicecontrol.svc_options |=
873: SVC_OPT_DONTDEREFERENCEALIAS;
874:
875: if (ptr = find_list_cache (list_arg.lsa_object = mydn,
876: SVC_NOSIZELIMIT)) {
877: if (ptr -> list_subs)
878: nchild = fred_children (mydn, ptr -> list_subs,
879: ptr -> list_problem);
880:
881: goto out;
882: }
883:
884: if (rebind () != OK)
885: goto out;
886:
887: if (ds_list (&list_arg, &list_error, &list_result) != DS_OK) {
888: ds_error (RPS, &list_error);
889: goto out;
890: }
891:
892: if (list_result.lsr_subordinates)
893: nchild = fred_children (mydn, list_result.lsr_subordinates,
894: list_result.lsr_limitproblem);
895:
896: cache_list (list_result.lsr_subordinates, list_result.lsr_limitproblem,
897: mydn, SVC_NOSIZELIMIT);
898: subords_free (list_result.lsr_subordinates);
899: }
900:
901: out: ;
902: if (mydn)
903: dn_free (mydn);
904: if (ps)
905: ps_free (ps);
906: postal_indent = -1;
907: ufn_indent = -1;
908:
909: return nchild;
910: }
911:
912: /* */
913:
914: static fred_children (parentdn, ptr, prob)
915: DN parentdn;
916: register struct subordinate *ptr;
917: int prob;
918: {
919: int i,
920: nchild;
921: register struct subordinate *qtr;
922: register DN adn,
923: newdn;
924:
925: newdn = dn_comp_new (rdn_comp_new (NULLAttrT, NULLAttrV));
926: if (adn = dn_cpy (parentdn))
927: dn_append (adn, newdn);
928: else
929: adn = newdn;
930:
931: i = 0;
932: for (qtr = ptr; qtr; qtr = qtr -> sub_next)
933: i++;
934: nchild = i;
935:
936: if (i > 0)
937: ps_printf (RPS, "%d child%s.\n-----\n", i, i != 1 ? "ren" : "");
938:
939: for (i = 0; ptr; ptr = ptr -> sub_next, i++) {
940: rdn_free (newdn -> dn_rdn);
941: dn_comp_fill (newdn, rdn_cpy (ptr -> sub_rdn));
942: (void) add_sequence (adn);
943:
944: (void) showfred (adn, 0, FALSE);
945: }
946:
947: dn_free (adn);
948:
949: if (prob != LSR_NOLIMITPROBLEM)
950: ps_print (RPS, "(Limit problem)\n");
951:
952: return nchild;
953: }
954:
955:
956: /* */
957:
958: static showfredattr (av)
959: register AttributeValue av;
960: {
961: int seqno;
962: static int once_only = 0;
963: static int s_dn;
964:
965: if (once_only == 0) {
966: once_only++;
967:
968: s_dn = str2syntax ("DN");
969: }
970:
971: if (av -> av_syntax == s_dn) {
972: ufn_dn_print_aux (RPS, (DN) av -> av_struct, NULLDN, 1);
973:
974: if (fred_sequence && (seqno = add_sequence ((DN) av -> av_struct)))
975: ps_printf (RPS, " (%d)", seqno);
976: }
977: else
978: AttrV_print (RPS, av, READOUT);
979: }
980:
981: /* */
982:
983: static Entry fredentry (adn, islong)
984: DN adn;
985: char islong;
986: {
987: register Entry newentry;
988:
989: struct ds_read_arg read_arg;
990: struct ds_read_result read_result;
991: struct DSError read_error;
992:
993: if (adn == NULLDN)
994: return NULLENTRY;
995:
996: if ((newentry = local_find_entry (read_arg.rda_object = adn,
997: FALSE)) == NULLENTRY
998: || !newentry -> e_lock
999: || (islong && !newentry -> e_complete)) {
1000: if (rebind () != OK)
1001: return newentry;
1002:
1003: (void) service_control (OPT, 0, NULLVP, &read_arg.rda_common);
1004: read_arg.rda_common.ca_servicecontrol.svc_options |=
1005: SVC_OPT_DONTDEREFERENCEALIAS;
1006: read_arg.rda_eis.eis_infotypes = TRUE;
1007: read_arg.rda_eis.eis_allattributes = TRUE;
1008: read_arg.rda_eis.eis_select = NULLATTR;
1009:
1010: if (ds_read (&read_arg, &read_error, &read_result) != DS_OK) {
1011: #ifdef notdef
1012: ds_error (RPS, &read_error);
1013: #endif
1014: return newentry;
1015: }
1016:
1017: cache_entry (&read_result.rdr_entry,
1018: read_arg.rda_eis.eis_allattributes,
1019: read_arg.rda_eis.eis_infotypes);
1020:
1021: entryinfo_comp_free (&read_result.rdr_entry, 0);
1022:
1023: newentry = local_find_entry (adn, FALSE);
1024: }
1025:
1026: return newentry;
1027: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.