Beispiel #1
0
void test_order(char *fileName)
{
	Key * parentKey = keyNew ("user/tests/augeas-hosts", KEY_VALUE,
			srcdir_file (fileName), KEY_END);
	KeySet *conf = ksNew (20,
			keyNew ("system/lens", KEY_VALUE, "Hosts.lns", KEY_END), KS_END);
	PLUGIN_OPEN("augeas");

	KeySet *ks = ksNew(0, KS_END);

	succeed_if(plugin->kdbGet (plugin, ks, parentKey) >= 1,
			"call to kdbGet was not successful");
	succeed_if(output_error (parentKey), "error in kdbGet");
	succeed_if(output_warnings (parentKey), "warnings in kdbGet");

	Key *key;
	size_t currentIndex = 0;
	size_t numKeys = ksGetSize (ks);
	long *usedOrders = malloc (numKeys * sizeof(long));

	exit_if_fail(usedOrders, "unable to allocate memory for order array");

	/* as 0 is a legit order we have to initialize the array manually */
	for (size_t index = 0; index < numKeys; index++)
	{
		usedOrders[index] = -1;
	}

	ksRewind (ks);
	while ((key = ksNext (ks)) != 0)
	{
		if (strcmp (keyName (key), keyName (parentKey)))
		{
			char errorMessage[150];
			const Key *orderKey = keyGetMeta (key, "order");

			snprintf (errorMessage, 150, "key %s has no order", keyName (key));

			succeed_if(orderKey, errorMessage);

			char *orderString = (char *) keyValue (orderKey);
			long order;
			char *end;
			order = strtol (orderString, &end, 10);
			snprintf (errorMessage, 150, "key %s has an unparseable order",
					keyName (key));

			succeed_if(*end == 0, errorMessage);

			snprintf (errorMessage, 150, "key %s has a negative order",
					keyName (key));
			succeed_if(order >= 0, errorMessage);

			snprintf (errorMessage, 150,
					"the order %ld exists more than once. Duplicate found in %s.",
					order, keyName (key));

			// TODO: this is in O(n^2) where n is the number of keys
			for (size_t i = 0; i < currentIndex; i++)
			{
				succeed_if(usedOrders[i] != order, errorMessage);
			}

			usedOrders[currentIndex] = order;
			++currentIndex;
		}
	}

	free (usedOrders);
	ksDel (ks);
	keyDel(parentKey);

	PLUGIN_CLOSE() ;
}
Beispiel #2
0
/**	Fetches the property requested and uses the appropriate op on the value.
	@return boolean value
**/
static int compare_property_alt(OBJECT *obj, char *propname, FINDOP op, void *value){
	complex *complex_target = NULL;
	char *char_target = NULL;
	int16 *int16_target = NULL;
	int32 *int32_target = NULL;
	int64 *int64_target = NULL;
	PROPERTY *prop = object_get_property(obj, propname,NULL);

	if(prop == NULL){
		/* property not found in object ~ normal operation */
		return 0;
	}

	switch(prop->ptype){
		case PT_void:
			return 0;	/* no comparsion to be made */
		case PT_double:
			break;
		case PT_complex:
			complex_target = object_get_complex(obj, prop);
			if(complex_target == NULL)
				return 0; /* error value */
			break;
		case PT_enumeration:
		case PT_set:
			break;		/* not 100% sure how to make these cooperate yet */
		case PT_int16:
			int16_target = (int16 *)object_get_int16(obj, prop);
			if(int16_target == NULL)
				return 0;
			return compare_int16(*int16_target, op, *(int64 *)value);
		case PT_int32:
			int32_target = (int32 *)object_get_int32(obj, prop);
			return compare_int32(*int32_target, op, *(int64 *)value);
			break;
		case PT_int64:
			int64_target = (int64 *)object_get_int64(obj, prop);
			return compare_int64(*int64_target, op, *(int64 *)value);
			break;
		case PT_char8:
		case PT_char32:
		case PT_char256:
		case PT_char1024:
			char_target = (char *)object_get_string(obj, prop);
			if(char_target == NULL)
				return 0;
			return compare_string(char_target, op, value);
			break;
		case PT_object:

			break;
		case PT_bool:
			break;
		case PT_timestamp:
		case PT_double_array:
		case PT_complex_array:
			break;
#ifdef USE_TRIPLETS
		case PT_triple:
		case PT_triplex:
			break;
#endif
		default:
			output_error("comparison operators not supported for property type %s", class_get_property_typename(prop->ptype));
			/* TROUBLESHOOT
				This error is caused when an object find procedure uses a comparison operator
			that isn't allowed on a that type of property.  Make sure the property type
			and the comparison operator are compatible and try again.  If your GLM file
			isn't the cause of the problem, try reducing the complexity of the GLM file 
			you are using to isolate which module is causing the error and file a report 
			with the GLM file attached.
			 */
			return 0;
	}
}
Beispiel #3
0
int enduse_publish(CLASS *oclass, PROPERTYADDR struct_address, char *prefix)
{
	enduse *this=NULL; // temporary enduse structure used for mapping variables
	int result = 0;
	struct s_map_enduse{
		PROPERTYTYPE type;
		char *name;
		char *addr;
		char *description;
		int flags;
	}*p, prop_list[]={
		{PT_complex, "energy[kVAh]", (char *)PADDR(energy), "the total energy consumed since the last meter reading"},
		{PT_complex, "power[kVA]", (char *)PADDR(total), "the total power consumption of the load"},
		{PT_complex, "peak_demand[kVA]", (char *)PADDR(demand), "the peak power consumption since the last meter reading"},
		{PT_double, "heatgain[Btu/h]", (char *)PADDR(heatgain), "the heat transferred from the enduse to the parent"},
		{PT_double, "cumulative_heatgain[Btu]", (char *)PADDR(cumulative_heatgain), "the cumulative heatgain from the enduse to the parent"},
		{PT_double, "heatgain_fraction[pu]", (char *)PADDR(heatgain_fraction), "the fraction of the heat that goes to the parent"},
		{PT_double, "current_fraction[pu]", (char *)PADDR(current_fraction),"the fraction of total power that is constant current"},
		{PT_double, "impedance_fraction[pu]", (char *)PADDR(impedance_fraction), "the fraction of total power that is constant impedance"},
		{PT_double, "power_fraction[pu]", (char *)PADDR(power_fraction), "the fraction of the total power that is constant power"},
		{PT_double, "power_factor", (char *)PADDR(power_factor), "the power factor of the load"},
		{PT_complex, "constant_power[kVA]", (char *)PADDR(power), "the constant power portion of the total load"},
		{PT_complex, "constant_current[kVA]", (char *)PADDR(current), "the constant current portion of the total load"},
		{PT_complex, "constant_admittance[kVA]", (char *)PADDR(admittance), "the constant admittance portion of the total load"},
		{PT_double, "voltage_factor[pu]", (char *)PADDR(voltage_factor), "the voltage change factor"},
		{PT_double, "breaker_amps[A]", (char *)PADDR(breaker_amps), "the rated breaker amperage"},
		{PT_set, "configuration", (char *)PADDR(config), "the load configuration options"},
			{PT_KEYWORD, "IS220", (set)EUC_IS220},
			//{PT_KEYWORD, "NONE",(set)0},
	}, *last=NULL;

	// publish the enduse load itself
	PROPERTY *prop = property_malloc(PT_enduse,oclass,strcmp(prefix,"")==0?"load":prefix,struct_address,NULL);
	prop->description = "the enduse load description";
	prop->flags = 0;
	class_add_property(oclass,prop);

	for (p=prop_list;p<prop_list+sizeof(prop_list)/sizeof(prop_list[0]);p++)
	{
		char name[256], lastname[256];

		if(prefix == NULL || strcmp(prefix,"")==0)
		{
			strcpy(name,p->name);
		}
		else
		{
			//strcpy(name,prefix);
			//strcat(name, ".");
			//strcat(name, p->name);
			sprintf(name,"%s.%s",prefix,p->name);
		}

		if (p->type<_PT_LAST)
		{
			prop = property_malloc(p->type,oclass,name,p->addr+(int64)struct_address,NULL);
			prop->description = p->description;
			prop->flags = p->flags;
			class_add_property(oclass,prop);
			result++;
		}
		else if (last==NULL)
		{
			output_error("PT_KEYWORD not allowed unless it follows another property specification");
			/* TROUBLESHOOT
				The enduse_publish structure is not defined correctly.  This is an internal error and cannot be corrected by
				users.  Contact technical support and report this problem.
			 */
			return -result;
		}
		else if (p->type==PT_KEYWORD) {
			switch (last->type) {
			case PT_enumeration:
				if (!class_define_enumeration_member(oclass,lastname,p->name,p->type))
				{
					output_error("unable to publish enumeration member '%s' of enduse '%s'", p->name,last->name);
					/* TROUBLESHOOT
					The enduse_publish structure is not defined correctly.  This is an internal error and cannot be corrected by
					users.  Contact technical support and report this problem.
					 */
					return -result;
				}
				break;
			case PT_set:
				if (!class_define_set_member(oclass,lastname,p->name,(int64)p->addr))
				{
					output_error("unable to publish set member '%s' of enduse '%s'", p->name,last->name);
					/* TROUBLESHOOT
					The enduse_publish structure is not defined correctly.  This is an internal error and cannot be corrected by
					users.  Contact technical support and report this problem.
					 */
					return -result;
				}
				break;
			default:
				output_error("PT_KEYWORD not supported after property '%s %s' in enduse_publish", class_get_property_typename(last->type), last->name);
				/* TROUBLESHOOT
				The enduse_publish structure is not defined correctly.  This is an internal error and cannot be corrected by
				users.  Contact technical support and report this problem.
				 */
				return -result;
			}
		}
		else
		{
			output_error("property type '%s' not recognized in enduse_publish", class_get_property_typename(last->type));
			/* TROUBLESHOOT
				The enduse_publish structure is not defined correctly.  This is an internal error and cannot be corrected by
				users.  Contact technical support and report this problem.
			*/
			return -result;
		}

		last = p;
		strcpy(lastname,name);
	}

	return result;
}
Beispiel #4
0
int
main (int argc, char **argv)
{
  int status = EXIT_SUCCESS;
  int DEFAULT_GROUPING = 0x01;
  int group_by = DEFAULT_GROUPING;
  bool un_flag = false, iso_flag = false;
  progname = *argv++;

  /*
   ** -hex		hex dump
   ** -group-by-8-bits
   ** -group-by-16-bits
   ** -group-by-32-bits
   ** -group-by-64-bits
   ** -iso		iso character set.
   ** -un || -de	from hexl format to binary.
   ** --		End switch list.
   ** <filename>	dump filename
   ** -		(as filename == stdin)
   */

  for (; *argv && *argv[0] == '-' && (*argv)[1]; argv++)
    {
      /* A switch! */
      if (!strcmp (*argv, "--"))
	{
	  argv++;
	  break;
	}
      else if (!strcmp (*argv, "-un") || !strcmp (*argv, "-de"))
	{
	  un_flag = true;
	  set_binary_mode (fileno (stdout), O_BINARY);
	}
      else if (!strcmp (*argv, "-hex"))
	/* Hex is the default and is only base supported.  */;
      else if (!strcmp (*argv, "-iso"))
	iso_flag = true;
      else if (!strcmp (*argv, "-group-by-8-bits"))
	group_by = 0x00;
      else if (!strcmp (*argv, "-group-by-16-bits"))
	group_by = 0x01;
      else if (!strcmp (*argv, "-group-by-32-bits"))
	group_by = 0x03;
      else if (!strcmp (*argv, "-group-by-64-bits"))
	group_by = 0x07;
      else
	{
	  fprintf (stderr, "%s: invalid switch: \"%s\".\n", progname,
		   *argv);
	  fprintf (stderr, "usage: %s [-de] [-iso]\n", progname);
	  return EXIT_FAILURE;
	}
    }

  char const *filename = *argv ? *argv++ : "-";

  do
    {
      FILE *fp;

      if (!strcmp (filename, "-"))
	{
	  fp = stdin;
	  if (!un_flag)
	    set_binary_mode (fileno (stdin), O_BINARY);
	}
      else
	{
	  fp = fopen (filename, un_flag ? "r" : "rb");
	  if (!fp)
	    {
	      perror (filename);
	      status = EXIT_FAILURE;
	      continue;
	    }
	}

      if (un_flag)
	{
	  for (int c; 0 <= (c = getc (fp)); )
	    {
	      /* Skip address at start of line.  */
	      if (c != ' ')
		continue;

	      for (int i = 0; i < 16; i++)
		{
		  c = getc (fp);
		  if (c < 0 || c == ' ')
		    break;

		  int hc = hexchar (c);
		  c = getc (fp);
		  if (c < 0)
		    break;
		  putchar (hc * 0x10 + hexchar (c));

		  if ((i & group_by) == group_by)
		    {
		      c = getc (fp);
		      if (c < 0)
			break;
		    }
		}

	      while (0 <= c && c != '\n')
		c = getc (fp);
	      if (c < 0)
		break;
	      if (ferror (stdout))
		output_error ();
	    }
	}
      else
	{
	  int c = 0;
	  char string[18];
	  string[0] = ' ';
	  string[17] = '\0';
	  for (uintmax_t address = 0; 0 <= c; address += 0x10)
	    {
	      int i;
	      for (i = 0; i < 16; i++)
		{
		  if (0 <= c)
		    c = getc (fp);
		  if (c < 0)
		    {
		      if (!i)
			break;

		      fputs ("  ", stdout);
		      string[i + 1] = '\0';
		    }
		  else
		    {
		      if (!i)
			printf ("%08"PRIxMAX": ", address);

		      string[i + 1]
			= (c < 0x20 || (0x7F <= c && (!iso_flag || c < 0xa0))
			   ? '.' : c);

		      printf ("%02x", c + 0u);
		    }

		  if ((i & group_by) == group_by)
		    putchar (' ');
		}

	      if (i)
		puts (string);

	      if (ferror (stdout))
		output_error ();
	    }
	}

      bool trouble = ferror (fp) != 0;
      trouble |= fp != stdin && fclose (fp) != 0;
      if (trouble)
	{
	  fprintf (stderr, "%s: read error\n", progname);
	  status = EXIT_FAILURE;
	}

      filename = *argv++;
    }
  while (filename);

  if (ferror (stdout) || fclose (stdout) != 0)
    output_error ();
  return status;
}
Beispiel #5
0
/** Convert to a \e set
	Converts a string to a \e set property.  
	@return number of values read on success, 0 on failure, -1 if conversion was incomplete
 **/
