1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-12-14 12:10:34 +00:00

Merge branch 'jwmelto-security-fix' into next

This commit is contained in:
Carles Fernandez 2022-08-11 10:24:26 +02:00
commit 8048bcaf88
No known key found for this signature in database
GPG Key ID: 4C583C52B0C3877D
8 changed files with 337 additions and 444 deletions

View File

@ -68,12 +68,23 @@ endif()
target_link_libraries(algorithms_libs_rtklib target_link_libraries(algorithms_libs_rtklib
PRIVATE PRIVATE
core_system_parameters core_system_parameters
algorithms_libs
Gflags::gflags Gflags::gflags
Glog::glog Glog::glog
LAPACK::LAPACK LAPACK::LAPACK
BLAS::BLAS BLAS::BLAS
) )
if(FILESYSTEM_FOUND)
target_compile_definitions(algorithms_libs_rtklib PUBLIC -DHAS_STD_FILESYSTEM=1)
if(find_experimental)
target_compile_definitions(algorithms_libs_rtklib PUBLIC -DHAS_STD_FILESYSTEM_EXPERIMENTAL=1)
endif()
target_link_libraries(algorithms_libs_rtklib PUBLIC std::filesystem)
else()
target_link_libraries(algorithms_libs_rtklib PUBLIC Boost::filesystem Boost::system)
endif()
set_property(TARGET algorithms_libs_rtklib set_property(TARGET algorithms_libs_rtklib
APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>

View File

@ -1108,28 +1108,28 @@ typedef struct
} serial_t; } serial_t;
typedef struct struct file_t
{ /* file control type */ { /* file control type */
FILE *fp; /* file pointer */ FILE *fp = nullptr; /* file pointer */
FILE *fp_tag; /* file pointer of tag file */ FILE *fp_tag = nullptr; /* file pointer of tag file */
FILE *fp_tmp; /* temporary file pointer for swap */ FILE *fp_tmp = nullptr; /* temporary file pointer for swap */
FILE *fp_tag_tmp; /* temporary file pointer of tag file for swap */ FILE *fp_tag_tmp = nullptr; /* temporary file pointer of tag file for swap */
char path[MAXSTRPATH]; /* file path */ std::string path; /* file path */
char openpath[MAXSTRPATH]; /* open file path */ std::string openpath; /* open file path */
int mode; /* file mode */ int mode = 0; /* file mode */
int timetag; /* time tag flag (0:off,1:on) */ int timetag; /* time tag flag (0:off,1:on) */
int repmode; /* replay mode (0:master,1:slave) */ int repmode = 0; /* replay mode (0:master,1:slave) */
int offset; /* time offset (ms) for slave */ int offset = 0; /* time offset (ms) for slave */
gtime_t time; /* start time */ gtime_t time = {}; /* start time */
gtime_t wtime; /* write time */ gtime_t wtime = {}; /* write time */
unsigned int tick; /* start tick */ unsigned int tick = 0; /* start tick */
unsigned int tick_f; /* start tick in file */ unsigned int tick_f = 0; /* start tick in file */
unsigned int fpos; /* current file position */ unsigned int fpos = 0; /* current file position */
double start; /* start offset (s) */ double start = 0; /* start offset (s) */
double speed; /* replay speed (time factor) */ double speed = 0; /* replay speed (time factor) */
double swapintv; /* swap interval (hr) (0: no swap) */ double swapintv = 0; /* swap interval (hr) (0: no swap) */
lock_t lock; /* lock flag */ lock_t lock; /* lock flag */
} file_t; };
typedef struct typedef struct

View File

