/* * Returns an array of rk_member structs. */ struct rk_member * rk_get_membership(u_int32_t conf) { struct get_conf_stat_store *walker; struct rk_member *rm; int i, nmembers; walker = findconf(conf); if ((walker = findconf(conf)) == NULL) { if (rk_confinfo(conf) == NULL) return NULL; /* Komerr will be set already */ walker = findconf(conf); /* Cannot fail */ } if (walker->rkm != NULL) return walker->rkm; if (send_reply("101 %d 0 65535\n", conf)) { komerr = get_int(); get_eat('\n'); return NULL; } nmembers = get_int(); rm = calloc(sizeof(struct rk_member), nmembers+1); get_accept('{'); for (i = 0; i < nmembers; i++) { rm[i].rm_member = get_int(); rm[i].rm_added_by = get_int(); read_in_time(&rm[i].rm_added_at); rm[i].rm_type = get_int(); } get_accept('}'); get_accept('\n'); walker->rkm = rm; return rm; }
static void readin_conf_stat(struct rk_conference *c) { struct rk_aux_item *rai; int i, len; c->rc_name = get_string(); c->rc_type = get_bitfield(); read_in_time(&c->rc_creation_time); read_in_time(&c->rc_last_written); c->rc_creator = get_int(); c->rc_presentation = get_int(); c->rc_supervisor = get_int(); c->rc_permitted_submitters = get_int(); c->rc_super_conf = get_int(); c->rc_msg_of_day = get_int(); c->rc_nice = get_int(); c->rc_keep_commented = get_int(); c->rc_no_of_members = get_int(); c->rc_first_local_no = get_int(); c->rc_no_of_texts = get_int(); c->rc_expire = get_int(); c->rc_aux_item.rc_aux_item_len = len = get_int(); if (len) { rai = calloc(sizeof(struct rk_aux_item), len); c->rc_aux_item.rc_aux_item_val = rai; get_accept('{'); for (i = 0; i < len; i++) read_in_aux_item(&rai[i]); get_accept('}'); } else get_accept('*'); get_accept('\n'); }
struct rk_membership * rk_membership(u_int32_t uid, u_int32_t conf) { struct membership_store *mb; struct rk_membership *m; struct person_store *pp; int len; /* First, force the user into the cache */ if (rk_persinfo(uid) == NULL) return NULL; /* The person do not exist, or something */ pp = findperson(uid); if (pp->next) { mb = findmember(conf, pp->next); if (mb) return &mb->member; } /* No, we failed cache search. Fetch from server. */ if (send_reply("98 %d %d\n", uid, conf)) { komerr = get_int(); get_eat('\n'); return NULL; } mb = calloc(sizeof(struct membership_store), 1); m = &mb->member; m->rm_position = get_int(); read_in_time(&m->rm_last_time_read); m->rm_conference = get_int(); m->rm_priority = get_int(); m->rm_last_text_read = get_int(); len = m->rm_read_texts_len = get_int(); if (len) { int *txts, j; txts = malloc(sizeof(int) * len); get_accept('{'); for (j = 0; j < len; j++) txts[j] = get_int(); get_accept('}'); m->rm_read_texts_val = txts; } else get_accept('*'); m->rm_added_by = get_int(); read_in_time(&m->rm_added_at); m->rm_type = get_int(); mb->mid = m->rm_conference; mb->next = pp->next; pp->next = mb; get_accept('\n'); return m; }
static void rk_mark_read_server_callback(int err, int arg) { if (err) get_eat('\n'); else get_accept('\n'); }
int32_t rk_delete_conf(u_int32_t conf) { int i; if (send_reply("11 %d\n", conf)) { i = get_int(); get_eat('\n'); return i; } get_accept('\n'); return 0; }
int32_t rk_change_conference(u_int32_t conf) { int ret; ret = send_reply("2 %d\n", conf); if (ret) { ret = get_int(); get_eat('\n'); } else get_accept('\n'); return ret; }
/* * XXX - should remember the membership structs also. */ u_int32_t * rk_memberconf(u_int32_t uid) { struct person_store *ps; int i, nconfs; ps = findperson(uid); if (ps == 0) { if (rk_persinfo(uid) == NULL) return NULL; ps = findperson(uid); /* Cannot fail here */ if (ps == 0) printf("EEEK! Person %d finns inte!\n", uid); } if (ps->confs == NULL) { if (send_reply("46 %d 0 65535 0\n", uid)) { komerr = get_int(); get_eat('\n'); return NULL; } nconfs = get_int(); ps->confs = calloc(sizeof(u_int32_t), nconfs+1); if (nconfs) { get_accept('{'); for (i = 0; i < nconfs; i++) { struct rk_time t; read_in_time(&t); ps->confs[i] = get_int(); get_int();get_int();get_int();get_accept('*'); } get_accept('}'); } else get_accept('*'); get_accept('\n'); } return ps->confs; }
int32_t rk_create_person(char *name, char *passwd, u_int32_t btype) { int i; if (send_reply("89 %ldH%s %ldH%s 00000000 0 { }\n", (long)strlen(name), name, (long)strlen(passwd), passwd)) { i = get_int(); get_eat('\n'); return -i; } i = get_int(); get_accept('\n'); return i; }
int32_t rk_sub_member(u_int32_t conf, u_int32_t uid) { int ret; ret = send_reply("15 %d %d\n", conf, uid); if (ret) { ret = get_int(); get_eat('\n'); return ret; } get_accept('\n'); delete_membership_internal(conf, uid); return ret; }
int32_t rk_add_member(u_int32_t conf, u_int32_t uid, u_int8_t prio, u_int16_t where, u_int32_t flags) { int ret; ret = send_reply("100 %d %d %d %d %d\n", conf, uid, prio, where, flags); if (ret) { ret = get_int(); get_eat('\n'); return ret; } get_accept('\n'); delete_membership_internal(conf, uid); return ret; }
int32_t rk_create_conf(char *name, u_int32_t btype) { char *type; int i; type = bitfield2str(btype); if (send_reply("88 %ldH%s %s 0 { }\n", (long)strlen(name), name, &type[28])) { i = get_int(); get_eat('\n'); return -i; } i = get_int(); get_accept('\n'); return i; }
/* * Return the person struct. */ struct rk_person * rk_persinfo(u_int32_t uid) { struct person_store *pp; struct rk_person *p; if ((pp = findperson(uid))) return &pp->person; if (send_reply("49 %d\n", uid)) { komerr = get_int(); get_eat('\n'); return NULL; } pp = calloc(sizeof(struct person_store), 1); pp->uid = uid; p = &pp->person; p->rp_username = get_string(); p->rp_privileges = get_int(); p->rp_flags = get_int(); read_in_time(&p->rp_last_login); p->rp_user_area = get_int(); p->rp_total_time_present = get_int(); p->rp_sessions = get_int(); p->rp_created_lines = get_int(); p->rp_created_bytes = get_int(); p->rp_read_texts = get_int(); p->rp_no_of_text_fetches = get_int(); p->rp_created_persons = get_int(); p->rp_created_confs = get_int(); p->rp_first_created_local_no = get_int(); p->rp_no_of_created_texts = get_int(); p->rp_no_of_marks = get_int(); p->rp_no_of_confs = get_int(); get_accept('\n'); pp->nextp = gps; gps = pp; return p; }
int32_t rk_modify_conf_info(struct rk_modifyconfinfo *rkm) { struct rk_aux_item_input *raii; int i, nr; /* Send request */ send_reply("93 %d ", rkm->rkm_conf); /* Send delete items */ nr = rkm->rkm_delete.rkm_delete_len; send_reply(" %d { ", nr); for (i = 0; i < nr; i++) { send_reply("%d ", rkm->rkm_delete.rkm_delete_val[i]); } /* Send add items */ nr = rkm->rkm_add.rkm_add_len; raii = rkm->rkm_add.rkm_add_val; send_reply("} %d { ", nr); for (i = 0; i < nr; i++) { send_reply("%d 00000000 %d ", raii[i].raii_tag, raii[i].inherit_limit); send_reply("%ldH%s ", (long)strlen(raii[i].raii_data), raii[i].raii_data); } i = 0; if (send_reply("}\n")) { i = get_int(); get_eat('\n'); return i; } get_accept('\n'); reread_conf_stat_bg(rkm->rkm_conf); return 0; }
/* * First connect to the server, then fork away the backend after informing * about our existance. */ struct rk_server * rkom_connect(char *server, char *frontend, char *os_username, char *fevers) { static struct rk_server rs; struct addrinfo hints, *res, *ressave; int n; char *buf2; komerr = -1; /* XXX */ memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; /* Locate our KOM server */ n = getaddrinfo(server, "4894", &hints, &res); if (n < 0) { return NULL; } ressave = res; // Try all possible IP/IPv6 addresses while (res) { /* Create a socket to play with */ if ((pfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) < 0) continue; /* Connect to the server we want to talk with */ if (connect(pfd, res->ai_addr, res->ai_addrlen) == 0) { // Connection successful break; } close(pfd); pfd = -1; res = res->ai_next; } freeaddrinfo(ressave); if (pfd < 0) { // Connection failed return NULL; } if ((sfd = fdopen(pfd, "w")) == NULL) return NULL; setvbuf(sfd, (char *)NULL, _IOLBF, 0); put_char('A'); put_string(os_username); put_char('\n'); buf2 = alloca(8); bzero(buf2, 8); read(pfd, buf2, 7); if (bcmp(buf2, "LysKOM\n", 7)) return NULL; if (*frontend == 0) { buf2 = alloca(20); sprintf(buf2, "%s", "raggkom"); } else { buf2 = alloca(strlen(frontend) + 30); sprintf(buf2, "%s (rkom backend)", frontend); } send_reply("69 %ldH%s %ldH%s\n", (long)strlen(buf2), buf2, (long)strlen(fevers), fevers); get_accept('\n'); /* Check what the server is running */ send_reply("75\n"); rs.rs_proto = get_int(); rs.rs_servtype = get_string(); rs.rs_version = get_string(); get_accept('\n'); /* Set what async messages we want */ send_reply("80 10 { 5 8 9 12 13 14 15 16 17 18 }\n"); get_accept('\n'); return &rs; }
/* * Get the local->global table. Store it as an array from 0 and up, * this is waste of memory but we do not care right now. */ static void read_lgtable(struct get_conf_stat_store *g) { int top, i, base, cont, cnt, num; if (g->mapsz) return; /* Done already */ #if 0 /* It seems like some real conferences are marked as letterboxes. * so the below code seems to do more harm than good. /oj */ if (g->number != myuid && g->confer.rc_type & RK_CONF_TYPE_LETTERBOX) return; /* Do not try to read someones letterbox. */ #endif /* * First get the highest local text number. */ if (send_reply("78 %d\n", g->number)) { get_eat('\n'); /* Do what??? */ return; } get_string(); get_int(); top = get_int(); g->mapsz = top + 50; get_int(); get_accept('\n'); g->map = calloc(g->mapsz, sizeof(int)); base = 1; for (;;) { if (send_reply("103 %d %d 200\n", g->number, base)) { get_eat('\n'); return; /* XXX ??? */ } get_int(); base = get_int(); cont = get_int(); if (get_int() == 0) { /* Sparse block */ cnt = get_int(); if (cnt != 0) { get_accept('{'); for (i = 0; i < cnt; i++) { num = get_int(); g->map[num] = get_int(); } get_accept('}'); } else get_accept('*'); } else { /* Dense block */ num = get_int(); cnt = get_int(); get_accept('{'); for (i = 0; i < cnt; i++) g->map[num++] = get_int(); get_accept('}'); } get_accept('\n'); if (cont == 0) break; } }
void async_new_text(struct mesg *m) { int i, type, cnt, conf, local; struct rk_time time; m->ra.ra_text = get_int(); reread_text_stat_bg(m->ra.ra_text); read_in_time(&time); m->ra.ra_pers = get_int(); get_int();get_int();get_int(); cnt = get_int(); get_accept('{'); for (i = 0; i < cnt; i++) { type = get_int(); switch (type) { case rec_time: case sentat: read_in_time(&time); break; case bcc_recpt: case cc_recpt: case recpt: conf = get_int(); if (get_int() != loc_no) printf("async_new_text: bad protocol\n"); local = get_int(); i++; conf_set_high_local(conf, local, m->ra.ra_text); break; case comm_to: case footn_to: reread_text_stat_bg(get_int()); break; default: get_int(); break; } } get_accept('}'); cnt = get_int(); /* aux-info, throw it away */ if (cnt) { struct rk_time t; char *c; get_accept('{'); for (i = 0; i < cnt; i++) { get_int(); /* aux-no */ get_int(); /* tag */ get_int(); /* creator */ read_in_time(&t); /* created-at */ get_int(); /* flags */ get_int(); /* inherit-limit */ c = get_string(); /* data */ if (*c) free(c); } get_accept('}'); } else get_accept('*'); get_accept('\n'); }
/* * Handle an async message. Put it on a queue; then leave it to * async_handler() to do the rest. */ void async(int handle) { struct rk_text_stat rts; struct mesg *m; int narg, type, tmp; narg = get_int(); type = get_int(); m = calloc(sizeof(struct mesg), 1); m->ra.ra_message = m->ra.ra_message2 = ""; m->ra.ra_type = type; switch (type) { case 15: /* New text created */ async_new_text(m); putinq(m); break; case 12: /* async-send-message */ m->ra.ra_conf = get_int(); m->ra.ra_pers = get_int(); m->ra.ra_message = get_string(); get_accept('\n'); if (handle) { /* XXX - temporary */ /* Get time for message from server */ send_reply("35\n"); read_in_time(&m->ra.ra_time); get_accept('\n'); } else { /* XXX - get local time */ struct tm *tm; time_t clock = time(NULL); tm = localtime(&clock); m->ra.ra_time.rt_seconds = tm->tm_sec; m->ra.ra_time.rt_minutes = tm->tm_min; m->ra.ra_time.rt_hours = tm->tm_hour; m->ra.ra_time.rt_day = tm->tm_mday; m->ra.ra_time.rt_month = tm->tm_mon; m->ra.ra_time.rt_year = tm->tm_year; m->ra.ra_time.rt_day_of_week = tm->tm_wday; m->ra.ra_time.rt_day_of_year = tm->tm_yday; m->ra.ra_time.rt_is_dst = tm->tm_isdst; } putinq(m); break; case 9: /* async-login */ case 13: /* async-logout */ m->ra.ra_pers = get_int(); m->ra.ra_conf = get_int(); get_accept('\n'); putinq(m); break; case 5: /* async-new-name */ tmp = m->ra.ra_pers = get_int(); m->ra.ra_message = get_string(); m->ra.ra_message2 = get_string(); get_accept('\n'); putinq(m); reread_conf_stat_bg(tmp); newname(tmp); break; case 16: /* async-new-recipient */ case 17: /* async-sub-recipient */ reread_text_stat_bg(get_int()); reread_conf_stat_bg(get_int()); get_int(); get_accept('\n'); free(m); break; case 8: /* async-leave-conf */ m->ra.ra_conf = get_int(); get_accept('\n'); putinq(m); break; case 14: /* async-deleted-text */ m->ra.ra_text = get_int(); readin_textstat(&rts); invalidate_local(&rts); reread_text_stat_bg(m->ra.ra_text); putinq(m); break; case 18: /* async-new-membership */ m->ra.ra_pers = get_int(); m->ra.ra_conf = get_int(); get_accept('\n'); putinq(m); break; default: printf("BG: Unknown async %d\n", type); case 7: /* Save database */ get_eat('\n'); free(m); return; } if (handle) async_collect(); }
static int cpl_process_register(struct sip_msg* msg, int no_rpl) { struct disposition *disp; struct disposition_param *param; int ret; int mime; int *mimes; /* make sure that is a REGISTER ??? */ /* here should be the CONTACT- hack */ /* is there a CONTENT-TYPE hdr ? */ mime = parse_content_type_hdr( msg ); if (mime==-1) goto error; /* check the mime type */ LM_DBG("Content-Type mime found %u, %u\n", mime>>16,mime&0x00ff); if ( mime && mime==(TYPE_APPLICATION<<16)+SUBTYPE_CPLXML ) { /* can be an upload or remove -> check for the content-purpose and * content-action headers */ LM_DBG("carrying CPL -> look at Content-Disposition\n"); if (parse_content_disposition( msg )!=0) { LM_ERR("Content-Disposition missing or corrupted\n"); goto error; } disp = get_content_disposition(msg); print_disposition( disp ); /* just for DEBUG */ /* check if the type of disposition is SCRIPT */ if (disp->type.len!=CPL_SCRIPT_LEN || strncasecmp(disp->type.s,CPL_SCRIPT,CPL_SCRIPT_LEN) ) { LM_ERR("bogus message - Content-Type" "says CPL_SCRIPT, but Content-Disposition something else\n"); goto error; } /* disposition type is OK -> look for action parameter */ for(param=disp->params;param;param=param->next) { if (param->name.len==ACTION_PARAM_LEN && !strncasecmp(param->name.s,ACTION_PARAM,ACTION_PARAM_LEN)) break; } if (param==0) { LM_ERR("bogus message - " "Content-Disposition has no action param\n"); goto error; } /* action param found -> check its value: store or remove */ if (param->body.len==STORE_ACTION_LEN && !strncasecmp( param->body.s, STORE_ACTION, STORE_ACTION_LEN)) { /* it's a store action -> get the script from body message and store * it into database (CPL and BINARY format) */ if (do_script_action( msg, STORE_SCRIPT)==-1) goto error; } else if (param->body.len==REMOVE_ACTION_LEN && !strncasecmp( param->body.s, REMOVE_ACTION, REMOVE_ACTION_LEN)) { /* it's a remove action -> remove the script from database */ if (do_script_action( msg, REMOVE_SCRIPT)==-1) goto error; } else { LM_ERR("unknown action <%.*s>\n", param->body.len,param->body.s); goto error; } /* do I have to send to reply? */ if (no_rpl) goto resume_script; /* send a 200 OK reply back */ cpl_fct.sigb.reply( msg, 200, &cpl_ok_rpl,NULL); /* I send the reply and I don't want to return to script execution, so * I return 0 to do break */ goto stop_script; } /* is there an ACCEPT hdr ? */ if ( (ret=parse_accept_hdr(msg))<0) goto error; if (ret==0 || (mimes=get_accept(msg))==0 ) /* accept header not present or no mimes found */ goto resume_script; /* looks if the REGISTER accepts cpl-xml or * */ while (*mimes) { LM_DBG("accept mime found %u, %u\n", (*mimes)>>16,(*mimes)&0x00ff); if (*mimes==(TYPE_ALL<<16)+SUBTYPE_ALL || *mimes==(TYPE_APPLICATION<<16)+SUBTYPE_CPLXML ) break; mimes++; } if (*mimes==0) /* no accept mime that matched cpl */ goto resume_script; /* get the user name from msg, retrieve the script from db * and appended to reply */ if (do_script_download( msg )==-1) goto error; /* do I have to send to reply? */ if (no_rpl) goto resume_script; /* send a 200 OK reply back */ cpl_fct.sigb.reply( msg, 200, &cpl_ok_rpl,NULL); stop_script: return 0; resume_script: return 1; error: /* send a error reply back */ cpl_fct.sigb.reply( msg, cpl_err->err_code, &cpl_err->err_msg, NULL); /* I don't want to return to script execution, so I return 0 to do break */ return 0; }