Exemple #1
0
double ChainStatisticsOptimizerState::
get_correlation_time()const {
  double sum=0;
  int n=0;
  for (unsigned int i=0; i< positions_.size(); ++i) {
    double last=0;
    for (unsigned int j=i+1; j < positions_.size(); ++j) {
      algebra::Transformation3D tr
          =algebra::get_transformation_aligning_first_to_second(positions_[i],
                                                                positions_[j]);
      algebra::Rotation3D rel = tr.get_rotation();
      double angle=algebra::get_axis_and_angle(rel).second;
      if (angle >1) {
        sum+=get_period()*(j-i-1 + (angle-last)) *get_dt();
        ++n;
        break;
      }
      last=angle;
    }
  }
  std::cout << n << " events" << std::endl;

  if (n==0) {
    return std::numeric_limits<double>::infinity();
  }
  return sum/n;
}
Exemple #2
0
static inline void apply_freqmod(uint8_t chn)
/*
  SQ1/2/TRI: Applies calculated frequency modulations by converting them to 
  period compensated period modulations. 

  NOISE: Applies envelope modulation and LFOs directly to period
*/
{
  // Convert frequency delta to a period delta and add to the base period
  uint16_t period = 0;
  if (chn <= CHN_TRI) 
    period = get_period(chn, apply_dc(portamento_cs[chn], dc_temp[chn]));
	
  switch (chn) {
  case CHN_SQ1:
    sq1.period = period;
    break;
  case CHN_SQ2:
    sq2.period = period;
    break;
  case CHN_TRI:
    tri.period = period;
    break;
  case CHN_NOISE:
    noise.period = noise_period;
  }
}
Exemple #3
0
    bool Pong::init()
    {
        m_ping_subscription = new SRTX::Subscription<topic::Ping_msg_t>(
            topic::ping_topic, get_period());
        if((NULL == m_ping_subscription) ||
           (false == m_ping_subscription->is_valid())) {
            return false;
        }

        m_pong_publication = new SRTX::Publication<topic::Pong_msg_t>(
            topic::pong_topic, get_period());
        if((NULL == m_pong_publication) ||
           (false == m_pong_publication->is_valid())) {
            return false;
        }

        /* Set an initial value in the published content.
         */
        m_pong_publication->content.count = 0;
        m_pong_publication->put();

        return true;
    }
Exemple #4
0
double ChainStatisticsOptimizerState::get_diffusion_coefficient() const {
  if (positions_.empty()) return 0;
  algebra::Vector3Ds positions(positions_.size());
  for (unsigned int i=0; i< positions_.size(); ++i) {
    positions[i]= std::accumulate(positions_[i].begin(), positions_[i].end(),
                           algebra::get_zero_vector_d<3>())
        /positions_[i].size();
  }
  algebra::Vector3Ds
    displacements(positions.size()-1);
  for (unsigned int i=1; i< positions_.size(); ++i) {
    displacements[i-1]= positions[i] -positions[i-1];
  }
  return atom::get_diffusion_coefficient(displacements,
                                         get_period()*get_dt());
}
Exemple #5
0
/**
 * The main function.
 */
int main()
{
    /* Seeding random number generator */
    srand( time(NULL) );

    int my_pid = getpid();
    unsigned int period = get_period();
    unsigned int computation_time = get_comp_time(period);

    register_process(my_pid, period, computation_time);

    if(!is_registered(my_pid))
    {
        printf("%d: I was unable to register.  ;_;\n", my_pid);
        exit(1);
    }
    printf("%d: Registered! \n", my_pid);

    unsigned int iterations = get_iterations();
    yield(my_pid);

    while(iterations > 0)
    {
        struct timeval time;
        gettimeofday(&time);
        unsigned int start_time = time.tv_usec;

        unsigned int time_elapsed = 0;
        while(time_elapsed < computation_time)
        {
            int i;
            for(i = 0; i < 100; i++)
            {
                factorial((i % 20)+1);
            }
            gettimeofday(&time);
            time_elapsed = time.tv_usec - start_time;
        }

        yield(my_pid);
        iterations--;
    }

    unregister(my_pid);
    return 0;
}
Exemple #6
0
Floats ChainStatisticsOptimizerState::get_diffusion_coefficients() const {
  if (positions_.empty()) return Floats();
  base::Vector<algebra::Vector3Ds >
    displacements(positions_[0].size(),
                  algebra::Vector3Ds( positions_.size()-1));
  for (unsigned int i=1; i< positions_.size(); ++i) {
    algebra::Transformation3D rel
        = algebra::get_transformation_aligning_first_to_second(positions_[i-1],
                                                               positions_[i]);
    for (unsigned int j=0; j < positions_[i].size(); ++j) {
      displacements[j][i-1]= rel.get_transformed(positions_[i-1][j])
        - positions_[i][j];
    }
  }
  Floats ret;
  for (unsigned int i=0; i < displacements.size(); ++i) {
    ret.push_back(atom::get_diffusion_coefficient(displacements[i],
                                                  get_period()*get_dt()));
  }
  return ret;
}
Exemple #7
0
        bool execute()
        {
            units::Nanoseconds period = get_period();

            ++counter[m_instance];
            DPRINTF("Running task %d with period %lld\n", m_instance,
                    (int64_t)period);

            /* If this is a aperiodic task (period is 0), sleep for a
             * second.
             */
            if(0 == period)
            {
                sleep(units::Nanoseconds(1 * units::SEC));
                if(--m_run_count <= 0)
                {
                    return false;
                }
            }

            return true;
        }
Exemple #8
0
  static void
  run(float tempo,
      const Control::time_signature& sig,
      ossia::value_port& res,
      ossia::token_request tk,
      ossia::exec_state_facade st)
  {
    if (tk.date > tk.prev_date)
    {
      if (tk.prev_date == 0)
      {
        res.write_value(1, tk.tick_start());
      }

      const auto period
          = get_period(1. / sig.second, (double)tempo, st.sampleRate());
      const auto next = next_date(tk.prev_date, period);
      if (next.impl < tk.date.impl)
      {
        if (sig == Control::time_signature{3, 4})
        {
          ossia::timed_value t;
          if (next.impl == 0 || (next.impl % (3 * period)) == 0)
            res.write_value(1, tk.to_tick_time(next));
          else
            res.write_value(0, tk.to_tick_time(next));
        }
        else if (sig == Control::time_signature{4, 4})
        {
          ossia::timed_value t;
          if (next.impl == 0 || next.impl % (2 * period) == 0)
            res.write_value(1, tk.to_tick_time(next));
          else
            res.write_value(0, tk.to_tick_time(next));
        }
      }
    }
  }
Exemple #9
0
 void Scheduler::terminate()
 {
     if(m_use_external_clock)
     {
         /* If we're set to use an external trigger, we need to generate the
          * necessary triggers internally to wind down all of the tasks to
          * allow for a clean exit.
          */
         const units::Nanoseconds s_period = get_period();
         while(sched_unwind_tics)
         {
             usleep(s_period / 1000);
             trigger();
         }
     }
     else
     {
         this->lock();
         m_sched_impl->sync.condition_satisfied();
         m_sched_impl->sync.release();
         this->unlock();
     }
 }
Exemple #10
0
uint32_t PWM_Sysfs_Base::get_freq()
{
    return nsec_to_hz(get_period());
}
 // returns if it was able to process
