00001
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "config.h"
00021 #include "defines.h"
00022
00023 #include <stdlib.h>
00024 #include <stdio.h>
00025 #include <string.h>
00026 #include <ctype.h>
00027 #include <stdarg.h>
00028 #include <fcntl.h>
00029 #include <sys/types.h>
00030 #include <sys/stat.h>
00031 #include <sys/uio.h>
00032 #include <sys/un.h>
00033 #include <sys/socket.h>
00034 #include <dlfcn.h>
00035 #include <locale.h>
00036
00037 #include <pthread.h>
00038
00039 #include <pwd.h>
00040
00041 #ifdef CF_SHARED_MEM
00042 #include <sys/ipc.h>
00043 #include <sys/shm.h>
00044 #include <sys/sem.h>
00045 #endif
00046
00047 #ifdef CF_SHARED_MEM
00048 #include "semaphores.h"
00049 #endif
00050
00051 #include "hashlib.h"
00052 #include "utils.h"
00053 #include "configparser.h"
00054 #include "template.h"
00055 #include "readline.h"
00056 #include "charconvert.h"
00057 #include "clientlib.h"
00058
00059
00060
00061 t_cf_hash *GlobalValues = NULL;
00062
00063 t_cf_hash *APIEntries = NULL;
00064
00065
00066 u_char ErrorString[50];
00067
00068 #ifdef CF_SHARED_MEM
00069
00070
00071 static int shm_id = -1;
00072 static void *shm_ptr = NULL;
00073 static int shm_lock_sem = -1;
00075 void *reget_shm_ptr() {
00076 t_name_value *shm = cfg_get_value(&fo_default_conf,"SharedMemIds");
00077 unsigned short val;
00078
00079 if(shm_ptr) {
00080 shmdt(shm_ptr);
00081 shm_ptr = NULL;
00082 }
00083
00084 if(cf_sem_getval(shm_lock_sem,0,1,&val) == 0) {
00085 if((shm_id = shmget(atoi(shm->values[val]),0,0)) == -1) {
00086 return NULL;
00087 }
00088
00089
00090
00091
00092
00093 if((shm_ptr = shmat(shm_id,0,SHM_RDONLY)) == (void *)-1) {
00094 return NULL;
00095 }
00096 }
00097
00098 return shm_ptr;
00099 }
00100
00101 void *get_shm_ptr() {
00102 t_name_value *shm = cfg_get_value(&fo_default_conf,"SharedMemIds");
00103 unsigned short val;
00104
00105 if(shm_lock_sem == -1) {
00106
00107 if((shm_lock_sem = semget(atoi(shm->values[2]),0,0)) == -1) {
00108 return NULL;
00109 }
00110 }
00111
00112 if(cf_sem_getval(shm_lock_sem,0,1,&val) == 0) {
00113 val = val == 1 ? 0 : 1;
00114
00115 if(shm_id == -1) {
00116 if((shm_id = shmget(atoi(shm->values[val]),0,0)) == -1) {
00117 return NULL;
00118 }
00119 }
00120
00121 if(shm_ptr == NULL) {
00122
00123
00124
00125
00126 if((shm_ptr = shmat(shm_id,0,SHM_RDONLY)) == (void *)-1) {
00127 return NULL;
00128 }
00129 }
00130 }
00131
00132 return shm_ptr;
00133 }
00134
00135
00136 #endif
00137
00138
00139
00140
00141
00142
00143
00144
00145 u_char *get_uconf_name(const u_char *uname) {
00146 u_char *path,*name;
00147 u_char *ptr;
00148 struct stat sb;
00149 t_name_value *confpath = cfg_get_value(&fo_default_conf,"ConfigDirectory");
00150
00151 if(!uname) return NULL;
00152
00153 name = strdup(uname);
00154 if(!name) return NULL;
00155
00156 for(ptr = name;*ptr;ptr++) {
00157 if(isupper(*ptr)) {
00158 *ptr = tolower(*ptr);
00159 }
00160 }
00161
00162 path = fo_alloc(NULL,strlen(confpath->values[0]) + strlen(name) + 12,1,FO_ALLOC_MALLOC);
00163
00164 sprintf(path,"%s%c/%c/%c/%s.conf",confpath->values[0],name[0],name[1],name[2],name);
00165
00166 if(stat(path,&sb) == -1) {
00167 free(path);
00168 free(name);
00169 fprintf(stderr,"user config file '%s' not found!\n",path);
00170 return NULL;
00171 }
00172
00173 free(name);
00174
00175 return path;
00176 }
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186 int set_us_up_the_socket(void) {
00187 int sock;
00188 struct sockaddr_un addr;
00189 t_name_value *sockpath = cfg_get_value(&fo_default_conf,"SocketName");
00190
00191 if(sockpath) {
00192 memset(&addr,0,sizeof(addr));
00193 addr.sun_family = AF_LOCAL;
00194 (void)strncpy(addr.sun_path,sockpath->values[0],103);
00195
00196 if((sock = socket(AF_LOCAL,SOCK_STREAM,0)) == -1) {
00197 strcpy(ErrorString,"E_NO_SOCK");
00198 return -1;
00199 }
00200
00201 if((connect(sock,(struct sockaddr *)&addr,sizeof(addr))) != 0) {
00202 strcpy(ErrorString,"E_NO_CONN");
00203 return -1;
00204 }
00205
00206 return sock;
00207 }
00208
00209 strcpy(ErrorString,"E_CONFIG_ERR");
00210 return -1;
00211 }
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223 void generate_tpl_name(u_char buff[],int len,t_name_value *v) {
00224 t_name_value *vn = cfg_get_value(&fo_default_conf,"TemplateMode");
00225
00226 if(vn) {
00227 snprintf(buff,len,v->values[0],"tpl_",vn->values[0]);
00228 }
00229 else {
00230 snprintf(buff,len,v->values[0],"","");
00231 }
00232 }
00233
00234
00235
00236 void cf_set_variable(t_cf_template *tpl,t_name_value *cs,u_char *vname,const u_char *val,size_t len,int html) {
00237 u_char *tmp;
00238 size_t len1;
00239
00240 if(cs) {
00241 if(cf_strcmp(cs->values[0],"UTF-8")) {
00242 if(html) {
00243 tmp = htmlentities_charset_convert(val,"UTF-8",cs->values[0],&len1,0);
00244 html = 0;
00245 }
00246 else {
00247 tmp = charset_convert(val,len,"UTF-8",cs->values[0],&len1);
00248 }
00249
00250 if(!tmp) {
00251 tpl_cf_setvar(tpl,vname,val,len,html);
00252 }
00253 else {
00254 tpl_cf_setvar(tpl,vname,tmp,len1,html);
00255 free(tmp);
00256 }
00257 }
00258
00259 else {
00260 tpl_cf_setvar(tpl,vname,val,len,html);
00261 }
00262 }
00263 else {
00264 tpl_cf_setvar(tpl,vname,val,len,html);
00265 }
00266
00267 }
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278 void str_error_message(const u_char *err,FILE *out,int rd, ...) {
00279 t_name_value *v = cfg_get_value(&fo_default_conf,"ErrorTemplate");
00280 t_name_value *v1 = cfg_get_value(&fo_default_conf,"ErrorMessages");
00281 t_name_value *cs = cfg_get_value(&fo_default_conf,"ExternCharset");
00282 t_cf_template tpl;
00283 u_char tplname[256];
00284 va_list ap;
00285
00286 FILE *fd;
00287 u_char *buff = NULL;
00288 u_char *fmt = NULL;
00289 register u_char *ptr;
00290 t_string msg;
00291 int found = 0;
00292 size_t size,chars;
00293 u_char ibuff[50];
00294
00295 int ivar;
00296 u_char *svar;
00297
00298 if(v && v1) {
00299 fd = fopen(v1->values[0],"r");
00300
00301 if(fd) {
00302 generate_tpl_name(tplname,256,v);
00303
00304 tpl_cf_init(&tpl,tplname);
00305
00306 if(tpl.tpl) {
00307 while((chars = getline((char **)&buff,&size,fd)) != 0) {
00308 if(cf_strncmp(buff,err,rd) == 0) {
00309
00310 str_init(&msg);
00311 fmt = strndup(buff+rd+2,chars-rd-3);
00312 va_start(ap,rd);
00313
00314 for(ptr=fmt;*ptr;ptr++) {
00315 if(*ptr == '%') {
00316 ptr++;
00317
00318 switch(*ptr) {
00319 case '%':
00320 str_char_append(&msg,*ptr);
00321 break;
00322
00323 case 's':
00324 svar = va_arg(ap,u_char *);
00325 str_chars_append(&msg,svar,strlen(svar));
00326 break;
00327
00328 case 'd':
00329 ivar = va_arg(ap,int);
00330 size = snprintf(ibuff,50,"%d",ivar);
00331 str_chars_append(&msg,ibuff,50);
00332 break;
00333
00334 default:
00335 str_char_append(&msg,*ptr);
00336 break;
00337 }
00338 }
00339 else {
00340 str_char_append(&msg,*ptr);
00341 }
00342 }
00343
00344 va_end(ap);
00345 free(fmt);
00346
00347 cf_set_variable(&tpl,cs,"error",msg.content,msg.len,1);
00348
00349 str_cleanup(&msg);
00350 found = 1;
00351 break;
00352 }
00353 }
00354
00355 fclose(fd);
00356
00357 if(found == 0) {
00358 found = snprintf(buff,2048,"Message not found: %s\n",err);
00359 tpl_cf_setvar(&tpl,"error",buff,found,1);
00360 }
00361
00362 if(out) {
00363 tpl_cf_parse_to_mem(&tpl);
00364 fwrite(tpl.parsed.content,1,tpl.parsed.len,out);
00365 }
00366 else {
00367 tpl_cf_parse(&tpl);
00368 }
00369
00370 tpl_cf_finish(&tpl);
00371 }
00372 else {
00373 printf("Sorry, could not find template file. I got error %s\n",err);
00374 }
00375 }
00376 else {
00377 printf("Sorry, could not find error messages. I got error %s\n",err);
00378 }
00379 }
00380 else {
00381 printf("Sorry, but I could not find my templates.\nI got error %s\n",err);
00382 }
00383
00384 if(size) free(buff);
00385 }
00386
00387
00388
00389 u_char *get_error_message(const u_char *err,int rd,size_t *len, ...) {
00390 t_name_value *v1 = cfg_get_value(&fo_default_conf,"ErrorMessages");
00391 FILE *fd;
00392 u_char *buff = NULL;
00393 size_t size = 0,chars;
00394 t_string msg;
00395 u_char *fmt = NULL,*svar;
00396 register u_char *ptr;
00397 va_list ap;
00398 int ivar;
00399 u_char ibuff[50];
00400
00401 if(v1) {
00402 fd = fopen(v1->values[0],"r");
00403
00404 if(fd) {
00405 while((chars = getline((char **)&buff,&size,fd)) != 0) {
00406 if(cf_strncmp(buff,err,rd) == 0) {
00407 str_init(&msg);
00408 fmt = strndup(buff+rd+1,chars-rd-1);
00409 va_start(ap,len);
00410
00411 for(ptr=fmt;*ptr;ptr++) {
00412 if(*ptr == '%') {
00413 ptr++;
00414
00415 switch(*ptr) {
00416 case '%':
00417 str_char_append(&msg,*ptr);
00418 break;
00419
00420 case 's':
00421 svar = va_arg(ap,u_char *);
00422 str_chars_append(&msg,svar,strlen(svar));
00423 break;
00424
00425 case 'd':
00426 ivar = va_arg(ap,int);
00427 size = snprintf(ibuff,50,"%d",ivar);
00428 str_chars_append(&msg,ibuff,50);
00429 break;
00430
00431 default:
00432 str_char_append(&msg,*ptr);
00433 break;
00434 }
00435 }
00436 else {
00437 str_char_append(&msg,*ptr);
00438 }
00439 }
00440
00441 va_end(ap);
00442 free(fmt);
00443 free(buff);
00444
00445 fclose(fd);
00446 return msg.content;
00447 }
00448 }
00449
00450 fclose(fd);
00451 }
00452 else {
00453 return NULL;
00454 }
00455 }
00456 else {
00457 return NULL;
00458 }
00459
00460 if(buff && size) free(buff);
00461 return NULL;
00462 }
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473 t_message *delete_subtree(t_message *msg) {
00474 int lvl = msg->level;
00475
00476 for(msg=msg->next;msg && msg->level > lvl;msg=msg->next) {
00477 msg->may_show = 0;
00478 }
00479
00480 return msg;
00481 }
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492 void cleanup_struct(t_cl_thread *thr) {
00493 t_message *msg = thr->messages,*last = thr->messages;
00494
00495 for(;msg;msg=last) {
00496 last = msg->next;
00497
00498 #ifndef CF_SHARED_MEM
00499 free(msg->author);
00500 free(msg->subject);
00501
00502 if(msg->category) {
00503 free(msg->category);
00504 }
00505
00506 if(msg->content) {
00507 free(msg->content);
00508 }
00509
00510 if(msg->email) {
00511 free(msg->email);
00512 }
00513
00514 if(msg->hp) {
00515 free(msg->hp);
00516 }
00517
00518 if(msg->img) {
00519 free(msg->img);
00520 }
00521 #endif
00522
00523 tpl_cf_finish(&msg->tpl);
00524
00525 free(msg);
00526 }
00527
00528 }
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540 u_char *get_link(u_int64_t tid,u_int64_t mid) {
00541 t_name_value *vs = cfg_get_value(&fo_default_conf,cf_hash_get(GlobalValues,"UserName",8) ? "UBaseURL" : "BaseURL");
00542 u_char *buff = NULL;
00543 size_t len;
00544
00545 if(vs) {
00546 len = 50 + strlen(vs->values[0]);
00547 buff = fo_alloc(NULL,len,1,FO_ALLOC_MALLOC);
00548 snprintf(buff,len,"%s?t=%lld&m=%lld",vs->values[0],tid,mid);
00549 }
00550
00551 return buff;
00552 }
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563 int has_answers(t_message *msg) {
00564 int lvl = msg->level;
00565 int ShowInvisible = cf_hash_get(GlobalValues,"ShowInvisible",13) == NULL ? 0 : 1;
00566
00567 if(msg->next) {
00568 if((msg->next->may_show && msg->invisible == 0) || ShowInvisible == 1) {
00569 if(msg->next->level > msg->level) {
00570 return 1;
00571 }
00572 return 0;
00573 }
00574 else {
00575 for(msg=msg->next;msg && (msg->may_show == 0 || msg->invisible == 1) && ShowInvisible == 0;msg=msg->next);
00576
00577 if(!msg) {
00578 return 0;
00579 }
00580 else {
00581 if(msg->level > lvl) {
00582 return 1;
00583 }
00584
00585 return 0;
00586 }
00587 }
00588 }
00589 else {
00590 return 0;
00591 }
00592 }
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606 int handle_thread_list_posting(t_message *p,t_cf_hash *head,u_int64_t tid,int mode) {
00607 int ret = FLT_OK;
00608 t_handler_config *handler;
00609 size_t i;
00610 t_filter_list_posting fkt;
00611
00612 if(Modules[VIEW_LIST_HANDLER].elements) {
00613 for(i=0;i<Modules[VIEW_LIST_HANDLER].elements && (ret == FLT_OK || ret == FLT_DECLINE);i++) {
00614 handler = array_element_at(&Modules[VIEW_LIST_HANDLER],i);
00615 fkt = (t_filter_list_posting)handler->func;
00616 ret = fkt(head,&fo_default_conf,&fo_view_conf,p,tid,mode);
00617 }
00618 }
00619
00620 return ret;
00621 }
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632 int handle_thread(t_cl_thread *thr,t_cf_hash *head,int mode) {
00633 int ret = FLT_OK;
00634 t_handler_config *handler;
00635 size_t i;
00636 t_filter_list fkt;
00637
00638 if(Modules[VIEW_HANDLER].elements) {
00639 for(i=0;i<Modules[VIEW_HANDLER].elements && (ret == FLT_OK || ret == FLT_DECLINE);i++) {
00640 handler = array_element_at(&Modules[VIEW_HANDLER],i);
00641 fkt = (t_filter_list)handler->func;
00642 ret = fkt(head,&fo_default_conf,&fo_view_conf,thr,mode);
00643 }
00644 }
00645
00646 return ret;
00647 }
00648
00649
00650
00651 int handle_posting_filters(t_cf_hash *head,t_cl_thread *thr,t_cf_template *tpl) {
00652 int ret = FLT_OK;
00653 t_handler_config *handler;
00654 size_t i;
00655 t_filter_posting fkt;
00656
00657 if(Modules[POSTING_HANDLER].elements) {
00658 for(i=0;i<Modules[POSTING_HANDLER].elements && (ret == FLT_OK || ret == FLT_DECLINE);i++) {
00659 handler = array_element_at(&Modules[POSTING_HANDLER],i);
00660 fkt = (t_filter_posting)handler->func;
00661 ret = fkt(head,&fo_default_conf,&fo_view_conf,thr,tpl);
00662 }
00663 }
00664
00665 return ret;
00666 }
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678 u_char *get_time(t_configuration *cfg,const u_char *symbol,int *len,time_t *date) {
00679 t_name_value *symb = cfg_get_value(cfg,symbol);
00680 t_name_value *loc = cfg_get_value(&fo_default_conf,"DateLocale");
00681 u_char *buff;
00682 int ln = 0;
00683 struct tm *tptr;
00684
00685 if(!symb || !loc) {
00686 return NULL;
00687 }
00688
00689 if(!setlocale(LC_TIME,loc->values[0])) {
00690 return NULL;
00691 }
00692
00693 ln = strlen(symb->values[0]) + 50;
00694 buff = fo_alloc(NULL,ln,1,FO_ALLOC_MALLOC);
00695 if(!buff) return NULL;
00696
00697 tptr = localtime(date);
00698
00699 *len = strftime(buff,(size_t)ln,symb->values[0],tptr);
00700
00701 return buff;
00702 }
00703
00704
00705
00706 int cf_get_next_thread_through_sock(int sock,rline_t *tsd,t_cl_thread *thr,const u_char *tplname) {
00707 u_char *line,*chtmp;
00708 int shallRun = 1;
00709 t_message *x;
00710 int ok = 0;
00711
00712 memset(thr,0,sizeof(*thr));
00713
00714
00715 while(shallRun) {
00716 line = readline(sock,tsd);
00717
00718 if(line) {
00719 line[tsd->rl_len-1] = '\0';
00720
00721 if(*line == '\0') {
00722 shallRun = 0;
00723 }
00724 else if(cf_strncmp(line,"THREAD t",8) == 0) {
00725 chtmp = strstr(line,"m");
00726
00727 thr->messages = fo_alloc(NULL,1,sizeof(t_message),FO_ALLOC_CALLOC);
00728 thr->last = thr->messages;
00729 thr->last->mid = strtoull(&line[chtmp-line+1],NULL,10);
00730 thr->messages->may_show = 1;
00731 thr->msg_len = 1;
00732 thr->tid = strtoull(line+8,NULL,10);
00733
00734 if(tplname) {
00735 tpl_cf_init(&thr->last->tpl,tplname);
00736 tpl_cf_setvar(&thr->last->tpl,"start","1",1,0);
00737 }
00738 }
00739 else if(cf_strncmp(line,"MSG m",5) == 0) {
00740 x = thr->last;
00741
00742 if(thr->last) {
00743 thr->last->next = fo_alloc(NULL,1,sizeof(t_message),FO_ALLOC_CALLOC);
00744 thr->last->next->prev = thr->last;
00745 thr->last = thr->last->next;
00746 }
00747 else {
00748 thr->messages = fo_alloc(NULL,1,sizeof(t_message),FO_ALLOC_CALLOC);
00749 thr->last = thr->messages;
00750 }
00751
00752 thr->last->mid = strtoull(&line[5],NULL,10);
00753 thr->last->may_show = 1;
00754
00755 thr->msg_len++;
00756
00757 if(tplname) {
00758 tpl_cf_init(&thr->last->tpl,tplname);
00759 }
00760 }
00761 else if(cf_strncmp(line,"Author:",7) == 0) {
00762 thr->last->author = strdup(&line[7]);
00763 }
00764 else if(cf_strncmp(line,"Visible:",8) == 0) {
00765 thr->last->invisible = line[8] == '0';
00766 }
00767 else if(cf_strncmp(line,"Subject:",8) == 0) {
00768 thr->last->subject = strdup(&line[8]);
00769 }
00770 else if(cf_strncmp(line,"Category:",9) == 0) {
00771 thr->last->category = strdup(&line[9]);
00772 }
00773 else if(cf_strncmp(line,"Date:",5) == 0) {
00774 thr->last->date = strtoul(&line[5],NULL,10);
00775 }
00776 else if(cf_strncmp(line,"Level:",6) == 0) {
00777 thr->last->level = atoi(&line[6]);
00778 }
00779 else if(cf_strncmp(line,"Content:",8) == 0) {
00780 thr->last->content = strdup(&line[8]);
00781 }
00782 else if(cf_strncmp(line,"Homepage:",9) == 0) {
00783 thr->last->hp = strdup(&line[9]);
00784 }
00785 else if(cf_strncmp(line,"Image:",6) == 0) {
00786 thr->last->img = strdup(&line[6]);
00787 }
00788 else if(cf_strncmp(line,"EMail:",6) == 0) {
00789 thr->last->email = strdup(&line[6]);
00790 }
00791 else if(cf_strncmp(line,"END",3) == 0) {
00792 shallRun = 0;
00793 ok = 1;
00794 }
00795
00796 free(line);
00797 }
00798 else {
00799 shallRun = 0;
00800 strcpy(ErrorString,"E_COMMUNICATE");
00801 }
00802 }
00803
00804 if(ok) return 0;
00805 return -1;
00806 }
00807
00808 #ifdef CF_SHARED_MEM
00809 void *cf_get_next_thread_through_shm(void *shm_ptr,t_cl_thread *thr,const u_char *tplname) {
00810 register void *ptr = shm_ptr;
00811 u_int32_t post;
00812 struct shmid_ds shm_buf;
00813 void *ptr1 = get_shm_ptr();
00814 size_t len;
00815 u_char buff[128];
00816
00817 memset(thr,0,sizeof(*thr));
00818
00819 if(shmctl(shm_id,IPC_STAT,&shm_buf) != 0) {
00820 strcpy(ErrorString,"E_CONFIG_ERR");
00821 return NULL;
00822 }
00823
00824
00825 if(ptr >= ptr1 + shm_buf.shm_segsz) return NULL;
00826
00827
00828 thr->tid = *((u_int64_t *)ptr);
00829 ptr += sizeof(u_int64_t);
00830
00831
00832 thr->msg_len = *((int32_t *)ptr);
00833 ptr += sizeof(int32_t);
00834
00835 for(post = 0;post < thr->msg_len;post++) {
00836 if(thr->last == NULL) {
00837 thr->messages = thr->last = fo_alloc(NULL,1,sizeof(t_message),FO_ALLOC_CALLOC);
00838 }
00839 else {
00840 thr->last->next = fo_alloc(NULL,1,sizeof(t_message),FO_ALLOC_CALLOC);
00841 thr->last->next->prev = thr->last;
00842 thr->last = thr->last->next;
00843 }
00844
00845 if(tplname) tpl_cf_init(&thr->last->tpl,tplname);
00846
00847
00848 thr->last->mid = *((u_int64_t *)ptr);
00849 ptr += sizeof(u_int64_t);
00850
00851
00852 thr->last->subject_len = *((u_int32_t *)ptr) - 1;
00853 ptr += sizeof(u_int32_t);
00854
00855
00856 thr->last->subject = ptr;
00857 ptr += thr->last->subject_len + 1;
00858
00859
00860 thr->last->category_len = *((u_int32_t *)ptr) - 1;
00861 ptr += sizeof(u_int32_t);
00862
00863
00864 if(thr->last->category_len) {
00865 thr->last->category = ptr;
00866 ptr += thr->last->category_len + 1;
00867 }
00868
00869
00870 thr->last->content_len = *((u_int32_t *)ptr) - 1;
00871 ptr += sizeof(u_int32_t);
00872
00873
00874 thr->last->content = ptr;
00875 ptr += thr->last->content_len + 1;
00876
00877
00878 thr->last->date = *((time_t *)ptr);
00879 ptr += sizeof(time_t);
00880
00881
00882 thr->last->level = *((u_int16_t *)ptr);
00883 ptr += sizeof(u_int16_t);
00884
00885
00886 thr->last->invisible = *((u_int16_t *)ptr);
00887 thr->last->may_show = 1;
00888 ptr += sizeof(u_int16_t);
00889
00890
00891 thr->last->author_len = *((u_int32_t *)ptr) - 1;
00892 ptr += sizeof(u_int32_t);
00893
00894
00895 thr->last->author = ptr;
00896 ptr += thr->last->author_len + 1;
00897
00898
00899 thr->last->email_len = *((u_int32_t *)ptr);
00900 ptr += sizeof(u_int32_t);
00901
00902
00903 if(thr->last->email_len) {
00904 thr->last->email = ptr;
00905 ptr += thr->last->email_len;
00906 }
00907
00908
00909 thr->last->hp_len = *((u_int32_t *)ptr);
00910 ptr += sizeof(u_int32_t);
00911
00912
00913 if(thr->last->hp_len) {
00914 thr->last->hp = ptr;
00915 ptr += thr->last->hp_len;
00916 }
00917
00918
00919 thr->last->img_len = *((u_int32_t *)ptr);
00920 ptr += sizeof(u_int32_t);
00921
00922
00923 if(thr->last->img_len) {
00924 thr->last->img = ptr;
00925 ptr += thr->last->img_len;
00926 }
00927 }
00928
00929 if(tplname) {
00930 if(thr->messages) {
00931 tpl_cf_setvar(&thr->messages->tpl,"start","1",1,0);
00932
00933 len = snprintf(buff,128,"%d",thr->msg_len);
00934 tpl_cf_setvar(&thr->messages->tpl,"msgnum",buff,len,0);
00935
00936 len = snprintf(buff,128,"%d",thr->msg_len-1);
00937 tpl_cf_setvar(&thr->messages->tpl,"answers",buff,len,0);
00938 }
00939 }
00940
00941 return ptr;
00942 }
00943 #endif
00944
00945
00946
00947 int cf_get_message_through_sock(int sock,rline_t *tsd,t_cl_thread *thr,const u_char *tplname,u_int64_t tid,u_int64_t mid,int del) {
00948 int len;
00949 u_char buff[128],*line;
00950 t_message *msg;
00951
00952 memset(thr,0,sizeof(*thr));
00953
00954 len = snprintf(buff,128,"GET POSTING t%lld m%lld invisible=%d\n",tid,mid,del);
00955 writen(sock,buff,len);
00956
00957 line = readline(sock,tsd);
00958
00959 if(line && cf_strncmp(line,"200 Ok",6) == 0) {
00960 free(line);
00961
00962 thr->tid = tid;
00963 thr->messages = NULL;
00964 thr->last = NULL;
00965
00966 if(cf_get_next_thread_through_sock(sock,tsd,thr,tplname) < 0 && *ErrorString) {
00967 strcpy(ErrorString,"E_COMMUNICATION");
00968 return -1;
00969 }
00970 else {
00971
00972 if(mid == 0) {
00973 thr->threadmsg = thr->messages;
00974 }
00975 else {
00976 for(msg = thr->messages;msg;msg=msg->next) {
00977 if(msg->mid == mid) {
00978 thr->threadmsg = msg;
00979 break;
00980 }
00981 }
00982 }
00983 }
00984 }
00985 else {
00986
00987 if(line) {
00988 len = snprintf(ErrorString,50,"E_FO_%d",atoi(line));
00989 free(line);
00990 }
00991 else {
00992 strcpy(ErrorString,"E_COMMUNICATION");
00993 }
00994
00995 return -1;
00996 }
00997
00998 return 0;
00999 }
01000
01001 #ifdef CF_SHARED_MEM
01002 int cf_get_message_through_shm(void *shm_ptr,t_cl_thread *thr,const u_char *tplname,u_int64_t tid,u_int64_t mid,int del) {
01003 struct shmid_ds shm_buf;
01004 register void *ptr1;
01005 u_int64_t val = 0;
01006 size_t posts,post;
01007 t_message *msg;
01008
01009 if(shmctl(shm_id,IPC_STAT,&shm_buf) != 0) {
01010 strcpy(ErrorString,"E_CONFIG_ERR");
01011 return -1;
01012 }
01013
01014
01015
01016
01017
01018
01019
01020
01021 for(ptr1=shm_ptr+sizeof(time_t);ptr1 < shm_ptr+shm_buf.shm_segsz;) {
01022
01023 val = *((u_int64_t *)ptr1);
01024
01025 if(val == tid) break;
01026
01027 ptr1 += sizeof(u_int64_t);
01028
01029
01030 posts = *((int32_t *)ptr1);
01031 ptr1 += sizeof(int32_t);
01032
01033 for(post = 0;post < posts;post++) {
01034
01035 ptr1 += sizeof(u_int64_t);
01036
01037
01038 val = *((u_int32_t *)ptr1);
01039 ptr1 += sizeof(u_int32_t) + val;
01040
01041
01042 val = *((u_int32_t *)ptr1);
01043 ptr1 += sizeof(u_int32_t);
01044 if(val) ptr1 += val;
01045
01046
01047 val = *((u_int32_t *)ptr1);
01048 ptr1 += sizeof(u_int32_t) + val;
01049
01050
01051 ptr1 += sizeof(time_t) + sizeof(u_int16_t) + sizeof(u_int16_t);
01052
01053
01054 val = *((u_int32_t *)ptr1);
01055 ptr1 += sizeof(u_int32_t) + val;
01056
01057
01058 val = *((u_int32_t *)ptr1);
01059 ptr1 += sizeof(u_int32_t);
01060 if(val) ptr1 += val;
01061
01062
01063 val = *((u_int32_t *)ptr1);
01064 ptr1 += sizeof(u_int32_t);
01065 if(val) ptr1 += val;
01066
01067
01068 val = *((u_int32_t *)ptr1);
01069 ptr1 += sizeof(u_int32_t);
01070 if(val) ptr1 += val;
01071 }
01072 }
01073
01074
01075
01076
01077
01078
01079
01080 if(ptr1 >= shm_ptr + shm_buf.shm_segsz) {
01081 strcpy(ErrorString,"E_FO_404");
01082 return -1;
01083 }
01084
01085 if((ptr1 = cf_get_next_thread_through_shm(ptr1,thr,tplname)) == NULL) {
01086 return -1;
01087 }
01088
01089 if(mid == 0) {
01090 thr->threadmsg = thr->messages;
01091 }
01092 else {
01093 for(msg=thr->messages;msg;msg=msg->next) {
01094 if(msg->mid == mid) {
01095 thr->threadmsg = msg;
01096 break;
01097 }
01098 }
01099 }
01100
01101 if(!thr->threadmsg) {
01102 strcpy(ErrorString,"E_FO_404");
01103 return -1;
01104 }
01105
01106 if((thr->messages->invisible == 1 || thr->threadmsg->invisible == 1) && del == CF_KILL_DELETED) {
01107 strcpy(ErrorString,"E_FO_404");
01108 return -1;
01109 }
01110
01111 return 0;
01112 }
01113 #endif
01114
01115
01116
01117 int cf_register_mod_api_ent(const u_char *mod_name,const u_char *unique_identifier,t_mod_api func) {
01118 size_t len2 = strlen(unique_identifier);
01119 t_mod_api_ent *ent;
01120
01121 if((ent = cf_hash_get(APIEntries,(u_char *)unique_identifier,len2)) != NULL) {
01122 if(cf_strcmp(ent->mod_name,mod_name)) {
01123 return -1;
01124 }
01125
01126 ent->function = func;
01127 }
01128 else {
01129 ent = fo_alloc(NULL,1,sizeof(*ent),FO_ALLOC_MALLOC);
01130 ent->mod_name = strdup(mod_name);
01131 ent->unique_identifier = strdup(unique_identifier);
01132 ent->function = func;
01133
01134 cf_hash_set(APIEntries,(u_char *)unique_identifier,len2,ent,sizeof(*ent));
01135
01136 free(ent);
01137 }
01138
01139 return 0;
01140 }
01141
01142
01143
01144 int cf_unregister_mod_api_ent(const u_char *unid) {
01145 size_t len1 = strlen(unid);
01146 t_mod_api_ent *ent;
01147
01148 if((ent = cf_hash_get(APIEntries,(u_char *)unid,len1)) == NULL) {
01149 return -1;
01150 }
01151
01152 cf_hash_entry_delete(APIEntries,(u_char *)unid,len1);
01153 return 0;
01154 }
01155
01156
01157
01158 t_mod_api cf_get_mod_api_ent(const u_char *unid) {
01159 t_mod_api_ent *ent;
01160 size_t len1 = strlen(unid);
01161
01162 if((ent = cf_hash_get(APIEntries,(u_char *)unid,len1)) == NULL) {
01163 return NULL;
01164 }
01165
01166 return ent->function;
01167 }
01168
01169
01170
01175 void destroy_entry(void *elem) {
01176 t_mod_api_ent *a = (t_mod_api_ent *)elem;
01177 free(a->mod_name);
01178 free(a->unique_identifier);
01179 }
01180
01181
01182
01186 void cf_init(void) {
01187 GlobalValues = cf_hash_new(NULL);
01188 APIEntries = cf_hash_new(destroy_entry);
01189 memset(ErrorString,0,sizeof(ErrorString));
01190 }
01191
01192
01193
01197 void cf_fini(void) {
01198 cf_hash_destroy(GlobalValues);
01199 cf_hash_destroy(APIEntries);
01200 }
01201
01202
01203