/* remember a file block using next available cache block */ int remember_fblock(const char *name, int fblock, const char *block) { Content *f; Map *b; int cblock; if (strlen(name)>255) { flog("name %s too long",name); return FALSE; } if (!block) { flog("can't read from NULL pointer"); return FALSE; } f = content_add(name); if ((b=content_fblock_stored(f,fblock))) { cblock=b->cblock; flog("reused old cache block %d",cblock); } else { cblock=next_cblock(); flog("chose new cache block %d",cblock); } storage_put(cblock, (const char *)block); map_add(&(f->bhead),fblock,cblock); flog("stored block %d of %s (cblock %d)",fblock,name,cblock); return TRUE; }
/* map a file block to a specific cache block */ int remember_fblock_at_cblock(const char *name, int fblock, int cblock, const char *block) { Content *f, *g; if (strlen(name)>255) { flog("name %s too long",name); return FALSE; } if (cblock<0 || cblock>=storage_blocks) { flog("cache block %d does not exist",cblock); return FALSE; } f = content_add(name); if ((g=clist_cblock_used(cblock))) { Map *b=content_cblock_used(g,cblock); flog("cache block %d in use for (%s %d) (removing)",cblock,g->name,b->fblock); content_forget_cblock(g,cblock); } Map *b; if ((b=content_fblock_stored(f,fblock))) { flog("file block %d already stored for file %s (local %d) (removing)",fblock,f->name,b->cblock); storage_forget(b->cblock); content_forget_fblock(f,fblock); } storage_put(cblock, (const char *)block); map_add(&(f->bhead),fblock,cblock); flog("stored block %d of %s (cblock %d)",fblock,name,cblock); return TRUE; }
static int _active_user_create(mod_instance_t mi, jid_t jid) { time_t t; os_t os; os_object_t o; log_debug(ZONE, "activating user %s", jid_user(jid)); t = time(NULL); os = os_new(); o = os_object_new(os); os_object_put_time(o, "time", &t); storage_put(mi->sm->st, "active", jid_user(jid), os); os_free(os); return 0; }
/** Handles iq messages */ mod_ret_t archive_iq_in_sess(mod_instance_t mi, sess_t sess, pkt_t pkt) { int prefs, type; int section, ptr; os_t os; os_object_t o; char* owner; char buff[2048]; log_debug(ZONE, "In session"); // we only want to play IQs if((!((pkt->type & pkt_IQ) || (pkt->type & pkt_IQ_SET))) || (pkt->ns != ns_ARCHIVE)) return mod_PASS; log_debug(ZONE, "Passed through packet checks"); // if it has a to, throw it out if(pkt->to != NULL) return -stanza_err_BAD_REQUEST; // Who are we? owner=jid_user(sess->jid); // Check for no type or get to send current settings if((type = (nad_find_attr(pkt->nad, 2, -1, "type", NULL)<0)) || ((NAD_AVAL_L(pkt->nad, type ) == 3) && strncmp("get", NAD_AVAL(pkt->nad, type), 3))) { log_debug(ZONE, "Somebody is asking about settings"); send_arch_prefs(mi, sess, pkt); return mod_HANDLED; } // We are setting stuff if(pkt->type == pkt_IQ_SET) { // Prepare to store them log_debug(ZONE, "Setting archiving preferences..."); os = os_new(); if(os == NULL) return mod_PASS; o = os_object_new(os); if(o == NULL) return mod_PASS; // Get rid of old settings storage_delete(pkt->sm->st, tbl_name "_settings", owner, NULL); log_debug(ZONE, "Got rid of old preferences..."); // Find if there is an default option if(!((prefs=nad_find_elem(pkt->nad, 1, -1, "prefs", 1))>0)) return mod_PASS; ptr=nad_find_attr(pkt->nad, prefs, -1, "default", NULL); if(ptr>0) { // Defaults log_debug(ZONE, "Saving defaults..."); os_object_put(o, "jid", owner, os_type_STRING); if (strncmp("roster",NAD_AVAL(pkt->nad, ptr), NAD_AVAL_L(pkt->nad, ptr))==0) prefs=A_ROSTER; else if(strncmp("always",NAD_AVAL(pkt->nad, ptr), NAD_AVAL_L(pkt->nad, ptr))==0) prefs=A_ALWAYS; else prefs=A_NEVER; os_object_put(o, "setting", &prefs, os_type_INTEGER); log_debug(ZONE, "Setting default to %d...", prefs); // What to save always log_debug(ZONE, "Saving what to save always..."); if(((section = nad_find_elem(pkt->nad, prefs, -1, "always", 1))>0)) { log_debug(ZONE, "Found always section %d...", section); prefs=A_ALWAYS; for(ptr = nad_find_elem(pkt->nad, section, -1, "jid", 1); ptr > 0; ptr = nad_find_elem(pkt->nad, ptr, -1, "jid", 0)) { o = os_object_new(os); strncpy(buff, NAD_CDATA(pkt->nad, ptr), min(2047,NAD_CDATA_L(pkt->nad, ptr))); buff[min(2047,NAD_CDATA_L(pkt->nad, ptr))]=0; os_object_put(o, "jid", buff, os_type_STRING); os_object_put(o, "setting", &prefs, os_type_INTEGER); log_debug(ZONE, "Always archiving %s...", buff); } } // What to never save log_debug(ZONE, "Saving what never save..."); if(((section = nad_find_elem(pkt->nad, 2, -1, "never", 1))>0)) { log_debug(ZONE, "Found never section %d...", section); prefs=A_NEVER; for(ptr = nad_find_elem(pkt->nad, section, -1, "jid", 1); ptr > 0; ptr = nad_find_elem(pkt->nad, ptr, -1, "jid", 0)) { o = os_object_new(os); strncpy(buff, NAD_CDATA(pkt->nad, ptr), min(2047,NAD_CDATA_L(pkt->nad, ptr))); buff[min(2047,NAD_CDATA_L(pkt->nad, ptr))]=0; os_object_put(o, "jid", buff, os_type_STRING); os_object_put(o, "setting", &prefs, os_type_INTEGER); log_debug(ZONE, "Never archiving %s...", buff); } } // Save everything storage_put(pkt->sm->st, tbl_name "_settings", owner, os); } // Send current settings send_arch_prefs(mi, sess, pkt); return mod_HANDLED; } return mod_PASS; }
/** * Saves packet into database. * @param direct Direction of the message - 2 = incomming, 1 = sent */ mod_ret_t savepkt(pkt_t pkt, int direct) { int body=-1, sub=-1, type=-1, arch=-1; char *mem=NULL; const *owner = NULL, *other = NULL; int sz = 0; int archive=default_mode; char filter[2060]; // 2048 is jid_user maximum length time_t t=0; jid_t own_jid, other_jid; os_t os, set_os=NULL; os_object_t o, set_o=NULL; // Is it a message? log_debug(ZONE, "Testing message..."); if ( (pkt->type & pkt_MESSAGE) == 0) return mod_PASS; log_debug(ZONE, "It is a message..."); // 0 element is route, 1st is message, we need subelement of message body = nad_find_elem(pkt->nad, 1, -1, "body", 1); log_debug(ZONE, "Body is at %d", body); sub = nad_find_elem(pkt->nad, 1, -1, "subject", 1); log_debug(ZONE, "Subject is at %d", sub); type = nad_find_attr(pkt->nad, 1, -1, "type", NULL); log_debug(ZONE, "Type %d", type); // Are these parts really interesting? if( ( (body < 0) || (NAD_CDATA_L(pkt->nad, body) < 1) ) && ( (sub < 0) || (NAD_CDATA_L(pkt->nad, sub ) < 1) ) ) return mod_PASS; log_debug(ZONE, "It's meaningful message!", pkt->from); // What direction are we talking about? if (direct == IN_D) { own_jid = pkt->to; other_jid = pkt->from; } else { own_jid = pkt->from; other_jid = pkt->to; } // Get JIDs if(own_jid != NULL) { owner=jid_user(own_jid); } else { return mod_PASS; } if(other_jid != NULL) { other=jid_user(other_jid); } else { return mod_PASS; } // Check settings // Load defaults snprintf(filter, 2060, "(jid=%s)", owner); if((storage_get(pkt->sm->st, tbl_name "_settings", owner, filter, &set_os) == st_SUCCESS) && (os_iter_first(set_os)) && ((set_o=os_iter_object(set_os))!=NULL)) os_object_get_int(set_os, set_o, "setting", &archive); // Cleanup if(set_o != NULL) { os_object_free(set_o); set_o=NULL; } if(set_os != NULL) { os_free(set_os); set_os=NULL; } // Load contact specific snprintf(filter, 2060, "(jid=%s)", other); if((storage_get(pkt->sm->st, tbl_name "_settings", owner, filter, &set_os) == st_SUCCESS) && (os_iter_first(set_os)) && ((set_o=os_iter_object(set_os))!=NULL)) os_object_get_int(set_os, set_o, "setting", &archive); // Cleanup if(set_o != NULL) { os_object_free(set_o); set_o=NULL; } if(set_os != NULL) { os_free(set_os); set_os=NULL; } // Do we need to check roster? if(archive==A_ROSTER) { snprintf(filter, 2060, "(jid=%s)", other); if(storage_get(pkt->sm->st, "roster-items", owner, filter, &set_os) == st_SUCCESS) archive=A_ALWAYS; else archive=A_NEVER; if(set_os != NULL) { os_free(set_os); set_os=NULL; } } // Decide if(archive==A_NEVER) return mod_PASS; // Prepare to store them os = os_new(); if(os == NULL) return mod_PASS; o = os_object_new(os); if(o == NULL) return mod_PASS; // Real storing log_debug(ZONE, "Saving message for %s (other party is %s)", owner, other); // Message // Buffer allocation if(body > 0) { sz = NAD_CDATA_L(pkt->nad, body) / 1024; log_debug(ZONE, "Body size %d", NAD_CDATA_L(pkt->nad, body)); } if(sub > 0) { sz = max(sz, NAD_CDATA_L(pkt->nad, sub) / 1024); log_debug(ZONE, "Subj size %d", NAD_CDATA_L(pkt->nad, sub)); } log_debug(ZONE, "Creating buffer of size %d", sz); mem = (char*)malloc(1024 * (sz+1)); if(mem == NULL) return mod_PASS; log_debug(ZONE, "We got past the buffer allocation."); // JID os_object_put(o, "other_jid", other, os_type_STRING); // Body mem[0]=0; if ( (body > 0) && (NAD_CDATA_L(pkt->nad, body) > 0) ) { strncpy(mem, NAD_CDATA(pkt->nad, body), NAD_CDATA_L(pkt->nad, body)); mem[NAD_CDATA_L(pkt->nad, body)] = 0; } os_object_put(o, "message", mem, os_type_STRING); // Subject mem[0]=0; if ( (sub > 0) && (NAD_CDATA_L(pkt->nad, sub ) > 0) ) { strncpy(mem, NAD_CDATA(pkt->nad, sub), NAD_CDATA_L(pkt->nad, sub)); mem[NAD_CDATA_L(pkt->nad, sub)] = 0; } os_object_put(o, "subject", mem, os_type_STRING); // Type mem[0]=0; if ( (type > 0) && (NAD_AVAL_L(pkt->nad, type ) > 0) ) { strncpy(mem, NAD_AVAL(pkt->nad, type), NAD_AVAL_L(pkt->nad, type)); mem[NAD_AVAL_L(pkt->nad, type)] = 0; } os_object_put(o, "type", mem, os_type_STRING); // To and from resources os_object_put(o, "my_resource", own_jid->resource, os_type_STRING); os_object_put(o, "other_resource", other_jid->resource, os_type_STRING); // Time and direction t=time(NULL); os_object_put(o, "direct", &direct, os_type_INTEGER); os_object_put_time(o, "time", &t); // Message ID if (direct == IN_D) { arch = nad_insert_elem(pkt->nad, 1, -1, "archived", ""); nad_set_attr(pkt->nad,arch,-1,"by",jid_user(own_jid), strlen(jid_user(own_jid))); } set_mid(&(pkt->sm->st), &o, pkt->nad, arch); // Save itself storage_put(pkt->sm->st, tbl_name, owner, os); // Cleanup os_object_free(o); os_free(os); free(mem); log_debug(ZONE, "Saved."); return mod_PASS; }