Annotation of src/usr.bin/gencat/gencat.c, Revision 1.10
1.10 ! otto 1: /* $OpenBSD: gencat.c,v 1.9 2004/07/01 19:23:34 mickey Exp $ */
1.6 danh 2: /* $NetBSD: gencat.c,v 1.9 1998/10/09 17:00:56 itohy Exp $ */
1.4 deraadt 3:
1.3 deraadt 4: /*-
5: * Copyright (c) 1996 The NetBSD Foundation, Inc.
6: * All rights reserved.
7: *
8: * This code is derived from software contributed to The NetBSD Foundation
9: * by J.T. Conklin.
10: *
11: * Redistribution and use in source and binary forms, with or without
12: * modification, are permitted provided that the following conditions
13: * are met:
14: * 1. Redistributions of source code must retain the above copyright
15: * notice, this list of conditions and the following disclaimer.
16: * 2. Redistributions in binary form must reproduce the above copyright
17: * notice, this list of conditions and the following disclaimer in the
18: * documentation and/or other materials provided with the distribution.
19: * 3. All advertising materials mentioning features or use of this software
1.5 jdm 20: * must display the following acknowledgment:
1.3 deraadt 21: * This product includes software developed by the NetBSD
22: * Foundation, Inc. and its contributors.
23: * 4. Neither the name of The NetBSD Foundation nor the names of its
24: * contributors may be used to endorse or promote products derived
25: * from this software without specific prior written permission.
26: *
27: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1.6 danh 30: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1.3 deraadt 32: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37: * POSSIBILITY OF SUCH DAMAGE.
38: */
1.1 deraadt 39:
1.6 danh 40: #include <sys/cdefs.h>
41: #ifndef lint
1.9 mickey 42: static const char rcsid[] =
1.10 ! otto 43: "$OpenBSD: gencat.c,v 1.9 2004/07/01 19:23:34 mickey Exp $";
1.6 danh 44: #endif /* not lint */
45:
1.1 deraadt 46: /***********************************************************
47: Copyright 1990, by Alfalfa Software Incorporated, Cambridge, Massachusetts.
48:
49: All Rights Reserved
50:
51: Permission to use, copy, modify, and distribute this software and its
52: documentation for any purpose and without fee is hereby granted,
53: provided that the above copyright notice appear in all copies and that
54: both that copyright notice and this permission notice appear in
55: supporting documentation, and that Alfalfa's name not be used in
56: advertising or publicity pertaining to distribution of the software
57: without specific, written prior permission.
58:
59: ALPHALPHA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
60: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
61: ALPHALPHA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
62: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
63: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
64: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
65: SOFTWARE.
66:
67: If you make any modifications, bugfixes or other changes to this software
68: we'd appreciate it if you could send a copy to us so we can keep things
69: up-to-date. Many thanks.
70: Kee Hinckley
71: Alfalfa Software, Inc.
72: 267 Allston St., #3
73: Cambridge, MA 02139 USA
74: nazgul@alfalfa.com
1.3 deraadt 75:
1.1 deraadt 76: ******************************************************************/
77:
1.3 deraadt 78: #define _NLS_PRIVATE
1.1 deraadt 79:
1.5 jdm 80: /* ensure 8-bit cleanliness */
1.6 danh 81: #define ISSPACE(c) \
82: (isascii((unsigned char)c) && isspace((unsigned char)c))
1.5 jdm 83:
1.3 deraadt 84: #include <sys/queue.h>
85: #include <ctype.h>
1.6 danh 86: #include <err.h>
87: #include <fcntl.h>
88: #include <nl_types.h>
1.1 deraadt 89: #include <stdio.h>
1.3 deraadt 90: #include <stdlib.h>
91: #include <string.h>
92: #include <unistd.h>
1.9 mickey 93: #include <fcntl.h>
94: #include <nl_types.h>
95: #include <err.h>
1.3 deraadt 96:
97: struct _msgT {
98: long msgId;
99: char *str;
100: LIST_ENTRY(_msgT) entries;
101: };
102:
103: struct _setT {
104: long setId;
105: LIST_HEAD(msghead, _msgT) msghead;
106: LIST_ENTRY(_setT) entries;
107: };
1.1 deraadt 108:
1.3 deraadt 109: LIST_HEAD(sethead, _setT) sethead;
110: static struct _setT *curSet;
1.1 deraadt 111:
1.3 deraadt 112: static char *curline = NULL;
113: static long lineno = 0;
1.1 deraadt 114:
1.6 danh 115: extern char *__progname; /* from crt0.o */
116:
1.7 millert 117: static char *cskip(char *);
118: static void error(char *, char *);
119: static void nomem(void);
120: static char *getline(int);
121: static char *getmsg(int, char *, char);
122: static void warning(char *, char *);
123: static char *wskip(char *);
124: static char *xstrdup(const char *);
125: static void *xmalloc(size_t);
126: static void *xrealloc(void *, size_t);
127:
128: void MCParse(int fd);
129: void MCWriteCat(int fd);
130: void MCDelMsg(int msgId);
131: void MCAddMsg(int msgId, const char *msg);
132: void MCAddSet(int setId);
133: void MCDelSet(int setId);
134: int main(int, char **);
135: void usage(void);
1.6 danh 136:
137:
1.3 deraadt 138: void
1.8 deraadt 139: usage(void)
1.3 deraadt 140: {
1.6 danh 141: fprintf(stderr, "Usage: %s catfile msgfile ...\n", __progname);
1.3 deraadt 142: exit(1);
143: }
1.1 deraadt 144:
1.3 deraadt 145: int
1.8 deraadt 146: main(int argc, char *argv[])
1.3 deraadt 147: {
148: int ofd, ifd;
149: char *catfile = NULL;
150: int c;
151:
152: while ((c = getopt(argc, argv, "")) != -1) {
153: switch (c) {
154: case '?':
155: default:
156: usage();
157: /* NOTREACHED */
158: }
159: }
160: argc -= optind;
161: argv += optind;
1.1 deraadt 162:
1.3 deraadt 163: if (argc < 2) {
1.1 deraadt 164: usage();
1.3 deraadt 165: /* NOTREACHED */
166: }
167: catfile = *argv++;
168:
169: for (; *argv; argv++) {
1.6 danh 170: if ((ifd = open(*argv, O_RDONLY)) < 0)
171: err(1, "Unable to read %s", *argv);
1.1 deraadt 172: MCParse(ifd);
173: close(ifd);
174: }
1.3 deraadt 175:
1.6 danh 176: if ((ofd = open(catfile, O_WRONLY | O_TRUNC | O_CREAT, 0666)) < 0)
177: err(1, "Unable to create a new %s", catfile);
1.1 deraadt 178: MCWriteCat(ofd);
179: exit(0);
1.3 deraadt 180: }
181:
182: static void
1.8 deraadt 183: warning(char *cptr, char *msg)
1.3 deraadt 184: {
1.9 mickey 185: warnx("%s on line %ld\n%s", msg, lineno, curline);
1.3 deraadt 186: if (cptr) {
187: char *tptr;
188: for (tptr = curline; tptr < cptr; ++tptr)
189: putc(' ', stderr);
190: fprintf(stderr, "^\n");
191: }
192: }
193:
194: static void
1.8 deraadt 195: error(char *cptr, char *msg)
1.3 deraadt 196: {
197: warning(cptr, msg);
1.1 deraadt 198: exit(1);
199: }
200:
1.3 deraadt 201: static void
1.8 deraadt 202: nomem(void)
1.3 deraadt 203: {
204: error(NULL, "out of memory");
205: }
206:
207: static void *
1.8 deraadt 208: xmalloc(size_t len)
1.3 deraadt 209: {
210: void *p;
211:
212: if ((p = malloc(len)) == NULL)
213: nomem();
214: return (p);
215: }
216:
217: static void *
1.8 deraadt 218: xrealloc(void *ptr, size_t size)
1.3 deraadt 219: {
220: if ((ptr = realloc(ptr, size)) == NULL)
221: nomem();
222: return (ptr);
223: }
224:
225: static char *
1.8 deraadt 226: xstrdup(const char *str)
1.3 deraadt 227: {
1.6 danh 228: char *nstr;
229:
230: if ((nstr = strdup(str)) == NULL)
1.3 deraadt 231: nomem();
1.6 danh 232: return (nstr);
1.3 deraadt 233: }
234:
235: static char *
1.8 deraadt 236: getline(int fd)
1.3 deraadt 237: {
238: static long curlen = BUFSIZ;
239: static char buf[BUFSIZ], *bptr = buf, *bend = buf;
240: char *cptr, *cend;
241: long buflen;
242:
243: if (!curline) {
244: curline = xmalloc(curlen);
245: }
246: ++lineno;
247:
248: cptr = curline;
249: cend = curline + curlen;
250: for (;;) {
251: for (; bptr < bend && cptr < cend; ++cptr, ++bptr) {
252: if (*bptr == '\n') {
253: *cptr = '\0';
254: ++bptr;
255: return (curline);
256: } else
257: *cptr = *bptr;
258: }
259: if (bptr == bend) {
260: buflen = read(fd, buf, BUFSIZ);
261: if (buflen <= 0) {
262: if (cptr > curline) {
263: *cptr = '\0';
264: return (curline);
265: }
266: return (NULL);
267: }
268: bend = buf + buflen;
269: bptr = buf;
270: }
271: if (cptr == cend) {
272: cptr = curline = xrealloc(curline, curlen *= 2);
273: cend = curline + curlen;
274: }
275: }
276: }
277:
278: static char *
1.8 deraadt 279: wskip(char *cptr)
1.3 deraadt 280: {
1.5 jdm 281: if (!*cptr || !ISSPACE(*cptr)) {
1.3 deraadt 282: warning(cptr, "expected a space");
283: return (cptr);
284: }
1.5 jdm 285: while (*cptr && ISSPACE(*cptr))
1.3 deraadt 286: ++cptr;
287: return (cptr);
288: }
289:
290: static char *
1.8 deraadt 291: cskip(char *cptr)
1.3 deraadt 292: {
1.5 jdm 293: if (!*cptr || ISSPACE(*cptr)) {
1.3 deraadt 294: warning(cptr, "wasn't expecting a space");
295: return (cptr);
296: }
1.5 jdm 297: while (*cptr && !ISSPACE(*cptr))
1.3 deraadt 298: ++cptr;
299: return (cptr);
300: }
301:
302: static char *
1.8 deraadt 303: getmsg(int fd, char *cptr, char quote)
1.3 deraadt 304: {
305: static char *msg = NULL;
306: static long msglen = 0;
307: long clen, i;
308: char *tptr;
309:
310: if (quote && *cptr == quote) {
311: ++cptr;
1.6 danh 312: }
1.3 deraadt 313:
314: clen = strlen(cptr) + 1;
315: if (clen > msglen) {
316: if (msglen)
317: msg = xrealloc(msg, clen);
318: else
319: msg = xmalloc(clen);
320: msglen = clen;
321: }
322: tptr = msg;
323:
324: while (*cptr) {
325: if (quote && *cptr == quote) {
326: char *tmp;
327: tmp = cptr + 1;
1.5 jdm 328: if (*tmp && (!ISSPACE(*tmp) || *wskip(tmp))) {
329: warning(cptr, "unexpected quote character, ignoring");
1.3 deraadt 330: *tptr++ = *cptr++;
331: } else {
332: *cptr = '\0';
333: }
334: } else
335: if (*cptr == '\\') {
336: ++cptr;
337: switch (*cptr) {
338: case '\0':
339: cptr = getline(fd);
340: if (!cptr)
341: error(NULL, "premature end of file");
342: msglen += strlen(cptr);
343: i = tptr - msg;
344: msg = xrealloc(msg, msglen);
345: tptr = msg + i;
346: break;
347: case 'n':
348: *tptr++ = '\n';
349: ++cptr;
350: break;
351: case 't':
352: *tptr++ = '\t';
353: ++cptr;
354: break;
355: case 'v':
356: *tptr++ = '\v';
357: ++cptr;
358: break;
359: case 'b':
360: *tptr++ = '\b';
361: ++cptr;
362: break;
363: case 'r':
364: *tptr++ = '\r';
365: ++cptr;
366: break;
367: case 'f':
368: *tptr++ = '\f';
369: ++cptr;
370: break;
371: case '\\':
372: *tptr++ = '\\';
373: ++cptr;
374: break;
1.6 danh 375: case '"':
376: /* FALLTHROUGH */
1.5 jdm 377: case '\'':
1.6 danh 378: /*
1.5 jdm 379: * While it isn't necessary to
380: * escape ' and ", let's accept
381: * them escaped and not complain.
382: * (XPG4 states that '\' should be
1.6 danh 383: * ignored when not used in a
1.5 jdm 384: * valid escape sequence)
385: */
386: *tptr++ = '"';
387: ++cptr;
388: break;
1.3 deraadt 389: default:
1.6 danh 390: if (quote && *cptr == quote) {
391: *tptr++ = *cptr++;
392: } else if (isdigit((unsigned char) *cptr)) {
1.3 deraadt 393: *tptr = 0;
394: for (i = 0; i < 3; ++i) {
1.6 danh 395: if (!isdigit((unsigned char) *cptr))
1.3 deraadt 396: break;
397: if (*cptr > '7')
398: warning(cptr, "octal number greater than 7?!");
399: *tptr *= 8;
400: *tptr += (*cptr - '0');
401: ++cptr;
402: }
403: } else {
1.6 danh 404: warning(cptr, "unrecognized escape sequence; ignoring esacpe character");
1.3 deraadt 405: }
1.6 danh 406: break;
1.3 deraadt 407: }
408: } else {
409: *tptr++ = *cptr++;
410: }
411: }
412: *tptr = '\0';
413: return (msg);
414: }
415:
416: void
1.8 deraadt 417: MCParse(int fd)
1.3 deraadt 418: {
419: char *cptr, *str;
420: int setid, msgid = 0;
421: char quote = 0;
422:
423: /* XXX: init sethead? */
424:
425: while ((cptr = getline(fd))) {
426: if (*cptr == '$') {
427: ++cptr;
428: if (strncmp(cptr, "set", 3) == 0) {
429: cptr += 3;
430: cptr = wskip(cptr);
431: setid = atoi(cptr);
432: MCAddSet(setid);
433: msgid = 0;
434: } else if (strncmp(cptr, "delset", 6) == 0) {
435: cptr += 6;
436: cptr = wskip(cptr);
437: setid = atoi(cptr);
438: MCDelSet(setid);
439: } else if (strncmp(cptr, "quote", 5) == 0) {
440: cptr += 5;
441: if (!*cptr)
442: quote = 0;
443: else {
444: cptr = wskip(cptr);
445: if (!*cptr)
446: quote = 0;
447: else
448: quote = *cptr;
449: }
1.5 jdm 450: } else if (ISSPACE(*cptr)) {
1.3 deraadt 451: ;
452: } else {
453: if (*cptr) {
454: cptr = wskip(cptr);
455: if (*cptr)
456: warning(cptr, "unrecognized line");
457: }
458: }
459: } else {
1.6 danh 460: /*
461: * First check for (and eat) empty lines....
462: */
463: if (!*cptr)
464: continue;
465: /*
466: * We have a digit? Start of a message. Else,
467: * syntax error.
468: */
469: if (isdigit((unsigned char) *cptr)) {
1.3 deraadt 470: msgid = atoi(cptr);
471: cptr = cskip(cptr);
472: cptr = wskip(cptr);
473: /* if (*cptr) ++cptr; */
1.6 danh 474: } else {
475: warning(cptr, "neither blank line nor start of a message id");
476: continue;
1.3 deraadt 477: }
1.6 danh 478: /*
479: * If we have a message ID, but no message,
480: * then this means "delete this message id
481: * from the catalog".
482: */
483: if (!*cptr) {
1.3 deraadt 484: MCDelMsg(msgid);
1.6 danh 485: } else {
1.3 deraadt 486: str = getmsg(fd, cptr, quote);
487: MCAddMsg(msgid, str);
488: }
489: }
490: }
491: }
492:
493: /*
494: * Write message catalog.
495: *
496: * The message catalog is first converted from its internal to its
497: * external representation in a chunk of memory allocated for this
498: * purpose. Then the completed catalog is written. This approach
499: * avoids additional housekeeping variables and/or a lot of seeks
500: * that would otherwise be required.
501: */
502: void
1.8 deraadt 503: MCWriteCat(int fd)
1.1 deraadt 504: {
1.3 deraadt 505: int nsets; /* number of sets */
506: int nmsgs; /* number of msgs */
507: int string_size; /* total size of string pool */
508: int msgcat_size; /* total size of message catalog */
509: void *msgcat; /* message catalog data */
510: struct _nls_cat_hdr *cat_hdr;
511: struct _nls_set_hdr *set_hdr;
512: struct _nls_msg_hdr *msg_hdr;
513: char *strings;
514: struct _setT *set;
515: struct _msgT *msg;
516: int msg_index;
517: int msg_offset;
518:
519: /* determine number of sets, number of messages, and size of the
520: * string pool */
521: nsets = 0;
522: nmsgs = 0;
523: string_size = 0;
524:
1.10 ! otto 525: LIST_FOREACH(set, &sethead, entries) {
1.3 deraadt 526: nsets++;
527:
1.10 ! otto 528: LIST_FOREACH(msg, &set->msghead, entries) {
1.3 deraadt 529: nmsgs++;
530: string_size += strlen(msg->str) + 1;
531: }
532: }
533:
534: #ifdef DEBUG
535: printf("number of sets: %d\n", nsets);
536: printf("number of msgs: %d\n", nmsgs);
537: printf("string pool size: %d\n", string_size);
538: #endif
539:
540: /* determine size and then allocate buffer for constructing external
541: * message catalog representation */
542: msgcat_size = sizeof(struct _nls_cat_hdr)
543: + (nsets * sizeof(struct _nls_set_hdr))
544: + (nmsgs * sizeof(struct _nls_msg_hdr))
545: + string_size;
546:
547: msgcat = xmalloc(msgcat_size);
548: memset(msgcat, '\0', msgcat_size);
549:
550: /* fill in msg catalog header */
551: cat_hdr = (struct _nls_cat_hdr *) msgcat;
552: cat_hdr->__magic = htonl(_NLS_MAGIC);
553: cat_hdr->__nsets = htonl(nsets);
554: cat_hdr->__mem = htonl(msgcat_size - sizeof(struct _nls_cat_hdr));
555: cat_hdr->__msg_hdr_offset =
556: htonl(nsets * sizeof(struct _nls_set_hdr));
557: cat_hdr->__msg_txt_offset =
558: htonl(nsets * sizeof(struct _nls_set_hdr) +
559: nmsgs * sizeof(struct _nls_msg_hdr));
560:
561: /* compute offsets for set & msg header tables and string pool */
562: set_hdr = (struct _nls_set_hdr *) ((char *) msgcat +
563: sizeof(struct _nls_cat_hdr));
564: msg_hdr = (struct _nls_msg_hdr *) ((char *) msgcat +
565: sizeof(struct _nls_cat_hdr) +
566: nsets * sizeof(struct _nls_set_hdr));
567: strings = (char *) msgcat +
568: sizeof(struct _nls_cat_hdr) +
569: nsets * sizeof(struct _nls_set_hdr) +
570: nmsgs * sizeof(struct _nls_msg_hdr);
571:
572: msg_index = 0;
573: msg_offset = 0;
1.10 ! otto 574: LIST_FOREACH(set, &sethead, entries) {
1.3 deraadt 575:
576: nmsgs = 0;
1.10 ! otto 577: LIST_FOREACH(msg, &set->msghead, entries) {
1.3 deraadt 578: int msg_len = strlen(msg->str) + 1;
579:
580: msg_hdr->__msgno = htonl(msg->msgId);
581: msg_hdr->__msglen = htonl(msg_len);
582: msg_hdr->__offset = htonl(msg_offset);
583:
584: memcpy(strings, msg->str, msg_len);
585: strings += msg_len;
586: msg_offset += msg_len;
587:
588: nmsgs++;
589: msg_hdr++;
590: }
591:
592: set_hdr->__setno = htonl(set->setId);
593: set_hdr->__nmsgs = htonl(nmsgs);
594: set_hdr->__index = htonl(msg_index);
595: msg_index += nmsgs;
596: set_hdr++;
597: }
598:
599: /* write out catalog. XXX: should this be done in small chunks? */
600: write(fd, msgcat, msgcat_size);
601: }
602:
603: void
1.8 deraadt 604: MCAddSet(int setId)
1.3 deraadt 605: {
606: struct _setT *p, *q;
607:
608: if (setId <= 0) {
609: error(NULL, "setId's must be greater than zero");
610: /* NOTREACHED */
611: }
612: #if 0
613: /* XXX */
614: if (setId > NL_SETMAX) {
615: error(NULL, "setId %d exceeds limit (%d)");
616: /* NOTREACHED */
617: }
618: #endif
619:
1.10 ! otto 620: p = LIST_FIRST(&sethead);
1.3 deraadt 621: q = NULL;
1.10 ! otto 622: for (; p != NULL && p->setId < setId; q = p, p = LIST_NEXT(p, entries));
1.3 deraadt 623:
624: if (p && p->setId == setId) {
625: ;
626: } else {
627: p = xmalloc(sizeof(struct _setT));
628: memset(p, '\0', sizeof(struct _setT));
629: LIST_INIT(&p->msghead);
630:
631: p->setId = setId;
632:
633: if (q == NULL) {
634: LIST_INSERT_HEAD(&sethead, p, entries);
635: } else {
636: LIST_INSERT_AFTER(q, p, entries);
637: }
638: }
639:
640: curSet = p;
641: }
642:
643: void
1.8 deraadt 644: MCAddMsg(int msgId, const char *str)
1.3 deraadt 645: {
646: struct _msgT *p, *q;
647:
648: if (!curSet)
649: error(NULL, "can't specify a message when no set exists");
650:
651: if (msgId <= 0) {
652: error(NULL, "msgId's must be greater than zero");
653: /* NOTREACHED */
654: }
655: #if 0
656: /* XXX */
657: if (msgId > NL_SETMAX) {
1.5 jdm 658: error(NULL, "msgId %d exceeds limit (%d)");
1.3 deraadt 659: /* NOTREACHED */
660: }
661: #endif
662:
1.10 ! otto 663: p = LIST_FIRST(&curSet->msghead);
1.3 deraadt 664: q = NULL;
1.10 ! otto 665: for (; p != NULL && p->msgId < msgId; q = p, p = LIST_NEXT(p, entries));
1.3 deraadt 666:
667: if (p && p->msgId == msgId) {
668: free(p->str);
669: } else {
670: p = xmalloc(sizeof(struct _msgT));
671: memset(p, '\0', sizeof(struct _msgT));
672:
673: if (q == NULL) {
674: LIST_INSERT_HEAD(&curSet->msghead, p, entries);
675: } else {
676: LIST_INSERT_AFTER(q, p, entries);
677: }
678: }
679:
680: p->msgId = msgId;
681: p->str = xstrdup(str);
682: }
683:
684: void
1.8 deraadt 685: MCDelSet(int setId)
1.3 deraadt 686: {
687: struct _setT *set;
688: struct _msgT *msg;
689:
1.10 ! otto 690: set = LIST_FIRST(&sethead);
! 691: for (; set != NULL && set->setId < setId;
! 692: set = LIST_NEXT(set, entries));
1.3 deraadt 693:
694: if (set && set->setId == setId) {
695:
1.10 ! otto 696: msg = LIST_FIRST(&set->msghead);
1.3 deraadt 697: while (msg) {
698: free(msg->str);
1.5 jdm 699: LIST_REMOVE(msg, entries);
1.3 deraadt 700: }
701:
702: LIST_REMOVE(set, entries);
703: return;
704: }
705: warning(NULL, "specified set doesn't exist");
706: }
1.1 deraadt 707:
1.3 deraadt 708: void
1.8 deraadt 709: MCDelMsg(int msgId)
1.3 deraadt 710: {
711: struct _msgT *msg;
1.1 deraadt 712:
1.3 deraadt 713: if (!curSet)
714: error(NULL, "you can't delete a message before defining the set");
1.1 deraadt 715:
1.10 ! otto 716: msg = LIST_FIRST(&curSet->msghead);
! 717: for (; msg != NULL && msg->msgId < msgId;
! 718: msg = LIST_NEXT(msg, entries));
1.1 deraadt 719:
1.3 deraadt 720: if (msg && msg->msgId == msgId) {
721: free(msg->str);
722: LIST_REMOVE(msg, entries);
723: return;
724: }
725: warning(NULL, "specified msg doesn't exist");
1.1 deraadt 726: }