示例#1
0
UBool
IslamicCalendar::inDaylightTime(UErrorCode& status) const
{
    // copied from GregorianCalendar
    if (U_FAILURE(status) || (&(getTimeZone()) == NULL && !getTimeZone().useDaylightTime())) 
        return FALSE;

    // Force an update of the state of the Calendar.
    ((IslamicCalendar*)this)->complete(status); // cast away const

    return (UBool)(U_SUCCESS(status) ? (internalGet(UCAL_DST_OFFSET) != 0) : FALSE);
}
示例#2
0
//
//{--MM-DD}[TimeZone]
// 0123456
//
void TimeVal::parseMonthDay()
{
  initParser();

  if (parser_context.fBuffer[0] != DATE_SEPARATOR ||
      parser_context.fBuffer[1] != DATE_SEPARATOR ||
      parser_context.fBuffer[4] != DATE_SEPARATOR ) {
    throw TimeValXMLParseErrorException("DateTime_gMthDay_invalid", parser_context.fBuffer);
  }

  //initialize
  parser_context.fValue[CentYear] = YEAR_DEFAULT;
  parser_context.fValue[Month]    = parseInt(2, 4);
  parser_context.fValue[Day]      = parseInt(5, 7);

  if ( MONTHDAY_SIZE < parser_context.fEnd ) {
      int sign = findUTCSign(MONTHDAY_SIZE);
      if ( sign<0 ) {
	throw TimeValXMLParseErrorException("DateTime_gMthDay_invalid",parser_context.fBuffer);
      }
      else {
	getTimeZone(sign);
      }
  }

  validateDateTime();
  xmlnormalize();
}
// . #4: 06 Nov 1994 08:49:37 GMT  ;RFC 822, updated by RFC 1123
// . like atotime1()
static time_t atotime4 ( const char *s ) {
	// this time structure, once filled, will help yield a time_t
	struct tm t;
	// DAY OF WEEK 
	//t.tm_wday = getWeekday ( s );
	//while ( *s && ! isdigit(*s) ) s++;
	// DAY OF MONTH
	t.tm_mday = atol ( s );
	while ( *s && ! isalpha (*s) ) s++;
	// MONTH
	t.tm_mon = getMonth ( s );
	while ( *s && ! isdigit (*s) ) s++;
	// YEAR
	t.tm_year = atol ( s ) - 1900 ; // # of years since 1900
	while ( *s && isdigit (*s) ) s++;
	while ( *s && isspace (*s) ) s++;
	// TIME
	getTime ( s , &t.tm_sec , &t.tm_min , &t.tm_hour );
	// unknown if we're in  daylight savings time
	t.tm_isdst = -1;
	// translate using mktime
	time_t global = timegm ( &t );

	// skip HH:MM:SS
	while ( *s && !isspace (*s) ) s++;
	// skip spaces
	while ( *s && isspace (*s) ) s++;
	// convert local time to "utc" or whatever timezone "s" points to,
	// which is usually gmt or utc
	if( *s ) {
		int32_t tzoff = getTimeZone ( s ) ;
		if ( tzoff != BADTIMEZONE ) global += tzoff;
	}
	return global;
}
示例#4
0
UBool
CECalendar::inDaylightTime(UErrorCode& status) const
{
    if (U_FAILURE(status) || !getTimeZone().useDaylightTime()) {
        return FALSE;
    }

    // Force an update of the state of the Calendar.
    ((CECalendar*)this)->complete(status); // cast away const

    return (UBool)(U_SUCCESS(status) ? (internalGet(UCAL_DST_OFFSET) != 0) : FALSE);
}
示例#5
0
THREAD(AlarmSync, arg)
{
    NutThreadSetPriority(50);

    while(initialized == false){
        NutSleep(1000);
    }
    int dayCounter = 0;
    int counter = 0;
    while(!NtpSync() && counter < 10)
    {
        NutSleep(1000);
        counter++;
    }
    counter = 0;
    for(;;)
    {

        if((initialized == true) && (hasNetworkConnection() == true))
        {
            checkSleep();
            isAlarmSyncing = true;
            char url[49];
            sprintf(url, "/getAlarmen.php?radiomac=%s&tz=%d", getMacAdress(), getTimeZone());
            httpGet(url, parseAlarmJson);
            isAlarmSyncing = false;

            char url2[43];
            sprintf(url2, "/getTwitch.php?radiomac=%s", getMacAdress());
            httpGet(url2, parseTwitch);
            char url3[43];
            sprintf(url3,"/getTwitter.php?radiomac=%s", getMacAdress());
            httpGet(url3,TwitterParser);

            //Command que (Telegram) sync
            sprintf(url, "%s%s", "/getCommands.php?radiomac=", getMacAdress());
            httpGet(url, parseCommandQue);
        }
        while(dayCounter > 28800 && (hasNetworkConnection() == true))
        {
            while(!NtpSync() && counter < 10)
            {
                NutSleep(1000);
                counter++;
            }
            dayCounter = 28800;
            counter = 0;
        }
        dayCounter++;
        NutSleep(3000);
    }
    NutThreadExit();
}
示例#6
0
void TimeVal::parseTimeZone()
{
  if ( parser_context.fStart < parser_context.fEnd ) {
    int sign = findUTCSign(parser_context.fStart);
    if ( sign < 0 ) {
      throw TimeValXMLParseErrorException("DateTime_tz_noUTCsign",parser_context.fBuffer);
      //("Error in month parsing");
    }
    else {
      getTimeZone(sign);
    }
  }

  return;
}
// #1: Sun, 06 Nov 1994 08:49:37 GMT  ;RFC 822, updated by RFC 1123
time_t atotime1 ( const char *s ) {
	// this time structure, once filled, will help yield a time_t
	struct tm t;
	// DAY OF WEEK 
	t.tm_wday = getWeekday ( s );
	while ( *s && ! isdigit(*s) ) s++;
	// DAY OF MONTH
	t.tm_mday = atol ( s );
	while ( *s && ! isalpha (*s) ) s++;
	// MONTH
	t.tm_mon = getMonth ( s );
	while ( *s && ! isdigit (*s) ) s++;
	// YEAR
	t.tm_year = atol ( s ) - 1900 ; // # of years since 1900
	while ( isdigit (*s) ) s++;
	while ( isspace (*s) ) s++;	
	// TIME
	getTime ( s , &t.tm_sec , &t.tm_min , &t.tm_hour );
	// unknown if we're in  daylight savings time
	t.tm_isdst = -1;

	// translate using mktime
	time_t global = timegm ( &t );

	// skip HH:MM:SS
	while ( *s && ! isspace (*s) ) s++;	

	// no timezone following??? fix core.
	if ( ! *s ) return global;

	// skip spaces
	while ( isspace (*s) ) s++;
	// convert local time to "utc" or whatever timezone "s" points to,
	// which is usually gmt or utc
	int32_t tzoff = getTimeZone ( s ) ;
	if ( tzoff != BADTIMEZONE ) global += tzoff;
	return global;

	// now, convert to utc
	//time_t utc  = time(NULL);
	// get time here locally
	//time_t here = localtime(&utc);
	// what is the diff?
	//int32_t delta = here - utc;
	// modify our time to make it into utc
	//return local - delta;
}
示例#8
0
void
GregorianCalendar::setGregorianChange(UDate date, UErrorCode& status)
{
    if (U_FAILURE(status)) 
        return;

    fGregorianCutover = date;

    // Precompute two internal variables which we use to do the actual
    // cutover computations.  These are the normalized cutover, which is the
    // midnight at or before the cutover, and the cutover year.  The
    // normalized cutover is in pure date milliseconds; it contains no time
    // of day or timezone component, and it used to compare against other
    // pure date values.
    int32_t cutoverDay = (int32_t)ClockMath::floorDivide(fGregorianCutover, (double)kOneDay);
    fNormalizedGregorianCutover = cutoverDay * kOneDay;

    // Handle the rare case of numeric overflow.  If the user specifies a
    // change of UDate(Long.MIN_VALUE), in order to get a pure Gregorian
    // calendar, then the epoch day is -106751991168, which when multiplied
    // by ONE_DAY gives 9223372036794351616 -- the negative value is too
    // large for 64 bits, and overflows into a positive value.  We correct
    // this by using the next day, which for all intents is semantically
    // equivalent.
    if (cutoverDay < 0 && fNormalizedGregorianCutover > 0) {
        fNormalizedGregorianCutover = (cutoverDay + 1) * kOneDay;
    }

    // Normalize the year so BC values are represented as 0 and negative
    // values.
    GregorianCalendar *cal = new GregorianCalendar(getTimeZone(), status);
    /* test for NULL */
    if (cal == 0) {
        status = U_MEMORY_ALLOCATION_ERROR;
        return;
    }
    if(U_FAILURE(status))
        return;
    cal->setTime(date, status);
    fGregorianCutoverYear = cal->get(UCAL_YEAR, status);
    if (cal->get(UCAL_ERA, status) == BC) 
        fGregorianCutoverYear = 1 - fGregorianCutoverYear;
    fCutoverJulianDay = cutoverDay;
    delete cal;
}
std::string terrama2::core::DataAccessorJsonCemaden::retrieveData(const DataRetrieverPtr dataRetriever,
                                                                  DataSetPtr dataSet,
                                                                  const Filter& filter,
                                                                  std::shared_ptr<FileRemover> remover) const
{
  std::string mask = getDataMask(dataSet);
  std::string folderPath = getFolderMask(dataSet);

  std::string timezone;
  try
  {
    timezone = getTimeZone(dataSet);
  }
  catch(const UndefinedTagException& /*e*/)
  {
    timezone = "UTC+00";
  }

  return dataRetriever->retrieveData(mask, filter, timezone, remover, "", folderPath);
}
示例#10
0
//
// {--MM--}[TimeZone]
// {--MM}[TimeZone]
//  012345
//
void TimeVal::parseMonth()
{
  initParser();

  if (parser_context.fBuffer[0] != DATE_SEPARATOR ||
      parser_context.fBuffer[1] != DATE_SEPARATOR  ) {
    throw TimeValXMLParseErrorException("DateTime_gMth_invalid", parser_context.fBuffer);
  }

  //set constants
  parser_context.fValue[CentYear] = YEAR_DEFAULT;
  parser_context.fValue[Day]      = DAY_DEFAULT;
  parser_context.fValue[Month]    = parseInt(2, 4);

  // REVISIT: allow both --MM and --MM-- now.
  // need to remove the following lines to disallow --MM--
  // when the errata is officially in the rec.
  parser_context.fStart = 4;
  if ( parser_context.fEnd >= parser_context.fStart+2 && parser_context.fBuffer[parser_context.fStart] == DATE_SEPARATOR && parser_context.fBuffer[parser_context.fStart+1] == DATE_SEPARATOR ) {
    parser_context.fStart += 2;
  }

  //
  // parse TimeZone if any
  //
  if ( parser_context.fStart < parser_context.fEnd ) {
    int sign = findUTCSign(parser_context.fStart);
    if ( sign < 0 )
      {
	throw TimeValXMLParseErrorException("DateTime_gMth_invalid",parser_context.fBuffer);
      }
    else {
      getTimeZone(sign);
    }
  }

  validateDateTime();
  xmlnormalize();
}
示例#11
0
//
//[-]{CCYY}[TimeZone]
// 0  1234
//
void TimeVal::parseYear()
{
  initParser();

  // skip the first '-' and search for timezone
  //
  int sign = findUTCSign((parser_context.fBuffer[0] == '-') ? 1 : 0);

  if (sign == NOT_FOUND) {
    parser_context.fValue[CentYear] = parseIntYear(parser_context.fEnd);
  }
  else {
    parser_context.fValue[CentYear] = parseIntYear(sign);
    getTimeZone(sign);
  }

  //initialize values
  parser_context.fValue[Month] = MONTH_DEFAULT;
  parser_context.fValue[Day]   = DAY_DEFAULT;   //java is 1

  validateDateTime();
  xmlnormalize();
}
示例#12
0
//
// hh:mm:ss[.msssss]['Z']
// hh:mm:ss[.msssss][['+'|'-']hh:mm]
// 012345678
//
// Note: Assuming parser_context.fStart point to the beginning of the Time Section
//       parser_context.fStart updated to point to the position right AFTER the second 's'
//                                                  or ms if any
//
void TimeVal::getTime()
{

  // Ensure enough chars in buffer
  if ( (parser_context.fStart+TIME_MIN_SIZE) > parser_context.fEnd)
    throw TimeValXMLParseErrorException("DateTime_time_incomplete", parser_context.fBuffer);
  //"Imcomplete Time Format"

  // check (fixed) format first
  if ((parser_context.fBuffer[parser_context.fStart + 2] != TIME_SEPARATOR) ||
      (parser_context.fBuffer[parser_context.fStart + 5] != TIME_SEPARATOR)  )
    {
      throw TimeValXMLParseErrorException("DateTime_time_invalid", parser_context.fBuffer);
      //("Error in parsing time" );
    }

  //
  // get hours, minute and second
  //
  parser_context.fValue[Hour]   = parseInt(parser_context.fStart + 0, parser_context.fStart + 2);
  parser_context.fValue[Minute] = parseInt(parser_context.fStart + 3, parser_context.fStart + 5);
  parser_context.fValue[Second] = parseInt(parser_context.fStart + 6, parser_context.fStart + 8);
  parser_context.fStart += 8;

  // to see if any ms and/or utc part after that
  if (parser_context.fStart >= parser_context.fEnd)
    return;

  //find UTC sign if any
  int sign = findUTCSign(parser_context.fStart);

  //parse miliseconds
  int milisec = (parser_context.fBuffer[parser_context.fStart] == MILISECOND_SEPARATOR)? parser_context.fStart : NOT_FOUND;
  if ( milisec != NOT_FOUND )
    {
      parser_context.fStart++;   // skip the '.'
      // make sure we have some thing between the '.' and parser_context.fEnd
      if (parser_context.fStart >= parser_context.fEnd)
        {
	  throw TimeValXMLParseErrorException("DateTime_ms_noDigit",parser_context.fBuffer);
	  //("ms shall be present once '.' is present" );
        }

      if ( sign == NOT_FOUND )
        {
	  parser_context.fValue[MiliSecond] = parseInt(parser_context.fStart, parser_context.fEnd);  //get ms between '.' and parser_context.fEnd
	  parser_context.fStart = parser_context.fEnd;
        }
      else
        {
	  parser_context.fValue[MiliSecond] = parseInt(parser_context.fStart, sign);  //get ms between UTC sign and parser_context.fEnd
        }
    }
  else if(sign == 0 || sign != parser_context.fStart)
    {
      // seconds has more than 2 digits
      throw TimeValXMLParseErrorException("DateTime_min_invalid", parser_context.fBuffer);
    }

  //parse UTC time zone (hh:mm)
  if ( sign > 0 ) {
    getTimeZone(sign);
  }

}
void terrama2::core::DataAccessorOccurrenceLightning::adapt(DataSetPtr dataSet, std::shared_ptr<te::da::DataSetTypeConverter> converter) const
{
  // only one timestamp column
  size_t lonPos = std::numeric_limits<size_t>::max();
  size_t latPos = std::numeric_limits<size_t>::max();

  Srid srid = getSrid(dataSet);

  auto timestampPropertyName = terrama2::core::simplifyString(getTimestampPropertyName(dataSet));

  te::dt::DateTimeProperty* timestampProperty = new te::dt::DateTimeProperty(timestampPropertyName, te::dt::TIME_INSTANT);
  te::dt::SimpleProperty* latProperty = new te::dt::SimpleProperty(getLatitudePropertyName(dataSet), te::dt::DOUBLE_TYPE);
  te::dt::SimpleProperty* lonProperty = new te::dt::SimpleProperty(getLongitudePropertyName(dataSet), te::dt::DOUBLE_TYPE);
  te::gm::GeometryProperty* geomProperty = new te::gm::GeometryProperty("geom", srid, te::gm::PointType);

  // Find the right column to adapt
  std::vector<te::dt::Property*> properties = converter->getConvertee()->getProperties();
  for(size_t i = 0, size = properties.size(); i < size; ++i)
  {
    te::dt::Property* property = properties.at(i);
    if(property->getName() == getTimestampPropertyName(dataSet))
    {
      // datetime column found
      converter->add(i, timestampProperty,
                     boost::bind(&terrama2::core::DataAccessorOccurrenceLightning::stringToTimestamp, this, _1, _2, _3, getTimeZone(dataSet)));
    }
    else if(property->getName() == getLatitudePropertyName(dataSet) || property->getName() == getLongitudePropertyName(dataSet))
    {
      // update latitude column index
      if(property->getName() == getLatitudePropertyName(dataSet))
      {
        latPos = i;
        converter->add(i, latProperty, boost::bind(&terrama2::core::DataAccessor::stringToDouble, this, _1, _2, _3));
      }

      // update longitude column index
      if(property->getName() == getLongitudePropertyName(dataSet))
      {
        lonPos = i;
        converter->add(i, lonProperty, boost::bind(&terrama2::core::DataAccessor::stringToDouble, this, _1, _2, _3));
      }

      if(!isValidColumn(latPos) || !isValidColumn(lonPos))
        continue;


      std::vector<size_t> latLonAttributes;
      latLonAttributes.push_back(lonPos);
      latLonAttributes.push_back(latPos);

      converter->add(latLonAttributes, geomProperty, boost::bind(&terrama2::core::DataAccessorOccurrenceLightning::stringToPoint, this, _1, _2, _3, srid));
    }
    else
    {
      auto newName = terrama2::core::simplifyString(converter->getConvertee()->getProperty(i)->getName());
      te::dt::SimpleProperty* property = new te::dt::SimpleProperty(newName, te::dt::DOUBLE_TYPE);
      
      converter->add(i, property, boost::bind(&terrama2::core::DataAccessor::stringToDouble, this, _1, _2, _3));
    }
  }
}
示例#14
0
void terrama2::core::DataAccessorDcpToa5::adapt(DataSetPtr dataset, std::shared_ptr<te::da::DataSetTypeConverter> converter) const
{
    //only one timestamp column
    te::dt::DateTimeProperty* dtProperty = new te::dt::DateTimeProperty("DateTime", te::dt::TIME_INSTANT_TZ);

    //Find the rigth column to adapt
    std::vector<te::dt::Property*> properties = converter->getConvertee()->getProperties();
    for(size_t i = 0, size = properties.size(); i < size; ++i)
    {
        te::dt::Property* property = properties.at(i);

        if (property->getName() == getRecordPropertyName(dataset))
        {
            te::dt::Property* property = properties.at(i);

            std::string name = property->getName();

            te::dt::SimpleProperty* newProperty = new te::dt::SimpleProperty(name, te::dt::INT32_TYPE);
            converter->add(i, newProperty, boost::bind(&terrama2::core::DataAccessor::stringToInt, this, _1, _2, _3));
        }
        else if (property->getName() == getStationPropertyName(dataset))
        {
            te::dt::Property* property = properties.at(i);

            converter->add(i, property->clone());
        }
        else if(property->getName() == getTimestampPropertyName(dataset))
        {
            // datetime column found
            converter->add(i, dtProperty, boost::bind(&terrama2::core::DataAccessorDcpToa5::stringToTimestamp, this, _1, _2, _3, getTimeZone(dataset)));
        }
        else
        {
            // DCP-TOA5 dataset columns have the name of the dcp before every column,
            // remove the name and keep only the column name
            te::dt::Property* property = properties.at(i);

            std::string name = property->getName();

            te::dt::SimpleProperty* newProperty = new te::dt::SimpleProperty(name, te::dt::DOUBLE_TYPE);
            converter->add(i, newProperty, boost::bind(&terrama2::core::DataAccessor::stringToDouble, this, _1, _2, _3));
        }
    }
}
示例#15
0
int main(int *argc, char *argv[])
{
	//code for taking the date of the system
	time_t t = time(NULL);
	struct tm tm = *localtime(&t);
	SOCKET sockfd;
	struct sockaddr_in server_in;
	char buffer_in[1024], buffer_out[1024],input[1024];
	int recibidos=0,enviados=0;
	int estado=S_CONNECT;
	char option = 's';
	char d_option[5] = "";	//DATA option, for selecting the option in the DATA state
	int i_d_option = 0;		//for working with integer values on the DATA state option
	int error = 0;			//for controlling some possible errors during the insertion of the mail data
	char date[50] = "";		//for taking the date into a variable for later use
	char m_from[50] = "";	//source email
	char m_to[50] = "";		//destination email
	char subject[50] = "";	//subject of the message
	char from[50] = "";		//variable for the from of the mail header
	char to[50] = "";		//variable for the to of the mail header
	char message[1000] = "";//the message's body

	//for getting the time zone
	int time_zone = 0;
	char timezone[5];

	//variables for date
	int d_day = 0;
	int d_month = 0;
	char c_day[4] = "";
	char c_month[4] = "";

	WORD wVersionRequested;
	WSADATA wsaData;
	int err;

    char ipdest[16];
	char default_ip[16]="127.0.0.1";
	//variables for the port of the server, 25 as default port
	char tcp_port[16];
	char default_tcp_port[16]="25";
	int s_tcp_port = 0;
	//variable for the recived code as response from the server for a command
	int r_code;
	char r_c_code[20] = "";
	//Inicialización Windows sockets
	wVersionRequested=MAKEWORD(1,1);
	err=WSAStartup(wVersionRequested,&wsaData);
	if(err!=0)
		return(0);

	if(LOBYTE(wsaData.wVersion)!=1||HIBYTE(wsaData.wVersion)!=1)
	{
		WSACleanup();
		return(0);
	}
	//Fin: Inicialización Windows sockets

	do{
		sockfd=socket(AF_INET,SOCK_STREAM,0);

		if(sockfd==INVALID_SOCKET)
		{
			printf("CLIENTE> ERROR AL CREAR SOCKET\r\n");
			exit(-1);
		}
		else
		{
			printf("CLIENTE> SOCKET CREADO CORRECTAMENTE\r\n");

		
			printf("CLIENTE> Introduzca la IP destino (pulsar enter para IP por defecto): ");
			gets(ipdest);

			if(strcmp(ipdest,"")==0)
				strcpy(ipdest,default_ip);
			
			//user must insert the TCP port of the SMTP server, 25 as default
			printf("CLIENTE> Insert the TCP port of the server (intro for default PORT): ");
			gets(tcp_port);

			if(strcmp(tcp_port, "") == 0)
			{
				strcpy(tcp_port, default_tcp_port);
			}
			//once the user has inserted the port, it's converted into short
			sscanf_s(tcp_port, "%d", &s_tcp_port);

			server_in.sin_family=AF_INET;
			server_in.sin_port=htons(s_tcp_port);
			server_in.sin_addr.s_addr=inet_addr(ipdest);
			
			estado=S_CONNECT;
		
			// establece la conexion de transporte
			if(connect(sockfd,(struct sockaddr*)&server_in,sizeof(server_in))==0)
			{
				printf("CLIENTE> CONEXION ESTABLECIDA CON %s:%d\r\n",ipdest,s_tcp_port);
			
		
				//Inicio de la máquina de estados
				do{
					switch(estado)
					{
					case S_CONNECT:
						break;
					case S_HELO:
						// Se recibe el mensaje de bienvenida
						sprintf_s(buffer_out, sizeof(buffer_out), "HELO hi\r\n");
						break;
					case S_DATA:
						do
						{
							printf("CLIENTE> Select an option\r\n");
							printf("1) Write email\r\n");
							printf("2) QUIT (close session)\r\n");
							printf("3) EXIT (from program)\r\n");
							gets(d_option);
							sscanf_s(d_option, "%d", &i_d_option);
							switch (i_d_option)
							{
								case 1:
									/* if the user choose to write an email, it will change the state to S_MAIL_F, but this state 
									*  is what you can see hear, after the user insert the email, the state will change to S_RCPT_T
									*/
									estado++;
									printf("CLIENT> Insert the email source:");
									gets(input);
									strcpy(m_from, input);
									if(strcmp(input, "QUIT") == 0)
									{
										sprintf_s(buffer_out, sizeof(buffer_out), "%s%s", SD, CRLF);
									}
									else
									{
										sprintf_s(buffer_out, sizeof(buffer_out), "MAIL FROM: %s%s", input, CRLF);
									}
									break;
								case 2:
									sprintf_s (buffer_out, sizeof(buffer_out), "%s%s",SD,CRLF);
									estado=S_QUIT;
									break;
								case 3:
									sprintf_s (buffer_out, sizeof(buffer_out), "%s%s",SD,CRLF);
									estado=S_QUIT;
									option = 'n';
									break;
								default:
									printf("CLIENT> Incorrect option, please, choose one of the following options");
									break;
							}
						}while(i_d_option < 1 || i_d_option > 3);
						break;
					case S_RCPT_T:
						printf("CLIENT> Insert the destination email:");
						gets(input);
						strcpy(m_to, input);
						if(strcmp(input, "QUIT") == 0)
						{
							sprintf_s(buffer_out, sizeof(buffer_out), "%s%s", SD, CRLF);
						}
						else
						{
							sprintf_s(buffer_out, sizeof(buffer_out), "RCPT TO:%s%s", input, CRLF);
						}
						break;
					case S_SEND_D:
						printf("DATA%s", CRLF);
						sprintf_s(buffer_out, sizeof(buffer_out), "DATA%s", CRLF);
						break;
					case S_MAIL_B:
						//code for taking the date from the system, it must be taken foreach time a user write an email
						t = time(NULL);
						tm = *localtime(&t);
						//constructing the date format
						d_day = tm.tm_wday;
						d_month = tm.tm_mon;
						//taking the day

						/** NOTA DEL PROFESOR *************************
						La función strtime aporta toda esta información
						automáticamente
						**********************************************/
						switch (d_day)
						{
							case 0:
								sprintf_s(c_day, sizeof(c_day), "Sun");
								break;
							case 1:
								sprintf_s(c_day, sizeof(c_day), "Mon");
								break;
							case 2:
								sprintf_s(c_day, sizeof(c_day), "Tue");
								break;
							case 3:
								sprintf_s(c_day, sizeof(c_day), "Wed");
								break;
							case 4:
								sprintf_s(c_day, sizeof(c_day), "Thu");
								break;
							case 5:
								sprintf_s(c_day, sizeof(c_day), "Fri");
								break;
							case 6:
								sprintf_s(c_day, sizeof(c_day), "Sat");
								break;
						}
						//taking the month
						switch (d_month)
						{
							case 0:
								sprintf_s(c_month, sizeof(c_month), "Jan");
								break;
							case 1:
								sprintf_s(c_month, sizeof(c_month), "Feb");
								break;
							case 2:
								sprintf_s(c_month, sizeof(c_month), "Mar");
								break;
							case 3:
								sprintf_s(c_month, sizeof(c_month), "Apr");
								break;
							case 4:
								sprintf_s(c_month, sizeof(c_month), "May");
								break;
							case 5:
								sprintf_s(c_month, sizeof(c_month), "Jun");
								break;
							case 6:
								sprintf_s(c_month, sizeof(c_month), "Jul");
								break;
							case 7:
								sprintf_s(c_month, sizeof(c_month), "Aug");
								break;
							case 8:
								sprintf_s(c_month, sizeof(c_month), "Sep");
								break;
							case 9:
								sprintf_s(c_month, sizeof(c_month), "Oct");
								break;
							case 10:
								sprintf_s(c_month, sizeof(c_month), "Nov");
								break;
							case 11:
								sprintf_s(c_month, sizeof(c_month), "Dec");
								break;
						}

						time_zone = getTimeZone();
						if(time_zone < 10)
						{
							sprintf_s(timezone, sizeof(timezone), "0%d", time_zone);
						}
						else
						{
							sprintf_s(timezone, sizeof(timezone), "%d", time_zone);
						}

						sprintf_s(date, sizeof(date), "%s, %d %s %d %d:%d:%d +%s00", c_day, tm.tm_mday, c_month, tm.tm_year + 1900, tm.tm_hour, tm.tm_min, tm.tm_sec, timezone);
						//user must insert a subjet, if user do not insert anything, it'll loop until user insert it
						printf("subjet: ");
						do
						{
							if(error == 1)
							{
								printf("CLIENT> subjet required, please, insert a subjet: ");
							}
							gets(input);
							error = 1;
						}while(strcmp(input, "") == 0);
						error = 0;
						strcpy(subject, input);
						//if user don't insert an alias for the source of the message and the destination, it'll be set
						//the source and destination email address
						printf("CLIENT> from (if empty it'll be set the mail inserted on the MAIL FROM before): ");
						gets(input);
						if(strcmp(input, "") == 0)
						{
							strcpy(from, m_from);
						}
						else
						{
							strcpy(from, input);
						}
						printf("CLIENT> to (if empty it'll be set the mail inserted on the MAIL FROM before): ");
						gets(input);
						if(strcmp(input, "") == 0)
						{
							strcpy(to, m_to);
						}
						else
						{
							strcpy(to, input);
						}
						printf("CLIENT> Insert the body of the message: %s", CRLF);
						printf("NOTE: insert CRLF.CRLF for ending the text typing%s", CRLF);
						/*	this loop sentence will take endless lines until user insert in a new line just the "." char
						*	the way it works is by getting all the lines the user insert, and concatenating the new inputs
						*	with the old ones in a vector of char (string message). Just one the user insert in a new line
						*	a simple char ".", the condition in the while sentence will detect it and will make the loop end
						*/
						do
						{
							gets(input);
							strcat(input, CRLF);
							strcat(message, input);
						}while(strcmp(input, ".\r\n") != 0);
						/*** NOTA DEL PROFESOR ******************************+
						No se pueden enviar correos más largos que la longitude de buffer_out
						por lo que se cumple con uno de los objetivos
						
						*/

						sprintf_s(buffer_out, sizeof(buffer_out), "date:%s\r\nsubject:%s\r\nto:%s\r\nfrom:%s\r\n\r\n%s", date, subject, to, from, message);
						break;
					}
					//Envio
					// Ejercicio: Comprobar el estado de envio
					if(estado != S_CONNECT)
					{
						enviados=send(sockfd,buffer_out,(int)strlen(buffer_out),0);
					}
					if(enviados <= 0 && estado != S_CONNECT)
					{
						DWORD error = GetLastError();
						if(enviados < 0)
						{
							printf("CLIENTE> FAIL SENDING DATA TO THE SERVER: %d%s", error, CRLF);
							estado=S_QUIT;
						}
						else
						{
							printf("CLIENTE> END CONEXION WITH THE SERVER%s", CRLF);
							estado=S_QUIT;
						}
					}
					//Recibo
					recibidos=recv(sockfd,buffer_in,512,0);

					if(recibidos<=0 && estado != S_CONNECT)
					{
						DWORD error=GetLastError();
						if(recibidos<0)
						{
							printf("CLIENTE> Error %d en la recepción de datos\r\n",error);
							estado=S_QUIT;
						}
						else
						{
							printf("CLIENTE> Conexión con el servidor cerrada\r\n");
							estado=S_QUIT;
						
					
						}
					}
					else
					{
						buffer_in[recibidos]=0x00;
						//takes the error code (or non error code) from the server response
						sscanf_s(buffer_in, "%d %s", &r_code, r_c_code, sizeof(r_c_code));
						printf(buffer_in);
						switch (r_code)
						{
							//response for the initial connection with the server
							case 220:
								estado++;
								break;
							//server code response to a QUIT message
							case 221:
									estado = S_QUIT;
								break;
							case 250:
								//Controlling the server response for a helo message, if cliente is in HELO state and a 250 code message is received, it means that
								//the helo message was valid
								if(estado == S_HELO)
								{
									estado++;
								}
								//for controlling the MAIL FROM and RCPT TO message
								else if(estado == S_MAIL_F || estado == S_RCPT_T)
								{
									estado++;
								}
								//for controlling that the message has been sent correctly to it's destination
								else if(estado = S_MAIL_B)
								{
									printf("CLIENT> Write more email? (Y/N)%s", CRLF);
									option=_getch();
									if(option == 'y' || option == 'Y')
									{
										//cleaning the buffer_out
										sprintf_s(message, sizeof(message), "");
										estado = S_DATA;
									}
									else if(option == 'n' || option == 'N')
									{
										estado = S_QUIT;
									}
								}
								break;
							case 354:
								//recieve from the server after the DATA message is send
								estado++;
								break;
							default:
								break;
						}
					}

				}while(estado!=S_QUIT);
				
	
		
			}
			else
			{
				printf("CLIENTE> ERROR AL CONECTAR CON %s:%d\r\n",ipdest,s_tcp_port);
			}		
			// fin de la conexion de transporte
			closesocket(sockfd);
			
		}
		if(option != 'n' && option != 'N')
		{
			printf("-----------------------\r\n\r\nCLIENTE> Volver a conectar (S/N)\r\n");
			//if user want to send another mail, the state will be set to the initial state
			option=_getche();
			if(option == 's' || option == 'S')
			{
				estado=S_CONNECT;
				sprintf_s(buffer_out, sizeof(buffer_out), "0x00");	//cleaning the buffer_out for new connections
			}
		}
	}while(option!='n' && option!='N');

	
	
	return(0);

}
示例#16
0
int main(int *argc, char *argv[])
{
	SOCKET sockfd; // Definimos un socket, lo llamamos sockfd
	struct sockaddr_in server_in; // Estructura basica para llamadas al sistema y funciones relacionada con direcciones de Internet
	char buffer_in[1024], buffer_out[1048],origen[15],destino[15],mensaje[500]="",asunto[20],copia[500]; // Buffers y entrada de datos
	int recibidos=0,enviados=0; // Variables para el envio y recepcion de los datos, ambas iniciadas a 0
	int estado=S_HELO; // Estados de la conexion iniciado a S_HELO
	char option; // Variable condicional para el bucle "do"
	WORD wVersionRequested; // Para trabajar con sockets en Windows
	WSADATA wsaData; // Para trabajar con sockets en Windows
	int err,fin=0,opcion; // Usamos "err" para la comprobacion de errores
    char ipdest[16];// Declaramos la direccion IP destino
	char default_ip[16]="127.0.0.1"; // Direccion IP establecida por defecto
	int i;
	/*Para la fecha y hora*/
	time_t tiempo = time(0);
	struct tm *tlocal = localtime(&tiempo);
	char zona[10];
	char output[20];

	//Inicialización Windows sockets
	wVersionRequested=MAKEWORD(1,1);
	err=WSAStartup(wVersionRequested,&wsaData);
	if(err!=0)
		return(0);

	if(LOBYTE(wsaData.wVersion)!=1||HIBYTE(wsaData.wVersion)!=1)
	{
		WSACleanup();  // Liberar recursos de la liberia
		return(0);
	}
	//Fin: Inicialización Windows sockets

	/* Con "do" se crea el socket en el que se recibiran y se enviaran los datos */

	do{
		sockfd=socket(AF_INET,SOCK_STREAM,0);  //Creamos socket

		if(sockfd==INVALID_SOCKET) // Si el socket es invalido, mostramos un error por pantalla.
		{
			printf("CLIENTE> ERROR AL CREAR SOCKET\r\n");
			exit(-1);
		} 
		else // Si el socket es valido, mostramos mensaje por pantalla
		{
			printf("CLIENTE> SOCKET CREADO CORRECTAMENTE\r\n");

			// Pedimos la IP de destino, si pulsamos "Enter" introduciremos la IP por defecto indicada en la parte superior del codigo		
			printf("CLIENTE> Introduzca la IP destino (pulsar enter para IP por defecto): ");
			gets(ipdest);

			// Para introducir la IP por defecto al pulsar "Enter"
			if(strcmp(ipdest,"")==0)
				strcpy(ipdest,default_ip);

			// Asignamos los valores a la estructura creada al inicio del codigo, "server_in"
			server_in.sin_family=AF_INET; // Familia de protocolos de Internet
			server_in.sin_port=htons(SMTP_SERVICE_PORT); // Puerto del servidor
			server_in.sin_addr.s_addr=inet_addr(ipdest); // Direccion IP del servidor
			
			estado=S_WELCOME; // Se reestablece el estado inicial
		
			// establece la conexion de transporte
			if(connect(sockfd,(struct sockaddr*)&server_in,sizeof(server_in))==0)
			{
				printf("CLIENTE> CONEXION ESTABLECIDA CON %s:%d\r\n",ipdest,SMTP_SERVICE_PORT);
				fin=0;
			
				//Inicio de la máquina de estados

				do{
					fflush(stdin); /*limpiamos el buffer de teclado*/

					/*Enviar más de un correo*/
						if(estado==S_QUIT  && strncmp(buffer_in,"2",1)==0)
						{
							char opcion;
							printf("¿Deseas enviar otro correo? S/N\n");
							opcion=getch();
							if(opcion=='s' || opcion=='S')
							{
							estado=S_MAIL; /*Pasamos al estado de destinatario*/
							}
						 }
				
					switch(estado)  //Maquina de estados
					{

					case S_WELCOME:
						// Se recibe el mensaje de bienvenida
						
						break;
					case S_HELO:
						// Se prepara el comando helo
						sprintf_s (buffer_out, sizeof(buffer_out), "HELO %s%s",ipdest,CRLF);
						break;

					case S_MAIL:
						// Establece la conexion de aplicacion 
						printf("CLIENTE> Introduzca su usuario: ");
						gets(origen);
						if(strlen(origen)==0) /*Si no se introduce nada, se vuelve a pedir*/
						{
							do{
								printf("CLIENTE> Introduzca su usuario: ");
								gets(origen);

							}while(strlen(origen)==0); //Repetimos la peticion de usuario hasta cumplir la condicion

						sprintf_s (buffer_out, sizeof(buffer_out), "MAIL FROM: %s%s",origen,CRLF);  //Guardamos MAIL FROM en el buffer junto al usuario origen

						}
						else
						{
						sprintf_s (buffer_out, sizeof(buffer_out), "MAIL FROM: %s%s",origen,CRLF); //Guardamos MAIL FROM en el buffer junto al usuario origen
						}
						break;

					case S_RCPT:
						// Introducimos el destinatario del mail
						printf("CLIENTE> Introduzca el destinatario: ");
						gets(destino);
						if(strlen(destino)==0)  /*Si no se introduce nada, se vuelve a pedir*/

						{ 
								do{
									printf("CLIENTE> Introduzca el destinatario: ");
									gets(destino);
								
								}while(strlen(destino)==0); //Repetimos la peticion de usuario hasta cumplir la condicion

							sprintf_s (buffer_out, sizeof(buffer_out), "RCPT TO: %s%s",destino,CRLF); //Guardamos RCPT TO en el buffer junto al destinatario
						}
						else
						{
							sprintf_s (buffer_out, sizeof(buffer_out), "RCPT TO: %s%s",destino,CRLF); //Guardamos RCPT TO en el buffer junto al destinatario
						}
						break;

					case S_DATA:
				// Empieza el envio del cuerpo del mensaje
						sprintf_s (buffer_out, sizeof(buffer_out), "DATA%s",CRLF);
						estado=S_MENSAJE;
						break;
				case S_MENSAJE:
					// Escribimos el mensaje
					 strftime(output,128,"%d/%m/%y %H:%M:%S",tlocal);				//Fecha, hora y zona horaria
					 printf("Introduce el asunto del mensaje:");
					 gets(asunto); // Asunto del email

					 /*Envio de las cabeceras*/
					 sprintf_s(buffer_out, sizeof(buffer_out), "Date: %s GMT:%d%sFrom: <%s>%sSubject: %s%sTo: <%s>%s%s",output,getTimeZone(),CRLF,origen,CRLF,asunto,CRLF,destino,CRLF,CRLF); // Cabeceras del correo según RFC

					 enviados=send(sockfd,buffer_out,(int)strlen(buffer_out),0);
					 /*Comprobacion de envío correcto*/
					 if(enviados==SOCKET_ERROR || enviados==0) // Si ha habido error en el socket o no hay datos enviados
						{
							if(enviados==SOCKET_ERROR)
							{
							DWORD error=GetLastError();
							printf("CLIENTE> Error %d en el envío de datos\r\n",error); // Error 
							fin=1;
							}
							else
							{
							printf("CLIENTE> Conexión con el servidor cerrada\r\n"); // Cerramos conexion
							fin=1;
							}
							continue;
						}
									 
					 printf("Introduce el mensaje: "); // Introducimos el mensaje
						do
						{
							gets(copia);
							sprintf_s(buffer_out, sizeof(buffer_out), "%s%s",copia,CRLF);
							if(strcmp(copia,".")!=0)  /*Solo se envia el mensaje si es distinto de '.'*/ 
							{
							enviados=send(sockfd,buffer_out,(int)strlen(buffer_out),0);
							/*Comprobacion de envio correcto*/
								if(enviados==SOCKET_ERROR || enviados==0) // Error o sin datos enviados
								{
									if(enviados==SOCKET_ERROR)
									{
										DWORD error=GetLastError();
										printf("CLIENTE> Error %d en el envío de datos\r\n",error);
										fin=1;
									}
									else
									{
										printf("CLIENTE> Conexión con el servidor cerrada\r\n");
										fin=1;
									}
								continue;
								}
							}
						}while(strcmp(copia,".")!=0); /*Se van enviando todas las cadenas que introduce el cliente hasta introducir un "."*/
										
						sprintf_s(buffer_out, sizeof(buffer_out), ".%s",CRLF); /*Metemos en el buffer_out el fin de mensaje*/
						
					break;

				case S_QUIT:
//Fin
					sprintf_s (buffer_out, sizeof(buffer_out), "QUIT%s",CRLF); 
					fin=1;
					break;
					}/*Cierre del switch*/
								
				
					if(estado!=S_WELCOME){ //Si no estamos en WELCOME, se produce el envio
						enviados=send(sockfd,buffer_out,(int)strlen(buffer_out),0);
						if(enviados==SOCKET_ERROR || enviados==0) // Si hay error o no hay datos enviados, mostramos los errores
						{
							if(enviados==SOCKET_ERROR)
							{
							DWORD error=GetLastError();
							printf("CLIENTE> Error %d en el envío de datos\r\n",error);
							fin=1;
							}
							else
							{
							printf("CLIENTE> Conexión con el servidor cerrada\r\n");
							fin=1;
							}
							continue;
						}
					}
						
					/*Recibimos los datos del servidor*/
					recibidos=recv(sockfd,buffer_in,512,0);
					
					if(recibidos<=0) // Si recibimos 0 o -1
					{
						DWORD error=GetLastError();
						if(recibidos<0) // Si recibimos un -1 o SOCKET_ERROR la operacion ha fallado
						{
							printf("CLIENTE> Error %d en la recepción de datos\r\n",error); 
							fin=1;
						}
						else // Si recibimos un 0, la conexion ha sido liberada de forma acordada
						{
							printf("CLIENTE> Conexión con el servidor cerrada\r\n");
							fin=1;
						
					
						}
					}else{  // Si recibimos la cantidad de bytes enviados
						
						buffer_in[recibidos]=0x00; // Iniciamos a 0 porque en C los arrays finalizan con el byte 0000 0000
						printf(buffer_in); // Imprimimos por pantalla el valor
 
						/*Comprobacion de envio correcto mediante las respuestas del servidor, todas empezaran por 2 (250,221) */
						if((estado==S_WELCOME || estado==S_HELO || estado==S_MAIL || estado==S_RCPT || estado==S_MENSAJE) && strncmp(buffer_in,"2",1)==0)
							estado++;
						/*La respuesta del servidor para DATA es 354*/
						if(estado==S_DATA && strncmp(buffer_in,"3",1)==0)
							estado++;
					}

				}while(fin!=1); 
			}
			else
			{
				printf("CLIENTE> ERROR AL CONECTAR CON %s:%d\r\n",ipdest,SMTP_SERVICE_PORT); // Muestra el mensaje de error al conectar el cliente con la IP destino y el puerto TCP escogidos
			}		
			// fin de la conexion de transporte
			closesocket(sockfd);
			
		}	
		do{
		printf("-----------------------\r\n\r\nCLIENTE> Volver a conectar (S/N)\r\n"); // Opcion para volver a realizar una conexion
		option=_getche();
		}while((option!='s' && option!='S') && (option!='n' && option!='N'));
		
	}while(option!='n' && option!='N');
	// Fin del primer "do", sale de el cuando se introduce por teclado una "n" o una "N"
	
	
	return(0);

}