bool CPPlayer::process_note_and_instrument(int p_track,int p_note,int p_instrument) {

	bool aux_result;
	aux_result=false;
	CPSample *aux_sample=0; // current sample
	int dest_sample_index;
	bool new_instrument=false;

	control.channel[p_track].row_has_note=false; // wise man says.. "we dont have a note... until we really know we have a note".
	control.channel[p_track].new_instrument=false;

	if ( (p_note<0) && (p_instrument<0) ) return aux_result; // nothing to do here
	if ( (p_note==255) && (p_instrument==255) ) return aux_result;

	if ( (p_note>=0) && (p_note<120) ) {

		process_new_note(p_track,p_note);

	} else if (p_note==CPNote::CUT) {
	
		control.channel[p_track].aux_volume=0;
		control.channel[p_track].note_end_flags|=END_NOTE_OFF;
		control.channel[p_track].note_end_flags|=END_NOTE_KILL;
		return aux_result;

	} else if ((p_note==CPNote::OFF) && (song->has_instruments())) {

		if (control.channel[p_track].instrument_ptr!=NULL) {
			
			control.channel[p_track].note_end_flags|=END_NOTE_OFF;

			if (!control.channel[p_track].instrument_ptr->get_volume_envelope()->is_enabled() || control.channel[p_track].instrument_ptr->get_volume_envelope()->is_loop_enabled()) {

				control.channel[p_track].note_end_flags|=END_NOTE_FADE;
			}
        	}

		return aux_result;
	} else return aux_result; // invalid note!


	if ( (p_instrument>=0) && (p_instrument<CPSong::MAX_INSTRUMENTS)) {
		new_instrument=process_new_instrument(p_track,p_instrument);
	
		if ( song->has_instruments() ) {
			// If we're in instrument mode...
			if ( control.channel[p_track].instrument_ptr->get_sample_number(control.channel[p_track].real_note) >= CPSong::MAX_SAMPLES) {
	
				control.channel[p_track].kick=KICK_NOTHING;
				return aux_result;
	
			} else {
				dest_sample_index=control.channel[p_track].instrument_ptr->get_sample_number(control.channel[p_track].real_note);
				control.channel[p_track].note=control.channel[p_track].instrument_ptr->get_note_number(control.channel[p_track].real_note);
			}
	
		} else {
			// If we're in sample mode...
			dest_sample_index=control.channel[p_track].instrument_index;
				control.channel[p_track].note=control.channel[p_track].real_note;
		}
	
		control.channel[p_track].sample_index=dest_sample_index;
		aux_sample=song->get_sample(dest_sample_index);
		
		if (!CPSampleManager::get_singleton()->check( aux_sample->get_sample_data() )) {
			/* INVALID SAMPLE */
			control.channel[p_track].kick=KICK_NOTHING;
			return aux_result;
			
		}
		
		aux_sample=song->get_sample(dest_sample_index);
	} else {
		
		
		if (!control.channel[p_track].sample_ptr)
			return aux_result;
		
		if (song->has_instruments()) {
			
			if (!control.channel[p_track].instrument_ptr)
				return aux_result;
			
			control.channel[p_track].note=control.channel[p_track].instrument_ptr->get_note_number(control.channel[p_track].real_note);
			
		} else {
						
			control.channel[p_track].note=control.channel[p_track].real_note;
			
		}
		
		aux_sample=control.channel[p_track].sample_ptr;
		
	}

	
	
	if (p_instrument>=CPSong::MAX_INSTRUMENTS && control.channel[p_track].sample_ptr!=aux_sample) {

		control.channel[p_track].new_instrument=(control.channel[p_track].period>0);
	}

	control.channel[p_track].sample_ptr=aux_sample;

	/* channel or instrument determined panning ? */

	control.channel[p_track].panning=control.channel[p_track].channel_panning;

	/* set filter,if any ? */	
	

	if (aux_sample->is_pan_enabled()) {
				
		control.channel[p_track].panning=(int)aux_sample->get_pan()*255/64;

	} else if ( song->has_instruments() && (control.channel[p_track].instrument_ptr->is_pan_default_enabled()) ) {

		control.channel[p_track].panning=(int)control.channel[p_track].instrument_ptr->get_pan_default_amount()*255/64;
	}


	if (song->has_instruments()) {

		
                /* Pitch-Pan Separation */
		if ((control.channel[p_track].instrument_ptr->get_pan_pitch_separation()!=0) && (control.channel[p_track].channel_panning!=PAN_SURROUND)){

			control.channel[p_track].panning+=((control.channel[p_track].real_note-control.channel[p_track].instrument_ptr->get_pan_pitch_center())*control.channel[p_track].instrument_ptr->get_pan_pitch_separation())/8;

			if (control.channel[p_track].panning<PAN_LEFT) control.channel[p_track].panning=PAN_LEFT;
			if (control.channel[p_track].panning>PAN_RIGHT) control.channel[p_track].panning=PAN_RIGHT;
		}

		/* Random Volume Variation */
		if (control.channel[p_track].instrument_ptr->get_volume_random_variation()>0) {

			control.channel[p_track].random_volume_variation=100-(cp_random_generate(&control.random_seed) % control.channel[p_track].instrument_ptr->get_volume_random_variation());

		} else {

			control.channel[p_track].random_volume_variation=100;
		}


		/* Random Pan Variation */
		if ((control.channel[p_track].instrument_ptr->get_pan_random_variation()>0) && (control.channel[p_track].panning!=PAN_SURROUND)){

			int aux_pan_modifier;

			aux_pan_modifier=(cp_random_generate(&control.random_seed) % (control.channel[p_track].instrument_ptr->get_pan_random_variation() << 2));
			if ((cp_random_generate(&control.random_seed) % 2)==1) aux_pan_modifier=0-aux_pan_modifier; /* it's 5am, let me sleep :) */

			control.channel[p_track].panning+=aux_pan_modifier;

			if (control.channel[p_track].panning<PAN_LEFT) control.channel[p_track].panning=PAN_LEFT;
			if (control.channel[p_track].panning>PAN_RIGHT) control.channel[p_track].panning=PAN_RIGHT;
			

		}

		/*filter*/
		
		if (control.channel[p_track].instrument_ptr->filter_use_default_cutoff()) {
		
			control.channel[p_track].filter.it_cutoff=control.channel[p_track].instrument_ptr->get_filter_default_cutoff()*2;
		
		}
		
		if (control.channel[p_track].instrument_ptr->filter_use_default_resonance()) {
		
			control.channel[p_track].filter.it_reso=control.channel[p_track].instrument_ptr->get_filter_default_resonance()*2;
		
		}
		
		/*envelopes*/
		
		
		control.channel[p_track].volume_envelope_on=control.channel[p_track].instrument_ptr->get_volume_envelope()->is_enabled();
		control.channel[p_track].panning_envelope_on=control.channel[p_track].instrument_ptr->get_pan_envelope()->is_enabled();
		control.channel[p_track].pitch_envelope_on=control.channel[p_track].instrument_ptr->get_pitch_filter_envelope()->is_enabled();
		control.channel[p_track].NNA_type=control.channel[p_track].instrument_ptr->get_NNA_type();
		control.channel[p_track].duplicate_check_type=control.channel[p_track].instrument_ptr->get_DC_type();
		control.channel[p_track].duplicate_check_action=control.channel[p_track].instrument_ptr->get_DC_action();


	} else {

		control.channel[p_track].NNA_type=CPInstrument::NNA_NOTE_CUT;
		control.channel[p_track].duplicate_check_type=CPInstrument::DCT_DISABLED;
		control.channel[p_track].duplicate_check_action=CPInstrument::DCA_NOTE_CUT;
	}


	if (p_instrument<CPSong::MAX_INSTRUMENTS) { // instrument change
		
		control.channel[p_track].volume=control.channel[p_track].aux_volume=aux_sample->get_default_volume();

	}


	control.channel[p_track].slide_to_period=control.channel[p_track].aux_period=get_period((uint16_t)(control.channel[p_track].note)<<1,CPSampleManager::get_singleton()->get_c5_freq( (aux_sample->get_sample_data())));

	control.channel[p_track].note_end_flags=END_NOTE_NOTHING; /* clears flags */

	return true;
}
Exemple #12
0
/* This driver uses INST_IO links,
 * the string has to be of the format
 *
 *      @PLC tag flags
 *
 * count: number of array elements to read (only != 1 for waveform record)
 * bits: if >0 indicates that we want binary data,
 *       then it's the number of bits
 */
