/** Frees the server * \relates adbus_Server */ void adbus_serv_free(adbus_Server* s) { if (s == NULL) return; adbus_Remote* r = s->remotes.next; while (r) { adbus_Remote* next = r->hl.next; adbus_remote_disconnect(r); r = next; } dl_clear(Remote, &s->remotes); for (dh_Iter ii = dh_begin(&s->services); ii != dh_end(&s->services); ++ii) { if (dh_exist(&s->services, ii)) { adbusI_serv_freeservice(dh_val(&s->services, ii)); } } dh_clear(Service, &s->services); dh_free(Service, &s->services); adbusI_serv_freebus(s); adbus_iface_deref(s->busInterface); free(s); }
static void FreeMember(adbus_Member* m) { if (!m) return; if (m->release[0]) m->release[0](m->ruser[0]); if (m->release[1]) m->release[1](m->ruser[1]); for (dh_Iter ii = dh_begin(&m->annotations); ii != dh_end(&m->annotations); ++ii) { if (dh_exist(&m->annotations, ii)) { free((char*) dh_key(&m->annotations, ii)); free(dh_val(&m->annotations, ii)); } } dh_free(StringPair, &m->annotations); for (size_t i = 0; i < dv_size(&m->arguments); i++) { free(dv_a(&m->arguments, i)); } dv_free(String, &m->arguments); for (size_t j = 0; j < dv_size(&m->returns); j++) { free(dv_a(&m->returns, j)); } dv_free(String, &m->returns); free(m->propertyType); free((char*) m->name.str); free(m); }
/* -------------------------------------------------------------------------- */ adbus_Remote* adbusI_serv_remote(adbus_Server* s, const char* name) { dh_Iter ii = dh_get(Service, &s->services, name); if (ii == dh_end(&s->services)) return NULL; struct Service* serv = dh_val(&s->services, ii); return dv_a(&serv->queue, 0).remote; }
static void IntrospectInterfaces(struct ObjectPath* p, d_String* out) { for (dh_Iter bi = dh_begin(&p->interfaces); bi != dh_end(&p->interfaces); ++bi) { if (dh_exist(&p->interfaces, bi)) { adbus_Interface* i = dh_val(&p->interfaces, bi)->interface; ds_cat(out, "\t<interface name=\""); ds_cat_n(out, i->name.str, i->name.sz); ds_cat(out, "\">\n"); for (dh_Iter mi = dh_begin(&i->members); mi != dh_end(&i->members); ++mi) { if (dh_exist(&i->members, mi)) { IntrospectMember(dh_val(&i->members, mi), out); } } ds_cat(out, "\t</interface>\n"); } } }
static void IntrospectAnnotations(adbus_Member* m, d_String* out) { for (dh_Iter ai = dh_begin(&m->annotations); ai != dh_end(&m->annotations); ++ai) { if (dh_exist(&m->annotations, ai)) { ds_cat(out, "\t\t\t<annotation name=\""); ds_cat(out, dh_key(&m->annotations, ai)); ds_cat(out, "\" value=\""); ds_cat(out, dh_val(&m->annotations, ai)); ds_cat(out, "\"/>\n"); } } }
static int ProxiedGetAllProperties(adbus_CbData* d) { adbus_Interface* interface = (adbus_Interface*) d->user1; // User2 is already set to the bind cuser2 // Iterate over the properties and marshal up the values adbus_BufArray a; adbus_msg_setsig(d->ret, "a{sv}", 5); adbus_msg_beginarray(d->ret, &a); d_Hash(MemberPtr)* mbrs = &interface->members; for (dh_Iter mi = dh_begin(mbrs); mi != dh_end(mbrs); ++mi) { if (dh_exist(mbrs, mi)) { adbus_Member* mbr = dh_val(mbrs, mi); // Check that it is a property if (mbr->type != ADBUSI_PROPERTY) { continue; } // Check that we can read the property adbus_MsgCallback callback = mbr->getPropertyCallback; if (!callback) { continue; } // Set the property entry adbus_BufVariant v; adbus_msg_arrayentry(d->ret, &a); adbus_msg_begindictentry(d->ret); adbus_msg_string(d->ret, mbr->name.str, mbr->name.sz); adbus_msg_beginvariant(d->ret, &v, mbr->propertyType, -1); d->getprop = adbus_msg_argbuffer(d->ret); d->user1 = mbr->getPropertyData; if (callback(d) || adbus_msg_type(d->ret) == ADBUS_MSG_ERROR) goto err; adbus_msg_endvariant(d->ret, &v); adbus_msg_enddictentry(d->ret); } } adbus_msg_endarray(d->ret, &a); adbus_msg_end(d->ret); adbus_iface_deref(interface); return 0; err: adbus_iface_deref(interface); return -1; }
/** Derefs an interface. * \relates adbus_Interface */ void adbus_iface_deref(adbus_Interface* i) { if (i && adbus_InterlockedDecrement(&i->ref) == 0) { if (ADBUS_TRACE_MEMORY) { adbusI_log("free interface %s", i->name); } for (dh_Iter ii = dh_begin(&i->members); ii != dh_end(&i->members); ++ii) { if (dh_exist(&i->members, ii)) FreeMember(dh_val(&i->members, ii)); } dh_free(MemberPtr, &i->members); free((char*) i->name.str); free(i); } }
/* -------------------------------------------------------------------------- */ int adbusI_serv_releasename( adbus_Server* s, adbus_Remote* r, const char* name) { dh_Iter ii = dh_get(Service, &s->services, name); if (ii == dh_end(&s->services)) return ADBUS_SERVICE_RELEASE_INVALID_NAME; // We have bidirectional links with the remote having a list of services // it is queued for (or owns) and the service having its list of remotes // queued. First we remove the service from the remote list via // removeServiceFromRemote, then we remove the service from the queue. We // need to special case if the remote currently owns the service, since we // need to then either shift ownership to the next in the queue or remove // the service. struct Service* serv = dh_val(&s->services, ii); adbusI_serv_removeServiceFromRemote(r, serv); if (dv_a(&serv->queue, 0).remote == r) { dv_remove(ServiceOwner, &serv->queue, 0, 1); if (dv_size(&serv->queue) == 0) { adbusI_serv_ownerchanged(s, serv->name, r, NULL); adbusI_serv_freeservice(serv); dh_del(Service, &s->services, ii); } else { adbusI_serv_ownerchanged(s, serv->name, r, dv_a(&serv->queue, 0).remote); } return ADBUS_SERVICE_SUCCESS; } for (size_t i = 1; i < dv_size(&serv->queue); i++) { if (dv_a(&serv->queue, 0).remote == r) { dv_remove(ServiceOwner, &serv->queue, i, 1); return ADBUS_SERVICE_SUCCESS; } } return ADBUS_SERVICE_RELEASE_NOT_OWNER; }
static adbus_Member* GetMethod( adbus_Interface* i, adbusI_MemberType type, const char* name, int size) { dh_strsz_t mstr = { name, size >= 0 ? (size_t) size : strlen(name), }; dh_Iter ii = dh_get(MemberPtr, &i->members, mstr); if (ii == dh_end(&i->members)) return NULL; adbus_Member* m = dh_val(&i->members, ii); if (m->type != type) return NULL; return m; }
void rcv_account_delete (struct htlc_conn *htlc) { struct htlc_conn *htlcp; u_int8_t login[32]; u_int16_t llen; int err; dh_start(htlc) if (dh_type != HTLC_DATA_LOGIN) continue; llen = dh_len > 31 ? 31 : dh_len; hl_decode(login, dh_data, llen); /* terminate the login name with a null character */ login[llen] = 0; /* log the account deletion */ hxd_log("%s:%s:%u - delete account %s", htlc->name, htlc->login, htlc->uid, login); /* delete the account, test for error */ if ((err = account_delete(login))) { snd_strerror(htlc, err); continue; } dh_end() /* confirm that the account was successfully deleted */ hlwrite(htlc, HTLS_HDR_TASK, 0, 0); /* kick any users using this account (can be turned off in hxd.conf) */ if (hxd_cfg.emulation.kick_transients) { for (htlcp = htlc_list->next; htlcp; htlcp = htlcp->next) { /* check if user is logged in with the account */ if (!strcmp(login, htlcp->login)) { htlc_close(htlcp); } } /* for */ } /* execute a script after deleting the account */ if (strlen(hxd_cfg.paths.duser)) { switch (fork()) { case -1: hxd_log("rcv_account_delete: fork: %s", strerror(errno)); break; case 0: { char *envp[3], acctdir[MAXPATHLEN + 16], account[32]; char rlpath[MAXPATHLEN], expath[MAXPATHLEN]; #ifdef HAVE_CORESERVICES resolve_alias_path(hxd_cfg.paths.duser, expath); resolve_alias_path(hxd_cfg.paths.accounts, rlpath); #else realpath(hxd_cfg.paths.duser, expath); realpath(hxd_cfg.paths.accounts, rlpath); #endif snprintf(acctdir, sizeof(acctdir), "ACCOUNTDIR=%s", rlpath); snprintf(account, sizeof(htlc->login), "ACCOUNT=%s", login); envp[0] = acctdir; envp[1] = account; envp[2] = 0; execle(expath, expath, 0, envp); exit(0); } } } }