Пример #1
0
static int output_write(Output *o, const void *buf, size_t size) {
        ssize_t len;
        int r;

        assert_return(o, -EINVAL);
        assert_return(buf || size < 1, -EINVAL);

        if (size < 1)
                return 0;

        if (o->n_obuf + size > o->n_obuf && o->n_obuf + size <= sizeof(o->obuf)) {
                memcpy(o->obuf + o->n_obuf, buf, size);
                o->n_obuf += size;
                return 0;
        }

        r = output_flush(o);
        if (r < 0)
                return r;

        len = loop_write(o->fd, buf, size, false);
        if (len < 0) {
                log_error("error: cannot write to TTY (%zd): %s", len, strerror(-len));
                return len;
        }

        return 0;
}
Пример #2
0
/*
 * literal8_output() copies the 8 byte literals for the data passed to it into
 * the output file's buffer.  The pointer to the merged section passed to it is
 * used to tell where in the output file this section goes.  Then this routine
 * calls literal8_free() to free up all space used by the data block except the
 * data block itself.
 */
__private_extern__
void
literal8_output(
struct literal8_data *data,
struct merged_section *ms)
{
    unsigned long align_multiplier, i, offset;
    struct literal8_block **p, *literal8_block;

	align_multiplier = 1;
 	if((1 << ms->s.align) > 8)
	    align_multiplier = (1 << ms->s.align) / 8;

