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); }
// //{--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; }
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); }
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(); }
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; }
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); }
// // {--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(); }
// //[-]{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(); }
// // 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)); } } }
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)); } } }
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); }
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); }