|
|
1.1 root 1: /* imagesbr.c - image subroutines */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/others/image/RCS/imagesbr.c,v 7.4 90/04/18 08:50:12 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/others/image/RCS/imagesbr.c,v 7.4 90/04/18 08:50:12 mrose Exp $
9: *
10: *
11: * $Log: imagesbr.c,v $
12: * Revision 7.4 90/04/18 08:50:12 mrose
13: * typo
14: *
15: * Revision 7.3 90/03/29 20:39:18 mrose
16: * update
17: *
18: * Revision 7.2 90/03/15 11:18:10 mrose
19: * quipu-sync
20: *
21: * Revision 7.1 90/03/08 08:04:12 mrose
22: * touch-up
23: *
24: * Revision 7.0 89/11/23 21:59:58 mrose
25: * Release 6.0
26: *
27: */
28:
29: /*
30: * NOTICE
31: *
32: * Acquisition, use, and distribution of this module and related
33: * materials are subject to the restrictions of a license agreement.
34: * Consult the Preface in the User's Manual for the full terms of
35: * this agreement.
36: *
37: */
38:
39:
40: #include <ctype.h>
41: #include <stdio.h>
42: #include <varargs.h>
43: #include "imagesbr.h"
44: #include "quipu/bind.h"
45: #include "quipu/ds_search.h"
46: #include "quipu/entry.h"
47:
48: /* GENERAL */
49:
50: static char *myname = "image";
51:
52: int recording = 0;
53:
54: static LLog _pgm_log = {
55: "./image.log", NULLCP, NULLCP, LLOG_FATAL | LLOG_EXCEPTIONS | LLOG_NOTICE,
56: LLOG_FATAL, -1, LLOGCLS | LLOGCRT | LLOGZER, NOTOK
57: };
58: LLog *pgm_log = &_pgm_log;
59:
60:
61: /* AKA */
62:
63: struct aka {
64: struct aka *ak_forw;
65: struct aka *ak_back;
66:
67: char *ak_domain;
68: char *ak_local;
69:
70: struct dn_seq *ak_bases;
71: struct type_IMAGE_Image *ak_image;
72: };
73: static struct aka akas;
74: static struct aka *AHead = &akas;
75:
76:
77: static int stay_bound = 0;
78:
79: DN local_dn;
80:
81:
82: struct dn_seq *dm2dn_seq ();
83:
84:
85: extern char *local_dit;
86: struct dn_seq *dn_seq_push ();
87: int dn_seq_print ();
88:
89: /* */
90:
91: void init_aka (pgm, stayopen, dit)
92: char *pgm,
93: *dit;
94: int stayopen;
95: {
96: char *cp;
97: register struct aka *ak;
98: static int once_only = 0;
99:
100: if (once_only == 0) {
101: int argp;
102: char *arg[2],
103: **argptr;
104:
105: quipu_syntaxes ();
106:
107: argp = 0;
108: arg[argp++] = myname;
109: arg[argp] = NULLCP;
110:
111: dsap_init (&argp, (argptr = arg, &argptr));
112:
113: once_only = 1;
114: }
115: stay_bound = stayopen;
116: myname = pgm;
117:
118: AHead -> ak_forw = AHead -> ak_back = AHead;
119: if ((ak = (struct aka *) calloc (1, sizeof *ak)) == NULL)
120: adios (NULLCP, "out of memory");
121:
122: ak -> ak_domain = ak -> ak_local = "";
123:
124: insque (ak, AHead -> ak_back);
125:
126: if ((local_dn = str2dn (cp = dit ? dit
127: : *local_dit != '@' ? local_dit
128: : local_dit + 1))
129: == NULLDN)
130: adios (NULLCP, "local_dit invalid: \"%s\"", cp);
131: }
132:
133: /* */
134:
135: static struct aka *mbox2ak (local, domain)
136: char *local,
137: *domain;
138: {
139: register struct aka *ak,
140: *am;
141:
142: if (domain == NULL)
143: domain = "";
144: if (local == NULL)
145: local = "";
146:
147: for (ak = AHead -> ak_forw; ak != AHead; ak = ak -> ak_forw)
148: if (!lexequ (domain, ak -> ak_domain)
149: && !lexequ (local, ak -> ak_local)) {
150: if (recording)
151: LLOG (pgm_log, LLOG_NOTICE,
152: ("hit \"%s\" \"%s\"", domain, local));
153:
154: return ak;
155: }
156:
157: if ((am = (struct aka *) calloc (1, sizeof *am)) == NULL
158: || (am -> ak_domain = strdup (domain)) == NULL
159: || (am -> ak_local = strdup (local)) == NULL)
160: adios (NULLCP, "out of memory");
161:
162: if (recording)
163: LLOG (pgm_log, LLOG_NOTICE, ("miss \"%s\" \"%s\"", domain, local));
164:
165: if (index (domain, '.'))
166: am -> ak_bases = dm2dn_seq (domain);
167: else
168: am -> ak_bases = dn_seq_push (local_dn, NULLDNSEQ);
169:
170: insque (ak = am, AHead);
171:
172: return ak;
173: }
174:
175: /* DIRECTORY */
176:
177: #define ADOMAIN "associatedDomain"
178: #define PHOTO "photo"
179: #define USERID "userid"
180:
181: static int bound = 0;
182: static int dlevel = 0;
183:
184: struct dn_seq *dm2dn_seq_aux ();
185:
186:
187: static struct dn_seq *dm2dn_seq (dm)
188: char *dm;
189: {
190: register char *dp;
191:
192: for (dp = dm; *dp; dp++)
193: if (isupper (*dp))
194: *dp = tolower (*dp);
195:
196: dlevel = 0;
197:
198: if (!bound && do_bind () == NOTOK)
199: return NULLDNSEQ;
200:
201: return dm2dn_seq_aux (dm, NULLDN, NULLDNSEQ);
202: }
203:
204: /* */
205:
206: static struct dn_seq *dm2dn_seq_aux (dm, dn, dlist)
207: char *dm;
208: DN dn;
209: struct dn_seq *dlist;
210: {
211: register char *dp;
212: char buffer[BUFSIZ];
213: struct ds_search_arg search_arg;
214: register struct ds_search_arg *sa = &search_arg;
215: struct ds_search_result search_result;
216: register CommonArgs *ca;
217: register struct ds_search_result *sr = &search_result;
218: struct DSError error;
219: register struct DSError *se = &error;
220: PS ps;
221:
222: if ((ps = ps_alloc (str_open))
223: && str_setup (ps, buffer, sizeof buffer, 1) != NOTOK) {
224: dn_print (ps, dn, EDBOUT);
225: *ps -> ps_ptr = NULL;
226: }
227: else
228: buffer[0] = NULL;
229: if (ps)
230: (void) ps_free (ps);
231:
232: if (debug)
233: fprintf (stderr, "dlevel=%d dm=%s dn=%s\n", dlevel, dm, buffer);
234:
235: bzero ((char *) sa, sizeof *sa);
236:
237: ca = &sa -> sra_common;
238: ca -> ca_servicecontrol.svc_options = SVC_OPT_PREFERCHAIN;
239: ca -> ca_servicecontrol.svc_prio = SVC_PRIO_LOW;
240: ca -> ca_servicecontrol.svc_timelimit = SVC_NOTIMELIMIT;
241: ca -> ca_servicecontrol.svc_sizelimit = SVC_NOSIZELIMIT;
242: ca -> ca_servicecontrol.svc_scopeofreferral = SVC_REFSCOPE_NONE;
243:
244: sa -> sra_baseobject = dn;
245: sa -> sra_subset = SRA_ONELEVEL;
246: sa -> sra_searchaliases = FALSE;
247:
248: dp = dm;
249: for (;;) {
250: int i;
251: EntryInfo *ptr;
252: register filter *fi;
253: register AttributeType at;
254:
255: if (debug)
256: fprintf (stderr, "-- dlevel=%d dp=%s(%d) dn=%s\n",
257: dlevel, dp, strlen (dp), buffer);
258:
259: if ((i = strlen (dp)) < dlevel)
260: break;
261:
262: sa -> sra_filter = fi = filter_alloc ();
263:
264: bzero ((char *) fi, sizeof *fi);
265: fi -> flt_type = FILTER_ITEM;
266: fi -> FUITEM.fi_type = FILTERITEM_EQUALITY;
267: if ((fi -> FUITEM.UNAVA.ava_type = at = AttrT_new (ADOMAIN)) == NULL)
268: adios ("invalid attribute type \"%s\"", ADOMAIN);
269: fi -> FUITEM.UNAVA.ava_value =
270: str2AttrV (dp, at -> at_table -> oa_syntax);
271:
272: if (ds_search (sa, se, sr) != DS_OK) {
273: if (recording)
274: LLOG (pgm_log, LLOG_EXCEPTIONS,
275: ("search operation failed"));
276:
277: (void) ds_unbind ();
278:
279: bound = 0;
280:
281: goto free_filter;
282: }
283:
284: if (sr -> srr_correlated != TRUE)
285: correlate_search_results (sr);
286:
287: if (sr -> CSR_entries == NULLENTRYINFO) {
288: if (recording)
289: LLOG (pgm_log, LLOG_NOTICE,
290: ("search for %s \"%s\" at baseobject \"%s\" failed",
291: ADOMAIN, dp, buffer));
292:
293: filter_free (sa -> sra_filter);
294: if (dp = index (dp, '.'))
295: dp++;
296: if (dp == NULL)
297: break;
298: continue;
299: }
300:
301: if (recording)
302: LLOG (pgm_log, LLOG_NOTICE,
303: ("search for %s \"%s\" at baseobject \"%s\" succeeded",
304: ADOMAIN, dp, buffer));
305:
306: if (i > dlevel) {
307: dlevel = i;
308: if (dlist)
309: dn_seq_free (dlist), dlist = NULLDNSEQ;
310: }
311:
312: if (i == dlevel)
313: for (ptr = sr -> CSR_entries; ptr; ptr = ptr -> ent_next) {
314: struct dn_seq *dprev = dlist;
315: (void) dn_decode (ptr -> ent_dn);
316:
317: dlist = dm2dn_seq_aux (dm, ptr -> ent_dn, dlist);
318:
319: if (dprev == dlist)
320: dlist = dn_seq_push (ptr -> ent_dn, dlist);
321: else
322: if (i < dlevel)
323: break;
324: }
325:
326: entryinfo_free (sr -> CSR_entries, 0);
327: free_filter: ;
328: filter_free (sa -> sra_filter);
329: break;
330: }
331:
332: return dlist;
333: }
334:
335: /* */
336:
337: static PE image_search (ak)
338: register struct aka *ak;
339: {
340: register struct dn_seq *dlist;
341: struct ds_search_arg search_arg;
342: register struct ds_search_arg *sa = &search_arg;
343: struct ds_search_result search_result;
344: register CommonArgs *ca;
345: register struct ds_search_result *sr = &search_result;
346: struct DSError error;
347: register struct DSError *se = &error;
348: PE pe = NULLPE;
349:
350: bzero ((char *) sa, sizeof *sa);
351:
352: ca = &sa -> sra_common;
353: ca -> ca_servicecontrol.svc_options = SVC_OPT_PREFERCHAIN;
354: ca -> ca_servicecontrol.svc_prio = SVC_PRIO_LOW;
355: ca -> ca_servicecontrol.svc_timelimit = SVC_NOTIMELIMIT;
356: ca -> ca_servicecontrol.svc_sizelimit = SVC_NOSIZELIMIT;
357: ca -> ca_servicecontrol.svc_scopeofreferral = SVC_REFSCOPE_NONE;
358:
359: sa -> sra_subset = SRA_WHOLESUBTREE;
360: sa -> sra_searchaliases = TRUE;
361:
362: if (recording) {
363: LLOG (pgm_log, LLOG_NOTICE, ("searching for %s %s",
364: ak -> ak_domain, ak -> ak_local));
365: pslog (pgm_log, LLOG_NOTICE, " using baseobjects ",
366: dn_seq_print, (caddr_t) ak -> ak_bases);
367: }
368:
369: for (dlist = ak -> ak_bases; dlist; dlist = dlist -> dns_next) {
370: register filter *fi;
371: register AttributeType at;
372:
373: if ((sa -> sra_baseobject = dlist -> dns_dn) == NULL)
374: continue;
375:
376: sa -> sra_filter = fi = filter_alloc ();
377:
378: bzero ((char *) fi, sizeof *fi);
379: fi -> flt_type = FILTER_ITEM;
380: fi -> FUITEM.fi_type = FILTERITEM_EQUALITY;
381: if ((fi -> FUITEM.UNAVA.ava_type = at = AttrT_new (USERID)) == NULL)
382: adios ("invalid attribute type \"%s\"", USERID);
383: fi -> FUITEM.UNAVA.ava_value =
384: str2AttrV (ak -> ak_local, at -> at_table -> oa_syntax);
385:
386: sa -> sra_eis.eis_allattributes = FALSE;
387: sa -> sra_eis.eis_select = as_comp_new (str2AttrT (PHOTO), NULLAV,
388: NULLACL_INFO);
389: sa -> sra_eis.eis_infotypes = EIS_ATTRIBUTESANDVALUES;
390:
391: if (ds_search (sa, se, sr) != DS_OK) {
392: if (recording)
393: LLOG (pgm_log, LLOG_EXCEPTIONS, ("search operation failed"));
394:
395: (void) ds_unbind ();
396:
397: bound = 0;
398:
399: goto free_filter;
400: }
401:
402: if (sr -> srr_correlated != TRUE)
403: correlate_search_results (sr);
404:
405: if (sr -> CSR_entries == NULLENTRYINFO) {
406: if (recording)
407: pslog (pgm_log, LLOG_NOTICE,
408: "search failed at baseobject ", dn_print,
409: (caddr_t) dlist -> dns_dn);
410: filter_free (sa -> sra_filter);
411: continue;
412: }
413:
414: if (sr -> CSR_entries -> ent_attr == NULLATTR) {
415: if (recording)
416: pslog (pgm_log, LLOG_NOTICE,
417: "search succeeded (but no attribute) at baseobject ",
418: dn_print, (caddr_t) dlist -> dns_dn);
419: }
420: else {
421: AttributeValue av = &sr -> CSR_entries -> ent_attr -> attr_value
422: -> avseq_av;
423:
424: pe = (PE) av -> av_struct;
425: av -> av_struct = NULL;
426:
427: if (recording)
428: pslog (pgm_log, LLOG_NOTICE, "search succeeded at baseobject ",
429: dn_print, (caddr_t) dlist -> dns_dn);
430: }
431:
432: entryinfo_free (sr -> CSR_entries, 0);
433: free_filter: ;
434: filter_free (sa -> sra_filter);
435: break;
436: }
437:
438: return pe;
439: }
440:
441: /* */
442:
443: static do_bind ()
444: {
445: struct ds_bind_arg bind_arg,
446: bind_result;
447: register struct ds_bind_arg *ba = &bind_arg,
448: *br = &bind_result;
449: struct ds_bind_error bind_error;
450: register struct ds_bind_error *be = &bind_error;
451:
452: bzero ((char *) ba, sizeof *ba);
453: ba -> dba_version = DBA_VERSION_V1988;
454:
455: if (ds_bind (ba, be, br) != DS_OK) {
456: if (recording)
457: LLOG (pgm_log, LLOG_EXCEPTIONS,
458: ("directory bind failed: %s",
459: be -> dbe_type == DBE_TYPE_SECURITY ? "security error"
460: : "DSA unavailable"));
461:
462: return NOTOK;
463: }
464:
465: bound = 1;
466:
467: return OK;
468: }
469:
470: /* IMAGE */
471:
472: static int passno;
473: static int x, y, maxx;
474:
475: static struct type_IMAGE_Image *im = NULL;
476:
477: /* */
478:
479: struct type_IMAGE_Image *fetch_image (local, domain)
480: char *local,
481: *domain;
482: {
483: PE pe;
484: PS ps;
485: register struct aka *ak;
486:
487: if ((ak = mbox2ak (local, domain)) == NULL)
488: return NULL;
489: if (ak -> ak_image)
490: return ak -> ak_image;
491:
492: if (!bound && do_bind () == NOTOK)
493: return NULL;
494:
495: if ((pe = image_search (ak)) == NULLPE)
496: return NULL;
497:
498: if (!stay_bound) {
499: (void) ds_unbind ();
500: bound = 0;
501: }
502:
503: im = NULL;
504:
505: if ((ps = ps_alloc (str_open)) == NULLPS) {
506: if (debug)
507: fprintf (stderr, "ps_alloc: failed\n");
508:
509: goto out;
510: }
511: if (str_setup (ps, NULLCP, 0, 0) == NOTOK) {
512: if (debug)
513: fprintf (stderr, "ps_alloc: %s\n", ps_error (ps -> ps_errno));
514:
515: goto out;
516: }
517:
518: if (pe2ps (ps, pe) == NOTOK) {
519: if (debug)
520: fprintf (stderr, "pe2ps: %s\n", pe_error (pe -> pe_errno));
521:
522: goto out;
523: }
524:
525: for (passno = 1; passno < 3; passno++)
526: if (decode_t4 (ps -> ps_base, PHOTO, 0) == NOTOK) {
527: fprintf (stderr, "\n");
528: if (im) {
529: qb_free (im -> data);
530: free ((char *) im);
531: im = NULL;
532: }
533: break;
534: }
535:
536: out: ;
537: if (ps)
538: ps_free (ps);
539: pe_free (pe);
540:
541: return (ak -> ak_image = im);
542: }
543:
544: /* */
545:
546: /* ARGSUSED */
547:
548: photo_start (name)
549: char *name;
550: {
551: if (passno == 1)
552: maxx = 0;
553: x = y = 0;
554:
555: return OK;
556: }
557:
558:
559: /* ARGSUSED */
560:
561: photo_end (name)
562: char *name;
563: {
564: int len;
565: register struct qbuf *qb,
566: *pb;
567:
568: if (passno == 1) {
569: x = maxx, y--;
570:
571: if (debug)
572: fprintf (stderr, "ending pass one for \"%s\", %dx%d\n",
573: name, x, y);
574:
575: if ((im = (struct type_IMAGE_Image *) calloc (1, sizeof *im))
576: == NULL) {
577: if (debug)
578: fprintf (stderr, "calloc fails");
579: return NOTOK;
580: }
581: im -> width = x, im -> height = y;
582:
583: len = ((im -> width + 7) / 8) * im -> height;
584: if ((im -> data = qb = (struct qbuf *) malloc (sizeof *qb)) == NULL) {
585: if (debug)
586: fprintf (stderr, "unable to allocate qbuf");
587: return NOTOK;
588: }
589: qb -> qb_forw = qb -> qb_back = qb;
590: qb -> qb_data = NULL, qb -> qb_len = len;
591:
592: if ((pb = (struct qbuf *) calloc ((unsigned) (sizeof *pb + len), 1))
593: == NULL) {
594: if (debug)
595: fprintf (stderr, "unable to allocate qbuf (%d+%d)",
596: sizeof *qb, len);
597: return NOTOK;
598: }
599: pb -> qb_data = pb -> qb_base, pb -> qb_len = len;
600: insque (pb, qb);
601: }
602:
603: return OK;
604: }
605:
606:
607: photo_black (length)
608: int length;
609: {
610: if (passno == 2) {
611: register int i,
612: j;
613: register unsigned char *cp;
614:
615: cp = (unsigned char *) im -> data -> qb_forw -> qb_data
616: + ((im -> width + 7) / 8) * y + x / 8;
617: i = x % 8;
618: for (j = length; j > 0; j--) {
619: *cp |= 1 << i;
620: if (++i == 8)
621: cp++, i = 0;
622: }
623:
624: }
625:
626: x += length;
627:
628: return OK;
629: }
630:
631:
632: photo_white (length)
633: int length;
634: {
635: x += length;
636:
637: return OK;
638: }
639:
640:
641: /* ARGSUSED */
642:
643: photo_line_end (line)
644: caddr_t line;
645: {
646: if (passno == 1 && x > maxx)
647: maxx = x;
648: x = 0, y++;
649:
650: return OK;
651: }
652:
653: /* ERRORS */
654:
655: #ifndef lint
656: void _advise ();
657:
658:
659: void adios (va_alist)
660: va_dcl
661: {
662: va_list ap;
663:
664: va_start (ap);
665:
666: _advise (ap);
667:
668: va_end (ap);
669:
670: _exit (1);
671: }
672: #else
673: /* VARARGS */
674:
675: void adios (what, fmt)
676: char *what,
677: *fmt;
678: {
679: adios (what, fmt);
680: }
681: #endif
682:
683:
684: #ifndef lint
685: void advise (va_alist)
686: va_dcl
687: {
688: va_list ap;
689:
690: va_start (ap);
691:
692: _advise (ap);
693:
694: va_end (ap);
695: }
696:
697:
698: static void _advise (ap)
699: va_list ap;
700: {
701: char buffer[BUFSIZ];
702:
703: asprintf (buffer, ap);
704:
705: (void) fflush (stdout);
706:
707: if (errsw != NOTOK) {
708: fprintf (stderr, "%s: ", myname);
709: (void) fputs (buffer, stderr);
710: (void) fputc ('\n', stderr);
711:
712: (void) fflush (stderr);
713: }
714: }
715: #else
716: /* VARARGS */
717:
718: void advise (what, fmt)
719: char *what,
720: *fmt;
721: {
722: advise (what, fmt);
723: }
724: #endif
725:
726: /* MISC */
727:
728: #ifndef lint
729: char *strdup (s)
730: char *s;
731: {
732: char *p;
733:
734: if (p = malloc ((unsigned) (strlen (s) + 1)))
735: (void) strcpy (p, s);
736:
737: return p;
738: }
739: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.