Import ezmlm-idx 0.40
[ezmlm] / sub_pgsql / tagmsg.c
1 /*$Id: tagmsg.c,v 1.2 1999/10/07 23:31:01 lindberg Exp $*/
2 /*$Name: ezmlm-idx-040 $*/
3 #include "stralloc.h"
4 #include "scan.h"
5 #include "fmt.h"
6 #include "strerr.h"
7 #include "cookie.h"
8 #include "slurp.h"
9 #include "errtxt.h"
10 #include "subscribe.h"
11 #include "makehash.h"
12 #include <unistd.h>
13 #include <libpq-fe.h>
14
15 static stralloc line = {0};
16 static stralloc key = {0};
17 static char hash[COOKIE];
18 static char strnum[FMT_ULONG]; /* message number as sz */
19
20 static void die_nomem(fatal)
21 char *fatal;
22 {
23 strerr_die2x(100,fatal,ERR_NOMEM);
24 }
25
26 void tagmsg(dir,msgnum,seed,action,hashout,bodysize,chunk,fatal)
27 /* This routine creates a cookie from num,seed and the */
28 /* list key and returns that cookie in hashout. The use of sender/num and */
29 /* first char of action is used to make cookie differ between messages, */
30 /* the key is the secret list key. The cookie will be inserted into */
31 /* table_cookie where table and other data is taken from dir/sql. We log */
32 /* arrival of the message (done=0). */
33
34 char *dir; /* db base dir */
35 unsigned long msgnum; /* number of this message */
36 char *seed; /* seed. NULL ok, but less entropy */
37 char *action; /* to make it certain the cookie differs from*/
38 /* one used for a digest */
39 char *hashout; /* calculated hash goes here */
40 unsigned long bodysize;
41 unsigned long chunk;
42 char *fatal;
43 {
44 PGresult *result;
45 PGresult *result2; /* Need for dupicate check */
46 char *table = (char *) 0;
47 char *ret;
48 unsigned int i;
49
50 strnum[fmt_ulong(strnum,msgnum)] = '\0'; /* message nr ->string*/
51
52 switch(slurp("key",&key,32)) {
53 case -1:
54 strerr_die3sys(111,fatal,ERR_READ,"key: ");
55 case 0:
56 strerr_die3x(100,fatal,"key",ERR_NOEXIST);
57 }
58 cookie(hash,key.s,key.len,strnum,seed,action);
59 for (i = 0; i < COOKIE; i++)
60 hashout[i] = hash[i];
61
62 if ((ret = opensql(dir,&table))) {
63 if (*ret) strerr_die2x(111,fatal,ret);
64 return; /* no sql => success */
65
66 } else {
67 if (chunk >= 53L) chunk = 0L; /* sanity */
68
69 /* INSERT INTO table_cookie (msgnum,cookie) VALUES (num,cookie) */
70 /* (we may have tried message before, but failed to complete, so */
71 /* ER_DUP_ENTRY is ok) */
72 if (!stralloc_copys(&line,"INSERT INTO ")) die_nomem(fatal);
73 if (!stralloc_cats(&line,table)) die_nomem(fatal);
74 if (!stralloc_cats(&line,"_cookie (msgnum,cookie,bodysize,chunk) VALUES ("))
75 die_nomem(fatal);
76 if (!stralloc_cats(&line,strnum)) die_nomem(fatal);
77 if (!stralloc_cats(&line,",'")) die_nomem(fatal);
78 if (!stralloc_catb(&line,hash,COOKIE)) die_nomem(fatal);
79 if (!stralloc_cats(&line,"',")) die_nomem(fatal);
80 if (!stralloc_catb(&line,strnum,fmt_ulong(strnum,bodysize)))
81 die_nomem(fatal);
82 if (!stralloc_cats(&line,",")) die_nomem(fatal);
83 if (!stralloc_catb(&line,strnum,fmt_ulong(strnum,chunk))) die_nomem(fatal);
84 if (!stralloc_cats(&line,")")) die_nomem(fatal);
85
86 if (!stralloc_0(&line)) die_nomem(fatal);
87 result = PQexec(psql,line.s);
88 if (result == NULL)
89 strerr_die2x(111,fatal,PQerrorMessage(psql));
90 if (PQresultStatus(result) != PGRES_COMMAND_OK) { /* Possible tuplicate */
91 if (!stralloc_copys(&line,"SELECT msgnum FROM ")) die_nomem(fatal);
92 if (!stralloc_cats(&line,table)) die_nomem(fatal);
93 if (!stralloc_cats(&line,"_cookie WHERE msgnum = ")) die_nomem(fatal);
94 if (!stralloc_catb(&line,strnum,fmt_ulong(strnum,msgnum)))
95 die_nomem(fatal);
96 /* Query */
97 if (!stralloc_0(&line)) die_nomem(fatal);
98 result2 = PQexec(psql,line.s);
99 if (result2 == NULL)
100 strerr_die2x(111,fatal,PQerrorMessage(psql));
101 if (PQresultStatus(result2) != PGRES_TUPLES_OK)
102 strerr_die2x(111,fatal,PQresultErrorMessage(result2));
103 /* No duplicate, return ERROR from first query */
104 if (PQntuples(result2)<1)
105 strerr_die2x(111,fatal,PQresultErrorMessage(result));
106 PQclear(result2);
107 }
108 PQclear(result);
109
110 if (! (ret = logmsg(dir,msgnum,0L,0L,1))) return; /* log done=1*/
111 if (*ret) strerr_die2x(111,fatal,ret);
112 }
113
114 return;
115 }