static long analyze_link(dbCommon *rec,
                         EIPCallback cbtype,
                         const DBLINK *link,
                         size_t count,
                         size_t bits)
{
    DevicePrivate  *pvt = (DevicePrivate *)rec->dpvt;
    char           *p, *end;
    size_t         i, tag_len, last_element, bit=0;
    unsigned long  mask;
    double         period = 0.0;
    eip_bool       single_element = false;
    SpecialOptions special = 0;
    
    if (! EIP_strdup(&pvt->link_text, link->value.instio.string,
                     strlen (link->value.instio.string)))
    {
        errlogPrintf("devEtherIP (%s): Cannot copy link\n", rec->name);
        return S_dev_noMemory;
    }
    /* Find PLC */
    p = find_token(pvt->link_text, &end);
    if (! p)
    {
        errlogPrintf("devEtherIP (%s): Missing PLC in link '%s'\n",
                     rec->name, pvt->link_text);
        return S_db_badField;
    }
    if (! EIP_strdup(&pvt->PLC_name, p, end-p))
    {
        errlogPrintf("devEtherIP (%s): Cannot copy PLC\n", rec->name);
        return S_dev_noMemory;
    }

    /* Find Tag */
    p = find_token(end, &end);
    if (! p)
    {
        errlogPrintf("devEtherIP (%s): Missing tag in link '%s'\n",
                     rec->name, pvt->link_text);
        return(S_db_badField);
    }
    tag_len = end-p;
    if (! EIP_strdup(&pvt->string_tag, p, tag_len))
    {
        errlogPrintf("devEtherIP (%s): Cannot copy tag\n", rec->name);
        return S_dev_noMemory;
    }
    
    /* Check for more flags */
    while ((p = find_token(end, &end)))
    {
        for (i=0, mask=1;
             mask < SPCO_INVALID;
             ++i, mask=mask<<1)
        {
            if (strncmp(p,
                        special_options[i].text,
                        special_options[i].len) == 0)
            {
                special |= mask;
                if (mask==SPCO_READ_SINGLE_ELEMENT)
                {
                    if (count != 1)
                    {
                        errlogPrintf("devEtherIP (%s): "
                                     "Array record cannot use 'E' flag "
                                     "('%s')\n",
                                     rec->name, pvt->link_text);
                        return S_db_badField;
                    }
                    single_element = true;
                }
                else if (mask==SPCO_SCAN_PERIOD)
                {
                    period = strtod(p+2, &end);
                    if (end==p || period==HUGE_VAL || period==-HUGE_VAL)
                    {
                        errlogPrintf("devEtherIP (%s): "
                                     "Error in scan flag in link '%s'\n",
                                     rec->name, pvt->link_text);
                        return S_db_badField;
                    }
                }
                else if (mask==SPCO_BIT)
                {
                    bit = strtod(p+2, &end);
                    if (end==p || period==HUGE_VAL || period==-HUGE_VAL)
                    {
                        errlogPrintf("devEtherIP (%s): "
                                     "Error in bit flag in link '%s'\n",
                                     rec->name, pvt->link_text);
                        return S_db_badField;
                    }
                }
                break;
            }
        }
        if (mask >= SPCO_INVALID)
        {
            errlogPrintf("devEtherIP (%s): Invalid flag '%s' in link '%s'\n",
                         rec->name, p, pvt->link_text);
            return S_db_badField;
        }
    }
    
    pvt->special = special;
    if (period <= 0.0) /* no scan flag-> get SCAN field: */
    {
        period = get_period(rec);
        if (period <= 0)
            period = drvEtherIP_default_rate;
        if (period <= 0)
        {
            errlogPrintf("devEtherIP (%s): cannot decode SCAN field,"
                         " no scan flag given\n", rec->name);
            period = 1.0; /* default scan rate */
            errlogPrintf("Device support will use the default of %g secs, ",
                         period);
            errlogPrintf("please complete the record configuration\n");
        }
    }
    
    /* Parsed link_text into PLC_name, string_tag, special flags.
     * Analyse further */
    pvt->element = 0;
    p = &pvt->string_tag[tag_len-1];
    if (*p == ']') /* array tag? */
    {
        if (! single_element)
        {   /* Cut "array_tag[el]" into "array_tag" + el */
            while (p > pvt->string_tag)
                if (*(--p) == '[')
                    break;
            if (p <= pvt->string_tag)
            {
                errlogPrintf("devEtherIP (%s): malformed array tag in '%s'\n",
                             rec->name, pvt->link_text);
                return S_db_badField;
            }
            /* read element number */
            pvt->element = strtol(p+1, &end, 0);
            if (end==p+1 || pvt->element==LONG_MAX || pvt->element==LONG_MIN)
            {
                errlogPrintf("devEtherIP (%s): malformed array tag in '%s'\n",
                             rec->name, pvt->link_text);
                return S_db_badField;
            }
            /* remove element number text from tag */
            *p = '\0';
        }
    }

    pvt->plc = drvEtherIP_find_PLC(pvt->PLC_name);
    if (! pvt->plc)
    {
        errlogPrintf("devEtherIP (%s): unknown PLC '%s'\n",
                     rec->name, pvt->PLC_name);
        return S_db_badField;
    }

    if (count > 1 && (bits > 0  || (special & SPCO_BIT)))
    {
        errlogPrintf("devEtherIP (%s): cannot access bits for array records\n",
                     rec->name);
        return S_db_badField;
    }
    /* For Element==0 the following makes no difference, only
     * for binary records (bits=1 or more)
     * Options:
     * a) assume BOOL array (default)
     * b) non-BOOL, SPCO_BIT selected a bit in INT, DINT, ...
     */
    if (bits>0 && !(special & SPCO_BIT))
    {
        /* For element>0, assume that it's a BOOL array,
         * so the data is packed into UDINTs (CIP "BITS").
         * The actual element requested is the UDINT index,
         * not the bit#.
         * Pick the bits within the UDINT via the mask. */
        pvt->mask = 1U << (pvt->element & 0x1F); /* 0x1F == 31 */
        last_element = pvt->element + bits - 1;
        pvt->element >>= 5;
        last_element >>= 5;
    }
Exemple #13
0
int cafe_mainX(int ac,const char *av[],FILE *out,FILE *log)
{	const char *arg;
	int ai;
	int period;
	CStr(cwd,1024);
	const char *Root = 0;
	IStr(Rtop,1024);
	const char *tops[1024]; /**/
	const char *top;
	int topx,tx;
	int cacheonly = 0,wonly = 0;
	CStr(ls_optsb,128);
	CStr(args,64*1024);
	refQStr(ap,args); /**/
	const char *ax = &args[sizeof(args)-1];
	const char *pp;
	int fnot = 0;

	minit_icache();

	topx = 0;
	LOG = out;

	if( ac == 1 ){
		put_usage(LOG,av[0]);
		exit(0);
	}

	NOW = time(0);

	for( ai = 1; ai < ac; ai++ ){
		arg = av[ai];
		pp = ap;
		ap = catarg1(args,AVStr(ap),arg);
		if( ax <= ap ){
			break;
		}

		if( strncmp(arg,"-root=",6) == 0 ){
			Root = arg+6;
		}else
		if( strcmp(arg,"-not") == 0 ){
			fnot = ai+1;
		}else
		if( strcmp(arg,"-ign") == 0 ){
			++ai;
			ap = (char*)pp;
		}else
		if( strcmp(arg,"-log") == 0 || strcmp(arg,"-err") == 0 ){
			if( ++ai < ac ){
				LOG = setlog(av[ai]);
				ap = (char*)pp;
			}
		}else
		if( strcmp(arg,"-utime") == 0 ){
			F_UATIME = 1;
		}else
		if( strcmp(arg,"-atime") == 0 ){
			if( ++ai < ac ){
				ap = catarg1(args,AVStr(ap),av[ai]);
				period = get_period(av[ai]);
				if( period < 0 )
					A_FROM = NOW + period;
				else	A_TILL = NOW - period;
			}
		}else
		if( strcmp(arg,"-mtime") == 0 ){
			if( ++ai < ac ){
				ap = catarg1(args,AVStr(ap),av[ai]);
				period = get_period(av[ai]);
				if( period < 0 )
					M_FROM = NOW + period;
				else	M_TILL = NOW - period;
			}
		}else
		if( strcmp(arg,"-asize") == 0 ){
			if( ++ai < ac ){
				ap = catarg1(args,AVStr(ap),av[ai]);
				REM_SIZE = atoi(av[ai]);
			}
		}else
		if( strcmp(arg,"-name") == 0 ){
			if( ++ai < ac ){
				F_NAME_NOT = (fnot == ai-1);
				F_NAME = av[ai];
			}
		}else
		if( strcmp(arg,"-type") == 0 ){
			if( ++ai < ac ){
				F_TYPE = av[ai];
			}
		}else
		if( strncmp(arg,"-ls",3) == 0 ){
			F_LSFORM = 1;
			if( arg[3] == 0 )
				strcpy(ls_optsb,"dl");
			else	sprintf(ls_optsb,"d%s",&arg[3]);
			ls_opts = ls_optsb;
		}else
		if( strncmp(arg,"-du",3) == 0 ){
			F_DU = 1;
			if( strchr(&arg[3],'s') == 0 )
				F_DIR = 1;
			if( strchr(&arg[3],'a') != 0 )
				F_PRINT = 1;
		}else
		if( strcmp(arg,"-s") == 0 ){
			F_DIR = 0;
		}else
		if( strncmp(arg,"-ic",3) == 0
		 || strncmp(arg,"-iw",3) == 0
		 || strncmp(arg,"-ir",3) == 0
		){
			if( arg[3] )
				icachedir = &arg[3];
			else	icachedir = "/tmp/cafe";
			if( strncmp(arg,"-ir",3) == 0 )
				cacheonly = 1;
			if( strncmp(arg,"-iw",3) == 0 )
				wonly = 1;
		}else
		if( strncmp(arg,"-mv",3) == 0 ){
			F_MOVE = 1;
		}else
		if( strcmp(arg,"-h") == 0 ){ F_FOLLOW_SYMLINK = 1; }else
		if( strcmp(arg,"-m") == 0 ){ F_FOLLOW_MOUNT = 1; }else
		if( strcmp(arg,"-v") == 0 ){ F_VERBOSE = 1; }else
		if( strcmp(arg,"-a") == 0 ){ /* ignore */ }else
		if( strncmp(arg,"-p",2) == 0 ){ F_PRINT = 1; }else
		if( strcmp(arg,"-sum") == 0 ){ F_SUMMARY = 1; }else
		if( strcmp(arg,"-rm") == 0 ){ F_REMOVE = 1; }else
		if( arg[0] == '-' ){
			if( atoi(&arg[1]) )
				N_LIST = atoi(&arg[1]);
		}else{
			if( elnumof(tops)-2 <= topx ){
				continue;
			}
			tops[topx++] = arg;
			tops[topx] = 0;
			ap = (char*)pp;
		}
	}
	XsetVStrEnd(AVStr(ap),0);

	if( topx == 0 ){
		tops[topx++] = ".";
		tops[topx] = 0;
	}

	if( !F_PRINT && !F_LSFORM && !F_DU && !F_SUMMARY ){
		F_DU = 1;
	}

	if( icachedir != NULL && !fileIsdir(icachedir) ){
		if( mkdir(icachedir,0755) != 0 ){
			errlog("%s: can't make inode cache directory: %s\n",
				av[0],icachedir);
			exit(1);
		}
	}

	IGNRETS getcwd(cwd,sizeof(cwd));
	CWD = cwd;

	for( tx = 0; tx < topx; tx++ ){
		top = tops[tx];
		if( Root ){
			IStr(tmp,1024);
			strcpy(tmp,"");
			chdir_cwd(AVStr(tmp),top,0);
			strcpy(Rtop,Root);
			if( *tmp == '/' )
				ovstrcpy(tmp,tmp+1);
			if( *tmp ){
				if( strtailchr(Rtop) != '/' )
					strcat(Rtop,"/");
				strcat(Rtop,tmp);
			}
			top = Rtop;
		}

		if( LOG != stdout )
		if( LOG != out )
		errlog("%s %s\n",top,args);

		if( !icachedir || !cacheonly )
			find0(LOG,Root,top);
			/*
			find0(LOG,top);
			*/

		if( icachedir != NULL )
		if( !wonly )
			find_icache(LOG,top,N_LIST);

		if( F_SUMMARY )
			summary(LOG,top);
	}

	if( LOG != out )
	fclose(LOG);
	return 0;
}
Exemple #14
0
/* Run continual mode loop
   This is the main loop of the continual mode which keeps track of the
   current time and continuously updates the screen to the appropriate
   color temperature. */
static int
run_continual_mode(const location_t *loc,
		   const transition_scheme_t *scheme,
		   const gamma_method_t *method,
		   gamma_state_t *state,
		   int transition, int verbose)
{
	int r;

	/* Make an initial transition from 6500K */
	int short_trans_delta = -1;
	int short_trans_len = 10;

	/* Amount of adjustment to apply. At zero the color
	   temperature will be exactly as calculated, and at one it
	   will be exactly 6500K. */
	double adjustment_alpha = 1.0;

#if defined(HAVE_SIGNAL_H) && !defined(__WIN32__)
	struct sigaction sigact;
	sigset_t sigset;
	sigemptyset(&sigset);

	/* Install signal handler for INT and TERM signals */
	sigact.sa_handler = sigexit;
	sigact.sa_mask = sigset;
	sigact.sa_flags = 0;

	r = sigaction(SIGINT, &sigact, NULL);
	if (r < 0) {
		perror("sigaction");
		return -1;
	}

	r = sigaction(SIGTERM, &sigact, NULL);
	if (r < 0) {
		perror("sigaction");
		return -1;
	}

	/* Install signal handler for USR1 signal */
	sigact.sa_handler = sigdisable;
	sigact.sa_mask = sigset;
	sigact.sa_flags = 0;

	r = sigaction(SIGUSR1, &sigact, NULL);
	if (r < 0) {
		perror("sigaction");
		return -1;
	}

	/* Ignore CHLD signal. This causes child processes
	   (hooks) to be reaped automatically. */
	sigact.sa_handler = SIG_IGN;
	sigact.sa_mask = sigset;
	sigact.sa_flags = 0;

	r = sigaction(SIGCHLD, &sigact, NULL);
	if (r < 0) {
		perror("sigaction");
		return -1;
	}
#endif /* HAVE_SIGNAL_H && ! __WIN32__ */

	if (verbose) {
		printf(_("Status: %s\n"), _("Enabled"));
	}

	/* Save previous colors so we can avoid
	   printing status updates if the values
	   did not change. */
	period_t prev_period = PERIOD_NONE;
	color_setting_t prev_interp =
		{ -1, { NAN, NAN, NAN }, NAN };

	/* Continuously adjust color temperature */
	int done = 0;
	int disabled = 0;
	while (1) {
		/* Check to see if disable signal was caught */
		if (disable) {
			short_trans_len = 2;
			if (!disabled) {
				/* Transition to disabled state */
				short_trans_delta = 1;
			} else {
				/* Transition back to enabled */
				short_trans_delta = -1;
			}
			disabled = !disabled;
			disable = 0;

			if (verbose) {
				printf(_("Status: %s\n"), disabled ?
				       _("Disabled") : _("Enabled"));
			}
		}

		/* Check to see if exit signal was caught */
		if (exiting) {
			if (done) {
				/* On second signal stop the ongoing
				   transition */
				short_trans_delta = 0;
				adjustment_alpha = 0.0;
			} else {
				if (!disabled) {
					/* Make a short transition
					   back to 6500K */
					short_trans_delta = 1;
					short_trans_len = 2;
				}

				done = 1;
			}
			exiting = 0;
		}

		/* Read timestamp */
		double now;
		r = systemtime_get_time(&now);
		if (r < 0) {
			fputs(_("Unable to read system time.\n"), stderr);
			return -1;
		}

		/* Skip over transition if transitions are disabled */
		int set_adjustments = 0;
		if (!transition) {
			if (short_trans_delta) {
				adjustment_alpha = short_trans_delta < 0 ?
					0.0 : 1.0;
				short_trans_delta = 0;
				set_adjustments = 1;
			}
		}

		/* Current angular elevation of the sun */
		double elevation = solar_elevation(now, loc->lat,
						   loc->lon);

		/* Use elevation of sun to set color temperature */
		color_setting_t interp;
		interpolate_color_settings(scheme, elevation, &interp);

		/* Print period if it changed during this update,
		   or if we are in transition. In transition we
		   print the progress, so we always print it in
		   that case. */
		period_t period = get_period(scheme, elevation);
		if (verbose && (period != prev_period ||
				period == PERIOD_TRANSITION)) {
			double transition =
				get_transition_progress(scheme,
							elevation);
			print_period(period, transition);
		}

		/* Activate hooks if period changed */
		if (period != prev_period) {
			hooks_signal_period_change(prev_period, period);
		}

		/* Ongoing short transition */
		if (short_trans_delta) {
			/* Calculate alpha */
			adjustment_alpha += short_trans_delta * 0.1 /
				(float)short_trans_len;

			/* Stop transition when done */
			if (adjustment_alpha <= 0.0 ||
			    adjustment_alpha >= 1.0) {
				short_trans_delta = 0;
			}

			/* Clamp alpha value */
			adjustment_alpha = CLAMP(0.0, adjustment_alpha, 1.0);
		}

		/* Interpolate between 6500K and calculated
		   temperature */
		interp.temperature = adjustment_alpha*6500 +
			(1.0-adjustment_alpha)*interp.temperature;

		interp.brightness = adjustment_alpha*1.0 +
			(1.0-adjustment_alpha)*interp.brightness;

		/* Quit loop when done */
		if (done && !short_trans_delta) break;

		if (verbose) {
			if (interp.temperature !=
			    prev_interp.temperature) {
				printf(_("Color temperature: %uK\n"),
				       interp.temperature);
			}
			if (interp.brightness !=
			    prev_interp.brightness) {
				printf(_("Brightness: %.2f\n"),
				       interp.brightness);
			}
		}

		/* Adjust temperature */
		if (!disabled || short_trans_delta || set_adjustments) {
			r = method->set_temperature(state, &interp);
			if (r < 0) {
				fputs(_("Temperature adjustment"
					" failed.\n"), stderr);
				return -1;
			}
		}

		/* Save temperature as previous */
		prev_period = period;
		memcpy(&prev_interp, &interp,
		       sizeof(color_setting_t));

		/* Sleep for 5 seconds or 0.1 second. */
		if (short_trans_delta) {
			systemtime_msleep(SLEEP_DURATION_SHORT);
		} else {
			systemtime_msleep(SLEEP_DURATION);
		}
	}

	/* Restore saved gamma ramps */
	method->restore(state);

	return 0;
}
Exemple #15
0
int
main(int argc, char *argv[])
{
	int r;

#ifdef ENABLE_NLS
	/* Init locale */
	setlocale(LC_CTYPE, "");
	setlocale(LC_MESSAGES, "");

	/* Internationalisation */
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);
#endif

	/* Initialize settings to NULL values. */
	char *config_filepath = NULL;

	/* Settings for day, night and transition.
	   Initialized to indicate that the values are not set yet. */
	transition_scheme_t scheme =
		{ TRANSITION_HIGH, TRANSITION_LOW };

	scheme.day.temperature = -1;
	scheme.day.gamma[0] = NAN;
	scheme.day.brightness = NAN;

	scheme.night.temperature = -1;
	scheme.night.gamma[0] = NAN;
	scheme.night.brightness = NAN;

	/* Temperature for manual mode */
	int temp_set = -1;

	const gamma_method_t *method = NULL;
	char *method_args = NULL;

	const location_provider_t *provider = NULL;
	char *provider_args = NULL;

	int transition = -1;
	program_mode_t mode = PROGRAM_MODE_CONTINUAL;
	int verbose = 0;
	char *s;

	/* Flush messages consistently even if redirected to a pipe or
	   file.  Change the flush behaviour to line-buffered, without
	   changing the actual buffers being used. */
	setvbuf(stdout, NULL, _IOLBF, 0);
	setvbuf(stderr, NULL, _IOLBF, 0);

	/* Parse command line arguments. */
	int opt;
	while ((opt = getopt(argc, argv, "b:c:g:hl:m:oO:prt:vVx")) != -1) {
		switch (opt) {
		case 'b':
			parse_brightness_string(optarg,
						&scheme.day.brightness,
						&scheme.night.brightness);
			break;
		case 'c':
			free(config_filepath);
			config_filepath = strdup(optarg);
			break;
		case 'g':
			r = parse_gamma_string(optarg, scheme.day.gamma);
			if (r < 0) {
				fputs(_("Malformed gamma argument.\n"),
				      stderr);
				fputs(_("Try `-h' for more"
					" information.\n"), stderr);
				exit(EXIT_FAILURE);
			}

			/* Set night gamma to the same value as day gamma.
			   To set these to distinct values use the config
			   file. */
			memcpy(scheme.night.gamma, scheme.day.gamma,
			       sizeof(scheme.night.gamma));
			break;
		case 'h':
			print_help(argv[0]);
			exit(EXIT_SUCCESS);
			break;
		case 'l':
			/* Print list of providers if argument is `list' */
			if (strcasecmp(optarg, "list") == 0) {
				print_provider_list();
				exit(EXIT_SUCCESS);
			}

			char *provider_name = NULL;

			/* Don't save the result of strtof(); we simply want
			   to know if optarg can be parsed as a float. */
			errno = 0;
			char *end;
			strtof(optarg, &end);
			if (errno == 0 && *end == ':') {
				/* Use instead as arguments to `manual'. */
				provider_name = "manual";
				provider_args = optarg;
			} else {
				/* Split off provider arguments. */
				s = strchr(optarg, ':');
				if (s != NULL) {
					*(s++) = '\0';
					provider_args = s;
				}

				provider_name = optarg;
			}

			/* Lookup provider from name. */
			provider = find_location_provider(provider_name);
			if (provider == NULL) {
				fprintf(stderr, _("Unknown location provider"
						  " `%s'.\n"), provider_name);
				exit(EXIT_FAILURE);
			}

			/* Print provider help if arg is `help'. */
			if (provider_args != NULL &&
			    strcasecmp(provider_args, "help") == 0) {
				provider->print_help(stdout);
				exit(EXIT_SUCCESS);
			}
			break;
		case 'm':
			/* Print list of methods if argument is `list' */
			if (strcasecmp(optarg, "list") == 0) {
				print_method_list();
				exit(EXIT_SUCCESS);
			}

			/* Split off method arguments. */
			s = strchr(optarg, ':');
			if (s != NULL) {
				*(s++) = '\0';
				method_args = s;
			}

			/* Find adjustment method by name. */
			method = find_gamma_method(optarg);
			if (method == NULL) {
				/* TRANSLATORS: This refers to the method
				   used to adjust colors e.g VidMode */
				fprintf(stderr, _("Unknown adjustment method"
						  " `%s'.\n"), optarg);
				exit(EXIT_FAILURE);
			}

			/* Print method help if arg is `help'. */
			if (method_args != NULL &&
			    strcasecmp(method_args, "help") == 0) {
				method->print_help(stdout);
				exit(EXIT_SUCCESS);
			}
			break;
		case 'o':
			mode = PROGRAM_MODE_ONE_SHOT;
			break;
		case 'O':
			mode = PROGRAM_MODE_MANUAL;
			temp_set = atoi(optarg);
			break;
		case 'p':
			mode = PROGRAM_MODE_PRINT;
			break;
		case 'r':
			transition = 0;
			break;
		case 't':
			s = strchr(optarg, ':');
			if (s == NULL) {
				fputs(_("Malformed temperature argument.\n"),
				      stderr);
				fputs(_("Try `-h' for more information.\n"),
				      stderr);
				exit(EXIT_FAILURE);
			}
			*(s++) = '\0';
			scheme.day.temperature = atoi(optarg);
			scheme.night.temperature = atoi(s);
			break;
		case 'v':
			verbose = 1;
			break;
                case 'V':
                        printf("%s\n", PACKAGE_STRING);
                        exit(EXIT_SUCCESS);
                        break;
		case 'x':
			mode = PROGRAM_MODE_RESET;
			break;
		case '?':
			fputs(_("Try `-h' for more information.\n"), stderr);
			exit(EXIT_FAILURE);
			break;
		}
	}

	/* Load settings from config file. */
	config_ini_state_t config_state;
	r = config_ini_init(&config_state, config_filepath);
	if (r < 0) {
		fputs("Unable to load config file.\n", stderr);
		exit(EXIT_FAILURE);
	}

	free(config_filepath);

	/* Read global config settings. */
	config_ini_section_t *section = config_ini_get_section(&config_state,
							       "redshift");
	if (section != NULL) {
		config_ini_setting_t *setting = section->settings;
		while (setting != NULL) {
			if (strcasecmp(setting->name, "temp-day") == 0) {
				if (scheme.day.temperature < 0) {
					scheme.day.temperature =
						atoi(setting->value);
				}
			} else if (strcasecmp(setting->name,
					      "temp-night") == 0) {
				if (scheme.night.temperature < 0) {
					scheme.night.temperature =
						atoi(setting->value);
				}
			} else if (strcasecmp(setting->name,
					      "transition") == 0) {
				if (transition < 0) {
					transition = !!atoi(setting->value);
				}
			} else if (strcasecmp(setting->name,
					      "brightness") == 0) {
				if (isnan(scheme.day.brightness)) {
					scheme.day.brightness =
						atof(setting->value);
				}
				if (isnan(scheme.night.brightness)) {
					scheme.night.brightness =
						atof(setting->value);
				}
			} else if (strcasecmp(setting->name,
					      "brightness-day") == 0) {
				if (isnan(scheme.day.brightness)) {
					scheme.day.brightness =
						atof(setting->value);
				}
			} else if (strcasecmp(setting->name,
					      "brightness-night") == 0) {
				if (isnan(scheme.night.brightness)) {
					scheme.night.brightness =
						atof(setting->value);
				}
			} else if (strcasecmp(setting->name,
					      "elevation-high") == 0) {
				scheme.high = atof(setting->value);
			} else if (strcasecmp(setting->name,
					      "elevation-low") == 0) {
				scheme.low = atof(setting->value);
			} else if (strcasecmp(setting->name, "gamma") == 0) {
				if (isnan(scheme.day.gamma[0])) {
					r = parse_gamma_string(setting->value,
							       scheme.day.gamma);
					if (r < 0) {
						fputs(_("Malformed gamma"
							" setting.\n"),
						      stderr);
						exit(EXIT_FAILURE);
					}
					memcpy(scheme.night.gamma, scheme.day.gamma,
					       sizeof(scheme.night.gamma));
				}
			} else if (strcasecmp(setting->name, "gamma-day") == 0) {
				if (isnan(scheme.day.gamma[0])) {
					r = parse_gamma_string(setting->value,
							       scheme.day.gamma);
					if (r < 0) {
						fputs(_("Malformed gamma"
							" setting.\n"),
						      stderr);
						exit(EXIT_FAILURE);
					}
				}
			} else if (strcasecmp(setting->name, "gamma-night") == 0) {
				if (isnan(scheme.night.gamma[0])) {
					r = parse_gamma_string(setting->value,
							       scheme.night.gamma);
					if (r < 0) {
						fputs(_("Malformed gamma"
							" setting.\n"),
						      stderr);
						exit(EXIT_FAILURE);
					}
				}
			} else if (strcasecmp(setting->name,
					      "adjustment-method") == 0) {
				if (method == NULL) {
					method = find_gamma_method(
						setting->value);
					if (method == NULL) {
						fprintf(stderr, _("Unknown"
								  " adjustment"
								  " method"
								  " `%s'.\n"),
							setting->value);
						exit(EXIT_FAILURE);
					}
				}
			} else if (strcasecmp(setting->name,
					      "location-provider") == 0) {
				if (provider == NULL) {
					provider = find_location_provider(
						setting->value);
					if (provider == NULL) {
						fprintf(stderr, _("Unknown"
								  " location"
								  " provider"
								  " `%s'.\n"),
							setting->value);
						exit(EXIT_FAILURE);
					}
				}
			} else {
				fprintf(stderr, _("Unknown configuration"
						  " setting `%s'.\n"),
					setting->name);
			}
			setting = setting->next;
		}
	}

	/* Use default values for settings that were neither defined in
	   the config file nor on the command line. */
	if (scheme.day.temperature < 0) {
		scheme.day.temperature = DEFAULT_DAY_TEMP;
	}
	if (scheme.night.temperature < 0) {
		scheme.night.temperature = DEFAULT_NIGHT_TEMP;
	}

	if (isnan(scheme.day.brightness)) {
		scheme.day.brightness = DEFAULT_BRIGHTNESS;
	}
	if (isnan(scheme.night.brightness)) {
		scheme.night.brightness = DEFAULT_BRIGHTNESS;
	}

	if (isnan(scheme.day.gamma[0])) {
		scheme.day.gamma[0] = DEFAULT_GAMMA;
		scheme.day.gamma[1] = DEFAULT_GAMMA;
		scheme.day.gamma[2] = DEFAULT_GAMMA;
	}
	if (isnan(scheme.night.gamma[0])) {
		scheme.night.gamma[0] = DEFAULT_GAMMA;
		scheme.night.gamma[1] = DEFAULT_GAMMA;
		scheme.night.gamma[2] = DEFAULT_GAMMA;
	}

	if (transition < 0) transition = 1;

	location_t loc = { NAN, NAN };

	/* Initialize location provider. If provider is NULL
	   try all providers until one that works is found. */
	location_state_t location_state;

	/* Location is not needed for reset mode and manual mode. */
	if (mode != PROGRAM_MODE_RESET &&
	    mode != PROGRAM_MODE_MANUAL) {
		if (provider != NULL) {
			/* Use provider specified on command line. */
			r = provider_try_start(provider, &location_state,
					       &config_state, provider_args);
			if (r < 0) exit(EXIT_FAILURE);
		} else {
			/* Try all providers, use the first that works. */
			for (int i = 0;
			     location_providers[i].name != NULL; i++) {
				const location_provider_t *p =
					&location_providers[i];
				fprintf(stderr,
					_("Trying location provider `%s'...\n"),
					p->name);
				r = provider_try_start(p, &location_state,
						       &config_state, NULL);
				if (r < 0) {
					fputs(_("Trying next provider...\n"),
					      stderr);
					continue;
				}

				/* Found provider that works. */
				printf(_("Using provider `%s'.\n"), p->name);
				provider = p;
				break;
			}

			/* Failure if no providers were successful at this
			   point. */
			if (provider == NULL) {
				fputs(_("No more location providers"
					" to try.\n"), stderr);
				exit(EXIT_FAILURE);
			}
		}

		/* Get current location. */
		r = provider->get_location(&location_state, &loc);
		if (r < 0) {
		        fputs(_("Unable to get location from provider.\n"),
		              stderr);
		        exit(EXIT_FAILURE);
		}
	
		provider->free(&location_state);
	
		if (verbose) {
			print_location(&loc);

			printf(_("Temperatures: %dK at day, %dK at night\n"),
			       scheme.day.temperature,
			       scheme.night.temperature);

		        /* TRANSLATORS: Append degree symbols if possible. */
			printf(_("Solar elevations: day above %.1f, night below %.1f\n"),
			       scheme.high, scheme.low);
		}

		/* Latitude */
		if (loc.lat < MIN_LAT || loc.lat > MAX_LAT) {
		        /* TRANSLATORS: Append degree symbols if possible. */
		        fprintf(stderr,
		                _("Latitude must be between %.1f and %.1f.\n"),
		                MIN_LAT, MAX_LAT);
		        exit(EXIT_FAILURE);
		}
	
		/* Longitude */
		if (loc.lon < MIN_LON || loc.lon > MAX_LON) {
		        /* TRANSLATORS: Append degree symbols if possible. */
		        fprintf(stderr,
		                _("Longitude must be between"
		                  " %.1f and %.1f.\n"), MIN_LON, MAX_LON);
		        exit(EXIT_FAILURE);
		}

		/* Color temperature */
		if (scheme.day.temperature < MIN_TEMP ||
		    scheme.day.temperature > MAX_TEMP ||
		    scheme.night.temperature < MIN_TEMP ||
		    scheme.night.temperature > MAX_TEMP) {
			fprintf(stderr,
				_("Temperature must be between %uK and %uK.\n"),
				MIN_TEMP, MAX_TEMP);
			exit(EXIT_FAILURE);
		}

		/* Solar elevations */
		if (scheme.high < scheme.low) {
		        fprintf(stderr,
		                _("High transition elevation cannot be lower than"
				  " the low transition elevation.\n"));
		        exit(EXIT_FAILURE);
		}
	}

	if (mode == PROGRAM_MODE_MANUAL) {
		/* Check color temperature to be set */
		if (temp_set < MIN_TEMP || temp_set > MAX_TEMP) {
			fprintf(stderr,
				_("Temperature must be between %uK and %uK.\n"),
				MIN_TEMP, MAX_TEMP);
			exit(EXIT_FAILURE);
		}
	}

	/* Brightness */
	if (scheme.day.brightness < MIN_BRIGHTNESS ||
	    scheme.day.brightness > MAX_BRIGHTNESS ||
	    scheme.night.brightness < MIN_BRIGHTNESS ||
	    scheme.night.brightness > MAX_BRIGHTNESS) {
		fprintf(stderr,
			_("Brightness values must be between %.1f and %.1f.\n"),
			MIN_BRIGHTNESS, MAX_BRIGHTNESS);
		exit(EXIT_FAILURE);
	}

	if (verbose) {
		printf(_("Brightness: %.2f:%.2f\n"),
		       scheme.day.brightness, scheme.night.brightness);
	}

	/* Gamma */
	if (!gamma_is_valid(scheme.day.gamma) ||
	    !gamma_is_valid(scheme.night.gamma)) {
		fprintf(stderr,
			_("Gamma value must be between %.1f and %.1f.\n"),
			MIN_GAMMA, MAX_GAMMA);
		exit(EXIT_FAILURE);
	}

	if (verbose) {
		/* TRANSLATORS: The string in parenthesis is either
		   Daytime or Night (translated). */
		printf(_("Gamma (%s): %.3f, %.3f, %.3f\n"),
		       _("Daytime"), scheme.day.gamma[0],
		       scheme.day.gamma[1], scheme.day.gamma[2]);
		printf(_("Gamma (%s): %.3f, %.3f, %.3f\n"),
		       _("Night"), scheme.night.gamma[0],
		       scheme.night.gamma[1], scheme.night.gamma[2]);
	}

	/* Initialize gamma adjustment method. If method is NULL
	   try all methods until one that works is found. */
	gamma_state_t state;

	/* Gamma adjustment not needed for print mode */
	if (mode != PROGRAM_MODE_PRINT) {
		if (method != NULL) {
			/* Use method specified on command line. */
			r = method_try_start(method, &state, &config_state,
					     method_args);
			if (r < 0) exit(EXIT_FAILURE);
		} else {
			/* Try all methods, use the first that works. */
			for (int i = 0; gamma_methods[i].name != NULL; i++) {
				const gamma_method_t *m = &gamma_methods[i];
				if (!m->autostart) continue;

				r = method_try_start(m, &state, &config_state, NULL);
				if (r < 0) {
					fputs(_("Trying next method...\n"), stderr);
					continue;
				}

				/* Found method that works. */
				printf(_("Using method `%s'.\n"), m->name);
				method = m;
				break;
			}

			/* Failure if no methods were successful at this point. */
			if (method == NULL) {
				fputs(_("No more methods to try.\n"), stderr);
				exit(EXIT_FAILURE);
			}
		}
	}

	config_ini_free(&config_state);

	switch (mode) {
	case PROGRAM_MODE_ONE_SHOT:
	case PROGRAM_MODE_PRINT:
	{
		/* Current angular elevation of the sun */
		double now;
		r = systemtime_get_time(&now);
		if (r < 0) {
			fputs(_("Unable to read system time.\n"), stderr);
			method->free(&state);
			exit(EXIT_FAILURE);
		}

		double elevation = solar_elevation(now, loc.lat, loc.lon);

		if (verbose) {
			/* TRANSLATORS: Append degree symbol if possible. */
			printf(_("Solar elevation: %f\n"), elevation);
		}

		/* Use elevation of sun to set color temperature */
		color_setting_t interp;
		interpolate_color_settings(&scheme, elevation, &interp);

		if (verbose || mode == PROGRAM_MODE_PRINT) {
			period_t period = get_period(&scheme,
						     elevation);
			double transition =
				get_transition_progress(&scheme,
							elevation);
			print_period(period, transition);
			printf(_("Color temperature: %uK\n"),
			       interp.temperature);
			printf(_("Brightness: %.2f\n"),
			       interp.brightness);
		}

		if (mode == PROGRAM_MODE_PRINT) {
			exit(EXIT_SUCCESS);
		}

		/* Adjust temperature */
		r = method->set_temperature(&state, &interp);
		if (r < 0) {
			fputs(_("Temperature adjustment failed.\n"), stderr);
			method->free(&state);
			exit(EXIT_FAILURE);
		}

		/* In Quartz (OSX) the gamma adjustments will automatically
		   revert when the process exits. Therefore, we have to loop
		   until CTRL-C is received. */
		if (strcmp(method->name, "quartz") == 0) {
			fputs(_("Press ctrl-c to stop...\n"), stderr);
			pause();
		}
	}
	break;
	case PROGRAM_MODE_MANUAL:
	{
		if (verbose) printf(_("Color temperature: %uK\n"), temp_set);

		/* Adjust temperature */
		color_setting_t manual;
		memcpy(&manual, &scheme.day, sizeof(color_setting_t));
		manual.temperature = temp_set;
		r = method->set_temperature(&state, &manual);
		if (r < 0) {
			fputs(_("Temperature adjustment failed.\n"), stderr);
			method->free(&state);
			exit(EXIT_FAILURE);
		}

		/* In Quartz (OSX) the gamma adjustments will automatically
		   revert when the process exits. Therefore, we have to loop
		   until CTRL-C is received. */
		if (strcmp(method->name, "quartz") == 0) {
			fputs(_("Press ctrl-c to stop...\n"), stderr);
			pause();
		}
	}
	break;
	case PROGRAM_MODE_RESET:
	{
		/* Reset screen */
		color_setting_t reset = { NEUTRAL_TEMP, { 1.0, 1.0, 1.0 }, 1.0 };
		r = method->set_temperature(&state, &reset);
		if (r < 0) {
			fputs(_("Temperature adjustment failed.\n"), stderr);
			method->free(&state);
			exit(EXIT_FAILURE);
		}

		/* In Quartz (OSX) the gamma adjustments will automatically
		   revert when the process exits. Therefore, we have to loop
		   until CTRL-C is received. */
		if (strcmp(method->name, "quartz") == 0) {
			fputs(_("Press ctrl-c to stop...\n"), stderr);
			pause();
		}
	}
	break;
	case PROGRAM_MODE_CONTINUAL:
	{
		r = run_continual_mode(&loc, &scheme,
				       method, &state,
				       transition, verbose);
		if (r < 0) exit(EXIT_FAILURE);
	}
	break;
	}

	/* Clean up gamma adjustment state */
	method->free(&state);

	return EXIT_SUCCESS;
}
Exemple #16
0
void reload(GLOBAL *g, struct payments_module *p)
{
	QueryHandle *res, *result;
	char *insert, *description, *invoiceid, *value, *taxid, *currtime;
	char *d_period, *w_period, *m_period, *q_period, *y_period, *h_period;
	int i, imonth, imday, today, n=2, k=2, m=2, o=2, pl=0;
	int docid=0, last_cid=0, last_paytype=0, last_plan=0, exec=0, suspended=0, itemid=0;

	time_t t;
	struct tm tt;
	char monthday[3], month[3], year[5], quarterday[4], weekday[2], yearday[4], halfday[4];
	char monthname[20], nextmon[8];

	char *nets = strdup(" AND EXISTS (SELECT 1 FROM nodes, networks n "
				"WHERE ownerid = a.customerid "
				    "AND (%nets) "
	                "AND ((ipaddr > address AND ipaddr < ("BROADCAST")) "
				        "OR (ipaddr_pub > address AND ipaddr_pub < ("BROADCAST"))) )");

	char *netnames = strdup(p->networks);
	char *netname = strdup(netnames);
	char *netsql = strdup("");

	char *enets = strdup(" AND NOT EXISTS (SELECT 1 FROM nodes, networks n "
				"WHERE ownerid = a.customerid "
				    "AND (%enets) "
	                "AND ((ipaddr > address AND ipaddr < ("BROADCAST")) "
				        "OR (ipaddr_pub > address AND ipaddr_pub < ("BROADCAST"))) )");

	char *enetnames = strdup(p->excluded_networks);
	char *enetname = strdup(enetnames);
	char *enetsql = strdup("");

	char *groups = strdup(" AND EXISTS (SELECT 1 FROM customergroups g, customerassignments ca "
				"WHERE ca.customerid = a.customerid "
				    "AND g.id = ca.customergroupid "
				    "AND (%groups)) ");

	char *groupnames = strdup(p->customergroups);
	char *groupname = strdup(groupnames);
	char *groupsql = strdup("");

	char *egroups = strdup(" AND NOT EXISTS (SELECT 1 FROM customergroups g, customerassignments ca "
				"WHERE ca.customerid = a.customerid "
				    "AND g.id = ca.customergroupid "
				    "AND (%egroups)) ");

	char *egroupnames = strdup(p->excluded_customergroups);
	char *egroupname = strdup(egroupnames);
	char *egroupsql = strdup("");

	while( n>1 )
	{
    		n = sscanf(netnames, "%s %[._a-zA-Z0-9- ]", netname, netnames);

		if( strlen(netname) )
		{
			netsql = realloc(netsql, sizeof(char *) * (strlen(netsql) + strlen(netname) + 30));
			if(strlen(netsql))
				strcat(netsql, " OR UPPER(n.name) = UPPER('");
			else
				strcat(netsql, "UPPER(n.name) = UPPER('");

			strcat(netsql, netname);
			strcat(netsql, "')");
		}
	}
	free(netname); free(netnames);

	if(strlen(netsql))
		g->str_replace(&nets, "%nets", netsql);

	while( o>1 )
	{
    		o = sscanf(enetnames, "%s %[._a-zA-Z0-9- ]", enetname, enetnames);

		if( strlen(enetname) )
		{
			enetsql = realloc(enetsql, sizeof(char *) * (strlen(enetsql) + strlen(enetname) + 30));
			if(strlen(enetsql))
				strcat(enetsql, " OR UPPER(n.name) = UPPER('");
			else
				strcat(enetsql, "UPPER(n.name) = UPPER('");

			strcat(enetsql, enetname);
			strcat(enetsql, "')");
		}
	}
	free(enetname); free(enetnames);

	if(strlen(enetsql))
		g->str_replace(&enets, "%enets", enetsql);

	while( k>1 )
	{
		k = sscanf(groupnames, "%s %[._a-zA-Z0-9- ]", groupname, groupnames);

		if( strlen(groupname) )
		{
			groupsql = realloc(groupsql, sizeof(char *) * (strlen(groupsql) + strlen(groupname) + 30));
			if(strlen(groupsql))
				strcat(groupsql, " OR UPPER(g.name) = UPPER('");
			else
				strcat(groupsql, "UPPER(g.name) = UPPER('");

			strcat(groupsql, groupname);
			strcat(groupsql, "')");
		}
	}
	free(groupname); free(groupnames);

	if(strlen(groupsql))
		g->str_replace(&groups, "%groups", groupsql);

	while( m>1 )
	{
		m = sscanf(egroupnames, "%s %[._a-zA-Z0-9- ]", egroupname, egroupnames);

		if( strlen(egroupname) )
		{
			egroupsql = realloc(egroupsql, sizeof(char *) * (strlen(egroupsql) + strlen(egroupname) + 30));
			if(strlen(egroupsql))
				strcat(egroupsql, " OR UPPER(g.name) = UPPER('");
			else
				strcat(egroupsql, "UPPER(g.name) = UPPER('");

			strcat(egroupsql, egroupname);
			strcat(egroupsql, "')");
		}
	}
	free(egroupname); free(egroupnames);

	if(strlen(egroupsql))
		g->str_replace(&egroups, "%egroups", egroupsql);

	// get current date
	t = time(NULL);
	memcpy(&tt, localtime(&t), sizeof(tt));
	strftime(monthday, 	sizeof(monthday), 	"%d", &tt);
	strftime(weekday, 	sizeof(weekday), 	"%u", &tt);
	strftime(monthname, 	sizeof(monthname), 	"%B", &tt);
	strftime(month, 	sizeof(month), 		"%m", &tt);
	strftime(year, 		sizeof(year), 		"%Y", &tt);

	currtime = strdup(itoa(t));
	imday = tt.tm_mday;
	imonth = tt.tm_mon+1;

	// leap year fix
	if(is_leap_year(tt.tm_year+1900) && tt.tm_yday+1 > 31+28)
		strncpy(yearday, itoa(tt.tm_yday), sizeof(yearday));
	else
		strncpy(yearday, itoa(tt.tm_yday+1), sizeof(yearday));

	// halfyear
	if(imonth > 6)
		strncpy(halfday, itoa(imday + (imonth - 7) * 100), sizeof(halfday));
	else
		strncpy(halfday, itoa(imday + (imonth - 1) * 100), sizeof(halfday));

	switch(imonth) {
		case 1:
		case 4:
		case 7:
		case 10:
			sprintf(quarterday, "%d", imday);
			break;
		case 2:
		case 5:
		case 8:
		case 11:
			sprintf(quarterday, "%d", imday+100);
			break;
		default:
			sprintf(quarterday, "%d", imday+200);
			break;
	}

	// next month in YYYY/MM format
	if (imonth == 12)
		snprintf(nextmon, sizeof(nextmon), "%04d/%02d", tt.tm_year+1901, 1);
	else
		snprintf(nextmon, sizeof(nextmon), "%04d/%02d", tt.tm_year+1900, imonth+1);

	// time periods
	y_period = get_period(&tt, YEARLY, p->up_payments);
	h_period = get_period(&tt, HALFYEARLY, p->up_payments);
	q_period = get_period(&tt, QUARTERLY, p->up_payments);
	m_period = get_period(&tt, MONTHLY, p->up_payments);
	w_period = get_period(&tt, WEEKLY, p->up_payments);
	d_period = get_period(&tt, DAILY, p->up_payments);

	// today (for disposable liabilities)
	tt.tm_sec = 0;
	tt.tm_min = 0;
	tt.tm_hour = 0;
	today = mktime(&tt);

	/****** main payments *******/
	if( (res = g->db_pquery(g->conn, "SELECT * FROM payments "
		"WHERE value <> 0 AND (period="_DAILY_" OR (period="_WEEKLY_" AND at=?) "
			"OR (period="_MONTHLY_" AND at=?) "
			"OR (period="_QUARTERLY_" AND at=?) "
			"OR (period="_HALFYEARLY_" AND at=?) "
			"OR (period="_YEARLY_" AND at=?))",
			weekday, monthday, quarterday, halfday, yearday))!= NULL )
	{
		for(i=0; i<g->db_nrows(res); i++) 
		{
			exec = (g->db_pexec(g->conn, "INSERT INTO cash (time, type, value, customerid, comment, docid) "
				"VALUES (?, 1, ? * -1, 0, '? / ?', 0)",
					currtime,
					g->db_get_data(res,i,"value"),
					g->db_get_data(res,i,"name"),
					g->db_get_data(res,i,"creditor")
				) ? 1 : exec);
		}
		g->db_free(&res);
#ifdef DEBUG1
		syslog(LOG_INFO, "DEBUG: [%s/payments] Main payments reloaded", p->base.instance);
#endif
	}
	else 
		syslog(LOG_ERR, "[%s/payments] Unable to read 'payments' table", p->base.instance);

	/****** customer payments *******/
	// let's create main query
	char *query = strdup("SELECT a.tariffid, a.customerid, a.period, t.period AS t_period, "
	    "a.at, a.suspended, a.invoice, a.id AS assignmentid, a.settlement, a.datefrom, a.pdiscount, a.vdiscount, "
		"c.paytype, a.paytype AS a_paytype, a.numberplanid, d.inv_paytype AS d_paytype, "
		"UPPER(c.lastname) AS lastname, c.name AS custname, c.address, c.zip, c.city, c.ten, c.ssn, "
		"c.countryid, c.divisionid, c.paytime, "
		"(CASE a.liabilityid WHEN 0 THEN t.type ELSE -1 END) AS tarifftype, "
		"(CASE a.liabilityid WHEN 0 THEN t.name ELSE li.name END) AS name, "
		"(CASE a.liabilityid WHEN 0 THEN t.taxid ELSE li.taxid END) AS taxid, "
		"(CASE a.liabilityid WHEN 0 THEN t.prodid ELSE li.prodid END) AS prodid, "
		"(CASE a.liabilityid WHEN 0 THEN "
		    "ROUND((t.value - t.value * a.pdiscount / 100) - a.vdiscount, 2) "
			"ELSE ROUND((li.value - li.value * a.pdiscount / 100) - a.vdiscount, 2) "
			"END) AS value "
		"FROM assignments a "
		"JOIN customers c ON (a.customerid = c.id) "
		"LEFT JOIN tariffs t ON (a.tariffid = t.id) "
		"LEFT JOIN liabilities li ON (a.liabilityid = li.id) "
		"LEFT JOIN divisions d ON (d.id = c.divisionid) "
		"WHERE c.status = 3 AND c.deleted = 0 "
		    "AND ("
		        "(a.period="_DISPOSABLE_" AND at=?) "
		        "OR (("
		            "(a.period="_DAILY_") "
			        "OR (a.period="_WEEKLY_" AND at=?) "
			        "OR (a.period="_MONTHLY_" AND at=?) "
			        "OR (a.period="_QUARTERLY_" AND at=?) "
			        "OR (a.period="_HALFYEARLY_" AND at=?) "
			        "OR (a.period="_YEARLY_" AND at=?) "
			        ") "
			        "AND (a.datefrom <= ? OR a.datefrom = 0) "
			        "AND (a.dateto >= ? OR a.dateto = 0)"
			    ")"
			")"
		    "%nets"
		    "%enets"
		    "%groups"
		    "%egroups"
		" ORDER BY a.customerid, a.invoice DESC, a.paytype, a.numberplanid, value DESC");

	g->str_replace(&query, "%nets", strlen(netsql) ? nets : "");
	g->str_replace(&query, "%enets", strlen(enetsql) ? enets : "");
	g->str_replace(&query, "%groups", strlen(groupsql) ? groups : "");
	g->str_replace(&query, "%egroups", strlen(egroupsql) ? egroups : "");

	if( (res = g->db_pquery(g->conn, query,
		itoa(today), weekday, monthday, quarterday, halfday, yearday,  currtime, currtime)) != NULL)
	{
		struct plan *plans = (struct plan *) malloc(sizeof(struct plan));
		int invoice_number = 0;

		if( g->db_nrows(res) )
		{
			if (!p->numberplanid)
			{
				// get numbering plans for all divisions
				result = g->db_query(g->conn, "SELECT n.id, n.period, COALESCE(a.divisionid, 0) AS divid, isdefault "
					"FROM numberplans n "
					"LEFT JOIN numberplanassignments a ON (a.planid = n.id) "
					"WHERE doctype = 1");

				for(i=0; i<g->db_nrows(result); i++) 
				{
					plans = (struct plan *) realloc(plans, (sizeof(struct plan) * (pl+1)));
					plans[pl].plan = atoi(g->db_get_data(result, i, "id"));
					plans[pl].period = atoi(g->db_get_data(result, i, "period"));
					plans[pl].division = atoi(g->db_get_data(result, i, "divid"));
					plans[pl].isdefault = atoi(g->db_get_data(result, i, "isdefault"));
					plans[pl].number = 0;
					pl++;
				}
				g->db_free(&result);
			}
		}
#ifdef DEBUG1
		else
			syslog(LOG_INFO, "DEBUG: [%s/payments] Customer assignments not found", p->base.instance);
#endif
		// payments accounting and invoices writing
		for(i=0; i<g->db_nrows(res); i++)
		{
			char *cid_c         = g->db_get_data(res,i,"customerid");
			char *pdiscount     = g->db_get_data(res,i,"pdiscount");
			char *vdiscount     = g->db_get_data(res,i,"vdiscount");
			int cid             = atoi(cid_c);
			int s_state         = atoi(g->db_get_data(res,i,"suspended"));
			int period          = atoi(g->db_get_data(res,i,"period"));
			int settlement      = atoi(g->db_get_data(res,i,"settlement"));
			int datefrom        = atoi(g->db_get_data(res,i,"datefrom"));
			int t_period        = atoi(g->db_get_data(res,i,"t_period"));
			double val          = atof(g->db_get_data(res,i,"value"));
			int tarifftype_int  = atoi(g->db_get_data(res, i, "tarifftype"));
			char *tarifftype    = (tarifftype_int == -1 ? "" : get_tarifftype_str(p, tarifftype_int));

			if( !val ) continue;

			// assignments suspending check
			if( last_cid != cid )
			{
				result = g->db_pquery(g->conn, "SELECT 1 FROM assignments "
					"WHERE customerid = ? AND tariffid = 0 AND liabilityid = 0 "
					    "AND (datefrom <= ? OR datefrom = 0) AND (dateto >= ? OR dateto = 0)",
					cid_c, currtime, currtime);

				suspended = g->db_nrows(result) ? 1 : 0;
				g->db_free(&result);
			}

			if( suspended || s_state )
				val = val * p->suspension_percentage / 100;

			if( !val ) continue;

			// calculate assignment value according to tariff's period
			if (t_period && period != DISPOSABLE && t_period != period) {
				if (t_period == YEARLY)
					val = val / 12.0;
				else if (t_period == HALFYEARLY)
					val = val / 6.0;
				else if (t_period == QUARTERLY)
					val = val / 3.0;

				if (period == YEARLY)
					val = val * 12.0;
				else if (period == HALFYEARLY)
					val = val * 6.0;
				else if (period == QUARTERLY)
					val = val * 3.0;
				else if (period == WEEKLY)
					val = val / 4.0;
				else if (period == DAILY)
					val = val / 30.0;
			}

			value = ftoa(val);
			taxid = g->db_get_data(res,i,"taxid");

			// prepare insert to 'cash' table
			insert = strdup("INSERT INTO cash (time, value, taxid, customerid, comment, docid, itemid) "
				"VALUES (?, %value * -1, %taxid, %customerid, '?', %docid, %itemid)");
			g->str_replace(&insert, "%customerid", cid_c);
			g->str_replace(&insert, "%value", value);
			g->str_replace(&insert, "%taxid", taxid);

			if( period == DISPOSABLE )
				description = strdup(g->db_get_data(res,i,"name"));
			else
				description = strdup(p->comment);

			switch( period )
			{
				case DAILY: g->str_replace(&description, "%period", d_period); break;
				case WEEKLY: g->str_replace(&description, "%period", w_period); break;
				case MONTHLY: g->str_replace(&description, "%period", m_period); break;
				case QUARTERLY: g->str_replace(&description, "%period", q_period); break;
				case HALFYEARLY: g->str_replace(&description, "%period", h_period); break;
				case YEARLY: g->str_replace(&description, "%period", y_period); break;
			}
			g->str_replace(&description, "%type", tarifftype);
			g->str_replace(&description, "%tariff", g->db_get_data(res,i,"name"));
			g->str_replace(&description, "%next_mon", nextmon);
			g->str_replace(&description, "%month", monthname);
			g->str_replace(&description, "%currentm", month);
			g->str_replace(&description, "%year", year);
			g->str_replace(&description, "%currenty", year);

			if( atoi(g->db_get_data(res,i,"invoice")) )
			{
				char *divisionid = g->db_get_data(res,i,"divisionid");
				int a_numberplan = atoi(g->db_get_data(res,i,"numberplanid"));
				int a_paytype = atoi(g->db_get_data(res,i,"a_paytype")); // assignment
				int c_paytype = atoi(g->db_get_data(res,i,"paytype"));   // customer
				int d_paytype = atoi(g->db_get_data(res,i,"d_paytype")); // division
				int paytype, numberplan, divid = atoi(divisionid);

				// paytype (by priority)
				if (a_paytype)
					paytype = a_paytype;
				else if (c_paytype)
					paytype = c_paytype;
				else if (d_paytype)
					paytype = d_paytype;
				else
					paytype = p->paytype;

				// select numberplan
				if (a_numberplan) {
					for (n=0; n<pl; n++)
						if (plans[n].plan == a_numberplan)
							break;
				} else {
					for (n=0; n<pl; n++)
						if (plans[n].division == divid && plans[n].isdefault)
							break;
				}

				numberplan = (n < pl) ? n : -1;

				if ( last_cid != cid || last_paytype != paytype || last_plan != numberplan)
				{
					char *countryid = g->db_get_data(res,i,"countryid");
					char *numberplanid, *paytime, *paytype_str = strdup(itoa(paytype));
					int period, number = 0;

					last_paytype = paytype;
					last_plan = numberplan;

					// numberplan found
					if (numberplan >= 0)
					{
						numberplanid = strdup(itoa(plans[numberplan].plan));
						period = plans[numberplan].period;
						number = plans[numberplan].number;
					}
					else // not found, use default/shared plan
					{
						numberplanid = strdup(itoa(p->numberplanid));
						period = p->num_period;
						number = invoice_number;
					}

					if(!number)
					{
						char *start = get_num_period_start(&tt, period);
						char *end = get_num_period_end(&tt, period);

						// set invoice number
						result = g->db_pquery(g->conn, "SELECT MAX(number) AS number FROM documents "
							"WHERE cdate >= ? AND cdate < ? AND numberplanid = ? AND type = 1", 
							start, end, numberplanid); 

						if( g->db_nrows(result) )
							number = atoi(g->db_get_data(result,0,"number"));
						g->db_free(&result);
					}

					++number;

					if(n < pl)
					{
						// update number
						for(m=0; m<pl; m++)
							if(plans[m].plan == plans[n].plan)
								plans[m].number = number;
					}
					else
						invoice_number = number;

					// deadline
					if(atoi(g->db_get_data(res,i,"paytime")) < 0)
						paytime = p->deadline;
					else
						paytime = g->db_get_data(res,i,"paytime");

					// prepare insert to 'invoices' table
					g->db_pexec(g->conn, "INSERT INTO documents (number, numberplanid, type, countryid, divisionid, "
						"customerid, name, address, zip, city, ten, ssn, cdate, sdate, paytime, paytype) "
						"VALUES (?, ?, 1, ?, ?, ?, '? ?', '?', '?', '?', '?', '?', ?, ?, ?, ?)",
						itoa(number),
						numberplanid,
						countryid,
						divisionid,
						cid_c,
						g->db_get_data(res,i,"lastname"),
						g->db_get_data(res,i,"custname"),
						g->db_get_data(res,i,"address"),
						g->db_get_data(res,i,"zip"),
						g->db_get_data(res,i,"city"),
						g->db_get_data(res,i,"ten"),
						g->db_get_data(res,i,"ssn"),
						currtime,
						currtime,
						paytime,
						paytype_str
					);

					docid = g->db_last_insert_id(g->conn, "documents");
					itemid = 0;

					free(numberplanid);
					free(paytype_str);
				}

				invoiceid = strdup(itoa(docid));

				result = g->db_pquery(g->conn, "SELECT itemid FROM invoicecontents "
				    "WHERE tariffid = ? AND docid = ? AND description = '?' AND value = ? AND pdiscount = ? AND vdiscount = ?",
				    g->db_get_data(res,i,"tariffid"), invoiceid, description, value, pdiscount, vdiscount);

				if( g->db_nrows(result) ) 
				{
					g->db_pexec(g->conn, "UPDATE invoicecontents SET count = count+1 WHERE docid = ? AND itemid = ?",
						invoiceid,
						g->db_get_data(result,0,"itemid")
						);

					exec = g->db_pexec(g->conn, "UPDATE cash SET value = value + (? * -1) "
					    "WHERE docid = ? AND itemid = ?",
					    value, invoiceid, g->db_get_data(result,0,"itemid"));
				}
				else if (docid)
				{
					itemid++;

					g->db_pexec(g->conn,"INSERT INTO invoicecontents (docid, itemid, value, "
					        "taxid, prodid, content, count, description, tariffid, pdiscount, vdiscount) "
					        "VALUES (?, ?, ?, ?, '?', 'szt.', 1, '?', ?, ?, ?)",
						invoiceid,
						itoa(itemid),
						value,
						taxid,
						g->db_get_data(res,i,"prodid"),
						description,
						g->db_get_data(res,i,"tariffid"),
						pdiscount,
						vdiscount
						);

					g->str_replace(&insert, "%docid", invoiceid);
					g->str_replace(&insert, "%itemid", itoa(itemid));
					exec = g->db_pexec(g->conn, insert, currtime, description);
				}

				g->db_free(&result);
				free(invoiceid);
			}
			else
			{
				g->str_replace(&insert, "%docid", "0");
				g->str_replace(&insert, "%itemid", "0");
				exec = g->db_pexec(g->conn, insert, currtime, description) ? 1 : exec;
			}

			free(insert);
			free(description);

			// settlements accounting has sense only for up payments
			if( settlement && datefrom && p->up_payments)
			{
				int alldays = 1;
				int diffdays = (int) ((today - datefrom)/86400);

				switch( period )
				{
					// there are no disposable or daily liabilities with settlement
					case WEEKLY: 	alldays = 7; break;
					case MONTHLY: 	alldays = 30; break;
					case QUARTERLY: alldays = 90; break;
					case HALFYEARLY: alldays = 182; break;
					case YEARLY: 	alldays = 365; break;
				}

				value = ftoa(diffdays * val/alldays);

				description = strdup(p->s_comment);
				g->str_replace(&description, "%period", get_diff_period(datefrom, today-86400));
				g->str_replace(&description, "%type", tarifftype);
				g->str_replace(&description, "%tariff", g->db_get_data(res,i,"name"));
				g->str_replace(&description, "%month", monthname);
				g->str_replace(&description, "%year", year);

				// prepare insert to 'cash' table
				insert = strdup("INSERT INTO cash (time, value, taxid, customerid, comment, docid, itemid) "
					"VALUES (?, %value * -1, %taxid, %customerid, '?', %docid, %itemid)");

				g->str_replace(&insert, "%customerid", cid_c);
				g->str_replace(&insert, "%value", value);
				g->str_replace(&insert, "%taxid", taxid);

				// we're using transaction to not disable settlement flag
				// when something will goes wrong
				g->db_begin(g->conn);

				if( atoi(g->db_get_data(res,i,"invoice")) )
				{
					// oh, now we've got invoice id
					invoiceid = strdup(itoa(docid));

					result = g->db_pquery(g->conn, "SELECT itemid FROM invoicecontents "
					    "WHERE tariffid = ? AND docid = ? AND description = '?' AND value = ?",
					    g->db_get_data(res,i,"tariffid"), invoiceid, description, value);

					if( g->db_nrows(result) )
					{
						g->db_pexec(g->conn, "UPDATE invoicecontents SET count = count+1 WHERE docid = ? AND itemid = ?",
							invoiceid,
							g->db_get_data(result,0,"itemid")
						);

						exec = g->db_pexec(g->conn, "UPDATE cash SET value = value + (? * -1) "
						    "WHERE docid = ? AND itemid = ?",
						    value, invoiceid, g->db_get_data(result,0,"itemid"));
					}
					else if (docid)
					{
						itemid++;

						g->db_pexec(g->conn,"INSERT INTO invoicecontents (docid, itemid, value, taxid, prodid, "
						        "content, count, description, tariffid, pdiscount, vdiscount) "
						        "VALUES (?, ?, ?, ?, '?', 'szt.', 1, '?', ?, ?, ?)",
							invoiceid,
							itoa(itemid),
							value,
							taxid,
							g->db_get_data(res,i,"prodid"),
							description,
							g->db_get_data(res,i,"tariffid"),
							pdiscount,
							vdiscount
							);

						g->str_replace(&insert, "%docid", invoiceid);
						g->str_replace(&insert, "%itemid", itoa(itemid));
						g->str_replace(&insert, "%value", value);
						exec = g->db_pexec(g->conn, insert, currtime, description);
					}

					g->db_free(&result);
					free(invoiceid);
				}
				else
				{
					g->str_replace(&insert, "%docid", "0");
					g->str_replace(&insert, "%itemid", "0");
					g->str_replace(&insert, "%value", value);
					g->db_pexec(g->conn, insert, currtime, description) ? 1 : exec;
				}

				// uncheck settlement flag
				g->db_pexec(g->conn, "UPDATE assignments SET settlement = 0 WHERE id = ?", g->db_get_data(res,i,"assignmentid"));

				g->db_commit(g->conn);

				free(insert);
				free(description);
			}

			last_cid = cid;
		}

		g->db_free(&res);
		free(y_period);
		free(h_period);
		free(q_period);
		free(m_period);
		free(w_period);
		free(d_period);

		free(plans);
#ifdef DEBUG1
		syslog(LOG_INFO, "DEBUG: [%s/payments] Customer payments reloaded", p->base.instance);
#endif
	}
	else 
		syslog(LOG_ERR, "[%s/payments] Unable to read tariff assignments", p->base.instance);

	free(query);

	/****** invoices checking *******/
	if (p->check_invoices)
	{
		char *query = strdup(
			"UPDATE documents SET closed = 1 "
			"WHERE customerid IN ( "
				"SELECT a.customerid "
				"FROM cash a "
				"WHERE a.time <= %NOW% "
				"   %nets%enets%groups%egroups "
				"GROUP BY a.customerid "
				"HAVING SUM(a.value) >= 0) "
			"AND type IN (1, 3, 5) "
			"AND cdate <= %NOW% "
			"AND closed = 0");

		g->str_replace(&query, "%nets", strlen(netsql) ? nets : "");
		g->str_replace(&query, "%enets", strlen(enetsql) ? enets : "");
		g->str_replace(&query, "%groups", strlen(groupsql) ? groups : "");
		g->str_replace(&query, "%egroups", strlen(egroupsql) ? egroups : "");

		g->db_pexec(g->conn, query);

		free(query);
	}

	// remove old assignments
	if(p->expiry_days<0) p->expiry_days *= -1; // number of expiry days can't be negative

    char *exp_days = strdup(itoa(p->expiry_days));

	g->db_pexec(g->conn, "DELETE FROM liabilities "
	    "WHERE id IN ("
		    "SELECT liabilityid FROM assignments "
	        "WHERE dateto < ? - 86400 * ? AND dateto != 0 AND at < ? - 86400 * ? "
		        "AND liabilityid != 0)",
	    currtime, exp_days, itoa(today), exp_days);
	g->db_pexec(g->conn, "DELETE FROM assignments "
	    "WHERE dateto < ? - 86400 * ? AND dateto != 0 AND at < ? - 86400 * ?",
	    currtime, exp_days, itoa(today), exp_days);

	// clean up
	free(exp_days);
	free(currtime);
	free(nets); free(enets);
	free(groups); free(egroups);
	free(netsql); free(enetsql);
	free(groupsql);	free(egroupsql);
	free(p->comment);
	free(p->s_comment);
	free(p->deadline);
	free(p->networks);
	free(p->customergroups);
	free(p->excluded_networks);
	free(p->excluded_customergroups);
}
Exemple #17
0
    Syncpoint *Scheduler::add_task(Task &p)
    {
        static unsigned int list_len = 0;
        const units::Nanoseconds p_period = p.get_period();
        const units::Nanoseconds s_period = get_period();

        /* If periodic tasks period is faster than the scheduler's period,
         * then reject the task as unschedulable. A periodic task is also
         * not schedulable if its period is not a modulo of the scheduler
         * period.
         */
        if((p_period < s_period) || ((p_period % s_period) != 0))
        {
            EPRINTF("Invalid task period: %" PRId64 "\n", int64_t(p_period));
            return NULL;
        }

        Sched_list &list = m_sched_impl->rategroup;
        Sched_list::Node *n = list.head();

        /* Search for an existing rategroup entry with the same period.
        */
        while(n)
        {
            if(p_period == n->data->period)
            {
                /* Found the rategroup. Pass the associated syncpoint back to
                 * the task.
                 */
                return &(n->data->sync);
            }

            n = n->next();
        }

        /* Didn't find the rategroup. We'll have to add an entry in the list.
        */
        DPRINTF("Adding rategroup entry for %" PRId64 " period\n",
                int64_t(p_period));
        Sched_item *item = new Sched_item(p_period);
        if(NULL == item)
        {
            return NULL;
        }

        /* Add a symbol table entry for the runtime attributes of the rategroup.
        */
        Runtime_attributes_db &rt_db = Runtime_attributes_db::get_instance();
        char name[SYM_ENTRY_STRLEN + 1];
        snprintf(name, SYM_ENTRY_STRLEN, "%s%" PRId64 "",
                 runtime_attr_symbol_prefix, int64_t(p_period));
        item->rt_attr_symbol = rt_db.add_symbol(name);
        if((NULL == item->rt_attr_symbol) ||
           (false == item->rt_attr_symbol->is_valid()))
        {
            EPRINTF(
                "Failed while adding runtime attributes symbol table entry\n");
            delete item;
            return NULL;
        }

        /* Initialize the runtime attribute data.
        */
        item->rt_attr_symbol->entry->write(item->rt_attr);

        DPRINTF("%s rategroup mutex is %p\n", name, &(item->sync));

        /* If this is the scheduler's rategroup (which defines the minor
         * frame), then alias the runtime properties to the minor frame runtime
         * properties name.
         */
        if(p_period == s_period)
        {
            Runtime_attributes_db::symbol_t *rt_sym_alias = rt_db.alias_symbol(
                minor_frame_runtime_attr_symbol_name, item->rt_attr_symbol);
            if((NULL == rt_sym_alias) || (false == rt_sym_alias->is_valid()))
            {
                EPRINTF("Failed while aliasing runtime attributes symbol table "
                        "entry\n");
                delete item;
                return NULL;
            }

            DPRINTF("Aliased the minor frame runtime attributes symbol\n");
        }

        update_unwind_tics(p_period / s_period);
        list.add_back(item);
        ++list_len;
        DPRINTF("List length is now %u\n", list_len);

        /*  Add a lowest priority task to this rategroup which its execution
         *  will signify the completion of all other tasks in this this
         *  rategroup.
         */
        Task_properties tprops;
        tprops.period = p_period;
        tprops.prio = MIN_PRIO;
        snprintf(name, SYM_ENTRY_STRLEN, "End_of_frame_%" PRId64,
                 int64_t(p_period));
        item->eof_task =
            new End_of_frame(name, item->finished, item->end_time, item->sync);
        item->eof_task->set_properties(tprops);
        item->eof_task->start();

        return &(item->sync);
    }