Beispiel #1
0
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 );
  }

}
Beispiel #2
0
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 );
  }
}
Beispiel #3
0
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 );
  }
}
Beispiel #4
0
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 );
  }
}
Beispiel #5
0
/* 
 * 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;
}
Beispiel #6
0
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;
}