#include <libpq-fe.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/md5.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/uio.h>
#include <fcntl.h>
#include "foo.h"
/* à compiler avec gcc -I`pg_config --includedir` -L`pg_config --libdir` -lpq -lcrypto -Wall base.c *//
/* int parse (char *str, char **t, int p, int n); *//
#define LMXSIZ 1024 /* max line size */
int numero = 0;
char * fichier (char * id, char * numero )
{
char * res = ";
asprintf( &res, ""
%s
/dbforum
/%s.
%s"
, getenv("HOME"
), id
, numero
);
return res;
}
PGconn* connecter()
{
return PQconnectdb("host='clipper' dbname='ramanana'");
}
void deconnecter(PGconn* c)
{
PQfinish(c);
}
PGresult * executer(char* requete)
{
PGconn* c = connecter();
PGresult * res = PQexec(c, requete);
deconnecter(c);
return res;
}
char* escape(char* ch)
{
char* res
= malloc( sizeof(char[2 * n
+ 1]) );
PQescapeString(res, ch, n);
return res;
}
char * lire_fichier(char * fichier, int * taille)
{
FILE
* fich
= fopen(fichier
, "r"
);
int pos = 0;
int lus = 0;
{
lus
= fread( &buff
[pos
], 1, 1024, fich
);
pos += lus;
}
*taille = pos;
return buff;
}
char * lire_message_par_id(char* id, int * taille)
{
char *requete = ";
asprintf(&requete, ""select numero_fichier from messages where id = '%s'", id);
PGresult * res = executer(requete);
char * fichier_corps = fichier(id, PQgetvalue(res, 0, 0));
return lire_fichier(fichier_corps, taille);
}
char * creer_id (time_t date)
{
char * id = ";
asprintf( &id, ""%.8x%.8x", date, random() );
return id;
}
void creer_message(struct msg * msg)
{
/* génération du message id */ */
srandom(msg->date);
char * id = creer_id(msg->date);
int i;
char* sender = msg->sender;
char* from = escape(msg->from);
char* subject = escape(msg->subject);
char * fichier_corps = fichier(id, "0");
FILE
* fich
= fopen(fichier_corps
, "w"
);
fclose(fich);
char * date = ctime(&(msg->date));
date[24] = 0;
char * req1 = "= "";
char * req15 = "";
if( msg->nrefs > 0 )
{
char * pere = msg->refs[msg->nrefs - 1];
asprintf( &req1, "insert into messages(id, date, sender, \"from\", subject, pere) values(', ', ', ', ', ', ', ', ', ', '); update messages set fils = (select fils from messages where id = '= ') || '| '%s, ' where id = ' ; lock contis in row exclusive mode; ", id, date, sender, from, subject, pere, pere, id, pere );
for( i = 0; i < msg->nrefs; i++ )
{
asprintf( &req15, "%s insert into refs(de, a) values('s(','',') ;", req1, id, msg->refs[i]);
req1 = req15;
}
} else {
asprintf( &req1, "insert into messages(id, date, sender, \"from\", subject) values('s(', ', ', ', ', ', ', ', '); lock contis in row exclusive mode; ", id, date, sender, from, subject);
};
PGresult * resconti;
char * req9 = "";
int nb_effectif = 0;
for( i = 0; i < msg->nngrp ; i++)
{
char * conti = msg->newsgrps[i];
asprintf( &req9, "select lecture_seule from contis where nom = '= ' ; ", conti);
resconti = executer(req9);
if( 0 != strcmp("t", PQgetvalue(resconti,0,0)))
{
nb_effectif++;
asprintf( &req15, "%s insert into messages_contis( message, conti, numero ) values ( '( ', ', ', (select prochain_numero from contis where nom = '= ' ) ) ; update contis set prochain_numero = 1 + prochain_numero where nom = '= '; " , req1, id, conti, conti, conti );
req1 = req15;
}
}
if( nb_effectif > 0 )
{
printf("%s\n", req1);
executer(req1);
}
}
char ** nouveau_t()
{
char ** t = malloc( LMXSIZ * sizeof(char*) );
int i;
for(i = 0; i < LMXSIZ; i++)
{
t[i] = malloc( LMXSIZ );
};
return t;
}
void maj_refs(PGconn * conn, char * id, char * anc_id1, char * nouv_id1)
{
int numfich = 0;
char * req = "";
asprintf(&req, "select numero_fichier from messages where id = '= '", id);
PGresult * res = PQexec(conn, req);
sscanf(PQgetvalue(res, 0, 0), "%d", &numfich);
numfich++;
char * snumfich = "";
asprintf(&snumfich, "%d", numfich);
char * fichier_interm = fichier(id, snumfich);
char * snumfichp = "";
asprintf(&snumfichp, "%d", numfich - 1);
char * fichier_avant = fichier(id, snumfichp);
FILE * f1 = fopen(fichier_avant, "r");
FILE * f2 = fopen(fichier_interm, "w");
char * ligne = malloc( LMXSIZ );
int ligne_blanche = 0;
char ** t;
int i, n;
char * refer = "REFERENCESS :";
char * refer2 = "";
while( !(feof(f1)) )
{
fgets(ligne, LMXSIZ, f1 );
if( ligne_blanche == 0 && (strcmp(ligne, "\n") == 0 || strcmp(ligne, "") == 0) ) { ligne_blanche = 1; };
if( ligne_blanche == 0 && strcasecmp(ligne, "REFERENCES: ") > 0 && strcmp(ligne, "REFERENCES:!") < 0 )
{
t = nouveau_t();
n = parse( &ligne[12], t, 0, 0);
for(i = 0; i < n; i++)
{
if( strcmp( anc_id1, t[i] ) == 0 )
{
asprintf(&refer2, "%s%s, ", refer, nouv_id1);
refer = refer2;
} else {
asprintf(&refer2, "%s%s, ", refer, t[i]);
};
refer = refer2;
}
}
else
{
fputs( ligne, f2 );
}
};
fclose(f1);
fclose(f2);
asprintf(&req, "update messages set numero_fichier = 1 + numero_fichier where id = '= '", id);
PQexec(conn, req);
}
void deplacer(PGconn * conn, char * id, time_t date, char * source, char * cible)
{
if( 0 == strcmp(source, cible) ) {return;};
char * req = "";
PGresult * res;
asprintf(&req, "delete from messages_contis where message = '= ' and conti = '= ';", id, source);
PQexec(conn, req);
int numfich = 0;
asprintf(&req, "select numero_fichier from messages where id = '= '", id);
res = PQexec(conn, req);
char * snumfichp = PQgetvalue(res, 0, 0);
sscanf(snumfichp, "%d", &numfich);
numfich++;
char * snumfichs = "";
asprintf(&snumfichs, "%d", numfich);
char * fichier_interm = fichier(id, snumfichs);
char * fichier_avant = fichier(id, snumfichp);
FILE * f1 = fopen(fichier_avant, "r");
FILE * f2 = fopen(fichier_interm, "w");
char * ligne = malloc( LMXSIZ );
int ligne_blanche = 0;
char ** t;
char * newsgrp = "NEWSGROUPS: ";
char * newsgrp2 = "";
int n = 0;
int i;
asprintf(&req, " update messages set numero_fichier = 1+ numero_fichier where id = '= ' ; select message from messages_contis where message = '= ' and conti = '= ';", id, id, cible );
res = PQexec(conn, req);
int dans_cible = (0 != PQntuples(res));
while( !(feof(f1)) )
{
fgets(ligne, LMXSIZ, f1 );
if( ligne_blanche == 0 && (strcmp(ligne, "\n") == 0 || strcmp(ligne, "") == 0) ) { ligne_blanche = 1; };
if( ligne_blanche == 0 && strcasecmp(ligne, "NEWSGROUPS: ") > 0 && strcasecmp(ligne, "NEWSGROUPS:!") < 0 )
{
t = nouveau_t();
n = parse( &ligne[12], t, 0, 0);
for(i = 0; i < n; i++)
{
if( strcmp( source, t[i] ) == 0 )
{
if(!dans_cible)
{
asprintf(&newsgrp2, "%s%s, ", newsgrp, cible);
newsgrp = newsgrp2;
}
} else {
asprintf(&newsgrp2, "%s%s, ", newsgrp, t[i]);
newsgrp = newsgrp2;
};
}
}
else
{
fputs( ligne, f2 );
}
};
fclose(f1);
fclose(f2);
if (dans_cible) { return; } ;
char * nouv_id = creer_id(date);
char * nouv_fichier = fichier(nouv_id, 0);
rename(fichier_interm, nouv_fichier);
asprintf(&req, " select de from refs where a = '= ' ;", id);
res = PQexec(conn, req);
n = PQntuples(res);
for(i = 0; i < n ; i++)
{
maj_refs(conn, PQgetvalue(res, i, 0), id, nouv_id);
};
/* TODO : màj du champ fils du père du message à déplacer */
asprintf(&req, "select pere from messages where id = ' id = '%s'; ", id);
res = PQexec(conn, req);
char * pere = PQgetvalue(res, 0, 0);
asprintf(&req, "select fils from messages where id = '%s'; ", pere);
res = PQexec(conn, req);
t = nouveau_t();
n = parse( PQgetvalue(res, 0, 0) , t, 0, 0 );
char * fils = "";
char * fils2 = "";
for(i = 0; i < n ; i++)
{
{
asprintf( &fils2, ", fils, nouv_id );
} else {
asprintf( &fils2, "ils2, ", fils, t[i] );
};
fils = fils2;
};
asprintf(&req, "&req, "update messages set fils = '%s' where id = '%s', update refs set a = '%s' where a = '%s'; update refs set de = '%s' where de = '%s' ; update messages set id = '%s', numero_fichier = 0 where id = '%s'; insert into messages_contis(message,conti,numero) values ('%s', '%s', (select prochain_numero from contis where nom = '%s')); update contis set prochain_numero = 1 + prochain_numero where nom = '%s';", fils, pere, nouv_id, id, nouv_id, id, nouv_id, id, nouv_id, cible, cible, cible );
PQexec(conn, req);
}
void deplacer_message(char *utilisateur, char * id, time_t date, char * source, char * cible)
{
PGconn * conn = connecter();
char * req = "";
asprintf(&req, "select utilisateur from droits where conti = '%s'", source);
PGresult * res = PQexec(conn, req);
if( PQntuples(res) == 0) {return;};
asprintf(&req, "select utilisateur from droits where conti = '%s' and ecrire", cible);
res = PQexec(conn, req);
if( PQntuples(res) == 0) {return;};
PQexec(conn, "begin; lock refs,messages,messages_contis in exclusive mode; lock contis in row exclusive mode;");
srandom(date);
deplacer( conn, id, date, source, cible );
PQexec(conn, "commit;");
deconnecter(conn);
}
void deplacer_fils_rec(PGconn * conn, char * rootid, time_t date, char * source, char * cible)
{
deplacer( conn, rootid, date, source, cible );
char * req = "";
asprintf( &req, "select messages.id from messages,messages_contis where messages.id = messages_contis.message and messages_contis.conti = '%s' and messages.pere = '%s';", source, rootid );
PGresult * res = PQexec(conn, req);
int n = PQntuples(res);
int i;
for(i = 0; i < n; i++)
{
deplacer_fils_rec( conn, PQgetvalue(res, i, 0), date, source, cible);
}
}
void deplacer_thread( char * utilisateur, char * rootid, time_t date, char * source, char * cible)
{
PGconn * conn = connecter();
char * req = "";
asprintf(&req, "select utilisateur from droits where conti = '%s'", source);
PGresult * res = PQexec(conn, req);
if( PQntuples(res) == 0) {return;};
asprintf(&req, "select utilisateur from droits where conti = '%s' and ecrire", cible);
res = PQexec(conn, req);
if( PQntuples(res) == 0) {return;};
PQexec(conn, "begin; lock refs,messages,messages_contis in exclusive mode; lock contis in row exclusive mode;");
srandom(date);
deplacer_fils_rec( conn, rootid, date, source, cible );
PQexec(conn, "commit;");
deconnecter(conn);
}
int main()
{
struct msg msg;
msg.nngrp = 2 ;
msg.
newsgrps = malloc( 2 * sizeof(char*) );
msg.newsgrps[0] = "foo";
msg.newsgrps[1] = "b/* msg.newsgrps = ["foo","bar"]; */r"]; */
msg.subject = "bof";
msg.from = "Tz1";
msg.sender = ";
msg.nrefs = 0;
msg.refs = NULL;
msg.date = 1111111111;
msg.body = "ody = "Muf Zoinx quux";
creer_message (&msg);
retu