Esempio n. 1
0
//--------------------------------------------------------------------------------------------
cartman_mpd_t * cartman_mpd_convert(cartman_mpd_t *dst, map_t *src)
{
    if (!src || !dst)
    {
        return nullptr;
    }
    
    map_mem_t *mem_src = &(src->_mem);
    map_info_t *info_src = &(src->_info);

    // Reset the destination mesh.
    if (!dst->reset())
    {
        return nullptr;
    }

    // set up the destination mesh from the source mesh
    cartman_mpd_info_init(&(dst->info), info_src->vertexCount, info_src->tileCountX, info_src->tileCountY);

    // copy all the per-tile info
    for (int itile_src = 0; itile_src < dst->info.tiles_count; itile_src++ )
    {
        const tile_info_t& ptile_src = mem_src->tiles[itile_src];
        cartman_mpd_tile_t *pfan_dst  = &(dst->fan2[itile_src]);

        pfan_dst->type     = ptile_src.type;
        pfan_dst->tx_bits  = ptile_src.img;
        pfan_dst->fx       = ptile_src.fx;
        pfan_dst->twist    = ptile_src.twist;
    }

    // store the vertices in the vertex chain for editing
    for (int ifan_dst = 0, ivrt_src = 0; ifan_dst < dst->info.tiles_count; ifan_dst++)
    {
        int ivrt_dst, cnt;
        int vert_count, allocate_rv;

        
        Cartman::mpd_vertex_t * pvrt_dst = NULL;

        // use the data that was transferred to the destination fan
        cartman_mpd_tile_t& fan_dst = dst->fan2[ifan_dst];

        // check for valid fan type
        tile_definition_t *pdef = TILE_DICT_PTR(tile_dict, fan_dst.type);
        if (!pdef)
        {
            log_warning( "%s - invalid fan type in fan # %d\n", __FUNCTION__, ifan_dst );
            goto cartman_mpd_convert_fail;
        }

        // get an appropriate number of vertices from the tile definition
        if ( 0 == pdef->numvertices )
        {
            log_warning( "%s - undefined fan type %d in fan # %d\n", __FUNCTION__, fan_dst.type, ifan_dst );
            vert_count = 4;
        }
        else
        {
            vert_count = pdef->numvertices;
        }

        // check for valid vertex count
        if ( vert_count > MAP_FAN_VERTICES_MAX )
        {
            log_warning( "%s - too many vertices in fan type %d in fan # %d\n", __FUNCTION__, fan_dst.type, ifan_dst );
            goto cartman_mpd_convert_fail;
        }

        // allocate the vertices
        allocate_rv = cartman_mpd_allocate_verts(dst, vert_count);
        if ( -1 == allocate_rv )
        {
            log_warning( "%s - could not allocate enough vertices for the mesh at fan # %d\n", __FUNCTION__, ifan_dst );
            goto cartman_mpd_convert_fail;
        }

        // set the fan's vertex start position
        fan_dst.vrtstart = allocate_rv;

        // fill in the vertex values
        for ( cnt = 0, ivrt_dst = fan_dst.vrtstart, pvrt_dst = NULL;
              cnt < vert_count;
              cnt++, ivrt_dst = pvrt_dst->next, ivrt_src++ )
        {
            if ( CHAINEND == ivrt_dst )
            {
                log_warning( "%s - unexpected CHAINEND in tile %d vertex %d\n.", __FUNCTION__, ifan_dst, ivrt_dst );
                goto cartman_mpd_convert_fail;
            }

            const map_vertex_t& pvrt_src = mem_src->vertices[ivrt_src];
            pvrt_dst = &(dst->vrt2[ivrt_dst]);

            pvrt_dst->x = pvrt_src.pos[kX];
            pvrt_dst->y = pvrt_src.pos[kY];
            pvrt_dst->z = pvrt_src.pos[kZ];
            pvrt_dst->a = std::max(pvrt_src.a, (Uint8)(VERTEXUNUSED+1));  // force a != VERTEXUNUSED
        };
    }

    return dst;

cartman_mpd_convert_fail:

    dst->reset();

    return nullptr;
}
Esempio n. 2
0
static void LIBUSB_CALL lusb_stream_cb(struct libusb_transfer *transfer)
{
    struct bladerf_stream *stream = transfer->user_data;
    void *next_buffer = NULL;
    struct bladerf_metadata metadata;
    struct lusb_stream_data *stream_data = stream->backend_data;
    size_t transfer_i;

    /* Currently unused - zero out for out own debugging sanity... */
    memset(&metadata, 0, sizeof(metadata));

    MUTEX_LOCK(&stream->lock);

    transfer_i = transfer_idx(stream_data, transfer);
    assert(stream_data->transfer_status[transfer_i] == TRANSFER_IN_FLIGHT ||
           stream_data->transfer_status[transfer_i] == TRANSFER_CANCEL_PENDING);

    if (transfer_i >= stream_data->num_transfers) {
        log_error("Unable to find transfer");
        stream->state = STREAM_SHUTTING_DOWN;
    } else {
        stream_data->transfer_status[transfer_i] = TRANSFER_AVAIL;
        stream_data->num_avail++;
        pthread_cond_signal(&stream->can_submit_buffer);
    }

    /* Check to see if the transfer has been cancelled or errored */
    if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {

        /* Errored out for some reason .. */
        stream->state = STREAM_SHUTTING_DOWN;

        switch(transfer->status) {
            case LIBUSB_TRANSFER_CANCELLED:
                /* We expect this case when we begin tearing down the stream */
                break;

            case LIBUSB_TRANSFER_STALL:
                log_error("Hit stall for buffer %p\n", transfer->buffer);
                stream->error_code = BLADERF_ERR_IO;
                break;

            case LIBUSB_TRANSFER_ERROR:
                log_error("Got transfer error for buffer %p\n",
                          transfer->buffer);
                stream->error_code = BLADERF_ERR_IO;
                break;

            case LIBUSB_TRANSFER_OVERFLOW :
                log_error("Got transfer over for buffer %p, "
                            "transfer \"actual_length\" = %d\n",
                            transfer->buffer, transfer->actual_length);
                stream->error_code = BLADERF_ERR_IO;
                break;

            case LIBUSB_TRANSFER_TIMED_OUT:
                stream->error_code = BLADERF_ERR_TIMEOUT;
                break;

            case LIBUSB_TRANSFER_NO_DEVICE:
                stream->error_code = BLADERF_ERR_NODEV;
                break;

            default:
                log_error( "Unexpected transfer status: %d\n", transfer->status );
                break;
        }

    }

    if (stream->state == STREAM_RUNNING) {

        /* Sanity check for debugging purposes */
        if (transfer->length != transfer->actual_length) {
            log_warning( "Received short transfer\n" );
        }

       /* Call user callback requesting more data to transmit */
        next_buffer = stream->cb(
                        stream->dev,
                        stream,
                        &metadata,
                        transfer->buffer,
                        bytes_to_sc16q11(transfer->actual_length),
                        stream->user_data);

        if (next_buffer == BLADERF_STREAM_SHUTDOWN) {
            stream->state = STREAM_SHUTTING_DOWN;
        } else if (next_buffer != BLADERF_STREAM_NO_DATA) {
            int status = submit_transfer(stream, next_buffer);
            if (status != 0) {
                /* If this fails, we probably have a serious problem...so just
                 * shut it down. */
                stream->state = STREAM_SHUTTING_DOWN;
            }
        }
    }


    /* Check to see if all the transfers have been cancelled,
     * and if so, clean up the stream */
    if (stream->state == STREAM_SHUTTING_DOWN) {

        /* We know we're done when all of our transfers have returned to their
         * "available" states */
        if (stream_data->num_avail == stream_data->num_transfers) {
            stream->state = STREAM_DONE;
        } else {
            cancel_all_transfers(stream);
        }
    }

    MUTEX_UNLOCK(&stream->lock);
}
Esempio n. 3
0
static int
_conference_message_handler(xmpp_conn_t * const conn,
    xmpp_stanza_t * const stanza, void * const userdata)
{
    xmpp_ctx_t *ctx = connection_get_ctx();
    xmpp_stanza_t *x_muc = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_MUC_USER);
    xmpp_stanza_t *x_groupchat = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_CONFERENCE);
    xmpp_stanza_t *captcha = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_CAPTCHA);
    char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
    char *room = NULL;
    char *invitor = NULL;
    char *reason = NULL;

    if (from == NULL) {
        log_warning("Message received with no from attribute, ignoring");
        return 1;
    }

    // XEP-0045
    if (x_muc != NULL) {
        room = from;

        xmpp_stanza_t *invite = xmpp_stanza_get_child_by_name(x_muc, STANZA_NAME_INVITE);
        if (invite == NULL) {
            return 1;
        }

        char *invitor_jid = xmpp_stanza_get_attribute(invite, STANZA_ATTR_FROM);
        if (invitor_jid == NULL) {
            log_warning("Chat room invite received with no from attribute");
            return 1;
        }

        Jid *jidp = jid_create(invitor_jid);
        if (jidp == NULL) {
            return 1;
        }
        invitor = jidp->barejid;

        xmpp_stanza_t *reason_st = xmpp_stanza_get_child_by_name(invite, STANZA_NAME_REASON);
        if (reason_st != NULL) {
            reason = xmpp_stanza_get_text(reason_st);
        }

        prof_handle_room_invite(INVITE_MEDIATED, invitor, room, reason);
        jid_destroy(jidp);
        if (reason != NULL) {
            xmpp_free(ctx, reason);
        }

    // XEP-0429
    } else if (x_groupchat != NULL) {
        room = xmpp_stanza_get_attribute(x_groupchat, STANZA_ATTR_JID);
        if (room == NULL) {
            return 1;
        }

        Jid *jidp = jid_create(from);
        if (jidp == NULL) {
            return 1;
        }
        invitor = jidp->barejid;

        reason = xmpp_stanza_get_attribute(x_groupchat, STANZA_ATTR_REASON);

        prof_handle_room_invite(INVITE_DIRECT, invitor, room, reason);

        jid_destroy(jidp);

    // XEP-0158
    } else if (captcha != NULL) {
        xmpp_stanza_t *body = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_BODY);
        if (body != NULL) {
            char *message = xmpp_stanza_get_text(body);
            if (message != NULL) {
                prof_handle_room_broadcast(from, message);
                xmpp_free(ctx, message);
            }
        }
    }

    return 1;
}
Esempio n. 4
0
File: pop.c Progetto: ctubio/claws
static gint pop3_getrange_uidl_recv(Pop3Session *session, const gchar *data,
				    guint len)
{
	gchar id[IDLEN + 1];
	gchar buf[POPBUFSIZE];
	gint buf_len;
	guint32 num;
	time_t recv_time;
	gint partial_recv;
	const gchar *p = data;
	const gchar *lastp = data + len;
	const gchar *newline;

	while (p < lastp) {
		if ((newline = memchr(p, '\r', lastp - p)) == NULL)
			return -1;
		buf_len = MIN(newline - p, sizeof(buf) - 1);
		memcpy(buf, p, buf_len);
		buf[buf_len] = '\0';

		p = newline + 1;
		if (p < lastp && *p == '\n') p++;

		if (sscanf(buf, "%d %" Xstr(IDLEN) "s", &num, id) != 2 ||
		    num <= 0 || num > session->count) {
			log_warning(LOG_PROTOCOL, _("invalid UIDL response: %s\n"), buf);
			continue;
		}

		session->msg[num].uidl = g_strdup(id);

		recv_time = (time_t)(GPOINTER_TO_INT(g_hash_table_lookup(
			   		session->uidl_table, id)));
		session->msg[num].recv_time = recv_time;

		if (recv_time != RECV_TIME_NONE) {
			debug_print("num %d uidl %s: already got it\n", num, id);		
		} else {
			debug_print("num %d uidl %s: unknown\n", num, id);
		}

		partial_recv = (gint)(GPOINTER_TO_INT(g_hash_table_lookup(
					session->partial_recv_table, id)));

		if (recv_time != RECV_TIME_NONE
		|| partial_recv != POP3_TOTALLY_RECEIVED) {
			session->msg[num].received = 
				(partial_recv != POP3_MUST_COMPLETE_RECV);
			session->msg[num].partial_recv = partial_recv;
			if (partial_recv == POP3_MUST_COMPLETE_RECV)
				session->new_msg_exist = TRUE;
		}
		if (!session->new_msg_exist &&
		    (recv_time == RECV_TIME_NONE ||
		     session->ac_prefs->rmmail)) {
			session->cur_msg = num;
			session->new_msg_exist = TRUE;
		}
	}

	session->uidl_is_valid = TRUE;
	return PS_SUCCESS;
}
Esempio n. 5
0
/*
Primary superblock is at 1024 (SUPERBLOCK_OFFSET)
Group 0 begin at s_first_data_block
*/
int recover_EXT2(disk_t *disk, const struct ext2_super_block *sb,partition_t *partition,const int verbose, const int dump_ind)
{
  if(test_EXT2(sb, partition)!=0)
    return 1;
  if(dump_ind!=0)
  {
    if(partition!=NULL && disk!=NULL)
      log_info("\nEXT2/EXT3 magic value at %u/%u/%u\n",
	  offset2cylinder(disk,partition->part_offset),
	  offset2head(disk,partition->part_offset),
	  offset2sector(disk,partition->part_offset));
    /* There is a little offset ... */
    dump_log(sb,DEFAULT_SECTOR_SIZE);
  }
  if(partition==NULL)
    return 0;
  set_EXT2_info(sb, partition, verbose);
  partition->part_type_i386=P_LINUX;
  partition->part_type_mac=PMAC_LINUX;
  partition->part_type_sun=PSUN_LINUX;
  partition->part_type_gpt=GPT_ENT_TYPE_LINUX_DATA;
  partition->part_size=td_ext2fs_blocks_count(sb) * EXT2_MIN_BLOCK_SIZE<<le32(sb->s_log_block_size);
  guid_cpy(&partition->part_uuid, (const efi_guid_t *)&sb->s_uuid);
  if(verbose>0)
  {
    log_info("\n");
  }
  partition->sborg_offset=0x400;
  partition->sb_size=EXT2_SUPERBLOCK_SIZE;
  if(le16(sb->s_block_group_nr)>0)
  {
    const unsigned long int block_nr=(le32(sb->s_first_data_block)+le16(sb->s_block_group_nr)*le32(sb->s_blocks_per_group));
    if(partition->part_offset< (uint64_t)block_nr * (EXT2_MIN_BLOCK_SIZE<<le32(sb->s_log_block_size)))
    {
      log_error("recover_EXT2: part_offset problem\n");
      return 1;
    }
    partition->sb_offset=(uint64_t)block_nr * (EXT2_MIN_BLOCK_SIZE<<le32(sb->s_log_block_size));
    partition->part_offset-=partition->sb_offset;
    log_warning("recover_EXT2: \"e2fsck -b %lu -B %u device\" may be needed\n",
        block_nr, partition->blocksize);
  }
  else
  {
    partition->sb_offset=0;
  }
  if(verbose>0)
  {
    log_info("recover_EXT2: s_block_group_nr=%u/%u, s_mnt_count=%u/%u, s_blocks_per_group=%u, s_inodes_per_group=%u\n",
        le16(sb->s_block_group_nr),
        (unsigned int)(td_ext2fs_blocks_count(sb) /le32(sb->s_blocks_per_group)),
        le16(sb->s_mnt_count), le16(sb->s_max_mnt_count),
        (unsigned int)le32(sb->s_blocks_per_group),
        (unsigned int)le32(sb->s_inodes_per_group));
    log_info("recover_EXT2: s_blocksize=%u\n", partition->blocksize);
    log_info("recover_EXT2: s_blocks_count %lu\n", (long unsigned int)td_ext2fs_blocks_count(sb));
    if(disk==NULL)
      log_info("recover_EXT2: part_size %lu\n", (long unsigned)(partition->part_size / DEFAULT_SECTOR_SIZE));
    else
      log_info("recover_EXT2: part_size %lu\n", (long unsigned)(partition->part_size / disk->sector_size));
  }
  return 0;
}
Esempio n. 6
0
int main(int argc, char *argv[]) {
        static struct list_sample_data *sampledata;
        _cleanup_closedir_ DIR *proc = NULL;
        _cleanup_free_ char *build = NULL;
        _cleanup_fclose_ FILE *of = NULL;
        _cleanup_close_ int sysfd = -1;
        int schfd;
        struct ps_struct *ps_first;
        double graph_start;
        double log_start;
        double interval;
        char output_file[PATH_MAX];
        char datestr[200];
        int pscount = 0;
        int n_cpus = 0;
        int overrun = 0;
        time_t t = 0;
        int r, samples;
        struct ps_struct *ps;
        struct rlimit rlim;
        struct list_sample_data *head;
        struct sigaction sig = {
                .sa_handler = signal_handler,
        };

        parse_conf();

        r = parse_argv(argc, argv);
        if (r < 0)
                return EXIT_FAILURE;

        if (r == 0)
                return EXIT_SUCCESS;

        /*
         * If the kernel executed us through init=/usr/lib/systemd/systemd-bootchart, then
         * fork:
         * - parent execs executable specified via init_path[] (/usr/lib/systemd/systemd by default) as pid=1
         * - child logs data
         */
        if (getpid() == 1) {
                if (fork())
                        /* parent */
                        execl(arg_init_path, arg_init_path, NULL);
        }
        argv[0][0] = '@';

        rlim.rlim_cur = 4096;
        rlim.rlim_max = 4096;
        (void) setrlimit(RLIMIT_NOFILE, &rlim);

        schfd = open("/proc/sys/kernel/sched_schedstats", O_WRONLY);
        if (schfd >= 0) {
                write(schfd, "1\n", 2);
                close(schfd);
        }

        /* start with empty ps LL */
        ps_first = new0(struct ps_struct, 1);
        if (!ps_first) {
                log_oom();
                return EXIT_FAILURE;
        }

        /* handle TERM/INT nicely */
        sigaction(SIGHUP, &sig, NULL);

        interval = (1.0 / arg_hz) * 1000000000.0;

        if (arg_relative)
                graph_start = log_start = gettime_ns();
        else {
                struct timespec n;
                double uptime;

                clock_gettime(clock_boottime_or_monotonic(), &n);
                uptime = (n.tv_sec + (n.tv_nsec / (double) NSEC_PER_SEC));

                log_start = gettime_ns();
                graph_start = log_start - uptime;
        }

        if (graph_start < 0.0) {
                log_error("Failed to setup graph start time.\n\n"
                          "The system uptime probably includes time that the system was suspended. "
                          "Use --rel to bypass this issue.");
                return EXIT_FAILURE;
        }

        LIST_HEAD_INIT(head);

        /* main program loop */
        for (samples = 0; !exiting && samples < arg_samples_len; samples++) {
                int res;
                double sample_stop;
                double elapsed;
                double timeleft;

                sampledata = new0(struct list_sample_data, 1);
                if (sampledata == NULL) {
                        log_oom();
                        return EXIT_FAILURE;
                }

                sampledata->sampletime = gettime_ns();
                sampledata->counter = samples;

                if (sysfd < 0)
                        sysfd = open("/sys", O_RDONLY|O_CLOEXEC);

                if (!build) {
                        if (parse_env_file("/etc/os-release", NEWLINE, "PRETTY_NAME", &build, NULL) == -ENOENT)
                                parse_env_file("/usr/lib/os-release", NEWLINE, "PRETTY_NAME", &build, NULL);
                }

                if (proc)
                        rewinddir(proc);
                else
                        proc = opendir("/proc");

                /* wait for /proc to become available, discarding samples */
                if (proc) {
                        r = log_sample(proc, samples, ps_first, &sampledata, &pscount, &n_cpus);
                        if (r < 0)
                                return EXIT_FAILURE;
                }

                sample_stop = gettime_ns();

                elapsed = (sample_stop - sampledata->sampletime) * 1000000000.0;
                timeleft = interval - elapsed;

                /*
                 * check if we have not consumed our entire timeslice. If we
                 * do, don't sleep and take a new sample right away.
                 * we'll lose all the missed samples and overrun our total
                 * time
                 */
                if (timeleft > 0) {
                        struct timespec req;

                        req.tv_sec = (time_t)(timeleft / 1000000000.0);
                        req.tv_nsec = (long)(timeleft - (req.tv_sec * 1000000000.0));

                        res = nanosleep(&req, NULL);
                        if (res) {
                                if (errno == EINTR)
                                        /* caught signal, probably HUP! */
                                        break;
                                log_error_errno(errno, "nanosleep() failed: %m");
                                return EXIT_FAILURE;
                        }
                } else {
                        overrun++;
                        /* calculate how many samples we lost and scrap them */
                        arg_samples_len -= (int)(-timeleft / interval);
                }
                LIST_PREPEND(link, head, sampledata);
        }

        /* do some cleanup, close fd's */
        ps = ps_first;
        while (ps->next_ps) {
                ps = ps->next_ps;
                ps->schedstat = safe_close(ps->schedstat);
                ps->sched = safe_close(ps->sched);
                ps->smaps = safe_fclose(ps->smaps);
        }

        if (!of) {
                t = time(NULL);
                r = strftime(datestr, sizeof(datestr), "%Y%m%d-%H%M", localtime(&t));
                assert_se(r > 0);

                snprintf(output_file, PATH_MAX, "%s/bootchart-%s.svg", arg_output_path, datestr);
                of = fopen(output_file, "we");
        }

        if (!of) {
                log_error("Error opening output file '%s': %m\n", output_file);
                return EXIT_FAILURE;
        }

        r = svg_do(of, strna(build), head, ps_first,
                   samples, pscount, n_cpus, graph_start,
                   log_start, interval, overrun);

        if (r < 0) {
                log_error_errno(r, "Error generating svg file: %m");
                return EXIT_FAILURE;
        }

        log_info("systemd-bootchart wrote %s\n", output_file);

        r = do_journal_append(output_file);
        if (r < 0)
                return EXIT_FAILURE;

        /* nitpic cleanups */
        ps = ps_first->next_ps;
        while (ps->next_ps) {
                struct ps_struct *old;

                old = ps;
                old->sample = ps->first;
                ps = ps->next_ps;
                while (old->sample->next) {
                        struct ps_sched_struct *oldsample = old->sample;

                        old->sample = old->sample->next;
                        free(oldsample);
                }
                free(old->cgroup);
                free(old->sample);
                free(old);
        }

        free(ps->cgroup);
        free(ps->sample);
        free(ps);

        sampledata = head;
        while (sampledata->link_prev) {
                struct list_sample_data *old_sampledata = sampledata;
                sampledata = sampledata->link_prev;
                free(old_sampledata);
        }
        free(sampledata);

        /* don't complain when overrun once, happens most commonly on 1st sample */
        if (overrun > 1)
                log_warning("systemd-bootchart: sample time overrun %i times\n", overrun);

        return 0;
}
Esempio n. 7
0
/* evaluate the expression, reducing it down to a single constant expression
 * node if possible.
 * If constant_only is true, this routine will return false when it hits
 * the name of a parameter to indicate that the expression is not a constant
 * expression.
 * */
