Exemplo n.º 1
0
/********************************************************************
 * FUNCTION load_debug_test_module 
 * 
 * RETURNS:
 *     status
 *********************************************************************/
static status_t load_debug_test_module( agt_profile_t* profile )
{
#define TESTMOD             (const xmlChar *)"test"
#define TESTFEATURE1        (const xmlChar *)"feature1"
#define TESTFEATURE2        (const xmlChar *)"feature2"
#define TESTFEATURE3        (const xmlChar *)"feature3"
#define TESTFEATURE4        (const xmlChar *)"feature4"

    log_debug2("\nnetconfd: Loading Debug Test Module");

    /* Load test module */
    status_t res = ncxmod_load_module( TESTMOD, NULL, 
                                       &profile->agt_savedevQ, NULL );

    if (res != NO_ERR) {
        return res;
    } else {
        agt_enable_feature(TESTMOD, TESTFEATURE1);
        agt_disable_feature(TESTMOD, TESTFEATURE2);
        agt_enable_feature(TESTMOD, TESTFEATURE3);
        agt_disable_feature(TESTMOD, TESTFEATURE4);
    }
}
Exemplo n.º 2
0
static char *myunquote(const char *s, const char *e)
{
  char *r = trim(s);
  char *p = &r[strlen(e)];
  while (isspace(p[0]) && p[0] != '\0') {
    p++;
  }
  if (p[0] == '\0') {
    return mystrdup("");
  } else {
    if (p[0] == '"') {
      p += 1;
    }
    if (p[strlen(p) - 1] == '"') {
      p[strlen(p) - 1] = '\0';
    }
    char *k = mystrdup(p);
    trim_replace(&k);
    mc_free(r);
    log_debug2("k=%s", k);
    return k;
  }
}
Exemplo n.º 3
0
void
input_state_intermediate(u_char ch, struct input_ctx *ictx)
{
	if (INPUT_INTERMEDIATE(ch)) {
		/* Multiple intermediates currently ignored. */
		log_debug2(":: in2 %zu: %hhu (%c)", ictx->off, ch, ch);
		return;
	}

	if (INPUT_PARAMETER(ch)) {
		input_state(ictx, input_state_first);
		input_handle_private_two(ch, ictx);
		return;
	}

	if (INPUT_UPPERCASE(ch) || INPUT_LOWERCASE(ch)) {
		input_state(ictx, input_state_first);
		input_handle_standard_two(ch, ictx);
		return;
	}

	input_state(ictx, input_state_first);
}
Exemplo n.º 4
0
void bec::ValidationManager::scan(GRTManager* grtm)
{
  const std::vector<app_PluginRef> plugins = grtm->get_plugin_manager()->get_plugins_for_group("");
  
  for (size_t i = 0; i < plugins.size(); ++i)
  {
    if (bec::ValidationManager::is_validation_plugin(plugins[i]))
    {
      grt::Module* module = plugins[i]->get_grt()->get_module(plugins[i]->moduleName());
      grt::CPPModule* cpp_module = dynamic_cast<grt::CPPModule*>(module);
      if (cpp_module)
      { 
        // Handle plugin directly
        //1. Fetch slot
        log_debug2("ValidationManager: %s", plugins[i]->caption().c_str());
      }
      else
      {
        throw std::logic_error(std::string("Handling of non-C++ validation plugins is not implemented. ") + __FILE__);
      }
    }
  }
}
Exemplo n.º 5
0
/********************************************************************
* FUNCTION allocate_txid
*
* Allocate a new transaction ID 
*
* SIDE EFFECTS:
*    agt_cfg_txid is updated
* RETURNS:
*    new value of agt_cfg_txid
*********************************************************************/
static cfg_transaction_id_t
    allocate_txid (void)
{
    ++agt_cfg_txid;
    if (agt_cfg_txid == 0) {
        /* skip value zero */
        ++agt_cfg_txid;
    }
    log_debug2("\nAllocated transaction ID '%llu'", 
               (unsigned long long)agt_cfg_txid);

    /* for now, update txid file every time new transaction allocated
     * may need to change this to timer-based task if lots of
     * transactions requested per second   */
    status_t res = agt_cfg_update_txid();
    if (res != NO_ERR) {
        log_error("\nError: could not update TXID file (%s)",
                  get_error_string(res));
    }

    return agt_cfg_txid;

}  /* allocate_txid */
Exemplo n.º 6
0
void library_view_col_visible(GtkCheckMenuItem* item, GObject* lview)
{
  library_view_t* view = (library_view_t*) g_object_get_data(lview, "library_view_t");
  
  if (view->column_layout_changing) {
    return;
  }
  
  //long long hash = playlist_player_get_hash(backtobasics_player(view->btb));
  long long hash = playlist_model_tracks_hash(view->playlist_model);
  log_debug2("set column layout for hash %lld", hash);
  
  const char* names[] = {
    "chk_col_nr", "chk_col_title", "chk_col_artist", "chk_col_composer",
    "chk_col_piece", "chk_col_album", "chk_col_albumartist", "chk_col_genre",
    "chk_col_year", "chk_col_length", NULL
  };
  const playlist_column_enum es[] = {
      PLAYLIST_MODEL_COL_NR, PLAYLIST_MODEL_COL_TITLE, PLAYLIST_MODEL_COL_ARTIST,
      PLAYLIST_MODEL_COL_COMPOSER, PLAYLIST_MODEL_COL_PIECE, 
      PLAYLIST_MODEL_COL_ALBUM_TITLE, PLAYLIST_MODEL_COL_ALBUM_ARTIST,
      PLAYLIST_MODEL_COL_GENRE, PLAYLIST_MODEL_COL_YEAR, PLAYLIST_MODEL_COL_LENGTH,
      PLAYLIST_MODEL_N_COLUMNS
  };
  int i;
  const char* name = gtk_widget_get_name(GTK_WIDGET(item));
  for(i = 0; names[i] != NULL && strcmp(name, names[i]) != 0;++i);
  
  if (names[i] != NULL) {
    char cfgitem[200];
    sprintf(cfgitem,"library.cols.hash_%lld.%s", hash, names[i]);
    int active =  gtk_check_menu_item_get_active(item);
    el_config_set_int(btb_config(view->btb), cfgitem, active);
    int ei = es[i];
    gtk_tree_view_column_set_visible(view->cols[ei], gtk_check_menu_item_get_active(item));
  }
}
Exemplo n.º 7
0
int
match_age_match(struct mail_ctx *mctx, struct expritem *ei)
{
	struct match_age_data	*data = ei->data;
	struct account		*a = mctx->account;
	struct mail		*m = mctx->mail;
	time_t			 then, now;
	long long		 diff;

	/* Get current and mail time. */
	now = time(NULL);
	if (mailtime(m, &then) != 0) {
		/* Invalid, so return true if testing validity, else false. */
		if (data->time < 0)
			return (MATCH_TRUE);
		return (MATCH_FALSE);
	}
	/* Not invalid, so return false if validity is being tested for. */
	if (data->time < 0)
		return (MATCH_FALSE);

	/* Work out the time difference. */
	diff = difftime(now, then);
	log_debug2("%s: time difference is %lld (now %lld, then %lld)", a->name,
	    diff, (long long) now, (long long) then);
	if (diff < 0) {
		/* Reset all ages in the future to zero. */
		diff = 0;
	}

	if (data->cmp == CMP_LT && diff < data->time)
		return (MATCH_TRUE);
	else if (data->cmp == CMP_GT && diff > data->time)
		return (MATCH_TRUE);
	return (MATCH_FALSE);
}
Exemplo n.º 8
0
static void ngx_http_clojure_jvm_worker_result_handler(ngx_event_t *e) {
	jlong rp;
	ngx_int_t rc;
	ssize_t rdc = 0;
	log_debug0(ngx_http_clojure_global_cycle->log, "ngx clojure: ngx clojure read event ......");

	do {
		//sizeof(jlong) is zero on win32 vc2010, so we have to use const 8
		if ((rdc = ngx_http_clojure_pipe_read(nc_jvm_worker_pipe_fds[0], &rp, 8))
				< 0) {
			return;
		} else if (rdc > 0) {
			log_debug2(ngx_http_clojure_global_cycle->log,
					"ngx clojure: ngx clojure read event %" PRIu64 ", size: %d",
					rp, rdc);
			rc = ngx_http_clojure_handle_response(rp);
			if (rc != NGX_OK) {
				ngx_log_error(NGX_LOG_ERR, e->log, 0,
						"ngx clojure: ngx_http_clojure_handle_response failed");
			}
		}
	} while (rdc != 0);

}
Exemplo n.º 9
0
/********************************************************************
 * FUNCTION expand_alias
 * 
 * Check if the first token is an alias name
 * If so, construct a new command line with the alias contents
 *
 * INPUT:
 *   line == command line to check and possibly convert
 *   res == address of return status
 *
 * OUTPUTS:
 *   *res == return status (ERR_NCX_SKIPPED if nothing done)
 *
 * RETURNS:
 *   pointer to malloced command string if *res==NO_ERR
 *   NULL if *res==ERR_NCX_SKIPPED or some real error
 *********************************************************************/
xmlChar *
    expand_alias (xmlChar *line,
                  status_t *res)
{
    xmlChar  *start, *p = line, *newline;
    alias_cb_t *alias;
    uint32    namelen, newlen;
    boolean   done = FALSE;

    /* skip any leading whitespace; not expected from yangcli */
    while (*p && xml_isspace(*p)) {
        p++;
    }
    if (*p == 0) {
        *res = ERR_NCX_SKIPPED;
        return NULL;
    }

    /* look for end of name */
    start = p;
    if (!ncx_valid_fname_ch(*p++)) {
        *res = ERR_NCX_SKIPPED;
        return NULL;
    }
    while (*p && !done) {
        if (xml_isspace(*p)) {
            done = TRUE;
        } else if (!ncx_valid_name_ch(*p)) {
            *res = ERR_NCX_SKIPPED;
            return NULL;
        } else {
            p++;
        }
    }

    /* look for the alias */
    namelen = (uint32)(p - start);
    alias = find_alias(start, namelen);
    if (alias == NULL) {
        *res = ERR_NCX_SKIPPED;
        return NULL;
    }

    /* replace the alias name with its contents and make a new string */
    if (alias->value) {
        newlen = xml_strlen(p) + xml_strlen(alias->value);
    } else {
        newlen = xml_strlen(p);
    }
    newline = m__getMem(newlen + 1);
    if (newline == NULL) {
        *res = ERR_INTERNAL_MEM;
        return NULL;
    }
    start = newline;
    if (alias->value) {
        start += xml_strcpy(start, alias->value);
    }
    xml_strcpy(start, p);

    if (LOGDEBUG2) {
        log_debug2("\nExpanded alias '%s'; new line: '%s'",
                   alias->name, newline);
    }

    *res = NO_ERR;
    return newline;

}  /* expand_alias */
Exemplo n.º 10
0
/********************************************************************
 * FUNCTION handle_alias_parm
 * 
 * alias def
 * alias def=def-value
 *
 * Handle the alias command, based on the parameter
 *
 * INPUTS:
 *    varstr == alias command line
 *    setonly == TRUE if expecting set version only; ignore show alias
 *               FALSE if expecting show alias or set alias
 *    loginfo == TRUE if log-level=info should be used
 *               FALSE if log-level=debug2 should be used
 * RETURNS:
 *   status
 *********************************************************************/
