int SubReqCommand::Execute() { Networks networks(*config()->config()); if (!networks.IsInitialized()) { LOG(ERROR) << "Unable to load networks."; return 1; } wwiv::net::NetworkCommandLine net_cmdline(config()->bbsdir(), arg("net").as_int()); if (!net_cmdline.IsInitialized()) { return 1; } auto r = this->remaining(); if (r.size() < 3) { cout << GetUsage(); return 2; } auto net = net_cmdline.network(); string packet_filename = wwiv::net::create_pend(net.dir, false, 'r'); uint16_t main_type = main_type_sub_add_req; auto add_drop = upcase(r.at(0).front()); if (add_drop != 'A') { main_type = main_type_sub_drop_req; } net_header_rec nh = {}; auto host = StringToUnsignedShort(r.at(2)); nh.tosys = static_cast<uint16_t>(host); nh.touser = 1; nh.fromsys = net.sysnum; nh.fromuser = 1; nh.main_type = main_type_sub_add_req; // always use 0 since we use the stype nh.minor_type = 0; nh.list_len = 0; nh.daten = static_cast<uint32_t>(time(nullptr)); nh.method = 0; // This is an alphanumeric sub type. auto subtype = r.at(1); nh.length = subtype.size() + 1; string text = subtype; StringUpperCase(&text); text.push_back('\0'); wwiv::net::Packet packet(nh, {}, text); bool ok = wwiv::net::write_packet(packet_filename, net, packet); if (!ok) { LOG(ERROR) << "Error writing packet: " << packet_filename; return 1; } LOG(INFO) << "Wrote Packet: " << packet_filename; return 0; }
bool ReadSubcriberFile(const std::string& dir, const std::string& filename, std::set<uint16_t>& subscribers) { subscribers.clear(); TextFile file(dir, filename, "rt"); if (!file.IsOpen()) { return false; } string line; while (file.ReadLine(&line)) { StringTrim(&line); uint16_t s = StringToUnsignedShort(line); if (s > 0) { subscribers.insert(s); } } return true; }
// [[ VisibleForTesting ]] bool ParseCalloutNetLine(const string& ss, net_call_out_rec* con) { if (ss.empty() || ss[0] != '@') { // skip empty lines and those not starting with @. return false; } con->min_hr = -1; con->max_hr = -1; for (auto iter = ss.cbegin(); iter != ss.cend(); iter++) { switch (*iter) { case '@': { con->sysnum = StringToUnsignedShort(string(++iter, ss.end())); } break; case '&': con->options |= options_sendback; break; case '-': con->options |= unused_options_ATT_night; break; case '_': con->options |= unused_options_ppp; break; case '+': con->options |= options_no_call; break; case '~': con->options |= options_receive_only; break; case '!': { con->options |= options_once_per_day; con->times_per_day = std::max<uint8_t>(1, StringToUnsignedChar(string(++iter, ss.end()))); } break; case '%': { con->macnum = StringToUnsignedChar(string(++iter, ss.end())); } break; case '/': { con->call_anyway = StringToUnsignedChar(string(++iter, ss.end())); if (con->call_anyway > 0) { // Let's set a minimum of 10 minutes in between calls. con->call_anyway = std::max<uint8_t>(con->call_anyway, 10); } } break; case '#': { con->call_x_days = StringToUnsignedChar(string(++iter, ss.end())); } break; case '(': { con->min_hr = StringToChar(string(++iter, ss.end())); } break; case ')': { con->max_hr = StringToChar(string(++iter, ss.end())); } break; case '|': { con->min_k = std::max<uint16_t>(1, StringToUnsignedShort(string(++iter, ss.end()))); } break; case ';': con->options |= unused_options_compress; break; case '^': con->options |= unused_options_hslink; break; case '$': con->options |= unused_options_force_ac; break; case '=': con->options |= options_hide_pend; break; case '*': con->options |= unused_options_dial_ten; break; case '\"': { ++iter; // skip past first " string password; while (iter != ss.end() && *iter != '\"') { password.push_back(*iter++); } if (!password.empty() && password.back() == '\"') { // remove trailing " password.pop_back(); } strncpy(con->password, password.c_str(), sizeof(con->password)); } break; default: break; } } return true; }