boolean ASTP_evaluate_expr(AST_exp_n_t * exp, boolean constant_only)
{
	boolean result;
	long val, val1, val2;
	AST_exp_n_t * op1=NULL, *op2=NULL, *op3=NULL;

	if (exp == NULL)	{
		log_warning(nidl_yylineno, NIDL_EXP_IS_NULL, NULL);
		return true;
	}
	
	if (exp->exp_type == AST_EXP_CONSTANT)	{
		/* resolve binding for identifiers */
		if (exp->exp.constant.type == AST_nil_const_k &&
				exp->exp.constant.val.other == NULL)	{

			exp->exp.constant.val.other = (AST_constant_n_t*)ASTP_lookup_binding(exp->exp.constant.name,
					fe_constant_n_k, FALSE);
			
			if (exp->exp.constant.val.other == NULL)
				return false;
					
		}
		/* already reduced to the simplest form */
		return true;
	}
	/* time to evaluate some expressions.
	 * First, reduce the operands to their simplest forms too */

	result = ASTP_evaluate_expr(exp->exp.expression.oper1, constant_only);
	if (result == false)
		return false;
	op1 = exp->exp.expression.oper1;

	if ((exp->exp_type & AST_EXP_2_OP_MASK) != 0)	{
		result = ASTP_evaluate_expr(exp->exp.expression.oper2, constant_only);
		if (result == false)
			return false;
		op2 = exp->exp.expression.oper2;
	}
	{
	unsigned long x = AST_EXP_3_OP_MASK_LOWWORD;
	unsigned long et = exp->exp_type >> 32;
	if ((et & x) != 0)	{
		result = ASTP_evaluate_expr(exp->exp.expression.oper3, constant_only);
		if (result == false)
			return false;
		op3 = exp->exp.expression.oper3;
	}
	}
	/* only reached if we are dealing with a constant expression,
	 * and that means that we can play around with the operands */
	switch(exp->exp_type)	{
		case AST_EXP_UNARY_NOT:
			exp->exp.constant.val.integer = !ASTP_expr_integer_value(op1);
			break;
		case AST_EXP_UNARY_TILDE:
			exp->exp.constant.val.integer = ~ASTP_expr_integer_value(op1);
			break;
		case AST_EXP_UNARY_PLUS: /* why this? I can't remember what I was thinking */
			exp->exp.constant.val.integer = +ASTP_expr_integer_value(op1);
			break;
		case AST_EXP_UNARY_MINUS:
			exp->exp.constant.val.integer = -ASTP_expr_integer_value(op1);
			break;
		case AST_EXP_UNARY_STAR:
			return false;
		case AST_EXP_BINARY_PERCENT:
			val = ASTP_expr_integer_value(op2);
			if (val == 0)
				acf_error( NIDL_INTDIVBY0, NULL);
			else
				val = ASTP_expr_integer_value(op1) % val;
			exp->exp.constant.val.integer = val;
			break;
		case AST_EXP_BINARY_SLASH:
			val = ASTP_expr_integer_value(op2);
			if (val == 0)
				acf_error( NIDL_INTDIVBY0, NULL);
			else
				val = ASTP_expr_integer_value(op1) / val;
			exp->exp.constant.val.integer = val;
			break;
		case AST_EXP_BINARY_STAR:
			val1 = ASTP_expr_integer_value(op1);
			val2 = ASTP_expr_integer_value(op2);
			val = val1 * val2;
			if (val < val1 && val > val2)
				acf_error( NIDL_INTOVERFLOW, KEYWORDS_lookup_text(LONG_KW), NULL);
			exp->exp.constant.val.integer = val;
			break;
		case AST_EXP_BINARY_MINUS:
			exp->exp.constant.val.integer = ASTP_expr_integer_value(op1) - ASTP_expr_integer_value(op2);
			break;
		case AST_EXP_BINARY_PLUS:
			exp->exp.constant.val.integer = ASTP_expr_integer_value(op1) + ASTP_expr_integer_value(op2);
			break;
		case AST_EXP_BINARY_RSHIFT:
			exp->exp.constant.val.integer = ASTP_expr_integer_value(op1) >> ASTP_expr_integer_value(op2);
			break;
		case AST_EXP_BINARY_LSHIFT:
			exp->exp.constant.val.integer = ASTP_expr_integer_value(op1) << ASTP_expr_integer_value(op2);
			break;
		case AST_EXP_BINARY_GE:
			exp->exp.constant.val.integer = ASTP_expr_integer_value(op1) >= ASTP_expr_integer_value(op2);
			break;
		case AST_EXP_BINARY_LE:
			exp->exp.constant.val.integer = ASTP_expr_integer_value(op1) <= ASTP_expr_integer_value(op2);
			break;
		case AST_EXP_BINARY_GT:
			exp->exp.constant.val.integer = ASTP_expr_integer_value(op1) > ASTP_expr_integer_value(op2);
			break;
		case AST_EXP_BINARY_LT:
			exp->exp.constant.val.integer = ASTP_expr_integer_value(op1) < ASTP_expr_integer_value(op2);
			break;
		case AST_EXP_BINARY_NE:
			exp->exp.constant.val.integer = ASTP_expr_integer_value(op1) != ASTP_expr_integer_value(op2);
			break;
		case AST_EXP_BINARY_EQUAL:
			exp->exp.constant.val.integer = ASTP_expr_integer_value(op1) == ASTP_expr_integer_value(op2);
			break;
		case AST_EXP_BINARY_AND:
			exp->exp.constant.val.integer = ASTP_expr_integer_value(op1) & ASTP_expr_integer_value(op2);
			break;
		case AST_EXP_BINARY_OR:
			exp->exp.constant.val.integer = ASTP_expr_integer_value(op1) | ASTP_expr_integer_value(op2);
			break;
		case AST_EXP_BINARY_XOR:
			exp->exp.constant.val.integer = ASTP_expr_integer_value(op1) ^ ASTP_expr_integer_value(op2);
			break;
		case AST_EXP_BINARY_LOG_AND:
			exp->exp.constant.val.integer = ASTP_expr_integer_value(op1) && ASTP_expr_integer_value(op2);
			break;
		case AST_EXP_BINARY_LOG_OR:
			exp->exp.constant.val.integer = ASTP_expr_integer_value(op1) || ASTP_expr_integer_value(op2);
			break;
		case AST_EXP_TERNARY_OP:
			/* we want to preserve the type for this, so we short-circuit the return */
			*exp = ASTP_expr_integer_value(op1) ? *op2 : *op3;
			return true;
		default:
			/* NOTREACHED (hopefully!) */
			break;
	}
	ASTP_free_exp(op1);
	ASTP_free_exp(op2);
	ASTP_free_exp(op3);
	exp->exp_type = AST_EXP_CONSTANT;
	exp->exp.constant.type = AST_int_const_k;
	return true;
}
Esempio n. 8
0
static sync_worker_state exec_idle_state(struct bladerf_sync *s)
{
    sync_worker_state next_state = SYNC_WORKER_STATE_IDLE;
    unsigned int requests;
    unsigned int i;

    pthread_mutex_lock(&s->worker->request_lock);

    while (s->worker->requests == 0) {
        log_verbose("%s worker: Waiting for pending requests\n", MODULE_STR(s));

        pthread_cond_wait(&s->worker->requests_pending,
                          &s->worker->request_lock);
    }

    requests = s->worker->requests;
    s->worker->requests = 0;
    pthread_mutex_unlock(&s->worker->request_lock);

    if (requests & SYNC_WORKER_STOP) {
        log_verbose("%s worker: Got request to stop\n",
                module2str(s->stream_config.module));

        next_state = SYNC_WORKER_STATE_SHUTTING_DOWN;

    } else if (requests & SYNC_WORKER_START) {
        log_verbose("%s worker: Got request to start\n",
                module2str(s->stream_config.module));
        pthread_mutex_lock(&s->buf_mgmt.lock);

        if (s->stream_config.module == BLADERF_MODULE_TX) {
            /* If we've previously timed out on a stream, we'll likely have some
            * stale buffers marked "in-flight" that have since been cancelled. */
            for (i = 0; i < s->buf_mgmt.num_buffers; i++) {
                if (s->buf_mgmt.status[i] == SYNC_BUFFER_IN_FLIGHT) {
                    s->buf_mgmt.status[i] = SYNC_BUFFER_EMPTY;
                }
            }

            pthread_cond_signal(&s->buf_mgmt.buf_ready);
        } else {
            assert(s->stream_config.module == BLADERF_MODULE_RX);
            s->buf_mgmt.prod_i = s->stream_config.num_xfers;

            for (i = 0; i < s->buf_mgmt.num_buffers; i++) {
                if (i < s->stream_config.num_xfers) {
                    s->buf_mgmt.status[i] = SYNC_BUFFER_IN_FLIGHT;
                } else if (s->buf_mgmt.status[i] == SYNC_BUFFER_IN_FLIGHT) {
                    s->buf_mgmt.status[i] = SYNC_BUFFER_EMPTY;
                }
            }
        }

        pthread_mutex_unlock(&s->buf_mgmt.lock);

        next_state = SYNC_WORKER_STATE_RUNNING;
    } else {
        log_warning("Invalid request value encountered: 0x%08X\n",
                    s->worker->requests);
    }

    return next_state;
}
Esempio n. 9
0
static char *convert_abs_rel(const char *from, const char *target)
{
        /* we use the 4*MAXPATHLEN, which should not overrun */
        char relative_from[MAXPATHLEN * 4];
        _cleanup_free_ char *realtarget = NULL;
        _cleanup_free_ char *target_dir_p = NULL, *realpath_p = NULL;
        const char *realfrom = from;
        size_t level = 0, fromlevel = 0, targetlevel = 0;
        int l;
        size_t i, rl, dirlen;
        int ret;

        target_dir_p = strdup(target);
        if (!target_dir_p)
                return strdup(from);

        dirlen = dir_len(target_dir_p);
        target_dir_p[dirlen] = '\0';
        realpath_p = realpath(target_dir_p, NULL);

        if (realpath_p == NULL) {
                log_warning("convert_abs_rel(): target '%s' directory has no realpath.", target);
                return strdup(from);
        }

        /* dir_len() skips double /'s e.g. //lib64, so we can't skip just one
         * character - need to skip all leading /'s */
        rl = strlen(target);
        for (i = dirlen + 1; i < rl; ++i)
                if (target_dir_p[i] != '/')
                        break;
        ret = asprintf(&realtarget, "%s/%s", realpath_p, &target_dir_p[i]);
        if (ret < 0) {
                log_error("Out of memory!");
                exit(EXIT_FAILURE);
        }

        /* now calculate the relative path from <from> to <target> and
           store it in <relative_from>
         */
        relative_from[0] = 0;
        rl = 0;

        /* count the pathname elements of realtarget */
        for (targetlevel = 0, i = 0; realtarget[i]; i++)
                if (realtarget[i] == '/')
                        targetlevel++;

        /* count the pathname elements of realfrom */
        for (fromlevel = 0, i = 0; realfrom[i]; i++)
                if (realfrom[i] == '/')
                        fromlevel++;

        /* count the pathname elements, which are common for both paths */
        for (level = 0, i = 0; realtarget[i] && (realtarget[i] == realfrom[i]); i++)
                if (realtarget[i] == '/')
                        level++;

        /* add "../" to the relative_from path, until the common pathname is
           reached */
        for (i = level; i < targetlevel; i++) {
                if (i != level)
                        relative_from[rl++] = '/';
                relative_from[rl++] = '.';
                relative_from[rl++] = '.';
        }

        /* set l to the next uncommon pathname element in realfrom */
        for (l = 1, i = 1; i < level; i++)
                for (l++; realfrom[l] && realfrom[l] != '/'; l++) ;
        /* skip next '/' */
        l++;

        /* append the uncommon rest of realfrom to the relative_from path */
        for (i = level; i <= fromlevel; i++) {
                if (rl)
                        relative_from[rl++] = '/';
                while (realfrom[l] && realfrom[l] != '/')
                        relative_from[rl++] = realfrom[l++];
                l++;
        }

        relative_from[rl] = 0;
        return strdup(relative_from);
}
Esempio n. 10
0
int socket_address_parse(SocketAddress *a, const char *s) {
        int r;
        char *e, *n;
        unsigned u;

        assert(a);
        assert(s);

        zero(*a);
        a->type = SOCK_STREAM;

        if (*s == '[') {
                /* IPv6 in [x:.....:z]:p notation */

                if (!socket_ipv6_is_supported()) {
                        log_warning("Binding to IPv6 address not available since kernel does not support IPv6.");
                        return -EAFNOSUPPORT;
                }

                if (!(e = strchr(s+1, ']')))
                        return -EINVAL;

                if (!(n = strndup(s+1, e-s-1)))
                        return -ENOMEM;

                errno = 0;
                if (inet_pton(AF_INET6, n, &a->sockaddr.in6.sin6_addr) <= 0) {
                        free(n);
                        return errno != 0 ? -errno : -EINVAL;
                }

                free(n);

                e++;
                if (*e != ':')
                        return -EINVAL;

                e++;
                if ((r = safe_atou(e, &u)) < 0)
                        return r;

                if (u <= 0 || u > 0xFFFF)
                        return -EINVAL;

                a->sockaddr.in6.sin6_family = AF_INET6;
                a->sockaddr.in6.sin6_port = htons((uint16_t) u);
                a->size = sizeof(struct sockaddr_in6);

        } else if (*s == '/') {
                /* AF_UNIX socket */

                size_t l;

                l = strlen(s);
                if (l >= sizeof(a->sockaddr.un.sun_path))
                        return -EINVAL;

                a->sockaddr.un.sun_family = AF_UNIX;
                memcpy(a->sockaddr.un.sun_path, s, l);
                a->size = offsetof(struct sockaddr_un, sun_path) + l + 1;

        } else if (*s == '@') {
Esempio n. 11
0
//--------------------------------------------------------------------------------------------
egoboo_rv get_random_treasure( char * buffer, size_t buffer_length )
{
    //ZF> Gets the name for a treasure randomly selected from the specified treasure table
    //    This function effectively "converts" a table name into a random element from that table

    IPair loc_rand;
    size_t i;
    int treasure_index;

    bool_t found = bfalse;
    STRING tmp_buffer;

    // Trap invalid strings
    if ( 0 == buffer_length || INVALID_CSTR( buffer ) ) return rv_error;

    // make a local copy of the string
    strncpy( tmp_buffer, buffer, SDL_arraysize( tmp_buffer ) );

    // Iterate through every treasure table until we find the one we want
    found = bfalse;
    for ( i = 0; i < MAX_TABLES; i++ )
    {
        //Continue looking until we find the correct table
        if ( 0 != strcmp( treasureTableList[i].table_name, tmp_buffer ) ) continue;

        //Pick a random number between 0 and the length of the table to get a random element out of the array
        loc_rand.base = 0;
        loc_rand.rand = treasureTableList[i].size;
        treasure_index = generate_irand_pair( loc_rand );
        strncpy( tmp_buffer, treasureTableList[i].object_list[treasure_index], buffer_length );

        //See if it is an actual random object or a reference to a different random table
        if ( '%' != tmp_buffer[0] )
        {
            found = btrue;
        }
        else
        {
            if ( rv_success == get_random_treasure( tmp_buffer, buffer_length ) )
            {
                found = btrue;
            }
        }
    }

    //Could not find anything
    if ( found )
    {
        // copy the local string to the output
        strncpy( buffer, tmp_buffer, buffer_length );
        printf( "Random treasure: %s\n", buffer );
    }
    else
    {
        // give a warning
        tmp_buffer[0] = CSTR_END;
        log_warning( "Could not find treasure table: %s!\n", buffer );
    }

    return found ? rv_success : rv_fail;
}
Esempio n. 12
0
static int parse_proc_cmdline(
    char ***arg_proc_cmdline_disks,
    char ***arg_proc_cmdline_options,
    char **arg_proc_cmdline_keyfile) {

    _cleanup_free_ char *line = NULL;
    char *w = NULL, *state = NULL;
    size_t l;
    int r;

    r = proc_cmdline(&line);
    if (r < 0)
        log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
    if (r <= 0)
        return 0;

    FOREACH_WORD_QUOTED(w, l, line, state) {
        _cleanup_free_ char *word = NULL;

        word = strndup(w, l);
        if (!word)
            return log_oom();

        if (startswith(word, "luks=")) {
            r = parse_boolean(word + 5);
            if (r < 0)
                log_warning("Failed to parse luks switch %s. Ignoring.", word + 5);
            else
                arg_enabled = r;

        } else if (startswith(word, "rd.luks=")) {

            if (in_initrd()) {
                r = parse_boolean(word + 8);
                if (r < 0)
                    log_warning("Failed to parse luks switch %s. Ignoring.", word + 8);
                else
                    arg_enabled = r;
            }

        } else if (startswith(word, "luks.crypttab=")) {
            r = parse_boolean(word + 14);
            if (r < 0)
                log_warning("Failed to parse luks crypttab switch %s. Ignoring.", word + 14);
            else
                arg_read_crypttab = r;

        } else if (startswith(word, "rd.luks.crypttab=")) {

            if (in_initrd()) {
                r = parse_boolean(word + 17);
                if (r < 0)
                    log_warning("Failed to parse luks crypttab switch %s. Ignoring.", word + 17);
                else
                    arg_read_crypttab = r;
            }

        } else if (startswith(word, "luks.uuid=")) {
            if (strv_extend(arg_proc_cmdline_disks, word + 10) < 0)
                return log_oom();

        } else if (startswith(word, "rd.luks.uuid=")) {

            if (in_initrd()) {
                if (strv_extend(arg_proc_cmdline_disks, word + 13) < 0)
                    return log_oom();
            }

        } else if (startswith(word, "luks.options=")) {
            if (strv_extend(arg_proc_cmdline_options, word + 13) < 0)
                return log_oom();

        } else if (startswith(word, "rd.luks.options=")) {

            if (in_initrd()) {
                if (strv_extend(arg_proc_cmdline_options, word + 16) < 0)
                    return log_oom();
            }

        } else if (startswith(word, "luks.key=")) {
            if (*arg_proc_cmdline_keyfile)
                free(*arg_proc_cmdline_keyfile);
            *arg_proc_cmdline_keyfile = strdup(word + 9);
            if (!*arg_proc_cmdline_keyfile)
                return log_oom();

        } else if (startswith(word, "rd.luks.key=")) {

            if (in_initrd()) {
                if (*arg_proc_cmdline_keyfile)
                    free(*arg_proc_cmdline_keyfile);
                *arg_proc_cmdline_keyfile = strdup(word + 12);
                if (!*arg_proc_cmdline_keyfile)
                    return log_oom();
            }

        } else if (startswith(word, "luks.") ||
                   (in_initrd() && startswith(word, "rd.luks."))) {

            log_warning("Unknown kernel switch %s. Ignoring.", word);
        }
    }
Esempio n. 13
0
static void window_title_editor_scrollpaint_commands(rct_window * w, rct_drawpixelinfo * dpi)
{
    sint32 position = -1;
    if (title_is_previewing_sequence() && _selectedTitleSequence == title_get_current_sequence())
    {
        ITitleSequencePlayer * player = window_title_editor_get_player();
        position = title_sequence_player_get_current_position(player);
    }

    sint32 x = 0;
    sint32 y = 0;
    for (sint32 i = 0; i < (sint32)_editingTitleSequence->NumCommands; i++, y += SCROLLABLE_ROW_HEIGHT)
    {
        TitleCommand * command = &_editingTitleSequence->Commands[i];
        bool selected = false;
        bool hover = false;
        bool error = false;
        if (i == w->selected_list_item)
        {
            selected = true;
            gfx_fill_rect(dpi, x, y, x + SCROLL_WIDTH + 100, y + SCROLLABLE_ROW_HEIGHT - 1, ColourMapA[w->colours[1]].dark);
        }
        else if (i == (sint32)_window_title_editor_highlighted_index || i == position)
        {
            hover = true;
            gfx_fill_rect(dpi, x, y, x + SCROLL_WIDTH + 100, y + SCROLLABLE_ROW_HEIGHT - 1, ColourMapA[w->colours[1]].mid_dark);
        }
        else if (i & 1)
        {
            gfx_fill_rect(dpi, x, y, x + SCROLL_WIDTH + 100, y + SCROLLABLE_ROW_HEIGHT - 1, ColourMapA[w->colours[1]].lighter | 0x1000000);
        }

        rct_string_id commandName = STR_NONE;
        switch (command->Type)
        {
        case TITLE_SCRIPT_LOAD:
            commandName = STR_TITLE_EDITOR_COMMAND_LOAD_FILE;
            if (command->SaveIndex == SAVE_INDEX_INVALID)
            {
                commandName = STR_TITLE_EDITOR_COMMAND_LOAD_NO_SAVE;
                error = true;
            }
            else
            {
                set_format_arg(0, uintptr_t, _editingTitleSequence->Saves[command->SaveIndex]);
            }
            break;
        case TITLE_SCRIPT_LOADMM:
            commandName = STR_TITLE_EDITOR_COMMAND_LOAD_SFMM;
            break;
        case TITLE_SCRIPT_LOCATION:
            commandName = STR_TITLE_EDITOR_COMMAND_LOCATION;
            set_format_arg(0, uint16, command->X);
            set_format_arg(2, uint16, command->Y);
            break;
        case TITLE_SCRIPT_ROTATE:
            commandName = STR_TITLE_EDITOR_COMMAND_ROTATE;
            set_format_arg(0, uint16, command->Rotations);
            break;
        case TITLE_SCRIPT_ZOOM:
            commandName = STR_TITLE_EDITOR_COMMAND_ZOOM;
            set_format_arg(0, uint16, command->Zoom);
            break;
        case TITLE_SCRIPT_SPEED:
            commandName = STR_TITLE_EDITOR_COMMAND_SPEED;
            set_format_arg(0, rct_string_id, SpeedNames[command->Speed - 1]);
            break;
        case TITLE_SCRIPT_FOLLOW:
            commandName = STR_TITLE_EDITOR_COMMAND_FOLLOW;
            if (command->SpriteIndex == SPRITE_INDEX_NULL)
            {
                commandName = STR_TITLE_EDITOR_COMMAND_FOLLOW_NO_SPRITE;
            }
            else
            {
                set_format_arg(0, uintptr_t, (uintptr_t)command->SpriteName);
            }
            break;
        case TITLE_SCRIPT_WAIT:
            commandName = STR_TITLE_EDITOR_COMMAND_WAIT;
            set_format_arg(0, uint16, command->Milliseconds);
            break;
        case TITLE_SCRIPT_RESTART:
            commandName = STR_TITLE_EDITOR_RESTART;
            break;
        case TITLE_SCRIPT_END:
            commandName = STR_TITLE_EDITOR_END;
            break;
        case TITLE_SCRIPT_LOADRCT1:
        {
            commandName = STR_TITLE_EDITOR_COMMAND_LOAD_FILE;
            const char * name = "";
            source_desc desc;
            if (scenario_get_source_desc_by_id(command->SaveIndex, &desc))
            {
                name = desc.title;
            }
            set_format_arg(0, uintptr_t, name);
            break;
        }
        case TITLE_SCRIPT_LOADSC:
        {
            commandName = STR_TITLE_EDITOR_COMMAND_LOAD_FILE;
            const char * name = "";
            auto scenario =
                GetScenarioRepository()->GetByInternalName(command->Scenario);
            if (command->Scenario[0] == '\0')
            {
                commandName = STR_TITLE_EDITOR_COMMAND_LOAD_NO_SCENARIO;
            }
            else if (scenario != nullptr)
            {
                name = scenario->name;
            }
            else
            {
                commandName = STR_TITLE_EDITOR_COMMAND_LOAD_MISSING_SCENARIO;
            }
            set_format_arg(0, uintptr_t, name);
            break;
        }
        default:
            log_warning("Unknown command %d", command->Type);
        }

        char buffer[256];
        if ((selected || hover) && !error)
        {
            format_string(buffer, 256, commandName, gCommonFormatArgs);
        }
        else
        {
            format_string(buffer + 1, 255, commandName, gCommonFormatArgs);
            buffer[0] = (utf8)(error ? ((selected || hover) ? FORMAT_LIGHTPINK : FORMAT_RED) : FORMAT_BLACK);
        }
        set_format_arg(0, uintptr_t, &buffer);
        gfx_draw_string_left(dpi, STR_STRING, gCommonFormatArgs, w->colours[1], x + 5, y);
    }
}
Esempio n. 14
0
//--------------------------------------------------------------------------------------------
map_t *cartman_mpd_revert(map_t *dst, cartman_mpd_t *src)
{
    if (!dst || !src)
    {
        return nullptr;
    }
    cartman_mpd_info_t& info_src = src->info;

    // Clear out all data in the destination mesh.
    dst->setInfo();

    // Make sure we have the accurate(!) vertx count.
    info_src.vertex_count = src->count_used_vertices();

    // Allocate the correct size for the destination mesh.
    map_info_t loc_info_dst;
    loc_info_dst.tileCountX  = info_src.tiles_x;
    loc_info_dst.tileCountY  = info_src.tiles_y;
    loc_info_dst.vertexCount = info_src.vertex_count;
    dst->setInfo(loc_info_dst);
    
    map_mem_t *pmem_dst = &(dst->_mem);

    // revert the tile information
    for (size_t cnt = 0; cnt < info_src.tiles_count; cnt++ )
    {
        tile_info_t& tile_dst = pmem_dst->tiles[cnt];
        cartman_mpd_tile_t& tile_src = src->fan2[cnt];

        tile_dst.type   = tile_src.type;
        tile_dst.img    = tile_src.tx_bits;
        tile_dst.fx     = tile_src.fx;
        tile_dst.twist  = tile_src.twist;
    }

    // revert the vertex information
    for (int itile = 0, ivrt_dst = 0; itile < info_src.tiles_count; itile++ )
    {

        // grab the source fan
        const cartman_mpd_tile_t& fan_src = src->fan2[itile];

        // is the type valid?
        tile_definition_t *pdef = TILE_DICT_PTR(tile_dict, fan_src.type);
        if (!pdef)
        {
            log_warning("%s:%d: invalid fan type %d used in the mesh\n", __FILE__, __LINE__, fan_src.type);
            goto cartman_mpd_revert_fail;
        }

        // is the vertex_count valid?
        int vert_count = pdef->numvertices;
        if ( 0 == vert_count )
        {
            log_warning("%s:%d: undefined fan type %d used in the mesh\n", __FILE__,__LINE__, fan_src.type);
        }
        else if ( vert_count > MAP_FAN_VERTICES_MAX )
        {
            log_warning("%s:%d: too many vertices %d used in tile type %d\n", __FILE__,__LINE__, vert_count, fan_src.type );
            goto cartman_mpd_revert_fail;
        }

        // is the initial vertex valid?
        if (!CART_VALID_VERTEX_RANGE(fan_src.vrtstart))
        {
            log_warning("%s:%d: vertex %d is outside of valid vertex range\n", __FILE__, __LINE__, fan_src.vrtstart );
            goto cartman_mpd_revert_fail;
        }

        Cartman::mpd_vertex_t *pvrt_src = nullptr;
        int tnc, ivrt_src;
        for ( tnc = 0, ivrt_src = fan_src.vrtstart;
              tnc < vert_count;
              tnc++, ivrt_src = pvrt_src->next, ivrt_dst++ )
        {
            // check for a bad CHAINEND
            if ( CHAINEND == ivrt_src )
            {
                log_warning( "%s - vertex %d of tile %d is marked as unused\n", __FUNCTION__, tnc, itile );
                goto cartman_mpd_revert_fail;
            }

            // grab the src pointer
            pvrt_src = &(src->vrt2[ivrt_src]);

            // check for VERTEXUNUSED
            if ( VERTEXUNUSED == pvrt_src->a )
            {
                log_warning( "%s - vertex %d of tile %d is marked as unused\n", __FUNCTION__, tnc, itile );
                goto cartman_mpd_revert_fail;
            }

            // grab the destination vertex
            map_vertex_t& pvrt_dst = pmem_dst->vertices[ivrt_dst];

            pvrt_dst.pos[kX] = pvrt_src->x;
            pvrt_dst.pos[kY] = pvrt_src->y;
            pvrt_dst.pos[kZ] = pvrt_src->z;
            pvrt_dst.a       = pvrt_src->a;
        }
    }

    return dst;

cartman_mpd_revert_fail:

    // deallocate any dynamic memory
    dst->setInfo();
#if 0
    map_renew( pmesh_dst );
#endif
    return NULL;
}
Esempio n. 15
0
static void print_status_info(const StatusInfo *i) {
        char a[LINE_MAX];
        struct tm tm;
        time_t sec;
        bool have_time = false;
        const char *old_tz = NULL, *tz;
        int r;
        size_t n;

        assert(i);

        /* Save the old $TZ */
        tz = getenv("TZ");
        if (tz)
                old_tz = strdupa(tz);

        /* Set the new $TZ */
        if (setenv("TZ", isempty(i->timezone) ? "UTC" : i->timezone, true) < 0)
                log_warning_errno(errno, "Failed to set TZ environment variable, ignoring: %m");
        else
                tzset();

        if (i->time != 0) {
                sec = (time_t) (i->time / USEC_PER_SEC);
                have_time = true;
        } else if (IN_SET(arg_transport, BUS_TRANSPORT_LOCAL, BUS_TRANSPORT_MACHINE)) {
                sec = time(NULL);
                have_time = true;
        } else
                log_warning("Could not get time from timedated and not operating locally, ignoring.");

        if (have_time) {
                n = strftime(a, sizeof a, "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&sec, &tm));
                printf("                      Local time: %s\n", n > 0 ? a : "n/a");

                n = strftime(a, sizeof a, "%a %Y-%m-%d %H:%M:%S UTC", gmtime_r(&sec, &tm));
                printf("                  Universal time: %s\n", n > 0 ? a : "n/a");
        } else {
                printf("                      Local time: %s\n", "n/a");
                printf("                  Universal time: %s\n", "n/a");
        }

        if (i->rtc_time > 0) {
                time_t rtc_sec;

                rtc_sec = (time_t) (i->rtc_time / USEC_PER_SEC);
                n = strftime(a, sizeof a, "%a %Y-%m-%d %H:%M:%S", gmtime_r(&rtc_sec, &tm));
                printf("                        RTC time: %s\n", n > 0 ? a : "n/a");
        } else
                printf("                        RTC time: %s\n", "n/a");

        if (have_time)
                n = strftime(a, sizeof a, "%Z, %z", localtime_r(&sec, &tm));

        /* Restore the $TZ */
        if (old_tz)
                r = setenv("TZ", old_tz, true);
        else
                r = unsetenv("TZ");
        if (r < 0)
                log_warning_errno(errno, "Failed to set TZ environment variable, ignoring: %m");
        else
                tzset();

        printf("                       Time zone: %s (%s)\n"
               "       System clock synchronized: %s\n"
               "systemd-timesyncd.service active: %s\n"
               "                 RTC in local TZ: %s\n",
               strna(i->timezone), have_time && n > 0 ? a : "n/a",
               yes_no(i->ntp_synced),
               i->ntp_capable ? yes_no(i->ntp_enabled) : "n/a",
               yes_no(i->rtc_local));

        if (i->rtc_local)
                printf("\n%s"
                       "Warning: The system is configured to read the RTC time in the local time zone.\n"
                       "         This mode can not be fully supported. It will create various problems\n"
                       "         with time zone changes and daylight saving time adjustments. The RTC\n"
                       "         time is never updated, it relies on external facilities to maintain it.\n"
                       "         If at all possible, use RTC in UTC by calling\n"
                       "         'timedatectl set-local-rtc 0'.%s\n", ansi_highlight(), ansi_normal());
}
Esempio n. 16
0
int perform_format_config(struct bladerf *dev, bladerf_module module,
                          bladerf_format format)
{
    int status = 0;
    bool use_timestamps;
    bladerf_module other;
    bool other_using_timestamps;
    uint32_t gpio_val;

    status = requires_timestamps(format, &use_timestamps);
    if (status != 0) {
        log_debug("%s: Invalid format: %d\n", __FUNCTION__, format);
        return status;
    }

    if (use_timestamps && version_less_than(&dev->fpga_version, 0, 1, 0)) {
        log_warning("Timestamp support requires FPGA v0.1.0 or later.\n");
        return BLADERF_ERR_UPDATE_FPGA;
    }

    switch (module) {
        case BLADERF_MODULE_RX:
            other = BLADERF_MODULE_TX;
            break;

        case BLADERF_MODULE_TX:
            other = BLADERF_MODULE_RX;
            break;

        default:
            log_debug("Invalid module: %d\n", module);
            return BLADERF_ERR_INVAL;
    }

    status = requires_timestamps(dev->module_format[other],
                                 &other_using_timestamps);

    if ((status == 0) && (other_using_timestamps != use_timestamps)) {
        log_debug("Format conflict detected: RX=%d, TX=%d\n");
        return BLADERF_ERR_INVAL;
    }

    status = CONFIG_GPIO_READ(dev, &gpio_val);
    if (status != 0) {
        return status;
    }

    if (use_timestamps) {
        gpio_val |= (BLADERF_GPIO_TIMESTAMP | BLADERF_GPIO_TIMESTAMP_DIV2);
    } else {
        gpio_val &= ~(BLADERF_GPIO_TIMESTAMP | BLADERF_GPIO_TIMESTAMP_DIV2);
    }

    status = CONFIG_GPIO_WRITE(dev, gpio_val);

    if (status == 0) {
        dev->module_format[module] = format;
    }

    return status;
}
Esempio n. 17
0
static int drive_resources_type(int val, void *param)
{
    unsigned int type, dnr;
    int busses;
    drive_t *drive, *drive0;
    char *rtc_device = NULL;

    dnr = vice_ptr_to_uint(param);
    drive = drive_context[dnr]->drive;

    type = (unsigned int)val;
    busses = iec_available_busses();

    /* if bus for drive type is not allowed, set to default value for bus */
    if (!drive_check_bus(type, busses)) {
        if (busses & IEC_BUS_IEC) {
            type = DRIVE_TYPE_1541;
        } else
        if (busses & IEC_BUS_IEEE) {
            type = DRIVE_TYPE_2031;
        } else {
            type = DRIVE_TYPE_NONE;
        }
    }

    if (is_drive0(dnr)) {
        if (drive_check_dual(type)) {
            int drive1 = mk_drive1(dnr);

            /* dual disk drives disable second emulated unit */
            log_warning(drive->log,
                        "Dual disk drive %d disables emulated drive %d", dnr, drive1);

            drive_resources_type(DRIVE_TYPE_NONE, int_to_void_ptr(drive1));
        }
    } else {
        drive0 = drive_context[mk_drive0(dnr)]->drive;
        if (drive0->enable && drive_check_dual(drive0->type)) {
            /* dual disk drives disable second emulated unit */
            log_warning(drive->log,
                        "Dual disk drive %d disables emulated drive %d", mk_drive0(dnr), dnr);

            type = DRIVE_TYPE_NONE;
        }
    }

    if (type == DRIVE_TYPE_2000 || type == DRIVE_TYPE_4000) {
        if (drive->type != DRIVE_TYPE_2000 && drive->type != DRIVE_TYPE_4000) {
            rtc_device = lib_msprintf("FD%d", dnr + 8);
            drive->ds1216 = ds1216e_init(rtc_device);
            drive->ds1216->hours12 = 1;
            lib_free(rtc_device);
        }
    } else {
        if (drive->type == DRIVE_TYPE_2000 || drive->type == DRIVE_TYPE_4000) {
            if (drive->ds1216) {
                ds1216e_destroy(drive->ds1216, drive->rtc_save);
                drive->ds1216 = NULL;
            }
        }
    }

    switch (type) {
        case DRIVE_TYPE_1540:
        case DRIVE_TYPE_1541:
        case DRIVE_TYPE_1541II:
        case DRIVE_TYPE_1551:
        case DRIVE_TYPE_1570:
        case DRIVE_TYPE_1571:
        case DRIVE_TYPE_1571CR:
        case DRIVE_TYPE_1581:
        case DRIVE_TYPE_2000:
        case DRIVE_TYPE_4000:
        case DRIVE_TYPE_2031:
        case DRIVE_TYPE_1001:
        case DRIVE_TYPE_2040:
        case DRIVE_TYPE_3040:
        case DRIVE_TYPE_4040:
        case DRIVE_TYPE_8050:
        case DRIVE_TYPE_8250:
            if (drive->type != type) {
                drive->current_half_track = 2 * 18;
                if ((type == DRIVE_TYPE_1001)
                    || (type == DRIVE_TYPE_8050)
                    || (type == DRIVE_TYPE_8250)) {
                    drive->current_half_track = 2 * 38;
                }
            }
            drive->type = type;
            if (drive_true_emulation) {
                drive->enable = 1;
                drive_enable(drive_context[dnr]);
                /* 1551 drive does not use the IEC bus */
                machine_bus_status_drivetype_set(dnr + 8, drive_check_bus(type,
                                                                          IEC_BUS_IEC));
            } else {
                drive_enable_update_ui(drive_context[dnr]);
            }
            drive_set_disk_drive_type(type, drive_context[dnr]);
            driverom_initialize_traps(drive);
            machine_drive_idling_method(dnr);
            return 0;
        case DRIVE_TYPE_NONE:
            drive->type = type;
            drive_disable(drive_context[dnr]);
            machine_bus_status_drivetype_set(dnr + 8, 0);
            return 0;
        default:
            return -1;
    }
}
Esempio n. 18
0
static inline int apply_lms_dc_cals(struct bladerf *dev)
{
    int status = 0;
    struct bladerf_lms_dc_cals cals;
    const bool have_rx = BLADERF_HAS_RX_DC_CAL(dev);
    const bool have_tx = BLADERF_HAS_TX_DC_CAL(dev);

    cals.lpf_tuning = -1;
    cals.tx_lpf_i   = -1;
    cals.tx_lpf_q   = -1;
    cals.rx_lpf_i   = -1;
    cals.rx_lpf_q   = -1;
    cals.dc_ref     = -1;
    cals.rxvga2a_i  = -1;
    cals.rxvga2a_q  = -1;
    cals.rxvga2b_i  = -1;
    cals.rxvga2b_q  = -1;

    if (have_rx) {
        const struct bladerf_lms_dc_cals *reg_vals = &dev->cal.dc_rx->reg_vals;

        cals.lpf_tuning = reg_vals->lpf_tuning;
        cals.rx_lpf_i   = reg_vals->rx_lpf_i;
        cals.rx_lpf_q   = reg_vals->rx_lpf_q;
        cals.dc_ref     = reg_vals->dc_ref;
        cals.rxvga2a_i  = reg_vals->rxvga2a_i;
        cals.rxvga2a_q  = reg_vals->rxvga2a_q;
        cals.rxvga2b_i  = reg_vals->rxvga2b_i;
        cals.rxvga2b_q  = reg_vals->rxvga2b_q;
    }

    if (have_tx) {
        const struct bladerf_lms_dc_cals *reg_vals = &dev->cal.dc_tx->reg_vals;

        cals.tx_lpf_i = reg_vals->tx_lpf_i;
        cals.tx_lpf_q = reg_vals->tx_lpf_q;

        if (have_rx) {
            if (cals.lpf_tuning != reg_vals->lpf_tuning) {
                log_warning("LPF tuning mismatch in tables. "
                            "RX=0x%04x, TX=0x%04x",
                            cals.lpf_tuning, reg_vals->lpf_tuning);
            }
        } else {
            /* Have TX cal but no RX cal -- use the RX values that came along
             * for the ride when the TX table was generated */
            cals.rx_lpf_i   = reg_vals->rx_lpf_i;
            cals.rx_lpf_q   = reg_vals->rx_lpf_q;
            cals.dc_ref     = reg_vals->dc_ref;
            cals.rxvga2a_i  = reg_vals->rxvga2a_i;
            cals.rxvga2a_q  = reg_vals->rxvga2a_q;
            cals.rxvga2b_i  = reg_vals->rxvga2b_i;
            cals.rxvga2b_q  = reg_vals->rxvga2b_q;
        }
    }

    /* No TX table was loaded, so load LMS TX register cals from the RX table,
     * if available */
    if (have_rx && !have_tx) {
        const struct bladerf_lms_dc_cals *reg_vals = &dev->cal.dc_rx->reg_vals;

        cals.tx_lpf_i   = reg_vals->tx_lpf_i;
        cals.tx_lpf_q   = reg_vals->tx_lpf_q;
    }

    if (have_rx || have_tx) {
        status = lms_set_dc_cals(dev, &cals);

        /* Force a re-tune so that we can apply the appropriate I/Q DC offset
         * values from our calibration table */
        if (status == 0) {
            int rx_status = 0;
            int tx_status = 0;

            if (have_rx) {
                unsigned int rx_f;
                rx_status = tuning_get_freq(dev, BLADERF_MODULE_RX, &rx_f);
                if (rx_status == 0) {
                    rx_status = tuning_set_freq(dev, BLADERF_MODULE_RX, rx_f);
                }
            }

            if (have_tx) {
                unsigned int rx_f;
                rx_status = tuning_get_freq(dev, BLADERF_MODULE_RX, &rx_f);
                if (rx_status == 0) {
                    rx_status = tuning_set_freq(dev, BLADERF_MODULE_RX, rx_f);
                }
            }

            /* Report the first of any failures */
            status = (rx_status == 0) ? tx_status : rx_status;
        }
    }

    return status;
}
Esempio n. 19
0
int switch_root(const char *new_root, const char *oldroot, bool detach_oldroot,  unsigned long mountflags) {

        /*  Don't try to unmount/move the old "/", there's no way to do it. */
        static const char move_mounts[] =
                "/dev\0"
                "/proc\0"
                "/sys\0"
                "/run\0";

        _cleanup_close_ int old_root_fd = -1;
        struct stat new_root_stat;
        bool old_root_remove;
        const char *i, *temporary_old_root;

        if (path_equal(new_root, "/"))
                return 0;

        temporary_old_root = strjoina(new_root, oldroot);
        mkdir_p_label(temporary_old_root, 0755);

        old_root_remove = in_initrd();

        if (stat(new_root, &new_root_stat) < 0)
                return log_error_errno(errno, "Failed to stat directory %s: %m", new_root);

        /* Work-around for kernel design: the kernel refuses switching
         * root if any file systems are mounted MS_SHARED. Hence
         * remount them MS_PRIVATE here as a work-around.
         *
         * https://bugzilla.redhat.com/show_bug.cgi?id=847418 */
        if (mount(NULL, "/", NULL, MS_REC|MS_PRIVATE, NULL) < 0)
                log_warning_errno(errno, "Failed to make \"/\" private mount: %m");

        NULSTR_FOREACH(i, move_mounts) {
                char new_mount[PATH_MAX];
                struct stat sb;
                size_t n;

                n = snprintf(new_mount, sizeof new_mount, "%s%s", new_root, i);
                if (n >= sizeof new_mount) {
                        bool move = mountflags & MS_MOVE;

                        log_warning("New path is too long, %s: %s%s",
                                    move ? "forcing unmount instead" : "ignoring",
                                    new_root, i);

                        if (move)
                                if (umount2(i, MNT_FORCE) < 0)
                                        log_warning_errno(errno, "Failed to unmount %s: %m", i);
                        continue;
                }

                mkdir_p_label(new_mount, 0755);

                if (stat(new_mount, &sb) < 0 ||
                    sb.st_dev != new_root_stat.st_dev) {

                        /* Mount point seems to be mounted already or
                         * stat failed. Unmount the old mount point. */
                        if (umount2(i, MNT_DETACH) < 0)
                                log_warning_errno(errno, "Failed to unmount %s: %m", i);
                        continue;
                }

                if (mount(i, new_mount, NULL, mountflags, NULL) < 0) {
                        if (mountflags & MS_MOVE) {
                                log_error_errno(errno, "Failed to move mount %s to %s, forcing unmount: %m", i, new_mount);

                                if (umount2(i, MNT_FORCE) < 0)
                                        log_warning_errno(errno, "Failed to unmount %s: %m", i);

                        } else if (mountflags & MS_BIND)
                                log_error_errno(errno, "Failed to bind mount %s to %s: %m", i, new_mount);
                }
        }
Esempio n. 20
0
static int add_swap(
                const char *what,
                struct mntent *me,
                MountpointFlags flags) {

        _cleanup_free_ char *name = NULL;
        _cleanup_fclose_ FILE *f = NULL;
        int r;

        assert(what);
        assert(me);

        if (access("/proc/swaps", F_OK) < 0) {
                log_info("Swap not supported, ignoring fstab swap entry for %s.", what);
                return 0;
        }

        if (detect_container() > 0) {
                log_info("Running in a container, ignoring fstab swap entry for %s.", what);
                return 0;
        }

        r = unit_name_from_path(what, ".swap", &name);
        if (r < 0)
                return log_error_errno(r, "Failed to generate unit name: %m");

        r = generator_open_unit_file(arg_dest, "/etc/fstab", name, &f);
        if (r < 0)
                return r;

        fputs("# Automatically generated by systemd-fstab-generator\n\n"
              "[Unit]\n"
              "SourcePath=/etc/fstab\n"
              "Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n\n"
              "[Swap]\n", f);

        r = write_what(f, what);
        if (r < 0)
                return r;

        r = write_options(f, me->mnt_opts);
        if (r < 0)
                return r;

        r = fflush_and_check(f);
        if (r < 0)
                return log_error_errno(r, "Failed to write unit file %s: %m", name);

        /* use what as where, to have a nicer error message */
        r = generator_write_timeouts(arg_dest, what, what, me->mnt_opts, NULL);
        if (r < 0)
                return r;

        if (flags & MAKEFS) {
                r = generator_hook_up_mkswap(arg_dest, what);
                if (r < 0)
                        return r;
        }

        if (flags & GROWFS)
                /* TODO: swap devices must be wiped and recreated */
                log_warning("%s: growing swap devices is currently unsupported.", what);

        if (!(flags & NOAUTO)) {
                r = generator_add_symlink(arg_dest, SPECIAL_SWAP_TARGET,
                                          (flags & NOFAIL) ? "wants" : "requires", name);
                if (r < 0)
                        return r;
        }

        return 0;
}
Esempio n. 21
0
File: pop.c Progetto: ctubio/claws
static gint pop3_session_recv_data_finished(Session *session, guchar *data,
					    guint len)
{
	Pop3Session *pop3_session = POP3_SESSION(session);
	Pop3ErrorValue val = PS_SUCCESS;

	switch (pop3_session->state) {
	case POP3_GETRANGE_UIDL_RECV:
		val = pop3_getrange_uidl_recv(pop3_session, data, len);
		if (val == PS_SUCCESS) {
			if (pop3_session->new_msg_exist)
				pop3_getsize_list_send(pop3_session);
			else
				pop3_logout_send(pop3_session);
		} else
			return -1;
		break;
	case POP3_GETSIZE_LIST_RECV:
		val = pop3_getsize_list_recv(pop3_session, data, len);
		if (val == PS_SUCCESS) {
			if (pop3_lookup_next(pop3_session) == POP3_ERROR)
				return -1;
		} else
			return -1;
		break;
	case POP3_RETR_RECV:
		if (pop3_retr_recv(pop3_session, data, len) < 0)
			return -1;

		if (pop3_session->ac_prefs->rmmail &&
		    pop3_session->ac_prefs->msg_leave_time == 0 &&
		    pop3_session->ac_prefs->msg_leave_hour == 0 &&
		    pop3_session->msg[pop3_session->cur_msg].recv_time
		    != RECV_TIME_KEEP)
			pop3_delete_send(pop3_session);
		else if (pop3_session->cur_msg == pop3_session->count)
			pop3_logout_send(pop3_session);
		else {
			pop3_session->cur_msg++;
			if (pop3_lookup_next(pop3_session) == POP3_ERROR)
				return -1;
		}
		break;
	case POP3_TOP_RECV:
		if (pop3_top_recv(pop3_session, data, len) < 0)
			return -1;

		if (pop3_session->cur_msg == pop3_session->count)
			pop3_logout_send(pop3_session);
		else {
			pop3_session->cur_msg++;
			if (pop3_lookup_next(pop3_session) == POP3_ERROR)
				return -1;
		}
		break;
	case POP3_TOP:
		log_warning(LOG_PROTOCOL, _("TOP command unsupported\n"));
		if (pop3_session->cur_msg == pop3_session->count)
			pop3_logout_send(pop3_session);
		else {
			pop3_session->cur_msg++;
			if (pop3_lookup_next(pop3_session) == POP3_ERROR)
				return -1;
		}
		break;
	case POP3_ERROR:
	default:
		return -1;
	}

	return 0;
}
Esempio n. 22
0
/* Open a file
 * Return values:
 *  < 0 => errno
 * == 0 => Opening file succeeded
 *  > 0 => It is a symlink which needs to be redirected (target written)
 */
static int open_file(HANDLE *hFile, struct mount_point *mp, const char *pathname,
	DWORD desired_access, DWORD create_disposition, DWORD attributes,
	int flags, BOOL bInherit, char *target, int buflen, char *drive_letter)
{
	WCHAR buf[PATH_MAX];
	UNICODE_STRING name;
	name.Buffer = buf;
	name.MaximumLength = name.Length = 2 * filename_to_nt_pathname(mp, pathname, buf, PATH_MAX);
	if (name.Length == 0)
		return -L_ENOENT;
	*drive_letter = buf[4];

	OBJECT_ATTRIBUTES attr;
	attr.Length = sizeof(OBJECT_ATTRIBUTES);
	attr.RootDirectory = NULL;
	attr.ObjectName = &name;
	attr.Attributes = (bInherit? OBJ_INHERIT: 0);
	attr.SecurityDescriptor = NULL;
	attr.SecurityQualityOfService = NULL;

	NTSTATUS status;
	IO_STATUS_BLOCK status_block;
	HANDLE handle;
	DWORD create_options = FILE_SYNCHRONOUS_IO_NONALERT; /* For synchronous I/O */
	if (desired_access & GENERIC_ALL)
		create_options |= FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_REMOTE_INSTANCE;
	else
	{
		if (desired_access & GENERIC_READ)
			create_options |= FILE_OPEN_FOR_BACKUP_INTENT;
		if (desired_access & GENERIC_WRITE)
			create_options |= FILE_OPEN_REMOTE_INSTANCE;
	}
	desired_access |= SYNCHRONIZE | FILE_READ_ATTRIBUTES;
	status = NtCreateFile(&handle, desired_access, &attr, &status_block, NULL,
		attributes, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
		create_disposition, create_options, NULL, 0);
	if (status == STATUS_OBJECT_NAME_COLLISION)
	{
		log_warning("File already exists.");
		return -L_EEXIST;
	}
	else if (!NT_SUCCESS(status))
	{
		log_warning("Unhandled NtCreateFile error, status: %x, returning ENOENT.", status);
		return -L_ENOENT;
	}

	FILE_ATTRIBUTE_TAG_INFORMATION attribute_info;
	status = NtQueryInformationFile(handle, &status_block, &attribute_info, sizeof(attribute_info), FileAttributeTagInformation);
	if (!NT_SUCCESS(status))
	{
		log_error("NtQueryInformationFile(FileAttributeTagInformation) failed, status: %x", status);
		NtClose(handle);
		return -L_EIO;
	}
	/* Test if the file is a symlink */
	int is_symlink = 0;
	if (!(attribute_info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (attribute_info.FileAttributes & FILE_ATTRIBUTE_SYSTEM))
	{
		/* The file has system flag set. A potential symbolic link. */
		if (!(desired_access & GENERIC_READ))
		{
			/* But the handle does not have READ access, try reopening file */
			HANDLE read_handle = ReOpenFile(handle, desired_access | GENERIC_READ,
				FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_FLAG_BACKUP_SEMANTICS);
			if (read_handle == INVALID_HANDLE_VALUE)
			{
				log_warning("Reopen symlink file failed, error code %d. Assume not symlink.", GetLastError());
				*hFile = handle;
				return 0;
			}
			NtClose(handle);
			handle = read_handle;
		}
		if (winfs_read_symlink_unsafe(handle, target, buflen) > 0)
		{
			if (!(flags & O_NOFOLLOW))
			{
				NtClose(handle);
				return 1;
			}
			if (!(flags & O_PATH))
			{
				NtClose(handle);
				log_info("Specified O_NOFOLLOW but not O_PATH, returning ELOOP.");
				return -L_ELOOP;
			}
		}
	}
	else if (!(attribute_info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (flags & O_DIRECTORY))
	{
		log_warning("Not a directory.");
		return -L_ENOTDIR;
	}
	*hFile = handle;
	return 0;
}
Esempio n. 23
0
static gboolean mail_filtering_hook(gpointer source, gpointer data)
{
	MailFilteringData *mail_filtering_data = (MailFilteringData *) source;
	MsgInfo *msginfo = mail_filtering_data->msginfo;
	gboolean is_spam = FALSE, error = FALSE;
	static gboolean warned_error = FALSE;
	FILE *fp = NULL;
	int pid = 0;
	int status;

	/* SPAMASSASSIN_DISABLED : keep test for compatibility purpose */
	if (!config.enable || config.transport == SPAMASSASSIN_DISABLED) {
		log_warning(LOG_PROTOCOL, _("SpamAssassin plugin is disabled by its preferences.\n"));
		return FALSE;
	}
	debug_print("Filtering message %d\n", msginfo->msgnum);
	if (message_callback != NULL)
		message_callback(_("SpamAssassin: filtering message..."));

	if ((fp = procmsg_open_message(msginfo)) == NULL) {
		debug_print("failed to open message file\n");
		return FALSE;
	}

	if (config.whitelist_ab) {
		gchar *ab_folderpath;
		gboolean whitelisted = FALSE;

		if (*config.whitelist_ab_folder == '\0' ||
			strcasecmp(config.whitelist_ab_folder, "Any") == 0) {
			/* match the whole addressbook */
			ab_folderpath = NULL;
		} else {
			/* match the specific book/folder of the addressbook */
			ab_folderpath = config.whitelist_ab_folder;
		}

		start_address_completion(ab_folderpath);
		if (msginfo->from && 
		    sa_found_in_addressbook(msginfo->from))
				whitelisted = TRUE;
		end_address_completion();
		
		if (whitelisted) {
			debug_print("message is ham (whitelisted)\n");
			fclose(fp);
			return FALSE;
		}
	}
	pid = fork();
	if (pid == 0) {
		_exit(msg_is_spam(fp));
	} else {
		gint running = 0;

		running |= CHILD_RUNNING;

		g_timeout_add(50, timeout_func, &running);
		running |= TIMEOUT_RUNNING;

		while(running & CHILD_RUNNING) {
			int ret;

			ret = waitpid(pid, &status, WNOHANG);
			if (ret == pid) {
				if (WIFEXITED(status)) {
					MsgStatus result = MSG_IS_HAM;
					running &= ~CHILD_RUNNING;
					result = WEXITSTATUS(status);
    					is_spam = (result == MSG_IS_SPAM) ? TRUE : FALSE;
					error = (result == MSG_FILTERING_ERROR);
				}
			} if (ret < 0) {
				running &= ~CHILD_RUNNING;
			} /* ret == 0 continue */
	    
			g_main_context_iteration(NULL, TRUE);
    		}

		while (running & TIMEOUT_RUNNING)
			g_main_context_iteration(NULL, TRUE);
	}

	fclose(fp);

	if (is_spam) {
		debug_print("message is spam\n");
		procmsg_msginfo_set_flags(msginfo, MSG_SPAM, 0);
		if (config.receive_spam) {
			FolderItem *save_folder = NULL;

			if ((!config.save_folder) ||
			    (config.save_folder[0] == '\0') ||
			    ((save_folder = folder_find_item_from_identifier(config.save_folder)) == NULL)) {
			 	if (mail_filtering_data->account && mail_filtering_data->account->set_trash_folder) {
					save_folder = folder_find_item_from_identifier(
						mail_filtering_data->account->trash_folder);
					if (save_folder)
						debug_print("found trash folder from account's advanced settings\n");
				}
				if (save_folder == NULL && mail_filtering_data->account &&
				    mail_filtering_data->account->folder) {
				    	save_folder = mail_filtering_data->account->folder->trash;
					if (save_folder)
						debug_print("found trash folder from account's trash\n");
				}
				if (save_folder == NULL && mail_filtering_data->account &&
				    !mail_filtering_data->account->folder)  {
					if (mail_filtering_data->account->inbox) {
						FolderItem *item = folder_find_item_from_identifier(
							mail_filtering_data->account->inbox);
						if (item && item->folder->trash) {
							save_folder = item->folder->trash;
							debug_print("found trash folder from account's inbox\n");
						}
					} 
					if (!save_folder && mail_filtering_data->account->local_inbox) {
						FolderItem *item = folder_find_item_from_identifier(
							mail_filtering_data->account->local_inbox);
						if (item && item->folder->trash) {
							save_folder = item->folder->trash;
							debug_print("found trash folder from account's local_inbox\n");
						}
					}
				}
				if (save_folder == NULL) {
					debug_print("using default trash folder\n");
					save_folder = folder_get_default_trash();
				}
			}
			if (config.mark_as_read)
				procmsg_msginfo_unset_flags(msginfo, ~0, 0);
			procmsg_msginfo_set_flags(msginfo, MSG_SPAM, 0);
			msginfo->filter_op = IS_MOVE;
			msginfo->to_filter_folder = save_folder;
		} else {
			folder_item_remove_msg(msginfo->folder, msginfo->msgnum);
		}

		return TRUE;
	} else {
		debug_print("message is ham\n");
		procmsg_msginfo_unset_flags(msginfo, MSG_SPAM, 0);
	}
	
	if (error) {
		gchar *msg = _("The SpamAssassin plugin couldn't filter "
					   "a message. The probable cause of the error "
					   "is an unreachable spamd daemon. Please make "
					   "sure spamd is running and accessible.");
		if (!prefs_common.no_recv_err_panel) {
			if (!warned_error) {
				alertpanel_error("%s", msg);
			}
			warned_error = TRUE;
		} else {
			log_error(LOG_PROTOCOL, "%s\n", msg);
		}
	}
	
	return FALSE;
}
Esempio n. 24
0
static int winfs_open(struct mount_point *mp, const char *pathname, int flags, int internal_flags, int mode, struct file **fp, char *target, int buflen)
{
	/* TODO: mode */
	DWORD desired_access, create_disposition;
	HANDLE handle;

	if (flags & O_PATH)
		desired_access = 0;
	else if (flags & O_RDWR)
		desired_access = GENERIC_READ | GENERIC_WRITE;
	else if (flags & O_WRONLY)
		desired_access = GENERIC_WRITE;
	else
		desired_access = GENERIC_READ;
	if (internal_flags & INTERNAL_O_DELETE)
		desired_access |= DELETE;
	if (flags & O_EXCL)
		create_disposition = FILE_CREATE;
	else if (flags & O_CREAT)
		create_disposition = FILE_OPEN_IF;
	else
		create_disposition = FILE_OPEN;
	DWORD attributes;
	if (internal_flags & INTERNAL_O_SPECIAL)
		attributes = FILE_ATTRIBUTE_SYSTEM;
	else
		attributes = FILE_ATTRIBUTE_NORMAL;
	char drive_letter;
	BOOL bInherit = TRUE;
	if (fp == NULL || (internal_flags & INTERNAL_O_NOINHERIT))
		bInherit = FALSE;
	int r = open_file(&handle, mp, pathname, desired_access, create_disposition, attributes, flags, bInherit, target, buflen, &drive_letter);
	if (r < 0 || r == 1)
		return r;
	if ((flags & O_TRUNC) && ((flags & O_WRONLY) || (flags & O_RDWR)))
	{
		/* Truncate the file */
		FILE_END_OF_FILE_INFORMATION info;
		info.EndOfFile.QuadPart = 0;
		IO_STATUS_BLOCK status_block;
		NTSTATUS status = NtSetInformationFile(handle, &status_block, &info, sizeof(info), FileEndOfFileInformation);
		if (!NT_SUCCESS(status))
			log_error("NtSetInformationFile() failed, status: %x", status);
	}

	if (fp)
	{
		int pathlen = strlen(pathname);
		struct winfs_file *file = (struct winfs_file *)kmalloc(sizeof(struct winfs_file));
		file_init(&file->base_file, &winfs_ops, flags);
		file->handle = handle;
		SECURITY_ATTRIBUTES attr;
		attr.nLength = sizeof(SECURITY_ATTRIBUTES);
		attr.bInheritHandle = TRUE;
		attr.lpSecurityDescriptor = NULL;
		/* TODO: Don't need this mutex for directory or symlink */
		file->fp_mutex = CreateMutexW(&attr, FALSE, NULL);
		file->restart_scan = 1;
		file->mp_key = mp->key;
		file->drive_letter = drive_letter;
		if (internal_flags & INTERNAL_O_TMP)
		{
			FILE_DISPOSITION_INFORMATION info;
			IO_STATUS_BLOCK status_block;
			info.DeleteFile = TRUE;
			NTSTATUS status;
			status = NtSetInformationFile(handle, &status_block, &info, sizeof(info), FileDispositionInformation);
			if (!NT_SUCCESS(status))
			{
				log_warning("NtSetInformation(FileDispositionInformation) failed, status: %x", status);
				return -L_EBUSY;
			}
		}
		*fp = (struct file *)file;
	}
	else
		NtClose(handle);
	return 0;
}
Esempio n. 25
0
int read_borders(gamedata *data)
{
    struct storage *store = data->store;
    for (;;) {
        int bid = 0;
        char zText[32];
        region *from, *to;
        border_type *type;

        READ_TOK(store, zText, sizeof(zText));
        if (!strcmp(zText, "end"))
            break;
        READ_INT(store, &bid);
        if (data->version < UIDHASH_VERSION) {
            int fx, fy, tx, ty;
            READ_INT(store, &fx);
            READ_INT(store, &fy);
            READ_INT(store, &tx);
            READ_INT(store, &ty);
            from = findregion(fx, fy);
            to = findregion(tx, ty);
        }
        else {
            int fid, tid;
            READ_INT(store, &fid);
            READ_INT(store, &tid);
            from = findregionbyid(fid);
            to = findregionbyid(tid);
            if (!to || !from) {
                log_warning("%s connection between incomplete regions %d and %d", zText, fid, tid);
                continue;
            }
        }

        type = find_bordertype(zText);
        if (type == NULL) {
            log_error("[read_borders] unknown connection type '%s' in %s\n", zText, regionname(from, NULL));
            assert(type || !"connection type not registered");
        }

        if (to == from && type && from) {
            direction_t dir = (direction_t)(rng_int() % MAXDIRECTIONS);
            region *r = rconnect(from, dir);
            log_error("[read_borders] invalid %s in %s\n", type->__name, regionname(from, NULL));
            if (r != NULL)
                to = r;
        }
        if ((type->read && !type->write)) {
            log_warning("ignore invalid border '%s' between '%s' and '%s'\n", zText, regionname(from, 0), regionname(to, 0));
        }
        else {
            connection *b = new_border(type, from, to);
            nextborder--;               /* new_border erhöht den Wert */
            b->id = bid;
            assert(bid <= nextborder);
            if (type->read) {
                type->read(b, data);
            }
            if (data->version < NOBORDERATTRIBS_VERSION) {
                attrib *a = NULL;
                int result = read_attribs(data, &a, b);
                if (border_convert_cb) {
                    border_convert_cb(b, a);
                }
                while (a) {
                    a_remove(&a, a);
                }
                if (result < 0) {
                    return result;
                }
            }
        }
    }
    return 0;
}
Esempio n. 26
0
static int winfs_getdents(struct file *f, void *dirent, size_t count, getdents_callback *fill_callback)
{
	AcquireSRWLockShared(&f->rw_lock);
	NTSTATUS status;
	struct winfs_file *winfile = (struct winfs_file *) f;
	IO_STATUS_BLOCK status_block;
	#define BUFFER_SIZE	32768
	char buffer[BUFFER_SIZE];
	int size = 0;

	for (;;)
	{
		/* sizeof(FILE_ID_FULL_DIR_INFORMATION) is larger than both sizeof(struct dirent) and sizeof(struct dirent64)
		 * So we don't need to worry about header size.
		 * For the file name, in worst case, a UTF-16 character (2 bytes) requires 4 bytes to store */
		int buffer_size = (count - size) / 2;
		if (buffer_size >= BUFFER_SIZE)
			buffer_size = BUFFER_SIZE;
		status = NtQueryDirectoryFile(winfile->handle, NULL, NULL, NULL, &status_block, buffer, buffer_size, FileIdFullDirectoryInformation, FALSE, NULL, winfile->restart_scan);
		winfile->restart_scan = 0;
		if (!NT_SUCCESS(status))
		{
			if (status != STATUS_NO_MORE_FILES)
				log_error("NtQueryDirectoryFile() failed, status: %x", status);
			break;
		}
		if (status_block.Information == 0)
			break;
		int offset = 0;
		FILE_ID_FULL_DIR_INFORMATION *info;
		do
		{
			info = (FILE_ID_FULL_DIR_INFORMATION *) &buffer[offset];
			offset += info->NextEntryOffset;
			void *p = (char *)dirent + size;
			//uint64_t inode = info->FileId.QuadPart;
			/* Hash 64 bit inode to 32 bit to fix legacy applications
			 * We may later add an option for changing this behaviour
			 */
			uint64_t inode = info->FileId.HighPart ^ info->FileId.LowPart;
			char type = DT_REG;
			if (info->FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
				type = DT_DIR;
			else if (info->FileAttributes & FILE_ATTRIBUTE_SYSTEM)
			{
				/* Test if it is a symlink */
				UNICODE_STRING pathname;
				pathname.Length = info->FileNameLength;
				pathname.MaximumLength = info->FileNameLength;
				pathname.Buffer = info->FileName;

				NTSTATUS status;
				IO_STATUS_BLOCK status_block;
				OBJECT_ATTRIBUTES attr;
				attr.Length = sizeof(OBJECT_ATTRIBUTES);
				attr.RootDirectory = winfile->handle;
				attr.ObjectName = &pathname;
				attr.Attributes = 0;
				attr.SecurityDescriptor = NULL;
				attr.SecurityQualityOfService = NULL;
				HANDLE handle;
				status = NtCreateFile(&handle, SYNCHRONIZE | FILE_READ_DATA, &attr, &status_block, NULL,
					FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN,
					FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
				if (NT_SUCCESS(status))
				{
					int type = winfs_get_special_file_type(handle);
					if (type == SPECIAL_FILE_SYMLINK)
						type = DT_LNK;
					else if (type == SPECIAL_FILE_SOCKET)
						type = DT_SOCK;
					NtClose(handle);
				}
				else
					log_warning("NtCreateFile() failed, status: %x", status);
			}
			intptr_t reclen = fill_callback(p, inode, info->FileName, info->FileNameLength / 2, type, count - size, GETDENTS_UTF16);
			if (reclen < 0)
			{
				size = reclen;
				goto out;
			}
			size += reclen;
		} while (info->NextEntryOffset);
	}
out:
	ReleaseSRWLockShared(&f->rw_lock);
	return size;
	#undef BUFFER_SIZE
}
Esempio n. 27
0
static int lusb_stream(void *driver, struct bladerf_stream *stream,
                       bladerf_module module)
{
    size_t i;
    int status = 0;
    void *buffer;
    struct bladerf_metadata metadata;
    struct bladerf *dev = stream->dev;
    struct bladerf_lusb *lusb = (struct bladerf_lusb *) driver;
    struct lusb_stream_data *stream_data = stream->backend_data;
    struct timeval tv = { 0, LIBUSB_HANDLE_EVENTS_TIMEOUT_NSEC };

    /* Currently unused, so zero it out for a sanity check when debugging */
    memset(&metadata, 0, sizeof(metadata));

    MUTEX_LOCK(&stream->lock);

    /* Set up initial set of buffers */
    for (i = 0; i < stream_data->num_transfers; i++) {
        if (module == BLADERF_MODULE_TX) {
            buffer = stream->cb(dev,
                                stream,
                                &metadata,
                                NULL,
                                stream->samples_per_buffer,
                                stream->user_data);

            if (buffer == BLADERF_STREAM_SHUTDOWN) {
                /* If we have transfers in flight and the user prematurely
                 * cancels the stream, we'll start shutting down */
                if (stream_data->num_avail != stream_data->num_transfers) {
                    stream->state = STREAM_SHUTTING_DOWN;
                } else {
                    /* No transfers have been shipped out yet so we can
                     * simply enter our "done" state */
                    stream->state = STREAM_DONE;
                }

                /* In either of the above we don't want to attempt to
                 * get any more buffers from the user */
                break;
            }
        } else {
            buffer = stream->buffers[i];
        }

        if (buffer != BLADERF_STREAM_NO_DATA) {
            status = submit_transfer(stream, buffer);

            /* If we failed to submit any transfers, cancel everything in
             * flight.  We'll leave the stream in the running state so we can
             * have libusb fire off callbacks with the cancelled status*/
            if (status < 0) {
                stream->error_code = status;
                cancel_all_transfers(stream);
            }
        }
    }
    MUTEX_UNLOCK(&stream->lock);

    /* This loop is required so libusb can do callbacks and whatnot */
    while (stream->state != STREAM_DONE) {
        status = libusb_handle_events_timeout(lusb->context, &tv);

        if (status < 0 && status != LIBUSB_ERROR_INTERRUPTED) {
            log_warning("unexpected value from events processing: "
                        "%d: %s\n", status, libusb_error_name(status));
            status = error_conv(status);
        }
    }

    return status;
}
static int builtin_keyboard(struct udev_device *dev, int argc, char *argv[], bool test) {
        struct udev_list_entry *entry;
        unsigned release[1024];
        unsigned release_count = 0;
        _cleanup_close_ int fd = -1;
        const char *node;

        node = udev_device_get_devnode(dev);
        if (!node) {
                log_error("No device node for \"%s\"", udev_device_get_syspath(dev));
                return EXIT_FAILURE;
        }

        udev_list_entry_foreach(entry, udev_device_get_properties_list_entry(dev)) {
                const char *key;
                char *endptr;

                key = udev_list_entry_get_name(entry);
                if (startswith(key, "KEYBOARD_KEY_")) {
                        const char *keycode;
                        unsigned scancode;

                        /* KEYBOARD_KEY_<hex scan code>=<key identifier string> */
                        scancode = strtoul(key + 13, &endptr, 16);
                        if (endptr[0] != '\0') {
                                log_warning("Unable to parse scan code from \"%s\"", key);
                                continue;
                        }

                        keycode = udev_list_entry_get_value(entry);

                        /* a leading '!' needs a force-release entry */
                        if (keycode[0] == '!') {
                                keycode++;

                                release[release_count] = scancode;
                                if (release_count <  ELEMENTSOF(release)-1)
                                        release_count++;

                                if (keycode[0] == '\0')
                                        continue;
                        }

                        if (fd == -1) {
                                fd = open_device(node);
                                if (fd < 0)
                                        return EXIT_FAILURE;
                        }

                        map_keycode(fd, node, scancode, keycode);
                } else if (startswith(key, "EVDEV_ABS_")) {
                        unsigned evcode;

                        /* EVDEV_ABS_<EV_ABS code>=<min>:<max>:<res>:<fuzz>:<flat> */
                        evcode = strtoul(key + 10, &endptr, 16);
                        if (endptr[0] != '\0') {
                                log_warning("Unable to parse EV_ABS code from \"%s\"", key);
                                continue;
                        }

                        if (fd == -1) {
                                fd = open_device(node);
                                if (fd < 0)
                                        return EXIT_FAILURE;
                        }

                        override_abs(fd, node, evcode, udev_list_entry_get_value(entry));
                } else if (streq(key, "POINTINGSTICK_SENSITIVITY")) {
                        set_trackpoint_sensitivity(dev, udev_list_entry_get_value(entry));
                }
        }

        /* install list of force-release codes */
        if (release_count > 0)
                install_force_release(dev, release, release_count);

        return EXIT_SUCCESS;
}
Esempio n. 29
0
int main(int argc, char *argv[]) {
        const char *cmdline[9];
        int i = 0, r = EXIT_FAILURE, q;
        pid_t pid;
        siginfo_t status;
        _cleanup_udev_unref_ struct udev *udev = NULL;
        _cleanup_udev_device_unref_ struct udev_device *udev_device = NULL;
        const char *device;
        bool root_directory;
        int progress_pipe[2] = { -1, -1 };
        char dash_c[2+10+1];

        if (argc > 2) {
                log_error("This program expects one or no arguments.");
                return EXIT_FAILURE;
        }

        log_set_target(LOG_TARGET_AUTO);
        log_parse_environment();
        log_open();

        umask(0022);

        parse_proc_cmdline();
        test_files();

        if (!arg_force && arg_skip)
                return 0;

        if (argc > 1) {
                device = argv[1];
                root_directory = false;
        } else {
                struct stat st;
                struct timespec times[2];

                /* Find root device */

                if (stat("/", &st) < 0) {
                        log_error("Failed to stat() the root directory: %m");
                        goto finish;
                }

                /* Virtual root devices don't need an fsck */
                if (major(st.st_dev) == 0)
                        return 0;

                /* check if we are already writable */
                times[0] = st.st_atim;
                times[1] = st.st_mtim;
                if (utimensat(AT_FDCWD, "/", times, 0) == 0) {
                        log_info("Root directory is writable, skipping check.");
                        return 0;
                }

                if (!(udev = udev_new())) {
                        log_oom();
                        goto finish;
                }

                if (!(udev_device = udev_device_new_from_devnum(udev, 'b', st.st_dev))) {
                        log_error("Failed to detect root device.");
                        goto finish;
                }

                if (!(device = udev_device_get_devnode(udev_device))) {
                        log_error("Failed to detect device node of root directory.");
                        goto finish;
                }

                root_directory = true;
        }

        if (arg_show_progress)
                if (pipe(progress_pipe) < 0) {
                        log_error("pipe(): %m");
                        goto finish;
                }

        cmdline[i++] = "/sbin/fsck";
        cmdline[i++] = "-a";
        cmdline[i++] = "-T";
        cmdline[i++] = "-l";

        if (!root_directory)
                cmdline[i++] = "-M";

        if (arg_force)
                cmdline[i++] = "-f";

        if (progress_pipe[1] >= 0) {
                snprintf(dash_c, sizeof(dash_c), "-C%i", progress_pipe[1]);
                char_array_0(dash_c);
                cmdline[i++] = dash_c;
        }

        cmdline[i++] = device;
        cmdline[i++] = NULL;

        pid = fork();
        if (pid < 0) {
                log_error("fork(): %m");
                goto finish;
        } else if (pid == 0) {
                /* Child */
                if (progress_pipe[0] >= 0)
                        close_nointr_nofail(progress_pipe[0]);
                execv(cmdline[0], (char**) cmdline);
                _exit(8); /* Operational error */
        }

        if (progress_pipe[1] >= 0) {
                close_nointr_nofail(progress_pipe[1]);
                progress_pipe[1] = -1;
        }

        if (progress_pipe[0] >= 0) {
                process_progress(progress_pipe[0]);
                progress_pipe[0] = -1;
        }

        q = wait_for_terminate(pid, &status);
        if (q < 0) {
                log_error("waitid(): %s", strerror(-q));
                goto finish;
        }

        if (status.si_code != CLD_EXITED || (status.si_status & ~1)) {

                if (status.si_code == CLD_KILLED || status.si_code == CLD_DUMPED)
                        log_error("fsck terminated by signal %s.", signal_to_string(status.si_status));
                else if (status.si_code == CLD_EXITED)
                        log_error("fsck failed with error code %i.", status.si_status);
                else
                        log_error("fsck failed due to unknown reason.");

                if (status.si_code == CLD_EXITED && (status.si_status & 2) && root_directory)
                        /* System should be rebooted. */
                        start_target(SPECIAL_REBOOT_TARGET);
                else if (status.si_code == CLD_EXITED && (status.si_status & 6))
                        /* Some other problem */
                        start_target(SPECIAL_EMERGENCY_TARGET);
                else {
                        r = EXIT_SUCCESS;
                        log_warning("Ignoring error.");
                }

        } else
                r = EXIT_SUCCESS;

        if (status.si_code == CLD_EXITED && (status.si_status & 1))
                touch("/run/systemd/quotacheck");

finish:
        close_pipe(progress_pipe);

        return r;
}
Esempio n. 30
0
int main(int argc, char *argv[]) {
        int cmd, r;
        unsigned retries;
        bool need_umount = true, need_swapoff = true, need_loop_detach = true, need_dm_detach = true;
        bool killed_everbody = false, in_container;

        log_parse_environment();
        log_set_target(LOG_TARGET_CONSOLE); /* syslog will die if not gone yet */
        log_open();

        if (getpid() != 1) {
                log_error("Not executed by init (pid 1).");
                r = -EPERM;
                goto error;
        }

        if (argc != 2) {
                log_error("Invalid number of arguments.");
                r = -EINVAL;
                goto error;
        }

        in_container = detect_container(NULL) > 0;

        if (streq(argv[1], "reboot"))
                cmd = RB_AUTOBOOT;
        else if (streq(argv[1], "poweroff"))
                cmd = RB_POWER_OFF;
        else if (streq(argv[1], "halt"))
                cmd = RB_HALT_SYSTEM;
        else if (streq(argv[1], "kexec"))
                cmd = LINUX_REBOOT_CMD_KEXEC;
        else {
                log_error("Unknown action '%s'.", argv[1]);
                r = -EINVAL;
                goto error;
        }

        /* lock us into memory */
        if (mlockall(MCL_CURRENT|MCL_FUTURE) != 0)
                log_warning("Cannot lock process memory: %m");

        log_info("Sending SIGTERM to remaining processes...");
        send_signal(SIGTERM);

        log_info("Sending SIGKILL to remaining processes...");
        send_signal(SIGKILL);

        if (in_container)
                need_swapoff = false;

        /* Unmount all mountpoints, swaps, and loopback devices */
        for (retries = 0; retries < FINALIZE_ATTEMPTS; retries++) {
                bool changed = false;

                if (need_umount) {
                        log_info("Unmounting file systems.");
                        r = umount_all(&changed);
                        if (r == 0)
                                need_umount = false;
                        else if (r > 0)
                                log_info("Not all file systems unmounted, %d left.", r);
                        else
                                log_error("Failed to unmount file systems: %s", strerror(-r));
                }

                if (need_swapoff) {
                        log_info("Disabling swaps.");
                        r = swapoff_all(&changed);
                        if (r == 0)
                                need_swapoff = false;
                        else if (r > 0)
                                log_info("Not all swaps are turned off, %d left.", r);
                        else
                                log_error("Failed to turn off swaps: %s", strerror(-r));
                }

                if (need_loop_detach) {
                        log_info("Detaching loop devices.");
                        r = loopback_detach_all(&changed);
                        if (r == 0)
                                need_loop_detach = false;
                        else if (r > 0)
                                log_info("Not all loop devices detached, %d left.", r);
                        else
                                log_error("Failed to detach loop devices: %s", strerror(-r));
                }

                if (need_dm_detach) {
                        log_info("Detaching DM devices.");
                        r = dm_detach_all(&changed);
                        if (r == 0)
                                need_dm_detach = false;
                        else if (r > 0)
                                log_warning("Not all DM devices detached, %d left.", r);
                        else
                                log_error("Failed to detach DM devices: %s", strerror(-r));
                }

                if (!need_umount && !need_swapoff && !need_loop_detach && !need_dm_detach)
                        /* Yay, done */
                        break;

                /* If in this iteration we didn't manage to
                 * unmount/deactivate anything, we either kill more
                 * processes, or simply give up */
                if (!changed) {

                        if (killed_everbody) {
                                /* Hmm, we already killed everybody,
                                 * let's just give up */
                                log_error("Cannot finalize remaining file systems and devices, giving up.");
                                break;
                        }

                        log_warning("Cannot finalize remaining file systems and devices, trying to kill remaining processes.");
                        ultimate_send_signal(SIGTERM);
                        ultimate_send_signal(SIGKILL);
                        killed_everbody = true;
                }

                log_debug("Couldn't finalize remaining file systems and devices after %u retries, trying again.", retries+1);
        }

        if (retries >= FINALIZE_ATTEMPTS)
                log_error("Too many iterations, giving up.");

        execute_directory(SYSTEM_SHUTDOWN_PATH, NULL, NULL);

        /* If we are in a container, just exit, this will kill our
         * container for good. */
        if (in_container) {
                log_error("Exiting container.");
                exit(0);
        }

        sync();

        if (cmd == LINUX_REBOOT_CMD_KEXEC) {
                /* We cheat and exec kexec to avoid doing all its work */
                pid_t pid = fork();

                if (pid < 0)
                        log_error("Could not fork: %m. Falling back to normal reboot.");
                else if (pid > 0) {
                        wait_for_terminate_and_warn("kexec", pid);
                        log_warning("kexec failed. Falling back to normal reboot.");
                } else {
                        /* Child */
                        const char *args[3] = { "/sbin/kexec", "-e", NULL };
                        execv(args[0], (char * const *) args);
                        return EXIT_FAILURE;
                }

                cmd = RB_AUTOBOOT;
        }

        reboot(cmd);
        log_error("Failed to invoke reboot(): %m");
        r = -errno;

  error:
        log_error("Critical error while doing system shutdown: %s", strerror(-r));

        freeze();
        return EXIT_FAILURE;
}