static status_t
    handle_alias_parm (const xmlChar *varstr,
                       boolean setonly,
                       boolean loginfo)
{
    const xmlChar *valptr = NULL;    
    uint32    nlen = 0;
    status_t  res;

    res = parse_alias(varstr, &nlen, &valptr);
    if (res == NO_ERR) {
        if (valptr) {
            /* setting an alias */
            alias_cb_t *alias = find_alias(varstr, nlen);
            if (alias) {
                if (LOGDEBUG3) {
                    log_debug3("\nAbout to replace alias '%s'"
                               "\n  old value: '%s'"
                               "\n  new value: '%s'",
                               alias->name, 
                               alias->value ? alias->value : EMPTY_STRING,
                               valptr);
                }
                /* modify an existing alias */
                res = set_alias(alias, valptr);
                if (res == NO_ERR) {
                    if (loginfo) {
                        log_info("\nUpdated alias '%s'\n", alias->name);
                    } else {
                        log_debug2("\nUpdated alias '%s'", alias->name);
                    }
                } else {
                    log_error("\nError: invalid alias value '%s'\n",
                              valptr);
                }
            } else {
                /* create a new alias */
                alias = new_alias(varstr, nlen);
                if (alias == NULL) {
                    res = ERR_INTERNAL_MEM;
                } else {
                    res = set_alias(alias, valptr);
                    if (res == NO_ERR) {
                        res = add_alias(alias);
                        if (res == NO_ERR) {
                            if (loginfo) {
                                log_info("\nAdded alias '%s'\n", alias->name);
                            } else {
                                log_debug2("\nAdded alias '%s'", alias->name);
                            }
                        } else {
                            log_error("\nError: alias was not added '%s'\n",
                                      get_error_string(res));
                        }
                    } else {
                        log_error("\nError: invalid alias value '%s'\n",
                                  valptr);
                        free_alias(alias);
                    }
                }
            }
        } else if (!setonly) {
            /* just provided a name; show alias */
            show_alias_name(varstr, nlen);
        } else if (LOGDEBUG) {
            log_debug("\nSkipping alias '%s' because no value set", varstr);
        }
    } else if (res == ERR_NCX_INVALID_NAME) {
        log_error("\nError: invalid alias (%s)", get_error_string(res));
    } else {
        log_error("\nError: invalid alias '%s' (%s)", varstr,
                  get_error_string(res));
    }
    return res;

}  /* handle_alias_parm */
Exemplo n.º 11
0
cue_t *cue_new(const char *file)
{
  cue_t *r = (cue_t *) mc_malloc(sizeof(cue_t));

  r->audio_file = NULL;
  r->album_title = NULL;
  r->album_performer = NULL;
  r->album_composer = NULL;
  r->genre = NULL;
  r->cuefile = mystrdup(file);
  r->count = 0;
  r->entries = NULL;
  r->_errno = 0;

  FILE *f = fopen(file, "rt");
  time_t _audio_mtime=0;

  if (f == NULL) {
    r->_errno = ENOFILECUE;
  } else {
    char *line;
    char *image = NULL;
    char *year = NULL;
    cue_entry_t *entry = NULL;
    int in_tracks = 0;
    while ((line = readline(f)) != NULL) {
      trim_replace(&line);
      if (strcmp(line, "") != 0) {
        if (!in_tracks) {
          if (eq(line, "performer")) {
            mc_free(r->album_performer);
            r->album_performer = unquote(line, "performer");
          } else if (eq(line, "title")) {
            mc_free(r->album_title);
            r->album_title = unquote(line, "title");
          } else if (eq(line, "file")) {
            mc_free(r->audio_file);
            char *fl = getFilePart(line);
            char *af = unquote(fl, "");
            if (strlen(af) > 0) {
              if (af[0] == '/') {
                r->audio_file = af;
              } else {
                char *cf = mc_strdup(r->cuefile);
                int ii;
                for (ii = strlen(cf) - 1; ii >= 0 && cf[ii] != '/'; ii--) ;
                if (ii >= 0) {
                  cf[ii] = '\0';
                  char *aaf = (char *)mc_malloc(strlen(cf) + strlen(af) + strlen("/") + 1);
                  sprintf(aaf, "%s/%s", cf, af);
                  r->audio_file = aaf;
                  mc_free(cf);
                  mc_free(af);
                } else {
                  r->audio_file = af;
                }
              }
            } else {
              r->audio_file = af;
            }
            // We have a full path audio file now.
            // get the mtime.
            {
              struct stat st;
              stat(r->audio_file,&st);
              _audio_mtime=st.st_mtime;
            }

            mc_free(fl);
          } else if (eq(line, "rem")) {
            if (eq(&line[3], "date")) {
              mc_free(year);
              year = unquote(&line[3], "date");
            } else if (eq(&line[3], "image")) {
              mc_free(image);
              image = unquote(&line[3], "image");
            } else if (eq(&line[3], "composer")) {
              mc_free(r->album_composer);
              r->album_performer = unquote(&line[3], "composer");
            } else if (eq(&line[3], "genre")) {
              mc_free(r->genre);
              r->genre = unquote(&line[3], "genre");
            }
          } else if (eq(line, "track")) {
            in_tracks = 1;
          }
        }

        if (in_tracks) {
          if (eq(line, "track")) {
            log_debug2("track: entry=%p", entry);
            if (entry != NULL) {
              addEntry(r, entry);
            }
            entry = cue_entry_new(r);
            entry->audio_mtime=_audio_mtime;
            entry->year = mystrdup(year);
            entry->performer = mystrdup(r->album_performer);
            entry->composer = mystrdup(r->album_composer);
            entry->piece = NULL;
            log_debug2("track: created new entry %p", entry);
          } else if (eq(line, "title")) {
            mc_free(entry->title);
            entry->title = unquote(line, "title");
          } else if (eq(line, "performer")) {
            mc_free(entry->performer);
            entry->performer = unquote(line, "performer");
          } else if (eq(line, "index")) {
            char *index = unquote(line, "index");
            entry->begin_offset_in_ms = calculateOffset(index);
            mc_free(index);
          } else if (eq(line, "rem")) {
            if (eq(&line[3], "composer")) {
              mc_free(entry->composer);
              entry->composer = unquote(&line[3], "composer");
            } else if (eq(&line[3], "piece")) {
              mc_free(entry->piece);
              entry->piece = unquote(&line[3], "piece");
            } else if (eq(&line[3], "year")) {
              mc_free(year);
              year = unquote(&line[3], "year");
              mc_free(entry->year);
              entry->year = mystrdup(year);
            }
          }
        }
      }
      mc_free(line);
    }
    if (entry != NULL) {
      addEntry(r, entry);
    }
    mc_free(year);
    mc_free(image);


    {
      int i, N;
      for (i = 0, N = r->count; i < N - 1; i++) {
        r->entries[i]->end_offset_in_ms = r->entries[i + 1]->begin_offset_in_ms;
        r->entries[i]->tracknr = i + 1;
      }
      r->entries[i]->tracknr = i + 1;
    }

    fclose(f);
  }

  return r;
}
Exemplo n.º 12
0
int
deliver_pipe_deliver(struct deliver_ctx *dctx, struct actitem *ti)
{
	struct account			*a = dctx->account;
	struct mail			*m = dctx->mail;
	struct deliver_pipe_data	*data = ti->data;
	char				*s, *cause, *err;
	int				 status;
	struct cmd			*cmd = NULL;
	char				*lbuf;
	size_t				 llen;

	s = replacepath(&data->cmd, m->tags, m, &m->rml, dctx->udata->home);
	if (s == NULL || *s == '\0') {
		log_warnx("%s: empty command", a->name);
		goto error;
	}

	if (data->pipe) {
		log_debug2("%s: piping to \"%s\"", a->name, s);
		cmd = cmd_start(s, CMD_IN|CMD_ONCE, m->data, m->size, &cause);
	} else {
		log_debug2("%s: executing \"%s\"", a->name, s);
		cmd = cmd_start(s, 0, NULL, 0, &cause);
	}
	if (cmd == NULL)
		goto error_cause;
	log_debug3("%s: %s: started", a->name, s);

	llen = IO_LINESIZE;
	lbuf = xmalloc(llen);

	do {
		status = cmd_poll(
		    cmd, NULL, &err, &lbuf, &llen, conf.timeout, &cause);
		if (status == -1) {
			xfree(lbuf);
			goto error_cause;
		}
		if (status == 0 && err != NULL)
			log_warnx("%s: %s: %s", a->name, s, err);
	} while (status == 0);
	status--;

	xfree(lbuf);

	if (status != 0) {
		log_warnx("%s: %s: command returned %d", a->name, s, status);
		goto error;
	}

	cmd_free(cmd);
	xfree(s);
	return (DELIVER_SUCCESS);

error_cause:
	log_warnx("%s: %s: %s", a->name, s, cause);
	xfree(cause);

error:
	if (cmd != NULL)
		cmd_free(cmd);
	if (s != NULL)
		xfree(s);
	return (DELIVER_FAILURE);
}
Exemplo n.º 13
0
static int mp3splt(segmenter_t * S)
{
  char *ext = getExt(S->segment.filename);

  //log_debug("mp3splt_split: entered");

  mc_free(S->memory_block);
  S->size = -1;
  S->memory_block = NULL;
#ifndef SEGMENT_USING_FILE
  FILE *f = open_memstream((char **)&S->memory_block, &S->size);
#endif

  int begin_offset_in_hs = S->segment.begin_offset_in_ms / 10;
  int end_offset_in_hs = -1;
  if (S->segment.end_offset_in_ms >= 0) {
    end_offset_in_hs = S->segment.end_offset_in_ms / 10;
  }
  // Creating state
  splt_state *state = mp3splt_new_state(NULL);
  //log_debug("new state");
  mp3splt_find_plugins(state);
  //log_debug("plugins found");

  // Set split path and custom name
  mp3splt_set_path_of_split(state, "/tmp");
  //log_debug("split path set");
  mp3splt_set_int_option(state, SPLT_OPT_OUTPUT_FILENAMES, SPLT_OUTPUT_CUSTOM);
  //log_debug("custom split set");

  // Set filename to split and pretend mode, for memory based splitting
  mp3splt_set_filename_to_split(state, S->segment.filename);
  //log_debug("filename to split set");
#ifndef SEGMENT_USING_FILE
  mp3splt_set_int_option(state, SPLT_OPT_PRETEND_TO_SPLIT, SPLT_TRUE);
  mp3splt_set_pretend_to_split_write_function(state, mp3splt_writer, (void *)f);
  //log_debug("pretend split and write function set");
#endif

  // Create splitpoints
  splt_point *point = mp3splt_point_new(begin_offset_in_hs, NULL);
  mp3splt_point_set_type(point, SPLT_SPLITPOINT);
#ifdef SEGMENT_USING_FILE
  char buf[20];
  sprintf(buf, "mp3cue%09d", ++splitnr);
  mp3splt_point_set_name(point, buf);
#endif
  mp3splt_append_splitpoint(state, point);

  splt_point *skip = mp3splt_point_new(end_offset_in_hs, NULL);
  mp3splt_point_set_type(skip, SPLT_SKIPPOINT);
  mp3splt_append_splitpoint(state, skip);
  //log_debug("split points set");

  // Append cuesheet tags and merge with existing
  {
    splt_tags *tags = mp3splt_tags_new(NULL);

    char *title = S->segment.title;
    char *artist = S->segment.artist;
    char *album = S->segment.album;
    char *performer = S->segment.album_artist;
    char year[20];
    sprintf(year, "%d", S->segment.year);
    char *comment = S->segment.comment;
    char *genre = S->segment.genre;
    char track[20];
    sprintf(track, "%d", S->segment.track);

    mp3splt_read_original_tags(state);
    //log_debug("original tags read");

    mp3splt_tags_set(tags, SPLT_TAGS_ORIGINAL, "true", NULL);
    //log_debug("SPLT_TAGS_ORIGINAL set");
    mp3splt_tags_set(tags,
         SPLT_TAGS_TITLE, title,
         SPLT_TAGS_ARTIST, artist,
         SPLT_TAGS_ALBUM, album,
         SPLT_TAGS_PERFORMER, performer,
         SPLT_TAGS_YEAR, year,
         SPLT_TAGS_COMMENT, comment, SPLT_TAGS_GENRE, genre, SPLT_TAGS_TRACK, track, NULL);
    //log_debug("tags set");
    mp3splt_append_tags(state, tags);
    //log_debug("tag appended");
  }

  // split the stuff
  int error = SPLT_OK;
  error = mp3splt_split(state);
  //log_debug("split done");
  mp3splt_free_state(state);
  //log_debug("state freeed");
  log_debug2("mp3splt_split: result=%d", error);

#ifndef SEGMENT_USING_FILE
  fclose(f);
  mc_take_control(S->memory_block, S->size);
  //log_debug("memory file closed");
#endif

  if (error == SPLT_OK_SPLIT || error == SPLT_OK_SPLIT_EOF) {
#ifdef SEGMENT_USING_FILE
    char fn[250];
    sprintf(fn, "/tmp/%s.%s", buf, ext);
    FILE *f = fopen(fn, "rb");
    FILE *g = open_memstream((char **)&S->memory_block, &S->size);
    int size;
    char fbuf[10240];
    while ((size = fread(fbuf, 1, 10240, f)) > 0) {
      fwrite(fbuf, size, 1, g);
    }
    fclose(f);
    fclose(g);
    unlink(fn);
#endif
    mc_free(ext);
    return SEGMENTER_OK;
  } else {
    mc_free(ext);
    return SEGMENTER_ERR_CREATE;
  }
}
Exemplo n.º 14
0
/********************************************************************
* FUNCTION send_discard_changes_pdu_to_server
* 
* Send a <discard-changes> operation to the server
*
* INPUTS:
*   server_cb == server control block to use
*
* RETURNS:
*    status
*********************************************************************/
status_t
    send_discard_changes_pdu_to_server (server_cb_t *server_cb)
{
    obj_template_t        *rpc;
    mgr_rpc_req_t         *req;
    val_value_t           *reqdata;
    ses_cb_t              *scb;
    status_t               res;
    xmlns_id_t             obj_nsid;

    req = NULL;
    reqdata = NULL;
    res = NO_ERR;

    if (LOGDEBUG) {
        log_debug("\nSending <discard-changes> request");
    }
    
    rpc = ncx_find_object(get_netconf_mod(server_cb), 
                          NCX_EL_DISCARD_CHANGES);
    if (!rpc) {
        return SET_ERROR(ERR_NCX_DEF_NOT_FOUND);
    }

    obj_nsid = obj_get_nsid(rpc);

    /* construct a method node */
    reqdata = xml_val_new_flag(obj_get_name(rpc), 
                               obj_nsid);
    if (!reqdata) {
        log_error("\nError allocating a new RPC request");
        return ERR_INTERNAL_MEM;
    }

    scb = mgr_ses_get_scb(server_cb->mysid);
    if (!scb) {
        res = SET_ERROR(ERR_INTERNAL_PTR);
    } else {
        req = mgr_rpc_new_request(scb);
        if (!req) {
            res = ERR_INTERNAL_MEM;
            log_error("\nError allocating a new RPC request");
        } else {
            req->data = reqdata;
            req->rpc = rpc;
            req->timeout = server_cb->timeout;
        }
    }
        
    /* if all OK, send the RPC request */
    if (res == NO_ERR) {
        if (LOGDEBUG2) {
            log_debug2("\nabout to send RPC request with reqdata:");
            val_dump_value_max(reqdata, 
                               0,
                               server_cb->defindent,
                               DUMP_VAL_LOG,
                               server_cb->display_mode,
                               FALSE,
                               FALSE);
        }

        /* the request will be stored if this returns NO_ERR */
        res = mgr_rpc_send_request(scb, req, yangcli_reply_handler);
        if (res == NO_ERR) {
            server_cb->command_mode = CMD_MODE_AUTODISCARD;
        }
    }

    /* cleanup and set next state */
    if (res != NO_ERR) {
        if (req) {
            mgr_rpc_free_request(req);
        } else if (reqdata) {
            val_free_value(reqdata);
        }
    } else {
        server_cb->state = MGR_IO_ST_CONN_RPYWAIT;
    }

    return res;

} /* send_discard_changes_pdu_to_server */
Exemplo n.º 15
0
/* Translate a key code into an output key sequence. */
void
input_key(struct window_pane *wp, int key)
{
	struct input_key_ent   *ike;
	u_int			i;
	size_t			dlen;
	char		       *out;

	log_debug2("writing key 0x%x", key);

	/*
	 * If this is a normal 7-bit key, just send it, with a leading escape
	 * if necessary.
	 */
	if (key != KEYC_NONE && (key & ~KEYC_ESCAPE) < 0x100) {
		if (key & KEYC_ESCAPE)
			buffer_write8(wp->out, '\033');
		buffer_write8(wp->out, (uint8_t) (key & ~KEYC_ESCAPE));
		return;
	}

	/* 
	 * Then try to look this up as an xterm key, if the flag to output them
	 * is set.
	 */
	if (options_get_number(&wp->window->options, "xterm-keys")) {
		if ((out = xterm_keys_lookup(key)) != NULL) {
			buffer_write(wp->out, out, strlen(out));
			xfree(out);
			return;
		}
	}

	/* Otherwise look the key up in the table. */
	for (i = 0; i < nitems(input_keys); i++) {
		ike = &input_keys[i];

		if ((ike->flags & INPUTKEY_KEYPAD) &&
		    !(wp->screen->mode & MODE_KKEYPAD))
			continue;
		if ((ike->flags & INPUTKEY_CURSOR) &&
		    !(wp->screen->mode & MODE_KCURSOR))
			continue;

		if ((key & KEYC_ESCAPE) && (ike->key | KEYC_ESCAPE) == key)
			break;
		if (ike->key == key)
			break;
	}
	if (i == nitems(input_keys)) {
		log_debug2("key 0x%x missing", key);
		return;
	}
	dlen = strlen(ike->data);
	log_debug2("found key 0x%x: \"%s\"", key, ike->data);

	/* Prefix a \033 for escape. */
	if (key & KEYC_ESCAPE)
		buffer_write8(wp->out, '\033');
	buffer_write(wp->out, ike->data, dlen);
}
Exemplo n.º 16
0
void triton_thread_wakeup(struct _triton_thread_t *thread)
{
	log_debug2("wake up thread %p\n", thread);
	pthread_kill(thread->thread, SIGUSR1);
}
Exemplo n.º 17
0
/********************************************************************
* FUNCTION load_running_config
* 
* Load the NV startup config into the running config
* 
* INPUTS:
*   startup == startup filespec provided by the user
*           == NULL if not set by user 
*              (use default name and specified search path instead)
*   loaded == address of return config loaded flag
*
* OUTPUTS:
*   *loaded == TRUE if some config file was loaded
*
*   The <running> config is loaded from NV-storage,
*   if the NV-storage <startup> config can be found an read
* RETURNS:
*   status
*********************************************************************/
static status_t
    load_running_config (const xmlChar *startup,
                         boolean *loaded)
{
    cfg_template_t  *cfg;
    xmlChar         *fname;
    agt_profile_t   *profile;
    status_t         res;

    res = NO_ERR;
    *loaded = FALSE;
    profile = agt_get_profile();

    cfg = cfg_get_config(NCX_CFG_RUNNING);
    if (!cfg) {
        log_error("\nagt: No running config found!!");
        return SET_ERROR(ERR_INTERNAL_VAL);
    }

    /* use the user-set startup or default filename */
    if (startup) {
        /* relative filespec, use search path */
        fname = ncxmod_find_data_file(startup, FALSE, &res);
    } else {
        /* search for the default startup-cfg.xml filename */
        fname = ncxmod_find_data_file(NCX_DEF_STARTUP_FILE, FALSE, &res);
    }

    /* check if error finding the filespec */
    if (!fname) {
        if (startup) {
            if (res == NO_ERR) {
                res = ERR_NCX_MISSING_FILE;
            }
            log_error("\nError: Startup config file (%s) not found (%s).",
                      startup, get_error_string(res));
            return res;
        } else {
            log_info("\nDefault startup config file (%s) not found."
                     "\n   Booting with default running configuration!\n",
                     NCX_DEF_STARTUP_FILE);
            return NO_ERR;
        }
    } else if (LOGDEBUG2) {
        log_debug2("\nFound startup config: '%s'", fname);
    }
    
    /* try to load the config file that was found or given */
    res = agt_ncx_cfg_load(cfg, CFG_LOC_FILE, fname);
    if (res == ERR_XML_READER_START_FAILED) {
        log_error("\nagt: Error: Could not open startup config file"
                  "\n     (%s)\n", fname);
    } else if (res != NO_ERR) {
        /* if an error is returned then it was a hard error
         * since the startup_error and running_error profile
         * variables have already been accounted for.
         * An error in the setup or in the AGT_RPC_PH_INVOKE phase
         * of the <load-config> operation occurred
         */
        log_error("\nError: load startup config failed (%s)",
                  get_error_string(res));
        if (!dlq_empty(&cfg->load_errQ)) {
            *loaded = TRUE;
        }
    } else {
        /* assume OK or startup and running continue; if 1 or both is not
         * set then the server will exit anyway and the config state
         * will not matter
         */
        profile->agt_config_state = AGT_CFG_STATE_OK;

        *loaded = TRUE;

        boolean errdone = FALSE;
        boolean errcontinue = FALSE;

        if (profile->agt_load_validate_errors) {
            if (profile->agt_startup_error) {
                /* quit if any startup validation errors */
                log_error("\nError: validation errors occurred loading the "
                          "<running> database\n   from NV-storage"
                          " (%s)\n", fname);
                errdone = TRUE;
            } else {
                /* continue if any startup errors */
                log_warn("\nWarning: validation errors occurred loading "
                         "the <running> database\n   from NV-storage"
                         " (%s)\n", fname);
                errcontinue = TRUE;
            }
        }
        if (!errdone && profile->agt_load_rootcheck_errors) {
            if (profile->agt_startup_error) {
                /* quit if any startup root-check validation errors */
                log_error("\nError: root-check validation errors "
                          "occurred loading the <running> database\n"
                          "   from NV-storage (%s)\n", fname);
                errdone = TRUE;
            } else {
                /* continue if any root-check validation errors */
                log_warn("\nWarning: root-check validation errors "
                         "occurred loading the <running> database\n"
                         "   from NV-storage (%s)\n", fname);
                errcontinue = TRUE;
            }
        }
        if (!errdone && profile->agt_load_top_rootcheck_errors) {
            if (profile->agt_running_error) {
                /* quit if any top-level root-check validation errors */
                log_error("\nError: top-node root-check validation errors "
                          "occurred loading the <running> database\n"
                          "   from NV-storage (%s)\n", fname);
                errdone = TRUE;
            } else {
                /* continue if any startup errors */
                log_warn("\nWarning: top-node root-check validation errors "
                         "occurred loading the <running> database\n"
                         "   from NV-storage (%s)\n", fname);
                profile->agt_config_state = AGT_CFG_STATE_BAD;
                errcontinue = TRUE;
            }
        }
        if (!errdone && profile->agt_load_apply_errors) {
            /* quit if any apply-to-running SIL errors */
            errdone = TRUE;
            log_error("\nError: fatal errors "
                      "occurred loading the <running> database "
                      "from NV-storage\n     (%s)\n", fname);
        }

        if (errdone) {
            res = ERR_NCX_OPERATION_FAILED;
        } else if (errcontinue) {
            val_purge_errors_from_root(cfg->root);
            log_info("\nagt: Startup config loaded after pruning error nodes\n"
                     "Source: %s\n", fname);
        } else {
            log_info("\nagt: Startup config loaded OK\n     Source: %s\n",
                     fname);
        }
    }

    if (LOGDEBUG) {
        log_debug("\nContents of %s configuration:", cfg->name);
        val_dump_value(cfg->root, 0);
        log_debug("\n");
    }

    if (fname) {
        m__free(fname);
    }

    return res;

} /* load_running_config */
Exemplo n.º 18
0
/********************************************************************
* FUNCTION agt_hello_dispatch
*
* Handle an incoming <hello> message from the client
*
* INPUTS:
*   scb == session control block
*   top == top element descriptor
*********************************************************************/
void 
    agt_hello_dispatch (ses_cb_t *scb,
                        xml_node_t *top)
{
    assert( scb && "scb is NULL!" );
    assert( top && "top is NULL!" );

    if (LOGDEBUG2) {
        log_debug2("\nagt_hello: got node");
        if (LOGDEBUG3) {
            xml_dump_node(top);
        }
    }

    /* only process this message in hello wait state */
    if (scb->state != SES_ST_HELLO_WAIT) {
        log_info("\nagt_hello dropped, wrong state "
                 "(%d) for session %d", scb->state, scb->sid);
        mytotals->inBadHellos++;
        mytotals->droppedSessions++;
        agt_ses_request_close(scb, scb->sid, SES_TR_BAD_HELLO);
        return;
    }

    /* init local vars */
    status_t res = NO_ERR;
    obj_template_t *obj = NULL;
    xml_msg_hdr_t msg;
    xml_msg_init_hdr(&msg);

    /* get a value struct to hold the client hello msg */
    val_value_t *val = val_new_value();
    if (!val) {
        res = ERR_INTERNAL_MEM;
    }

    /* get the type definition from the registry */
    if (res == NO_ERR) {
        ncx_module_t *mod = ncx_find_module(NC_MODULE, NULL);
        if (mod) {
            obj = ncx_find_object(mod, CLIENT_HELLO_CON);
        }
        if (!obj) {
            /* netconf module should have loaded this definition */
            res = SET_ERROR(ERR_INTERNAL_PTR);
        }
    }

    /* parse a manager hello message */
    if (res == NO_ERR) {
        res = agt_val_parse_nc(scb, &msg, obj, top, NCX_DC_STATE, val);
    }
    
    /* check that the NETCONF base capability is included
     * and it matches the server protocol version
     */
    if (res == NO_ERR) {
        res = check_manager_hello(scb, val);
    }

    /* report first error and close session */
    if (res != NO_ERR) {
        if (LOGINFO) {
            log_info("\nagt_connect error (%s), dropping session %d",
                     get_error_string(res), scb->sid);
        }
        mytotals->inBadHellos++;
        mytotals->droppedSessions++;
        agt_ses_request_close(scb, scb->sid, SES_TR_BAD_HELLO);

    } else {
        scb->state = SES_ST_IDLE;
        scb->active = TRUE;
        /* start the timer for the first rpc request */
        (void)time(&scb->last_rpc_time);

        if (LOGDEBUG) {
            log_debug("\nSession %d for %s@%s now active", 
                      scb->sid, scb->username, scb->peeraddr);
            if (ses_get_protocol(scb) == NCX_PROTO_NETCONF11) {
                log_debug_append(" (base:1.1)");
            } else {
                log_debug_append(" (base:1.0)");
            }
        }
    }

    if (val) {
        val_free_value(val);
    }

} /* agt_hello_dispatch */
Exemplo n.º 19
0
/********************************************************************
* FUNCTION agt_ses_process_first_ready
*
* Check the readyQ and process the first message, if any
*
* RETURNS:
*     TRUE if a message was processed
*     FALSE if the readyQ was empty
*********************************************************************/
boolean
    agt_ses_process_first_ready (void)
{
    ses_cb_t     *scb;
    ses_ready_t  *rdy;
    ses_msg_t    *msg;
    status_t      res;
    uint32        cnt;
    xmlChar       buff[32];

    rdy = ses_msg_get_first_inready();
    if (!rdy) {
        return FALSE;
    }

    /* get the session control block that rdy is embedded into */
    scb = agtses[rdy->sid];

    if (scb == NULL) {
        log_debug("\nagt_ses: session %d gone", rdy->sid);
        return FALSE;
    }

    log_debug2("\nagt_ses msg ready for session %d", scb->sid);

    /* check the session control block state */
    if (scb->state >= SES_ST_SHUTDOWN_REQ) {
        /* don't process the message or even it mark it
         * It will be cleaned up when the session is freed
         */
        log_debug("\nagt_ses drop input, session %d shutting down", 
                  scb->sid);
        return TRUE;
    }

    /* make sure a message is really there */
    msg = (ses_msg_t *)dlq_firstEntry(&scb->msgQ);
    if (!msg || !msg->ready) {
        SET_ERROR(ERR_INTERNAL_PTR);
        log_error("\nagt_ses ready Q message not correct");
        if (msg && scb->state != SES_ST_INIT) {
            /* do not echo the ncx-connect message */
            cnt = xml_strcpy(buff, 
                             (const xmlChar *)"Incoming msg for session ");
            snprintf((char *)(&buff[cnt]), sizeof(buff) - cnt, "%u", scb->sid);
            ses_msg_dump(msg, buff);
        }
            
        return FALSE;
    } else if (LOGDEBUG2 && scb->state != SES_ST_INIT) {
        cnt = xml_strcpy(buff, 
                         (const xmlChar *)"Incoming msg for session ");
        snprintf((char *)(&buff[cnt]), sizeof(buff) - cnt, "%u", scb->sid);
        ses_msg_dump(msg, buff);
    }

    /* setup the XML parser */
    if (scb->reader) {
            /* reset the xmlreader */
        res = xml_reset_reader_for_session(ses_read_cb,
                                           NULL, 
                                           scb, 
                                           scb->reader);
    } else {
        res = xml_get_reader_for_session(ses_read_cb,
                                         NULL, 
                                         scb, 
                                         &scb->reader);
    }

    /* process the message */
    if (res == NO_ERR) {
        /* process the message 
         * the scb pointer may get deleted !!!
         */
        agt_top_dispatch_msg(&scb);
    } else {
        if (LOGINFO) {
            log_info("\nReset xmlreader failed for session %d (%s)",
                     scb->sid, 
                     get_error_string(res));
        }
        agt_ses_kill_session(scb, 0, SES_TR_OTHER);
        scb = NULL;
    }

    if (scb) {
        /* free the message that was just processed */
        dlq_remove(msg);
        ses_msg_free_msg(scb, msg);


        /* check if any messages left for this session */
        msg = (ses_msg_t *)dlq_firstEntry(&scb->msgQ);
        if (msg && msg->ready) {
            ses_msg_make_inready(scb);
        }
    }

    return TRUE;
    
}  /* agt_ses_process_first_ready */
Exemplo n.º 20
0
static void* player_thread(void* _minfo) 
{
  ogg_t* minfo = (ogg_t*) _minfo;
  
  log_debug("ogg player started");
  
  long current_position_in_ms = 0;
  long previous_position_in_ms = -1; 
  long guard_position_in_ms = -1;
  el_bool playing = el_false;
  
  post_event(minfo->client_notification, AUDIO_READY, current_position_in_ms);
 
  audio_event_t *event;
  event = audio_event_fifo_dequeue(minfo->player_control);
  while (event->state != INTERNAL_CMD_DESTROY) {
    
    audio_state_t event_state = event->state;
    long event_position = event->position_in_ms;
    audio_event_destroy(event);
    
    switch (event_state) {
      case INTERNAL_CMD_LOAD_FILE: {
        playing = el_false;
        if (minfo->is_open) {
          ov_clear(&minfo->vf);
          fclose(minfo->fh);
          aodev_close(minfo->ao_handle);
        }

        minfo->fh = fopen(minfo->file_or_url, "rb");
        if (minfo->fh != NULL) {
          if (ov_open_callbacks(minfo->fh , &minfo->vf, NULL, 0, OV_CALLBACKS_NOCLOSE) < 0) {
            fclose(minfo->fh);
            post_event(minfo->client_notification, AUDIO_NOT_SUPPORTED, -1);
            minfo->is_open = el_false;
          } else {
            minfo->is_open = el_true;
            minfo->can_seek = ov_seekable(&minfo->vf);
            minfo->length = (long) (ov_time_total(&minfo->vf, -1) * 1000.0);
            psem_post(minfo->length_set);
            minfo->current_section = 0;
            vorbis_info* vi = ov_info(&minfo->vf, -1);
            aodev_set_format(minfo->ao_handle, 16, vi->rate, vi->channels);
            aodev_set_endian(minfo->ao_handle, AO_FMT_LITTLE);
            aodev_open(minfo->ao_handle);
          }
        } else {
          post_event(minfo->client_notification, AUDIO_IO_ERROR, -1);
          minfo->is_open = el_false;
        }
        
        current_position_in_ms = 0;
        guard_position_in_ms = -1; 
        
        log_debug("Stream initialized");
          
      }
      break;
      case INTERNAL_CMD_LOAD_URL: {
      }
      break;
      case INTERNAL_CMD_SEEK: {
        ov_time_seek_lap(&minfo->vf, ((double) event_position / 1000.0));
      }
      break;
      case INTERNAL_CMD_PLAY: {
        playing = el_true;
      }
      break;
      case INTERNAL_CMD_PAUSE: {
        playing = el_false;
      }
      break;
      case INTERNAL_CMD_GUARD: {
        guard_position_in_ms = event_position;
      }
      break;
      case INTERNAL_CMD_SET_VOLUME: {
        double scale = ((double) event_position) / 1000.0;
        minfo->volume_scale = scale;
        log_debug2("setting volume to %lf", scale);
      }
      break;
      case INTERNAL_CMD_NONE:
      break;
      default:
      break;
    }
    
    if (guard_position_in_ms >= 0 && current_position_in_ms >= guard_position_in_ms) {

      guard_position_in_ms = -1;
      post_event(minfo->client_notification, AUDIO_GUARD_REACHED, current_position_in_ms);
      
    } else if (playing) {
      if (minfo->is_file) {
        int n = ov_read_filter(&minfo->vf, minfo->buffer, BUFFER_SIZE(minfo), 0, 2, 1, &minfo->current_section,
                               adjust_volume, minfo
                              );
        if (n > 0) {
          aodev_play_buffer(minfo->ao_handle, minfo->buffer, n);
          //log_debug("buffer played");
          
          double tm = ov_time_tell(&minfo->vf);
          current_position_in_ms = (long) (tm * 1000.0);
          
          if ((current_position_in_ms - previous_position_in_ms) >= STATE_REPORT_THRESHOLD) {
            post_event(minfo->client_notification, AUDIO_PLAYING, current_position_in_ms);
          }
          previous_position_in_ms = current_position_in_ms;
          
        } else {
          post_event(minfo->client_notification, AUDIO_EOS, current_position_in_ms);
          playing = el_false;
        } 
      } else { // Stream playing
        post_event(minfo->client_notification, AUDIO_STATE_ERROR, -1);
        playing = el_false;
      } 
    
    }
    
    if (playing) {
      if (audio_event_fifo_peek(minfo->player_control) != NULL) {
        event = audio_event_fifo_dequeue(minfo->player_control);
      } else {
        event = (audio_event_t*) mc_malloc(sizeof(audio_event_t));
        event->state = INTERNAL_CMD_NONE;
        event->position_in_ms = -1;
      }
    } else {
      event = audio_event_fifo_dequeue(minfo->player_control);
    }
  }

  // destroy event received
  audio_event_destroy(event);

  // exit thread  
  return NULL;
}
Exemplo n.º 21
0
void* player_thread(void* _mp3_info) 
{
  log_debug("player thread started");
  
  mp3_t* mp3_info = (mp3_t* ) _mp3_info;
  long current_position_in_ms = 0;
  long previous_position_in_ms = -1; 
  long guard_position_in_ms = -1;
  el_bool playing = el_false;
  pthread_t thread_id;
  int no_count = 0;
  
  post_event(mp3_info->client_notification, AUDIO_READY, current_position_in_ms);
 
  audio_event_t *event;
  event = audio_event_fifo_dequeue(mp3_info->player_control);
  while (event->state != INTERNAL_CMD_DESTROY) {
    
    if (event->state != INTERNAL_CMD_NONE) {
      log_debug4("event = %s, %ld, %s", audio_event_name(event->state), event->position_in_ms, mp3_info->file_or_url);
    }
    
    audio_state_t event_state = event->state;
    long event_position = event->position_in_ms;
    audio_event_destroy(event);
    
    switch (event_state) {
      case INTERNAL_CMD_LOAD_FILE: {
        playing = el_false;
        
        // Stop stream, if playing
        if (!mp3_info->is_file) {
          mp3_info->continue_streaming = el_false;
          psem_wait(mp3_info->stream_ready);
        }
        
        if (mp3_info->is_open) {
          mpg123_close(mp3_info->handle);
          aodev_close(mp3_info->ao_handle);
        }
        mpg123_open(mp3_info->handle, mp3_info->file_or_url);
        mpg123_getformat(mp3_info->handle, &mp3_info->rate, &mp3_info->channels, &mp3_info->encoding);
        mp3_info->buffer_size = mpg123_outblock(mp3_info->handle);
        mc_free(mp3_info->buffer);
        mp3_info->buffer = mc_malloc(mp3_info->buffer_size * sizeof(char) );
        int bytes_per_sample = get_encsize(mp3_info->encoding);
        aodev_set_format(mp3_info->ao_handle, bytes_per_sample * 8, mp3_info->rate, mp3_info->channels);
        aodev_open(mp3_info->ao_handle);
        mp3_info->is_open = el_true;
        mp3_info->is_file = el_true;
        mp3_info->can_seek = el_true;
        current_position_in_ms = 0;
        guard_position_in_ms = -1; 
        {
          off_t l = mpg123_length(mp3_info->handle);
          if (l == MPG123_ERR) {
            mp3_info->length = -1; 
          } else {
            mp3_info->length = (l * 1000) / mp3_info->rate;
          }
          psem_post(mp3_info->length_set);
        }
      }
      break;
      case INTERNAL_CMD_LOAD_URL: {
        playing = el_false;
        log_debug2("loading url %s", mp3_info->file_or_url);
        // Wait for feeding streams to end
        if (!mp3_info->is_file) {
          mp3_info->continue_streaming = el_false;
          psem_wait(mp3_info->stream_ready);
        }
        mp3_info->is_file = el_false;
        log_debug("current stream ended");
        
        if (mp3_info->is_open) {
          mpg123_close(mp3_info->handle);
          aodev_close(mp3_info->ao_handle);
          mp3_info->is_open = el_false;
        }
        log_debug("aodev closed");
        
        mpg123_open_feed(mp3_info->handle);
        log_debug("feed opened");
        
        pthread_create(&thread_id, NULL, stream_thread, mp3_info);
        log_debug("stream thread started");
        
        mp3_info->is_open = el_true;
        mp3_info->can_seek = el_false;
        current_position_in_ms = 0;
        guard_position_in_ms = -1;
        mp3_info->length = 0;
        mp3_info->continue_streaming = el_true;
        
        psem_post(mp3_info->length_set);
      }
      break;
      case INTERNAL_CMD_SEEK: {
        off_t pos = mpg123_timeframe(mp3_info->handle, (event_position / 1000.0));
        mpg123_seek_frame(mp3_info->handle, pos, SEEK_SET);
      }
      break;
      case INTERNAL_CMD_PLAY: {
        playing = el_true;
      }
      break;
      case INTERNAL_CMD_PAUSE: {
        playing = el_false;
      }
      break;
      case INTERNAL_CMD_GUARD: {
        guard_position_in_ms = event_position;
      }
      break;
      case INTERNAL_CMD_SET_VOLUME: {
        double volume = ((double) event_position) / 1000.0;
        mpg123_volume(mp3_info->handle, volume);
      }
      case INTERNAL_CMD_NONE:
      break;
      default:
      break;
    }
    
    //log_debug3("guard = %d, playing = %d", guard_position_in_ms, playing);
    if (guard_position_in_ms >= 0 && current_position_in_ms >= guard_position_in_ms) {

      guard_position_in_ms = -1;
      post_event(mp3_info->client_notification, AUDIO_GUARD_REACHED, current_position_in_ms);
      
    } else if (playing) {

      if (mp3_info->is_file) {  
        size_t bytes;
        int res = mpg123_read(mp3_info->handle, mp3_info->buffer, mp3_info->buffer_size, &bytes);
        if (res == MPG123_OK) {
          aodev_play_buffer(mp3_info->ao_handle, mp3_info->buffer, bytes);
          off_t frame = mpg123_tellframe(mp3_info->handle);
          double time_per_frame = (mpg123_tpf(mp3_info->handle)*1000.0);
          //static int prt = 1;
          //if (prt) { printf("tpf=%.6lf\n",time_per_frame);prt=0; }
          current_position_in_ms = (long) (frame * time_per_frame);    // 1 frame is about 26 milliseconds
          if (previous_position_in_ms == -1) previous_position_in_ms = current_position_in_ms;
          if ((current_position_in_ms - previous_position_in_ms) >= STATE_REPORT_THRESHOLD) {
            post_event(mp3_info->client_notification, AUDIO_PLAYING, current_position_in_ms);
          }
          previous_position_in_ms = current_position_in_ms;
        } else if (res == MPG123_DONE) {
          post_event(mp3_info->client_notification, AUDIO_EOS, current_position_in_ms);
          playing = el_false;
        } else {
          post_event(mp3_info->client_notification, AUDIO_STATE_ERROR, current_position_in_ms);
          playing = el_false;
        }
      } else { // Stream playing
        
        if (mp3_stream_fifo_peek(mp3_info->stream_fifo) != NULL) {
          el_bool go_on = el_true; 
          while (go_on && mp3_stream_fifo_peek(mp3_info->stream_fifo) != NULL) {
            memblock_t* blk = mp3_stream_fifo_dequeue(mp3_info->stream_fifo);
            
            mpg123_feed(mp3_info->handle, (const unsigned char*) memblock_as_str(blk), memblock_size(blk));
            memblock_destroy(blk);
            
            size_t done;
            int err;
            unsigned char *audio;
            off_t frame_offset;
            
            do {
              err = mpg123_decode_frame(mp3_info->handle, &frame_offset, &audio, &done);
              switch(err) {
                case MPG123_NEW_FORMAT:
                  mpg123_getformat(mp3_info->handle, &mp3_info->rate, &mp3_info->channels, &mp3_info->encoding);
                  if (aodev_is_open(mp3_info->ao_handle)) {
                    aodev_close(mp3_info->ao_handle);
                  }
                  aodev_set_format(mp3_info->ao_handle, get_encsize(mp3_info->encoding) * 8, mp3_info->rate, mp3_info->channels);
                  aodev_open(mp3_info->ao_handle);
                break;
                case MPG123_OK:
                  //log_debug2("playing buffer %d", done);
                  aodev_play_buffer(mp3_info->ao_handle, audio, done);
                  off_t frame = mpg123_tellframe(mp3_info->handle);
                  double time_per_frame = (mpg123_tpf(mp3_info->handle)*1000.0);
                  current_position_in_ms = (long) (frame * time_per_frame);    // 1 frame is about 26 milliseconds
                  if (previous_position_in_ms == -1) previous_position_in_ms = current_position_in_ms;
                  if ((current_position_in_ms - previous_position_in_ms) >= STATE_REPORT_THRESHOLD) {
                    post_event(mp3_info->client_notification, AUDIO_PLAYING, current_position_in_ms);
                  }
                  previous_position_in_ms = current_position_in_ms;
                  go_on = el_false;
                  break;
                case MPG123_NEED_MORE:
                  break;
                default:
                  break;
              }
            } while (done > 0);
          }
        } else {
          // no streaming data, prevent race conditions
          // sleep for a small time (50 ms);
          no_count += 1;
          if (no_count > 10) { 
            post_event(mp3_info->client_notification, AUDIO_BUFFERING, current_position_in_ms);
          }
          sleep_ms(50);
        }
      } 
    }
    
    if (playing) {
      if (audio_event_fifo_peek(mp3_info->player_control) != NULL) {
        event = audio_event_fifo_dequeue(mp3_info->player_control);
      } else {
        event = (audio_event_t*) mc_malloc(sizeof(audio_event_t));
        event->state = INTERNAL_CMD_NONE;
        event->position_in_ms = -1;
      }
    } else {
      //log_debug("waiting for next event");
      event = audio_event_fifo_dequeue(mp3_info->player_control);
    }
  }

  // destroy event received
  log_debug("destroy event received");
  
  // Kill playing streams
  if (mp3_info->streaming) {
    mp3_info->continue_streaming = el_false;
    psem_wait(mp3_info->stream_ready);
  }
  
  audio_event_destroy(event);

  // exit thread  
  return NULL;
}
Exemplo n.º 22
0
/********************************************************************
* FUNCTION process_server_hello
*
* Process the NETCONF server <hello> contents
*
*  1) Protocol capabilities
*  2) Module capabilities
*  3) Unrecognized capabilities
*
* INPUTS:
*    scb == session control block to set
*    hello == value struct for the hello message to check
*
* OUTPUTS:
*    server caps in the scb->mgrcb is set
*
* RETURNS:
*   status
*********************************************************************/
static status_t
    process_server_hello (ses_cb_t *scb,
                         val_value_t *hello)
{

    val_value_t  *caps, *sidval, *cap;
    mgr_scb_t    *mscb;
    boolean       c1, c2;
    status_t      res;

    mscb = mgr_ses_get_mscb(scb);

    /* make sure the capabilities element is present
     * This should not fail, since already parsed this far 
     */
    caps = val_find_child(hello, NC_MODULE, NCX_EL_CAPABILITIES);
    if (!caps || caps->res != NO_ERR) {
        log_error("\nError: no <capabilities> found in server <hello>");
        return ERR_NCX_MISSING_VAL_INST;
    }   

    /* make sure the session-id element is present
     * This should not fail, since already parsed this far 
     */
    sidval = val_find_child(hello, NC_MODULE, NCX_EL_SESSION_ID);
    if (!sidval || sidval->res != NO_ERR) {
        log_error("\nError: no <session-id> found in server <hello>");
        return ERR_NCX_MISSING_VAL_INST;
    } else {
        mscb->agtsid = VAL_UINT(sidval);
    }

    /* go through the capability nodes and construct a caplist */
    for (cap = val_find_child(caps, NC_MODULE, NCX_EL_CAPABILITY);
         cap != NULL;
         cap = val_find_next_child(caps, 
                                   NC_MODULE, 
                                   NCX_EL_CAPABILITY, 
                                   cap)) {

        if (cap->res != NO_ERR) {
            continue;
        }
        
        res = cap_add_std_string(&mscb->caplist, VAL_STR(cap));
        if (res == ERR_NCX_SKIPPED) {
            res = cap_add_module_string(&mscb->caplist, VAL_STR(cap));
            if (res == ERR_NCX_SKIPPED) {
                /* 
                 * if (ncx_warning_enabled(ERR_NCX_RCV_UNKNOWN_CAP)) {
                 *    log_warn("\nWarning: received unknown capability '%s'",
                 *             VAL_STR(cap));
                 * }
                 */
                if (LOGDEBUG2) {
                    log_debug2("\nmgr: Got enterprise capability %s", 
                               VAL_STR(cap));
                }

                /* hack: check for juniper 1.0 server
                 * change the useprefix mode to TRUE to get
                 * <rpc> operations to work with this server
                 */
                if (!xml_strcmp(VAL_STR(cap), CAP_JUNOS)) {
                    if (LOGDEBUG) {
                        log_debug("\nUsing XML prefixes to work "
                                  "with Junos 1.0 server\n");
                    }
                    ncx_set_useprefix(TRUE);
                }

                res = cap_add_ent(&mscb->caplist, VAL_STR(cap));
                if (res != NO_ERR) {
                    return res;
                }
            }
        }
    }

    /* check if the mandatory base protocol capability was set */
    res = NO_ERR;
    c1 = cap_std_set(&mscb->caplist, CAP_STDID_V1);
    c2 = cap_std_set(&mscb->caplist, CAP_STDID_V11);

    if (c1 && c2) {
        if (LOGDEBUG2) {
            log_debug2("\nmgr_hello: server supports "
                       "base:1.0 and base:1.1");
        }
        if (ses_protocol_requested(scb, NCX_PROTO_NETCONF11)) {
            if (LOGDEBUG2) {
                log_debug2("\nmgr_hello: set protocol to base:1.1 "
                           "for session '%d'",
                           scb->sid);
            }
            ses_set_protocol(scb, NCX_PROTO_NETCONF11);
        } else if (ses_protocol_requested(scb, NCX_PROTO_NETCONF10)) {
            if (LOGDEBUG2) {
                log_debug2("\nmgr_hello: set protocol to base:1.0 "
                           "for session '%d'",
                           scb->sid);
            }
            ses_set_protocol(scb, NCX_PROTO_NETCONF10);
        } else {
            log_error("\nError: Internal: no protocols requested, "
                      "dropping session '%d'",
                      scb->sid);
            res = ERR_NCX_MISSING_VAL_INST;
        }
    } else if (c1) {
        if (LOGDEBUG2) {
            log_debug2("\nmgr_hello: server supports "
                       "base:1.0 only");
        }
        if (ses_protocol_requested(scb, NCX_PROTO_NETCONF10)) {
            if (LOGDEBUG2) {
                log_debug2("\nmgr_hello: set protocol to base:1.0 "
                           "for session '%d'",
                           scb->sid);
            }
            ses_set_protocol(scb, NCX_PROTO_NETCONF10);
        } else {
            log_error("\nError: Server supports base:1.0 only;"
                     "\n  Protocol 'netconf1.0' not enabled, "
                      "dropping session '%d'",
                      scb->sid);
            res = ERR_NCX_MISSING_VAL_INST;
        }
    } else if (c2) {
        if (LOGDEBUG2) {
            log_debug2("\nmgr_hello: server supports "
                       "base:1.1 only");
        }
        if (ses_protocol_requested(scb, NCX_PROTO_NETCONF11)) {
            if (LOGDEBUG2) {
                log_debug2("\nmgr_hello: set protocol to base:1.1 "
                           "for session '%d'",
                           scb->sid);
            }
            ses_set_protocol(scb, NCX_PROTO_NETCONF11);
        } else {
            log_error("\nError: Server supports base:1.1 only;"
                     "\n  Protocol 'netconf1.1' not enabled, "
                      "dropping session '%d'",
                      scb->sid);
            res = ERR_NCX_MISSING_VAL_INST;
        }
    } else {
        log_error("\nError: no support for base:1.0 "
                  "or base:1.1 found in server <hello>;"
                  "\n   dropping session '%d'",
                  scb->sid);
        return ERR_NCX_MISSING_VAL_INST;
    }

    /* set target type var in the manager session control block */
    c1 = cap_std_set(&mscb->caplist, CAP_STDID_WRITE_RUNNING);
    c2 = cap_std_set(&mscb->caplist, CAP_STDID_CANDIDATE);

    if (c1 && c2) {
        mscb->targtyp = NCX_AGT_TARG_CAND_RUNNING;
    } else if (c1) {
        mscb->targtyp = NCX_AGT_TARG_RUNNING;
    } else if (c2) {
        mscb->targtyp = NCX_AGT_TARG_CANDIDATE;
    } else {
        mscb->targtyp = NCX_AGT_TARG_NONE;
        if (LOGINFO) {
            log_info("\nmgr_hello: no writable target found for"
                     " session %u (a:%u)", 
                     scb->sid,
                     mscb->agtsid);
        }
    }

    /* set the startup type in the mscb */
    if (cap_std_set(&mscb->caplist, CAP_STDID_STARTUP)) {
        mscb->starttyp = NCX_AGT_START_DISTINCT;
    } else {
        mscb->starttyp = NCX_AGT_START_MIRROR;
    }

    return NO_ERR;

} /* process_server_hello */
Exemplo n.º 23
0
/********************************************************************
* FUNCTION mgr_hello_send
*
* Send the manager <hello> message to the server on the 
* specified session
*
* INPUTS:
*   scb == session control block
*
* RETURNS:
*   status
*********************************************************************/
status_t
    mgr_hello_send (ses_cb_t *scb)
{
    val_value_t  *mycaps;
    xml_msg_hdr_t msg;
    status_t      res;
    xml_attrs_t   attrs;
    boolean       anyout;
    xmlns_id_t    nc_id;

#ifdef DEBUG
    if (!scb) {
        return SET_ERROR(ERR_INTERNAL_PTR);
    }
#endif

#ifdef MGR_HELLO_DEBUG
    if (LOGDEBUG2) {
        log_debug2("\nmgr sending hello on session %d", scb->sid);
    }
#endif

    res = NO_ERR;
    anyout = FALSE;
    xml_msg_init_hdr(&msg);
    xml_init_attrs(&attrs);
    nc_id = xmlns_nc_id();

    /* get my client caps, custom made for this session */
    mycaps = mgr_cap_get_ses_capsval(scb);
    if (!mycaps) {
        res = SET_ERROR(ERR_INTERNAL_PTR);
    }

    /* setup the prefix map with the NETCONF namespace */
    if (res == NO_ERR) {
        res = xml_msg_build_prefix_map(&msg, &attrs, TRUE, FALSE);
    }

    /* send the <?xml?> directive */
    if (res == NO_ERR) {
        res = ses_start_msg(scb);
    }

    /* start the hello element */
    if (res == NO_ERR) {
        anyout = TRUE;
        xml_wr_begin_elem_ex(scb, 
                             &msg, 
                             0, 
                             nc_id, 
                             NCX_EL_HELLO, 
                             &attrs, 
                             ATTRQ, 
                             0, 
                             START);
    }
    
    /* send the capabilities list */
    if (res == NO_ERR) {
        xml_wr_full_val(scb, &msg, mycaps, NCX_DEF_INDENT);
    }

    /* finish the hello element */
    if (res == NO_ERR) {
        xml_wr_end_elem(scb, &msg, nc_id, NCX_EL_HELLO, 0);
    }

    /* finish the message */
    if (anyout) {
        ses_finish_msg(scb);
    }

    xml_clean_attrs(&attrs);
    xml_msg_clean_hdr(&msg);
    if (mycaps != NULL) {
        val_free_value(mycaps);
    }
    return res;

} /* mgr_hello_send */
Exemplo n.º 24
0
int
deliver_imap_deliver(struct deliver_ctx *dctx, struct actitem *ti)
{
	struct account			*a = dctx->account;
	struct mail			*m = dctx->mail;
	struct deliver_imap_data	*data = ti->data;
	struct io			*io;
	struct fetch_ctx		 fctx;
	struct fetch_imap_data		 fdata;
	char				*cause, *folder, *ptr, *line;
	size_t				 len, maillen;
	u_int				 total, body;

	/* Connect to the IMAP server. */
	io = connectproxy(&data->server,
	    conf.verify_certs, conf.proxy, IO_CRLF, conf.timeout, &cause);
	if (io == NULL) {
		log_warnx("%s: %s", a->name, cause);
		xfree(cause);
		return (DELIVER_FAILURE);
	}
	if (conf.debug > 3 && !conf.syslog)
		io->dup_fd = STDOUT_FILENO;

	/* Work out the folder name. */
	folder = replacestr(&data->folder, m->tags, m, &m->rml);
	if (folder == NULL || *folder == '\0') {
		log_warnx("%s: empty folder", a->name);
		goto error;
	}

	/* Fake up the fetch context for the fetch code. */
	memset(&fdata, 0, sizeof fdata);
	fdata.user = data->user;
	fdata.pass = data->pass;
	fdata.nocrammd5 = data->nocrammd5;
	fdata.nologin = data->nologin;
	memcpy(&fdata.server, &data->server, sizeof fdata.server);
	fdata.io = io;
	fdata.only = FETCH_ONLY_ALL;
	a->data = &fdata;
	fetch_imap_state_init(a, &fctx);
	fctx.state = imap_state_connected;
	fctx.llen = IO_LINESIZE;
	fctx.lbuf = xmalloc(fctx.llen);

	/* Use the fetch code until the select1 state is reached. */
	if (deliver_imap_pollto(imap_state_select1, a, io, &fctx) != 0)
		goto error;

retry:
	/* Send an append command. */
	if (imap_putln(a, "%u APPEND {%zu}", ++fdata.tag, strlen(folder)) != 0)
		goto error;
	switch (deliver_imap_waitappend(a, &fctx, io, &line)) {
	case IMAP_TAG_ERROR:
		if (line != NULL)
			imap_invalid(a, line);
		goto error;
	case IMAP_TAG_CONTINUE:
		break;
	default:
		if (imap_no(line) && strstr(line, "[TRYCREATE]") != NULL)
			goto try_create;
		imap_invalid(a, line);
		goto error;
	}

	/*
	 * Send the mail size, not forgetting lines are CRLF terminated. The
	 * Google IMAP server is written strangely, so send the size as if
	 * every CRLF was a CR if the server has XYZZY.
	 */
	count_lines(m, &total, &body);
	maillen = m->size + total - 1;
	if (fdata.capa & IMAP_CAPA_XYZZY) {
		log_debug2("%s: adjusting size: actual %zu", a->name, maillen);
		maillen = m->size;
	}
	if (fdata.capa & IMAP_CAPA_NOSPACE) {
		if (imap_putln(a, "%s{%zu}", folder, maillen) != 0)
			goto error;
	} else {
		if (imap_putln(a, "%s {%zu}", folder, maillen) != 0)
			goto error;
	}
	switch (deliver_imap_waitappend(a, &fctx, io, &line)) {
	case IMAP_TAG_ERROR:
		if (line != NULL)
			imap_invalid(a, line);
		goto error;
	case IMAP_TAG_CONTINUE:
		break;
	default:
		if (imap_no(line) && strstr(line, "[TRYCREATE]") != NULL)
			goto try_create;
		imap_invalid(a, line);
		goto error;
	}

	/* Send the mail data. */
	line_init(m, &ptr, &len);
	while (ptr != NULL) {
		if (len > 1)
			io_write(io, ptr, len - 1);
		io_writeline(io, NULL);

		/* Update if necessary. */
		if (io_update(io, conf.timeout, &cause) != 1) {
			log_warnx("%s: %s", a->name, cause);
			xfree(cause);
			goto error;
		}

		line_next(m, &ptr, &len);
	}

	/* Wait for an okay from the server. */
	switch (deliver_imap_waitappend(a, &fctx, io, &line)) {
	case IMAP_TAG_ERROR:
	case IMAP_TAG_CONTINUE:
		if (line != NULL)
			imap_invalid(a, line);
		goto error;
	default:
		if (imap_okay(line))
			break;
		if (strstr(line, "[TRYCREATE]") != NULL)
			goto try_create;
		imap_invalid(a, line);
		goto error;
	}

	xfree(fctx.lbuf);
	xfree(folder);

	if (imap_putln(a, "%u LOGOUT", ++fdata.tag) != 0)
		goto error;
	if (deliver_imap_waitokay(a, &fctx, io, &line) != 0)
		goto error;

	fdata.disconnect(a);
	return (DELIVER_SUCCESS);

try_create:	/* XXX function? */
	/* Try to create the folder. */
	if (imap_putln(a, "%u CREATE {%zu}", ++fdata.tag, strlen(folder)) != 0)
		goto error;
	if (deliver_imap_waitcontinue(a, &fctx, io, &line) != 0)
		goto error;
	if (imap_putln(a, "%s", folder) != 0)
		goto error;
	if (deliver_imap_waitokay(a, &fctx, io, &line) != 0)
		goto error;
	goto retry;

error:
	io_writeline(io, "QUIT");
	io_flush(io, conf.timeout, NULL);

	xfree(fctx.lbuf);
	if (folder != NULL)
		xfree(folder);

	fdata.disconnect(a);
	return (DELIVER_FAILURE);
}
Exemplo n.º 25
0
/********************************************************************
* FUNCTION send_lock_pdu_to_server
* 
* Send a <lock> or <unlock> operation to the server
*
* INPUTS:
*   server_cb == server control block to use
*   lockcb == lock control block to use within server_cb
*   islock == TRUE for lock; FALSE for unlock
*
* RETURNS:
*    status
*********************************************************************/
static status_t
    send_lock_pdu_to_server (server_cb_t *server_cb,
                            lock_cb_t *lockcb,
                            boolean islock)
{
    obj_template_t        *rpc, *input;
    mgr_rpc_req_t         *req;
    val_value_t           *reqdata, *targetval, *parmval;
    ses_cb_t              *scb;
    status_t               res;
    xmlns_id_t             obj_nsid;

    req = NULL;
    reqdata = NULL;
    res = NO_ERR;

    if (LOGDEBUG) {
        log_debug("\nSending <%s> request",
                  (islock) ? NCX_EL_LOCK : NCX_EL_UNLOCK);
    }

    if (islock) {
        rpc = ncx_find_object(get_netconf_mod(server_cb), 
                              NCX_EL_LOCK);
    } else {
        rpc = ncx_find_object(get_netconf_mod(server_cb), 
                              NCX_EL_UNLOCK);
    }
    if (!rpc) {
        return SET_ERROR(ERR_NCX_DEF_NOT_FOUND);
    }

    obj_nsid = obj_get_nsid(rpc);

    /* get the 'input' section container */
    input = obj_find_child(rpc, NULL, YANG_K_INPUT);
    if (!input) {
        return SET_ERROR(ERR_NCX_DEF_NOT_FOUND);
    }

    /* construct a method + parameter tree */
    reqdata = xml_val_new_struct(obj_get_name(rpc), obj_nsid);
    if (!reqdata) {
        log_error("\nError allocating a new RPC request");
        return ERR_INTERNAL_MEM;
    }

    /* set the [un]lock/input/target node XML namespace */
    targetval = xml_val_new_struct(NCX_EL_TARGET, obj_nsid);
    if (!targetval) {
        log_error("\nError allocating a new RPC request");
        val_free_value(reqdata);
        return ERR_INTERNAL_MEM;
    } else {
        val_add_child(targetval, reqdata);
    }

    parmval = xml_val_new_flag(lockcb->config_name,
                               obj_nsid);
    if (!parmval) {
        val_free_value(reqdata);
        return ERR_INTERNAL_MEM;
    } else {
        val_add_child(parmval, targetval);
    }

    scb = mgr_ses_get_scb(server_cb->mysid);
    if (!scb) {
        res = SET_ERROR(ERR_INTERNAL_PTR);
    } else {
        req = mgr_rpc_new_request(scb);
        if (!req) {
            res = ERR_INTERNAL_MEM;
            log_error("\nError allocating a new RPC request");
        } else {
            req->data = reqdata;
            req->rpc = rpc;
            req->timeout = server_cb->timeout;
        }
    }
        
    /* if all OK, send the RPC request */
    if (res == NO_ERR) {
        if (LOGDEBUG2) {
            log_debug2("\nabout to send RPC request with reqdata:");
            val_dump_value_max(reqdata, 
                               0,
                               server_cb->defindent,
                               DUMP_VAL_LOG,
                               server_cb->display_mode,
                               FALSE,
                               FALSE);
        }

        /* the request will be stored if this returns NO_ERR */
        res = mgr_rpc_send_request(scb, req, yangcli_reply_handler);
        if (res == NO_ERR) {
            if (islock) {
                lockcb->lock_state = LOCK_STATE_REQUEST_SENT;
            } else {
                lockcb->lock_state = LOCK_STATE_RELEASE_SENT;
            }
            (void)uptime(&lockcb->last_msg_time);
            server_cb->locks_cur_cfg = lockcb->config_id;
        }
    }

    /* cleanup and set next state */
    if (res != NO_ERR) {
        if (req) {
            mgr_rpc_free_request(req);
        } else if (reqdata) {
            val_free_value(reqdata);
        }
    } else {
        server_cb->state = MGR_IO_ST_CONN_RPYWAIT;
    }

    return res;

} /* send_lock_pdu_to_server */
Exemplo n.º 26
0
/********************************************************************
* FUNCTION parse_parm
* 
* Parse, and fill one val_value_t struct during
* processing of a parmset
*
* Error messages are printed by this function!!
* Do not duplicate error messages upon error return
*
*
* INPUTS:
*   tkc == token chain
*   val == container val to fill in
*   keepvals == TRUE to save existing parms in 'ps', as needed
*               FALSE to overwrite old parms in 'ps', as needed
*
* RETURNS:
*   status of the operation
*********************************************************************/
static status_t 
    parse_parm (tk_chain_t  *tkc,
                val_value_t *val,
                boolean keepvals)
{
    obj_template_t         *obj;
    const xmlChar          *modname;
    val_value_t            *curparm, *newparm;
    status_t                res;
    ncx_iqual_t             iqual;
    boolean                 match, usewarning, isdefault;

    
    /* get the next token, which must be a TSTRING
     * representing the parameter name 
     */
    if (TK_CUR_TYP(tkc) != TK_TT_TSTRING) {
        res = ERR_NCX_WRONG_TKTYPE;
        ncx_conf_exp_err(tkc, res, "parameter name");
        return res;
    }

    curparm = NULL;
    usewarning = ncx_warning_enabled(ERR_NCX_CONF_PARM_EXISTS);

    /* check if this TSTRING is a parameter in this parmset
     * make sure to always check for prefix:identifier
     * This is automatically processed in tk.c
     */
    if (TK_CUR_MOD(tkc)) {
        modname = xmlns_get_module
            (xmlns_find_ns_by_prefix(TK_CUR_MOD(tkc)));
        if (modname) {
            curparm = val_find_child(val, 
                                     modname,
                                     TK_CUR_VAL(tkc));
        }
    }  else {
        curparm = val_find_child(val, 
                                 val_get_mod_name(val),
                                 TK_CUR_VAL(tkc));
    }
        
    if (curparm) {
        obj = curparm->obj;
    } else {
        obj = obj_find_child(val->obj, 
                             TK_CUR_MOD(tkc),
                             TK_CUR_VAL(tkc));
    }
    if (!obj) {
        res = ERR_NCX_UNKNOWN_PARM;
        if (TK_CUR_MOD(tkc)) {
            log_error("\nError: parameter '%s:%s' not found",
                      TK_CUR_MOD(tkc),
                      TK_CUR_VAL(tkc));
        } else {
            log_error("\nError: parameter '%s' not found",
                      TK_CUR_VAL(tkc));
        }
        ncx_conf_exp_err(tkc, res, "parameter name");
        return res;
    }

    /* got a valid parameter name, now create a new parm
     * even if it may not be kept.  There are corner-cases
     * that require the new value be parsed before knowing
     * if a parm value is a duplicate or not
     */
    newparm = val_new_value();
    if (!newparm) {
        res = ERR_INTERNAL_MEM;
        ncx_print_errormsg(tkc, NULL, res);
        return res;
    }
    val_init_from_template(newparm, obj);

    /* parse the parameter value */
    res = parse_val(tkc, obj, newparm);
    if (res != NO_ERR) {
        val_free_value(newparm);
        return res;
    }

    /* check if a potential current value exists, or just
     * add the newparm to the parmset
     */
    if (curparm) {
        isdefault = val_set_by_default(curparm);
        iqual = obj_get_iqualval(obj);
        if (iqual == NCX_IQUAL_ONE || iqual == NCX_IQUAL_OPT) {
            /* only one allowed, check really a match */
            match = TRUE;
            if (val_has_index(curparm) &&
                !val_index_match(newparm, curparm)) {
                match = FALSE;
            }

            if (!match) {
                val_add_child(newparm, val);
            } else if (isdefault) {
                dlq_remove(curparm);
                val_free_value(curparm);
                val_add_child(newparm, val);
            } else if (keepvals) {
                if (usewarning) {
                    /* keep current value and toss new value */
                    log_warn("\nWarning: Parameter '%s' already exists. "
                             "Not using new value\n", 
                             curparm->name);
                    if (LOGDEBUG2) {
                        val_dump_value(newparm, NCX_DEF_INDENT);
                        log_debug2("\n");
                    }
                }
                val_free_value(newparm);
            } else {
                if (usewarning) {
                    /* replace current value and warn old value tossed */
                    log_warn("\nconf: Parameter '%s' already exists. "
                             "Overwriting with new value\n",
                             curparm->name);
                    if (LOGDEBUG2) {
                        val_dump_value(newparm, NCX_DEF_INDENT);
                        log_debug2("\n");
                    }
                }
                dlq_remove(curparm);
                val_free_value(curparm);
                val_add_child(newparm, val);
            }
        } else {
            /* mutliple instances allowed */
            val_add_child(newparm, val);
        }
    } else {
        val_add_child(newparm, val);
    }

    return NO_ERR;

}  /* parse_parm */
Exemplo n.º 27
0
/********************************************************************
 * FUNCTION cmn_init
 * 
 * 
 * 
 *********************************************************************/