int convert_to_set(const char *buffer, /**< a pointer to the string buffer */
					    void *data, /**< a pointer to the data */
					    PROPERTY *prop) /**< a pointer to keywords that are supported */
{
	KEYWORD *keys=prop->keywords;
	char temp[4096];
	const char *ptr;
	uint32 value=0;
	int count=0;

	/* directly convert numeric strings */
	if (strnicmp(buffer,"0x",2)==0)
		return sscanf(buffer,"0x%x",(uint32*)data);
	else if (isdigit(buffer[0]))
		return sscanf(buffer,"%d",(uint32*)data);

	/* prevent long buffer from being scanned */
	if (strlen(buffer)>sizeof(temp)-1)
		return 0;

	/* make a temporary copy of the buffer */
	strcpy(temp,buffer);

	/* check for CHARSET keys (single character keys) and usage without | */
	if ((prop->flags&PF_CHARSET) && strchr(buffer,'|')==NULL)
	{
		for (ptr=buffer; *ptr!='\0'; ptr++)
		{
			bool found = false;
			KEYWORD *key;
			for (key=keys; key!=NULL; key=key->next)
			{
				if (*ptr==key->name[0])
				{
					value |= key->value;
					count ++;
					found = true;
					break; /* we found our key */
				}
			}
			if (!found)
			{
				output_error("set member '%c' is not a keyword of property %s", *ptr, prop->name);
				return 0;
			}
		}
	}
	else
	{
		/* process each keyword in the temporary buffer*/
		for (ptr=strtok(temp,SETDELIM); ptr!=NULL; ptr=strtok(NULL,SETDELIM))
		{
			bool found = false;
			KEYWORD *key;

			/* scan each of the keywords in the set */
			for (key=keys; key!=NULL; key=key->next)
			{
				if (strcmp(ptr,key->name)==0)
				{
					value |= key->value;
					count ++;
					found = true;
					break; /* we found our key */
				}
			}
			if (!found)
			{
				output_error("set member '%s' is not a keyword of property %s", ptr, prop->name);
				return 0;
			}
		}
	}
	*(uint32*)data = value;
	return count;
}
Beispiel #6
0
STATUS server_startup(int argc, char *argv[])
{
	static int started = 0;
	int portNumber = global_server_portnum;
	SOCKET sockfd;
	struct sockaddr_in serv_addr;
#ifdef WIN32
	static WSADATA wsaData;
#endif

	if (started)
		return SUCCESS;

#ifdef WIN32
	output_debug("starting WS2");
	if (WSAStartup(MAKEWORD(2,0),&wsaData)!=0)
	{
		output_error("socket library initialization failed: %s",strerror(GetLastError()));
		return FAILED;	
	}
#endif

	/* create a new socket */
	if ((sockfd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) == INVALID_SOCKET)
	{
		output_error("can't create stream socket: %s",strerror(GetLastError()));
		return FAILED;
	}
	atexit(shutdown_now);

	memset(&serv_addr,0,sizeof(serv_addr));

Retry:
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	serv_addr.sin_port = htons(portNumber);

	/* bind socket to server address */
	if (bind(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
	{
		if (portNumber<global_server_portnum+1000)
		{
			portNumber++;
			output_warning("server port not available, trying port %d...", portNumber);
			goto Retry;
		}
#ifdef WIN32
		output_error("can't bind to %d.%d.%d.%d",serv_addr.sin_addr.S_un.S_un_b.s_b1,serv_addr.sin_addr.S_un.S_un_b.s_b2,serv_addr.sin_addr.S_un.S_un_b.s_b3,serv_addr.sin_addr.S_un.S_un_b.s_b4);
#else
		output_error("can't bind address: %s",strerror(GetLastError()));
#endif
		return FAILED;
	}
#ifdef WIN32
	output_verbose("bind ok to %d.%d.%d.%d",serv_addr.sin_addr.S_un.S_un_b.s_b1,serv_addr.sin_addr.S_un.S_un_b.s_b2,serv_addr.sin_addr.S_un.S_un_b.s_b3,serv_addr.sin_addr.S_un.S_un_b.s_b4);
#else
	output_verbose("bind ok to address");
#endif	
	/* listen for connection */
	listen(sockfd,5);
	output_verbose("server listening to port %d", portNumber);
	global_server_portnum = portNumber;

	/* start the server thread */
	if (pthread_create(&thread,NULL,server_routine,(void*)sockfd))
	{
		output_error("server thread startup failed: %s",strerror(GetLastError()));
		return FAILED;
	}

	started = 1;
	return SUCCESS;
}
Beispiel #7
0
/* initialize modules */
int link_initall(void)
{
	output_debug("link_initall(): link startup in progress...");
	glxlink *mod;
	for ( mod=glxlink::get_first() ; mod!=NULL ; mod=mod->get_next() )
	{
		LINKLIST *item;

		output_debug("link_initall(): setting up %s link", mod->get_target());

		// set default global list (if needed)
		if ( mod->get_globals()==NULL )
		{
			GLOBALVAR *var = NULL;
			while ( (var=global_getnext(var))!=NULL )
			{
				if ( var->prop!=NULL && var->prop->name!=NULL )
				{
					LINKLIST *item = mod->add_global(var->prop->name);
					if ( item!=NULL )
						item->data = (void*)var;
					else
						output_error("link_initall(): unable to link %s", var->prop->name);
				}
				else
					output_warning("link_initall(): a variable property definition is null"); 
			}
		}
		else 
		{
			// link global variables
			for ( item=mod->get_globals() ; item!=NULL ; item=mod->get_next(item) )
			{
				if ( strcmp(item->name,"")==0 ) continue;
				item->data = (void*)global_find(item->name);
				if ( item->data==NULL )
					output_error("link_initall(target='%s'): global '%s' is not found", mod->get_target(), item->name);
			}
		}

		// link objects
		if ( mod->get_objects()==NULL )
		{
			// set default object list
			OBJECT *obj = NULL;
			for ( obj=object_get_first() ; obj!=NULL ; obj=object_get_next(obj) )
			{
				// add named objects
				LINKLIST *item = NULL;
				if ( obj->name!=NULL )
					item = mod->add_object(obj->name);
				else
				{
					char id[256];
					sprintf(id,"%s:%d",obj->oclass->name,obj->id);
					item = mod->add_object(id);
				}
				item->data = (void*)obj;
			}
		}
		else
		{
			LINKLIST *item;

			// link global variables
			for ( item=mod->get_objects() ; item!=NULL ; item=mod->get_next(item) )
			{
				if ( strcmp(item->name,"")==0 ) continue;
				OBJECT *obj = NULL;
				item->data = (void*)object_find_name(item->name);
				if ( item->data==NULL)
					output_error("link_initall(target='%s'): object '%s' is not found", mod->get_target(), item->name);
			}
		}

		// link exports
		for ( item=mod->get_exports() ; item!=NULL ; item=mod->get_next(item) )
		{
			char objname[64], propname[64], varname[64];
			if ( sscanf(item->name,"%[^.].%s %s",objname,propname,varname)==3 )
			{
				OBJECTPROPERTY *objprop = (OBJECTPROPERTY*)malloc(sizeof(OBJECTPROPERTY));
				objprop->obj = object_find_name(objname);
				if ( objprop->obj )
				{
					objprop->prop = class_find_property(objprop->obj->oclass,propname);
					if ( objprop->prop==NULL )
						output_error("link_initall(target='%s'): export '%s' property not found", mod->get_target(), item->name);
					else
					{
						item->data = objprop;
						strcpy(item->name,varname);
					}
				}
				else
					output_error("link_initall(target='%s'): export '%s' object not found", mod->get_target(), item->name);
			}
			else
				output_error("link_initall(target='%s'): '%s' is not a valid export specification", mod->get_target(), item->name);
		}

		// link imports
		for ( item=mod->get_imports() ; item!=NULL ; item=mod->get_next(item) )
		{
			char objname[64], propname[64], varname[64];
			if ( sscanf(item->name,"%[^.].%s %s",objname,propname,varname)==3 )
			{
				OBJECTPROPERTY *objprop = (OBJECTPROPERTY*)malloc(sizeof(OBJECTPROPERTY));
				objprop->obj = object_find_name(objname);
				if ( objprop->obj )
				{
					objprop->prop = class_find_property(objprop->obj->oclass,propname);
					if ( objprop->prop==NULL )
						output_error("link_initall(target='%s'): import '%s' property not found", mod->get_target(), item->name);
					else
					{
						item->data = objprop;
						strcpy(item->name,varname);
					}
				}
				else
					output_error("link_initall(target='%s'): import '%s' object not found", mod->get_target(), item->name);
			}
			else
				output_error("link_initall(target='%s'): '%s' is not a valid import specification", mod->get_target(), item->name);
		}

		// initialize link module
		if ( !mod->do_init() )
		{
			output_error("link_initall(): link startup failed");
			link_termall();
			return 0;
		}
	}
	output_debug("link_initall(): link startup done ok");
	atexit((void(*)(void))link_termall);
	return 1;
}
Beispiel #8
0
/** Load a timezone from the timezone info file
 **/
void load_tzspecs(char *tz){
	char filepath[1024];
	char *pTzname = 0;
	FILE *fp = NULL;
	char buffer[1024];
	int linenum = 0;
	int year = YEAR0;
	int y;
	int found;

	found = 0;
	tzvalid = 0;
	pTzname = tz_name(tz);

	if(pTzname == 0){
		THROW("timezone '%s' was not understood by tz_name.", tz);
		/* TROUBLESHOOT
			The specific timezone is not valid.
			Try using a valid timezone or add the desired timezone to the timezone file <code>.../etc/tzinfo.txt</code> and try again.
		 */
	}

	strncpy(current_tzname, pTzname, sizeof(current_tzname));
	tzoffset = tz_offset(current_tzname);
	strncpy(tzstd, tz_std(current_tzname), sizeof(tzstd));
	strncpy(tzdst, tz_dst(current_tzname), sizeof(tzdst));

	if(find_file(TZFILE, NULL, R_OK,filepath,sizeof(filepath)) == NULL){
		THROW("timezone specification file %s not found in GLPATH=%s: %s", TZFILE, getenv("GLPATH"), strerror(errno));
		/* TROUBLESHOOT
			The system could not locate the timezone file <code>tzinfo.txt</code>.
			Check that the <code>etc</code> folder is included in the '''GLPATH''' environment variable and try again.
		 */
	}

	fp = fopen(filepath,"r");

	if(fp == NULL){
		THROW("%s: access denied: %s", filepath, strerror(errno));
		/* TROUBLESHOOT
			The system was unable to read the timezone file.  Check that the file has the correct permissions and try again.
		 */
	}

	// zero previous DST start/end times
	for (y = 0; y < sizeof(tszero) / sizeof(tszero[0]); y++){
		dststart[y] = dstend[y] = -1;
	}

	while(fgets(buffer,sizeof(buffer),fp)){
		char *p = NULL;
		char tzname[32];
		SPEC start, end;
		int form = -1;

		linenum++;

		/* wipe comments */
		p = strchr(buffer,';');

		if(p != NULL){
			*p = '\0';
		}

		/* remove trailing whitespace */
		p = buffer + strlen(buffer) - 1;

		while (iswspace(*p) && p > buffer){
			*p-- = '\0';
		}

		/* ignore blank lines or lines starting with white space*/
		if (buffer[0] == '\0' || iswspace(buffer[0])){
			continue;
		}

		/* year section */
		if(sscanf(buffer, "[%d]", &year) == 1){
			continue;
		}

		/* TZ spec */
		form = sscanf(buffer, "%[^,],M%d.%d.%d/%d:%d,M%d.%d.%d/%d:%d", tzname,
			&start.month, &start.nth, &start.day, &start.hour, &start.minute,
			&end.month, &end.nth, &end.day, &end.hour, &end.minute);

		/* load only TZ requested */
		pTzname = tz_name(tzname);

		if (tz != NULL && pTzname != NULL && strcmp(pTzname,current_tzname) != 0){
			continue;
		}

		if(form == 1){ /* no DST */
			set_tzspec(year, current_tzname, NULL, NULL);
			found = 1;
		} else if(form == 11) { /* full DST spec */
			set_tzspec(year, current_tzname, &start, &end);
			found = 1;
		} else {
			THROW("%s(%d): %s is not a valid timezone spec", filepath, linenum, buffer);
			/* TROUBLESHOOT
				The timezone specification is not valid.  Verify the syntax of the timezone spec and that it is defined in the timezone file
				<code>.../etc/tzinfo.txt</code> or add it, and try again.
			 */
		}
	}

	if(found == 0){
		output_warning("%s(%d): timezone spec '%s' not found in 'tzinfo.txt', will include no DST information", filepath, linenum, current_tzname);
	}

	if(ferror(fp)){
		output_error("%s(%d): %s", filepath, linenum, strerror(errno));
	} else {
		output_verbose("%s loaded ok", filepath);
	}

	fclose(fp);
	tzvalid = 1;
}
/**	characters() is where the raw text between the tags is handled.
*/
void gld_loadHndl::characters(const XMLCh* const chars, const unsigned int length){
    char buffer[1024];
	char tbuff[1024];
	wchar_t wbuff[1024];
	SAXParseException *e = NULL;
	char *unit_ptr = NULL;
	unsigned int i = 0;
	size_t len = 0;
	char *retval = NULL;	//	negative logic
	switch(stack_state){
		case MODULE_PROP:
		case GLOBAL_PROP:
		case OBJECT_PROP:
		case CLOCK_PROP:
			//	get prop
			if((len = wcslen((const wchar_t *)chars)) < 1){
				sprintf(tbuff, "Unable to get length of characters in characters()");
				mbstowcs(wbuff, tbuff, 1024);
				e = new SAXParseException((const XMLCh *)wbuff, *(this->locator));
				error(*e);
				delete e;
				return;
			}
			if(len != wcstombs(buffer, (const wchar_t *)chars, 1024)){
				sprintf(tbuff, "Unable to convert wcs to char in characters()");
				mbstowcs(wbuff, tbuff, 1024);
				e = new SAXParseException((const XMLCh *)wbuff, *(this->locator));
				error(*e);
				delete e;
				return;
			}
			break;
		default:
			return;	//	ignore whatever characters we read, we don't use them here.
	}
	if(len > 0){
		int j = 0;
		int i = 0;
		for(i = 0; i < (int)len; ++i){
			if(isspace(buffer[i])){
				++j;
			}
		}
		if(i == j){
			output_verbose("XML_Load: ignored: %i spaces.", length);
			retval = 0;
			return;
		}
	} else {
		output_verbose("XML_Load: ignored empty characters() call");
		retval = 0;
		return;
	}
	if(buffer[0] == '"' && buffer[1] == '"'){
		output_verbose("XML_Load: ignored empty doublequote characters() call");
		retval = 0;
		return;
	}
	switch(stack_state){
		case MODULE_PROP:
			retval = this->read_module_prop(buffer, len);
			break;
		case GLOBAL_PROP:
			retval = this->read_global_prop(buffer, len);
			break;
		case OBJECT_PROP:
			retval = this->read_object_prop(buffer, len);
			//	get prop
			break;
		case CLOCK_PROP:
			retval = this->read_clock_prop(buffer, len);
	}
	if(retval != NULL){
		stack_state = EMPTY;	//	stop processing
		output_error("Error reading the XML file");
		mbstowcs(wbuff, errmsg, 1024);
		e = new SAXParseException((const XMLCh *)wbuff, *(this->locator));
		error(*e);
		delete e;
		load_state = 0;
	}

}
Beispiel #10
0
/** Convert a datetime struct to a string
 **/
int strdatetime(DATETIME *t, char *buffer, int size){
	int len;
	char tbuffer[1024];

	if(t == NULL){
		output_error("strdatetime: null DATETIME pointer passed in");
		return 0;
	}

	if(buffer == NULL){
		output_error("strdatetime: null string buffer passed in");
		return 0;
	}

	/* choose best format */
	if(global_dateformat == DF_ISO){
		if(t->nanosecond != 0){
			len = sprintf(tbuffer, "%04d-%02d-%02d %02d:%02d:%02d.%09d %s",
				t->year, t->month, t->day, t->hour, t->minute, t->second, t->nanosecond, t->tz);
		} else {
			len = sprintf(tbuffer, "%04d-%02d-%02d %02d:%02d:%02d %s",
				t->year, t->month, t->day, t->hour, t->minute, t->second, t->tz);
		}
	} else if(global_dateformat == DF_US){
		if(t->nanosecond != 0){
			len = sprintf(tbuffer, "%02d-%02d-%04d %02d:%02d:%02d.%09d %s",
				t->month, t->day, t->year, t->hour, t->minute, t->second, t->nanosecond, t->tz);
		} else {
			len = sprintf(tbuffer, "%02d-%02d-%04d %02d:%02d:%02d %s",
				t->month, t->day, t->year, t->hour, t->minute, t->second, t->tz);
		}
	} else if(global_dateformat == DF_EURO){
		if(t->nanosecond != 0){
			len = sprintf(tbuffer,"%02d-%02d-%04d %02d:%02d:%02d.%09d %s",
				t->day, t->month, t->year, t->hour, t->minute, t->second, t->nanosecond,t->tz);
		} else {
			len = sprintf(tbuffer,"%02d-%02d-%04d %02d:%02d:%02d %s",
				t->day, t->month, t->year, t->hour, t->minute, t->second,t->tz);
		}
	} else {
		THROW("global_dateformat=%d is not valid", global_dateformat);
		/* TROUBLESHOOT
			The value of the global variable 'global_dateformat' is not valid.
			Check for attempts to set this variable and make sure that is one of the valid
			values (e.g., DF_ISO, DF_US, DF_EURO)
		 */
	}

	if(len < size){
		strncpy(buffer, tbuffer, len+1);
		return len;
	} else {
		output_error("strdatetime: timestamp larger than provided buffer");
		/*	TROUBLESHOOT
			The buffer provided to strdatetime was insufficiently large, or was otherwise packed with
			data beforehand.  The relevant code should use a larger buffer, or the output data set should
			be smaller.
		*/
		return 0;
	}
}
Beispiel #11
0
/** Extract information from an ISO timezone specification
 **/
int tz_info(char *tzspec, char *tzname, char *std, char *dst, time_t *offset){
	int hours = 0, minutes = 0;
	char buf1[32], buf2[32];
	int rv = 0;
	memset(buf1,0,sizeof(buf1));
	memset(buf2,0,sizeof(buf2));


	if ((strchr(tzspec, ':') != NULL ) && (sscanf(tzspec, "%[A-Z]%d:%d%[A-Z]", buf1, &hours, &minutes, buf2) < 3)){
		output_error("tz_info: \'%s\' not a timezone-format string", tzspec);
		return 0;
	}

	rv =  sscanf(tzspec, "%[A-Z]%d%[A-Z]", buf1, &hours, buf2);
	if(rv < 2){
		output_error("tz_info: \'%s\' not a timezone-format string", tzspec);
		return 0;
	}

	if (hours < -12 || hours > 12){
		output_error("timezone %s (%s) has out-of-bounds hour offset of %i", tzname, std, hours);
		return 0;
	}

	if (minutes < 0 || minutes > 59){
		output_error("timezone %s (%s) has out-of-bounds minutes offset of %i", tzname, std, minutes);
		return 0;
	}

	if ( std!=NULL )
	{
		strcpy(std, buf1);
	}
	
	if ( rv>2 && dst!=NULL )
	{
		strcpy(dst, buf2);
	}

	if(minutes == 0) {
		if(tzname){
			sprintf(tzname, "%s%d%s", buf1, hours, (rv == 2 ? "" : buf2));
		}

		if(offset){
			*offset = hours * 3600;
		}

		return 1;
	} else {
		if ( tzname!=NULL )
		{
			sprintf(tzname, "%s%d:%02d%s", buf1, hours, minutes, buf2);
		}
		
		if ( offset!=NULL )
		{
			*offset = hours * 3600 + minutes * 60;
		}

		return 2;
	}
}
Beispiel #12
0
/** Converts a GMT timestamp to local datetime struct
	Adjusts to TZ if possible
 **/
int local_datetime(TIMESTAMP ts, DATETIME *dt)
{

	int64 n;
	TIMESTAMP rem = 0;
	TIMESTAMP local;
	int tsyear;

#ifdef USE_TS_CACHE
	/* allow caching */
	static TIMESTAMP old_ts =0;
	static DATETIME old_dt;
#endif

	if( ts == TS_NEVER || ts==TS_ZERO )
		return 0;

	if( dt==NULL || ts<TS_ZERO || ts>TS_MAX ) /* no buffer or timestamp out of range */
	{
		output_error("local_datetime(ts=%lli,...): invalid local_datetime request",ts);
		return 0;
	}
#ifdef USE_TS_CACHE
	/* check cache */
	if (old_ts == ts && old_ts!=0)
		memcpy(dt,&old_dt,sizeof(DATETIME));
	else
		old_ts = 0;
#endif

	local = LOCALTIME(ts);
	tsyear = timestamp_year(local, &rem);

	if (rem < 0)
	{
		// DPC: note that as of 3.0, the clock is initialized by default, so this error can only
		//      occur when an invalid timestamp is being converted to local time.  It should no
		//      longer occur as a result of a missing clock directive.
		//THROW("local_datetime(ts=%lli, ...): invalid timestamp cannot be converted to local time", ts);
		/*	TROUBLESHOOT
			This is the result of an internal core or module coding error which resulted in an
			invalid UTC clock time being converted to local time.
		*/
		output_error("local_datetime(ts=%lli,...): invalid local_datetime request",ts);
		return 0;
	}

	if(ts < TS_ZERO && ts > TS_MAX){ /* timestamp out of range */
		return 0;
	}
	
	if(ts == TS_NEVER){
		return 0;
	}

	/* ts is valid */
	dt->timestamp = ts;

	/* DST? */
	dt->is_dst = (tzvalid && isdst(ts));

	/* compute year */
	dt->year = tsyear;

	/* yearday and weekday */
	dt->yearday = (unsigned short)(rem / DAY);
	dt->weekday = (unsigned short)((local / DAY + DOW0 + 7) % 7);

	/* compute month */
	dt->month = 0;
	n = daysinmonth[0] * DAY;
	while(rem >= n){
		rem -= n; /* subtract n ticks from ts */
		dt->month++; /* add to month */
		if(dt->month == 12){
			dt->month = 0;
			++dt->year;
		}
		n = (daysinmonth[dt->month] + ((dt->month == 1 && ISLEAPYEAR(dt->year)) ? 1:0)) * 86400 * TS_SECOND;
		if(n < 86400 * 28){ /**/
			output_fatal("Breaking an infinite loop in local_datetime! (ts = %"FMT_INT64"ds", ts);
			/*	TROUBLESHOOT
				An internal protection against infinite loops in the time calculation
				module has encountered a critical problem.  This is often caused by
				an incorrectly initialized timezone system, a missing timezone specification before
				a timestamp was used, or a missing timezone localization in your system.
				Correct the timezone problem and try again.
			 */
			return 0;
		}
	}
	dt->month++; /* Jan=1 */

	/* compute day */
	dt->day = (unsigned short)(rem / DAY + 1);
	rem %= DAY;

	/* compute hour */
	dt->hour = (unsigned short)(rem / HOUR);
	rem %= HOUR;

	/* compute minute */
	dt->minute = (unsigned short)(rem / MINUTE);
	rem %= MINUTE;

	/* compute second */
	dt->second = (unsigned short)rem / TS_SECOND;
	rem %= SECOND;

	/* compute nanosecond */
	dt->nanosecond = (unsigned int)(rem * 1e9);

	/* determine timezone */
	strncpy(dt->tz, tzvalid ? (dt->is_dst ? tzdst : tzstd) : "GMT", sizeof(dt->tz));

	/* timezone offset in seconds */
	dt->tzoffset = tzoffset - (isdst(dt->timestamp)?3600:0);

#ifdef USE_TS_CACHE
	/* cache result */
	old_ts = ts;
	memcpy(&old_dt,dt,sizeof(old_dt));
#endif
	return 1;
}
Beispiel #13
0
/** sanitize

	Sanitizes a gridlabd model by clear names and position from object headers

    @returns 0 on success, -2 on error
 **/
extern "C" int sanitize(int argc, char *argv[])
{
	OBJECT *obj;
	FILE *fp;
	double delta_latitude, delta_longitude;

	// lat/lon change
	if ( strcmp(global_sanitizeoffset,"")==0 )
	{
		delta_latitude = random_uniform(NULL,-5,+5);
		delta_longitude = random_uniform(NULL,-180,+180);
	}
	else if ( global_sanitizeoffset=="destroy" )
		delta_latitude = delta_longitude = QNAN;
	else if ( sscanf(global_sanitizeoffset.get_string(),"%lf%*[,/]%lf",&delta_latitude,&delta_longitude)!=2 )
	{
		output_error("sanitize_offset lat/lon '%s' is not valid", global_sanitizeoffset.get_string());
		return -2;
	}

	// sanitize object names
	for ( obj=object_get_first() ; obj!=NULL ; obj=object_get_next(obj) )
	{
		if ( obj->name!=NULL && (global_sanitizeoptions&SO_NAMES)==SO_NAMES )
			sanitize_name(obj);
		if ( isfinite(obj->latitude) && (global_sanitizeoptions&SO_GEOCOORDS)==SO_GEOCOORDS )
		{
			obj->latitude += delta_latitude;
			if ( obj->latitude<-90 ) obj->latitude = -90;
			if ( obj->latitude>+90 ) obj->latitude = +90;
		}
		if ( isfinite(obj->longitude) && (global_sanitizeoptions&SO_GEOCOORDS)==SO_GEOCOORDS )
			obj->longitude = fmod(obj->longitude+delta_longitude,360);
	}

	// dump object name index
	if ( strcmp(global_sanitizeindex,".xml")==0 )
	{
		strcpy(global_sanitizeindex,global_modelname);
		char *ext = strrchr(global_sanitizeindex,'.');
		if ( ext && strcmp(ext,".glm")==0 ) strcpy(ext,"-index.xml");
		else strcat(global_sanitizeindex,"-index.xml");
	}
	else if ( strcmp(global_sanitizeindex,".txt")==0 )
	{
		strcpy(global_sanitizeindex,global_modelname);
		char *ext = strrchr(global_sanitizeindex,'.');
		if ( ext && strcmp(ext,".glm")==0 ) strcpy(ext,"-index.txt");
		else strcat(global_sanitizeindex,"-index.txt");
	}
	else if ( global_sanitizeindex[0]=='.' )
	{
		output_error("sanitization index file spec '%s' is not recognized", global_sanitizeindex.get_string());
		return -2;
	}
	if ( strcmp(global_sanitizeindex,"")!=0 )
	{
		char *ext = strrchr(global_sanitizeindex,'.');
		bool use_xml = (ext && strcmp(ext,".xml")==0) ;
		fp = fopen(global_sanitizeindex,"w");
		if ( fp )
		{
			SAFENAME *item;
			if ( use_xml )
			{
				fprintf(fp,"<data>\n");
				fprintf(fp,"\t<modelname>%s</modelname>\n",global_modelname);
				fprintf(fp,"\t<geographic_offsets>\n");
				fprintf(fp,"\t\t<latitude>%.6f</latitude>\n",delta_latitude);
				fprintf(fp,"\t\t<longitude>%.6f</longitude>\n",delta_longitude);
				fprintf(fp,"\t</geographic_offsets>\n");
				fprintf(fp,"\t<safename_list>\n");
				for ( item=safename_list ; item!=NULL ; item=item->next )
					fprintf(fp,"\t\t<name>\n\t\t\t<safe>%s</safe>\n\t\t\t<unsafe>%s</unsafe>\n\t\t</name>\n", item->name, item->old);
				fprintf(fp,"\t</safename_list>\n");
				fprintf(fp,"</data>\n");
			}
			else
			{
				fprintf(fp,"modelname\t= %s\n", global_modelname);
				fprintf(fp,"\n[POSITIONS]\n");
				fprintf(fp,"latitude\t= %.6f\n",delta_latitude);
				fprintf(fp,"longitude\t= %.6f\n",delta_longitude);
				fprintf(fp,"\n[NAMES]\n");
				for ( item=safename_list ; item!=NULL ; item=item->next )
					fprintf(fp,"%s\t= %s\n", item->name, item->old);
			}
			fclose(fp);
		}
	}

	return 0;
}
Beispiel #14
0
uint_t		get_midi_meta_event(midimev_t *metaev, byte_t *buffer)
{
  uint_t offset = 0;
  /* byte_t type; */

  switch (buffer[offset])
    {
    case ME_SEQUENCENUMBER:
      /* debug_midifile("*** Sequence number event ***\n"); */
      offset++;
      if (buffer[offset] != 2)
	{
	  output_error("Error: unexpected size\n");
	  return FALSE;
	}
      offset++;
      metaev->type = ME_SEQUENCENUMBER;

      metaev->val = (buffer[offset] << 8) + buffer[offset + 1];
      /* debug_midifile("\tSequence number: %i\n", metaev->val); */
      offset += 2;
      break;

    case ME_TEXTEVENT:
      offset++;
      get_midifile_asciitext(buffer, metaev, &offset);
      metaev->type = ME_TEXTEVENT;
      offset += metaev->val;
      break;

    case ME_COPYRIGHTNOTICE:
      offset++;
      get_midifile_asciitext(buffer, metaev, &offset);
      metaev->type = ME_COPYRIGHTNOTICE;
      offset += metaev->val;
      break;

    case ME_NAME:
      /* debug_midifile("*** Sequence name event ***\n"); */
      offset++;
      get_midifile_asciitext(buffer, metaev, &offset);
      metaev->type = ME_NAME;
      /* debug_midifile("\tSequence name: %s (size=%d)\n", (char *) metaev->data, metaev->val); */

      offset += metaev->val;
      break;

    case ME_CUEPOINT:
      offset++;
      get_midifile_asciitext(buffer, metaev, &offset);
      metaev->type = ME_CUEPOINT;

      offset += metaev->val;
      break;

    case ME_ENDOFTRACK:
      /* debug_midifile("*** End of track event %p ***\n", &(buffer[offset]) + 2); */
      metaev->type = ME_ENDOFTRACK;
      offset++;
      break;

    case ME_SETTEMPO:
      /* debug_midifile("*** Set tempo event ***\n"); */
      offset++;
      if (buffer[offset] != 3)
	{
	  output_error("Error: unexpected size\n");
	  return 0;
	}
      offset++;
      metaev->type = ME_SETTEMPO;

      metaev->val = (buffer[offset] << 16) + (buffer[offset + 1] << 8) + buffer[offset + 2];
      /* metaev->val = (buffer[offset]) + (buffer[offset + 1] << 8) + (buffer[offset + 2] << 16); */
      debug_midi("\ttempo: %i (micro second / quarter note)\n", metaev->val);
      offset += 3;
      break;

    case ME_SMPTE_OFFSET:
      /* debug_midi("*** SMPTE offset event ***\n"); */
      offset++;
      if (buffer[offset] != 5)
	{
	  output_error("Error: unexpected size\n");
	  return 0;
	}
      offset++;
      metaev->type = ME_SMPTE_OFFSET;
      /* debug_midi("\tTime: %i:%02i:%02i\n" */
      /* 	  "\tFr: %i\n" */
      /* 	  "\tSubFr: %i\n", */
      /* 	 y a d truc; a faire ;ici c pas ;bon du tout  buffer[0] & 127 >> 7 ? , buffer[1], buffer[2], buffer[3], buffer[4]); */
      offset += 5;
      break;

    case ME_TIMESIGNATURE:
      /* debug_midi("*** Time Signature event ***\n"); */
      offset++;
      if (buffer[offset] != 4)
	{
	  output_error("Error: unexpected size\n");
	  return 0;
	}
      offset++;
      metaev->type = ME_TIMESIGNATURE;

      /* debug_midi("\tNumerator of time sig: %i\n" */
      /*       "\tDenominator of time sig: %i\n" */
      /*       "\tNumber of ticks in metronome click: %i\n" */
      /*       "\tNumber of 32nd notes to the quarter note: %i\n", */
      /*       buffer[offset], buffer[offset + 1], buffer[offset + 2], buffer[offset + 3]); */
      offset += 4;
      break;

    case ME_KEYSIGNATURE:
      /* debug_midi("*** Key Signature event ***\n"); */
      offset++;
      if (buffer[offset] != 2)
	{
	  output_error("Error: unexpected size\n");
	  return 0;
	}
      offset++;
      metaev->type = ME_KEYSIGNATURE;

      /* debug_midi("\tsharps/flats %i\n" */
      /*       "\tmajor/minor %i\n", */
      /*       buffer[offset], buffer[offset + 1]); */
      offset += 2;
      break;

    case ME_SEQUENCERSPECIFIC:
      /* debug_midi("*** Sequencer Specific event ***\n"); */
      offset++;
      metaev->val = get_varlen_from_idx(buffer, &offset);
      metaev->type = ME_SEQUENCERSPECIFIC;

      /* debug_midi("\t Manufacturer's ID %i\n", */
      /*       buffer[offset]); */
      offset += metaev->val;
      break;

    default:
      debug_midi("!!! UNKNOWN meta event hex:0x%02X dec:%i\n",
                 buffer[offset],
                 buffer[offset]);
      metaev->type = buffer[offset];
      offset++;
      offset += get_varlen_from_idx(buffer, &offset);
      debug_midi("offset=%u\n\n", offset);
      break;
    }
  return offset;
}
Beispiel #15
0
static SIMULATIONMODE delta_clockupdate(DT timestep, SIMULATIONMODE interupdate_result)
{
	clock_t t = clock();
	double nextTime = 0;
	DT exitDeltaTimestep = 0;
	MODULE ** module;
	SIMULATIONMODE rv = SM_DELTA;
	SIMULATIONMODE result = SM_EVENT;
	if(interupdate_result == SM_DELTA)
	{
		//calculate the next timestep that we are going to in nanoseconds
		nextTime = global_delta_curr_clock + ((double)timestep)/((double)DT_SECOND);
		for(module=delta_modulelist; module < (delta_modulelist + delta_modulecount); module++)
		{
			if((*module)->deltaClockUpdate != NULL)
			{
				result = (*module)->deltaClockUpdate(*module, nextTime, timestep, interupdate_result);
				switch ( result )
				{
				case SM_DELTA_ITER:
					output_error("delta_clockupdate(): It is too late to reiterate on the current time step.");
					return SM_EVENT;
				case SM_DELTA:
						rv = SM_DELTA;
					/* default else - leave it as is (SM_DELTA_ITER) */
					break;
				case SM_ERROR:
					return SM_ERROR;
				case SM_EVENT:
					rv = SM_DELTA;
					break;
				default: /* mode remains untouched */
					break;
				}
			}
		}
	} else if(interupdate_result == SM_EVENT) {
		// we are exiting deltamode so we need to determine the timestep to the next whole second.
		nextTime = ceil(global_delta_curr_clock);
		exitDeltaTimestep = (DT)((nextTime - global_delta_curr_clock)*DT_SECOND);
		for(module=delta_modulelist; module < (delta_modulelist + delta_modulecount); module++)
		{
			if((*module)->deltaClockUpdate != NULL)
			{
				result = (*module)->deltaClockUpdate(*module, nextTime, exitDeltaTimestep, interupdate_result);
				switch ( result )
				{
				case SM_DELTA_ITER:
					output_error("delta_clockupdate(): It is too late to reiterate on the current time step.");
					return SM_ERROR;
				case SM_DELTA:
					output_error("delta_clockupdate(); Every object wishes to exit delta mode. It is too late to stay in it.");
					/* default else - leave it as is (SM_DELTA_ITER) */
					return SM_ERROR;
					break;
				case SM_ERROR:
					return SM_ERROR;
				case SM_EVENT:
					rv = SM_EVENT;
					break;
				default: /* mode remains untouched */
					break;
				}
			}
		}
	}
	profile.t_clockupdate += clock() - t;
	return rv;
}
char *gld_loadHndl::start_element_module_build_object(const Attributes &attributes){
	static wchar_t str_id[3],
			str_name[5],
			str_type[5];
	static size_t str_id_len = mbstowcs(str_id, "id", 3),
			str_name_len = mbstowcs(str_name, "name", 5),
			str_type_len = mbstowcs(str_type, "type", 5);
	char object_type[64],
		object_id[64],
		object_name[64];
	char *temp = NULL;
	char *retval = NULL;
	int first = -1,
		last = -1;
	if(attributes.getIndex((const XMLCh *) str_type) < 0){
		sprintf(errmsg, "object tag without a type in start_element_module_build_object()");
		return errmsg;
	} else {
		wcstombs(object_type, (const wchar_t *)attributes.getValue((const XMLCh *) str_type), 64);
		oclass = class_get_class_from_classname_in_module(object_type, module);
		if(oclass == NULL){
			sprintf(errmsg, "Class \"%s\" for module \"%s\"is not recognized in start_element_module_build_object()", object_type, module->name);
			return errmsg;
		} else {
			; /* recognized class type */
		}
	}
	if(attributes.getIndex((const XMLCh *) str_id) < 0){
		/* anonymous objects are legit - mh */
		last = first = -1;
	} else {
		wcstombs(object_id, (wchar_t *)attributes.getValue((const XMLCh *) str_id), 64);
		temp = strchr(object_id, '.');
		if(temp == NULL){ /* no "..", just a number*/
			first = strtol(object_id, NULL, 10);
			if(first < 0){
				sprintf(errmsg, "Invalid object id of %i in start_element_module_build_object()", first);
				return errmsg;
			} else {
				last = first;
			}
		} else {
			if(temp[0] == temp[1]){
				if(temp == object_id){ /* "..x", count */
					last = strtol(object_id+2, NULL, 10);
					if(last < 1){
						sprintf(errmsg, "Invalid object id of %i in start_element_module_build_object()", first);
						return errmsg;
					} else {
						first = -1;
					}
				} else { /* "x..y", range */
					*temp = 0;
					first = strtol(object_id, NULL, 10);
					last = strtol(temp+2, NULL, 10);
					*temp = '.';
					if(first < 0){
						output_error("XML_Load: first ID < 0 !");
						sprintf(errmsg, "Invalid object id of %i in start_element_module_build_object()", first);
						return errmsg;
					}
					if(last < 1){
						output_error("XML_Load: last ID < 1 !");
						sprintf(errmsg, "Invalid object id of %i in start_element_module_build_object()", first);
						return errmsg;
					}
					if(first >= last){
						output_error("XML_Load: first id >= last id!");
						sprintf(errmsg, "Invalid object id of %i in start_element_module_build_object()", first);
						return errmsg;
					}
				}
			} else {
				sprintf(errmsg, "Invalid ID format in start_element_module_build_object()");
				return errmsg;
			}
		}
	}
	if((retval = build_object_vect(first, last)) != 0){ /* unable to call constructors */
		sprintf(errmsg, "Unable to create objects in start_element_module_build_object()");
		return errmsg;
	} else {
		;
	}
	if(attributes.getIndex((const XMLCh *) str_name) < 0){
		strcpy(object_name, "(none)");
	} else {
		wcstombs(object_name, (wchar_t *)attributes.getValue((const XMLCh *) str_name), 64);
		object_set_name(obj, object_name);
	}
	//printf("object: type = %s, id = %s, name = %s\n", object_type, object_id, object_name);
	stack_state = OBJECT_STATE;
	return NULL;
}
Beispiel #17
0
command_stream_t
make_command_stream (int (*get_next_byte) (void *),
		     void *get_next_byte_argument)
{
  size_t size = 1000;
  char *buf = (char*) checked_malloc(size); 
  size_t i = 0;
  char c = get_next_byte(get_next_byte_argument);
  while(c != EOF)
  { 
     if(i >= size)
	checked_grow_alloc(buf, &size);
     buf[i]=c;
     c = get_next_byte(get_next_byte_argument);
     i += sizeof(char);
  }
  
  buf[i] = '\0';
  char* err_buf = checked_malloc(size);
  strcpy(err_buf, buf);
  //printf("%s\n", buf);
  // char delimiters  = 'a';
  char* token = strtok(buf, "\n"); 
  size = 1000;
  i = 0;
  // printf("here\n");
  command_stream_t result = checked_malloc(sizeof(command_stream_t));
  result->my_commands = checked_malloc(size);
  result->size = 0;
  result->next_pos = 0;

  while(token != NULL)
  {
    
     //printf("%s\n", token);
     if(analyze_token(token))
     {	
        //printf("%s\n", token);
  	result->my_commands[result->size] = process_buffer(token);
	//printf("Finished: %s\n", token);
	if(result->my_commands[result->size] == NULL)
	{}
	else if(result->my_commands[result->size]->status <= -2)
	{
	   // printf("BUF: %s\n", err_buf);
	   output_error(err_buf, token,
			result->my_commands[result->size]->status);
	}
	else
	{
	// print_command(result->my_commands[command_count]);
           result->size++;
        }
        token = strtok(NULL, "\n"); 
     //   printf("%s\n", token);
     }
     else
     {
       // printf("%s\n", token);
	char *temp = strtok(NULL, "\n");
	//printf("NEXT TOKEN: %s\n", temp);
	if(temp!=NULL)
	{
		strcat(token,temp);
        	printf("%s\n", token);
	}
	else
	   output_error(err_buf, token,0);
     }
  }


/*ONE COMMAND TESTING PURPOSES ONLY
  command_t e1 =  process_buffer(set_of_tokens[0]);
  if(e1==NULL)
  {
	printf("NULL command, comment");
	return result;
  }
  // printf("Word 1: %s %d\n", e1->u.word[2], strlen(e1->u.word[0]));
  print_command(e1);
  // while(e1->u.word[index] != NULL)
  result->my_commands[0] = e1;
*/
  return result;

}
void gld_loadHndl::fatalError(const SAXParseException& e){
	output_error("XML_Load: %ls(%i:char %i)\n Message: %ls", (char *)e.getSystemId(), e.getLineNumber(), e.getColumnNumber(), (char *)e.getMessage());
	load_state = false;
}
Beispiel #19
0
/** Process an incoming XML data request
	@returns non-zero on success, 0 on failure (errno set)
 **/
int http_xml_request(HTTPCNX *http,char *uri)
{
	char arg1[1024]="", arg2[1024]="";
	int nargs = sscanf(uri,"%1023[^/=\r\n]/%1023[^\r\n=]",arg1,arg2);
	char *value = strchr(uri,'=');
	char buffer[1024]="";
	OBJECT *obj=NULL;
	char *id;

	/* value */
	if (value) *value++;

	/* decode %.. */
	http_decode(arg1);
	http_decode(arg2);
	if (value) http_decode(value);

	/* process request */
	switch (nargs) {

	/* get global variable */
	case 1: 

		/* find the variable */
		if (global_getvar(arg1,buffer,sizeof(buffer))==NULL)
		{
			output_error("global variable '%s' not found", arg1);
			return 0;
		}

		/* assignment, if any */
		if (value) global_setvar(arg1,value);
		
		/* post the response */
		http_format(http,"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
		http_format(http,"<globalvar>\n\t<name>%s</name>\n\t<value>%s</value>\n</globalvar>\n",
			arg1, http_unquote(buffer));
		http_type(http,"text/xml");
		return 1;

	/* get object property */
	case 2:

		/* find the object */
		id = strchr(arg1,':');
		if ( id==NULL )
			obj = object_find_name(arg1);
		else
			obj = object_find_by_id(atoi(id+1));
		if ( obj==NULL )
		{
			output_error("object '%s' not found", arg1);
			return 0;
		}

		/* post the current value */
		if ( !object_get_value_by_name(obj,arg2,buffer,sizeof(buffer)) )
		{
			output_error("object '%s' property '%s' not found", arg1, arg2);
			return 0;
		}

		/* assignment, if any */
		if ( value && !object_set_value_by_name(obj,arg2,value) )
		{
			output_error("cannot set object '%s' property '%s' to '%s'", arg1, arg2, value);
			return 0;
		}

		/* post the response */
		http_format(http,"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<property>\n");
		http_format(http,"\t<object>%s</object>\n", arg1);
		http_format(http,"\t<name>%s</name>\n", arg2);
		http_format(http,"\t<value>%s</value>\n", http_unquote(buffer));
		/* TODO add property type info */
		http_format(http,"</property>\n");
		http_type(http,"text/xml");
		return 1;

	default:
		return 0;
	}
	return 0;
}
void gld_loadHndl::startElement(const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname,
								const Attributes& attributes){
	char buffer[128];
	char *temp = NULL;
	unsigned int i = 0;
	size_t len = 0;
	char *retval = 0;	//	negative logic
	gldStack *currStack = NULL;
	wchar_t str_id[3],	/* = "id", */
			str_name[5],/* = "name", */
			str_type[5];/* = "type"; */

	mbstowcs(str_id, "id", 3);
	mbstowcs(str_name, "name", 5);
	mbstowcs(str_type, "type", 5);

	if((len = wcslen((const wchar_t *)qname)) < 1){
		output_error("startElement: Unable to parse element tag length!");
		load_state = 0;
		return;
	}
	if(wcstombs(buffer, (const wchar_t *)qname, 128) < 1){
		output_error("startElement: Unable to convert element tag name from wchar to char!");
		load_state = 0;
		return;
	}
	switch(this->stack_state){
		case EMPTY:
			retval = start_element_empty(buffer, len, attributes);
			break;
		case LOAD:
			retval = start_element_load(buffer, len, attributes);
			break;
		case MODULE_STATE:
			retval = start_element_module(buffer, len, attributes);
			break;
		case MODULE_PROP:
			retval = start_element_module_prop(buffer, len, attributes);
			break;
		case OBJECT_STATE:
			retval = start_element_object(buffer, len, attributes);
			break;
		case OBJECT_PROP:
			retval = start_element_object_prop(buffer, len, attributes);
			break;
		case GLOBAL_STATE:
			retval = start_element_global(buffer, len, attributes);
			break;
		case GLOBAL_PROP:
			retval = start_element_global_prop(buffer, len, attributes);
			break;
		case CLOCK_STATE:
			retval = start_element_clock(buffer, len, attributes);
			break;
		case CLOCK_PROP:
			retval = start_element_clock_prop(buffer, len, attributes);
			break;
	}
	if(retval != NULL){
		char tbuff[256];
		wchar_t wbuff[256];
		SAXParseException *e = NULL;
		sprintf(tbuff, "Error in start_element with tag \"%s\": %s", buffer, retval);
		mbstowcs(wbuff, tbuff, 1024);
		e = new SAXParseException((const XMLCh *)wbuff, *(this->locator));
		error(*e);
		delete e;
	}
}
Beispiel #21
0
glxlink::glxlink(char *filename)
{
	bool ok = true;
	globals = NULL;
	imports = NULL;
	exports = NULL;
	objects = NULL;
	handle = NULL;
	settag = NULL;
	init = NULL;
	sync = NULL;
	term = NULL;
	glxflags = 0;
	valid_to = 0;
	last_t = 0;

	FILE *fp = fopen(filename,"rt");
	if ( fp==NULL )
		throw "file open failed";
	output_debug("opened link '%s'", filename);

	char line[1024];
	int linenum=0;
	while ( fgets(line,sizeof(line),fp)!=NULL )
	{
		linenum++;
		if ( line[0]=='#' ) continue;
		char tag[64], data[1024]="";
		if ( sscanf(line,"%s %[^\r\n]",tag,data)>0 )
		{
			output_debug("%s(%d): %s %s", filename, linenum, tag,data);
			if ( settag!=NULL )
			{
				if ( strcmp(tag,"global")==0 )
				{
					add_global(data);
				}
				else if ( strcmp(tag,"object")==0 )
				{
					add_object(data);
				}
				else if ( strcmp(tag,"export")==0 )
				{
					add_export(data);
				}
				else if ( strcmp(tag,"import")==0 )
				{
					add_import(data);
				}
				else if ( !(*settag)(this,tag,data) )
					output_error("%s(%d): tag '%s' not accepted", filename, linenum, tag);
			}
			else if ( strcmp(tag,"target")==0)
			{
				if ( !set_target(data) )
				{
					output_error("%s(%d): target '%s' is not valid", filename, linenum, data);
					ok = false;
				}
			}
			else
				output_warning("%s(%d): tag '%s' cannot be processed until target module is loaded", filename, linenum, tag);
		}
	}

	fclose(fp);

	// append to link list
	next = first;
	first = this;

	if ( ok )
		output_verbose("link '%s' ok", filename);
	else
		throw "cannot establish link";
}
Beispiel #22
0
quota_t *quota_new (int q_type, int id, char *fs_spec)
{
  quota_t *myquota;
  fs_t *fs;
  char *qfile;

  q_type--;			/* see defs in quota.h */
  if ( q_type >= MAXQUOTAS ) {
    output_error ("Unknown quota type: %d", q_type);
    return 0;
  }

  myquota = (quota_t *) malloc (sizeof(quota_t));
  if ( ! myquota ) {
    output_error ("Insufficient memory");
    exit (ERR_MEM);
  }

  fs = system_getfs (fs_spec);
  if ( ! fs ) {
    return NULL;
  }

  /*
   * Detect quota format
   */
  output_debug("Detecting quota format");
  if (kern_quota_format(fs, q_type) == QF_ERROR) {
     output_error("Cannot determine quota format!");
     exit (ERR_SYS);
  }
  if (QF_IS_TOO_NEW(quota_format)) {
     output_error("Quota format too new (?)");
     exit (ERR_SYS);
  }
  if (QF_IS_XFS(quota_format)) {
     output_debug("Detected quota format: XFS");
  }
  if (QF_IS_V0(quota_format)) {
     output_debug("Detected quota format: VFSV0");
     if (IF_GENERIC) {
       output_debug("Detected quota interface: GENERIC");
     }
     else {
       myquota->_v0_quotainfo = (struct v0_kern_dqinfo *) 0;
       myquota->_v0_quotainfo = (struct v0_kern_dqinfo *) malloc (sizeof(struct v0_kern_dqinfo));
       if ( ! myquota->_v0_quotainfo ) {
	 output_error ("Insufficient memory");
	 exit (ERR_MEM);
       }
     }
  }
  else if (QF_IS_V1(quota_format)) {
     output_debug("Detected quota format: VFSV1");
     if (IF_GENERIC) {
       output_debug("Detected quota interface: GENERIC");
     }
     else {
       output_error("Unsupported quota format: VFSV1 but not GENERIC, please report Issue on github: https://github.com/ekenberg/quotatool");
       exit(ERR_SYS);
     }
  }
  else if (QF_IS_OLD(quota_format)) {
     output_debug("Detected quota format: OLD");
     if (IF_GENERIC) {
       output_debug("Detected quota interface: GENERIC");
     }
  }
  else if (! QF_IS_XFS(quota_format)) {
     output_error("Unknown quota format!");
     exit(ERR_SYS);
  }
  if (IF_GENERIC) {
       myquota->_generic_quotainfo = (struct if_dqinfo *) 0;
       myquota->_generic_quotainfo = (struct if_dqinfo *) malloc (sizeof(struct if_dqinfo));
       if ( ! myquota->_generic_quotainfo ) {
	 output_error ("Insufficient memory");
	 exit (ERR_MEM);
       }
  }

  qfile = strdup (fs->device);

  myquota->_id = id;
  myquota->_id_type = q_type;
  myquota->_qfile = qfile;

  free (fs);
  return myquota;
}
Beispiel #23
0
/** Convert to a \e complex_array data type
	Converts a string to a \e complex_array data type property.  
	@return 1 on success, 0 on failure, -1 if conversion was incomplete
 **/
int convert_to_complex_array(const char *buffer, void *data, PROPERTY *prop)
{
	complex_array *a=(complex_array*)data;
	unsigned row=0, col=0;
	const char *p = buffer;
	
	/* new array */
	/* parse input */
	for ( p=buffer ; *p!='\0' ; )
	{
		char value[256];
		char objectname[64], propertyname[64];
		complex c;
		while ( *p!='\0' && isspace(*p) ) p++; /* skip spaces */
		if ( *p!='\0' && sscanf(p,"%s",value)==1 )
		{

			if ( *p==';' ) /* end row */
			{
				row++;
				col=0;
				p++;
				continue;
			}
			else if ( strnicmp(p,"NAN",3)==0 ) /* NULL value */
			{
				a->grow_to(row,col);
				a->clr_at(row,col);
				col++;
			}
			else if ( convert_to_complex(value,(void*)&c,prop) ) /* probably real value */
			{
				a->grow_to(row,col);
				a->set_at(row,col,c);
				col++;
			}
			else if ( sscanf(value,"%[^.].%[^; \t]",objectname,propertyname)==2 ) /* object property */
			{
				OBJECT *obj = object_find_name(objectname);
				PROPERTY *prop;
				if ( obj==NULL )
				{
					output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d - object '%s' not found", buffer,row,col,objectname);
					return 0;
				}
				prop = object_get_property(obj,propertyname,NULL);
				if ( prop==NULL )
				{
					output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d - property '%s' not found in object '%s'", buffer,row,col,propertyname,objectname);
					return 0;
				}
				a->grow_to(row,col);
				a->set_at(row,col,object_get_complex(obj,prop));
				if ( a->is_nan(row,col) )
				{
					output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d property '%s' in object '%s' is not accessible", buffer,row,col,propertyname,objectname);
					return 0;
				}
				col++;
			}
			else if ( sscanf(value,"%[^; \t]",propertyname)==1 ) /* object property */
			{
				GLOBALVAR *var = global_find(propertyname);
				if ( var==NULL )
				{
					output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d global '%s' not found", buffer,row,col,propertyname);
					return 0;
				}
				a->grow_to(row,col);
				a->set_at(row,col,(complex*)var->prop->addr);
				if ( a->is_nan(row,col) )
				{
					output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d property '%s' in object '%s' is not accessible", buffer,row,col,propertyname,objectname);
					return 0;
				}
				col++;
			}
			else /* not a valid entry */
			{
				output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d is not valid (value='%10s')", buffer,row,col,p);
				return 0;
			}
			while ( *p!='\0' && !isspace(*p) && *p!=';' ) p++; /* skip characters just parsed */
		}
	}
	return 1;
}
Beispiel #24
0
int kern_quota_format(fs_t *fs, int q_type) {
   u_int32_t version;
   struct v0_dqstats v0_stats;
   FILE *f;
   int ret = 0;
   struct stat st;

   if (strcasecmp(fs->mnt_type, "xfs") == 0) {
      if (stat("/proc/fs/xfs/stat", &st) == 0) {
	 quota_format |= (1 << QF_XFS);
	 return ret;
      }
      else {
	 output_error("%s is mounted as XFS but no kernel support for XFS quota!", fs->device);
	 exit(ERR_SYS);
      }
   }

   if ((f = fopen("/proc/fs/quota", "r"))) {
      if (fscanf(f, "Version %u", &version) != 1) {
	 fclose(f);
	 return QF_TOONEW;
      }
      fclose(f);
   }
   else if (stat("/proc/sys/fs/quota", &st) == 0) {
      /* Either QF_VFSOLD or QF_VFSV0 or QF_VFSV1 */
      int actfmt, retval;
      kernel_iface = IFACE_GENERIC;
      retval = quotactl(QCMD(Q_GETFMT, q_type), fs->device, 0, (void *) &actfmt);
      if (retval < 0) {
	 if (! QF_IS_XFS(quota_format)) {
	    output_error("Error while detecting kernel quota version: %s\n", strerror(errno));
	    exit(ERR_SYS);
	 }
      }
      else {
	 if (actfmt == 1)  /* Q_GETFMT retval for QF_VFSOLD */
	    quota_format |= (1 << QF_VFSOLD);
	 else if (actfmt == 2)  /* Q_GETFMT retval for QF_VFSV0 */
	    quota_format |= (1 << QF_VFSV0);
	 else if (actfmt == 4)  /* Q_GETFMT retval for QF_VFSV1 */
	    quota_format |= (1 << QF_VFSV1);
	 else {
            output_debug("Unknown Q_GETFMT: %d\n", actfmt);
	    return QF_ERROR;
         }
      }
      return ret;
   }
   else if (quotactl(QCMD(Q_V0_GETSTATS, 0), NULL, 0, (void *) &v0_stats) >= 0) {
      version = v0_stats.version;	/* Copy the version */
   }
   else {
      if (errno == ENOSYS || errno == ENOTSUP)	/* Quota not compiled? */
	 return QF_ERROR;
      if (errno == EINVAL || errno == EFAULT || errno == EPERM) {	/* Old quota compiled? */
	 /* RedHat 7.1 (2.4.2-2) newquota check
	  * Q_V0_GETSTATS in it's old place, Q_GETQUOTA in the new place
	  * (they haven't moved Q_GETSTATS to its new value) */
	 int err_stat = 0;
	 int err_quota = 0;
	 char tmp[1024];         /* Just temporary buffer */

	 if (quotactl(QCMD(Q_OLD_GETSTATS, 0), NULL, 0, tmp))
	    err_stat = errno;
	 if (quotactl(QCMD(Q_OLD_GETQUOTA, 0), "/dev/null", 0, tmp))
	    err_quota = errno;

	 /* On a RedHat 2.4.2-2 	we expect 0, EINVAL
	  * On a 2.4.x 		we expect 0, ENOENT
	  * On a 2.4.x-ac	we wont get here */
	 if (err_stat == 0 && err_quota == EINVAL) {
	    quota_format |= (1 << QF_VFSV0);	/* New format supported */
	    kernel_iface = IFACE_VFSV0;
	 }
	 else {
	    quota_format |= (1 << QF_VFSOLD);
	    kernel_iface = IFACE_VFSOLD;
	 }
	 return ret;
      }
      output_error("Error while detecting kernel quota version: %s\n", strerror(errno));
      exit(ERR_SYS);
   }
   if (version > KERN_KNOWN_QUOTA_VERSION)	/* Newer kernel than we know? */
      quota_format = QF_TOONEW;
   if (version <= 6*10000+4*100+0) {		/* Old quota format? */
      quota_format |= (1 << QF_VFSOLD);
      kernel_iface = IFACE_VFSOLD;
   }
   else {
      quota_format |= (1 << QF_VFSV0);			/* New format supported */
      kernel_iface = IFACE_VFSOLD;
   }
   return ret;
}
Beispiel #25
0
/** Convert to a \e double_array data type
	Converts a string to a \e double_array data type property.  
	@return 1 on success, 0 on failure, -1 if conversion was incomplete
 **/
int convert_to_double_array(const char *buffer, void *data, PROPERTY *prop)
{
	double_array *a=(double_array*)data;
	a->set_name(prop->name);
	unsigned row=0, col=0;
	const char *p = buffer;
	
	/* new array */
	/* parse input */
	for ( p=buffer ; *p!='\0' ; )
	{
		char value[256];
		char objectname[64], propertyname[64];
		while ( *p!='\0' && isspace(*p) ) p++; /* skip spaces */
		if ( *p!='\0' && sscanf(p,"%s",value)==1 )
		{

			if ( *p==';' ) /* end row */
			{
				row++;
				col=0;
				p++;
				continue;
			}
			else if ( strnicmp(p,"NAN",3)==0 ) /* NULL value */
			{
				a->grow_to(row,col);
				a->clr_at(row,col);
				col++;
			}
			else if ( isdigit(*p) || *p=='.' || *p=='-' || *p=='+' ) /* probably real value */
			{
				a->grow_to(row+1,col+1);
				a->set_at(row,col,atof(p));
				col++;
			}
			else if ( sscanf(value,"%[^.].%[^; \t]",objectname,propertyname)==2 ) /* object property */
			{
				OBJECT *obj = load_get_current_object();
				if ( obj!=NULL && strcmp(objectname,"parent")==0 )
					obj = obj->parent;
				else if ( strcmp(objectname,"this")!=0 )
					obj = object_find_name(objectname);
				if ( obj==NULL )
				{
					output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d - object property '%s' not found", buffer,row,col,objectname);
					return 0;
				}
				PROPERTY *prop = object_get_property(obj,propertyname,NULL);
				if ( prop==NULL )
				{
					output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d - property '%s' not found in object '%s'", buffer,row,col,propertyname,objectname);
					return 0;
				}
				a->grow_to(row+1,col+1);
				a->set_at(row,col,object_get_double(obj,prop));
				if ( a->is_nan(row,col) )
				{
					output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d property '%s' in object '%s' is not accessible", buffer,row,col,propertyname,objectname);
					return 0;
				}
				col++;
			}
			else if ( sscanf(value,"%[^; \t]",propertyname)==1 ) /* current object/global property */
			{
				OBJECT *obj;
				PROPERTY *target = NULL;
				obj  = (OBJECT*)((char*)data - (char*)prop->addr)-1;
				object_name(obj,objectname,sizeof(objectname));
				target = object_get_property(obj,propertyname,NULL);
				if ( target!=NULL )
				{
					if ( target->ptype!=PT_double && target->ptype!=PT_random && target->ptype!=PT_enduse && target->ptype!=PT_loadshape && target->ptype!=PT_enduse )
					{
						output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d property '%s' in object '%s' refers to property '%s', which is not an underlying double",
								buffer,row,col,propertyname,objectname,target->name);
						return 0;
					}
					a->grow_to(row+1,col+1);
					a->set_at(row,col,object_get_double(obj,target));
					if ( a->is_nan(row,col) )
					{
						output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d property '%s' in object '%s' is not accessible", buffer,row,col,propertyname,objectname);
						return 0;
					}
					col++;
				}
				else
				{
					GLOBALVAR *var = global_find(propertyname);
					if ( var==NULL )
					{
						output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d global '%s' not found", buffer,row,col,propertyname);
						return 0;
					}
					if ( var->prop->ptype!=PT_double )
					{
						output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d property '%s' in object '%s' refers to a global '%s', which is not an underlying double", buffer,row,col,propertyname,objectname,propertyname);
						return 0;
					}
					a->grow_to(row+1,col+1);
					a->set_at(row,col,(double*)var->prop->addr);
					if ( a->is_nan(row,col) )
					{
						output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d property '%s' in object '%s' is not accessible", buffer,row,col,propertyname,objectname);
						return 0;
					}
					col++;
				}
			}
			else /* not a valid entry */
			{
				output_error("convert_to_double_array(const char *buffer='%10s...',...): entry at row %d, col %d is not valid (value='%10s')", buffer,row,col,p);
				return 0;
			}
			while ( *p!='\0' && !isspace(*p) && *p!=';' ) p++; /* skip characters just parsed */
		}
	}
	return 1;
}
Beispiel #26
0
/** Run a series of delta mode updates until mode changes back to event mode
	@return number of seconds to advance clock
 **/
DT delta_update(void)
{
	char temp_name_buff[64];
	clock_t t = clock();
	DT seconds_advance, timestep;
	DELTAT temp_time;
	unsigned int delta_iteration_remaining, delta_iteration_count;
	SIMULATIONMODE interupdate_mode, interupdate_mode_result, clockupdate_result;
	int n;
	double dbl_stop_time;
	double dbl_curr_clk_time;
	OBJECT *d_obj = NULL;
	CLASS *d_oclass = NULL;

	/* send preupdate messages */
	timestep=delta_preupdate();
	if ( 0 == timestep ){
		output_error("delta_update(): preupdate failed");
		/* TROUBLESHOOT
		   A module failed to complete a preupdate operation correctly while operating in deltamode.
		   Generally, this is an internal error and should be reported to the GridLAB-D developers.
		 */
		return DT_INVALID;
	}

	/* Populate global stop time as double - just do so only cast it once */
	dbl_stop_time = (double)global_stoptime;

	/* Do the same with the current "timestamp" */
	dbl_curr_clk_time = (double)global_clock;

	/* process updates until mode is switched or 1 hour elapses */
	for ( global_deltaclock=0; global_deltaclock<global_deltamode_maximumtime; global_deltaclock+=timestep )
	{
		/* Check to make sure we haven't reached a stop time */
		global_delta_curr_clock = dbl_curr_clk_time + (double)global_deltaclock/(double)DT_SECOND;

		/* Make sure it isn't over the limit */
		if (global_delta_curr_clock>dbl_stop_time)
		{
			break;	/* Just get us out of here */
		}

		/* set time context for deltamode */
		output_set_delta_time_context(global_clock,global_deltaclock);

		/* Initialize iteration limit counter */
		delta_iteration_remaining = global_deltamode_iteration_limit;

		/* Initialize the iteration counter - seems silly to do, but saves a fetch */
		delta_iteration_count = 0;

		/* main object update loop */
		realtime_run_schedule();

		/* Begin deltamode iteration loop */
		while (delta_iteration_remaining>0) /* Iterate on this delta timestep */
		{
			/* Assume we are ready to go on, initially */
			interupdate_mode = SM_EVENT;

			/* Loop through objects with their individual updates */
			for ( n=0 ; n<delta_objectcount ; n++ )
			{
				d_obj = delta_objectlist[n];	/* Shouldn't need NULL checks, since they were done above */
				d_oclass = d_obj->oclass;

				/* See if the object is in service or not */
				if ((d_obj->in_svc_double <= global_delta_curr_clock) && (d_obj->out_svc_double >= global_delta_curr_clock))
				{
					if ( d_oclass->update )	/* Make sure it exists - init should handle this */
					{
						/* Call the object-level interupdate */
						interupdate_mode_result = d_oclass->update(d_obj,global_clock,global_deltaclock,timestep,delta_iteration_count);

						/* Check the status and handle appropriately */
						switch ( interupdate_mode_result ) {
							case SM_DELTA_ITER:
								interupdate_mode = SM_DELTA_ITER;
								break;
							case SM_DELTA:
								if (interupdate_mode != SM_DELTA_ITER)
									interupdate_mode = SM_DELTA;
								/* default else - leave it as is (SM_DELTA_ITER) */
								break;
							case SM_ERROR:
								output_error("delta_update(): update failed for object \'%s\'", object_name(d_obj, temp_name_buff, 63));
								/* TROUBLESHOOT
								   An object failed to update correctly while operating in deltamode.
								   Generally, this is an internal error and should be reported to the GridLAB-D developers.
								 */
								return DT_INVALID;
							case SM_EVENT:
							default: /* mode remains untouched */
								break;
						}
					} /*End update exists */
				}/* End in service */
				/* Defaulted else, skip over it (not in service) */
			}

			/* send interupdate messages */
			interupdate_mode_result = delta_interupdate(timestep,delta_iteration_count);

			/* Check interupdate return statii */
			if (interupdate_mode_result == SM_ERROR)
			{
				output_error("delta_update(): interupdate failed");
				/* TROUBLESHOOT
				   A module failed to complete an interupdate correctly while operating in deltamode.
				   Generally, this is an internal error and should be reported to the GridLAB-D developers.
				 */
				return DT_INVALID;
			}

			/* Now reconcile with object-level (if called) -- error is already handled */
			if ((interupdate_mode_result != SM_EVENT) && (interupdate_mode == SM_EVENT))
			{
				interupdate_mode = interupdate_mode_result;	/* It is SM_DELTA or SM_DELTA_ITER, which trumps SM_EVENT */
			}
			else if ((interupdate_mode_result == SM_DELTA_ITER) && (interupdate_mode == SM_DELTA))
			{
				interupdate_mode = interupdate_mode_result;	/* Sets us to SM_DELTA_ITER */
			}
			/* defaulted else - interupdate is SM_DELTA_ITER or both are, so it doesn't matter */

			if ((interupdate_mode == SM_DELTA) || (interupdate_mode == SM_EVENT))
			{
				break;	/* Get us out of the while and proceed as appropriate */
			}
			/* Defaulted else - SM_DELTA_ITER - stay here and continue on */

			/* Update iteration counters */
			delta_iteration_remaining--;
			delta_iteration_count++;
		} /* End iterating loop of deltamode */

		/* If iteration limit reached, error us out */
		if (delta_iteration_remaining==0)
		{
			output_error("delta_update(): interupdate iteration limit reached");
			/*  TROUBLESHOOT
			While performing the interupdate portion of the deltamode updates, too many
			reiterations were requested, so the simulation failed to progress forward.  You can
			increase the iteration count with the global variable deltamode_iteration_limit.
			*/
			return DT_INVALID;
		}

		// We have finished the current timestep. Call delta_clockUpdate.
		clockupdate_result = delta_clockupdate(timestep, interupdate_mode);

		if(clockupdate_result == SM_ERROR)
		{
			output_error("delta_update(): clockupdate failed");
			/* TROUBLESHOOT
			 * A module failed to complete an clockupdate correctly while operating in deltamode.
			 * Generally, this is an internal error and should be reported to the GridLAB-D developers.
			 */
			return DT_INVALID;
		}

		if ( interupdate_mode==SM_EVENT )
		{
			/* no module wants deltamode to continue any further */
			break;
		}
	}

	/* profile */
	if ( profile.t_min==0 || timestep<profile.t_min ) profile.t_min = timestep;
	if ( profile.t_max==0 || timestep>profile.t_max ) profile.t_max = timestep;
	profile.t_delta += global_deltaclock;

	/* send postupdate messages */
	if ( FAILED == delta_postupdate() ){
		output_error("delta_update(): postupdate failed");
		/* TROUBLESHOOT
		   A module failed to complete an postupdate correctly while operating in deltamode.
		   Generally, this is an internal error and should be reported to the GridLAB-D developers.
		 */
		return DT_INVALID;
	}

	profile.t_update += clock() - t;
	seconds_advance = (DT)(global_deltaclock/DT_SECOND);	/* Initial guess, check rounding */
	
	/* See what's left and determine rounding */
	temp_time = global_deltaclock - ((DELTAT)(seconds_advance)*DT_SECOND);

	/* Determine if an increment is necessary */
	if (temp_time != 0)
		seconds_advance++;

	return seconds_advance;
}
Beispiel #27
0
void test_parentAppendMode()
{
	Key *parentKey = keyNew ("user/tests/keytometa", KEY_END);
	KeySet *conf = ksNew(0, KS_END);
	PLUGIN_OPEN ("keytometa");

	KeySet *ks = createParentTestKeys ();

	succeed_if(plugin->kdbGet (plugin, ks, parentKey) >= 1,
			"call to kdbGet was not successful");
	succeed_if(output_error (parentKey), "error in kdbGet");
	succeed_if(output_warnings (parentKey), "warnings in kdbGet");

	/* parentkey1 must contain meta information generated from convertkeydirect (via parent) */
	Key *key = ksLookupByName(ks, "user/parentkey1", 0);
	succeed_if (key, "parentkey1 was removed");

	const Key *metaKey1 = keyGetMeta(key, "testmeta");
	succeed_if (metaKey1, "parentkey1 contained no metakey");
	succeed_if (!strcmp (keyString(metaKey1), "testvalue1"), "metakey of parentkey1 contained incorrect data");

	/* parentkey2 must contain meta information generated from convertkeyhole (via parent) */
	key = ksLookupByName(ks, "user/parentkey2", 0);
	succeed_if (key, "parentkey2 was removed");

	const Key *metaKey2 = keyGetMeta(key, "testmeta");
	succeed_if (metaKey2, "parentkey2 contained no metakey");
	succeed_if (!strcmp (keyString(metaKey2), "testvalue2"), "metakey of parentkey2 contained incorrect data");

	/* parentkey3 must contain meta information generated from convertkeyprev
	 * (via previous append samelevel which falls back to parent) */
	key = ksLookupByName(ks, "user/parentkey3", 0);
	succeed_if (key, "parentkey3 was removed");

	const Key *metaKey3 = keyGetMeta(key, "testmeta");
	succeed_if (metaKey3, "parentkey3 contained no metakey");
	succeed_if (!strcmp (keyString(metaKey3), "testvalue3"), "metakey of parentkey3 contained incorrect data");

	/* normalkey1 must not contain meta data */
	key = ksLookupByName(ks, "user/normalkey1", 0);
	succeed_if (key, "normalkey1 was removed");
	succeed_if (!keyGetMeta (key, "testmeta"), "normalkey1 should not contain any meta data");

	/* parentkey4 must contain meta information generated from convertkeynext
	 * (via next append samelevel which falls back to parent) */
	key = ksLookupByName(ks, "user/parentkey4", 0);
	succeed_if (key, "parentkey4 was removed");

	const Key *metaKey4 = keyGetMeta(key, "testmeta");
	succeed_if (metaKey4, "parentkey4 contained no metakey");
	succeed_if (!strcmp (keyString(metaKey4), "testvalue4"), "metakey of parentkey4 contained incorrect data");

	/* normalkey2 must not contain meta data */
	key = ksLookupByName(ks, "user/normalkey2", 0);
	succeed_if (key, "normalkey2 was removed");
	succeed_if (!keyGetMeta (key, "testmeta"), "normalkey2 should not contain any meta data");


	keyDel (parentKey);
	ksDel (ks);
	PLUGIN_CLOSE();
}
Beispiel #28
0
/** Initialize the delta mode code

	This call must be completed before the first call to any delta mode code.
	If the call fails, no delta mode code can be executed.  Failure does not
	affect whether event mode code can run.

	@return SUCCESS or FAILED
 **/
STATUS delta_init(void)
{
	OBJECT *obj, **pObj;
	char temp_name_buff[64];
	unsigned int n, toprank = 0;
	OBJECT ***ranklist;
	int *rankcount;
	MODULE *module;
	clock_t t = clock();

	/* count qualified modules */
	for ( module=module_get_first() ; module!=NULL ; module=module_get_next(module) )
	{
		if ( 0 != module->deltadesired ){
			// this could probably be counted in module_init()...
			delta_modulecount++;
			if (profile.module_list[0]!=0)
				strcat(profile.module_list,",");
			strcat(profile.module_list,module->name);
		}
	}

	/* if none, stop here */
	if ( delta_modulecount==0 ){
		goto Success;
	}

	/* allocate memory for qualified module list */
	delta_modulelist = (MODULE**)malloc(sizeof(MODULE**)*delta_modulecount);
	if(0 == delta_modulelist){
		output_error("unable to allocate memory for deltamode module list");
		/* TROUBLESHOOT
		  Deltamode operation requires more memory than is available.
		  Try freeing up memory by making more heap available or making the model smaller. 
		 */
		return FAILED;
	}
	/* build qualified module list */
	delta_modulecount = 0;
	global_deltamode_updateorder[0]='\0';
	for ( module=module_get_first() ; module!=NULL ; module=module_get_next(module) )
	{
		if ( 0 != module->deltadesired )
		{
			if ( delta_modulecount>0 )
				strcat(global_deltamode_updateorder,",");
			strcat(global_deltamode_updateorder,module->name);
			delta_modulelist[delta_modulecount++] = module;
		}
	}

	/* count qualified objects */
	for ( obj=object_get_first() ; obj!=NULL ; obj=object_get_next(obj) )
	{
		if ( obj->flags&OF_DELTAMODE )
		{
			if ( !obj->oclass->update )
				output_debug("object '%s' requested deltamode updates but the class '%s' does not export the update function", object_name(obj, temp_name_buff, 63), obj->oclass->name);
			delta_objectcount++;
			if ( obj->rank > toprank ){
				toprank = obj->rank;
			}
		}
	}

	/* if none, stop here */
	if ( delta_objectcount==0 ){
		goto Success;
	}

	/* allocate final object list */
	delta_objectlist = (OBJECT**)malloc(sizeof(OBJECT*)*delta_objectcount);
	if ( delta_objectlist==NULL)
	{
		output_error("unable to allocate memory for deltamode object list");
		/* TROUBLESHOOT
		  Deltamode operation requires more memory than is available.
		  Try freeing up memory by making more heap available or making the model smaller. 
		 */
		return FAILED;
	}

	/* allocate rank lists */
	ranklist = (OBJECT***)malloc(sizeof(OBJECT**)*(toprank+1));
	if ( 0 == ranklist ){
		output_error("unable to allocate memory for deltamode ranklist");
		/* TROUBLESHOOT
		  Deltamode operation requires more memory than is available.
		  Try freeing up memory by making more heap available or making the model smaller. 
		 */
		return FAILED;
	}
	memset(ranklist,0,sizeof(OBJECT**)*(toprank+1));

	/* allocate rank counts */
	rankcount = (int*)malloc(sizeof(int)*(toprank+1));
	if ( 0 == rankcount ){
		output_error("unable to allocate memory for deltamode rankcount");
		/* TROUBLESHOOT
		  Deltamode operation requires more memory than is available.
		  Try freeing up memory by making more heap available or making the model smaller. 
		 */
		return FAILED;
	}
	memset(rankcount,0,sizeof(int)*(toprank+1));

	/* count qualified objects in each rank */
	for ( obj=object_get_first() ; obj!=NULL ; obj=object_get_next(obj) )
	{
		if ( obj->flags&OF_DELTAMODE ){
			rankcount[obj->rank]++;
		}
	}

	/* allocate rank lists */
	for ( n=0 ; n<=toprank ; n++)
	{
		if ( rankcount[n]>0 )
		{
			ranklist[n] = (OBJECT**)malloc(sizeof(OBJECT*)*rankcount[n]);
			if ( !ranklist[n] ){
				output_error("unable to allocate memory for deltamode rankcount %i", n);
				/* TROUBLESHOOT
				  Deltamode operation requires more memory than is available.
				  Try freeing up memory by making more heap available or making the model smaller. 
				 */
				return FAILED;
			}
			rankcount[n] = 0; /* clear for index recount */
		}
		else
			ranklist[n] = NULL;
	}

	/* assign qualified objects to rank lists */
	for ( obj=object_get_first() ; obj!=NULL ; obj=object_get_next(obj) )
	{
		if ( obj->flags&OF_DELTAMODE ){
			ranklist[obj->rank][rankcount[obj->rank]++] = obj;
		}
	}

	/* build final object list */
	pObj = delta_objectlist;
	for ( n=0 ; n<=toprank ; n++)
	{
		int m;
		for ( m=0 ; m<rankcount[n] ; m++ ){
			*pObj++ = ranklist[n][m];
		}
		if ( ranklist[n]!=NULL ){
			free(ranklist[n]);
			ranklist[n] = NULL;
		}
	}

	/* release memory */
	free(rankcount);
	rankcount = NULL;
	free(ranklist);
	ranklist = NULL;
Success:
	profile.t_init += clock() - t;
	return SUCCESS;
}
Beispiel #29
0
int convert_to_enduse(char *string, void *data, PROPERTY *prop)
{
	enduse *e = (enduse*)data;
	char buffer[1024];
	char *token = NULL;

	/* check string length before copying to buffer */
	if (strlen(string)>sizeof(buffer)-1)
	{
		output_error("convert_to_enduse(string='%-.64s...', ...) input string is too long (max is 1023)",string);
		return 0;
	}
	strcpy(buffer,string);

	/* parse tuples separate by semicolon*/
	while ((token=strtok(token==NULL?buffer:NULL,";"))!=NULL)
	{
		/* colon separate tuple parts */
		char *param = token;
		char *value = strchr(token,':');

		/* isolate param and token and eliminte leading whitespaces */
		while (isspace(*param) || iscntrl(*param)) param++;
		if (value==NULL)
			value="1";
		else
			*value++ = '\0'; /* separate value from param */
		while (isspace(*value) || iscntrl(*value)) value++;

		// parse params
		if (strcmp(param,"current_fraction")==0)
			e->current_fraction = atof(value);
		else if (strcmp(param,"impedance_fraction")==0)
			e->impedance_fraction = atof(value);
		else if (strcmp(param,"power_fraction")==0)
			e->power_fraction = atof(value);
		else if (strcmp(param,"power_factor")==0)
			e->power_factor = atof(value);
		else if (strcmp(param,"loadshape")==0)
		{
			PROPERTY *pref = class_find_property(prop->oclass,value);
			if (pref==NULL)
			{
				output_warning("convert_to_enduse(string='%-.64s...', ...) loadshape '%s' not found in class '%s'",string,value,prop->oclass->name);
				return 0;
			}
			e->shape = (loadshape*)((char*)e - (int64)(prop->addr) + (int64)(pref->addr));
		}
		else
		{
			output_error("convert_to_enduse(string='%-.64s...', ...) parameter '%s' is not valid",string,param);
			return 0;
		}
	}

	/* reinitialize the loadshape */
	if (enduse_init((enduse*)data))
		return 0;

	/* everything converted ok */
	return 1;
}
Beispiel #30
0
int main(int argc, char ** argv)
{
	int events = 0;
        int orig_events;
	bool monitor = false;
	int quiet = 0;
	unsigned long int timeout = 0;
	int recursive = 0;
	bool csv = false;
	bool daemon = false;
	bool syslog = false;
	char * format = NULL;
	char * timefmt = NULL;
	char * fromfile = NULL;
	char * outfile = NULL;
	char * exc_regex = NULL;
	char * exc_iregex = NULL;
	char * inc_regex = NULL;
	char * inc_iregex = NULL;
	pid_t pid;
    int fd;

	// Parse commandline options, aborting if something goes wrong
	if ( !parse_opts(&argc, &argv, &events, &monitor, &quiet, &timeout,
	                 &recursive, &csv, &daemon, &syslog, &format, &timefmt, 
                         &fromfile, &outfile,
                         &exc_regex, &exc_iregex, &inc_regex, &inc_iregex) ) {
		return EXIT_FAILURE;
	}

	if ( !inotifytools_initialize() ) {
		warn_inotify_init_error();
		return EXIT_FAILURE;
	}

	if ( timefmt ) inotifytools_set_printf_timefmt( timefmt );
	if (
		(exc_regex && !inotifytools_ignore_events_by_regex(exc_regex, REG_EXTENDED) ) ||
		(exc_iregex && !inotifytools_ignore_events_by_regex(exc_iregex, REG_EXTENDED|
		                                                        REG_ICASE))
	) {
		fprintf(stderr, "Error in `exclude' regular expression.\n");
		return EXIT_FAILURE;
	}
	if (
		(inc_regex && !inotifytools_ignore_events_by_inverted_regex(inc_regex, REG_EXTENDED) ) ||
		(inc_iregex && !inotifytools_ignore_events_by_inverted_regex(inc_iregex, REG_EXTENDED|
		                                                        REG_ICASE))
	) {
		fprintf(stderr, "Error in `include' regular expression.\n");
		return EXIT_FAILURE;
	}


	if ( format ) validate_format(format);

	// Attempt to watch file
	// If events is still 0, make it all events.
	if (events == 0)
		events = IN_ALL_EVENTS;
        orig_events = events;
        if ( monitor && recursive ) {
                events = events | IN_CREATE | IN_MOVED_TO | IN_MOVED_FROM;
        }

	FileList list = construct_path_list( argc, argv, fromfile );

	if (0 == list.watch_files[0]) {
		fprintf(stderr, "No files specified to watch!\n");
		return EXIT_FAILURE;
	}


    // Daemonize - BSD double-fork approach
	if ( daemon ) {

		pid = fork();
	        if (pid < 0) {
			fprintf(stderr, "Failed to fork1 whilst daemonizing!\n");
	                return EXIT_FAILURE;
	        } 
	        if (pid > 0) {
			_exit(0);
	        }
		if (setsid() < 0) {
			fprintf(stderr, "Failed to setsid whilst daemonizing!\n");
	                return EXIT_FAILURE;
	        }
		signal(SIGHUP,SIG_IGN);
	        pid = fork();
	        if (pid < 0) {
	                fprintf(stderr, "Failed to fork2 whilst daemonizing!\n");
	                return EXIT_FAILURE;
	        }
	        if (pid > 0) {
	                _exit(0);
	        }
		if (chdir("/") < 0) {
			fprintf(stderr, "Failed to chdir whilst daemonizing!\n");
	                return EXIT_FAILURE;
	        }

		// Redirect stdin from /dev/null
	        fd = open("/dev/null", O_RDONLY);
		if (fd != fileno(stdin)) {
			dup2(fd, fileno(stdin));
			close(fd);
		}

		// Redirect stdout to a file
	        fd = open(outfile, O_WRONLY | O_CREAT | O_APPEND, 0600);
		if (fd < 0) {
                        fprintf( stderr, "Failed to open output file %s\n", outfile );
                        return EXIT_FAILURE;
                }
		if (fd != fileno(stdout)) {
			dup2(fd, fileno(stdout));
			close(fd);
		}

        // Redirect stderr to /dev/null
		fd = open("/dev/null", O_WRONLY);
	        if (fd != fileno(stderr)) {
	                dup2(fd, fileno(stderr));
	                close(fd);
	        }
	
        } else if (outfile != NULL) { // Redirect stdout to a file if specified
		fd = open(outfile, O_WRONLY | O_CREAT | O_APPEND, 0600);
		if (fd < 0) {
			fprintf( stderr, "Failed to open output file %s\n", outfile );
			return EXIT_FAILURE;
		}
		if (fd != fileno(stdout)) {
			dup2(fd, fileno(stdout));
			close(fd);
		}
        }

        if ( syslog ) {
		openlog ("inotifywait", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_DAEMON);
        }

	if ( !quiet ) {
		if ( recursive ) {
			output_error( syslog, "Setting up watches.  Beware: since -r "
				"was given, this may take a while!\n" );
		} else {
			output_error( syslog, "Setting up watches.\n" );
		}
	}

	// now watch files
	for ( int i = 0; list.watch_files[i]; ++i ) {
		char const *this_file = list.watch_files[i];
		if ( (recursive && !inotifytools_watch_recursively_with_exclude(
		                        this_file,
		                        events,
		                        list.exclude_files ))
		     || (!recursive && !inotifytools_watch_file( this_file, events )) ){
			if ( inotifytools_error() == ENOSPC ) {
				output_error( syslog, "Failed to watch %s; upper limit on inotify "
				                "watches reached!\n", this_file );
				output_error( syslog, "Please increase the amount of inotify watches "
				        "allowed per user via `/proc/sys/fs/inotify/"
				        "max_user_watches'.\n");
			}
			else {
				output_error( syslog, "Couldn't watch %s: %s\n", this_file,
				        strerror( inotifytools_error() ) );
			}
			return EXIT_FAILURE;
		}
	}

	if ( !quiet ) {
		output_error( syslog, "Watches established.\n" );
	}

	// Now wait till we get event
	struct inotify_event * event;
	char * moved_from = 0;

	do {
		event = inotifytools_next_event( timeout );
		if ( !event ) {
			if ( !inotifytools_error() ) {
				return EXIT_TIMEOUT;
			}
			else {
				output_error( syslog, "%s\n", strerror( inotifytools_error() ) );
				return EXIT_FAILURE;
			}
		}

		if ( quiet < 2 && (event->mask & orig_events) ) {
			if ( csv ) {
				output_event_csv( event );
			}
			else if ( format ) {
				inotifytools_printf( event, format );
			}
			else {
				inotifytools_printf( event, "%w %,e %f\n" );
			}
		}

		// if we last had MOVED_FROM and don't currently have MOVED_TO,
		// moved_from file must have been moved outside of tree - so unwatch it.
		if ( moved_from && !(event->mask & IN_MOVED_TO) ) {
			if ( !inotifytools_remove_watch_by_filename( moved_from ) ) {
				output_error( syslog, "Error removing watch on %s: %s\n",
				         moved_from, strerror(inotifytools_error()) );
			}
			free( moved_from );
			moved_from = 0;
		}

		if ( monitor && recursive ) {
			if ((event->mask & IN_CREATE) ||
			    (!moved_from && (event->mask & IN_MOVED_TO))) {
				// New file - if it is a directory, watch it
				static char * new_file;

				nasprintf( &new_file, "%s%s",
				           inotifytools_filename_from_wd( event->wd ),
				           event->name );

				if ( isdir(new_file) &&
				    !inotifytools_watch_recursively( new_file, events ) ) {
					output_error( syslog, "Couldn't watch new directory %s: %s\n",
					         new_file, strerror( inotifytools_error() ) );
				}
				free( new_file );
			} // IN_CREATE
			else if (event->mask & IN_MOVED_FROM) {
				nasprintf( &moved_from, "%s%s/",
				           inotifytools_filename_from_wd( event->wd ),
				           event->name );
				// if not watched...
				if ( inotifytools_wd_from_filename(moved_from) == -1 ) {
					free( moved_from );
					moved_from = 0;
				}
			} // IN_MOVED_FROM
			else if (event->mask & IN_MOVED_TO) {
				if ( moved_from ) {
					static char * new_name;
					nasprintf( &new_name, "%s%s/",
					           inotifytools_filename_from_wd( event->wd ),
					           event->name );
					inotifytools_replace_filename( moved_from, new_name );
					free( moved_from );
					moved_from = 0;
				} // moved_from
			}
		}

		fflush( NULL );

	} while ( monitor );

	// If we weren't trying to listen for this event...
	if ( (events & event->mask) == 0 ) {
		// ...then most likely something bad happened, like IGNORE etc.
		return EXIT_FAILURE;
	}

	return EXIT_SUCCESS;
}