@ -720,7 +720,6 @@ int raim_fde(const obsd_t *obs, int n, const double *rs,
obsd_t *obs_e; obsd_t *obs_e;
sol_t sol_e = {{0, 0}, {}, {}, {}, '0', '0', '0', 0.0, 0.0, 0.0}; sol_t sol_e = {{0, 0}, {}, {}, {}, '0', '0', '0', 0.0, 0.0, 0.0};
char tstr[32]; char tstr[32];
char name[16];
char msg_e[128]; char msg_e[128];
double *rs_e; double *rs_e;
double *dts_e; double *dts_e;
@ -819,8 +818,8 @@ int raim_fde(const obsd_t *obs, int n, const double *rs,
if (stat) if (stat)
{ {
time2str(obs[0].time, tstr, 2); time2str(obs[0].time, tstr, 2);
satno2id(sat, name); auto name = satno2id(sat);
trace(2, "%s: %s excluded by raim\n", tstr + 11, name); trace(2, "%s: %s excluded by raim\n", tstr + 11, name.data());
} }
free(obs_e); free(obs_e);
free(rs_e); free(rs_e);

View File

@ -747,7 +747,6 @@ void pppoutsolstat(rtk_t *rtk, int level, FILE *fp)
int j; int j;
int week; int week;
int nfreq = 1; int nfreq = 1;
char id[32];
if (level <= 0 || !fp) if (level <= 0 || !fp)
{ {
@ -804,11 +803,11 @@ void pppoutsolstat(rtk_t *rtk, int level, FILE *fp)
{ {
continue; continue;
} }
satno2id(i + 1, id); auto id = satno2id(i + 1);
for (j = 0; j < nfreq; j++) for (j = 0; j < nfreq; j++)
{ {
fprintf(fp, "$SAT,%d,%.3f,%s,%d,%.1f,%.1f,%.4f,%.4f,%d,%.0f,%d,%d,%d,%d,%d,%d\n", fprintf(fp, "$SAT,%d,%.3f,%s,%d,%.1f,%.1f,%.4f,%.4f,%d,%.0f,%d,%d,%d,%d,%d,%d\n",
week, tow, id, j + 1, ssat->azel[0] * R2D, ssat->azel[1] * R2D, week, tow, id.data(), j + 1, ssat->azel[0] * R2D, ssat->azel[1] * R2D,
ssat->resp[j], ssat->resc[j], ssat->vsat[j], ssat->snr[j] * 0.25, ssat->resp[j], ssat->resc[j], ssat->vsat[j], ssat->snr[j] * 0.25,
ssat->fix[j], ssat->slip[j] & 3, ssat->lock[j], ssat->outc[j], ssat->fix[j], ssat->slip[j] & 3, ssat->lock[j], ssat->outc[j],
ssat->slipc[j], ssat->rejc[j]); ssat->slipc[j], ssat->rejc[j]);

View File

@ -35,7 +35,7 @@
#include <cassert> #include <cassert>
#include <cstring> #include <cstring>
#include <dirent.h> #include <dirent.h>
#include <iostream> #include <iomanip>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <sys/stat.h> #include <sys/stat.h>
@ -43,7 +43,6 @@
#include <sys/types.h> #include <sys/types.h>
#include <vector> #include <vector>
const double GPST0[] = {1980, 1, 6, 0, 0, 0}; /* gps time reference */ const double GPST0[] = {1980, 1, 6, 0, 0, 0}; /* gps time reference */
const double GST0[] = {1999, 8, 22, 0, 0, 0}; /* galileo system time reference */ const double GST0[] = {1999, 8, 22, 0, 0, 0}; /* galileo system time reference */
const double BDT0[] = {2006, 1, 1, 0, 0, 0}; /* beidou time reference */ const double BDT0[] = {2006, 1, 1, 0, 0, 0}; /* beidou time reference */
@ -460,37 +459,50 @@ int satid2no(const char *id)
* char *id O satellite id (Gnn,Rnn,Enn,Jnn,Cnn,Inn or nnn) * char *id O satellite id (Gnn,Rnn,Enn,Jnn,Cnn,Inn or nnn)
* return : none * return : none
*-----------------------------------------------------------------------------*/ *-----------------------------------------------------------------------------*/
void satno2id(int sat, char *id) std::string satno2id(int sat)
{ {
std::ostringstream ss;
ss << std::setfill('0'); // all PRNs are 0-filled
std::string prefix;
int width = 2;
int prn; int prn;
char id_aux[16];
switch (satsys(sat, &prn)) switch (satsys(sat, &prn))
{ {
case SYS_GPS: case SYS_GPS:
std::snprintf(id, sizeof(id_aux), "G%02d", prn - MINPRNGPS + 1); prefix = "G";
return; prn = prn - MINPRNGPS + 1;
break;
case SYS_GLO: case SYS_GLO:
snprintf(id, sizeof(id_aux), "R%02d", prn - MINPRNGLO + 1); prefix = "R";
return; prn = prn - MINPRNGLO + 1;
break;
case SYS_GAL: case SYS_GAL:
std::snprintf(id, sizeof(id_aux), "E%02d", prn - MINPRNGAL + 1); prefix = "E";
return; prn = prn - MINPRNGAL + 1;
break;
case SYS_QZS: case SYS_QZS:
std::snprintf(id, sizeof(id_aux), "J%02d", prn - MINPRNQZS + 1); prefix = "J";
return; prn = prn - MINPRNQZS + 1;
break;
case SYS_BDS: case SYS_BDS:
std::snprintf(id, sizeof(id_aux), "C%02d", prn - MINPRNBDS + 1); prefix = "C";
return; prn = prn - MINPRNBDS + 1;
break;
case SYS_IRN: case SYS_IRN:
std::snprintf(id, sizeof(id_aux), "I%02d", prn - MINPRNIRN + 1); prefix = "I";
return; prn = prn - MINPRNIRN + 1;
break;
case SYS_LEO: case SYS_LEO:
std::snprintf(id, sizeof(id_aux), "L%02d", prn - MINPRNLEO + 1); prefix = "L";
return; prn = prn - MINPRNLEO + 1;
break;
case SYS_SBS: case SYS_SBS:
std::snprintf(id, sizeof(id_aux), "%03d", prn); width = 3;
return; break;
} }
ss << prefix << std::setw(width) << prn;
return ss.str();
} }
@ -2833,9 +2845,9 @@ int readantex(const char *file, pcvs_t *pcvs)
if (strstr(buff + 60, "TYPE / SERIAL NO")) if (strstr(buff + 60, "TYPE / SERIAL NO"))
{ {
strncpy(pcv.type, buff, 20); strncpy(pcv.type, buff, 20); // MAXANT (64)
pcv.type[20] = '\0'; pcv.type[20] = '\0';
strncpy(pcv.code, buff + 20, 20); strncpy(pcv.code, buff + 20, 20); // MAXANT (64)
pcv.code[20] = '\0'; pcv.code[20] = '\0';
if (!strncmp(pcv.code + 3, " ", 8)) if (!strncmp(pcv.code + 3, " ", 8))
{ {
@ -3090,9 +3102,9 @@ void readpos(const char *file, const char *rcv, double *pos)
{ {
continue; continue;
} }
// strncpy(stas[np], str, 15); This line triggers a warning. Replaced by: auto sta = stas[np++]; // NOLINT(readability-qualified-auto)
memcpy(stas[np], str, 15 * sizeof(stas[np][0])); std::strncpy(sta, str, 16);
stas[np++][15] = '\0'; sta[15] = '\0';
} }
fclose(fp); fclose(fp);
len = static_cast<int>(strlen(rcv)); len = static_cast<int>(strlen(rcv));
@ -3700,7 +3712,6 @@ int savenav(const char *file, const nav_t *nav)
{ {
FILE *fp; FILE *fp;
int i; int i;
char id[32];
trace(3, "savenav: file=%s\n", file); trace(3, "savenav: file=%s\n", file);
@ -3715,12 +3726,12 @@ int savenav(const char *file, const nav_t *nav)
{ {
continue; continue;
} }
satno2id(nav->eph[i].sat, id); auto id = satno2id(nav->eph[i].sat);
fprintf(fp, fprintf(fp,
"%s,%d,%d,%d,%d,%d,%d,%d,%.14E,%.14E,%.14E,%.14E,%.14E,%.14E," "%s,%d,%d,%d,%d,%d,%d,%d,%.14E,%.14E,%.14E,%.14E,%.14E,%.14E,"
"%.14E,%.14E,%.14E,%.14E,%.14E,%.14E,%.14E,%.14E,%.14E,%.14E," "%.14E,%.14E,%.14E,%.14E,%.14E,%.14E,%.14E,%.14E,%.14E,%.14E,"
"%.14E,%.14E,%.14E,%.14E,%.14E,%d,%d\n", "%.14E,%.14E,%.14E,%.14E,%.14E,%d,%d\n",
id, nav->eph[i].iode, nav->eph[i].iodc, nav->eph[i].sva, id.data(), nav->eph[i].iode, nav->eph[i].iodc, nav->eph[i].sva,
nav->eph[i].svh, static_cast<int>(nav->eph[i].toe.time), nav->eph[i].svh, static_cast<int>(nav->eph[i].toe.time),
static_cast<int>(nav->eph[i].toc.time), static_cast<int>(nav->eph[i].ttr.time), static_cast<int>(nav->eph[i].toc.time), static_cast<int>(nav->eph[i].ttr.time),
nav->eph[i].A, nav->eph[i].e, nav->eph[i].i0, nav->eph[i].OMG0, nav->eph[i].A, nav->eph[i].e, nav->eph[i].i0, nav->eph[i].OMG0,
@ -3736,11 +3747,11 @@ int savenav(const char *file, const nav_t *nav)
{ {
continue; continue;
} }
satno2id(nav->geph[i].sat, id); auto id = satno2id(nav->geph[i].sat);
fprintf(fp, fprintf(fp,
"%s,%d,%d,%d,%d,%d,%d,%d,%.14E,%.14E,%.14E,%.14E,%.14E,%.14E," "%s,%d,%d,%d,%d,%d,%d,%d,%.14E,%.14E,%.14E,%.14E,%.14E,%.14E,"
"%.14E,%.14E,%.14E,%.14E,%.14E,%.14E\n", "%.14E,%.14E,%.14E,%.14E,%.14E,%.14E\n",
id, nav->geph[i].iode, nav->geph[i].frq, nav->geph[i].svh, id.data(), nav->geph[i].iode, nav->geph[i].frq, nav->geph[i].svh,
nav->geph[i].sva, nav->geph[i].age, static_cast<int>(nav->geph[i].toe.time), nav->geph[i].sva, nav->geph[i].age, static_cast<int>(nav->geph[i].toe.time),
static_cast<int>(nav->geph[i].tof.time), static_cast<int>(nav->geph[i].tof.time),
nav->geph[i].pos[0], nav->geph[i].pos[1], nav->geph[i].pos[2], nav->geph[i].pos[0], nav->geph[i].pos[1], nav->geph[i].pos[2],
@ -3841,7 +3852,7 @@ void freenav(nav_t *nav, int opt)
// #ifdef TRACE // #ifdef TRACE
// //
FILE *fp_trace = nullptr; /* file pointer of trace */ FILE *fp_trace = nullptr; /* file pointer of trace */
char file_trace[1024]; /* trace file */ std::string file_trace; /* trace file */
static int level_trace = 0; /* level of trace */ static int level_trace = 0; /* level of trace */
unsigned int tick_trace = 0; /* tick time at traceopen (ms) */ unsigned int tick_trace = 0; /* tick time at traceopen (ms) */
gtime_t time_trace = {0, 0.0}; /* time at traceopen */ gtime_t time_trace = {0, 0.0}; /* time at traceopen */
@ -3850,7 +3861,7 @@ pthread_mutex_t lock_trace; /* lock for trace */
void traceswap() void traceswap()
{ {
gtime_t time = utc2gpst(timeget()); gtime_t time = utc2gpst(timeget());
char path[1024]; std::string path;
rtk_lock(&lock_trace); rtk_lock(&lock_trace);
@ -3872,7 +3883,7 @@ void traceswap()
fclose(fp_trace); fclose(fp_trace);
} }
if (!(fp_trace = fopen(path, "we"))) if (!(fp_trace = fopen(path.data(), "we")))
{ {
fp_trace = stderr; fp_trace = stderr;
} }
@ -3883,22 +3894,15 @@ void traceswap()
void traceopen(const char *file) void traceopen(const char *file)
{ {
gtime_t time = utc2gpst(timeget()); gtime_t time = utc2gpst(timeget());
char path[1024]; std::string path;
reppath(file, path, time, "", ""); reppath(file, path, time, "", "");
if (!*path || !(fp_trace = fopen(path, "we"))) if (path.empty() or (fp_trace = fopen(path.data(), "we")) == nullptr)
{ {
fp_trace = stderr; fp_trace = stderr;
} }
if (strlen(file) < 1025)
{ file_trace = file;
std::strncpy(file_trace, file, 1024);
file_trace[1023] = '\0';
}
else
{
trace(1, "file array is too long");
}
tick_trace = tickget(); tick_trace = tickget();
time_trace = time; time_trace = time;
initlock(&lock_trace); initlock(&lock_trace);
@ -3912,7 +3916,7 @@ void traceclose()
fclose(fp_trace); fclose(fp_trace);
} }
fp_trace = nullptr; fp_trace = nullptr;
file_trace[0] = '\0'; file_trace.clear();
} }
@ -3967,9 +3971,9 @@ void traceobs(int level __attribute__((unused)), const obsd_t *obs __attribute__
// if (!fp_trace||level>level_trace) return; // if (!fp_trace||level>level_trace) return;
// for (i=0;i<n;i++) { // for (i=0;i<n;i++) {
// time2str(obs[i].time,str,3); // time2str(obs[i].time,str,3);
// satno2id(obs[i].sat,id); // auto id = satno2id(obs[i].sat);
// fprintf(fp_trace," (%2d) %s %-3s rcv%d %13.3f %13.3f %13.3f %13.3f %d %d %d %d %3.1f %3.1f\n", // fprintf(fp_trace," (%2d) %s %-3s rcv%d %13.3f %13.3f %13.3f %13.3f %d %d %d %d %3.1f %3.1f\n",
// i+1,str,id,obs[i].rcv,obs[i].L[0],obs[i].L[1],obs[i].P[0], // i+1,str,id.data(),obs[i].rcv,obs[i].L[0],obs[i].L[1],obs[i].P[0],
// obs[i].P[1],obs[i].LLI[0],obs[i].LLI[1],obs[i].code[0], // obs[i].P[1],obs[i].LLI[0],obs[i].LLI[1],obs[i].code[0],
// obs[i].code[1],obs[i].SNR[0]*0.25,obs[i].SNR[1]*0.25); // obs[i].code[1],obs[i].SNR[0]*0.25,obs[i].SNR[1]*0.25);
// } // }
@ -3985,9 +3989,9 @@ void traceobs(int level __attribute__((unused)), const obsd_t *obs __attribute__
// for (i=0;i<nav->n;i++) { // for (i=0;i<nav->n;i++) {
// time2str(nav->eph[i].toe,s1,0); // time2str(nav->eph[i].toe,s1,0);
// time2str(nav->eph[i].ttr,s2,0); // time2str(nav->eph[i].ttr,s2,0);
// satno2id(nav->eph[i].sat,id); // auto id = satno2id(nav->eph[i].sat);
// fprintf(fp_trace,"(%3d) %-3s : %s %s %3d %3d %02x\n",i+1, // fprintf(fp_trace,"(%3d) %-3s : %s %s %3d %3d %02x\n",i+1,
// id,s1,s2,nav->eph[i].iode,nav->eph[i].iodc,nav->eph[i].svh); // id.data(),s1,s2,nav->eph[i].iode,nav->eph[i].iodc,nav->eph[i].svh);
// } // }
// fprintf(fp_trace,"(ion) %9.4e %9.4e %9.4e %9.4e\n",nav->ion_gps[0], // fprintf(fp_trace,"(ion) %9.4e %9.4e %9.4e %9.4e\n",nav->ion_gps[0],
// nav->ion_gps[1],nav->ion_gps[2],nav->ion_gps[3]); // nav->ion_gps[1],nav->ion_gps[2],nav->ion_gps[3]);
@ -4005,9 +4009,9 @@ void traceobs(int level __attribute__((unused)), const obsd_t *obs __attribute__
// for (i=0;i<nav->ng;i++) { // for (i=0;i<nav->ng;i++) {
// time2str(nav->geph[i].toe,s1,0); // time2str(nav->geph[i].toe,s1,0);
// time2str(nav->geph[i].tof,s2,0); // time2str(nav->geph[i].tof,s2,0);
// satno2id(nav->geph[i].sat,id); // auto id = satno2id(nav->geph[i].sat);
// fprintf(fp_trace,"(%3d) %-3s : %s %s %2d %2d %8.3f\n",i+1, // fprintf(fp_trace,"(%3d) %-3s : %s %s %2d %2d %8.3f\n",i+1,
// id,s1,s2,nav->geph[i].frq,nav->geph[i].svh,nav->geph[i].taun*1e6); // id.data(),s1,s2,nav->geph[i].frq,nav->geph[i].svh,nav->geph[i].taun*1e6);
// } // }
// } // }
// extern void tracehnav(int level, const nav_t *nav) // extern void tracehnav(int level, const nav_t *nav)
@ -4019,14 +4023,14 @@ void traceobs(int level __attribute__((unused)), const obsd_t *obs __attribute__
// for (i=0;i<nav->ns;i++) { // for (i=0;i<nav->ns;i++) {
// time2str(nav->seph[i].t0,s1,0); // time2str(nav->seph[i].t0,s1,0);
// time2str(nav->seph[i].tof,s2,0); // time2str(nav->seph[i].tof,s2,0);
// satno2id(nav->seph[i].sat,id); // auto id = satno2id(nav->seph[i].sat);
// fprintf(fp_trace,"(%3d) %-3s : %s %s %2d %2d\n",i+1, // fprintf(fp_trace,"(%3d) %-3s : %s %s %2d %2d\n",i+1,
// id,s1,s2,nav->seph[i].svh,nav->seph[i].sva); // id.data(),s1,s2,nav->seph[i].svh,nav->seph[i].sva);
// } // }
// } // }
// extern void tracepeph(int level, const nav_t *nav) // extern void tracepeph(int level, const nav_t *nav)
// { // {
// char s[64],id[16]; // char s[64];
// int i,j; // int i,j;
// //
// if (!fp_trace||level>level_trace) return; // if (!fp_trace||level>level_trace) return;
@ -4034,9 +4038,9 @@ void traceobs(int level __attribute__((unused)), const obsd_t *obs __attribute__
// for (i=0;i<nav->ne;i++) { // for (i=0;i<nav->ne;i++) {
// time2str(nav->peph[i].time,s,0); // time2str(nav->peph[i].time,s,0);
// for (j=0;j<MAXSAT;j++) { // for (j=0;j<MAXSAT;j++) {
// satno2id(j+1,id); // auto id = satno2id(j+1);
// fprintf(fp_trace,"%-3s %d %-3s %13.3f %13.3f %13.3f %13.3f %6.3f %6.3f %6.3f %6.3f\n", // fprintf(fp_trace,"%-3s %d %-3s %13.3f %13.3f %13.3f %13.3f %6.3f %6.3f %6.3f %6.3f\n",
// s,nav->peph[i].index,id, // s,nav->peph[i].index,id.data(),
// nav->peph[i].pos[j][0],nav->peph[i].pos[j][1], // nav->peph[i].pos[j][0],nav->peph[i].pos[j][1],
// nav->peph[i].pos[j][2],nav->peph[i].pos[j][3]*1e9, // nav->peph[i].pos[j][2],nav->peph[i].pos[j][3]*1e9,
// nav->peph[i].std[j][0],nav->peph[i].std[j][1], // nav->peph[i].std[j][0],nav->peph[i].std[j][1],
@ -4046,7 +4050,7 @@ void traceobs(int level __attribute__((unused)), const obsd_t *obs __attribute__
// } // }
// extern void tracepclk(int level, const nav_t *nav) // extern void tracepclk(int level, const nav_t *nav)
// { // {
// char s[64],id[16]; // char s[64];
// int i,j; // int i,j;
// //
// if (!fp_trace||level>level_trace) return; // if (!fp_trace||level>level_trace) return;
@ -4054,9 +4058,9 @@ void traceobs(int level __attribute__((unused)), const obsd_t *obs __attribute__
// for (i=0;i<nav->nc;i++) { // for (i=0;i<nav->nc;i++) {
// time2str(nav->pclk[i].time,s,0); // time2str(nav->pclk[i].time,s,0);
// for (j=0;j<MAXSAT;j++) { // for (j=0;j<MAXSAT;j++) {
// satno2id(j+1,id); // auto id = satno2id(j+1);
// fprintf(fp_trace,"%-3s %d %-3s %13.3f %6.3f\n", // fprintf(fp_trace,"%-3s %d %-3s %13.3f %6.3f\n",
// s,nav->pclk[i].index,id, // s,nav->pclk[i].index,id.data(),
// nav->pclk[i].clk[j][0]*1e9,nav->pclk[i].std[j][0]*1e9); // nav->pclk[i].clk[j][0]*1e9,nav->pclk[i].std[j][0]*1e9);
// } // }
// } // }
@ -4114,69 +4118,31 @@ int execcmd(const char *cmd)
* return : none * return : none
* notes : not recursive. only one level * notes : not recursive. only one level
*-----------------------------------------------------------------------------*/ *-----------------------------------------------------------------------------*/
void createdir(const char *path) void createdir(fs::path const &path)
{ {
char buff[1024]; errorlib::error_code ec;
char *p;
// tracet(3, "createdir: path=%s\n", path);
if (strlen(path) < 1025) auto created = fs::create_directory(path, ec);
if (not created)
{ {
std::strncpy(buff, path, 1024); trace(1, "Error creating folder: %s", path.c_str());
buff[1023] = '\0';
}
else
{
trace(1, "path is too long");
}
if (!(p = strrchr(buff, FILEPATHSEP)))
{
return;
}
*p = '\0';
if (mkdir(buff, 0777) != 0)
{
trace(1, "Error creating folder");
} }
} }
/* replace string ------------------------------------------------------------*/ /* replace string ------------------------------------------------------------*/
int repstr(char *str, const char *pat, const char *rep) int repstr(std::string &str, std::string const &pat, std::string const &rep)
{ {
int len = static_cast<int>(strlen(pat)); int replaced = 0;
char buff[1024];
char *p;
char *q;
char *r;
for (p = str, r = buff; *p; p = q + len) auto pos = str.find(pat);
if (pos != std::string::npos)
{ {
if (!(q = strstr(p, pat))) str.replace(pos, pat.length(), rep);
{ replaced = 1;
break;
}
strncpy(r, p, q - p);
r += q - p;
r += std::snprintf(r, sizeof(buff), "%s", rep);
}
if (p <= str)
{
return 0;
} }
if (strlen(p) < 1025) return replaced;
{
std::strncpy(r, p, 1024);
r[1023] = '\0';
}
else
{
trace(1, "pat array is too long");
}
std::strncpy(str, buff, 1024);
return 1;
} }
@ -4208,23 +4174,19 @@ int repstr(char *str, const char *pat, const char *rep)
* %r -> rrrr : rover id * %r -> rrrr : rover id
* %b -> bbbb : base station id * %b -> bbbb : base station id
*-----------------------------------------------------------------------------*/ *-----------------------------------------------------------------------------*/
int reppath(const char *path, char *rpath, gtime_t time, const char *rov, int reppath(std::string const &path, std::string &rpath, gtime_t time, const char *rov,
const char *base) const char *base)
{ {
double ep[6];
double ep0[6] = {2000, 1, 1, 0, 0, 0};
int week;
int dow;
int doy;
int stat = 0; int stat = 0;
char rep[64];
std::strncpy(rpath, path, 1024); rpath = path;
// synctactic sugar; implements C++23 std::string::contains()
auto patFind = [](std::string const &s, std::string const &pat) -> bool {
auto pos = s.find(pat);
return pos != s.npos;
};
if (!strstr(rpath, "%"))
{
return 0;
}
if (*rov) if (*rov)
{ {
stat |= repstr(rpath, "%r", rov); stat |= repstr(rpath, "%r", rov);
@ -4235,10 +4197,17 @@ int reppath(const char *path, char *rpath, gtime_t time, const char *rov,
} }
if (time.time != 0) if (time.time != 0)
{ {
char rep[64]; // scratch space for replacement string
double ep[6];
time2epoch(time, ep); time2epoch(time, ep);
ep0[0] = ep[0];
dow = static_cast<int>(floor(time2gpst(time, &week) / 86400.0)); int week = 0;
doy = static_cast<int>(floor(timediff(time, epoch2time(ep0)) / 86400.0)) + 1; auto dow = static_cast<int>(floor(time2gpst(time, &week) / 86400.0));
double ep0[6] = {ep[0], 1, 1, 0, 0, 0};
auto doy = static_cast<int>(floor(timediff(time, epoch2time(ep0)) / 86400.0)) + 1;
std::snprintf(rep, sizeof(rep), "%02d", (static_cast<int>(ep[3]) / 3) * 3); std::snprintf(rep, sizeof(rep), "%02d", (static_cast<int>(ep[3]) / 3) * 3);
stat |= repstr(rpath, "%ha", rep); stat |= repstr(rpath, "%ha", rep);
std::snprintf(rep, sizeof(rep), "%02d", (static_cast<int>(ep[3]) / 6) * 6); std::snprintf(rep, sizeof(rep), "%02d", (static_cast<int>(ep[3]) / 6) * 6);
@ -4270,78 +4239,18 @@ int reppath(const char *path, char *rpath, gtime_t time, const char *rov,
std::snprintf(rep, sizeof(rep), "%02d", (static_cast<int>(ep[4]) / 15) * 15); std::snprintf(rep, sizeof(rep), "%02d", (static_cast<int>(ep[4]) / 15) * 15);
stat |= repstr(rpath, "%t", rep); stat |= repstr(rpath, "%t", rep);
} }
else if (strstr(rpath, "%ha") || strstr(rpath, "%hb") || strstr(rpath, "%hc") || else if (patFind(rpath, "%ha") || patFind(rpath, "%hb") || patFind(rpath, "%hc") ||
strstr(rpath, "%Y") || strstr(rpath, "%y") || strstr(rpath, "%m") || patFind(rpath, "%Y") || patFind(rpath, "%y") || patFind(rpath, "%m") ||
strstr(rpath, "%d") || strstr(rpath, "%h") || strstr(rpath, "%M") || patFind(rpath, "%d") || patFind(rpath, "%h") || patFind(rpath, "%M") ||
strstr(rpath, "%S") || strstr(rpath, "%n") || strstr(rpath, "%W") || patFind(rpath, "%S") || patFind(rpath, "%n") || patFind(rpath, "%W") ||
strstr(rpath, "%D") || strstr(rpath, "%H") || strstr(rpath, "%t")) patFind(rpath, "%D") || patFind(rpath, "%H") || patFind(rpath, "%t"))
{ {
return -1; /* no valid time */ stat = -1; /* no valid time */
} }
return stat; return stat;
} }
/* replace keywords in file path and generate multiple paths -------------------
* replace keywords in file path with date, time, rover and base station id
* generate multiple keywords-replaced paths
* args : char *path I file path (see below)
* char *rpath[] O file paths in which keywords replaced
* int nmax I max number of output file paths
* gtime_t ts I time start (gpst)
* gtime_t te I time end (gpst)
* char *rov I rover id string ("": not replaced)
* char *base I base station id string ("": not replaced)
* return : number of replaced file paths
* notes : see reppath() for replacements of keywords.
* minimum interval of time replaced is 900s.
*-----------------------------------------------------------------------------*/
int reppaths(const char *path, char *rpath[], int nmax, gtime_t ts,
gtime_t te, const char *rov, const char *base)
{
gtime_t time;
double tow;
double tint = 86400.0;
int i;
int n = 0;
int week;
trace(3, "reppaths: path =%s nmax=%d rov=%s base=%s\n", path, nmax, rov, base);
if (ts.time == 0 || te.time == 0 || timediff(ts, te) > 0.0)
{
return 0;
}
if (strstr(path, "%S") || strstr(path, "%M") || strstr(path, "%t"))
{
tint = 900.0;
}
else if (strstr(path, "%h") || strstr(path, "%H"))
{
tint = 3600.0;
}
tow = time2gpst(ts, &week);
time = gpst2time(week, floor(tow / tint) * tint);
while (timediff(time, te) <= 0.0 && n < nmax)
{
reppath(path, rpath[n], time, rov, base);
if (n == 0 || strcmp(rpath[n], rpath[n - 1]) != 0)
{
n++;
}
time = timeadd(time, tint);
}
for (i = 0; i < n; i++)
{
trace(3, "reppaths: rpath=%s\n", rpath[i]);
}
return n;
}
/* satellite carrier wave length ----------------------------------------------- /* satellite carrier wave length -----------------------------------------------
* get satellite carrier wave lengths * get satellite carrier wave lengths
* args : int sat I satellite number * args : int sat I satellite number

View File

@ -62,6 +62,24 @@
#include <cstddef> #include <cstddef>
#include <string> #include <string>
#if HAS_STD_FILESYSTEM
#include <system_error>
namespace errorlib = std;
#if HAS_STD_FILESYSTEM_EXPERIMENTAL
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;
#else
#include <filesystem>
namespace fs = std::filesystem;
#endif
#else
#include <boost/filesystem/operations.hpp> // for create_directories, exists
#include <boost/filesystem/path.hpp> // for path, operator<<
#include <boost/filesystem/path_traits.hpp> // for filesystem
#include <boost/system/error_code.hpp> // for error_code
namespace fs = boost::filesystem;
namespace errorlib = boost::system;
#endif
/* coordinate rotation matrix ------------------------------------------------*/ /* coordinate rotation matrix ------------------------------------------------*/
#define Rx(t, X) \ #define Rx(t, X) \
@ -102,7 +120,7 @@ void fatalerr(const char *format, ...);
int satno(int sys, int prn); int satno(int sys, int prn);
int satsys(int sat, int *prn); int satsys(int sat, int *prn);
int satid2no(const char *id); int satid2no(const char *id);
void satno2id(int sat, char *id); std::string satno2id(int sat);
int satexclude(int sat, int svh, const prcopt_t *opt); int satexclude(int sat, int svh, const prcopt_t *opt);
int testsnr(int base, int freq, double el, double snr, const snrmask_t *mask); int testsnr(int base, int freq, double el, double snr, const snrmask_t *mask);
unsigned char obs2code(const char *obs, int *freq); unsigned char obs2code(const char *obs, int *freq);
@ -229,12 +247,9 @@ void traceobs(int level, const obsd_t *obs, int n);
// void traceb (int level, const unsigned char *p, int n); // void traceb (int level, const unsigned char *p, int n);
int execcmd(const char *cmd); int execcmd(const char *cmd);
void createdir(const char *path); void createdir(fs::path const &path);
int repstr(char *str, const char *pat, const char *rep); int reppath(std::string const &path, std::string &rpath, gtime_t time, const char *rov,
int reppath(const char *path, char *rpath, gtime_t time, const char *rov,
const char *base); const char *base);
int reppaths(const char *path, char *rpath[], int nmax, gtime_t ts,
gtime_t te, const char *rov, const char *base);
double satwavelen(int sat, int frq, const nav_t *nav); double satwavelen(int sat, int frq, const nav_t *nav);
double geodist(const double *rs, const double *rr, double *e); double geodist(const double *rs, const double *rr, double *e);
double satazel(const double *pos, const double *e, double *azel); double satazel(const double *pos, const double *e, double *azel);

View File

@ -37,6 +37,7 @@
#include "rtklib_tides.h" #include "rtklib_tides.h"
#include <cmath> #include <cmath>
#include <cstring> #include <cstring>
#include <string>
#include <vector> #include <vector>
static int resamb_WLNL(rtk_t *rtk __attribute((unused)), const obsd_t *obs __attribute((unused)), const int *sat __attribute((unused)), static int resamb_WLNL(rtk_t *rtk __attribute((unused)), const obsd_t *obs __attribute((unused)), const int *sat __attribute((unused)),
@ -124,7 +125,7 @@ static gtime_t time_stat = {0, 0}; /* rtk status file time */
int rtkopenstat(const char *file, int level) int rtkopenstat(const char *file, int level)
{ {
gtime_t time = utc2gpst(timeget()); gtime_t time = utc2gpst(timeget());
char path[1024]; std::string path;
trace(3, "rtkopenstat: file=%s level=%d\n", file, level); trace(3, "rtkopenstat: file=%s level=%d\n", file, level);
@ -135,9 +136,9 @@ int rtkopenstat(const char *file, int level)
reppath(file, path, time, "", ""); reppath(file, path, time, "", "");
if (!(fp_stat = fopen(path, "we"))) if (!(fp_stat = fopen(path.data(), "we")))
{ {
trace(1, "rtkopenstat: file open error path=%s\n", path); trace(1, "rtkopenstat: file open error path=%s\n", path.data());
return 0; return 0;
} }
if (strlen(file) < 1025) if (strlen(file) < 1025)
@ -191,7 +192,6 @@ void rtkoutstat(rtk_t *rtk, char *buff __attribute__((unused)))
int est; int est;
int nfreq; int nfreq;
int nf = NF_RTK(&rtk->opt); int nf = NF_RTK(&rtk->opt);
char id[32];
if (statlevel <= 0 || !fp_stat) if (statlevel <= 0 || !fp_stat)
{ {
@ -264,11 +264,11 @@ void rtkoutstat(rtk_t *rtk, char *buff __attribute__((unused)))
{ {
continue; continue;
} }
satno2id(i + 1, id); auto id = satno2id(i + 1);
j = II_RTK(i + 1, &rtk->opt); j = II_RTK(i + 1, &rtk->opt);
xa[0] = j < rtk->na ? rtk->xa[j] : 0.0; xa[0] = j < rtk->na ? rtk->xa[j] : 0.0;
fprintf(fp_stat, "$ION,%d,%.3f,%d,%s,%.1f,%.1f,%.4f,%.4f\n", week, tow, rtk->sol.stat, fprintf(fp_stat, "$ION,%d,%.3f,%d,%s,%.1f,%.1f,%.4f,%.4f\n", week, tow, rtk->sol.stat,
id, ssat->azel[0] * R2D, ssat->azel[1] * R2D, rtk->x[j], xa[0]); id.data(), ssat->azel[0] * R2D, ssat->azel[1] * R2D, rtk->x[j], xa[0]);
} }
} }
/* tropospheric parameters */ /* tropospheric parameters */
@ -306,11 +306,11 @@ void rtkoutstat(rtk_t *rtk, char *buff __attribute__((unused)))
{ {
continue; continue;
} }
satno2id(i + 1, id); auto id = satno2id(i + 1);
for (j = 0; j < nfreq; j++) for (j = 0; j < nfreq; j++)
{ {
fprintf(fp_stat, "$SAT,%d,%.3f,%s,%d,%.1f,%.1f,%.4f,%.4f,%d,%.0f,%d,%d,%d,%d,%d,%d\n", fprintf(fp_stat, "$SAT,%d,%.3f,%s,%d,%.1f,%.1f,%.4f,%.4f,%d,%.0f,%d,%d,%d,%d,%d,%d\n",
week, tow, id, j + 1, ssat->azel[0] * R2D, ssat->azel[1] * R2D, week, tow, id.data(), j + 1, ssat->azel[0] * R2D, ssat->azel[1] * R2D,
ssat->resp[j], ssat->resc[j], ssat->vsat[j], ssat->snr[j] * 0.25, ssat->resp[j], ssat->resc[j], ssat->vsat[j], ssat->snr[j] * 0.25,
ssat->fix[j], ssat->slip[j] & 3, ssat->lock[j], ssat->outc[j], ssat->fix[j], ssat->slip[j] & 3, ssat->lock[j], ssat->outc[j],
ssat->slipc[j], ssat->rejc[j]); ssat->slipc[j], ssat->rejc[j]);
@ -323,7 +323,7 @@ void rtkoutstat(rtk_t *rtk, char *buff __attribute__((unused)))
void swapsolstat() void swapsolstat()
{ {
gtime_t time = utc2gpst(timeget()); gtime_t time = utc2gpst(timeget());
char path[1024]; std::string path;
if (static_cast<int>(time2gpst(time, nullptr) / INT_SWAP_STAT) == if (static_cast<int>(time2gpst(time, nullptr) / INT_SWAP_STAT) ==
static_cast<int>(time2gpst(time_stat, nullptr) / INT_SWAP_STAT)) static_cast<int>(time2gpst(time_stat, nullptr) / INT_SWAP_STAT))
@ -341,12 +341,12 @@ void swapsolstat()
fclose(fp_stat); fclose(fp_stat);
} }
if (!(fp_stat = fopen(path, "we"))) if (!(fp_stat = fopen(path.data(), "we")))
{ {
trace(2, "swapsolstat: file open error path=%s\n", path); trace(2, "swapsolstat: file open error path=%s\n", path.data());
return; return;
} }
trace(3, "swapsolstat: path=%s\n", path); trace(3, "swapsolstat: path=%s\n", path.data());
} }
@ -367,7 +367,6 @@ void outsolstat(rtk_t *rtk)
int est; int est;
int nfreq; int nfreq;
int nf = NF_RTK(&rtk->opt); int nf = NF_RTK(&rtk->opt);
char id[32];
if (statlevel <= 0 || !fp_stat) if (statlevel <= 0 || !fp_stat)
{ {
@ -440,11 +439,11 @@ void outsolstat(rtk_t *rtk)
{ {
continue; continue;
} }
satno2id(i + 1, id); auto id = satno2id(i + 1);
j = II_RTK(i + 1, &rtk->opt); j = II_RTK(i + 1, &rtk->opt);
xa[0] = j < rtk->na ? rtk->xa[j] : 0.0; xa[0] = j < rtk->na ? rtk->xa[j] : 0.0;
fprintf(fp_stat, "$ION,%d,%.3f,%d,%s,%.1f,%.1f,%.4f,%.4f\n", week, tow, rtk->sol.stat, fprintf(fp_stat, "$ION,%d,%.3f,%d,%s,%.1f,%.1f,%.4f,%.4f\n", week, tow, rtk->sol.stat,
id, ssat->azel[0] * R2D, ssat->azel[1] * R2D, rtk->x[j], xa[0]); id.data(), ssat->azel[0] * R2D, ssat->azel[1] * R2D, rtk->x[j], xa[0]);
} }
} }
/* tropospheric parameters */ /* tropospheric parameters */
@ -482,11 +481,11 @@ void outsolstat(rtk_t *rtk)
{ {
continue; continue;
} }
satno2id(i + 1, id); auto id = satno2id(i + 1);
for (j = 0; j < nfreq; j++) for (j = 0; j < nfreq; j++)
{ {
fprintf(fp_stat, "$SAT,%d,%.3f,%s,%d,%.1f,%.1f,%.4f,%.4f,%d,%.0f,%d,%d,%d,%d,%d,%d\n", fprintf(fp_stat, "$SAT,%d,%.3f,%s,%d,%.1f,%.1f,%.4f,%.4f,%d,%.0f,%d,%d,%d,%d,%d,%d\n",
week, tow, id, j + 1, ssat->azel[0] * R2D, ssat->azel[1] * R2D, week, tow, id.data(), j + 1, ssat->azel[0] * R2D, ssat->azel[1] * R2D,
ssat->resp[j], ssat->resc[j], ssat->vsat[j], ssat->snr[j] * 0.25, ssat->resp[j], ssat->resc[j], ssat->vsat[j], ssat->snr[j] * 0.25,
ssat->fix[j], ssat->slip[j] & 3, ssat->lock[j], ssat->outc[j], ssat->fix[j], ssat->slip[j] & 3, ssat->lock[j], ssat->outc[j],
ssat->slipc[j], ssat->rejc[j]); ssat->slipc[j], ssat->rejc[j]);

View File

@ -31,6 +31,8 @@
*/ */
#include "rtklib_stream.h" #include "rtklib_stream.h"
#include "gnss_sdr_make_unique.h" // for std::make:unique in C++11
#include "gnss_sdr_string_literals.h" // for std::string_literals
#include "rtklib_rtkcmn.h" #include "rtklib_rtkcmn.h"
#include "rtklib_solution.h" #include "rtklib_solution.h"
#include <arpa/inet.h> #include <arpa/inet.h>
@ -38,9 +40,13 @@
#include <cerrno> #include <cerrno>
#include <cinttypes> #include <cinttypes>
#include <cstring> #include <cstring>
#include <deque>
#include <fcntl.h> #include <fcntl.h>
#include <memory>
#include <netdb.h> #include <netdb.h>
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <regex>
#include <sstream>
#include <string> #include <string>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/stat.h> #include <sys/stat.h>
@ -48,6 +54,7 @@
#include <termios.h> #include <termios.h>
#include <unistd.h> #include <unistd.h>
using namespace std::string_literals;
/* global options ------------------------------------------------------------*/ /* global options ------------------------------------------------------------*/
@ -118,7 +125,7 @@ serial_t *openserial(const char *path, int mode, char *msg)
} }
parity = static_cast<char>(toupper(static_cast<int>(parity))); parity = static_cast<char>(toupper(static_cast<int>(parity)));
std::string s_aux = "/dev/" + std::string(port); std::string s_aux = "/dev/"s + std::string(port);
s_aux.resize(128, '\0'); s_aux.resize(128, '\0');
int n = s_aux.length(); int n = s_aux.length();
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
@ -228,18 +235,17 @@ int stateserial(serial_t *serial)
int openfile_(file_t *file, gtime_t time, char *msg) int openfile_(file_t *file, gtime_t time, char *msg)
{ {
FILE *fp; FILE *fp;
char *rw;
char tagpath[MAXSTRPATH + 4] = ""; char tagpath[MAXSTRPATH + 4] = "";
char tagh[TIMETAGH_LEN + 1] = ""; char tagh[TIMETAGH_LEN + 1] = "";
tracet(3, "openfile_: path=%s time=%s\n", file->path, time_str(time, 0)); tracet(3, "openfile_: path=%s time=%s\n", file->path.data(), time_str(time, 0));
file->time = utc2gpst(timeget()); file->time = utc2gpst(timeget());
file->tick = file->tick_f = tickget(); file->tick = file->tick_f = tickget();
file->fpos = 0; file->fpos = 0;
/* use stdin or stdout if file path is null */ /* use stdin or stdout if file path is empty */
if (!*file->path) if (file->path.empty())
{ {
file->fp = file->mode & STR_MODE_R ? stdin : stdout; file->fp = file->mode & STR_MODE_R ? stdin : stdout;
return 1; return 1;
@ -250,37 +256,39 @@ int openfile_(file_t *file, gtime_t time, char *msg)
/* create directory */ /* create directory */
if ((file->mode & STR_MODE_W) && !(file->mode & STR_MODE_R)) if ((file->mode & STR_MODE_W) && !(file->mode & STR_MODE_R))
{ {
createdir(file->openpath); createdir(file->openpath.data());
} }
char const *mode;
if (file->mode & STR_MODE_R) if (file->mode & STR_MODE_R)
{ {
rw = const_cast<char *>("rb"); mode = "rb";
} }
else else
{ {
rw = const_cast<char *>("wb"); mode = "wb";
} }
if (!(file->fp = fopen(file->openpath, rw))) if (!(file->fp = fopen(file->openpath.data(), mode)))
{ {
std::snprintf(msg, MAXSTRMSG, "file open error"); std::snprintf(msg, MAXSTRMSG, "file open error");
tracet(1, "openfile: %s\n", msg); tracet(1, "openfile: %s\n", msg);
return 0; return 0;
} }
tracet(4, "openfile_: open file %s (%s)\n", file->openpath, rw); tracet(4, "openfile_: open file %s (%s)\n", file->openpath.data(), mode);
std::snprintf(tagpath, MAXSTRPATH + 4, "%s.tag", file->openpath); std::snprintf(tagpath, MAXSTRPATH + 4, "%s.tag", file->openpath.data());
if (file->timetag) if (file->timetag)
{ /* output/sync time-tag */ { /* output/sync time-tag */
if (!(file->fp_tag = fopen(tagpath, rw))) if (!(file->fp_tag = fopen(tagpath, mode)))
{ {
std::snprintf(msg, MAXSTRMSG, "tag open error"); std::snprintf(msg, MAXSTRMSG, "tag open error");
tracet(1, "openfile: %s\n", msg); tracet(1, "openfile: %s\n", msg);
fclose(file->fp); fclose(file->fp);
return 0; return 0;
} }
tracet(4, "openfile_: open tag file %s (%s)\n", tagpath, rw); tracet(4, "openfile_: open tag file %s (%s)\n", tagpath, mode);
if (file->mode & STR_MODE_R) if (file->mode & STR_MODE_R)
{ {
@ -326,131 +334,132 @@ int openfile_(file_t *file, gtime_t time, char *msg)
/* close file ----------------------------------------------------------------*/ /* close file ----------------------------------------------------------------*/
void closefile_(file_t *file) void closefile_(file_t *file)
{ {
tracet(3, "closefile_: path=%s\n", file->path); tracet(3, "closefile_: path=%s\n", file->path.data());
if (file->fp) if (file->fp)
{ {
fclose(file->fp); fclose(file->fp);
file->fp = nullptr;
} }
if (file->fp_tag) if (file->fp_tag)
{ {
fclose(file->fp_tag); fclose(file->fp_tag);
file->fp_tag = nullptr;
} }
if (file->fp_tmp) if (file->fp_tmp)
{ {
fclose(file->fp_tmp); fclose(file->fp_tmp);
file->fp_tmp = nullptr;
} }
if (file->fp_tag_tmp) if (file->fp_tag_tmp)
{ {
fclose(file->fp_tag_tmp); fclose(file->fp_tag_tmp);
file->fp_tag_tmp = nullptr;
} }
file->fp = file->fp_tag = file->fp_tmp = file->fp_tag_tmp = nullptr;
} }
/* open file (path=filepath[::T[::+<off>][::x<speed>]][::S=swapintv]) --------*/ /* open file (path=filepath[::T[::+<off>][::x<speed>]][::S=swapintv]) --------*/
file_t *openfile(const char *path, int mode, char *msg) file_t *openfile(std::string const &path, int mode, char *msg)
{ {
file_t *file; tracet(3, "openfile: path=%s mode=%d\n", path.data(), mode);
gtime_t time;
gtime_t time0 = {0, 0.0};
double speed = 0.0;
double start = 0.0;
double swapintv = 0.0;
char *p;
int timetag = 0;
tracet(3, "openfile: path=%s mode=%d\n", path, mode); if ((mode & (STR_MODE_R | STR_MODE_W)) == 0)
if (!(mode & (STR_MODE_R | STR_MODE_W)))
{ {
return nullptr; return nullptr;
} }
// Split the string by regular expression (in this case, the trivial "::" string)
std::regex re("::");
auto first = std::sregex_token_iterator(path.begin(), path.end(), re, -1);
auto last = std::sregex_token_iterator();
std::deque<std::string> tokens(first, last);
auto file = std::make_unique<file_t>();
file->mode = mode;
file->path = tokens.front(); // first token is the path
tokens.pop_front();
/* file options */ /* file options */
for (p = const_cast<char *>(path); (p = strstr(p, "::")); p += 2) while (not tokens.empty())
{ /* file options */
if (*(p + 2) == 'T')
{
timetag = 1;
}
else if (*(p + 2) == '+')
{
sscanf(p + 2, "+%lf", &start);
}
else if (*(p + 2) == 'x')
{
sscanf(p + 2, "x%lf", &speed);
}
else if (*(p + 2) == 'S')
{
sscanf(p + 2, "S=%lf", &swapintv);
}
}
if (start <= 0.0)
{ {
start = 0.0; auto tag = tokens.front();
} tokens.pop_front();
if (swapintv <= 0.0)
{ // edge case that may not be possible, but I don't want to test for right now
swapintv = 0.0; if (tag.empty()) continue; // NOLINT(readability-braces-around-statements)
if (tag == "T")
{
file->timetag = 1;
}
else if (tag[0] == '+')
{
double start = 0.0;
std::istringstream ss(tag);
ss.ignore(1, '+') >> start;
// do we care if there are extra characters?
if (start < 0)
{
start = 0;
}
file->start = start;
}
else if (tag[0] == 'x')
{
double speed = 0.0;
std::istringstream ss(tag);
ss.ignore(1, 'x') >> speed;
// do we care if there are extra characters?
file->speed = speed;
}
else if (tag[0] == 'S')
{
double swapintv = 0.0;
std::istringstream ss(tag);
ss.ignore(1, 'S').ignore(1, '=') >> swapintv;
// do we care if there are extra characters?
if (swapintv < 0) swapintv = 0; // NOLINT(readability-braces-around-statements)
file->swapintv = swapintv;
}
else
{
// unexpected value ... not previously handled
}
} }
if (!(file = static_cast<file_t *>(malloc(sizeof(file_t)))))
{
return nullptr;
}
file->fp = file->fp_tag = file->fp_tmp = file->fp_tag_tmp = nullptr;
if (strlen(path) < MAXSTRPATH)
{
std::strncpy(file->path, path, MAXSTRPATH);
file->path[MAXSTRPATH - 1] = '\0';
}
if ((p = strstr(file->path, "::")))
{
*p = '\0';
}
file->openpath[0] = '\0';
file->mode = mode;
file->timetag = timetag;
file->repmode = 0;
file->offset = 0;
file->time = file->wtime = time0;
file->tick = file->tick_f = file->fpos = 0;
file->start = start;
file->speed = speed;
file->swapintv = swapintv;
initlock(&file->lock); initlock(&file->lock);
time = utc2gpst(timeget()); auto time = utc2gpst(timeget());
/* open new file */ /* open new file */
if (!openfile_(file, time, msg)) if (!openfile_(file.get(), time, msg))
{ {
free(file); file.reset();
return nullptr;
} }
return file; return file.release(); // ownership belongs to the caller now
} }
/* close file ----------------------------------------------------------------*/ /* close file ----------------------------------------------------------------*/
void closefile(file_t *file) void closefile(file_t *file)
{ {
if (!file) if (file)
{ {
return; std::unique_ptr<file_t> fileH(file);
tracet(3, "closefile: fp=%p \n", fileH->fp);
closefile_(fileH.get());
} }
tracet(3, "closefile: fp=%p \n", file->fp);
closefile_(file);
free(file);
} }
/* open new swap file --------------------------------------------------------*/ /* open new swap file --------------------------------------------------------*/
void swapfile(file_t *file, gtime_t time, char *msg) void swapfile(file_t *file, gtime_t time, char *msg)
{ {
char openpath[MAXSTRPATH]; std::string openpath;
tracet(3, "swapfile: fp=%p \n time=%s\n", file->fp, time_str(time, 0)); tracet(3, "swapfile: fp=%p \n time=%s\n", file->fp, time_str(time, 0));
@ -463,9 +472,9 @@ void swapfile(file_t *file, gtime_t time, char *msg)
/* check path of new swap file */ /* check path of new swap file */
reppath(file->path, openpath, time, "", ""); reppath(file->path, openpath, time, "", "");
if (!strcmp(openpath, file->openpath)) if (openpath == file->openpath)
{ {
tracet(2, "swapfile: no need to swap %s\n", openpath); tracet(2, "swapfile: no need to swap %s\n", openpath.data());
return; return;
} }
/* save file pointer to temporary pointer */ /* save file pointer to temporary pointer */
@ -1739,7 +1748,7 @@ ntrip_t *openntrip(const char *path, int type, char *msg)
/* ntrip access via proxy server */ /* ntrip access via proxy server */
if (*proxyaddr) if (*proxyaddr)
{ {
std::string s_aux = "http://" + std::string(tpath); std::string s_aux = "http://"s + std::string(tpath);
int n = s_aux.length(); int n = s_aux.length();
if (n < 256) if (n < 256)
{ {
@ -1924,19 +1933,6 @@ gtime_t nextdltime(const int *topts, int stat)
void *ftpthread(void *arg) void *ftpthread(void *arg)
{ {
auto *ftp = static_cast<ftp_t *>(arg); auto *ftp = static_cast<ftp_t *>(arg);
FILE *fp;
gtime_t time;
char remote[1024];
char local[1024];
char tmpfile[1024];
char errfile[1024];
char *p;
char cmd[2048];
char env[1024] = "";
char opt[1024];
char *proxyopt = const_cast<char *>("");
char *proto;
int ret;
tracet(3, "ftpthread:\n"); tracet(3, "ftpthread:\n");
@ -1948,152 +1944,117 @@ void *ftpthread(void *arg)
return nullptr; return nullptr;
} }
/* replace keyword in file path and local path */ /* replace keyword in file path and local path */
time = timeadd(utc2gpst(timeget()), ftp->topts[0]); auto time = timeadd(utc2gpst(timeget()), ftp->topts[0]);
std::string remote;
reppath(ftp->file, remote, time, "", ""); reppath(ftp->file, remote, time, "", "");
auto remotePath = fs::path(remote);
if ((p = strrchr(remote, '/'))) auto local = fs::path(localdir);
{ local /= remotePath.filename();
p++;
}
else
{
p = remote;
}
std::string s_aux = std::string(localdir) + std::to_string(FILEPATHSEP) + std::string(p);
int n = s_aux.length();
if (n < 1024)
{
for (int i = 0; i < n; i++)
{
local[i] = s_aux[i];
}
}
std::string s_aux2 = std::string(local) + ".err"; auto errfile = fs::path(local);
n = s_aux2.length(); errfile.replace_extension("err");
if (n < 1024)
{
for (int i = 0; i < n; i++)
{
errfile[i] = s_aux2[i];
}
}
/* if local file exist, skip download */ /* if local file exist, skip download */
std::strncpy(tmpfile, local, 1024); auto tmpfile = local;
tmpfile[1023] = '\0'; for (auto ext : {".z", ".gz", ".zip", ".Z", ".GZ", ".ZIP"}) // NOLINT(readability-qualified-auto): auto decoration is less readable
if ((p = strrchr(tmpfile, '.')) &&
(!strcmp(p, ".z") || !strcmp(p, ".gz") || !strcmp(p, ".zip") ||
!strcmp(p, ".Z") || !strcmp(p, ".GZ") || !strcmp(p, ".ZIP")))
{ {
*p = '\0'; if (tmpfile.extension() == ext)
{
tmpfile.replace_extension("");
break;
}
} }
if ((fp = fopen(tmpfile, "rbe"))) if (fs::exists(tmpfile))
{ {
fclose(fp); std::strncpy(ftp->local, tmpfile.c_str(), 1024);
std::strncpy(ftp->local, tmpfile, 1024);
ftp->local[1023] = '\0'; ftp->local[1023] = '\0';
tracet(3, "ftpthread: file exists %s\n", ftp->local); tracet(3, "ftpthread: file exists %s\n", ftp->local);
ftp->state = 2; ftp->state = 2;
return nullptr; return nullptr;
} }
std::string env;
/* proxy settings for wget (ref [2]) */ /* proxy settings for wget (ref [2]) */
auto proxyopt = std::string();
if (*proxyaddr) if (*proxyaddr)
{ {
proto = ftp->proto ? const_cast<char *>("http") : const_cast<char *>("ftp"); auto proto = "ftp"s;
std::snprintf(env, sizeof(env), "set %s_proxy=http://%s & ", proto, proxyaddr); if (ftp->proto) proto = "http"s; // NOLINT(readability-braces-around-statements): adding braces reduces readability
proxyopt = const_cast<char *>("--proxy=on "); env = "set "s + proto + "_proxy=http://"s + std::string(proxyaddr) + " % ";
proxyopt = "--proxy=on ";
} }
/* download command (ref [2]) */ /* download command (ref [2]) */
auto cmd_str = std::string();
if (ftp->proto == 0) if (ftp->proto == 0)
{ /* ftp */ { /* ftp */
s_aux = "--ftp-user=" + std::string(ftp->user) + " --ftp-password=" + std::string(ftp->passwd) + auto opt_str = "--ftp-user="s + std::string(ftp->user) + " --ftp-password="s + std::string(ftp->passwd) +
" --glob=off --passive-ftp " + std::string(proxyopt) + "s-t 1 -T " + std::to_string(FTP_TIMEOUT) + " --glob=off --passive-ftp "s + proxyopt + "s-t 1 -T "s + std::to_string(FTP_TIMEOUT) +
" -O \"" + std::string(local) + "\""; R"( -O ")" + local.native() + R"(")"s;
int k = s_aux.length();
if (k < 1024)
{
for (int i = 0; i < k; i++)
{
opt[i] = s_aux[i];
}
}
s_aux2 = std::string(env) + std::string(FTP_CMD) + " " + std::string(opt) + " " + // TODO: this uses shell syntax; consider escaping paths
"\"ftp://" + std::string(ftp->addr) + "/" + std::string(remote) + "\" 2> \"" + std::string(errfile) + "\"\n"; cmd_str = env + std::string(FTP_CMD) + " "s + opt_str + " "s +
k = s_aux2.length(); R"("ftp://)"s + std::string(ftp->addr) + "/"s + remotePath.native() + R"(" 2> ")"s + errfile.native() + "\"\n"s;
for (int i = 0; (i < k) && (i < 1024); i++)
{
cmd[i] = s_aux2[i];
}
} }
else else
{ /* http */ { /* http */
s_aux = std::string(proxyopt) + " -t 1 -T " + std::to_string(FTP_TIMEOUT) + " -O \"" + std::string(local) + "\""; auto opt_str = proxyopt + " -t 1 -T "s + std::to_string(FTP_TIMEOUT) + " -O \""s + local.native() + "\""s;
int l = s_aux.length();
for (int i = 0; (i < l) && (i < 1024); i++)
{
opt[i] = s_aux[i];
}
s_aux2 = std::string(env) + std::string(FTP_CMD) + " " + std::string(opt) + " " + cmd_str = env + std::string(FTP_CMD) + " "s + opt_str + " "s +
"\"http://" + std::string(ftp->addr) + "/" + std::string(remote) + "\" 2> \"" + std::string(errfile) + "\"\n"; R"("http://)"s + std::string(ftp->addr) + "/"s + remotePath.native() + R"(" 2> ")"s + errfile.native() + "\"\n";
l = s_aux2.length();
for (int i = 0; (i < l) && (i < 1024); i++)
{
cmd[i] = s_aux2[i];
}
} }
/* execute download command */ /* execute download command */
if ((ret = execcmd(cmd))) errorlib::error_code ec; // prevent exceptions
auto ret = execcmd(cmd_str.c_str());
if ((ret != 0))
{ {
if (remove(local) != 0) if (fs::remove(local, ec) == false)
{ {
trace(1, "Error removing file"); trace(1, "Error removing file %s", local.c_str());
} }
tracet(1, "execcmd error: cmd=%s ret=%d\n", cmd, ret); tracet(1, "execcmd error: cmd=%s ret=%d\n", cmd_str.data(), ret);
ftp->error = ret; ftp->error = ret;
ftp->state = 3; ftp->state = 3;
return nullptr; return nullptr;
} }
if (remove(errfile) != 0) if (fs::remove(errfile, ec) == false)
{ {
trace(1, "Error removing file"); trace(1, "Error removing file %s", errfile.c_str());
} }
/* uncompress downloaded file */ /* uncompress downloaded file */
if ((p = strrchr(local, '.')) && for (auto ext : {".z", ".gz", ".zip", ".Z", ".GZ", ".ZIP"}) // NOLINT(readability-qualified-auto): auto decoration is less readable
(!strcmp(p, ".z") || !strcmp(p, ".gz") || !strcmp(p, ".zip") ||
!strcmp(p, ".Z") || !strcmp(p, ".GZ") || !strcmp(p, ".ZIP")))
{ {
if (rtk_uncompress(local, tmpfile)) if (local.extension() == ext)
{ {
if (remove(local) != 0) char tmpfile_arg[1024];
ret = rtk_uncompress(local.c_str(), tmpfile_arg);
if (ret != 0) // success
{ {
trace(1, "Error removing file"); if (fs::remove(local, ec) == false)
{
trace(1, "Error removing file %s", local.c_str());
}
local = tmpfile_arg;
} }
if (strlen(tmpfile) < 1024) else
{ {
std::strncpy(local, tmpfile, 1024); tracet(1, "file uncompact error: %s\n", local.c_str());
local[1023] = '\0'; ftp->error = 12;
ftp->state = 3;
return nullptr;
} }
} break;
else
{
tracet(1, "file uncompact error: %s\n", local);
ftp->error = 12;
ftp->state = 3;
return nullptr;
} }
} }
if (strlen(local) < 1024) std::strncpy(ftp->local, local.c_str(), 1024);
{ ftp->local[1023] = '\0';
std::strncpy(ftp->local, local, 1024);
ftp->local[1023] = '\0';
}
ftp->state = 2; /* ftp completed */ ftp->state = 2; /* ftp completed */
tracet(3, "ftpthread: complete cmd=%s\n", cmd); tracet(3, "ftpthread: complete cmd=%s\n", cmd_str.data());
return nullptr; return nullptr;
} }
@ -2115,7 +2076,7 @@ ftp_t *openftp(const char *path, int type, char *msg)
ftp->state = 0; ftp->state = 0;
ftp->proto = type; ftp->proto = type;
ftp->error = 0; ftp->error = 0;
ftp->thread = 0; // NOLINT ftp->thread = pthread_t();
ftp->local[0] = '\0'; ftp->local[0] = '\0';
/* decode ftp path */ /* decode ftp path */