static status_t cmn_init ( int argc, char *argv[], boolean *showver,
                           help_mode_t *showhelpmode)
{
#define BUFFLEN 256

    status_t     res;
    log_debug_t  dlevel;
    int          len;
    char         buff[BUFFLEN];

    /* set the default debug output level */
    dlevel = LOG_DEBUG_INFO;

    /* initialize the NCX Library first to allow NCX modules to be processed.  
     * No module can get its internal config until the NCX module parser and 
     * definition registry is up */
    len = strlen(START_MSG) + strlen(COPYRIGHT_STRING) + 2;

    if (len < BUFFLEN) {
        strcpy(buff, START_MSG);
        strcat(buff, COPYRIGHT_STRING);
    } else {
        return ERR_BUFF_OVFL;
    }

    res = ncx_init( FALSE, dlevel, TRUE, buff, argc, argv);

    if (res != NO_ERR) {
        return res;
    }

    log_debug2("\nnetconfd: Loading Netconf Server Library");

    /* at this point, modules that need to read config params can be 
     * initialized */

    /* Load the core modules (netconfd and netconf) */
    res = load_base_schema();
    if (res != NO_ERR) {
        return res;
    }

    /* Initialize the Netconf Server Library with command line and conf file 
     * parameters */
    res = agt_init1(argc, argv, showver, showhelpmode);
    if (res != NO_ERR) {
        return res;
    }

    /* check quick-exit mode */
    if (*showver || *showhelpmode != HELP_MODE_NONE) {
        return NO_ERR;
    }

    /* Load the core modules (netconfd and netconf) */
    res = load_core_schema(agt_get_profile());
    if (res != NO_ERR) {
        return res;
    }

    /* finidh initializing server data structures */
    res = agt_init2();
    if (res != NO_ERR) {
        return res;
    }

    log_debug("\nnetconfd init OK, ready for sessions\n");

    return NO_ERR;

}  /* cmn_init */
Exemplo n.º 28
0
/* Check mail against next rule or part of expression. */
int
mail_match(struct mail_ctx *mctx, struct msg *msg, struct msgbuf *msgbuf)
{
	struct account	*a = mctx->account;
	struct mail	*m = mctx->mail;
	struct expritem	*ei;
	struct replstrs	*users;
	int		 should_free, this = -1, error = MAIL_CONTINUE;
	char		 desc[DESCBUFSIZE];

	set_wrapped(m, ' ');

	/* If blocked, check for msgs from parent. */
	if (mctx->msgid != 0) {
		if (msg == NULL || msg->id != mctx->msgid)
			return (MAIL_BLOCKED);
		mctx->msgid = 0;

		if (msg->type != MSG_DONE)
			fatalx("unexpected message");
		if (msgbuf->buf != NULL && msgbuf->len != 0) {
			strb_destroy(&m->tags);
			m->tags = msgbuf->buf;
			reset_tags(&m->tags);
		}

		ei = mctx->expritem;
		switch (msg->data.error) {
		case MATCH_ERROR:
			return (MAIL_ERROR);
		case MATCH_TRUE:
			this = 1;
			break;
		case MATCH_FALSE:
			this = 0;
			break;
		default:
			fatalx("unexpected response");
		}
		apply_result(ei, &mctx->result, this);

		goto next_expritem;
	}

	/* Check for completion and end of ruleset. */
	if (mctx->done)
		return (MAIL_DONE);
	if (mctx->rule == NULL) {
		switch (conf.impl_act) {
		case DECISION_NONE:
			log_warnx("%s: reached end of ruleset. no "
			    "unmatched-mail option; keeping mail",  a->name);
			m->decision = DECISION_KEEP;
			break;
		case DECISION_KEEP:
			log_debug2("%s: reached end of ruleset. keeping mail",
			    a->name);
			m->decision = DECISION_KEEP;
			break;
		case DECISION_DROP:
			log_debug2("%s: reached end of ruleset. dropping mail",
			    a->name);
			m->decision = DECISION_DROP;
			break;
		}
		return (MAIL_DONE);
	}

	/* Expression not started. Start it. */
	if (mctx->expritem == NULL) {
		/* Start the expression. */
		mctx->result = 0;
		mctx->expritem = TAILQ_FIRST(mctx->rule->expr);
	}

	/* Check this expression item and adjust the result. */
	ei = mctx->expritem;

	/* Handle short-circuit evaluation. */
	switch (ei->op) {
	case OP_NONE:
		break;
	case OP_AND:
		/* And and the result is already false. */
		if (!mctx->result)
			goto next_expritem;
		break;
	case OP_OR:
		/* Or and the result is already true. */
		if (mctx->result)
			goto next_expritem;
		break;
	}

	switch (ei->match->match(mctx, ei)) {
	case MATCH_ERROR:
		return (MAIL_ERROR);
	case MATCH_PARENT:
		return (MAIL_BLOCKED);
	case MATCH_TRUE:
		this = 1;
		break;
	case MATCH_FALSE:
		this = 0;
		break;
	default:
		fatalx("unexpected op");
	}
	apply_result(ei, &mctx->result, this);

	ei->match->desc(ei, desc, sizeof desc);
	log_debug3("%s: tried %s, result now %d", a->name, desc, mctx->result);

next_expritem:
	/* Move to the next item. If there is one, then return. */
	mctx->expritem = TAILQ_NEXT(mctx->expritem, entry);
	if (mctx->expritem != NULL)
		return (MAIL_CONTINUE);

	log_debug3("%s: finished rule %u, result %d", a->name, mctx->rule->idx,
	    mctx->result);

	/* If the result was false, skip to find the next rule. */
	if (!mctx->result)
		goto next_rule;
	log_debug2("%s: matched to rule %u", a->name, mctx->rule->idx);

	/*
	 * If this rule is stop, mark the context so when we get back after
	 * delivery we know to stop.
	 */
	if (mctx->rule->stop)
		mctx->done = 1;

	/* Handle nested rules. */
	if (!TAILQ_EMPTY(&mctx->rule->rules)) {
		log_debug2("%s: entering nested rules", a->name);

		/*
		 * Stack the current rule (we are at the end of it so the
		 * the expritem must be NULL already).
		 */
		ARRAY_ADD(&mctx->stack, mctx->rule);

		/* Continue with the first rule of the nested list. */
		mctx->rule = TAILQ_FIRST(&mctx->rule->rules);
		return (MAIL_CONTINUE);
	}
	mctx->matched = 1;

	/* Handle lambda actions. */
	if (mctx->rule->lambda != NULL) {
		users = find_delivery_users(mctx, NULL, &should_free);

		chained = MAXACTIONCHAIN;
		if (fill_from_action(mctx,
		    mctx->rule, mctx->rule->lambda, users) != 0) {
			if (should_free)
				ARRAY_FREEALL(users);
			return (MAIL_ERROR);
		}

		if (should_free)
			ARRAY_FREEALL(users);
		error = MAIL_DELIVER;
	}

	/* Fill the delivery action queue. */
	if (!ARRAY_EMPTY(mctx->rule->actions)) {
		chained = MAXACTIONCHAIN;
		if (fill_from_strings(mctx,
		    mctx->rule, mctx->rule->actions) != 0)
			return (MAIL_ERROR);
		error = MAIL_DELIVER;
	}

next_rule:
	/* Move to the next rule. */
	mctx->ruleidx = mctx->rule->idx;	/* save last index */
	mctx->rule = TAILQ_NEXT(mctx->rule, entry);

	/* If no more rules, try to move up the stack. */
	while (mctx->rule == NULL) {
		if (ARRAY_EMPTY(&mctx->stack))
			break;
		log_debug2("%s: exiting nested rules", a->name);
		mctx->rule = ARRAY_LAST(&mctx->stack);
		mctx->rule = TAILQ_NEXT(mctx->rule, entry);
		ARRAY_TRUNC(&mctx->stack, 1);
	}

	return (error);
}
Exemplo n.º 29
0
static gboolean library_view_update_info(library_view_t* view)
{
  if (view->run_timeout) {
    
    // update play buttons
    playlist_player_t* player = backtobasics_player(view->btb);
    if (view->btn_play == NULL) {
      view->btn_play = GTK_WIDGET(gtk_builder_get_object(view->builder, "tbtn_library_play"));
    }
    if (view->btn_pause == NULL) {
      view->btn_pause = GTK_WIDGET(gtk_builder_get_object(view->builder, "tbtn_library_pause"));
    }
    GtkWidget* btn_play = view->btn_play;
    GtkWidget* btn_pause = view->btn_pause;
    if (!playlist_player_is_playing(player)) {
      if (!gtk_widget_get_visible(btn_play)) gtk_widget_show_all(btn_play);
      if (gtk_widget_get_visible(btn_pause)) gtk_widget_hide(btn_pause);
    } else if (playlist_player_is_playing(player)) {
      if (gtk_widget_get_visible(btn_play)) gtk_widget_hide(btn_play);
      if (!gtk_widget_get_visible(btn_pause)) gtk_widget_show_all(btn_pause);
    }
    
    // update slider and time
    long tr_tm = playlist_player_get_track_position_in_ms(player);
    track_t* track = playlist_player_get_track(player);
    int index = playlist_player_get_track_index(player);
    
    int a = tr_tm / 1000;
    int b = view->time_in_ms / 1000;
    
    if (a != b) {
      view->time_in_ms = tr_tm;
      int min = tr_tm / 1000 / 60;
      int sec = (tr_tm / 1000) % 60;
      { 
        char s[200]; 
        sprintf(s,"<span size=\"x-small\"><b><i>%02d:%02d</i></b></span>", min, sec);
        GtkLabel* lbl = GTK_LABEL(gtk_builder_get_object(view->builder, "lbl_time"));
        gtk_label_set_markup(lbl, s);
        
        // update presets
        reflect_presets(view->btb);
      }
      
      GtkScale* sc_playback = GTK_SCALE(gtk_builder_get_object(view->builder, "sc_library_playback"));
      double perc = 0.0;
      if (track != NULL) {
        int len_in_ms = track_get_length_in_ms(track);
        
        if (len_in_ms != view->len_in_ms) {
          view->len_in_ms = len_in_ms;
          int min = len_in_ms / 1000 / 60;
          int sec = (len_in_ms / 1000) % 60;
          {
            char s[200];
            sprintf(s,"<span size=\"x-small\"><b><i>%02d:%02d</i></b></span>", min, sec);
            GtkLabel* lbl = GTK_LABEL(gtk_builder_get_object(view->builder, "lbl_total"));
            gtk_label_set_markup(lbl, s);
          }
        }
        
        perc = (((double) tr_tm) / ((double) len_in_ms)) * 100.0;
        if (!view->sliding) {
          gtk_range_set_value(GTK_RANGE(sc_playback), perc);
        }
      }

      // update track info
      if (index != view->track_index || 
            (track != NULL && track_get_id(track) != view->track_id)) {
        log_debug3("updating track info, index = %d, %p", index, track);
        view->track_index = index;
        if (track != NULL) {
          
          // fetch lyric if possible
          if (strcmp(track_get_lyric(track),"") == 0) {
            struct lyric_cb* cb = (struct lyric_cb*) mc_malloc(sizeof(struct lyric_cb));
            cb->track_id = mc_strdup(track_get_id(track));
            cb->view = view;
            fetch_lyric(track, library_view_process_lyric, cb);
          } else {
            struct lyric_cb* cb = (struct lyric_cb*) mc_malloc(sizeof(struct lyric_cb));
            cb->track_id = mc_strdup(track_get_id(track));
            cb->view = view;
            library_view_process_lyric(mc_strdup(track_get_lyric(track)), cb);
          }
            
          // Print artist info
          view->track_id = track_get_id(track);
          log_debug2("artid = %s", track_get_artid(track));
          char s[200];
          char c = ',';
          char c1 = ',';
          char *artist = text_to_html(track_get_artist(track));
          char *title = text_to_html(track_get_title(track));
          char *piece = text_to_html(track_get_piece(track));
          
          if (strcmp(track_get_artist(track), "") == 0) { c = ' '; }
          if (strcmp(track_get_piece(track), "") == 0) { c1 = ' '; }
          snprintf(s, 125,
                   "%s%c %s%c %s", 
                   artist,
                   c,
                   piece,
                   c1,
                   title
                   );
          mc_free(artist);
          mc_free(title);
          mc_free(piece);
          char ss[400];
          log_debug2("s = %s", s);
          sprintf(ss,"<span size=\"x-small\"><i><b>%s</b></i></span>",s);
          GtkLabel* lbl = GTK_LABEL(gtk_builder_get_object(view->builder, "lbl_song_info"));
          gtk_label_set_markup(lbl, ss);
          
          log_debug2("artid = %s", track_get_artid(track));
          file_info_t* info = file_info_new(track_get_artid(track));
          if (!file_info_is_file(info)) {
            file_info_destroy(info);
            char *path = backtobasics_logo(view->btb); 
            info = file_info_new(path);
            mc_free(path);
            //info = file_info_new(backtobasics_logo(view->btb));
          }
          
          if (file_info_is_file(info)) {
            GError *err = NULL;
            GdkPixbuf* pb = gdk_pixbuf_new_from_file_at_scale(file_info_path(info),
                                                              view->img_w, view->img_h,
                                                              TRUE,
                                                              &err
                                                              );
            if (pb != NULL) {
              GtkImage* img = GTK_IMAGE(gtk_builder_get_object(view->builder, "img_art"));
              gtk_image_set_from_pixbuf(img, pb);
              g_object_unref(pb);
            } else {
              log_error3("error loading image art: %d, %s", err->code, err->message);
              //g_free(err);
            }
          }
          file_info_destroy(info);
        }

        log_debug("track hash");

        
        // Select the track in the librarylist if the librarylist is still
        // the same
        if (playlist_model_tracks_hash(view->playlist_model) == playlist_player_get_hash(player)) {
          GtkTreeView* tview = view->tview;
          GtkTreePath* path = gtk_tree_path_new();
          gtk_tree_path_append_index(path, index);
          gtk_tree_view_set_cursor(tview, path, NULL, FALSE);
          gtk_tree_path_free(path);
        } 
        log_debug("track hash 2");
        
      }

      //log_debug3("lib hash = %lld, pl hash = %lld", view->library_list_hash, playlist_player_get_hash(player));
      
      // TODO
      if (playlist_model_tracks_hash(view->playlist_model) ==  playlist_player_get_hash(player)) {
        //view->track_index = -1;
      } else {
        
        GtkTreeView* tview = view->tview;
        GtkTreeSelection* sel = gtk_tree_view_get_selection(tview);
        gtk_tree_selection_unselect_all(sel);
      }
      
    }
    
    // update repeat info
    playlist_player_repeat_t repeat = playlist_player_get_repeat(player);
    if (view->repeat != repeat) {
      log_debug3("repeat = %d, view repeat = %d", repeat, view->repeat);
      view->repeat = repeat;
      GtkWidget* r_btn = GTK_WIDGET(gtk_builder_get_object(view->builder, "tbtn_repeat"));
      GtkWidget* r1_btn = GTK_WIDGET(gtk_builder_get_object(view->builder, "tbtn_repeat_one"));
      GtkWidget* rlist_btn = GTK_WIDGET(gtk_builder_get_object(view->builder, "tbtn_repeat_all"));
      log_debug4("r = %p, r1 = %p, rall = %p", r_btn, r1_btn, rlist_btn);
      switch (repeat) {
        case PLP_NO_REPEAT: {
          gtk_widget_show_all(r_btn);
          gtk_widget_hide(rlist_btn);
          gtk_widget_hide(r1_btn);
        }
        break;
        case PLP_TRACK_REPEAT: {
          gtk_widget_hide(r_btn);
          gtk_widget_show_all(r1_btn);
          gtk_widget_hide(rlist_btn);
        }
        break;
        case PLP_LIST_REPEAT: {
          gtk_widget_hide(r1_btn);
          gtk_widget_show_all(rlist_btn);
          gtk_widget_hide(r_btn);
        }
        break;
      }
    }

    
    return TRUE;
  } else {
    return FALSE;
  }
}
Exemplo n.º 30
0
int
deliver_mbox_deliver(struct deliver_ctx *dctx, struct actitem *ti)
{
    struct account			*a = dctx->account;
    struct mail			*m = dctx->mail;
    struct deliver_mbox_data	*data = ti->data;
    char				*path, *ptr, *lptr, *from = NULL;
    const char			*msg;
    size_t				 len, llen;
    int				 fd, saved_errno;
    FILE				*f;
    gzFile				 gzf;
    long long			 used;
    sigset_t			 set, oset;
    struct stat			 sb;

    f = gzf = NULL;
    fd = -1;

    path = replacepath(&data->path, m->tags, m, &m->rml, dctx->udata->home);
    if (path == NULL || *path == '\0') {
        log_warnx("%s: empty path", a->name);
        goto error;
    }
    if (data->compress) {
        len = strlen(path);
        if (len < 3 || strcmp(path + len - 3, ".gz") != 0) {
            path = xrealloc(path, 1, len + 4);
            strlcat(path, ".gz", len + 4);
        }
    }
    log_debug2("%s: saving to mbox %s", a->name, path);

    /* Save the mbox path. */
    add_tag(&m->tags, "mbox_file", "%s", path);

    /* Check permissions and ownership. */
    if (stat(path, &sb) != 0) {
        if (conf.no_create || errno != ENOENT)
            goto error_log;

        log_debug2("%s: creating %s", a->name, xdirname(path));
        if (xmkpath(xdirname(path), -1, conf.file_group, DIRMODE) != 0)
            goto error_log;
    } else {
        if ((msg = checkmode(&sb, UMASK(FILEMODE))) != NULL)
            log_warnx("%s: %s: %s", a->name, path, msg);
        if ((msg = checkowner(&sb, -1)) != NULL)
            log_warnx("%s: %s: %s", a->name, path, msg);
        if ((msg = checkgroup(&sb, conf.file_group)) != NULL)
            log_warnx("%s: %s: %s", a->name, path, msg);
    }

    /* Create or open the mbox. */
    used = 0;
    do {
        if (conf.no_create)
            fd = openlock(path, O_WRONLY|O_APPEND, conf.lock_types);
        else {
            fd = createlock(path, O_WRONLY|O_APPEND,
                            -1, conf.file_group, FILEMODE, conf.lock_types);
        }
        if (fd == -1 && errno == EEXIST)
            fd = openlock(path, O_WRONLY|O_APPEND, conf.lock_types);
        if (fd == -1) {
            if (errno == EAGAIN) {
                if (locksleep(a->name, path, &used) != 0)
                    goto error;
                continue;
            }
            goto error_log;
        }
    } while (fd < 0);

    /* Open gzFile or FILE * for writing. */
    if (data->compress) {
        if ((gzf = gzdopen(fd, "a")) == NULL) {
            errno = ENOMEM;
            goto error_log;
        }
    } else {
        if ((f = fdopen(fd, "a")) == NULL)
            goto error_log;
    }

    /*
     * mboxes are a pain: if we are interrupted after this we risk
     * having written a partial mail. So, block SIGTERM until we're
     * done.
     */
    sigemptyset(&set);
    sigaddset(&set, SIGTERM);
    if (sigprocmask(SIG_BLOCK, &set, &oset) < 0)
        fatal("sigprocmask failed");

    /* Write the from line. */
    from = make_from(m, dctx->udata->name);
    if (deliver_mbox_write(f, gzf, from, strlen(from)) < 0) {
        xfree(from);
        goto error_unblock;
    }
    if (deliver_mbox_write(f, gzf, "\n", 1) < 0) {
        xfree(from);
        goto error_unblock;
    }
    log_debug3("%s: using from line: %s", a->name, from);
    xfree(from);

    /* Write the mail, escaping from lines. */
    line_init(m, &ptr, &len);
    while (ptr != NULL) {
        if (ptr != m->data) {
            /* Skip leading >s. */
            lptr = ptr;
            llen = len;
            while (*lptr == '>' && llen > 0) {
                lptr++;
                llen--;
            }

            if (llen >= 5 && strncmp(lptr, "From ", 5) == 0) {
                log_debug2("%s: quoting from line: %.*s",
                           a->name, (int) len - 1, ptr);
                if (deliver_mbox_write(f, gzf, ">", 1) < 0)
                    goto error_unblock;
            }
        }

        if (deliver_mbox_write(f, gzf, ptr, len) < 0)
            goto error_unblock;

        line_next(m, &ptr, &len);
    }

    /* Append newlines. */
    if (m->data[m->size - 1] == '\n') {
        if (deliver_mbox_write(f, gzf, "\n", 1) < 0)
            goto error_unblock;
    } else {
        if (deliver_mbox_write(f, gzf, "\n\n", 2) < 0)
            goto error_unblock;
    }

    /* Flush buffers and sync. */
    if (gzf == NULL) {
        if (fflush(f) != 0)
            goto error_unblock;
    } else {
        if (gzflush(gzf, Z_FINISH) != Z_OK) {
            errno = EIO;
            goto error_unblock;
        }
    }
    if (fsync(fd) != 0)
        goto error_unblock;

    if (sigprocmask(SIG_SETMASK, &oset, NULL) < 0)
        fatal("sigprocmask failed");

    if (gzf != NULL)
        gzclose(gzf);
    if (f != NULL)
        fclose(f);
    closelock(fd, path, conf.lock_types);

    xfree(path);
    return (DELIVER_SUCCESS);

error_unblock:
    saved_errno = errno;
    if (sigprocmask(SIG_SETMASK, &oset, NULL) < 0)
        fatal("sigprocmask failed");
    errno = saved_errno;

error_log:
    log_warn("%s: %s", a->name, path);

error:
    if (gzf != NULL)
        gzclose(gzf);
    if (f != NULL)
        fclose(f);
    if (fd != -1)
        closelock(fd, path, conf.lock_types);

    if (path != NULL)
        xfree(path);
    return (DELIVER_FAILURE);
}