bool Manager::delete_interface(const std::string& name, bool send_model_signal) { Prefixed_name split = split_name(name); if( split.second == "" ) { // if we're at the end of the path InterfaceMap::iterator it_row = interfaces_.find(split.first); if(it_row == interfaces_.end() ) { appli_warning( split.first << " does not exist" << std::endl ); return false; } if(send_model_signal && model_) { model_->begin_remove_item(this,std::distance(interfaces_.begin(), it_row)); } int n = interfaces_.erase(split.first); if(send_model_signal && model_) model_->end_remove_item(); return true; } else { // go down one level of the tree, if it exists SmartPtr<Directory> subdir = get_subdir( split.first ); if( subdir.raw_ptr() == 0 ) return false; else return subdir->delete_interface( split.second, send_model_signal ); } }
Named_interface* Manager::new_interface_raw(const std::string& type_param, const std::string& name ) { // Look for the required manager and create the new interface without smart pointer. // The memory allocated is not managed, it is the user to delete it when not needed // If no factory method can be found to create the interface, look // for a plugin that would provide a factory method. Prefixed_name split = split_name(name); if( split.second == "" ) { // we're at the end of the path //---------- // Extract the type of the object to be created // and the parameters for the creation. These information are // contained in string "type_param" String_Op::string_pair split_params = String_Op::split_string( type_param, "://", true ); std::string type = split_params.first; std::string param = split_params.second; CallBackMap::iterator it = factory_.find(type); if( it == factory_.end() ) { // No factory method found => try loading a plugin bool loaded = load_library( type ); if( loaded ) it = factory_.find(type); } if( it == factory_.end() ) { // No factory method could be found, and no plugin provides a // suitable one appli_warning( "No factory method to create type " << type << std::endl << "Interface ..." << name << " could not be created" << std::endl ); return 0; } // If we've reached this point, it means we have a factory method // to create the requested interface. std::pair<InterfaceMap::iterator, bool> pos; return (it->second)( param ); } else { // we're not at the end of the path. // go down one level of the tree, if it exists, and try again SmartPtr<Directory> subdir = get_subdir( split.first ); if( subdir.raw_ptr() == 0 ) { appli_warning( "Could not descend into directory " << split.first << std::endl ); return 0; } else return subdir->new_interface_raw( type_param, split.second ); } }
SmartPtr<Named_interface> Manager::interface(const std::string& name) { Prefixed_name split = split_name(name); if( split.second == "" ) { // if we're at the end of the path InterfaceMap::iterator it = interfaces_.find(split.first); if( it != interfaces_.end() ) { // if we found an object called "name" return it->second; } else return 0; } else { // go down one level of the tree, if it exists SmartPtr<Directory> subdir = get_subdir( split.first ); if( subdir.raw_ptr() == 0 ) return 0; else return subdir->interface( split.second ); } }
SmartPtr<Named_interface> Manager::new_interface(const std::string& type_param, const std::string& name, std::string* final_name ) { // Look for the required manager and create the new interface. // If no factory method can be found to create the interface, look // for a plugin that would provide a factory method. // It would be better to use the functionalities in namespace String_Op // rather than the split function defined above... I'll change that later Prefixed_name split = split_name(name); if( split.second == "" ) { // we're at the end of the path //---------- // Extract the type of the object to be created // and the parameters for the creation. These information are // contained in string "type_param" String_Op::string_pair split_params = String_Op::split_string( type_param, "://", true ); std::string type = split_params.first; std::string param = split_params.second; CallBackMap::iterator it = factory_.find(type); if( it == factory_.end() ) { // No factory method found => try loading a plugin bool loaded = load_library( type ); if( loaded ) it = factory_.find(type); } if( it == factory_.end() ) { // No factory method could be found, and no plugin provides a // suitable one appli_warning( "No factory method to create type " << type << std::endl << "Interface ..." << name << " could not be created" << std::endl ); return 0; } // If we've reached this point, it means we have a factory method // to create the requested interface. //First we need to find the name for the interface // if the interface has no name, don't manage it std::string interface_name = ""; if( !split.first.empty() ) { InterfaceMap::iterator it_interf = interfaces_.find(split.first); if(it_interf == interfaces_.end()) { // The interfaces does not already exist interface_name = split.first; } else { // If the name is already used, modify it if final_name is not null if( !final_name ) { appli_warning( "Interface " << split.first << " already exists" ); return 0; } else { int count = 1; std::string initial_name = split.first; do { final_name->erase(); std::ostringstream ostr; ostr << initial_name << "_" << count++; final_name->append( ostr.str() ); } while ( interfaces_.find(split.first) != interfaces_.end() ); interface_name = *final_name; } } if(model_) { InterfaceMap::iterator it_row = interfaces_.lower_bound(interface_name); model_->begin_insert_item(this,std::distance(interfaces_.begin(), it_row)); } //SmartPtr<Named_interface> interf = (it->second)( param ); SmartPtr<Named_interface> interf = (it->second)( param ); interf->name(interface_name); interf->parent_interface(this); interfaces_.insert( std::make_pair( interface_name, interf) ); if(model_) model_->end_insert_item(); return interf; } else { // No name hence will not be managed return (it->second)( param ); } } else { // we're not at the end of the path. // go down one level of the tree, if it exists, and try again SmartPtr<Directory> subdir = get_subdir( split.first ); if( subdir.raw_ptr() == 0 ) { appli_warning( "Could not descend into directory " << split.first << std::endl ); return 0; } else return subdir->new_interface( type_param, split.second, final_name ); } }
/* * Attempt to read an envelope from queue file: * - opens and locks the file. * - if the lock succeeds, check that file hasn't changed since opening. If it has * return NULL (i.e. file is being processed elsewhere -- race condition), otherwise read it. * - If should block is 1, then does a potentially blocking attempt to lock the file. */ static MmsEnvelope *mms_queue_readenvelope(char *qf, char *mms_queuedir, int shouldblock) { Octstr *fname; int fd; Octstr *qdata, *s; ParseContext *p; MmsEnvelope *e; int okfile = 0; char subdir[64]; char realqf[QFNAMEMAX]; char xqf[QFNAMEMAX+64]; struct qfile_t *qfs; get_subdir(qf, subdir, realqf); /* break it down... */ fname = octstr_format( "%.128s/%s%s", mms_queuedir, subdir, realqf); strncpy(xqf, octstr_get_cstr(fname), sizeof xqf); #ifdef SunOS if ((fd = open(octstr_get_cstr(fname), O_RDWR)) < 0) { #else if ((fd = open(octstr_get_cstr(fname), O_RDONLY)) < 0) { #endif debug("",0,"mms_queue_readenvelope: could not open file %s", octstr_get_cstr(fname)); octstr_destroy(fname); return NULL; } else if (mm_lockfile(fd, octstr_get_cstr(fname), shouldblock) != 0) { debug("",0,"mms_queue_readenvelope: could not lock file %s", octstr_get_cstr(fname)); unlock_and_close(fd); octstr_destroy(fname); return NULL; } debug("",0,"locked and opened file: %s", octstr_get_cstr(fname)); e = mms_queue_create_envelope(NULL, NULL, NULL, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, qf, NULL, sizeof (struct qfile_t), NULL); qfs = e->qfs_data; qfs->fd = fd; strncpy(qfs->name, realqf, sizeof qfs->name); strncpy(qfs->subdir, subdir, sizeof qfs->subdir); strncpy(qfs->dir, mms_queuedir, sizeof qfs->dir); qdata = octstr_read_file(octstr_get_cstr(fname)); octstr_destroy(fname); if (qdata == NULL) qdata = octstr_imm(""); p = parse_context_create(qdata); for (s = parse_get_line(p); s; s = parse_get_line(p)) { char *line = octstr_get_cstr(s); int ch = line[0]; char *res = line + 1; char *ptmp; switch (ch) { Octstr *t; MmsEnvelopeTo *to; case 'T': t = octstr_create(res); e->msgtype = mms_string_to_message_type(t); octstr_destroy(t); if (e->msgtype < 0) { e->msgtype = 0; error(0, "mms_queueread: Unknown MMS message type (%s) in file %s, skipped!\n", res, xqf); } break; case 'I': e->msgId = octstr_create(res); break; case 'i': strncpy(e->src_interface, res, sizeof e->src_interface); break; case 'F': e->from = octstr_create(res); if (mms_validate_address(e->from) != 0) { warning(0, "mms_queueread: Mal-formed address [%s] in file %s! " "Attempting fixup.", res, xqf); _mms_fixup_address(&e->from, NULL, NULL, 1); } break; case 'R': t = octstr_create(res); if (mms_validate_address(t) != 0) { warning(0, "mms_queueread: Mal-formed address [%s] in file %s! " "Attempting fixup.", res, xqf); _mms_fixup_address(&t, NULL, NULL, 1); } to = gw_malloc(sizeof *to); to->rcpt = t; to->process = 1; gwlist_append(e->to, to); break; case 'C': e->created = atol(res); break; case 'L': e->lasttry = atol(res); break; case 'D': e->sendt = atol(res); break; case 'X': e->expiryt = atol(res); break; case 'N': e->attempts = atol(res); break; case 'P': e->fromproxy = octstr_create(res); break; case 'M': e->mdata = octstr_create(res); break; case 'p': e->viaproxy = octstr_create(res); break; case 'S': e->msize = atol(res); break; case 's': e->subject = octstr_create(res); break; case 't': e->token = octstr_create(res); break; case 'f': e->lastaccess = atol(res); break; case 'b': e->bill.billed = 1; e->bill.amt = atof(res); break; case 'r': e->dlr = 1; break; case 'V': e->vaspid = octstr_create(res); break; case 'v': e->vasid = octstr_create(res); break; case 'U': e->url1 = octstr_create(res); break; case 'u': e->url2 = octstr_create(res); break; case 'H': if (e->hdrs == NULL) e->hdrs = http_create_empty_headers(); if ((ptmp = index(res, ':')) == NULL) error(0, "Incorrectly formatted line %s in queue file %s!", line, xqf); else { char *value = ptmp + 1; char hname[512]; int xlen = (ptmp - res < sizeof hname) ? ptmp - res : -1 + sizeof hname; strncpy(hname, res, xlen); hname[xlen] = 0; /* terminate it. */ http_header_add(e->hdrs, hname, value); } break; case '.': okfile = 1; break; default: error(0, "Unknown QF header %c in file %s!", ch, xqf); break; } octstr_destroy(s); if (okfile) break; /* We are done. */ } parse_context_destroy(p); octstr_destroy(qdata); /* We should properly validate the queue file here. */ if (!okfile) { free_envelope(e,0); e = NULL; error(0, "Corrupt queue control file: %s", xqf); } return e; } /* Updates envelope to queue file: * - opens temp file * - writes output to temp file, if not new else writes directly. * - renames temp file to queue file (if not new) * This function doesn't check that this envelope is useless (i.e. no recipients) * - If function returns -1, caller should check errno for error. */ static int writeenvelope(MmsEnvelope *e, int newenv) { Octstr *tfname = NULL; char *s; char buf[512]; int fd; int i, n; int res = 0; struct qfile_t *qfs = e ? e->qfs_data : NULL; gw_assert(e); if (newenv) fd = qfs->fd; else { tfname = octstr_format( "%s/%s%c%s.%d", qfs->dir, qfs->subdir, MTF, qfs->name + 1, random()); fd = open(octstr_get_cstr(tfname), O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP); if (fd < 0 ) { error(0, "mms_queueadd: Failed to open temp file %s: error = %s\n", octstr_get_cstr(tfname), strerror(errno)); res = -1; goto done; } else if (mm_lockfile(fd, octstr_get_cstr(tfname), 0) != 0) { /* Lock it. */ error(0, "mms_queueadd: Failed lock temp file %s: error = %s\n", octstr_get_cstr(tfname), strerror(errno)); res = -1; goto done; } } /* Write out. */ s = (char *)mms_message_type_to_cstr(e->msgtype); if (!s) { error(0, "mms_queuewrite: Unknown MMS message type %d! Skipped\n", e->msgtype); s = ""; } _putline(fd, "T", s); if (e->msgId) _putline(fd, "I", octstr_get_cstr(e->msgId)); if (e->src_interface[0]) _putline(fd, "i", e->src_interface); if (e->from) _putline(fd, "F", octstr_get_cstr(e->from)); if (e->to) n = gwlist_len(e->to); else n = 0; for (i = 0; i < n; i++) { MmsEnvelopeTo *to = gwlist_get(e->to, i); if (to->process) _putline(fd, "R", octstr_get_cstr(to->rcpt)); } /* Output headers if any. */ n = (e->hdrs) ? gwlist_len(e->hdrs) : 0; for (i = 0; i < n; i++) { Octstr *h = NULL, *v = NULL; http_header_get(e->hdrs, i, &h, &v); if (h && v) { Octstr *x = octstr_format("%s:%s", octstr_get_cstr(h), octstr_get_cstr(v)); _putline(fd, "H", octstr_get_cstr(x)); octstr_destroy(x); } if (h) octstr_destroy(h); if (v) octstr_destroy(v); } sprintf(buf, "%ld", e->created); _putline(fd, "C", buf); if (e->lasttry) { sprintf(buf, "%ld", e->lasttry); _putline(fd, "L", buf); } if (e->sendt) { sprintf(buf, "%ld", e->sendt); _putline(fd, "D", buf); } if (e->expiryt) { sprintf(buf, "%ld", e->expiryt); _putline(fd, "X", buf); } if (e->attempts) { sprintf(buf, "%ld", e->attempts); _putline(fd, "N", buf); } if (e->lastaccess) { sprintf(buf, "%ld", e->lastaccess); _putline(fd, "f", buf); } sprintf(buf, "%ld", e->msize); _putline(fd, "S", buf); if (e->fromproxy) _putline(fd, "P", octstr_get_cstr(e->fromproxy)); if (e->mdata) _putline(fd, "M", octstr_get_cstr(e->mdata)); if (e->subject) _putline(fd, "s", octstr_get_cstr(e->subject)); if (e->viaproxy) _putline(fd, "p", octstr_get_cstr(e->viaproxy)); if (e->token) _putline(fd, "t", octstr_get_cstr(e->token)); if (e->vaspid) _putline(fd, "V", octstr_get_cstr(e->vaspid)); if (e->vasid) _putline(fd, "v", octstr_get_cstr(e->vasid)); if (e->url1) _putline(fd, "U", octstr_get_cstr(e->url1)); if (e->url2) _putline(fd, "u", octstr_get_cstr(e->url2)); if (e->dlr) _putline(fd, "r", "Yes"); if (e->bill.billed) { sprintf(buf, "%.3f", e->bill.amt); _putline(fd,"b", buf); } _putline(fd, "", "."); fsync(fd); /* Sync data. */ if (!newenv) { /* An update */ Octstr *qfname; qfname = octstr_format("%s/%s%s", qfs->dir, qfs->subdir, qfs->name); if (rename(octstr_get_cstr(tfname), octstr_get_cstr(qfname)) < 0) { error(0, "mms_queuewrite: Failed to rename %s to %s: error = %s\n", octstr_get_cstr(qfname), octstr_get_cstr(tfname), strerror(errno)); unlock_and_close(fd); /* Close new one, keep old one. */ res = -1; } else { /* On success, new descriptor replaces old one and we close old one. */ unlock_and_close(qfs->fd); qfs->fd = fd; } octstr_destroy(qfname); } done: octstr_destroy(tfname); return res; }
static int merge_dirs (const char *root, char **dirs, int n_dirs) { DIR *dir; char *subdirs[n_dirs]; struct dirent *dirent; struct stat st; char *src_path; char *dest_path; int conflict; int i, j; for (i = 0; i < n_dirs; i++) { if (dirs[i] == NULL) continue; dir = opendir (dirs[i]); if (dir == NULL) continue; while ((dirent = readdir (dir)) != NULL) { src_path = strconcat (dirs[i], "/", dirent->d_name); if (strcmp (dirent->d_name, ".") == 0 || strcmp (dirent->d_name, "..") == 0) continue; dest_path = strconcat (root, "/", dirent->d_name); if (lstat (dest_path, &st) == 0) { free (dest_path); continue; /* We already copyed this file */ } if (lstat (src_path, &st) < 0) { free (dest_path); continue; } if (S_ISCHR (st.st_mode) || S_ISBLK (st.st_mode) || S_ISFIFO (st.st_mode) || S_ISSOCK (st.st_mode)) { fprintf (stderr, "WARNING: ignoring special file %s\n", src_path); free (dest_path); continue; } conflict = has_conflict (dirs, n_dirs, dirent->d_name, i); if (conflict == NO_CONFLICTS) { bind_file (src_path, dest_path, &st); } else if (conflict == DIR_CONFLICT) { if (mkdir (dest_path, st.st_mode & 0777)) fatal_errno ("create merged dir"); if (lchown(dest_path, st.st_uid, st.st_gid) < 0) fatal_errno ("lchown"); for (j = 0; j < n_dirs; j++) subdirs[j] = get_subdir (dirs[j], dirent->d_name); merge_dirs (dest_path, subdirs, n_dirs); for (j = 0; j < n_dirs; j++) { if (subdirs[j]) free (subdirs[j]); } } else fatal ("Filename conflicts, refusing to mount\n"); free (dest_path); } } return 0; }