// move assignment chain_parameters& chain_parameters::operator=(chain_parameters&& other) { if (&other != this) { current_fees = std::move(other.current_fees); safe_copy(*this, other); } return *this; }
// copy assignment chain_parameters& chain_parameters::operator=(const chain_parameters& other) { if (&other != this) { current_fees = std::make_shared<fee_schedule>(*other.current_fees); safe_copy(*this, other); } return *this; }
char *TCLinkGetResponse(TCLinkHandle handle, const char *name, char *value) { param *p; TCLinkCon *c = (TCLinkCon *)handle; for (p = c->recv_param_list; p; p = p->next) if (strcasecmp(name, p->name) == 0) { safe_copy(value, p->value, PARAM_MAX_LEN); return value; } return NULL; }
/* Peel a line off the current input. Note that this DOESN'T necessarily wait for all * input to come in, only up to a "\n". -1 is returned for a network error, otherwise * it returns the length of the line read. If there is not a complete line pending * for read this will block until there is, or an error occurs. */ static int ReadLine(TCLinkCon *c, char *buffer, char *destbuf) { struct timeval tv; fd_set read; fd_set error; while (1) /* we wait for a line to come in or an error to occur */ { char *eol = strchr(buffer, '\n'); if (eol != NULL) { /* peel off the line and return it */ *eol++ = 0; safe_copy(destbuf, buffer, TC_LINE_MAX); memmove(buffer, eol, strlen(eol)+1); return strlen(destbuf); } else { if (c->is_error == 1) return -1; /* do socket work to grab the most recent chunk of incoming data */ FD_ZERO(&read); FD_SET(c->sd, &read); FD_ZERO(&error); FD_SET(c->sd, &error); tv.tv_sec = TIMEOUT; tv.tv_usec = 0; if (select(c->sd + 1, &read, NULL, &error, &tv) < 1) c->is_error = 1; else if (FD_ISSET(c->sd, &error)) c->is_error = 1; else if (FD_ISSET(c->sd, &read)) { int buffer_end = strlen(buffer); int size = SSL_read(c->ssl, buffer + buffer_end, TC_BUFF_MAX-1 - buffer_end); if (size < 0) c->is_error = 1; else buffer[buffer_end + size] = 0; } } } }
void broadcast(Message&& message, channel_handler handle_channel, result_handler handle_complete) { // We cannot use a synchronizer here because handler closure in loop. auto counter = std::make_shared<std::atomic<size_t>>(channels_.size()); for (const auto channel: safe_copy()) { const auto handle_send = [=](code ec) { handle_channel(ec, channel); if (counter->fetch_sub(1) == 1) handle_complete(error::success); }; channel->send(std::forward<Message>(message), handle_send); } }
void mod_keybind(int device, int sym, int press, char cmd, char *script) { int i; for( i=0; i<binds_size; i++ ) if( binds[i].device==0 || (binds[i].sym==sym && binds[i].device==device && binds[i].press==press) ) break; if( i==binds_size ) { binds = realloc(binds, sizeof(*binds)*(binds_size+32)); memset(binds+binds_size, 0, sizeof(*binds)*32); binds_size += 32; } binds[i].sym = sym; binds[i].device = device; binds[i].press = press; binds[i].cmd = cmd; safe_free(binds[i].script); safe_copy(binds[i].script, script); }
struct arglist * store_plugin(struct arglist * plugin, char * file) { char desc_file[PATH_MAX+1]; char path[PATH_MAX+1]; struct plugin plug; struct pprefs pp[MAX_PREFS+1]; char * str; char * dir; struct arglist * arglist, * ret, *prefs; int e; int fd; int num_plugin_prefs = 0; if( current_mode == MODE_SYS ) dir = sys_store_dir; else dir = usr_store_dir; if(strlen(file) + 2 > sizeof(path)) return NULL; strncpy(path, dir, sizeof(path) - 2 - strlen(file)); str = strrchr(path, '/'); if(str != NULL) { str[0] = '\0'; } strcat(path, "/"); strcat(path, file); snprintf(desc_file, sizeof(desc_file), "%s/%s", dir, file); str = strrchr(desc_file, '.'); if( str != NULL ) { str[0] = '\0'; if(strlen(desc_file) + 6 < sizeof(desc_file) ) strcat(desc_file, ".desc"); } bzero(&plug, sizeof(plug)); bzero(pp, sizeof(pp)); plug.magic = MAGIC; plug.id = _plug_get_id(plugin); e = safe_copy(path, plug.path, sizeof(plug.path), path, "path"); if(e < 0)return NULL; plug.timeout = _plug_get_timeout(plugin); plug.category = _plug_get_category(plugin); str = _plug_get_name(plugin); e = safe_copy(str, plug.name, sizeof(plug.name), path, "name"); if(e < 0)return NULL; str = _plug_get_version(plugin); e = safe_copy(str, plug.version, sizeof(plug.version), path, "version"); if(e < 0)return NULL; str = _plug_get_summary(plugin); e = safe_copy(str, plug.summary, sizeof(plug.summary), path, "summary"); if(e < 0)return NULL; str = _plug_get_description(plugin); e = safe_copy(str, plug.description, sizeof(plug.description), path, "description"); if(e < 0)return NULL; str = _plug_get_copyright(plugin); e = safe_copy(str, plug.copyright, sizeof(plug.copyright), path, "copyright"); if(e < 0)return NULL; str = _plug_get_family(plugin); e = safe_copy(str, plug.family, sizeof(plug.family), path, "family"); if(e < 0)return NULL; str = _plug_get_cve_id(plugin); #ifdef DEBUG_STORE if ( str != NULL && strlen(str) > OLD_CVE_SZ ) fprintf(stderr, "WARNING! CVE size will be too long for older versions of Nessus!\n"); #endif e = safe_copy(str, plug.cve_id, sizeof(plug.cve_id), path, "cve_id"); if(e < 0)return NULL; str = _plug_get_bugtraq_id(plugin); #ifdef DEBUG_STORE if ( str != NULL && strlen(str) > OLD_BID_SZ) fprintf(stderr, "WARNING! BID size will be too long for older versions of Nessus!\n"); #endif e = safe_copy(str, plug.bid, sizeof(plug.bid), path, "bugtraq id"); if(e < 0)return NULL; str = _plug_get_xref(plugin); #ifdef DEBUG_STORE if ( str != NULL && strlen(str) > OLD_XREF_SZ) fprintf(stderr, "WARNING! BID size will be too long for older versions of Nessus!\n"); #endif e = safe_copy(str, plug.xref, sizeof(plug.xref), path, "xref id"); if(e < 0)return NULL; arglist = _plug_get_deps(plugin); str = arglist2str(arglist); e = safe_copy(str, plug.dependencies, sizeof(plug.dependencies), path, "dependencies"); efree(&str); if(e < 0)return NULL; arglist = _plug_get_required_keys(plugin); str = arglist2str(arglist); e = safe_copy(str, plug.required_keys, sizeof(plug.required_keys), path, "required keys"); efree(&str); if(e < 0)return NULL; arglist = _plug_get_excluded_keys(plugin); str = arglist2str(arglist); e = safe_copy(str, plug.excluded_keys, sizeof(plug.excluded_keys), path, "excluded_keys"); efree(&str); if(e < 0)return NULL; arglist = _plug_get_required_ports(plugin); str = arglist2str(arglist); e = safe_copy(str, plug.required_ports, sizeof(plug.required_ports), path, "required ports"); efree(&str); if(e < 0)return NULL; arglist = _plug_get_required_udp_ports(plugin); str = arglist2str(arglist); e = safe_copy(str, plug.required_udp_ports, sizeof(plug.required_udp_ports), path, "required udp ports"); efree(&str); if(e < 0)return NULL; prefs = arg_get_value(plugin, "preferences"); arglist = arg_get_value(plugin, "PLUGIN_PREFS"); if( arglist != NULL ) { char * p_name = _plug_get_name(plugin); while(arglist->next != NULL) { char * name = arglist->name; char * dfl = arglist->value; char * type, * str; type = arglist->name; str = strchr(type, '/'); str[0] = '\0'; name = str + 1; e = safe_copy(type, pp[num_plugin_prefs].type, sizeof(pp[num_plugin_prefs].type), path, "preference-type"); if(e < 0)return NULL; e = safe_copy(name, pp[num_plugin_prefs].name, sizeof(pp[num_plugin_prefs].name), path, "preference-name"); if(e < 0)return NULL; e = safe_copy(dfl, pp[num_plugin_prefs].dfl, sizeof(pp[num_plugin_prefs].dfl), path, "preference-default"); if(e < 0)return NULL; num_plugin_prefs ++; if(num_plugin_prefs >= MAX_PREFS) { fprintf(stderr, "%s: too many preferences\n", path); return NULL; } _add_plugin_preference(prefs, p_name, name, type, dfl); str[0] = '/'; arglist = arglist->next; } } if(num_plugin_prefs > 0) plug.has_prefs = 1; fd = open(desc_file, O_RDWR|O_CREAT|O_TRUNC, 0644); if(fd < 0) { return NULL; } if(write(fd, &plug, sizeof(plug)) < 0) { perror("write "); } if(num_plugin_prefs > 0) { write(fd, pp, sizeof(pp)); } close(fd); arg_set_value(plugin, "preferences", -1, NULL); arg_free_all(plugin); return NULL; }
static int read_arguments(int argc, char **argv) { int optchar; char *arg1 = argv[1]; char *op = NULL; if (argc < 2 || !strcmp(arg1, "help") || !strcmp(arg1, "--help") || !strcmp(arg1, "-h")) { print_usage(); exit(EXIT_SUCCESS); } if (!strcmp(arg1, "version") || !strcmp(arg1, "--version") || !strcmp(arg1, "-V")) { printf("%s %s (built %s %s)\n", argv[0], RELEASE_VERSION, __DATE__, __TIME__); exit(EXIT_SUCCESS); } if (!strcmp(arg1, "arbitrator")) { cl.type = ACT_ARBITRATOR; logging_entity = (char *) DAEMON_NAME "-arbitrator"; optind = 2; } else if (!strcmp(arg1, "site")) { cl.type = ACT_SITE; logging_entity = (char *) DAEMON_NAME "-site"; optind = 2; } else if (!strcmp(arg1, "client")) { cl.type = ACT_CLIENT; if (argc < 3) { print_usage(); exit(EXIT_FAILURE); } op = argv[2]; optind = 3; } else { cl.type = ACT_CLIENT; op = argv[1]; optind = 2; } switch (cl.type) { case ACT_ARBITRATOR: break; case ACT_SITE: break; case ACT_CLIENT: if (!strcmp(op, "list")) cl.op = OP_LIST; else if (!strcmp(op, "grant")) cl.op = OP_GRANT; else if (!strcmp(op, "revoke")) cl.op = OP_REVOKE; else { fprintf(stderr, "client operation \"%s\" is unknown\n", op); exit(EXIT_FAILURE); } break; } while (optind < argc) { optchar = getopt(argc, argv, OPTION_STRING); switch (optchar) { case 'c': safe_copy(cl.configfile, optarg, sizeof(cl.configfile), "config file"); break; case 'D': daemonize = 1; debug_level = 1; log_logfile_priority = LOG_DEBUG; log_syslog_priority = LOG_DEBUG; break; case 'l': safe_copy(cl.lockfile, optarg, sizeof(cl.lockfile), "lock file"); break; case 't': if (cl.op == OP_GRANT || cl.op == OP_REVOKE) { safe_copy(cl.ticket, optarg, sizeof(cl.ticket), "ticket name"); } else { print_usage(); exit(EXIT_FAILURE); } break; case 's': if (cl.op == OP_GRANT || cl.op == OP_REVOKE) { safe_copy(cl.site, optarg, sizeof(cl.ticket), "site name"); } else { print_usage(); exit(EXIT_FAILURE); } break; case 'f': if (cl.op == OP_GRANT) cl.force = 1; else { print_usage(); exit(EXIT_FAILURE); } break; case 'h': print_usage(); exit(EXIT_SUCCESS); break; case ':': case '?': fprintf(stderr, "Please use '-h' for usage.\n"); exit(EXIT_FAILURE); break; default: fprintf(stderr, "unknown option: %s\n", argv[optind]); exit(EXIT_FAILURE); break; }; } return 0; }
int strerror_r (int errnum, char *buf, size_t buflen) #undef strerror_r { /* Filter this out now, so that rest of this replacement knows that there is room for a non-empty message and trailing NUL. */ if (buflen <= 1) { if (buflen) *buf = '\0'; return ERANGE; } *buf = '\0'; /* Check for gnulib overrides. */ { char const *msg = strerror_override (errnum); if (msg) return safe_copy (buf, buflen, msg); } { int ret; int saved_errno = errno; #if USE_XPG_STRERROR_R { ret = __xpg_strerror_r (errnum, buf, buflen); if (ret < 0) ret = errno; if (!*buf) { /* glibc 2.13 would not touch buf on err, so we have to fall back to GNU strerror_r which always returns a thread-safe untruncated string to (partially) copy into our buf. */ safe_copy (buf, buflen, strerror_r (errnum, buf, buflen)); } } #elif USE_SYSTEM_STRERROR_R if (buflen > INT_MAX) buflen = INT_MAX; # ifdef __hpux /* On HP-UX 11.31, strerror_r always fails when buflen < 80; it also fails to change buf on EINVAL. */ { char stackbuf[80]; if (buflen < sizeof stackbuf) { ret = strerror_r (errnum, stackbuf, sizeof stackbuf); if (ret == 0) ret = safe_copy (buf, buflen, stackbuf); } else ret = strerror_r (errnum, buf, buflen); } # else ret = strerror_r (errnum, buf, buflen); /* Some old implementations may return (-1, EINVAL) instead of EINVAL. But on Haiku, valid error numbers are negative. */ # if !defined __HAIKU__ if (ret < 0) ret = errno; # endif # endif # if defined _AIX || defined __HAIKU__ /* AIX and Haiku return 0 rather than ERANGE when truncating strings; try again until we are sure we got the entire string. */ if (!ret && strlen (buf) == buflen - 1) { char stackbuf[STACKBUF_LEN]; size_t len; strerror_r (errnum, stackbuf, sizeof stackbuf); len = strlen (stackbuf); /* STACKBUF_LEN should have been large enough. */ if (len + 1 == sizeof stackbuf) abort (); if (buflen <= len) ret = ERANGE; } # else /* Solaris 10 does not populate buf on ERANGE. OpenBSD 4.7 truncates early on ERANGE rather than return a partial integer. We prefer the maximal string. We set buf[0] earlier, and we know of no implementation that modifies buf to be an unterminated string, so this strlen should be portable in practice (rather than pulling in a safer strnlen). */ if (ret == ERANGE && strlen (buf) < buflen - 1) { char stackbuf[STACKBUF_LEN]; /* STACKBUF_LEN should have been large enough. */ if (strerror_r (errnum, stackbuf, sizeof stackbuf) == ERANGE) abort (); safe_copy (buf, buflen, stackbuf); } # endif #else /* USE_SYSTEM_STRERROR */ /* Try to do what strerror (errnum) does, but without clobbering the buffer used by strerror(). */ # if defined __NetBSD__ || defined __hpux || (defined _WIN32 && !defined __CYGWIN__) || defined __CYGWIN__ /* NetBSD, HP-UX, native Windows, Cygwin */ /* NetBSD: sys_nerr, sys_errlist are declared through _NETBSD_SOURCE and <errno.h> above. HP-UX: sys_nerr, sys_errlist are declared explicitly above. native Windows: sys_nerr, sys_errlist are declared in <stdlib.h>. Cygwin: sys_nerr, sys_errlist are declared in <errno.h>. */ if (errnum >= 0 && errnum < sys_nerr) { # if HAVE_CATGETS && (defined __NetBSD__ || defined __hpux) # if defined __NetBSD__ nl_catd catd = catopen ("libc", NL_CAT_LOCALE); const char *errmsg = (catd != (nl_catd)-1 ? catgets (catd, 1, errnum, sys_errlist[errnum]) : sys_errlist[errnum]); # endif # if defined __hpux nl_catd catd = catopen ("perror", NL_CAT_LOCALE); const char *errmsg = (catd != (nl_catd)-1 ? catgets (catd, 1, 1 + errnum, sys_errlist[errnum]) : sys_errlist[errnum]); # endif # else const char *errmsg = sys_errlist[errnum]; # endif if (errmsg == NULL || *errmsg == '\0') ret = EINVAL; else ret = safe_copy (buf, buflen, errmsg); # if HAVE_CATGETS && (defined __NetBSD__ || defined __hpux) if (catd != (nl_catd)-1) catclose (catd); # endif } else ret = EINVAL; # elif defined __sgi || (defined __sun && !defined _LP64) /* IRIX, Solaris <= 9 32-bit */ /* For a valid error number, the system's strerror() function returns a pointer to a not copied string, not to a buffer. */ if (errnum >= 0 && errnum < sys_nerr) { char *errmsg = strerror (errnum); if (errmsg == NULL || *errmsg == '\0') ret = EINVAL; else ret = safe_copy (buf, buflen, errmsg); } else ret = EINVAL; # else gl_lock_lock (strerror_lock); { char *errmsg = strerror (errnum); /* For invalid error numbers, strerror() on - IRIX 6.5 returns NULL, - HP-UX 11 returns an empty string. */ if (errmsg == NULL || *errmsg == '\0') ret = EINVAL; else ret = safe_copy (buf, buflen, errmsg); } gl_lock_unlock (strerror_lock); # endif #endif #if defined _WIN32 && !defined __CYGWIN__ /* MSVC 14 defines names for many error codes in the range 100..140, but _sys_errlist contains strings only for the error codes < _sys_nerr = 43. */ if (ret == EINVAL) { const char *errmsg; switch (errnum) { case 100 /* EADDRINUSE */: errmsg = "Address already in use"; break; case 101 /* EADDRNOTAVAIL */: errmsg = "Cannot assign requested address"; break; case 102 /* EAFNOSUPPORT */: errmsg = "Address family not supported by protocol"; break; case 103 /* EALREADY */: errmsg = "Operation already in progress"; break; case 105 /* ECANCELED */: errmsg = "Operation canceled"; break; case 106 /* ECONNABORTED */: errmsg = "Software caused connection abort"; break; case 107 /* ECONNREFUSED */: errmsg = "Connection refused"; break; case 108 /* ECONNRESET */: errmsg = "Connection reset by peer"; break; case 109 /* EDESTADDRREQ */: errmsg = "Destination address required"; break; case 110 /* EHOSTUNREACH */: errmsg = "No route to host"; break; case 112 /* EINPROGRESS */: errmsg = "Operation now in progress"; break; case 113 /* EISCONN */: errmsg = "Transport endpoint is already connected"; break; case 114 /* ELOOP */: errmsg = "Too many levels of symbolic links"; break; case 115 /* EMSGSIZE */: errmsg = "Message too long"; break; case 116 /* ENETDOWN */: errmsg = "Network is down"; break; case 117 /* ENETRESET */: errmsg = "Network dropped connection on reset"; break; case 118 /* ENETUNREACH */: errmsg = "Network is unreachable"; break; case 119 /* ENOBUFS */: errmsg = "No buffer space available"; break; case 123 /* ENOPROTOOPT */: errmsg = "Protocol not available"; break; case 126 /* ENOTCONN */: errmsg = "Transport endpoint is not connected"; break; case 128 /* ENOTSOCK */: errmsg = "Socket operation on non-socket"; break; case 129 /* ENOTSUP */: errmsg = "Not supported"; break; case 130 /* EOPNOTSUPP */: errmsg = "Operation not supported"; break; case 132 /* EOVERFLOW */: errmsg = "Value too large for defined data type"; break; case 133 /* EOWNERDEAD */: errmsg = "Owner died"; break; case 134 /* EPROTO */: errmsg = "Protocol error"; break; case 135 /* EPROTONOSUPPORT */: errmsg = "Protocol not supported"; break; case 136 /* EPROTOTYPE */: errmsg = "Protocol wrong type for socket"; break; case 138 /* ETIMEDOUT */: errmsg = "Connection timed out"; break; case 140 /* EWOULDBLOCK */: errmsg = "Operation would block"; break; default: errmsg = NULL; break; } if (errmsg != NULL) ret = safe_copy (buf, buflen, errmsg); } #endif if (ret == EINVAL && !*buf) { #if defined __HAIKU__ /* For consistency with perror(). */ snprintf (buf, buflen, "Unknown Application Error (%d)", errnum); #else snprintf (buf, buflen, "Unknown error %d", errnum); #endif } errno = saved_errno; return ret; } }
static int read_arguments(int argc, char **argv) { int optchar; char *arg1 = argv[1]; char *op = NULL; char *cp; const char *opt_string = OPTION_STRING; char site_arg[INET_ADDRSTRLEN] = {0}; int left; cl.type = 0; if ((cp = strstr(argv[0], ATTR_PROG)) && !strcmp(cp, ATTR_PROG)) { cl.type = GEOSTORE; op = argv[1]; optind = 2; opt_string = ATTR_OPTION_STRING; } else if (argc > 1 && (strcmp(arg1, "arbitrator") == 0 || strcmp(arg1, "site") == 0 || strcmp(arg1, "start") == 0 || strcmp(arg1, "daemon") == 0)) { cl.type = DAEMON; optind = 2; } else if (argc > 1 && (strcmp(arg1, "status") == 0)) { cl.type = STATUS; optind = 2; } else if (argc > 1 && (strcmp(arg1, "client") == 0)) { cl.type = CLIENT; if (argc < 3) { print_usage(); exit(EXIT_FAILURE); } op = argv[2]; optind = 3; } if (!cl.type) { cl.type = CLIENT; op = argv[1]; optind = 2; } if (argc < 2 || !strcmp(arg1, "help") || !strcmp(arg1, "--help") || !strcmp(arg1, "-h")) { if (cl.type == GEOSTORE) print_geostore_usage(); else print_usage(); exit(EXIT_SUCCESS); } if (!strcmp(arg1, "version") || !strcmp(arg1, "--version") || !strcmp(arg1, "-V")) { printf("%s %s\n", argv[0], RELEASE_STR); exit(EXIT_SUCCESS); } if (cl.type == CLIENT) { if (!strcmp(op, "list")) cl.op = CMD_LIST; else if (!strcmp(op, "grant")) cl.op = CMD_GRANT; else if (!strcmp(op, "revoke")) cl.op = CMD_REVOKE; else if (!strcmp(op, "peers")) cl.op = CMD_PEERS; else { fprintf(stderr, "client operation \"%s\" is unknown\n", op); exit(EXIT_FAILURE); } } else if (cl.type == GEOSTORE) { if (!strcmp(op, "list")) cl.op = ATTR_LIST; else if (!strcmp(op, "set")) cl.op = ATTR_SET; else if (!strcmp(op, "get")) cl.op = ATTR_GET; else if (!strcmp(op, "delete")) cl.op = ATTR_DEL; else { fprintf(stderr, "attribute operation \"%s\" is unknown\n", op); exit(EXIT_FAILURE); } } while (optind < argc) { optchar = getopt(argc, argv, opt_string); switch (optchar) { case 'c': if (strchr(optarg, '/')) { safe_copy(cl.configfile, optarg, sizeof(cl.configfile), "config file"); } else { /* If no "/" in there, use with default directory. */ strcpy(cl.configfile, BOOTH_DEFAULT_CONF_DIR); cp = cl.configfile + strlen(BOOTH_DEFAULT_CONF_DIR); assert(cp > cl.configfile); assert(*(cp-1) == '/'); /* Write at the \0, ie. after the "/" */ safe_copy(cp, optarg, (sizeof(cl.configfile) - (cp - cl.configfile) - strlen(BOOTH_DEFAULT_CONF_EXT)), "config name"); /* If no extension, append ".conf". * Space is available, see -strlen() above. */ if (!strchr(cp, '.')) strcat(cp, BOOTH_DEFAULT_CONF_EXT); } break; case 'D': debug_level++; break; case 'S': daemonize = 0; enable_stderr = 1; break; case 'l': safe_copy(cl.lockfile, optarg, sizeof(cl.lockfile), "lock file"); break; case 't': if (cl.op == CMD_GRANT || cl.op == CMD_REVOKE) { safe_copy(cl.msg.ticket.id, optarg, sizeof(cl.msg.ticket.id), "ticket name"); } else if (cl.type == GEOSTORE) { safe_copy(cl.attr_msg.attr.tkt_id, optarg, sizeof(cl.attr_msg.attr.tkt_id), "ticket name"); } else { print_usage(); exit(EXIT_FAILURE); } break; case 's': /* For testing and debugging: allow "-s site" also for * daemon start, so that the address that should be used * can be set manually. * This makes it easier to start multiple processes * on one machine. */ if (cl.type == CLIENT || cl.type == GEOSTORE || (cl.type == DAEMON && debug_level)) { if (strcmp(optarg, OTHER_SITE) && host_convert(optarg, site_arg, INET_ADDRSTRLEN) == 0) { safe_copy(cl.site, site_arg, sizeof(cl.site), "site name"); } else { safe_copy(cl.site, optarg, sizeof(cl.site), "site name"); } } else { log_error("\"-s\" not allowed in daemon mode."); exit(EXIT_FAILURE); } break; case 'F': if (cl.type != CLIENT || cl.op != CMD_GRANT) { log_error("use \"-F\" only for client grant"); exit(EXIT_FAILURE); } cl.options |= OPT_IMMEDIATE; break; case 'w': if (cl.type != CLIENT || (cl.op != CMD_GRANT && cl.op != CMD_REVOKE)) { log_error("use \"-w\" only for grant and revoke"); exit(EXIT_FAILURE); } cl.options |= OPT_WAIT; break; case 'C': if (cl.type != CLIENT || cl.op != CMD_GRANT) { log_error("use \"-C\" only for grant"); exit(EXIT_FAILURE); } cl.options |= OPT_WAIT | OPT_WAIT_COMMIT; break; case 'h': if (cl.type == GEOSTORE) print_geostore_usage(); else print_usage(); exit(EXIT_SUCCESS); break; case ':': case '?': fprintf(stderr, "Please use '-h' for usage.\n"); exit(EXIT_FAILURE); break; case -1: /* No more parameters on cmdline, only arguments. */ goto extra_args; default: goto unknown; }; } return 0; extra_args: if (cl.type == CLIENT && !cl.msg.ticket.id[0]) { cparg(cl.msg.ticket.id, "ticket name"); } else if (cl.type == GEOSTORE) { if (cl.op != ATTR_LIST) { cparg(cl.attr_msg.attr.name, "attribute name"); } if (cl.op == ATTR_SET) { cparg(cl.attr_msg.attr.val, "attribute value"); } } if (optind == argc) return 0; left = argc - optind; fprintf(stderr, "Superfluous argument%s: %s%s\n", left == 1 ? "" : "s", argv[optind], left == 1 ? "" : "..."); exit(EXIT_FAILURE); unknown: fprintf(stderr, "unknown option: %s\n", argv[optind]); exit(EXIT_FAILURE); missingarg: fprintf(stderr, "not enough arguments\n"); exit(EXIT_FAILURE); }
/* Peel a line off the current input. Note that this DOESN'T necessarily wait for all * input to come in, only up to a "\n". -1 is returned for a network error, otherwise * it returns the length of the line read. If there is not a complete line pending * for read this will block until there is, or an error occurs. */ static int ReadLine(TCLinkCon *c, char *buffer, char *destbuf) { struct timeval tv; fd_set read; fd_set error; int sel; while (1) /* we wait for a line to come in or an error to occur */ { char *eol = strchr(buffer, '\n'); if (eol != NULL) { /* peel off the line and return it */ *eol++ = 0; safe_copy(destbuf, buffer, TC_LINE_MAX); memmove(buffer, eol, strlen(eol)+1); return strlen(destbuf); } else { if (c->is_error == 1) return -1; /* do socket work to grab the most recent chunk of incoming data */ FD_ZERO(&read); FD_SET(c->sd, &read); FD_ZERO(&error); FD_SET(c->sd, &error); tv.tv_sec = TIMEOUT; tv.tv_usec = 0; sel = select(c->sd+1, &read, NULL, &error, &tv); if (sel < 1) c->is_error = 1; else if (FD_ISSET(c->sd, &error)) c->is_error = 1; else if (FD_ISSET(c->sd, &read)) { int buffer_end = strlen(buffer); int size = SSL_read(c->ssl, buffer + buffer_end, TC_BUFF_MAX-1 - buffer_end); if (size == 0) { int error_type = SSL_get_error(c->ssl, size); switch (error_type) { /* this would never happen in practice */ case SSL_ERROR_NONE: /* this wouldn't happen either because the ssl transport is blocking */ case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: buffer[buffer_end] = 0; break; /* these others should not really happen but if they do, we bail */ /* we would never get any more data and it looks like the callee is expecting something */ case SSL_ERROR_ZERO_RETURN: case SSL_ERROR_WANT_CONNECT: case SSL_ERROR_WANT_ACCEPT: case SSL_ERROR_SYSCALL: case SSL_ERROR_WANT_X509_LOOKUP: case SSL_ERROR_SSL: default: c->is_error = 1; break; } } else if (size < 0) c->is_error = 1; else buffer[buffer_end + size] = 0; } } } }
// copy constructor chain_parameters::chain_parameters(const chain_parameters& other) { current_fees = std::make_shared<fee_schedule>(*other.current_fees); safe_copy(*this, other); }
// move constructor chain_parameters::chain_parameters(chain_parameters&& other) { current_fees = std::move(other.current_fees); safe_copy(*this, other); }
int strerror_r (int errnum, char *buf, size_t buflen) #undef strerror_r { /* Filter this out now, so that rest of this replacement knows that there is room for a non-empty message and trailing NUL. */ if (buflen <= 1) { if (buflen) *buf = '\0'; return ERANGE; } *buf = '\0'; /* Check for gnulib overrides. */ { char const *msg = strerror_override (errnum); if (msg) return safe_copy (buf, buflen, msg); } { int ret; int saved_errno = errno; #if USE_XPG_STRERROR_R { ret = __xpg_strerror_r (errnum, buf, buflen); if (ret < 0) ret = errno; if (!*buf) { /* glibc 2.13 would not touch buf on err, so we have to fall back to GNU strerror_r which always returns a thread-safe untruncated string to (partially) copy into our buf. */ safe_copy (buf, buflen, strerror_r (errnum, buf, buflen)); } } #elif USE_SYSTEM_STRERROR_R if (buflen > INT_MAX) buflen = INT_MAX; # ifdef __hpux /* On HP-UX 11.31, strerror_r always fails when buflen < 80; it also fails to change buf on EINVAL. */ { char stackbuf[80]; if (buflen < sizeof stackbuf) { ret = strerror_r (errnum, stackbuf, sizeof stackbuf); if (ret == 0) ret = safe_copy (buf, buflen, stackbuf); } else ret = strerror_r (errnum, buf, buflen); } # else ret = strerror_r (errnum, buf, buflen); /* Some old implementations may return (-1, EINVAL) instead of EINVAL. */ if (ret < 0) ret = errno; # endif # ifdef _AIX /* AIX returns 0 rather than ERANGE when truncating strings; try again until we are sure we got the entire string. */ if (!ret && strlen (buf) == buflen - 1) { char stackbuf[STACKBUF_LEN]; size_t len; strerror_r (errnum, stackbuf, sizeof stackbuf); len = strlen (stackbuf); /* STACKBUF_LEN should have been large enough. */ if (len + 1 == sizeof stackbuf) abort (); if (buflen <= len) ret = ERANGE; } # else /* Solaris 10 does not populate buf on ERANGE. OpenBSD 4.7 truncates early on ERANGE rather than return a partial integer. We prefer the maximal string. We set buf[0] earlier, and we know of no implementation that modifies buf to be an unterminated string, so this strlen should be portable in practice (rather than pulling in a safer strnlen). */ if (ret == ERANGE && strlen (buf) < buflen - 1) { char stackbuf[STACKBUF_LEN]; /* STACKBUF_LEN should have been large enough. */ if (strerror_r (errnum, stackbuf, sizeof stackbuf) == ERANGE) abort (); safe_copy (buf, buflen, stackbuf); } # endif #else /* USE_SYSTEM_STRERROR */ /* Try to do what strerror (errnum) does, but without clobbering the buffer used by strerror(). */ # if defined __NetBSD__ || defined __hpux || ((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__) || defined __CYGWIN__ /* NetBSD, HP-UX, native Windows, Cygwin */ /* NetBSD: sys_nerr, sys_errlist are declared through _NETBSD_SOURCE and <errno.h> above. HP-UX: sys_nerr, sys_errlist are declared explicitly above. native Windows: sys_nerr, sys_errlist are declared in <stdlib.h>. Cygwin: sys_nerr, sys_errlist are declared in <errno.h>. */ if (errnum >= 0 && errnum < sys_nerr) { # if HAVE_CATGETS && (defined __NetBSD__ || defined __hpux) # if defined __NetBSD__ nl_catd catd = catopen ("libc", NL_CAT_LOCALE); const char *errmsg = (catd != (nl_catd)-1 ? catgets (catd, 1, errnum, sys_errlist[errnum]) : sys_errlist[errnum]); # endif # if defined __hpux nl_catd catd = catopen ("perror", NL_CAT_LOCALE); const char *errmsg = (catd != (nl_catd)-1 ? catgets (catd, 1, 1 + errnum, sys_errlist[errnum]) : sys_errlist[errnum]); # endif # else const char *errmsg = sys_errlist[errnum]; # endif if (errmsg == NULL || *errmsg == '\0') ret = EINVAL; else ret = safe_copy (buf, buflen, errmsg); # if HAVE_CATGETS && (defined __NetBSD__ || defined __hpux) if (catd != (nl_catd)-1) catclose (catd); # endif } else ret = EINVAL; # elif defined __sgi || (defined __sun && !defined _LP64) /* IRIX, Solaris <= 9 32-bit */ /* For a valid error number, the system's strerror() function returns a pointer to a not copied string, not to a buffer. */ if (errnum >= 0 && errnum < sys_nerr) { char *errmsg = strerror (errnum); if (errmsg == NULL || *errmsg == '\0') ret = EINVAL; else ret = safe_copy (buf, buflen, errmsg); } else ret = EINVAL; # else gl_lock_lock (strerror_lock); { char *errmsg = strerror (errnum); /* For invalid error numbers, strerror() on - IRIX 6.5 returns NULL, - HP-UX 11 returns an empty string. */ if (errmsg == NULL || *errmsg == '\0') ret = EINVAL; else ret = safe_copy (buf, buflen, errmsg); } gl_lock_unlock (strerror_lock); # endif #endif if (ret == EINVAL && !*buf) snprintf (buf, buflen, "Unknown error %d", errnum); errno = saved_errno; return ret; } }
void subscribe(message_handler<Message>&& handler) { for (const auto channel: safe_copy()) channel->subscribe( std::forward<message_handler<Message>>(handler)); }
int read_config(const char *path, int type) { char line[1024]; FILE *fp; char *s, *key, *val, *end_of_key; const char *error; char *cp, *cp2; int i; int lineno = 0; int got_transport = 0; int min_timeout = 0; struct ticket_config defaults = { { 0 } }; struct ticket_config *current_tk = NULL; fp = fopen(path, "r"); if (!fp) { log_error("failed to open %s: %s", path, strerror(errno)); return -1; } booth_conf = malloc(sizeof(struct booth_config) + TICKET_ALLOC * sizeof(struct ticket_config)); if (!booth_conf) { fclose(fp); log_error("failed to alloc memory for booth config"); return -ENOMEM; } memset(booth_conf, 0, sizeof(struct booth_config) + TICKET_ALLOC * sizeof(struct ticket_config)); ticket_size = TICKET_ALLOC; booth_conf->proto = UDP; booth_conf->port = BOOTH_DEFAULT_PORT; booth_conf->maxtimeskew = BOOTH_DEFAULT_MAX_TIME_SKEW; booth_conf->authkey[0] = '\0'; /* Provide safe defaults. -1 is reserved, though. */ booth_conf->uid = -2; booth_conf->gid = -2; strcpy(booth_conf->site_user, "hacluster"); strcpy(booth_conf->site_group, "haclient"); strcpy(booth_conf->arb_user, "nobody"); strcpy(booth_conf->arb_group, "nobody"); parse_weights("", defaults.weight); defaults.clu_test.path = NULL; defaults.clu_test.pid = 0; defaults.clu_test.status = 0; defaults.clu_test.progstate = EXTPROG_IDLE; defaults.term_duration = DEFAULT_TICKET_EXPIRY; defaults.timeout = DEFAULT_TICKET_TIMEOUT; defaults.retries = DEFAULT_RETRIES; defaults.acquire_after = 0; defaults.mode = TICKET_MODE_AUTO; error = ""; log_debug("reading config file %s", path); while (fgets(line, sizeof(line), fp)) { lineno++; s = skip_while(line, isspace); if (is_end_of_line(s) || *s == '#') continue; key = s; /* Key */ end_of_key = skip_while_in(key, isalnum, "-_"); if (end_of_key == key) { error = "No key"; goto err; } if (!*end_of_key) goto exp_equal; /* whitespace, and something else but nothing more? */ s = skip_while(end_of_key, isspace); if (*s != '=') { exp_equal: error = "Expected '=' after key"; goto err; } s++; /* It's my buffer, and I terminate if I want to. */ /* But not earlier than that, because we had to check for = */ *end_of_key = 0; /* Value tokenizing */ s = skip_while(s, isspace); switch (*s) { case '"': case '\'': val = s+1; s = skip_until(val, *s); /* Terminate value */ if (!*s) { error = "Unterminated quoted string"; goto err; } /* Remove and skip quote */ *s = 0; s++; if (*(s = skip_while(s, isspace)) && *s != '#') { error = "Surplus data after value"; goto err; } *s = 0; break; case 0: no_value: error = "No value"; goto err; break; default: val = s; /* Rest of line. */ i = strlen(s); /* i > 0 because of "case 0" above. */ while (i > 0 && isspace(s[i-1])) i--; s += i; *s = 0; } if (val == s) goto no_value; if (strlen(key) > BOOTH_NAME_LEN || strlen(val) > BOOTH_NAME_LEN) { error = "key/value too long"; goto err; } if (strcmp(key, "transport") == 0) { if (got_transport) { error = "config file has multiple transport lines"; goto err; } if (strcasecmp(val, "UDP") == 0) booth_conf->proto = UDP; else if (strcasecmp(val, "SCTP") == 0) booth_conf->proto = SCTP; else { error = "invalid transport protocol"; goto err; } got_transport = 1; continue; } if (strcmp(key, "port") == 0) { booth_conf->port = atoi(val); continue; } if (strcmp(key, "name") == 0) { safe_copy(booth_conf->name, val, BOOTH_NAME_LEN, "name"); continue; } #if HAVE_LIBGCRYPT || HAVE_LIBMHASH if (strcmp(key, "authfile") == 0) { safe_copy(booth_conf->authfile, val, BOOTH_PATH_LEN, "authfile"); continue; } if (strcmp(key, "maxtimeskew") == 0) { booth_conf->maxtimeskew = atoi(val); continue; } #endif if (strcmp(key, "site") == 0) { if (add_site(val, SITE)) goto err; continue; } if (strcmp(key, "arbitrator") == 0) { if (add_site(val, ARBITRATOR)) goto err; continue; } if (strcmp(key, "site-user") == 0) { safe_copy(booth_conf->site_user, optarg, BOOTH_NAME_LEN, "site-user"); continue; } if (strcmp(key, "site-group") == 0) { safe_copy(booth_conf->site_group, optarg, BOOTH_NAME_LEN, "site-group"); continue; } if (strcmp(key, "arbitrator-user") == 0) { safe_copy(booth_conf->arb_user, optarg, BOOTH_NAME_LEN, "arbitrator-user"); continue; } if (strcmp(key, "arbitrator-group") == 0) { safe_copy(booth_conf->arb_group, optarg, BOOTH_NAME_LEN, "arbitrator-group"); continue; } if (strcmp(key, "debug") == 0) { if (type != CLIENT && type != GEOSTORE) debug_level = max(debug_level, atoi(val)); continue; } if (strcmp(key, "ticket") == 0) { if (current_tk && strcmp(current_tk->name, "__defaults__")) { if (!postproc_ticket(current_tk)) { goto err; } } if (!strcmp(val, "__defaults__")) { current_tk = &defaults; } else if (add_ticket(val, ¤t_tk, &defaults)) { goto err; } continue; } /* current_tk must be allocated at this point, otherwise * we don't know to which ticket the key refers */ if (!current_tk) { error = "Unexpected keyword"; goto err; } if (strcmp(key, "expire") == 0) { current_tk->term_duration = read_time(val); if (current_tk->term_duration <= 0) { error = "Expected time >0 for expire"; goto err; } continue; } if (strcmp(key, "timeout") == 0) { current_tk->timeout = read_time(val); if (current_tk->timeout <= 0) { error = "Expected time >0 for timeout"; goto err; } if (!min_timeout) { min_timeout = current_tk->timeout; } else { min_timeout = min(min_timeout, current_tk->timeout); } continue; } if (strcmp(key, "retries") == 0) { current_tk->retries = strtol(val, &s, 0); if (*s || s == val || current_tk->retries<3 || current_tk->retries > 100) { error = "Expected plain integer value in the range [3, 100] for retries"; goto err; } continue; } if (strcmp(key, "renewal-freq") == 0) { current_tk->renewal_freq = read_time(val); if (current_tk->renewal_freq <= 0) { error = "Expected time >0 for renewal-freq"; goto err; } continue; } if (strcmp(key, "acquire-after") == 0) { current_tk->acquire_after = read_time(val); if (current_tk->acquire_after < 0) { error = "Expected time >=0 for acquire-after"; goto err; } continue; } if (strcmp(key, "before-acquire-handler") == 0) { if (parse_extprog(val, current_tk)) { goto err; } continue; } if (strcmp(key, "attr-prereq") == 0) { if (parse_attr_prereq(val, current_tk)) { goto err; } continue; } if (strcmp(key, "mode") == 0) { current_tk->mode = retrieve_ticket_mode(val); continue; } if (strcmp(key, "weights") == 0) { if (parse_weights(val, current_tk->weight) < 0) goto err; continue; } error = "Unknown keyword"; goto err; } fclose(fp); if ((booth_conf->site_count % 2) == 0) { log_warn("Odd number of nodes is strongly recommended!"); } /* Default: make config name match config filename. */ if (!booth_conf->name[0]) { cp = strrchr(path, '/'); cp = cp ? cp+1 : (char *)path; cp2 = strrchr(cp, '.'); if (!cp2) cp2 = cp + strlen(cp); if (cp2-cp >= BOOTH_NAME_LEN) { log_error("booth config file name too long"); goto out; } strncpy(booth_conf->name, cp, cp2-cp); *(booth_conf->name+(cp2-cp)) = '\0'; } if (!postproc_ticket(current_tk)) { goto out; } poll_timeout = min(POLL_TIMEOUT, min_timeout/10); if (!poll_timeout) poll_timeout = POLL_TIMEOUT; return 0; err: fclose(fp); out: log_error("%s in config file line %d", error, lineno); free(booth_conf); booth_conf = NULL; return -1; }
/* * Find out what version of l2tp the other side is using. * I'm not sure what we're supposed to do with this but whatever.. */ int result_code_avp(struct tunnel *t, struct call *c, const struct avp *data, int datalen) { int error; int result; struct avp_result { unsigned short result; unsigned short error; char msg[0]; } * avpres = (struct avp_result *)&data->data.uc; if (sanity_enabled(t)) { int err = gen_sanity_check(c, datalen, 10, CDN, StopCCN, "Result Code"); if (err != SANITY_OK) return err; } result = ntohs(avpres->result); error = ntohs(avpres->error); /* * from prepare_StopCCN and prepare_CDN, note missing htons() call * http://www.opensource.apple.com/source/ppp/ppp-412.3/Drivers/L2TP/L2TP-plugin/l2tp.c */ result = fix_buggy_apple(result, "result"); error = fix_buggy_apple(error, "error"); if (((c->msgtype == StopCCN) && ((result > 7) || (result < 1))) || ((c->msgtype == CDN) && ((result > 11) || (result < 1)))) { l2tp_log(LOG_DEBUG, "%s: result code out of range (%d %d %d). Ignoring.\n", __func__, result, error, datalen); return 0; } c->error = error; c->result = result; safe_copy(c->errormsg, avpres->msg, datalen - 10); if (likely(!gconfig.debug_avp)) return 0; if (c->msgtype == StopCCN) { l2tp_log(LOG_DEBUG, "%s: peer closing for reason %d (%s), error = %d (%s)\n", __func__, result, stopccn_result_codes[result], error, c->errormsg); return 0; } l2tp_log(LOG_DEBUG, "%s: peer closing for reason %d (%s), error = %d (%s)\n", __func__, result, cdn_result_codes[result], error, c->errormsg); return 0; }