	/*
	 * Copy the literals into the output file.
	 */
	offset = ms->s.offset;
	for(p = &(data->literal8_blocks); *p ;){
	    literal8_block = *p;
	    for(i = 0; i < literal8_block->used; i++){
		memcpy(output_addr + offset,
		       literal8_block->literal8s + i,
		       sizeof(struct literal8));
		offset += 8 * align_multiplier;
	    }
	    p = &(literal8_block->next);
	}
#ifndef RLD
	output_flush(ms->s.offset, offset - ms->s.offset);
#endif /* !defined(RLD) */
	literal8_free(data);
}
Пример #3
0
static void
changed (guestfs_h *g1, struct file *file1,
         guestfs_h *g2, struct file *file2,
         int st, int cst)
{
    /* Did file content change? */
    if (cst != 0 ||
            (is_reg (file1->stat->st_mode) && is_reg (file2->stat->st_mode) &&
             (file1->stat->st_mtime_sec != file2->stat->st_mtime_sec ||
              file1->stat->st_ctime_sec != file2->stat->st_ctime_sec ||
              file1->stat->st_size != file2->stat->st_size))) {
        output_start_line ();
        output_string ("=");
        output_file (g1, file1);
        output_end_line ();

        if (!csv) {
            /* Display file changes. */
            output_flush ();
            diff (file1, g1, file2, g2);
        }
    }

    /* Did just stats change? */
    else if (st != 0) {
        output_start_line ();
        output_string ("-");
        output_file (g1, file1);
        output_end_line ();
        output_start_line ();
        output_string ("+");
        output_file (g2, file2);
        output_end_line ();

        /* Display stats fields that changed. */
        output_start_line ();
        output_string ("#");
        output_string ("changed:");
#define COMPARE_STAT(n) \
    if (file1->stat->n != file2->stat->n) output_string (#n)
        COMPARE_STAT (st_dev);
        COMPARE_STAT (st_ino);
        COMPARE_STAT (st_mode);
        COMPARE_STAT (st_nlink);
        COMPARE_STAT (st_uid);
        COMPARE_STAT (st_gid);
        COMPARE_STAT (st_rdev);
        COMPARE_STAT (st_size);
        COMPARE_STAT (st_blksize);
        COMPARE_STAT (st_blocks);
        COMPARE_STAT (st_atime_sec);
        COMPARE_STAT (st_mtime_sec);
        COMPARE_STAT (st_ctime_sec);
#undef COMPARE_STAT
        if (guestfs_compare_xattr_list (file1->xattrs, file2->xattrs))
            output_string ("xattrs");
        output_end_line ();
    }
}
Пример #4
0
int _dprintf_hwsync(const char *function, int line, const char *fmt, ...)
{
	char to_format[MAX_PRINT_SIZE];
	char formatted[MAX_PRINT_SIZE];
	va_list ap;
	int nb;

	va_start(ap, fmt);
	(void)vsnprintf(to_format, sizeof(to_format), fmt, ap);
	va_end(ap);

	nb = format_trace(function, line, TRACE_ALWAYS, "HWSYNC", to_format,
			  formatted);

	/* note: no contention or synchro handle with other CPU core ! */
	output_flush();
	output_string(formatted);
	output_flush();

	return nb;
}
Пример #5
0
static int
diff_guests (struct tree *t1, struct tree *t2)
{
    struct file *i1 = &t1->files[0];
    struct file *i2 = &t2->files[0];
    struct file *end1 = &t1->files[t1->nr_files];
    struct file *end2 = &t2->files[t2->nr_files];

    while (i1 < end1 || i2 < end2) {
        if (i1 < end1 && i2 < end2) {
            int comp = strcmp (i1->path, i2->path);

            /* i1->path < i2->path.  i1 catches up with i2 (files deleted) */
            if (comp < 0) {
                deleted (t1->g, i1);
                i1++;
            }
            /* i1->path > i2->path.  i2 catches up with i1 (files added) */
            else if (comp > 0) {
                added (t2->g, i2);
                i2++;
            }
            /* Otherwise i1->path == i2->path, compare in detail. */
            else {
                int st = compare_stats (i1, i2);
                if (st != 0)
                    changed (t1->g, i1, t2->g, i2, st, 0);
                else if (i1->csum && i2->csum) {
                    int cst = strcmp (i1->csum, i2->csum);
                    changed (t1->g, i1, t2->g, i2, 0, cst);
                }
                i1++;
                i2++;
            }
        }
        /* Reached end of i2 list (files deleted). */
        else if (i1 < end1) {
            deleted (t1->g, i1);
            i1++;
        }
        /* Reached end of i1 list (files added). */
        else {
            added (t2->g, i2);
            i2++;
        }
    }

    output_flush ();

    return 0;
}
Пример #6
0
static _rs_inline void *output_alloc( UINT_32 len )
{
  if (output_ptr + len <= output_limit)
    {
      char *p = output_ptr;
      output_ptr += len;
      return (void *)p;
    }
  else
    {
      output_flush(len);
      return (void *)output_buffer;
    }
}
Пример #7
0
/* ---------------------------------------------------------------------- */
void PHRQ_io::
warning_msg(const char *err_str)
/* ---------------------------------------------------------------------- */
{
	if (error_file != NULL && error_on)
	{
		//(*error_file) << err_str << "\n";
		std::string err_stdstr(err_str);
		err_stdstr.append("\n");
		screen_msg(err_stdstr.c_str());
		error_flush();
	}
	std::ostringstream warn_str;
	warn_str << err_str << "\n";
	log_msg(warn_str.str().c_str());
	log_flush();
	output_msg(warn_str.str().c_str());
	output_flush();
}
Пример #8
0
/*
 * setup_output_flush() flushes the gaps between things in the file that are
 * holes created by alignment.  This must stay in lock step with the layout
 * routine that lays out the file (layout_segments() in layout.c).
 */
static
void
setup_output_flush(void)
{
    unsigned long offset;
    struct merged_segment **p, *msg;
    struct merged_section **content, *ms;

	offset = sizeof(struct mach_header) + output_mach_header.sizeofcmds;

	/* the offsets to the contents of the sections */
	p = &merged_segments;
	while(*p){
	    msg = *p;
	    content = &(msg->content_sections);
	    while(*content){
		ms = *content;
		if(ms->s.size != 0){
		    if(ms->s.offset != offset)
			output_flush(offset, ms->s.offset - offset);
		    offset = ms->s.offset + ms->s.size;
		}
		content = &(ms->next);
	    }
	    p = &(msg->next);
	}

	/* the offsets to the relocation entries */
	p = &merged_segments;
	while(*p){
	    msg = *p;
	    content = &(msg->content_sections);
	    while(*content){
		ms = *content;
		if(ms->s.nreloc != 0){
		    if(ms->s.reloff != offset)
			output_flush(offset, ms->s.reloff - offset);
		    offset = ms->s.reloff +
			     ms->s.nreloc * sizeof(struct relocation_info);
		}
		content = &(ms->next);
	    }
	    p = &(msg->next);
	}
	if(output_dysymtab_info.dysymtab_command.nlocrel != 0){
	    output_flush(offset,
			 output_dysymtab_info.dysymtab_command.locreloff -
			 offset);
	    offset = output_dysymtab_info.dysymtab_command.locreloff +
		     output_dysymtab_info.dysymtab_command.nlocrel * 
		     sizeof(struct relocation_info);
	}
	if(output_for_dyld){
	    if(strip_level != STRIP_ALL){
		/* the offset to the symbol table */
		if(output_symtab_info.symtab_command.symoff != offset)
		    output_flush(offset,
			output_symtab_info.symtab_command.symoff - offset);
		offset = output_symtab_info.symtab_command.symoff +
			 output_symtab_info.symtab_command.nsyms *
							sizeof(struct nlist);
	    }
	}
	if(output_for_dyld && twolevel_namespace == TRUE &&
	   twolevel_namespace_hints == TRUE){
	    output_flush(offset,
			 output_hints_info.twolevel_hints_command.offset -
			 offset);
	    offset = output_hints_info.twolevel_hints_command.offset +
		     output_hints_info.twolevel_hints_command.nhints *
		     sizeof(struct twolevel_hint);
	}
	if(output_dysymtab_info.dysymtab_command.nextrel != 0){
	    output_flush(offset,
			 output_dysymtab_info.dysymtab_command.extreloff -
			 offset);
	    offset = output_dysymtab_info.dysymtab_command.extreloff +
		     output_dysymtab_info.dysymtab_command.nextrel *
		     sizeof(struct relocation_info);
	}
	/* the offset to the indirect symbol table */
	if(output_dysymtab_info.dysymtab_command.nindirectsyms != 0){
	    if(output_dysymtab_info.dysymtab_command.indirectsymoff != offset)
		output_flush(offset, output_dysymtab_info.
			     dysymtab_command.indirectsymoff - offset);
	    offset = output_dysymtab_info.dysymtab_command.indirectsymoff +
		     output_dysymtab_info.dysymtab_command.nindirectsyms *
							sizeof(unsigned long);
	}
#ifndef RLD
	/* the offset to the dylib table of contents */
	if(output_dysymtab_info.dysymtab_command.ntoc != 0){
	    if(output_dysymtab_info.dysymtab_command.tocoff != offset)
		output_flush(offset, output_dysymtab_info.
			     dysymtab_command.tocoff - offset);
	    offset = output_dysymtab_info.dysymtab_command.tocoff +
		     output_dysymtab_info.dysymtab_command.ntoc *
					sizeof(struct dylib_table_of_contents);
	}

	/* the offset to the dylib module table */
	if(output_dysymtab_info.dysymtab_command.nmodtab != 0){
	    if(output_dysymtab_info.dysymtab_command.modtaboff != offset)
		output_flush(offset, output_dysymtab_info.
			     dysymtab_command.modtaboff - offset);
	    offset = output_dysymtab_info.dysymtab_command.modtaboff +
		     output_dysymtab_info.dysymtab_command.nmodtab *
					sizeof(struct dylib_module);
	}

	/* the offset to the dylib reference table */
	if(output_dysymtab_info.dysymtab_command.nextrefsyms != 0){
	    if(output_dysymtab_info.dysymtab_command.extrefsymoff != offset)
		output_flush(offset, output_dysymtab_info.
			     dysymtab_command.extrefsymoff - offset);
	    offset = output_dysymtab_info.dysymtab_command.extrefsymoff +
		     output_dysymtab_info.dysymtab_command.nextrefsyms *
					sizeof(struct dylib_reference);
	}
#endif /* !defined(RLD) */

	if(output_for_dyld == FALSE){
	    if(strip_level != STRIP_ALL){
		/* the offset to the symbol table */
		if(output_symtab_info.symtab_command.symoff != offset)
		    output_flush(offset,
			output_symtab_info.symtab_command.symoff - offset);
		offset = output_symtab_info.symtab_command.symoff +
			 output_symtab_info.symtab_command.nsyms *
							sizeof(struct nlist);
	    }
	}

	if(strip_level != STRIP_ALL){
	    /* the offset to the string table */
	    /*
	     * This is flushed to output_symtab_info.symtab_command.stroff plus
	     * output_symtab_info.output_merged_strsize and not just to
	     * output_symtab_info.symtab_command.stroff because the first byte
	     * can't be used to store a string because a symbol with a string
	     * offset of zero (nlist.n_un.n_strx == 0) is defined to be a symbol
	     * with a null name "".  So this byte(s) have to be flushed.
	     */
	    if(output_symtab_info.symtab_command.stroff +
	       output_symtab_info.output_merged_strsize != offset)
		output_flush(offset, output_symtab_info.symtab_command.stroff +
			     output_symtab_info.output_merged_strsize - offset);
	    /* flush the string table pad if any */
	    if(output_symtab_info.output_strpad != 0){
		output_flush(output_symtab_info.symtab_command.stroff +
			     output_symtab_info.symtab_command.strsize -
			     output_symtab_info.output_strpad,
			     output_symtab_info.output_strpad);
	    }
	    offset = output_symtab_info.symtab_command.stroff +
		     output_symtab_info.symtab_command.strsize;
	}

	/* the offset to the end of the file */
	if(offset != output_size)
	    output_flush(offset, output_size - offset);
}
Пример #9
0
/*
 * output_headers() copys the headers of the object file into the buffer for
 * the output file.
 */
static
void
output_headers(void)
{
    unsigned long header_offset;
    struct merged_segment **p, *msg;
    struct merged_section **content, **zerofill, *ms;
#ifndef RLD
    unsigned long i;
    struct merged_fvmlib **q, *mfl;
    struct dylinker_command *dyld;
    struct merged_dylib *mdl;
    struct dylib_command *dl;
    struct dynamic_library *dp;
    enum bool some_symbols_referenced, some_non_weak_refs;
#endif /* !defined(RLD) */
    struct mach_header *mh;
    struct load_command *lc;

	header_offset = 0;

	/* first the mach header */
	mh = (struct mach_header *)output_addr;
	memcpy(mh, &output_mach_header, sizeof(struct mach_header));
	header_offset += sizeof(struct mach_header);
	lc = (struct load_command *)(output_addr + header_offset);

	/* next the segment load commands (and section structures) */
	p = &merged_segments;
	while(*p){
	    msg = *p;
	    memcpy(output_addr + header_offset, &(msg->sg),
		   sizeof(struct segment_command));
	    header_offset += sizeof(struct segment_command);
	    content = &(msg->content_sections);
	    while(*content){
		ms = *content;
		memcpy(output_addr + header_offset, &(ms->s),
		       sizeof(struct section));
		header_offset += sizeof(struct section);
		content = &(ms->next);
	    }
	    zerofill = &(msg->zerofill_sections);
	    while(*zerofill){
		ms = *zerofill;
		memcpy(output_addr + header_offset, &(ms->s),
		       sizeof(struct section));
		header_offset += sizeof(struct section);
		zerofill = &(ms->next);
	    }
	    p = &(msg->next);
	}

#ifndef RLD
	/* next the fixed VM shared library load commands */
	q = &merged_fvmlibs;
	while(*q){
	    mfl = *q;
	    memcpy(output_addr + header_offset, mfl->fl, mfl->fl->cmdsize);
	    header_offset += mfl->fl->cmdsize;
	    q = &(mfl->next);
	}

	/* next the dynamic linker load command */
	if(merged_dylinker != NULL){
	    memcpy(output_addr + header_offset, merged_dylinker->dyld,
		   merged_dylinker->dyld->cmdsize);
	    if(filetype != MH_DYLINKER){
		dyld = (struct dylinker_command *)(output_addr + header_offset);
		dyld->cmd = LC_LOAD_DYLINKER;
	    }
	    header_offset += merged_dylinker->dyld->cmdsize;
	}

	/* next the dynamicly linked shared library load commands */
	mdl = merged_dylibs;
	while(mdl != NULL){
	    memcpy(output_addr + header_offset, mdl->dl, mdl->dl->cmdsize);
	    if(mdl->output_id == FALSE){
		dl = (struct dylib_command *)(output_addr + header_offset);
		/*
		 * Propagate the some_non_weak_refs and some_non_weak_refs 
		 * booleans up through the sub images for this dylib.
		 */
		some_symbols_referenced =
		    mdl->dynamic_library->some_symbols_referenced;
		some_non_weak_refs = 
		    mdl->dynamic_library->some_non_weak_refs;
		for(i = 0; i < mdl->dynamic_library->nsub_images; i++){
		    if(mdl->dynamic_library->sub_images[i]->
		       some_symbols_referenced == TRUE){
			some_symbols_referenced = TRUE;
			if(mdl->dynamic_library->sub_images[i]->
			   some_non_weak_refs == TRUE)
			    some_non_weak_refs = TRUE;
		    }
		}
		if((some_symbols_referenced == TRUE &&
		    some_non_weak_refs == FALSE) ||
		    mdl->dynamic_library->force_weak_dylib == TRUE){
		    if(macosx_deployment_target.major >= 2){
			dl->cmd = LC_LOAD_WEAK_DYLIB;
		    }
		    else{
			warning("dynamic shared library: %s not made a weak "
				"library in output with "
				"MACOSX_DEPLOYMENT_TARGET environment variable "
				"set to: %s", mdl->definition_object->file_name,
				macosx_deployment_target.name);
			dl->cmd = LC_LOAD_DYLIB;
		    }
		}
		else
		    dl->cmd = LC_LOAD_DYLIB;
	    }
	    header_offset += mdl->dl->cmdsize;
	    mdl = mdl->next;
	}

	/* next the sub framework load command */
	if(merged_sub_framework != NULL){
	    memcpy(output_addr + header_offset, merged_sub_framework->sub,
		   merged_sub_framework->sub->cmdsize);
	    header_offset += merged_sub_framework->sub->cmdsize;
	}

	/* next the sub umbrella load commands */
	for(i = 0; i < nsub_umbrellas ; i++){
	    memcpy(output_addr + header_offset, merged_sub_umbrellas[i].sub,
		   merged_sub_umbrellas[i].sub->cmdsize);
	    header_offset += merged_sub_umbrellas[i].sub->cmdsize;
	}

	/* next the sub library load commands */
	for(i = 0; i < nsub_librarys ; i++){
	    memcpy(output_addr + header_offset, merged_sub_librarys[i].sub,
		   merged_sub_librarys[i].sub->cmdsize);
	    header_offset += merged_sub_librarys[i].sub->cmdsize;
	}

	/* next the sub client load commands */
	for(i = 0; i < nallowable_clients ; i++){
	    memcpy(output_addr + header_offset, merged_sub_clients[i].sub,
		   merged_sub_clients[i].sub->cmdsize);
	    header_offset += merged_sub_clients[i].sub->cmdsize;
	}

	/* next the prebound dynamic libraries load commands */
	if(filetype == MH_EXECUTE){
	    for(dp = dynamic_libs; dp != NULL; dp = dp->next){
		if(dp->type == DYLIB){
		    if(dp->pbdylib != NULL){
			memcpy(output_addr + header_offset, dp->pbdylib,
			       dp->pbdylib->cmdsize);
			header_offset += dp->pbdylib->cmdsize;
		    }
		}
	    }
	}
#endif /* !defined(RLD) */

	/* next the symbol table load command */
	memcpy(output_addr + header_offset,
	       &(output_symtab_info.symtab_command),
	       output_symtab_info.symtab_command.cmdsize);
	header_offset += output_symtab_info.symtab_command.cmdsize;

	/* next the dysymbol table load command */
	if(nindirectsyms != 0 || output_for_dyld){
	    memcpy(output_addr + header_offset,
		   &(output_dysymtab_info.dysymtab_command),
		   output_dysymtab_info.dysymtab_command.cmdsize);
	    header_offset += output_dysymtab_info.dysymtab_command.cmdsize;
	}

	/* next the two-level namespace hints load command */
	if(output_for_dyld && twolevel_namespace == TRUE &&
	   twolevel_namespace_hints == TRUE){
	    memcpy(output_addr + header_offset,
	    	   &(output_hints_info.twolevel_hints_command),
		   output_hints_info.twolevel_hints_command.cmdsize);
	    header_offset += output_hints_info.twolevel_hints_command.cmdsize;
	}

	/* next the prebind cksum load command */
	if(output_cksum_info.prebind_cksum_command.cmdsize != 0){
	    memcpy(output_addr + header_offset,
	    	   &(output_cksum_info.prebind_cksum_command),
		   output_cksum_info.prebind_cksum_command.cmdsize);
	    header_offset += output_cksum_info.prebind_cksum_command.cmdsize;
	}

	/* next the uuid load command */
	if(output_uuid_info.uuid_command.cmdsize != 0){
	    memcpy(output_addr + header_offset,
	    	   &(output_uuid_info.uuid_command),
		   output_uuid_info.uuid_command.cmdsize);
	    header_offset += output_uuid_info.uuid_command.cmdsize;
	}

	/* next the thread command if the output file has one */
	if(output_thread_info.thread_in_output == TRUE){
	    /* the thread command itself */
	    memcpy(output_addr + header_offset,
		   &(output_thread_info.thread_command),
		   sizeof(struct thread_command));
	    header_offset += sizeof(struct thread_command);
	    /* the flavor of the thread state */
	    memcpy(output_addr + header_offset, &(output_thread_info.flavor),
		   sizeof(long));
	    header_offset += sizeof(long);
	    /* the count of longs of the thread state */
	    memcpy(output_addr + header_offset, &(output_thread_info.count),
		   sizeof(long));
	    header_offset += sizeof(long);
	    /* the thread state */
	    memcpy(output_addr + header_offset, output_thread_info.state,
		   output_thread_info.count * sizeof(long));
	    header_offset += output_thread_info.count * sizeof(long);
	    /* the second thread state if any */
	    if(output_thread_info.second_count != 0){
		/* the flavor of the second thread state */
		memcpy(output_addr + header_offset,
		       &(output_thread_info.second_flavor),
		       sizeof(long));
		header_offset += sizeof(long);
		/* the count of longs of the second thread state */
		memcpy(output_addr + header_offset,
		       &(output_thread_info.second_count),
		       sizeof(long));
		header_offset += sizeof(long);
		/* the second thread state */
		memcpy(output_addr + header_offset,
		       output_thread_info.second_state,
		       output_thread_info.second_count * sizeof(long));
		header_offset += output_thread_info.second_count * sizeof(long);
	    }
	}
	/* next the routines command if the output file has one */
	if(output_routines_info.routines_in_output == TRUE){
	    memcpy(output_addr + header_offset,
		   &(output_routines_info.routines_command),
		   sizeof(struct routines_command));
	    header_offset += sizeof(struct routines_command);
	}
	if(host_byte_sex != target_byte_sex)
	    if(swap_object_headers(mh, lc) == FALSE)
		fatal("internal error: swap_object_headers() failed in "
		      "output_headers()");
#ifndef RLD
	output_flush(0, sizeof(struct mach_header) +
			output_mach_header.sizeofcmds);
#endif /* !defined(RLD) */
}
Пример #10
0
static void process_strm(u8_t *pkt, int len) {
	struct strm_packet *strm = (struct strm_packet *)pkt;

	LOG_INFO("strm command %c", strm->command);

	switch(strm->command) {
	case 't':
		sendSTAT("STMt", strm->replay_gain); // STMt replay_gain is no longer used to track latency, but support it
		break;
	case 'q':
		output_flush();
		status.frames_played = 0;
		stream_disconnect();
		sendSTAT("STMf", 0);
		buf_flush(streambuf);
		break;
	case 'f':
		output_flush();
		status.frames_played = 0;
		if (stream_disconnect()) {
			sendSTAT("STMf", 0);
		}
		buf_flush(streambuf);
		break;
	case 'p':
		{
			unsigned interval = unpackN(&strm->replay_gain);
			LOCK_O;
			output.pause_frames = interval * status.current_sample_rate / 1000;
			output.state = interval ? OUTPUT_PAUSE_FRAMES : OUTPUT_STOPPED;				
			UNLOCK_O;
			if (!interval) sendSTAT("STMp", 0);
			LOG_INFO("pause interval: %u", interval);
		}
		break;
	case 'a':
		{
			unsigned interval = unpackN(&strm->replay_gain);
			LOCK_O;
			output.skip_frames = interval * status.current_sample_rate / 1000;
			output.state = OUTPUT_SKIP_FRAMES;				
			UNLOCK_O;
			LOG_INFO("skip ahead interval: %u", interval);
		}
		break;
	case 'u':
		{
			unsigned jiffies = unpackN(&strm->replay_gain);
			LOCK_O;
			output.state = jiffies ? OUTPUT_START_AT : OUTPUT_RUNNING;
			output.start_at = jiffies;
			UNLOCK_O;
			LOCK_D;
			decode.state = DECODE_RUNNING;
			UNLOCK_D;
			LOG_INFO("unpause at: %u now: %u", jiffies, gettime_ms());
			sendSTAT("STMr", 0);
		}
		break;
	case 's':
		{
			unsigned header_len = len - sizeof(struct strm_packet);
			char *header = (char *)(pkt + sizeof(struct strm_packet));
			in_addr_t ip = (in_addr_t)strm->server_ip; // keep in network byte order
			u16_t port = strm->server_port; // keep in network byte order
			if (ip == 0) ip = slimproto_ip; 

			LOG_INFO("strm s autostart: %c transition period: %u transition type: %u", 
					 strm->autostart, strm->transition_period, strm->transition_type - '0');

			autostart = strm->autostart - '0';
			sendSTAT("STMf", 0);
			if (header_len > MAX_HEADER -1) {
				LOG_WARN("header too long: %u", header_len);
				break;
			}
			codec_open(strm->format, strm->pcm_sample_size, strm->pcm_sample_rate, strm->pcm_channels, strm->pcm_endianness);
			if (ip == LOCAL_PLAYER_IP && port == LOCAL_PLAYER_PORT) {
				// extension to slimproto for LocalPlayer - header is filename not http header, don't expect cont
				stream_file(header, header_len, strm->threshold * 1024);
				autostart -= 2;
			} else {
				stream_sock(ip, port, header, header_len, strm->threshold * 1024, autostart >= 2);
			}
			sendSTAT("STMc", 0);
			sentSTMu = sentSTMo = sentSTMl = false;
			LOCK_O;
			output.threshold = strm->output_threshold;
			output.next_replay_gain = unpackN(&strm->replay_gain);
			output.fade_mode = strm->transition_type - '0';
			output.fade_secs = strm->transition_period;
			LOG_INFO("set fade mode: %u", output.fade_mode);
			UNLOCK_O;
		}
		break;
	default:
		LOG_INFO("unhandled strm %c", strm->command);
		break;
	}
}
Пример #11
0
static void output_close( void )
{
  output_flush(0);
  free( output_buffer );
}