strappend(char *s, char *t) /* === */ { s = endstr( s ); while ( (*s++ = *t++) != '\0' ); *s = '\0'; }
bool upb_sink_endstr(upb_sink *s, upb_selector_t sel) { --s->top; assert(sel == s->top->selector); const upb_handlers *h = s->top->h; upb_endfield_handler *endstr = (upb_endfield_handler*)upb_handlers_gethandler(h, sel); if (endstr) { const void *hd = upb_handlers_gethandlerdata(h, sel); bool ok = endstr(s->top->closure, hd); if (!ok) { ++s->top; return false; } } return true; }
//-------------------------------------------------------- void WebSocketDSClass::write_class_property() { // First time, check if database used if (Tango::Util::_UseDb == false) return; Tango::DbData data; string classname = get_name(); string header; string::size_type start, end; // Put title Tango::DbDatum title("ProjectTitle"); string str_title("WebSocket access to tango device-server attributes, pipes and commands"); title << str_title; data.push_back(title); // Put Description Tango::DbDatum description("Description"); vector<string> str_desc; str_desc.push_back("WebSocket access to tango device-server attributes."); str_desc.push_back(""); str_desc.push_back("Configuration should be done via properties:"); str_desc.push_back(""); str_desc.push_back("Port - port to listen incoming ws connections;"); str_desc.push_back("DeviceServer - tango id of a required device server;"); str_desc.push_back("Attributes - list of required DS attributes, you wish to read via WS;"); str_desc.push_back("Commands - list of required DS commandes, you wish to executed via WS;"); str_desc.push_back("AuthDS - Tango web authentication device server (TangoWebAuth ) name."); str_desc.push_back("Secure - It will be used wss connection (websocket secure). (true if you want)"); str_desc.push_back("Certificate - Certificate file name (crt) with full path (if Secure = true)"); str_desc.push_back("Key - Private key file name (if Secure = true)"); str_desc.push_back("Options - Various options for the device server"); str_desc.push_back(""); str_desc.push_back("Then you should set polling to the UpdateData command. (1000 means that all connected clients would read attributes once per second)."); str_desc.push_back(""); str_desc.push_back("Data format: JSON string with array of attrubute objects {atrrtibute name, attribute value, quality, timestamp};"); str_desc.push_back(""); str_desc.push_back("if you want to record in the logs, define uselog in Property ``Options``."); str_desc.push_back("The database (defined in AuthDS) must contain a table `command_history` with columns:"); str_desc.push_back(" // id - autoincrement"); str_desc.push_back(" // argin[0] = timestamp_string UNIX_TIMESTAMP"); str_desc.push_back(" // argin[1] = login"); str_desc.push_back(" // argin[2] = deviceName"); str_desc.push_back(" // argin[3] = IP"); str_desc.push_back(" // argin[4] = commandName"); str_desc.push_back(" // argin[5] = commandJson"); str_desc.push_back(" // argin[6] = statusBool"); str_desc.push_back(" // argin[7] = isGroup"); description << str_desc; data.push_back(description); // put cvs or svn location string filename("WebSocketDS"); filename += "Class.cpp"; // check for cvs information string src_path(CvsPath); start = src_path.find("/"); if (start!=string::npos) { end = src_path.find(filename); if (end>start) { string strloc = src_path.substr(start, end-start); // Check if specific repository start = strloc.find("/cvsroot/"); if (start!=string::npos && start>0) { string repository = strloc.substr(0, start); if (repository.find("/segfs/")!=string::npos) strloc = "ESRF:" + strloc.substr(start, strloc.length()-start); } Tango::DbDatum cvs_loc("cvs_location"); cvs_loc << strloc; data.push_back(cvs_loc); } } // check for svn information else { string src_path(SvnPath); start = src_path.find("://"); if (start!=string::npos) { end = src_path.find(filename); if (end>start) { header = "$HeadURL: "; start = header.length(); string strloc = src_path.substr(start, (end-start)); Tango::DbDatum svn_loc("svn_location"); svn_loc << strloc; data.push_back(svn_loc); } } } // Get CVS or SVN revision tag // CVS tag string tagname(TagName); header = "$Name: "; start = header.length(); string endstr(" $"); end = tagname.find(endstr); if (end!=string::npos && end>start) { string strtag = tagname.substr(start, end-start); Tango::DbDatum cvs_tag("cvs_tag"); cvs_tag << strtag; data.push_back(cvs_tag); } // SVN tag string svnpath(SvnPath); header = "$HeadURL: "; start = header.length(); end = svnpath.find(endstr); if (end!=string::npos && end>start) { string strloc = svnpath.substr(start, end-start); string tagstr ("/tags/"); start = strloc.find(tagstr); if ( start!=string::npos ) { start = start + tagstr.length(); end = strloc.find(filename); string strtag = strloc.substr(start, end-start-1); Tango::DbDatum svn_tag("svn_tag"); svn_tag << strtag; data.push_back(svn_tag); } } // Get URL location string httpServ(HttpServer); if (httpServ.length()>0) { Tango::DbDatum db_doc_url("doc_url"); db_doc_url << httpServ; data.push_back(db_doc_url); } // Put inheritance Tango::DbDatum inher_datum("InheritedFrom"); vector<string> inheritance; inheritance.push_back("TANGO_BASE_CLASS"); inher_datum << inheritance; data.push_back(inher_datum); // Call database and and values get_db_class()->put_property(data); }
//+---------------------------------------------------------------------------- // // method : SimulatorCCDClass::write_class_property // // description : Set class description as property in database // //----------------------------------------------------------------------------- void SimulatorCCDClass::write_class_property() { // First time, check if database used //-------------------------------------------- if (Tango::Util::_UseDb == false) return; Tango::DbData data; string classname = get_name(); string header; string::size_type start, end; // Put title Tango::DbDatum title("ProjectTitle"); string str_title(""); title << str_title; data.push_back(title); // Put Description Tango::DbDatum description("Description"); vector<string> str_desc; str_desc.push_back(" "); description << str_desc; data.push_back(description); // put cvs or svn location string filename(classname); filename += "Class.cpp"; // Create a string with the class ID to // get the string into the binary string class_id(ClassId); // check for cvs information string src_path(CvsPath); start = src_path.find("/"); if (start!=string::npos) { end = src_path.find(filename); if (end>start) { string strloc = src_path.substr(start, end-start); // Check if specific repository start = strloc.find("/cvsroot/"); if (start!=string::npos && start>0) { string repository = strloc.substr(0, start); if (repository.find("/segfs/")!=string::npos) strloc = "ESRF:" + strloc.substr(start, strloc.length()-start); } Tango::DbDatum cvs_loc("cvs_location"); cvs_loc << strloc; data.push_back(cvs_loc); } } // check for svn information else { string src_path(SvnPath); start = src_path.find("://"); if (start!=string::npos) { end = src_path.find(filename); if (end>start) { header = "$HeadURL: "; start = header.length(); string strloc = src_path.substr(start, (end-start)); Tango::DbDatum svn_loc("svn_location"); svn_loc << strloc; data.push_back(svn_loc); } } } // Get CVS or SVN revision tag // CVS tag string tagname(TagName); header = "$Name: "; start = header.length(); string endstr(" $"); end = tagname.find(endstr); if (end!=string::npos && end>start) { string strtag = tagname.substr(start, end-start); Tango::DbDatum cvs_tag("cvs_tag"); cvs_tag << strtag; data.push_back(cvs_tag); } // SVN tag string svnpath(SvnPath); header = "$HeadURL: "; start = header.length(); end = svnpath.find(endstr); if (end!=string::npos && end>start) { string strloc = svnpath.substr(start, end-start); string tagstr ("/tags/"); start = strloc.find(tagstr); if ( start!=string::npos ) { start = start + tagstr.length(); end = strloc.find(filename); string strtag = strloc.substr(start, end-start-1); Tango::DbDatum svn_tag("svn_tag"); svn_tag << strtag; data.push_back(svn_tag); } } // Get URL location string httpServ(HttpServer); if (httpServ.length()>0) { Tango::DbDatum db_doc_url("doc_url"); db_doc_url << httpServ; data.push_back(db_doc_url); } // Put inheritance Tango::DbDatum inher_datum("InheritedFrom"); vector<string> inheritance; inheritance.push_back("Device_4Impl"); inher_datum << inheritance; data.push_back(inher_datum); // Call database and and values //-------------------------------------------- get_db_class()->put_property(data); }
//+---------------------------------------------------------------------------- // // method : GalilSlitClass::write_class_property // // description : Set class description as property in database // //----------------------------------------------------------------------------- void GalilSlitClass::write_class_property() { // First time, check if database used //-------------------------------------------- if (Tango::Util::_UseDb == false) return; Tango::DbData data; string classname = get_name(); string header; string::size_type start, end; // Put title Tango::DbDatum title("ProjectTitle"); string str_title("GalilSlit"); title << str_title; data.push_back(title); // Put Description Tango::DbDatum description("Description"); vector<string> str_desc; str_desc.push_back("handles generic slits"); str_desc.push_back("type independant blades"); str_desc.push_back("type 1 motor for gap plus 1 motor for translation"); str_desc.push_back("ETC"); description << str_desc; data.push_back(description); // put cvs location string rcsId(RcsId); string filename(classname); start = rcsId.find("/"); if (start!=string::npos) { filename += "Class.cpp"; end = rcsId.find(filename); if (end>start) { string strloc = rcsId.substr(start, end-start); // Check if specific repository start = strloc.find("/cvsroot/"); if (start!=string::npos && start>0) { string repository = strloc.substr(0, start); if (repository.find("/segfs/")!=string::npos) strloc = "ESRF:" + strloc.substr(start, strloc.length()-start); } Tango::DbDatum cvs_loc("cvs_location"); cvs_loc << strloc; data.push_back(cvs_loc); } } // Get CVS tag revision string tagname(TagName); header = "$Name: "; start = header.length(); string endstr(" $"); end = tagname.find(endstr); if (end!=string::npos && end>start) { string strtag = tagname.substr(start, end-start); Tango::DbDatum cvs_tag("cvs_tag"); cvs_tag << strtag; data.push_back(cvs_tag); } // Get URL location string httpServ(HttpServer); if (httpServ.length()>0) { Tango::DbDatum db_doc_url("doc_url"); db_doc_url << httpServ; data.push_back(db_doc_url); } // Put inheritance Tango::DbDatum inher_datum("InheritedFrom"); vector<string> inheritance; inheritance.push_back("Device_4Impl"); inher_datum << inheritance; data.push_back(inher_datum); // Call database and and values //-------------------------------------------- get_db_class()->put_property(data); }
/* * do_notice_ctcp: a re-entrant form of a CTCP reply parser. * See the implementation notes in do_ctcp(). */ char * do_notice_ctcp (const char *from, const char *to, char *str) { int flag; char local_ctcp_buffer [BIG_BUFFER_SIZE + 1], the_ctcp [IRCD_BUFFER_SIZE + 1], last [IRCD_BUFFER_SIZE + 1]; char *ctcp_command, *ctcp_argument; int i; char *ptr; int allow_ctcp_reply = 1; int l; int delim_char = charcount(str, CTCP_DELIM_CHAR); if (delim_char < 2) return str; /* No CTCPs. */ if (delim_char > 8) allow_ctcp_reply = 0; /* Ignore all the CTCPs. */ /* We handle ignore, but not flooding (obviously) */ flag = check_ignore_channel(from, FromUserHost, to, LEVEL_CTCP); in_ctcp_flag++; strlcpy(local_ctcp_buffer, str, sizeof(local_ctcp_buffer) - 2); for (;;strlcat(local_ctcp_buffer, last, sizeof(local_ctcp_buffer) - 2)) { if (split_CTCP(local_ctcp_buffer, the_ctcp, last)) break; /* All done! */ if (!*the_ctcp) continue; /* Empty requests are ignored */ /* * The logic of all this is essentially the same as * do_ctcp */ if (!allow_ctcp_reply) continue; if (flag == IGNORED) { if (x_debug & DEBUG_CTCPS) yell("CTCP REPLY from [%s] ignored", from); allow_ctcp_reply = 0; continue; } /* But we don't check ctcp flooding (obviously) */ /* Global messages -- just drop the CTCP */ if (*to == '$' || (is_channel(to) && !im_on_channel(to, from_server))) { allow_ctcp_reply = 0; continue; } /* * Parse CTCP message * CTCP spec says word delim MUST be space */ ctcp_command = the_ctcp; ctcp_argument = strchr(the_ctcp, ' '); if (ctcp_argument) *ctcp_argument++ = 0; else ctcp_argument = endstr(the_ctcp); /* Set up the window level/logging */ if (is_channel(to)) l = message_from(to, LEVEL_CTCP); else l = message_from(from, LEVEL_CTCP); /* * Find the correct CTCP and run it. */ for (i = 0; i < NUMBER_OF_CTCPS; i++) if (!strcmp(ctcp_command, ctcp_cmd[i].name)) break; /* * If its a built in CTCP command, check to see if its * got a reply handler, call if appropriate. */ if (i < NUMBER_OF_CTCPS && ctcp_cmd[i].repl) { if ((ptr = ctcp_cmd[i].repl(ctcp_cmd + i, from, to, ctcp_argument))) { strlcat(local_ctcp_buffer, ptr, sizeof local_ctcp_buffer); new_free(&ptr); pop_message_from(l); continue; } } /* Toss it at the user. */ if (ctcp_cmd[i].flag & CTCP_TELLUSER) { if (do_hook(CTCP_REPLY_LIST, "%s %s %s %s", from, to, ctcp_command, ctcp_argument)) say("CTCP %s reply from %s: %s", ctcp_command, from, ctcp_argument); } if (!(ctcp_cmd[i].flag & CTCP_NOLIMIT)) allow_ctcp_reply = 0; pop_message_from(l); } in_ctcp_flag--; /* * local_ctcp_buffer is derived from 'str', so its always * smaller or equal in size to 'str', so this copy is safe. */ strlcpy(str, local_ctcp_buffer, BIG_BUFFER_SIZE); return str; }
/* * do_ctcp: a re-entrant form of a CTCP parser. The old one was lame, * so i took a hatchet to it so it didnt suck. * * XXXX - important! The third argument -- 'str', is expected to be * 'BIG_BUFFER_SIZE + 1' or larger. If it isnt, chaos will probably * ensue if you get spammed with lots of CTCP UTC requests. * * UTC requests can be at minimum 5 bytes, and the expansion is always 24. * That means you can cram (510 - strlen("PRIVMSG x :") / 5) UTCs (100) * into a privmsg. That means itll expand to 2400 characters. We silently * limit the number of valid CTCPs to 4. Anything more than that we dont * even bother with. (4 * 24 + 11 -> 106), which is less than * IRCD_BUFFER_SIZE, which gives us plenty of safety. * * XXXX - The normal way of implementation required two copies -- once into a * temporary buffer, once back into the original buffer -- for the best case * scenario. This is horrendously inefficient, since most privmsgs dont * contain any CTCPs. So we check to see if there are any CTCPs in the * message before we bother doing anything. THIS IS AN INELEGANT HACK! * But the call to charcount() is less expensive than even one copy to * strlcpy() since they both evaluate *each* character, and charcount() * doesnt have to do a write unless the character is present. So it is * definitely worth the cost to save CPU time for 99% of the PRIVMSGs. */ char * do_ctcp (const char *from, const char *to, char *str) { int flag; int fflag; char local_ctcp_buffer [BIG_BUFFER_SIZE + 1], the_ctcp [IRCD_BUFFER_SIZE + 1], last [IRCD_BUFFER_SIZE + 1]; char *ctcp_command, *ctcp_argument; int i; char *ptr = NULL; int allow_ctcp_reply = 1; static time_t last_ctcp_parsed = 0; int l; char * extra = NULL; int delim_char = charcount(str, CTCP_DELIM_CHAR); if (delim_char < 2) return str; /* No CTCPs. */ if (delim_char > 8) allow_ctcp_reply = 0; /* Historical limit of 4 CTCPs */ flag = check_ignore_channel(from, FromUserHost, to, LEVEL_CTCP); fflag = new_check_flooding(from, FromUserHost, is_channel(to) ? to : NULL, str, LEVEL_CTCP); in_ctcp_flag++; strlcpy(local_ctcp_buffer, str, sizeof(local_ctcp_buffer) - 2); for (;;strlcat(local_ctcp_buffer, last, sizeof(local_ctcp_buffer) - 2)) { if (split_CTCP(local_ctcp_buffer, the_ctcp, last)) break; /* All done! */ if (!*the_ctcp) continue; /* Empty requests are ignored */ /* * Apply some integrety rules: * -- If we've already replied to a CTCP, ignore it. * -- If user is ignoring sender, ignore it. * -- If we're being flooded, ignore it. * -- If CTCP was a global msg, ignore it. */ /* * Yes, this intentionally ignores "unlimited" CTCPs like * UTC and SED. Ultimately, we have to make sure that * CTCP expansions dont overrun any buffers that might * contain this string down the road. So by allowing up to * 4 CTCPs, we know we cant overflow -- but if we have more * than 40, it might overflow, and its probably a spam, so * no need to shed tears over ignoring them. Also makes * the sanity checking much simpler. */ if (!allow_ctcp_reply) continue; /* * Check to see if the user is ignoring person. * Or if we're suppressing a flood. */ if (flag == IGNORED || fflag == 1) { if (x_debug & DEBUG_CTCPS) yell("CTCP from [%s] ignored", from); allow_ctcp_reply = 0; continue; } /* * Check for CTCP flooding */ if (get_int_var(NO_CTCP_FLOOD_VAR)) { if (time(NULL) - last_ctcp_parsed < 2) { /* * This extends the flood protection until * we dont get a CTCP for 2 seconds. */ last_ctcp_parsed = time(NULL); allow_ctcp_reply = 0; if (x_debug & DEBUG_CTCPS) say("CTCP flood from [%s] ignored", from); continue; } } /* * Check for global message */ if (*to == '$' || (*to == '#' && !im_on_channel(to, from_server))) { allow_ctcp_reply = 0; continue; } /* * Now its ok to parse the CTCP. * First we remove the argument. * XXX - CTCP spec says word delim MUST be space. */ ctcp_command = the_ctcp; ctcp_argument = strchr(the_ctcp, ' '); if (ctcp_argument) *ctcp_argument++ = 0; else ctcp_argument = endstr(the_ctcp); /* Set up the window level/logging */ if (im_on_channel(to, from_server)) l = message_from(to, LEVEL_CTCP); else l = message_from(from, LEVEL_CTCP); /* * Then we look for the correct CTCP. */ for (i = 0; i < NUMBER_OF_CTCPS; i++) if (!strcmp(ctcp_command, ctcp_cmd[i].name)) break; /* * We didnt find it? */ if (i == NUMBER_OF_CTCPS) { /* * Offer it to the user. * Maybe they know what to do with it. */ if (do_hook(CTCP_REQUEST_LIST, "%s %s %s %s", from, to, ctcp_command, ctcp_argument)) { if (do_hook(CTCP_LIST, "%s %s %s %s", from, to, ctcp_command, ctcp_argument)) { say("Unknown CTCP %s from %s to %s: %s%s", ctcp_command, from, to, *ctcp_argument ? ": " : empty_string, ctcp_argument); } } time(&last_ctcp_parsed); allow_ctcp_reply = 0; pop_message_from(l); continue; } /* * rfc1459_any_to_utf8 specifically ignores CTCPs, because * recoding binary data (such as an encrypted message) would * corrupt the message. * * So some CTCPs are "recodable" and some are not. * * The CTCP_NORECODE is set for any CTCPs which are NOT * to be recoded prior to handling. These are the encryption * CTCPS. * * All other CTCPs have not been recoded by the time they * reach here, so we must do it here! */ if (!(ctcp_cmd[i].flag & CTCP_NORECODE)) { /* * We must recode to UTF8 */ inbound_recode(from, from_server, to, ctcp_argument, &extra); if (extra) ctcp_argument = extra; } /* * We did find it. Acknowledge it. */ ptr = NULL; if (do_hook(CTCP_REQUEST_LIST, "%s %s %s %s", from, to, ctcp_command, ctcp_argument)) { ptr = ctcp_cmd[i].func(ctcp_cmd + i, from, to, ctcp_argument); } /* * If this isnt an 'unlimited' CTCP, set up flood protection. * * No, this wont allow users to flood any more than they * would normally. The UTC/SED gets converted into a * regular privmsg body, which is flagged via FLOOD_PUBLIC. */ if (!(ctcp_cmd[i].flag & CTCP_NOLIMIT)) { time(&last_ctcp_parsed); allow_ctcp_reply = 0; } /* * We've only gotten to this point if its a valid CTCP * query and we decided to parse it. */ /* * If its an ``INLINE'' CTCP, we paste it back in. */ if (ctcp_cmd[i].flag & CTCP_INLINE) strlcat(local_ctcp_buffer, ptr ? ptr : empty_string, sizeof local_ctcp_buffer); /* * If its ``INTERESTING'', tell the user. * Note that this isnt mutex with ``INLINE'' in theory, * even though it is in practice. Dont use 'else' here. */ if (ctcp_cmd[i].flag & CTCP_TELLUSER) { if (do_hook(CTCP_LIST, "%s %s %s %s", from, to, ctcp_command, ctcp_argument)) { if (is_me(from_server, to)) say("CTCP %s from %s%s%s", ctcp_command, from, *ctcp_argument ? ": " : empty_string, ctcp_argument); else say("CTCP %s from %s to %s%s%s", ctcp_command, from, to, *ctcp_argument ? ": " : empty_string, ctcp_argument); } } new_free(&extra); new_free(&ptr); pop_message_from(l); } in_ctcp_flag--; /* * 'str' is required to be BIG_BUFFER_SIZE + 1 or bigger per the API. */ strlcpy(str, local_ctcp_buffer, BIG_BUFFER_SIZE); return str; }
//-------------------------------------------------------- void ModbusControlRfqAndBuncherClass::write_class_property() { // First time, check if database used if (Tango::Util::_UseDb == false) return; Tango::DbData data; string classname = get_name(); string header; string::size_type start, end; // Put title Tango::DbDatum title("ProjectTitle"); string str_title("Control panel for modbus-tcp communication with PLC (DELTA-DVP28SR11R)"); title << str_title; data.push_back(title); // Put Description Tango::DbDatum description("Description"); vector<string> str_desc; str_desc.push_back("Control panel for modbus-tcp communication with PLC (DELTA-DVP28SR11R)"); str_desc.push_back("This device server read registers and read/write flags from PLC."); description << str_desc; data.push_back(description); // put cvs or svn location string filename("ModbusControlRfqAndBuncher"); filename += "Class.cpp"; // check for cvs information string src_path(CvsPath); start = src_path.find("/"); if (start!=string::npos) { end = src_path.find(filename); if (end>start) { string strloc = src_path.substr(start, end-start); // Check if specific repository start = strloc.find("/cvsroot/"); if (start!=string::npos && start>0) { string repository = strloc.substr(0, start); if (repository.find("/segfs/")!=string::npos) strloc = "ESRF:" + strloc.substr(start, strloc.length()-start); } Tango::DbDatum cvs_loc("cvs_location"); cvs_loc << strloc; data.push_back(cvs_loc); } } // check for svn information else { string src_path(SvnPath); start = src_path.find("://"); if (start!=string::npos) { end = src_path.find(filename); if (end>start) { header = "$HeadURL: "; start = header.length(); string strloc = src_path.substr(start, (end-start)); Tango::DbDatum svn_loc("svn_location"); svn_loc << strloc; data.push_back(svn_loc); } } } // Get CVS or SVN revision tag // CVS tag string tagname(TagName); header = "$Name: "; start = header.length(); string endstr(" $"); end = tagname.find(endstr); if (end!=string::npos && end>start) { string strtag = tagname.substr(start, end-start); Tango::DbDatum cvs_tag("cvs_tag"); cvs_tag << strtag; data.push_back(cvs_tag); } // SVN tag string svnpath(SvnPath); header = "$HeadURL: "; start = header.length(); end = svnpath.find(endstr); if (end!=string::npos && end>start) { string strloc = svnpath.substr(start, end-start); string tagstr ("/tags/"); start = strloc.find(tagstr); if ( start!=string::npos ) { start = start + tagstr.length(); end = strloc.find(filename); string strtag = strloc.substr(start, end-start-1); Tango::DbDatum svn_tag("svn_tag"); svn_tag << strtag; data.push_back(svn_tag); } } // Get URL location string httpServ(HttpServer); if (httpServ.length()>0) { Tango::DbDatum db_doc_url("doc_url"); db_doc_url << httpServ; data.push_back(db_doc_url); } // Put inheritance Tango::DbDatum inher_datum("InheritedFrom"); vector<string> inheritance; inheritance.push_back("TANGO_BASE_CLASS"); inher_datum << inheritance; data.push_back(inher_datum); // Call database and and values get_db_class()->put_property(data); }