1 /*++++++++++++++++++++++
2   xmlout.c: refdb application server, xml export functions
3   markus@mhoenicka.de 2002-09-05
4   $Id: xmlout.c,v 1.6.2.8 2006/04/05 20:19:26 mhoenicka Exp $
5 
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10 
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 
20    ++++++++++++++++++++++++*/
21 
22 #include <stdio.h>
23 #include <string.h>
24 #include <limits.h>
25 #include <sys/types.h>
26 #include <unistd.h>
27 #include <syslog.h>
28 #include <fcntl.h>
29 #include <dbi/dbi.h>
30 
31 #include "linklist.h"
32 #include "refdb.h"
33 #include "connect.h"
34 #include "refdbd.h"
35 #include "backend.h"
36 #include "xmlout.h"
37 #include "strfncs.h"
38 #include "dbfncs.h"
39 
40 /* globals */
41 extern int n_log_level;
42 
43 /* forward declarations of local functions */
44 static int iwrite_authorlist(struct CLIENT_REQUEST* ptr_clrequest, dbi_result dbires_ref, const char* role);
45 static int iwrite_authornames(struct CLIENT_REQUEST* ptr_clrequest, dbi_result dbires_ref, const char* role);
46 static int iwrite_authorseps(struct CLIENT_REQUEST* ptr_clrequest, dbi_result dbires_ref, const char* role);
47 static int iwrite_authortext(struct CLIENT_REQUEST* ptr_clrequest, dbi_result dbires_ref, const char* role);
48 static int iwrite_simple(struct CLIENT_REQUEST* ptr_clrequest, dbi_result dbires_ref, const char* elname);
49 static int iwrite_twoatt(struct CLIENT_REQUEST* ptr_clrequest, dbi_result dbires_ref, const char* elname);
50 static int iwrite_journalname(struct CLIENT_REQUEST* ptr_clrequest, dbi_result dbires_ref);
51 static int iwrite_pages(struct CLIENT_REQUEST* ptr_clrequest, dbi_result dbires_ref);
52 static int iwrite_pubdate(struct CLIENT_REQUEST* ptr_clrequest, dbi_result dbires_ref, const char* role);
53 static int iwrite_separator(struct CLIENT_REQUEST* ptr_clrequest, dbi_result dbires_ref, unsigned int separator_id);
54 static int iwrite_title(struct CLIENT_REQUEST* ptr_clrequest, dbi_result dbires_ref, const char* role);
55 
56 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
57   iwrite_elstart() writes a start tag of an element to a file descriptor
58 
59   int iwrite_elstart 0 if fine, 1 if some error occurred
60 
61   struct CLIENT_REQUEST* ptr_clrequest ptr to a structure with client info
62 
63   const char* elname string containing the element name
64 
65   Liliform *ptr_first pointer to sentinel of a list of attributes
66 
67   int nis_empty 0 if element has data, 1 if element is empty
68 
69   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
iwrite_elstart(struct CLIENT_REQUEST * ptr_clrequest,const char * elname,Liliform * ptr_first,int nis_empty)70 int iwrite_elstart(struct CLIENT_REQUEST* ptr_clrequest, const char* elname, Liliform *ptr_first, int nis_empty) {
71   Liliform *ptr_curr;
72   char outbuffer[512];
73 
74   if (!elname || !*elname) {
75     /* nothing to do */
76     return 0;
77   }
78 
79   if (tiwrite(ptr_clrequest->fd, "<", TERM_NO) == -1) {
80     LOG_PRINT(LOG_WARNING, get_status_msg(110));
81     return 1;
82   }
83 
84   if (tiwrite(ptr_clrequest->fd, elname, TERM_NO) == -1) {
85     LOG_PRINT(LOG_WARNING, get_status_msg(110));
86     return 1;
87   }
88 
89   /* add attributes if available */
90   if (ptr_first) {
91     ptr_curr = ptr_first;
92     while ((ptr_curr = get_next_liliform(ptr_curr)) != NULL) {
93       if (ptr_curr->name && *(ptr_curr->name)
94 	  && ptr_curr->value && *(ptr_curr->value)) {
95 	sprintf(outbuffer, " %s=\"%s\"", ptr_curr->name, ptr_curr->value);
96 	if (tiwrite(ptr_clrequest->fd, outbuffer, TERM_NO) == -1) {
97 	  LOG_PRINT(LOG_WARNING, get_status_msg(110));
98 	  return 1;
99 	}
100       }
101     }
102   }
103 
104   if (nis_empty) {
105     if (tiwrite(ptr_clrequest->fd, "/>\n", TERM_NO) == -1) {
106       LOG_PRINT(LOG_WARNING, get_status_msg(110));
107       return 1;
108     }
109   }
110   else {
111     if (tiwrite(ptr_clrequest->fd, ">", TERM_NO) == -1) {
112       LOG_PRINT(LOG_WARNING, get_status_msg(110));
113       return 1;
114     }
115   }
116 
117   return 0;
118 }
119 
120 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
121   iwrite_elend() writes an end tag of an element to a file descriptor
122 
123   int iwrite_elstart 0 if fine, 1 if some error occurred
124 
125   struct CLIENT_REQUEST* ptr_clrequest ptr to a structure with client info
126 
127   const char* elname string containing the element name
128 
129   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
iwrite_elend(struct CLIENT_REQUEST * ptr_clrequest,const char * elname)130 int iwrite_elend(struct CLIENT_REQUEST* ptr_clrequest, const char* elname) {
131   if (!elname || !*elname) {
132     /* nothing to do */
133     return 0;
134   }
135 
136   if (tiwrite(ptr_clrequest->fd, "</", TERM_NO) == -1) {
137     LOG_PRINT(LOG_WARNING, get_status_msg(110));
138     return 1;
139   }
140 
141   if (tiwrite(ptr_clrequest->fd, elname, TERM_NO) == -1) {
142     LOG_PRINT(LOG_WARNING, get_status_msg(110));
143     return 1;
144   }
145 
146   if (tiwrite(ptr_clrequest->fd, ">\n", TERM_NO) == -1) {
147     LOG_PRINT(LOG_WARNING, get_status_msg(110));
148     return 1;
149   }
150 
151   return 0;
152 }
153 
154 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
155   iwrite_element() writes an element to a file descriptor
156 
157   int iwrite_element 0 if fine, 1 if some error occurred
158 
159   struct CLIENT_REQUEST* ptr_clrequest ptr to a structure with client info
160 
161   const char* elname string containing the element name
162 
163   Liliform *ptr_first pointer to sentinel of a list of attributes
164 
165   const char *elvalue ptr to string with element value
166 
167   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
iwrite_element(struct CLIENT_REQUEST * ptr_clrequest,const char * elname,Liliform * ptr_first,const char * elvalue)168 int iwrite_element(struct CLIENT_REQUEST* ptr_clrequest, const char* elname, Liliform *ptr_first, const char *elvalue) {
169   char* entitize_buf;
170 
171   if (!elvalue || !elname || !*elname) {
172     /* nothing to do */
173     return 0;
174   }
175 
176   if (iwrite_elstart(ptr_clrequest, elname, ptr_first, 0)) {
177     return 1;
178   }
179 
180   /* take care of entities */
181   if ((entitize_buf = strdup(elvalue)) == NULL
182       || sgml_entitize(&entitize_buf, NULL) == NULL) {
183       return 1;
184   }
185 
186   if (tiwrite(ptr_clrequest->fd, entitize_buf, TERM_NO) == -1) {
187     free(entitize_buf);
188     return 1;
189   }
190 
191   free(entitize_buf);
192 
193   if (iwrite_elend(ptr_clrequest, elname)) {
194     return 1;
195   }
196   return 0;
197 }
198 
199 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
200   iwrite_pubtype() writes a pubtype element to a file descriptor. This
201                    works also for INTEXTDEF, AUTHORONLY etc.
202 
203   int iwrite_pubtype 0 if fine, 1 if some error occurred
204 
205   struct CLIENT_REQUEST* ptr_clrequest ptr to a structure with client info
206 
207   const char* type string containing the pubtype name
208 
209   unsigned int citstyle_id id of the current citstyle entry
210 
211   dbi_conn conn connection to database server
212 
213   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
iwrite_pubtype(struct CLIENT_REQUEST * ptr_clrequest,const char * type,unsigned int citstyle_id,dbi_conn conn)214 int iwrite_pubtype(struct CLIENT_REQUEST* ptr_clrequest, const char* type, unsigned int citstyle_id, dbi_conn conn) {
215   char sql_command[512];
216   const char *item;
217   const char *my_type;
218   const char type_intext[] = "INTEXT";
219   unsigned int refstyle_id;
220 
221   dbi_result dbires_ref;
222   dbi_result dbires_pos;
223   Liliform sentinel;
224 
225   sentinel.ptr_next = NULL;
226   sentinel.name[0] = '\0';
227   sentinel.value = NULL;
228 
229   /* start pubtype element */
230   my_type = type;
231 
232   if (!strcmp(type, "INTEXTDEF")) {
233     iwrite_elstart(ptr_clrequest, type, NULL, 0);
234     my_type = type_intext;
235   }
236   else if (!strcmp(type, "AUTHORONLY")
237       || !strcmp(type, "YEARONLY")) {
238     iwrite_elstart(ptr_clrequest, type, NULL, 0);
239   }
240   else {
241     if (insert_liliform(&sentinel, "TYPE", (char*)type)) {
242       LOG_PRINT(LOG_WARNING, get_status_msg(801));
243       return 1;
244     }
245     iwrite_elstart(ptr_clrequest, "PUBTYPE", &sentinel, 0);
246     delete_all_liliform(&sentinel);
247   }
248 
249   sprintf(sql_command, "SELECT * FROM REFSTYLE WHERE PUBTYPE=\'%s\' AND CITSTYLEID=%u", my_type, citstyle_id);
250   dbires_ref = dbi_conn_query(conn, sql_command);
251   LOG_PRINT(LOG_DEBUG, sql_command);
252   if (dbires_ref) {
253     while (dbi_result_next_row(dbires_ref)) { /* should run only once */
254       refstyle_id = my_dbi_result_get_int_idval(dbires_ref, "ID");
255       sprintf(sql_command, "SELECT * FROM POSITIONS WHERE REFSTYLEID=%u ORDER BY POS", refstyle_id);
256       dbires_pos = dbi_conn_query(conn, sql_command);
257       LOG_PRINT(LOG_DEBUG, sql_command);
258       if (dbires_pos) {
259 	/* loop over all positions */
260 	while (dbi_result_next_row(dbires_pos)) {
261 	  item = my_dbi_result_get_string(dbires_pos, "TYPE");
262 
263 	  /* first the simple ones */
264 	  if (!strcmp(item, "ISSUE")
265 	      || !strcmp(item, "PUBLISHER")
266 	      || !strcmp(item, "PUBPLACE")
267 	      || !strcmp(item, "SERIAL")
268 	      || !strcmp(item, "VOLUME")
269 	      || !strcmp(item, "ADDRESS")
270 	      || !strcmp(item, "NOTES")
271 	      || !strcmp(item, "ABSTRACT")
272 	      || !strcmp(item, "TYPEOFWORK")
273 	      || !strcmp(item, "AREA")
274 	      || !strcmp(item, "OSTYPE")
275 	      || !strcmp(item, "DEGREE")
276 	      || !strcmp(item, "RUNNINGTIME")
277 	      || !strcmp(item, "CLASSCODEINTL")
278 	      || !strcmp(item, "CLASSCODEUS")
279 	      || !strcmp(item, "SENDEREMAIL")
280 	      || !strcmp(item, "RECIPIENTEMAIL")
281 	      || !strcmp(item, "MEDIATYPE")
282 	      || !strcmp(item, "NUMVOLUMES")
283 	      || !strcmp(item, "EDITION")
284 	      || !strcmp(item, "COMPUTER")
285 	      || !strcmp(item, "CONFERENCELOCATION")
286 	      || !strcmp(item, "REGISTRYNUM")
287 	      || !strcmp(item, "CLASSIFICATION")
288 	      || !strcmp(item, "SECTION")
289 	      || !strcmp(item, "PAMPHLETNUM")
290 	      || !strcmp(item, "CHAPTERNUM")
291 	      || !strcmp(item, "CITEKEY")
292 	      || !strcmp(item, "REFNUMBER")) {
293 	    iwrite_simple(ptr_clrequest, dbires_ref, item);
294 	  }
295 	  /* now those with attributes */
296 	  else if (!strcmp(item, "AUTHORLIST")) {
297 	    iwrite_authorlist(ptr_clrequest, dbires_ref, "PART");
298 	  }
299 	  else if (!strcmp(item, "EDITORLIST")) {
300 	    iwrite_authorlist(ptr_clrequest, dbires_ref, "PUB");
301 	  }
302 	  else if (!strcmp(item, "SEDITORLIST")) {
303 	    iwrite_authorlist(ptr_clrequest, dbires_ref, "SERIES");
304 	  }
305 	  else if (!strcmp(item, "ALLALIST")) {
306 	    iwrite_authorlist(ptr_clrequest, dbires_ref, "ALL");
307 	  }
308 	  else if (!strcmp(item, "JOURNALNAME")) {
309 	    iwrite_journalname(ptr_clrequest, dbires_ref);
310 	  }
311 	  else if (!strcmp(item, "PAGES")) {
312 	    iwrite_pages(ptr_clrequest, dbires_ref);
313 	  }
314 	  else if (!strcmp(item, "PUBDATE")) {
315 	    iwrite_pubdate(ptr_clrequest, dbires_ref, "PRIMARY");
316 	  }
317 	  else if (!strcmp(item, "PUBDATESEC")) {
318 	    iwrite_pubdate(ptr_clrequest, dbires_ref, "SECONDARY");
319 	  }
320 	  else if (!strcmp(item, "PUBDATEALL")) {
321 	    iwrite_pubdate(ptr_clrequest, dbires_ref, "ALL");
322 	  }
323 	  else if (!strcmp(item, "USERDEF1")
324 		   || !strcmp(item, "USERDEF2")
325 		   || !strcmp(item, "USERDEF3")
326 		   || !strcmp(item, "USERDEF4")
327 		   || !strcmp(item, "USERDEF5")
328 		   || !strcmp(item, "LINK0")
329 		   || !strcmp(item, "LINK1")
330 		   || !strcmp(item, "LINK2")
331 		   || !strcmp(item, "LINK3")
332 		   || !strcmp(item, "LINK4")) {
333 	    iwrite_twoatt(ptr_clrequest, dbires_ref, item);
334 	  }
335 	  else if (!strcmp(item, "SEPARATOR")) {
336 	    iwrite_separator(ptr_clrequest, dbires_ref, my_dbi_result_get_int_idval(dbires_pos, "SEPARATORID"));
337 	  }
338 	  else if (!strcmp(item, "TITLE")) {
339 	    iwrite_title(ptr_clrequest, dbires_ref, "PART");
340 	  }
341 	  else if (!strcmp(item, "BOOKTITLE")) {
342 	    iwrite_title(ptr_clrequest, dbires_ref, "PUB");
343 	  }
344 	  else if (!strcmp(item, "SERIESTITLE")) {
345 	    iwrite_title(ptr_clrequest, dbires_ref, "SERIES");
346 	  }
347 	  else if (!strcmp(item, "ALLTITLE")) {
348 	    iwrite_title(ptr_clrequest, dbires_ref, "ALL");
349 	  }
350 	  /* ToDo: else: something is wrong here */
351 	}
352       }
353     }
354   }
355 
356   /* end pubtype element */
357  if (!strcmp(type, "AUTHORONLY")
358      || !strcmp(type, "YEARONLY")
359      || !strcmp(type, "INTEXTDEF")) {
360     iwrite_elend(ptr_clrequest, type);
361   }
362   else {
363     iwrite_elend(ptr_clrequest, "PUBTYPE");
364   }
365 
366   return 0;
367 }
368 
369 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
370   iwrite_months() writes a months element to a file descriptor.
371 
372   int iwrite_months 0 if fine, 1 if some error occurred
373 
374   struct CLIENT_REQUEST* ptr_clrequest ptr to a structure with client info
375 
376   dbi_result dbires ptr to citstyle query result structure
377 
378   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
iwrite_months(struct CLIENT_REQUEST * ptr_clrequest,dbi_result dbires)379 int iwrite_months(struct CLIENT_REQUEST* ptr_clrequest, dbi_result dbires) {
380   int i;
381   int j;
382   char monthnames[4][12][12] = {
383     {"JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"},
384     {"JANABBREV", "FEBABBREV", "MARABBREV", "APRABBREV", "MAYABBREV", "JUNABBREV", "JULABBREV", "AUGABBREV", "SEPABBREV", "OCTABBREV", "NOVABBREV", "DECABBREV"},
385     {"JANFULL", "FEBFULL", "MARFULL", "APRFULL", "MAYFULL", "JUNFULL", "JULFULL", "AUGFULL", "SEPFULL", "OCTFULL", "NOVFULL", "DECFULL"},
386     {"JANTHREELET", "FEBTHREELET", "MARTHREELET", "APRTHREELET", "MAYTHREELET", "JUNTHREELET", "JULTHREELET", "AUGTHREELET", "SEPTHREELET", "OCTTHREELET", "NOVTHREELET", "DECTHREELET"}
387   };
388   Liliform sentinel;
389 
390   sentinel.ptr_next = NULL;
391   sentinel.name[0] = '\0';
392   sentinel.value = NULL;
393 
394   /* start months block */
395   iwrite_elstart(ptr_clrequest, "MONTHS", NULL, 0);
396 
397   /* loop over all months */
398   for (i = 0; i < 12; i++) {
399     /* fill linked list with attributes abbrev, full, threelet */
400     for (j = 1; j < 4; j++) {
401       if (insert_liliform(&sentinel, monthnames[j][i]+3, (char*)my_dbi_result_get_string(dbires, monthnames[j][i]))) {
402 	LOG_PRINT(LOG_WARNING, get_status_msg(801));
403 	delete_all_liliform(&sentinel);
404 	return 1;
405       }
406     }
407     iwrite_elstart(ptr_clrequest, monthnames[0][i], &sentinel, 1);
408     delete_all_liliform(&sentinel);
409   }
410 
411   iwrite_elend(ptr_clrequest, "MONTHS");
412 
413   return 0;
414 }
415 
416 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
417   iwrite_authorlist() writes an authorlist element to a file descriptor.
418 
419   static int iwrite_authorlist 0 if fine, 1 if some error occurred
420 
421   struct CLIENT_REQUEST* ptr_clrequest ptr to a structure with client info
422 
423   dbi_result dbires_ref ptr to citstyle query result structure
424 
425   const char* role ptr to string with the authorlist role
426 
427   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
iwrite_authorlist(struct CLIENT_REQUEST * ptr_clrequest,dbi_result dbires_ref,const char * role)428 static int iwrite_authorlist(struct CLIENT_REQUEST* ptr_clrequest, dbi_result dbires_ref, const char* role) {
429   char *abbreviatefirst;
430   char *abbreviatefirstmaxauthor;
431   char *abbreviatefirstdisplayauthor;
432   char *abbreviatefirststyle;
433   char *abbreviatesubseq;
434   char *abbreviatesubseqmaxauthor;
435   char *abbreviatesubseqdisplayauthor;
436   char *abbreviatesubseqstyle;
437 
438   char authorfields[4][15][31] = {
439     {"QSTYLE", "QALTERNATESTYLE", "QALTERNATETEXT", "QABBREVIATEFIRST", "QABBREVIATEFIRSTMAXAUTHOR", "QABBREVIATEFIRSTDISPLAYAUTHOR", "QABBREVIATEFIRSTSTYLE", "QABBREVIATESUBSEQ", "QABBREVIATESUBSEQMAXAUTHOR", "QABBREVIATESUBSEQDISPLAYAUTHOR", "QABBREVIATESUBSEQSTYLE", "QAEMPTY", "QASAME", "QPRECEEDING", "QFOLLOWING"},
440     {"XSTYLE", "XALTERNATESTYLE", "XALTERNATETEXT", "XABBREVIATEFIRST", "XABBREVIATEFIRSTMAXAUTHOR", "XABBREVIATEFIRSTDISPLAYAUTHOR", "XABBREVIATEFIRSTSTYLE", "XABBREVIATESUBSEQ", "XABBREVIATESUBSEQMAXAUTHOR", "XABBREVIATESUBSEQDISPLAYAUTHOR", "XABBREVIATESUBSEQSTYLE", "XAEMPTY", "XASAME", "XPRECEEDING", "XFOLLOWING"},
441     {"YSTYLE", "YALTERNATESTYLE", "YALTERNATETEXT", "YABBREVIATEFIRST", "YABBREVIATEFIRSTMAXAUTHOR", "YABBREVIATEFIRSTDISPLAYAUTHOR", "YABBREVIATEFIRSTSTYLE", "YABBREVIATESUBSEQ", "YABBREVIATESUBSEQMAXAUTHOR", "YABBREVIATESUBSEQDISPLAYAUTHOR", "YABBREVIATESUBSEQSTYLE", "YAEMPTY", "YASAME", "YPRECEEDING", "YFOLLOWING"},
442     {"ZSTYLE", "ZALTERNATESTYLE", "ZALTERNATETEXT", "ZABBREVIATEFIRST", "ZABBREVIATEFIRSTMAXAUTHOR", "ZABBREVIATEFIRSTDISPLAYAUTHOR", "ZABBREVIATEFIRSTSTYLE", "ZABBREVIATESUBSEQ", "ZABBREVIATESUBSEQMAXAUTHOR", "ZABBREVIATESUBSEQDISPLAYAUTHOR", "ZABBREVIATESUBSEQSTYLE", "ZAEMPTY", "ZASAME", "ZPRECEEDING", "ZFOLLOWING"}
443   };
444 
445   int n_role = 0;
446   Liliform sentinel;
447 
448   sentinel.ptr_next = NULL;
449   sentinel.name[0] = '\0';
450   sentinel.value = NULL;
451 
452   if (!strcmp(role, "PRIMARY")) {
453     n_role = 0;
454   }
455   else if (!strcmp(role, "SECONDARY")) {
456     n_role = 1;
457   }
458   else if (!strcmp(role, "TERTIARY")) {
459     n_role = 2;
460   }
461   else if (!strcmp(role, "ALL")) {
462     n_role = 3;
463   }
464 
465   /* get required strings */
466   abbreviatefirst = (char*)my_dbi_result_get_string(dbires_ref, authorfields[n_role][3]);
467   abbreviatefirstmaxauthor = (char*)my_dbi_result_get_string(dbires_ref, authorfields[n_role][4]);
468   abbreviatefirstdisplayauthor = (char*)my_dbi_result_get_string(dbires_ref, authorfields[n_role][5]);
469   abbreviatefirststyle = (char*)my_dbi_result_get_string(dbires_ref, authorfields[n_role][6]);
470   abbreviatesubseq = (char*)my_dbi_result_get_string(dbires_ref, authorfields[n_role][7]);
471   abbreviatesubseqmaxauthor = (char*)my_dbi_result_get_string(dbires_ref, authorfields[n_role][8]);
472   abbreviatesubseqdisplayauthor = (char*)my_dbi_result_get_string(dbires_ref, authorfields[n_role][9]);
473   abbreviatesubseqstyle = (char*)my_dbi_result_get_string(dbires_ref, authorfields[n_role][10]);
474 
475   /* begin authorlist block */
476   if (insert_liliform(&sentinel, "STYLE", (char*)my_dbi_result_get_string(dbires_ref, authorfields[n_role][0]))) {
477     LOG_PRINT(LOG_WARNING, get_status_msg(801));
478     return 1;
479   }
480 
481   if (insert_liliform(&sentinel, "ALTERNATESTYLE", (char*)my_dbi_result_get_string(dbires_ref, authorfields[n_role][1]))) {
482     LOG_PRINT(LOG_WARNING, get_status_msg(801));
483     return 1;
484   }
485 
486   if (insert_liliform(&sentinel, "ALTERNATETEXT", (char*)my_dbi_result_get_string(dbires_ref, authorfields[n_role][2]))) {
487     LOG_PRINT(LOG_WARNING, get_status_msg(801));
488     return 1;
489   }
490 
491   if (insert_liliform(&sentinel, "ROLE", (char*)role)) {
492     LOG_PRINT(LOG_WARNING, get_status_msg(801));
493     return 1;
494   }
495 
496   iwrite_elstart(ptr_clrequest, "AUTHORLIST", &sentinel, 0);
497 
498   delete_all_liliform(&sentinel);
499 
500   /* preceeding */
501   iwrite_element(ptr_clrequest, "PRECEEDING", NULL, my_dbi_result_get_string(dbires_ref, authorfields[n_role][13]));
502 
503   /* following */
504   iwrite_element(ptr_clrequest, "FOLLOWING", NULL, my_dbi_result_get_string(dbires_ref, authorfields[n_role][14]));
505 
506   if ((abbreviatefirst && *abbreviatefirst)
507       || (abbreviatefirstmaxauthor && *abbreviatefirstmaxauthor)
508       || (abbreviatefirstdisplayauthor && *abbreviatefirstdisplayauthor)
509       || (abbreviatefirststyle && *abbreviatefirststyle)) {
510     /* start abbreviatefirst block */
511     if (insert_liliform(&sentinel, "MAXAUTHOR", abbreviatefirstmaxauthor)) {
512       LOG_PRINT(LOG_WARNING, get_status_msg(801));
513       return 1;
514     }
515 
516     if (insert_liliform(&sentinel, "DISPLAYAUTHOR", abbreviatefirstdisplayauthor)) {
517       LOG_PRINT(LOG_WARNING, get_status_msg(801));
518       return 1;
519     }
520 
521     if (insert_liliform(&sentinel, "STYLE", abbreviatefirststyle)) {
522       LOG_PRINT(LOG_WARNING, get_status_msg(801));
523       return 1;
524     }
525 
526     iwrite_elstart(ptr_clrequest, "ABBREVIATEFIRST", &sentinel, 0);
527 
528     delete_all_liliform(&sentinel);
529 
530     tiwrite(ptr_clrequest->fd, abbreviatefirst, TERM_NO);
531 
532     /* end abbreviatefirst block */
533     iwrite_elend(ptr_clrequest, "ABBREVIATEFIRST");
534   }
535 
536   if ((abbreviatesubseq && *abbreviatesubseq)
537       || (abbreviatesubseqmaxauthor && *abbreviatesubseqmaxauthor)
538       || (abbreviatesubseqdisplayauthor && *abbreviatesubseqdisplayauthor)
539       || (abbreviatesubseqstyle && *abbreviatesubseqstyle)) {
540     /* start abbreviatesubseq block */
541     if (insert_liliform(&sentinel, "MAXAUTHOR", abbreviatesubseqmaxauthor)) {
542       LOG_PRINT(LOG_WARNING, get_status_msg(801));
543       return 1;
544     }
545 
546     if (insert_liliform(&sentinel, "DISPLAYAUTHOR", abbreviatesubseqdisplayauthor)) {
547       LOG_PRINT(LOG_WARNING, get_status_msg(801));
548       return 1;
549     }
550 
551     if (insert_liliform(&sentinel, "STYLE", abbreviatesubseqstyle)) {
552       LOG_PRINT(LOG_WARNING, get_status_msg(801));
553       return 1;
554     }
555 
556     iwrite_elstart(ptr_clrequest, "ABBREVIATESUBSEQ", &sentinel, 0);
557 
558     delete_all_liliform(&sentinel);
559 
560     tiwrite(ptr_clrequest->fd, abbreviatesubseq, TERM_NO);
561 
562     /* end abbreviatesubseq block */
563     iwrite_elend(ptr_clrequest, "ABBREVIATESUBSEQ");
564   }
565 
566   /* aempty */
567   iwrite_element(ptr_clrequest, "AEMPTY", NULL, my_dbi_result_get_string(dbires_ref, authorfields[n_role][11]));
568 
569   /* asame */
570   iwrite_element(ptr_clrequest, "ASAME", NULL, my_dbi_result_get_string(dbires_ref, authorfields[n_role][12]));
571 
572   /* authornames, authorseps, text elements */
573   iwrite_authorseps(ptr_clrequest, dbires_ref, role);
574   iwrite_authornames(ptr_clrequest, dbires_ref, role);
575   iwrite_authortext(ptr_clrequest, dbires_ref, role);
576 
577   /* end authorlist block */
578   iwrite_elend(ptr_clrequest, "AUTHORLIST");
579 
580   return 0;
581 }
582 
583 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
584   iwrite_authornames() writes an authornames element to a file descriptor.
585 
586   static int iwrite_authornames 0 if fine, 1 if some error occurred
587 
588   struct CLIENT_REQUEST* ptr_clrequest ptr to a structure with client info
589 
590   dbi_result dbires_ref ptr to citstyle query result structure
591 
592   const char* role ptr to string with the authorlist role
593 
594   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
iwrite_authornames(struct CLIENT_REQUEST * ptr_clrequest,dbi_result dbires_ref,const char * role)595 static int iwrite_authornames(struct CLIENT_REQUEST* ptr_clrequest, dbi_result dbires_ref, const char* role) {
596   char *namefirstnameorder;
597   char *namefirstinitialstyle;
598   char *namefirstuppercase;
599   char *nameothernameorder;
600   char *nameotherinitialstyle;
601   char *nameotheruppercase;
602 
603   char authorfields[4][6][34] = {
604     {"QAUTHORNAMESNAMEFIRSTNAMEORDER", "QAUTHORNAMESNAMEFIRSTINITIALSTYLE", "QAUTHORNAMESNAMEFIRSTUPPERCASE", "QAUTHORNAMESNAMEOTHERNAMEORDER", "QAUTHORNAMESNAMEOTHERINITIALSTYLE", "QAUTHORNAMESNAMEOTHERUPPERCASE"},
605     {"XAUTHORNAMESNAMEFIRSTNAMEORDER", "XAUTHORNAMESNAMEFIRSTINITIALSTYLE", "XAUTHORNAMESNAMEFIRSTUPPERCASE", "XAUTHORNAMESNAMEOTHERNAMEORDER", "XAUTHORNAMESNAMEOTHERINITIALSTYLE", "XAUTHORNAMESNAMEOTHERUPPERCASE"},
606     {"YAUTHORNAMESNAMEFIRSTNAMEORDER", "YAUTHORNAMESNAMEFIRSTINITIALSTYLE", "YAUTHORNAMESNAMEFIRSTUPPERCASE", "YAUTHORNAMESNAMEOTHERNAMEORDER", "YAUTHORNAMESNAMEOTHERINITIALSTYLE", "YAUTHORNAMESNAMEOTHERUPPERCASE"},
607     {"ZAUTHORNAMESNAMEFIRSTNAMEORDER", "ZAUTHORNAMESNAMEFIRSTINITIALSTYLE", "ZAUTHORNAMESNAMEFIRSTUPPERCASE", "ZAUTHORNAMESNAMEOTHERNAMEORDER", "ZAUTHORNAMESNAMEOTHERINITIALSTYLE", "ZAUTHORNAMESNAMEOTHERUPPERCASE"}
608   };
609 
610   int n_role = 0;
611   Liliform sentinel;
612 
613   sentinel.ptr_next = NULL;
614   sentinel.name[0] = '\0';
615   sentinel.value = NULL;
616 
617   if (!strcmp(role, "PRIMARY")) {
618     n_role = 0;
619   }
620   else if (!strcmp(role, "SECONDARY")) {
621     n_role = 1;
622   }
623   else if (!strcmp(role, "TERTIARY")) {
624     n_role = 2;
625   }
626   else if (!strcmp(role, "ALL")) {
627     n_role = 3;
628   }
629 
630   /* get required strings */
631   namefirstnameorder = (char*)my_dbi_result_get_string(dbires_ref, authorfields[n_role][0]);
632   namefirstinitialstyle = (char*)my_dbi_result_get_string(dbires_ref, authorfields[n_role][1]);
633   namefirstuppercase = (char*)my_dbi_result_get_string(dbires_ref, authorfields[n_role][2]);
634   nameothernameorder = (char*)my_dbi_result_get_string(dbires_ref, authorfields[n_role][3]);
635   nameotherinitialstyle = (char*)my_dbi_result_get_string(dbires_ref, authorfields[n_role][4]);
636   nameotheruppercase = (char*)my_dbi_result_get_string(dbires_ref, authorfields[n_role][5]);
637 
638   if ((namefirstnameorder && *namefirstnameorder)
639       || (namefirstinitialstyle && *namefirstinitialstyle)
640       || (namefirstuppercase && *namefirstuppercase)
641       || (nameothernameorder && *nameothernameorder)
642       || (nameotherinitialstyle && *nameotherinitialstyle)
643       || (nameotheruppercase && *nameotheruppercase)) {
644     /* begin authornames block */
645     iwrite_elstart(ptr_clrequest, "AUTHORNAMES", &sentinel, 0);
646 
647     if ((namefirstnameorder && *namefirstnameorder)
648 	|| (namefirstinitialstyle && *namefirstinitialstyle)
649 	|| (namefirstuppercase && *namefirstuppercase)) {
650       /* start namefirst block */
651       if (insert_liliform(&sentinel, "NAMEORDER", namefirstnameorder)) {
652 	LOG_PRINT(LOG_WARNING, get_status_msg(801));
653 	return 1;
654       }
655 
656       if (insert_liliform(&sentinel, "INITIALSTYLE", namefirstinitialstyle)) {
657 	LOG_PRINT(LOG_WARNING, get_status_msg(801));
658 	return 1;
659       }
660 
661       if (insert_liliform(&sentinel, "UPPERCASE", namefirstuppercase)) {
662 	LOG_PRINT(LOG_WARNING, get_status_msg(801));
663 	return 1;
664       }
665 
666       iwrite_elstart(ptr_clrequest, "NAMEFIRST", &sentinel, 1);
667 
668       delete_all_liliform(&sentinel);
669     }
670 
671     if ((nameothernameorder && *nameothernameorder)
672 	|| (nameotherinitialstyle && *nameotherinitialstyle)
673 	|| (nameotheruppercase && *nameotheruppercase)) {
674       /* start nameother block */
675       if (insert_liliform(&sentinel, "NAMEORDER", nameothernameorder)) {
676 	LOG_PRINT(LOG_WARNING, get_status_msg(801));
677 	return 1;
678       }
679 
680       if (insert_liliform(&sentinel, "INITIALSTYLE", nameotherinitialstyle)) {
681 	LOG_PRINT(LOG_WARNING, get_status_msg(801));
682 	return 1;
683       }
684 
685       if (insert_liliform(&sentinel, "UPPERCASE", nameotheruppercase)) {
686 	LOG_PRINT(LOG_WARNING, get_status_msg(801));
687 	return 1;
688       }
689 
690       iwrite_elstart(ptr_clrequest, "NAMEOTHER", &sentinel, 1);
691 
692       delete_all_liliform(&sentinel);
693     }
694 
695     /* end authorlist block */
696     iwrite_elend(ptr_clrequest, "AUTHORNAMES");
697   }
698 
699   return 0;
700 }
701 
702 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
703   iwrite_authorseps() writes an authorseps element to a file descriptor.
704 
705   static int iwrite_authorseps 0 if fine, 1 if some error occurred
706 
707   struct CLIENT_REQUEST* ptr_clrequest ptr to a structure with client info
708 
709   dbi_result dbires_ref ptr to citstyle query result structure
710 
711   const char* role ptr to string with the authorlist role
712 
713   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
iwrite_authorseps(struct CLIENT_REQUEST * ptr_clrequest,dbi_result dbires_ref,const char * role)714 static int iwrite_authorseps(struct CLIENT_REQUEST* ptr_clrequest, dbi_result dbires_ref, const char* role) {
715   char *twoseps;
716   char *threesepseach;
717   char *threesepslast;
718 
719   char authorfields[4][3][34] = {
720     {"QAUTHORSEPSTWOSEPS", "QAUTHORSEPSTHREESEPSTHREESEPSEACH", "QAUTHORSEPSTHREESEPSTHREESEPSLAST"},
721     {"XAUTHORSEPSTWOSEPS", "XAUTHORSEPSTHREESEPSTHREESEPSEACH", "XAUTHORSEPSTHREESEPSTHREESEPSLAST"},
722     {"YAUTHORSEPSTWOSEPS", "YAUTHORSEPSTHREESEPSTHREESEPSEACH", "YAUTHORSEPSTHREESEPSTHREESEPSLAST"},
723     {"ZAUTHORSEPSTWOSEPS", "ZAUTHORSEPSTHREESEPSTHREESEPSEACH", "ZAUTHORSEPSTHREESEPSTHREESEPSLAST"}
724   };
725 
726   int n_role = 0;
727   Liliform sentinel;
728 
729   sentinel.ptr_next = NULL;
730   sentinel.name[0] = '\0';
731   sentinel.value = NULL;
732 
733   if (!strcmp(role, "PRIMARY")) {
734     n_role = 0;
735   }
736   else if (!strcmp(role, "SECONDARY")) {
737     n_role = 1;
738   }
739   else if (!strcmp(role, "TERTIARY")) {
740     n_role = 2;
741   }
742   else if (!strcmp(role, "ALL")) {
743     n_role = 3;
744   }
745 
746   /* get required strings */
747   twoseps = (char*)my_dbi_result_get_string(dbires_ref, authorfields[n_role][0]);
748   threesepseach = (char*)my_dbi_result_get_string(dbires_ref, authorfields[n_role][1]);
749   threesepslast = (char*)my_dbi_result_get_string(dbires_ref, authorfields[n_role][2]);
750 
751   if ((twoseps && *twoseps)
752       || (threesepseach && *threesepseach)
753       || (threesepslast && *threesepslast)) {
754     /* begin authorseps block */
755     iwrite_elstart(ptr_clrequest, "AUTHORSEPS", &sentinel, 0);
756 
757     iwrite_element(ptr_clrequest, "TWOSEPS", NULL, twoseps);
758 
759     if ((threesepseach && *threesepseach)
760       || (threesepslast && *threesepslast)) {
761       /* start threeseps block */
762       iwrite_elstart(ptr_clrequest, "THREESEPS", &sentinel, 0);
763 
764       iwrite_element(ptr_clrequest, "THREESEPSEACH", NULL, threesepseach);
765       iwrite_element(ptr_clrequest, "THREESEPSLAST", NULL, threesepslast);
766       iwrite_elend(ptr_clrequest, "THREESEPS");
767     }
768 
769     /* end authorseps block */
770     iwrite_elend(ptr_clrequest, "AUTHORSEPS");
771   }
772 
773   return 0;
774 }
775 
776 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
777   iwrite_authortext() writes an authortext element to a file descriptor.
778 
779   static int iwrite_authortext 0 if fine, 1 if some error occurred
780 
781   struct CLIENT_REQUEST* ptr_clrequest ptr to a structure with client info
782 
783   dbi_result dbires_ref ptr to citstyle query result structure
784 
785   const char* role ptr to string with the authorlist role
786 
787   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
iwrite_authortext(struct CLIENT_REQUEST * ptr_clrequest,dbi_result dbires_ref,const char * role)788 static int iwrite_authortext(struct CLIENT_REQUEST* ptr_clrequest, dbi_result dbires_ref, const char* role) {
789   char *singlepreceeding;
790   char *singlefollowing;
791   char *multiplepreceeding;
792   char *multiplefollowing;
793 
794   char authorfields[4][4][34] = {
795     {"QTEXTTEXTSINGLEPRECEEDING", "QTEXTTEXTSINGLEFOLLOWING", "QTEXTTEXTMULTIPLEPRECEEDING", "QTEXTTEXTMULTIPLEFOLLOWING"},
796     {"XTEXTTEXTSINGLEPRECEEDING", "XTEXTTEXTSINGLEFOLLOWING", "XTEXTTEXTMULTIPLEPRECEEDING", "XTEXTTEXTMULTIPLEFOLLOWING"},
797     {"YTEXTTEXTSINGLEPRECEEDING", "YTEXTTEXTSINGLEFOLLOWING", "YTEXTTEXTMULTIPLEPRECEEDING", "YTEXTTEXTMULTIPLEFOLLOWING"},
798     {"ZTEXTTEXTSINGLEPRECEEDING", "ZTEXTTEXTSINGLEFOLLOWING", "ZTEXTTEXTMULTIPLEPRECEEDING", "ZTEXTTEXTMULTIPLEFOLLOWING"}
799   };
800 
801   int n_role = 0;
802   Liliform sentinel;
803 
804   sentinel.ptr_next = NULL;
805   sentinel.name[0] = '\0';
806   sentinel.value = NULL;
807 
808   if (!strcmp(role, "PRIMARY")) {
809     n_role = 0;
810   }
811   else if (!strcmp(role, "SECONDARY")) {
812     n_role = 1;
813   }
814   else if (!strcmp(role, "TERTIARY")) {
815     n_role = 2;
816   }
817   else if (!strcmp(role, "ALL")) {
818     n_role = 3;
819   }
820 
821   /* get required strings */
822   singlepreceeding = (char*)my_dbi_result_get_string(dbires_ref, authorfields[n_role][0]);
823   singlefollowing = (char*)my_dbi_result_get_string(dbires_ref, authorfields[n_role][1]);
824   multiplepreceeding = (char*)my_dbi_result_get_string(dbires_ref, authorfields[n_role][2]);
825   multiplefollowing = (char*)my_dbi_result_get_string(dbires_ref, authorfields[n_role][3]);
826 
827   if ((singlepreceeding && *singlepreceeding)
828       || (singlefollowing && *singlefollowing)
829       || (multiplepreceeding && *multiplepreceeding)
830       || (multiplefollowing && *multiplefollowing)) {
831     /* begin text block */
832     iwrite_elstart(ptr_clrequest, "TEXT", &sentinel, 0);
833 
834     if ((singlepreceeding && *singlepreceeding)
835       || (singlefollowing && *singlefollowing)) {
836       /* start textsingle block */
837       iwrite_elstart(ptr_clrequest, "TEXTSINGLE", &sentinel, 0);
838 
839       iwrite_element(ptr_clrequest, "PRECEEDING", NULL, singlepreceeding);
840       iwrite_element(ptr_clrequest, "FOLLOWING", NULL, singlefollowing);
841       iwrite_elend(ptr_clrequest, "TEXTSINGLE");
842     }
843 
844     if ((multiplepreceeding && *multiplepreceeding)
845       || (multiplefollowing && *multiplefollowing)) {
846       /* start textmultiple block */
847       iwrite_elstart(ptr_clrequest, "TEXTMULTIPLE", &sentinel, 0);
848 
849       iwrite_element(ptr_clrequest, "PRECEEDING", NULL, multiplepreceeding);
850       iwrite_element(ptr_clrequest, "FOLLOWING", NULL, multiplefollowing);
851       iwrite_elend(ptr_clrequest, "TEXTMULTIPLE");
852     }
853 
854     /* end authorseps block */
855     iwrite_elend(ptr_clrequest, "TEXT");
856   }
857 
858   return 0;
859 }
860 
861 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
862   iwrite_journalname() writes a journalname element to a file descriptor.
863 
864   static int iwrite_journalname 0 if fine, 1 if some error occurred
865 
866   struct CLIENT_REQUEST* ptr_clrequest ptr to a structure with client info
867 
868   dbi_result dbires_ref ptr to citstyle query result structure
869 
870   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
iwrite_journalname(struct CLIENT_REQUEST * ptr_clrequest,dbi_result dbires_ref)871 static int iwrite_journalname(struct CLIENT_REQUEST* ptr_clrequest, dbi_result dbires_ref) {
872   Liliform sentinel;
873 
874   sentinel.ptr_next = NULL;
875   sentinel.name[0] = '\0';
876   sentinel.value = NULL;
877 
878   if (insert_liliform(&sentinel, "STYLE", (char*)my_dbi_result_get_string(dbires_ref, "JOURNALNAMESTYLE"))) {
879     LOG_PRINT(LOG_WARNING, get_status_msg(801));
880     return 1;
881   }
882 
883   if (insert_liliform(&sentinel, "PUNCTUATION", (char*)my_dbi_result_get_string(dbires_ref, "JOURNALNAMEPUNCTUATION"))) {
884     LOG_PRINT(LOG_WARNING, get_status_msg(801));
885     return 1;
886   }
887 
888   if (insert_liliform(&sentinel, "DEFAULTTEXT", (char*)my_dbi_result_get_string(dbires_ref, "JOURNALNAMEDEFAULTTEXT"))) {
889     LOG_PRINT(LOG_WARNING, get_status_msg(801));
890     return 1;
891   }
892 
893   if (insert_liliform(&sentinel, "CASE", (char*)my_dbi_result_get_string(dbires_ref, "JOURNALNAMECASE"))) {
894     LOG_PRINT(LOG_WARNING, get_status_msg(801));
895     return 1;
896   }
897 
898   if (insert_liliform(&sentinel, "ALTERNATETEXT", (char*)my_dbi_result_get_string(dbires_ref, "JOURNALNAMEALTERNATETEXT"))) {
899     LOG_PRINT(LOG_WARNING, get_status_msg(801));
900     return 1;
901   }
902 
903   iwrite_elstart(ptr_clrequest, "JOURNALNAME", &sentinel, 0);
904 
905   delete_all_liliform(&sentinel);
906 
907   /* preceeding */
908   iwrite_element(ptr_clrequest, "PRECEEDING", NULL, my_dbi_result_get_string(dbires_ref, "JOURNALNAMEPRECEEDING"));
909 
910   /* following */
911   iwrite_element(ptr_clrequest, "FOLLOWING", NULL, my_dbi_result_get_string(dbires_ref, "JOURNALNAMEFOLLOWING"));
912 
913   iwrite_elend(ptr_clrequest, "JOURNALNAME");
914 
915   return 0;
916 }
917 
918 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
919   iwrite_pages() writes a pages element to a file descriptor.
920 
921   static int iwrite_pages 0 if fine, 1 if some error occurred
922 
923   struct CLIENT_REQUEST* ptr_clrequest ptr to a structure with client info
924 
925   dbi_result dbires_ref ptr to citstyle query result structure
926 
927   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
iwrite_pages(struct CLIENT_REQUEST * ptr_clrequest,dbi_result dbires_ref)928 static int iwrite_pages(struct CLIENT_REQUEST* ptr_clrequest, dbi_result dbires_ref) {
929   char *pagespagerangetype;
930   char *pagespagerangepreceeding;
931   char *pagespagerangefollowing;
932   char *pagespagerangerangeseparator;
933   char *pagessinglepagepreceeding;
934   char *pagessinglepagefollowing;
935   Liliform sentinel;
936 
937   sentinel.ptr_next = NULL;
938   sentinel.name[0] = '\0';
939   sentinel.value = NULL;
940 
941   /* get required values */
942   pagespagerangetype = (char*)my_dbi_result_get_string(dbires_ref, "PAGESPAGERANGETYPE");
943   pagespagerangepreceeding =(char*) my_dbi_result_get_string(dbires_ref, "PAGESPAGERANGEPRECEEDING");
944   pagespagerangefollowing = (char*)my_dbi_result_get_string(dbires_ref, "PAGESPAGERANGEFOLLOWING");
945   pagespagerangerangeseparator = (char*)my_dbi_result_get_string(dbires_ref, "PAGESPAGERANGERANGESEPARATOR");
946   pagessinglepagepreceeding = (char*)my_dbi_result_get_string(dbires_ref, "PAGESSINGLEPAGEPRECEEDING");
947   pagessinglepagefollowing = (char*)my_dbi_result_get_string(dbires_ref, "PAGESSINGLEPAGEFOLLOWING");
948 
949   if (insert_liliform(&sentinel, "STYLE", (char*)my_dbi_result_get_string(dbires_ref, "PAGESSTYLE"))) {
950     LOG_PRINT(LOG_WARNING, get_status_msg(801));
951     return 1;
952   }
953 
954   iwrite_elstart(ptr_clrequest, "PAGES", &sentinel, 0);
955 
956   delete_all_liliform(&sentinel);
957 
958   /* preceeding */
959   iwrite_element(ptr_clrequest, "PRECEEDING", NULL, my_dbi_result_get_string(dbires_ref, "PAGESPRECEEDING"));
960 
961   /* following */
962   iwrite_element(ptr_clrequest, "FOLLOWING", NULL, my_dbi_result_get_string(dbires_ref, "PAGESFOLLOWING"));
963 
964   if ((pagessinglepagepreceeding && *pagessinglepagepreceeding)
965       || (pagessinglepagefollowing && *pagessinglepagefollowing)) {
966     /* start singlepage block */
967     iwrite_elstart(ptr_clrequest, "SINGLEPAGE", NULL, 0);
968 
969     /* preceeding */
970     iwrite_element(ptr_clrequest, "PRECEEDING", NULL, pagessinglepagepreceeding);
971 
972     /* following */
973     iwrite_element(ptr_clrequest, "FOLLOWING", NULL, pagessinglepagefollowing);
974 
975     /* end singlepage block */
976     iwrite_elend(ptr_clrequest, "SINGLEPAGE");
977   }
978 
979   if ((pagespagerangetype && *pagespagerangetype)
980       || (pagespagerangepreceeding && *pagespagerangepreceeding)
981       || (pagespagerangefollowing && *pagespagerangefollowing)
982       || (pagespagerangerangeseparator && *pagespagerangerangeseparator)) {
983     /* start pagerange block */
984     if (insert_liliform(&sentinel, "TYPE", pagespagerangetype)) {
985       LOG_PRINT(LOG_WARNING, get_status_msg(801));
986       return 1;
987     }
988     iwrite_elstart(ptr_clrequest, "PAGERANGE", &sentinel, 0);
989 
990     delete_all_liliform(&sentinel);
991 
992     /* preceeding */
993     iwrite_element(ptr_clrequest, "PRECEEDING", NULL, pagespagerangepreceeding);
994     /* rangesep */
995     iwrite_element(ptr_clrequest, "RANGESEPARATOR", NULL, pagespagerangerangeseparator);
996 
997     /* following */
998     iwrite_element(ptr_clrequest, "FOLLOWING", NULL, pagespagerangefollowing);
999 
1000     /* end pagerange block */
1001     iwrite_elend(ptr_clrequest, "PAGERANGE");
1002   }
1003 
1004   iwrite_elend(ptr_clrequest, "PAGES");
1005 
1006   return 0;
1007 }
1008 
1009 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1010   iwrite_pubdate() writes a pubdate element to a file descriptor.
1011 
1012   static int iwrite_pubdate 0 if fine, 1 if some error occurred
1013 
1014   struct CLIENT_REQUEST* ptr_clrequest ptr to a structure with client info
1015 
1016   dbi_result dbires_ref ptr to citstyle query result structure
1017 
1018   const char* role ptr to string with the authorlist role
1019 
1020   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
iwrite_pubdate(struct CLIENT_REQUEST * ptr_clrequest,dbi_result dbires_ref,const char * role)1021 static int iwrite_pubdate(struct CLIENT_REQUEST* ptr_clrequest, dbi_result dbires_ref, const char* role) {
1022   char pubdatefields[3][11][25] = {
1023     {"PUBDATEYEARFORMAT", "PUBDATEMONTHFORMAT", "PUBDATEFORMAT", "PUBDATESTYLE", "PUBDATEPADLEADINGZERO", "PUBDATEDAYFORMAT", "PUBDATESEQUENCE", "PUBDATEPRECEEDING", "PUBDATEFOLLOWING", "PUBDATEFIRSTSEP", "PUBDATESECONDSEP"},
1024     {"PUBDATESECYEARFORMAT", "PUBDATESECMONTHFORMAT", "PUBDATESECFORMAT", "PUBDATESECSTYLE", "PUBDATESECPADLEADINGZERO", "PUBDATESECDAYFORMAT", "PUBDATESECSEQUENCE", "PUBDATESECPRECEEDING", "PUBDATESECFOLLOWING", "PUBDATESECFIRSTSEP", "PUBDATESECSECONDSEP"},
1025     {"PUBDATEALLYEARFORMAT", "PUBDATEALLMONTHFORMAT", "PUBDATEALLFORMAT", "PUBDATEALLSTYLE", "PUBDATEALLPADLEADINGZERO", "PUBDATEALLDAYFORMAT", "PUBDATEALLSEQUENCE", "PUBDATEALLPRECEEDING", "PUBDATEALLFOLLOWING", "PUBDATEALLFIRSTSEP", "PUBDATEALLSECONDSEP"}
1026   };
1027 
1028   int n_role = 0;
1029 
1030   Liliform sentinel;
1031 
1032   sentinel.ptr_next = NULL;
1033   sentinel.name[0] = '\0';
1034   sentinel.value = NULL;
1035 
1036   if (!strcmp(role, "PRIMARY")) {
1037     n_role = 0;
1038   }
1039   else if (!strcmp(role, "SECONDARY")) {
1040     n_role = 1;
1041   }
1042   else if (!strcmp(role, "ALL")) {
1043     n_role = 2;
1044   }
1045 
1046   if (insert_liliform(&sentinel, "YEARFORMAT", (char*)my_dbi_result_get_string(dbires_ref, pubdatefields[n_role][0]))) {
1047     LOG_PRINT(LOG_WARNING, get_status_msg(801));
1048     return 1;
1049   }
1050 
1051   if (insert_liliform(&sentinel, "MONTHFORMAT", (char*)my_dbi_result_get_string(dbires_ref, pubdatefields[n_role][1]))) {
1052     LOG_PRINT(LOG_WARNING, get_status_msg(801));
1053     return 1;
1054   }
1055 
1056   if (insert_liliform(&sentinel, "FORMAT", (char*)my_dbi_result_get_string(dbires_ref, pubdatefields[n_role][2]))) {
1057     LOG_PRINT(LOG_WARNING, get_status_msg(801));
1058     return 1;
1059   }
1060 
1061   if (insert_liliform(&sentinel, "STYLE", (char*)my_dbi_result_get_string(dbires_ref, pubdatefields[n_role][3]))) {
1062     LOG_PRINT(LOG_WARNING, get_status_msg(801));
1063     return 1;
1064   }
1065 
1066   if (insert_liliform(&sentinel, "ROLE", (char*)role)) {
1067     LOG_PRINT(LOG_WARNING, get_status_msg(801));
1068     return 1;
1069   }
1070 
1071   if (insert_liliform(&sentinel, "PADLEADINGZERO", (char*)my_dbi_result_get_string(dbires_ref, pubdatefields[n_role][4]))) {
1072     LOG_PRINT(LOG_WARNING, get_status_msg(801));
1073     return 1;
1074   }
1075 
1076   if (insert_liliform(&sentinel, "DAYFORMAT", (char*)my_dbi_result_get_string(dbires_ref, pubdatefields[n_role][5]))) {
1077     LOG_PRINT(LOG_WARNING, get_status_msg(801));
1078     return 1;
1079   }
1080 
1081   if (insert_liliform(&sentinel, "SEQUENCE", (char*)my_dbi_result_get_string(dbires_ref, pubdatefields[n_role][6]))) {
1082     LOG_PRINT(LOG_WARNING, get_status_msg(801));
1083     return 1;
1084   }
1085 
1086   iwrite_elstart(ptr_clrequest, "PUBDATE", &sentinel, 0);
1087 
1088   delete_all_liliform(&sentinel);
1089 
1090   /* preceeding */
1091   iwrite_element(ptr_clrequest, "PRECEEDING", NULL, my_dbi_result_get_string(dbires_ref, pubdatefields[n_role][7]));
1092 
1093   /* following */
1094   iwrite_element(ptr_clrequest, "FOLLOWING", NULL, my_dbi_result_get_string(dbires_ref, pubdatefields[n_role][8]));
1095 
1096   /* firstsep */
1097   iwrite_element(ptr_clrequest, "FIRSTSEP", NULL, my_dbi_result_get_string(dbires_ref, pubdatefields[n_role][9]));
1098 
1099   /* secondsep */
1100   iwrite_element(ptr_clrequest, "SECONDSEP", NULL, my_dbi_result_get_string(dbires_ref, pubdatefields[n_role][10]));
1101 
1102   iwrite_elend(ptr_clrequest, "PUBDATE");
1103 
1104   return 0;
1105 }
1106 
1107 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1108   iwrite_separator() writes a separator element to a file descriptor.
1109 
1110   static int iwrite_separator 0 if fine, 1 if some error occurred
1111 
1112   struct CLIENT_REQUEST* ptr_clrequest ptr to a structure with client info
1113 
1114   dbi_result dbires_ref ptr to citstyle query result structure
1115 
1116   unsigned int separator_id id of the separator to format
1117 
1118   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
iwrite_separator(struct CLIENT_REQUEST * ptr_clrequest,dbi_result dbires_ref,unsigned int separator_id)1119 static int iwrite_separator(struct CLIENT_REQUEST* ptr_clrequest, dbi_result dbires_ref, unsigned int separator_id) {
1120   dbi_conn conn;
1121   dbi_result dbires;
1122   char sql_command[256];
1123 
1124   conn = dbi_result_get_conn(dbires_ref);
1125 
1126   sprintf(sql_command, "SELECT VALUE FROM SEPARATORS WHERE ID=%u", separator_id);
1127   dbires = dbi_conn_query(conn, sql_command);
1128   LOG_PRINT(LOG_DEBUG, sql_command);
1129   if (dbires) {
1130     while (dbi_result_next_row(dbires)) { /* should run only once */
1131       iwrite_element(ptr_clrequest, "SEPARATOR", NULL, my_dbi_result_get_string(dbires, "VALUE"));
1132     }
1133     dbi_result_free(dbires);
1134   }
1135   return 0;
1136 }
1137 
1138 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1139   iwrite_title() writes a title element to a file descriptor.
1140 
1141   static int iwrite_title 0 if fine, 1 if some error occurred
1142 
1143   struct CLIENT_REQUEST* ptr_clrequest ptr to a structure with client info
1144 
1145   dbi_result dbires_ref ptr to citstyle query result structure
1146 
1147   const char* role ptr to string with the authorlist role
1148 
1149   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
iwrite_title(struct CLIENT_REQUEST * ptr_clrequest,dbi_result dbires_ref,const char * role)1150 static int iwrite_title(struct CLIENT_REQUEST* ptr_clrequest, dbi_result dbires_ref, const char* role) {
1151   char titlefields[4][4][22] = {
1152     {"TITLEPRECEEDING", "TITLEFOLLOWING", "TITLECASE", "TITLESTYLE"},
1153     {"BOOKTITLEPRECEEDING", "BOOKTITLEFOLLOWING", "BOOKTITLECASE", "BOOKTITLESTYLE"},
1154     {"SERIESTITLEPRECEEDING", "SERIESTITLEFOLLOWING", "SERIESTITLECASE", "SERIESTITLESTYLE"},
1155     {"ALLTITLEPRECEEDING", "ALLTITLEFOLLOWING", "ALLTITLECASE", "ALLTITLESTYLE"}
1156   };
1157 
1158   int n_role = 0;
1159 
1160   Liliform sentinel;
1161 
1162   sentinel.ptr_next = NULL;
1163   sentinel.name[0] = '\0';
1164   sentinel.value = NULL;
1165 
1166   if (!strcmp(role, "PRIMARY")) {
1167     n_role = 0;
1168   }
1169   else if (!strcmp(role, "SECONDARY")) {
1170     n_role = 1;
1171   }
1172   else if (!strcmp(role, "TERTIARY")) {
1173     n_role = 2;
1174   }
1175   else if (!strcmp(role, "ALL")) {
1176     n_role = 3;
1177   }
1178 
1179   if (insert_liliform(&sentinel, "CASE", (char*)my_dbi_result_get_string(dbires_ref, titlefields[n_role][2]))) {
1180     LOG_PRINT(LOG_WARNING, get_status_msg(801));
1181     return 1;
1182   }
1183 
1184   if (insert_liliform(&sentinel, "STYLE", (char*)my_dbi_result_get_string(dbires_ref, titlefields[n_role][3]))) {
1185     LOG_PRINT(LOG_WARNING, get_status_msg(801));
1186     delete_all_liliform(&sentinel);
1187     return 1;
1188   }
1189 
1190   if (insert_liliform(&sentinel, "ROLE", (char*)role)) {
1191     LOG_PRINT(LOG_WARNING, get_status_msg(801));
1192     delete_all_liliform(&sentinel);
1193     return 1;
1194   }
1195 
1196   iwrite_elstart(ptr_clrequest, "TITLE", &sentinel, 0);
1197 
1198   delete_all_liliform(&sentinel);
1199 
1200   /* preceeding */
1201   iwrite_element(ptr_clrequest, "PRECEEDING", NULL, my_dbi_result_get_string(dbires_ref, titlefields[n_role][0]));
1202 
1203   /* following */
1204   iwrite_element(ptr_clrequest, "FOLLOWING", NULL, my_dbi_result_get_string(dbires_ref, titlefields[n_role][1]));
1205 
1206   iwrite_elend(ptr_clrequest, "TITLE");
1207 
1208   return 0;
1209 }
1210 
1211 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1212   iwrite_simple() writes a simple element to a file descriptor.
1213 
1214   static int iwrite_simple 0 if fine, 1 if some error occurred
1215 
1216   struct CLIENT_REQUEST* ptr_clrequest ptr to a structure with client info
1217 
1218   dbi_result dbires_ref ptr to citstyle query result structure
1219 
1220   const char* elname
1221 
1222   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
iwrite_simple(struct CLIENT_REQUEST * ptr_clrequest,dbi_result dbires_ref,const char * elname)1223 static int iwrite_simple(struct CLIENT_REQUEST* ptr_clrequest, dbi_result dbires_ref, const char* elname) {
1224   Liliform sentinel;
1225   char buffer[64];
1226 
1227   sentinel.ptr_next = NULL;
1228   sentinel.name[0] = '\0';
1229   sentinel.value = NULL;
1230 
1231   snprintf(buffer, 64, "%sSTYLE", elname);
1232 
1233   if (insert_liliform(&sentinel, "STYLE", (char*)my_dbi_result_get_string(dbires_ref, buffer))) {
1234     LOG_PRINT(LOG_WARNING, get_status_msg(801));
1235     return 1;
1236   }
1237 
1238   iwrite_elstart(ptr_clrequest, elname, &sentinel, 0);
1239 
1240   delete_all_liliform(&sentinel);
1241 
1242   /* preceeding */
1243   snprintf(buffer, 64, "%sPRECEEDING", elname);
1244   iwrite_element(ptr_clrequest, "PRECEEDING", NULL, my_dbi_result_get_string(dbires_ref, buffer));
1245 
1246   /* following */
1247   snprintf(buffer, 64, "%sFOLLOWING", elname);
1248   iwrite_element(ptr_clrequest, "FOLLOWING", NULL, my_dbi_result_get_string(dbires_ref, buffer));
1249 
1250   iwrite_elend(ptr_clrequest, elname);
1251 
1252   return 0;
1253 }
1254 
1255 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1256   iwrite_twoatt() writes an element with two attributes to a file descriptor.
1257 
1258   static int iwrite_twoatt 0 if fine, 1 if some error occurred
1259 
1260   struct CLIENT_REQUEST* ptr_clrequest ptr to a structure with client info
1261 
1262   dbi_result dbires_ref ptr to citstyle query result structure
1263 
1264   const char* elname ptr to string with element name
1265 
1266   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
iwrite_twoatt(struct CLIENT_REQUEST * ptr_clrequest,dbi_result dbires_ref,const char * elname)1267 static int iwrite_twoatt(struct CLIENT_REQUEST* ptr_clrequest, dbi_result dbires_ref, const char* elname) {
1268   char my_elname[10];
1269   char fields[10][4][20] = {
1270     {"USERDEF1PRECEEDING", "USERDEF1FOLLOWING", "USERDEF1STYLE", "1"},
1271     {"USERDEF2PRECEEDING", "USERDEF2FOLLOWING", "USERDEF2STYLE", "2"},
1272     {"USERDEF3PRECEEDING", "USERDEF3FOLLOWING", "USERDEF3STYLE", "3"},
1273     {"USERDEF4PRECEEDING", "USERDEF4FOLLOWING", "USERDEF4STYLE", "4"},
1274     {"USERDEF5PRECEEDING", "USERDEF5FOLLOWING", "USERDEF5STYLE", "5"},
1275     {"LINK0PRECEEDING", "LINK0FOLLOWING", "LINK0STYLE", "0"},
1276     {"LINK1PRECEEDING", "LINK1FOLLOWING", "LINK1STYLE", "1"},
1277     {"LINK2PRECEEDING", "LINK2FOLLOWING", "LINK2STYLE", "2"},
1278     {"LINK3PRECEEDING", "LINK3FOLLOWING", "LINK3STYLE", "3"},
1279     {"LINK4PRECEEDING", "LINK4FOLLOWING", "LINK4STYLE", "4"},
1280   };
1281 
1282   int n_role;
1283 
1284   Liliform sentinel;
1285 
1286   sentinel.ptr_next = NULL;
1287   sentinel.name[0] = '\0';
1288   sentinel.value = NULL;
1289 
1290   if (!strncmp(elname, "USERDEF", 7)) {
1291     n_role = atoi(elname+7) - 1; /* attributes are 1-based */
1292     strcpy(my_elname, "USERDEF");
1293   }
1294   else if (!strncmp(elname, "LINK", 4)) {
1295     n_role = atoi(elname+4) + 5;
1296     strcpy(my_elname, "LINK");
1297   }
1298   else {
1299     return 1; /* should never happen */
1300   }
1301 
1302   if (insert_liliform(&sentinel, "STYLE", (char*)my_dbi_result_get_string(dbires_ref, fields[n_role][2]))) {
1303     LOG_PRINT(LOG_WARNING, get_status_msg(801));
1304     delete_all_liliform(&sentinel);
1305     return 1;
1306   }
1307 
1308   if (insert_liliform(&sentinel, "ROLE", fields[n_role][3])) {
1309     LOG_PRINT(LOG_WARNING, get_status_msg(801));
1310     delete_all_liliform(&sentinel);
1311     return 1;
1312   }
1313 
1314   iwrite_elstart(ptr_clrequest, my_elname, &sentinel, 0);
1315 
1316   delete_all_liliform(&sentinel);
1317 
1318   /* preceeding */
1319   iwrite_element(ptr_clrequest, "PRECEEDING", NULL, my_dbi_result_get_string(dbires_ref, fields[n_role][0]));
1320 
1321   /* following */
1322   iwrite_element(ptr_clrequest, "FOLLOWING", NULL, my_dbi_result_get_string(dbires_ref, fields[n_role][1]));
1323 
1324   iwrite_elend(ptr_clrequest, my_elname);
1325 
1326   return 0;
1327 }
1328 
1329 
1330 
1331