MIDAS
Loading...
Searching...
No Matches
mhttpd.cxx File Reference
#include <stdio.h>
#include <math.h>
#include <assert.h>
#include <algorithm>
#include <thread>
#include <deque>
#include <mutex>
#include <condition_variable>
#include <atomic>
#include "midas.h"
#include "msystem.h"
#include "mxml.h"
#include "odbxx.h"
#include "mstrlcpy.h"
#include "mgd.h"
#include "history.h"
#include "mjsonrpc.h"
#include "mvodb.h"
Include dependency graph for mhttpd.cxx:

Go to the source code of this file.

Classes

class  Attachment
 
struct  MimetypeTableEntry
 
class  RequestTrace
 
class  RequestTraceBuf
 
class  Return
 
class  Param
 
struct  search_data
 
struct  CGIF_LABEL
 
struct  CGIF_BAR
 
struct  HistoryData
 
struct  HistVar
 
struct  HistPlot
 
struct  Cookies
 
struct  AuthEntry
 
class  Auth
 

Macros

#define DEFAULT_REFRESH   60
 
#define OBSOLETE   1
 
#define MAX_GROUPS   32
 
#define MAX_VARS   100
 
#define HTTP_ENCODING   "UTF-8"
 
#define WEB_BUFFER_SIZE   (6*1024*1024)
 
#define MAX_PARAM   500
 
#define PARAM_LENGTH   256
 
#define TEXT_SIZE   50000
 
#define LN10   2.302585094
 
#define LOG2   0.301029996
 
#define LOG5   0.698970005
 
#define ALLOC(t, n)   (t*)calloc(sizeof(t),(n))
 
#define DELETE(x)   if (x) { free(x); (x)=NULL; }
 
#define DELETEA(x, n)   if (x) { for (int i=0; i<(n); i++) { free((x)[i]); (x)[i]=NULL; }; DELETE(x); }
 
#define STRDUP(x)   strdup(x)
 
#define READ_HISTORY_DATA   0x1
 
#define READ_HISTORY_RUNMARKER   0x2
 
#define READ_HISTORY_LAST_WRITTEN   0x4
 
#define RESPONSE_SENT   1
 
#define RESPONSE_QUEUED   2
 
#define RESPONSE_501   3
 

Functions

static std::string toString (int i)
 
static std::string GetMimetype (const std::string &ext)
 
static void SaveMimetypes (MVOdb *odb)
 
void show_hist_page (MVOdb *odb, Param *p, Return *r, const char *dec_path, char *buffer, int *buffer_size, int refresh)
 
int vaxis (gdImagePtr im, gdFont *font, int col, int gcol, int x1, int y1, int width, int minor, int major, int text, int label, int grid, double ymin, double ymax, BOOL logaxis)
 
void haxis (gdImagePtr im, gdFont *font, int col, int gcol, int x1, int y1, int width, int minor, int major, int text, int label, int grid, double xmin, double xmax)
 
void get_elog_url (char *url, int len)
 
void show_header (Return *r, const char *title, const char *method, const char *path, int refresh)
 
void show_navigation_bar (Return *r, const char *cur_page)
 
char * stristr (const char *str, const char *pattern)
 
static double GetTimeSec ()
 
const char * mhttpd_revision (void)
 
static std::string UrlDecode (const char *p)
 
static void urlDecode (char *p)
 
static void urlEncode (char *ps, int ps_size)
 
static std::string urlEncode (const char *text)
 
std::vector< std::string > get_resource_paths ()
 
bool open_resource_file (const char *filename, std::string *ppath, FILE **pfp)
 
std::string get_content_type (const char *filename)
 
bool send_fp (Return *r, const std::string &path, FILE *fp)
 
bool send_file (Return *r, const std::string &path, bool generate_404=true)
 
bool send_resource (Return *r, const std::string &name, bool generate_404=true)
 
INT sendmail (const char *from_host, const char *smtp_host, const char *from, const char *to, const char *subject, const char *text)
 
void redirect (Return *r, const char *path)
 
void redirect_307 (Return *r, const char *path)
 
void redirect2 (Return *r, const char *path)
 
INT search_callback (HNDLE hDB, HNDLE hKey, KEY *key, INT level, void *info)
 
void show_help_page (Return *r, const char *dec_path)
 
void show_text_header (Return *r)
 
void show_error (Return *r, const char *error)
 
void show_error_404 (Return *r, const char *error)
 
void check_obsolete_odb (HNDLE hDB, const char *odb_path)
 
void init_menu_buttons (MVOdb *odb)
 
void init_mhttpd_odb (MVOdb *odb)
 
void init_elog_odb ()
 
void strencode (Return *r, const char *text)
 
std::string strencode2 (const char *text)
 
void strencode3 (Return *r, const char *text)
 
void strencode4 (Return *r, const char *text)
 
void gen_odb_attachment (Return *r, const char *path, std::string &bout)
 
void submit_elog (MVOdb *odb, Param *pp, Return *r, Attachment *a)
 
void show_elog_attachment (Param *p, Return *r, const char *path)
 
BOOL is_editable (char *eq_name, char *var_name)
 
void show_eqtable_page (Param *pp, Return *r, int refresh)
 
char * find_odb_tag (char *p, char *path, char *format, int *edit, char *type, char *pwd, char *tail)
 
void show_odb_tag (Param *pp, Return *r, const char *path, const char *keypath1, const char *format, int n_var, int edit, char *type, char *pwd, char *tail)
 
int evaluate_src (char *key, char *src, double *fvalue)
 
std::string add_custom_path (const std::string &filename)
 
void show_custom_file (Return *r, const char *name)
 
void show_custom_gif (Return *rr, const char *name)
 
void do_jrpc_rev0 (Param *p, Return *r)
 
void do_jrpc_rev1 (Param *p, Return *r)
 
void do_jrpc (Param *p, Return *r)
 
void output_key (Param *p, Return *r, HNDLE hkey, int index, const char *format)
 
bool starts_with (const std::string &s1, const char *s2)
 
void javascript_commands (Param *p, Return *r, const char *cookie_cpwd)
 
void show_custom_page (Param *pp, Return *r, const char *cookie_cpwd)
 
static void show_cnaf_page (Param *p, Return *rr)
 
void show_password_page (Return *r, const char *dec_path, const char *password)
 
BOOL check_web_password (Return *r, HNDLE hDB, const char *dec_path, const char *password, const char *redir)
 
void show_odb_page (Param *pp, Return *r, const char *dec_path, int write_access)
 
void show_set_page (Param *pp, Return *r, const char *group, int index, const char *value)
 
void show_find_page (Return *r, const char *value)
 
void sec_to_label (char *result, int sec, int base, int force_date)
 
void taxis (gdImagePtr im, gdFont *font, int col, int gcol, int x1, int y1, int width, int xr, int minor, int major, int text, int label, int grid, double xmin, double xmax)
 
int time_to_sec (const char *str)
 
time_t string_to_time (const char *str)
 
std::string time_to_string (time_t t)
 
static void history_watch_callback (HNDLE hDB, HNDLE hKey, int index, void *info)
 
static MidasHistoryInterfaceget_history (bool reset=false)
 
static void LoadHistPlotFromOdb (MVOdb *odb, HistPlot *hp, const char *group, const char *panel)
 
int read_history (const HistPlot &hp, int index, int flags, time_t tstart, time_t tend, time_t scale, HistoryData *data)
 
int get_hist_last_written (MVOdb *odb, const char *group, const char *panel, time_t endtime, int index, int want_all, time_t *plastwritten)
 
void generate_hist_graph (MVOdb *odb, Return *rr, const char *hgroup, const char *hpanel, char *buffer, int *buffer_size, int width, int height, time_t xendtime, int scale, int index, int labels, const char *bgcolor, const char *fgcolor, const char *gridcolor)
 
time_t mktime_with_dst (const struct tm *ptms)
 
static std::string add_param_to_url (const char *name, const char *value)
 
void show_query_page (Param *p, Return *r)
 
static int cmp_names (const void *a, const void *b)
 
const bool cmp_events (const std::string &a, const std::string &b)
 
const bool cmp_events1 (const std::string &a, const std::string &b)
 
const bool cmp_tags (const TAG &a, const TAG &b)
 
int xdb_get_data_index (HNDLE hDB, const char *str, void *value, int size, int index, int tid)
 
static int xdb_find_key (HNDLE hDB, HNDLE dir, const char *str, HNDLE *hKey, int tid, int size)
 
static bool cmp_vars (const HistVar &a, const HistVar &b)
 
static void PrintHistPlot (const HistPlot &hp)
 
static std::string NextHistPlotColour (const HistPlot &hp)
 
static int NextHistPlotOrder (const HistPlot &hp)
 
static void SplitEventAndTagNames (std::string var_name, std::string &event_name, std::string &tag_name)
 
static void LoadHistPlotFromParam (HistPlot *hp, Param *p)
 
static void AddHistPlotSelectedParam (HistPlot &hp, Param *p)
 
static void SaveHistPlotToOdb (MVOdb *odb, const HistPlot &hp, const char *group, const char *panel)
 
static void DeleteHistPlotDeleted (HistPlot &hp)
 
static void SortHistPlotVars (HistPlot &hp)
 
void show_hist_config_page (MVOdb *odb, Param *p, Return *r, const char *hgroup, const char *hpanel)
 
void export_hist (MVOdb *odb, Return *r, const char *group, const char *panel, time_t endtime, int scale, int index, int labels)
 
void send_icon (Return *r, const char *icon)
 
void Lock (RequestTrace *t)
 
void Unlock (RequestTrace *t)
 
void interprete (Param *p, Return *r, Attachment *a, const Cookies *c, const char *dec_path, RequestTrace *t)
 
void decode_query (Param *pp, const char *query_string)
 
void decode_get (Return *rr, char *string, const Cookies *c, const char *url, const char *query_string, RequestTrace *t)
 
void decode_post (Return *rr, const char *header, const char *string, const char *boundary, int length, const Cookies *c, const char *url, RequestTrace *t)
 
INT check_odb_records (MVOdb *odb)
 
void ctrlc_handler (int sig)
 
int try_file_mg (const char *try_dir, const char *filename, std::string &path, FILE **fpp, bool trace)
 
int find_file_mg (const char *filename, std::string &path, FILE **fpp, bool trace)
 
static bool read_passwords (Auth *auth)
 
static void xmg_mkmd5resp (const char *method, size_t method_len, const char *uri, size_t uri_len, const char *ha1, size_t ha1_len, const char *nonce, size_t nonce_len, const char *nc, size_t nc_len, const char *cnonce, size_t cnonce_len, const char *qop, size_t qop_len, char *resp)
 
static int xmg_check_nonce (const char *nonce)
 
static void xmg_http_send_digest_auth_request (struct mg_connection *c, const char *domain)
 
static std::string check_digest_auth (struct http_message *hm, Auth *auth)
 
static std::string mgstr (const mg_str *s)
 
static const std::string find_header_mg (const struct http_message *msg, const char *name)
 
static const std::string find_cookie_mg (const struct http_message *msg, const char *cookie_name)
 
static void handle_event_mg (struct mg_connection *nc, int ev, void *ev_data)
 
void decode_cookies (Cookies *c, const http_message *msg)
 
static int handle_decode_get (struct mg_connection *nc, const http_message *msg, const char *uri, const char *query_string, RequestTrace *t)
 
static int handle_decode_post (struct mg_connection *nc, const http_message *msg, const char *uri, const char *query_string, RequestTrace *t)
 
static int handle_http_get (struct mg_connection *nc, const http_message *msg, const char *uri, RequestTrace *t)
 
static int handle_http_post (struct mg_connection *nc, const http_message *msg, const char *uri, RequestTrace *t)
 
static void handle_http_options_cors (struct mg_connection *nc, const http_message *msg, RequestTrace *t)
 
static bool mongoose_passwords_enabled (const struct mg_connection *nc)
 
static void handle_http_message (struct mg_connection *nc, http_message *msg)
 
static MJsonNode * get_http_trace (const MJsonNode *params)
 
static MJsonNode * set_http_trace (const MJsonNode *params)
 
static void add_rpc_functions ()
 
int main (int argc, const char *argv[])
 

Variables

static std::mutex gMutex
 
static MVOdb * gOdb = NULL
 
static BOOL elog_mode = FALSE
 
static BOOL history_mode = FALSE
 
static BOOL verbose = FALSE
 
const char * mname []
 
static const char default_type_list [20][NAME_LENGTH]
 
static const char default_system_list [20][NAME_LENGTH]
 
const MimetypeTableEntry gMimetypeTable []
 
static MVOdb * gMimeTypesOdb = NULL
 
const unsigned char favicon_png []
 
const unsigned char favicon_ico []
 
static int http_trace = 0
 
static RequestTraceBufgTraceBuf = NULL
 
static const char * cgif_label_str []
 
static const char * cgif_bar_str []
 
static bool gDoSetupHistoryWatch = true
 
static bool gDoReloadHistory = false
 
static MidasHistoryInterfacegMh = NULL
 
static HNDLE gMhkey = 0
 
std::atomic_bool _abort {false}
 
static std::vector< std::string > gAllowedHosts
 
static bool verbose_mg = false
 
static bool trace_mg = false
 
static bool trace_mg_recv = false
 
static bool trace_mg_send = false
 
static bool trace_mg_verbose = false
 
static AuthgAuthMg = NULL
 

Macro Definition Documentation

◆ ALLOC

#define ALLOC (   t,
  n 
)    (t*)calloc(sizeof(t),(n))

Definition at line 8267 of file mhttpd.cxx.

◆ DEFAULT_REFRESH

#define DEFAULT_REFRESH   60

Definition at line 39 of file mhttpd.cxx.

◆ DELETE

#define DELETE (   x)    if (x) { free(x); (x)=NULL; }

Definition at line 8268 of file mhttpd.cxx.

◆ DELETEA

#define DELETEA (   x,
  n 
)    if (x) { for (int i=0; i<(n); i++) { free((x)[i]); (x)[i]=NULL; }; DELETE(x); }

Definition at line 8269 of file mhttpd.cxx.

◆ HTTP_ENCODING

#define HTTP_ENCODING   "UTF-8"

Definition at line 213 of file mhttpd.cxx.

◆ LN10

#define LN10   2.302585094

Definition at line 7661 of file mhttpd.cxx.

◆ LOG2

#define LOG2   0.301029996

Definition at line 7662 of file mhttpd.cxx.

◆ LOG5

#define LOG5   0.698970005

Definition at line 7663 of file mhttpd.cxx.

◆ MAX_GROUPS

#define MAX_GROUPS   32

Definition at line 52 of file mhttpd.cxx.

◆ MAX_PARAM

#define MAX_PARAM   500

Definition at line 727 of file mhttpd.cxx.

◆ MAX_VARS

#define MAX_VARS   100

Definition at line 53 of file mhttpd.cxx.

◆ OBSOLETE

#define OBSOLETE   1

Definition at line 45 of file mhttpd.cxx.

◆ PARAM_LENGTH

#define PARAM_LENGTH   256

Definition at line 728 of file mhttpd.cxx.

◆ READ_HISTORY_DATA

#define READ_HISTORY_DATA   0x1

Definition at line 8353 of file mhttpd.cxx.

◆ READ_HISTORY_LAST_WRITTEN

#define READ_HISTORY_LAST_WRITTEN   0x4

Definition at line 8355 of file mhttpd.cxx.

◆ READ_HISTORY_RUNMARKER

#define READ_HISTORY_RUNMARKER   0x2

Definition at line 8354 of file mhttpd.cxx.

◆ RESPONSE_501

#define RESPONSE_501   3

Definition at line 14288 of file mhttpd.cxx.

◆ RESPONSE_QUEUED

#define RESPONSE_QUEUED   2

Definition at line 14287 of file mhttpd.cxx.

◆ RESPONSE_SENT

#define RESPONSE_SENT   1

Definition at line 14286 of file mhttpd.cxx.

◆ STRDUP

#define STRDUP (   x)    strdup(x)

Definition at line 8270 of file mhttpd.cxx.

◆ TEXT_SIZE

#define TEXT_SIZE   50000

Definition at line 729 of file mhttpd.cxx.

◆ WEB_BUFFER_SIZE

#define WEB_BUFFER_SIZE   (6*1024*1024)

Definition at line 541 of file mhttpd.cxx.

Function Documentation

◆ add_custom_path()

std::string add_custom_path ( const std::string &  filename)

Definition at line 3602 of file mhttpd.cxx.

3603{
3604 // do not append custom path to absolute filenames
3605
3606 if (filename[0] == '/')
3607 return filename;
3608 if (filename[0] == DIR_SEPARATOR)
3609 return filename;
3610
3611 HNDLE hDB;
3613
3614 std::string custom_path = "";
3615
3616 int status = db_get_value_string(hDB, 0, "/Custom/Path", 0, &custom_path, TRUE);
3617
3618 if (status != DB_SUCCESS)
3619 return filename;
3620
3621 if (custom_path.length() < 1)
3622 return filename;
3623
3624 if ((custom_path == DIR_SEPARATOR_STR) || !strchr(custom_path.c_str(), DIR_SEPARATOR)) {
3625 cm_msg(MERROR, "add_custom_path", "ODB /Custom/Path has a forbidden value \"%s\", please change it", custom_path.c_str());
3626 return filename;
3627 }
3628
3629 custom_path = ss_replace_env_variables(custom_path);
3630
3631 std::string full_filename = custom_path;
3632 if (full_filename[full_filename.length()-1] != DIR_SEPARATOR)
3633 full_filename += DIR_SEPARATOR_STR;
3634 full_filename += filename;
3635
3636 return full_filename;
3637}
INT cm_get_experiment_database(HNDLE *hDB, HNDLE *hKeyClient)
Definition midas.cxx:3027
#define DB_SUCCESS
Definition midas.h:632
#define MERROR
Definition midas.h:559
std::string ss_replace_env_variables(const std::string &inputPath)
Definition system.cxx:2284
INT cm_msg(INT message_type, const char *filename, INT line, const char *routine, const char *format,...)
Definition midas.cxx:931
INT EXPRT db_get_value_string(HNDLE hdb, HNDLE hKeyRoot, const char *key_name, int index, std::string *s, BOOL create, int create_string_length)
Definition odb.cxx:13967
HNDLE hDB
main ODB handle
Definition mana.cxx:207
#define DIR_SEPARATOR
Definition midas.h:193
INT HNDLE
Definition midas.h:132
#define DIR_SEPARATOR_STR
Definition midas.h:194
#define TRUE
Definition midas.h:182
DWORD status
Definition odbhist.cxx:39
Here is the call graph for this function:
Here is the caller graph for this function:

◆ add_param_to_url()

static std::string add_param_to_url ( const char *  name,
const char *  value 
)
static

Definition at line 9813 of file mhttpd.cxx.

9814{
9815 std::string s;
9816 s += name; // FIXME: should be URI-encoded
9817 s += "=";
9818 s += value; // FIXME: should be URI-encoded
9819 return s;
9820}
#define name(x)
Definition midas_macro.h:24
double value[100]
Definition odbhist.cxx:42
Here is the caller graph for this function:

◆ add_rpc_functions()

static void add_rpc_functions ( )
static

Definition at line 16248 of file mhttpd.cxx.

16249{
16250 mjsonrpc_add_handler("set_http_trace", set_http_trace);
16251 mjsonrpc_add_handler("get_http_trace", get_http_trace);
16252}
void mjsonrpc_add_handler(const char *method, mjsonrpc_handler_t *handler, bool needs_locking)
static MJsonNode * get_http_trace(const MJsonNode *params)
Definition mhttpd.cxx:16221
static MJsonNode * set_http_trace(const MJsonNode *params)
Definition mhttpd.cxx:16234
Here is the call graph for this function:
Here is the caller graph for this function:

◆ AddHistPlotSelectedParam()

static void AddHistPlotSelectedParam ( HistPlot hp,
Param p 
)
static

Definition at line 10410 of file mhttpd.cxx.

10411{
10412 int seln = atoi(p->getparam("seln"));
10413 for (int i=0; i<seln; i++) {
10414 char str[256];
10415 sprintf(str, "sel%d", i);
10416
10417 std::string par = p->getparam(str);
10418 if (par.length() < 1)
10419 continue;
10420
10421 std::string event_name, tag_name;
10422 SplitEventAndTagNames(par, event_name, tag_name);
10423
10424 if (tag_name == "")
10425 continue;
10426
10427 HistVar v;
10428
10429 v.event_name = event_name;
10430 v.tag_name = tag_name;
10431 v.colour = NextHistPlotColour(hp);
10432 v.order = NextHistPlotOrder(hp);
10433
10434 hp.vars.push_back(v);
10435 }
10436}
const char * getparam(const char *param)
Definition mhttpd.cxx:806
INT i
Definition mdump.cxx:32
static void SplitEventAndTagNames(std::string var_name, std::string &event_name, std::string &tag_name)
Definition mhttpd.cxx:10184
static std::string NextHistPlotColour(const HistPlot &hp)
Definition mhttpd.cxx:10149
static int NextHistPlotOrder(const HistPlot &hp)
Definition mhttpd.cxx:10175
char str[256]
Definition odbhist.cxx:33
std::vector< HistVar > vars
Definition mhttpd.cxx:8384
std::string tag_name
Definition mhttpd.cxx:8360
int order
Definition mhttpd.cxx:8365
std::string colour
Definition mhttpd.cxx:8362
std::string event_name
Definition mhttpd.cxx:8359
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_digest_auth()

static std::string check_digest_auth ( struct http_message hm,
Auth auth 
)
static

Definition at line 13925 of file mhttpd.cxx.

13926{
13927 char expected_response[33];
13928
13929 //printf("HereA!\n");
13930
13931 /* Parse "Authorization:" header, fail fast on parse error */
13932 struct mg_str *hdr = mg_get_http_header(hm, "Authorization");
13933
13934 if (!hdr)
13935 return "";
13936
13937 //printf("HereB!\n");
13938
13939 std::string user = find_var_mg(hdr, "username");
13940 std::string cnonce = find_var_mg(hdr, "cnonce");
13941 std::string response = find_var_mg(hdr, "response");
13942 std::string uri = find_var_mg(hdr, "uri");
13943 std::string qop = find_var_mg(hdr, "qop");
13944 std::string nc = find_var_mg(hdr, "nc");
13945 std::string nonce = find_var_mg(hdr, "nonce");
13946
13947 if (user.length()<1) return "";
13948 if (cnonce.length()<1) return "";
13949 if (response.length()<1) return "";
13950 if (uri.length()<1) return "";
13951 if (qop.length()<1) return "";
13952 if (nc.length()<1) return "";
13953 if (nonce.length()<1) return "";
13954
13955 if (xmg_check_nonce(nonce.c_str()) == 0) return "";
13956 //printf("HereB8!\n");
13957
13958 //printf("HereC!\n");
13959
13960 const char* uri_end = strchr(hm->uri.p, ' ');
13961 if (!uri_end) return "";
13962
13963 size_t uri_length = uri_end - hm->uri.p;
13964
13965 if (uri_length != uri.length())
13966 return "";
13967
13968 int cmp = strncmp(hm->uri.p, uri.c_str(), uri_length);
13969
13970 //printf("check URI: message %d %d [%d] authorization [%s]\n", (int)hm->uri.len, uri_length, cmp, uri);
13971
13972 if (cmp != 0)
13973 return "";
13974
13975 for (unsigned i=0; i<auth->passwords.size(); i++) {
13976 AuthEntry* e = &auth->passwords[i];
13977 if (e->username != user)
13978 continue;
13979 if (e->realm != auth->realm)
13980 continue;
13981 const char* f_ha1 = e->password.c_str();
13982 int uri_len = hm->uri.len;
13983 if (hm->uri.p[uri_len] == '?')
13984 uri_len += hm->query_string.len + 1; // "+1" accounts for the "?" character
13985 xmg_mkmd5resp(hm->method.p, hm->method.len,
13986 hm->uri.p, uri_len,
13987 f_ha1, strlen(f_ha1),
13988 nonce.c_str(), nonce.length(),
13989 nc.c_str(), nc.length(),
13990 cnonce.c_str(), cnonce.length(),
13991 qop.c_str(), qop.length(),
13992 expected_response);
13993 int cmp = strcasecmp(response.c_str(), expected_response);
13994 //printf("digest_auth: expected %s, got %s, cmp %d\n", expected_response, response.c_str(), cmp);
13995 if (cmp == 0) {
13996 return e->username;
13997 }
13998 }
13999
14000 return "";
14001}
std::vector< AuthEntry > passwords
Definition mhttpd.cxx:13759
std::string realm
Definition mhttpd.cxx:13757
struct mg_str uri
Definition mongoose6.h:2072
struct mg_str method
Definition mongoose6.h:2071
size_t len
Definition mongoose6.h:1207
struct mg_str query_string
Definition mongoose6.h:2087
struct mg_str * mg_get_http_header(struct http_message *hm, const char *name)
const char * p
Definition mongoose6.h:1206
char response[10000]
Definition melog.cxx:90
static void xmg_mkmd5resp(const char *method, size_t method_len, const char *uri, size_t uri_len, const char *ha1, size_t ha1_len, const char *nonce, size_t nonce_len, const char *nc, size_t nc_len, const char *cnonce, size_t cnonce_len, const char *qop, size_t qop_len, char *resp)
Definition mhttpd.cxx:13787
static int xmg_check_nonce(const char *nonce)
Definition mhttpd.cxx:13808
Definition mhttpd.cxx:13749
static double e(void)
Definition tinyexpr.c:136
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_obsolete_odb()

void check_obsolete_odb ( HNDLE  hDB,
const char *  odb_path 
)

Definition at line 1910 of file mhttpd.cxx.

1911{
1912 HNDLE hKey;
1913 int status = db_find_key(hDB, 0, odb_path, &hKey);
1914 if (status == DB_SUCCESS) {
1915 cm_msg(MERROR, "check_obsolete_odb", "ODB \"%s\" is obsolete, please delete it.", odb_path);
1916 }
1917}
INT db_find_key(HNDLE hDB, HNDLE hKey, const char *key_name, HNDLE *subhKey)
Definition odb.cxx:4256
HNDLE hKey
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_odb_records()

INT check_odb_records ( MVOdb *  odb)

Definition at line 13421 of file mhttpd.cxx.

13422{
13423 HNDLE hDB, hKeyEq, hKey;
13424 RUNINFO_STR(runinfo_str);
13425 int i, status;
13426 KEY key;
13427
13428 /* check /Runinfo structure */
13430 assert(status == DB_SUCCESS);
13431
13432 status = db_check_record(hDB, 0, "/Runinfo", strcomb1(runinfo_str).c_str(), FALSE);
13433 if (status == DB_STRUCT_MISMATCH) {
13434 status = db_check_record(hDB, 0, "/Runinfo", strcomb1(runinfo_str).c_str(), TRUE);
13435 if (status == DB_SUCCESS) {
13436 cm_msg(MINFO, "check_odb_records", "ODB subtree /Runinfo corrected successfully");
13437 } else {
13438 cm_msg(MERROR, "check_odb_records", "Cannot correct ODB subtree /Runinfo, db_check_record() status %d", status);
13439 return 0;
13440 }
13441 } else if (status == DB_NO_KEY) {
13442 cm_msg(MERROR, "check_odb_records", "ODB subtree /Runinfo does not exist");
13443 status = db_create_record(hDB, 0, "/Runinfo", strcomb1(runinfo_str).c_str());
13444 if (status == DB_SUCCESS) {
13445 cm_msg(MINFO, "check_odb_records", "ODB subtree /Runinfo created successfully");
13446 } else {
13447 cm_msg(MERROR, "check_odb_records", "Cannot create ODB subtree /Runinfo, db_create_record() status %d", status);
13448 return 0;
13449 }
13450 } else if (status != DB_SUCCESS) {
13451 cm_msg(MERROR, "check_odb_records", "Cannot correct ODB subtree /Runinfo, db_check_record() status %d", status);
13452 return 0;
13453 }
13454
13455 /* check /Equipment/<name>/Common structures */
13456 if (db_find_key(hDB, 0, "/equipment", &hKeyEq) == DB_SUCCESS) {
13457 for (i = 0 ;; i++) {
13458 db_enum_key(hDB, hKeyEq, i, &hKey);
13459 if (!hKey)
13460 break;
13461 db_get_key(hDB, hKey, &key);
13462
13464 if (status == DB_STRUCT_MISMATCH) {
13466 if (status == DB_SUCCESS) {
13467 cm_msg(MINFO, "check_odb_records", "ODB subtree /Equipment/%s/Common corrected successfully", key.name);
13468 } else {
13469 cm_msg(MERROR, "check_odb_records", "Cannot correct ODB subtree /Equipment/%s/Common, db_check_record() status %d", key.name, status);
13470 }
13471 } else if (status != DB_SUCCESS) {
13472 cm_msg(MERROR, "check_odb_records", "Cannot correct ODB subtree /Equipment/%s/Common, db_check_record() status %d", key.name, status);
13473 }
13474 }
13475 }
13476
13477 return CM_SUCCESS;
13478}
#define FALSE
Definition cfortran.h:309
#define CM_SUCCESS
Definition midas.h:582
#define DB_STRUCT_MISMATCH
Definition midas.h:655
#define DB_NO_KEY
Definition midas.h:643
#define MINFO
Definition midas.h:560
std::string strcomb1(const char **list)
Definition odb.cxx:668
INT db_check_record(HNDLE hDB, HNDLE hKey, const char *keyname, const char *rec_str, BOOL correct)
Definition odb.cxx:13003
INT db_get_key(HNDLE hDB, HNDLE hKey, KEY *key)
Definition odb.cxx:6043
INT db_enum_key(HNDLE hDB, HNDLE hKey, INT idx, HNDLE *subkey_handle)
Definition odb.cxx:5357
INT db_create_record(HNDLE hDB, HNDLE hKey, const char *orig_key_name, const char *init_str)
Definition odb.cxx:12831
KEY key
Definition mdump.cxx:34
#define EQUIPMENT_COMMON_STR
Definition midas.h:1112
#define RUNINFO_STR(_name)
Definition midas.h:1409
Definition midas.h:1027
char name[NAME_LENGTH]
Definition midas.h:1030
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_web_password()

BOOL check_web_password ( Return r,
HNDLE  hDB,
const char *  dec_path,
const char *  password,
const char *  redir 
)

Definition at line 6769 of file mhttpd.cxx.

6770{
6771 HNDLE hkey;
6772 INT size;
6773 char str[256];
6774
6775 /* check for password */
6776 db_find_key(hDB, 0, "/Experiment/Security/Web Password", &hkey);
6777 if (hkey) {
6778 size = sizeof(str);
6779 db_get_data(hDB, hkey, str, &size, TID_STRING);
6780 if (strcmp(password, str) == 0)
6781 return TRUE;
6782
6783 /* show web password page */
6784 r->rsprintf("HTTP/1.1 200 Document follows\r\n");
6785 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
6786 r->rsprintf("Content-Type: text/html; charset=%s\r\n\r\n", HTTP_ENCODING);
6787
6788 r->rsprintf("<html><head>\n");
6789 r->rsprintf("<link rel=\"icon\" href=\"favicon.png\" type=\"image/png\" />\n");
6790 r->rsprintf("<link rel=\"stylesheet\" href=\"midas.css\" type=\"text/css\" />\n");
6791 r->rsprintf("<link rel=\"stylesheet\" href=\"mhttpd.css\" type=\"text/css\" />\n");
6792 r->rsprintf("<title>Enter password</title></head><body>\n\n");
6793
6794 r->rsprintf("<form method=\"GET\" action=\".\">\n\n");
6795
6796 /* define hidden fields for current experiment and destination */
6797 if (redir[0])
6798 r->rsprintf("<input type=hidden name=redir value=\"%s\">\n", redir);
6799
6800 /*---- page header ----*/
6801 r->rsprintf("<table class=\"headerTable\"><tr><td></td><tr></table>\n");
6802
6803 r->rsprintf("<table class=\"dialogTable\">\n"); //main table
6804
6805 if (password[0])
6806 r->rsprintf("<tr><th class=\"redLight\">Wrong password!</tr>\n");
6807
6808 r->rsprintf
6809 ("<tr><th>Please enter password to obtain write access</tr>\n");
6810 r->rsprintf("<tr><td align=center><input type=password name=wpwd></tr>\n");
6811 r->rsprintf("<tr><td align=center><input type=submit value=Submit></tr>");
6812
6813 r->rsprintf("</table>\n");
6814
6815 r->rsprintf("</div>\n"); // closing for <div id="mmain">
6816 r->rsprintf("</form>\n");
6817 r->rsprintf("</body></html>\r\n");
6818
6819 return FALSE;
6820 } else
6821 return TRUE;
6822}
void rsprintf(const char *format,...) MATTRPRINTF(2
#define TID_STRING
Definition midas.h:346
INT db_get_data(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, DWORD type)
Definition odb.cxx:6563
#define HTTP_ENCODING
Definition mhttpd.cxx:213
const char * mhttpd_revision(void)
Definition mhttpd.cxx:866
int INT
Definition midas.h:129
Here is the call graph for this function:
Here is the caller graph for this function:

◆ cmp_events()

const bool cmp_events ( const std::string &  a,
const std::string &  b 
)

Definition at line 10066 of file mhttpd.cxx.

10067{
10068 return cmp_names(a.c_str(), b.c_str()) < 0;
10069}
static int cmp_names(const void *a, const void *b)
Definition mhttpd.cxx:10008
Here is the call graph for this function:

◆ cmp_events1()

const bool cmp_events1 ( const std::string &  a,
const std::string &  b 
)

Definition at line 10071 of file mhttpd.cxx.

10072{
10073 return a < b;
10074}
Here is the caller graph for this function:

◆ cmp_names()

static int cmp_names ( const void *  a,
const void *  b 
)
static

Definition at line 10008 of file mhttpd.cxx.

10009{
10010 int i;
10011 const char*sa = (const char*)a;
10012 const char*sb = (const char*)b;
10013
10014 int debug = 0;
10015
10016 // Cannot use strcmp() because it does not know how to compare numerical values, e.g.
10017 // it thinks "111" is smaller than "9"
10018 //return strcmp(sa, sb);
10019
10020 if (debug)
10021 printf("compare [%s] and [%s]\n", sa, sb);
10022
10023 for (i=0; ; i++) {
10024 if (sa[i]==0 && sb[i]==0)
10025 return 0; // both strings have the same length and the same characters
10026
10027 //printf("index %d, char [%c] [%c], isdigit %d %d\n", i, sa[i], sb[i], isdigit(sa[i]), isdigit(sb[i]));
10028
10029 if (isdigit(sa[i]) && isdigit(sb[i])) {
10030 int va = atoi(sa+i);
10031 int vb = atoi(sb+i);
10032
10033 if (debug)
10034 printf("index %d, values %d %d\n", i, va, vb);
10035
10036 if (va < vb)
10037 return -1;
10038 else if (va > vb)
10039 return 1;
10040
10041 // values are equal, skip the the end of the digits, compare any trailing text
10042 continue;
10043 }
10044
10045 if (sa[i]==sb[i]) {
10046 continue;
10047 }
10048
10049 if (debug)
10050 printf("index %d, char [%c] [%c]\n", i, sa[i], sb[i]);
10051
10052 if (sa[i] == 0) // string sa is shorter
10053 return -1;
10054 else if (sb[i] == 0) // string sb is shorter
10055 return 1;
10056
10057 if (sa[i]<sb[i])
10058 return -1;
10059 else
10060 return 1;
10061 }
10062
10063 // NOT REACHED
10064}
BOOL debug
debug printouts
Definition mana.cxx:254
Here is the caller graph for this function:

◆ cmp_tags()

const bool cmp_tags ( const TAG a,
const TAG b 
)

Definition at line 10076 of file mhttpd.cxx.

10077{
10078 return cmp_names(a.name, b.name) < 0;
10079}
char name[NAME_LENGTH]
Definition midas.h:1234
Here is the call graph for this function:
Here is the caller graph for this function:

◆ cmp_vars()

static bool cmp_vars ( const HistVar a,
const HistVar b 
)
static

Definition at line 10134 of file mhttpd.cxx.

10135{
10136 return a.order < b.order;
10137}
Here is the caller graph for this function:

◆ ctrlc_handler()

void ctrlc_handler ( int  sig)

Definition at line 13485 of file mhttpd.cxx.

13486{
13487 _abort = true;
13488}
std::atomic_bool _abort
Definition mhttpd.cxx:13483
Here is the caller graph for this function:

◆ decode_cookies()

void decode_cookies ( Cookies c,
const http_message msg 
)

Definition at line 14239 of file mhttpd.cxx.

14240{
14241 // extract password cookies
14242
14243 char cookie_pwd[256]; // general access password
14244 char cookie_wpwd[256]; // "write mode" password
14245 char cookie_cpwd[256]; // custom page and javascript password
14246
14247 cookie_pwd[0] = 0;
14248 cookie_wpwd[0] = 0;
14249 cookie_cpwd[0] = 0;
14250
14251 std::string s = find_cookie_mg(msg, "midas_pwd");
14252 if (s.length() > 0) {
14253 mstrlcpy(cookie_pwd, s.c_str(), sizeof(cookie_pwd));
14254 cookie_pwd[strcspn(cookie_pwd, " ;\r\n")] = 0;
14255 }
14256
14257 s = find_cookie_mg(msg, "midas_wpwd");
14258 if (s.length()) {
14259 mstrlcpy(cookie_wpwd, s.c_str(), sizeof(cookie_pwd));
14260 cookie_wpwd[strcspn(cookie_wpwd, " ;\r\n")] = 0;
14261 }
14262
14263 s = find_cookie_mg(msg, "cpwd");
14264 if (s.length()) {
14265 mstrlcpy(cookie_cpwd, s.c_str(), sizeof(cookie_pwd));
14266 cookie_cpwd[strcspn(cookie_cpwd, " ;\r\n")] = 0;
14267 }
14268
14269 // extract refresh rate
14270 c->refresh = DEFAULT_REFRESH;
14271 s = find_cookie_mg(msg, "midas_refr");
14272 if (s.length() > 0)
14273 c->refresh = atoi(s.c_str());
14274
14275 // extract equipment expand flag
14276 //c->expand_equipment = 0;
14277 //s = find_cookie_mg(msg, "midas_expeq");
14278 //if (s.length() > 0)
14279 // c->expand_equipment = atoi(s.c_str());
14280
14281 c->cookie_pwd = cookie_pwd;
14282 c->cookie_wpwd = cookie_wpwd;
14283 c->cookie_cpwd = cookie_cpwd;
14284}
#define DEFAULT_REFRESH
Definition mhttpd.cxx:39
static const std::string find_cookie_mg(const struct http_message *msg, const char *cookie_name)
Definition mhttpd.cxx:14187
char c
Definition system.cxx:1312
Here is the call graph for this function:
Here is the caller graph for this function:

◆ decode_get()

void decode_get ( Return rr,
char *  string,
const Cookies c,
const char *  url,
const char *  query_string,
RequestTrace t 
)

Definition at line 13227 of file mhttpd.cxx.

13228{
13229 char path[256];
13230
13231 //printf("decode_get: string [%s], decode_url %d, url [%s], query_string [%s]\n", string, decode_url, url, query_string);
13232
13233 Param* param = new Param();
13234
13235 param->initparam();
13236
13237 if (url)
13238 mstrlcpy(path, url + 1, sizeof(path)); /* strip leading '/' */
13239 else {
13240 mstrlcpy(path, string + 1, sizeof(path)); /* strip leading '/' */
13241
13242 if (strchr(path, '?'))
13243 *strchr(path, '?') = 0;
13244 }
13245
13246 param->setparam("path", path);
13247
13248 assert(query_string != NULL);
13249
13250 decode_query(param, query_string);
13251
13252 param->setparam("query", query_string);
13253
13254 char dec_path[256];
13255 mstrlcpy(dec_path, path, sizeof(dec_path));
13256
13257 interprete(param, rr, NULL, c, dec_path, t);
13258
13259 param->freeparam();
13260 delete param;
13261}
char param[10][256]
Definition mana.cxx:250
void decode_query(Param *pp, const char *query_string)
Definition mhttpd.cxx:13202
void interprete(Param *p, Return *r, Attachment *a, const Cookies *c, const char *dec_path, RequestTrace *t)
Definition mhttpd.cxx:12283
Here is the call graph for this function:
Here is the caller graph for this function:

◆ decode_post()

void decode_post ( Return rr,
const char *  header,
const char *  string,
const char *  boundary,
int  length,
const Cookies c,
const char *  url,
RequestTrace t 
)

Definition at line 13265 of file mhttpd.cxx.

13266{
13267 bool debug_decode_post = false;
13268
13269 Param* param = new Param;
13270
13271 param->initparam();
13272
13273 char path[256];
13274
13275 if (url)
13276 mstrlcpy(path, url + 1, sizeof(path)); /* strip leading '/' */
13277 else {
13278 mstrlcpy(path, header + 1, sizeof(path)); /* strip leading '/' */
13279 if (strchr(path, '?'))
13280 *strchr(path, '?') = 0;
13281 if (strchr(path, ' '))
13282 *strchr(path, ' ') = 0;
13283 }
13284 param->setparam("path", path); // undecoded path
13285
13286 Attachment* a = new Attachment;
13287
13288 const char* pinit = string;
13289
13290 /* return if no boundary defined */
13291 if (!boundary[0])
13292 return;
13293
13294 if (strstr(string, boundary))
13295 string = strstr(string, boundary) + strlen(boundary);
13296
13297 if (debug_decode_post)
13298 printf("decode_post: -->[%s]<--\n", string);
13299
13300 do {
13301 //printf("decode_post: [%s]\n", string);
13302 if (strstr(string, "name=")) {
13303 const char* pitem = strstr(string, "name=") + 5;
13304 if (*pitem == '\"')
13305 pitem++;
13306
13307 //printf("decode_post: pitem [%s]\n", pitem);
13308
13309 if (strncmp(pitem, "attfile", 7) == 0) {
13310 int n = pitem[7] - '1';
13311
13312 char file_name[256];
13313 file_name[0] = 0;
13314
13315 /* evaluate file attachment */
13316 if (strstr(pitem, "filename=")) {
13317 const char* p = strstr(pitem, "filename=") + 9;
13318 if (*p == '\"')
13319 p++;
13320 if (strstr(p, "\r\n\r\n"))
13321 string = strstr(p, "\r\n\r\n") + 4;
13322 else if (strstr(p, "\r\r\n\r\r\n"))
13323 string = strstr(p, "\r\r\n\r\r\n") + 6;
13324
13325 mstrlcpy(file_name, p, sizeof(file_name));
13326
13327 char* pp = file_name;
13328 if (strchr(pp, '\"'))
13329 *strchr(pp, '\"') = 0;
13330
13331 /* set attachment filename */
13332 char str[256];
13333 sprintf(str, "attachment%d", n);
13334 if (debug_decode_post)
13335 printf("decode_post: [%s] = [%s]\n", str, file_name);
13336 param->setparam(str, file_name); // file_name should be decoded?
13337 }
13338
13339 /* find next boundary */
13340 const char* ptmp = string;
13341 const char* p = NULL;
13342 do {
13343 while (*ptmp != '-')
13344 ptmp++;
13345
13346 p = strstr(ptmp, boundary);
13347 if (p != NULL) {
13348 while (*p == '-')
13349 p--;
13350 if (*p == 10)
13351 p--;
13352 if (*p == 13)
13353 p--;
13354 p++;
13355 break;
13356 } else
13357 ptmp += strlen(ptmp);
13358
13359 } while (TRUE);
13360
13361 /* save pointer to file */
13362 if (file_name[0]) {
13363 size_t size = (POINTER_T) p - (POINTER_T) string;
13364 char* buf = (char*)malloc(size+1);
13365 if (!buf) {
13366 return;
13367 }
13368 memcpy(buf, string, size);
13369 buf[size] = 0; // make sure string is NUL terminated
13370 a->attachment_buffer[n] = buf;
13371 a->attachment_size[n] = size;
13372 if (debug_decode_post)
13373 printf("decode_post: attachment[%d] size %d data --->[%s]<---\n", n, (int)a->attachment_size[n], a->attachment_buffer[n]);
13374 }
13375
13376 string = strstr(p, boundary) + strlen(boundary);
13377 } else {
13378 const char* p = pitem;
13379 if (strstr(p, "\r\n\r\n"))
13380 p = strstr(p, "\r\n\r\n") + 4;
13381 else if (strstr(p, "\r\r\n\r\r\n"))
13382 p = strstr(p, "\r\r\n\r\r\n") + 6;
13383
13384 char* ppitem = (char*)strchr(pitem, '\"'); // NB: defeat "const char* string"
13385 if (ppitem)
13386 *ppitem = 0;
13387
13388 char* pb = (char*)(strstr(p, boundary)); // NB: defeat "const char* string"
13389 if (pb) {
13390 string = pb + strlen(boundary);
13391 *pb = 0;
13392 char* ptmp = (char*)(p + (strlen(p) - 1)); // NB: defeat "const char* string"
13393 while (*ptmp == '-' || *ptmp == '\n' || *ptmp == '\r')
13394 *ptmp-- = 0;
13395 } else {
13396 show_error(rr, "Invalid POST request");
13397 return;
13398 }
13399 if (debug_decode_post)
13400 printf("decode_post: [%s] = [%s]\n", pitem, p);
13401 param->setparam(pitem, p); // in decode_post()
13402 }
13403
13404 while (*string == '-' || *string == '\n' || *string == '\r')
13405 string++;
13406 }
13407
13408 } while ((POINTER_T) string - (POINTER_T) pinit < length);
13409
13410 char dec_path[256];
13411 mstrlcpy(dec_path, path, sizeof(dec_path));
13412
13413 interprete(param, rr, a, c, dec_path, t);
13414
13415 delete a;
13416 delete param;
13417}
char * attachment_buffer[3]
Definition mhttpd.cxx:69
size_t attachment_size[3]
Definition mhttpd.cxx:70
void initparam()
Definition mhttpd.cxx:749
DWORD n[4]
Definition mana.cxx:247
void show_error(Return *r, const char *error)
Definition mhttpd.cxx:1868
#define POINTER_T
Definition midas.h:166
char file_name[256]
Definition odbhist.cxx:41
Here is the call graph for this function:
Here is the caller graph for this function:

◆ decode_query()

void decode_query ( Param pp,
const char *  query_string 
)

Definition at line 13202 of file mhttpd.cxx.

13203{
13204 int len = strlen(query_string);
13205 char *buf = (char *)malloc(len+1);
13206 assert(buf != NULL);
13207 memcpy(buf, query_string, len+1);
13208 char* p = buf;
13209 p = strtok(p, "&");
13210 while (p != NULL) {
13211 char *pitem = p;
13212 p = strchr(p, '=');
13213 if (p != NULL) {
13214 *p++ = 0;
13215 urlDecode(pitem); // parameter name
13216 if (!equal_ustring(pitem, "format"))
13217 urlDecode(p); // parameter value
13218
13219 pp->setparam(pitem, p); // decoded query parameters
13220
13221 p = strtok(NULL, "&");
13222 }
13223 }
13224 free(buf);
13225}
void setparam(const char *param, const char *value)
Definition mhttpd.cxx:756
BOOL equal_ustring(const char *str1, const char *str2)
Definition odb.cxx:3285
static void urlDecode(char *p)
Definition mhttpd.cxx:912
Here is the call graph for this function:
Here is the caller graph for this function:

◆ DeleteHistPlotDeleted()

static void DeleteHistPlotDeleted ( HistPlot hp)
static

Definition at line 10514 of file mhttpd.cxx.

10515{
10516 /* delete variables according to "hist_order" */
10517
10518 while (1) {
10519 bool something_deleted = false;
10520 for (unsigned i=0; i<hp.vars.size(); i++) {
10521 if (hp.vars[i].order <= 0) {
10522 hp.vars.erase(hp.vars.begin() + i);
10523 something_deleted = true;
10524 }
10525 }
10526 if (!something_deleted)
10527 break;
10528 }
10529}
Here is the caller graph for this function:

◆ do_jrpc()

void do_jrpc ( Param p,
Return r 
)

Definition at line 4352 of file mhttpd.cxx.

4353{
4354 int status;
4355
4356 const char *name = p->getparam("name");
4357 const char *cmd = p->getparam("rcmd");
4358 const char *args = p->getparam("rarg");
4359
4360 if (!name || !cmd || !args) {
4362 r->rsprintf("<INVALID_ARGUMENTS>");
4363 return;
4364 }
4365
4367
4368 int buf_length = 1024;
4369
4370 int max_reply_length = atoi(p->getparam("max_reply_length"));
4371 if (max_reply_length > buf_length)
4372 buf_length = max_reply_length;
4373
4374 char* buf = (char*)malloc(buf_length);
4375 assert(buf != NULL);
4376
4377 buf[0] = 0;
4378
4379 HNDLE hconn;
4380
4381 status = cm_connect_client(name, &hconn);
4382
4383 if (status != RPC_SUCCESS) {
4384 r->rsprintf("<RPC_CONNECT_ERROR>%d</RPC_CONNECT_ERROR>", status);
4385 free(buf);
4386 return;
4387 }
4388
4389 status = rpc_client_call(hconn, RPC_JRPC, cmd, args, buf, buf_length);
4390
4391 if (status != RPC_SUCCESS) {
4392 r->rsprintf("<RPC_CALL_ERROR>%d</RPC_CALL_ERROR>", status);
4393 free(buf);
4394 return;
4395 }
4396
4397 r->rsprintf("%s", buf);
4398
4399 //status = cm_disconnect_client(hconn, FALSE);
4400
4401 free(buf);
4402}
INT cm_connect_client(const char *client_name, HNDLE *hConn)
Definition midas.cxx:2782
#define RPC_SUCCESS
Definition midas.h:699
INT rpc_client_call(HNDLE hConn, DWORD routine_id,...)
Definition midas.cxx:13926
#define RPC_JRPC
Definition mrpc.h:134
void show_text_header(Return *r)
Definition mhttpd.cxx:1856
Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_jrpc_rev0()

void do_jrpc_rev0 ( Param p,
Return r 
)

Definition at line 4046 of file mhttpd.cxx.

4047{
4048 static RPC_LIST rpc_list[] = {
4049 { 9999, "mhttpd_jrpc_rev0", {
4050 {TID_STRING, RPC_IN}, // arg0
4051 {TID_STRING, RPC_IN}, // arg1
4052 {TID_STRING, RPC_IN}, // arg2
4053 {TID_STRING, RPC_IN}, // arg3
4054 {TID_STRING, RPC_IN}, // arg4
4055 {TID_STRING, RPC_IN}, // arg5
4056 {TID_STRING, RPC_IN}, // arg6
4057 {TID_STRING, RPC_IN}, // arg7
4058 {TID_STRING, RPC_IN}, // arg8
4059 {TID_STRING, RPC_IN}, // arg9
4060 {0}} },
4061 { 0 }
4062 };
4063
4064 int count = 0, substring = 0, rpc;
4065
4066 const char *xname = p->getparam("name");
4067 const char *srpc = p->getparam("rpc");
4068
4069 if (!srpc || !xname) {
4071 r->rsprintf("<INVALID_ARGUMENTS>");
4072 return;
4073 }
4074
4075 char sname[256];
4076 mstrlcpy(sname, xname, sizeof(sname));
4077
4078 if (sname[strlen(sname)-1]=='*') {
4079 sname[strlen(sname)-1] = 0;
4080 substring = 1;
4081 }
4082
4083 rpc = atoi(srpc);
4084
4085 if (rpc<RPC_MIN_ID || rpc>RPC_MAX_ID) {
4087 r->rsprintf("<INVALID_RPC_ID>");
4088 return;
4089 }
4090
4091 rpc_list[0].id = rpc;
4093
4095 r->rsprintf("calling rpc %d | ", rpc);
4096
4097 if (1) {
4098 int status, i;
4099 char str[256];
4100 HNDLE hDB, hrootkey, hsubkey, hkey;
4101
4103
4104 /* find client which exports FCNA function */
4105 status = db_find_key(hDB, 0, "System/Clients", &hrootkey);
4106 if (status == DB_SUCCESS) {
4107 for (i=0; ; i++) {
4108 status = db_enum_key(hDB, hrootkey, i, &hsubkey);
4110 break;
4111
4112 sprintf(str, "RPC/%d", rpc);
4113 status = db_find_key(hDB, hsubkey, str, &hkey);
4114 if (status == DB_SUCCESS) {
4115 char client_name[NAME_LENGTH];
4116 HNDLE hconn;
4117 int size;
4118
4119 size = sizeof(client_name);
4120 status = db_get_value(hDB, hsubkey, "Name", client_name, &size, TID_STRING, FALSE);
4121 if (status != DB_SUCCESS)
4122 continue;
4123
4124 if (strlen(sname) > 0) {
4125 if (substring) {
4126 if (strstr(client_name, sname) != client_name)
4127 continue;
4128 } else {
4129 if (strcmp(sname, client_name) != 0)
4130 continue;
4131 }
4132 }
4133
4134 count++;
4135
4136 r->rsprintf("client %s", client_name);
4137
4138 status = cm_connect_client(client_name, &hconn);
4139 r->rsprintf(" %d", status);
4140
4141 if (status == RPC_SUCCESS) {
4142 status = rpc_client_call(hconn, rpc,
4143 p->getparam("arg0"),
4144 p->getparam("arg1"),
4145 p->getparam("arg2"),
4146 p->getparam("arg3"),
4147 p->getparam("arg4"),
4148 p->getparam("arg5"),
4149 p->getparam("arg6"),
4150 p->getparam("arg7"),
4151 p->getparam("arg8"),
4152 p->getparam("arg9")
4153 );
4154 r->rsprintf(" %d", status);
4155
4156 //status = cm_disconnect_client(hconn, FALSE);
4157 r->rsprintf(" %d", status);
4158 }
4159
4160 r->rsprintf(" | ");
4161 }
4162 }
4163 }
4164 }
4165
4166 r->rsprintf("rpc %d, called %d clients\n", rpc, count);
4167}
#define DB_NO_MORE_SUBKEYS
Definition midas.h:647
INT db_get_value(HNDLE hDB, HNDLE hKeyRoot, const char *key_name, void *data, INT *buf_size, DWORD type, BOOL create)
Definition odb.cxx:5185
INT rpc_register_functions(const RPC_LIST *new_list, RPC_HANDLER func)
Definition midas.cxx:11958
static std::vector< RPC_LIST > rpc_list
Definition midas.cxx:11704
double count
Definition mdump.cxx:33
#define RPC_IN
Definition midas.h:1563
#define RPC_MAX_ID
Definition midas.h:1591
#define NAME_LENGTH
Definition midas.h:272
Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_jrpc_rev1()

void do_jrpc_rev1 ( Param p,
Return r 
)

Definition at line 4171 of file mhttpd.cxx.

4172{
4173 static RPC_LIST rpc_list[] = {
4174 { 9998, "mhttpd_jrpc_rev1", {
4175 {TID_STRING, RPC_OUT}, // return string
4176 {TID_INT, RPC_IN}, // return string max length
4177 {TID_STRING, RPC_IN}, // arg0
4178 {TID_STRING, RPC_IN}, // arg1
4179 {TID_STRING, RPC_IN}, // arg2
4180 {TID_STRING, RPC_IN}, // arg3
4181 {TID_STRING, RPC_IN}, // arg4
4182 {TID_STRING, RPC_IN}, // arg5
4183 {TID_STRING, RPC_IN}, // arg6
4184 {TID_STRING, RPC_IN}, // arg7
4185 {TID_STRING, RPC_IN}, // arg8
4186 {TID_STRING, RPC_IN}, // arg9
4187 {0}} },
4188 { 0 }
4189 };
4190
4191 int status, substring = 0, rpc;
4192
4193 const char *xname = p->getparam("name");
4194 const char *srpc = p->getparam("rpc");
4195
4196 if (!srpc || !xname) {
4198 r->rsprintf("<INVALID_ARGUMENTS>");
4199 return;
4200 }
4201
4202 char sname[256];
4203 mstrlcpy(sname, xname, sizeof(sname));
4204
4205 if (sname[strlen(sname)-1]=='*') {
4206 sname[strlen(sname)-1] = 0;
4207 substring = 1;
4208 }
4209
4210 rpc = atoi(srpc);
4211
4212 if (rpc<RPC_MIN_ID || rpc>RPC_MAX_ID) {
4214 r->rsprintf("<INVALID_RPC_ID>");
4215 return;
4216 }
4217
4218 rpc_list[0].id = rpc;
4220
4221 //printf("cm_register_functions() for format \'%s\' status %d\n", sformat, status);
4222
4224
4225 std::string reply_header;
4226 std::string reply_body;
4227
4228 //r->rsprintf("<?xml version=\"1.0\" encoding=\"%s\"?>\n", HTTP_ENCODING);
4229 //r->rsprintf("<!-- created by MHTTPD on (timestamp) -->\n");
4230 //r->rsprintf("<jrpc_rev1>\n");
4231 //r->rsprintf(" <rpc>%d</rpc>\n", rpc);
4232
4233 if (1) {
4234 HNDLE hDB, hrootkey, hsubkey, hkey;
4235
4237
4238 int buf_length = 1024;
4239
4240 int max_reply_length = atoi(p->getparam("max_reply_length"));
4241 if (max_reply_length > buf_length)
4242 buf_length = max_reply_length;
4243
4244 char* buf = (char*)malloc(buf_length);
4245
4246 assert(buf != NULL);
4247
4248 /* find client which exports our RPC function */
4249 status = db_find_key(hDB, 0, "System/Clients", &hrootkey);
4250 if (status == DB_SUCCESS) {
4251 for (int i=0; ; i++) {
4252 status = db_enum_key(hDB, hrootkey, i, &hsubkey);
4254 break;
4255
4256 char str[256];
4257 sprintf(str, "RPC/%d", rpc);
4258 status = db_find_key(hDB, hsubkey, str, &hkey);
4259 if (status == DB_SUCCESS) {
4260 char client_name[NAME_LENGTH];
4261 HNDLE hconn;
4262 int size;
4263
4264 size = sizeof(client_name);
4265 status = db_get_value(hDB, hsubkey, "Name", client_name, &size, TID_STRING, FALSE);
4266 if (status != DB_SUCCESS)
4267 continue;
4268
4269 if (strlen(sname) > 0) {
4270 if (substring) {
4271 if (strstr(client_name, sname) != client_name)
4272 continue;
4273 } else {
4274 if (strcmp(sname, client_name) != 0)
4275 continue;
4276 }
4277 }
4278
4279 //r->rsprintf(" <client>\n");
4280 //r->rsprintf(" <name>%s</name>\n", client_name);
4281
4282 int connect_status = -1;
4283 int call_status = -1;
4284 int call_length = 0;
4285 int disconnect_status = -1;
4286
4287 connect_status = cm_connect_client(client_name, &hconn);
4288
4289 //r->rsprintf(" <connect_status>%d</connect_status>\n", status);
4290
4291 if (connect_status == RPC_SUCCESS) {
4292 buf[0] = 0;
4293
4294 call_status = rpc_client_call(hconn, rpc,
4295 buf,
4296 buf_length,
4297 p->getparam("arg0"),
4298 p->getparam("arg1"),
4299 p->getparam("arg2"),
4300 p->getparam("arg3"),
4301 p->getparam("arg4"),
4302 p->getparam("arg5"),
4303 p->getparam("arg6"),
4304 p->getparam("arg7"),
4305 p->getparam("arg8"),
4306 p->getparam("arg9")
4307 );
4308
4309 //r->rsprintf(" <rpc_status>%d</rpc_status>\n", status);
4311 //r->rsputs("<data>");
4312 //r->rsputs(buf);
4313 //r->rsputs("</data>\n");
4314
4315 if (call_status == RPC_SUCCESS) {
4316 call_length = strlen(buf);
4317 reply_body += buf;
4318 }
4319
4320 //disconnect_status = cm_disconnect_client(hconn, FALSE);
4321 //r->rsprintf(" <disconnect_status>%d</disconnect_status>\n", status);
4322 }
4323
4324 //r->rsprintf(" </client>\n");
4325
4326 if (reply_header.length() > 0)
4327 reply_header += " | ";
4328
4329 char tmp[256];
4330 sprintf(tmp, "%s %d %d %d %d", client_name, connect_status, call_status, disconnect_status, call_length);
4331 reply_header += tmp;
4332 }
4333 }
4334 }
4335
4336 free(buf);
4337 }
4338
4339 //r->rsprintf(" <called_clients>%d</called_clients>\n", count);
4340 //r->rsprintf("</jrpc_rev1>\n");
4341
4342 if (reply_header.length() > 0) {
4343 r->rsputs(reply_header.c_str());
4344 r->rsputs(" || ");
4345 r->rsputs(reply_body.c_str());
4346 r->rsputs("\n");
4347 }
4348}
void rsputs(const char *str)
Definition mhttpd.cxx:632
#define TID_INT
Definition midas.h:338
#define RPC_OUT
Definition midas.h:1564
Here is the call graph for this function:
Here is the caller graph for this function:

◆ evaluate_src()

int evaluate_src ( char *  key,
char *  src,
double *  fvalue 
)

Definition at line 3529 of file mhttpd.cxx.

3530{
3531 HNDLE hDB, hkeyval;
3532 KEY vkey;
3533 int i, n, size, ivalue;
3534 char str[256], data[256];
3535
3537
3538 /* separate source from operators */
3539 for (i=0 ; i<(int)strlen(src) ; i++)
3540 if (src[i] == '>' || src[i] == '&')
3541 break;
3542 strncpy(str, src, i);
3543 str[i] = 0;
3544
3545 /* strip trailing blanks */
3546 while (strlen(str) > 0 && str[strlen(str)-1] == ' ')
3547 str[strlen(str)-1] = 0;
3548
3549 db_find_key(hDB, 0, str, &hkeyval);
3550 if (!hkeyval) {
3551 cm_msg(MERROR, "evaluate_src", "Invalid Src key \"%s\" for Fill \"%s\"",
3552 src, key);
3553 return 0;
3554 }
3555
3556 db_get_key(hDB, hkeyval, &vkey);
3557 size = sizeof(data);
3558 db_get_value(hDB, 0, src, data, &size, vkey.type, FALSE);
3559 std::string value = db_sprintf(data, size, 0, vkey.type);
3560 if (equal_ustring(value.c_str(), "NAN"))
3561 return 0;
3562
3563 if (vkey.type == TID_BOOL) {
3564 *fvalue = (value[0] == 'y');
3565 } else
3566 *fvalue = atof(value.c_str());
3567
3568 /* evaluate possible operators */
3569 do {
3570 if (src[i] == '>' && src[i+1] == '>') {
3571 i+=2;
3572 n = atoi(src+i);
3573 while (src[i] == ' ' || isdigit(src[i]))
3574 i++;
3575 ivalue = (int)*fvalue;
3576 ivalue >>= n;
3577 *fvalue = ivalue;
3578 }
3579
3580 if (src[i] == '&') {
3581 i+=1;
3582 while (src[i] == ' ')
3583 i++;
3584 if (src[i] == '0' && src[i+1] == 'x')
3585 sscanf(src+2+i, "%x", &n);
3586 else
3587 n = atoi(src+i);
3588 while (src[i] == ' ' || isxdigit(src[i]) || src[i] == 'x')
3589 i++;
3590 ivalue = (int)*fvalue;
3591 ivalue &= n;
3592 *fvalue = ivalue;
3593 }
3594
3595 } while (src[i]);
3596
3597 return 1;
3598}
#define TID_BOOL
Definition midas.h:340
INT db_sprintf(char *string, const void *data, INT data_size, INT idx, DWORD type)
Definition odb.cxx:10865
void * data
Definition mana.cxx:268
DWORD type
Definition midas.h:1028
Here is the call graph for this function:
Here is the caller graph for this function:

◆ export_hist()

void export_hist ( MVOdb *  odb,
Return r,
const char *  group,
const char *  panel,
time_t  endtime,
int  scale,
int  index,
int  labels 
)

Definition at line 11058 of file mhttpd.cxx.

11059{
11060 //HNDLE hDB, hkey, hkeypanel;
11061 //int size;
11062 int status;
11063 //char str[256];
11064
11065 int debug = 0;
11066
11067 ss_tzset(); // required for localtime_r()
11068
11069#if 0
11071
11072 /* check panel name in ODB */
11073 sprintf(str, "/History/Display/%s/%s", group, panel);
11074 db_find_key(hDB, 0, str, &hkeypanel);
11075 if (!hkeypanel) {
11076 sprintf(str, "Cannot find /History/Display/%s/%s in ODB\n", group, panel);
11077 show_error(r, str);
11078 return;
11079 }
11080
11081 /* get runmarker flag */
11082 BOOL runmarker = 1;
11083 size = sizeof(runmarker);
11084 db_get_value(hDB, hkeypanel, "Show run markers", &runmarker, &size, TID_BOOL, TRUE);
11085
11086 if (scale == 0) {
11087 /* get timescale */
11088 std::string ts = "1h";
11089 status = db_get_value_string(hDB, hkeypanel, "Timescale", 0, &ts, TRUE);
11090 if (status != DB_SUCCESS) {
11091 /* delete old integer key */
11092 db_delete(hDB, hkeypanel, "Timescale");
11093
11094 ts = "1h";
11095 status = db_get_value_string(hDB, hkeypanel, "Timescale", 0, &ts, TRUE);
11096 }
11097
11098 scale = time_to_sec(ts.c_str());
11099 }
11100#endif
11101
11102 time_t now = ss_time();
11103
11104 if (endtime == 0)
11105 endtime = now;
11106
11107 HistoryData hsxxx;
11108 HistoryData* hsdata = &hsxxx;
11109
11110 HistPlot hp;
11111 LoadHistPlotFromOdb(odb, &hp, group, panel);
11112
11113 time_t starttime = endtime - scale;
11114
11115 //printf("start %.0f, end %.0f, scale %.0f\n", (double)starttime, (double)endtime, (double)scale);
11116
11117 status = read_history(hp, /*hDB, group, panel,*/ index, hp.show_run_markers, starttime, endtime, 0, hsdata);
11118 if (status != HS_SUCCESS) {
11119 char str[256];
11120 sprintf(str, "History error, status %d\n", status);
11121 show_error(r, str);
11122 return;
11123 }
11124
11125 if (debug)
11126 hsdata->Print();
11127
11128 int *i_var = (int *)malloc(sizeof(int)*hsdata->nvars);
11129
11130 assert(i_var != NULL);
11131
11132 for (int i = 0; i < hsdata->nvars; i++)
11133 i_var[i] = -1;
11134
11135 time_t t = 0;
11136
11137 /* find first time where all variables are available */
11138 for (int i = 0; i < hsdata->nvars; i++)
11139 if (hsdata->odb_index[i] >= 0)
11140 if (hsdata->num_entries[i] > 0)
11141 if ((t == 0) || (hsdata->t[i][0] > t))
11142 t = hsdata->t[i][0];
11143
11144 if (t == 0 && hsdata->nvars > 1) {
11145 show_error(r, "No history available for choosen period");
11146 free(i_var);
11147 return;
11148 }
11149
11150 int run_index = -1;
11151 int state_index = -1;
11152 int n_run_number = 0;
11153 time_t* t_run_number = NULL;
11154 if (hp.show_run_markers)
11155 for (int i = 0; i < hsdata->nvars; i++) {
11156 if (hsdata->odb_index[i] == -2) {
11157 n_run_number = hsdata->num_entries[i];
11158 t_run_number = hsdata->t[i];
11159 run_index = i;
11160 } else if (hsdata->odb_index[i] == -1) {
11161 state_index = i;
11162 }
11163 }
11164
11165 //printf("runmarker %d, state %d, run %d\n", runmarker, state_index, run_index);
11166
11167 /* header */
11168 r->rsprintf("HTTP/1.1 200 Document follows\r\n");
11169 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
11170 r->rsprintf("Accept-Ranges: bytes\r\n");
11171 r->rsprintf("Cache-control: private, max-age=0, no-cache\r\n");
11172 r->rsprintf("Expires: Fri, 01 Jan 1983 00:00:00 GMT\r\n");
11173 r->rsprintf("Content-Type: text/plain\r\n");
11174 r->rsprintf("Content-disposition: attachment; filename=\"export.csv\"\r\n");
11175 r->rsprintf("\r\n");
11176
11177 /* output header line with variable names */
11178 if (hp.show_run_markers && t_run_number)
11179 r->rsprintf("Time, Timestamp, Run, Run State, ");
11180 else
11181 r->rsprintf("Time, Timestamp, ");
11182
11183 for (int i = 0, first = 1; i < hsdata->nvars; i++) {
11184 if (hsdata->odb_index[i] < 0)
11185 continue;
11186 if (hsdata->num_entries[i] <= 0)
11187 continue;
11188 if (!first)
11189 r->rsprintf(", ");
11190 first = 0;
11191 r->rsprintf("%s", hsdata->var_names[i]);
11192 }
11193 r->rsprintf("\n");
11194
11195 int i_run = 0;
11196
11197 do {
11198
11199 if (debug)
11200 printf("hsdata %p, t %d, irun %d\n", hsdata, (int)t, i_run);
11201
11202 /* find run number/state which is valid for t */
11203 if (hp.show_run_markers && t_run_number)
11204 while (i_run < n_run_number-1 && t_run_number[i_run+1] <= t)
11205 i_run++;
11206
11207 //printf("irun %d\n", i_run);
11208
11209 /* find index for all variables which is valid for t */
11210 for (int i = 0; i < hsdata->nvars; i++)
11211 while (hsdata->num_entries[i] > 0 && i_var[i] < hsdata->num_entries[i] - 1 && hsdata->t[i][i_var[i]+1] <= t)
11212 i_var[i]++;
11213
11214 /* finish if last point for all variables reached */
11215 bool done = true;
11216 for (int i = 0 ; i < hsdata->nvars ; i++)
11217 if (hsdata->num_entries[i] > 0 && i_var[i] < hsdata->num_entries[i]) {
11218 done = false;
11219 break;
11220 }
11221
11222 if (debug) {
11223 printf("step to time %d: ", (int)t);
11224 for (int i = 0; i < hsdata->nvars; i++) {
11225 printf(" [%d] %d, ", hsdata->num_entries[i], i_var[i]);
11226 }
11227 printf(" done: %d\n", done);
11228 }
11229
11230 if (done)
11231 break;
11232
11233 struct tm tms;
11234 localtime_r(&t, &tms);
11235
11236 char fmt[256];
11237 //strcpy(fmt, "%c");
11238 strcpy(fmt, "%Y.%m.%d %H:%M:%S");
11239 char str[256];
11240 strftime(str, sizeof(str), fmt, &tms);
11241
11242 if (t_run_number && run_index>=0 && state_index>=0) {
11243 if (t_run_number[i_run] <= t)
11244 r->rsprintf("%s, %d, %.0f, %.0f, ", str, (int)t, hsdata->v[run_index][i_run], hsdata->v[state_index][i_run]);
11245 else
11246 r->rsprintf("%s, %d, N/A, N/A, ", str, (int)t);
11247 } else
11248 r->rsprintf("%s, %d, ", str, (int)t);
11249
11250 if (debug) {
11251 for (int i= 0 ; i < hsdata->nvars ; i++)
11252 printf(" %d (%g)", i_var[i], hsdata->v[i][i_var[i]]);
11253 printf("\n");
11254 }
11255
11256 for (int i=0, first=1 ; i<hsdata->nvars ; i++) {
11257 if (i_var[i] < 0)
11258 continue;
11259 if (hsdata->odb_index[i] < 0)
11260 continue;
11261 if (!first)
11262 r->rsprintf(", ");
11263 first = 0;
11264 //r->rsprintf("(%d %g)", i_var[i], hsdata->v[i][i_var[i]]);
11265 r->rsprintf("%g", hsdata->v[i][i_var[i]]);
11266 }
11267 r->rsprintf("\n");
11268
11269 /* find next t as smallest delta t */
11270 int dt = -1;
11271 for (int i = 0 ; i < hsdata->nvars ; i++)
11272 if (i_var[i]>=0 && hsdata->odb_index[i]>=0 && hsdata->num_entries[i]>0 && i_var[i]<hsdata->num_entries[i]-1) {
11273 int xdt = hsdata->t[i][i_var[i]+1] - t;
11274 if (debug)
11275 printf("var %d, i_var %d->%d, t %d->%d, dt %d\n", i, i_var[i], i_var[i]+1, (int)hsdata->t[i][i_var[i]], (int)hsdata->t[i][i_var[i]+1], xdt);
11276 if (dt <= 0 || xdt < dt)
11277 dt = xdt;
11278 }
11279
11280 if (debug)
11281 printf("dt %d\n", dt);
11282
11283 if (dt <= 0)
11284 break;
11285
11286 t += dt;
11287
11288 } while (1);
11289
11290 free(i_var);
11291}
int done
TRIGGER_SETTINGS ts
#define HS_SUCCESS
Definition midas.h:728
void ss_tzset()
Definition system.cxx:3427
DWORD ss_time()
Definition system.cxx:3534
INT db_delete(HNDLE hDB, HNDLE hKeyRoot, const char *odb_path)
Definition odb.cxx:3999
INT index
Definition mana.cxx:271
int read_history(const HistPlot &hp, int index, int flags, time_t tstart, time_t tend, time_t scale, HistoryData *data)
Definition mhttpd.cxx:8389
int time_to_sec(const char *str)
Definition mhttpd.cxx:8125
static void LoadHistPlotFromOdb(MVOdb *odb, HistPlot *hp, const char *group, const char *panel)
Definition mhttpd.cxx:10228
DWORD BOOL
Definition midas.h:105
MUTEX_T * tm
Definition odbedit.cxx:39
bool show_run_markers
Definition mhttpd.cxx:8378
int * odb_index
Definition mhttpd.cxx:8279
double ** v
Definition mhttpd.cxx:8283
void Print() const
Definition mhttpd.cxx:8325
time_t ** t
Definition mhttpd.cxx:8282
char ** var_names
Definition mhttpd.cxx:8277
int * num_entries
Definition mhttpd.cxx:8281
Here is the call graph for this function:
Here is the caller graph for this function:

◆ find_cookie_mg()

static const std::string find_cookie_mg ( const struct http_message msg,
const char *  cookie_name 
)
static

Definition at line 14187 of file mhttpd.cxx.

14188{
14189 const std::string cookies = find_header_mg(msg, "Cookie");
14190 if (cookies.length() < 1)
14191 return "";
14192 const char* p = strstr(cookies.c_str(), cookie_name);
14193 if (!p)
14194 return "";
14195 const char* v = p+strlen(cookie_name);
14196 if (*v != '=')
14197 return "";
14198 v++;
14199 //printf("cookie [%s] value [%s]\n", cookie_name, v);
14200 return v;
14201}
static const std::string find_header_mg(const struct http_message *msg, const char *name)
Definition mhttpd.cxx:14174
Here is the call graph for this function:
Here is the caller graph for this function:

◆ find_file_mg()

int find_file_mg ( const char *  filename,
std::string &  path,
FILE **  fpp,
bool  trace 
)

Definition at line 13704 of file mhttpd.cxx.

13705{
13706 std::string exptdir = cm_get_path();
13707
13708 if (try_file_mg(".", filename, path, fpp, trace) == SUCCESS)
13709 return SUCCESS;
13710
13711 if (try_file_mg(getenv("MIDAS_DIR"), filename, path, fpp, trace) == SUCCESS)
13712 return SUCCESS;
13713
13714 if (try_file_mg(exptdir.c_str(), filename, path, fpp, trace) == SUCCESS)
13715 return SUCCESS;
13716
13717 if (try_file_mg(getenv("MIDASSYS"), filename, path, fpp, trace) == SUCCESS)
13718 return SUCCESS;
13719
13720 // setup default filename
13721 try_file_mg(exptdir.c_str(), filename, path, NULL, false);
13722 return SS_FILE_ERROR;
13723}
std::string cm_get_path()
Definition midas.cxx:1553
#define SS_FILE_ERROR
Definition midas.h:670
#define SUCCESS
Definition mcstd.h:54
int try_file_mg(const char *try_dir, const char *filename, std::string &path, FILE **fpp, bool trace)
Definition mhttpd.cxx:13671
Here is the call graph for this function:
Here is the caller graph for this function:

◆ find_header_mg()

static const std::string find_header_mg ( const struct http_message msg,
const char *  name 
)
static

Definition at line 14174 of file mhttpd.cxx.

14175{
14176 size_t nlen = strlen(name);
14177 for (int i=0; i<MG_MAX_HTTP_HEADERS; i++) {
14178 if (msg->header_names[i].len != nlen)
14179 continue;
14180 if (strncmp(msg->header_names[i].p, name, nlen) != 0)
14181 continue;
14182 return mgstr(&msg->header_values[i]);
14183 }
14184 return "";
14185}
struct mg_str header_names[MG_MAX_HTTP_HEADERS]
Definition mongoose6.h:2090
#define MG_MAX_HTTP_HEADERS
Definition mongoose6.h:2031
struct mg_str header_values[MG_MAX_HTTP_HEADERS]
Definition mongoose6.h:2091
static std::string mgstr(const mg_str *s)
Definition mhttpd.cxx:14169
Here is the call graph for this function:
Here is the caller graph for this function:

◆ find_odb_tag()

char * find_odb_tag ( char *  p,
char *  path,
char *  format,
int *  edit,
char *  type,
char *  pwd,
char *  tail 
)

Definition at line 3123 of file mhttpd.cxx.

3124{
3125 char str[256], *ps, *pt;
3126 BOOL in_script;
3127
3128 *edit = 0;
3129 *tail = 0;
3130 *format = 0;
3131 pwd[0] = 0;
3132 in_script = FALSE;
3133 strcpy(type, "text");
3134 do {
3135 while (*p && *p != '<')
3136 p++;
3137
3138 /* return if end of string reached */
3139 if (!*p)
3140 return NULL;
3141
3142 p++;
3143 while (*p && ((*p == ' ') || iscntrl(*p)))
3144 p++;
3145
3146 strncpy(str, p, 6);
3147 str[6] = 0;
3148 if (equal_ustring(str, "script"))
3149 in_script = TRUE;
3150
3151 strncpy(str, p, 7);
3152 str[7] = 0;
3153 if (equal_ustring(str, "/script"))
3154 in_script = FALSE;
3155
3156 strncpy(str, p, 4);
3157 str[4] = 0;
3158 if (equal_ustring(str, "odb ")) {
3159 ps = p - 1;
3160 p += 4;
3161 while (*p && ((*p == ' ') || iscntrl(*p)))
3162 p++;
3163
3164 do {
3165 strncpy(str, p, 7);
3166 str[7] = 0;
3167 if (equal_ustring(str, "format=")) {
3168 p += 7;
3169 if (*p == '\"') {
3170 p++;
3171 while (*p && *p != '\"')
3172 *format++ = *p++;
3173 *format = 0;
3174 if (*p == '\"')
3175 p++;
3176 } else {
3177 while (*p && *p != ' ' && *p != '>')
3178 *format++ = *p++;
3179 *format = 0;
3180 }
3181
3182 } else {
3183
3184 strncpy(str, p, 4);
3185 str[4] = 0;
3186 if (equal_ustring(str, "src=")) {
3187 p += 4;
3188 if (*p == '\"') {
3189 p++;
3190 while (*p && *p != '\"')
3191 *path++ = *p++;
3192 *path = 0;
3193 if (*p == '\"')
3194 p++;
3195 } else {
3196 while (*p && *p != ' ' && *p != '>')
3197 *path++ = *p++;
3198 *path = 0;
3199 }
3200 } else {
3201
3202 if (in_script)
3203 break;
3204
3205 strncpy(str, p, 5);
3206 str[5] = 0;
3207 if (equal_ustring(str, "edit=")) {
3208 p += 5;
3209
3210 if (*p == '\"') {
3211 p++;
3212 *edit = atoi(p);
3213 if (*p == '\"')
3214 p++;
3215 } else {
3216 *edit = atoi(p);
3217 while (*p && *p != ' ' && *p != '>')
3218 p++;
3219 }
3220
3221 } else {
3222
3223 strncpy(str, p, 5);
3224 str[5] = 0;
3225 if (equal_ustring(str, "type=")) {
3226 p += 5;
3227 if (*p == '\"') {
3228 p++;
3229 while (*p && *p != '\"')
3230 *type++ = *p++;
3231 *type = 0;
3232 if (*p == '\"')
3233 p++;
3234 } else {
3235 while (*p && *p != ' ' && *p != '>')
3236 *type++ = *p++;
3237 *type = 0;
3238 }
3239 } else {
3240 strncpy(str, p, 4);
3241 str[4] = 0;
3242 if (equal_ustring(str, "pwd=")) {
3243 p += 4;
3244 if (*p == '\"') {
3245 p++;
3246 while (*p && *p != '\"')
3247 *pwd++ = *p++;
3248 *pwd = 0;
3249 if (*p == '\"')
3250 p++;
3251 } else {
3252 while (*p && *p != ' ' && *p != '>')
3253 *pwd++ = *p++;
3254 *pwd = 0;
3255 }
3256 } else {
3257 if (strchr(p, '=')) {
3258 mstrlcpy(str, p, sizeof(str));
3259 pt = strchr(str, '=')+1;
3260 if (*pt == '\"') {
3261 pt++;
3262 while (*pt && *pt != '\"')
3263 pt++;
3264 if (*pt == '\"')
3265 pt++;
3266 *pt = 0;
3267 } else {
3268 while (*pt && *pt != ' ' && *pt != '>')
3269 pt++;
3270 *pt = 0;
3271 }
3272 if (tail[0]) {
3273 mstrlcat(tail, " ", 256);
3274 mstrlcat(tail, str, 256);
3275 } else {
3276 mstrlcat(tail, str, 256);
3277 }
3278 p += strlen(str);
3279 }
3280 }
3281 }
3282 }
3283 }
3284 }
3285
3286 while (*p && ((*p == ' ') || iscntrl(*p)))
3287 p++;
3288
3289 if (*p == '<') {
3290 cm_msg(MERROR, "find_odb_tag", "Invalid odb tag '%s'", ps);
3291 return NULL;
3292 }
3293 } while (*p != '>');
3294
3295 return ps;
3296 }
3297
3298 while (*p && *p != '>')
3299 p++;
3300
3301 } while (1);
3302
3303}
INT type
Definition mana.cxx:269
char pwd[256]
Definition odbedit.cxx:24
Here is the call graph for this function:
Here is the caller graph for this function:

◆ gen_odb_attachment()

void gen_odb_attachment ( Return r,
const char *  path,
std::string &  bout 
)

Definition at line 2164 of file mhttpd.cxx.

2165{
2166 HNDLE hDB, hkeyroot, hkey;
2167 KEY key;
2168 INT i, j, size;
2169 char data[1024];
2170 time_t now;
2171
2173 db_find_key(hDB, 0, path, &hkeyroot);
2174 assert(hkeyroot);
2175
2176 /* title row */
2177 //size = sizeof(str);
2178 //str[0] = 0;
2179 //db_get_value(hDB, 0, "/Experiment/Name", str, &size, TID_STRING, TRUE);
2180 time(&now);
2181
2182 bout += "<table border=3 cellpadding=1 class=\"dialogTable\">\n";
2183 char ctimebuf[32];
2184 ctime_r(&now, ctimebuf);
2185 bout += msprintf("<tr><th colspan=2>%s</tr>\n", ctimebuf);
2186 bout += msprintf("<tr><th colspan=2>%s</tr>\n", path);
2187
2188 /* enumerate subkeys */
2189 for (i = 0;; i++) {
2190 db_enum_link(hDB, hkeyroot, i, &hkey);
2191 if (!hkey)
2192 break;
2193 db_get_key(hDB, hkey, &key);
2194
2195 /* resolve links */
2196 if (key.type == TID_LINK) {
2197 db_enum_key(hDB, hkeyroot, i, &hkey);
2198 db_get_key(hDB, hkey, &key);
2199 }
2200
2201 if (key.type == TID_KEY) {
2202 /* for keys, don't display data value */
2203 bout += msprintf("<tr><td colspan=2>%s</td></tr>\n", key.name);
2204 } else {
2205 /* display single value */
2206 if (key.num_values == 1) {
2207 size = sizeof(data);
2208 db_get_data(hDB, hkey, data, &size, key.type);
2209 //printf("data size %d [%s]\n", size, data);
2210 std::string data_str = db_sprintf(data, key.item_size, 0, key.type);
2211 std::string hex_str = db_sprintfh(data, key.item_size, 0, key.type);
2212
2213 if (data_str.empty() || equal_ustring(data_str.c_str(), "<NULL>")) {
2214 data_str = "(empty)";
2215 hex_str = "";
2216 }
2217
2218 if (strcmp(data_str.c_str(), hex_str.c_str()) != 0 && hex_str[0]) {
2219 //sprintf(b, "<tr><td>%s</td><td>%s (%s)</td></tr>\n", key.name, data_str, hex_str);
2220 bout += "<tr><td>";
2221 bout += key.name;
2222 bout += "</td><td>";
2223 bout += data_str;
2224 bout += " (";
2225 bout += hex_str;
2226 bout += ")</td></tr>\n";
2227 } else {
2228 bout += msprintf("<tr><td>%s</td><td>", key.name);
2229 bout += strencode2(data_str.c_str());
2230 bout += "</td></tr>\n";
2231 }
2232 } else {
2233 /* display first value */
2234 bout += msprintf("<tr><td rowspan=%d>%s</td>\n", key.num_values, key.name);
2235
2236 for (j = 0; j < key.num_values; j++) {
2237 size = sizeof(data);
2238 db_get_data_index(hDB, hkey, data, &size, j, key.type);
2239 std::string data_str = db_sprintf(data, key.item_size, 0, key.type);
2240 std::string hex_str = db_sprintfh(data, key.item_size, 0, key.type);
2241
2242 if (data_str.empty() || equal_ustring(data_str.c_str(), "<NULL>")) {
2243 data_str = "(empty)";
2244 hex_str = "";
2245 }
2246
2247 if (j > 0) {
2248 bout += "<tr>";
2249 }
2250
2251 if (strcmp(data_str.c_str(), hex_str.c_str()) != 0 && hex_str[0]) {
2252 //sprintf(b, "<td>[%d] %s (%s)<br></td></tr>\n", j, data_str, hex_str);
2253 bout += "<td>[";
2254 bout += toString(j);
2255 bout += "] ";
2256 bout += data_str;
2257 bout += " (";
2258 bout += hex_str;
2259 bout += ")<br></td></tr>\n";
2260 } else {
2261 //sprintf(b, "<td>[%d] %s<br></td></tr>\n", j, data_str);
2262 bout += "<td>[";
2263 bout += toString(j);
2264 bout += "] ";
2265 bout += data_str;
2266 bout += "<br></td></tr>\n";
2267 }
2268 }
2269 }
2270 }
2271 }
2272
2273 bout += "</table>\n";
2274}
#define TID_KEY
Definition midas.h:349
#define TID_LINK
Definition midas.h:350
INT db_sprintfh(char *string, const void *data, INT data_size, INT idx, DWORD type)
Definition odb.cxx:11005
INT db_get_data_index(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, INT idx, DWORD type)
Definition odb.cxx:6917
INT db_enum_link(HNDLE hDB, HNDLE hKey, INT idx, HNDLE *subkey_handle)
Definition odb.cxx:5495
std::string strencode2(const char *text)
Definition mhttpd.cxx:2077
static std::string toString(int i)
Definition mhttpd.cxx:57
std::string msprintf(const char *format,...)
Definition midas.cxx:419
INT j
Definition odbhist.cxx:40
INT num_values
Definition midas.h:1029
INT item_size
Definition midas.h:1033
Here is the call graph for this function:
Here is the caller graph for this function:

◆ generate_hist_graph()

void generate_hist_graph ( MVOdb *  odb,
Return rr,
const char *  hgroup,
const char *  hpanel,
char *  buffer,
int *  buffer_size,
int  width,
int  height,
time_t  xendtime,
int  scale,
int  index,
int  labels,
const char *  bgcolor,
const char *  fgcolor,
const char *  gridcolor 
)
  • check panel name in ODB *‍/
  • split varname in event, variable and index *‍/
  • get factors *‍/
  • get offsets *‍/
  • get axis type *‍/
  • get show_values type *‍/
  • get sort_vars type *‍/
  • get old_vars type *‍/
  • get min value *‍/
  • get max value *‍/
  • get runmarker flag *‍/

Definition at line 8637 of file mhttpd.cxx.

8643{
8644 HNDLE hDB;
8645 //KEY key;
8646 gdImagePtr im;
8647 gdGifBuffer gb;
8648 int i, j, k, l;
8649 //int n_vars;
8650 int size, status, r, g, b;
8651 //int x_marker;
8652 int length;
8653 int white, grey, red;
8654 //int black, ltgrey, green, blue;
8655 int fgcol, bgcol, gridcol;
8656 int curve_col[MAX_VARS];
8657 int state_col[3];
8658 char str[256], *p;
8659 //INT var_index[MAX_VARS];
8660 //char event_name[MAX_VARS][NAME_LENGTH];
8661 //char tag_name[MAX_VARS][64];
8662 //char var_name[MAX_VARS][NAME_LENGTH];
8663 //char varname[64];
8664 //char key_name[256];
8665 //float factor[MAX_VARS], offset[MAX_VARS];
8666 //BOOL logaxis, runmarker;
8667 //double xmin, xrange;
8668 double ymin, ymax;
8669 double upper_limit[MAX_VARS], lower_limit[MAX_VARS];
8670 //float minvalue = (float) -HUGE_VAL;
8671 //float maxvalue = (float) +HUGE_VAL;
8672 //int show_values = 0;
8673 //int sort_vars = 0;
8674 //int old_vars = 0;
8675 time_t starttime, endtime;
8676 int flags;
8677
8678 time_t now = ss_time();
8679
8680 if (xendtime == 0)
8681 xendtime = now;
8682
8683 HistPlot hp;
8684 LoadHistPlotFromOdb(odb, &hp, hgroup, hpanel);
8685
8686 std::vector<int> var_index; var_index.resize(hp.vars.size());
8687
8688 for (size_t i=0; i<hp.vars.size(); i++) {
8689 var_index[i] = 0;
8690 const char *vp = strchr(hp.vars[i].tag_name.c_str(), '[');
8691 if (vp) {
8692 var_index[i] = atoi(vp + 1);
8693 }
8694 }
8695
8696 int logaxis = hp.log_axis;
8697 double minvalue = hp.minimum;
8698 double maxvalue = hp.maximum;
8699
8700 if ((minvalue == 0) && (maxvalue == 0)) {
8701 minvalue = -HUGE_VAL;
8702 maxvalue = +HUGE_VAL;
8703 }
8704
8705 std::vector<int> x[MAX_VARS];
8706 std::vector<double> y[MAX_VARS];
8707
8708 HistoryData hsxxx;
8709 HistoryData* hsdata = &hsxxx;
8710
8712
8713 /* generate image */
8714 im = gdImageCreate(width, height);
8715
8716 /* allocate standard colors */
8717 sscanf(bgcolor, "%02x%02x%02x", &r, &g, &b);
8718 bgcol = gdImageColorAllocate(im, r, g, b);
8719 sscanf(fgcolor, "%02x%02x%02x", &r, &g, &b);
8720 fgcol = gdImageColorAllocate(im, r, g, b);
8721 sscanf(gridcolor, "%02x%02x%02x", &r, &g, &b);
8722 gridcol = gdImageColorAllocate(im, r, g, b);
8723
8724 grey = gdImageColorAllocate(im, 192, 192, 192);
8725 //ltgrey = gdImageColorAllocate(im, 208, 208, 208);
8726 white = gdImageColorAllocate(im, 255, 255, 255);
8727 //black = gdImageColorAllocate(im, 0, 0, 0);
8728 red = gdImageColorAllocate(im, 255, 0, 0);
8729 //green = gdImageColorAllocate(im, 0, 255, 0);
8730 //blue = gdImageColorAllocate(im, 0, 0, 255);
8731
8732 curve_col[0] = gdImageColorAllocate(im, 0, 0, 255);
8733 curve_col[1] = gdImageColorAllocate(im, 0, 192, 0);
8734 curve_col[2] = gdImageColorAllocate(im, 255, 0, 0);
8735 curve_col[3] = gdImageColorAllocate(im, 0, 192, 192);
8736 curve_col[4] = gdImageColorAllocate(im, 255, 0, 255);
8737 curve_col[5] = gdImageColorAllocate(im, 192, 192, 0);
8738 curve_col[6] = gdImageColorAllocate(im, 128, 128, 128);
8739 curve_col[7] = gdImageColorAllocate(im, 128, 255, 128);
8740 curve_col[8] = gdImageColorAllocate(im, 255, 128, 128);
8741 curve_col[9] = gdImageColorAllocate(im, 128, 128, 255);
8742 for (i=10; i<MAX_VARS; i++)
8743 curve_col[i] = gdImageColorAllocate(im, 128, 128, 128);
8744
8745 state_col[0] = gdImageColorAllocate(im, 255, 0, 0);
8746 state_col[1] = gdImageColorAllocate(im, 255, 255, 0);
8747 state_col[2] = gdImageColorAllocate(im, 0, 255, 0);
8748
8749 /* Set transparent color. */
8750 gdImageColorTransparent(im, grey);
8751
8752 /* Title */
8753 gdImageString(im, gdFontGiant, width / 2 - (strlen(hpanel) * gdFontGiant->w) / 2, 2, (char*)hpanel, fgcol);
8754
8755 /* connect to history */
8757 if (mh == NULL) {
8758 sprintf(str, "History is not configured, see messages");
8759 gdImageString(im, gdFontSmall, width / 2 - (strlen(str) * gdFontSmall->w) / 2, height / 2, str, red);
8760 goto error;
8761 }
8762
8764 //sprintf(str, "/History/Display/%s/%s", hgroup, hpanel);
8765 //db_find_key(hDB, 0, str, &hkeypanel);
8766 //if (!hkeypanel) {
8767 // sprintf(str, "Cannot find /History/Display/%s/%s in ODB", hgroup, hpanel);
8768 // gdImageString(im, gdFontSmall, width / 2 - (strlen(str) * gdFontSmall->w) / 2, height / 2, str, red);
8769 // goto error;
8770 //}
8771
8772 //db_find_key(hDB, hkeypanel, "Variables", &hkeydvar);
8773 //if (!hkeydvar) {
8774 // sprintf(str, "Cannot find /History/Display/%s/%s/Variables in ODB", hgroup, hpanel);
8775 // gdImageString(im, gdFontSmall, width / 2 - (strlen(str) * gdFontSmall->w) / 2, height / 2, str, red);
8776 // goto error;
8777 //}
8778
8779 //db_get_key(hDB, hkeydvar, &key);
8780 //n_vars = key.num_values;
8781
8782 if (hp.vars.empty()) {
8783 sprintf(str, "No variables in panel %s/%s", hgroup, hpanel);
8784 gdImageString(im, gdFontSmall, width / 2 - (strlen(str) * gdFontSmall->w) / 2, height / 2, str, red);
8785 goto error;
8786 }
8787
8788 if (hp.vars.size() > MAX_VARS) {
8789 sprintf(str, "Too many variables in panel %s/%s", hgroup, hpanel);
8790 gdImageString(im, gdFontSmall, width / 2 - (strlen(str) * gdFontSmall->w) / 2, height / 2, str, red);
8791 goto error;
8792 }
8793
8794 ymin = ymax = 0;
8795 //logaxis = runmarker = 0;
8796
8797 for (i = 0; i < (int)hp.vars.size(); i++) {
8798 if (index != -1 && index != i)
8799 continue;
8800
8801 //size = sizeof(str);
8802 //status = db_get_data_index(hDB, hkeydvar, str, &size, i, TID_STRING);
8803 //if (status != DB_SUCCESS) {
8804 // sprintf(str, "Cannot read tag %d in panel %s/%s, status %d", i, hgroup, hpanel, status);
8805 // gdImageString(im, gdFontSmall, width / 2 - (strlen(str) * gdFontSmall->w) / 2, height / 2, str, red);
8806 // goto error;
8807 //}
8808 //
8809 //mstrlcpy(tag_name[i], str, sizeof(tag_name[0]));
8810
8812 //char *tp = strchr(tag_name[i], ':');
8813 //if (tp) {
8814 // mstrlcpy(event_name[i], tag_name[i], sizeof(event_name[0]));
8815 // char *ep = strchr(event_name[i], ':');
8816 // if (ep)
8817 // *ep = 0;
8818 // mstrlcpy(var_name[i], tp+1, sizeof(var_name[0]));
8819 // var_index[i] = 0;
8820 // char *vp = strchr(var_name[i], '[');
8821 // if (vp) {
8822 // var_index[i] = atoi(vp + 1);
8823 // *vp = 0;
8824 // }
8825 //} else {
8826 // sprintf(str, "Tag \"%s\" has wrong format in panel \"%s/%s\"", tag_name[i], hgroup, hpanel);
8827 // gdImageString(im, gdFontSmall, width / 2 - (strlen(str) * gdFontSmall->w) / 2, height / 2, str, red);
8828 // goto error;
8829 //}
8830 //
8831 //db_find_key(hDB, hkeypanel, "Colour", &hkey);
8832 //if (hkey) {
8833 // size = sizeof(str);
8834 // status = db_get_data_index(hDB, hkey, str, &size, i, TID_STRING);
8835 // if (status == DB_SUCCESS) {
8836 // if (str[0] == '#') {
8837 // char sss[3];
8838 // int r, g, b;
8839 //
8840 // sss[0] = str[1];
8841 // sss[1] = str[2];
8842 // sss[2] = 0;
8843 // r = strtoul(sss, NULL, 16);
8844 // sss[0] = str[3];
8845 // sss[1] = str[4];
8846 // sss[2] = 0;
8847 // g = strtoul(sss, NULL, 16);
8848 // sss[0] = str[5];
8849 // sss[1] = str[6];
8850 // sss[2] = 0;
8851 // b = strtoul(sss, NULL, 16);
8852 //
8853 // curve_col[i] = gdImageColorAllocate(im, r, g, b);
8854 // }
8855 // }
8856 //}
8857
8858 if (hp.vars[i].colour[0] == '#') {
8859 const char* str = hp.vars[i].colour.c_str();
8860 char sss[3];
8861 int r, g, b;
8862
8863 sss[0] = str[1];
8864 sss[1] = str[2];
8865 sss[2] = 0;
8866 r = strtoul(sss, NULL, 16);
8867 sss[0] = str[3];
8868 sss[1] = str[4];
8869 sss[2] = 0;
8870 g = strtoul(sss, NULL, 16);
8871 sss[0] = str[5];
8872 sss[1] = str[6];
8873 sss[2] = 0;
8874 b = strtoul(sss, NULL, 16);
8875
8876 curve_col[i] = gdImageColorAllocate(im, r, g, b);
8877 }
8878
8879 /* get timescale */
8880 if (scale == 0) {
8881 //std::string ts = "1h";
8882 //status = db_get_value_string(hDB, hkeypanel, "Timescale", 0, &ts, TRUE);
8883 //if (status != DB_SUCCESS) {
8884 // /* delete old integer key */
8885 // db_find_key(hDB, hkeypanel, "Timescale", &hkey);
8886 // if (hkey)
8887 // db_delete_key(hDB, hkey, FALSE);
8888 //
8889 // ts = "1h";
8890 // status = db_get_value_string(hDB, hkeypanel, "Timescale", 0, &ts, TRUE);
8891 //}
8892
8893 scale = time_to_sec(hp.timescale.c_str());
8894 }
8895
8896 //for (j = 0; j < MAX_VARS; j++) {
8897 // factor[j] = 1;
8898 // offset[j] = 0;
8899 //}
8900
8902 //size = sizeof(float) * n_vars;
8903 //db_get_value(hDB, hkeypanel, "Factor", factor, &size, TID_FLOAT, TRUE);
8904
8906 //size = sizeof(float) * n_vars;
8907 //db_get_value(hDB, hkeypanel, "Offset", offset, &size, TID_FLOAT, TRUE);
8908
8910 //size = sizeof(logaxis);
8911 //logaxis = 0;
8912 //db_get_value(hDB, hkeypanel, "Log axis", &logaxis, &size, TID_BOOL, TRUE);
8913
8915 //size = sizeof(show_values);
8916 //show_values = 0;
8917 //db_get_value(hDB, hkeypanel, "Show values", &show_values, &size, TID_BOOL, TRUE);
8918
8920 //size = sizeof(sort_vars);
8921 //sort_vars = 0;
8922 //db_get_value(hDB, hkeypanel, "Sort vars", &sort_vars, &size, TID_BOOL, TRUE);
8923
8925 //size = sizeof(old_vars);
8926 //old_vars = 0;
8927 //db_get_value(hDB, hkeypanel, "Show old vars", &old_vars, &size, TID_BOOL, TRUE);
8928
8930 //size = sizeof(minvalue);
8931 //minvalue = (float) -HUGE_VAL;
8932 //db_get_value(hDB, hkeypanel, "Minimum", &minvalue, &size, TID_FLOAT, TRUE);
8933
8935 //size = sizeof(maxvalue);
8936 //maxvalue = (float) +HUGE_VAL;
8937 //db_get_value(hDB, hkeypanel, "Maximum", &maxvalue, &size, TID_FLOAT, TRUE);
8938
8939 //if ((minvalue == 0) && (maxvalue == 0)) {
8940 // minvalue = (float) -HUGE_VAL;
8941 // maxvalue = (float) +HUGE_VAL;
8942 //}
8943
8945 //size = sizeof(runmarker);
8946 //runmarker = 1;
8947 //db_get_value(hDB, hkeypanel, "Show run markers", &runmarker, &size, TID_BOOL, TRUE);
8948
8949 /* make ODB path from tag name */
8950 std::string odbpath;
8951 HNDLE hkeyeq = 0;
8952 HNDLE hkeyroot;
8953 db_find_key(hDB, 0, "/Equipment", &hkeyroot);
8954 if (hkeyroot) {
8955 for (j = 0;; j++) {
8956 HNDLE hkeyeq;
8957 db_enum_key(hDB, hkeyroot, j, &hkeyeq);
8958
8959 if (!hkeyeq)
8960 break;
8961
8962 KEY key;
8963 db_get_key(hDB, hkeyeq, &key);
8964 if (equal_ustring(key.name, hp.vars[i].event_name.c_str())) {
8965 /* check if variable is individual key under variables/ */
8966 sprintf(str, "Variables/%s", hp.vars[i].tag_name.c_str());
8967 HNDLE hkey;
8968 db_find_key(hDB, hkeyeq, str, &hkey);
8969 if (hkey) {
8970 //sprintf(odbpath, "/Equipment/%s/Variables/%s", event_name[i], var_name[i]);
8971 odbpath = "";
8972 odbpath += "/Equipment/";
8973 odbpath += hp.vars[i].event_name;
8974 odbpath += "/Variables/";
8975 odbpath += hp.vars[i].tag_name;
8976 break;
8977 }
8978
8979 /* check if variable is in setttins/names array */
8980 HNDLE hkeynames;
8981 db_find_key(hDB, hkeyeq, "Settings/Names", &hkeynames);
8982 if (hkeynames) {
8983 /* extract variable name and Variables/<key> */
8984 mstrlcpy(str, hp.vars[i].tag_name.c_str(), sizeof(str));
8985 p = str + strlen(str) - 1;
8986 while (p > str && *p != ' ')
8987 p--;
8988 std::string key_name = p + 1;
8989 *p = 0;
8990
8991 std::string varname = str;
8992
8993 /* find key in single name array */
8994 db_get_key(hDB, hkeynames, &key);
8995 for (k = 0; k < key.num_values; k++) {
8996 size = sizeof(str);
8997 db_get_data_index(hDB, hkeynames, str, &size, k, TID_STRING);
8998 if (equal_ustring(str, varname.c_str())) {
8999 //sprintf(odbpath, "/Equipment/%s/Variables/%s[%d]", event_name[i], key_name, k);
9000 odbpath = "";
9001 odbpath += "/Equipment/";
9002 odbpath += hp.vars[i].event_name;
9003 odbpath += "/Variables/";
9004 odbpath += key_name;
9005 odbpath += "[";
9006 odbpath += toString(k);
9007 odbpath += "]";
9008 break;
9009 }
9010 }
9011 } else {
9012 /* go through /variables/<name> entries */
9013 HNDLE hkeyvars;
9014 db_find_key(hDB, hkeyeq, "Variables", &hkeyvars);
9015 if (hkeyvars) {
9016 for (k = 0;; k++) {
9017 db_enum_key(hDB, hkeyvars, k, &hkey);
9018
9019 if (!hkey)
9020 break;
9021
9022 /* find "settins/names <key>" for this key */
9023 db_get_key(hDB, hkey, &key);
9024
9025 /* find key in key_name array */
9026 std::string key_name = key.name;
9027
9028 std::string path;
9029 //sprintf(str, "Settings/Names %s", key_name);
9030 path += "Settings/Names ";
9031 path += key_name;
9032
9033 HNDLE hkeynames;
9034 db_find_key(hDB, hkeyeq, path.c_str(), &hkeynames);
9035 if (hkeynames) {
9036 db_get_key(hDB, hkeynames, &key);
9037 for (l = 0; l < key.num_values; l++) {
9038 size = sizeof(str);
9039 db_get_data_index(hDB, hkeynames, str, &size, l, TID_STRING);
9040 if (equal_ustring(str, hp.vars[i].tag_name.c_str())) {
9041 //sprintf(odbpath, "/Equipment/%s/Variables/%s[%d]", event_name[i], key_name, l);
9042 odbpath = "";
9043 odbpath += "/Equipment/";
9044 odbpath += hp.vars[i].event_name;
9045 odbpath += "/Variables/";
9046 odbpath += key_name;
9047 odbpath += "[";
9048 odbpath += toString(l);
9049 odbpath += "]";
9050 break;
9051 }
9052 }
9053 }
9054 }
9055 }
9056 }
9057
9058 break;
9059 }
9060 }
9061
9062 if (!hkeyeq) {
9063 db_find_key(hDB, 0, "/History/Links", &hkeyroot);
9064 if (hkeyroot) {
9065 for (j = 0;; j++) {
9066 HNDLE hkey;
9067 db_enum_link(hDB, hkeyroot, j, &hkey);
9068
9069 if (!hkey)
9070 break;
9071
9072 KEY key;
9073 db_get_key(hDB, hkey, &key);
9074 if (equal_ustring(key.name, hp.vars[i].event_name.c_str())) {
9075 db_enum_key(hDB, hkeyroot, j, &hkey);
9076 db_find_key(hDB, hkey, hp.vars[i].tag_name.c_str(), &hkey);
9077 if (hkey) {
9078 db_get_key(hDB, hkey, &key);
9079 odbpath = db_get_path(hDB, hkey);
9080 if (key.num_values > 1) {
9081 odbpath += "[";
9082 odbpath += toString(var_index[i]);
9083 odbpath += "]";
9084 }
9085 break;
9086 }
9087 }
9088 }
9089 }
9090 }
9091 }
9092
9093 /* search alarm limits */
9094 upper_limit[i] = lower_limit[i] = -12345;
9095 db_find_key(hDB, 0, "Alarms/Alarms", &hkeyroot);
9096 if (odbpath.length() > 0 && hkeyroot) {
9097 for (j = 0;; j++) {
9098 HNDLE hkey;
9099 db_enum_key(hDB, hkeyroot, j, &hkey);
9100
9101 if (!hkey)
9102 break;
9103
9104 size = sizeof(str);
9105 db_get_value(hDB, hkey, "Condition", str, &size, TID_STRING, TRUE);
9106
9107 if (strstr(str, odbpath.c_str())) {
9108 if (strchr(str, '<')) {
9109 p = strchr(str, '<') + 1;
9110 if (*p == '=')
9111 p++;
9112 if (hp.enable_factor) {
9113 lower_limit[i] = (hp.vars[i].factor * (atof(p) - hp.vars[i].voffset) + hp.vars[i].offset);
9114 } else {
9115 lower_limit[i] = atof(p);
9116 }
9117 }
9118 if (strchr(str, '>')) {
9119 p = strchr(str, '>') + 1;
9120 if (*p == '=')
9121 p++;
9122 if (hp.enable_factor) {
9123 upper_limit[i] = (hp.vars[i].factor * (atof(p) - hp.vars[i].voffset) + hp.vars[i].offset);
9124 } else {
9125 upper_limit[i] = atof(p);
9126 }
9127 }
9128 }
9129 }
9130 }
9131 } // loop over variables
9132
9133 //starttime = now - scale + toffset;
9134 //endtime = now + toffset;
9135
9136 starttime = xendtime - scale;
9137 endtime = xendtime;
9138
9139 //printf("now %d, scale %d, xendtime %d, starttime %d, endtime %d\n", now, scale, xendtime, starttime, endtime);
9140
9141 flags = READ_HISTORY_DATA;
9142 if (hp.show_run_markers)
9143 flags |= READ_HISTORY_RUNMARKER;
9144
9145 status = read_history(hp, /*hDB, hgroup, hpanel,*/ index, flags, starttime, endtime, scale/1000+1, hsdata);
9146
9147 if (status != HS_SUCCESS) {
9148 sprintf(str, "Complete history failure, read_history() status %d, see messages", status);
9149 gdImageString(im, gdFontSmall, width / 2 - (strlen(str) * gdFontSmall->w) / 2, height / 2, str, red);
9150 goto error;
9151 }
9152
9153 DWORD n_point[MAX_VARS];
9154 char var_status[MAX_VARS][256];
9155
9156 for (int k=0; k<hsdata->nvars; k++) {
9157 int i = hsdata->odb_index[k];
9158
9159 if (i<0)
9160 continue;
9161
9162 if (index != -1 && index != i)
9163 continue;
9164
9165 n_point[i] = 0;
9166
9167 var_status[i][0] = 0;
9168 if (hsdata->status[k] == HS_UNDEFINED_VAR) {
9169 sprintf(var_status[i], "not found in history");
9170 continue;
9171 } else if (hsdata->status[k] != HS_SUCCESS) {
9172 sprintf(var_status[i], "hs_read() error %d, see messages", hsdata->status[k]);
9173 continue;
9174 }
9175
9176 int n_vp = 0;
9177 for (int j=0; j<hsdata->num_entries[k]; j++) {
9178 int xx = (int)(hsdata->t[k][j]);
9179 double yy = hsdata->v[k][j];
9180
9181 /* skip NaNs */
9182 if (ss_isnan(yy))
9183 continue;
9184
9185 /* skip INFs */
9186 if (!ss_isfin(yy))
9187 continue;
9188
9189 /* avoid overflow */
9190 if (yy > 1E30)
9191 yy = 1E30f;
9192
9193 /* apply factor and offset */
9194 if (hp.enable_factor) {
9195 yy = hp.vars[i].factor * (yy - hp.vars[i].voffset) + hp.vars[i].offset;
9196 }
9197
9198 /* calculate ymin and ymax */
9199 if ((i == 0 || index != -1) && n_vp == 0)
9200 ymin = ymax = yy;
9201 else {
9202 if (yy > ymax)
9203 ymax = yy;
9204 if (yy < ymin)
9205 ymin = yy;
9206 }
9207
9208 /* increment number of valid points */
9209
9210 x[i].push_back(xx);
9211 y[i].push_back(yy);
9212
9213 n_vp++;
9214
9215 } // loop over data
9216
9217 n_point[i] = n_vp;
9218
9219 assert(x[i].size() == y[i].size());
9220 }
9221
9222 //int flag;
9223 int xmaxm;
9224 int row;
9225 int xold;
9226 int yold;
9227 int aoffset;
9228 double yb1, yb2, yf1, yf2;
9229 int xs, ys;
9230 int x1, x2;
9231 int y1, y2;
9232 int xs_old;
9233 double ybase;
9234
9235 gdPoint poly[3];
9236
9237 if (ymin < minvalue)
9238 ymin = minvalue;
9239
9240 if (ymax > maxvalue)
9241 ymax = maxvalue;
9242
9243 /* check if ylow = 0 */
9244 if (index == -1) {
9245 //flag = 0;
9246 //size = sizeof(flag);
9247 //db_get_value(hDB, hkeypanel, "Zero ylow", &flag, &size, TID_BOOL, TRUE);
9248 if (hp.zero_ylow && ymin > 0)
9249 ymin = 0;
9250 }
9251
9252 /* if min and max too close together, switch to linear axis */
9253 if (logaxis && ymin > 0 && ymax > 0) {
9254 yb1 = pow(10, floor(log(ymin) / LN10));
9255 yf1 = floor(ymin / yb1);
9256 yb2 = pow(10, floor(log(ymax) / LN10));
9257 yf2 = floor(ymax / yb2);
9258
9259 if (yb1 == yb2 && yf1 == yf2)
9260 logaxis = 0;
9261 else {
9262 /* round down and up ymin and ymax */
9263 ybase = pow(10, floor(log(ymin) / LN10));
9264 ymin = (floor(ymin / ybase) * ybase);
9265 ybase = pow(10, floor(log(ymax) / LN10));
9266 ymax = ((floor(ymax / ybase) + 1) * ybase);
9267 }
9268 }
9269
9270 /* avoid negative limits for log axis */
9271 if (logaxis) {
9272 if (ymax <= 0)
9273 ymax = 1;
9274 if (ymin <= 0)
9275 ymin = 1E-12f;
9276 }
9277
9278 /* increase limits by 5% */
9279 if (ymin == 0 && ymax == 0) {
9280 ymin = -1;
9281 ymax = 1;
9282 } else {
9283 if (!logaxis) {
9284 ymax += (ymax - ymin) / 20.f;
9285
9286 if (ymin != 0)
9287 ymin -= (ymax - ymin) / 20.f;
9288 }
9289 }
9290
9291 /* avoid ymin == ymax */
9292 if (ymax == ymin) {
9293 if (logaxis) {
9294 ymax *= 2;
9295 ymin /= 2;
9296 } else {
9297 ymax += 10;
9298 ymin -= 10;
9299 }
9300 }
9301
9302 /* calculate X limits */
9303 //xmin = (double) (-scale / 3600.0 + toffset / 3600.0);
9304 //xmax = (double) (toffset / 3600.0);
9305 //xrange = xmax - xmin;
9306 //xrange = scale/3600.0;
9307
9308 /* caluclate required space for Y-axis */
9309 aoffset = vaxis(im, gdFontSmall, fgcol, gridcol, 0, 0, height, -3, -5, -7, -8, 0, ymin, ymax, logaxis);
9310 aoffset += 2;
9311
9312 x1 = aoffset;
9313 y1 = height - 20;
9314 x2 = width - 20;
9315 y2 = 20;
9316
9317 gdImageFilledRectangle(im, x1, y2, x2, y1, bgcol);
9318
9319 /* draw axis frame */
9320 taxis(im, gdFontSmall, fgcol, gridcol, x1, y1, x2 - x1, width, 3, 5, 9, 10, 0, (double)starttime, (double)endtime);
9321
9322 vaxis(im, gdFontSmall, fgcol, gridcol, x1, y1, y1 - y2, -3, -5, -7, -8, x2 - x1, ymin, ymax, logaxis);
9323 gdImageLine(im, x1, y2, x2, y2, fgcol);
9324 gdImageLine(im, x2, y2, x2, y1, fgcol);
9325
9326 xs = ys = xold = yold = 0;
9327
9328 /* old code for run markers, new code is below */
9329
9330 /* write run markes if selected */
9331 if (/* DISABLES CODE */ (0) && hp.show_run_markers) {
9332
9333 const char* event_names[] = {
9334 "Run transitions",
9335 "Run transitions",
9336 0 };
9337
9338 const char* tag_names[] = {
9339 "State",
9340 "Run number",
9341 0 };
9342
9343 const int tag_indexes[] = {
9344 0,
9345 0,
9346 0 };
9347
9348 int num_entries[3];
9349 time_t *tbuf[3];
9350 double *dbuf[3];
9351 int st[3];
9352
9353 num_entries[0] = 0;
9354 num_entries[1] = 0;
9355
9356 status = mh->hs_read(starttime - scale, endtime, 0,
9357 2, event_names, tag_names, tag_indexes,
9358 num_entries, tbuf, dbuf, st);
9359
9360 //printf("read run info: status %d, entries %d %d\n", status, num_entries[0], num_entries[1]);
9361
9362 int n_marker = num_entries[0];
9363
9364 if (status == HS_SUCCESS && n_marker > 0 && n_marker < 100) {
9365 xs_old = -1;
9366 xmaxm = x1;
9367 for (j = 0; j < (int) n_marker; j++) {
9368 int col;
9369
9370 // explicit algebra manipulation to clarify computations:
9371
9372 //xmin = (double) (-scale / 3600.0 + toffset / 3600.0);
9373 //xrange = scale/3600.0;
9374 //time_t starttime = now - scale + toffset;
9375
9376 //x_marker = (int)(tbuf[1][j] - now);
9377 //xs = (int) ((x_marker / 3600.0 - xmin) / xrange * (x2 - x1) + x1 + 0.5);
9378 //xs = (int) (((tbuf[1][j] - now) / 3600.0 - xmin) / xrange * (x2 - x1) + x1 + 0.5);
9379 //xs = (int) (((tbuf[1][j] - now) / 3600.0 - (-scale / 3600.0 + toffset / 3600.0)) / (scale/3600.0) * (x2 - x1) + x1 + 0.5);
9380 //xs = (int) (((tbuf[1][j] - now) - (-scale + toffset)) / (scale/1.0) * (x2 - x1) + x1 + 0.5);
9381 xs = (int) ((tbuf[1][j] - starttime) / (scale/1.0) * (x2 - x1) + x1 + 0.5);
9382
9383 if (xs < x1)
9384 continue;
9385 if (xs >= x2)
9386 continue;
9387
9388 double run_number = dbuf[1][j];
9389
9390 if (xs <= xs_old)
9391 xs = xs_old + 1;
9392 xs_old = xs;
9393
9394 if (dbuf[0][j] == 1)
9395 col = state_col[0];
9396 else if (dbuf[0][j] == 2)
9397 col = state_col[1];
9398 else if (dbuf[0][j] == 3)
9399 col = state_col[2];
9400 else
9401 col = state_col[0];
9402
9403 gdImageDashedLine(im, xs, y1, xs, y2, col);
9404
9405 sprintf(str, "%.0f", run_number);
9406
9407 if (dbuf[0][j] == STATE_RUNNING) {
9408 if (xs > xmaxm) {
9409 gdImageStringUp(im, gdFontSmall, xs + 0, y2 + 2 + gdFontSmall->w * strlen(str), str, fgcol);
9410 xmaxm = xs - 2 + gdFontSmall->h;
9411 }
9412 } else if (dbuf[0][j] == STATE_STOPPED) {
9413 if (xs + 2 - gdFontSmall->h > xmaxm) {
9414 gdImageStringUp(im, gdFontSmall, xs + 2 - gdFontSmall->h, y2 + 2 + gdFontSmall->w * strlen(str), str, fgcol);
9415 xmaxm = xs - 1;
9416 }
9417 }
9418 }
9419 }
9420
9421 if (num_entries[0]) {
9422 free(tbuf[0]);
9423 free(dbuf[0]);
9424 tbuf[0] = NULL;
9425 dbuf[0] = NULL;
9426 }
9427
9428 if (num_entries[1]) {
9429 free(tbuf[1]);
9430 free(dbuf[1]);
9431 tbuf[1] = NULL;
9432 dbuf[1] = NULL;
9433 }
9434 }
9435
9436 /* write run markes if selected */
9437 if (hp.show_run_markers) {
9438
9439 int index_state = -1;
9440 int index_run_number = -1;
9441
9442 for (int k=0; k<hsdata->nvars; k++) {
9443 if (hsdata->odb_index[k] == -1)
9444 index_state = k;
9445
9446 if (hsdata->odb_index[k] == -2)
9447 index_run_number = k;
9448 }
9449
9450 bool ok = true;
9451
9452 if (ok)
9453 ok = (index_state >= 0) && (index_run_number >= 0);
9454
9455 if (ok)
9456 ok = (hsdata->status[index_state] == HS_SUCCESS);
9457
9458 if (ok)
9459 ok = (hsdata->status[index_run_number] == HS_SUCCESS);
9460
9461 if (/* DISABLES CODE */ (0) && ok)
9462 printf("read run info: indexes: %d, %d, status: %d, %d, entries: %d, %d\n", index_state, index_run_number, hsdata->status[index_state], hsdata->status[index_run_number], hsdata->num_entries[index_state], hsdata->num_entries[index_run_number]);
9463
9464 if (ok)
9465 ok = (hsdata->num_entries[index_state] == hsdata->num_entries[index_run_number]);
9466
9467 int n_marker = hsdata->num_entries[index_state];
9468
9469 if (ok && n_marker > 0 && n_marker < 100) {
9470 xs_old = -1;
9471 xmaxm = x1;
9472 for (j = 0; j < (int) n_marker; j++) {
9473 int col;
9474
9475 // explicit algebra manipulation to clarify computations:
9476
9477 //xmin = (double) (-scale / 3600.0 + toffset / 3600.0);
9478 //xrange = scale/3600.0;
9479 //time_t starttime = now - scale + toffset;
9480
9481 //x_marker = (int)(tbuf[1][j] - now);
9482 //xs = (int) ((x_marker / 3600.0 - xmin) / xrange * (x2 - x1) + x1 + 0.5);
9483 //xs = (int) (((tbuf[1][j] - now) / 3600.0 - xmin) / xrange * (x2 - x1) + x1 + 0.5);
9484 //xs = (int) (((tbuf[1][j] - now) / 3600.0 - (-scale / 3600.0 + toffset / 3600.0)) / (scale/3600.0) * (x2 - x1) + x1 + 0.5);
9485 //xs = (int) (((tbuf[1][j] - now) - (-scale + toffset)) / (scale/1.0) * (x2 - x1) + x1 + 0.5);
9486 xs = (int) ((hsdata->t[index_state][j] - starttime) / (scale/1.0) * (x2 - x1) + x1 + 0.5);
9487
9488 if (xs < x1)
9489 continue;
9490 if (xs >= x2)
9491 continue;
9492
9493 double run_number = hsdata->v[index_run_number][j];
9494
9495 if (xs <= xs_old)
9496 xs = xs_old + 1;
9497 xs_old = xs;
9498
9499 int state = (int)hsdata->v[index_state][j];
9500
9501 if (state == 1)
9502 col = state_col[0];
9503 else if (state == 2)
9504 col = state_col[1];
9505 else if (state == 3)
9506 col = state_col[2];
9507 else
9508 col = state_col[0];
9509
9510 gdImageDashedLine(im, xs, y1, xs, y2, col);
9511
9512 sprintf(str, "%.0f", run_number);
9513
9514 if (state == STATE_RUNNING) {
9515 if (xs > xmaxm) {
9516 gdImageStringUp(im, gdFontSmall, xs + 0, y2 + 2 + gdFontSmall->w * strlen(str), str, fgcol);
9517 xmaxm = xs - 2 + gdFontSmall->h;
9518 }
9519 } else if (state == STATE_STOPPED) {
9520 if (xs + 2 - gdFontSmall->h > xmaxm) {
9521 gdImageStringUp(im, gdFontSmall, xs + 2 - gdFontSmall->h, y2 + 2 + gdFontSmall->w * strlen(str), str, fgcol);
9522 xmaxm = xs - 1;
9523 }
9524 }
9525 }
9526 }
9527 }
9528
9529 for (i = 0; i < (int)hp.vars.size(); i++) {
9530 if (index != -1 && index != i)
9531 continue;
9532
9533 /* draw alarm limits */
9534 if (lower_limit[i] != -12345) {
9535 if (logaxis) {
9536 if (lower_limit[i] <= 0)
9537 ys = y1;
9538 else
9539 ys = (int) (y1 - (log(lower_limit[i]) - log(ymin)) / (log(ymax) - log(ymin)) * (y1 - y2) + 0.5);
9540 } else {
9541 ys = (int) (y1 - (lower_limit[i] - ymin) / (ymax - ymin) * (y1 - y2) + 0.5);
9542 }
9543
9544 if (xs < 0)
9545 xs = 0;
9546 if (xs >= width)
9547 xs = width-1;
9548 if (ys < 0)
9549 ys = 0;
9550 if (ys >= height)
9551 ys = height-1;
9552
9553 if (ys > y2 && ys < y1) {
9554 gdImageDashedLine(im, x1, ys, x2, ys, curve_col[i]);
9555
9556 poly[0].x = x1;
9557 poly[0].y = ys;
9558 poly[1].x = x1 + 5;
9559 poly[1].y = ys;
9560 poly[2].x = x1;
9561 poly[2].y = ys - 5;
9562
9563 gdImageFilledPolygon(im, poly, 3, curve_col[i]);
9564 }
9565 }
9566 if (upper_limit[i] != -12345) {
9567 if (logaxis) {
9568 if (upper_limit[i] <= 0)
9569 ys = y1;
9570 else
9571 ys = (int) (y1 - (log(upper_limit[i]) - log(ymin)) / (log(ymax) - log(ymin)) * (y1 - y2) + 0.5);
9572 } else {
9573 ys = (int) (y1 - (upper_limit[i] - ymin) / (ymax - ymin) * (y1 - y2) + 0.5);
9574 }
9575
9576 if (xs < 0)
9577 xs = 0;
9578 if (xs >= width)
9579 xs = width-1;
9580 if (ys < 0)
9581 ys = 0;
9582 if (ys >= height)
9583 ys = height-1;
9584
9585 if (ys > y2 && ys < y1) {
9586 gdImageDashedLine(im, x1, ys, x2, ys, curve_col[i]);
9587
9588 poly[0].x = x1;
9589 poly[0].y = ys;
9590 poly[1].x = x1 + 5;
9591 poly[1].y = ys;
9592 poly[2].x = x1;
9593 poly[2].y = ys + 5;
9594
9595 gdImageFilledPolygon(im, poly, 3, curve_col[i]);
9596 }
9597 }
9598
9599 for (j = 0; j < (int) n_point[i]; j++) {
9600 //xmin = (double) (-scale / 3600.0 + toffset / 3600.0);
9601 //xrange = scale/3600.0;
9602 //xs = (int) (((x[i][j]-now) / 3600.0 - xmin) / xrange * (x2 - x1) + x1 + 0.5);
9603 //xs = (int) (((x[i][j] - now + scale - toffset) / 3600.0) / xrange * (x2 - x1) + x1 + 0.5);
9604 //xs = (int) (((x[i][j] - starttime) / 3600.0) / xrange * (x2 - x1) + x1 + 0.5);
9605 xs = (int) (((x[i][j] - starttime)/1.0) / (1.0*scale) * (x2 - x1) + x1 + 0.5);
9606
9607 if (logaxis) {
9608 if (y[i][j] <= 0)
9609 ys = y1;
9610 else
9611 ys = (int) (y1 - (log(y[i][j]) - log(ymin)) / (log(ymax) - log(ymin)) * (y1 - y2) + 0.5);
9612 } else {
9613 ys = (int) (y1 - (y[i][j] - ymin) / (ymax - ymin) * (y1 - y2) + 0.5);
9614 }
9615
9616 if (xs < 0)
9617 xs = 0;
9618 if (xs >= width)
9619 xs = width-1;
9620 if (ys < 0)
9621 ys = 0;
9622 if (ys >= height)
9623 ys = height-1;
9624
9625 if (j > 0)
9626 gdImageLine(im, xold, yold, xs, ys, curve_col[i]);
9627 xold = xs;
9628 yold = ys;
9629 }
9630
9631 if (n_point[i] > 0) {
9632 poly[0].x = xs;
9633 poly[0].y = ys;
9634 poly[1].x = xs + 12;
9635 poly[1].y = ys - 6;
9636 poly[2].x = xs + 12;
9637 poly[2].y = ys + 6;
9638
9639 gdImageFilledPolygon(im, poly, 3, curve_col[i]);
9640 }
9641 }
9642
9643 if (labels) {
9644 for (i = 0; i < (int)hp.vars.size(); i++) {
9645 if (index != -1 && index != i)
9646 continue;
9647
9648 //str[0] = 0;
9649 //status = db_find_key(hDB, hkeypanel, "Label", &hkeydvar);
9650 //if (status == DB_SUCCESS) {
9651 // size = sizeof(str);
9652 // status = db_get_data_index(hDB, hkeydvar, str, &size, i, TID_STRING);
9653 //}
9654
9655 std::string str = hp.vars[i].label.c_str();
9656
9657 if (str.empty()) {
9658 if (hp.enable_factor) {
9659 str = hp.vars[i].tag_name;
9660
9661 if (hp.vars[i].voffset > 0)
9662 str += msprintf(" - %G", hp.vars[i].voffset);
9663 else if (hp.vars[i].voffset < 0)
9664 str += msprintf(" + %G", -hp.vars[i].voffset);
9665
9666 if (hp.vars[i].factor != 1) {
9667 if (hp.vars[i].voffset == 0)
9668 str += msprintf(" * %+G", hp.vars[i].factor);
9669 else {
9670 str = msprintf("(%s) * %+G", str.c_str(), hp.vars[i].factor);
9671 }
9672 }
9673
9674 if (hp.vars[i].offset > 0)
9675 str += msprintf(" + %G", hp.vars[i].offset);
9676 else if (hp.vars[i].offset < 0)
9677 str += msprintf(" - %G", -hp.vars[i].offset);
9678
9679 } else {
9680 str = hp.vars[i].tag_name;
9681 }
9682 }
9683
9684 int k=0;
9685 for (int j=0; j<hsdata->nvars; j++)
9686 if (hsdata->odb_index[j] == i) {
9687 k = j;
9688 break;
9689 }
9690
9691 if (/* DISABLES CODE */ (0)) {
9692 printf("graph %d: odb index %d, n_point %d, num_entries %d, have_last_written %d %d, status %d, var_status [%s]\n", i, k, n_point[i], hsdata->num_entries[k], hsdata->have_last_written, (int)hsdata->last_written[k], hsdata->status[k], var_status[i]);
9693 }
9694
9695 if (hp.show_values) {
9696 char xstr[256];
9697 if (n_point[i] > 0) {
9698 sprintf(xstr," = %g", y[i][n_point[i]-1]);
9699 } else if (hsdata->num_entries[k] > 0) {
9700 sprintf(xstr," = all data is NaN or INF");
9701 } else if (hsdata->have_last_written) {
9702 if (hsdata->last_written[k]) {
9703 char ctimebuf[32];
9704 ctime_r(&hsdata->last_written[k], ctimebuf);
9705 sprintf(xstr," = last data %s", ctimebuf);
9706 // kill trailing '\n'
9707 char*s = strchr(xstr, '\n');
9708 if (s) *s=0;
9709 // clear the unnecessary error status report
9710 if (hsdata->status[k] == HS_UNDEFINED_VAR)
9711 var_status[i][0] = 0;
9712 } else {
9713 sprintf(xstr," = no data ever");
9714 }
9715 } else {
9716 sprintf(xstr," = no data");
9717 }
9718 str += xstr;
9719 }
9720
9721 if (strlen(var_status[i]) > 1) {
9722 str += msprintf(" (%s)", var_status[i]);
9723 }
9724
9725 row = index == -1 ? i : 0;
9726
9728 x1 + 10,
9729 y2 + 10 + row * (gdFontMediumBold->h + 10),
9730 x1 + 10 + str.length() * gdFontMediumBold->w + 10,
9731 y2 + 10 + row * (gdFontMediumBold->h + 10) +
9732 gdFontMediumBold->h + 2 + 2, white);
9733 gdImageRectangle(im, x1 + 10, y2 + 10 + row * (gdFontMediumBold->h + 10),
9734 x1 + 10 + str.length() * gdFontMediumBold->w + 10,
9735 y2 + 10 + row * (gdFontMediumBold->h + 10) +
9736 gdFontMediumBold->h + 2 + 2, curve_col[i]);
9737
9739 x1 + 10 + 5, y2 + 10 + 2 + row * (gdFontMediumBold->h + 10),
9740 (char*)str.c_str(),
9741 curve_col[i]);
9742 }
9743 }
9744
9745 gdImageRectangle(im, x1, y2, x2, y1, fgcol);
9746
9747 error:
9748
9749 /* generate GIF */
9750 gdImageInterlace(im, 1);
9751 gdImageGif(im, &gb);
9752 gdImageDestroy(im);
9753 length = gb.size;
9754
9755 if (buffer == NULL) {
9756 rr->rsprintf("HTTP/1.1 200 Document follows\r\n");
9757 rr->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
9758
9759 rr->rsprintf("Content-Type: image/gif\r\n");
9760 rr->rsprintf("Content-Length: %d\r\n", length);
9761 rr->rsprintf("Cache-control: private, max-age=0, no-cache\r\n");
9762 rr->rsprintf("Expires: Fri, 01-Jan-1983 00:00:00 GMT\r\n\r\n");
9763
9764 rr->rmemcpy(gb.data, length);
9765 } else {
9766 if (length > *buffer_size) {
9767 printf("return buffer too small\n");
9768 return;
9769 }
9770
9771 memcpy(buffer, gb.data, length);
9772 *buffer_size = length;
9773 }
9774}
virtual int hs_read(time_t start_time, time_t end_time, time_t interval, int num_var, const char *const event_name[], const char *const tag_name[], const int var_index[], int num_entries[], time_t *time_buffer[], double *data_buffer[], int status[])=0
see hs_read(), returns HS_SUCCESS
void rmemcpy(const void *buf, int len)
Definition mhttpd.cxx:608
#define HS_UNDEFINED_VAR
Definition midas.h:734
unsigned int DWORD
Definition mcstd.h:51
#define STATE_STOPPED
Definition midas.h:305
#define STATE_RUNNING
Definition midas.h:307
void gdImageFilledPolygon(gdImagePtr im, gdPointPtr p, int n, int c)
Definition mgd.cxx:2471
void gdImageRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color)
Definition mgd.cxx:2299
gdImagePtr gdImageCreate(int sx, int sy)
Definition mgd.cxx:417
void gdImageString(gdImagePtr im, gdFontPtr f, int x, int y, const char *s, int color)
Definition mgd.cxx:877
void gdImageFilledRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color)
Definition mgd.cxx:2307
void gdImageLine(gdImagePtr im, int x1, int y1, int x2, int y2, int color)
Definition mgd.cxx:638
int x
Definition mgd.h:121
char * data
Definition mgd.h:54
int w
Definition mgd.h:64
void gdImageStringUp(gdImagePtr im, gdFontPtr f, int x, int y, const char *s, int color)
Definition mgd.cxx:888
void gdImageDestroy(gdImagePtr im)
Definition mgd.cxx:439
gdFontPtr gdFontMediumBold
Definition mgd.cxx:408
int h
Definition mgd.h:65
gdFontPtr gdFontGiant
Definition mgd.cxx:409
void gdImageGif(gdImagePtr im, gdGifBuffer *buffer)
Definition mgd.cxx:1118
void gdImageDashedLine(gdImagePtr im, int x1, int y1, int x2, int y2, int color)
Definition mgd.cxx:738
int gdImageColorAllocate(gdImagePtr im, int r, int g, int b)
Definition mgd.cxx:492
void gdImageInterlace(gdImagePtr im, int interlaceArg)
Definition mgd.cxx:2619
int y
Definition mgd.h:121
gdFontPtr gdFontSmall
Definition mgd.cxx:410
void gdImageColorTransparent(gdImagePtr im, int color)
Definition mgd.cxx:533
int ss_isnan(double x)
Definition system.cxx:8039
int ss_isfin(double x)
Definition system.cxx:8044
INT db_get_path(HNDLE hDB, HNDLE hKey, char *path, INT buf_size)
Definition odb.cxx:4775
INT run_number[2]
Definition mana.cxx:246
#define LN10
Definition mhttpd.cxx:7661
#define MAX_VARS
Definition mhttpd.cxx:53
int vaxis(gdImagePtr im, gdFont *font, int col, int gcol, int x1, int y1, int width, int minor, int major, int text, int label, int grid, double ymin, double ymax, BOOL logaxis)
Definition mhttpd.cxx:7939
void taxis(gdImagePtr im, gdFont *font, int col, int gcol, int x1, int y1, int width, int xr, int minor, int major, int text, int label, int grid, double xmin, double xmax)
Definition mhttpd.cxx:7818
#define READ_HISTORY_DATA
Definition mhttpd.cxx:8353
static MidasHistoryInterface * get_history(bool reset=false)
Definition mhttpd.cxx:8190
#define READ_HISTORY_RUNMARKER
Definition mhttpd.cxx:8354
MidasHistoryInterface * mh
INT k
Definition odbhist.cxx:40
std::string timescale
Definition mhttpd.cxx:8373
bool enable_factor
Definition mhttpd.cxx:8382
double minimum
Definition mhttpd.cxx:8374
double maximum
Definition mhttpd.cxx:8375
bool zero_ylow
Definition mhttpd.cxx:8376
bool show_values
Definition mhttpd.cxx:8379
bool log_axis
Definition mhttpd.cxx:8377
int * status
Definition mhttpd.cxx:8280
bool have_last_written
Definition mhttpd.cxx:8285
time_t * last_written
Definition mhttpd.cxx:8286
Definition mgd.h:120
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_content_type()

std::string get_content_type ( const char *  filename)

Definition at line 1165 of file mhttpd.cxx.

1166{
1167 std::string ext_upper;
1168 const char* p = filename;
1169 const char* last_dot = NULL;
1170 for (; *p; p++) {
1171 if (*p == '.')
1172 last_dot = p;
1173 if (*p == DIR_SEPARATOR)
1174 last_dot = NULL;
1175 }
1176
1177 if (last_dot) {
1178 p = last_dot;
1179 for (; *p; p++)
1180 ext_upper += toupper(*p);
1181 }
1182
1183 //printf("filename: [%s], ext [%s]\n", filename, ext_upper.c_str());
1184
1185 std::string type = GetMimetype(ext_upper);
1186 if (type.length() > 0)
1187 return type;
1188
1189 cm_msg(MERROR, "get_content_type", "Unknown HTTP Content-Type for resource file \'%s\', file extension \'%s\'", filename, ext_upper.c_str());
1190
1191 return "text/plain";
1192}
static std::string GetMimetype(const std::string &ext)
Definition mhttpd.cxx:181
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_elog_url()

void get_elog_url ( char *  url,
int  len 
)
Here is the caller graph for this function:

◆ get_hist_last_written()

int get_hist_last_written ( MVOdb *  odb,
const char *  group,
const char *  panel,
time_t  endtime,
int  index,
int  want_all,
time_t *  plastwritten 
)

Definition at line 8554 of file mhttpd.cxx.

8555{
8556 //HNDLE hDB;
8557 int status;
8558
8559 time_t now = ss_time();
8560
8561 if (endtime == 0)
8562 endtime = now;
8563
8564 HistoryData hsxxx;
8565 HistoryData* hsdata = &hsxxx;
8566
8567 //cm_get_experiment_database(&hDB, NULL);
8568
8569 HistPlot hp;
8570 LoadHistPlotFromOdb(odb, &hp, group, panel);
8571
8572 double tstart = ss_millitime();
8573
8574 int flags = READ_HISTORY_LAST_WRITTEN;
8575
8576 status = read_history(hp, /*hDB, group, panel,*/ index, flags, endtime, endtime, 0, hsdata);
8577
8578 if (status != HS_SUCCESS) {
8579 //sprintf(str, "Complete history failure, read_history() status %d, see messages", status);
8580 return status;
8581 }
8582
8583 if (!hsdata->have_last_written) {
8584 //sprintf(str, "Complete history failure, read_history() status %d, see messages", status);
8585 return HS_FILE_ERROR;
8586 }
8587
8588 int count = 0;
8589 time_t tmin = endtime;
8590 time_t tmax = 0;
8591
8592 for (int k=0; k<hsdata->nvars; k++) {
8593 int i = hsdata->odb_index[k];
8594
8595 if (i<0)
8596 continue;
8597 if (index != -1 && index != i)
8598 continue;
8599
8600 time_t lw = hsdata->last_written[k];
8601
8602 if (lw==0) // no last_written for this variable, skip it.
8603 continue;
8604
8605 if (lw > endtime)
8606 lw = endtime; // just in case hs_get_last_written() returns dates in the "future" for this plot
8607
8608 if (lw > tmax)
8609 tmax = lw;
8610
8611 if (lw < tmin)
8612 tmin = lw;
8613
8614 count++;
8615
8616 //printf("odb index %d, last_written[%d] = %.0f, tmin %.0f, tmax %.0f, endtime %.0f\n", i, k, (double)lw, (double)tmin, (double)tmax, (double)endtime);
8617 }
8618
8619 if (count == 0) // all variables have no last_written
8620 return HS_FILE_ERROR;
8621
8622 if (want_all)
8623 *plastwritten = tmin; // all variables have data
8624 else
8625 *plastwritten = tmax; // at least one variable has data
8626
8627 //printf("tmin %.0f, tmax %.0f, endtime %.0f, last written %.0f\n", (double)tmin, (double)tmax, (double)endtime, (double)*plastwritten);
8628
8629 double tend = ss_millitime();
8630
8631 if (/* DISABLES CODE */ (0))
8632 printf("get_hist_last_written: elapsed time %f ms\n", tend-tstart);
8633
8634 return HS_SUCCESS;
8635}
#define HS_FILE_ERROR
Definition midas.h:729
DWORD ss_millitime()
Definition system.cxx:3465
#define READ_HISTORY_LAST_WRITTEN
Definition mhttpd.cxx:8355
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_history()

static MidasHistoryInterface * get_history ( bool  reset = false)
static

Definition at line 8190 of file mhttpd.cxx.

8191{
8192 int status;
8193 HNDLE hDB;
8194
8195 // history reconnect requested by watch callback?
8196
8197 if (gDoReloadHistory) {
8198 gDoReloadHistory = false;
8199 reset = true;
8200 }
8201
8202 // disconnect from previous history
8203
8204 if (reset && gMh) {
8205 gMh->hs_disconnect();
8206 delete gMh;
8207 gMh = NULL;
8208 gMhkey = 0;
8209 }
8210
8212 assert(status == CM_SUCCESS);
8213
8214 // setup a watch on history configuration
8215
8217 HNDLE hKey;
8218 gDoSetupHistoryWatch = false;
8219
8220 status = db_find_key(hDB, 0, "/Logger/History", &hKey);
8221 if (status == DB_SUCCESS)
8223
8224 status = db_find_key(hDB, 0, "/History/LoggerHistoryChannel", &hKey);
8225 if (status == DB_SUCCESS)
8227 }
8228
8229 // find out if ODB settings have changed and we need to connect to a different history channel
8230
8231 HNDLE hKey = 0;
8233 if (status != HS_SUCCESS)
8234 return gMh;
8235
8236 //printf("mh %p, hKey %d, mhkey %d\n", mh, hKey, mhkey);
8237
8238 if (gMh && hKey == gMhkey) // same channel as before
8239 return gMh;
8240
8241 if (gMh) {
8242 delete gMh;
8243 gMh = NULL;
8244 gMhkey = 0;
8245 }
8246
8248 if (status != HS_SUCCESS || gMh==NULL) {
8249 cm_msg(MERROR, "get_history", "Cannot configure history, hs_get_history() status %d", status);
8250 gMh = NULL;
8251 return NULL;
8252 }
8253
8254 gMhkey = hKey;
8255
8256 // cm_msg(MINFO, "get_history", "Reading history from channel \'%s\' type \'%s\'", mh->name, mh->type);
8257
8258 return gMh;
8259}
virtual int hs_disconnect()=0
disconnect from history, returns HS_SUCCESS
INT db_watch(HNDLE hDB, HNDLE hKey, void(*dispatcher)(INT, INT, INT, void *), void *info)
Definition odb.cxx:13845
#define HS_GET_INACTIVE
Definition history.h:37
#define HS_GET_READER
Definition history.h:35
int hs_find_reader_channel(HNDLE hDB, HNDLE *hKeyOut, int debug_flag)
int hs_get_history(HNDLE hDB, HNDLE hKey, int flags, int debug_flag, MidasHistoryInterface **mh)
static void history_watch_callback(HNDLE hDB, HNDLE hKey, int index, void *info)
Definition mhttpd.cxx:8178
static HNDLE gMhkey
Definition mhttpd.cxx:8186
static bool gDoReloadHistory
Definition mhttpd.cxx:8176
static MidasHistoryInterface * gMh
Definition mhttpd.cxx:8185
static bool gDoSetupHistoryWatch
Definition mhttpd.cxx:8175
static BOOL verbose
Definition mhttpd.cxx:96
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_http_trace()

static MJsonNode * get_http_trace ( const MJsonNode *  params)
static

Definition at line 16221 of file mhttpd.cxx.

16222{
16223 if (!params) {
16224 MJSO *doc = MJSO::I();
16225 doc->D("get current value of mhttpd http_trace");
16226 doc->P(NULL, 0, "there are no input parameters");
16227 doc->R(NULL, MJSON_INT, "current value of http_trace");
16228 return doc;
16229 }
16230
16231 return mjsonrpc_make_result("http_trace", MJsonNode::MakeInt(http_trace));
16232}
void D(const char *description)
Definition mjsonrpc.cxx:303
void P(const char *name, int mjson_type, const char *description)
Definition mjsonrpc.cxx:340
MJsonNode * mjsonrpc_make_result(MJsonNode *node)
Definition mjsonrpc.cxx:135
static MJSO * I()
Definition mjsonrpc.cxx:298
void R(const char *name, int mjson_type, const char *description)
Definition mjsonrpc.cxx:348
static int http_trace
Definition mhttpd.cxx:465
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_resource_paths()

std::vector< std::string > get_resource_paths ( )

Definition at line 1021 of file mhttpd.cxx.

1022{
1023 HNDLE hDB;
1024 int status;
1025
1027
1028 std::vector<std::string> paths;
1029
1030 // add /Experiment/Resources
1031 std::string buf;
1032 status = db_get_value_string(hDB, 0, "/Experiment/Resources", 0, &buf, TRUE);
1033 if (status == DB_SUCCESS && buf.length() > 0)
1034 paths.push_back(buf);
1035
1036 // add "/Logger/History/IMAGE/History dir"
1037 paths.push_back(cm_get_history_path("IMAGE"));
1038
1039 // add /Logger/Data dir
1040 status = db_get_value_string(hDB, 0, "/Logger/Data dir", 0, &buf, TRUE);
1041 if (status == DB_SUCCESS && buf.length() > 0)
1042 paths.push_back(buf);
1043
1044 std::string cwd = ss_getcwd();
1045 if (!cwd.empty()) {
1046 paths.push_back(cwd + "/");
1047 paths.push_back(cwd + "/resources/");
1048 }
1049 paths.push_back(cm_get_path());
1050 paths.push_back(cm_get_path() + "resources/");
1051 char *m = getenv("MIDASSYS");
1052 if (m) {
1053 paths.push_back(std::string(m) + "/resources/");
1054 }
1055
1056 return paths;
1057}
std::string cm_get_history_path(const char *history_channel)
Definition midas.cxx:5861
std::string ss_getcwd()
Definition system.cxx:5848
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetMimetype()

static std::string GetMimetype ( const std::string &  ext)
static

Definition at line 181 of file mhttpd.cxx.

182{
183 if (gMimeTypesOdb) {
184 std::string mimetype;
185 gMimeTypesOdb->RS(ext.c_str(), &mimetype);
186 if (mimetype.length() > 0) {
187 //printf("GetMimetype: %s -> %s from ODB\n", ext.c_str(), mimetype.c_str());
188 return mimetype;
189 }
190 }
191
192 for (int i=0; gMimetypeTable[i].ext[0]; i++) {
193 if (ext == gMimetypeTable[i].ext) {
194 //printf("GetMimetype: %s -> %s from built-in table\n", ext.c_str(), gMimetypeTable[i].mimetype.c_str());
195 return gMimetypeTable[i].mimetype;
196 }
197 }
198
199 //printf("GetMimetype: %s -> not found\n", ext.c_str());
200 return "";
201}
static MVOdb * gMimeTypesOdb
Definition mhttpd.cxx:179
const MimetypeTableEntry gMimetypeTable[]
Definition mhttpd.cxx:130
std::string mimetype
Definition mhttpd.cxx:127
std::string ext
Definition mhttpd.cxx:126
Here is the caller graph for this function:

◆ GetTimeSec()

static double GetTimeSec ( )
static

Definition at line 406 of file mhttpd.cxx.

407{
408 struct timeval tv;
409 gettimeofday(&tv, NULL);
410 return tv.tv_sec*1.0 + tv.tv_usec/1000000.0;
411}
int gettimeofday(struct timeval *tp, void *tzp)
timeval tv
Definition msysmon.cxx:1095
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_decode_get()

static int handle_decode_get ( struct mg_connection nc,
const http_message msg,
const char *  uri,
const char *  query_string,
RequestTrace t 
)
static

Definition at line 14290 of file mhttpd.cxx.

14291{
14292 Cookies cookies;
14293
14294 decode_cookies(&cookies, msg);
14295
14296 // lock shared structures
14297
14298#ifdef HAVE_MONGOOSE6
14299 int status = ss_mutex_wait_for(request_mutex, 0);
14300 assert(status == SS_SUCCESS);
14301#endif
14302
14303 //t->fTimeLocked = GetTimeSec();
14304
14305 // prepare return buffer
14306
14307 Return *rr = new Return();
14308
14309 rr->zero();
14310
14311 // call midas
14312
14313 decode_get(rr, NULL, &cookies, uri, query_string, t);
14314
14315 if (trace_mg)
14316 printf("handle_decode_get: return buffer length %d bytes, strlen %d\n", rr->return_length, (int)strlen(rr->return_buffer));
14317
14319
14320 if (rr->return_length == -1) {
14321 delete rr;
14322#ifdef HAVE_MONGOOSE6
14323 //t->fTimeUnlocked = GetTimeSec();
14324 ss_mutex_release(request_mutex);
14325#endif
14326 return RESPONSE_501;
14327 }
14328
14329 if (rr->return_length == 0)
14330 rr->return_length = strlen(rr->return_buffer);
14331
14332 //t->fTimeUnlocked = GetTimeSec();
14333
14334#ifdef HAVE_MONGOOSE6
14335 ss_mutex_release(request_mutex);
14336#endif
14337
14338 mg_send(nc, rr->return_buffer, rr->return_length);
14339
14340 if (!strstr(rr->return_buffer, "Content-Length")) {
14341 // cannot do pipelined http if response generated by mhttpd
14342 // decode_get() has no Content-Length header.
14343 // must close the connection.
14345 }
14346
14347 t->fTimeSent = GetTimeSec();
14348
14349 delete rr;
14350
14351 return RESPONSE_SENT;
14352}
double fTimeSent
Definition mhttpd.cxx:422
double fTimeProcessed
Definition mhttpd.cxx:421
void zero()
Definition mhttpd.cxx:579
int return_length
Definition mhttpd.cxx:551
char * return_buffer
Definition mhttpd.cxx:548
#define SS_SUCCESS
Definition midas.h:664
void mg_send(struct mg_connection *, const void *buf, int len)
unsigned long flags
Definition mongoose6.h:1276
#define MG_F_SEND_AND_CLOSE
Definition mongoose6.h:1288
INT ss_mutex_release(MUTEX_T *mutex)
Definition system.cxx:3229
INT ss_mutex_wait_for(MUTEX_T *mutex, INT timeout)
Definition system.cxx:3109
static bool trace_mg
Definition mhttpd.cxx:13737
#define RESPONSE_501
Definition mhttpd.cxx:14288
void decode_cookies(Cookies *c, const http_message *msg)
Definition mhttpd.cxx:14239
void decode_get(Return *rr, char *string, const Cookies *c, const char *url, const char *query_string, RequestTrace *t)
Definition mhttpd.cxx:13227
#define RESPONSE_SENT
Definition mhttpd.cxx:14286
static double GetTimeSec()
Definition mhttpd.cxx:406
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_decode_post()

static int handle_decode_post ( struct mg_connection nc,
const http_message msg,
const char *  uri,
const char *  query_string,
RequestTrace t 
)
static

Definition at line 14760 of file mhttpd.cxx.

14761{
14762
14763 char boundary[256];
14764 boundary[0] = 0;
14765 const std::string ct = find_header_mg(msg, "Content-Type");
14766 if (ct.length() > 0) {
14767 const char* s = strstr(ct.c_str(), "boundary=");
14768 if (s)
14769 mstrlcpy(boundary, s+9, sizeof(boundary));
14770 }
14771
14772#ifdef HAVE_MONGOOSE616
14773 if (multithread_mg)
14774 return queue_decode_post(nc, msg, boundary, uri, query_string, t);
14775#endif
14776
14777 Cookies cookies;
14778
14779 decode_cookies(&cookies, msg);
14780
14781 const char* post_data = msg->body.p;
14782 int post_data_len = msg->body.len;
14783
14784 // lock shared strctures
14785
14786#ifdef HAVE_MONGOOSE6
14787 int status = ss_mutex_wait_for(request_mutex, 0);
14788 assert(status == SS_SUCCESS);
14789#endif
14790
14791 // prepare return buffer
14792
14793 Return* rr = new Return;
14794
14795 rr->zero();
14796
14797 //printf("post_data_len %d, data [%s], boundary [%s]\n", post_data_len, post_data, boundary);
14798
14799 decode_post(rr, NULL, (char*)post_data, boundary, post_data_len, &cookies, uri, t);
14800
14801 if (trace_mg)
14802 printf("handle_decode_post: return buffer length %d bytes, strlen %d\n", rr->return_length, (int)strlen(rr->return_buffer));
14803
14804 if (rr->return_length == -1) {
14805#ifdef HAVE_MONGOOSE6
14806 ss_mutex_release(request_mutex);
14807#endif
14808 delete rr;
14809 return RESPONSE_501;
14810 }
14811
14812 if (rr->return_length == 0)
14813 rr->return_length = strlen(rr->return_buffer);
14814
14815#ifdef HAVE_MONGOOSE6
14816 ss_mutex_release(request_mutex);
14817#endif
14818
14819 mg_send(nc, rr->return_buffer, rr->return_length);
14820
14821 if (!strstr(rr->return_buffer, "Content-Length")) {
14822 // cannot do pipelined http if response generated by mhttpd
14823 // decode_get() has no Content-Length header.
14824 // must close the connection.
14826 }
14827
14828 delete rr;
14829
14830 return RESPONSE_SENT;
14831}
struct mg_str body
Definition mongoose6.h:2094
void decode_post(Return *rr, const char *header, const char *string, const char *boundary, int length, const Cookies *c, const char *url, RequestTrace *t)
Definition mhttpd.cxx:13265
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_event_mg()

static void handle_event_mg ( struct mg_connection nc,
int  ev,
void *  ev_data 
)
static

Definition at line 14205 of file mhttpd.cxx.

14206{
14207 struct mbuf *io = &nc->recv_mbuf;
14208 switch (ev) {
14209 case MG_EV_POLL: // periodic call from loop_mg() via mg_mgr_poll()
14210 break;
14211 case MG_EV_ACCEPT:
14212 if (trace_mg)
14213 printf("handle_event_mg: nc %p, ev %d, ev_data %p -> accept\n", nc, ev, ev_data);
14214 break;
14215 case MG_EV_RECV:
14216 if (trace_mg)
14217 printf("handle_event_mg: nc %p, ev %d, ev_data %p -> recv %d, buffered %d bytes\n", nc, ev, ev_data, *(int*)ev_data, (int)io->len);
14218#if 0
14219 // This event handler implements simple TCP echo server
14220 mg_send(nc, io->buf, io->len); // Echo received data back
14221 mbuf_remove(io, io->len); // Discard data from recv buffer
14222#endif
14223 break;
14224 case MG_EV_SEND:
14225 if (trace_mg)
14226 printf("handle_event_mg: nc %p, ev %d, ev_data %p -> send %d bytes\n", nc, ev, ev_data, *(int*)ev_data);
14227 break;
14228 case MG_EV_CLOSE:
14229 if (trace_mg)
14230 printf("handle_event_mg: nc %p, ev %d, ev_data %p -> close\n", nc, ev, ev_data);
14231 break;
14232 default:
14233 if (trace_mg)
14234 printf("handle_event_mg: nc %p, ev %d, ev_data %p\n", nc, ev, ev_data);
14235 break;
14236 }
14237}
void mbuf_remove(struct mbuf *, size_t data_size)
#define MG_EV_RECV
Definition mongoose6.h:1222
size_t len
Definition mongoose6.h:835
struct mbuf recv_mbuf
Definition mongoose6.h:1255
#define MG_EV_POLL
Definition mongoose6.h:1219
#define MG_EV_SEND
Definition mongoose6.h:1223
char * buf
Definition mongoose6.h:834
#define MG_EV_CLOSE
Definition mongoose6.h:1224
#define MG_EV_ACCEPT
Definition mongoose6.h:1220
Here is the call graph for this function:

◆ handle_http_get()

static int handle_http_get ( struct mg_connection nc,
const http_message msg,
const char *  uri,
RequestTrace t 
)
static

Definition at line 14833 of file mhttpd.cxx.

14834{
14835 std::string query_string = mgstr(&msg->query_string);
14836
14837 if (trace_mg||verbose_mg)
14838 printf("handle_http_get: uri [%s], query [%s]\n", uri, query_string.c_str());
14839
14840 if (query_string == "mjsonrpc_schema") {
14841 MJsonNode* s = mjsonrpc_get_schema();
14842 std::string reply = s->Stringify();
14843 delete s;
14844
14845 int reply_length = reply.length();
14846
14847 const std::string origin_header = find_header_mg(msg, "Origin");
14848
14849 std::string headers;
14850 headers += "HTTP/1.1 200 OK\n";
14851 if (origin_header.length() > 0)
14852 headers += "Access-Control-Allow-Origin: " + std::string(origin_header) + "\n";
14853 else
14854 headers += "Access-Control-Allow-Origin: *\n";
14855 headers += "Access-Control-Allow-Credentials: true\n";
14856 headers += "Content-Length: " + toString(reply_length) + "\n";
14857 headers += "Content-Type: application/json\n";
14858 //headers += "Date: Sat, 08 Jul 2006 12:04:08 GMT\n";
14859
14860 //printf("sending headers: %s\n", headers.c_str());
14861 //printf("sending reply: %s\n", reply.c_str());
14862
14863 std::string send = headers + "\n" + reply;
14864
14866
14867 mg_send(nc, send.c_str(), send.length());
14868
14869 t->fTimeSent = GetTimeSec();
14870
14871 return RESPONSE_SENT;
14872 }
14873
14874 if (query_string == "mjsonrpc_schema_text") {
14875 MJsonNode* s = mjsonrpc_get_schema();
14876 std::string reply = mjsonrpc_schema_to_text(s);
14877 delete s;
14878
14879 int reply_length = reply.length();
14880
14881 const std::string origin_header = find_header_mg(msg, "Origin");
14882
14883 std::string headers;
14884 headers += "HTTP/1.1 200 OK\n";
14885 if (origin_header.length() > 0)
14886 headers += "Access-Control-Allow-Origin: " + std::string(origin_header) + "\n";
14887 else
14888 headers += "Access-Control-Allow-Origin: *\n";
14889 headers += "Access-Control-Allow-Credentials: true\n";
14890 headers += "Content-Length: " + toString(reply_length) + "\n";
14891 headers += "Content-Type: text/plain\n";
14892 //headers += "Date: Sat, 08 Jul 2006 12:04:08 GMT\n";
14893
14894 //printf("sending headers: %s\n", headers.c_str());
14895 //printf("sending reply: %s\n", reply.c_str());
14896
14897 std::string send = headers + "\n" + reply;
14898
14900
14901 mg_send(nc, send.c_str(), send.length());
14902
14903 t->fTimeSent = GetTimeSec();
14904
14905 return RESPONSE_SENT;
14906 }
14907
14908#ifdef HAVE_MONGOOSE616
14909 if (multithread_mg)
14910 return queue_decode_get(nc, msg, uri, query_string.c_str(), t);
14911#endif
14912
14913 return handle_decode_get(nc, msg, uri, query_string.c_str(), t);
14914}
MJsonNode * mjsonrpc_get_schema()
std::string mjsonrpc_schema_to_text(const MJsonNode *schema)
static bool verbose_mg
Definition mhttpd.cxx:13736
static int handle_decode_get(struct mg_connection *nc, const http_message *msg, const char *uri, const char *query_string, RequestTrace *t)
Definition mhttpd.cxx:14290
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_http_message()

static void handle_http_message ( struct mg_connection nc,
http_message msg 
)
static

Definition at line 15112 of file mhttpd.cxx.

15113{
15114 std::string method = mgstr(&msg->method);
15115 std::string query_string = mgstr(&msg->query_string);
15116 std::string uri_encoded = mgstr(&msg->uri);
15117 std::string uri = UrlDecode(uri_encoded.c_str());
15118 mg_str* user_mg_str = mg_get_http_header(msg, "X-Remote-User");
15119 std::string user;
15120
15121 if (user_mg_str)
15122 user = mgstr(user_mg_str);
15123
15124 if (trace_mg)
15125 printf("handle_http_message: method [%s] uri [%s] proto [%s] user [%s]\n", method.c_str(), uri.c_str(), mgstr(&msg->proto).c_str(), user.c_str());
15126
15127 RequestTrace* t = new RequestTrace;
15129 t->fMethod = method;
15130 t->fUri = uri;
15131 t->fQuery = query_string;
15132
15133 // process OPTIONS for Cross-origin (CORS) preflight request
15134 // see https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
15135 if (method == "OPTIONS" && query_string == "mjsonrpc" && mg_get_http_header(msg, "Access-Control-Request-Method") != NULL) {
15136 handle_http_options_cors(nc, msg, t);
15137 t->fCompleted = true;
15139 return;
15140 }
15141
15143 std::string username = check_digest_auth(msg, gAuthMg);
15144
15145 // Cannot re-read the password file - it is not thread safe to do so
15146 // unless I lock gAuthMg for each call check_digest_auth() and if I do so,
15147 // I will serialize (single-thread) all the http requests and defeat
15148 // the whole point of multithreading the web server. K.O.
15149 //
15151 //if (username.length() < 1) {
15152 // bool ok = read_passwords(&gAuthMg);
15153 // if (ok)
15154 // username = check_digest_auth(msg, &gAuthMg);
15155 //}
15156
15157 if (trace_mg)
15158 printf("handle_http_message: auth user: \"%s\"\n", username.c_str());
15159
15160 if (username.length() == 0) {
15161 if (trace_mg||verbose_mg)
15162 printf("handle_http_message: method [%s] uri [%s] query [%s] proto [%s], sending auth request for realm \"%s\"\n", method.c_str(), uri.c_str(), query_string.c_str(), mgstr(&msg->proto).c_str(), gAuthMg->realm.c_str());
15163
15165 t->fCompleted = true;
15167 return;
15168 }
15169 t->fAuthOk = true;
15170 } else {
15171 t->fAuthOk = true;
15172 }
15173
15174#ifdef HAVE_MONGOOSE616
15175 if (gProxyOdb && starts_with(uri, "/proxy/")) {
15176 std::string::size_type p1 = uri.find("/", 1);
15177 if (p1 == uri.length()-1) {
15178 std::string response = "404 Not Found (Proxy name is missing)";
15179 mg_send_head(nc, 404, response.length(), NULL);
15180 mg_send(nc, response.c_str(), response.length());
15181 delete t;
15182 return;
15183 }
15184 std::string::size_type p2 = uri.find("/", p1+1);
15185 if (p2 == std::string::npos) {
15186 std::string response = "404 Not Found (Proxy URL should end with a slash)";
15187 mg_send_head(nc, 404, response.length(), NULL);
15188 mg_send(nc, response.c_str(), response.length());
15189 delete t;
15190 return;
15191 }
15192 std::string p = uri.substr(p1+1, p2-p1-1);
15193 //printf("uri [%s], p1: %d, p2: %d, substr: [%s]\n", uri.c_str(), (int)p1, (int)p2, p.c_str());
15194 if (p.length() < 1) {
15195 std::string response = "404 Not Found (Double-slash or Proxy name is too short)";
15196 mg_send_head(nc, 404, response.length(), NULL);
15197 mg_send(nc, response.c_str(), response.length());
15198 delete t;
15199 return;
15200 }
15201 std::string destination;
15202 gProxyOdb->RS(p.c_str(), &destination);
15203 if (destination.length() < 1) {
15204 std::string response = "404 Not Found (Proxy not found in ODB)";
15205 mg_send_head(nc, 404, response.length(), NULL);
15206 mg_send(nc, response.c_str(), response.length());
15207 delete t;
15208 return;
15209 } else if (destination[0] == '#') {
15210 std::string response = "404 Not Found (Proxy commented-out in ODB)";
15211 mg_send_head(nc, 404, response.length(), NULL);
15212 mg_send(nc, response.c_str(), response.length());
15213 delete t;
15214 return;
15215 } else if (ends_with_char(destination, '/')) {
15216 std::string response = "404 Not Found (Proxy address should not end with a slash)";
15217 mg_send_head(nc, 404, response.length(), NULL);
15218 mg_send(nc, response.c_str(), response.length());
15219 delete t;
15220 return;
15221 } else if (!starts_with(destination, "http")) {
15222 std::string response = "404 Not Found (Proxy address does not start with http";
15223 mg_send_head(nc, 404, response.length(), NULL);
15224 mg_send(nc, response.c_str(), response.length());
15225 delete t;
15226 return;
15227 } else {
15228 std::string m;
15229 m += "/proxy";
15230 m += "/";
15231 m += p;
15232 mg_str mount = mg_mk_str(m.c_str());
15233 mg_str upstream = mg_mk_str(destination.c_str());
15234 if (verbose_mg||trace_mg) {
15235 printf("proxy: uri [%s] mount [%s] upstream [%s]\n", uri.c_str(), mgstr(&mount).c_str(), mgstr(&upstream).c_str());
15236 }
15237 mg_http_reverse_proxy(nc, msg, mount, upstream);
15238 delete t;
15239 return;
15240 }
15241 }
15242#endif
15243
15244 int response = RESPONSE_501;
15245
15246 if (method == "GET")
15247 response = handle_http_get(nc, msg, uri.c_str(), t);
15248 else if (method == "POST")
15249 response = handle_http_post(nc, msg, uri.c_str(), t);
15250
15251 if (response == RESPONSE_501) {
15252 if (trace_mg||verbose_mg)
15253 printf("handle_http_message: sending 501 Not Implemented error\n");
15254
15255 std::string response = "501 Not Implemented";
15256 mg_send_head(nc, 501, response.length(), NULL); // 501 Not Implemented
15257 mg_send(nc, response.c_str(), response.length());
15258 }
15259
15260 if (response != RESPONSE_QUEUED) {
15261 t->fCompleted = true;
15263 }
15264}
void AddTraceMTS(RequestTrace *t)
Definition mhttpd.cxx:493
std::string fQuery
Definition mhttpd.cxx:426
std::string fMethod
Definition mhttpd.cxx:424
std::string fUri
Definition mhttpd.cxx:425
bool fCompleted
Definition mhttpd.cxx:423
double fTimeReceived
Definition mhttpd.cxx:418
void mg_send_head(struct mg_connection *n, int status_code, int64_t content_length, const char *extra_headers)
struct mg_str proto
Definition mongoose6.h:2073
struct mg_str mg_mk_str(const char *s)
static int handle_http_post(struct mg_connection *nc, const http_message *msg, const char *uri, RequestTrace *t)
Definition mhttpd.cxx:14916
static bool mongoose_passwords_enabled(const struct mg_connection *nc)
static std::string check_digest_auth(struct http_message *hm, Auth *auth)
Definition mhttpd.cxx:13925
static std::string UrlDecode(const char *p)
Definition mhttpd.cxx:873
bool starts_with(const std::string &s1, const char *s2)
Definition mhttpd.cxx:4465
#define RESPONSE_QUEUED
Definition mhttpd.cxx:14287
static int handle_http_get(struct mg_connection *nc, const http_message *msg, const char *uri, RequestTrace *t)
Definition mhttpd.cxx:14833
static RequestTraceBuf * gTraceBuf
Definition mhttpd.cxx:536
static void xmg_http_send_digest_auth_request(struct mg_connection *c, const char *domain)
Definition mhttpd.cxx:13819
static void handle_http_options_cors(struct mg_connection *nc, const http_message *msg, RequestTrace *t)
Definition mhttpd.cxx:15042
static Auth * gAuthMg
Definition mhttpd.cxx:13785
bool ends_with_char(const std::string &s, char c)
Definition midas.cxx:412
Here is the call graph for this function:

◆ handle_http_options_cors()

static void handle_http_options_cors ( struct mg_connection nc,
const http_message msg,
RequestTrace t 
)
static

Definition at line 15042 of file mhttpd.cxx.

15043{
15044 //
15045 // JSON-RPC CORS pre-flight request, see
15046 // https://en.wikipedia.org/wiki/Cross-origin_resource_sharing
15047 //
15048 // OPTIONS /resources/post-here/ HTTP/1.1
15049 // Host: bar.other
15050 // User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
15051 // Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
15052 // Accept-Language: en-us,en;q=0.5
15053 // Accept-Encoding: gzip,deflate
15054 // Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
15055 // Connection: keep-alive
15056 // Origin: http://foo.example
15057 // Access-Control-Request-Method: POST
15058 // Access-Control-Request-Headers: X-PINGOTHER
15059 //
15060 // HTTP/1.1 200 OK
15061 // Date: Mon, 01 Dec 2008 01:15:39 GMT
15062 // Server: Apache/2.0.61 (Unix)
15063 // Access-Control-Allow-Origin: http://foo.example
15064 // Access-Control-Allow-Methods: POST, GET, OPTIONS
15065 // Access-Control-Allow-Headers: X-PINGOTHER
15066 // Access-Control-Max-Age: 1728000
15067 // Vary: Accept-Encoding, Origin
15068 // Content-Encoding: gzip
15069 // Content-Length: 0
15070 // Keep-Alive: timeout=2, max=100
15071 // Connection: Keep-Alive
15072 // Content-Type: text/plain
15073 //
15074
15075 const std::string origin_header = find_header_mg(msg, "Origin");
15076
15077 if (trace_mg||verbose_mg)
15078 printf("handle_http_options_cors: origin [%s]\n", origin_header.c_str());
15079
15080 std::string headers;
15081 headers += "HTTP/1.1 200 OK\n";
15082 //headers += "Date: Sat, 08 Jul 2006 12:04:08 GMT\n";
15083 if (origin_header.length() > 0)
15084 headers += "Access-Control-Allow-Origin: " + origin_header + "\n";
15085 else
15086 headers += "Access-Control-Allow-Origin: *\n";
15087 headers += "Access-Control-Allow-Headers: Content-Type\n";
15088 headers += "Access-Control-Allow-Credentials: true\n";
15089 headers += "Access-Control-Max-Age: 120\n";
15090 headers += "Content-Length: 0\n";
15091 headers += "Content-Type: text/plain\n";
15092 //printf("sending headers: %s\n", headers.c_str());
15093 //printf("sending reply: %s\n", reply.c_str());
15094
15095 std::string send = headers + "\n";
15096
15098
15099 mg_send(nc, send.c_str(), send.length());
15100
15101 t->fTimeSent = GetTimeSec();
15102}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_http_post()

static int handle_http_post ( struct mg_connection nc,
const http_message msg,
const char *  uri,
RequestTrace t 
)
static

Definition at line 14916 of file mhttpd.cxx.

14917{
14918 std::string query_string = mgstr(&msg->query_string);
14919 std::string post_data = mgstr(&msg->body);
14920
14921 if (trace_mg||verbose_mg)
14922 printf("handle_http_post: uri [%s], query [%s], post data %d bytes\n", uri, query_string.c_str(), (int)post_data.length());
14923 if (trace_mg_verbose)
14924 printf("handle_http_post: post data = \n%s\n", post_data.c_str());
14925
14926 if (query_string.substr(0, 8) == "mjsonrpc") { // ignore any parameter after "mjsonrpc"
14927 const std::string origin_header = find_header_mg(msg, "Origin");
14928 const std::string ctype_header = find_header_mg(msg, "Content-Type");
14929
14930 if (strstr(ctype_header.c_str(), "application/json") == NULL) {
14931 std::string headers;
14932 headers += "HTTP/1.1 415 Unsupported Media Type\n";
14933 //headers += "Date: Sat, 08 Jul 2006 12:04:08 GMT\n";
14934
14935 //printf("sending headers: %s\n", headers.c_str());
14936 //printf("sending reply: %s\n", reply.c_str());
14937
14938 if (trace_mg_verbose)
14939 printf("handle_http_post: unsupported media type \"%s\"\n", ctype_header.c_str());
14940
14941 std::string send = headers + "\n";
14942
14944
14945 mg_send(nc, send.c_str(), send.length());
14946
14947 t->fTimeSent = GetTimeSec();
14948
14949 return RESPONSE_SENT;
14950 }
14951
14952#ifdef HAVE_MONGOOSE616
14953 if (multithread_mg)
14954 return queue_mjsonrpc(nc, origin_header, post_data, t);
14955#endif
14956
14957 //printf("post body: %s\n", post_data.c_str());
14958
14959 t->fRPC = post_data;
14960
14961#ifdef HAVE_MONGOOSE6
14962 int status = ss_mutex_wait_for(request_mutex, 0);
14963 assert(status == SS_SUCCESS);
14964#endif
14965
14966 //t->fTimeLocked = GetTimeSec();
14967
14968 MJsonNode* reply = mjsonrpc_decode_post_data(post_data.c_str());
14969
14970 //t->fTimeUnlocked = GetTimeSec();
14971
14972#ifdef HAVE_MONGOOSE6
14973 ss_mutex_release(request_mutex);
14974#endif
14975
14976 if (reply->GetType() == MJSON_ARRAYBUFFER) {
14977 const char* ptr;
14978 size_t size;
14979 reply->GetArrayBuffer(&ptr, &size);
14980
14981 std::string headers;
14982 headers += "HTTP/1.1 200 OK\n";
14983 if (origin_header.length() > 0)
14984 headers += "Access-Control-Allow-Origin: " + std::string(origin_header) + "\n";
14985 else
14986 headers += "Access-Control-Allow-Origin: *\n";
14987 headers += "Access-Control-Allow-Credentials: true\n";
14988 headers += "Content-Length: " + toString(size) + "\n";
14989 headers += "Content-Type: application/octet-stream\n";
14990 //headers += "Date: Sat, 08 Jul 2006 12:04:08 GMT\n";
14991
14992 //printf("sending headers: %s\n", headers.c_str());
14993 //printf("sending reply: %s\n", reply_string.c_str());
14994
14995 std::string send = headers + "\n";
14996
14998
14999 mg_send(nc, send.c_str(), send.length());
15000 mg_send(nc, ptr, size);
15001
15002 t->fTimeSent = GetTimeSec();
15003
15004 delete reply;
15005
15006 return RESPONSE_SENT;
15007 }
15008
15009 std::string reply_string = reply->Stringify();
15010 int reply_length = reply_string.length();
15011
15012 std::string headers;
15013 headers += "HTTP/1.1 200 OK\n";
15014 if (origin_header.length() > 0)
15015 headers += "Access-Control-Allow-Origin: " + std::string(origin_header) + "\n";
15016 else
15017 headers += "Access-Control-Allow-Origin: *\n";
15018 headers += "Access-Control-Allow-Credentials: true\n";
15019 headers += "Content-Length: " + toString(reply_length) + "\n";
15020 headers += "Content-Type: application/json\n";
15021 //headers += "Date: Sat, 08 Jul 2006 12:04:08 GMT\n";
15022
15023 //printf("sending headers: %s\n", headers.c_str());
15024 //printf("sending reply: %s\n", reply_string.c_str());
15025
15026 std::string send = headers + "\n" + reply_string;
15027
15029
15030 mg_send(nc, send.c_str(), send.length());
15031
15032 t->fTimeSent = GetTimeSec();
15033
15034 delete reply;
15035
15036 return RESPONSE_SENT;
15037 }
15038
15039 return handle_decode_post(nc, msg, uri, query_string.c_str(), t);
15040}
std::string fRPC
Definition mhttpd.cxx:427
MJsonNode * mjsonrpc_decode_post_data(const char *post_data)
static int handle_decode_post(struct mg_connection *nc, const http_message *msg, const char *uri, const char *query_string, RequestTrace *t)
Definition mhttpd.cxx:14760
static bool trace_mg_verbose
Definition mhttpd.cxx:13740
Here is the call graph for this function:
Here is the caller graph for this function:

◆ haxis()

void haxis ( gdImagePtr  im,
gdFont font,
int  col,
int  gcol,
int  x1,
int  y1,
int  width,
int  minor,
int  major,
int  text,
int  label,
int  grid,
double  xmin,
double  xmax 
)

Definition at line 7665 of file mhttpd.cxx.

7668{
7669 double dx, int_dx, frac_dx, x_act, label_dx, major_dx, x_screen, maxwidth;
7670 int tick_base, major_base, label_base, n_sig1, n_sig2, xs;
7671 char str[80];
7672 double base[] = { 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000 };
7673
7674 if (xmax <= xmin || width <= 0)
7675 return;
7676
7677 /* use 5 as min tick distance */
7678 dx = (xmax - xmin) / (double) (width / 5);
7679
7680 frac_dx = modf(log(dx) / LN10, &int_dx);
7681 if (frac_dx < 0) {
7682 frac_dx += 1;
7683 int_dx -= 1;
7684 }
7685
7686 tick_base = frac_dx < LOG2 ? 1 : frac_dx < LOG5 ? 2 : 3;
7687 major_base = label_base = tick_base + 1;
7688
7689 /* rounding up of dx, label_dx */
7690 dx = pow(10, int_dx) * base[tick_base];
7691 major_dx = pow(10, int_dx) * base[major_base];
7692 label_dx = major_dx;
7693
7694 /* number of significant digits */
7695 if (xmin == 0)
7696 n_sig1 = 0;
7697 else
7698 n_sig1 = (int) floor(log(fabs(xmin)) / LN10) - (int) floor(log(fabs(label_dx)) / LN10) + 1;
7699
7700 if (xmax == 0)
7701 n_sig2 = 0;
7702 else
7703 n_sig2 =
7704 (int) floor(log(fabs(xmax)) / LN10) - (int) floor(log(fabs(label_dx)) / LN10) + 1;
7705
7706 n_sig1 = MAX(n_sig1, n_sig2);
7707 n_sig1 = MAX(n_sig1, 4);
7708
7709 /* determination of maximal width of labels */
7710 sprintf(str, "%1.*lG", n_sig1, floor(xmin / dx) * dx);
7711 maxwidth = font->h / 2 * strlen(str);
7712 sprintf(str, "%1.*lG", n_sig1, floor(xmax / dx) * dx);
7713 maxwidth = MAX(maxwidth, font->h / 2 * strlen(str));
7714 sprintf(str, "%1.*lG", n_sig1, floor(xmax / dx) * dx + label_dx);
7715 maxwidth = MAX(maxwidth, font->h / 2 * strlen(str));
7716
7717 /* increasing label_dx, if labels would overlap */
7718 while (maxwidth > 0.7 * label_dx / (xmax - xmin) * width) {
7719 label_base++;
7720 label_dx = pow(10, int_dx) * base[label_base];
7721 if (label_base % 3 == 2 && major_base % 3 == 1) {
7722 major_base++;
7723 major_dx = pow(10, int_dx) * base[major_base];
7724 }
7725 }
7726
7727 x_act = floor(xmin / dx) * dx;
7728
7729 gdImageLine(im, x1, y1, x1 + width, y1, col);
7730
7731 do {
7732 x_screen = (x_act - xmin) / (xmax - xmin) * width + x1;
7733 xs = (int) (x_screen + 0.5);
7734
7735 if (x_screen > x1 + width + 0.001)
7736 break;
7737
7738 if (x_screen >= x1) {
7739 if (fabs(floor(x_act / major_dx + 0.5) - x_act / major_dx) <
7740 dx / major_dx / 10.0) {
7741
7742 if (fabs(floor(x_act / label_dx + 0.5) - x_act / label_dx) <
7743 dx / label_dx / 10.0) {
7744 /* label tick mark */
7745 gdImageLine(im, xs, y1, xs, y1 + text, col);
7746
7747 /* grid line */
7748 if (grid != 0 && xs > x1 && xs < x1 + width)
7749 gdImageLine(im, xs, y1, xs, y1 + grid, col);
7750
7751 /* label */
7752 if (label != 0) {
7753 sprintf(str, "%1.*lG", n_sig1, x_act);
7754 gdImageString(im, font, (int) xs - font->w * strlen(str) / 2,
7755 y1 + label, str, col);
7756 }
7757 } else {
7758 /* major tick mark */
7759 gdImageLine(im, xs, y1, xs, y1 + major, col);
7760
7761 /* grid line */
7762 if (grid != 0 && xs > x1 && xs < x1 + width)
7763 gdImageLine(im, xs, y1 - 1, xs, y1 + grid, gcol);
7764 }
7765
7766 } else
7767 /* minor tick mark */
7768 gdImageLine(im, xs, y1, xs, y1 + minor, col);
7769
7770 }
7771
7772 x_act += dx;
7773
7774 /* supress 1.23E-17 ... */
7775 if (fabs(x_act) < dx / 100)
7776 x_act = 0;
7777
7778 } while (1);
7779}
#define MAX(a, b)
Definition midas.h:509
#define LOG2
Definition mhttpd.cxx:7662
#define LOG5
Definition mhttpd.cxx:7663
static te_expr * base(state *s)
Definition tinyexpr.c:357
Here is the call graph for this function:
Here is the caller graph for this function:

◆ history_watch_callback()

static void history_watch_callback ( HNDLE  hDB,
HNDLE  hKey,
int  index,
void *  info 
)
static

Definition at line 8178 of file mhttpd.cxx.

8179{
8180 //printf("history_watch_callback %d %d %d\n", hDB, hKey, index);
8181 gDoReloadHistory = true;
8182 cm_msg(MINFO, "history_watch_callback", "History configuration may have changed, will reconnect");
8183}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ init_elog_odb()

void init_elog_odb ( )

Definition at line 2008 of file mhttpd.cxx.

2009{
2010 HNDLE hDB;
2011 int size;
2012 HNDLE hkey;
2014
2015 BOOL external_elog = FALSE;
2016 std::string external_elog_url;
2017
2018 size = sizeof(external_elog);
2019 db_get_value(hDB, 0, "/Elog/External Elog", &external_elog, &size, TID_BOOL, TRUE);
2020 db_get_value_string(hDB, 0, "/Elog/URL", 0, &external_elog_url, TRUE);
2021
2022 BOOL allow_delete = FALSE;
2023 BOOL allow_edit = FALSE;
2024 size = sizeof(BOOL);
2025 db_get_value(hDB, 0, "/Elog/Allow delete", &allow_delete, &size, TID_BOOL, TRUE);
2026 db_get_value(hDB, 0, "/Elog/Allow edit", &allow_edit, &size, TID_BOOL, TRUE);
2027 //db_get_value(hDB, 0, "/Elog/Display run number", &display_run_number, &size, TID_BOOL, TRUE);
2028
2029 if (db_find_key(hDB, 0, "/Elog/Buttons", &hkey) != DB_SUCCESS) {
2030 const char def_button[][NAME_LENGTH] = { "8h", "24h", "7d" };
2031 db_set_value(hDB, 0, "/Elog/Buttons", def_button, NAME_LENGTH*3, 3, TID_STRING);
2032 }
2033
2034
2035 /* get type list from ODB */
2036 size = 20 * NAME_LENGTH;
2037 if (db_find_key(hDB, 0, "/Elog/Types", &hkey) != DB_SUCCESS) {
2038 db_set_value(hDB, 0, "/Elog/Types", default_type_list, NAME_LENGTH * 20, 20, TID_STRING);
2039 }
2040
2041 /* get system list from ODB */
2042 size = 20 * NAME_LENGTH;
2043 if (db_find_key(hDB, 0, "/Elog/Systems", &hkey) != DB_SUCCESS)
2044 db_set_value(hDB, 0, "/Elog/Systems", default_system_list, NAME_LENGTH * 20, 20, TID_STRING);
2045}
INT db_set_value(HNDLE hDB, HNDLE hKeyRoot, const char *key_name, const void *data, INT data_size, INT num_values, DWORD type)
Definition odb.cxx:5028
static const char default_type_list[20][NAME_LENGTH]
Definition mhttpd.cxx:101
static const char default_system_list[20][NAME_LENGTH]
Definition mhttpd.cxx:116
Here is the call graph for this function:
Here is the caller graph for this function:

◆ init_menu_buttons()

void init_menu_buttons ( MVOdb *  odb)

Definition at line 1919 of file mhttpd.cxx.

1920{
1921 HNDLE hDB;
1922 BOOL true_value = TRUE;
1923 BOOL false_value = FALSE;
1924 int size = sizeof(true_value);
1926 db_get_value(hDB, 0, "/Experiment/Menu/Status", &true_value, &size, TID_BOOL, TRUE);
1927 db_get_value(hDB, 0, "/Experiment/Menu/Start", &false_value, &size, TID_BOOL, TRUE);
1928 db_get_value(hDB, 0, "/Experiment/Menu/Transition", &true_value, &size, TID_BOOL, TRUE);
1929 db_get_value(hDB, 0, "/Experiment/Menu/ODB", &true_value, &size, TID_BOOL, TRUE);
1930 db_get_value(hDB, 0, "/Experiment/Menu/OldODB", &true_value, &size, TID_BOOL, TRUE);
1931 db_get_value(hDB, 0, "/Experiment/Menu/Messages", &true_value, &size, TID_BOOL, TRUE);
1932 db_get_value(hDB, 0, "/Experiment/Menu/Chat", &true_value, &size, TID_BOOL, TRUE);
1933 db_get_value(hDB, 0, "/Experiment/Menu/Elog", &true_value, &size, TID_BOOL, TRUE);
1934 db_get_value(hDB, 0, "/Experiment/Menu/Alarms", &true_value, &size, TID_BOOL, TRUE);
1935 db_get_value(hDB, 0, "/Experiment/Menu/Programs", &true_value, &size, TID_BOOL, TRUE);
1936 db_get_value(hDB, 0, "/Experiment/Menu/Buffers", &true_value, &size, TID_BOOL, TRUE);
1937 db_get_value(hDB, 0, "/Experiment/Menu/History", &true_value, &size, TID_BOOL, TRUE);
1938 db_get_value(hDB, 0, "/Experiment/Menu/OldHistory", &true_value, &size, TID_BOOL, TRUE);
1939 db_get_value(hDB, 0, "/Experiment/Menu/MSCB", &true_value, &size, TID_BOOL, TRUE);
1940 db_get_value(hDB, 0, "/Experiment/Menu/Sequencer", &true_value, &size, TID_BOOL, TRUE);
1941 db_get_value(hDB, 0, "/Experiment/Menu/PySequencer",&true_value, &size, TID_BOOL, TRUE);
1942 db_get_value(hDB, 0, "/Experiment/Menu/Event Dump", &true_value, &size, TID_BOOL, TRUE);
1943 db_get_value(hDB, 0, "/Experiment/Menu/Config", &true_value, &size, TID_BOOL, TRUE);
1944 db_get_value(hDB, 0, "/Experiment/Menu/Example", &true_value, &size, TID_BOOL, TRUE);
1945 db_get_value(hDB, 0, "/Experiment/Menu/Help", &true_value, &size, TID_BOOL, TRUE);
1946
1947 //std::string buf;
1948 //status = db_get_value_string(hDB, 0, "/Experiment/Menu buttons", 0, &buf, FALSE);
1949 //if (status == DB_SUCCESS) {
1950 // cm_msg(MERROR, "init_menu_buttons", "ODB \"/Experiment/Menu buttons\" is obsolete, please delete it.");
1951 //}
1952
1953 check_obsolete_odb(hDB, "/Experiment/Menu buttons");
1954 check_obsolete_odb(hDB, "/Experiment/Menu/OldSequencer");
1955 check_obsolete_odb(hDB, "/Experiment/Menu/NewSequencer");
1956}
void check_obsolete_odb(HNDLE hDB, const char *odb_path)
Definition mhttpd.cxx:1910
Here is the call graph for this function:
Here is the caller graph for this function:

◆ init_mhttpd_odb()

void init_mhttpd_odb ( MVOdb *  odb)

Definition at line 1960 of file mhttpd.cxx.

1961{
1962 HNDLE hDB;
1963 HNDLE hKey;
1964 int status;
1965 std::string s;
1967
1968 status = db_find_key(hDB, 0, "/Experiment/Base URL", &hKey);
1969 if (status == DB_SUCCESS) {
1970 cm_msg(MERROR, "init_mhttpd_odb", "ODB \"/Experiment/Base URL\" is obsolete, please delete it.");
1971 }
1972
1973 status = db_find_key(hDB, 0, "/Experiment/CSS File", &hKey);
1974 if (status == DB_SUCCESS) {
1975 cm_msg(MERROR, "init_mhttpd_odb", "ODB \"/Experiment/CSS File\" is obsolete, please delete it.");
1976 }
1977
1978 status = db_find_key(hDB, 0, "/Experiment/JS File", &hKey);
1979 if (status == DB_SUCCESS) {
1980 cm_msg(MERROR, "init_mhttpd_odb", "ODB \"/Experiment/JS File\" is obsolete, please delete it.");
1981 }
1982
1983 status = db_find_key(hDB, 0, "/Experiment/Start-Stop Buttons", &hKey);
1984 if (status == DB_SUCCESS) {
1985 cm_msg(MERROR, "init_mhttpd_odb", "ODB \"/Experiment/Start-Stop Buttons\" is obsolete, please delete it.");
1986 }
1987
1988 bool xdefault = true;
1989 odb->RB("Experiment/Pause-Resume Buttons", &xdefault, true);
1990
1991#ifdef HAVE_MONGOOSE616
1992 check_obsolete_odb(hDB, "/Experiment/midas http port");
1993 check_obsolete_odb(hDB, "/Experiment/midas https port");
1994 check_obsolete_odb(hDB, "/Experiment/http redirect to https");
1995 check_obsolete_odb(hDB, "/Experiment/Security/mhttpd hosts");
1996#endif
1997
1998 status = db_find_key(hDB, 0, "/Logger/Message file", &hKey);
1999 if (status == DB_SUCCESS) {
2000 cm_msg(MERROR, "init_mhttpd_odb", "ODB \"/Logger/Message file\" is obsolete, please delete it and use \"/Logger/Message dir\" and \"/Logger/message file date format\" instead.");
2001 }
2002
2003 check_obsolete_odb(hDB, "/Logger/Watchdog timeout");
2004}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ interprete()

void interprete ( Param p,
Return r,
Attachment a,
const Cookies c,
const char *  dec_path,
RequestTrace t 
)

Definition at line 12283 of file mhttpd.cxx.

12291{
12292 int status;
12293 HNDLE hkey, hDB;
12294
12295 //printf("dec_path [%s]\n", dec_path);
12296
12297 if (strstr(dec_path, "favicon.ico") != 0 ||
12298 strstr(dec_path, "favicon.png")) {
12299 send_icon(r, dec_path);
12300 return;
12301 }
12302
12303 const char* password = p->getparam("pwd");
12304 const char* wpassword = p->getparam("wpwd");
12305 const char* command = p->getparam("cmd");
12306
12307 //printf("interprete: dec_path [%s], command [%s]\n", dec_path, command);
12308
12310 MVOdb* odb = gOdb;
12311
12312 if (history_mode) {
12313 if (equal_ustring(command, "history")) {
12314 if (equal_ustring(command, "config")) {
12315 return;
12316 }
12317
12318 Lock(t);
12319 show_hist_page(odb, p, r, dec_path, NULL, NULL, c->refresh);
12320 Unlock(t);
12321 return;
12322 }
12323 return;
12324 }
12325
12326 /* check for password */
12327 db_find_key(hDB, 0, "/Experiment/Security/Password", &hkey);
12328 if (!password[0] && hkey) {
12329 char str[256];
12330 int size = sizeof(str);
12331 db_get_data(hDB, hkey, str, &size, TID_STRING);
12332
12333 /* check for excemption */
12334 db_find_key(hDB, 0, "/Experiment/Security/Allowed programs/mhttpd", &hkey);
12335 if (hkey == 0 && strcmp(c->cookie_pwd.c_str(), str) != 0) {
12336 Lock(t);
12337 show_password_page(r, dec_path, "");
12338 Unlock(t);
12339 return;
12340 }
12341 }
12342
12343 /*---- redirect with cookie if password given --------------------*/
12344
12345 if (password[0]) {
12346 r->rsprintf("HTTP/1.1 302 Found\r\n");
12347 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
12348
12349 time_t now;
12350 time(&now);
12351
12352 now += 3600 * 24;
12353
12354 struct tm gmt_tms;
12355 gmtime_r(&now, &gmt_tms);
12356
12357 char str[256];
12358 strftime(str, sizeof(str), "%A, %d-%b-%Y %H:00:00 GMT", &gmt_tms);
12359
12360 r->rsprintf("Set-Cookie: midas_pwd=%s; path=/; expires=%s\r\n",
12361 ss_crypt(password, "mi"), str);
12362
12363 r->rsprintf("Location: ./\n\n<html>redir</html>\r\n");
12364 return;
12365 }
12366
12367 if (wpassword[0]) {
12368 /* check if password correct */
12369 if (!check_web_password(r, hDB, dec_path, ss_crypt(wpassword, "mi"), p->getparam("redir")))
12370 return;
12371
12372 r->rsprintf("HTTP/1.1 302 Found\r\n");
12373 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
12374
12375 time_t now;
12376 time(&now);
12377
12378 now += 3600 * 24;
12379
12380 struct tm gmt_tms;
12381 gmtime_r(&now, &gmt_tms);
12382
12383 char str[256];
12384 strftime(str, sizeof(str), "%A, %d-%b-%Y %H:%M:%S GMT", &gmt_tms);
12385
12386 r->rsprintf("Set-Cookie: midas_wpwd=%s; path=/; expires=%s\r\n", ss_crypt(wpassword, "mi"), str);
12387
12388 sprintf(str, "./%s", p->getparam("redir"));
12389 r->rsprintf("Location: %s\n\n<html>redir</html>\r\n", str);
12390 return;
12391 }
12392
12393 /*---- send sound file -------------------------------------------*/
12394
12395 if (strlen(dec_path) > 3 &&
12396 dec_path[strlen(dec_path)-3] == 'm' &&
12397 dec_path[strlen(dec_path)-2] == 'p' &&
12398 dec_path[strlen(dec_path)-1] == '3') {
12399 if (strrchr(dec_path, '/'))
12400 send_resource(r, strrchr(dec_path, '/')+1);
12401 else
12402 send_resource(r, dec_path);
12403 return;
12404 }
12405
12406 /*---- send midas.js and midas.css -------------------------------*/
12407
12408 if (strstr(dec_path, "midas.js")) {
12409 send_resource(r, "midas.js");
12410 return;
12411 }
12412
12413 if (strstr(dec_path, "midas.css")) {
12414 send_resource(r, "midas.css");
12415 return;
12416 }
12417
12418 /*---- send mhttpd.js --------------------------------------------*/
12419
12420 if (strstr(dec_path, "mhttpd.js")) {
12421 send_resource(r, "mhttpd.js");
12422 return;
12423 }
12424
12425 /*---- send obsolete.js ------------------------------------------*/
12426
12427 if (strstr(dec_path, "obsolete.js")) {
12428 send_resource(r, "obsolete.js");
12429 return;
12430 }
12431
12432 /*---- send the obsolete mhttpd.css ------------------------------*/
12433
12434 if (strstr(dec_path, "mhttpd.css")) {
12435 send_resource(r, "mhttpd.css");
12436 return;
12437 }
12438
12439 /*---- send controls.js ------------------------------------------*/
12440
12441 if (strstr(dec_path, "controls.js")) {
12442 send_resource(r, "controls.js");
12443 return;
12444 }
12445
12446 /*---- send example web page -------------------------------------*/
12447
12448 if (equal_ustring(command, "example")) {
12449 send_resource(r, "example.html");
12450 return;
12451 }
12452
12453 /*---- send example custom page -------------------------------------*/
12454
12455 if (equal_ustring(command, "custom_example")) {
12456 send_resource(r, "custom_example.html");
12457 return;
12458 }
12459
12460 if (equal_ustring(command, "plot_example")) {
12461 send_resource(r, "plot_example.html");
12462 return;
12463 }
12464
12465 /*---- script command --------------------------------------------*/
12466
12467 if (p->getparam("script") && *p->getparam("script")) {
12468
12469 std::string str = msprintf("%s?script=%s", dec_path, p->getparam("script"));
12470 if (!check_web_password(r, hDB, dec_path, c->cookie_wpwd.c_str(), str.c_str()))
12471 return;
12472
12473 std::string path;
12474 path += "/Script/";
12475 path += p->getparam("script");
12476
12477 Lock(t);
12478
12479 cm_exec_script(path.c_str());
12480
12481 Unlock(t);
12482
12483 if (p->isparam("redir"))
12484 redirect2(r, p->getparam("redir"));
12485 else
12486 redirect2(r, "");
12487
12488 return;
12489 }
12490
12491 /*---- customscript command --------------------------------------*/
12492
12493 if (p->getparam("customscript") && *p->getparam("customscript")) {
12494
12495 std::string str = msprintf("%s?customscript=%s", dec_path, p->getparam("customscript"));
12496 if (!check_web_password(r, hDB, dec_path, c->cookie_wpwd.c_str(), str.c_str()))
12497 return;
12498
12499 std::string path;
12500 path += "/CustomScript/";
12501 path += p->getparam("customscript");
12502
12503 Lock(t);
12504
12505 cm_exec_script(path.c_str());
12506
12507 Unlock(t);
12508
12509 if (p->isparam("redir"))
12510 redirect2(r, p->getparam("redir"));
12511 else
12512 redirect2(r, str.c_str());
12513
12514 return;
12515 }
12516
12517 /*---- send the new html pages -----------------------------------*/
12518
12519 if (equal_ustring(command, "start")) {
12520 send_resource(r, "start.html");
12521 return;
12522 }
12523
12524 if ((equal_ustring(command, "") || equal_ustring(command, "status")) && strlen(dec_path) == 0) {
12525 if (midas::odb::exists("/Custom/Status")) {
12526 midas::odb custom("/Custom");
12527
12528 std::string filename = custom["Status"];
12529 filename = add_custom_path(filename);
12530
12531 // if custom file exists, send it (like normal web server)
12532 if (ss_file_exist(filename.c_str())) {
12533 send_file(r, filename);
12534 return;
12535 }
12536 } else
12537 send_resource(r, "status.html");
12538 return;
12539 }
12540
12541 if (equal_ustring(command, "eqtable")) {
12542 send_resource(r, "eqtable.html");
12543 return;
12544 }
12545
12546 if (equal_ustring(command, "newODB")) {
12547 send_resource(r, "odb.html");
12548 return;
12549 }
12550
12551 if (equal_ustring(command, "programs")) {
12552 send_resource(r, "programs.html");
12553 return;
12554 }
12555
12556 if (equal_ustring(command, "alarms")) {
12557 send_resource(r, "alarms.html");
12558 return;
12559 }
12560
12561 if (equal_ustring(command, "transition")) {
12562 send_resource(r, "transition.html");
12563 return;
12564 }
12565
12566 if (equal_ustring(command, "messages")) {
12567 send_resource(r, "messages.html");
12568 return;
12569 }
12570
12571 if (equal_ustring(command, "config") &&
12572 !(dec_path[0] == 'H' && dec_path[1] == 'S' && dec_path[2] == '/')) {
12573 send_resource(r, "config.html");
12574 return;
12575 }
12576
12577 if (equal_ustring(command, "chat")) {
12578 send_resource(r, "chat.html");
12579 return;
12580 }
12581
12582 if (equal_ustring(command, "buffers")) {
12583 send_resource(r, "buffers.html");
12584 return;
12585 }
12586
12587 if (equal_ustring(command, "Show elog")) {
12588 send_resource(r, "elog_show.html");
12589 return;
12590 }
12591
12592 if (equal_ustring(command, "Query elog")) {
12593 send_resource(r, "elog_query_form.html");
12594 return;
12595 }
12596
12597 if (equal_ustring(command, "New elog")) {
12598 send_resource(r, "elog_edit.html");
12599 return;
12600 }
12601
12602 if (equal_ustring(command, "Edit elog")) {
12603 send_resource(r, "elog_edit.html");
12604 return;
12605 }
12606
12607 if (equal_ustring(command, "Reply Elog")) {
12608 send_resource(r, "elog_edit.html");
12609 return;
12610 }
12611
12612 if (equal_ustring(command, "Last elog")) {
12613 send_resource(r, "elog_show.html");
12614 return;
12615 }
12616
12617 if (equal_ustring(command, "Submit Query")) {
12618 send_resource(r, "elog_query.html");
12619 return;
12620 }
12621
12622 if (equal_ustring(dec_path, "spinning-wheel.gif")) {
12623 send_resource(r, "spinning-wheel.gif");
12624 return;
12625 }
12626
12627 /*---- java script commands --------------------------------------*/
12628
12629 if (equal_ustring(command, "jset") ||
12630 equal_ustring(command, "jget") ||
12631 equal_ustring(command, "jcopy") ||
12632 equal_ustring(command, "jpaste") ||
12633 equal_ustring(command, "jkey") ||
12634 equal_ustring(command, "jcreate") ||
12635 equal_ustring(command, "jresize") ||
12636 equal_ustring(command, "jlink") ||
12637 equal_ustring(command, "jrename") ||
12638 equal_ustring(command, "jreorder") ||
12639 equal_ustring(command, "jdelete") ||
12640 equal_ustring(command, "jmsg") ||
12641 equal_ustring(command, "jalm") ||
12642 equal_ustring(command, "jgenmsg") ||
12643 equal_ustring(command, "jrpc_rev0") ||
12644 equal_ustring(command, "jrpc_rev1") ||
12645 equal_ustring(command, "jrpc")) {
12646 Lock(t);
12647 javascript_commands(p, r, c->cookie_cpwd.c_str());
12648 Unlock(t);
12649 return;
12650 }
12651
12652 /*---- history editord -------------------------------------------*/
12653
12654 if (equal_ustring(command, "hs_edit")) {
12655 send_resource(r, "hs_edit.html");
12656 return;
12657 }
12658
12659 /*---- history command -------------------------------------------*/
12660
12661 if (equal_ustring(command, "oldhistory")) {
12662 Lock(t);
12663 show_hist_page(odb, p, r, dec_path, NULL, NULL, c->refresh);
12664 Unlock(t);
12665 return;
12666 }
12667
12668 if (equal_ustring(command, "history")) {
12669 send_resource(r, "history.html");
12670 return;
12671 }
12672
12673 /*---- MSCB command ----------------------------------------------*/
12674
12675 if (equal_ustring(command, "MSCB")) {
12676 if (equal_ustring(command, "set")) {
12677 std::string str;
12678 str += dec_path;
12679 str += "?";
12680 str += add_param_to_url("cmd", command);
12681 if (!check_web_password(r, hDB, dec_path, c->cookie_wpwd.c_str(), str.c_str()))
12682 return;
12683 }
12684
12685 Lock(t);
12686
12687#ifdef HAVE_MSCB
12688 show_mscb_page(p, r, c->refresh);
12689#else
12690 show_error(r, "MSCB support not compiled into this version of mhttpd");
12691#endif
12692
12693 Unlock(t);
12694 return;
12695 }
12696
12697 /*---- help command ----------------------------------------------*/
12698
12699 if (equal_ustring(command, "help")) {
12700 Lock(t);
12701 show_help_page(r, dec_path);
12702 Unlock(t);
12703 return;
12704 }
12705
12706 /*---- trigger equipment readout ---------------------------*/
12707
12708 if (strncmp(command, "Trigger", 7) == 0) {
12709 std::string cmd;
12710 cmd += "?cmd=";
12711 cmd += command;
12712 if (!check_web_password(r, hDB, dec_path, c->cookie_wpwd.c_str(), cmd.c_str())) {
12713 return;
12714 }
12715
12716 Lock(t);
12717
12718 /* extract equipment name */
12719 char eq_name[NAME_LENGTH];
12720
12721 mstrlcpy(eq_name, command + 8, sizeof(eq_name));
12722 if (strchr(eq_name, ' '))
12723 *strchr(eq_name, ' ') = 0;
12724
12725 /* get frontend name */
12726 std::string path;
12727 path += "/Equipment/";
12728 path += eq_name;
12729 path += "/Common/Frontend name";
12730 char fe_name[NAME_LENGTH];
12731 int size = NAME_LENGTH;
12732 db_get_value(hDB, 0, path.c_str(), fe_name, &size, TID_STRING, TRUE);
12733
12734 /* and ID */
12735 path = "";
12736 path += "/Equipment/";
12737 path += eq_name;
12738 path += "/Common/Event ID";
12739 WORD event_id = 0;
12740 size = sizeof(event_id);
12741 db_get_value(hDB, 0, path.c_str(), &event_id, &size, TID_WORD, TRUE);
12742
12743 if (cm_exist(fe_name, FALSE) != CM_SUCCESS) {
12744 std::string str;
12745 str += "Frontend \"";
12746 str += fe_name;
12747 str += "\" not running!";
12748 show_error(r, str.c_str());
12749 } else {
12750 HNDLE hconn;
12751 status = cm_connect_client(fe_name, &hconn);
12752 if (status != RPC_SUCCESS) {
12753 std::string str;
12754 str += "Cannot connect to frontend \"";
12755 str += fe_name;
12756 str +="\" !";
12757 show_error(r, str.c_str());
12758 } else {
12760 if (status != CM_SUCCESS)
12761 show_error(r, "Error triggering event");
12762 else
12763 redirect(r, "");
12764
12765 //cm_disconnect_client(hconn, FALSE);
12766 }
12767 }
12768
12769 Unlock(t);
12770
12771 return;
12772 }
12773
12774 /*---- switch to next subrun -------------------------------------*/
12775
12776 if (strncmp(command, "Next Subrun", 11) == 0) {
12777 int i = TRUE;
12778 db_set_value(hDB, 0, "/Logger/Next subrun", &i, sizeof(i), 1, TID_BOOL);
12779 redirect(r, "");
12780 return;
12781 }
12782
12783 /*---- cancel command --------------------------------------------*/
12784
12785 if (equal_ustring(command, "cancel")) {
12786 if (p->isparam("redir"))
12787 redirect(r, p->getparam("redir"));
12788 else
12789 redirect(r, "");
12790 return;
12791 }
12792
12793 /*---- set command -----------------------------------------------*/
12794
12795 if (equal_ustring(command, "set")) {
12796 char str[256];
12797 mstrlcpy(str, "?cmd=set", sizeof(str));
12798 if (!check_web_password(r, hDB, dec_path, c->cookie_wpwd.c_str(), str))
12799 return;
12800
12801 const char* group = p->getparam("group");
12802 int index = atoi(p->getparam("index"));
12803 const char* value = p->getparam("value");
12804
12805 Lock(t);
12806 show_set_page(p, r, group, index, value);
12807 Unlock(t);
12808 return;
12809 }
12810
12811 /*---- find command ----------------------------------------------*/
12812
12813 if (equal_ustring(command, "find")) {
12814 const char* value = p->getparam("value");
12815 Lock(t);
12817 Unlock(t);
12818 return;
12819 }
12820
12821 /*---- CAMAC CNAF command ----------------------------------------*/
12822
12823 if (equal_ustring(command, "CNAF") || strncmp(dec_path, "CNAF", 4) == 0) {
12824 if (!check_web_password(r, hDB, dec_path, c->cookie_wpwd.c_str(), "?cmd=CNAF"))
12825 return;
12826
12827 Lock(t);
12828 show_cnaf_page(p, r);
12829 Unlock(t);
12830 return;
12831 }
12832
12833 /*---- ELog command ----------------------------------------------*/
12834
12835 if (equal_ustring(command, "elog")) {
12836 /* redirect to external ELOG if URL present */
12838 BOOL external_elog = FALSE;
12839 std::string external_elog_url;
12840 int size = sizeof(external_elog);
12841 status = db_get_value(hDB, 0, "/Elog/External Elog", &external_elog, &size, TID_BOOL, TRUE);
12842 status = db_get_value_string(hDB, 0, "/Elog/URL", 0, &external_elog_url, TRUE);
12843 if (external_elog && (external_elog_url.length() > 0)) {
12844 redirect(r, external_elog_url.c_str());
12845 return;
12846 }
12847 send_resource(r, "elog_show.html");
12848 return;
12849 }
12850
12851 // special processing for "Elog last 7d", etc
12852
12853 char cmdx[32];
12854 mstrlcpy(cmdx, command, sizeof(cmdx));
12855 cmdx[9] = 0;
12856
12857 if (equal_ustring(cmdx, "Elog last")) {
12858 // "Elog last 7d", etc
12859 send_resource(r, "elog_query.html");
12860 return;
12861 }
12862
12863 if (equal_ustring(command, "Create ELog from this page")) {
12864 std::string redir;
12865 redir += "?cmd=New+elog";
12866 redir += "&odb_path=";
12867 redir += p->getparam("odb_path");
12868 redirect(r, redir.c_str());
12869 return;
12870 }
12871
12872 if (equal_ustring(command, "Submit elog")) {
12873 Lock(t);
12874 submit_elog(odb, p, r, a);
12875 Unlock(t);
12876 return;
12877 }
12878
12879 if (equal_ustring(command, "elog_att")) {
12880 Lock(t);
12881 show_elog_attachment(p, r, dec_path);
12882 Unlock(t);
12883 return;
12884 }
12885
12886 /*---- accept command --------------------------------------------*/
12887
12888 if (equal_ustring(command, "accept")) {
12889 int refresh = atoi(p->getparam("refr"));
12890
12891 /* redirect with cookie */
12892 r->rsprintf("HTTP/1.1 302 Found\r\n");
12893 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
12894 r->rsprintf("Content-Type: text/html; charset=%s\r\n", HTTP_ENCODING);
12895
12896 time_t now;
12897 time(&now);
12898
12899 now += 3600 * 24 * 365;
12900
12901 struct tm gmt_tms;
12902 gmtime_r(&now, &gmt_tms);
12903
12904 char str[256];
12905 strftime(str, sizeof(str), "%A, %d-%b-%Y %H:00:00 GMT", &gmt_tms);
12906
12907 r->rsprintf("Set-Cookie: midas_refr=%d; path=/; expires=%s\r\n", refresh, str);
12908 r->rsprintf("Location: ./\r\n\r\n<html>redir</html>\r\n");
12909
12910 return;
12911 }
12912
12913#ifdef OBSOLETE
12914 /*---- slow control display --------------------------------------*/
12915
12916 if (equal_ustring(command, "eqtable")) {
12917 Lock(t);
12918 show_eqtable_page(p, r, c->refresh);
12919 Unlock(t);
12920 return;
12921 }
12922#endif
12923
12924 /*---- sequencer page --------------------------------------------*/
12925
12926 if (equal_ustring(command, "Sequencer")) {
12927 send_resource(r, "sequencer.html");
12928 return;
12929 }
12930
12931 // obsolete
12932 if (equal_ustring(command, "seq")) {
12933 send_resource(r, "sequencer.html");
12934 return;
12935 }
12936
12937 if (equal_ustring(command, "start_script")) {
12938 send_resource(r, "start_script.html");
12939 return;
12940 }
12941
12942 if (equal_ustring(command, "load_script")) {
12943 send_resource(r, "load_script.html");
12944 return;
12945 }
12946
12947 if (equal_ustring(command, "edit_script")) {
12948 send_resource(r, "edit_script.html");
12949 return;
12950 }
12951
12952 /*---- show ODB --------------------------------------------------*/
12953
12954 if (equal_ustring(command, "oldOdb")) {
12955 int write_access = TRUE;
12956 db_find_key(hDB, 0, "/Experiment/Security/Web Password", &hkey);
12957 if (hkey) {
12958 char str[256];
12959 int size = sizeof(str);
12960 db_get_data(hDB, hkey, str, &size, TID_STRING);
12961 if (strcmp(c->cookie_wpwd.c_str(), str) == 0)
12962 write_access = TRUE;
12963 else
12964 write_access = FALSE;
12965 }
12966
12967 std::string odb_path;
12968 if (p->getparam("odb_path") && *p->getparam("odb_path"))
12969 odb_path = p->getparam("odb_path");
12970
12971 Lock(t);
12972 show_odb_page(p, r, odb_path.c_str(), write_access);
12973 Unlock(t);
12974 return;
12975 }
12976
12977 /*---- New ODB browser --------------------------------------------*/
12978
12979 if (equal_ustring(command, "odb")) {
12980 send_resource(r, "odb.html");
12981 return;
12982 }
12983
12984 /*---- ODB show open records --------------------------------------*/
12985
12986 if (equal_ustring(command, "odb_sor")) {
12987 send_resource(r, "odb_sor.html");
12988 return;
12989 }
12990
12991 /*---- ODB show clients -------------------------------------------*/
12992
12993 if (equal_ustring(command, "odb_scl")) {
12994 send_resource(r, "odb_scl.html");
12995 return;
12996 }
12997
12998 /*---- old ODB path ----------------------------------------------*/
12999
13000 if ((command[0]==0) && dec_path[0]) {
13001 if (equal_ustring(dec_path, "root")) {
13002 std::string new_url = "./?cmd=odb";
13003 //printf("redirect old odb path url [%s] to [%s]\n", dec_path, new_url.c_str());
13004 redirect_307(r, new_url.c_str());
13005 return;
13006 }
13007 }
13008
13009 if ((command[0]==0) && dec_path[0]) {
13010 HNDLE hkey;
13011 status = db_find_key(hDB, 0, dec_path, &hkey);
13012 //printf("try odb path [%s], status %d\n", dec_path, status);
13013 if (status == DB_SUCCESS) {
13014 int level = 0;
13015 for (const char* s = dec_path; *s; s++) {
13016 if (*s == '/')
13017 level++;
13018 }
13019 std::string new_url;
13020 if (level == 0) {
13021 // Top-level directory like /Logger, (which appears in dec_path as "Logger")
13022 new_url += "./";
13023 } else {
13024 for (int i=0; i<level; i++) {
13025 if (i>0)
13026 new_url += "/";
13027 new_url += "..";
13028 }
13029 }
13030 new_url += "?cmd=odb";
13031 new_url += "&odb_path=";
13032 new_url += urlEncode(dec_path);
13033 //printf("redirect old odb path url [%s] to [%s]\n", dec_path, new_url.c_str());
13034 redirect_307(r, new_url.c_str());
13035 return;
13036 }
13037 }
13038
13039 /*---- event dump ------------------------------------------------*/
13040
13041 if (equal_ustring(command, "event dump")) {
13042 send_resource(r, "event_dump.html");
13043 return;
13044 }
13045
13046 /*---- custom page -----------------------------------------------*/
13047
13048 if (equal_ustring(command, "custom")) {
13049 Lock(t);
13050 show_custom_page(p, r, c->cookie_cpwd.c_str());
13051 Unlock(t);
13052 return;
13053 }
13054
13055 /*---- custom page accessed by direct URL that used to be under /CS/... ----*/
13056
13057 if (db_find_key(hDB, 0, "/Custom", &hkey) == DB_SUCCESS && dec_path[0]) {
13058 std::string odb_path;
13059 std::string value;
13060 int status;
13061
13062 odb_path = "";
13063 odb_path += "/Custom/Images/";
13064 odb_path += dec_path;
13065 odb_path += "/Background";
13066
13067 status = db_get_value_string(hDB, 0, odb_path.c_str(), 0, &value, FALSE);
13068
13069 //printf("Try custom gif [%s] status %d\n", odb_path.c_str(), status);
13070
13071 if (status == DB_SUCCESS) {
13072 if (strstr(dec_path, "..")) {
13073 std::string str;
13074 str += "Invalid custom gif name \'";
13075 str += dec_path;
13076 str += "\' contains \'..\'";
13077 show_error_404(r, str.c_str());
13078 return;
13079 }
13080
13081 Lock(t);
13082 show_custom_gif(r, dec_path);
13083 Unlock(t);
13084 return;
13085 }
13086
13087 bool found_custom = false;
13088
13089 odb_path = "";
13090 odb_path += "/Custom/";
13091 odb_path += dec_path;
13092
13093 status = db_get_value_string(hDB, 0, odb_path.c_str(), 0, &value, FALSE);
13094
13095 //printf("Try [%s] status %d\n", odb_path.c_str(), status);
13096
13097 if (status == DB_SUCCESS) {
13098 found_custom = true;
13099 } else {
13100 odb_path = "";
13101 odb_path += "/Custom/";
13102 odb_path += dec_path;
13103 odb_path += "&";
13104
13105 status = db_get_value_string(hDB, 0, odb_path.c_str(), 0, &value, FALSE);
13106
13107 //printf("Try [%s] status %d\n", odb_path.c_str(), status);
13108
13109 if (status == DB_SUCCESS) {
13110 found_custom = true;
13111 } else {
13112 odb_path = "";
13113 odb_path += "/Custom/";
13114 odb_path += dec_path;
13115 odb_path += "!";
13116
13117 status = db_get_value_string(hDB, 0, odb_path.c_str(), 0, &value, FALSE);
13118
13119 //printf("Try [%s] status %d\n", odb_path.c_str(), status);
13120
13121 if (status == DB_SUCCESS) {
13122 found_custom = true;
13123 }
13124 }
13125 }
13126
13127 if (found_custom) {
13128 //printf("custom file: serving [%s] value [%s]\n", dec_path, value.c_str());
13129 if (strstr(dec_path, "..")) {
13130 std::string str;
13131 str += "Invalid custom page name \'";
13132 str += dec_path;
13133 str += "\' contains \'..\'";
13134 show_error_404(r, str.c_str());
13135 return;
13136 }
13137
13138 p->setparam("page", dec_path);
13139 Lock(t);
13140 show_custom_page(p, r, c->cookie_cpwd.c_str());
13141 Unlock(t);
13142 return;
13143 }
13144 }
13145
13146 /* new custom pages */
13147 if (db_find_key(hDB, 0, "/Custom", &hkey) == DB_SUCCESS && dec_path[0]) {
13148 std::string custom_path;
13149 status = db_get_value_string(hDB, 0, "/Custom/Path", 0, &custom_path, TRUE);
13150 if ((status == DB_SUCCESS) && (custom_path.length() > 0)) {
13151 if (strstr(dec_path, "..")) {
13152 std::string str;
13153 str += "Invalid custom file name \'";
13154 str += dec_path;
13155 str += "\' contains \'..\'";
13156 show_error_404(r, str.c_str());
13157 return;
13158 }
13159
13160 std::string full_filename = add_custom_path(dec_path);
13161
13162 // if custom file exists, send it (like normal web server)
13163 if (ss_file_exist(full_filename.c_str())) {
13164 send_file(r, full_filename);
13165 return;
13166 }
13167 }
13168 }
13169
13170 /*---- redirect if web page --------------------------------------*/
13171
13172 //if (strlen(command) > 0) {
13173 // if (send_resource(r, std::string(command) + ".html", false))
13174 // return;
13175 //}
13176
13177 /*---- serve url as a resource file ------------------------------*/
13178
13179 if (strlen(p->getparam("path")) > 0) {
13180 if (send_resource(r, p->getparam("path"), false)) {
13181 return;
13182 }
13183 }
13184
13185 /*---- show status -----------------------------------------------*/
13186
13187 if (elog_mode) {
13188 redirect(r, "EL/");
13189 return;
13190 }
13191
13192 /* header */
13193 r->rsprintf("HTTP/1.1 400 Bad Request\r\n");
13194 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
13195 r->rsprintf("Content-Type: text/plain; charset=%s\r\n", HTTP_ENCODING);
13196 r->rsprintf("\r\n");
13197 r->rsprintf("Error: Invalid URL \"%s\" or query \"%s\" or command \"%s\"\n", p->getparam("path"), p->getparam("query"), command);
13198}
BOOL isparam(const char *param)
Definition mhttpd.cxx:835
static bool exists(const std::string &name)
Definition odbxx.cxx:76
int cm_exec_script(const char *odb_path_to_script)
Definition midas.cxx:5479
INT cm_exist(const char *name, BOOL bUnique)
Definition midas.cxx:7531
unsigned short int WORD
Definition mcstd.h:49
#define TID_WORD
Definition midas.h:332
int ss_file_exist(const char *path)
Definition system.cxx:7196
char * ss_crypt(const char *buf, const char *salt)
Definition system.cxx:7969
#define RPC_MANUAL_TRIG
Definition mrpc.h:132
static MVOdb * gOdb
Definition mhttpd.cxx:48
static BOOL history_mode
Definition mhttpd.cxx:95
void show_eqtable_page(Param *pp, Return *r, int refresh)
Definition mhttpd.cxx:2589
void show_find_page(Return *r, const char *value)
Definition mhttpd.cxx:7600
BOOL check_web_password(Return *r, HNDLE hDB, const char *dec_path, const char *password, const char *redir)
Definition mhttpd.cxx:6769
void submit_elog(MVOdb *odb, Param *pp, Return *r, Attachment *a)
Definition mhttpd.cxx:2278
static void urlEncode(char *ps, int ps_size)
Definition mhttpd.cxx:951
void redirect2(Return *r, const char *path)
Definition mhttpd.cxx:1478
static void show_cnaf_page(Param *p, Return *rr)
Definition mhttpd.cxx:5687
void javascript_commands(Param *p, Return *r, const char *cookie_cpwd)
Definition mhttpd.cxx:4481
void show_password_page(Return *r, const char *dec_path, const char *password)
Definition mhttpd.cxx:6735
bool send_resource(Return *r, const std::string &name, bool generate_404=true)
Definition mhttpd.cxx:1261
bool send_file(Return *r, const std::string &path, bool generate_404=true)
Definition mhttpd.cxx:1242
void show_elog_attachment(Param *p, Return *r, const char *path)
Definition mhttpd.cxx:2513
void Unlock(RequestTrace *t)
Definition mhttpd.cxx:12275
void redirect(Return *r, const char *path)
Definition mhttpd.cxx:1441
static std::string add_param_to_url(const char *name, const char *value)
Definition mhttpd.cxx:9813
std::string add_custom_path(const std::string &filename)
Definition mhttpd.cxx:3602
void show_odb_page(Param *pp, Return *r, const char *dec_path, int write_access)
Definition mhttpd.cxx:6826
void send_icon(Return *r, const char *icon)
Definition mhttpd.cxx:12217
static BOOL elog_mode
Definition mhttpd.cxx:94
void Lock(RequestTrace *t)
Definition mhttpd.cxx:12269
void show_set_page(Param *pp, Return *r, const char *group, int index, const char *value)
Definition mhttpd.cxx:7466
void show_hist_page(MVOdb *odb, Param *p, Return *r, const char *dec_path, char *buffer, int *buffer_size, int refresh)
Definition mhttpd.cxx:11295
void redirect_307(Return *r, const char *path)
Definition mhttpd.cxx:1465
void show_custom_page(Param *pp, Return *r, const char *cookie_cpwd)
Definition mhttpd.cxx:5453
void show_help_page(Return *r, const char *dec_path)
Definition mhttpd.cxx:1574
void show_error_404(Return *r, const char *error)
Definition mhttpd.cxx:1883
void show_custom_gif(Return *rr, const char *name)
Definition mhttpd.cxx:3704
#define event_id
Here is the call graph for this function:
Here is the caller graph for this function:

◆ is_editable()

BOOL is_editable ( char *  eq_name,
char *  var_name 
)

Definition at line 2561 of file mhttpd.cxx.

2562{
2563 HNDLE hDB, hkey;
2564 KEY key;
2565 char str[256];
2566 int i, size;
2567
2569 sprintf(str, "/Equipment/%s/Settings/Editable", eq_name);
2570 db_find_key(hDB, 0, str, &hkey);
2571
2572 /* if no editable entry found, use default */
2573 if (!hkey) {
2574 return (equal_ustring(var_name, "Demand") ||
2575 equal_ustring(var_name, "Output") || strncmp(var_name, "D_", 2) == 0);
2576 }
2577
2578 db_get_key(hDB, hkey, &key);
2579 for (i = 0; i < key.num_values; i++) {
2580 size = sizeof(str);
2581 db_get_data_index(hDB, hkey, str, &size, i, TID_STRING);
2583 return TRUE;
2584 }
2585 return FALSE;
2586}
char var_name[256]
Definition odbhist.cxx:41
Here is the call graph for this function:
Here is the caller graph for this function:

◆ javascript_commands()

void javascript_commands ( Param p,
Return r,
const char *  cookie_cpwd 
)

Definition at line 4481 of file mhttpd.cxx.

4482{
4483 int status;
4484 int size, i, n, index, type;
4485 unsigned int t;
4486 char str[TEXT_SIZE], format[256], facility[256], user[256];
4487 HNDLE hDB, hkey;
4488 KEY key;
4489 char data[TEXT_SIZE];
4490
4492
4493 // process common parameters
4494
4495 const int ENCODING_NONE = 0;
4496 const int ENCODING_ODB = 1;
4497 const int ENCODING_XML = 2;
4498 const int ENCODING_JSON = 3;
4499
4500 std::string cmd_parameter;
4501 std::string encoding_parameter;
4502 int encoding = ENCODING_NONE; // default encoding
4503 bool jsonp = false; // default is no JSONP wrapper
4504 std::string jsonp_callback; // default is no JSONP
4505 bool single = false; // single encoding
4506 bool multiple = false; // multiple encoding
4507 std::vector<std::string> odb; // multiple odb parameters
4508 //HNDLE hodb; // ODB handle for single odb parameter
4509 //std::vector<HNDLE> hodbm; // ODB handle for multiple odb parameter
4510
4511 if (p->isparam("cmd")) {
4512 cmd_parameter = p->getparam("cmd");
4513 }
4514
4515 if (p->isparam("encoding")) {
4516 encoding_parameter = p->getparam("encoding");
4517 }
4518
4519 if (encoding_parameter.length() > 0) {
4520 if (starts_with(encoding_parameter, "odb"))
4521 encoding = ENCODING_ODB;
4522 else if (starts_with(encoding_parameter, "xml"))
4523 encoding = ENCODING_XML;
4524 else if (starts_with(encoding_parameter, "json"))
4525 encoding = ENCODING_JSON;
4526 }
4527
4528 if (encoding == ENCODING_JSON) {
4529 if (p->isparam("callback")) {
4530 jsonp = true;
4531 jsonp_callback = p->getparam("callback");
4532 }
4533 }
4534
4535 if (p->isparam("odb")) {
4536 single = true;
4537 odb.push_back(p->getparam("odb"));
4538 }
4539
4540 if (p->isparam("odb0")) {
4541 multiple = true;
4542 for (int i=0 ; ; i++) {
4543 char ppath[256];
4544 sprintf(ppath, "odb%d", i);
4545 if (!p->isparam(ppath))
4546 break;
4547 odb.push_back(p->getparam(ppath));
4548 }
4549 }
4550
4551 if (/* DISABLES CODE */ (0)) {
4552 printf("command [%s], encoding %d [%s], jsonp %d, single %d, multiple %d, odb array size %d\n", cmd_parameter.c_str(), encoding, encoding_parameter.c_str(), jsonp, single, multiple, (int)odb.size());
4553 }
4554
4555 /* process "jset" command */
4556 if (equal_ustring(p->getparam("cmd"), "jset")) {
4557
4558 if (*p->getparam("pnam")) {
4559 std::string ppath;
4560 ppath += "/Custom/Pwd/";
4561 ppath += p->getparam("pnam");
4562 str[0] = 0;
4563 db_get_value(hDB, 0, ppath.c_str(), str, &size, TID_STRING, TRUE);
4564 if (!equal_ustring(cookie_cpwd, str)) {
4566 r->rsprintf("Invalid password!");
4567 return;
4568 }
4569 }
4570 mstrlcpy(str, p->getparam("odb"), sizeof(str));
4571 if (strchr(str, '[')) {
4572 if (*(strchr(str, '[')+1) == '*')
4573 index = -1;
4574 else
4575 index = atoi(strchr(str, '[')+1);
4576 *strchr(str, '[') = 0;
4577 } else
4578 index = 0;
4579
4580 if (db_find_key(hDB, 0, str, &hkey) == DB_SUCCESS && p->isparam("value")) {
4581 db_get_key(hDB, hkey, &key);
4582 memset(data, 0, sizeof(data));
4583 if (key.item_size <= (int)sizeof(data)) {
4584 if (index == -1) {
4585 const char* ptr = p->getparam("value");
4586 for (i=0 ; ptr != NULL ; i++) {
4587 size = sizeof(data);
4588 db_sscanf(ptr, data, &size, 0, key.type);
4589 if (strchr(data, ','))
4590 *strchr(data, ',') = 0;
4592 ptr = strchr(ptr, ',');
4593 if (ptr != NULL)
4594 ptr++;
4595 }
4596 } else {
4597 size = sizeof(data);
4598 db_sscanf(p->getparam("value"), data, &size, 0, key.type);
4599
4600 /* extend data size for single string if necessary */
4601 if ((key.type == TID_STRING || key.type == TID_LINK)
4602 && (int) strlen(data) + 1 > key.item_size && key.num_values == 1) {
4603 key.item_size = strlen(data) + 1;
4604 db_set_data(hDB, hkey, data, key.item_size, 1, key.type);
4605 } else
4607 }
4608 }
4609 } else {
4610 if (p->isparam("value") && p->isparam("type") && p->isparam("len")) {
4611 int type = atoi(p->getparam("type"));
4612 if (type == 0) {
4614 r->rsprintf("Invalid type %d!", type);
4615 return;
4616 }
4617 db_create_key(hDB, 0, str, type);
4618 db_find_key(hDB, 0, str, &hkey);
4619 if (!hkey) {
4621 r->rsprintf("Cannot create \'%s\' type %d", str, type);
4622 return;
4623 }
4624 db_get_key(hDB, hkey, &key);
4625 memset(data, 0, sizeof(data));
4626 size = sizeof(data);
4627 db_sscanf(p->getparam("value"), data, &size, 0, key.type);
4628 if (key.type == TID_STRING)
4629 db_set_data(hDB, hkey, data, atoi(p->getparam("len")), 1, TID_STRING);
4630 else {
4631 for (i=0 ; i<atoi(p->getparam("len")) ; i++)
4633 }
4634 }
4635 }
4636
4638 r->rsprintf("OK");
4639 return;
4640 }
4641
4642 /* process "jget" command */
4643 if (equal_ustring(p->getparam("cmd"), "jget")) {
4644
4645 if (p->isparam("odb")) {
4646 mstrlcpy(str, p->getparam("odb"), sizeof(str));
4647 if (strchr(str, '[')) {
4648 if (*(strchr(str, '[')+1) == '*')
4649 index = -1;
4650 else
4651 index = atoi(strchr(str, '[')+1);
4652 *strchr(str, '[') = 0;
4653 } else
4654 index = 0;
4655
4657
4658 status = db_find_key(hDB, 0, str, &hkey);
4659
4660 if (status == DB_SUCCESS)
4661 output_key(p, r, hkey, index, p->getparam("format"));
4662 else
4663 r->rsputs("<DB_NO_KEY>");
4664 }
4665
4666 if (p->isparam("odb0")) {
4668 for (i=0 ; ; i++) {
4669 char ppath[256];
4670 sprintf(ppath, "odb%d", i);
4671 sprintf(format, "format%d", i);
4672 if (p->isparam(ppath)) {
4673 mstrlcpy(str, p->getparam(ppath), sizeof(str));
4674 if (strchr(str, '[')) {
4675 if (*(strchr(str, '[')+1) == '*')
4676 index = -1;
4677 else
4678 index = atoi(strchr(str, '[')+1);
4679 *strchr(str, '[') = 0;
4680 } else
4681 index = 0;
4682 if (i > 0)
4683 r->rsputs("$#----#$\n");
4684 if (db_find_key(hDB, 0, str, &hkey) == DB_SUCCESS)
4685 output_key(p, r, hkey, index, p->getparam(format));
4686 else
4687 r->rsputs("<DB_NO_KEY>");
4688
4689 } else
4690 break;
4691 }
4692 }
4693
4694 return;
4695 }
4696
4697 /* process "jcopy" command */
4698 if (equal_ustring(p->getparam("cmd"), "jcopy")) {
4699
4700 bool fmt_odb = false;
4701 bool fmt_xml = false;
4702 bool fmt_json = true;
4703 bool fmt_jsonp = false;
4704 int follow_links = 1;
4705 int save_keys = 1;
4706 int recurse = 1;
4707 const char* fmt = NULL;
4708 const char* jsonp_callback = "callback";
4709
4710 if (p->isparam("encoding")) {
4711 fmt = p->getparam("encoding");
4712 } else if (p->isparam("format")) {
4713 fmt = p->getparam("format");
4714 }
4715
4716 if (fmt) {
4717 fmt_odb = (equal_ustring(fmt, "odb") > 0);
4718 fmt_xml = (equal_ustring(fmt, "xml") > 0);
4719 fmt_json = (strstr(fmt, "json") != NULL);
4720
4721 if (fmt_odb)
4722 fmt_xml = fmt_json = false;
4723 if (fmt_xml)
4724 fmt_odb = fmt_json = false;
4725 if (fmt_json)
4726 fmt_odb = fmt_xml = false;
4727
4728 if (fmt_json)
4729 fmt_jsonp = (strstr(fmt, "-p") != NULL);
4730 if (fmt_jsonp && p->isparam("callback"))
4731 jsonp_callback = p->getparam("callback");
4732 if (fmt_json && strstr(fmt, "-nofollowlinks"))
4733 follow_links = 0;
4734 if (fmt_json && strstr(fmt, "-nokeys"))
4735 save_keys = 2;
4736 if (fmt_json && strstr(fmt, "-nolastwritten"))
4737 save_keys = 0;
4738 if (fmt_json && strstr(fmt, "-norecurse"))
4739 recurse = 0;
4740 }
4741
4742 if (p->isparam("odb")) {
4743 mstrlcpy(str, p->getparam("odb"), sizeof(str));
4744
4746
4747 if (fmt_json)
4748 status = db_find_link(hDB, 0, str, &hkey);
4749 else
4750 status = db_find_key(hDB, 0, str, &hkey);
4751 if (status == DB_SUCCESS) {
4752
4753 if (fmt_jsonp) {
4754 r->rsputs(jsonp_callback);
4755 r->rsputs("(");
4756 }
4757
4758 int end = 0;
4759 int bufsize = WEB_BUFFER_SIZE;
4760 char* buf = (char *)malloc(bufsize);
4761
4762 if (fmt_xml)
4763 db_copy_xml(hDB, hkey, buf, &bufsize, true);
4764 else if (fmt_json)
4765 db_copy_json_obsolete(hDB, hkey, &buf, &bufsize, &end, save_keys, follow_links, recurse);
4766 else
4767 db_copy(hDB, hkey, buf, &bufsize, (char *)"");
4768
4769 r->rsputs(buf);
4770 free(buf);
4771
4772 if (fmt_jsonp) {
4773 r->rsputs(");\n");
4774 }
4775 } else
4776 r->rsputs("<DB_NO_KEY>");
4777 }
4778
4779 if (p->isparam("odb0")) {
4781 if (fmt_jsonp) {
4782 r->rsputs(jsonp_callback);
4783 r->rsputs("(");
4784 }
4785 if (fmt_xml) {
4786 r->rsprintf("<?xml version=\"1.0\" encoding=\"%s\"?>\n", HTTP_ENCODING);
4787 r->rsputs("<jcopy>\n");
4788 r->rsputs("<data>\n");
4789 } else if (fmt_json)
4790 r->rsputs("[\n");
4791 else
4792 r->rsputs("");
4793 for (int i=0 ; ; i++) {
4794 char ppath[256];
4795 sprintf(ppath, "odb%d", i);
4796 if (!p->isparam(ppath))
4797 break;
4798 mstrlcpy(str, p->getparam(ppath), sizeof(str));
4799
4800 if (i > 0) {
4801 if (fmt_xml)
4802 r->rsputs("</data>\n<data>\n");
4803 else if (fmt_json)
4804 r->rsputs(",\n");
4805 else
4806 r->rsputs("$#----#$\n");
4807 }
4808
4809 if (fmt_json)
4810 status = db_find_link(hDB, 0, str, &hkey);
4811 else
4812 status = db_find_key(hDB, 0, str, &hkey);
4813 if (status != DB_SUCCESS) {
4814 if (fmt_xml)
4815 r->rsputs("<DB_NO_KEY/>\n");
4816 else if (fmt_json) {
4817 char tmp[256];
4818 sprintf(tmp, "{ \"/error\" : %d }\n", status);
4819 r->rsputs(tmp);
4820 } else
4821 r->rsputs("<DB_NO_KEY>\n");
4822 continue;
4823 }
4824
4825 int end = 0;
4826 int bufsize = WEB_BUFFER_SIZE;
4827 char* buf = (char *)malloc(bufsize);
4828
4829 if (fmt_xml) {
4830 db_copy_xml(hDB, hkey, buf, &bufsize, true);
4831 const char* s = strstr(buf, "-->");
4832 if (s)
4833 s+=4;
4834 else
4835 s = buf;
4836 r->rsputs(s);
4837 } else if (fmt_json) {
4838 db_copy_json_obsolete(hDB, hkey, &buf, &bufsize, &end, save_keys, follow_links, recurse);
4839 r->rsputs(buf);
4840 } else {
4841 db_copy(hDB, hkey, buf, &bufsize, (char *)"");
4842 r->rsputs(buf);
4843 }
4844
4845 free(buf);
4846 }
4847
4848 if (fmt_xml)
4849 r->rsputs("</data>\n</jcopy>\n");
4850 else if (fmt_json)
4851 r->rsputs("]\n");
4852 else
4853 r->rsputs("");
4854
4855 if (fmt_jsonp) {
4856 r->rsputs(");\n");
4857 }
4858 }
4859 return;
4860 }
4861
4862 /* process "jkey" command */
4863 if (equal_ustring(p->getparam("cmd"), "jkey")) {
4864
4865 // test:
4866 // curl "http://localhost:8080?cmd=jkey&odb0=/runinfo/run+number&odb1=/nonexistant&odb2=/&encoding=json&callback=aaa"
4867
4869
4870 if (jsonp) {
4871 r->rsputs(jsonp_callback.c_str());
4872 r->rsputs("(");
4873 }
4874
4875 if (multiple) {
4876 switch (encoding) {
4877 default:
4878 break;
4879 case ENCODING_JSON:
4880 r->rsprintf("[ ");
4881 break;
4882 }
4883 }
4884
4885 for (unsigned i=0; i<odb.size(); i++) {
4886 status = db_find_key(hDB, 0, odb[i].c_str(), &hkey);
4887 if (status == DB_SUCCESS)
4888 status = db_get_key(hDB, hkey, &key);
4889 switch (encoding) {
4890 default:
4891 if (multiple && i>0)
4892 r->rsputs("$#----#$\n");
4893 if (status == DB_SUCCESS) {
4894 r->rsprintf("%s\n", key.name);
4895 r->rsprintf("TID_%s\n", rpc_tid_name(key.type));
4896 r->rsprintf("%d\n", key.num_values);
4897 r->rsprintf("%d\n", key.item_size);
4898 r->rsprintf("%d\n", key.last_written);
4899 } else {
4900 r->rsputs("<DB_NO_KEY>\n");
4901 }
4902 break;
4903 case ENCODING_JSON:
4904 if (multiple && i>0)
4905 r->rsprintf(", ");
4906 if (status == DB_SUCCESS) {
4907 r->rsprintf("{ ");
4908 r->rsprintf("\"name\":\"%s\",", key.name);
4909 r->rsprintf("\"type\":%d,", key.type);
4910 r->rsprintf("\"type_name\":\"TID_%s\",", rpc_tid_name(key.type));
4911 r->rsprintf("\"num_values\":%d,", key.num_values);
4912 r->rsprintf("\"item_size\":%d,", key.item_size);
4913 r->rsprintf("\"last_written\":%d", key.last_written);
4914 r->rsprintf(" }");
4915 } else {
4916 r->rsprintf("{ \"/error\":%d }", status);
4917 }
4918 break;
4919 }
4920 }
4921
4922 if (multiple) {
4923 switch (encoding) {
4924 default:
4925 break;
4926 case ENCODING_JSON:
4927 r->rsprintf(" ]");
4928 break;
4929 }
4930 }
4931
4932 if (jsonp) {
4933 r->rsputs(");\n");
4934 }
4935
4936 return;
4937 }
4938
4939 /* process "jcreate" command */
4940 if (equal_ustring(p->getparam("cmd"), "jcreate")) {
4941
4942 // test:
4943 // curl "http://localhost:8080?cmd=jcreate&odb0=/test/foo&type0=7&odb1=/nonexistant&type1=100&odb2=/test/bar&type2=12&encoding=json&callback=aaa"
4944 // curl "http://localhost:8080?cmd=jcreate&odb=/test/foo&type=7"
4945 // curl "http://localhost:8080?cmd=jcreate&odb=/test/foo70&type=7&arraylen=10"
4946 // curl "http://localhost:8080?cmd=jcreate&odb=/test/foo12s&type=12&strlen=32"
4947 // curl "http://localhost:8080?cmd=jcreate&odb=/test/foo12s5&type=12&strlen=32&arraylen=5"
4948 // curl "http://localhost:8080?cmd=jcreate&odb0=/test/foo12s5x&type0=12&strlen0=32&arraylen0=5"
4949
4950
4952
4953 if (jsonp) {
4954 r->rsputs(jsonp_callback.c_str());
4955 r->rsputs("(");
4956 }
4957
4958 if (multiple) {
4959 switch (encoding) {
4960 default:
4961 case ENCODING_JSON:
4962 r->rsprintf("[ ");
4963 break;
4964 }
4965 }
4966
4967 for (unsigned i=0; i<odb.size(); i++) {
4968 HNDLE hkey = 0;
4969 int type = 0;
4970 int arraylength = 0;
4971 int strlength = 0;
4972
4973 if (single) {
4974 type = atoi(p->getparam("type"));
4975 arraylength = atoi(p->getparam("arraylen"));
4976 strlength = atoi(p->getparam("strlen"));
4977 }
4978 else if (multiple) {
4979 char buf[256];
4980 sprintf(buf, "type%d", i);
4981 type = atoi(p->getparam(buf));
4982 sprintf(buf, "arraylen%d", i);
4983 arraylength = atoi(p->getparam(buf));
4984 sprintf(buf, "strlen%d", i);
4985 strlength = atoi(p->getparam(buf));
4986 }
4987
4988 status = db_create_key(hDB, 0, odb[i].c_str(), type);
4989
4990 if (status == DB_SUCCESS) {
4991 status = db_find_link(hDB, 0, odb[i].c_str(), &hkey);
4992 }
4993
4994 if (status == DB_SUCCESS && hkey && type == TID_STRING && strlength > 0) {
4995 char* s = (char*)calloc(strlength, 1); // initialized to zero
4996 status = db_set_data(hDB, hkey, s, strlength, 1, TID_STRING);
4997 free(s);
4998 }
4999
5000 if (status == DB_SUCCESS && hkey && arraylength > 1) {
5001 status = db_set_num_values(hDB, hkey, arraylength);
5002 }
5003
5004 switch (encoding) {
5005 default:
5006 case ENCODING_JSON:
5007 if (multiple && i>0)
5008 r->rsprintf(", ");
5009 r->rsprintf("%d", status);
5010 break;
5011 }
5012 }
5013
5014 if (multiple) {
5015 switch (encoding) {
5016 default:
5017 case ENCODING_JSON:
5018 r->rsprintf(" ]");
5019 break;
5020 }
5021 }
5022
5023 if (jsonp) {
5024 r->rsputs(");\n");
5025 }
5026
5027 return;
5028 }
5029
5030 /* process "jresize" command */
5031 if (equal_ustring(p->getparam("cmd"), "jresize")) {
5032
5033 // test:
5034
5035 // curl "http://localhost:8080?cmd=jresize&odb=/test/foo70&arraylen=5"
5036 // curl "http://localhost:8080?cmd=jresize&odb=/test/foo12s5&arraylen=5"
5037 // curl "http://localhost:8080?cmd=jresize&odb=/test/foo12s5&strlen=16"
5038 // curl "http://localhost:8080?cmd=jresize&odb=/test/foo12s5&strlen=30&arraylen=10"
5039
5041
5042 if (jsonp) {
5043 r->rsputs(jsonp_callback.c_str());
5044 r->rsputs("(");
5045 }
5046
5047 if (multiple) {
5048 switch (encoding) {
5049 default:
5050 case ENCODING_JSON:
5051 r->rsprintf("[ ");
5052 break;
5053 }
5054 }
5055
5056 for (unsigned i=0; i<odb.size(); i++) {
5057 HNDLE hkey;
5058 KEY key;
5059 int arraylength = 0;
5060 int strlength = 0;
5061
5062 if (single) {
5063 arraylength = atoi(p->getparam("arraylen"));
5064 strlength = atoi(p->getparam("strlen"));
5065 }
5066 else if (multiple) {
5067 char buf[256];
5068 sprintf(buf, "arraylen%d", i);
5069 arraylength = atoi(p->getparam(buf));
5070 sprintf(buf, "strlen%d", i);
5071 strlength = atoi(p->getparam(buf));
5072 }
5073
5074 status = db_find_key(hDB, 0, odb[i].c_str(), &hkey);
5075
5076 if (status == DB_SUCCESS && hkey) {
5077 status = db_get_key(hDB, hkey, &key);
5078 }
5079
5080 if (status == DB_SUCCESS && hkey && key.type == TID_STRING && strlength > 0) {
5081 int oldsize = key.item_size * key.num_values;
5082 char* olddata = (char*)malloc(oldsize);
5083 int size = oldsize;
5084 status = db_get_data(hDB, hkey, olddata, &size, TID_STRING);
5085
5086 if (status == DB_SUCCESS) {
5087 int newsize = strlength * key.num_values;
5088 char* s = (char*)calloc(newsize, 1); // initialized to zero
5089 for (int k=0; k<key.num_values; k++) {
5090 mstrlcpy(s + strlength*k, olddata + key.item_size*k, strlength);
5091 }
5092
5093 status = db_set_data(hDB, hkey, s, newsize, key.num_values, TID_STRING);
5094 free(s);
5095 }
5096
5097 free(olddata);
5098 }
5099
5100 if (status == DB_SUCCESS && hkey && arraylength > 0) {
5101 status = db_set_num_values(hDB, hkey, arraylength);
5102 }
5103
5104 switch (encoding) {
5105 default:
5106 case ENCODING_JSON:
5107 if (multiple && i>0)
5108 r->rsprintf(", ");
5109 r->rsprintf("%d", status);
5110 break;
5111 }
5112 }
5113
5114 if (multiple) {
5115 switch (encoding) {
5116 default:
5117 case ENCODING_JSON:
5118 r->rsprintf(" ]");
5119 break;
5120 }
5121 }
5122
5123 if (jsonp) {
5124 r->rsputs(");\n");
5125 }
5126
5127 return;
5128 }
5129
5130 /* process "jrename" command */
5131 if (equal_ustring(p->getparam("cmd"), "jrename")) {
5132
5133 // test:
5134 // curl "http://localhost:8080?cmd=jrename&odb0=/test/foo&type0=7&odb1=/nonexistant&type1=100&odb2=/test/bar&type2=12&encoding=json&callback=aaa"
5135 // curl "http://localhost:8080?cmd=jrename&odb=/test/foo&name=foofoo"
5136
5138
5139 if (jsonp) {
5140 r->rsputs(jsonp_callback.c_str());
5141 r->rsputs("(");
5142 }
5143
5144 if (multiple) {
5145 switch (encoding) {
5146 default:
5147 case ENCODING_JSON:
5148 r->rsprintf("[ ");
5149 break;
5150 }
5151 }
5152
5153 for (unsigned i=0; i<odb.size(); i++) {
5154 const char* name = NULL;
5155 if (single)
5156 name = p->getparam("name");
5157 else if (multiple) {
5158 char buf[256];
5159 sprintf(buf, "name%d", i);
5160 name = p->getparam(buf);
5161 }
5162 status = db_find_key(hDB, 0, odb[i].c_str(), &hkey);
5163 if (status == DB_SUCCESS) {
5164 status = db_rename_key(hDB, hkey, name);
5165 }
5166 switch (encoding) {
5167 default:
5168 case ENCODING_JSON:
5169 if (multiple && i>0)
5170 r->rsprintf(", ");
5171 r->rsprintf("%d", status);
5172 break;
5173 }
5174 }
5175
5176 if (multiple) {
5177 switch (encoding) {
5178 default:
5179 case ENCODING_JSON:
5180 r->rsprintf(" ]");
5181 break;
5182 }
5183 }
5184
5185 if (jsonp) {
5186 r->rsputs(");\n");
5187 }
5188
5189 return;
5190 }
5191
5192 /* process "jlink" command */
5193 if (equal_ustring(p->getparam("cmd"), "jlink")) {
5194
5195 // test:
5196 // curl "http://localhost:8080?cmd=jlink&odb=/test/link&dest=/test/foo"
5197 // curl "http://localhost:8080?cmd=jlink&odb0=/test/link0&dest0=/test/foo&odb1=/test/link1&dest1=/test/foo"
5198
5200
5201 if (jsonp) {
5202 r->rsputs(jsonp_callback.c_str());
5203 r->rsputs("(");
5204 }
5205
5206 if (multiple) {
5207 switch (encoding) {
5208 default:
5209 case ENCODING_JSON:
5210 r->rsprintf("[ ");
5211 break;
5212 }
5213 }
5214
5215 for (unsigned i=0; i<odb.size(); i++) {
5216 const char* dest = NULL;
5217 if (single)
5218 dest = p->getparam("dest");
5219 else if (multiple) {
5220 char buf[256];
5221 sprintf(buf, "dest%d", i);
5222 dest = p->getparam(buf);
5223 }
5224
5225 status = db_create_link(hDB, 0, odb[i].c_str(), dest);
5226
5227 switch (encoding) {
5228 default:
5229 case ENCODING_JSON:
5230 if (multiple && i>0)
5231 r->rsprintf(", ");
5232 r->rsprintf("%d", status);
5233 break;
5234 }
5235 }
5236
5237 if (multiple) {
5238 switch (encoding) {
5239 default:
5240 case ENCODING_JSON:
5241 r->rsprintf(" ]");
5242 break;
5243 }
5244 }
5245
5246 if (jsonp) {
5247 r->rsputs(");\n");
5248 }
5249
5250 return;
5251 }
5252
5253 /* process "jreorder" command */
5254 if (equal_ustring(p->getparam("cmd"), "jreorder")) {
5255
5256 // test:
5257 // curl "http://localhost:8080?cmd=jreorder&odb0=/test/foo&index0=0&odb1=/test/bar&index1=1"
5258 // curl "http://localhost:8080?cmd=jreorder&odb=/test/bar&index=0"
5259
5261
5262 if (jsonp) {
5263 r->rsputs(jsonp_callback.c_str());
5264 r->rsputs("(");
5265 }
5266
5267 if (multiple) {
5268 switch (encoding) {
5269 default:
5270 case ENCODING_JSON:
5271 r->rsprintf("[ ");
5272 break;
5273 }
5274 }
5275
5276 for (unsigned i=0; i<odb.size(); i++) {
5277 int index = 0;
5278 if (single)
5279 index = atoi(p->getparam("index"));
5280 else if (multiple) {
5281 char buf[256];
5282 sprintf(buf, "index%d", i);
5283 index = atoi(p->getparam(buf));
5284 }
5285
5286 status = db_find_key(hDB, 0, odb[i].c_str(), &hkey);
5287 if (status == DB_SUCCESS) {
5288 status = db_reorder_key(hDB, hkey, index);
5289 }
5290
5291 switch (encoding) {
5292 default:
5293 case ENCODING_JSON:
5294 if (multiple && i>0)
5295 r->rsprintf(", ");
5296 r->rsprintf("%d", status);
5297 break;
5298 }
5299 }
5300
5301 if (multiple) {
5302 switch (encoding) {
5303 default:
5304 case ENCODING_JSON:
5305 r->rsprintf(" ]");
5306 break;
5307 }
5308 }
5309
5310 if (jsonp) {
5311 r->rsputs(");\n");
5312 }
5313
5314 return;
5315 }
5316
5317 /* process "jdelete" command */
5318 if (equal_ustring(p->getparam("cmd"), "jdelete")) {
5319
5320 // test:
5321 // curl "http://localhost:8080?cmd=jdelete&odb0=/test/foo&odb1=/nonexistant&odb2=/test/bar&encoding=json&callback=aaa"
5322 // curl "http://localhost:8080?cmd=jdelete&odb=/test/foo"
5323
5325
5326 if (jsonp) {
5327 r->rsputs(jsonp_callback.c_str());
5328 r->rsputs("(");
5329 }
5330
5331 if (multiple) {
5332 switch (encoding) {
5333 default:
5334 case ENCODING_JSON:
5335 r->rsprintf("[ ");
5336 break;
5337 }
5338 }
5339
5340 for (unsigned i=0; i<odb.size(); i++) {
5341 status = db_delete(hDB, 0, odb[i].c_str());
5342 switch (encoding) {
5343 default:
5344 case ENCODING_JSON:
5345 if (multiple && i>0)
5346 r->rsprintf(", ");
5347 r->rsprintf("%d", status);
5348 break;
5349 }
5350 }
5351
5352 if (multiple) {
5353 switch (encoding) {
5354 default:
5355 case ENCODING_JSON:
5356 r->rsprintf(" ]");
5357 break;
5358 }
5359 }
5360
5361 if (jsonp) {
5362 r->rsputs(");\n");
5363 }
5364
5365 return;
5366 }
5367
5368 /* process "jmsg" command */
5369 if (equal_ustring(p->getparam("cmd"), "jmsg")) {
5370
5371 if (p->getparam("f") && *p->getparam("f"))
5372 mstrlcpy(facility, p->getparam("f"), sizeof(facility));
5373 else
5374 mstrlcpy(facility, "midas", sizeof(facility));
5375
5376 n = 1;
5377 if (p->getparam("n") && *p->getparam("n"))
5378 n = atoi(p->getparam("n"));
5379
5380 t = 0;
5381 if (p->getparam("t") && p->getparam("t"))
5382 t = atoi(p->getparam("t"));
5383
5385 char* messages = NULL;
5386 int num_messages = 0;
5387 cm_msg_retrieve2(facility, t, n, &messages, &num_messages);
5388 if (messages) {
5389 r->rsputs(messages);
5390 free(messages);
5391 }
5392 return;
5393 }
5394
5395 /* process "jgenmsg" command */
5396 if (equal_ustring(p->getparam("cmd"), "jgenmsg")) {
5397
5398 if (p->getparam("facility") && *p->getparam("facility"))
5399 mstrlcpy(facility, p->getparam("facility"), sizeof(facility));
5400 else
5401 mstrlcpy(facility, "midas", sizeof(facility));
5402
5403 if (p->getparam("user") && *p->getparam("user"))
5404 mstrlcpy(user, p->getparam("user"), sizeof(user));
5405 else
5406 mstrlcpy(user, "javascript_commands", sizeof(user));
5407
5408 if (p->getparam("type") && *p->getparam("type"))
5409 type = atoi(p->getparam("type"));
5410 else
5411 type = MT_INFO;
5412
5413 if (p->getparam("msg") && *p->getparam("msg")) {
5414 cm_msg1(type, __FILE__, __LINE__, facility, user, "%s", p->getparam("msg"));
5415 }
5416
5418 r->rsputs("Message successfully created\n");
5419 return;
5420 }
5421
5422 /* process "jalm" command */
5423 if (equal_ustring(p->getparam("cmd"), "jalm")) {
5424
5426 std::string alarms;
5427 al_get_alarms(&alarms);
5428 r->rsputs(alarms.c_str());
5429 return;
5430 }
5431
5432 /* process "jrpc" command */
5433 if (equal_ustring(p->getparam("cmd"), "jrpc_rev0")) {
5434 do_jrpc_rev0(p, r);
5435 return;
5436 }
5437
5438 /* process "jrpc" command */
5439 if (equal_ustring(p->getparam("cmd"), "jrpc_rev1")) {
5440 do_jrpc_rev1(p, r);
5441 return;
5442 }
5443
5444 /* process "jrpc" command */
5445 if (equal_ustring(p->getparam("cmd"), "jrpc")) {
5446 do_jrpc(p, r);
5447 return;
5448 }
5449}
INT al_get_alarms(std::string *presult)
Definition alarm.cxx:862
#define MT_INFO
Definition midas.h:543
INT cm_msg1(INT message_type, const char *filename, INT line, const char *facility, const char *routine, const char *format,...)
Definition midas.cxx:989
INT cm_msg_retrieve2(const char *facility, time_t t, INT n_message, char **messages, int *num_messages)
Definition midas.cxx:1280
INT db_find_link(HNDLE hDB, HNDLE hKey, const char *key_name, HNDLE *subhKey)
Definition odb.cxx:4293
INT db_reorder_key(HNDLE hDB, HNDLE hKey, INT idx)
Definition odb.cxx:6385
INT db_copy(HNDLE hDB, HNDLE hKey, char *buffer, INT *buffer_size, const char *path)
Definition odb.cxx:8230
INT db_create_key(HNDLE hDB, HNDLE hKey, const char *key_name, DWORD type)
Definition odb.cxx:3392
INT db_copy_xml(HNDLE hDB, HNDLE hKey, char *buffer, int *buffer_size, bool header)
Definition odb.cxx:9055
INT db_set_data_index(HNDLE hDB, HNDLE hKey, const void *data, INT data_size, INT idx, DWORD type)
Definition odb.cxx:7668
INT db_set_data(HNDLE hDB, HNDLE hKey, const void *data, INT buf_size, INT num_values, DWORD type)
Definition odb.cxx:7239
INT db_copy_json_obsolete(HNDLE hDB, HNDLE hKey, char **buffer, int *buffer_size, int *buffer_end, int save_keys, int follow_links, int recurse)
Definition odb.cxx:10529
INT db_rename_key(HNDLE hDB, HNDLE hKey, const char *name)
Definition odb.cxx:6285
INT db_sscanf(const char *data_str, void *data, INT *data_size, INT i, DWORD tid)
Definition odb.cxx:11336
INT db_set_num_values(HNDLE hDB, HNDLE hKey, INT num_values)
Definition odb.cxx:7523
INT db_create_link(HNDLE hDB, HNDLE hKey, const char *link_name, const char *destination)
Definition odb.cxx:3688
const char * rpc_tid_name(INT id)
Definition midas.cxx:11895
INT rpc_tid_size(INT id)
Definition midas.cxx:11888
#define WEB_BUFFER_SIZE
Definition mhttpd.cxx:541
void output_key(Param *p, Return *r, HNDLE hkey, int index, const char *format)
Definition mhttpd.cxx:4406
void do_jrpc(Param *p, Return *r)
Definition mhttpd.cxx:4352
void do_jrpc_rev1(Param *p, Return *r)
Definition mhttpd.cxx:4171
void do_jrpc_rev0(Param *p, Return *r)
Definition mhttpd.cxx:4046
#define TEXT_SIZE
Definition mhttpd.cxx:729
#define end
INT last_written
Definition midas.h:1038
Here is the call graph for this function:
Here is the caller graph for this function:

◆ LoadHistPlotFromOdb()

static void LoadHistPlotFromOdb ( MVOdb *  odb,
HistPlot hp,
const char *  group,
const char *  panel 
)
static

Definition at line 10228 of file mhttpd.cxx.

10229{
10230 std::string path = "History/Display/";
10231 path += group;
10232 path += "/";
10233 path += panel;
10234
10235 MVOdb* o = odb->Chdir(path.c_str());
10236 if (!o) {
10237 return;
10238 }
10239
10240 o->RS("Timescale", &hp->timescale);
10241 o->RD("Minimum", &hp->minimum);
10242 o->RD("Maximum", &hp->maximum);
10243 o->RB("Zero ylow", &hp->zero_ylow);
10244 o->RB("Log axis", &hp->log_axis);
10245 o->RB("Zero ylow", &hp->zero_ylow);
10246 o->RB("Show run markers", &hp->show_run_markers);
10247 o->RB("Show values", &hp->show_values);
10248 o->RB("Show fill", &hp->show_fill);
10249 o->RB("Show factor", &hp->show_factor);
10250 //o->RB("Enable factor and offset", &hp->enable_factor);
10251
10252 std::vector<std::string> hist_vars;
10253 std::vector<std::string> hist_formula;
10254 std::vector<std::string> hist_colour;
10255 std::vector<std::string> hist_label;
10256 std::vector<bool> hist_show_raw_value;
10257 std::vector<double> hist_factor;
10258 std::vector<double> hist_offset;
10259 std::vector<double> hist_voffset;
10260
10261 o->RSA("Variables", &hist_vars);
10262 o->RSA("Formula", &hist_formula);
10263 o->RSA("Colour", &hist_colour);
10264 o->RSA("Label", &hist_label);
10265 o->RBA("Show raw value", &hist_show_raw_value);
10266 o->RDA("Factor", &hist_factor);
10267 o->RDA("Offset", &hist_offset);
10268 o->RDA("VOffset", &hist_voffset);
10269
10270 // fix broken plots with "factor" all zero. for reasons
10271 // unknown the new history code has corrupted many
10272 // history plot definitions like this. K.O.
10273 {
10274 bool all_zero = true;
10275 for (size_t i=0; i<hist_factor.size(); i++) {
10276 if (hist_factor[i] != 0)
10277 all_zero = false;
10278 }
10279 if (all_zero) {
10280 for (size_t i=0; i<hist_factor.size(); i++) {
10281 hist_factor[i] = 1.0;
10282 }
10283 }
10284 }
10285
10286 size_t num = std::max(hist_vars.size(), hist_formula.size());
10287 num = std::max(num, hist_colour.size());
10288 num = std::max(num, hist_label.size());
10289 num = std::max(num, hist_show_raw_value.size());
10290 num = std::max(num, hist_factor.size());
10291 num = std::max(num, hist_offset.size());
10292 num = std::max(num, hist_voffset.size());
10293
10294 hist_vars.resize(num);
10295 hist_formula.resize(num);
10296 hist_colour.resize(num);
10297 hist_label.resize(num);
10298 hist_show_raw_value.resize(num);
10299 hist_factor.resize(num, 1.0);
10300 hist_offset.resize(num, 0.0);
10301 hist_voffset.resize(num, 0.0);
10302
10303 for (size_t i=0; i<num; i++) {
10304 HistVar v;
10305
10306 SplitEventAndTagNames(hist_vars[i], v.event_name, v.tag_name);
10307
10308 v.formula = hist_formula[i];
10309 v.colour = hist_colour[i];
10310 v.label = hist_label[i];
10311 v.show_raw_value = hist_show_raw_value[i];
10312 v.factor = hist_factor[i];
10313 v.offset = hist_offset[i];
10314 v.voffset = hist_voffset[i];
10315 v.order = NextHistPlotOrder(*hp);
10316
10317 // one-time migration of factor and offset to formula
10318 if (hp->enable_factor && v.formula.empty()) {
10319 if (v.factor!=1 || v.offset!=0 || v.voffset!=0) {
10320 v.formula = msprintf("%g%+g*(x%+g)", v.offset, v.factor, -v.voffset);
10321 }
10322 }
10323
10324 hp->vars.push_back(v);
10325 }
10326
10327// printf("Load from ODB %s: ", path.c_str());
10328// PrintHistPlot(*hp);
10329
10330 delete o;
10331}
bool show_fill
Definition mhttpd.cxx:8380
bool show_factor
Definition mhttpd.cxx:8381
double factor
Definition mhttpd.cxx:8366
double offset
Definition mhttpd.cxx:8367
std::string formula
Definition mhttpd.cxx:8361
std::string label
Definition mhttpd.cxx:8363
double voffset
Definition mhttpd.cxx:8368
bool show_raw_value
Definition mhttpd.cxx:8364
Here is the call graph for this function:
Here is the caller graph for this function:

◆ LoadHistPlotFromParam()

static void LoadHistPlotFromParam ( HistPlot hp,
Param p 
)
static

Definition at line 10333 of file mhttpd.cxx.

10334{
10335 hp->timescale = p->getparam("timescale");
10336 hp->minimum = strtod(p->getparam("minimum"), NULL);
10337 hp->maximum = strtod(p->getparam("maximum"), NULL);
10338 hp->zero_ylow = *p->getparam("zero_ylow");
10339 hp->log_axis = *p->getparam("log_axis");
10340 hp->show_run_markers = *p->getparam("run_markers");
10341 hp->show_values = *p->getparam("show_values");
10342 hp->show_fill = *p->getparam("show_fill");
10343 hp->show_factor = *p->getparam("show_factor");
10344 //hp->enable_factor = *p->getparam("enable_factor");
10345
10346 for (int index=0; ; index++) {
10347 char str[256];
10348 sprintf(str, "event%d", index);
10349
10350 //printf("param event %d: [%s] [%s] [%d]\n", index, str, p->getparam(str), *p->getparam(str));
10351
10352 if (!p->isparam(str))
10353 break;
10354
10355 if (*p->getparam(str) == '/') // "/empty"
10356 continue;
10357
10358 HistVar v;
10359
10360 v.event_name = p->xgetparam(str);
10361
10362 sprintf(str, "var%d", index);
10363 v.tag_name = p->xgetparam(str);
10364
10365 sprintf(str, "form%d", index);
10366 v.formula = p->xgetparam(str);
10367
10368 sprintf(str, "col%d", index);
10369 v.colour = p->xgetparam(str);
10370
10371 sprintf(str, "lab%d", index);
10372 v.label = p->xgetparam(str);
10373
10374 sprintf(str, "raw%d", index);
10375 v.show_raw_value = atoi(p->xgetparam(str).c_str());
10376
10377 sprintf(str, "factor%d", index);
10378 if (p->isparam(str)) {
10379 v.factor = atof(p->xgetparam(str).c_str());
10380 } else {
10381 v.factor = 1.0;
10382 }
10383
10384 sprintf(str, "offset%d", index);
10385 v.offset = atof(p->xgetparam(str).c_str());
10386
10387 sprintf(str, "voffset%d", index);
10388 v.voffset = atof(p->xgetparam(str).c_str());
10389
10390 sprintf(str, "ord%d", index);
10391 if (p->isparam(str)) {
10392 v.order = atoi(p->xgetparam(str).c_str());
10393 } else {
10394 v.order = NextHistPlotOrder(*hp);
10395 }
10396
10397 hp->vars.push_back(v);
10398 }
10399
10400 /* correctly number newly added variables */
10401 for (size_t index=0; index<hp->vars.size(); index++) {
10402 if (hp->vars[index].order < 0)
10403 hp->vars[index].order = NextHistPlotOrder(*hp);
10404 }
10405
10406// printf("Load from param:\n");
10407// PrintHistPlot(*hp);
10408}
std::string xgetparam(const char *param)
Definition mhttpd.cxx:826
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Lock()

void Lock ( RequestTrace t)

Definition at line 12269 of file mhttpd.cxx.

12270{
12271 gMutex.lock();
12272 t->fTimeLocked = GetTimeSec();
12273}
double fTimeLocked
Definition mhttpd.cxx:419
static std::mutex gMutex
Definition mhttpd.cxx:47
Here is the call graph for this function:
Here is the caller graph for this function:

◆ main()

int main ( int  argc,
const char *  argv[] 
)

Definition at line 16256 of file mhttpd.cxx.

16257{
16258 int status;
16259 int daemon = FALSE;
16260#ifdef HAVE_MONGOOSE6
16261 int user_http_port = 0;
16262 int user_https_port = 0;
16263#endif
16264#ifdef HAVE_MONGOOSE616
16265 bool no_passwords = false;
16266 bool no_hostlist = false;
16267#endif
16268 const char *myname = "mhttpd";
16269
16270 setbuf(stdout, NULL);
16271 setbuf(stderr, NULL);
16272#ifdef SIGPIPE
16273 /* avoid getting killed by "Broken pipe" signals */
16274 signal(SIGPIPE, SIG_IGN);
16275#endif
16276
16277#ifdef HAVE_MONGOOSE6
16278 //
16279 // if running setuid-root, unconditionally bind to port 80.
16280 //
16281
16282 int socket_priviledged_port = -1;
16283
16284#ifdef OS_UNIX
16285 // in setuid-root mode bind to priviledged port
16286 if (getuid() != geteuid()) {
16287 int port80 = 80;
16288
16289 printf("mhttpd is running in setuid-root mode.\n");
16290
16291 socket_priviledged_port = open_listening_socket(port80);
16292 if (socket_priviledged_port < 0) {
16293 printf("Cannot open listening socket on TCP port %d, aborting.\n", port80);
16294 exit(1);
16295 }
16296
16297 // give up root privilege
16298 status = setuid(getuid());
16299 if (status != 0) {
16300 printf("Cannot give up root privelege, aborting.\n");
16301 exit(1);
16302 }
16303 status = setuid(getuid());
16304 if (status != 0) {
16305 printf("Cannot give up root privelege, aborting.\n");
16306 exit(1);
16307 }
16308 }
16309#endif
16310#endif
16311
16312 char midas_hostname[256];
16313 char midas_expt[256];
16314
16315 /* get default from environment */
16316 cm_get_environment(midas_hostname, sizeof(midas_hostname), midas_expt, sizeof(midas_expt));
16317
16318 /* parse command line parameters */
16319#ifdef HAVE_MONGOOSE6
16320 gUserAllowedHosts.clear();
16321#else
16322 std::vector<std::string> user_hostlist;
16323#endif
16324 for (int i = 1; i < argc; i++) {
16325 if (argv[i][0] == '-' && argv[i][1] == 'D')
16326 daemon = TRUE;
16327 else if (argv[i][0] == '-' && argv[i][1] == 'v')
16328 verbose = TRUE;
16329 else if (argv[i][0] == '-' && argv[i][1] == 'E')
16330 elog_mode = TRUE;
16331 else if (argv[i][0] == '-' && argv[i][1] == 'H') {
16333#ifdef HAVE_MONGOOSE6
16334 } else if (strcmp(argv[i], "--http") == 0) {
16335 if (argv[i+1]) {
16336 user_http_port = atoi(argv[i+1]);
16337 }
16338 } else if (strcmp(argv[i], "--https") == 0) {
16339 if (argv[i+1]) {
16340 user_https_port = atoi(argv[i+1]);
16341 }
16342#endif
16343 } else if (strcmp(argv[i], "--trace-mg") == 0) {
16344 trace_mg = true;
16345 trace_mg_recv = true;
16346 trace_mg_send = true;
16347 } else if (strcmp(argv[i], "--trace-mg-verbose") == 0) {
16348 trace_mg_verbose = true;
16349 } else if (strcmp(argv[i], "--no-trace-mg-recv") == 0) {
16350 trace_mg_recv = false;
16351 } else if (strcmp(argv[i], "--no-trace-mg-send") == 0) {
16352 trace_mg_send = false;
16353 } else if (strcmp(argv[i], "--verbose-mg") == 0) {
16354 verbose_mg = true;
16355#ifdef HAVE_MONGOOSE616
16356 } else if (strcmp(argv[i], "--no-multithread") == 0) {
16357 multithread_mg = false;
16358 } else if (strcmp(argv[i], "--no-passwords") == 0) {
16359 no_passwords = true;
16360 } else if (strcmp(argv[i], "--no-hostlist") == 0) {
16361 no_hostlist = true;
16362#endif
16363 } else if (argv[i][0] == '-') {
16364 if (i + 1 >= argc || argv[i + 1][0] == '-')
16365 goto usage;
16366 if (argv[i][1] == 'h')
16367 mstrlcpy(midas_hostname, argv[++i], sizeof(midas_hostname));
16368 else if (argv[i][1] == 'e')
16369 mstrlcpy(midas_expt, argv[++i], sizeof(midas_hostname));
16370 else if (argv[i][1] == 'a') {
16371#ifdef HAVE_MONGOOSE6
16372 gUserAllowedHosts.push_back(argv[++i]);
16373#else
16374 user_hostlist.push_back(argv[++i]);
16375#endif
16376 } else if (argv[i][1] == 'p') {
16377 printf("Option \"-p port_number\" for the old web server is obsolete.\n");
16378 printf("mongoose web server is the new default, port number is set in ODB or with \"--http port_number\".\n");
16379 printf("To run the obsolete old web server, please use \"--oldserver\" switch.\n");
16380 return 1;
16381 } else {
16382 usage:
16383 printf("usage: %s [-h Hostname[:port]] [-e Experiment] [-v] [-D] [-a Hostname]\n\n", argv[0]);
16384 printf(" -a add hostname to the hostlist of hosts allowed to connect to mhttpd\n");
16385 printf(" -e experiment to connect to\n");
16386 printf(" -h connect to midas server (mserver) on given host\n");
16387 printf(" -v display verbose HTTP communication\n");
16388 printf(" -D become a daemon\n");
16389 printf(" -E only display ELog system\n");
16390 printf(" -H only display history plots\n");
16391#ifdef HAVE_MONGOOSE6
16392 printf(" --http port - bind to specified HTTP port (default is ODB \"/Experiment/midas http port\")\n");
16393 printf(" --https port - bind to specified HTTP port (default is ODB \"/Experiment/midas https port\")\n");
16394#endif
16395 printf(" --verbose-mg - trace mongoose web requests\n");
16396 printf(" --trace-mg - trace mongoose events\n");
16397 printf(" --no-trace-mg-recv - do not trace mongoose recv events\n");
16398 printf(" --no-trace-mg-send - dop not trace mongoose send events\n");
16399#ifdef HAVE_MONGOOSE616
16400 printf(" --no-multithread - disable mongoose multithreading\n");
16401 printf(" --no-passwords - disable password protection\n");
16402 printf(" --no-hostlist - disable access control host list\n");
16403#endif
16404 return 0;
16405 }
16406 }
16407 }
16408
16409 if (daemon) {
16410 printf("Becoming a daemon...\n");
16412 }
16413
16414#ifdef OS_LINUX
16415 /* write PID file */
16416 FILE *f = fopen("/var/run/mhttpd.pid", "w");
16417 if (f != NULL) {
16418 fprintf(f, "%d", ss_getpid());
16419 fclose(f);
16420 }
16421#endif
16422
16423 if (history_mode)
16424 myname = "mhttpd_history";
16425
16426 /*---- connect to experiment ----*/
16427 status = cm_connect_experiment1(midas_hostname, midas_expt, myname, NULL,
16430 return 1;
16431 else if (status == DB_INVALID_HANDLE) {
16432 std::string s = cm_get_error(status);
16433 puts(s.c_str());
16434 } else if (status != CM_SUCCESS) {
16435 std::string s = cm_get_error(status);
16436 puts(s.c_str());
16437 return 1;
16438 }
16439
16440 /* mhttpd needs the watchdog thread until we are sure
16441 * we do not have any long sleeps anywhere in the mhttpd code.
16442 * this includes reads from the history files or databases,
16443 * that can take arbitrary long time */
16445
16446 /* Get ODB handles */
16447
16448 HNDLE hDB;
16449
16451
16452 MVOdb *odb = MakeMidasOdb(hDB);
16453 gOdb = odb;
16454
16455 /* do ODB record checking */
16456 if (!check_odb_records(odb)) {
16457 // check_odb_records() fails with nothing printed to the terminal
16458 // because mhttpd does not print cm_msg(MERROR, ...) messages to the terminal.
16459 // At least print something!
16460 printf("check_odb_records() failed, see messages and midas.log, bye!\n");
16462 return 1;
16463 }
16464
16465#ifdef HAVE_MONGOOSE6
16466 if (init_allowed_hosts() != SUCCESS) {
16467 printf("init_allowed_hosts() failed, see messages and midas.log, bye!\n");
16469 return 1;
16470 }
16471
16472 if (verbose) {
16473 if (gAllowedHosts.size() > 0) {
16474 printf("mhttpd allowed hosts list: ");
16475 for (unsigned int i=0; i<gAllowedHosts.size(); i++) {
16476 if (i>0)
16477 printf(", ");
16478 printf("%s", gAllowedHosts[i].c_str());
16479 }
16480 printf("\n");
16481 } else {
16482 printf("mhttpd allowed hosts list is empty\n");
16483 }
16484 }
16485
16486 // populate the MIME.types table
16487 SaveMimetypes(odb->Chdir("WebServer/mime.types", true));
16488#endif
16489
16490 /* initialize odb entries needed for mhttpd and midas web pages */
16491 init_mhttpd_odb(odb);
16492
16493 /* initialize menu buttons */
16494 init_menu_buttons(odb);
16495
16496 /* initialize elog odb entries */
16497 init_elog_odb();
16498
16499 /* initialize the JSON RPC handlers */
16500 mjsonrpc_init();
16502
16504
16505#ifdef HAVE_MONGOOSE6
16506 status = start_mg(user_http_port, user_https_port, socket_priviledged_port, verbose);
16507 if (status != SUCCESS) {
16508 // At least print something!
16509 printf("could not start the mongoose web server, see messages and midas.log, bye!\n");
16511 return 1;
16512 }
16513#endif
16514
16515#ifdef HAVE_MONGOOSE616
16516
16517#ifdef SIGPIPE
16518#ifdef SIG_IGN
16519 signal(SIGPIPE, SIG_IGN);
16520#endif
16521#endif
16522
16523 if (!gTraceBuf) {
16525 }
16526
16527 //if (!request_mutex) {
16528 // status = ss_mutex_create(&request_mutex, FALSE);
16529 // assert(status==SS_SUCCESS || status==SS_CREATED);
16530 //}
16531
16532 /* establish Ctrl-C handler - will set _abort to TRUE */
16534
16535 MVOdb* o = odb->Chdir("WebServer", true);
16536 status = mongoose_init(o, no_passwords, no_hostlist, user_hostlist);
16537 if (status != SUCCESS) {
16538 // At least print something!
16539 printf("Error: Could not start the mongoose web server, see messages and midas.log, bye!\n");
16541 return 1;
16542 }
16543
16544 delete o;
16545#endif
16546
16547#ifdef HAVE_MONGOOSE6
16548 loop_mg();
16549 stop_mg();
16550#endif
16551
16552#ifdef HAVE_MONGOOSE616
16553 while (!_abort) {
16554
16555 /* cm_yield() is not thread safe, need to take a lock */
16556
16557 //status = ss_mutex_wait_for(request_mutex, 0);
16558 gMutex.lock();
16559
16560 /* check for shutdown message */
16561 status = cm_yield(0);
16562 if (status == RPC_SHUTDOWN)
16563 break;
16564
16565 gMutex.unlock();
16566 //status = ss_mutex_release(request_mutex);
16567
16568 //ss_sleep(10);
16569
16570 mongoose_poll(10);
16571 }
16572
16573 mongoose_cleanup();
16574#endif
16575
16576 if (gMh) {
16577 delete gMh;
16578 gMh = NULL;
16579 gMhkey = 0;
16580 }
16581
16582 mjsonrpc_exit();
16584 return 0;
16585}
static void usage()
INT cm_yield(INT millisec)
Definition midas.cxx:5660
INT cm_start_watchdog_thread()
Definition midas.cxx:7366
INT cm_connect_experiment1(const char *host_name, const char *default_exp_name, const char *client_name, void(*func)(char *), INT odb_size, DWORD watchdog_timeout)
Definition midas.cxx:2313
INT cm_disconnect_experiment(void)
Definition midas.cxx:2862
INT cm_get_environment(char *host_name, int host_name_size, char *exp_name, int exp_name_size)
Definition midas.cxx:2150
#define CM_WRONG_PASSWORD
Definition midas.h:589
#define DB_INVALID_HANDLE
Definition midas.h:636
#define RPC_SHUTDOWN
Definition midas.h:708
void mjsonrpc_init()
void mjsonrpc_exit()
void mjsonrpc_set_std_mutex(void *mutex)
INT ss_getpid(void)
Definition system.cxx:1379
INT ss_daemon_init(BOOL keep_stdout)
Definition system.cxx:2073
void * ss_ctrlc_handler(void(*func)(int))
Definition system.cxx:3971
std::string cm_get_error(INT code)
Definition midas.cxx:469
BOOL daemon
Definition mana.cxx:258
static bool trace_mg_send
Definition mhttpd.cxx:13739
static void add_rpc_functions()
Definition mhttpd.cxx:16248
INT check_odb_records(MVOdb *odb)
Definition mhttpd.cxx:13421
void init_elog_odb()
Definition mhttpd.cxx:2008
static void SaveMimetypes(MVOdb *odb)
Definition mhttpd.cxx:203
void ctrlc_handler(int sig)
Definition mhttpd.cxx:13485
static std::vector< std::string > gAllowedHosts
Definition mhttpd.cxx:13495
void init_mhttpd_odb(MVOdb *odb)
Definition mhttpd.cxx:1960
void init_menu_buttons(MVOdb *odb)
Definition mhttpd.cxx:1919
static bool trace_mg_recv
Definition mhttpd.cxx:13738
#define DEFAULT_WATCHDOG_TIMEOUT
Definition midas.h:290
#define DEFAULT_ODB_SIZE
Definition midas.h:270
Here is the call graph for this function:

◆ mgstr()

static std::string mgstr ( const mg_str s)
static

Definition at line 14169 of file mhttpd.cxx.

14170{
14171 return std::string(s->p, s->len);
14172}
Here is the caller graph for this function:

◆ mhttpd_revision()

const char * mhttpd_revision ( void  )

Definition at line 866 of file mhttpd.cxx.

867{
868 return cm_get_revision();
869}
const char * cm_get_revision()
Definition midas.cxx:1500
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mktime_with_dst()

time_t mktime_with_dst ( const struct tm ptms)

Definition at line 9778 of file mhttpd.cxx.

9779{
9780 // this silly stuff is required to correctly handle daylight savings time (Summer time/Winter time)
9781 // when we fill "struct tm" from user input, we cannot know if daylight savings time is in effect
9782 // and we do not know how to initialize the value of tms.tm_isdst.
9783 // This can cause the output of mktime() to be off by one hour.
9784 // (Rules for daylight savings time are set by national and local govt and in some locations, changes yearly)
9785 // (There are no locations with 2 hour or half-hour daylight savings that I know of)
9786 // (Yes, "man mktime" talks about using "tms.tm_isdst = -1")
9787 //
9788 // We assume the user is using local time and we convert in two steps:
9789 //
9790 // first we convert "struct tm" to "time_t" using mktime() with unknown tm_isdst
9791 // second we convert "time_t" back to "struct tm" using localtime_r()
9792 // this fills "tm_isdst" with correct value from the system time zone database
9793 // then we reset all the time fields (except for sub-minute fields not affected by daylight savings)
9794 // and call mktime() again, now with the correct value of "tm_isdst".
9795 // K.O. 2013-09-14
9796
9797 struct tm tms = *ptms;
9798 struct tm tms2;
9799 time_t t1 = ss_mktime(&tms);
9800 localtime_r(&t1, &tms2);
9801 tms2.tm_year = ptms->tm_year;
9802 tms2.tm_mon = ptms->tm_mon;
9803 tms2.tm_mday = ptms->tm_mday;
9804 tms2.tm_hour = ptms->tm_hour;
9805 tms2.tm_min = ptms->tm_min;
9806 time_t t2 = ss_mktime(&tms2);
9807 //printf("t1 %.0f, t2 %.0f, diff %d\n", (double)t1, (double)t2, (int)(t1-t2));
9808 return t2;
9809}
time_t ss_mktime(struct tm *tms)
Definition system.cxx:3437
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mongoose_passwords_enabled()

static bool mongoose_passwords_enabled ( const struct mg_connection nc)
static
Here is the caller graph for this function:

◆ NextHistPlotColour()

static std::string NextHistPlotColour ( const HistPlot hp)
static

Definition at line 10149 of file mhttpd.cxx.

10150{
10151 const char* const colour[] =
10152 {
10153 "#00AAFF", "#FF9000", "#FF00A0", "#00C030",
10154 "#A0C0D0", "#D0A060", "#C04010", "#807060",
10155 "#F0C000", "#2090A0", "#D040D0", "#90B000",
10156 "#B0B040", "#B0B0FF", "#FFA0A0", "#A0FFA0",
10157 NULL };
10158
10159 for (int i=0; colour[i]; i++) {
10160 bool in_use = false;
10161
10162 for (size_t j=0; j<hp.vars.size(); j++)
10163 if (hp.vars[j].colour == colour[i]) {
10164 in_use = true;
10165 break;
10166 }
10167
10168 if (!in_use)
10169 return colour[i];
10170 }
10171
10172 return "#808080";
10173}
Here is the caller graph for this function:

◆ NextHistPlotOrder()

static int NextHistPlotOrder ( const HistPlot hp)
static

Definition at line 10175 of file mhttpd.cxx.

10176{
10177 int order = 0;
10178 for (size_t i=0; i<hp.vars.size(); i++)
10179 if (hp.vars[i].order > order)
10180 order = hp.vars[i].order;
10181 return order + 10;
10182}
Here is the caller graph for this function:

◆ open_resource_file()

bool open_resource_file ( const char *  filename,
std::string *  ppath,
FILE **  pfp 
)

Definition at line 1061 of file mhttpd.cxx.

1062{
1063 // resource file names should not start with a directory separator "/"
1064 // or contain ".." as this will allow them to escape the mhttpd filename "jail"
1065 // by asking file files names like "../../etc/passwd", etc.
1066
1067 if (strlen(filename) < 1) {
1068 cm_msg(MERROR, "open_resource_file", "Invalid resource file name \'%s\' is too short",
1069 filename);
1070 return false;
1071 }
1072
1073 if (filename[0] == DIR_SEPARATOR) {
1074 cm_msg(MERROR, "open_resource_file", "Invalid resource file name \'%s\' starting with \'%c\' which is not allowed",
1075 filename, DIR_SEPARATOR);
1076 return false;
1077 }
1078
1079 if (strstr(filename, "..") != NULL) {
1080 cm_msg(MERROR, "open_resource_file", "Invalid resource file name \'%s\' containing \'..\' which is not allowed",
1081 filename);
1082 return false;
1083 }
1084
1085 std::vector<std::string> paths = get_resource_paths();
1086
1087 std::vector<std::string> paths_not_found;
1088
1089 for (unsigned i=0; i<paths.size(); i++) {
1090 std::string path = paths[i];
1091 if (path.length() < 1)
1092 continue;
1093 if (path[0] == '#')
1094 continue;
1095
1096 // expand env.variables before we add the filename.
1097 // the filename comes from the URL and if the URL
1098 // has '$' characters we will try to expand them
1099 // as an env.variable and maybe escape the file jail.
1100
1101 std::string xpath = cm_expand_env(path.c_str());
1102
1103 if (xpath[xpath.length()-1] != DIR_SEPARATOR)
1104 xpath += DIR_SEPARATOR_STR;
1105 xpath += filename;
1106
1107 //printf("path [%s] [%s] [%s]\n", paths[i].c_str(), path.c_str(), xpath.c_str());
1108
1109 FILE* fp = fopen(xpath.c_str(), "r");
1110 if (fp) {
1111 struct stat statbuf;
1112 int status = fstat(fileno(fp), &statbuf);
1113 if (status != 0) {
1114 cm_msg(MERROR, "open_resource_file", "Cannot fstat() file \'%s\', error %d (%s)", xpath.c_str(), errno, strerror(errno));
1115 fclose(fp);
1116 fp = NULL;
1117 }
1118
1119 if (statbuf.st_mode & S_IFREG) {
1120 // good, normal file
1121 //printf("%s: regular!\n", xpath.c_str());
1122 //} else if (statbuf.st_mode & S_IFLNK) {
1123 // symlink
1124 //printf("%s: symlink!\n", xpath.c_str());
1125 } else if (statbuf.st_mode & S_IFDIR) {
1126 cm_msg(MERROR, "open_resource_file", "File \'%s\' for resource \'%s\' is a directory", xpath.c_str(), filename);
1127 fclose(fp);
1128 fp = NULL;
1129 } else {
1130 cm_msg(MERROR, "open_resource_file", "File \'%s\' for resource \'%s\' is not a regular file, st_mode is 0x%08x", xpath.c_str(), filename, statbuf.st_mode);
1131 fclose(fp);
1132 fp = NULL;
1133 }
1134
1135 if (fp) {
1136 if (ppath)
1137 *ppath = xpath;
1138 if (pfp) {
1139 *pfp = fp;
1140 } else {
1141 fclose(fp);
1142 fp = NULL;
1143 }
1144 //cm_msg(MINFO, "open_resource_file", "Resource file \'%s\' is \'%s\'", filename, xpath.c_str());
1145 return true;
1146 }
1147 }
1148
1149 paths_not_found.push_back(xpath);
1150 }
1151
1152 std::string s;
1153 for (unsigned i=0; i<paths_not_found.size(); i++) {
1154 if (i>0)
1155 s += ", ";
1156 s += paths_not_found[i];
1157 }
1158
1159 cm_msg(MERROR, "open_resource_file", "Cannot find resource file \'%s\', tried %s", filename, s.c_str());
1160 return false;
1161}
std::string cm_expand_env(const char *str)
Definition midas.cxx:7721
std::vector< std::string > get_resource_paths()
Definition mhttpd.cxx:1021
static FILE * fp
Here is the call graph for this function:
Here is the caller graph for this function:

◆ output_key()

void output_key ( Param p,
Return r,
HNDLE  hkey,
int  index,
const char *  format 
)

Definition at line 4406 of file mhttpd.cxx.

4407{
4408 int size, i;
4409 HNDLE hDB, hsubkey;
4410 KEY key;
4411 char data[TEXT_SIZE];
4412
4414
4415 db_get_key(hDB, hkey, &key);
4416 if (key.type == TID_KEY) {
4417 for (i=0 ; ; i++) {
4418 db_enum_key(hDB, hkey, i, &hsubkey);
4419 if (!hsubkey)
4420 break;
4421 output_key(p, r, hsubkey, -1, format);
4422 }
4423 } else {
4424 if (key.item_size <= (int)sizeof(data)) {
4425 size = sizeof(data);
4426 db_get_data(hDB, hkey, data, &size, key.type);
4427 if (index == -1) {
4428 for (i=0 ; i<key.num_values ; i++) {
4429 if (p->isparam("name") && atoi(p->getparam("name")) == 1) {
4430 if (key.num_values == 1)
4431 r->rsprintf("%s:", key.name);
4432 else
4433 r->rsprintf("%s[%d]:", key.name, i);
4434 }
4435 std::string data_str;
4436 if (format && format[0])
4437 data_str = db_sprintff(format, data, key.item_size, i, key.type);
4438 else
4439 data_str = db_sprintf(data, key.item_size, i, key.type);
4440 r->rsputs(data_str.c_str());
4441 if (i<key.num_values-1)
4442 r->rsputs("\n");
4443 }
4444 } else {
4445 if (p->isparam("name") && atoi(p->getparam("name")) == 1)
4446 r->rsprintf("%s[%d]:", key.name, index);
4447 if (index >= key.num_values)
4448 r->rsputs("<DB_OUT_OF_RANGE>");
4449 else {
4450 std::string data_str;
4451 if (p->isparam("format"))
4452 data_str = db_sprintff(p->getparam("format"), data, key.item_size, index, key.type);
4453 else
4454 data_str = db_sprintf(data, key.item_size, index, key.type);
4455 r->rsputs(data_str.c_str());
4456 }
4457 }
4458 r->rsputs("\n");
4459 }
4460 }
4461}
INT db_sprintff(char *string, const char *format, const void *data, INT data_size, INT idx, DWORD type)
Definition odb.cxx:10941
Here is the call graph for this function:
Here is the caller graph for this function:

◆ PrintHistPlot()

static void PrintHistPlot ( const HistPlot hp)
static

Definition at line 10139 of file mhttpd.cxx.

10140{
10141 printf("hist plot: %d variables\n", (int)hp.vars.size());
10142 printf("timescale: %s, minimum: %f, maximum: %f, zero_ylow: %d, log_axis: %d, show_run_markers: %d, show_values: %d, show_fill: %d, show_factor %d, enable_factor: %d\n", hp.timescale.c_str(), hp.minimum, hp.maximum, hp.zero_ylow, hp.log_axis, hp.show_run_markers, hp.show_values, hp.show_fill, hp.show_factor, hp.enable_factor);
10143
10144 for (size_t i=0; i<hp.vars.size(); i++) {
10145 printf("var[%d] event [%s][%s] formula [%s], colour [%s] label [%s] show_raw_value %d factor %f offset %f voffset %f order %d\n", (int)i, hp.vars[i].event_name.c_str(), hp.vars[i].tag_name.c_str(), hp.vars[i].formula.c_str(), hp.vars[i].colour.c_str(), hp.vars[i].label.c_str(), hp.vars[i].show_raw_value, hp.vars[i].factor, hp.vars[i].offset , hp.vars[i].voffset, hp.vars[i].order);
10146 }
10147}

◆ read_history()

int read_history ( const HistPlot hp,
int  index,
int  flags,
time_t  tstart,
time_t  tend,
time_t  scale,
HistoryData data 
)

Definition at line 8389 of file mhttpd.cxx.

8390{
8391 //HNDLE hkeypanel, hkeydvar, hkey;
8392 //KEY key;
8393 //char path[256];
8394 //int n_vars;
8395 int status;
8396 int debug = 1;
8397
8398 //mstrlcpy(path, group, sizeof(path));
8399 //mstrlcat(path, "/", sizeof(path));
8400 //mstrlcat(path, panel, sizeof(path));
8401
8402 //printf("read_history, path %s, index %d, flags 0x%x, start %d, end %d, scale %d, data %p\n", path, index, flags, (int)tstart, (int)tend, (int)scale, data);
8403
8404 /* connect to history */
8406 if (mh == NULL) {
8407 //r->rsprintf(str, "History is not configured\n");
8408 return HS_FILE_ERROR;
8409 }
8410
8411#if 0
8412 /* check panel name in ODB */
8413 status = db_find_key(hDB, 0, "/History/Display", &hkey);
8414 if (!hkey) {
8415 cm_msg(MERROR, "read_history", "Cannot find \'/History/Display\' in ODB, status %d", status);
8416 return HS_FILE_ERROR;
8417 }
8418
8419 /* check panel name in ODB */
8420 status = db_find_key(hDB, hkey, path, &hkeypanel);
8421 if (!hkeypanel) {
8422 cm_msg(MERROR, "read_history", "Cannot find \'%s\' in ODB, status %d", path, status);
8423 return HS_FILE_ERROR;
8424 }
8425
8426 status = db_find_key(hDB, hkeypanel, "Variables", &hkeydvar);
8427 if (!hkeydvar) {
8428 cm_msg(MERROR, "read_history", "Cannot find \'%s/Variables\' in ODB, status %d", path, status);
8429 return HS_FILE_ERROR;
8430 }
8431
8432 db_get_key(hDB, hkeydvar, &key);
8433 n_vars = key.num_values;
8434#endif
8435
8436 data->Allocate(hp.vars.size()+2);
8437
8438 data->tstart = tstart;
8439 data->tend = tend;
8440 data->scale = scale;
8441
8442 for (size_t i=0; i<hp.vars.size(); i++) {
8443 if (index != -1 && (size_t)index != i)
8444 continue;
8445
8446 //char str[256];
8447 //int size = sizeof(str);
8448 //status = db_get_data_index(hDB, hkeydvar, str, &size, i, TID_STRING);
8449 //if (status != DB_SUCCESS) {
8450 // cm_msg(MERROR, "read_history", "Cannot read tag %d in panel %s, status %d", i, path, status);
8451 // continue;
8452 //}
8453
8454 /* split varname in event, variable and index: "event/tag[index]" */
8455
8456 //char *p = strchr(str, ':');
8457 //if (!p)
8458 // p = strchr(str, '/');
8459 //
8460 //if (!p) {
8461 // cm_msg(MERROR, "read_history", "Tag \"%s\" has wrong format in panel \"%s\"", str, path);
8462 // continue;
8463 //}
8464
8465 //*p = 0;
8466
8467 data->odb_index[data->nvars] = i;
8468 data->event_names[data->nvars] = STRDUP(hp.vars[i].event_name.c_str());
8469 data->var_names[data->nvars] = STRDUP(hp.vars[i].tag_name.c_str());
8470 data->var_index[data->nvars] = 0;
8471
8472 char *q = strchr(data->var_names[data->nvars], '[');
8473 if (q) {
8474 data->var_index[data->nvars] = atoi(q+1);
8475 *q = 0;
8476 }
8477
8478 data->nvars++;
8479 } // loop over variables
8480
8481 /* write run markes if selected */
8482 if (flags & READ_HISTORY_RUNMARKER) {
8483
8484 data->event_names[data->nvars+0] = STRDUP("Run transitions");
8485 data->event_names[data->nvars+1] = STRDUP("Run transitions");
8486
8487 data->var_names[data->nvars+0] = STRDUP("State");
8488 data->var_names[data->nvars+1] = STRDUP("Run number");
8489
8490 data->var_index[data->nvars+0] = 0;
8491 data->var_index[data->nvars+1] = 0;
8492
8493 data->odb_index[data->nvars+0] = -1;
8494 data->odb_index[data->nvars+1] = -2;
8495
8496 data->nvars += 2;
8497 }
8498
8499 bool get_last_written = false;
8500
8501 if (flags & READ_HISTORY_DATA) {
8502 status = mh->hs_read(tstart, tend, scale,
8503 data->nvars,
8504 data->event_names,
8505 data->var_names,
8506 data->var_index,
8507 data->num_entries,
8508 data->t,
8509 data->v,
8510 data->status);
8511
8512 if (debug) {
8513 printf("read_history: nvars %d, hs_read() status %d\n", data->nvars, status);
8514 for (int i=0; i<data->nvars; i++) {
8515 printf("read_history: %d: event [%s], var [%s], index %d, odb index %d, status %d, num_entries %d\n", i, data->event_names[i], data->var_names[i], data->var_index[i], data->odb_index[i], data->status[i], data->num_entries[i]);
8516 }
8517 }
8518
8519 if (status != HS_SUCCESS) {
8520 cm_msg(MERROR, "read_history", "Complete history failure, hs_read() status %d, see messages", status);
8521 return HS_FILE_ERROR;
8522 }
8523
8524 for (int i=0; i<data->nvars; i++) {
8525 if (data->status[i] != HS_SUCCESS || data->num_entries[i] < 1) {
8526 get_last_written = true;
8527 break;
8528 }
8529 }
8530 }
8531
8532 if (flags & READ_HISTORY_LAST_WRITTEN)
8533 get_last_written = true;
8534
8535 if (get_last_written) {
8536 data->have_last_written = true;
8537
8539 tstart,
8540 data->nvars,
8541 data->event_names,
8542 data->var_names,
8543 data->var_index,
8544 data->last_written);
8545
8546 if (status != HS_SUCCESS) {
8547 data->have_last_written = false;
8548 }
8549 }
8550
8551 return SUCCESS;
8552}
virtual int hs_get_last_written(time_t start_time, int num_var, const char *const event_name[], const char *const tag_name[], const int var_index[], time_t last_written[])=0
static std::string q(const char *s)
#define STRDUP(x)
Definition mhttpd.cxx:8270
Here is the call graph for this function:
Here is the caller graph for this function:

◆ read_passwords()

static bool read_passwords ( Auth auth)
static

Definition at line 13829 of file mhttpd.cxx.

13830{
13831 std::string path;
13832 FILE *fp;
13833 int status = find_file_mg("htpasswd.txt", path, &fp, trace_mg||verbose_mg);
13834
13835 auth->passwd_filename = path;
13836 auth->passwords.clear();
13837
13838 if (status != SUCCESS || fp == NULL) {
13839 cm_msg(MERROR, "mongoose", "mongoose web server cannot find password file \"%s\"", path.c_str());
13840 cm_msg(MERROR, "mongoose", "please create password file: touch %s", path.c_str());
13841 return false;
13842 }
13843
13844 bool have_realm = false;
13845 char buf[256];
13846
13847 /*
13848 * Read passwords file line by line. If should have htdigest format,
13849 * i.e. each line should be a colon-separated sequence:
13850 * USER_NAME:DOMAIN_NAME:HA1_HASH_OF_USER_DOMAIN_AND_PASSWORD
13851 */
13852 while (fgets(buf, sizeof(buf), fp) != NULL) {
13853 char f_user[256];
13854 char f_domain[256];
13855 char f_ha1[256];
13856
13857 if (sscanf(buf, "%[^:]:%[^:]:%s", f_user, f_domain, f_ha1) == 3) {
13858 AuthEntry e;
13859 e.realm = f_domain;
13860 e.username = f_user;
13861 e.password = f_ha1;
13862
13863 if (e.realm == auth->realm) {
13864 have_realm = true;
13865 auth->passwords.push_back(e);
13866 }
13867 }
13868 }
13869
13870 fclose(fp);
13871
13872 return have_realm;
13873}
std::string passwd_filename
Definition mhttpd.cxx:13758
int find_file_mg(const char *filename, std::string &path, FILE **fpp, bool trace)
Definition mhttpd.cxx:13704
std::string realm
Definition mhttpd.cxx:13751
Here is the call graph for this function:
Here is the caller graph for this function:

◆ redirect()

void redirect ( Return r,
const char *  path 
)

Definition at line 1441 of file mhttpd.cxx.

1442{
1443 char str[256];
1444
1445 //printf("redirect to [%s]\n", path);
1446
1447 mstrlcpy(str, path, sizeof(str));
1448 if (str[0] == 0)
1449 strcpy(str, "./");
1450
1451 /* redirect */
1452 r->rsprintf("HTTP/1.1 302 Found\r\n");
1453 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
1454 r->rsprintf("Content-Type: text/html; charset=%s\r\n", HTTP_ENCODING);
1455
1456 if (strncmp(path, "http:", 5) == 0)
1457 r->rsprintf("Location: %s\r\n\r\n<html>redir</html>\r\n", str);
1458 else if (strncmp(path, "https:", 6) == 0)
1459 r->rsprintf("Location: %s\r\n\r\n<html>redir</html>\r\n", str);
1460 else {
1461 r->rsprintf("Location: %s\r\n\r\n<html>redir</html>\r\n", str);
1462 }
1463}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ redirect2()

void redirect2 ( Return r,
const char *  path 
)

Definition at line 1478 of file mhttpd.cxx.

1479{
1480 redirect(r, path);
1481}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ redirect_307()

void redirect_307 ( Return r,
const char *  path 
)

Definition at line 1465 of file mhttpd.cxx.

1466{
1467 //printf("redirect_307 to [%s]\n", path);
1468
1469 /* redirect */
1470 r->rsprintf("HTTP/1.1 307 Temporary Redirect\r\n");
1471 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
1472 r->rsprintf("Content-Type: text/html; charset=%s\r\n", HTTP_ENCODING);
1473 r->rsprintf("Location: %s\r\n", path);
1474 r->rsprintf("\r\n");
1475 r->rsprintf("<html>redirect to %s</html>\r\n", path);
1476}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ SaveHistPlotToOdb()

static void SaveHistPlotToOdb ( MVOdb *  odb,
const HistPlot hp,
const char *  group,
const char *  panel 
)
static

Definition at line 10438 of file mhttpd.cxx.

10439{
10440 if (strlen(group) < 1) {
10441 cm_msg(MERROR, "SaveHistPlotToOdb", "Error: Cannot write history plot to ODB, group \"%s\", panel \"%s\", invalid group name", group, panel);
10442 return;
10443 }
10444
10445 if (strlen(panel) < 1) {
10446 cm_msg(MERROR, "SaveHistPlotToOdb", "Error: Cannot write history plot to ODB, group \"%s\", panel \"%s\", invalid panel name", group, panel);
10447 return;
10448 }
10449
10450 std::string path = "History/Display/";
10451 path += group;
10452 path += "/";
10453 path += panel;
10454
10455// printf("Save to ODB %s: ", path.c_str());
10456// PrintHistPlot(hp);
10457
10458 MVOdb* o = odb->Chdir(path.c_str(), true);
10459
10460 o->WS("Timescale", hp.timescale.c_str());
10461 o->WD("Minimum", hp.minimum);
10462 o->WD("Maximum", hp.maximum);
10463 o->WB("Zero ylow", hp.zero_ylow);
10464 o->WB("Log axis", hp.log_axis);
10465 o->WB("Show run markers", hp.show_run_markers);
10466 o->WB("Show values", hp.show_values);
10467 o->WB("Show fill", hp.show_fill);
10468 o->WB("Show factor and offset", hp.show_factor);
10469 //o->WB("Enable factor and offset", hp.enable_factor);
10470
10471 std::vector<std::string> hist_vars;
10472 std::vector<std::string> hist_formula;
10473 std::vector<std::string> hist_colour;
10474 std::vector<std::string> hist_label;
10475 std::vector<bool> hist_show_raw_value;
10476 std::vector<double> hist_factor;
10477 std::vector<double> hist_offset;
10478 std::vector<double> hist_voffset;
10479
10480 for (size_t i=0; i<hp.vars.size(); i++) {
10481 hist_vars.push_back(hp.vars[i].event_name + ":" + hp.vars[i].tag_name);
10482 hist_formula.push_back(hp.vars[i].formula);
10483 hist_colour.push_back(hp.vars[i].colour);
10484 hist_label.push_back(hp.vars[i].label);
10485 hist_show_raw_value.push_back(hp.vars[i].show_raw_value);
10486 hist_factor.push_back(hp.vars[i].factor);
10487 hist_offset.push_back(hp.vars[i].offset);
10488 hist_voffset.push_back(hp.vars[i].voffset);
10489 }
10490
10491 if (hp.vars.size() > 0) {
10492 o->WSA("Variables", hist_vars, 64);
10493 o->WSA("Formula", hist_formula, 64);
10494 o->WSA("Colour", hist_colour, NAME_LENGTH);
10495 o->WSA("Label", hist_label, NAME_LENGTH);
10496 o->WBA("Show raw value", hist_show_raw_value);
10497 o->WDA("Factor", hist_factor);
10498 o->WDA("Offset", hist_offset);
10499 o->WDA("VOffset", hist_voffset);
10500 } else {
10501 o->Delete("Variables");
10502 o->Delete("Formula");
10503 o->Delete("Colour");
10504 o->Delete("Label");
10505 o->Delete("Show raw value");
10506 o->Delete("Factor");
10507 o->Delete("Offset");
10508 o->Delete("VOffset");
10509 }
10510
10511 delete o;
10512}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ SaveMimetypes()

static void SaveMimetypes ( MVOdb *  odb)
static

Definition at line 203 of file mhttpd.cxx.

204{
205 gMimeTypesOdb = odb;
206
207 for (int i=0; gMimetypeTable[i].ext.length() > 0; i++) {
208 std::string tmp = gMimetypeTable[i].mimetype;
209 gMimeTypesOdb->RS(gMimetypeTable[i].ext.c_str(), &tmp, true);
210 }
211}
Here is the caller graph for this function:

◆ search_callback()

INT search_callback ( HNDLE  hDB,
HNDLE  hKey,
KEY key,
INT  level,
void *  info 
)

Definition at line 1491 of file mhttpd.cxx.

1492{
1493 search_data* sinfo = (search_data*)info;
1494 int i;
1495 INT size, status;
1496
1497 Return* r = sinfo->r;
1498 const char* search_name = sinfo->search_name;
1499
1500 /* convert strings to uppercase */
1501
1502 char xstr1[MAX_ODB_PATH];
1503 for (i = 0; key->name[i]; i++)
1504 xstr1[i] = toupper(key->name[i]);
1505 xstr1[i] = 0;
1506
1507 char str2[MAX_ODB_PATH];
1508 for (i = 0; search_name[i] ; i++)
1509 str2[i] = toupper(search_name[i]);
1510 str2[i] = 0;
1511
1512 if (strstr(xstr1, str2) != NULL) {
1513 char data[10000];
1514 std::string path = db_get_path(hDB, hKey).substr(1);
1515 std::string path_encoded = urlEncode(path.c_str());
1516
1517 if (key->type == TID_KEY || key->type == TID_LINK) {
1518 /* for keys, don't display data value */
1519 r->rsprintf("<tr><td class=\"ODBkey\"><a href=\"?cmd=odb&odb_path=/%s\">/%s</a></tr>\n", path_encoded.c_str(), path.c_str());
1520 } else {
1521 /* strip variable name from path */
1522 char* p = const_cast<char *>(path.data() + path.length() - 1);
1523 while (*p && *p != '/')
1524 *p-- = 0;
1525 if (*p == '/')
1526 *p = 0;
1527
1528 /* display single value */
1529 if (key->num_values == 1) {
1530 size = sizeof(data);
1531 status = db_get_data(hDB, hKey, data, &size, key->type);
1532 std::string data_str;
1533 if (status == DB_NO_ACCESS)
1534 data_str = "<no read access>";
1535 else
1536 data_str = db_sprintf(data, key->item_size, 0, key->type);
1537
1538 r->rsprintf("<tr><td class=\"ODBkey\">");
1539 r->rsprintf("<a href=\"?cmd=odb&odb_path=/%s\">/%s/%s</a></td>", path_encoded.c_str(), path.c_str(), key->name);
1540 r->rsprintf("<td class=\"ODBvalue\">%s</td></tr>\n", data_str.c_str());
1541 } else {
1542 /* display first value */
1543 i = key->num_values;
1544 if (i > 10)
1545 i = 11;
1546 r->rsprintf("<tr><td rowspan=%d class=\"ODBkey\">", i);
1547 r->rsprintf("<a href=\"?cmd=odb&odb_path=/%s\">/%s/%s\n", path_encoded.c_str(), path.c_str(), key->name);
1548
1549 for (int i = 0; i < key->num_values; i++) {
1550 size = sizeof(data);
1551 db_get_data_index(hDB, hKey, data, &size, i, key->type);
1552
1553 std::string data_str = db_sprintf(data, key->item_size, 0, key->type);
1554
1555 if (i > 0)
1556 r->rsprintf("<tr>");
1557
1558 r->rsprintf("<td class=\"ODBvalue\">[%d] %s</td></tr>\n", i, data_str.c_str());
1559
1560 if (i > 8) {
1561 r->rsprintf("<tr><td class=\"ODBvalue\">... [%d] values ...</td></tr>\n", key->num_values - i - 1);
1562 break;
1563 }
1564 }
1565 }
1566 }
1567 }
1568
1569 return SUCCESS;
1570}
#define DB_NO_ACCESS
Definition midas.h:649
void ** info
Definition fesimdaq.cxx:41
#define MAX_ODB_PATH
Definition midas.h:277
Return * r
Definition mhttpd.cxx:1487
const char * search_name
Definition mhttpd.cxx:1488
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sec_to_label()

void sec_to_label ( char *  result,
int  sec,
int  base,
int  force_date 
)

Definition at line 7783 of file mhttpd.cxx.

7784{
7785 char mon[80];
7786 time_t t_sec;
7787
7788 t_sec = (time_t) sec;
7789
7790 struct tm tms;
7791 localtime_r(&t_sec, &tms);
7792 strcpy(mon, mname[tms.tm_mon]);
7793 mon[3] = 0;
7794
7795 if (force_date) {
7796 if (base < 600)
7797 sprintf(result, "%02d %s %02d %02d:%02d:%02d",
7798 tms.tm_mday, mon, tms.tm_year % 100, tms.tm_hour, tms.tm_min,
7799 tms.tm_sec);
7800 else if (base < 3600 * 24)
7801 sprintf(result, "%02d %s %02d %02d:%02d",
7802 tms.tm_mday, mon, tms.tm_year % 100, tms.tm_hour, tms.tm_min);
7803 else
7804 sprintf(result, "%02d %s %02d", tms.tm_mday, mon, tms.tm_year % 100);
7805 } else {
7806 if (base < 600)
7807 sprintf(result, "%02d:%02d:%02d", tms.tm_hour, tms.tm_min, tms.tm_sec);
7808 else if (base < 3600 * 3)
7809 sprintf(result, "%02d:%02d", tms.tm_hour, tms.tm_min);
7810 else if (base < 3600 * 24)
7811 sprintf(result, "%02d %s %02d %02d:%02d",
7812 tms.tm_mday, mon, tms.tm_year % 100, tms.tm_hour, tms.tm_min);
7813 else
7814 sprintf(result, "%02d %s %02d", tms.tm_mday, mon, tms.tm_year % 100);
7815 }
7816}
const char * mname[]
Definition midas.cxx:144
Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_file()

bool send_file ( Return r,
const std::string &  path,
bool  generate_404 = true 
)

Definition at line 1242 of file mhttpd.cxx.

1243{
1244 FILE *fp = fopen(path.c_str(), "rb");
1245
1246 if (!fp) {
1247 if (generate_404) {
1248 /* header */
1249 r->rsprintf("HTTP/1.1 404 Not Found\r\n");
1250 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
1251 r->rsprintf("Content-Type: text/plain; charset=%s\r\n", HTTP_ENCODING);
1252 r->rsprintf("\r\n");
1253 r->rsprintf("Error: Cannot read \"%s\", fopen() errno %d (%s)\n", path.c_str(), errno, strerror(errno));
1254 }
1255 return false;
1256 }
1257
1258 return send_fp(r, path, fp);
1259}
bool send_fp(Return *r, const std::string &path, FILE *fp)
Definition mhttpd.cxx:1196
Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_fp()

bool send_fp ( Return r,
const std::string &  path,
FILE *  fp 
)

Definition at line 1196 of file mhttpd.cxx.

1197{
1198 assert(fp != NULL);
1199
1200 // send HTTP headers
1201
1202 r->rsprintf("HTTP/1.1 200 Document follows\r\n");
1203 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
1204 r->rsprintf("Accept-Ranges: bytes\r\n");
1205
1206 // send HTTP cache control headers
1207
1208 time_t now = time(NULL);
1209 now += (int) (3600 * 24);
1210 struct tm gmt_tms;
1211 gmtime_r(&now, &gmt_tms);
1212 const char* format = "%A, %d-%b-%y %H:%M:%S GMT";
1213
1214 char str[256];
1215 strftime(str, sizeof(str), format, &gmt_tms);
1216 r->rsprintf("Expires: %s\r\n", str);
1217
1218 // send Content-Type header
1219
1220 r->rsprintf("Content-Type: %s\r\n", get_content_type(path.c_str()).c_str());
1221
1222 // send Content-Length header
1223
1224 struct stat stat_buf;
1225 fstat(fileno(fp), &stat_buf);
1226 int length = stat_buf.st_size;
1227 r->rsprintf("Content-Length: %d\r\n", length);
1228
1229 // send end of headers
1230
1231 r->rsprintf("\r\n");
1232
1233 // send file data
1234
1235 r->rread(path.c_str(), fileno(fp), length);
1236
1237 fclose(fp);
1238
1239 return true;
1240}
void rread(const char *filename, int fh, int len)
Definition mhttpd.cxx:618
std::string get_content_type(const char *filename)
Definition mhttpd.cxx:1165
Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_icon()

void send_icon ( Return r,
const char *  icon 
)

Definition at line 12217 of file mhttpd.cxx.

12218{
12219 int length;
12220 const unsigned char *picon;
12221 char str[256], format[256];
12222 time_t now;
12223
12224 if (strstr(icon, "favicon.ico") != 0) {
12225 length = sizeof(favicon_ico);
12226 picon = favicon_ico;
12227 } else if (strstr(icon, "favicon.png") != 0) {
12228 length = sizeof(favicon_png);
12229 picon = favicon_png;
12230 } else
12231 return;
12232
12233 r->rsprintf("HTTP/1.1 200 Document follows\r\n");
12234 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
12235 r->rsprintf("Accept-Ranges: bytes\r\n");
12236
12237 /* set expiration time to one day */
12238 time(&now);
12239 now += (int) (3600 * 24);
12240 struct tm gmt_tms;
12241 gmtime_r(&now, &gmt_tms);
12242 strcpy(format, "%A, %d-%b-%y %H:%M:%S GMT");
12243 strftime(str, sizeof(str), format, &gmt_tms);
12244 r->rsprintf("Expires: %s\r\n", str);
12245
12246 if (equal_ustring(icon, "favicon.ico"))
12247 r->rsprintf("Content-Type: image/x-icon\r\n");
12248 else
12249 r->rsprintf("Content-Type: image/png\r\n");
12250
12251 r->rsprintf("Content-Length: %d\r\n\r\n", length);
12252
12253 r->rmemcpy(picon, length);
12254}
const unsigned char favicon_png[]
Definition mhttpd.cxx:217
const unsigned char favicon_ico[]
Definition mhttpd.cxx:288
Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_resource()

bool send_resource ( Return r,
const std::string &  name,
bool  generate_404 = true 
)

Definition at line 1261 of file mhttpd.cxx.

1262{
1263 std::string path;
1264 FILE *fp = NULL;
1265
1266 bool found = open_resource_file(name.c_str(), &path, &fp);
1267
1268 if (!found) {
1269 if (generate_404) {
1270 /* header */
1271 r->rsprintf("HTTP/1.1 404 Not Found\r\n");
1272 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
1273 r->rsprintf("Content-Type: text/plain; charset=%s\r\n", HTTP_ENCODING);
1274 r->rsprintf("\r\n");
1275 r->rsprintf("Error: resource file \"%s\" not found, see messages\n", name.c_str());
1276 }
1277 return false;
1278 }
1279
1280 return send_fp(r, path, fp);
1281}
bool open_resource_file(const char *filename, std::string *ppath, FILE **pfp)
Definition mhttpd.cxx:1061
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sendmail()

INT sendmail ( const char *  from_host,
const char *  smtp_host,
const char *  from,
const char *  to,
const char *  subject,
const char *  text 
)

Definition at line 1285 of file mhttpd.cxx.

1286{
1287 struct sockaddr_in bind_addr;
1288 struct hostent *phe;
1289 int i, s, strsize, offset;
1290 char *str, buf[256];
1291
1292 if (verbose)
1293 printf("\n\nEmail from %s to %s, SMTP host %s:\n", from, to, smtp_host);
1294
1295 /* create a new socket for connecting to remote server */
1296 s = socket(AF_INET, SOCK_STREAM, 0);
1297 if (s == -1)
1298 return -1;
1299
1300 /* connect to remote node port 25 */
1301 memset(&bind_addr, 0, sizeof(bind_addr));
1302 bind_addr.sin_family = AF_INET;
1303 bind_addr.sin_port = htons((short) 25);
1304
1305 phe = gethostbyname(smtp_host);
1306 if (phe == NULL)
1307 return -1;
1308 memcpy((char *) &(bind_addr.sin_addr), phe->h_addr, phe->h_length);
1309
1310 if (connect(s, (const sockaddr*)&bind_addr, sizeof(bind_addr)) < 0) {
1311 closesocket(s);
1312 return -1;
1313 }
1314
1315 strsize = TEXT_SIZE + 1000;
1316 str = (char*)malloc(strsize);
1317
1318 assert(str != NULL);
1319
1320 recv_string(s, str, strsize, 3000);
1321 if (verbose)
1322 puts(str);
1323
1324 /* drain server messages */
1325 do {
1326 str[0] = 0;
1327 recv_string(s, str, strsize, 300);
1328 if (verbose)
1329 puts(str);
1330 } while (str[0]);
1331
1332 sprintf(str, "HELO %s\r\n", from_host);
1333 send(s, str, strlen(str), 0);
1334 if (verbose)
1335 puts(str);
1336 recv_string(s, str, strsize, 3000);
1337 if (verbose)
1338 puts(str);
1339
1340 if (strchr(from, '<')) {
1341 mstrlcpy(buf, strchr(from, '<') + 1, sizeof(buf));
1342 if (strchr(buf, '>'))
1343 *strchr(buf, '>') = 0;
1344 } else
1345 mstrlcpy(buf, from, sizeof(buf));
1346
1347 sprintf(str, "MAIL FROM: %s\n", buf);
1348 send(s, str, strlen(str), 0);
1349 if (verbose)
1350 puts(str);
1351 recv_string(s, str, strsize, 3000);
1352 if (verbose)
1353 puts(str);
1354
1355 sprintf(str, "RCPT TO: <%s>\r\n", to);
1356 send(s, str, strlen(str), 0);
1357 if (verbose)
1358 puts(str);
1359 recv_string(s, str, strsize, 3000);
1360 if (verbose)
1361 puts(str);
1362
1363 sprintf(str, "DATA\r\n");
1364 send(s, str, strlen(str), 0);
1365 if (verbose)
1366 puts(str);
1367 recv_string(s, str, strsize, 3000);
1368 if (verbose)
1369 puts(str);
1370
1371 sprintf(str, "To: %s\r\nFrom: %s\r\nSubject: %s\r\n", to, from, subject);
1372 send(s, str, strlen(str), 0);
1373 if (verbose)
1374 puts(str);
1375
1376 sprintf(str, "X-Mailer: mhttpd revision %s\r\n", mhttpd_revision());
1377 send(s, str, strlen(str), 0);
1378 if (verbose)
1379 puts(str);
1380
1381 ss_tzset(); // required for localtime_r()
1382 time_t now;
1383 time(&now);
1384 struct tm tms;
1385 localtime_r(&now, &tms);
1386 strftime(buf, sizeof(buf), "%a, %d %b %Y %H:%M:%S", &tms);
1387 offset = (-(int) timezone);
1388 if (tms.tm_isdst)
1389 offset += 3600;
1390 sprintf(str, "Date: %s %+03d%02d\r\n", buf, (int) (offset / 3600),
1391 (int) ((abs((int) offset) / 60) % 60));
1392 send(s, str, strlen(str), 0);
1393 if (verbose)
1394 puts(str);
1395
1396 sprintf(str, "Content-Type: TEXT/PLAIN; charset=US-ASCII\r\n\r\n");
1397 send(s, str, strlen(str), 0);
1398 if (verbose)
1399 puts(str);
1400
1401 /* analyze text for "." at beginning of line */
1402 const char* p = text;
1403 str[0] = 0;
1404 while (strstr(p, "\r\n.\r\n")) {
1405 i = (POINTER_T) strstr(p, "\r\n.\r\n") - (POINTER_T) p + 1;
1406 mstrlcat(str, p, i);
1407 p += i + 4;
1408 mstrlcat(str, "\r\n..\r\n", strsize);
1409 }
1410 mstrlcat(str, p, strsize);
1411 mstrlcat(str, "\r\n", strsize);
1412 send(s, str, strlen(str), 0);
1413 if (verbose)
1414 puts(str);
1415
1416 /* send ".<CR>" to signal end of message */
1417 sprintf(str, ".\r\n");
1418 send(s, str, strlen(str), 0);
1419 if (verbose)
1420 puts(str);
1421 recv_string(s, str, strsize, 3000);
1422 if (verbose)
1423 puts(str);
1424
1425 sprintf(str, "QUIT\n");
1426 send(s, str, strlen(str), 0);
1427 if (verbose)
1428 puts(str);
1429 recv_string(s, str, strsize, 3000);
1430 if (verbose)
1431 puts(str);
1432
1433 closesocket(s);
1434 free(str);
1435
1436 return 1;
1437}
INT recv_string(int sock, char *buffer, DWORD buffer_size, INT millisec)
Definition system.cxx:5471
#define closesocket(s)
Definition melog.cxx:29
static int offset
Definition mgd.cxx:1500
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_http_trace()

static MJsonNode * set_http_trace ( const MJsonNode *  params)
static

Definition at line 16234 of file mhttpd.cxx.

16235{
16236 if (!params) {
16237 MJSO* doc = MJSO::I();
16238 doc->D("set new value of mhttpd http_trace");
16239 doc->P(NULL, MJSON_INT, "new value of http_trace");
16240 doc->R(NULL, MJSON_INT, "new value of http_trace");
16241 return doc;
16242 }
16243
16244 http_trace = params->GetInt();
16245 return mjsonrpc_make_result("http_trace", MJsonNode::MakeInt(http_trace));
16246}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_cnaf_page()

static void show_cnaf_page ( Param p,
Return rr 
)
static

Definition at line 5687 of file mhttpd.cxx.

5688{
5689 char str[256];
5690 int c, n, a, f, d, q, x, r, ia, id, w;
5691 int i, size, status;
5692 HNDLE hDB, hrootkey, hsubkey, hkey;
5693
5694 static char client_name[NAME_LENGTH];
5695 static HNDLE hconn = 0;
5696
5698
5699 /* find FCNA server if not specified */
5700 if (hconn == 0) {
5701 /* find client which exports FCNA function */
5702 status = db_find_key(hDB, 0, "System/Clients", &hrootkey);
5703 if (status == DB_SUCCESS) {
5704 for (i = 0;; i++) {
5705 status = db_enum_key(hDB, hrootkey, i, &hsubkey);
5707 break;
5708
5709 sprintf(str, "RPC/%d", RPC_CNAF16);
5710 status = db_find_key(hDB, hsubkey, str, &hkey);
5711 if (status == DB_SUCCESS) {
5712 size = sizeof(client_name);
5713 db_get_value(hDB, hsubkey, "Name", client_name, &size, TID_STRING, TRUE);
5714 break;
5715 }
5716 }
5717 }
5718
5719 if (client_name[0]) {
5720 status = cm_connect_client(client_name, &hconn);
5721 if (status != RPC_SUCCESS)
5722 hconn = 0;
5723 }
5724 }
5725
5726 /* header */
5727 rr->rsprintf("HTTP/1.1 200 Document follows\r\n");
5728 rr->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
5729 rr->rsprintf("Content-Type: text/html; charset=%s\r\n\r\n", HTTP_ENCODING);
5730
5731 rr->rsprintf("<html><head>\n");
5732 rr->rsprintf("<link rel=\"icon\" href=\"favicon.png\" type=\"image/png\" />\n");
5733 rr->rsprintf("<link rel=\"stylesheet\" href=\"midas.css\" type=\"text/css\" />\n");
5734 rr->rsprintf("<link rel=\"stylesheet\" href=\"mhttpd.css\" type=\"text/css\" />\n");
5735 rr->rsprintf("<title>MIDAS CAMAC interface</title></head>\n");
5736 rr->rsprintf("<body><form method=\"GET\" action=\"CNAF\">\n\n");
5737
5738 /* title row */
5739
5740 size = sizeof(str);
5741 str[0] = 0;
5742 db_get_value(hDB, 0, "/Experiment/Name", str, &size, TID_STRING, TRUE);
5743
5744 rr->rsprintf("<table border=3 cellpadding=1>\n");
5745 rr->rsprintf("<tr><th colspan=3>MIDAS experiment \"%s\"", str);
5746
5747 if (client_name[0] == 0)
5748 rr->rsprintf("<th colspan=3 class=\"redLight\">No CAMAC server running</tr>\n");
5749 else if (hconn == 0)
5750 rr->rsprintf("<th colspan=3 class=\"redLight\">Cannot connect to %s</tr>\n", client_name);
5751 else
5752 rr->rsprintf("<th colspan=3>CAMAC server: %s</tr>\n", client_name);
5753
5754 /* default values */
5755 c = n = 1;
5756 a = f = d = q = x = 0;
5757 r = 1;
5758 ia = id = w = 0;
5759
5760 /*---- menu buttons ----*/
5761
5762 rr->rsprintf("<tr><td colspan=3>\n");
5763 rr->rsprintf("<input type=submit name=cmd value=Execute>\n");
5764
5765 rr->rsprintf("<td colspan=3>\n");
5766 rr->rsprintf("<input type=submit name=cmd value=ODB>\n");
5767 rr->rsprintf("<input type=submit name=cmd value=Status>\n");
5768 rr->rsprintf("<input type=submit name=cmd value=Help>\n");
5769 rr->rsprintf("</tr>\n\n");
5770
5771 /* header */
5772 rr->rsprintf("<tr><th>N");
5773 rr->rsprintf("<th>A");
5774 rr->rsprintf("<th>F");
5775 rr->rsprintf("<th colspan=3>Data");
5776
5777 /* execute commands */
5778 size = sizeof(d);
5779
5780 const char* cmd = p->getparam("cmd");
5781 if (equal_ustring(cmd, "C cycle")) {
5782 rpc_client_call(hconn, RPC_CNAF16, CNAF_CRATE_CLEAR, 0, 0, 0, 0, 0, &d, &size, &x,
5783 &q);
5784
5785 rr->rsprintf("<tr><td colspan=6 class=\"greenLight\">C cycle executed sucessfully</tr>\n");
5786 } else if (equal_ustring(cmd, "Z cycle")) {
5787 rpc_client_call(hconn, RPC_CNAF16, CNAF_CRATE_ZINIT, 0, 0, 0, 0, 0, &d, &size, &x,
5788 &q);
5789
5790 rr->rsprintf("<tr><td colspan=6 class=\"greenLight\">Z cycle executed sucessfully</tr>\n");
5791 } else if (equal_ustring(cmd, "Clear inhibit")) {
5792 rpc_client_call(hconn, RPC_CNAF16, CNAF_INHIBIT_CLEAR, 0, 0, 0, 0, 0, &d, &size, &x,
5793 &q);
5794
5795 rr->rsprintf
5796 ("<tr><td colspan=6 class=\"greenLight\">Clear inhibit executed sucessfully</tr>\n");
5797 } else if (equal_ustring(cmd, "Set inhibit")) {
5798 rpc_client_call(hconn, RPC_CNAF16, CNAF_INHIBIT_SET, 0, 0, 0, 0, 0, &d, &size, &x,
5799 &q);
5800
5801 rr->rsprintf
5802 ("<tr><td colspan=6 class=\"greenLight\">Set inhibit executed sucessfully</tr>\n");
5803 } else if (equal_ustring(cmd, "Execute")) {
5804 c = atoi(p->getparam("C"));
5805 n = atoi(p->getparam("N"));
5806 a = atoi(p->getparam("A"));
5807 f = atoi(p->getparam("F"));
5808 r = atoi(p->getparam("R"));
5809 w = atoi(p->getparam("W"));
5810 id = atoi(p->getparam("ID"));
5811 ia = atoi(p->getparam("IA"));
5812
5813 const char* pd = p->getparam("D");
5814 if (strncmp(pd, "0x", 2) == 0)
5815 sscanf(pd + 2, "%x", &d);
5816 else
5817 d = atoi(p->getparam("D"));
5818
5819 /* limit repeat range */
5820 if (r == 0)
5821 r = 1;
5822 if (r > 100)
5823 r = 100;
5824 if (w > 1000)
5825 w = 1000;
5826
5827 for (i = 0; i < r; i++) {
5828 status = SUCCESS;
5829
5830 if (hconn) {
5831 size = sizeof(d);
5832 status =
5833 rpc_client_call(hconn, RPC_CNAF24, CNAF, 0, c, n, a, f, &d, &size, &x,
5834 &q);
5835
5836 if (status == RPC_NET_ERROR) {
5837 /* try to reconnect */
5838 //cm_disconnect_client(hconn, FALSE);
5839 status = cm_connect_client(client_name, &hconn);
5840 if (status != RPC_SUCCESS) {
5841 hconn = 0;
5842 client_name[0] = 0;
5843 }
5844
5845 if (hconn) {
5846 status = rpc_client_call(hconn, RPC_CNAF24, CNAF, 0, c, n, a, f, &d, &size, &x, &q);
5847 }
5848 }
5849 }
5850
5851 if (status != SUCCESS) {
5852 rr->rsprintf
5853 ("<tr><td colspan=6 class=\"redLight\">Error executing function, code = %d</tr>",
5854 status);
5855 } else {
5856 rr->rsprintf("<tr align=center><td>%d", n);
5857 rr->rsprintf("<td>%d", a);
5858 rr->rsprintf("<td>%d", f);
5859 rr->rsprintf("<td colspan=3>%d / 0x%04X Q%d X%d", d, d, q, x);
5860 }
5861
5862 d += id;
5863 a += ia;
5864
5865 if (w > 0)
5866 ss_sleep(w);
5867 }
5868 }
5869
5870 /* input fields */
5871 rr->rsprintf
5872 ("<tr align=center><td><input type=text size=3 name=N value=%d>\n",
5873 n);
5874 rr->rsprintf("<td><input type=text size=3 name=A value=%d>\n", a);
5875 rr->rsprintf("<td><input type=text size=3 name=F value=%d>\n", f);
5876 rr->rsprintf
5877 ("<td colspan=3><input type=text size=8 name=D value=%d></tr>\n",
5878 d);
5879
5880 /* control fields */
5881 rr->rsprintf("<tr><td colspan=2>Repeat");
5882 rr->rsprintf("<td><input type=text size=3 name=R value=%d>\n", r);
5883
5884 rr->rsprintf
5885 ("<td align=center colspan=3><input type=submit name=cmd value=\"C cycle\">\n");
5886 rr->rsprintf("<input type=submit name=cmd value=\"Z cycle\">\n");
5887
5888 rr->rsprintf("<tr><td colspan=2>Repeat delay [ms]");
5889 rr->rsprintf("<td><input type=text size=3 name=W value=%d>\n", w);
5890
5891 rr->rsprintf
5892 ("<td align=center colspan=3><input type=submit name=cmd value=\"Set inhibit\">\n");
5893 rr->rsprintf("<input type=submit name=cmd value=\"Clear inhibit\">\n");
5894
5895 rr->rsprintf("<tr><td colspan=2>Data increment");
5896 rr->rsprintf("<td><input type=text size=3 name=ID value=%d>\n", id);
5897
5898 rr->rsprintf
5899 ("<td colspan=3 align=center>Branch <input type=text size=3 name=B value=0>\n");
5900
5901 rr->rsprintf("<tr><td colspan=2>A increment");
5902 rr->rsprintf("<td><input type=text size=3 name=IA value=%d>\n", ia);
5903
5904 rr->rsprintf
5905 ("<td colspan=3 align=center>Crate <input type=text size=3 name=C value=%d>\n",
5906 c);
5907
5908 rr->rsprintf("</table></body>\r\n");
5909}
#define RPC_NET_ERROR
Definition midas.h:702
INT ss_sleep(INT millisec)
Definition system.cxx:3700
#define RPC_CNAF16
Definition mrpc.h:129
#define RPC_CNAF24
Definition mrpc.h:130
#define CNAF_INHIBIT_SET
Definition midas.h:494
#define CNAF_CRATE_ZINIT
Definition midas.h:497
#define CNAF
Definition midas.h:491
#define CNAF_CRATE_CLEAR
Definition midas.h:496
#define CNAF_INHIBIT_CLEAR
Definition midas.h:495
double d
Definition system.cxx:1313
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_custom_file()

void show_custom_file ( Return r,
const char *  name 
)

Definition at line 3641 of file mhttpd.cxx.

3642{
3643 char str[256];
3644 std::string filename;
3645 HNDLE hDB;
3646
3648
3649 HNDLE hkey;
3650 sprintf(str, "/Custom/%s", name);
3651 db_find_key(hDB, 0, str, &hkey);
3652
3653 if (!hkey) {
3654 sprintf(str, "/Custom/%s&", name);
3655 db_find_key(hDB, 0, str, &hkey);
3656 if (!hkey) {
3657 sprintf(str, "/Custom/%s!", name);
3658 db_find_key(hDB, 0, str, &hkey);
3659 }
3660 }
3661
3662 if(!hkey){
3663 sprintf(str,"show_custom_file: Invalid custom page: \"/Custom/%s\" not found in ODB", name);
3664 show_error_404(r, str);
3665 return;
3666 }
3667
3668 int status;
3669 KEY key;
3670
3671 status = db_get_key(hDB, hkey, &key);
3672
3673 if (status != DB_SUCCESS) {
3674 char errtext[512];
3675 sprintf(errtext, "show_custom_file: Error: db_get_key() for \"%s\" status %d", str, status);
3676 show_error_404(r, errtext);
3677 return;
3678 }
3679
3680 int size = key.total_size;
3681 char* ctext = (char*)malloc(size);
3682
3683 status = db_get_data(hDB, hkey, ctext, &size, TID_STRING);
3684
3685 if (status != DB_SUCCESS) {
3686 char errtext[512];
3687 sprintf(errtext, "show_custom_file: Error: db_get_data() for \"%s\" status %d", str, status);
3688 show_error_404(r, errtext);
3689 free(ctext);
3690 return;
3691 }
3692
3693 filename = add_custom_path(ctext);
3694
3695 free(ctext);
3696
3697 send_file(r, filename, true);
3698
3699 return;
3700}
INT total_size
Definition midas.h:1032
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_custom_gif()

void show_custom_gif ( Return rr,
const char *  name 
)

Definition at line 3704 of file mhttpd.cxx.

3705{
3706 char str[256], data[256], src[256];
3707 int i, index, length, status, size, width, height, bgcol, fgcol, bdcol, r, g, b, x, y;
3708 HNDLE hDB, hkeygif, hkeyroot, hkey, hkeyval;
3709 double fvalue, ratio;
3710 KEY key, vkey;
3711 gdImagePtr im;
3712 gdGifBuffer gb;
3713 gdFontPtr pfont;
3714 FILE *f;
3715 CGIF_LABEL label;
3716 CGIF_BAR bar;
3717
3719
3720 /* find image description in ODB */
3721 sprintf(str, "/Custom/Images/%s", name);
3722 db_find_key(hDB, 0, str, &hkeygif);
3723 if (!hkeygif) {
3724
3725 // If we don't have Images directory,
3726 // then just treat this like any other custom file.
3728 return;
3729 }
3730
3731 /* load background image */
3732 std::string filename;
3733 db_get_value_string(hDB, hkeygif, "Background", 0, &filename, FALSE);
3734
3735 std::string full_filename = add_custom_path(filename);
3736
3737 f = fopen(full_filename.c_str(), "rb");
3738 if (f == NULL) {
3739 sprintf(str, "show_custom_gif: Cannot open file \"%s\"", full_filename.c_str());
3740 show_error_404(rr, str);
3741 return;
3742 }
3743
3744 im = gdImageCreateFromGif(f);
3745 fclose(f);
3746
3747 if (im == NULL) {
3748 sprintf(str, "show_custom_gif: File \"%s\" is not a GIF image", filename.c_str());
3749 show_error_404(rr, str);
3750 return;
3751 }
3752
3754
3755 /*---- draw labels ----------------------------------------------*/
3756
3757 db_find_key(hDB, hkeygif, "Labels", &hkeyroot);
3758 if (hkeyroot) {
3759 for (index = 0;; index++) {
3760 db_enum_key(hDB, hkeyroot, index, &hkey);
3761 if (!hkey)
3762 break;
3763 db_get_key(hDB, hkey, &key);
3764
3765 size = sizeof(label);
3766 status = db_get_record1(hDB, hkey, &label, &size, 0, strcomb1(cgif_label_str).c_str());
3767 if (status != DB_SUCCESS) {
3768 cm_msg(MERROR, "show_custom_gif", "Cannot open data record for label \"%s\"",
3769 key.name);
3770 continue;
3771 }
3772
3773 if (label.src[0] == 0) {
3774 cm_msg(MERROR, "show_custom_gif", "Empty Src key for label \"%s\"", key.name);
3775 continue;
3776 }
3777
3778 db_find_key(hDB, 0, label.src, &hkeyval);
3779 if (!hkeyval) {
3780 cm_msg(MERROR, "show_custom_gif", "Invalid Src key \"%s\" for label \"%s\"",
3781 label.src, key.name);
3782 continue;
3783 }
3784
3785 db_get_key(hDB, hkeyval, &vkey);
3786 size = sizeof(data);
3787 status = db_get_value(hDB, 0, label.src, data, &size, vkey.type, FALSE);
3788
3789 std::string value;
3790
3791 if (label.format[0]) {
3792 if (vkey.type == TID_FLOAT)
3793 value = msprintf(label.format, *(((float *) data)));
3794 else if (vkey.type == TID_DOUBLE)
3795 value = msprintf(label.format, *(((double *) data)));
3796 else if (vkey.type == TID_INT)
3797 value = msprintf(label.format, *(((INT *) data)));
3798 else if (vkey.type == TID_BOOL) {
3799 if (strstr(label.format, "%c"))
3800 value = msprintf(label.format, *(((INT *) data)) ? 'y' : 'n');
3801 else
3802 value = msprintf(label.format, *(((INT *) data)));
3803 } else
3804 value = db_sprintf(data, size, 0, vkey.type);
3805 } else
3806 value = db_sprintf(data, size, 0, vkey.type);
3807
3808 sscanf(label.fgcolor, "%02x%02x%02x", &r, &g, &b);
3809 fgcol = gdImageColorAllocate(im, r, g, b);
3810 if (fgcol == -1)
3811 fgcol = gdImageColorClosest(im, r, g, b);
3812
3813 sscanf(label.bgcolor, "%02x%02x%02x", &r, &g, &b);
3814 bgcol = gdImageColorAllocate(im, r, g, b);
3815 if (bgcol == -1)
3816 bgcol = gdImageColorClosest(im, r, g, b);
3817
3818 /* select font */
3819 if (equal_ustring(label.font, "Small"))
3820 pfont = gdFontSmall;
3821 else if (equal_ustring(label.font, "Medium"))
3822 pfont = gdFontMediumBold;
3823 else if (equal_ustring(label.font, "Giant"))
3824 pfont = gdFontGiant;
3825 else
3826 pfont = gdFontMediumBold;
3827
3828 width = value.length() * pfont->w + 5 + 5;
3829 height = pfont->h + 2 + 2;
3830
3831 if (label.align == 0) {
3832 /* left */
3833 gdImageFilledRectangle(im, label.x, label.y, label.x + width,
3834 label.y + height, bgcol);
3835 gdImageRectangle(im, label.x, label.y, label.x + width, label.y + height,
3836 fgcol);
3837 gdImageString(im, pfont, label.x + 5, label.y + 2, value.c_str(), fgcol);
3838 } else if (label.align == 1) {
3839 /* center */
3840 gdImageFilledRectangle(im, label.x - width / 2, label.y, label.x + width / 2,
3841 label.y + height, bgcol);
3842 gdImageRectangle(im, label.x - width / 2, label.y, label.x + width / 2,
3843 label.y + height, fgcol);
3844 gdImageString(im, pfont, label.x + 5 - width / 2, label.y + 2, value.c_str(), fgcol);
3845 } else {
3846 /* right */
3847 gdImageFilledRectangle(im, label.x - width, label.y, label.x,
3848 label.y + height, bgcol);
3849 gdImageRectangle(im, label.x - width, label.y, label.x, label.y + height,
3850 fgcol);
3851 gdImageString(im, pfont, label.x - width + 5, label.y + 2, value.c_str(), fgcol);
3852 }
3853 }
3854 }
3855
3856 /*---- draw bars ------------------------------------------------*/
3857
3858 db_find_key(hDB, hkeygif, "Bars", &hkeyroot);
3859 if (hkeyroot) {
3860 for (index = 0;; index++) {
3861 db_enum_key(hDB, hkeyroot, index, &hkey);
3862 if (!hkey)
3863 break;
3864 db_get_key(hDB, hkey, &key);
3865
3866 size = sizeof(bar);
3867 status = db_get_record1(hDB, hkey, &bar, &size, 0, strcomb1(cgif_bar_str).c_str());
3868 if (status != DB_SUCCESS) {
3869 cm_msg(MERROR, "show_custom_gif", "Cannot open data record for bar \"%s\"",
3870 key.name);
3871 continue;
3872 }
3873
3874 if (bar.src[0] == 0) {
3875 cm_msg(MERROR, "show_custom_gif", "Empty Src key for bar \"%s\"", key.name);
3876 continue;
3877 }
3878
3879 db_find_key(hDB, 0, bar.src, &hkeyval);
3880 if (!hkeyval) {
3881 cm_msg(MERROR, "show_custom_gif", "Invalid Src key \"%s\" for bar \"%s\"",
3882 bar.src, key.name);
3883 continue;
3884 }
3885
3886 db_get_key(hDB, hkeyval, &vkey);
3887 size = sizeof(data);
3888 status = db_get_value(hDB, 0, bar.src, data, &size, vkey.type, FALSE);
3889 std::string value = db_sprintf(data, size, 0, vkey.type);
3890 if (equal_ustring(value.c_str(), "NAN"))
3891 continue;
3892
3893 fvalue = atof(value.c_str());
3894
3895 sscanf(bar.fgcolor, "%02x%02x%02x", &r, &g, &b);
3896 fgcol = gdImageColorAllocate(im, r, g, b);
3897 if (fgcol == -1)
3898 fgcol = gdImageColorClosest(im, r, g, b);
3899
3900 sscanf(bar.bgcolor, "%02x%02x%02x", &r, &g, &b);
3901 bgcol = gdImageColorAllocate(im, r, g, b);
3902 if (bgcol == -1)
3903 bgcol = gdImageColorClosest(im, r, g, b);
3904
3905 sscanf(bar.bdcolor, "%02x%02x%02x", &r, &g, &b);
3906 bdcol = gdImageColorAllocate(im, r, g, b);
3907 if (bdcol == -1)
3908 bdcol = gdImageColorClosest(im, r, g, b);
3909
3910 if (bar.min == bar.max)
3911 bar.max += 1;
3912
3913 if (bar.logscale) {
3914 if (fvalue < 1E-20)
3915 fvalue = 1E-20;
3916 ratio = (log(fvalue) - log(bar.min)) / (log(bar.max) - log(bar.min));
3917 } else
3918 ratio = (fvalue - bar.min) / (bar.max - bar.min);
3919 if (ratio < 0)
3920 ratio = 0;
3921 if (ratio > 1)
3922 ratio = 1;
3923
3924 if (bar.direction == 0) {
3925 /* vertical */
3926 ratio = (bar.height - 2) - ratio * (bar.height - 2);
3927 r = (int) (ratio + 0.5);
3928
3929 gdImageFilledRectangle(im, bar.x, bar.y, bar.x + bar.width,
3930 bar.y + bar.height, bgcol);
3931 gdImageRectangle(im, bar.x, bar.y, bar.x + bar.width, bar.y + bar.height,
3932 bdcol);
3933 gdImageFilledRectangle(im, bar.x + 1, bar.y + r + 1, bar.x + bar.width - 1,
3934 bar.y + bar.height - 1, fgcol);
3935
3936 if (bar.axis == 1)
3937 vaxis(im, gdFontSmall, bdcol, 0, bar.x, bar.y + bar.height, bar.height, -3,
3938 -5, -7, -8, 0, bar.min, bar.max, bar.logscale);
3939 else if (bar.axis == 2)
3940 vaxis(im, gdFontSmall, bdcol, 0, bar.x + bar.width, bar.y + bar.height,
3941 bar.height, 3, 5, 7, 10, 0, bar.min, bar.max, bar.logscale);
3942
3943 } else {
3944 /* horizontal */
3945 ratio = ratio * (bar.height - 2);
3946 r = (int) (ratio + 0.5);
3947
3948 gdImageFilledRectangle(im, bar.x, bar.y, bar.x + bar.height,
3949 bar.y + bar.width, bgcol);
3950 gdImageRectangle(im, bar.x, bar.y, bar.x + bar.height, bar.y + bar.width,
3951 bdcol);
3952 gdImageFilledRectangle(im, bar.x + 1, bar.y + 1, bar.x + r,
3953 bar.y + bar.width - 1, fgcol);
3954
3955 if (bar.axis == 1)
3956 haxis(im, gdFontSmall, bdcol, 0, bar.x, bar.y, bar.height, -3, -5, -7, -18,
3957 0, bar.min, bar.max);
3958 else if (bar.axis == 2)
3959 haxis(im, gdFontSmall, bdcol, 0, bar.x, bar.y + bar.width, bar.height, 3,
3960 5, 7, 8, 0, bar.min, bar.max);
3961 }
3962 }
3963 }
3964
3965 /*---- draw fills -----------------------------------------------*/
3966
3967 db_find_key(hDB, hkeygif, "Fills", &hkeyroot);
3968 if (hkeyroot) {
3969 for (index = 0;; index++) {
3970 db_enum_key(hDB, hkeyroot, index, &hkey);
3971 if (!hkey)
3972 break;
3973 db_get_key(hDB, hkey, &key);
3974
3975 size = sizeof(src);
3976 src[0] = 0;
3977 db_get_value(hDB, hkey, "Src", src, &size, TID_STRING, TRUE);
3978
3979 if (src[0] == 0) {
3980 cm_msg(MERROR, "show_custom_gif", "Empty Src key for Fill \"%s\"", key.name);
3981 continue;
3982 }
3983
3984 if (!evaluate_src(key.name, src, &fvalue))
3985 continue;
3986
3987 x = y = 0;
3988 size = sizeof(x);
3989 db_get_value(hDB, hkey, "X", &x, &size, TID_INT, TRUE);
3990 db_get_value(hDB, hkey, "Y", &y, &size, TID_INT, TRUE);
3991
3992 size = sizeof(data);
3993 status = db_get_value(hDB, hkey, "Limits", data, &size, TID_DOUBLE, FALSE);
3994 if (status != DB_SUCCESS) {
3995 cm_msg(MERROR, "show_custom_gif", "No \"Limits\" entry for Fill \"%s\"",
3996 key.name);
3997 continue;
3998 }
3999 for (i = 0; i < size / (int) sizeof(double); i++)
4000 if (*((double *) data + i) > fvalue)
4001 break;
4002 if (i > 0)
4003 i--;
4004
4005 db_find_key(hDB, hkey, "Fillcolors", &hkeyval);
4006 if (!hkeyval) {
4007 cm_msg(MERROR, "show_custom_gif", "No \"Fillcolors\" entry for Fill \"%s\"",
4008 key.name);
4009 continue;
4010 }
4011
4012 size = sizeof(data);
4013 strcpy(data, "FFFFFF");
4014 status = db_get_data_index(hDB, hkeyval, data, &size, i, TID_STRING);
4015 if (status == DB_SUCCESS) {
4016 sscanf(data, "%02x%02x%02x", &r, &g, &b);
4017 fgcol = gdImageColorAllocate(im, r, g, b);
4018 if (fgcol == -1)
4019 fgcol = gdImageColorClosest(im, r, g, b);
4020 gdImageFill(im, x, y, fgcol);
4021 }
4022 }
4023 }
4024
4025 /* generate GIF */
4026 gdImageInterlace(im, 1);
4027 gdImageGif(im, &gb);
4028 gdImageDestroy(im);
4029 length = gb.size;
4030
4031 rr->rsprintf("HTTP/1.1 200 Document follows\r\n");
4032 rr->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
4033
4034 rr->rsprintf("Content-Type: image/gif\r\n");
4035 rr->rsprintf("Content-Length: %d\r\n", length);
4036 rr->rsprintf("Cache-control: private, max-age=0, no-cache\r\n");
4037 rr->rsprintf("Expires: Fri, 01-Jan-1983 00:00:00 GMT\r\n\r\n");
4038
4039 rr->rmemcpy(gb.data, length);
4040}
#define TID_DOUBLE
Definition midas.h:343
#define TID_FLOAT
Definition midas.h:341
gdImagePtr gdImageCreateFromGif(FILE *fd)
Definition mgd.cxx:1888
int gdImageColorClosest(gdImagePtr im, int r, int g, int b)
Definition mgd.cxx:455
void gdImageFill(gdImagePtr im, int x, int y, int color)
Definition mgd.cxx:964
INT db_get_record1(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, INT align, const char *rec_str)
Definition odb.cxx:11834
void haxis(gdImagePtr im, gdFont *font, int col, int gcol, int x1, int y1, int width, int minor, int major, int text, int label, int grid, double xmin, double xmax)
Definition mhttpd.cxx:7665
void show_custom_file(Return *r, const char *name)
Definition mhttpd.cxx:3641
int evaluate_src(char *key, char *src, double *fvalue)
Definition mhttpd.cxx:3529
static const char * cgif_bar_str[]
Definition mhttpd.cxx:3500
static const char * cgif_label_str[]
Definition mhttpd.cxx:3460
char bgcolor[8]
Definition mhttpd.cxx:3523
double max
Definition mhttpd.cxx:3521
char src[256]
Definition mhttpd.cxx:3518
BOOL logscale
Definition mhttpd.cxx:3520
double min
Definition mhttpd.cxx:3521
int width
Definition mhttpd.cxx:3519
char fgcolor[8]
Definition mhttpd.cxx:3522
int height
Definition mhttpd.cxx:3519
int direction
Definition mhttpd.cxx:3519
char bdcolor[8]
Definition mhttpd.cxx:3524
char format[32]
Definition mhttpd.cxx:3474
char src[256]
Definition mhttpd.cxx:3473
char bgcolor[8]
Definition mhttpd.cxx:3478
char font[32]
Definition mhttpd.cxx:3475
char fgcolor[8]
Definition mhttpd.cxx:3477
Definition mgd.h:58
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_custom_page()

void show_custom_page ( Param pp,
Return r,
const char *  cookie_cpwd 
)

Definition at line 5453 of file mhttpd.cxx.

5454{
5455 int size, n_var, index, edit;
5456 char keypath[256], type[32], *p, *ps;
5457 char pwd[256], tail[256];
5458 HNDLE hDB, hkey;
5459 KEY key;
5460 char data[TEXT_SIZE];
5461
5462 std::string path = pp->getparam("page");
5463
5464 if (path[0] == 0) {
5465 show_error_404(r, "show_custom_page: Invalid custom page: \"page\" parameter is empty");
5466 return;
5467 }
5468
5469 if (strstr(path.c_str(), "..")) {
5470 std::string str;
5471 str += "Invalid custom page name \'";
5472 str += path;
5473 str += "\' contains \'..\'";
5474 show_error_404(r, str.c_str());
5475 return;
5476 }
5477
5478 if (strstr(path.c_str(), ".gif")) {
5479 show_custom_gif(r, path.c_str());
5480 return;
5481 }
5482
5483 if (strchr(path.c_str(), '.')) {
5484 show_custom_file(r, path.c_str());
5485 return;
5486 }
5487
5489
5490 std::string xpath = std::string("/Custom/") + path;
5491 db_find_key(hDB, 0, xpath.c_str(), &hkey);
5492 if (!hkey) {
5493 xpath = std::string("/Custom/") + path + "&";
5494 db_find_key(hDB, 0, xpath.c_str(), &hkey);
5495 if (!hkey) {
5496 xpath = std::string("/Custom/") + path + "!";
5497 db_find_key(hDB, 0, xpath.c_str(), &hkey);
5498 }
5499 }
5500
5501 if (hkey) {
5502 char* ctext;
5503 int status;
5504
5505 status = db_get_key(hDB, hkey, &key);
5506 assert(status == DB_SUCCESS);
5507 size = key.total_size;
5508 ctext = (char*)malloc(size);
5509 status = db_get_data(hDB, hkey, ctext, &size, TID_STRING);
5510 if (status != DB_SUCCESS) {
5511 std::string errtext = msprintf("show_custom_page: Error: db_get_data() for \"%s\" status %d", xpath.c_str(), status);
5512 show_error_404(r, errtext.c_str());
5513 free(ctext);
5514 return;
5515 }
5516
5517 std::string content_type = "text/html";
5518
5519 /* check for link */
5520 if (std::string(ctext).substr(0, 5) == "?cmd=") {
5521 redirect(r, ctext);
5522 free(ctext);
5523 return;
5524 }
5525
5526 /* check if filename */
5527 if (strchr(ctext, '\n') == 0) {
5528 std::string full_filename = add_custom_path(ctext);
5529 int fh = open(full_filename.c_str(), O_RDONLY | O_BINARY);
5530 if (fh < 0) {
5531 std::string str = msprintf("show_custom_page: Cannot open file \"%s\", open() errno %d (%s)", full_filename.c_str(), errno, strerror(errno));
5532 show_error_404(r, str.c_str());
5533 free(ctext);
5534 return;
5535 }
5536 free(ctext);
5537 ctext = NULL;
5538 off_t off = lseek(fh, 0, SEEK_END);
5539 if (off < 0) {
5540 std::string str = msprintf("show_custom_page: Cannot open file \"%s\", lseek(SEEK_END) errno %d (%s)", full_filename.c_str(), errno, strerror(errno));
5541 show_error_404(r, str.c_str());
5542 free(ctext);
5543 close(fh);
5544 return;
5545 }
5546 size_t size = off;
5547 lseek(fh, 0, SEEK_SET);
5548 ctext = (char*)malloc(size+1);
5549 ssize_t rd = read(fh, ctext, size);
5550 if (rd > 0) {
5551 ctext[rd] = 0; // make sure string is zero-terminated
5552 size = rd;
5553 } else {
5554 ctext[0] = 0;
5555 size = 0;
5556 }
5557 close(fh);
5558
5559 content_type = get_content_type(full_filename.c_str());
5560 }
5561
5562 /* check for valid password */
5563 if (equal_ustring(pp->getparam("cmd"), "Edit")) {
5564 p = ps = ctext;
5565 n_var = 0;
5566 do {
5567 char format[256];
5568
5569 p = find_odb_tag(ps, keypath, format, &edit, type, pwd, tail);
5570 if (p == NULL)
5571 break;
5572 ps = strchr(p, '>') + 1;
5573
5574 if (pwd[0] && n_var == atoi(pp->getparam("index"))) {
5575 char str[256];
5576 size = NAME_LENGTH;
5577 mstrlcpy(str, path.c_str(), sizeof(str)); // FIXME: overflows "str"
5578 if (strlen(str)>0 && str[strlen(str)-1] == '&')
5579 str[strlen(str)-1] = 0;
5580 std::string ppath;
5581 ppath += "/Custom/Pwd/";
5582 if (pp->getparam("pnam") && *pp->getparam("pnam")) {
5583 ppath += pp->getparam("pnam");
5584 } else {
5585 ppath += str;
5586 }
5587 str[0] = 0;
5588 db_get_value(hDB, 0, ppath.c_str(), str, &size, TID_STRING, TRUE);
5589 if (!equal_ustring(cookie_cpwd, str)) {
5590 show_error_404(r, "show_custom_page: Invalid password!");
5591 free(ctext);
5592 return;
5593 } else
5594 break;
5595 }
5596
5597 n_var++;
5598 } while (p != NULL);
5599 }
5600
5601 /* process toggle command */
5602 if (equal_ustring(pp->getparam("cmd"), "Toggle")) {
5603
5604 if (pp->getparam("pnam") && *pp->getparam("pnam")) {
5605 std::string ppath;
5606 ppath += "/Custom/Pwd/";
5607 ppath += pp->getparam("pnam");
5608 std::string str;
5609 db_get_value_string(hDB, 0, ppath.c_str(), 0, &str, TRUE, 256);
5610 if (!equal_ustring(cookie_cpwd, str.c_str())) {
5611 show_error_404(r, "show_custom_page: Invalid password!");
5612 free(ctext);
5613 return;
5614 }
5615 }
5616 std::string podb = pp->getparam("odb");
5617 std::string::size_type pos = podb.find('[');
5618 if (pos != std::string::npos) {
5619 index = atoi(podb.substr(pos+1).c_str());
5620 podb.resize(pos);
5621 //printf("found index %d in [%s] [%s]\n", index, pp->getparam("odb"), podb.c_str());
5622 } else
5623 index = 0;
5624
5625 if (db_find_key(hDB, 0, podb.c_str(), &hkey)) {
5626 db_get_key(hDB, hkey, &key);
5627 memset(data, 0, sizeof(data));
5628 if (key.item_size <= (int)sizeof(data)) {
5629 size = sizeof(data);
5630 db_get_data_index(hDB, hkey, data, &size, index, key.type);
5631 std::string data_str = db_sprintf(data, size, 0, key.type);
5632 if (atoi(data_str.c_str()) == 0)
5633 db_sscanf("1", data, &size, 0, key.type);
5634 else
5635 db_sscanf("0", data, &size, 0, key.type);
5637 }
5638 }
5639
5640 /* redirect (so that 'reload' does not toggle again) */
5641 redirect(r, path.c_str());
5642 free(ctext);
5643 return;
5644 }
5645
5646 /* HTTP header */
5647 r->rsprintf("HTTP/1.1 200 Document follows\r\n");
5648 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
5649 r->rsprintf("Content-Type: %s; charset=%s\r\n\r\n", content_type.c_str(), HTTP_ENCODING);
5650
5651 /* interprete text, replace <odb> tags with ODB values */
5652 p = ps = ctext;
5653 n_var = 0;
5654 do {
5655 char format[256];
5656 p = find_odb_tag(ps, keypath, format, &edit, type, pwd, tail);
5657 if (p != NULL)
5658 *p = 0;
5659 r->rsputs(ps);
5660
5661 if (p == NULL)
5662 break;
5663 ps = strchr(p + 1, '>') + 1;
5664
5665 show_odb_tag(pp, r, path.c_str(), keypath, format, n_var, edit, type, pwd, tail);
5666 n_var++;
5667
5668 } while (p != NULL);
5669
5670 if (equal_ustring(pp->getparam("cmd"), "Set") || pp->isparam("cbi")) {
5671 /* redirect (so that 'reload' does not change value) */
5672 r->reset();
5673 redirect(r, path.c_str());
5674 }
5675
5676 free(ctext);
5677 ctext = NULL;
5678 } else {
5679 std::string str = msprintf("Invalid custom page: Page \"%s\" not found in ODB", path.c_str());
5680 show_error_404(r, str.c_str());
5681 return;
5682 }
5683}
void reset()
Definition mhttpd.cxx:574
#define O_BINARY
Definition msystem.h:226
char * find_odb_tag(char *p, char *path, char *format, int *edit, char *type, char *pwd, char *tail)
Definition mhttpd.cxx:3123
void show_odb_tag(Param *pp, Return *r, const char *path, const char *keypath1, const char *format, int n_var, int edit, char *type, char *pwd, char *tail)
Definition mhttpd.cxx:3307
#define read(n, a, f)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_elog_attachment()

void show_elog_attachment ( Param p,
Return r,
const char *  path 
)

Definition at line 2513 of file mhttpd.cxx.

2514{
2515 HNDLE hDB;
2516 int size;
2517 int status;
2518 char file_name[256];
2519
2521 file_name[0] = 0;
2522 if (hDB > 0) {
2523 size = sizeof(file_name);
2524 memset(file_name, 0, size);
2525
2526 status = db_get_value(hDB, 0, "/Logger/Elog dir", file_name, &size, TID_STRING, FALSE);
2527 if (status != DB_SUCCESS)
2528 db_get_value(hDB, 0, "/Logger/Data dir", file_name, &size, TID_STRING, TRUE);
2529
2530 if (file_name[0] != 0)
2531 if (file_name[strlen(file_name) - 1] != DIR_SEPARATOR)
2532 mstrlcat(file_name, DIR_SEPARATOR_STR, sizeof(file_name));
2533 }
2534 mstrlcat(file_name, path, sizeof(file_name));
2535
2536 int fh = open(file_name, O_RDONLY | O_BINARY);
2537 if (fh > 0) {
2538 lseek(fh, 0, SEEK_END);
2539 int length = TELL(fh);
2540 lseek(fh, 0, SEEK_SET);
2541
2542 r->rsprintf("HTTP/1.1 200 Document follows\r\n");
2543 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
2544 r->rsprintf("Accept-Ranges: bytes\r\n");
2545 //r->rsprintf("Content-disposition: attachment; filename=%s\r\n", path);
2546
2547 r->rsprintf("Content-Type: %s\r\n", get_content_type(file_name).c_str());
2548
2549 r->rsprintf("Content-Length: %d\r\n\r\n", length);
2550
2551 r->rread(file_name, fh, length);
2552
2553 close(fh);
2554 }
2555
2556 return;
2557}
#define TELL(fh)
Definition msystem.h:250
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_eqtable_page()

void show_eqtable_page ( Param pp,
Return r,
int  refresh 
)

Definition at line 2589 of file mhttpd.cxx.

2590{
2591 int i, j, k, colspan, size, n_var, i_edit, i_set, line;
2592 char eq_name[32], group[32];
2593 char group_name[MAX_GROUPS][32], data[256], style[80];
2594 HNDLE hDB;
2595 char odb_path[256];
2596
2598
2599 /* check if variable to edit */
2600 i_edit = -1;
2601 if (equal_ustring(pp->getparam("cmd"), "Edit"))
2602 i_edit = atoi(pp->getparam("index"));
2603
2604 /* check if variable to set */
2605 i_set = -1;
2606 if (equal_ustring(pp->getparam("cmd"), "Set"))
2607 i_set = atoi(pp->getparam("index"));
2608
2609 /* get equipment and group */
2610 if (pp->getparam("eq"))
2611 mstrlcpy(eq_name, pp->getparam("eq"), sizeof(eq_name));
2612 mstrlcpy(group, "All", sizeof(group));
2613 if (pp->getparam("group") && *pp->getparam("group"))
2614 mstrlcpy(group, pp->getparam("group"), sizeof(group));
2615
2616#if 0
2617 /* check for "names" in settings */
2618 if (eq_name[0]) {
2619 sprintf(str, "/Equipment/%s/Settings", eq_name);
2620 HNDLE hkeyset;
2621 db_find_key(hDB, 0, str, &hkeyset);
2622 HNDLE hkeynames = 0;
2623 if (hkeyset) {
2624 for (i = 0;; i++) {
2625 db_enum_link(hDB, hkeyset, i, &hkeynames);
2626
2627 if (!hkeynames)
2628 break;
2629
2630 KEY key;
2631 db_get_key(hDB, hkeynames, &key);
2632
2633 if (strncmp(key.name, "Names", 5) == 0)
2634 break;
2635 }
2636 }
2637
2638 /* redirect if no names found */
2639 if (!hkeyset || !hkeynames) {
2640 /* redirect */
2641 sprintf(str, "?cmd=odb&odb_path=/Equipment/%s/Variables", eq_name);
2642 redirect(r, str);
2643 return;
2644 }
2645 }
2646#endif
2647
2648 show_header(r, "MIDAS slow control", "", group, i_edit == -1 ? refresh : 0);
2649 r->rsprintf("<script type=\"text/javascript\" src=\"midas.js\"></script>\n");
2650 r->rsprintf("<script type=\"text/javascript\" src=\"mhttpd.js\"></script>\n");
2651 r->rsprintf("<script type=\"text/javascript\" src=\"obsolete.js\"></script>\n");
2652 show_navigation_bar(r, "SC");
2653
2654 /*---- menu buttons ----*/
2655
2656 r->rsprintf("<tr><td colspan=15>\n");
2657
2658 if (equal_ustring(pp->getparam("cmd"), "Edit"))
2659 r->rsprintf("<input type=submit name=cmd value=Set>\n");
2660
2661 r->rsprintf("</tr>\n\n");
2662 r->rsprintf("</table>"); //end header table
2663
2664 r->rsprintf("<table class=\"ODBtable\" style=\"max-width:700px;\">"); //body table
2665
2666 /*---- enumerate SC equipment ----*/
2667
2668 r->rsprintf("<tr><td class=\"subStatusTitle\" colspan=15><i>Equipment:</i> &nbsp;&nbsp;\n");
2669
2670 HNDLE hkeyeqroot;
2671 db_find_key(hDB, 0, "/Equipment", &hkeyeqroot);
2672 if (hkeyeqroot)
2673 for (i = 0;; i++) {
2674 HNDLE hkeyeq;
2675 db_enum_link(hDB, hkeyeqroot, i, &hkeyeq);
2676
2677 if (!hkeyeq)
2678 break;
2679
2680 KEY eqkey;
2681 db_get_key(hDB, hkeyeq, &eqkey);
2682
2683 HNDLE hkeyset;
2684 db_find_key(hDB, hkeyeq, "Settings", &hkeyset);
2685 if (hkeyset) {
2686 for (j = 0;; j++) {
2687 HNDLE hkeynames;
2688 db_enum_link(hDB, hkeyset, j, &hkeynames);
2689
2690 if (!hkeynames)
2691 break;
2692
2693 KEY key;
2694 db_get_key(hDB, hkeynames, &key);
2695
2696 if (strncmp(key.name, "Names", 5) == 0) {
2697 if (equal_ustring(eq_name, eqkey.name))
2698 r->rsprintf("<b>%s</b> &nbsp;&nbsp;", eqkey.name);
2699 else {
2700 r->rsprintf("<a href=\"?cmd=eqtable&eq=%s\">%s</a> &nbsp;&nbsp;", urlEncode(eqkey.name).c_str(), eqkey.name);
2701 }
2702 break;
2703 }
2704 }
2705 }
2706 }
2707 r->rsprintf("</tr>\n");
2708
2709 if (!eq_name[0]) {
2710 r->rsprintf("</table>");
2711 return;
2712 }
2713
2714 /*---- display SC ----*/
2715
2716 n_var = 0;
2717 std::string names_path = msprintf("/Equipment/%s/Settings/Names", eq_name);
2718 HNDLE hkeyeqnames;
2719 db_find_key(hDB, 0, names_path.c_str(), &hkeyeqnames);
2720
2721 if (hkeyeqnames) {
2722
2723 /*---- single name array ----*/
2724 r->rsprintf("<tr><td colspan=15><i>Groups:</i> &nbsp;&nbsp;");
2725
2726 /* "all" group */
2727 if (equal_ustring(group, "All"))
2728 r->rsprintf("<b>All</b> &nbsp;&nbsp;");
2729 else
2730 r->rsprintf("<a href=\"?cmd=eqtable&eq=%s\">All</a> &nbsp;&nbsp;", urlEncode(eq_name).c_str());
2731
2732 /* collect groups */
2733
2734 memset(group_name, 0, sizeof(group_name));
2735 KEY key;
2736 db_get_key(hDB, hkeyeqnames, &key);
2737
2738 for (int level = 0; ; level++) {
2739 bool next_level = false;
2740 for (i = 0; i < key.num_values; i++) {
2741 char name_str[256];
2742 size = sizeof(name_str);
2743 db_get_data_index(hDB, hkeyeqnames, name_str, &size, i, TID_STRING);
2744
2745 char *s = strchr(name_str, '%');
2746 for (int k=0; s && k<level; k++)
2747 s = strchr(s+1, '%');
2748
2749 if (s) {
2750 *s = 0;
2751 if (strchr(s+1, '%'))
2752 next_level = true;
2753
2754 //printf("try group [%s] name [%s], level %d, %d\n", name_str, s+1, level, next_level);
2755
2756 for (j = 0; j < MAX_GROUPS; j++) {
2757 if (equal_ustring(group_name[j], name_str) || group_name[j][0] == 0)
2758 break;
2759 }
2760 if ((j < MAX_GROUPS) && (group_name[j][0] == 0))
2761 mstrlcpy(group_name[j], name_str, sizeof(group_name[0]));
2762 }
2763 }
2764
2765 if (!next_level)
2766 break;
2767 }
2768
2769 for (i = 0; i < MAX_GROUPS && group_name[i][0]; i++) {
2770 if (equal_ustring(group_name[i], group))
2771 r->rsprintf("<b>%s</b> &nbsp;&nbsp;", group_name[i]);
2772 else {
2773 r->rsprintf("<a href=\"?cmd=eqtable&eq=%s&group=%s\">%s</a> &nbsp;&nbsp;", urlEncode(eq_name).c_str(), urlEncode(group_name[i]).c_str(), group_name[i]);
2774 }
2775 }
2776
2777 r->rsprintf("<i>ODB:</i> &nbsp;&nbsp;");
2778 r->rsprintf("<a href=\"?cmd=odb&odb_path=Equipment/%s/Common\">Common</a> &nbsp;&nbsp;", urlEncode(eq_name).c_str());
2779 r->rsprintf("<a href=\"?cmd=odb&odb_path=Equipment/%s/Settings\">Settings</a> &nbsp;&nbsp;", urlEncode(eq_name).c_str());
2780 r->rsprintf("<a href=\"?cmd=odb&odb_path=Equipment/%s/Variables\">Variables</a> &nbsp;&nbsp;", urlEncode(eq_name).c_str());
2781 r->rsprintf("</tr>\n");
2782
2783 /* count variables */
2784 std::string vars_path = msprintf("/Equipment/%s/Variables", eq_name);
2785 HNDLE hkeyvar;
2786 db_find_key(hDB, 0, vars_path.c_str(), &hkeyvar);
2787 if (!hkeyvar) {
2788 r->rsprintf("</table>");
2789 return;
2790 }
2791 for (i = 0;; i++) {
2792 HNDLE hkey;
2793 db_enum_link(hDB, hkeyvar, i, &hkey);
2794 if (!hkey)
2795 break;
2796 }
2797
2798 if (i == 0 || i > 15) {
2799 r->rsprintf("</table>");
2800 return;
2801 }
2802
2803 /* title row */
2804 colspan = 15 - i;
2805 r->rsprintf("<tr class=\"subStatusTitle\"><th colspan=%d>Names", colspan);
2806
2807 /* display entries for this group */
2808 for (int i = 0;; i++) {
2809 HNDLE hkey;
2810 db_enum_link(hDB, hkeyvar, i, &hkey);
2811
2812 if (!hkey)
2813 break;
2814
2815 KEY key;
2816 db_get_key(hDB, hkey, &key);
2817 r->rsprintf("<th>%s", key.name);
2818 }
2819
2820 r->rsprintf("</tr>\n");
2821
2822 /* data for current group */
2823 std::string names_path = msprintf("/Equipment/%s/Settings/Names", eq_name);
2824 int num_values = 0;
2825 HNDLE hnames_key;
2826 db_find_key(hDB, 0, names_path.c_str(), &hnames_key);
2827 if (hnames_key) {
2828 KEY names_key;
2829 db_get_key(hDB, hnames_key, &names_key);
2830 num_values = names_key.num_values;
2831 }
2832 for (int i = 0; i < num_values; i++) {
2833 char names_str[256];
2834 size = sizeof(names_str);
2835 db_get_data_index(hDB, hnames_key, names_str, &size, i, TID_STRING);
2836
2837 char name[NAME_LENGTH+32];
2838 mstrlcpy(name, names_str, sizeof(name));
2839
2840 //printf("group [%s], name [%s], str [%s]\n", group, name, names_str);
2841
2842 if (!equal_ustring(group, "All")) {
2843 // check if name starts with the name of the group we want to display
2844 char *s = strstr(name, group);
2845 if (s != name)
2846 continue;
2847 if (name[strlen(group)] != '%')
2848 continue;
2849 }
2850
2851 if (strlen(name) < 1)
2852 sprintf(name, "[%d]", i);
2853
2854 if (i % 2 == 0)
2855 r->rsprintf("<tr class=\"ODBtableEven\"><td colspan=%d><nobr>%s</nobr>", colspan, name);
2856 else
2857 r->rsprintf("<tr class=\"ODBtableOdd\"><td colspan=%d><nobr>%s</nobr>", colspan, name);
2858
2859 for (int j = 0;; j++) {
2860 HNDLE hkey;
2861 db_enum_link(hDB, hkeyvar, j, &hkey);
2862 if (!hkey)
2863 break;
2864
2865 KEY varkey;
2866 db_get_key(hDB, hkey, &varkey);
2867
2868 /* check if "variables" array is shorter than the "names" array */
2869 if (i >= varkey.num_values)
2870 continue;
2871
2872 size = sizeof(data);
2873 db_get_data_index(hDB, hkey, data, &size, i, varkey.type);
2874 std::string data_str = db_sprintf(data, varkey.item_size, 0, varkey.type);
2875
2876 if (is_editable(eq_name, varkey.name)) {
2877 if (n_var == i_set) {
2878 /* set value */
2879 char str[256];
2880 mstrlcpy(str, pp->getparam("value"), sizeof(str));
2881 db_sscanf(str, data, &size, 0, varkey.type);
2882 db_set_data_index(hDB, hkey, data, size, i, varkey.type);
2883
2884 /* redirect (so that 'reload' does not reset value) */
2885 r->reset();
2886 redirect(r, group);
2887 return;
2888 }
2889 if (n_var == i_edit) {
2890 r->rsprintf("<td align=center>");
2891 r->rsprintf("<input type=text size=10 maxlenth=80 name=value value=\"%s\">\n", data_str.c_str());
2892 r->rsprintf("<input type=submit size=20 name=cmd value=Set>\n");
2893 r->rsprintf("<input type=hidden name=index value=%d>\n", i_edit);
2894 n_var++;
2895 } else {
2896 sprintf(odb_path, "Equipment/%s/Variables/%s[%d]", eq_name, varkey.name, i);
2897 r->rsprintf("<td align=center>");
2898 r->rsprintf("<a href=\"#\" onClick=\"ODBInlineEdit(this.parentNode,\'%s\', 0);return false;\" >%s</a>", odb_path, data_str.c_str());
2899 n_var++;
2900 }
2901 } else
2902 r->rsprintf("<td align=center>%s", data_str.c_str());
2903 }
2904
2905 r->rsprintf("</tr>\n");
2906 }
2907 } else {
2908 /*---- multiple name arrays ----*/
2909 r->rsprintf("<tr><td colspan=15><i>Groups:</i> ");
2910
2911 /* "all" group */
2912 if (equal_ustring(group, "All"))
2913 r->rsprintf("<b>All</b> &nbsp;&nbsp;");
2914 else
2915 r->rsprintf("<a href=\"?cmd=eqtable&eq=%s\">All</a> &nbsp;&nbsp;", eq_name);
2916
2917 /* groups from Variables tree */
2918
2919 std::string vars_path = msprintf("/Equipment/%s/Variables", eq_name);
2920 HNDLE hkeyvar;
2921 db_find_key(hDB, 0, vars_path.c_str(), &hkeyvar);
2922
2923 if (hkeyvar) {
2924 for (int i = 0;; i++) {
2925 HNDLE hkey;
2926 db_enum_link(hDB, hkeyvar, i, &hkey);
2927
2928 if (!hkey)
2929 break;
2930
2931 KEY key;
2932 db_get_key(hDB, hkey, &key);
2933
2934 if (equal_ustring(key.name, group)) {
2935 r->rsprintf("<b>%s</b> &nbsp;&nbsp;", key.name);
2936 } else {
2937 r->rsprintf("<a href=\"?cmd=eqtable&eq=%s&group=%s\">%s</a> &nbsp;&nbsp;", urlEncode(eq_name).c_str(), urlEncode(key.name).c_str(), key.name);
2938 }
2939 }
2940 }
2941
2942 r->rsprintf("<i>ODB:</i> &nbsp;&nbsp;");
2943 r->rsprintf("<a href=\"?cmd=odb&odb_path=Equipment/%s/Common\">Common</a> &nbsp;&nbsp;", urlEncode(eq_name).c_str());
2944 r->rsprintf("<a href=\"?cmd=odb&odb_path=Equipment/%s/Settings\">Settings</a> &nbsp;&nbsp;", urlEncode(eq_name).c_str());
2945 r->rsprintf("<a href=\"?cmd=odb&odb_path=Equipment/%s/Variables\">Variables</a> &nbsp;&nbsp;", urlEncode(eq_name).c_str());
2946 r->rsprintf("</tr>\n");
2947
2948 /* enumerate variable arrays */
2949 line = 0;
2950 for (i = 0;; i++) {
2951 HNDLE hkey;
2952 db_enum_link(hDB, hkeyvar, i, &hkey);
2953
2954 if (line % 2 == 0)
2955 mstrlcpy(style, "ODBtableEven", sizeof(style));
2956 else
2957 mstrlcpy(style, "ODBtableOdd", sizeof(style));
2958
2959 if (!hkey)
2960 break;
2961
2962 KEY varkey;
2963 db_get_key(hDB, hkey, &varkey);
2964
2965 if (!equal_ustring(group, "All") && !equal_ustring(varkey.name, group))
2966 continue;
2967
2968 /* title row */
2969 r->rsprintf("<tr class=\"subStatusTitle\"><th colspan=9>Names<th>%s</tr>\n", varkey.name);
2970
2971 if (varkey.type == TID_KEY) {
2972 HNDLE hkeyroot = hkey;
2973
2974 /* enumerate subkeys */
2975 for (j = 0;; j++) {
2976 db_enum_key(hDB, hkeyroot, j, &hkey);
2977 if (!hkey)
2978 break;
2979
2980 KEY key;
2981 db_get_key(hDB, hkey, &key);
2982
2983 if (key.type == TID_KEY) {
2984 /* for keys, don't display data value */
2985 r->rsprintf("<tr class=\"%s\"><td colspan=9>%s<br></tr>\n", style, key.name);
2986 } else {
2987 /* display single value */
2988 if (key.num_values == 1) {
2989 size = sizeof(data);
2990 db_get_data(hDB, hkey, data, &size, key.type);
2991
2992 std::string data_str = db_sprintf(data, key.item_size, 0, key.type);
2993 std::string hex_str = db_sprintfh(data, key.item_size, 0, key.type);
2994
2995 if (data_str.empty() || equal_ustring(data_str.c_str(), "<NULL>")) {
2996 data_str = "(empty)";
2997 hex_str = "";
2998 }
2999
3000 if (strcmp(data_str.c_str(), hex_str.c_str()) != 0 && hex_str[0])
3001 r->rsprintf
3002 ("<tr class=\"%s\" ><td colspan=9>%s<td align=center>%s (%s)<br></tr>\n",
3003 style, key.name, data_str.c_str(), hex_str.c_str());
3004 else
3005 r->rsprintf("<tr class=\"%s\"><td colspan=9>%s<td align=center>%s<br></tr>\n",
3006 style, key.name, data_str.c_str());
3007 line++;
3008 } else {
3009 /* display first value */
3010 r->rsprintf("<tr class=\"%s\"><td colspan=9 rowspan=%d>%s\n", style, key.num_values,
3011 key.name);
3012
3013 for (k = 0; k < key.num_values; k++) {
3014 size = sizeof(data);
3015 db_get_data_index(hDB, hkey, data, &size, k, key.type);
3016 std::string data_str = db_sprintf(data, key.item_size, 0, key.type);
3017 std::string hex_str = db_sprintfh(data, key.item_size, 0, key.type);
3018
3019 if (data_str.empty() || equal_ustring(data_str.c_str(), "<NULL>")) {
3020 data_str = "(empty)";
3021 hex_str = "";
3022 }
3023
3024 if (k > 0)
3025 r->rsprintf("<tr>");
3026
3027 if (strcmp(data_str.c_str(), hex_str.c_str()) != 0 && hex_str[0])
3028 r->rsprintf("<td>[%d] %s (%s)<br></tr>\n", k, data_str.c_str(), hex_str.c_str());
3029 else
3030 r->rsprintf("<td>[%d] %s<br></tr>\n", k, data_str.c_str());
3031 line++;
3032 }
3033 }
3034 }
3035 }
3036 } else {
3037 /* data for current group */
3038 std::string names_path = msprintf("/Equipment/%s/Settings/Names %s", eq_name, varkey.name);
3039 HNDLE hkeyset;
3040 db_find_key(hDB, 0, names_path.c_str(), &hkeyset);
3041 KEY key;
3042 if (hkeyset)
3043 db_get_key(hDB, hkeyset, &key);
3044
3045 if (varkey.num_values > 1000)
3046 r->rsprintf("<tr class=\"%s\"><td colspan=9>%s<td align=center><i>... %d values ...</i>",
3047 style, varkey.name, varkey.num_values);
3048 else {
3049 for (j = 0; j < varkey.num_values; j++) {
3050
3051 if (line % 2 == 0)
3052 mstrlcpy(style, "ODBtableEven", sizeof(style));
3053 else
3054 mstrlcpy(style, "ODBtableOdd", sizeof(style));
3055
3056 char name[NAME_LENGTH+32];
3057 if (hkeyset && j<key.num_values) {
3058 size = sizeof(name);
3059 db_get_data_index(hDB, hkeyset, name, &size, j, TID_STRING);
3060 } else {
3061 sprintf(name, "%s[%d]", varkey.name, j);
3062 }
3063
3064 if (strlen(name) < 1) {
3065 sprintf(name, "%s[%d]", varkey.name, j);
3066 }
3067
3068 r->rsprintf("<tr class=\"%s\"><td colspan=9>%s", style, name);
3069
3070 size = sizeof(data);
3071 db_get_data_index(hDB, hkey, data, &size, j, varkey.type);
3072 std::string data_str = db_sprintf(data, varkey.item_size, 0, varkey.type);
3073
3074 if (is_editable(eq_name, varkey.name)) {
3075 if (n_var == i_set) {
3076 /* set value */
3077 char str[256];
3078 mstrlcpy(str, pp->getparam("value"), sizeof(str));
3079 db_sscanf(str, data, &size, 0, varkey.type);
3080 db_set_data_index(hDB, hkey, data, size, j, varkey.type);
3081
3082 /* redirect (so that 'reload' does not reset value) */
3083 r->reset();
3084 sprintf(str, "%s", group);
3085 redirect(r, str);
3086 return;
3087 }
3088 if (n_var == i_edit) {
3089 r->rsprintf("<td align=center><input type=text size=10 maxlenth=80 name=value value=\"%s\">\n", data_str.c_str());
3090 r->rsprintf("<input type=submit size=20 name=cmd value=Set></tr>\n");
3091 r->rsprintf("<input type=hidden name=index value=%d>\n", i_edit);
3092 r->rsprintf("<input type=hidden name=cmd value=Set>\n");
3093 n_var++;
3094 } else {
3095 sprintf(odb_path, "Equipment/%s/Variables/%s[%d]", eq_name, varkey.name, j);
3096
3097 r->rsprintf("<td align=cernter>");
3098 r->rsprintf("<a href=\"#\" onClick=\"ODBInlineEdit(this.parentNode,\'%s\', 0);return false;\" >%s</a>", odb_path, data_str.c_str());
3099 n_var++;
3100 }
3101
3102 } else
3103 r->rsprintf("<td align=center>%s\n", data_str.c_str());
3104 r->rsprintf("</tr>\n");
3105 line++;
3106 }
3107 }
3108
3109 r->rsprintf("</tr>\n");
3110 }
3111 }
3112 }
3113
3114 r->rsprintf("</table>\n");
3115 r->rsprintf("</div>\n"); // closing for <div id="mmain">
3116 r->rsprintf("</form>\n");
3117 r->rsprintf("</body></html>\r\n");
3118}
BOOL is_editable(char *eq_name, char *var_name)
Definition mhttpd.cxx:2561
#define MAX_GROUPS
Definition mhttpd.cxx:52
void show_navigation_bar(Return *r, const char *cur_page)
Definition mhttpd.cxx:1896
void show_header(Return *r, const char *title, const char *method, const char *path, int refresh)
Definition mhttpd.cxx:1808
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_error()

void show_error ( Return r,
const char *  error 
)

Definition at line 1868 of file mhttpd.cxx.

1869{
1870 /* header */
1871 r->rsprintf("HTTP/1.1 200 Document follows\r\n");
1872 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
1873 r->rsprintf("Content-Type: text/html; charset=%s\r\n\r\n", HTTP_ENCODING);
1874
1875 r->rsprintf("<html><head>\n");
1876 r->rsprintf("<link rel=\"stylesheet\" href=\"mhttpd.css\" type=\"text/css\" />\n");
1877 r->rsprintf("<title>MIDAS error</title></head>\n");
1878 r->rsprintf("<body><H1>%s</H1></body></html>\n", error);
1879}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_error_404()

void show_error_404 ( Return r,
const char *  error 
)

Definition at line 1883 of file mhttpd.cxx.

1884{
1885 /* header */
1886 r->rsprintf("HTTP/1.1 404 Not Found\r\n");
1887 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
1888 r->rsprintf("Content-Type: text/plain\r\n");
1889 r->rsprintf("\r\n");
1890
1891 r->rsprintf("MIDAS error: %s\n", error);
1892}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_find_page()

void show_find_page ( Return r,
const char *  value 
)

Definition at line 7600 of file mhttpd.cxx.

7601{
7602 HNDLE hDB, hkey;
7603
7605
7606 if (value[0] == 0) {
7607 /* without value, show find dialog */
7608 show_header(r, "Find value", "GET", "", 0);
7609
7610 //end header:
7611 r->rsprintf("</table>");
7612
7613 //find dialog:
7614 r->rsprintf("<table class=\"dialogTable\">");
7615
7616 r->rsprintf("<tr><th colspan=2>Find string in Online Database</tr>\n");
7617 r->rsprintf("<tr><td>Enter substring (case insensitive)\n");
7618
7619 r->rsprintf("<td><input type=\"text\" size=\"20\" maxlength=\"80\" name=\"value\">\n");
7620 r->rsprintf("</tr>");
7621
7622 r->rsprintf("<tr><td align=center colspan=2>");
7623 r->rsprintf("<input type=submit name=cmd value=Find>");
7624 r->rsprintf("<input type=submit name=cmd value=Cancel>");
7625 r->rsprintf("</tr>");
7626 r->rsprintf("</table>");
7627
7628 r->rsprintf("<input type=hidden name=cmd value=Find>");
7629
7630 r->rsprintf("</div>\n"); // closing for <div id="mmain">
7631 r->rsprintf("</form>\n");
7632 r->rsprintf("</body></html>\r\n");
7633 } else {
7634 show_header(r, "Search results", "GET", "", 0);
7635
7636 r->rsprintf("<table class=\"mtable\">\n");
7637 r->rsprintf("<tr><th colspan=2 class=\"mtableheader\">");
7638 r->rsprintf("Results of search for substring \"%s\"</tr>\n", value);
7639 r->rsprintf("<tr><th class=\"titlerow\">Key<th>Value</tr>\n");
7640
7641 /* start from root */
7642 db_find_key(hDB, 0, "", &hkey);
7643 assert(hkey);
7644
7645 /* scan tree, call "search_callback" for each key */
7647 data.r = r;
7648 data.search_name = value;
7649
7650 db_scan_tree(hDB, hkey, 0, search_callback, (void *)&data);
7651
7652 r->rsprintf("</table>");
7653 r->rsprintf("</div>\n"); // closing for <div id="mmain">
7654 r->rsprintf("</form>\n");
7655 r->rsprintf("</body></html>\r\n");
7656 }
7657}
INT db_scan_tree(HNDLE hDB, HNDLE hKey, INT level, INT(*callback)(HNDLE, HNDLE, KEY *, INT, void *), void *info)
Definition odb.cxx:4544
INT search_callback(HNDLE hDB, HNDLE hKey, KEY *key, INT level, void *info)
Definition mhttpd.cxx:1491
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_header()

void show_header ( Return r,
const char *  title,
const char *  method,
const char *  path,
int  refresh 
)

Definition at line 1808 of file mhttpd.cxx.

1809{
1810 HNDLE hDB;
1811 time_t now;
1812 char str[256];
1813
1815
1816 /* header */
1817 r->rsprintf("HTTP/1.1 200 Document follows\r\n");
1818 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
1819 r->rsprintf("Cache-control: private, max-age=0, no-cache\r\n");
1820 r->rsprintf("Expires: Fri, 01 Jan 1983 00:00:00 GMT\r\n");
1821 r->rsprintf("Content-Type: text/html; charset=%s\r\n\r\n", HTTP_ENCODING);
1822
1823 r->rsprintf("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n");
1824 r->rsprintf("<html><head>\n");
1825
1826 /* style sheet */
1827 r->rsprintf("<link rel=\"icon\" href=\"favicon.png\" type=\"image/png\" />\n");
1828 r->rsprintf("<link rel=\"stylesheet\" href=\"mhttpd.css\" type=\"text/css\" />\n");
1829 r->rsprintf("<link rel=\"stylesheet\" href=\"midas.css\" type=\"text/css\" />\n");
1830
1831 /* auto refresh */
1832 if (refresh > 0)
1833 r->rsprintf("<meta http-equiv=\"Refresh\" content=\"%02d\">\n", refresh);
1834
1835 r->rsprintf("<title>%s</title></head>\n", title);
1836
1837 mstrlcpy(str, path, sizeof(str));
1838 urlEncode(str, sizeof(str));
1839
1840 if (equal_ustring(method, "POST"))
1841 r->rsprintf
1842 ("<body><form name=\"form1\" method=\"POST\" action=\"%s\" enctype=\"multipart/form-data\">\n\n",
1843 str);
1844 else if (equal_ustring(method, "GET"))
1845 r->rsprintf("<body><form name=\"form1\" method=\"GET\" action=\"%s\">\n\n", str);
1846
1847 /* title row */
1848
1849 std::string exptname;
1850 db_get_value_string(hDB, 0, "/Experiment/Name", 0, &exptname, TRUE);
1851 time(&now);
1852}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_help_page()

void show_help_page ( Return r,
const char *  dec_path 
)

Definition at line 1574 of file mhttpd.cxx.

1575{
1576 const char *s;
1577 char str[256];
1578 int status;
1579
1580 show_header(r, "Help", "", "./", 0);
1581 r->rsprintf("<script type=\"text/javascript\" src=\"midas.js\"></script>\n");
1582 r->rsprintf("<script type=\"text/javascript\" src=\"mhttpd.js\"></script>\n");
1583 show_navigation_bar(r, "Help");
1584
1585 r->rsprintf("<table class=\"mtable\" style=\"width: 95%%\">\n");
1586 r->rsprintf(" <tr>\n");
1587 r->rsprintf(" <td class=\"mtableheader\">MIDAS Help Page</td>\n");
1588 r->rsprintf(" </tr>\n");
1589 r->rsprintf(" <tr>\n");
1590 r->rsprintf(" <td>\n");
1591 r->rsprintf(" <table>\n");
1592
1593 r->rsprintf(" <tr>\n");
1594 r->rsprintf(" <td style=\"text-align:right;\">Documentation:</td>\n");
1595 r->rsprintf(" <td style=\"text-align:left;\"><a href=\"https://midas.triumf.ca\">https://midas.triumf.ca</a></td>\n");
1596 r->rsprintf(" </tr>\n");
1597 r->rsprintf(" <tr>\n");
1598 r->rsprintf(" <td style=\"text-align:right;\">Discussion Forum:</td>\n");
1599 r->rsprintf(" <td style=\"text-align:left;\"><a href=\"https://midas.triumf.ca/forum/\">https://midas.triumf.ca/forum/</a></td>\n");
1600 r->rsprintf(" </tr>\n");
1601 r->rsprintf(" <tr>\n");
1602 r->rsprintf(" <td style=\"text-align:right;\">Code:</td>\n");
1603 r->rsprintf(" <td style=\"text-align:left;\"><a href=\"https://bitbucket.org/tmidas/midas/\">https://bitbucket.org/tmidas/midas/</a></td>\n");
1604 r->rsprintf(" </tr>\n");
1605 r->rsprintf(" <tr>\n");
1606 r->rsprintf(" <td style=\"text-align:right;\">Report a bug:</td>\n");
1607 r->rsprintf(" <td style=\"text-align:left;\"><a href=\"https://bitbucket.org/tmidas/midas/issues/\">https://bitbucket.org/tmidas/midas/issues/</a></td>\n");
1608 r->rsprintf(" </tr>\n");
1609
1610 r->rsprintf(" <tr>\n");
1611 r->rsprintf(" <td style=\"text-align:right;\">Version:</td>\n");
1612 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", cm_get_version());
1613 r->rsprintf(" </tr>\n");
1614 r->rsprintf(" <tr>\n");
1615 r->rsprintf(" <td style=\"text-align:right;\">Revision:</td>\n");
1616 std::string rev = cm_get_revision();
1617 std::string url = "https://bitbucket.org/tmidas/midas/commits/";
1618 // rev format looks like this:
1619 // Fri Nov 24 10:15:54 2017 -0800 - midas-2017-07-c-171-gb8928d5c-dirty on branch develop
1620 // -gXXX is the commit hash
1621 // -dirty should be removed from the hash url, if present
1622 // " " before "on branch" should be removed from the hash url
1623 std::string::size_type pos = rev.find("-g");
1624 if (pos != std::string::npos) {
1625 std::string hash = rev.substr(pos+2);
1626 pos = hash.find("-dirty");
1627 if (pos != std::string::npos) {
1628 hash = hash.substr(0, pos);
1629 }
1630 pos = hash.find(" ");
1631 if (pos != std::string::npos) {
1632 hash = hash.substr(0, pos);
1633 }
1634 url += hash;
1635 r->rsprintf(" <td style=\"text-align:left;\"><a href=\"%s\">%s</a></td>\n", url.c_str(), rev.c_str());
1636 } else {
1637 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", rev.c_str());
1638 }
1639 r->rsprintf(" </tr>\n");
1640
1641 r->rsprintf(" <tr>\n");
1642 r->rsprintf(" <td style=\"text-align:right;\">MIDASSYS:</td>\n");
1643 s = getenv("MIDASSYS");
1644 if (!s) s = "(unset)";
1645 mstrlcpy(str, s, sizeof(str));
1646 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", str);
1647 r->rsprintf(" </tr>\n");
1648
1649 r->rsprintf(" <tr>\n");
1650 r->rsprintf(" <td style=\"text-align:right;\">mhttpd current directory:</td>\n");
1651 std::string cwd = ss_getcwd();
1652 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", cwd.c_str());
1653 r->rsprintf(" </tr>\n");
1654
1655 r->rsprintf(" <tr>\n");
1656 r->rsprintf(" <td style=\"text-align:right;\">Exptab file:</td>\n");
1657 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", cm_get_exptab_filename().c_str());
1658 r->rsprintf(" </tr>\n");
1659
1660 r->rsprintf(" <tr>\n");
1661 r->rsprintf(" <td style=\"text-align:right;\">Experiment:</td>\n");
1662 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", cm_get_experiment_name().c_str());
1663 r->rsprintf(" </tr>\n");
1664
1665 r->rsprintf(" <tr>\n");
1666 r->rsprintf(" <td style=\"text-align:right;\">Experiment directory:</td>\n");
1667 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", cm_get_path().c_str());
1668 r->rsprintf(" </tr>\n");
1669
1672
1673 if (status == CM_SUCCESS) {
1674 if (list.size() == 1) {
1675 r->rsprintf(" <tr>\n");
1676 r->rsprintf(" <td style=\"text-align:right;\">System logfile:</td>\n");
1677 std::string s;
1678 cm_msg_get_logfile("midas", 0, &s, NULL, NULL);
1679 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", s.c_str());
1680 r->rsprintf(" </tr>\n");
1681 } else {
1682 r->rsprintf(" <tr>\n");
1683 r->rsprintf(" <td style=\"text-align:right;\">Logfiles:</td>\n");
1684 r->rsprintf(" <td style=\"text-align:left;\">\n");
1685 for (unsigned i=0 ; i<list.size() ; i++) {
1686 if (i>0)
1687 r->rsputs("<br />\n");
1688 std::string s;
1689 cm_msg_get_logfile(list[i].c_str(), 0, &s, NULL, NULL);
1690 r->rsputs(s.c_str());
1691 }
1692 r->rsprintf("\n </td>\n");
1693 r->rsprintf(" </tr>\n");
1694 }
1695 }
1696
1697 r->rsprintf(" <tr>\n");
1698 r->rsprintf(" <td style=\"text-align:right;\">Image history:</td>\n");
1699 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", cm_get_history_path("IMAGE").c_str());
1700 r->rsprintf(" </tr>\n");
1701
1702 r->rsprintf(" <tr>\n");
1703 r->rsprintf(" <td style=\"text-align:right;\">Resource paths:</td>\n");
1704 r->rsprintf(" <td style=\"text-align:left;\">");
1705 std::vector<std::string> resource_paths = get_resource_paths();
1706 for (unsigned i=0; i<resource_paths.size(); i++) {
1707 if (i>0)
1708 r->rsputs("<br>");
1709 r->rsputs(resource_paths[i].c_str());
1710 std::string exp = cm_expand_env(resource_paths[i].c_str());
1711 //printf("%d %d [%s] [%s]\n", resource_paths[i].length(), exp.length(), resource_paths[i].c_str(), exp.c_str());
1712 if (exp != resource_paths[i]) {
1713 r->rsputs(" (");
1714 r->rsputs(exp.c_str());
1715 r->rsputs(")");
1716 }
1717 }
1718 r->rsprintf(" </td>\n");
1719 r->rsprintf(" </tr>\n");
1720
1721 std::string path;
1722
1723 r->rsprintf(" <tr>\n");
1724 r->rsprintf(" <td style=\"text-align:right;\">midas.css:</td>\n");
1725 if (open_resource_file("midas.css", &path, NULL))
1726 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", path.c_str());
1727 else
1728 r->rsprintf(" <td style=\"text-align:left;\">NOT FOUND</td>\n");
1729 r->rsprintf(" </tr>\n");
1730
1731 r->rsprintf(" <tr>\n");
1732 r->rsprintf(" <td style=\"text-align:right;\">midas.js:</td>\n");
1733 if (open_resource_file("midas.js", &path, NULL))
1734 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", path.c_str());
1735 else
1736 r->rsprintf(" <td style=\"text-align:left;\">NOT FOUND</td>\n");
1737 r->rsprintf(" </tr>\n");
1738
1739 r->rsprintf(" <tr>\n");
1740 r->rsprintf(" <td style=\"text-align:right;\">controls.js:</td>\n");
1741 if (open_resource_file("controls.js", &path, NULL))
1742 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", path.c_str());
1743 else
1744 r->rsprintf(" <td style=\"text-align:left;\">NOT FOUND</td>\n");
1745 r->rsprintf(" </tr>\n");
1746
1747 r->rsprintf(" <tr>\n");
1748 r->rsprintf(" <td style=\"text-align:right;\">mhttpd.js:</td>\n");
1749 if (open_resource_file("mhttpd.js", &path, NULL))
1750 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", path.c_str());
1751 else
1752 r->rsprintf(" <td style=\"text-align:left;\">NOT FOUND</td>\n");
1753 r->rsprintf(" </tr>\n");
1754
1755 r->rsprintf(" <tr>\n");
1756 r->rsprintf(" <td style=\"text-align:right;\">obsolete.js:</td>\n");
1757 if (open_resource_file("obsolete.js", &path, NULL))
1758 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", path.c_str());
1759 else
1760 r->rsprintf(" <td style=\"text-align:left;\">NOT FOUND</td>\n");
1761 r->rsprintf(" </tr>\n");
1762
1763 r->rsprintf(" <tr>\n");
1764 r->rsprintf(" <td style=\"text-align:right;\">Obsolete mhttpd.css:</td>\n");
1765 if (open_resource_file("mhttpd.css", &path, NULL))
1766 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", path.c_str());
1767 else
1768 r->rsprintf(" <td style=\"text-align:left;\">NOT FOUND</td>\n");
1769 r->rsprintf(" </tr>\n");
1770
1771 r->rsprintf(" <tr>\n");
1772 r->rsprintf(" <td style=\"text-align:right;\">JSON-RPC schema:</td>\n");
1773 r->rsprintf(" <td style=\"text-align:left;\"><a href=\"?mjsonrpc_schema\">json format</a> or <a href=\"?mjsonrpc_schema_text\">text table format</a></td>\n");
1774 r->rsprintf(" </tr>\n");
1775
1776 r->rsprintf(" <tr>\n");
1777 r->rsprintf(" <td style=\"text-align:right;\">JavaScript examples:</td>\n");
1778 r->rsprintf(" <td style=\"text-align:left;\"><a href=\"?cmd=example\">example.html</a></td>\n");
1779 r->rsprintf(" </tr>\n");
1780
1781 r->rsprintf(" <tr>\n");
1782 r->rsprintf(" <td style=\"text-align:right;\">Custom page example:</td>\n");
1783 r->rsprintf(" <td style=\"text-align:left;\"><a href=\"?cmd=custom_example\">custom_example.html</a></td>\n");
1784 r->rsprintf(" </tr>\n");
1785
1786 r->rsprintf(" </table>\n");
1787 r->rsprintf(" </td>\n");
1788 r->rsprintf(" </tr>\n");
1789 r->rsprintf("</table>\n");
1790
1791 r->rsprintf("<table class=\"mtable\" style=\"width: 95%%\">\n");
1792 r->rsprintf(" <tr>\n");
1793 r->rsprintf(" <td class=\"mtableheader\">Contributions</td>\n");
1794 r->rsprintf(" </tr>\n");
1795 r->rsprintf(" <tr>\n");
1796 r->rsprintf(" <td>\n");
1797 r->rsprintf("Pierre-Andre&nbsp;Amaudruz - Sergio&nbsp;Ballestrero - Suzannah&nbsp;Daviel - Peter&nbsp;Green - Qing&nbsp;Gu - Greg&nbsp;Hackman - Gertjan&nbsp;Hofman - Paul&nbsp;Knowles - Exaos&nbsp;Lee - Thomas&nbsp;Lindner - Shuoyi&nbsp;Ma - Rudi&nbsp;Meier - Bill&nbsp;Mills - Glenn&nbsp;Moloney - Dave&nbsp;Morris - John&nbsp;M&nbsp;O'Donnell - Konstantin&nbsp;Olchanski - Chris&nbsp;Pearson - Renee&nbsp;Poutissou - Stefan&nbsp;Ritt - Zaher&nbsp;Salman - Ryu&nbsp;Sawada - Tamsen&nbsp;Schurman - Ben&nbsp;Smith - Andreas&nbsp;Suter - Jan&nbsp;M.&nbsp;Wouters - Piotr&nbsp;Adam&nbsp;Zolnierczuk\n");
1798 r->rsprintf(" </td>\n");
1799 r->rsprintf(" </tr>\n");
1800 r->rsprintf("</table>\n");
1801
1802 r->rsprintf("</div></form>\n");
1803 r->rsprintf("</body></html>\r\n");
1804}
std::string cm_get_exptab_filename()
Definition midas.cxx:1804
const char * cm_get_version()
Definition midas.cxx:1492
std::string cm_get_experiment_name()
Definition midas.cxx:1596
INT EXPRT cm_msg_facilities(STRING_LIST *list)
Definition midas.cxx:518
void cm_msg_get_logfile(const char *fac, time_t t, std::string *filename, std::string *linkname, std::string *linktarget)
Definition midas.cxx:553
std::vector< std::string > STRING_LIST
Definition midas.h:246
static te_expr * list(state *s)
Definition tinyexpr.c:567
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_hist_config_page()

void show_hist_config_page ( MVOdb *  odb,
Param p,
Return r,
const char *  hgroup,
const char *  hpanel 
)

Definition at line 10552 of file mhttpd.cxx.

10553{
10554 int status;
10555 int max_display_events = 20;
10556 int max_display_tags = 200;
10557 char str[256], hcmd[256];
10558
10559 odb->RI("History/MaxDisplayEvents", &max_display_events, true);
10560 odb->RI("History/MaxDisplayTags", &max_display_tags, true);
10561
10562 mstrlcpy(hcmd, p->getparam("hcmd"), sizeof(hcmd));
10563
10564 if (equal_ustring(hcmd, "Clear history cache")) {
10565 //printf("clear history cache!\n");
10566 strcpy(hcmd, "Refresh");
10568 if (mh)
10569 mh->hs_clear_cache();
10570 }
10571
10572 //printf("cmd [%s]\n", cmd);
10573 //printf("cmdx [%s]\n", p->getparam("cmdx"));
10574
10575 HistPlot hp;
10576
10577 if (equal_ustring(hcmd, "refresh") || equal_ustring(hcmd, "save")) {
10578 LoadHistPlotFromParam(&hp, p);
10580 } else {
10581 LoadHistPlotFromOdb(odb, &hp, hgroup, hpanel);
10582 }
10583
10584 SortHistPlotVars(hp);
10585
10586 if (strlen(p->getparam("seln")) > 0)
10588
10589 //hp->Print();
10590
10591 if (hcmd[0] && equal_ustring(hcmd, "save")) {
10592 SaveHistPlotToOdb(odb, hp, hgroup, hpanel);
10593
10594 if (p->getparam("redir") && *p->getparam("redir"))
10595 redirect(r, p->getparam("redir"));
10596 else {
10597 sprintf(str, "?cmd=oldhistory&group=%s&panel=%s", hgroup, hpanel);
10598 redirect(r, str);
10599 }
10600 return;
10601 }
10602
10603 show_header(r, "History Config", "GET", "", 0);
10604 r->rsprintf("</table>"); //close header table
10605
10606 r->rsprintf("<table class=\"mtable\">"); //open main table
10607
10608 r->rsprintf("<tr><th colspan=11 class=\"subStatusTitle\">History Panel \"%s\" / \"%s\"</th></tr>\n", hgroup, hpanel);
10609
10610 /* menu buttons */
10611 r->rsprintf("<tr><td colspan=11>\n");
10612
10613 r->rsprintf("<input type=button value=Refresh ");
10614 r->rsprintf("onclick=\"document.form1.hcmd.value='Refresh';document.form1.submit()\">\n");
10615
10616 r->rsprintf("<input type=button value=Save ");
10617 r->rsprintf("onclick=\"document.form1.hcmd.value='Save';document.form1.submit()\">\n");
10618
10619 {
10620 r->rsprintf("<input type=button value=Cancel ");
10621 std::string url = "?cmd=oldhistory&group=";
10622 url += hgroup;
10623 url += "&panel=";
10624 url += hpanel;
10625 url += "&hcmd=Cancel";
10626 if (p->getparam("redir")) {
10627 url += "&redir=";
10628 url += urlEncode(p->getparam("redir"));
10629 }
10630 r->rsprintf("onclick=\"window.location.search='%s'\">\n", url.c_str());
10631 }
10632 {
10633 r->rsprintf("<input type=button value=\"Edit in ODB\"");
10634 std::string url = "?cmd=odb&odb_path=";
10635 url += "/History/Display/";
10636 url += urlEncode(hgroup);
10637 url += "/";
10638 url += urlEncode(hpanel);
10639 r->rsprintf("onclick=\"window.location.search='%s'\">\n", url.c_str());
10640 }
10641 {
10642 r->rsprintf("<input type=button value=\"Edit in new editor\"");
10643 std::string url = "?cmd=hs_edit";
10644 url += "&group=";
10645 url += urlEncode(hgroup);
10646 url += "&panel=";
10647 url += urlEncode(hpanel);
10648 if (p->getparam("redir")) {
10649 url += "&redir=";
10650 url += urlEncode(p->getparam("redir"));
10651 }
10652 r->rsprintf("onclick=\"window.location.search='%s'\">\n", url.c_str());
10653 }
10654 r->rsprintf("<input type=button value=\"Clear history cache\"");
10655 r->rsprintf("onclick=\"document.form1.hcmd.value='Clear history cache';document.form1.submit()\">\n");
10656 r->rsprintf("<input type=button value=\"Delete panel\"");
10657 r->rsprintf("onclick=\"window.location.search='?cmd=oldhistory&group=%s&panel=%s&hcmd=Delete%%20panel'\">\n", hgroup, hpanel);
10658 r->rsprintf("</td></tr>\n");
10659
10660 r->rsprintf("<tr><td colspan=11>\n");
10661
10662 /* sort_vars */
10663 int sort_vars = *p->getparam("sort_vars");
10664 r->rsprintf("<input type=checkbox %s name=sort_vars value=1 onclick=\"this.form.submit();\">Sort variable names", sort_vars?"checked":"");
10665
10666 /* old_vars */
10667 int old_vars = *p->getparam("old_vars");
10668 r->rsprintf("&nbsp;&nbsp;<input type=checkbox %s name=old_vars value=1 onclick=\"this.form.submit();\">Show deleted and renamed variables", old_vars?"checked":"");
10669
10670 if (hp.show_factor)
10671 r->rsprintf("&nbsp;&nbsp;<input type=checkbox checked name=show_factor value=1 onclick=\"document.form1.hcmd.value='Refresh';document.form1.submit()\">");
10672 else
10673 r->rsprintf("&nbsp;&nbsp;<input type=checkbox name=show_factor value=1 onclick=\"document.form1.hcmd.value='Refresh';document.form1.submit()\">");
10674 r->rsprintf("Show&nbsp;factor&nbsp;and&nbsp;offset\n");
10675
10676 /* hidden command for refresh */
10677 r->rsprintf("<input type=hidden name=cmd value=Oldhistory>\n");
10678 r->rsprintf("<input type=hidden name=hcmd value=Refresh>\n");
10679 r->rsprintf("<input type=hidden name=panel value=\"%s\">\n", hpanel);
10680 r->rsprintf("<input type=hidden name=group value=\"%s\">\n", hgroup);
10681
10682 if (p->getparam("redir") && *p->getparam("redir"))
10683 r->rsprintf("<input type=hidden name=redir value=\"%s\">\n", p->getparam("redir"));
10684
10685 r->rsprintf("</td></tr>\n");
10686
10687 r->rsprintf("<tr><td colspan=4 style='text-align:right'>Time scale (in units 'm', 'h', 'd'):</td>\n");
10688 r->rsprintf("<td colspan=3><input type=text size=12 name=timescale value=%s></td><td colspan=4></td></tr>\n", hp.timescale.c_str());
10689
10690 r->rsprintf("<tr><td colspan=4 style='text-align:right'>Minimum (set to '-inf' for autoscale):</td>\n");
10691 r->rsprintf("<td colspan=3><input type=text size=12 name=minimum value=%f></td><td colspan=4></td></tr>\n", hp.minimum);
10692
10693 r->rsprintf("<tr><td colspan=4 style='text-align:right'>Maximum (set to 'inf' for autoscale):</td>\n");
10694 r->rsprintf("<td colspan=3><input type=text size=12 name=maximum value=%f></td><td colspan=4></td></tr>\n", hp.maximum);
10695
10696 r->rsprintf("<tr><td colspan=11>");
10697
10698 if (hp.zero_ylow)
10699 r->rsprintf("<input type=checkbox checked name=zero_ylow value=1>");
10700 else
10701 r->rsprintf("<input type=checkbox name=zero_ylow value=1>");
10702 r->rsprintf("Zero&nbsp;Y;&nbsp;axis\n");
10703
10704 if (hp.log_axis)
10705 r->rsprintf("<input type=checkbox checked name=log_axis value=1>");
10706 else
10707 r->rsprintf("<input type=checkbox name=log_axis value=1>");
10708 r->rsprintf("Logarithmic&nbsp;Y&nbsp;axis\n");
10709
10710 if (hp.show_run_markers)
10711 r->rsprintf("&nbsp;&nbsp;<input type=checkbox checked name=run_markers value=1>");
10712 else
10713 r->rsprintf("&nbsp;&nbsp;<input type=checkbox name=run_markers value=1>");
10714 r->rsprintf("Show&nbsp;run&nbsp;markers\n");
10715
10716 if (hp.show_values)
10717 r->rsprintf("&nbsp;&nbsp;<input type=checkbox checked name=show_values value=1>");
10718 else
10719 r->rsprintf("&nbsp;&nbsp;<input type=checkbox name=show_values value=1>");
10720 r->rsprintf("Show&nbsp;values&nbsp;of&nbsp;variables\n");
10721
10722 if (hp.show_fill)
10723 r->rsprintf("&nbsp;&nbsp;<input type=checkbox checked name=show_fill value=1>");
10724 else
10725 r->rsprintf("&nbsp;&nbsp;<input type=checkbox name=show_fill value=1>");
10726 r->rsprintf("Show&nbsp;graph&nbsp;fill\n");
10727
10728 r->rsprintf("</td></tr>\n");
10729
10730 /*---- events and variables ----*/
10731
10732 /* get display event name */
10733
10735 if (mh == NULL) {
10736 r->rsprintf(str, "History is not configured\n");
10737 return;
10738 }
10739
10740 time_t t = time(NULL);
10741
10742 if (old_vars)
10743 t = 0;
10744
10745 std::vector<std::string> events;
10746
10747 if (!old_vars)
10748 hs_read_event_list(&events);
10749
10750 if (events.size() == 0)
10751 mh->hs_get_events(t, &events);
10752
10753#if 0
10754 for (unsigned i=0; i<events.size(); i++)
10755 printf("event %d: \"%s\"\n", i, events[i].c_str());
10756#endif
10757
10758 // has to be sorted or equipment name code below would not work
10759 //std::sort(events.begin(), events.end(), cmp_events);
10760 std::sort(events.begin(), events.end(), cmp_events1);
10761
10762 if (strlen(p->getparam("cmdx")) > 0) {
10763 r->rsprintf("<tr><th colspan=8 class=\"subStatusTitle\">List of available history variables</th></tr>\n");
10764 r->rsprintf("<tr><th colspan=1>Sel<th colspan=1>Equipment<th colspan=1>Event<th colspan=1>Variable</tr>\n");
10765
10766 std::string cmdx = p->xgetparam("cmdx");
10767 std::string xeqname;
10768
10769 int i=0;
10770 for (unsigned e=0; e<events.size(); e++) {
10771 std::string eqname;
10772 eqname = events[e].substr(0, events[e].find("/"));
10773
10774 if (eqname.length() < 1)
10775 eqname = events[e];
10776
10777 bool once = false;
10778 if (eqname != xeqname)
10779 once = true;
10780
10781 std::string qcmd = "Expand " + eqname;
10782
10783 //printf("param [%s] is [%s]\n", qcmd.c_str(), p->getparam(qcmd.c_str()));
10784
10785 bool collapsed = true;
10786
10787 if (cmdx == qcmd)
10788 collapsed = false;
10789
10790 if (strlen(p->getparam(qcmd.c_str())) > 0)
10791 collapsed = false;
10792
10793 if (collapsed) {
10794 if (eqname == xeqname)
10795 continue;
10796
10797 r->rsprintf("<tr align=left>\n");
10798 r->rsprintf("<td></td>\n");
10799 r->rsprintf("<td>%s</td>\n", eqname.c_str());
10800 r->rsprintf("<td><input type=submit name=cmdx value=\"%s\"></td>\n", qcmd.c_str());
10801 r->rsprintf("<td>%s</td>\n", "");
10802 r->rsprintf("</tr>\n");
10803 xeqname = eqname;
10804 continue;
10805 }
10806
10807 if (once)
10808 r->rsprintf("<tr><input type=hidden name=\"%s\" value=%d></tr>\n", qcmd.c_str(), 1);
10809
10810 std::string rcmd = "Expand " + events[e];
10811
10812 //printf("param [%s] is [%s]\n", rcmd.c_str(), p->getparam(rcmd.c_str()));
10813
10814 collapsed = true;
10815
10816 if (cmdx == rcmd)
10817 collapsed = false;
10818
10819 if (strlen(p->getparam(rcmd.c_str())) > 0)
10820 collapsed = false;
10821
10822 if (collapsed) {
10823 r->rsprintf("<tr align=left>\n");
10824 r->rsprintf("<td></td>\n");
10825 r->rsprintf("<td>%s</td>\n", eqname.c_str());
10826 r->rsprintf("<td>%s</td>\n", events[e].c_str());
10827 r->rsprintf("<td><input type=submit name=cmdx value=\"%s\"></td>\n", rcmd.c_str());
10828 r->rsprintf("</tr>\n");
10829 continue;
10830 }
10831
10832 r->rsprintf("<tr><input type=hidden name=\"%s\" value=%d></tr>\n", rcmd.c_str(), 1);
10833
10834 xeqname = eqname;
10835
10836 std::vector<TAG> tags;
10837
10838 status = mh->hs_get_tags(events[e].c_str(), t, &tags);
10839
10840 if (status == HS_SUCCESS && tags.size() > 0) {
10841
10842 if (sort_vars)
10843 std::sort(tags.begin(), tags.end(), cmp_tags);
10844
10845 for (unsigned v=0; v<tags.size(); v++) {
10846
10847 for (unsigned j=0; j<tags[v].n_data; j++) {
10848 char tagname[256];
10849
10850 if (tags[v].n_data == 1)
10851 sprintf(tagname, "%s", tags[v].name);
10852 else
10853 sprintf(tagname, "%s[%d]", tags[v].name, j);
10854
10855 bool checked = false;
10856#if 0
10857 for (int index=0; index<MAX_VARS; index++) {
10858 if (equal_ustring(vars[index].event_name, events[e].c_str()) && equal_ustring(vars[index].var_name, tagname)) {
10859 checked = true;
10860 break;
10861 }
10862 }
10863#endif
10864
10865 r->rsprintf("<tr align=left>\n");
10866 r->rsprintf("<td><input type=checkbox %s name=\"sel%d\" value=\"%s:%s\"></td>\n", checked?"checked":"", i++, events[e].c_str(), tagname);
10867 r->rsprintf("<td>%s</td>\n", eqname.c_str());
10868 r->rsprintf("<td>%s</td>\n", events[e].c_str());
10869 r->rsprintf("<td>%s</td>\n", tagname);
10870 r->rsprintf("</tr>\n");
10871 }
10872 }
10873 }
10874 }
10875
10876 r->rsprintf("<tr>\n");
10877 r->rsprintf("<td></td>\n");
10878 r->rsprintf("<td>\n");
10879 r->rsprintf("<input type=hidden name=seln value=%d>\n", i);
10880 r->rsprintf("<input type=submit value=\"Add Selected\">\n");
10881 r->rsprintf("</td>\n");
10882 r->rsprintf("</tr>\n");
10883 }
10884
10885 r->rsprintf("<tr><td colspan=11 style='text-align:left'>New history: displayed_value = formula(history_value)</td></tr>\n");
10886 r->rsprintf("<tr><td colspan=11 style='text-align:left'>Old history: displayed_value = offset + factor*(history_value - voffset)</td></tr>\n");
10887 r->rsprintf("<tr><td colspan=11 style='text-align:left'>Formula format: \"3*x+4\", \"10*Math.sin(x)\", etc. all javascript math functions can be used</td></tr>\n");
10888 r->rsprintf("<tr><td colspan=11 style='text-align:left'>To display the raw history value instead of computed formula or offset value, check the \"raw\" checkbox</td></tr>\n");
10889 r->rsprintf("<tr><td colspan=11 style='text-align:left'>To reorder entries: enter new ordering in the \"order\" column and press \"refresh\"</td></tr>\n");
10890 r->rsprintf("<tr><td colspan=11 style='text-align:left'>To delete entries: enter \"-1\" or leave blank the \"order\" column and press \"refresh\"</td></tr>\n");
10891
10892 r->rsprintf("<tr>\n");
10893 r->rsprintf("<th>Col<th>Event<th>Variable<th>Formula<th>Colour<th>Label<th>Raw<th>Order");
10894 if (hp.show_factor) {
10895 r->rsprintf("<th>Factor<th>Offset<th>VOffset");
10896 }
10897 r->rsprintf("</tr>\n");
10898
10899 //print_vars(vars);
10900
10901 size_t nvars = hp.vars.size();
10902 for (size_t index = 0; index <= nvars; index++) {
10903
10904 r->rsprintf("<tr>");
10905
10906 if (index < nvars) {
10907 if (hp.vars[index].colour.empty())
10908 hp.vars[index].colour = NextHistPlotColour(hp);
10909 r->rsprintf("<td style=\"background-color:%s\">&nbsp;<td>\n", hp.vars[index].colour.c_str());
10910 } else {
10911 r->rsprintf("<td>&nbsp;<td>\n");
10912 }
10913
10914 /* event and variable selection */
10915
10916 r->rsprintf("<select name=\"event%d\" size=1 onChange=\"document.form1.submit()\">\n", (int)index);
10917
10918 /* enumerate events */
10919
10920 /* empty option */
10921 r->rsprintf("<option value=\"/empty\">&lt;empty&gt;\n");
10922
10923 if (index==nvars) { // last "empty" entry
10924 for (unsigned e=0; e<events.size(); e++) {
10925 const char *p = events[e].c_str();
10926 r->rsprintf("<option value=\"%s\">%s\n", p, p);
10927 }
10928 } else if ((int)events.size() > max_display_events) { // too many events
10929 r->rsprintf("<option selected value=\"%s\">%s\n", hp.vars[index].event_name.c_str(), hp.vars[index].event_name.c_str());
10930 r->rsprintf("<option>(%d events omitted)\n", (int)events.size());
10931 } else { // show all events
10932 bool found = false;
10933 for (unsigned e=0; e<events.size(); e++) {
10934 const char *s = "";
10935 const char *p = events[e].c_str();
10936 if (equal_ustring(hp.vars[index].event_name.c_str(), p)) {
10937 s = "selected";
10938 found = true;
10939 }
10940 r->rsprintf("<option %s value=\"%s\">%s\n", s, p, p);
10941 }
10942 if (!found) {
10943 const char *p = hp.vars[index].event_name.c_str();
10944 r->rsprintf("<option selected value=\"%s\">%s\n", p, p);
10945 }
10946 }
10947
10948 r->rsprintf("</select></td>\n");
10949
10950 //if (hp.vars[index].order <= 0)
10951 // hp.vars[index].order = (index+1)*10;
10952
10953 if (index < nvars) {
10954 bool found_tag = false;
10955 std::string selected_tag = hp.vars[index].tag_name;
10956
10957 r->rsprintf("<td><select name=\"var%d\">\n", (int)index);
10958
10959 std::vector<TAG> tags;
10960
10961 status = mh->hs_get_tags(hp.vars[index].event_name.c_str(), t, &tags);
10962
10963 if (status == HS_SUCCESS && tags.size() > 0) {
10964
10965 if (/* DISABLES CODE */ (0)) {
10966 printf("Compare %d\n", cmp_names("AAA", "BBB"));
10967 printf("Compare %d\n", cmp_names("BBB", "AAA"));
10968 printf("Compare %d\n", cmp_names("AAA", "AAA"));
10969 printf("Compare %d\n", cmp_names("A", "AAA"));
10970 printf("Compare %d\n", cmp_names("A111", "A1"));
10971 printf("Compare %d\n", cmp_names("A111", "A2"));
10972 printf("Compare %d\n", cmp_names("A111", "A222"));
10973 printf("Compare %d\n", cmp_names("A111a", "A111b"));
10974 }
10975
10976 if (sort_vars)
10977 std::sort(tags.begin(), tags.end(), cmp_tags);
10978
10979 if (/* DISABLES CODE */ (0)) {
10980 printf("Event [%s] %d tags\n", hp.vars[index].event_name.c_str(), (int)tags.size());
10981
10982 for (unsigned v=0; v<tags.size(); v++) {
10983 printf("tag[%d] [%s]\n", v, tags[v].name);
10984 }
10985 }
10986
10987 unsigned count_tags = 0;
10988 for (unsigned v=0; v<tags.size(); v++)
10989 count_tags += tags[v].n_data;
10990
10991 //printf("output %d option tags\n", count_tags);
10992
10993 if ((int)count_tags < max_display_tags) {
10994 for (unsigned v=0; v<tags.size(); v++) {
10995
10996 for (unsigned j=0; j<tags[v].n_data; j++) {
10997 std::string tagname;
10998
10999 if (tags[v].n_data == 1)
11000 tagname = tags[v].name;
11001 else {
11002 char buf[256];
11003 sprintf(buf, "[%d]", j);
11004 tagname = std::string(tags[v].name) + buf;
11005 }
11006
11007 if (equal_ustring(selected_tag.c_str(), tagname.c_str())) {
11008 r->rsprintf("<option selected value=\"%s\">%s\n", tagname.c_str(), tagname.c_str());
11009 found_tag = true;
11010 }
11011 else
11012 r->rsprintf("<option value=\"%s\">%s\n", tagname.c_str(), tagname.c_str());
11013
11014 //printf("%d [%s] [%s] [%s][%s] %d\n", (int)index, vars[index].event_name, tagname, vars[index].var_name, selected_var, found_var);
11015 }
11016 }
11017 }
11018 }
11019
11020 if (!found_tag)
11021 if (hp.vars[index].tag_name.length() > 0)
11022 r->rsprintf("<option selected value=\"%s\">%s\n", hp.vars[index].tag_name.c_str(), hp.vars[index].tag_name.c_str());
11023
11024 r->rsprintf("</select></td>\n");
11025 r->rsprintf("<td><input type=text size=15 maxlength=256 name=\"form%d\" value=%s></td>\n", (int)index, hp.vars[index].formula.c_str());
11026 r->rsprintf("<td><input type=text size=8 maxlength=10 name=\"col%d\" value=%s></td>\n", (int)index, hp.vars[index].colour.c_str());
11027 r->rsprintf("<td><input type=text size=8 maxlength=%d name=\"lab%d\" value=\"%s\"></td>\n", NAME_LENGTH, (int)index, hp.vars[index].label.c_str());
11028 if (hp.vars[index].show_raw_value)
11029 r->rsprintf("<td><input type=checkbox checked name=\"raw%d\" value=1></td>", (int)index);
11030 else
11031 r->rsprintf("<td><input type=checkbox name=\"raw%d\" value=1></td>", (int)index);
11032 r->rsprintf("<td><input type=text size=3 maxlength=32 name=\"ord%d\" value=\"%d\"></td>\n", (int)index, hp.vars[index].order);
11033 if (hp.show_factor) {
11034 r->rsprintf("<td><input type=text size=6 maxlength=32 name=\"factor%d\" value=\"%g\"></td>\n", (int)index, hp.vars[index].factor);
11035 r->rsprintf("<td><input type=text size=6 maxlength=32 name=\"offset%d\" value=\"%g\"></td>\n", (int)index, hp.vars[index].offset);
11036 r->rsprintf("<td><input type=text size=6 maxlength=32 name=\"voffset%d\" value=\"%g\"></td>\n", (int)index, hp.vars[index].voffset);
11037 } else {
11038 r->rsprintf("<input type=hidden name=\"factor%d\" value=\"%f\">\n", (int)index, hp.vars[index].factor);
11039 r->rsprintf("<input type=hidden name=\"offset%d\" value=\"%f\">\n", (int)index, hp.vars[index].offset);
11040 r->rsprintf("<input type=hidden name=\"voffset%d\" value=\"%f\">\n", (int)index, hp.vars[index].voffset);
11041 }
11042 } else {
11043 r->rsprintf("<td colspan=2><input type=submit name=cmdx value=\"List all variables\"></td>\n");
11044 }
11045
11046 r->rsprintf("</tr>\n");
11047 }
11048
11049 r->rsprintf("</table>\n");
11050 //r->rsprintf("</form>\n");
11051 r->rsprintf("</div>\n"); // closing for <div id="mmain">
11052 r->rsprintf("</form>\n");
11053 r->rsprintf("</body></html>\r\n");
11054}
virtual int hs_get_events(time_t time_from, std::vector< std::string > *pevents)=0
get list of events that exist(ed) at given time and later (value 0 means "return all events from begi...
virtual int hs_get_tags(const char *event_name, time_t time_from, std::vector< TAG > *ptags)=0
get list of history variables for given event (use event names returned by hs_get_events()) that exis...
virtual int hs_clear_cache()=0
clear internal cache, returns HS_SUCCESS
int hs_read_event_list(std::vector< std::string > *pevents)
static void SaveHistPlotToOdb(MVOdb *odb, const HistPlot &hp, const char *group, const char *panel)
Definition mhttpd.cxx:10438
static void DeleteHistPlotDeleted(HistPlot &hp)
Definition mhttpd.cxx:10514
static void LoadHistPlotFromParam(HistPlot *hp, Param *p)
Definition mhttpd.cxx:10333
const bool cmp_tags(const TAG &a, const TAG &b)
Definition mhttpd.cxx:10076
const bool cmp_events1(const std::string &a, const std::string &b)
Definition mhttpd.cxx:10071
static void SortHistPlotVars(HistPlot &hp)
Definition mhttpd.cxx:10531
static void AddHistPlotSelectedParam(HistPlot &hp, Param *p)
Definition mhttpd.cxx:10410
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_hist_page()

void show_hist_page ( MVOdb *  odb,
Param p,
Return r,
const char *  dec_path,
char *  buffer,
int *  buffer_size,
int  refresh 
)

Definition at line 11295 of file mhttpd.cxx.

11296{
11297 HNDLE hDB, hkey, hikeyp, hkeyp, hkeybutton;
11298 KEY key, ikey;
11299 int i, j, k, scale, index, width, size, status, labels;
11300 char hgroup[256], hpanel[256], hcmd[256];
11301 const char def_button[][NAME_LENGTH] = { "10m", "1h", "3h", "12h", "24h", "3d", "7d" };
11302
11304
11305 hcmd[0] = hgroup[0] = hpanel[0] = 0;
11306
11307 if (p->getparam("group") && *p->getparam("group"))
11308 mstrlcpy(hgroup, p->getparam("group"), sizeof(hgroup));
11309 if (p->getparam("panel") && *p->getparam("panel"))
11310 mstrlcpy(hpanel, p->getparam("panel"), sizeof(hpanel));
11311 if (p->getparam("hcmd") && *p->getparam("hcmd"))
11312 mstrlcpy(hcmd, p->getparam("hcmd"), sizeof(hcmd));
11313
11314 if (equal_ustring(hcmd, "Reset")) {
11315 std::string redir;
11316 //sprintf(str, "?cmd=oldhistory&group=%s&panel=%s", hgroup, hpanel);
11317 redir += "?cmd=oldhistory&group=";
11318 redir += hgroup;
11319 redir += "&panel=";
11320 redir += hpanel;
11321 redirect(r, redir.c_str());
11322 return;
11323 }
11324
11325 if (equal_ustring(hcmd, "Query")) {
11326 show_query_page(p, r);
11327 return;
11328 }
11329
11330 if (equal_ustring(hcmd, "Cancel")) {
11331 //sprintf(str, "?cmd=oldhistory&group=%s&panel=%s", hgroup, hpanel);
11332 if (p->getparam("redir") && *p->getparam("redir"))
11333 redirect(r, p->getparam("redir"));
11334 else {
11335 std::string redir;
11336 redir += "?cmd=oldhistory&group=";
11337 redir += hgroup;
11338 redir += "&panel=";
11339 redir += hpanel;
11340 redirect(r, redir.c_str());
11341 }
11342 return;
11343 }
11344
11345 if (equal_ustring(hcmd, "Config") ||
11346 equal_ustring(hcmd, "Save")
11347 || equal_ustring(hcmd, "Clear history cache")
11348 || equal_ustring(hcmd, "Refresh")) {
11349
11350 show_hist_config_page(odb, p, r, hgroup, hpanel);
11351 return;
11352 }
11353
11354 if (equal_ustring(hcmd, "New")) {
11355 show_header(r, "History", "GET", "", 0);
11356
11357 r->rsprintf("<table class=\"dialogTable\">");
11358 r->rsprintf("<tr><th class=\"subStatusTitle\" colspan=2>New History Item</th><tr>");
11359 r->rsprintf("<tr><td align=center colspan=2>\n");
11360 r->rsprintf("Select group: &nbsp;&nbsp;");
11361 r->rsprintf("<select id=\"group\" name=\"group\">\n");
11362
11363 /* list existing groups */
11364 db_find_key(hDB, 0, "/History/Display", &hkey);
11365 i = 0;
11366 if (hkey) {
11367 for (i = 0;; i++) {
11368 db_enum_link(hDB, hkey, i, &hkeyp);
11369
11370 if (!hkeyp)
11371 break;
11372
11373 db_get_key(hDB, hkeyp, &key);
11374 if (equal_ustring(hgroup, key.name))
11375 r->rsprintf("<option selected>%s</option>\n", key.name);
11376 else
11377 r->rsprintf("<option>%s</option>\n", key.name);
11378 }
11379 }
11380 if (!hkey || i == 0)
11381 r->rsprintf("<option>Default</option>\n");
11382 r->rsprintf("</select><p>\n");
11383
11384 r->rsprintf("Or enter new group name: &nbsp;&nbsp;");
11385 r->rsprintf("<input type=text size=15 maxlength=31 id=new_group name=new_group>\n");
11386
11387 r->rsprintf("<tr><td align=center colspan=2>\n");
11388 r->rsprintf("<br>Panel name: &nbsp;&nbsp;");
11389 r->rsprintf("<input type=text size=15 maxlength=31 id=panel name=panel><br><br>\n");
11390 r->rsprintf("</td></tr>\n");
11391
11392 r->rsprintf("<tr><td align=center colspan=2>");
11393 std::string str = "?cmd=oldhistory&hcmd=createnew";
11394 str += "&new_group='+document.getElementById('new_group').value+'";
11395 str += "&group='+document.getElementById('group').value+'";
11396 str += "&panel='+document.getElementById('panel').value+'";
11397 r->rsprintf("<input type=button value=Submit onclick=\"window.location.search='%s'\">\n", str.c_str());
11398 r->rsprintf("</td></tr>\n");
11399
11400 r->rsprintf("</table>\r\n");
11401 r->rsprintf("</div>\n"); // closing for <div id="mmain">
11402 r->rsprintf("</form>\n");
11403 r->rsprintf("</body></html>\r\n");
11404 return;
11405 }
11406
11407 if (equal_ustring(hcmd, "Delete Panel")) {
11408 std::string path;
11409 //sprintf(str, "/History/Display/%s/%s", hgroup, hpanel);
11410 path += "/History/Display/";
11411 path += hgroup;
11412 path += "/";
11413 path += hpanel;
11414 db_delete(hDB, 0, path.c_str());
11415 redirect(r, "?cmd=oldhistory");
11416 return;
11417 }
11418
11419 if (equal_ustring(hcmd, "createnew")) {
11420
11421 /* strip leading/trailing spaces */
11422 while (hpanel[0] == ' ') {
11423 char str[256];
11424 mstrlcpy(str, hpanel+1, sizeof(str));
11425 mstrlcpy(hpanel, str, sizeof(hpanel));
11426 }
11427 while (strlen(hpanel)> 1 && hpanel[strlen(hpanel)-1] == ' ')
11428 hpanel[strlen(hpanel)-1] = 0;
11429
11430 /* use new group if present */
11431 if (p->isparam("new_group") && *p->getparam("new_group"))
11432 mstrlcpy(hgroup, p->getparam("new_group"), sizeof(hgroup));
11433
11434 /* configure that panel */
11435 show_hist_config_page(odb, p, r, hgroup, hpanel);
11436 return;
11437 }
11438
11439 const char* pscale = p->getparam("scale");
11440 if (pscale == NULL || *pscale == 0)
11441 pscale = p->getparam("hscale");
11442 const char* pwidth = p->getparam("width");
11443 if (pwidth == NULL || *pwidth == 0)
11444 pwidth = p->getparam("hwidth");
11445 const char* pheight = p->getparam("height");
11446 if (pheight == NULL || *pheight == 0)
11447 pheight = p->getparam("hheight");
11448 const char* pindex = p->getparam("index");
11449 if (pindex == NULL || *pindex == 0)
11450 pindex = p->getparam("hindex");
11451
11452 labels = 1;
11453 if (*p->getparam("labels") && atoi(p->getparam("labels")) == 0)
11454 labels = 0;
11455
11456 std::string bgcolor = "FFFFFF";
11457 if (*p->getparam("bgcolor"))
11458 bgcolor = p->xgetparam("bgcolor");
11459
11460 std::string fgcolor = "000000";
11461 if (*p->getparam("fgcolor"))
11462 fgcolor = p->xgetparam("fgcolor");
11463
11464 std::string gridcolor = "A0A0A0";
11465 if (*p->getparam("gcolor"))
11466 gridcolor = p->xgetparam("gcolor");
11467
11468 /* evaluate scale and offset */
11469
11470 time_t endtime = 0;
11471 if (p->isparam("time"))
11472 endtime = string_to_time(p->getparam("time"));
11473 else if (p->isparam("htime"))
11474 endtime = string_to_time(p->getparam("htime"));
11475
11476 if (pscale && *pscale)
11477 scale = time_to_sec(pscale);
11478 else
11479 scale = 0;
11480
11481 index = -1;
11482 if (pindex && *pindex)
11483 index = atoi(pindex);
11484
11485#ifdef BROKEN
11486 if (equal_ustring(hcmd, "Create ELog")) {
11487 std::string xurl;
11488 status = db_get_value_string(hDB, 0, "/Elog/URL", 0, &xurl, FALSE);
11489 if (status == DB_SUCCESS) {
11490 char url[256];
11491 get_elog_url(url, sizeof(url));
11492
11493 /*---- use external ELOG ----*/
11494 fsize = 100000;
11495 char* fbuffer = (char*)M_MALLOC(fsize);
11496 assert(fbuffer != NULL);
11497
11498 int width = 640;
11499 int height = 400;
11500
11501 if (equal_ustring(pmag, "Large")) {
11502 width = 1024;
11503 height = 768;
11504 } else if (equal_ustring(pmag, "Small")) {
11505 width = 320;
11506 height = 200;
11507 } else if (atoi(pmag) > 0) {
11508 width = atoi(pmag);
11509 height = 200;
11510 }
11511
11512 printf("hereA\n");
11513 generate_hist_graph(odb, r, hgroup, hpanel, fbuffer, &fsize, width, height, endtime, scale, index, labels, bgcolor.c_str(), fgcolor.c_str(), gridcolor.c_str());
11514
11515 /* save temporary file */
11516 std::string dir;
11517 db_get_value_string(hDB, 0, "/Elog/Logbook Dir", 0, &dir, TRUE);
11518 if (dir.length() > 0 && dir[dir.length()-1] != DIR_SEPARATOR)
11519 dir += DIR_SEPARATOR_STR;
11520
11521 time_t now = time(NULL);
11522 localtime_r(&now, &tms);
11523
11524 std::string file_name = msprintf("%02d%02d%02d_%02d%02d%02d_%s.gif",
11525 tms.tm_year % 100, tms.tm_mon + 1, tms.tm_mday,
11526 tms.tm_hour, tms.tm_min, tms.tm_sec, hpanel);
11527 std::string fname = dir + file_name;
11528
11529 /* save attachment */
11530 fh = open(fname.c_str(), O_CREAT | O_RDWR | O_BINARY, 0644);
11531 if (fh < 0) {
11532 cm_msg(MERROR, "show_hist_page", "Cannot write attachment file \"%s\", open() errno %d (%s)", fname.c_str(), errno, strerror(errno));
11533 } else {
11534 int wr = write(fh, fbuffer, fsize);
11535 if (wr != fsize) {
11536 cm_msg(MERROR, "show_hist_page", "Cannot write attachment file \"%s\", write(%d) returned %d, errno %d (%s)", fname.c_str(), fsize, wr, errno, strerror(errno));
11537 }
11538 close(fh);
11539 }
11540
11541 /* redirect to ELOG */
11542 if (strlen(url) > 1 && url[strlen(url)-1] != '/')
11543 mstrlcat(url, "/", sizeof(url));
11544 mstrlcat(url, "?cmd=New&fa=", sizeof(url));
11545 mstrlcat(url, file_name, sizeof(url));
11546 redirect(r, url);
11547
11548 M_FREE(fbuffer);
11549 return;
11550
11551 } else {
11552 /*---- use internal ELOG ----*/
11553 std::string str = msprintf("\\HS\\%s.gif", hpanel);
11554 if (p->getparam("hscale") && *p->getparam("hscale"))
11555 str += msprintf("?scale=%s", p->getparam("hscale"));
11556 if (p->getparam("htime") && *p->getparam("htime")) {
11557 if (strchr(str.c_str(), '?'))
11558 str += "&";
11559 else
11560 str += "?";
11561 str += msprintf("time=%s", p->getparam("htime"));
11562 }
11563 //if (p->getparam("hoffset") && *p->getparam("hoffset")) {
11564 // if (strchr(str, '?'))
11565 // mstrlcat(str, "&", sizeof(str));
11566 // else
11567 // mstrlcat(str, "?", sizeof(str));
11568 // sprintf(str + strlen(str), "offset=%s", p->getparam("hoffset"));
11569 //}
11570 if (p->getparam("hwidth") && *p->getparam("hwidth")) {
11571 if (strchr(str.c_str(), '?'))
11572 str += "&";
11573 else
11574 str += "?";
11575 str += msprintf("width=%s", p->getparam("hwidth"));
11576 }
11577 if (p->getparam("hindex") && *p->getparam("hindex")) {
11578 if (strchr(str.c_str(), '?'))
11579 str += "&";
11580 else
11581 str += "?";
11582 str += msprintf("index=%s", p->getparam("hindex"));
11583 }
11584
11585 show_elog_new(r, hpanel, NULL, FALSE, str.c_str(), "../../EL/");
11586 return;
11587 }
11588 }
11589#endif
11590
11591 if (equal_ustring(hcmd, "Export")) {
11592 export_hist(odb, r, hgroup, hpanel, endtime, scale, index, labels);
11593 return;
11594 }
11595
11596 if (strstr(dec_path, ".gif")) {
11597 int width = 640;
11598 int height = 400;
11599 if (equal_ustring(pwidth, "Large")) {
11600 width = 1024;
11601 height = 768;
11602 } else if (equal_ustring(pwidth, "Small")) {
11603 width = 320;
11604 height = 200;
11605 } else if (atoi(pwidth) > 0) {
11606 width = atoi(pwidth);
11607 if (atoi(pheight) > 0)
11608 height = atoi(pheight);
11609 else
11610 height = (int)(0.625 * width);
11611 }
11612
11613 //printf("dec_path [%s], buf %p, %p, width %d, height %d, endtime %ld, scale %d, index %d, labels %d\n", dec_path, buffer, buffer_size, width, height, endtime, scale, index, labels);
11614
11615 generate_hist_graph(odb, r, hgroup, hpanel, buffer, buffer_size, width, height, endtime, scale, index, labels, bgcolor.c_str(), fgcolor.c_str(), gridcolor.c_str());
11616
11617 return;
11618 }
11619
11620 if (history_mode && index < 0)
11621 return;
11622
11623 time_t now = time(NULL);
11624
11625 /* evaluate offset shift */
11626 if (equal_ustring(p->getparam("shift"), "leftmaxall")) {
11627 if (endtime == 0)
11628 endtime = now;
11629 time_t last_written = 0;
11630 status = get_hist_last_written(odb, hgroup, hpanel, endtime, index, 1, &last_written);
11631 if (status == HS_SUCCESS)
11632 endtime = last_written + scale/2;
11633 }
11634
11635 if (equal_ustring(p->getparam("shift"), "leftmax")) {
11636 if (endtime == 0)
11637 endtime = now;
11638 time_t last_written = 0;
11639 status = get_hist_last_written(odb, hgroup, hpanel, endtime, index, 0, &last_written);
11640 if (status == HS_SUCCESS)
11641 if (last_written != endtime)
11642 endtime = last_written + scale/2;
11643 }
11644
11645 if (equal_ustring(p->getparam("shift"), "left")) {
11646 if (endtime == 0)
11647 endtime = now;
11648 endtime -= scale/2;
11649 //offset -= scale / 2;
11650 }
11651
11652 if (equal_ustring(p->getparam("shift"), "right")) {
11653 if (endtime == 0)
11654 endtime = now;
11655 endtime += scale/2;
11656 if (endtime > now)
11657 endtime = now;
11658 }
11659
11660 if (equal_ustring(p->getparam("shift"), "rightmax")) {
11661 endtime = 0;
11662 }
11663
11664 if (equal_ustring(p->getparam("shift"), "zoomin")) {
11665 if (endtime == 0)
11666 endtime = now;
11667 endtime -= scale / 4;
11668 scale /= 2;
11669 }
11670
11671 if (equal_ustring(p->getparam("shift"), "zoomout")) {
11672 if (endtime == 0)
11673 endtime = now;
11674 endtime += scale / 2;
11675 if (endtime > now)
11676 endtime = now;
11677 scale *= 2;
11678 }
11679
11680 int xrefresh = refresh;
11681 if (endtime != 0)
11682 xrefresh = 0;
11683 show_header(r, hpanel, "GET", "", xrefresh);
11684
11685 r->rsprintf("<script type=\"text/javascript\" src=\"midas.js\"></script>\n");
11686 r->rsprintf("<script type=\"text/javascript\" src=\"mhttpd.js\"></script>\n");
11687 show_navigation_bar(r, "History");
11688
11689 r->rsprintf("<table class=\"mtable\">");
11690 r->rsprintf("<tr><th class=\"mtableheader\" colspan=2>History</th></tr>");
11691
11692 {
11693 /* check if panel exists */
11694 std::string path;
11695 //sprintf(str, "/History/Display/%s/%s", hgroup, hpanel);
11696 path += "/History/Display/";
11697 path += hgroup;
11698 path += "/";
11699 path += hpanel;
11700 status = db_find_key(hDB, 0, path.c_str(), &hkey);
11701 if (status != DB_SUCCESS && !equal_ustring(hpanel, "All") && !equal_ustring(hpanel,"")) {
11702 r->rsprintf("<h1>Error: History panel \"%s\" in group \"%s\" does not exist</h1>\n", hpanel, hgroup);
11703 r->rsprintf("</table>\r\n");
11704 r->rsprintf("</div>\n"); // closing for <div id="mmain">
11705 r->rsprintf("</form>\n");
11706 r->rsprintf("</body></html>\r\n");
11707 return;
11708 }
11709 }
11710
11711 /* define hidden field for parameters */
11712 if (pscale && *pscale)
11713 r->rsprintf("<input type=hidden name=hscale id=hscale value=%d>\n", scale);
11714 else {
11715 /* if no scale and offset given, get it from default */
11716 if (hpanel[0] && !equal_ustring(hpanel, "All") && hgroup[0]) {
11717 std::string path;
11718 path += "/History/Display/";
11719 path += hgroup;
11720 path += "/";
11721 path += hpanel;
11722 path += "/Timescale";
11723
11724 std::string scalestr = "1h";
11725 status = db_get_value_string(hDB, 0, path.c_str(), 0, &scalestr, TRUE);
11726 if (status != DB_SUCCESS) {
11727 /* delete old integer key */
11728 db_delete(hDB, 0, path.c_str());
11729 scalestr = "1h";
11730 db_get_value_string(hDB, 0, path.c_str(), 0, &scalestr, TRUE);
11731 }
11732
11733 r->rsprintf("<input type=hidden name=hscale id=hscale value=%s>\n", scalestr.c_str());
11734 scale = time_to_sec(scalestr.c_str());
11735 }
11736 }
11737
11738 if (endtime != 0)
11739 r->rsprintf("<input type=hidden name=htime id=htime value=%s>\n", time_to_string(endtime).c_str());
11740 if (pwidth && *pwidth)
11741 r->rsprintf("<input type=hidden name=hwidth id=hwidth value=%s>\n", pwidth);
11742 if (pheight && *pheight)
11743 r->rsprintf("<input type=hidden name=hheight id=hheight value=%s>\n", pheight);
11744 if (pindex && *pindex)
11745 r->rsprintf("<input type=hidden name=hindex id=hindex value=%s>\n", pindex);
11746
11747 r->rsprintf("</td></tr>\n");
11748
11749 if (hgroup[0] == 0) {
11750 /* "New" button */
11751 r->rsprintf("<tr><td colspan=2><input type=\"button\" name=\"New\" value=\"New\" ");
11752 r->rsprintf("onClick=\"window.location.href='?cmd=oldhistory&hcmd=New'\"></td></tr>\n");
11753
11754 /* links for history panels */
11755 r->rsprintf("<tr><td colspan=2 style=\"text-align:left;\">\n");
11756 if (!hpanel[0])
11757 r->rsprintf("<b>Please select panel:</b><br>\n");
11758
11759 /* table for panel selection */
11760 r->rsprintf("<table class=\"historyTable\">");
11761
11762 /* "All" link */
11763 r->rsprintf("<tr><td colspan=2 class=\"titleCell\">\n");
11764 if (equal_ustring(hgroup, "All"))
11765 r->rsprintf("All &nbsp;&nbsp;");
11766 else
11767 r->rsprintf("<a href=\"?cmd=oldhistory&group=All\">ALL</a>\n");
11768 r->rsprintf("</td></tr>\n");
11769
11770 /* Setup History table links */
11771 db_find_key(hDB, 0, "/History/Display", &hkey);
11772 if (!hkey) {
11773 /* create default panel */
11774 char str[256];
11775 strcpy(str, "System:Trigger per sec.");
11776 strcpy(str + 2 * NAME_LENGTH, "System:Trigger kB per sec.");
11777 db_set_value(hDB, 0, "/History/Display/Default/Trigger rate/Variables", str, 64, 2, TID_STRING);
11778 strcpy(str, "1h");
11779 db_set_value(hDB, 0, "/History/Display/Default/Trigger rate/Time Scale", str, NAME_LENGTH, 1, TID_STRING);
11780
11781 strcpy(str, "1h");
11782 db_set_value(hDB, 0, "/History/Display/Default/Trigger rate/Timescale", str, NAME_LENGTH, 1, TID_STRING);
11783 i = 1;
11784 db_set_value(hDB, 0, "/History/Display/Default/Trigger rate/Zero ylow", &i, sizeof(BOOL), 1, TID_BOOL);
11785 i = 1;
11786 db_set_value(hDB, 0, "/History/Display/Default/Trigger rate/Show run markers", &i, sizeof(BOOL), 1, TID_BOOL);
11787
11788 strcpy(str, "");
11789 db_set_value(hDB, 0, "/History/Display/Default/Trigger rate/Formula", str, 64, 1, TID_STRING);
11790 db_set_value_index(hDB, 0, "/History/Display/Default/Trigger rate/Formula", str, 64, 1, TID_STRING, FALSE);
11791 }
11792
11793 db_find_key(hDB, 0, "/History/Display", &hkey);
11794 if (hkey) {
11795 for (i = 0;; i++) {
11796 db_enum_link(hDB, hkey, i, &hkeyp);
11797
11798 if (!hkeyp)
11799 break;
11800
11801 // Group key
11802 db_get_key(hDB, hkeyp, &key);
11803
11804 char enc_name[256];
11805 mstrlcpy(enc_name, key.name, sizeof(enc_name));
11806 urlEncode(enc_name, sizeof(enc_name));
11807
11808 if (equal_ustring(hpanel, key.name))
11809 r->rsprintf("<tr><td class=\"titleCell\">%s</td>\n<td>", key.name);
11810 else
11811 r->rsprintf("<tr><td class=\"titleCell\"><a href=\"?cmd=oldhistory&group=%s\">%s</a></td>\n<td>", enc_name, key.name);
11812
11813 for (j = 0;; j++) {
11814 // scan items
11815 db_enum_link(hDB, hkeyp, j, &hikeyp);
11816
11817 if (!hikeyp) {
11818 r->rsprintf("</tr>");
11819 break;
11820 }
11821 // Item key
11822 db_get_key(hDB, hikeyp, &ikey);
11823
11824 char enc_iname[256];
11825 mstrlcpy(enc_iname, ikey.name, sizeof(enc_iname));
11826 urlEncode(enc_iname, sizeof(enc_iname));
11827
11828 if (equal_ustring(hpanel, ikey.name))
11829 r->rsprintf("<small><b>%s</b></small> &nbsp;", ikey.name);
11830 else
11831 r->rsprintf("<small><a href=\"?cmd=oldhistory&group=%s&panel=%s\">%s</a></small> &nbsp;\n", enc_name, enc_iname, ikey.name);
11832 }
11833 }
11834 }
11835
11836 r->rsprintf("</table></tr>\n");
11837
11838 } else {
11839 int found = 0;
11840
11841 /* show drop-down selectors */
11842 r->rsprintf("<tr><td colspan=2>\n");
11843
11844 r->rsprintf("Group:\n");
11845
11846 r->rsprintf("<select title=\"Select group\" id=\"fgroup\" onChange=\"window.location.search='?cmd=oldhistory&group='+document.getElementById('fgroup').value;\">\n");
11847
11848 db_find_key(hDB, 0, "/History/Display", &hkey);
11849 if (hkey) {
11850 hkeyp = 0;
11851 for (i = 0;; i++) {
11852 db_enum_link(hDB, hkey, i, &hikeyp);
11853
11854 if (!hikeyp)
11855 break;
11856
11857 if (i == 0)
11858 hkeyp = hikeyp;
11859
11860 // Group key
11861 db_get_key(hDB, hikeyp, &key);
11862
11863 if (equal_ustring(key.name, hgroup)) {
11864 r->rsprintf("<option selected value=\"%s\">%s\n", key.name, key.name);
11865 hkeyp = hikeyp;
11866 } else
11867 r->rsprintf("<option value=\"%s\">%s\n", key.name, key.name);
11868 }
11869
11870 if (equal_ustring("ALL", hgroup)) {
11871 r->rsprintf("<option selected value=\"%s\">%s\n", "ALL", "ALL");
11872 } else {
11873 r->rsprintf("<option value=\"%s\">%s\n", "ALL", "ALL");
11874 }
11875
11876 r->rsprintf("</select>\n");
11877 r->rsprintf("&nbsp;&nbsp;Panel:\n");
11878 r->rsprintf("<select title=\"Select panel\" id=\"fpanel\" ");
11879 r->rsprintf("onChange=\"window.location.search='?cmd=oldhistory&group='+document.getElementById('fgroup').value+");
11880 r->rsprintf("'&panel='+document.getElementById('fpanel').value;\">\n");
11881
11882 found = 0;
11883 if (hkeyp) {
11884 for (i = 0;; i++) {
11885 // scan panels
11886 db_enum_link(hDB, hkeyp, i, &hikeyp);
11887
11888 if (!hikeyp)
11889 break;
11890
11891 // Item key
11892 db_get_key(hDB, hikeyp, &key);
11893
11894 if (equal_ustring(hpanel, key.name)) {
11895 r->rsprintf("<option selected value=\"%s\">%s\n", key.name, key.name);
11896 found = 1;
11897 } else
11898 r->rsprintf("<option value=\"%s\">%s\n", key.name, key.name);
11899 }
11900 }
11901
11902 if (found)
11903 r->rsprintf("<option value=\"\">- all -\n");
11904 else
11905 r->rsprintf("<option selected value=\"\">- all -\n");
11906
11907 r->rsprintf("</select>\n");
11908 }
11909
11910 r->rsprintf("<noscript>\n");
11911 r->rsprintf("<input type=submit value=\"Go\">\n");
11912 r->rsprintf("</noscript>\n");
11913
11914 r->rsprintf("&nbsp;&nbsp;<input type=\"button\" name=\"New\" value=\"New\" ");
11915 r->rsprintf("onClick=\"window.location.href='?cmd=oldhistory&hcmd=New&group=%s'\">\n", hgroup);
11916
11917 r->rsprintf("<input type=\"button\" name=\"Cmd\" value=\"Reset\" onClick=\"window.location.href='?cmd=oldhistory&hcmd=Reset&group=%s&panel=%s'\">\n", hgroup, hpanel);
11918
11919 r->rsprintf("<input type=\"button\" name=\"Cmd\" value=\"Query\" onClick=\"window.location.href='?cmd=oldhistory&hcmd=Query&group=%s&panel=%s'\">\n", hgroup, hpanel);
11920
11921 double xendtime = endtime;
11922 if (xendtime == 0)
11923 xendtime = now;
11924 double xstarttime = xendtime - scale;
11925
11926 r->rsprintf("<input type=\"button\" name=\"Cmd\" value=\"New history\" onClick=\"window.location.href='?cmd=history&group=%s&panel=%s&A=%.0f&B=%.0f'\">\n", hgroup, hpanel, xstarttime, xendtime);
11927
11928 r->rsprintf("</td></tr>\n");
11929 }
11930
11931 //printf("hgroup [%s] hpanel [%s]\n", hgroup, hpanel);
11932
11933 /* check if whole group should be displayed */
11934 if (hgroup[0] && !equal_ustring(hgroup, "ALL") && hpanel[0] == 0) {
11935 std::string strwidth = "Small";
11936 db_get_value_string(hDB, 0, "/History/Display Settings/Width Group", 0, &strwidth, TRUE);
11937
11938 std::string path;
11939 path += "/History/Display/";
11940 path += hgroup;
11941 db_find_key(hDB, 0, path.c_str(), &hkey);
11942 if (hkey) {
11943 for (i = 0 ;; i++) { // scan group
11944 db_enum_link(hDB, hkey, i, &hikeyp);
11945
11946 if (!hikeyp)
11947 break;
11948
11949 db_get_key(hDB, hikeyp, &key);
11950
11951 char enc_name[256];
11952 mstrlcpy(enc_name, key.name, sizeof(enc_name));
11953 urlEncode(enc_name, sizeof(enc_name));
11954
11955 std::string ref;
11956 ref += "graph.gif?width=";
11957 ref += strwidth;
11958 ref += "&cmd=oldhistory&group=";
11959 ref += hgroup;
11960 ref += "&panel=";
11961 ref += enc_name;
11962
11963 std::string ref2;
11964 ref2 += "?cmd=oldhistory&group=";
11965 ref2 += hgroup;
11966 ref2 += "&panel=";
11967 ref2 += enc_name;
11968
11969 if (endtime != 0) {
11970 char tmp[256];
11971 sprintf(tmp, "time=%s&scale=%d", time_to_string(endtime).c_str(), scale);
11972 ref += "&";
11973 ref += tmp;
11974 ref2 += "?";
11975 ref2 += tmp;
11976 }
11977
11978 if (i % 2 == 0)
11979 r->rsprintf("<tr><td><a href=\"%s\"><img src=\"%s\"></a>\n", ref2.c_str(), ref.c_str());
11980 else
11981 r->rsprintf("<td><a href=\"%s\"><img src=\"%s\"></a></tr>\n", ref2.c_str(), ref.c_str());
11982 }
11983
11984 } else {
11985 r->rsprintf("Group \"%s\" not found", hgroup);
11986 }
11987 }
11988
11989 /* image panel */
11990 else if (hpanel[0] && !equal_ustring(hpanel, "All")) {
11991 /* navigation links */
11992 r->rsprintf("<tr><td>\n");
11993
11994 std::string path;
11995 path += "/History/Display/";
11996 path += hgroup;
11997 path += "/";
11998 path += hpanel;
11999 path += "/Buttons";
12000 db_find_key(hDB, 0, path.c_str(), &hkeybutton);
12001 if (hkeybutton == 0) {
12002 /* create default buttons */
12003 db_create_key(hDB, 0, path.c_str(), TID_STRING);
12004 status = db_find_key(hDB, 0, path.c_str(), &hkeybutton);
12005 if (status != DB_SUCCESS || !hkey) {
12006 cm_msg(MERROR, "show_hist_page", "Cannot create history panel with invalid ODB path \"%s\"", path.c_str());
12007 return;
12008 }
12009 db_set_data(hDB, hkeybutton, def_button, sizeof(def_button), 7, TID_STRING);
12010 }
12011
12012 r->rsprintf("<script>\n");
12013 r->rsprintf("function histDisp(p) {\n");
12014 r->rsprintf(" var params = '?cmd=oldhistory&group=%s&panel=%s';\n", hgroup, hpanel);
12015 r->rsprintf(" params += '&'+p;\n");
12016 r->rsprintf(" if (document.getElementById(\'hscale\') !== null)\n");
12017 r->rsprintf(" params += '&hscale='+document.getElementById(\'hscale\').value;\n");
12018 r->rsprintf(" if (document.getElementById(\'htime\') !== null)\n");
12019 r->rsprintf(" params += '&htime='+document.getElementById(\'htime\').value;\n");
12020 r->rsprintf(" if (document.getElementById(\'hwdith\') !== null)\n");
12021 r->rsprintf(" params += '&hwidth='+document.getElementById(\'hwidth\').value;\n");
12022 r->rsprintf(" if (document.getElementById(\'hindex\') !== null)\n");
12023 r->rsprintf(" params += '&hindex='+document.getElementById(\'hindex\').value;\n");
12024 r->rsprintf(" window.location.search = params;\n");
12025 r->rsprintf("}\n\n");
12026 r->rsprintf("</script>\n");
12027
12028 db_get_key(hDB, hkeybutton, &key);
12029
12030 for (i = 0; i < key.num_values; i++) {
12031 char str[256];
12032 size = sizeof(str);
12033 db_get_data_index(hDB, hkeybutton, str, &size, i, TID_STRING);
12034 r->rsprintf("<input type=\"button\" title=\"display last %s\" value=%s onclick=\"histDisp('scale=%s')\">\n", str, str, str);
12035 }
12036
12037 r->rsprintf("<input type=\"button\" value=\"<<<\" title=\"go back in time to last available data for all variables on the plot\" onclick=\"histDisp('shift=leftmaxall')\">");
12038 r->rsprintf("<input type=\"button\" value=\"<<\" title=\"go back in time to last available data\" onclick=\"histDisp('shift=leftmax')\">");
12039 r->rsprintf("<input type=\"button\" value=\"<\" title=\"go back in time\" onclick=\"histDisp('shift=left')\">");
12040
12041 r->rsprintf("<input type=\"button\" value=\" + \" title=\"zoom in\" onclick=\"histDisp('shift=zoomin')\">");
12042 r->rsprintf("<input type=\"button\" value=\" - \" title=\"zoom out\" onclick=\"histDisp('shift=zoomout')\">");
12043
12044 if (endtime != 0) {
12045 r->rsprintf("<input type=\"button\" value=\">\" title=\"go forward in time\" onclick=\"histDisp('shift=right')\">");
12046 r->rsprintf("<input type=\"button\" value=\">>\" title=\"go to currently updated fresh data\" onclick=\"histDisp('shift=rightmax')\">");
12047 }
12048
12049 r->rsprintf("<td>\n");
12050 r->rsprintf("<input type=\"button\" value=\"Large\" title=\"large display\" onclick=\"histDisp('width=Large')\">\n");
12051 r->rsprintf("<input type=\"button\" value=\"Small\" title=\"large display\" onclick=\"histDisp('width=Small')\">\n");
12052 r->rsprintf("<input type=\"button\" value=\"Create Elog\" title=\"large display\" onclick=\"histDisp('hcmd=Create Elog')\">\n");
12053 r->rsprintf("<input type=\"button\" value=\"Config\" title=\"large display\" onclick=\"histDisp('hcmd=Config')\">\n");
12054 r->rsprintf("<input type=\"button\" value=\"Export\" title=\"large display\" onclick=\"histDisp('hcmd=Export')\">\n");
12055 r->rsprintf("</tr>\n");
12056
12057 char paramstr[256];
12058
12059 paramstr[0] = 0;
12060 sprintf(paramstr + strlen(paramstr), "&scale=%d", scale);
12061 if (endtime != 0)
12062 sprintf(paramstr + strlen(paramstr), "&time=%s", time_to_string(endtime).c_str());
12063 if (pwidth && *pwidth)
12064 sprintf(paramstr + strlen(paramstr), "&width=%s", pwidth);
12065 else {
12066 std::string wi = "640";
12067 db_get_value_string(hDB, 0, "/History/Display Settings/Width Individual", 0, &wi, TRUE);
12068 sprintf(paramstr + strlen(paramstr), "&width=%s", wi.c_str());
12069 }
12070 if (pheight && *pheight)
12071 sprintf(paramstr + strlen(paramstr), "&height=%s", pheight);
12072
12073 /* define image map */
12074 r->rsprintf("<map name=\"%s\">\r\n", hpanel);
12075
12076 if (!(pindex && *pindex)) {
12077 std::string path;
12078 path += "/History/Display/";
12079 path += hgroup;
12080 path += "/";
12081 path += hpanel;
12082 path += "/Variables";
12083 db_find_key(hDB, 0, path.c_str(), &hkey);
12084 if (hkey) {
12085 db_get_key(hDB, hkey, &key);
12086
12087 for (i = 0; i < key.num_values; i++) {
12088 std::string ref;
12089 //if (paramstr[0]) {
12090 // sprintf(ref, "?cmd=oldhistory&group=%s&panel=%s&%s&index=%d", hgroup, hpanel, paramstr, i);
12091 //} else {
12092 // sprintf(ref, "?cmd=oldhistory&group=%s&panel=%s&index=%d", hgroup, hpanel, i);
12093 //}
12094
12095 ref += "?cmd=oldhistory&group=";
12096 ref += hgroup;
12097 ref += "&panel=";
12098 ref += hpanel;
12099 if (paramstr[0]) {
12100 ref += "&";
12101 ref += paramstr;
12102 }
12103 ref += "&index=";
12104 ref += toString(i);
12105
12106 r->rsprintf(" <area shape=rect coords=\"%d,%d,%d,%d\" href=\"%s\">\r\n", 30, 31 + 23 * i, 150, 30 + 23 * i + 17, ref.c_str());
12107 }
12108 }
12109 } else {
12110 std::string ref = "?cmd=oldhistory&group=";
12111 ref += hgroup;
12112 ref += "&panel=";
12113 ref += hpanel;
12114
12115 if (paramstr[0]) {
12116 ref += "&";
12117 ref += paramstr;
12118 }
12119
12120 if (equal_ustring(pwidth, "Large"))
12121 width = 1024;
12122 else if (equal_ustring(pwidth, "Small"))
12123 width = 320;
12124 else if (atoi(pwidth) > 0)
12125 width = atoi(pwidth);
12126 else
12127 width = 640;
12128
12129 r->rsprintf(" <area shape=rect coords=\"%d,%d,%d,%d\" href=\"%s\">\r\n", 0, 0, width, 20, ref.c_str());
12130 }
12131
12132 r->rsprintf("</map>\r\n");
12133
12134 /* Display individual panels */
12135 if (pindex && *pindex)
12136 sprintf(paramstr + strlen(paramstr), "&index=%s", pindex);
12137
12138 std::string ref;
12139 //sprintf(ref, "graph.gif?cmd=oldhistory&group=%s&panel=%s%s", hgroup, hpanel, paramstr);
12140 ref += "graph.gif?cmd=oldhistory&group=";
12141 ref += hgroup;
12142 ref += "&panel=";
12143 ref += hpanel;
12144 ref += paramstr;
12145
12146 /* put reference to graph */
12147 r->rsprintf("<tr><td colspan=2><img src=\"%s\" usemap=\"#%s\"></tr>\n", ref.c_str(), hpanel);
12148 }
12149
12150 else if (equal_ustring(hgroup, "All")) {
12151 /* Display all panels */
12152 db_find_key(hDB, 0, "/History/Display", &hkey);
12153 if (hkey)
12154 for (i = 0, k = 0;; i++) { // scan Groups
12155 db_enum_link(hDB, hkey, i, &hkeyp);
12156
12157 if (!hkeyp)
12158 break;
12159
12160 db_get_key(hDB, hkeyp, &key);
12161
12162 char enc_group_name[256];
12163 mstrlcpy(enc_group_name, key.name, sizeof(enc_group_name));
12164 urlEncode(enc_group_name, sizeof(enc_group_name));
12165
12166 for (j = 0;; j++, k++) {
12167 // scan items
12168 db_enum_link(hDB, hkeyp, j, &hikeyp);
12169
12170 if (!hikeyp)
12171 break;
12172
12173 db_get_key(hDB, hikeyp, &ikey);
12174
12175 char enc_panel_name[256];
12176 mstrlcpy(enc_panel_name, ikey.name, sizeof(enc_panel_name));
12177 urlEncode(enc_panel_name, sizeof(enc_panel_name));
12178
12179 std::string ref;
12180 ref += "graph.gif?width=Small";
12181 ref += "&cmd=oldhistory&group=";
12182 ref += enc_group_name;
12183 ref += "&panel=";
12184 ref += enc_panel_name;
12185
12186 std::string ref2;
12187 ref2 += "?cmd=oldhistory&group=";
12188 ref2 += enc_group_name;
12189 ref2 += "&panel=";
12190 ref2 += enc_panel_name;
12191
12192 if (endtime != 0) {
12193 char tmp[256];
12194 sprintf(tmp, "time=%s&scale=%d", time_to_string(endtime).c_str(), scale);
12195 ref += "&";
12196 ref += tmp;
12197 ref2 += "&";
12198 ref2 += tmp;
12199 }
12200
12201 if (k % 2 == 0)
12202 r->rsprintf("<tr><td><a href=\"%s\"><img src=\"%s\"></a>\n", ref2.c_str(), ref.c_str());
12203 else
12204 r->rsprintf("<td><a href=\"%s\"><img src=\"%s\"></a></tr>\n", ref2.c_str(), ref.c_str());
12205 } // items loop
12206 } // Groups loop
12207 } // All
12208 r->rsprintf("</table>\r\n");
12209 r->rsprintf("</div>\n"); // closing for <div id="mmain">
12210 r->rsprintf("</form>\n");
12211 r->rsprintf("</body></html>\r\n");
12212}
INT db_set_value_index(HNDLE hDB, HNDLE hKeyRoot, const char *key_name, const void *data, INT data_size, INT idx, DWORD type, BOOL trunc)
Definition odb.cxx:5135
void get_elog_url(char *url, int len)
void show_query_page(Param *p, Return *r)
Definition mhttpd.cxx:9824
std::string time_to_string(time_t t)
Definition mhttpd.cxx:8166
int get_hist_last_written(MVOdb *odb, const char *group, const char *panel, time_t endtime, int index, int want_all, time_t *plastwritten)
Definition mhttpd.cxx:8554
time_t string_to_time(const char *str)
Definition mhttpd.cxx:8150
void show_hist_config_page(MVOdb *odb, Param *p, Return *r, const char *hgroup, const char *hpanel)
Definition mhttpd.cxx:10552
void generate_hist_graph(MVOdb *odb, Return *rr, const char *hgroup, const char *hpanel, char *buffer, int *buffer_size, int width, int height, time_t xendtime, int scale, int index, int labels, const char *bgcolor, const char *fgcolor, const char *gridcolor)
Definition mhttpd.cxx:8637
void export_hist(MVOdb *odb, Return *r, const char *group, const char *panel, time_t endtime, int scale, int index, int labels)
Definition mhttpd.cxx:11058
#define M_MALLOC(x)
Definition midas.h:1535
#define M_FREE(x)
Definition midas.h:1537
#define write(n, a, f, d)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_navigation_bar()

void show_navigation_bar ( Return r,
const char *  cur_page 
)

Definition at line 1896 of file mhttpd.cxx.

1897{
1898 r->rsprintf("<script>\n");
1899 r->rsprintf("window.addEventListener(\"load\", function(e) { mhttpd_init('%s', 1000); });\n", cur_page);
1900 r->rsprintf("</script>\n");
1901
1902 r->rsprintf("<!-- header and side navigation will be filled in mhttpd_init -->\n");
1903 r->rsprintf("<div id=\"mheader\"></div>\n");
1904 r->rsprintf("<div id=\"msidenav\"></div>\n");
1905 r->rsprintf("<div id=\"mmain\">\n");
1906}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_odb_page()

void show_odb_page ( Param pp,
Return r,
const char *  dec_path,
int  write_access 
)

Definition at line 6826 of file mhttpd.cxx.

6827{
6828 int keyPresent, size, status, line, link_index;
6829 char colspan;
6830 char style[32];
6831 HNDLE hDB, hkey, hkeyroot;
6832 KEY key;
6833 DWORD delta;
6834
6836
6837 //printf("path [%s]\n", dec_path);
6838
6839 if (strcmp(dec_path, "root") == 0) {
6840 dec_path = "";
6841 }
6842
6843 char xdecpath[256];
6844 mstrlcpy(xdecpath, dec_path, sizeof(xdecpath));
6845 if (strrchr(xdecpath, '/'))
6846 mstrlcpy(xdecpath, strrchr(xdecpath, '/')+1, sizeof(xdecpath));
6847 if (xdecpath[0] == 0)
6848 mstrlcpy(xdecpath, "root", sizeof(xdecpath));
6849 show_header(r, "MIDAS online database", "", xdecpath, 0);
6850
6851 /* use javascript file */
6852 r->rsprintf("<script type=\"text/javascript\" src=\"midas.js\"></script>\n");
6853 r->rsprintf("<script type=\"text/javascript\" src=\"mhttpd.js\"></script>\n");
6854 r->rsprintf("<script type=\"text/javascript\" src=\"obsolete.js\"></script>\n");
6855 r->rsprintf("<script type=\"text/javascript\" src=\"controls.js\"></script>\n");
6856
6857 /* find key via path */
6858 status = db_find_key(hDB, 0, dec_path, &hkeyroot);
6859 if (status != DB_SUCCESS) {
6860 r->rsprintf("Error: cannot find key %s<P>\n", dec_path);
6861 r->rsprintf("</body></html>\r\n");
6862 return;
6863 }
6864
6865 char xdec_path[MAX_ODB_PATH];
6866
6867 /* if key is not of type TID_KEY, cut off key name */
6868 db_get_key(hDB, hkeyroot, &key);
6869 if (key.type != TID_KEY) {
6870 mstrlcpy(xdec_path, dec_path, sizeof(xdec_path));
6871
6872 /* strip variable name from path */
6873 char* p = xdec_path + strlen(xdec_path) - 1;
6874 while (*p && *p != '/')
6875 *p-- = 0;
6876 if (*p == '/')
6877 *p = 0;
6878
6879 status = db_find_key(hDB, 0, xdec_path, &hkeyroot);
6880 if (status != DB_SUCCESS) {
6881 r->rsprintf("Error: cannot find key %s<P>\n", xdec_path);
6882 r->rsprintf("</body></html>\r\n");
6883 return;
6884 }
6885
6886 dec_path = xdec_path;
6887 }
6888
6889 //mstrlcpy(enc_path, dec_path, enc_path_size);
6890 //urlEncode(enc_path, enc_path_size);
6891
6892 std::string odbpath = db_get_path(hDB, hkeyroot);
6893
6894 /*---- navigation bar ----*/
6895
6896 colspan = 7;
6897
6898 if (elog_mode) {
6899 r->rsprintf("<table class=\"mtableheader\">\n");
6900 r->rsprintf("<tr><td colspan=%d>\n", colspan);
6901 r->rsprintf("<input type=button value=ELog onclick=\"self.location=\'?cmd=Alarms\';\">\n");
6902 r->rsprintf("</td></tr></table>\n\n");
6903 } else
6904 show_navigation_bar(r, "ODB");
6905
6906 /*---- begin ODB directory table ----*/
6907
6908 r->rsprintf("<table class=\"mtable\" style=\"border-spacing:0px;\">\n");
6909 r->rsprintf("<tr><th colspan=%d class=\"mtableheader\">Online Database Browser</tr>\n", colspan);
6910 //buttons:
6911 if(!elog_mode){
6912 r->rsprintf("<tr><td colspan=%d>\n", colspan);
6913 r->rsprintf("<input type=button value=Find onclick=\"self.location=\'?cmd=Find\';\">\n");
6914 r->rsprintf("<input type=button value=Create onclick=\"dlgShow('dlgCreate')\">\n");
6915 r->rsprintf("<input type=button value=Link onclick=\"dlgShow('dlgLink')\">\n");
6916 r->rsprintf("<input type=button value=Delete onclick=\"dlgShow('dlgDelete')\">\n");
6917 r->rsprintf("<input type=button value=\"Create Elog from this page\" onclick=\"self.location=\'?cmd=Create Elog from this page&odb_path=%s\';\">\n", urlEncode(odbpath.c_str()).c_str());
6918 r->rsprintf("<input type=button value=\"Show open records\" onclick=\"self.location=\'?cmd=odb_sor&odb_path=%s\';\">\n", urlEncode(odbpath.c_str()).c_str());
6919 r->rsprintf("<input type=button value=\"Show ODB clients\" onclick=\"self.location=\'?cmd=odb_scl\';\">\n");
6920 r->rsprintf("</td></tr>\n");
6921 }
6922
6923 /*---- Build the Delete dialog------------------------------------*/
6924
6925 std::string dd = "";
6926
6927 dd += "<!-- Demo dialog -->\n";
6928 dd += "<div id=\"dlgDelete\" class=\"dlgFrame\">\n";
6929 dd += "<div class=\"dlgTitlebar\">Delete ODB entry</div>\n";
6930 dd += "<div class=\"dlgPanel\">\n";
6931 dd += "<div id=odbpath>";
6932 dd += "\"";
6933 dd += MJsonNode::Encode(odbpath.c_str());
6934 dd += "\"";
6935 dd += "</div>\n";
6936 dd += "<div><br></div>\n";
6937
6938 dd += "<table class=\"dialogTable\">\n";
6939 dd += "<th colspan=2>Delete ODB entries:</th>\n";
6940
6941 std::vector<std::string> delete_list;
6942
6943 int count_delete = 0;
6944
6945 /*---- ODB display -----------------------------------------------*/
6946
6947 /* display root key */
6948 r->rsprintf("<tr><td colspan=%d class='ODBpath'><b>", colspan);
6949 r->rsprintf("<a href=\"?cmd=oldodb\">/</a> \n");
6950
6951 std::string enc_root_path;
6952
6953 /*---- display path ----*/
6954 {
6955 const char* p = dec_path;
6956 while (*p) {
6957 std::string pd;
6958 while (*p && *p != '/')
6959 pd += *p++;
6960
6961 enc_root_path += urlEncode(pd.c_str());
6962
6963 if (pd.length() > 0)
6964 r->rsprintf("<a href=\"?cmd=oldodb&odb_path=%s\">%s</a>\n / ", enc_root_path.c_str(), pd.c_str());
6965
6966 enc_root_path += "/";
6967 if (*p == '/')
6968 p++;
6969 }
6970 }
6971
6972 r->rsprintf("</b></tr>\n");
6973
6974 /* enumerate subkeys */
6975 keyPresent = 0;
6976 for(int scan=0; scan<2; scan++){
6977 if(scan==1 && keyPresent==1) {
6978 r->rsprintf("<tr class=\"titleRow\">\n");
6979 r->rsprintf("<th class=\"ODBkey\">Key</th>\n");
6980 r->rsprintf("<th class=\"ODBvalue\">Value&nbsp;");
6981 r->rsprintf("<script type=\"text/javascript\">\n");
6982 r->rsprintf("function expand()\n");
6983 r->rsprintf("{\n");
6984 r->rsprintf(" var n = document.getElementsByName('ext');\n");
6985 r->rsprintf(" for (i=0 ; i<n.length ; i++) {\n");
6986 r->rsprintf(" if (n[i].style.display == 'none')\n");
6987 r->rsprintf(" n[i].style.display = 'table-cell';\n");
6988 r->rsprintf(" else\n");
6989 r->rsprintf(" n[i].style.display = 'none';\n");
6990 r->rsprintf(" }\n");
6991 r->rsprintf(" if (document.getElementById('expp').expflag === true) {\n");
6992 r->rsprintf(" document.getElementById('expp').expflag = false;\n");
6993 r->rsprintf(" document.getElementById('expp').innerHTML = '&#x21E5;';\n");
6994 r->rsprintf(" } else {\n");
6995 r->rsprintf(" document.getElementById('expp').expflag = true;\n");
6996 r->rsprintf(" document.getElementById('expp').innerHTML = '&#x21E4;';\n");
6997 r->rsprintf(" }\n");
6998 r->rsprintf("}\n");
6999 r->rsprintf("</script>");
7000 r->rsprintf("<div style=\"display:inline;float:right\"><a id=\"expp\"href=\"#\" onClick=\"expand();return false;\">&#x21E5;</div>");
7001 r->rsprintf("</th>\n");
7002 r->rsprintf("<th class=\"ODBvalue\" name=\"ext\" style=\"display:none\">Type</th>\n");
7003 r->rsprintf("<th class=\"ODBvalue\" name=\"ext\" style=\"display:none\">#Val</th>\n");
7004 r->rsprintf("<th class=\"ODBvalue\" name=\"ext\" style=\"display:none\">Size</th>\n");
7005 r->rsprintf("<th class=\"ODBvalue\" name=\"ext\" style=\"display:none\">Written</th>\n");
7006 r->rsprintf("<th class=\"ODBvalue\" name=\"ext\" style=\"display:none\">Mode</th>\n");
7007 r->rsprintf("</tr>\n");
7008 }
7009 line = 0;
7010 for (int i = 0;; i++) {
7011 db_enum_link(hDB, hkeyroot, i, &hkey);
7012 if (!hkey)
7013 break;
7014 db_get_link(hDB, hkey, &key);
7015
7016 if (scan == 0) {
7017 delete_list.push_back(key.name);
7018 }
7019
7020 if (line % 2 == 0)
7021 mstrlcpy(style, "ODBtableEven", sizeof(style));
7022 else
7023 mstrlcpy(style, "ODBtableOdd", sizeof(style));
7024
7025 std::string keyname = key.name;
7026 std::string enc_keyname = urlEncode(key.name);
7027
7028 std::string enc_full_path = enc_root_path + enc_keyname;
7029
7030 std::string odb_path = dec_path;
7031 if (odb_path.length() > 0 && odb_path[odb_path.length() - 1] != '/')
7032 odb_path += "/";
7033 odb_path += key.name;
7034
7035 /* resolve links */
7036 std::string enc_link_ref;
7037 char link_name[MAX_ODB_PATH];
7038 link_name[0] = 0;
7040 if (key.type == TID_LINK) {
7041 size = sizeof(link_name);
7042 db_get_link_data(hDB, hkey, link_name, &size, TID_LINK);
7043
7044 status = db_find_key(hDB, 0, link_name, &hkey);
7045
7046 if (status == DB_SUCCESS)
7047 db_get_key(hDB, hkey, &key);
7048
7049 //sprintf(link_ref, "?cmd=Set&odb_path=%s", full_path);
7050 enc_link_ref = "?cmd=Set&odb_path=";
7051 enc_link_ref += enc_full_path;
7052
7053 if (status == DB_SUCCESS && link_name[0] == 0) {
7054 // fake the case when an empty link somehow resolves
7055 sprintf(link_name, "%s", "(empty)");
7056 }
7057 }
7058
7059 std::string enc_ref;
7060
7061 if (link_name[0]) {
7062 if (enc_root_path.back() == '/' && link_name[0] == '/') {
7063 //sprintf(ref, "?cmd=Set&odb_path=%s%s", root_path, link_name+1);
7064 enc_ref = "";
7065 enc_ref += "?cmd=Set&odb_path=";
7066 enc_ref += enc_root_path;
7067 enc_ref += urlEncode(link_name + 1);
7068 } else {
7069 //sprintf(ref, "?cmd=Set&odb_path=%s%s", root_path, link_name);
7070 enc_ref = "";
7071 enc_ref += "?cmd=Set&odb_path=";
7072 enc_ref += enc_root_path;
7073 enc_ref += urlEncode(link_name);
7074 }
7075 } else {
7076 //sprintf(ref, "?cmd=Set&odb_path=%s", full_path);
7077 enc_ref = "";
7078 enc_ref += "?cmd=Set&odb_path=";
7079 enc_ref += enc_full_path;
7080 }
7081
7082 if (status != DB_SUCCESS) {
7083 if (scan == 1) {
7084 r->rsprintf("<tr><td class=\"yellowLight\">");
7085 r->rsprintf("%s <i>&rarr; <a href=\"%s\">%s</a></i><td><b><div style=\"color:red\">&lt;cannot resolve link&gt;</div></b></tr>\n", keyname.c_str(), enc_link_ref.c_str(), link_name[0]?link_name:"(empty)");
7086 }
7087 } else {
7088
7089 if (key.type == TID_KEY && scan == 0) {
7090 /* for keys, don't display data value */
7091 r->rsprintf("<tr><td colspan=%d class=\"ODBdirectory\"><a href=\"?cmd=oldodb&odb_path=%s\">&#x25B6 %s</a>\n", colspan, enc_full_path.c_str(), keyname.c_str());
7092 if (link_name[0])
7093 r->rsprintf("<i>&rarr; <a href=\"%s\">%s</a></i>", enc_link_ref.c_str(), link_name);
7094 r->rsprintf("</tr>\n");
7095 } else if(key.type != TID_KEY && scan == 1) {
7096
7097 if (strchr(link_name, '['))
7098 link_index = atoi(strchr(link_name, '[')+1);
7099 else
7100 link_index = -1;
7101
7102 /* display single value */
7103 if (key.num_values == 1 || link_index != -1) {
7104 char data[TEXT_SIZE];
7105 size = sizeof(data);
7106 db_get_data(hDB, hkey, data, &size, key.type);
7107
7108 std::string data_str;
7109
7110 if (link_index != -1)
7111 data_str = db_sprintf(data, key.item_size, link_index, key.type);
7112 else
7113 data_str = db_sprintf(data, key.item_size, 0, key.type);
7114
7115 if (key.type == TID_STRING) {
7116 if (size == sizeof(data)) {
7117 data_str += "...(truncated)";
7118 }
7119 }
7120
7121 std::string hex_str;
7122
7123 if (key.type != TID_STRING) {
7124 if (link_index != -1)
7125 hex_str = db_sprintfh(data, key.item_size, link_index, key.type);
7126 else
7127 hex_str = db_sprintfh(data, key.item_size, 0, key.type);
7128 }
7129
7130 if (data_str.empty() || equal_ustring(data_str.c_str(), "<NULL>")) {
7131 data_str = "(empty)";
7132 hex_str = "";
7133 }
7134
7135 r->rsprintf("<tr>\n");
7136 if (strcmp(data_str.c_str(), hex_str.c_str()) != 0 && hex_str[0]) {
7137 if (link_name[0]) {
7138 r->rsprintf("<td class=\"ODBkey\">\n");
7139 r->rsprintf("%s <i>&rarr; ", keyname.c_str());
7140 r->rsprintf("<a href=\"%s\">%s</a></i>\n", enc_link_ref.c_str(), link_name);
7141 r->rsprintf("<td class=\"%s\">\n", style);
7142 if (!write_access)
7143 r->rsprintf("%s (%s)", data_str.c_str(), hex_str.c_str());
7144 else {
7145 r->rsprintf("<a href=\"%s\" onClick=\"ODBInlineEdit(this.parentNode,\'%s\');return false;\" ", enc_ref.c_str(), odb_path.c_str());
7146 r->rsprintf("onFocus=\"ODBInlineEdit(this.parentNode,\'%s\');\">%s (%s)</a>\n", odb_path.c_str(), data_str.c_str(), hex_str.c_str());
7147 }
7148 } else {
7149 r->rsprintf("<td class=\"ODBkey\">\n");
7150 r->rsprintf("%s<td class=\"%s\">", keyname.c_str(), style);
7151 if (!write_access)
7152 r->rsprintf("%s (%s)", data_str.c_str(), hex_str.c_str());
7153 else {
7154 r->rsprintf("<a href=\"%s\" onClick=\"ODBInlineEdit(this.parentNode,\'%s\');return false;\" ", enc_ref.c_str(), odb_path.c_str());
7155 r->rsprintf("onFocus=\"ODBInlineEdit(this.parentNode,\'%s\');\">%s (%s)</a>\n", odb_path.c_str(), data_str.c_str(), hex_str.c_str());
7156 }
7157 }
7158 } else {
7159 if (strchr(data_str.c_str(), '\n')) {
7160 if (link_name[0]) {
7161 r->rsprintf("<td class=\"ODBkey\">");
7162 r->rsprintf("%s <i>&rarr; <a href=\"%s\">%s</a></i><td class=\"ODBvalue\">", keyname.c_str(), enc_link_ref.c_str(), link_name);
7163 } else
7164 r->rsprintf("<td class=\"ODBkey\">%s<td class=\"%s\">", keyname.c_str(), style);
7165 r->rsprintf("\n<pre>");
7166 strencode3(r, data_str.c_str());
7167 r->rsprintf("</pre>");
7168 if (strlen(data) > data_str.length())
7169 r->rsprintf("<i>... (%d bytes total)<p>\n", (int)strlen(data));
7170
7171 r->rsprintf("<a href=\"%s\">Edit</a>\n", enc_ref.c_str());
7172 } else {
7173 if (link_name[0]) {
7174 r->rsprintf("<td class=\"ODBkey\">\n");
7175 r->rsprintf("%s <i>&rarr; <a href=\"%s\">%s</a></i><td class=\"%s\">", keyname.c_str(), enc_link_ref.c_str(), link_name, style);
7176 if (!write_access)
7177 strencode(r, data_str.c_str());
7178 else {
7179 r->rsprintf("<a href=\"%s\" onClick=\"ODBInlineEdit(this.parentNode,\'%s\');return false;\" ", enc_ref.c_str(), odb_path.c_str());
7180 r->rsprintf("onFocus=\"ODBInlineEdit(this.parentNode,\'%s\');\">", odb_path.c_str());
7181 strencode(r, data_str.c_str());
7182 r->rsprintf("</a>\n");
7183 }
7184 } else {
7185 r->rsprintf("<td class=\"ODBkey\">%s<td class=\"%s\">", keyname.c_str(), style);
7186 if (!write_access) {
7187 strencode(r, data_str.c_str());
7188 } else {
7189 r->rsprintf("<a href=\"%s\" onClick=\"ODBInlineEdit(this.parentNode,\'%s\');return false;\" ", enc_ref.c_str(), odb_path.c_str());
7190 r->rsprintf("onFocus=\"ODBInlineEdit(this.parentNode,\'%s\');\">", odb_path.c_str());
7191 strencode(r, data_str.c_str());
7192 r->rsprintf("</a>\n");
7193 }
7194 }
7195 }
7196 }
7197
7198 /* extended key information */
7199 r->rsprintf("<td class=\"ODBkey\" name=\"ext\" style=\"display:none\">");
7200 r->rsprintf("%s", rpc_tid_name(key.type));
7201 r->rsprintf("</td>\n");
7202
7203 r->rsprintf("<td class=\"ODBkey\" name=\"ext\" style=\"display:none\">");
7204 r->rsprintf("%d", key.num_values);
7205 r->rsprintf("</td>\n");
7206
7207 r->rsprintf("<td class=\"ODBkey\" name=\"ext\" style=\"display:none\">");
7208 r->rsprintf("%d", key.item_size);
7209 r->rsprintf("</td>\n");
7210
7211 r->rsprintf("<td class=\"ODBkey\" name=\"ext\" style=\"display:none\">");
7212 db_get_key_time(hDB, hkey, &delta);
7213 if (delta < 60)
7214 r->rsprintf("%ds", delta);
7215 else if (delta < 3600)
7216 r->rsprintf("%1.0lfm", delta / 60.0);
7217 else if (delta < 86400)
7218 r->rsprintf("%1.0lfh", delta / 3600.0);
7219 else if (delta < 86400 * 99)
7220 r->rsprintf("%1.0lfd", delta / 86400.0);
7221 else
7222 r->rsprintf(">99d");
7223 r->rsprintf("</td>\n");
7224
7225 r->rsprintf("<td class=\"ODBkey\" name=\"ext\" style=\"display:none\">");
7227 r->rsprintf("R");
7229 r->rsprintf("W");
7231 r->rsprintf("D");
7233 r->rsprintf("E");
7234 r->rsprintf("</td>\n");
7235
7236 line++;
7237 r->rsprintf("</tr>\n");
7238 } else { /* display array value */
7239 /* check for exceeding length */
7240 if (key.num_values > 1000 && !pp->isparam("all"))
7241 r->rsprintf("<tr><td class=\"ODBkey\">%s<td class=\"%s\"><span style=\"font-style: italic\"><a href=\"?cmd=oldodb&odb_path=%s&all=1\">... %d values ...</a></span>\n", keyname.c_str(), style, enc_full_path.c_str(), key.num_values);
7242 else {
7243 /* display first value */
7244 if (link_name[0])
7245 r->rsprintf("<tr><td class=\"ODBkey\" rowspan=%d>%s<br><i>&rarr; <a href=\"%s\">%s</a></i>\n", key.num_values, keyname.c_str(), enc_link_ref.c_str(), link_name);
7246 else
7247 r->rsprintf("<tr><td class=\"ODBkey\" rowspan=%d>%s\n", key.num_values, keyname.c_str());
7248
7249 for (int j = 0; j < key.num_values; j++) {
7250 if (line % 2 == 0)
7251 mstrlcpy(style, "ODBtableEven", sizeof(style));
7252 else
7253 mstrlcpy(style, "ODBtableOdd", sizeof(style));
7254
7255 char data[TEXT_SIZE];
7256 size = sizeof(data);
7257 db_get_data_index(hDB, hkey, data, &size, j, key.type);
7258 std::string data_str = db_sprintf(data, key.item_size, 0, key.type);
7259
7260 std::string hex_str;
7261 if (key.type == TID_STRING || key.type == TID_LINK) {
7262 hex_str = "";
7263 } else {
7264 hex_str = db_sprintfh(data, key.item_size, 0, key.type);
7265 }
7266
7267 if (key.type == TID_STRING) {
7268 if (size == sizeof(data)) {
7269 data_str += "...(truncated)";
7270 }
7271 }
7272
7273 if (data_str.empty() || equal_ustring(data_str.c_str(), "<NULL>")) {
7274 data_str = "(empty)";
7275 hex_str = "";
7276 }
7277
7278 //sprintf(ref, "?cmd=Set&odb_path=%s&index=%d", full_path, j);
7279 enc_ref = "";
7280 enc_ref += "?cmd=Set&odb_path=";
7281 enc_ref += enc_full_path;
7282 enc_ref += "&index=";
7283 enc_ref += toString(j);
7284
7285 std::string tmpstr;
7286 //sprintf(str, "%s[%d]", odb_path, j);
7287 tmpstr += odb_path;
7288 tmpstr += "[";
7289 tmpstr += toString(j);
7290 tmpstr += "]";
7291
7292 if (j > 0)
7293 r->rsprintf("<tr>");
7294
7295 r->rsprintf("<td class=\"%s\">[%d]&nbsp;", style, j);
7296 if (!write_access)
7297 r->rsprintf("<a href=\"%s\">", enc_ref.c_str());
7298 else {
7299 r->rsprintf("<a href=\"%s\" onClick=\"ODBInlineEdit(this.parentNode,\'%s\');return false;\" ", enc_ref.c_str(), tmpstr.c_str());
7300 r->rsprintf("onFocus=\"ODBInlineEdit(this.parentNode,\'%s\');\">", tmpstr.c_str());
7301 }
7302 if (strcmp(data_str.c_str(), hex_str.c_str()) != 0 && hex_str[0])
7303 r->rsprintf("%s (%s)</a>\n", data_str.c_str(), hex_str.c_str());
7304 else
7305 r->rsprintf("%s</a>\n", data_str.c_str());
7306
7307 if (j == 0) {
7308 /* extended key information */
7309 r->rsprintf("<td class=\"ODBkey\" name=\"ext\" style=\"display:none\" rowspan=%d>", key.num_values);
7310 r->rsprintf("%s", rpc_tid_name(key.type));
7311 r->rsprintf("</td>\n");
7312
7313 r->rsprintf("<td class=\"ODBkey\" name=\"ext\" style=\"display:none\" rowspan=%d>", key.num_values);
7314 r->rsprintf("%d", key.num_values);
7315 r->rsprintf("</td>\n");
7316
7317 r->rsprintf("<td class=\"ODBkey\" name=\"ext\" style=\"display:none\" rowspan=%d>", key.num_values);
7318 r->rsprintf("%d", key.item_size);
7319 r->rsprintf("</td>\n");
7320
7321 r->rsprintf("<td class=\"ODBkey\" name=\"ext\" style=\"display:none\" rowspan=%d>", key.num_values);
7322 db_get_key_time(hDB, hkey, &delta);
7323 if (delta < 60)
7324 r->rsprintf("%ds", delta);
7325 else if (delta < 3600)
7326 r->rsprintf("%1.0lfm", delta / 60.0);
7327 else if (delta < 86400)
7328 r->rsprintf("%1.0lfh", delta / 3600.0);
7329 else if (delta < 86400 * 99)
7330 r->rsprintf("%1.0lfh", delta / 86400.0);
7331 else
7332 r->rsprintf(">99d");
7333 r->rsprintf("</td>\n");
7334
7335 r->rsprintf("<td class=\"ODBkey\" name=\"ext\" style=\"display:none\" rowspan=%d>", key.num_values);
7337 r->rsprintf("R");
7339 r->rsprintf("W");
7341 r->rsprintf("D");
7343 r->rsprintf("E");
7344 r->rsprintf("</td>\n");
7345 }
7346 line++;
7347 }
7348
7349 r->rsprintf("</tr>\n");
7350 }
7351 }
7352 } else if(key.type != TID_KEY){
7353 keyPresent = 1; //flag that we've seen a key on the first pass, and should therefore write the Key / Value headline
7354 }
7355 }
7356 }
7357 }
7358 r->rsprintf("</table>\n");
7359 r->rsprintf("</div>\n"); // <div id="mmain">
7360
7361 /*---- Build the Delete dialog------------------------------------*/
7362
7363 std::sort(delete_list.begin(), delete_list.end());
7364
7365 for (unsigned i=0; i<delete_list.size(); i++) {
7366 std::string name = delete_list[i];
7367
7368 dd += "<tr><td style=\"text-align:left;\" align=left><input align=left type=checkbox id=delete";
7369 dd += toString(count_delete++);
7370 dd += " value=\'";
7371 dd += "\"";
7372 dd += MJsonNode::Encode(name.c_str());
7373 dd += "\"";
7374 dd += "\'>";
7375 dd += name;
7376 dd += "</input></td></tr>\n";
7377 }
7378
7379 dd += "</table>\n";
7380 dd += "<input type=button value=Delete onClick='mhttpd_delete_page_handle_delete(event);'>\n";
7381 dd += "<input type=button value=Cancel onClick='mhttpd_delete_page_handle_cancel(event);'>\n";
7382 dd += "</div>\n";
7383 dd += "</div>\n";
7384
7385 r->rsputs(dd.c_str());
7386
7387 /*---- Build the Create dialog------------------------------------*/
7388
7389 std::string cd = "";
7390
7391 cd += "<!-- Demo dialog -->\n";
7392 cd += "<div id=\"dlgCreate\" class=\"dlgFrame\">\n";
7393 cd += "<div class=\"dlgTitlebar\">Create ODB entry</div>\n";
7394 cd += "<div class=\"dlgPanel\">\n";
7395 cd += "<br />\n";
7396 cd += "<div id=odbpath>";
7397 cd += "\"";
7398 cd += MJsonNode::Encode(odbpath.c_str());
7399 cd += "\"";
7400 cd += "</div>\n";
7401 cd += "<div><br></div>\n";
7402
7403 cd += "<table class=\"dialogTable\">\n";
7404 cd += "<th colspan=2>Create ODB entry:</th>\n";
7405 cd += "<tr>";
7406 cd += "<td>Type";
7407 cd += "<td>";
7408 cd += "<select type=text size=1 id=create_tid name=type>";
7409 cd += "<option value=7>Integer (32-bit)";
7410 cd += "<option value=9>Float (4 Bytes)";
7411 cd += "<option value=12>String";
7412 cd += "<option selected value=15>Subdirectory";
7413 cd += "<option value=1>Byte";
7414 cd += "<option value=2>Signed byte";
7415 cd += "<option value=3>Character (8-bit)";
7416 cd += "<option value=4>Word (16-bit)";
7417 cd += "<option value=5>Short integer (16-bit)";
7418 cd += "<option value=6>Double Word (32-bit)";
7419 cd += "<option value=8>Boolean";
7420 cd += "<option value=10>Double float (8 Bytes)";
7421 //cd += "<option value=16>Symbolic link";
7422 cd += "</select>";
7423 cd += "</tr>\n";
7424 cd += "<tr><td>Name<td><input type=text size=31 maxlength=31 id=create_name name=value></tr>\n";
7425 cd += "<tr><td>Array size<td><input type=text size=31 maxlength=31 id=create_array_length name=index value=1></tr>\n";
7426 cd += "<tr><td>String length<td><input type=text size=31 maxlength=31 id=create_strlen name=strlen value=32></tr>\n";
7427 cd += "</table>\n";
7428 cd += "<input type=button value=Create onClick='mhttpd_create_page_handle_create(event);'>\n";
7429 cd += "<input type=button value=Cancel onClick='mhttpd_create_page_handle_cancel(event);'>\n";
7430 cd += "</div>\n";
7431 cd += "</div>\n";
7432
7433 r->rsputs(cd.c_str());
7434
7435 /*---- Build the Link dialog------------------------------------*/
7436
7437 std::string ld = "";
7438
7439 ld += "<!-- Demo dialog -->\n";
7440 ld += "<div id=\"dlgLink\" class=\"dlgFrame\">\n";
7441 ld += "<div class=\"dlgTitlebar\">Create a link to an ODB entry</div>\n";
7442 ld += "<div class=\"dlgPanel\">\n";
7443 ld += "<br />\n";
7444 ld += "<div id=link_odbpath>";
7445 ld += "\"";
7446 ld += MJsonNode::Encode(odbpath.c_str());
7447 ld += "\"";
7448 ld += "</div>\n";
7449 ld += "<div><br></div>\n";
7450
7451 ld += "<table class=\"dialogTable\">\n";
7452 ld += "<th colspan=2>Create a link to an ODB entry:</th>\n";
7453 ld += "<tr><td>Name<td><input type=text size=31 maxlength=31 id=link_name name=value></tr>\n";
7454 ld += "<tr><td>Link target<td><input type=text size=31 maxlength=256 id=link_target name=target></tr>\n";
7455 ld += "</table>\n";
7456 ld += "<input type=button value=Link onClick='mhttpd_link_page_handle_link(event);'>\n";
7457 ld += "<input type=button value=Cancel onClick='mhttpd_link_page_handle_cancel(event);'>\n";
7458 ld += "</div>\n";
7459 ld += "</div>\n";
7460
7461 r->rsputs(ld.c_str());
7462}
#define MODE_EXCLUSIVE
Definition midas.h:373
#define MODE_DELETE
Definition midas.h:372
#define MODE_WRITE
Definition midas.h:371
#define MODE_READ
Definition midas.h:370
INT db_get_link(HNDLE hDB, HNDLE hKey, KEY *key)
Definition odb.cxx:6096
INT db_get_link_data(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, DWORD type)
Definition odb.cxx:6680
INT db_get_key_time(HNDLE hDB, HNDLE hKey, DWORD *delta)
Definition odb.cxx:6156
void strencode(Return *r, const char *text)
Definition mhttpd.cxx:2049
void strencode3(Return *r, const char *text)
Definition mhttpd.cxx:2108
WORD access_mode
Definition midas.h:1034
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_odb_tag()

void show_odb_tag ( Param pp,
Return r,
const char *  path,
const char *  keypath1,
const char *  format,
int  n_var,
int  edit,
char *  type,
char *  pwd,
char *  tail 
)

Definition at line 3307 of file mhttpd.cxx.

3308{
3309 int size, index, i_edit, i_set;
3310 char data[TEXT_SIZE], full_keypath[256], keypath[256], *p;
3311 HNDLE hDB, hkey;
3312 KEY key;
3313
3314 /* check if variable to edit */
3315 i_edit = -1;
3316 if (equal_ustring(pp->getparam("cmd"), "Edit"))
3317 i_edit = atoi(pp->getparam("index"));
3318
3319 /* check if variable to set */
3320 i_set = -1;
3321 if (equal_ustring(pp->getparam("cmd"), "Set"))
3322 i_set = atoi(pp->getparam("index"));
3323
3324 /* check if path contains index */
3325 mstrlcpy(full_keypath, keypath1, sizeof(full_keypath));
3326 mstrlcpy(keypath, keypath1, sizeof(keypath));
3327 index = 0;
3328
3329 if (strchr(keypath, '[') && strchr(keypath, ']')) {
3330 for (p = strchr(keypath, '[') + 1; *p && *p != ']'; p++)
3331 if (!isdigit(*p))
3332 break;
3333
3334 if (*p && *p == ']') {
3335 index = atoi(strchr(keypath, '[') + 1);
3336 *strchr(keypath, '[') = 0;
3337 }
3338 }
3339
3341 db_find_key(hDB, 0, keypath, &hkey);
3342 if (!hkey)
3343 r->rsprintf("<b>Key \"%s\" not found in ODB</b>\n", keypath);
3344 else {
3345 db_get_key(hDB, hkey, &key);
3346 size = sizeof(data);
3347 db_get_data_index(hDB, hkey, data, &size, index, key.type);
3348
3349 std::string data_str;
3350 if (format && strlen(format)>0)
3351 data_str = db_sprintff(format, data, key.item_size, 0, key.type);
3352 else
3353 data_str= db_sprintf(data, key.item_size, 0, key.type);
3354
3355 if (equal_ustring(type, "checkbox")) {
3356
3357 if (pp->isparam("cbi"))
3358 i_set = atoi(pp->getparam("cbi"));
3359 if (n_var == i_set) {
3360 /* toggle state */
3361 if (key.type == TID_BOOL) {
3362 if (data_str[0] == 'y')
3363 data_str = "n";
3364 else
3365 data_str = "y";
3366 } else {
3367 if (atoi(data_str.c_str()) > 0)
3368 data_str = "0";
3369 else
3370 data_str = "1";
3371 }
3372
3373 db_sscanf(data_str.c_str(), data, &size, 0, key.type);
3374 db_set_data_index(hDB, hkey, data, size, index, key.type);
3375 }
3376
3377 std::string options;
3378 if (data_str[0] == 'y' || atoi(data_str.c_str()) > 0)
3379 options += "checked ";
3380 if (!edit)
3381 options += "disabled ";
3382 else {
3383 if (edit == 1) {
3384 options += "onClick=\"o=document.createElement('input');o.type='hidden';o.name='cbi';o.value='";
3385 options += msprintf("%d", n_var);
3386 options += "';document.form1.appendChild(o);";
3387 options += "document.form1.submit();\" ";
3388 }
3389 }
3390
3391 if (tail[0])
3392 options += tail;
3393
3394 r->rsprintf("<input type=\"checkbox\" %s>\n", options.c_str());
3395
3396 } else { // checkbox
3397
3398 if (edit == 1) {
3399 if (n_var == i_set) {
3400 /* set value */
3401 char str[256];
3402 mstrlcpy(str, pp->getparam("value"), sizeof(str));
3403 db_sscanf(str, data, &size, 0, key.type);
3404 db_set_data_index(hDB, hkey, data, size, index, key.type);
3405
3406 /* read back value */
3407 size = sizeof(data);
3408 db_get_data_index(hDB, hkey, data, &size, index, key.type);
3409 data_str = db_sprintf(data, key.item_size, 0, key.type);
3410 }
3411
3412 if (n_var == i_edit) {
3413 r->rsprintf("<input type=text size=10 maxlength=80 name=value value=\"%s\">\n", data_str.c_str());
3414 r->rsprintf("<input type=submit size=20 name=cmd value=Set>\n");
3415 r->rsprintf("<input type=hidden name=index value=%d>\n", n_var);
3416 r->rsprintf("<input type=hidden name=cmd value=Set>\n");
3417 } else {
3418 if (edit == 2) {
3419 /* edit handling through user supplied JavaScript */
3420 r->rsprintf("<a href=\"#\" %s>", tail);
3421 } else {
3422 /* edit handling through form submission */
3423 if (pwd[0]) {
3424 r->rsprintf("<a onClick=\"promptpwd('%s?cmd=Edit&index=%d&pnam=%s')\" href=\"#\">", path, n_var, pwd);
3425 } else {
3426 r->rsprintf("<a href=\"%s?cmd=Edit&index=%d\" %s>", path, n_var, tail);
3427 }
3428 }
3429
3430 r->rsputs(data_str.c_str());
3431 r->rsprintf("</a>");
3432 }
3433 } else if (edit == 2) {
3434 r->rsprintf("<a href=\"#\" onclick=\"ODBEdit('%s')\">\n", full_keypath);
3435 r->rsputs(data_str.c_str());
3436 r->rsprintf("</a>");
3437 }
3438 else
3439 r->rsputs(data_str.c_str());
3440 }
3441 }
3442}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_password_page()

void show_password_page ( Return r,
const char *  dec_path,
const char *  password 
)

Definition at line 6735 of file mhttpd.cxx.

6736{
6737 r->rsprintf("HTTP/1.1 200 Document follows\r\n");
6738 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
6739 r->rsprintf("Content-Type: text/html; charset=%s\r\n\r\n", HTTP_ENCODING);
6740
6741 r->rsprintf("<html><head>\n");
6742 r->rsprintf("<link rel=\"icon\" href=\"favicon.png\" type=\"image/png\" />\n");
6743 r->rsprintf("<link rel=\"stylesheet\" href=\"midas.css\" type=\"text/css\" />\n");
6744 r->rsprintf("<link rel=\"stylesheet\" href=\"mhttpd.css\" type=\"text/css\" />\n");
6745 r->rsprintf("<title>Enter password</title></head><body>\n\n");
6746
6747 r->rsprintf("<form method=\"GET\" action=\".\">\n\n");
6748
6749 /*---- page header ----*/
6750 r->rsprintf("<table class=\"headerTable\"><tr><td></td><tr></table>\n");
6751
6752 r->rsprintf("<table class=\"dialogTable\">\n"); //main table
6753 if (password[0])
6754 r->rsprintf("<tr><th class=\"redLight\">Wrong password!</tr>\n");
6755
6756 r->rsprintf("<tr><th>Please enter password</tr>\n");
6757 r->rsprintf("<tr><td align=center><input type=password name=pwd></tr>\n");
6758 r->rsprintf("<tr><td align=center><input type=submit value=Submit></tr>");
6759
6760 r->rsprintf("</table>\n");
6761
6762 r->rsprintf("</div>\n"); // closing for <div id="mmain">
6763 r->rsprintf("</form>\n");
6764 r->rsprintf("</body></html>\r\n");
6765}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_query_page()

void show_query_page ( Param p,
Return r 
)

Definition at line 9824 of file mhttpd.cxx.

9825{
9826 int i;
9827 HNDLE hDB;
9828
9829 if (p->getparam("m1") && *p->getparam("m1")) {
9830 struct tm tms;
9831 memset(&tms, 0, sizeof(struct tm));
9832
9833 tms.tm_year = atoi(p->getparam("y1")) % 100;
9834
9835 std::string m1 = p->getparam("m1");
9836 for (i = 0; i < 12; i++)
9837 if (equal_ustring(m1.c_str(), mname[i]))
9838 break;
9839 if (i == 12)
9840 i = 0;
9841
9842 tms.tm_mon = i;
9843 tms.tm_mday = atoi(p->getparam("d1"));
9844 tms.tm_hour = atoi(p->getparam("h1"));
9845
9846 if (tms.tm_year < 90)
9847 tms.tm_year += 100;
9848
9849 time_t ltime_start = mktime_with_dst(&tms);
9850
9851 memset(&tms, 0, sizeof(struct tm));
9852 tms.tm_year = atoi(p->getparam("y2")) % 100;
9853
9854 std::string m2 = p->getparam("m2");
9855 for (i = 0; i < 12; i++)
9856 if (equal_ustring(m2.c_str(), mname[i]))
9857 break;
9858 if (i == 12)
9859 i = 0;
9860
9861 tms.tm_mon = i;
9862 tms.tm_mday = atoi(p->getparam("d2"));
9863 tms.tm_hour = atoi(p->getparam("h2"));
9864
9865 if (tms.tm_year < 90)
9866 tms.tm_year += 100;
9867
9868 time_t ltime_end = mktime_with_dst(&tms);
9869
9870 if (ltime_end == ltime_start)
9871 ltime_end += 3600 * 24;
9872
9873 std::string redir;
9874 redir += "?cmd=oldhistory&";
9875 redir += add_param_to_url("group", p->getparam("group"));
9876 redir += "&";
9877 redir += add_param_to_url("panel", p->getparam("panel"));
9878 redir += "&";
9879 redir += add_param_to_url("scale", toString((int)(ltime_end - ltime_start)).c_str());
9880 redir += "&";
9881 redir += add_param_to_url("time", time_to_string(ltime_end).c_str());
9882 if (p->isparam("hindex")) {
9883 redir += "&";
9884 redir += add_param_to_url("index", p->getparam("hindex"));
9885 }
9886 redirect(r, redir.c_str());
9887 return;
9888 }
9889
9891 show_header(r, "History", "GET", "", 0);
9892
9893 /* set the times */
9894
9895 time_t now = time(NULL);
9896
9897 time_t starttime = now - 3600 * 24;
9898 time_t endtime = now;
9899 bool full_day = true;
9900
9901 if (p->isparam("htime")) {
9902 endtime = string_to_time(p->getparam("htime"));
9903
9904 if (p->isparam("hscale")) {
9905 starttime = endtime - atoi(p->getparam("hscale"));
9906 full_day = false;
9907 } else {
9908 starttime = endtime - 3600 * 24;
9909 full_day = false;
9910 }
9911 }
9912
9913 /* menu buttons */
9914 r->rsprintf("<tr><td colspan=2>\n");
9915 r->rsprintf("<input type=hidden name=cmd value=OldHistory>\n");
9916 r->rsprintf("<input type=submit name=hcmd value=Query>\n");
9917 r->rsprintf("<input type=submit name=hcmd value=Cancel>\n");
9918 if (p->isparam("group"))
9919 r->rsprintf("<input type=hidden name=group value=\"%s\">\n", p->getparam("group"));
9920 if (p->isparam("panel"))
9921 r->rsprintf("<input type=hidden name=panel value=\"%s\">\n", p->getparam("panel"));
9922 if (p->isparam("htime"))
9923 r->rsprintf("<input type=hidden name=htime value=\"%s\">\n", p->getparam("htime"));
9924 if (p->isparam("hscale"))
9925 r->rsprintf("<input type=hidden name=hscale value=\"%s\">\n", p->getparam("hscale"));
9926 if (p->isparam("hindex"))
9927 r->rsprintf("<input type=hidden name=hindex value=\"%s\">\n", p->getparam("hindex"));
9928 r->rsprintf("</tr>\n\n");
9929 r->rsprintf("</table>"); //end header
9930
9931 r->rsprintf("<table class=\"dialogTable\">"); //main table
9932
9933 struct tm tms;
9934 localtime_r(&starttime, &tms);
9935 tms.tm_year += 1900;
9936
9937 r->rsprintf("<tr><td nowrap>Start date:</td>");
9938
9939 r->rsprintf("<td>Month: <select name=\"m1\">\n");
9940 r->rsprintf("<option value=\"\">\n");
9941 for (i = 0; i < 12; i++)
9942 if (i == tms.tm_mon)
9943 r->rsprintf("<option selected value=\"%s\">%s\n", mname[i], mname[i]);
9944 else
9945 r->rsprintf("<option value=\"%s\">%s\n", mname[i], mname[i]);
9946 r->rsprintf("</select>\n");
9947
9948 r->rsprintf("&nbsp;Day: <select name=\"d1\">");
9949 r->rsprintf("<option selected value=\"\">\n");
9950 for (i = 0; i < 31; i++)
9951 if (i + 1 == tms.tm_mday)
9952 r->rsprintf("<option selected value=%d>%d\n", i + 1, i + 1);
9953 else
9954 r->rsprintf("<option value=%d>%d\n", i + 1, i + 1);
9955 r->rsprintf("</select>\n");
9956
9957 int start_hour = tms.tm_hour;
9958 if (full_day)
9959 start_hour = 0;
9960
9961 r->rsprintf("&nbsp;Hour: <input type=\"text\" size=5 maxlength=5 name=\"h1\" value=\"%d\">", start_hour);
9962
9963 r->rsprintf("&nbsp;Year: <input type=\"text\" size=5 maxlength=5 name=\"y1\" value=\"%d\">", tms.tm_year);
9964 r->rsprintf("</td></tr>\n");
9965
9966 r->rsprintf("<tr><td nowrap>End date:</td>");
9967
9968 localtime_r(&endtime, &tms);
9969 tms.tm_year += 1900;
9970
9971 r->rsprintf("<td>Month: <select name=\"m2\">\n");
9972 r->rsprintf("<option value=\"\">\n");
9973 for (i = 0; i < 12; i++)
9974 if (i == tms.tm_mon)
9975 r->rsprintf("<option selected value=\"%s\">%s\n", mname[i], mname[i]);
9976 else
9977 r->rsprintf("<option value=\"%s\">%s\n", mname[i], mname[i]);
9978 r->rsprintf("</select>\n");
9979
9980 r->rsprintf("&nbsp;Day: <select name=\"d2\">");
9981 r->rsprintf("<option selected value=\"\">\n");
9982 for (i = 0; i < 31; i++)
9983 if (i + 1 == tms.tm_mday)
9984 r->rsprintf("<option selected value=%d>%d\n", i + 1, i + 1);
9985 else
9986 r->rsprintf("<option value=%d>%d\n", i + 1, i + 1);
9987 r->rsprintf("</select>\n");
9988
9989 int end_hour = tms.tm_hour;
9990 if (full_day)
9991 end_hour = 24;
9992
9993 r->rsprintf("&nbsp;Hour: <input type=\"text\" size=5 maxlength=5 name=\"h2\" value=\"%d\">", end_hour);
9994
9995 r->rsprintf("&nbsp;Year: <input type=\"text\" size=5 maxlength=5 name=\"y2\" value=\"%d\">", tms.tm_year);
9996 r->rsprintf("</td></tr>\n");
9997
9998 r->rsprintf("</table>\n");
9999 r->rsprintf("</div>\n"); // closing for <div id="mmain">
10000 r->rsprintf("</form>\n");
10001 r->rsprintf("</body></html>\r\n");
10002}
time_t mktime_with_dst(const struct tm *ptms)
Definition mhttpd.cxx:9778
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_set_page()

void show_set_page ( Param pp,
Return r,
const char *  group,
int  index,
const char *  value 
)

Definition at line 7466 of file mhttpd.cxx.

7469{
7470 int status, size;
7471 HNDLE hDB, hkey;
7472 KEY key;
7473 char data[TEXT_SIZE];
7474
7475 std::string odb_path = pp->getparam("odb_path");
7476
7477 //printf("show_set_page: odb_path [%s] group [%s] index %d value [%s]\n", odb_path.c_str(), group, index, value);
7478
7480
7481 /* show set page if no value is given */
7482 if (!pp->isparam("value") && !*pp->getparam("text")) {
7483 status = db_find_link(hDB, 0, odb_path.c_str(), &hkey);
7484 if (status != DB_SUCCESS) {
7485 r->rsprintf("Error: cannot find key %s<P>\n", odb_path.c_str());
7486 return;
7487 }
7488 db_get_link(hDB, hkey, &key);
7489
7490 show_header(r, "Set value", "POST", "", 0);
7491 //close header:
7492 r->rsprintf("</table>");
7493
7494 //main table:
7495 r->rsprintf("<table class=\"dialogTable\">");
7496
7497 if (index > 0)
7498 r->rsprintf("<input type=hidden name=index value=\"%d\">\n", index);
7499 else
7500 index = 0;
7501
7502 if (group[0])
7503 r->rsprintf("<input type=hidden name=group value=\"%s\">\n", group);
7504
7505 r->rsprintf("<input type=hidden name=odb_path value=\"%s\">\n", odb_path.c_str());
7506
7507 std::string data_str1 = rpc_tid_name(key.type);
7508 std::string str1;
7509 if (key.num_values > 1) {
7510 data_str1 += msprintf("[%d]", key.num_values);
7511 str1 = msprintf("%s[%d]", odb_path.c_str(), index);
7512 } else
7513 str1 = odb_path.c_str();
7514
7515 r->rsprintf("<tr><th colspan=2>Set new value - type = %s</tr>\n", data_str1.c_str());
7516 r->rsprintf("<tr><td>%s<td>\n", str1.c_str());
7517
7518 /* set current value as default */
7519 size = sizeof(data);
7520 db_get_link_data(hDB, hkey, data, &size, key.type);
7521 std::string data_str = db_sprintf(data, key.item_size, index, key.type);
7522
7523 if (equal_ustring(data_str.c_str(), "<NULL>"))
7524 data_str = "";
7525
7526 if (strchr(data_str.c_str(), '\n') != NULL) {
7527 r->rsprintf("<textarea rows=20 cols=80 name=\"text\">\n");
7528 strencode3(r, data);
7529 r->rsprintf("</textarea>\n");
7530 } else {
7531 size = 20;
7532 if ((int) data_str.length() > size)
7533 size = data_str.length() + 3;
7534 if (size > 80)
7535 size = 80;
7536
7537 r->rsprintf("<input type=\"text\" size=%d maxlength=256 name=\"value\" value=\"", size);
7538 strencode(r, data_str.c_str());
7539 r->rsprintf("\">\n");
7540 }
7541
7542 r->rsprintf("</tr>\n");
7543
7544 r->rsprintf("<tr><td align=center colspan=2>");
7545 r->rsprintf("<input type=submit name=cmd value=Set>");
7546 r->rsprintf("<input type=submit name=cmd value=Cancel>");
7547 r->rsprintf("</tr>");
7548 r->rsprintf("</table>");
7549
7550 r->rsprintf("<input type=hidden name=cmd value=Set>\n");
7551
7552 r->rsprintf("</div>\n"); // closing for <div id="mmain">
7553 r->rsprintf("</form>\n");
7554 r->rsprintf("</body></html>\r\n");
7555 return;
7556 } else {
7557 /* set value */
7558
7559 status = db_find_link(hDB, 0, odb_path.c_str(), &hkey);
7560 if (status != DB_SUCCESS) {
7561 r->rsprintf("Error: cannot find key %s<P>\n", odb_path.c_str());
7562 return;
7563 }
7564 db_get_link(hDB, hkey, &key);
7565
7566 memset(data, 0, sizeof(data));
7567
7568 if (pp->getparam("text") && *pp->getparam("text"))
7569 mstrlcpy(data, pp->getparam("text"), sizeof(data));
7570 else
7571 db_sscanf(value, data, &size, 0, key.type);
7572
7573 if (index < 0)
7574 index = 0;
7575
7576 /* extend data size for single string if necessary */
7577 if ((key.type == TID_STRING || key.type == TID_LINK)
7578 && (int) strlen(data) + 1 > key.item_size && key.num_values == 1)
7579 key.item_size = strlen(data) + 1;
7580
7581 if (key.item_size == 0)
7583
7584 if (key.num_values > 1)
7586 else
7588
7589 if (status == DB_NO_ACCESS)
7590 r->rsprintf("<h2>Write access not allowed</h2>\n");
7591
7592 redirect(r, "");
7593
7594 return;
7595 }
7596}
INT db_set_link_data(HNDLE hDB, HNDLE hKey, const void *data, INT buf_size, INT num_values, DWORD type)
Definition odb.cxx:7449
INT db_set_link_data_index(HNDLE hDB, HNDLE hKey, const void *data, INT data_size, INT idx, DWORD type)
Definition odb.cxx:7773
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_text_header()

void show_text_header ( Return r)

Definition at line 1856 of file mhttpd.cxx.

1857{
1858 r->rsprintf("HTTP/1.1 200 Document follows\r\n");
1859 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
1860 r->rsprintf("Access-Control-Allow-Origin: *\r\n");
1861 r->rsprintf("Cache-control: private, max-age=0, no-cache\r\n");
1862 r->rsprintf("Expires: Fri, 01 Jan 1983 00:00:00 GMT\r\n");
1863 r->rsprintf("Content-Type: text/plain; charset=%s\r\n\r\n", HTTP_ENCODING);
1864}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ SortHistPlotVars()

static void SortHistPlotVars ( HistPlot hp)
static

Definition at line 10531 of file mhttpd.cxx.

10532{
10533 /* sort variables according to "hist_order" */
10534
10535 bool need_sort = false;
10536 for (size_t i=1; i<hp.vars.size(); i++) {
10537 if (hp.vars[i-1].order >= hp.vars[i].order) {
10538 need_sort = true;
10539 }
10540 }
10541
10542 if (need_sort) {
10543 /* sort variables by order */
10544 std::sort(hp.vars.begin(), hp.vars.end(), cmp_vars);
10545
10546 /* renumber the variables according to the new sorted order */
10547 for (size_t index=0; index<hp.vars.size(); index++)
10548 hp.vars[index].order = (index+1)*10;
10549 }
10550}
static bool cmp_vars(const HistVar &a, const HistVar &b)
Definition mhttpd.cxx:10134
Here is the call graph for this function:
Here is the caller graph for this function:

◆ SplitEventAndTagNames()

static void SplitEventAndTagNames ( std::string  var_name,
std::string &  event_name,
std::string &  tag_name 
)
static

Definition at line 10184 of file mhttpd.cxx.

10184 {
10185 event_name = "";
10186 tag_name = "";
10187
10188 std::vector<size_t> colons;
10189
10190 for (size_t i = 0; i < var_name.size(); i++) {
10191 if (var_name[i] == ':') {
10192 colons.push_back(i);
10193 }
10194 }
10195
10196 if (colons.size() == 0) {
10197 // No colons - leave the tag name empty
10198 event_name = var_name;
10199 } else {
10200 size_t split_pos;
10201 size_t slash_pos = var_name.find("/");
10202 bool uses_per_variable_naming = (slash_pos != std::string::npos);
10203
10204 if (uses_per_variable_naming && colons.size() % 2 == 1) {
10205 size_t middle_colon_pos = colons[colons.size() / 2];
10206 std::string slash_to_mid = var_name.substr(slash_pos + 1, middle_colon_pos - slash_pos - 1);
10207 std::string mid_to_end = var_name.substr(middle_colon_pos + 1);
10208
10209 if (slash_to_mid == mid_to_end) {
10210 // Special case - we have a string of the form Beamlime/GS2:FC1:GS2:FC1.
10211 // Logger has already warned people that having colons in the equipment/event
10212 // names is a bad idea, so we only need to worry about them in the tag name.
10213 split_pos = middle_colon_pos;
10214 } else {
10215 // We have a string of the form Beamlime/Demand:GS2:FC1. Split at the first colon.
10216 split_pos = colons[0];
10217 }
10218 } else {
10219 // Normal case - split at the fist colon.
10220 split_pos = colons[0];
10221 }
10222
10223 event_name = var_name.substr(0, split_pos);
10224 tag_name = var_name.substr(split_pos + 1);
10225 }
10226}
Here is the caller graph for this function:

◆ starts_with()

bool starts_with ( const std::string &  s1,
const char *  s2 
)

Definition at line 4465 of file mhttpd.cxx.

4466{
4467 if (s1.length() < strlen(s2))
4468 return false;
4469 return (strncasecmp(s1.c_str(), s2, strlen(s2)) == 0);
4470}
Here is the caller graph for this function:

◆ strencode()

void strencode ( Return r,
const char *  text 
)

Definition at line 2049 of file mhttpd.cxx.

2050{
2051 size_t len = strlen(text);
2052 for (size_t i = 0; i < len; i++) {
2053 switch (text[i]) {
2054 case '\n':
2055 r->rsprintf("<br>\n");
2056 break;
2057 case '<':
2058 r->rsprintf("&lt;");
2059 break;
2060 case '>':
2061 r->rsprintf("&gt;");
2062 break;
2063 case '&':
2064 r->rsprintf("&amp;");
2065 break;
2066 case '\"':
2067 r->rsprintf("&quot;");
2068 break;
2069 default:
2070 r->rsprintf("%c", text[i]);
2071 }
2072 }
2073}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ strencode2()

std::string strencode2 ( const char *  text)

Definition at line 2077 of file mhttpd.cxx.

2078{
2079 std::string b;
2080 size_t len = strlen(text);
2081 for (size_t i = 0; i < len; i++) {
2082 switch (text[i]) {
2083 case '\n':
2084 b += "<br>\n";
2085 break;
2086 case '<':
2087 b += "&lt;";
2088 break;
2089 case '>':
2090 b += "&gt;";
2091 break;
2092 case '&':
2093 b += "&amp;";
2094 break;
2095 case '\"':
2096 b += "&quot;";
2097 break;
2098 default:
2099 b += text[i];
2100 break;
2101 }
2102 }
2103 return b;
2104}
Here is the caller graph for this function:

◆ strencode3()

void strencode3 ( Return r,
const char *  text 
)

Definition at line 2108 of file mhttpd.cxx.

2109{
2110 size_t len = strlen(text);
2111 for (size_t i = 0; i < len; i++) {
2112 switch (text[i]) {
2113 case '<':
2114 r->rsprintf("&lt;");
2115 break;
2116 case '>':
2117 r->rsprintf("&gt;");
2118 break;
2119 case '&':
2120 r->rsprintf("&amp;");
2121 break;
2122 case '\"':
2123 r->rsprintf("&quot;");
2124 break;
2125 default:
2126 r->rsprintf("%c", text[i]);
2127 }
2128 }
2129}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ strencode4()

void strencode4 ( Return r,
const char *  text 
)

Definition at line 2133 of file mhttpd.cxx.

2134{
2135 size_t len = strlen(text);
2136 for (size_t i = 0; i < len; i++) {
2137 switch (text[i]) {
2138 case '\n':
2139 r->rsprintf("<br>\n");
2140 break;
2141 case '<':
2142 r->rsprintf("&lt;");
2143 break;
2144 case '>':
2145 r->rsprintf("&gt;");
2146 break;
2147 case '&':
2148 r->rsprintf("&amp;");
2149 break;
2150 case '\"':
2151 r->rsprintf("&quot;");
2152 break;
2153 case ' ':
2154 r->rsprintf("&nbsp;");
2155 break;
2156 default:
2157 r->rsprintf("%c", text[i]);
2158 }
2159 }
2160}
Here is the call graph for this function:

◆ string_to_time()

time_t string_to_time ( const char *  str)

Definition at line 8150 of file mhttpd.cxx.

8151{
8152 time_t t = 0;
8153 for (; *str != 0; str++) {
8154 if (*str < '0')
8155 break;
8156 if (*str > '9')
8157 break;
8158 t *= 10;
8159 t += *str - '0';
8160 }
8161 return t;
8162}
Here is the caller graph for this function:

◆ stristr()

char * stristr ( const char *  str,
const char *  pattern 
)

Definition at line 371 of file mhttpd.cxx.

372{
373 char c1, c2, *ps, *pp;
374
375 if (str == NULL || pattern == NULL)
376 return NULL;
377
378 while (*str) {
379 ps = (char *) str;
380 pp = (char *) pattern;
381 c1 = *ps;
382 c2 = *pp;
383 if (toupper(c1) == toupper(c2)) {
384 while (*pp) {
385 c1 = *ps;
386 c2 = *pp;
387
388 if (toupper(c1) != toupper(c2))
389 break;
390
391 ps++;
392 pp++;
393 }
394
395 if (!*pp)
396 return (char *) str;
397 }
398 str++;
399 }
400
401 return NULL;
402}

◆ submit_elog()

void submit_elog ( MVOdb *  odb,
Param pp,
Return r,
Attachment a 
)

Definition at line 2278 of file mhttpd.cxx.

2279{
2280 char path[256], path1[256];
2281 char mail_to[256], mail_from[256], mail_list[256],
2282 smtp_host[256], tag[80], mail_param[1000];
2283 char *p, *pitem;
2284 HNDLE hDB, hkey;
2285 char att_file[3][256];
2286 int fh, size, n_mail;
2287 char mhttpd_full_url[256];
2288
2290 mstrlcpy(att_file[0], pp->getparam("attachment0"), sizeof(att_file[0]));
2291 mstrlcpy(att_file[1], pp->getparam("attachment1"), sizeof(att_file[1]));
2292 mstrlcpy(att_file[2], pp->getparam("attachment2"), sizeof(att_file[2]));
2293
2294 /* check for valid attachment files */
2295 for (int i = 0; i < 3; i++) {
2296 char str[256];
2297 sprintf(str, "attachment%d", i);
2298 //printf("submit_elog: att %d, [%s] param [%s], size %d\n", i, str, pp->getparam(str), a->_attachment_size[i]);
2299 if (pp->getparam(str) && *pp->getparam(str) && a->attachment_size[i] == 0) {
2300 /* replace '\' by '/' */
2301 mstrlcpy(path, pp->getparam(str), sizeof(path));
2302 mstrlcpy(path1, path, sizeof(path1));
2303 while (strchr(path, '\\'))
2304 *strchr(path, '\\') = '/';
2305
2306 /* check if valid ODB tree */
2307 if (db_find_key(hDB, 0, path, &hkey) == DB_SUCCESS) {
2308 std::string bout;
2309 gen_odb_attachment(r, path, bout);
2310 int bufsize = bout.length()+1;
2311 char* buf = (char*)M_MALLOC(bufsize);
2312 memcpy(buf, bout.c_str(), bufsize);
2313 mstrlcpy(att_file[i], path, sizeof(att_file[0]));
2314 mstrlcat(att_file[i], ".html", sizeof(att_file[0]));
2315 a->attachment_buffer[i] = buf;
2316 a->attachment_size[i] = bufsize;
2317 }
2318 /* check if local file */
2319 else if ((fh = open(path1, O_RDONLY | O_BINARY)) >= 0) {
2320 size = lseek(fh, 0, SEEK_END);
2321 char* buf = (char*)M_MALLOC(size);
2322 lseek(fh, 0, SEEK_SET);
2323 int rd = read(fh, buf, size);
2324 if (rd < 0)
2325 rd = 0;
2326 close(fh);
2327 mstrlcpy(att_file[i], path, sizeof(att_file[0]));
2328 a->attachment_buffer[i] = buf;
2329 a->attachment_size[i] = rd;
2330 } else if (strncmp(path, "/HS/", 4) == 0) {
2331 char* buf = (char*)M_MALLOC(100000);
2332 size = 100000;
2333 mstrlcpy(str, path + 4, sizeof(str));
2334 if (strchr(str, '?')) {
2335 p = strchr(str, '?') + 1;
2336 p = strtok(p, "&");
2337 while (p != NULL) {
2338 pitem = p;
2339 p = strchr(p, '=');
2340 if (p != NULL) {
2341 *p++ = 0;
2342 urlDecode(pitem); // parameter name
2343 urlDecode(p); // parameter value
2344
2345 pp->setparam(pitem, p);
2346
2347 p = strtok(NULL, "&");
2348 }
2349 }
2350 *strchr(str, '?') = 0;
2351 }
2352 show_hist_page(odb, pp, r, "image.gif", buf, &size, 0);
2353 mstrlcpy(att_file[i], str, sizeof(att_file[0]));
2354 a->attachment_buffer[i] = buf;
2355 a->attachment_size[i] = size;
2356 pp->unsetparam("scale");
2357 pp->unsetparam("offset");
2358 pp->unsetparam("width");
2359 pp->unsetparam("index");
2360 } else {
2361 r->rsprintf("HTTP/1.1 200 Document follows\r\n");
2362 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
2363 r->rsprintf("Content-Type: text/html; charset=%s\r\n\r\n", HTTP_ENCODING);
2364
2365 r->rsprintf("<html><head>\n");
2366 r->rsprintf("<link rel=\"icon\" href=\"favicon.png\" type=\"image/png\" />\n");
2367 r->rsprintf("<link rel=\"stylesheet\" href=\"midas.css\" type=\"text/css\" />\n");
2368 r->rsprintf("<link rel=\"stylesheet\" href=\"mhttpd.css\" type=\"text/css\" />\n");
2369 r->rsprintf("<title>ELog Error</title></head>\n");
2370 r->rsprintf("<i>Error: Attachment file <i>%s</i> not valid.</i><p>\n", pp->getparam(str));
2371 r->rsprintf("Please go back and enter a proper filename (use the <b>Browse</b> button).\n");
2372 r->rsprintf("<body></body></html>\n");
2373 return;
2374 }
2375 }
2376 }
2377
2378 int edit = atoi(pp->getparam("edit"));
2379 //printf("submit_elog: edit [%s] %d, orig [%s]\n", pp->getparam("edit"), edit, pp->getparam("orig"));
2380
2381 tag[0] = 0;
2382 if (edit) {
2383 mstrlcpy(tag, pp->getparam("orig"), sizeof(tag));
2384 }
2385
2386 int status = el_submit(atoi(pp->getparam("run")),
2387 pp->getparam("author"),
2388 pp->getparam("type"),
2389 pp->getparam("system"),
2390 pp->getparam("subject"),
2391 pp->getparam("text"),
2392 pp->getparam("orig"),
2393 *pp->getparam("html") ? "HTML" : "plain",
2394 att_file[0], a->attachment_buffer[0], a->attachment_size[0],
2395 att_file[1], a->attachment_buffer[1], a->attachment_size[1],
2396 att_file[2], a->attachment_buffer[2], a->attachment_size[2],
2397 tag, sizeof(tag));
2398
2399 //printf("el_submit status %d, tag [%s]\n", status, tag);
2400
2401 if (status != EL_SUCCESS) {
2402 cm_msg(MERROR, "submit_elog", "el_submit() returned status %d", status);
2403 }
2404
2405 /* supersede host name with "/Elog/Host name" */
2406 std::string elog_host_name;
2407 db_get_value_string(hDB, 0, "/Elog/Host name", 0, &elog_host_name, TRUE);
2408
2409 // K.O. FIXME: we cannot guess the Elog URL like this because
2410 // we do not know if access is through a proxy or redirect
2411 // we do not know if it's http: or https:, etc. Better
2412 // to read the whole "mhttpd_full_url" string from ODB.
2413 sprintf(mhttpd_full_url, "http://%s/", elog_host_name.c_str());
2414
2415 /* check for mail submissions */
2416 mail_param[0] = 0;
2417 n_mail = 0;
2418
2419 for (int index = 0; index <= 1; index++) {
2420 std::string str;
2421 str += "/Elog/Email ";
2422 if (index == 0)
2423 str += pp->getparam("type");
2424 else
2425 str += pp->getparam("system");
2426
2427 if (db_find_key(hDB, 0, str.c_str(), &hkey) == DB_SUCCESS) {
2428 size = sizeof(mail_list);
2429 db_get_data(hDB, hkey, mail_list, &size, TID_STRING);
2430
2431 if (db_find_key(hDB, 0, "/Elog/SMTP host", &hkey) != DB_SUCCESS) {
2432 show_error(r, "No SMTP host defined under /Elog/SMTP host");
2433 return;
2434 }
2435 size = sizeof(smtp_host);
2436 db_get_data(hDB, hkey, smtp_host, &size, TID_STRING);
2437
2438 p = strtok(mail_list, ",");
2439 while (1) {
2440 mstrlcpy(mail_to, p, sizeof(mail_to));
2441
2442 std::string exptname;
2443 db_get_value_string(hDB, 0, "/Experiment/Name", 0, &exptname, TRUE);
2444
2445 sprintf(mail_from, "MIDAS %s <MIDAS@%s>", exptname.c_str(), elog_host_name.c_str());
2446
2447 std::string mail_text;
2448 mail_text += "A new entry has been submitted by ";
2449 mail_text += pp->getparam("author");
2450 mail_text += "\n";
2451 mail_text += "\n";
2452
2453 mail_text += "Experiment : ";
2454 mail_text += exptname.c_str();
2455 mail_text += "\n";
2456
2457 mail_text += "Type : ";
2458 mail_text += pp->getparam("type");
2459 mail_text += "\n";
2460
2461 mail_text += "System : ";
2462 mail_text += pp->getparam("system");
2463 mail_text += "\n";
2464
2465 mail_text += "Subject : ";
2466 mail_text += pp->getparam("subject");
2467 mail_text += "\n";
2468
2469 mail_text += "Link : ";
2470 mail_text += mhttpd_full_url;
2471 mail_text += "/EL/";
2472 mail_text += tag;
2473 mail_text += "\n";
2474
2475 mail_text += "\n";
2476
2477 mail_text += pp->getparam("text");
2478 mail_text += "\n";
2479
2480 sendmail(elog_host_name.c_str(), smtp_host, mail_from, mail_to, pp->getparam("type"), mail_text.c_str());
2481
2482 if (mail_param[0] == 0)
2483 mstrlcpy(mail_param, "?", sizeof(mail_param));
2484 else
2485 mstrlcat(mail_param, "&", sizeof(mail_param));
2486 sprintf(mail_param + strlen(mail_param), "mail%d=%s", n_mail++, mail_to);
2487
2488 p = strtok(NULL, ",");
2489 if (!p)
2490 break;
2491 while (*p == ' ')
2492 p++;
2493 }
2494 }
2495 }
2496
2497 r->rsprintf("HTTP/1.1 302 Found\r\n");
2498 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
2499
2500 //if (mail_param[0])
2501 // r->rsprintf("Location: ../EL/%s?%s\n\n<html>redir</html>\r\n", tag, mail_param + 1);
2502 //else
2503 // r->rsprintf("Location: ../EL/%s\n\n<html>redir</html>\r\n", tag);
2504
2505 if (mail_param[0])
2506 r->rsprintf("Location: ?cmd=Show+elog&tag=%s&%s\n\n<html>redir</html>\r\n", tag, mail_param + 1);
2507 else
2508 r->rsprintf("Location: ?cmd=Show+elog&tag=%s\n\n<html>redir</html>\r\n", tag);
2509}
void unsetparam(const char *param)
Definition mhttpd.cxx:849
INT el_submit(int run, const char *author, const char *type, const char *syst, const char *subject, const char *text, const char *reply_to, const char *encoding, const char *afilename1, const char *buffer1, INT buffer_size1, const char *afilename2, const char *buffer2, INT buffer_size2, const char *afilename3, const char *buffer3, INT buffer_size3, char *tag, INT tag_size)
Definition elog.cxx:126
#define EL_SUCCESS
Definition midas.h:746
INT sendmail(const char *from_host, const char *smtp_host, const char *from, const char *to, const char *subject, const char *text)
Definition mhttpd.cxx:1285
void gen_odb_attachment(Return *r, const char *path, std::string &bout)
Definition mhttpd.cxx:2164
Here is the call graph for this function:
Here is the caller graph for this function:

◆ taxis()

void taxis ( gdImagePtr  im,
gdFont font,
int  col,
int  gcol,
int  x1,
int  y1,
int  width,
int  xr,
int  minor,
int  major,
int  text,
int  label,
int  grid,
double  xmin,
double  xmax 
)

Definition at line 7818 of file mhttpd.cxx.

7821{
7822 int dx, x_act, label_dx, major_dx, x_screen, maxwidth;
7823 int tick_base, major_base, label_base, xs, xl;
7824 char str[80];
7825 const int base[] = { 1, 5, 10, 60, 300, 600, 1800, 3600, 3600 * 6, 3600 * 12, 3600 * 24, 0 };
7826 time_t ltime;
7827 int force_date, d1, d2;
7828 struct tm tms;
7829
7830 if (xmax <= xmin || width <= 0)
7831 return;
7832
7833 /* force date display if xmax not today */
7834 ltime = ss_time();
7835 localtime_r(&ltime, &tms);
7836 d1 = tms.tm_mday;
7837 ltime = (time_t) xmax;
7838 localtime_r(&ltime, &tms);
7839 d2 = tms.tm_mday;
7840 force_date = (d1 != d2);
7841
7842 /* use 5 pixel as min tick distance */
7843 dx = (int) ((xmax - xmin) / (double) (width / 5) + 0.5);
7844
7845 for (tick_base = 0; base[tick_base]; tick_base++) {
7846 if (base[tick_base] > dx)
7847 break;
7848 }
7849 if (!base[tick_base])
7850 tick_base--;
7851 dx = base[tick_base];
7852
7853 if (base[tick_base + 1])
7854 major_base = tick_base + 1;
7855 else
7856 major_base = tick_base;
7857 major_dx = base[major_base];
7858
7859 if (base[major_base + 1])
7860 label_base = major_base + 1;
7861 else
7862 label_base = major_base;
7863 label_dx = base[label_base];
7864
7865 do {
7866 sec_to_label(str, (int) (xmin + 0.5), label_dx, force_date);
7867 maxwidth = font->h / 2 * strlen(str);
7868
7869 /* increasing label_dx, if labels would overlap */
7870 if (maxwidth > 0.7 * label_dx / (xmax - xmin) * width) {
7871 if (base[label_base + 1])
7872 label_dx = base[++label_base];
7873 else
7874 label_dx += 3600 * 24;
7875 } else
7876 break;
7877 } while (1);
7878
7879 x_act =
7880 (int) floor((double) (xmin - ss_timezone()) / label_dx) * label_dx + ss_timezone();
7881
7882 gdImageLine(im, x1, y1, x1 + width, y1, col);
7883
7884 do {
7885 x_screen = (int) ((x_act - xmin) / (xmax - xmin) * width + x1 + 0.5);
7886 xs = (int) (x_screen + 0.5);
7887
7888 if (x_screen > x1 + width + 0.001)
7889 break;
7890
7891 if (x_screen >= x1) {
7892 if ((x_act - ss_timezone()) % major_dx == 0) {
7893 if ((x_act - ss_timezone()) % label_dx == 0) {
7894 /* label tick mark */
7895 gdImageLine(im, xs, y1, xs, y1 + text, col);
7896
7897 /* grid line */
7898 if (grid != 0 && xs > x1 && xs < x1 + width)
7899 gdImageLine(im, xs, y1, xs, y1 + grid, col);
7900
7901 /* label */
7902 if (label != 0) {
7903 sec_to_label(str, x_act, label_dx, force_date);
7904
7905 /* if labels at edge, shift them in */
7906 xl = (int) xs - font->w * strlen(str) / 2;
7907 if (xl < 0)
7908 xl = 0;
7909 if (xl + font->w * (int) strlen(str) > xr)
7910 xl = xr - font->w * strlen(str);
7911 gdImageString(im, font, xl, y1 + label, str, col);
7912 }
7913 } else {
7914 /* major tick mark */
7915 gdImageLine(im, xs, y1, xs, y1 + major, col);
7916
7917 /* grid line */
7918 if (grid != 0 && xs > x1 && xs < x1 + width)
7919 gdImageLine(im, xs, y1 - 1, xs, y1 + grid, gcol);
7920 }
7921
7922 } else
7923 /* minor tick mark */
7924 gdImageLine(im, xs, y1, xs, y1 + minor, col);
7925
7926 }
7927
7928 x_act += dx;
7929
7930 /* supress 1.23E-17 ... */
7931 if (fabs((double)x_act) < dx / 100)
7932 x_act = 0;
7933
7934 } while (1);
7935}
INT ss_timezone()
Definition system.cxx:3652
void sec_to_label(char *result, int sec, int base, int force_date)
Definition mhttpd.cxx:7783
Here is the call graph for this function:
Here is the caller graph for this function:

◆ time_to_sec()

int time_to_sec ( const char *  str)

Definition at line 8125 of file mhttpd.cxx.

8126{
8127 double s;
8128
8129 s = atof(str);
8130 switch (str[strlen(str) - 1]) {
8131 case 'm':
8132 case 'M':
8133 s *= 60;
8134 break;
8135 case 'h':
8136 case 'H':
8137 s *= 3600;
8138 break;
8139 case 'd':
8140 case 'D':
8141 s *= 3600 * 24;
8142 break;
8143 }
8144
8145 return (int) s;
8146}
Here is the caller graph for this function:

◆ time_to_string()

std::string time_to_string ( time_t  t)

Definition at line 8166 of file mhttpd.cxx.

8167{
8168 char buf[256];
8169 sprintf(buf, "%.0f", (double)t);
8170 return buf;
8171}
Here is the caller graph for this function:

◆ toString()

static std::string toString ( int  i)
static

Definition at line 57 of file mhttpd.cxx.

58{
59 char buf[256];
60 sprintf(buf, "%d", i);
61 return buf;
62}
Here is the caller graph for this function:

◆ try_file_mg()

int try_file_mg ( const char *  try_dir,
const char *  filename,
std::string &  path,
FILE **  fpp,
bool  trace 
)

Definition at line 13671 of file mhttpd.cxx.

13672{
13673 if (fpp)
13674 *fpp = NULL;
13675 if (!try_dir)
13676 return SS_FILE_ERROR;
13677 if (strlen(try_dir) < 1)
13678 return SS_FILE_ERROR;
13679
13680 path = try_dir;
13681 if (path[path.length()-1] != DIR_SEPARATOR)
13682 path += DIR_SEPARATOR_STR;
13683 path += filename;
13684
13685 FILE* fp = fopen(path.c_str(), "r");
13686
13687 if (trace) {
13688 if (fp)
13689 printf("file \"%s\": OK!\n", path.c_str());
13690 else
13691 printf("file \"%s\": not found.\n", path.c_str());
13692 }
13693
13694 if (!fp)
13695 return SS_FILE_ERROR;
13696 else if (fpp)
13697 *fpp = fp;
13698 else
13699 fclose(fp);
13700
13701 return SUCCESS;
13702}
Here is the caller graph for this function:

◆ Unlock()

void Unlock ( RequestTrace t)

Definition at line 12275 of file mhttpd.cxx.

12276{
12278 gMutex.unlock();
12279}
double fTimeUnlocked
Definition mhttpd.cxx:420
Here is the call graph for this function:
Here is the caller graph for this function:

◆ urlDecode()

static void urlDecode ( char *  p)
static

Definition at line 912 of file mhttpd.cxx.

916{
917 //char *px = p;
918 char *pD, str[3];
919 int i;
920
921 //printf("URL decode: [%s] --> ", p);
922
923 pD = p;
924 while (*p) {
925 if (*p == '%') {
926 /* Escape: next 2 chars are hex representation of the actual character */
927 p++;
928 if (isxdigit(p[0]) && isxdigit(p[1])) {
929 str[0] = p[0];
930 str[1] = p[1];
931 str[2] = 0;
932 sscanf(str, "%02X", &i);
933
934 *pD++ = (char) i;
935 p += 2;
936 } else
937 *pD++ = '%';
938 } else if (*p == '+') {
939 /* convert '+' to ' ' */
940 *pD++ = ' ';
941 p++;
942 } else {
943 *pD++ = *p++;
944 }
945 }
946 *pD = '\0';
947
948 //printf("[%s]\n", px);
949}
Here is the caller graph for this function:

◆ UrlDecode()

static std::string UrlDecode ( const char *  p)
static

Definition at line 873 of file mhttpd.cxx.

877{
878 std::string s;
879
880 //printf("URL decode: [%s] --> ", p);
881
882 while (*p) {
883 if (*p == '%') {
884 /* Escape: next 2 chars are hex representation of the actual character */
885 p++;
886 if (isxdigit(p[0]) && isxdigit(p[1])) {
887 int i = 0;
888 char str[3];
889 str[0] = p[0];
890 str[1] = p[1];
891 str[2] = 0;
892 sscanf(str, "%02X", &i);
893
894 s += (char) i;
895 p += 2;
896 } else
897 s += '%';
898 } else if (*p == '+') {
899 /* convert '+' to ' ' */
900 s += ' ';
901 p++;
902 } else {
903 s += *p++;
904 }
905 }
906
907 //printf("[%s]\n", s.c_str());
908
909 return s;
910}
Here is the caller graph for this function:

◆ urlEncode() [1/2]

static void urlEncode ( char *  ps,
int  ps_size 
)
static

Definition at line 951 of file mhttpd.cxx.

956{
957 char *pd, *p;
958 int len = strlen(ps);
959 char *str = (char*)malloc(len*3 + 10); // at worst, each input character is expanded into 3 output characters
960
961 pd = str;
962 p = ps;
963 while (*p) {
964 if (isalnum(*p)) {
965 *pd++ = *p++;
966 } else {
967 sprintf(pd, "%%%02X", (*p)&0xFF);
968 pd += 3;
969 p++;
970 }
971 }
972 *pd = '\0';
973
974 if (/* DISABLES CODE */ (0)) {
975 printf("urlEncode [");
976 for (p=ps; *p!=0; p++)
977 printf("0x%02x ", (*p)&0xFF);
978 printf("]\n");
979
980 printf("urlEncode [%s] -> [%s]\n", ps, str);
981 }
982
983 mstrlcpy(ps, str, ps_size);
984 free(str);
985}
Here is the caller graph for this function:

◆ urlEncode() [2/2]

static std::string urlEncode ( const char *  text)
static

Definition at line 987 of file mhttpd.cxx.

992{
993 std::string encoded;
994
995 const char* p = text;
996 while (*p) {
997 if (isalnum(*p)) {
998 encoded += *p++;
999 } else {
1000 char buf[16];
1001 sprintf(buf, "%%%02X", (*p)&0xFF);
1002 encoded += buf;
1003 p++;
1004 }
1005 }
1006
1007 if (/* DISABLES CODE */ (0)) {
1008 printf("urlEncode [");
1009 for (p=text; *p!=0; p++)
1010 printf("0x%02x ", (*p)&0xFF);
1011 printf("]\n");
1012
1013 printf("urlEncode [%s] -> [%s]\n", text, encoded.c_str());
1014 }
1015
1016 return encoded;
1017}

◆ vaxis()

int vaxis ( gdImagePtr  im,
gdFont font,
int  col,
int  gcol,
int  x1,
int  y1,
int  width,
int  minor,
int  major,
int  text,
int  label,
int  grid,
double  ymin,
double  ymax,
BOOL  logaxis 
)

Definition at line 7939 of file mhttpd.cxx.

7943{
7944 double dy, int_dy, frac_dy, y_act, label_dy, major_dy, y_screen, y_next;
7945 int tick_base, major_base, label_base, n_sig1, n_sig2, ys, max_width;
7946 int last_label_y;
7947 char str[80];
7948 const double base[] = { 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000 };
7949
7950 if (ymax <= ymin || width <= 0)
7951 return 0;
7952
7953 // data type "double" only has about 15 significant digits, if difference between ymax and ymin is less than 10 significant digits, bailout! Otherwise code below goes into infinite loop
7954 if (fabs(ymax - ymin) <= 1e-10)
7955 return 0;
7956
7957 if (logaxis) {
7958 dy = pow(10, floor(log(ymin) / LN10));
7959 label_dy = dy;
7960 major_dy = dy * 10;
7961 n_sig1 = 4;
7962 } else {
7963 dy = (ymax - ymin) / (double) (width / 5);
7964
7965 frac_dy = modf(log(dy) / LN10, &int_dy);
7966 if (frac_dy < 0) {
7967 frac_dy += 1;
7968 int_dy -= 1;
7969 }
7970
7971 tick_base = frac_dy < LOG2 ? 1 : frac_dy < LOG5 ? 2 : 3;
7972 major_base = label_base = tick_base + 1;
7973
7974 /* rounding up of dy, label_dy */
7975 dy = pow(10, int_dy) * base[tick_base];
7976 major_dy = pow(10, int_dy) * base[major_base];
7977 label_dy = major_dy;
7978
7979 /* number of significant digits */
7980 if (ymin == 0)
7981 n_sig1 = 0;
7982 else
7983 n_sig1 =
7984 (int) floor(log(fabs(ymin)) / LN10) -
7985 (int) floor(log(fabs(label_dy)) / LN10) + 1;
7986
7987 if (ymax == 0)
7988 n_sig2 = 0;
7989 else
7990 n_sig2 =
7991 (int) floor(log(fabs(ymax)) / LN10) -
7992 (int) floor(log(fabs(label_dy)) / LN10) + 1;
7993
7994 n_sig1 = MAX(n_sig1, n_sig2);
7995 n_sig1 = MAX(n_sig1, 4);
7996
7997 /* increasing label_dy, if labels would overlap */
7998 while (label_dy / (ymax - ymin) * width < 1.5 * font->h) {
7999 label_base++;
8000 label_dy = pow(10, int_dy) * base[label_base];
8001 if (label_base % 3 == 2 && major_base % 3 == 1) {
8002 major_base++;
8003 major_dy = pow(10, int_dy) * base[major_base];
8004 }
8005 }
8006 }
8007
8008 max_width = 0;
8009 y_act = floor(ymin / dy) * dy;
8010
8011 if (x1 != 0 || y1 != 0)
8012 gdImageLine(im, x1, y1, x1, y1 - width, col);
8013
8014 last_label_y = y1 + 2 * font->h;
8015
8016 do {
8017 if (logaxis)
8018 y_screen = y1 - (log(y_act) - log(ymin)) / (log(ymax) - log(ymin)) * width;
8019 else
8020 y_screen = y1 - (y_act - ymin) / (ymax - ymin) * width;
8021 ys = (int) (y_screen + 0.5);
8022
8023 if (y_screen < y1 - width - 0.001)
8024 break;
8025
8026 if (y_screen <= y1 + 0.001) {
8027 if (fabs(floor(y_act / major_dy + 0.5) - y_act / major_dy) <
8028 dy / major_dy / 10.0) {
8029 if (fabs(floor(y_act / label_dy + 0.5) - y_act / label_dy) <
8030 dy / label_dy / 10.0) {
8031 if (x1 != 0 || y1 != 0) {
8032 /* label tick mark */
8033 gdImageLine(im, x1, ys, x1 + text, ys, col);
8034
8035 /* grid line */
8036 if (grid != 0 && y_screen < y1 && y_screen > y1 - width) {
8037 if (grid > 0)
8038 gdImageLine(im, x1 + 1, ys, x1 + grid, ys, gcol);
8039 else
8040 gdImageLine(im, x1 - 1, ys, x1 + grid, ys, gcol);
8041 }
8042
8043 /* label */
8044 if (label != 0) {
8045 sprintf(str, "%1.*lG", n_sig1, y_act);
8046 if (label < 0)
8047 gdImageString(im, font, x1 + label - font->w * strlen(str),
8048 ys - font->h / 2, str, col);
8049 else
8050 gdImageString(im, font, x1 + label, ys - font->h / 2, str, col);
8051
8052 last_label_y = ys - font->h / 2;
8053 }
8054 } else {
8055 sprintf(str, "%1.*lG", n_sig1, y_act);
8056 max_width = MAX(max_width, (int) (font->w * strlen(str)));
8057 }
8058 } else {
8059 if (x1 != 0 || y1 != 0) {
8060 /* major tick mark */
8061 gdImageLine(im, x1, ys, x1 + major, ys, col);
8062
8063 /* grid line */
8064 if (grid != 0 && y_screen < y1 && y_screen > y1 - width)
8065 gdImageLine(im, x1, ys, x1 + grid, ys, col);
8066 }
8067 }
8068 if (logaxis) {
8069 dy *= 10;
8070 major_dy *= 10;
8071 label_dy *= 10;
8072 }
8073
8074 } else {
8075 if (x1 != 0 || y1 != 0) {
8076 /* minor tick mark */
8077 gdImageLine(im, x1, ys, x1 + minor, ys, col);
8078 }
8079
8080 /* for logaxis, also put labes on minor tick marks */
8081 if (logaxis) {
8082 if (label != 0) {
8083 if (x1 != 0 || y1 != 0) {
8084 /* calculate position of next major label */
8085 y_next = pow(10, floor(log(y_act) / LN10) + 1);
8086 y_screen =
8087 (int) (y1 -
8088 (log(y_next) - log(ymin)) / (log(ymax) -
8089 log(ymin)) * width + 0.5);
8090
8091 if (ys + font->h / 2 < last_label_y
8092 && ys - font->h / 2 > y_screen + font->h / 2) {
8093 sprintf(str, "%1.*lG", n_sig1, y_act);
8094 if (label < 0)
8095 gdImageString(im, font, x1 + label - font->w * strlen(str),
8096 ys - font->h / 2, str, col);
8097 else
8098 gdImageString(im, font, x1 + label, ys - font->h / 2, str,
8099 col);
8100 }
8101
8102 last_label_y = ys - font->h / 2;
8103 } else {
8104 sprintf(str, "%1.*lG", n_sig1, y_act);
8105 max_width = MAX(max_width, (int) (font->w * strlen(str)));
8106 }
8107 }
8108 }
8109 }
8110 }
8111
8112 y_act += dy;
8113
8114 /* supress 1.23E-17 ... */
8115 if (fabs(y_act) < dy / 100)
8116 y_act = 0;
8117
8118 } while (1);
8119
8120 return max_width + abs(label);
8121}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ xdb_find_key()

static int xdb_find_key ( HNDLE  hDB,
HNDLE  dir,
const char *  str,
HNDLE hKey,
int  tid,
int  size 
)
static

Definition at line 10111 of file mhttpd.cxx.

10112{
10113 int status = db_find_key(hDB, dir, str, hKey);
10114 if (status == DB_SUCCESS)
10115 return status;
10116
10117 db_create_key(hDB, dir, str, tid);
10118 status = db_find_key(hDB, dir, str, hKey);
10119 if (status != DB_SUCCESS || !*hKey) {
10120 cm_msg(MERROR, "xdb_find_key", "Invalid ODB path \"%s\"", str);
10121 str = "bad_xdb_find_key";
10122 db_create_key(hDB, dir, str, tid);
10123 db_find_key(hDB, dir, str, hKey);
10124 }
10125 assert(*hKey);
10126
10127 if (tid == TID_STRING) {
10128 db_set_data_index(hDB, *hKey, "", size, 0, TID_STRING);
10129 }
10130
10131 return status;
10132}
Here is the call graph for this function:

◆ xdb_get_data_index()

int xdb_get_data_index ( HNDLE  hDB,
const char *  str,
void *  value,
int  size,
int  index,
int  tid 
)

Definition at line 10095 of file mhttpd.cxx.

10096{
10097 HNDLE hKey;
10098 int status = db_find_key(hDB, 0, str, &hKey);
10099 if (status != DB_SUCCESS)
10100 return status;
10101
10102 KEY key;
10103 db_get_key(hDB, hKey, &key);
10104 if (index >= key.num_values)
10105 return DB_OUT_OF_RANGE;
10106
10107 status = db_get_data_index(hDB, hKey, value, &size, index, tid);
10108 return status;
10109}
#define DB_OUT_OF_RANGE
Definition midas.h:652
Here is the call graph for this function:

◆ xmg_check_nonce()

static int xmg_check_nonce ( const char *  nonce)
static

Definition at line 13808 of file mhttpd.cxx.

13808 {
13809 unsigned long now = (unsigned long) time(NULL);
13810 unsigned long val = (unsigned long) strtoul(nonce, NULL, 16);
13811 return now < val || now - val < 3600;
13812}
Here is the caller graph for this function:

◆ xmg_http_send_digest_auth_request()

static void xmg_http_send_digest_auth_request ( struct mg_connection c,
const char *  domain 
)
static

Definition at line 13819 of file mhttpd.cxx.

13820 {
13821 mg_printf(c,
13822 "HTTP/1.1 401 Unauthorized\r\n"
13823 "WWW-Authenticate: Digest qop=\"auth\", "
13824 "realm=\"%s\", nonce=\"%lu\"\r\n"
13825 "Content-Length: 0\r\n\r\n",
13826 domain, (unsigned long) time(NULL));
13827}
int mg_printf(struct mg_connection *, PRINTF_FORMAT_STRING(const char *fmt),...) PRINTF_ARGS(2
Here is the call graph for this function:
Here is the caller graph for this function:

◆ xmg_mkmd5resp()

static void xmg_mkmd5resp ( const char *  method,
size_t  method_len,
const char *  uri,
size_t  uri_len,
const char *  ha1,
size_t  ha1_len,
const char *  nonce,
size_t  nonce_len,
const char *  nc,
size_t  nc_len,
const char *  cnonce,
size_t  cnonce_len,
const char *  qop,
size_t  qop_len,
char *  resp 
)
static

Definition at line 13787 of file mhttpd.cxx.

13791 {
13792 static const char colon[] = ":";
13793 static const size_t one = 1;
13794 char ha2[33];
13795
13796 cs_md5(ha2, method, method_len, colon, one, uri, uri_len, NULL);
13797 cs_md5(resp, ha1, ha1_len, colon, one, nonce, nonce_len, colon, one, nc,
13798 nc_len, colon, one, cnonce, cnonce_len, colon, one, qop, qop_len,
13799 colon, one, ha2, sizeof(ha2) - 1, NULL);
13800}
char * cs_md5(char buf[33],...)
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ _abort

std::atomic_bool _abort {false}

Definition at line 13483 of file mhttpd.cxx.

13483{false};

◆ cgif_bar_str

const char* cgif_bar_str[]
static
Initial value:
= {
"Src = STRING : [256] ",
"X = INT : 0",
"Y = INT : 0",
"Width = INT : 10",
"Height = INT : 100",
"Direction = INT : 0",
"Axis = INT : 1",
"Logscale = BOOL : n",
"Min = DOUBLE : 0",
"Max = DOUBLE : 10",
"FGColor = STRING : [8] 000000",
"BGColor = STRING : [8] FFFFFF",
"BDColor = STRING : [8] 808080",
NULL
}

Definition at line 3500 of file mhttpd.cxx.

3500 {
3501 "Src = STRING : [256] ",
3502 "X = INT : 0",
3503 "Y = INT : 0",
3504 "Width = INT : 10",
3505 "Height = INT : 100",
3506 "Direction = INT : 0",
3507 "Axis = INT : 1",
3508 "Logscale = BOOL : n",
3509 "Min = DOUBLE : 0",
3510 "Max = DOUBLE : 10",
3511 "FGColor = STRING : [8] 000000",
3512 "BGColor = STRING : [8] FFFFFF",
3513 "BDColor = STRING : [8] 808080",
3514 NULL
3515};

◆ cgif_label_str

const char* cgif_label_str[]
static
Initial value:
= {
"Src = STRING : [256] ",
"Format = STRING : [32] %1.1f",
"Font = STRING : [32] Medium",
"X = INT : 0",
"Y = INT : 0",
"Align = INT : 0",
"FGColor = STRING : [8] 000000",
"BGColor = STRING : [8] FFFFFF",
NULL
}

Definition at line 3460 of file mhttpd.cxx.

3460 {
3461 "Src = STRING : [256] ",
3462 "Format = STRING : [32] %1.1f",
3463 "Font = STRING : [32] Medium",
3464 "X = INT : 0",
3465 "Y = INT : 0",
3466 "Align = INT : 0",
3467 "FGColor = STRING : [8] 000000",
3468 "BGColor = STRING : [8] FFFFFF",
3469 NULL
3470};

◆ default_system_list

const char default_system_list[20][NAME_LENGTH]
static
Initial value:
= {
"General",
"DAQ",
"Detector",
"Electronics",
"Target",
"Beamline"
}

Definition at line 116 of file mhttpd.cxx.

116 {
117 "General",
118 "DAQ",
119 "Detector",
120 "Electronics",
121 "Target",
122 "Beamline"
123};

◆ default_type_list

const char default_type_list[20][NAME_LENGTH]
static
Initial value:
= {
"Routine",
"Shift summary",
"Minor error",
"Severe error",
"Fix",
"Question",
"Info",
"Modification",
"Reply",
"Alarm",
"Test",
"Other"
}

Definition at line 101 of file mhttpd.cxx.

101 {
102 "Routine",
103 "Shift summary",
104 "Minor error",
105 "Severe error",
106 "Fix",
107 "Question",
108 "Info",
109 "Modification",
110 "Reply",
111 "Alarm",
112 "Test",
113 "Other"
114};

◆ elog_mode

BOOL elog_mode = FALSE
static

Definition at line 94 of file mhttpd.cxx.

◆ favicon_ico

const unsigned char favicon_ico[]

Definition at line 288 of file mhttpd.cxx.

288 {
289 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x10, 0x10,
290 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0xe4, 0x01,
291 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x89, 0x50,
292 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00,
293 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00,
294 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x08, 0x06,
295 0x00, 0x00, 0x00, 0x1f, 0xf3, 0xff, 0x61, 0x00,
296 0x00, 0x01, 0xab, 0x49, 0x44, 0x41, 0x54, 0x78,
297 0x9c, 0x95, 0x92, 0x3d, 0x68, 0x14, 0x61, 0x10,
298 0x86, 0x9f, 0xf9, 0x76, 0xef, 0x27, 0x26, 0x5b,
299 0x28, 0xb1, 0x31, 0x55, 0x0a, 0x15, 0xce, 0xbd,
300 0x58, 0x1c, 0x36, 0x36, 0x62, 0xe3, 0x1d, 0x88,
301 0x4a, 0x2e, 0xb9, 0x2b, 0x2c, 0xc4, 0x46, 0x2b,
302 0x5b, 0x2b, 0xd1, 0x3a, 0xbd, 0x85, 0x68, 0x95,
303 0x80, 0x8d, 0xb7, 0x47, 0x40, 0x21, 0xf1, 0x12,
304 0x41, 0x22, 0x16, 0x42, 0x10, 0x8b, 0xf5, 0x12,
305 0x4d, 0xa7, 0x58, 0xab, 0x88, 0x8a, 0x3f, 0x7b,
306 0x3b, 0x63, 0x11, 0x02, 0x2a, 0xb7, 0x97, 0xdc,
307 0xc0, 0x54, 0xf3, 0xce, 0xc3, 0xfb, 0x0e, 0x83,
308 0x99, 0x91, 0xd5, 0xd3, 0xcb, 0xf1, 0xa9, 0xf3,
309 0x0f, 0xdf, 0x06, 0x83, 0x34, 0x8e, 0x8c, 0xaa,
310 0x77, 0xba, 0x75, 0x4f, 0xa4, 0x9d, 0x2b, 0x24,
311 0xcf, 0x2f, 0x3c, 0xda, 0x0a, 0xb2, 0x74, 0x7d,
312 0x01, 0x33, 0x9d, 0x8d, 0x13, 0x4e, 0xb8, 0x67,
313 0x30, 0x8e, 0x11, 0xe6, 0xf2, 0xc9, 0xd3, 0xa1,
314 0x00, 0xde, 0xd7, 0xcd, 0x57, 0x18, 0x2f, 0x11,
315 0x7e, 0x02, 0x1f, 0x55, 0xdd, 0xcd, 0x2c, 0x80,
316 0x98, 0x59, 0xdf, 0x41, 0x33, 0x8a, 0x3c, 0x0d,
317 0x4a, 0x5d, 0x4d, 0xed, 0xc6, 0xe2, 0xd9, 0x70,
318 0x71, 0x28, 0x07, 0x00, 0xad, 0x46, 0x23, 0x15,
319 0xec, 0x81, 0x25, 0xbd, 0x4c, 0xfb, 0x03, 0x01,
320 0xdb, 0xa5, 0xf9, 0xdc, 0x48, 0x7e, 0xa0, 0xa6,
321 0x6f, 0x84, 0x66, 0xf4, 0x62, 0x44, 0x83, 0xe0,
322 0x9a, 0xc0, 0x11, 0xc5, 0x7c, 0x4f, 0xbc, 0x3b,
323 0xad, 0x6a, 0x69, 0x7d, 0xcf, 0x0e, 0x34, 0x08,
324 0xe6, 0x80, 0x95, 0xa8, 0x16, 0x5e, 0x19, 0x3f,
325 0xf8, 0xfb, 0xaa, 0xa2, 0x97, 0x67, 0x9f, 0xbc,
326 0x39, 0x3c, 0x54, 0x84, 0x76, 0x2d, 0x8c, 0x01,
327 0xee, 0x56, 0x2a, 0x89, 0x99, 0x74, 0xb1, 0x9e,
328 0xb7, 0x27, 0xc0, 0xa5, 0xd5, 0x78, 0x14, 0x98,
329 0xac, 0xaf, 0xc6, 0x21, 0xc0, 0xe9, 0xb5, 0x35,
330 0x5f, 0xc4, 0x2a, 0xa2, 0xb9, 0x52, 0x3f, 0xc0,
331 0x3f, 0x37, 0x98, 0x7d, 0xbc, 0x71, 0xce, 0xb0,
332 0xe9, 0x3c, 0xee, 0x76, 0x8f, 0xf4, 0x0c, 0x22,
333 0x13, 0x86, 0x04, 0x42, 0xb2, 0xa0, 0xe6, 0x97,
334 0x45, 0x6c, 0xd2, 0x15, 0xbd, 0x5b, 0xf6, 0x23,
335 0x39, 0x69, 0xf8, 0x85, 0xf2, 0xfa, 0xb1, 0x25,
336 0x99, 0x59, 0x7e, 0xfd, 0x1e, 0xcc, 0x33, 0x71,
337 0x22, 0xa4, 0xcf, 0xda, 0xb5, 0xa9, 0x8b, 0x3b,
338 0xc0, 0xe6, 0xca, 0xe6, 0x81, 0xa8, 0x5a, 0xfa,
339 0x6c, 0x60, 0x00, 0xcd, 0x4e, 0x7c, 0x54, 0x8d,
340 0x05, 0xc4, 0x95, 0x01, 0x87, 0xb0, 0xe4, 0x10,
341 0x53, 0x44, 0x26, 0x04, 0x3b, 0x84, 0xb8, 0x2f,
342 0x7f, 0xdb, 0x6b, 0x55, 0x4b, 0x9f, 0x76, 0x96,
343 0x01, 0x5a, 0xb5, 0xa9, 0x2d, 0x9c, 0x1b, 0x05,
344 0xf6, 0x01, 0x45, 0x8c, 0xe3, 0x4e, 0x4c, 0x76,
345 0xf9, 0x85, 0xff, 0x32, 0xc3, 0x3b, 0x81, 0x14,
346 0x50, 0x84, 0x0f, 0xbe, 0x39, 0x99, 0x17, 0xd3,
347 0xfd, 0xdb, 0x43, 0xbd, 0xbf, 0x1b, 0x60, 0xac,
348 0x30, 0xd6, 0xf8, 0xf6, 0xeb, 0xfb, 0x75, 0x55,
349 0x2b, 0xf8, 0x45, 0x37, 0xf7, 0x07, 0x3b, 0x67,
350 0xc6, 0x0c, 0xb9, 0x56, 0xe3, 0x39, 0x00, 0x00,
351 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42,
352 0x60, 0x82
353};

◆ favicon_png

const unsigned char favicon_png[]

Definition at line 217 of file mhttpd.cxx.

217 {
218 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a,
219 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
220 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10,
221 0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0xf3, 0xff,
222 0x61, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59,
223 0x73, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00,
224 0xa0, 0x01, 0x5d, 0x7e, 0xbb, 0xa3, 0x00, 0x00,
225 0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f,
226 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x00, 0x77,
227 0x77, 0x77, 0x2e, 0x69, 0x6e, 0x6b, 0x73, 0x63,
228 0x61, 0x70, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x9b,
229 0xee, 0x3c, 0x1a, 0x00, 0x00, 0x01, 0xab, 0x49,
230 0x44, 0x41, 0x54, 0x38, 0x8d, 0x95, 0x92, 0x3d,
231 0x68, 0x14, 0x61, 0x10, 0x86, 0x9f, 0xf9, 0x76,
232 0xef, 0x27, 0x26, 0x5b, 0x28, 0xb1, 0x31, 0x55,
233 0x0a, 0x15, 0xce, 0xbd, 0x58, 0x1c, 0x36, 0x36,
234 0x62, 0xe3, 0x1d, 0x88, 0x4a, 0x2e, 0xb9, 0x2b,
235 0x2c, 0xc4, 0x46, 0x2b, 0x5b, 0x2b, 0xd1, 0x3a,
236 0xbd, 0x85, 0x68, 0x95, 0x80, 0x8d, 0xb7, 0x47,
237 0x40, 0x21, 0xf1, 0x12, 0x41, 0x22, 0x16, 0x42,
238 0x10, 0x8b, 0xf5, 0x12, 0x4d, 0xa7, 0x58, 0xab,
239 0x88, 0x8a, 0x3f, 0x7b, 0x3b, 0x63, 0x11, 0x02,
240 0x2a, 0xb7, 0x97, 0xdc, 0xc0, 0x54, 0xf3, 0xce,
241 0xc3, 0xfb, 0x0e, 0x83, 0x99, 0x91, 0xd5, 0xd3,
242 0xcb, 0xf1, 0xa9, 0xf3, 0x0f, 0xdf, 0x06, 0x83,
243 0x34, 0x8e, 0x8c, 0xaa, 0x77, 0xba, 0x75, 0x4f,
244 0xa4, 0x9d, 0x2b, 0x24, 0xcf, 0x2f, 0x3c, 0xda,
245 0x0a, 0xb2, 0x74, 0x7d, 0x01, 0x33, 0x9d, 0x8d,
246 0x13, 0x4e, 0xb8, 0x67, 0x30, 0x8e, 0x11, 0xe6,
247 0xf2, 0xc9, 0xd3, 0xa1, 0x00, 0xde, 0xd7, 0xcd,
248 0x57, 0x18, 0x2f, 0x11, 0x7e, 0x02, 0x1f, 0x55,
249 0xdd, 0xcd, 0x2c, 0x80, 0x98, 0x59, 0xdf, 0x41,
250 0x33, 0x8a, 0x3c, 0x0d, 0x4a, 0x5d, 0x4d, 0xed,
251 0xc6, 0xe2, 0xd9, 0x70, 0x71, 0x28, 0x07, 0x00,
252 0xad, 0x46, 0x23, 0x15, 0xec, 0x81, 0x25, 0xbd,
253 0x4c, 0xfb, 0x03, 0x01, 0xdb, 0xa5, 0xf9, 0xdc,
254 0x48, 0x7e, 0xa0, 0xa6, 0x6f, 0x84, 0x66, 0xf4,
255 0x62, 0x44, 0x83, 0xe0, 0x9a, 0xc0, 0x11, 0xc5,
256 0x7c, 0x4f, 0xbc, 0x3b, 0xad, 0x6a, 0x69, 0x7d,
257 0xcf, 0x0e, 0x34, 0x08, 0xe6, 0x80, 0x95, 0xa8,
258 0x16, 0x5e, 0x19, 0x3f, 0xf8, 0xfb, 0xaa, 0xa2,
259 0x97, 0x67, 0x9f, 0xbc, 0x39, 0x3c, 0x54, 0x84,
260 0x76, 0x2d, 0x8c, 0x01, 0xee, 0x56, 0x2a, 0x89,
261 0x99, 0x74, 0xb1, 0x9e, 0xb7, 0x27, 0xc0, 0xa5,
262 0xd5, 0x78, 0x14, 0x98, 0xac, 0xaf, 0xc6, 0x21,
263 0xc0, 0xe9, 0xb5, 0x35, 0x5f, 0xc4, 0x2a, 0xa2,
264 0xb9, 0x52, 0x3f, 0xc0, 0x3f, 0x37, 0x98, 0x7d,
265 0xbc, 0x71, 0xce, 0xb0, 0xe9, 0x3c, 0xee, 0x76,
266 0x8f, 0xf4, 0x0c, 0x22, 0x13, 0x86, 0x04, 0x42,
267 0xb2, 0xa0, 0xe6, 0x97, 0x45, 0x6c, 0xd2, 0x15,
268 0xbd, 0x5b, 0xf6, 0x23, 0x39, 0x69, 0xf8, 0x85,
269 0xf2, 0xfa, 0xb1, 0x25, 0x99, 0x59, 0x7e, 0xfd,
270 0x1e, 0xcc, 0x33, 0x71, 0x22, 0xa4, 0xcf, 0xda,
271 0xb5, 0xa9, 0x8b, 0x3b, 0xc0, 0xe6, 0xca, 0xe6,
272 0x81, 0xa8, 0x5a, 0xfa, 0x6c, 0x60, 0x00, 0xcd,
273 0x4e, 0x7c, 0x54, 0x8d, 0x05, 0xc4, 0x95, 0x01,
274 0x87, 0xb0, 0xe4, 0x10, 0x53, 0x44, 0x26, 0x04,
275 0x3b, 0x84, 0xb8, 0x2f, 0x7f, 0xdb, 0x6b, 0x55,
276 0x4b, 0x9f, 0x76, 0x96, 0x01, 0x5a, 0xb5, 0xa9,
277 0x2d, 0x9c, 0x1b, 0x05, 0xf6, 0x01, 0x45, 0x8c,
278 0xe3, 0x4e, 0x4c, 0x76, 0xf9, 0x85, 0xff, 0x32,
279 0xc3, 0x3b, 0x81, 0x14, 0x50, 0x84, 0x0f, 0xbe,
280 0x39, 0x99, 0x17, 0xd3, 0xfd, 0xdb, 0x43, 0xbd,
281 0xbf, 0x1b, 0x60, 0xac, 0x30, 0xd6, 0xf8, 0xf6,
282 0xeb, 0xfb, 0x75, 0x55, 0x2b, 0xf8, 0x45, 0x37,
283 0xf7, 0x07, 0x3b, 0x67, 0xc6, 0x0c, 0xa4, 0x18,
284 0xfd, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45,
285 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
286};

◆ gAllowedHosts

std::vector<std::string> gAllowedHosts
static

Definition at line 13495 of file mhttpd.cxx.

◆ gAuthMg

Auth* gAuthMg = NULL
static

Definition at line 13785 of file mhttpd.cxx.

◆ gDoReloadHistory

bool gDoReloadHistory = false
static

Definition at line 8176 of file mhttpd.cxx.

◆ gDoSetupHistoryWatch

bool gDoSetupHistoryWatch = true
static

Definition at line 8175 of file mhttpd.cxx.

◆ gMh

MidasHistoryInterface* gMh = NULL
static

Definition at line 8185 of file mhttpd.cxx.

◆ gMhkey

HNDLE gMhkey = 0
static

Definition at line 8186 of file mhttpd.cxx.

◆ gMimeTypesOdb

MVOdb* gMimeTypesOdb = NULL
static

Definition at line 179 of file mhttpd.cxx.

◆ gMimetypeTable

const MimetypeTableEntry gMimetypeTable[]

Definition at line 130 of file mhttpd.cxx.

130 {
131 { ".ASC", "text/plain" },
132 { ".CSS", "text/css" },
133 { ".CSV", "text/csv" },
134 { ".HTM", "text/html" },
135 { ".HTML", "text/html" },
136 { ".TXT", "text/plain" },
137
138 { ".BMP", "image/bmp" },
139 { ".GIF", "image/gif" },
140 { ".ICO", "image/x-icon" },
141 { ".JPEG", "image/jpeg" },
142 { ".JPG", "image/jpeg" },
143 { ".PNG", "image/png" },
144 { ".SVG", "image/svg+xml" },
145 { ".TIF", "image/tiff" },
146 { ".TIFF", "image/tiff" },
147
148 { ".MID", "audio/midi" },
149 { ".MP3", "audio/mpeg" },
150 { ".OGA", "audio/ogg" },
151 { ".OGG", "audio/ogg" },
152 { ".WAV", "audio/wav" },
153
154 { ".BIN", "application/octet-stream" },
155 { ".BZ", "application/x-bzip" },
156 { ".BZ2", "application/x-bzip2" },
157 { ".DOC", "application/msword" },
158 { ".EPS", "application/postscript" },
159 { ".GZ", "application/gzip" },
160 { ".JS", "application/javascript" },
161 { ".JSON", "application/json" },
162 { ".MJS", "application/javascript" },
163 { ".PDF", "application/pdf" },
164 { ".PHP", "application/x-httpd-php" },
165 { ".RTF", "application/rtf" },
166 { ".PS", "application/postscript" },
167 { ".ROOT", "application/octet-stream" },
168 { ".XLS", "application/x-msexcel" },
169 { ".XML", "application/xml" },
170 { ".ZIP", "application/zip" },
171
172 { ".ODP", "application/vnd.oasis.opendocument.presentation" },
173 { ".ODS", "application/vnd.oasis.opendocument.spreadsheet" },
174 { ".ODT", "application/vnd.oasis.opendocument.text" },
175
176 { "", "" }
177};

◆ gMutex

std::mutex gMutex
static

Definition at line 47 of file mhttpd.cxx.

◆ gOdb

MVOdb* gOdb = NULL
static

Definition at line 48 of file mhttpd.cxx.

◆ gTraceBuf

RequestTraceBuf* gTraceBuf = NULL
static

Definition at line 536 of file mhttpd.cxx.

◆ history_mode

BOOL history_mode = FALSE
static

Definition at line 95 of file mhttpd.cxx.

◆ http_trace

int http_trace = 0
static

Definition at line 465 of file mhttpd.cxx.

◆ mname

const char* mname[]
extern

Definition at line 144 of file midas.cxx.

144 {
145 "January",
146 "February",
147 "March",
148 "April",
149 "May",
150 "June",
151 "July",
152 "August",
153 "September",
154 "October",
155 "November",
156 "December"
157};

◆ trace_mg

bool trace_mg = false
static

Definition at line 13737 of file mhttpd.cxx.

◆ trace_mg_recv

bool trace_mg_recv = false
static

Definition at line 13738 of file mhttpd.cxx.

◆ trace_mg_send

bool trace_mg_send = false
static

Definition at line 13739 of file mhttpd.cxx.

◆ trace_mg_verbose

bool trace_mg_verbose = false
static

Definition at line 13740 of file mhttpd.cxx.

◆ verbose

BOOL verbose = FALSE
static

Definition at line 96 of file mhttpd.cxx.

◆ verbose_mg

bool verbose_mg = false
static

Definition at line 13736 of file mhttpd.cxx.