You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-11-02 06:13:16 +03:00
713 lines
18 KiB
C++
713 lines
18 KiB
C++
/* Copyright (C) 2014 InfiniDB, Inc.
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License
|
|
as published by the Free Software Foundation; version 2 of
|
|
the License.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
MA 02110-1301, USA. */
|
|
|
|
/******************************************************************************************
|
|
* Author: Zhixuan Zhu
|
|
******************************************************************************************/
|
|
#define SNMPMANAGER_DLLEXPORT
|
|
#include "snmpmanager.h"
|
|
#undef SNMPMANAGER_DLLEXPORT
|
|
|
|
#include <unistd.h>
|
|
#include <cstdio>
|
|
#include <algorithm>
|
|
#include <vector>
|
|
#include <iterator>
|
|
|
|
#include "messagequeue.h"
|
|
#include "snmpglobal.h"
|
|
#include "liboamcpp.h"
|
|
#include "installdir.h"
|
|
|
|
using namespace std;
|
|
using namespace oam;
|
|
using namespace messageqcpp;
|
|
using namespace logging;
|
|
|
|
namespace snmpmanager {
|
|
|
|
#ifdef __linux__
|
|
inline pid_t gettid(void) { return syscall(__NR_gettid); }
|
|
#else
|
|
inline pid_t gettid(void) { return getpid(); }
|
|
#endif
|
|
|
|
/*****************************************************************************************
|
|
* @brief Constructor
|
|
*
|
|
* purpose:
|
|
*
|
|
*****************************************************************************************/
|
|
|
|
SNMPManager::SNMPManager()
|
|
{
|
|
Oam oam;
|
|
// Get Parent OAM Module Name
|
|
try{
|
|
oam.getSystemConfig("ParentOAMModuleName", SNMPManager::parentOAMModuleName);
|
|
}
|
|
catch(...)
|
|
{
|
|
//Log event
|
|
LoggingID lid(11);
|
|
MessageLog ml(lid);
|
|
Message msg;
|
|
Message::Args args;
|
|
args.add("Failed to read Parent OAM Module Name");
|
|
msg.format(args);
|
|
ml.logErrorMessage(msg);
|
|
throw runtime_error ("Failed to read Parent OAM Module Name");
|
|
}
|
|
|
|
}
|
|
|
|
/*****************************************************************************************
|
|
* @brief Destructor
|
|
*
|
|
* purpose:
|
|
*
|
|
*****************************************************************************************/
|
|
|
|
SNMPManager::~SNMPManager()
|
|
{
|
|
}
|
|
|
|
/*****************************************************************************************
|
|
* @brief sendAlarmReport API
|
|
*
|
|
* purpose: Process Alarm Report
|
|
*
|
|
*****************************************************************************************/
|
|
void SNMPManager::sendAlarmReport (const char* componentID, int alarmID, int state,
|
|
std::string repModuleName, std::string repProcessName)
|
|
{
|
|
|
|
#ifdef SKIP_SNMP
|
|
return;
|
|
#else
|
|
LoggingID lid(11);
|
|
MessageLog ml(lid);
|
|
Message msg;
|
|
Message::Args args;
|
|
|
|
//Log receiving of Alarm report
|
|
if (CALPONT_SNMP_DEBUG)
|
|
{
|
|
args.add("sendAlarmReport: alarm #");
|
|
args.add(alarmID);
|
|
args.add(", state: ");
|
|
args.add(state);
|
|
args.add(", component: ");
|
|
args.add(componentID);
|
|
msg.format(args);
|
|
ml.logDebugMessage(msg);
|
|
}
|
|
|
|
Oam oam;
|
|
|
|
// get current Module name
|
|
string ModuleName;
|
|
if ( repModuleName.empty()) {
|
|
oamModuleInfo_t st;
|
|
try {
|
|
st = oam.getModuleInfo();
|
|
ModuleName = boost::get<0>(st);
|
|
}
|
|
catch (...) {
|
|
ModuleName = "Unknown Reporting Module";
|
|
}
|
|
}
|
|
else
|
|
ModuleName = repModuleName;
|
|
|
|
//
|
|
// FILTERING: Don't process CLEAR alarms if there is no associated SET alarm
|
|
//
|
|
// comment out, issues with race conditions when coded here..
|
|
/*
|
|
if (state == CLEAR) {
|
|
// get active alarms
|
|
AlarmList alarmList;
|
|
SNMPManager sm;
|
|
sm.getActiveAlarm (alarmList);
|
|
|
|
bool found = false;
|
|
AlarmList::iterator i;
|
|
for (i = alarmList.begin(); i != alarmList.end(); ++i)
|
|
{
|
|
// check if matching ID
|
|
if (alarmID != (i->second).getAlarmID() )
|
|
continue;
|
|
|
|
string ScomponentID = componentID;
|
|
// check if the same fault component on same Module
|
|
if (ScomponentID.compare((i->second).getComponentID()) == 0 &&
|
|
ModuleName.compare((i->second).getSname()) == 0) {
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
// check is a SET alarm was found, if not return
|
|
if (!found)
|
|
return;
|
|
}
|
|
*/
|
|
// get pid, tid info
|
|
int pid = getpid();
|
|
int tid = gettid();
|
|
|
|
// get reporting Pprocess Name
|
|
string processName;
|
|
if ( repProcessName.empty()) {
|
|
// get current process name
|
|
myProcessStatus_t t;
|
|
try {
|
|
t = oam.getMyProcessStatus();
|
|
processName = boost::get<1>(t);
|
|
}
|
|
catch (...) {
|
|
processName = "Unknown-Reporting-Process";
|
|
}
|
|
}
|
|
else
|
|
processName = repProcessName;
|
|
|
|
string ComponentID = componentID;
|
|
// send Trap
|
|
|
|
string cmd = startup::StartUp::installDir() + "/bin/sendtrap " + ComponentID + " " + oam.itoa(alarmID) + " " + oam.itoa(state) + " " + ModuleName + " " + processName + " " + oam.itoa(pid) + " " + oam.itoa(tid) + " " + SNMPManager::parentOAMModuleName;
|
|
|
|
system(cmd.c_str());
|
|
|
|
return;
|
|
#endif //SKIP_SNMP
|
|
}
|
|
|
|
/*****************************************************************************************
|
|
* @brief getActiveAlarm API
|
|
*
|
|
* purpose: Get List of Active Alarm from activealarm file
|
|
*
|
|
*****************************************************************************************/
|
|
void SNMPManager::getActiveAlarm(AlarmList& alarmList) const
|
|
{
|
|
//add-on to fileName with mount name if on non Parent Module
|
|
Oam oam;
|
|
string fileName = ACTIVE_ALARM_FILE;
|
|
|
|
int fd = open(fileName.c_str(),O_RDONLY);
|
|
|
|
if (fd == -1) {
|
|
// file may being deleted temporarily by trapHandler
|
|
sleep (1);
|
|
fd = open(fileName.c_str(),O_RDONLY);
|
|
if (fd == -1) {
|
|
// no active alarms, return
|
|
return;
|
|
}
|
|
}
|
|
|
|
ifstream activeAlarm (fileName.c_str(), ios::in);
|
|
|
|
// acquire read lock
|
|
if (flock(fd,LOCK_SH) == -1)
|
|
{
|
|
throw runtime_error ("Lock active alarm log file error");
|
|
}
|
|
|
|
Alarm alarm;
|
|
|
|
while (!activeAlarm.eof())
|
|
{
|
|
activeAlarm >> alarm;
|
|
if (alarm.getAlarmID() != INVALID_ALARM_ID)
|
|
//don't sort
|
|
// alarmList.insert (AlarmList::value_type(alarm.getAlarmID(), alarm));
|
|
alarmList.insert (AlarmList::value_type(INVALID_ALARM_ID, alarm));
|
|
}
|
|
activeAlarm.close();
|
|
|
|
// release lock
|
|
if (flock(fd,LOCK_UN) == -1)
|
|
{
|
|
throw runtime_error ("Release lock active alarm log file error");
|
|
}
|
|
|
|
close(fd);
|
|
|
|
if (CALPONT_SNMP_DEBUG)
|
|
{
|
|
AlarmList :: iterator i;
|
|
for (i = alarmList.begin(); i != alarmList.end(); ++i)
|
|
{
|
|
cout << i->second << endl;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
/*****************************************************************************************
|
|
* @brief getAlarm API
|
|
*
|
|
* purpose: Get List of Historical Alarms from alarm file
|
|
*
|
|
* date = MM/DD/YY format
|
|
*
|
|
*****************************************************************************************/
|
|
void SNMPManager::getAlarm(std::string date, AlarmList& alarmList) const
|
|
{
|
|
string alarmFile = "/tmp/alarms";
|
|
|
|
//make 1 alarm log file made up of archive and current alarm.log
|
|
(void)system("touch /tmp/alarms");
|
|
|
|
string cmd = ("ls " + ALARM_ARCHIVE_FILE + " | grep 'alarm.log' > /tmp/alarmlogfiles");
|
|
(void)system(cmd.c_str());
|
|
|
|
string fileName = "/tmp/alarmlogfiles";
|
|
|
|
ifstream oldFile (fileName.c_str());
|
|
if (oldFile) {
|
|
char line[200];
|
|
string buf;
|
|
while (oldFile.getline(line, 200))
|
|
{
|
|
buf = line;
|
|
string cmd = "cat " + ALARM_ARCHIVE_FILE + "/" + buf + " >> /tmp/alarms";
|
|
(void)system(cmd.c_str());
|
|
}
|
|
|
|
oldFile.close();
|
|
unlink (fileName.c_str());
|
|
}
|
|
|
|
cmd = "cat " + ALARM_FILE + " >> /tmp/alarms";
|
|
(void)system(cmd.c_str());
|
|
|
|
int fd = open(alarmFile.c_str(),O_RDONLY);
|
|
|
|
if (fd == -1)
|
|
// doesn't exist yet, return
|
|
return;
|
|
|
|
ifstream hisAlarm (alarmFile.c_str(), ios::in);
|
|
|
|
// acquire read lock
|
|
if (flock(fd,LOCK_SH) == -1)
|
|
{
|
|
throw runtime_error ("Lock alarm log file error");
|
|
}
|
|
|
|
//get mm / dd / yy from incoming date
|
|
string mm = date.substr(0,2);
|
|
string dd = date.substr(3,2);
|
|
string yy = date.substr(6,2);
|
|
|
|
Alarm alarm;
|
|
|
|
while (!hisAlarm.eof())
|
|
{
|
|
hisAlarm >> alarm;
|
|
if (alarm.getAlarmID() != INVALID_ALARM_ID) {
|
|
time_t cal = alarm.getTimestampSeconds();
|
|
struct tm tm;
|
|
localtime_r(&cal, &tm);
|
|
char tmp[3];
|
|
strftime (tmp, 3, "%m", &tm);
|
|
string alarm_mm = tmp;
|
|
alarm_mm = alarm_mm.substr(0,2);
|
|
strftime (tmp, 3, "%d", &tm);
|
|
string alarm_dd = tmp;
|
|
alarm_dd = alarm_dd.substr(0,2);
|
|
strftime (tmp, 3, "%y", &tm);
|
|
string alarm_yy = tmp;
|
|
alarm_yy = alarm_yy.substr(0,2);
|
|
|
|
if ( mm == alarm_mm && dd == alarm_dd && yy == alarm_yy )
|
|
//don't sort
|
|
// alarmList.insert (AlarmList::value_type(alarm.getAlarmID(), alarm));
|
|
alarmList.insert (AlarmList::value_type(INVALID_ALARM_ID, alarm));
|
|
}
|
|
}
|
|
hisAlarm.close();
|
|
unlink (alarmFile.c_str());
|
|
|
|
// release lock
|
|
if (flock(fd,LOCK_UN) == -1)
|
|
{
|
|
throw runtime_error ("Release lock active alarm log file error");
|
|
}
|
|
|
|
if (CALPONT_SNMP_DEBUG)
|
|
{
|
|
AlarmList :: iterator i;
|
|
for (i = alarmList.begin(); i != alarmList.end(); ++i)
|
|
{
|
|
cout << i->second << endl;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************************
|
|
* @brief getNMSAddr API
|
|
*
|
|
* purpose: Get NMS IP Address from the snmptrapd config file
|
|
*
|
|
*****************************************************************************************/
|
|
void SNMPManager::getNMSAddr (string& addr)
|
|
{
|
|
getSNMPConfig (SNMPManager::parentOAMModuleName, TRAPD, "NMSADDR", addr);
|
|
}
|
|
|
|
/*****************************************************************************************
|
|
* @brief setNMSAddr API
|
|
*
|
|
* purpose: Set NMS IP Address from the snmptrapd config file
|
|
*
|
|
*****************************************************************************************/
|
|
void SNMPManager::setNMSAddr (const string addr)
|
|
{
|
|
setSNMPConfig (SNMPManager::parentOAMModuleName, TRAPD, "NMSADDR", addr);
|
|
}
|
|
|
|
|
|
/*****************************************************************************************
|
|
* @brief setSNMPConfig API
|
|
*
|
|
* purpose: Set a SNMP monitoring threashold value in the snmpdx config file
|
|
* Set NMS IP Address in snmptrapd config file
|
|
*
|
|
*
|
|
*****************************************************************************************/
|
|
void SNMPManager::setSNMPConfig (const string ModuleName, const std::string agentName,
|
|
const string paramName, const string value)
|
|
{
|
|
string fileName;
|
|
makeFileName (agentName, fileName);
|
|
vector <string> lines;
|
|
string calParamName = "CALPONT_" + paramName;
|
|
Oam oam;
|
|
|
|
ifstream oldFile (fileName.c_str());
|
|
if (!oldFile) throw runtime_error ("No configuration file found");
|
|
|
|
char line[200];
|
|
string buf;
|
|
string changeValue;
|
|
string delimiters = " ";
|
|
while (oldFile.getline(line, 200))
|
|
{
|
|
buf = line;
|
|
if (buf.find(calParamName) != string::npos)
|
|
{
|
|
lines.push_back(buf);
|
|
// change next line
|
|
oldFile.getline(line, 200);
|
|
buf = line;
|
|
|
|
// if change NMS IP Addr to 0.0.0.0, then comment out forward line if not already
|
|
if ( paramName == "NMSADDR" && value == oam::UnassignedIpAddr ) {
|
|
string::size_type pos = buf.find("#", 0);
|
|
if ( string::npos == pos ) {
|
|
string templine = line;
|
|
buf = "#" + templine;
|
|
}
|
|
}
|
|
|
|
// if change NMS IP Addr to NOT 0.0.0.0, then un-comment line if needed
|
|
if ( paramName == "NMSADDR" && value != oam::UnassignedIpAddr ) {
|
|
string::size_type pos = buf.find("#", 0);
|
|
if ( string::npos != pos )
|
|
buf = buf.substr(1,200);
|
|
}
|
|
|
|
string::size_type lastPos = buf.find_first_not_of(delimiters, 0);
|
|
string::size_type pos = buf.find_first_of(delimiters, lastPos);
|
|
|
|
// find the last token, which is the value to be changed
|
|
while (string::npos != pos || string::npos != lastPos)
|
|
{
|
|
changeValue = buf.substr(lastPos, pos - lastPos);
|
|
lastPos = buf.find_first_not_of(delimiters, pos);
|
|
pos = buf.find_first_of(delimiters, lastPos);
|
|
}
|
|
pos = buf.find(changeValue);
|
|
buf.replace(pos, 20, value);
|
|
}
|
|
|
|
// output to temp file
|
|
lines.push_back(buf);
|
|
}
|
|
|
|
oldFile.close();
|
|
unlink (fileName.c_str());
|
|
ofstream newFile (fileName.c_str());
|
|
|
|
// create new file
|
|
int fd = open(fileName.c_str(),O_RDWR|O_CREAT, 0664);
|
|
|
|
// Aquire an exclusive lock
|
|
if (flock(fd,LOCK_EX) == -1) {
|
|
throw runtime_error ("Lock SNMP configuration file error");
|
|
}
|
|
|
|
copy(lines.begin(), lines.end(), ostream_iterator<string>(newFile, "\n"));
|
|
newFile.close();
|
|
|
|
// Release lock
|
|
if (flock(fd,LOCK_UN) == -1)
|
|
{
|
|
throw runtime_error ("Release lock SNMP configuration file error");
|
|
}
|
|
close(fd);
|
|
|
|
//re-init snmp processes
|
|
string processName;
|
|
makeProcessName (agentName, processName);
|
|
|
|
/* try {
|
|
oam.reinitProcessType(processName);
|
|
}
|
|
catch(...)
|
|
{}
|
|
*/
|
|
}
|
|
|
|
/*****************************************************************************************
|
|
* @brief getSNMPConfig API
|
|
*
|
|
* purpose: Get a SNMP monitoring threashold value in the snmpdx config file
|
|
*
|
|
* paramName options: DISK_CRITICAL, DISK_MAJOR, DISK_MINOR
|
|
* MEM_CRITICAL, MEM_MAJOR, MEM_MINOR
|
|
* SWAP_CRITICAL, SWAP_MAJOR, SWAP_MINOR
|
|
*
|
|
*****************************************************************************************/
|
|
void SNMPManager::getSNMPConfig (const string ModuleName, const std::string agentName,
|
|
const string paramName, string& value)
|
|
{
|
|
string fileName;
|
|
makeFileName (agentName, fileName);
|
|
|
|
ifstream configFile (fileName.c_str());
|
|
char line[200];
|
|
string buf;
|
|
string delimiters = " ";
|
|
string calParamName = "CALPONT_" + paramName;
|
|
|
|
while (configFile.getline(line, 200))
|
|
{
|
|
buf = line;
|
|
if (buf.find(calParamName) != string::npos)
|
|
{
|
|
configFile.getline(line, 200);
|
|
buf = line;
|
|
string::size_type lastPos = buf.find_first_not_of(delimiters, 0);
|
|
string::size_type pos = buf.find_first_of(delimiters, lastPos);
|
|
|
|
// find the last token, which is the value to be read
|
|
while (string::npos != pos || string::npos != lastPos)
|
|
{
|
|
value = buf.substr(lastPos, pos - lastPos);
|
|
lastPos = buf.find_first_not_of(delimiters, pos);
|
|
pos = buf.find_first_of(delimiters, lastPos);
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
throw runtime_error("Error processing snmptrapd configuration file");
|
|
}
|
|
|
|
/*****************************************************************************************
|
|
* @brief setSNMPModuleName API
|
|
*
|
|
* purpose: Set SNMP Module name in the snmpdx.conf file
|
|
*
|
|
*****************************************************************************************/
|
|
void SNMPManager::setSNMPModuleName ()
|
|
{
|
|
// get current Module name
|
|
Oam oam;
|
|
string ModuleName;
|
|
oamModuleInfo_t st;
|
|
try {
|
|
st = oam.getModuleInfo();
|
|
ModuleName = boost::get<0>(st);
|
|
}
|
|
catch (...) {
|
|
ModuleName = "Unknown Report Module";
|
|
}
|
|
|
|
string agentName = SUB_AGENT;
|
|
string fileName;
|
|
makeFileName (agentName, fileName);
|
|
vector <string> lines;
|
|
|
|
ifstream oldFile (fileName.c_str());
|
|
if (!oldFile) throw runtime_error ("No configuration file found");
|
|
|
|
char line[200];
|
|
string buf;
|
|
string newLine;
|
|
string newLine1;
|
|
string delimiters = " ";
|
|
while (oldFile.getline(line, 200))
|
|
{
|
|
buf = line;
|
|
string::size_type pos = buf.find("ModuleNameStub",0);
|
|
if (pos != string::npos)
|
|
{
|
|
newLine = buf.substr(0, pos);
|
|
newLine.append(ModuleName);
|
|
|
|
string::size_type pos1 = buf.find("|",pos);
|
|
if (pos1 != string::npos)
|
|
{
|
|
newLine1 = buf.substr(pos1, 200);
|
|
newLine.append(newLine1);
|
|
}
|
|
buf = newLine;
|
|
}
|
|
// output to temp file
|
|
lines.push_back(buf);
|
|
}
|
|
|
|
oldFile.close();
|
|
unlink (fileName.c_str());
|
|
ofstream newFile (fileName.c_str());
|
|
|
|
// create new file
|
|
int fd = open(fileName.c_str(), O_RDWR|O_CREAT, 0664);
|
|
|
|
// Aquire an exclusive lock
|
|
if (flock(fd,LOCK_EX) == -1) {
|
|
throw runtime_error ("Lock SNMP configuration file error");
|
|
}
|
|
|
|
copy(lines.begin(), lines.end(), ostream_iterator<string>(newFile, "\n"));
|
|
newFile.close();
|
|
|
|
// Release lock
|
|
if (flock(fd,LOCK_UN) == -1)
|
|
{
|
|
throw runtime_error ("Release lock SNMP configuration file error");
|
|
}
|
|
close(fd);
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Private functions definition
|
|
*/
|
|
|
|
/*****************************************************************************************
|
|
* @brief makeFileName API
|
|
*
|
|
* purpose: returns path for associated snmp conf file
|
|
*
|
|
*****************************************************************************************/
|
|
void SNMPManager::makeFileName (const std::string agentName, std::string& fileName)
|
|
{
|
|
string defaultPath = startup::StartUp::installDir() + "/etc/";
|
|
string localPath = startup::StartUp::installDir() + "/local/";
|
|
if (agentName.compare (MASTER_AGENT) == 0) {
|
|
fileName = defaultPath;
|
|
fileName += "snmpd.conf";
|
|
}
|
|
else if (agentName.compare (TRAPD) == 0) {
|
|
fileName = defaultPath;
|
|
fileName += "snmptrapd.conf";
|
|
}
|
|
else {
|
|
fileName = localPath;
|
|
fileName += "snmpdx.conf";
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************************
|
|
* @brief makeProcessName API
|
|
*
|
|
* purpose: returns process name for AGENT
|
|
*
|
|
*****************************************************************************************/
|
|
void SNMPManager::makeProcessName (const std::string agentName, std::string& processName)
|
|
{
|
|
if (agentName.compare (MASTER_AGENT) == 0) {
|
|
processName = "SNMPParentAgent";
|
|
}
|
|
else if (agentName.compare (TRAPD) == 0) {
|
|
processName = "SNMPTrapDaemon";
|
|
}
|
|
else {
|
|
processName = "SNMPSubagent";
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************************
|
|
* @brief updateSNMPD API
|
|
*
|
|
* purpose: updates Parent OAm IP address in snmpd.conf file
|
|
*
|
|
*****************************************************************************************/
|
|
void SNMPManager::updateSNMPD(std::string oldIPAddr, std::string parentOAMModuleIPAddr)
|
|
{
|
|
string fileName = startup::StartUp::installDir() + "/etc/snmpd.conf";
|
|
|
|
ifstream oldFile (fileName.c_str());
|
|
if (!oldFile) return;
|
|
|
|
vector <string> lines;
|
|
char line[200];
|
|
string buf;
|
|
string newLine;
|
|
string newLine1;
|
|
while (oldFile.getline(line, 200))
|
|
{
|
|
buf = line;
|
|
string::size_type pos = buf.find(oldIPAddr,0);
|
|
if (pos != string::npos)
|
|
{
|
|
newLine = buf.substr(0, pos);
|
|
newLine.append(parentOAMModuleIPAddr);
|
|
|
|
newLine1 = buf.substr(pos + oldIPAddr.size(), 200);
|
|
newLine.append(newLine1);
|
|
|
|
buf = newLine;
|
|
}
|
|
//output to temp file
|
|
lines.push_back(buf);
|
|
}
|
|
|
|
oldFile.close();
|
|
unlink (fileName.c_str());
|
|
ofstream newFile (fileName.c_str());
|
|
|
|
//create new file
|
|
int fd = open(fileName.c_str(), O_RDWR|O_CREAT, 0664);
|
|
|
|
copy(lines.begin(), lines.end(), ostream_iterator<string>(newFile, "\n"));
|
|
newFile.close();
|
|
|
|
close(fd);
|
|
return;
|
|
}
|
|
|
|
} //namespace snmpmanager
|
|
// vim:ts=4 sw=4:
|
|
|